mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-10 15:42:14 +00:00
ICU-12708 bye bye layout engine
X-SVN-Rev: 39176
This commit is contained in:
parent
78e91a274f
commit
4136a2f257
211 changed files with 209 additions and 32161 deletions
.gitignore
icu4c
readme.html
source
Makefile.inaclocal.m4
allinone
config
configureconfigure.acdata
icudefs.mk.inlayout
AlternateSubstSubtables.cppAlternateSubstSubtables.hAnchorTables.cppAnchorTables.hArabicLayoutEngine.cppArabicLayoutEngine.hArabicShaping.cppArabicShaping.hAttachmentPosnSubtables.hCanonData.cppCanonShaping.cppCanonShaping.hCharSubstitutionFilter.hClassDefinitionTables.cppClassDefinitionTables.hContextualGlyphInsertion.hContextualGlyphInsertionProc2.cppContextualGlyphInsertionProc2.hContextualGlyphSubstProc.cppContextualGlyphSubstProc.hContextualGlyphSubstProc2.cppContextualGlyphSubstProc2.hContextualGlyphSubstitution.hContextualSubstSubtables.cppContextualSubstSubtables.hCoverageTables.cppCoverageTables.hCursiveAttachmentSubtables.cppCursiveAttachmentSubtables.hDefaultCharMapper.hDeviceTables.cppDeviceTables.hExtensionSubtables.cppExtensionSubtables.hFeatures.cppGDEFMarkFilter.cppGDEFMarkFilter.hGXLayoutEngine.cppGXLayoutEngine.hGXLayoutEngine2.cppGXLayoutEngine2.hGlyphDefinitionTables.cppGlyphDefinitionTables.hGlyphIterator.cppGlyphIterator.hGlyphLookupTables.cppGlyphLookupTables.hGlyphPositionAdjustments.cppGlyphPositionAdjustments.hGlyphPositioningTables.cppGlyphPositioningTables.hGlyphPosnLookupProc.cppGlyphPosnLookupProc.hGlyphSubstLookupProc.cppGlyphSubstLookupProc.hGlyphSubstitutionTables.cppGlyphSubstitutionTables.hHanLayoutEngine.cppHanLayoutEngine.hHangulLayoutEngine.cppHangulLayoutEngine.hICUFeatures.hIndicClassTables.cppIndicLayoutEngine.cppIndicLayoutEngine.hIndicRearrangement.hIndicRearrangementProcessor.cppIndicRearrangementProcessor.hIndicRearrangementProcessor2.cppIndicRearrangementProcessor2.hIndicReordering.cppIndicReordering.hKernTable.cppKernTable.hKhmerLayoutEngine.cppKhmerLayoutEngine.hKhmerReordering.cppKhmerReordering.hLEFontInstance.cppLEFontInstance.hLEGlyphFilter.hLEGlyphStorage.cppLEGlyphStorage.h
14
.gitignore
vendored
14
.gitignore
vendored
|
@ -125,20 +125,6 @@ icu4c/source/io/io.vcproj.*.*.user
|
|||
icu4c/source/io/release
|
||||
icu4c/source/io/x64
|
||||
icu4c/source/io/x86
|
||||
icu4c/source/layout/*.ao
|
||||
icu4c/source/layout/*.d
|
||||
icu4c/source/layout/*.o
|
||||
icu4c/source/layout/*.pdb
|
||||
icu4c/source/layout/*.vcxproj.user
|
||||
icu4c/source/layout/Debug
|
||||
icu4c/source/layout/Makefile
|
||||
icu4c/source/layout/Release
|
||||
icu4c/source/layout/debug
|
||||
icu4c/source/layout/layout.res
|
||||
icu4c/source/layout/layout.vcproj.*.*.user
|
||||
icu4c/source/layout/release
|
||||
icu4c/source/layout/x64
|
||||
icu4c/source/layout/x86
|
||||
icu4c/source/layoutex/*.ao
|
||||
icu4c/source/layoutex/*.d
|
||||
icu4c/source/layoutex/*.o
|
||||
|
|
|
@ -149,8 +149,6 @@
|
|||
|
||||
<li>Calendar specific date and time manipulation</li>
|
||||
|
||||
<li>Complex text layout for Arabic, Hebrew, Indic and Thai</li>
|
||||
|
||||
<li>Text boundary analysis for finding characters, word and sentence
|
||||
boundaries</li>
|
||||
</ul>
|
||||
|
@ -235,6 +233,24 @@
|
|||
<h2><a name="News" href="#News" id="News">What is new in this
|
||||
release?</a></h2>
|
||||
|
||||
<h3>Layout Engine Removed</h3>
|
||||
<p>The LayoutEngine was deprecated in ICU 54 and has now been removed.
|
||||
see <a href='http://userguide.icu-project.org/layoutengine'>the
|
||||
User's Guide</a> for more details and migration recommendations.
|
||||
</p>
|
||||
<p>
|
||||
Note that the ParagraphLayout (layoutex) library is not deprecated.
|
||||
There is a new option, <tt>--enable-layoutex</tt> which will build
|
||||
the ParagraphLayout library using <a href="http://harfbuzz.org">HarfBuzz</a>
|
||||
instead of ICU as the layout engine. See <a href="http://userguide.icu-project.org/layoutengine">
|
||||
the users' guide</a> for more information about how to build.
|
||||
</p>
|
||||
<p>
|
||||
The options <tt>--disable-layout</tt>
|
||||
or <tt>--with-layout=false</tt> are being retained for
|
||||
compatibility, but have no effect.
|
||||
</p>
|
||||
|
||||
<h3>API Changes</h3>
|
||||
<p>See the <a href="APIChangeReport.html">API Change Report</a> for a complete
|
||||
list of APIs added, removed, or changed in this release.</p>
|
||||
|
@ -269,21 +285,6 @@
|
|||
<tt>#define UCONFIG_ENABLE_PLUGINS</tt>.
|
||||
</p>
|
||||
|
||||
<!-- ICU 55 items -->
|
||||
<h3>ICU 55: Layout Engine breaking API change</h3>
|
||||
<p>The LayoutEngine (already deprecated) has had the function
|
||||
<tt>LEFontInstance::getFontTable(LETag, size_t &length)</tt>
|
||||
since ICU 52. Its implementation was optional. In ICU 55, this
|
||||
version
|
||||
of <tt>getFontTable</tt> has been made pure virtual, and the
|
||||
version without a length (<tt>getFontTable(LETag)</tt>) has been
|
||||
completely removed. This is a breaking change for users who have
|
||||
not implemented the two-argument <tt>getFontTable()</tt>
|
||||
function in their <tt>LEFontInstance</tt> subclasses.
|
||||
The break is intentional, as the one-argument version cannot be
|
||||
made secure. See <tt>LEFontInstance</tt> api docs for more detail.
|
||||
</p>
|
||||
|
||||
<h3>ICU 55: Deprecations in PluralRules (plurrule.h)</h3>
|
||||
<p>The following PluralRules methods never had an implementation
|
||||
but were inadvertently marked @stable; they have now been
|
||||
|
@ -306,21 +307,6 @@
|
|||
<li><tt>uidna_toUnicode</tt></li>
|
||||
</ul>
|
||||
|
||||
<!-- ICU 54 items -->
|
||||
<h3>ICU 54: Deprecation of Layout Engine</h3>
|
||||
<p>The LayoutEngine is now deprecated. Please
|
||||
see <a href='http://userguide.icu-project.org/layoutengine'>the
|
||||
User's Guide</a> for more details and migration recommendations.
|
||||
In the future, passing "<tt>--enable-layout</tt>" to configure
|
||||
will be required to
|
||||
enable the layout engine.</p>
|
||||
<p>
|
||||
Note that the ParagraphLayout (layoutex) library is not deprecated.
|
||||
There is a new option, <tt>--enable-layoutex</tt> which will build
|
||||
the ParagraphLayout library using <a href="http://harfbuzz.org">HarfBuzz</a>
|
||||
instead of ICU as the layout engine. See <a href="http://userguide.icu-project.org/layoutengine">
|
||||
the users' guide</a> for more information about how to build.
|
||||
</p>
|
||||
<h3>ICU 54: Deprecation of Collation Short Strings</h3>
|
||||
<p>The collation short naming scheme and its API functions are deprecated.
|
||||
Use ucol_open() with language tag collation keywords instead (see <a href="http://userguide.icu-project.org/collation/api">Collation API Details</a>). For example, <code>ucol_open("de-u-co-phonebk-ka-shifted", &errorCode)</code>
|
||||
|
@ -442,11 +428,6 @@
|
|||
analysis, and transliteration.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><i><ICU></i>/source/<b>layout</b>/</td>
|
||||
|
||||
<td>Contains the ICU complex text layout engine. (Deprecated)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><i><ICU></i>/source/<b>layoutex</b>/</td>
|
||||
|
||||
|
@ -1512,16 +1493,6 @@ gnumake</pre>
|
|||
functions.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Layout Engine</td>
|
||||
|
||||
<td>icule<i>XY</i>.dll</td>
|
||||
|
||||
<td>libicule.so.<i>XY</i>.<i>Z</i></td>
|
||||
|
||||
<td>An optional engine for doing font layout.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Layout Extensions Engine</td>
|
||||
|
||||
|
@ -1529,7 +1500,9 @@ gnumake</pre>
|
|||
|
||||
<td>libiculx.so.<i>XY</i>.<i>Z</i></td>
|
||||
|
||||
<td>An optional engine for doing font layout that uses parts of ICU.</td>
|
||||
<td>An optional engine for doing paragraph layout that uses
|
||||
parts of ICU.
|
||||
HarfBuzz is required.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
|
|
@ -31,7 +31,6 @@ subdir = .
|
|||
#AUTOCONF = @AUTOCONF@
|
||||
|
||||
## Optional directory setup
|
||||
@LAYOUT_TRUE@LAYOUT = layout
|
||||
@LAYOUTEX_TRUE@LAYOUTEX = layoutex
|
||||
@ICUIO_TRUE@ICUIO = io
|
||||
@EXTRAS_TRUE@EXTRA = extra
|
||||
|
@ -41,7 +40,6 @@ subdir = .
|
|||
|
||||
## pkgconfig setup. Always have uc and i18n. Others are optional.
|
||||
ALL_PKGCONFIG_SUFFIX=uc i18n
|
||||
@LAYOUT_TRUE@ALL_PKGCONFIG_SUFFIX+= le
|
||||
@LAYOUTEX_TRUE@ALL_PKGCONFIG_SUFFIX+= lx
|
||||
@ICUIO_TRUE@ALL_PKGCONFIG_SUFFIX+= io
|
||||
|
||||
|
@ -60,7 +58,7 @@ INSTALLED_BUILT_FILES = $(top_builddir)/config/Makefile.inc $(top_builddir)/conf
|
|||
LOCAL_BUILT_FILES = icudefs.mk config/icucross.mk config/icucross.inc
|
||||
|
||||
DOCDIRS = common i18n
|
||||
SUBDIRS = stubdata common i18n $(LAYOUT) $(LAYOUTEX) $(ICUIO) $(TOOLS) data $(EXTRA) $(SAMPLE) $(TEST)
|
||||
SUBDIRS = stubdata common i18n $(LAYOUTEX) $(ICUIO) $(TOOLS) data $(EXTRA) $(SAMPLE) $(TEST)
|
||||
|
||||
SECTION = 1
|
||||
|
||||
|
@ -115,13 +113,13 @@ doc doc-searchengine:
|
|||
else
|
||||
doc: doc/html/index.html
|
||||
|
||||
doc-searchengine: Doxyfile $(wildcard ./common/unicode/platform.h $(srcdir)/common/unicode/*.h $(srcdir)/i18n/unicode/*.h $(srcdir)/layout/unicode/*.h $(srcdir)/io/unicode/*.h)
|
||||
doc-searchengine: Doxyfile $(wildcard ./common/unicode/platform.h $(srcdir)/common/unicode/*.h $(srcdir)/i18n/unicode/*.h $(srcdir)/io/unicode/*.h)
|
||||
sed < Doxyfile -e 's%[^#]*SEARCHENGINE.*%SEARCHENGINE=YES%' | $(DOXYGEN) -
|
||||
@echo adding links from non-namespaced class files
|
||||
find doc/html -name 'classicu_1_1*' -print | sed -e 's%^\(.*class\)icu_1_1\(.*\)$$%ln & \1\2%' | sh
|
||||
@echo Docs created - WARNING, probably contains non-GPL .js files
|
||||
|
||||
doc/html/index.html: Doxyfile $(wildcard ./common/unicode/platform.h $(srcdir)/common/unicode/*.h $(srcdir)/i18n/unicode/*.h $(srcdir)/layout/unicode/*.h $(srcdir)/io/unicode/*.h)
|
||||
doc/html/index.html: Doxyfile $(wildcard ./common/unicode/platform.h $(srcdir)/common/unicode/*.h $(srcdir)/i18n/unicode/*.h $(srcdir)/io/unicode/*.h)
|
||||
$(DOXYGEN)
|
||||
@echo adding links from non-namespaced class files
|
||||
find doc/html -name 'classicu_1_1*' -print | sed -e 's%^\(.*class\)icu_1_1\(.*\)$$%ln & \1\2%' | sh
|
||||
|
@ -285,14 +283,6 @@ config/icu-io.pc: config/icu.pc Makefile icudefs.mk
|
|||
@echo "Libs:" "${ICULIBS_IO}" >> $@
|
||||
@echo $@ updated.
|
||||
|
||||
config/icu-le.pc: config/icu.pc Makefile icudefs.mk
|
||||
@cat config/icu.pc > $@
|
||||
@echo "Description: $(PACKAGE_ICU_DESCRIPTION): Layout library" >> $@
|
||||
@echo "Name: $(PACKAGE)-le" >> $@
|
||||
@echo "Requires: icu-uc" >> $@
|
||||
@echo "Libs:" "${ICULIBS_LE}" >> $@
|
||||
@echo $@ updated.
|
||||
|
||||
ICULEHB_LIBS=@ICULEHB_LIBS@
|
||||
USING_HB=
|
||||
ifneq ($(ICULEHB_LIBS),)
|
||||
|
|
213
icu4c/source/aclocal.m4
vendored
213
icu4c/source/aclocal.m4
vendored
|
@ -1,6 +1,6 @@
|
|||
# generated automatically by aclocal 1.15 -*- Autoconf -*-
|
||||
# generated automatically by aclocal 1.14.1 -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1996-2014 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1996-2013 Free Software Foundation, Inc.
|
||||
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
|
@ -12,32 +12,63 @@
|
|||
# PARTICULAR PURPOSE.
|
||||
|
||||
m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
|
||||
# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
|
||||
# serial 1 (pkg-config-0.24)
|
||||
#
|
||||
# Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
dnl pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
|
||||
dnl serial 11 (pkg-config-0.29.1)
|
||||
dnl
|
||||
dnl Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
|
||||
dnl Copyright © 2012-2015 Dan Nicholson <dbn.lists@gmail.com>
|
||||
dnl
|
||||
dnl This program is free software; you can redistribute it and/or modify
|
||||
dnl it under the terms of the GNU General Public License as published by
|
||||
dnl the Free Software Foundation; either version 2 of the License, or
|
||||
dnl (at your option) any later version.
|
||||
dnl
|
||||
dnl This program is distributed in the hope that it will be useful, but
|
||||
dnl WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
dnl General Public License for more details.
|
||||
dnl
|
||||
dnl You should have received a copy of the GNU General Public License
|
||||
dnl along with this program; if not, write to the Free Software
|
||||
dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
dnl 02111-1307, USA.
|
||||
dnl
|
||||
dnl As a special exception to the GNU General Public License, if you
|
||||
dnl distribute this file as part of a program that contains a
|
||||
dnl configuration script generated by Autoconf, you may include it under
|
||||
dnl the same distribution terms that you use for the rest of that
|
||||
dnl program.
|
||||
|
||||
# PKG_PROG_PKG_CONFIG([MIN-VERSION])
|
||||
# ----------------------------------
|
||||
dnl PKG_PREREQ(MIN-VERSION)
|
||||
dnl -----------------------
|
||||
dnl Since: 0.29
|
||||
dnl
|
||||
dnl Verify that the version of the pkg-config macros are at least
|
||||
dnl MIN-VERSION. Unlike PKG_PROG_PKG_CONFIG, which checks the user's
|
||||
dnl installed version of pkg-config, this checks the developer's version
|
||||
dnl of pkg.m4 when generating configure.
|
||||
dnl
|
||||
dnl To ensure that this macro is defined, also add:
|
||||
dnl m4_ifndef([PKG_PREREQ],
|
||||
dnl [m4_fatal([must install pkg-config 0.29 or later before running autoconf/autogen])])
|
||||
dnl
|
||||
dnl See the "Since" comment for each macro you use to see what version
|
||||
dnl of the macros you require.
|
||||
m4_defun([PKG_PREREQ],
|
||||
[m4_define([PKG_MACROS_VERSION], [0.29.1])
|
||||
m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1,
|
||||
[m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])])
|
||||
])dnl PKG_PREREQ
|
||||
|
||||
dnl PKG_PROG_PKG_CONFIG([MIN-VERSION])
|
||||
dnl ----------------------------------
|
||||
dnl Since: 0.16
|
||||
dnl
|
||||
dnl Search for the pkg-config tool and set the PKG_CONFIG variable to
|
||||
dnl first found in the path. Checks that the version of pkg-config found
|
||||
dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is
|
||||
dnl used since that's the first version where most current features of
|
||||
dnl pkg-config existed.
|
||||
AC_DEFUN([PKG_PROG_PKG_CONFIG],
|
||||
[m4_pattern_forbid([^_?PKG_[A-Z_]+$])
|
||||
m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$])
|
||||
|
@ -59,18 +90,19 @@ if test -n "$PKG_CONFIG"; then
|
|||
PKG_CONFIG=""
|
||||
fi
|
||||
fi[]dnl
|
||||
])# PKG_PROG_PKG_CONFIG
|
||||
])dnl PKG_PROG_PKG_CONFIG
|
||||
|
||||
# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
|
||||
#
|
||||
# Check to see whether a particular set of modules exists. Similar
|
||||
# to PKG_CHECK_MODULES(), but does not set variables or print errors.
|
||||
#
|
||||
# Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG])
|
||||
# only at the first occurence in configure.ac, so if the first place
|
||||
# it's called might be skipped (such as if it is within an "if", you
|
||||
# have to call PKG_CHECK_EXISTS manually
|
||||
# --------------------------------------------------------------
|
||||
dnl PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
|
||||
dnl -------------------------------------------------------------------
|
||||
dnl Since: 0.18
|
||||
dnl
|
||||
dnl Check to see whether a particular set of modules exists. Similar to
|
||||
dnl PKG_CHECK_MODULES(), but does not set variables or print errors.
|
||||
dnl
|
||||
dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG])
|
||||
dnl only at the first occurence in configure.ac, so if the first place
|
||||
dnl it's called might be skipped (such as if it is within an "if", you
|
||||
dnl have to call PKG_CHECK_EXISTS manually
|
||||
AC_DEFUN([PKG_CHECK_EXISTS],
|
||||
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
|
||||
if test -n "$PKG_CONFIG" && \
|
||||
|
@ -80,8 +112,10 @@ m4_ifvaln([$3], [else
|
|||
$3])dnl
|
||||
fi])
|
||||
|
||||
# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])
|
||||
# ---------------------------------------------
|
||||
dnl _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])
|
||||
dnl ---------------------------------------------
|
||||
dnl Internal wrapper calling pkg-config via PKG_CONFIG and setting
|
||||
dnl pkg_failed based on the result.
|
||||
m4_define([_PKG_CONFIG],
|
||||
[if test -n "$$1"; then
|
||||
pkg_cv_[]$1="$$1"
|
||||
|
@ -93,10 +127,11 @@ m4_define([_PKG_CONFIG],
|
|||
else
|
||||
pkg_failed=untried
|
||||
fi[]dnl
|
||||
])# _PKG_CONFIG
|
||||
])dnl _PKG_CONFIG
|
||||
|
||||
# _PKG_SHORT_ERRORS_SUPPORTED
|
||||
# -----------------------------
|
||||
dnl _PKG_SHORT_ERRORS_SUPPORTED
|
||||
dnl ---------------------------
|
||||
dnl Internal check to see if pkg-config supports short errors.
|
||||
AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED],
|
||||
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])
|
||||
if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
|
||||
|
@ -104,19 +139,17 @@ if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
|
|||
else
|
||||
_pkg_short_errors_supported=no
|
||||
fi[]dnl
|
||||
])# _PKG_SHORT_ERRORS_SUPPORTED
|
||||
])dnl _PKG_SHORT_ERRORS_SUPPORTED
|
||||
|
||||
|
||||
# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
|
||||
# [ACTION-IF-NOT-FOUND])
|
||||
#
|
||||
#
|
||||
# Note that if there is a possibility the first call to
|
||||
# PKG_CHECK_MODULES might not happen, you should be sure to include an
|
||||
# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac
|
||||
#
|
||||
#
|
||||
# --------------------------------------------------------------
|
||||
dnl PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
|
||||
dnl [ACTION-IF-NOT-FOUND])
|
||||
dnl --------------------------------------------------------------
|
||||
dnl Since: 0.4.0
|
||||
dnl
|
||||
dnl Note that if there is a possibility the first call to
|
||||
dnl PKG_CHECK_MODULES might not happen, you should be sure to include an
|
||||
dnl explicit call to PKG_PROG_PKG_CONFIG in your configure.ac
|
||||
AC_DEFUN([PKG_CHECK_MODULES],
|
||||
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
|
||||
AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
|
||||
|
@ -170,16 +203,40 @@ else
|
|||
AC_MSG_RESULT([yes])
|
||||
$3
|
||||
fi[]dnl
|
||||
])# PKG_CHECK_MODULES
|
||||
])dnl PKG_CHECK_MODULES
|
||||
|
||||
|
||||
# PKG_INSTALLDIR(DIRECTORY)
|
||||
# -------------------------
|
||||
# Substitutes the variable pkgconfigdir as the location where a module
|
||||
# should install pkg-config .pc files. By default the directory is
|
||||
# $libdir/pkgconfig, but the default can be changed by passing
|
||||
# DIRECTORY. The user can override through the --with-pkgconfigdir
|
||||
# parameter.
|
||||
dnl PKG_CHECK_MODULES_STATIC(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
|
||||
dnl [ACTION-IF-NOT-FOUND])
|
||||
dnl ---------------------------------------------------------------------
|
||||
dnl Since: 0.29
|
||||
dnl
|
||||
dnl Checks for existence of MODULES and gathers its build flags with
|
||||
dnl static libraries enabled. Sets VARIABLE-PREFIX_CFLAGS from --cflags
|
||||
dnl and VARIABLE-PREFIX_LIBS from --libs.
|
||||
dnl
|
||||
dnl Note that if there is a possibility the first call to
|
||||
dnl PKG_CHECK_MODULES_STATIC might not happen, you should be sure to
|
||||
dnl include an explicit call to PKG_PROG_PKG_CONFIG in your
|
||||
dnl configure.ac.
|
||||
AC_DEFUN([PKG_CHECK_MODULES_STATIC],
|
||||
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
|
||||
_save_PKG_CONFIG=$PKG_CONFIG
|
||||
PKG_CONFIG="$PKG_CONFIG --static"
|
||||
PKG_CHECK_MODULES($@)
|
||||
PKG_CONFIG=$_save_PKG_CONFIG[]dnl
|
||||
])dnl PKG_CHECK_MODULES_STATIC
|
||||
|
||||
|
||||
dnl PKG_INSTALLDIR([DIRECTORY])
|
||||
dnl -------------------------
|
||||
dnl Since: 0.27
|
||||
dnl
|
||||
dnl Substitutes the variable pkgconfigdir as the location where a module
|
||||
dnl should install pkg-config .pc files. By default the directory is
|
||||
dnl $libdir/pkgconfig, but the default can be changed by passing
|
||||
dnl DIRECTORY. The user can override through the --with-pkgconfigdir
|
||||
dnl parameter.
|
||||
AC_DEFUN([PKG_INSTALLDIR],
|
||||
[m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])])
|
||||
m4_pushdef([pkg_description],
|
||||
|
@ -190,16 +247,18 @@ AC_ARG_WITH([pkgconfigdir],
|
|||
AC_SUBST([pkgconfigdir], [$with_pkgconfigdir])
|
||||
m4_popdef([pkg_default])
|
||||
m4_popdef([pkg_description])
|
||||
]) dnl PKG_INSTALLDIR
|
||||
])dnl PKG_INSTALLDIR
|
||||
|
||||
|
||||
# PKG_NOARCH_INSTALLDIR(DIRECTORY)
|
||||
# -------------------------
|
||||
# Substitutes the variable noarch_pkgconfigdir as the location where a
|
||||
# module should install arch-independent pkg-config .pc files. By
|
||||
# default the directory is $datadir/pkgconfig, but the default can be
|
||||
# changed by passing DIRECTORY. The user can override through the
|
||||
# --with-noarch-pkgconfigdir parameter.
|
||||
dnl PKG_NOARCH_INSTALLDIR([DIRECTORY])
|
||||
dnl --------------------------------
|
||||
dnl Since: 0.27
|
||||
dnl
|
||||
dnl Substitutes the variable noarch_pkgconfigdir as the location where a
|
||||
dnl module should install arch-independent pkg-config .pc files. By
|
||||
dnl default the directory is $datadir/pkgconfig, but the default can be
|
||||
dnl changed by passing DIRECTORY. The user can override through the
|
||||
dnl --with-noarch-pkgconfigdir parameter.
|
||||
AC_DEFUN([PKG_NOARCH_INSTALLDIR],
|
||||
[m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])])
|
||||
m4_pushdef([pkg_description],
|
||||
|
@ -210,13 +269,15 @@ AC_ARG_WITH([noarch-pkgconfigdir],
|
|||
AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir])
|
||||
m4_popdef([pkg_default])
|
||||
m4_popdef([pkg_description])
|
||||
]) dnl PKG_NOARCH_INSTALLDIR
|
||||
])dnl PKG_NOARCH_INSTALLDIR
|
||||
|
||||
|
||||
# PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE,
|
||||
# [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
|
||||
# -------------------------------------------
|
||||
# Retrieves the value of the pkg-config variable for the given module.
|
||||
dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE,
|
||||
dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
|
||||
dnl -------------------------------------------
|
||||
dnl Since: 0.28
|
||||
dnl
|
||||
dnl Retrieves the value of the pkg-config variable for the given module.
|
||||
AC_DEFUN([PKG_CHECK_VAR],
|
||||
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
|
||||
AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl
|
||||
|
@ -225,7 +286,7 @@ _PKG_CONFIG([$1], [variable="][$3]["], [$2])
|
|||
AS_VAR_COPY([$1], [pkg_cv_][$1])
|
||||
|
||||
AS_VAR_IF([$1], [""], [$5], [$4])dnl
|
||||
])# PKG_CHECK_VAR
|
||||
])dnl PKG_CHECK_VAR
|
||||
|
||||
m4_include([config/m4/icu-conditional.m4])
|
||||
m4_include([acinclude.m4])
|
||||
|
|
|
@ -31,10 +31,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "i18n", "..\i18n\i18n.vcxpro
|
|||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "intltest", "..\test\intltest\intltest.vcxproj", "{73632960-B3A6-464D-83A3-4B43365F19B8}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "layout", "..\layout\layout.vcxproj", "{C920062A-0647-4553-A3B2-37C58065664B}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "layoutex", "..\layoutex\layoutex.vcxproj", "{37FC2C7F-1904-4811-8955-2F478830EAD1}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "makeconv", "..\tools\makeconv\makeconv.vcxproj", "{F5AD9738-1A3D-4906-B9C4-A7D9CE33DC2C}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "makedata", "..\data\makedata.vcxproj", "{D9DF7F2F-93B7-4810-B5CD-96F4F33C079B}"
|
||||
|
@ -57,8 +53,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "icupkg", "..\tools\icupkg\i
|
|||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gendict", "..\tools\gendict\gendict.vcxproj", "{9D4211F7-2C77-439C-82F0-30A4E43BA569}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "letest", "..\test\letest\letest.vcxproj", "{67351485-4D18-4245-BE39-A7EF0675ACD2}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gencfu", "..\tools\gencfu\gencfu.vcxproj", "{691EE0C0-DC57-4A48-8AEE-8ED75EB3A057}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gennorm2", "..\tools\gennorm2\gennorm2.vcxproj", "{C7891A65-80AB-4245-912E-5F1E17B0E6C4}"
|
||||
|
@ -295,14 +289,6 @@ Global
|
|||
{9D4211F7-2C77-439C-82F0-30A4E43BA569}.Release|Win32.Build.0 = Release|Win32
|
||||
{9D4211F7-2C77-439C-82F0-30A4E43BA569}.Release|x64.ActiveCfg = Release|x64
|
||||
{9D4211F7-2C77-439C-82F0-30A4E43BA569}.Release|x64.Build.0 = Release|x64
|
||||
{67351485-4D18-4245-BE39-A7EF0675ACD2}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{67351485-4D18-4245-BE39-A7EF0675ACD2}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{67351485-4D18-4245-BE39-A7EF0675ACD2}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{67351485-4D18-4245-BE39-A7EF0675ACD2}.Debug|x64.Build.0 = Debug|x64
|
||||
{67351485-4D18-4245-BE39-A7EF0675ACD2}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{67351485-4D18-4245-BE39-A7EF0675ACD2}.Release|Win32.Build.0 = Release|Win32
|
||||
{67351485-4D18-4245-BE39-A7EF0675ACD2}.Release|x64.ActiveCfg = Release|x64
|
||||
{67351485-4D18-4245-BE39-A7EF0675ACD2}.Release|x64.Build.0 = Release|x64
|
||||
{691EE0C0-DC57-4A48-8AEE-8ED75EB3A057}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{691EE0C0-DC57-4A48-8AEE-8ED75EB3A057}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{691EE0C0-DC57-4A48-8AEE-8ED75EB3A057}.Debug|x64.ActiveCfg = Debug|x64
|
||||
|
|
|
@ -91,7 +91,7 @@ set ICUFAILCNT=0
|
|||
:OK_cintltst
|
||||
@set ICURUN=%ICURUN% %THT%
|
||||
|
||||
@REM (Layout is deprecated)
|
||||
@REM (Layout is deprecated - this would require HarfBuzz)
|
||||
@REM @set THT=letest
|
||||
@REM @echo ==== %THT% =========================================================================
|
||||
@REM @cd %ICU_ICUDIR%\source\test\letest
|
||||
|
|
|
@ -92,7 +92,6 @@ endif
|
|||
DATA_STUBNAME = data
|
||||
COMMON_STUBNAME = uc
|
||||
I18N_STUBNAME = i18n
|
||||
LAYOUT_STUBNAME = le
|
||||
LAYOUTEX_STUBNAME = lx
|
||||
IO_STUBNAME = io
|
||||
TOOLUTIL_STUBNAME = tu
|
||||
|
@ -105,7 +104,6 @@ CTESTFW_STUBNAME = test
|
|||
# 2. link with $(ICULIBS)
|
||||
# 3. optionally, add one or more of:
|
||||
# - $(ICULIBS_I18N) - i18n library, formatting, etc.
|
||||
# - $(ICULIBS_LAYOUT) - ICU layout library.
|
||||
# - $(ICULIBS_ICUIO) - ICU stdio equivalent library
|
||||
|
||||
ICULIBS_COMMON = -l$(ICUPREFIX)uc$(ICULIBSUFFIX)$(ICULIBSUFFIX_VERSION)
|
||||
|
@ -115,7 +113,6 @@ ICULIBS_TOOLUTIL = -l$(ICUPREFIX)tu$(ICULIBSUFFIX)$(ICULIBSUFFIX_VERSION)
|
|||
ICULIBS_CTESTFW = -l$(ICUPREFIX)ctestfw$(ICULIBSUFFIX)$(ICULIBSUFFIX_VERSION)
|
||||
ICULIBS_ICUIO = -l$(ICUPREFIX)io$(ICULIBSUFFIX)$(ICULIBSUFFIX_VERSION)
|
||||
ICULIBS_OBSOLETE = -l$(ICUPREFIX)obsolete$(ICULIBSUFFIX)$(ICULIBSUFFIX_VERSION)
|
||||
ICULIBS_LAYOUT = -l$(ICUPREFIX)le$(ICULIBSUFFIX)$(ICULIBSUFFIX_VERSION)
|
||||
ICULIBS_LAYOUTEX = -l$(ICUPREFIX)lx$(ICULIBSUFFIX)$(ICULIBSUFFIX_VERSION)
|
||||
ICULIBS_BASE = -L$(libdir)
|
||||
|
||||
|
|
|
@ -46,7 +46,6 @@ allflags()
|
|||
echo " --invoke Print commands to invoke an ICU program"
|
||||
echo " --invoke=<prog> Print commands to invoke an ICU program named <prog> (ex: genrb)"
|
||||
echo " --ldflags Print -L search path and -l libraries to link with ICU [LDFLAGS]. This is for the data, uc (common), and i18n libraries only. "
|
||||
echo " --ldflags-layout Print ICU layout engine link directive. Use in addition to --ldflags"
|
||||
echo " --ldflags-libsonly Same as --ldflags, but only the -l directives"
|
||||
echo " --ldflags-searchpath Print only -L (search path) directive"
|
||||
echo " --ldflags-system Print only system libs ICU links with (-lpthread, -lm)"
|
||||
|
@ -281,7 +280,8 @@ do
|
|||
;;
|
||||
|
||||
--ldflags-layout)
|
||||
echo $ECHO_N "${ICULIBS_LAYOUT} ${ICULIBS_LAYOUTEX} ${ECHO_C}"
|
||||
echo ${ME}: ERROR: the old layout engine has been removed. use HarfBuzz.
|
||||
exit 1
|
||||
;;
|
||||
|
||||
--ldflags-searchpath)
|
||||
|
|
|
@ -76,9 +76,6 @@
|
|||
.BI "\-\-ldflags"
|
||||
]
|
||||
[
|
||||
.BI "\-\-ldflags\-layout"
|
||||
]
|
||||
[
|
||||
.BI "\-\-ldflags\-libsonly"
|
||||
]
|
||||
[
|
||||
|
|
|
@ -120,7 +120,6 @@ LDFLAGSICUDT+= -base:"0x4ad00000" -NOENTRY# The NOENTRY option is required for c
|
|||
LDFLAGSICUUC= -base:"0x4a800000"# in-uc = 1MB
|
||||
LDFLAGSICUI18N= -base:"0x4a900000"# io-in = 2MB
|
||||
LDFLAGSICUIO= -base:"0x4ab00000"# le-io = 1MB
|
||||
LDFLAGSICULE= -base:"0x4ac00000"# lx-le = 512KB
|
||||
LDFLAGSICULX= -base:"0x4ac80000"
|
||||
LDFLAGSCTESTFW=# Unused for now.
|
||||
LDFLAGSICUTOOLUTIL= -base:"0x4ac00000"# Same as layout. Layout and tools probably won't mix.
|
||||
|
|
|
@ -125,7 +125,6 @@ LDFLAGSICUDT+= -base:"0x4ad00000" -NOENTRY# The NOENTRY option is required for c
|
|||
LDFLAGSICUUC= -base:"0x4a800000"# in-uc = 1MB
|
||||
LDFLAGSICUI18N= -base:"0x4a900000"# io-in = 2MB
|
||||
LDFLAGSICUIO= -base:"0x4ab00000"# le-io = 1MB
|
||||
LDFLAGSICULE= -base:"0x4ac00000"# lx-le = 512KB
|
||||
LDFLAGSICULX= -base:"0x4ac80000"
|
||||
LDFLAGSCTESTFW=# Unused for now.
|
||||
LDFLAGSICUTOOLUTIL= -base:"0x4ac00000"# Same as layout. Layout and tools probably won't mix.
|
||||
|
|
|
@ -177,7 +177,6 @@ endif
|
|||
LIBICUDT= $(top_builddir)/stubdata/$(LIBICU)data$(ICULIBSUFFIX)$(STUB_SUFFIX)$(SO_TARGET_VERSION).x
|
||||
LIBICUUC= $(top_builddir)/common/$(LIBICU)uc$(ICULIBSUFFIX)$(SO_TARGET_VERSION).x
|
||||
LIBICUI18N= $(top_builddir)/i18n/$(LIBICU)i18n$(ICULIBSUFFIX)$(SO_TARGET_VERSION).x
|
||||
LIBICULE= $(top_builddir)/layout/$(LIBICU)le$(ICULIBSUFFIX)$(SO_TARGET_VERSION).x
|
||||
LIBICULX= $(top_builddir)/layoutex/$(LIBICU)lx$(ICULIBSUFFIX)$(SO_TARGET_VERSION).x
|
||||
LIBICUIO= $(top_builddir)/io/$(LIBICU)io$(ICULIBSUFFIX)$(SO_TARGET_VERSION).x
|
||||
LIBCTESTFW= $(top_builddir)/tools/ctestfw/$(LIBICU)test$(ICULIBSUFFIX)$(SO_TARGET_VERSION).x
|
||||
|
|
|
@ -26,7 +26,6 @@ icu-config --invoke=genrb
|
|||
icu-config --invoke=./myapp
|
||||
icu-config --invoke=/path/to/myapp
|
||||
icu-config --ldflags
|
||||
icu-config --ldflags-layout
|
||||
icu-config --ldflags-searchpath
|
||||
icu-config --ldflags-libsonly
|
||||
icu-config --ldflags-system
|
||||
|
@ -47,5 +46,5 @@ icu-config --version
|
|||
icu-config --prefix=/tmp --bindir
|
||||
# following needs to point to an alternate path that will work
|
||||
icu-config --prefix=/Users/srl/II --cflags
|
||||
icu-config --detect-prefix --ldflags --ldflags-layout
|
||||
icu-config --detect-prefix --ldflags
|
||||
|
||||
|
|
65
icu4c/source/configure
vendored
65
icu4c/source/configure
vendored
|
@ -649,8 +649,6 @@ U_HAVE_TOOLS
|
|||
TOOLS_TRUE
|
||||
U_HAVE_LAYOUTEX
|
||||
LAYOUTEX_TRUE
|
||||
U_HAVE_LAYOUT
|
||||
LAYOUT_TRUE
|
||||
U_HAVE_ICUIO
|
||||
ICUIO_TRUE
|
||||
U_HAVE_EXTRAS
|
||||
|
@ -754,7 +752,6 @@ infodir
|
|||
docdir
|
||||
oldincludedir
|
||||
includedir
|
||||
runstatedir
|
||||
localstatedir
|
||||
sharedstatedir
|
||||
sysconfdir
|
||||
|
@ -795,8 +792,8 @@ enable_rpath
|
|||
enable_weak_threads
|
||||
enable_extras
|
||||
enable_icuio
|
||||
enable_layout
|
||||
enable_layoutex
|
||||
enable_layout
|
||||
enable_tools
|
||||
with_data_packaging
|
||||
with_library_suffix
|
||||
|
@ -858,7 +855,6 @@ datadir='${datarootdir}'
|
|||
sysconfdir='${prefix}/etc'
|
||||
sharedstatedir='${prefix}/com'
|
||||
localstatedir='${prefix}/var'
|
||||
runstatedir='${localstatedir}/run'
|
||||
includedir='${prefix}/include'
|
||||
oldincludedir='/usr/include'
|
||||
docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
|
||||
|
@ -1111,15 +1107,6 @@ do
|
|||
| -silent | --silent | --silen | --sile | --sil)
|
||||
silent=yes ;;
|
||||
|
||||
-runstatedir | --runstatedir | --runstatedi | --runstated \
|
||||
| --runstate | --runstat | --runsta | --runst | --runs \
|
||||
| --run | --ru | --r)
|
||||
ac_prev=runstatedir ;;
|
||||
-runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
|
||||
| --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
|
||||
| --run=* | --ru=* | --r=*)
|
||||
runstatedir=$ac_optarg ;;
|
||||
|
||||
-sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
|
||||
ac_prev=sbindir ;;
|
||||
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
|
||||
|
@ -1257,7 +1244,7 @@ fi
|
|||
for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
|
||||
datadir sysconfdir sharedstatedir localstatedir includedir \
|
||||
oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
|
||||
libdir localedir mandir runstatedir
|
||||
libdir localedir mandir
|
||||
do
|
||||
eval ac_val=\$$ac_var
|
||||
# Remove trailing slashes.
|
||||
|
@ -1410,7 +1397,6 @@ Fine tuning of the installation directories:
|
|||
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
|
||||
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
|
||||
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
|
||||
--runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run]
|
||||
--libdir=DIR object code libraries [EPREFIX/lib]
|
||||
--includedir=DIR C header files [PREFIX/include]
|
||||
--oldincludedir=DIR C header files for non-gcc [/usr/include]
|
||||
|
@ -1461,10 +1447,9 @@ Optional Features:
|
|||
--enable-weak-threads weakly reference the threading library default=no
|
||||
--enable-extras build ICU extras default=yes
|
||||
--enable-icuio build ICU's icuio library default=yes
|
||||
--enable-layout build ICU's DEPRECATED layout library default=yes
|
||||
--enable-layoutex build ICU's Paragraph Layout library default=same-as-layout.
|
||||
If not building with the ICU Layout library, then icu-le-hb must be installed via pkg-config.
|
||||
See http://harfbuzz.org
|
||||
--enable-layoutex build ICU's Paragraph Layout library default=yes.
|
||||
icu-le-hb must be installed via pkg-config. See http://harfbuzz.org
|
||||
|
||||
--enable-tools build ICU's tools default=yes
|
||||
--enable-tests build ICU tests default=yes
|
||||
--enable-samples build ICU samples default=yes
|
||||
|
@ -7545,38 +7530,16 @@ else
|
|||
U_HAVE_ICUIO=0
|
||||
fi
|
||||
|
||||
# Enable/disable layout
|
||||
# Check whether --enable-layout was given.
|
||||
if test "${enable_layout+set}" = set; then :
|
||||
enableval=$enable_layout; case "${enableval}" in
|
||||
yes) layout=true ;;
|
||||
no) layout=false ;;
|
||||
*) as_fn_error $? "bad value ${enableval} for --enable-layout" "$LINENO" 5 ;;
|
||||
esac
|
||||
else
|
||||
layout=true
|
||||
fi
|
||||
|
||||
|
||||
|
||||
if test "$layout" = true; then
|
||||
LAYOUT_TRUE=
|
||||
U_HAVE_LAYOUT=1
|
||||
else
|
||||
LAYOUT_TRUE='#'
|
||||
U_HAVE_LAYOUT=0
|
||||
fi
|
||||
|
||||
# Enable/disable layoutex
|
||||
# Check whether --enable-layoutex was given.
|
||||
if test "${enable_layoutex+set}" = set; then :
|
||||
enableval=$enable_layoutex; case "${enableval}" in
|
||||
yes) layoutex=true ;;
|
||||
yes) layoutex=$have_icu_le_hb ;;
|
||||
no) layoutex=false ;;
|
||||
*) as_fn_error $? "bad value ${enableval} for --enable-layoutex" "$LINENO" 5 ;;
|
||||
esac
|
||||
else
|
||||
layoutex=$layout
|
||||
layoutex=$have_icu_le_hb
|
||||
fi
|
||||
|
||||
|
||||
|
@ -7589,6 +7552,17 @@ else
|
|||
U_HAVE_LAYOUTEX=0
|
||||
fi
|
||||
|
||||
# Enable/disable layoutex
|
||||
# Check whether --enable-layout was given.
|
||||
if test "${enable_layout+set}" = set; then :
|
||||
enableval=$enable_layout; case "${enableval}" in
|
||||
yes) as_fn_error $? "The ICU Layout Engine has been removed." "$LINENO" 5 ;;
|
||||
no) ;;
|
||||
*) ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
|
||||
# Enable/disable tools
|
||||
# Check whether --enable-tools was given.
|
||||
if test "${enable_tools+set}" = set; then :
|
||||
|
@ -7829,7 +7803,7 @@ echo "CXXFLAGS=$CXXFLAGS"
|
|||
|
||||
|
||||
# output the Makefiles
|
||||
ac_config_files="$ac_config_files icudefs.mk Makefile data/pkgdataMakefile config/Makefile.inc config/icu.pc config/pkgdataMakefile data/Makefile stubdata/Makefile common/Makefile i18n/Makefile layout/Makefile layoutex/Makefile io/Makefile extra/Makefile extra/uconv/Makefile extra/uconv/pkgdataMakefile extra/scrptrun/Makefile tools/Makefile tools/ctestfw/Makefile tools/toolutil/Makefile tools/makeconv/Makefile tools/genrb/Makefile tools/genccode/Makefile tools/gencmn/Makefile tools/gencnval/Makefile tools/gendict/Makefile tools/gentest/Makefile tools/gennorm2/Makefile tools/genbrk/Makefile tools/gensprep/Makefile tools/icuinfo/Makefile tools/icupkg/Makefile tools/icuswap/Makefile tools/pkgdata/Makefile tools/tzcode/Makefile tools/gencfu/Makefile test/Makefile test/compat/Makefile test/testdata/Makefile test/testdata/pkgdataMakefile test/hdrtst/Makefile test/intltest/Makefile test/cintltst/Makefile test/iotest/Makefile test/letest/Makefile test/perf/Makefile test/perf/collationperf/Makefile test/perf/collperf/Makefile test/perf/collperf2/Makefile test/perf/dicttrieperf/Makefile test/perf/ubrkperf/Makefile test/perf/charperf/Makefile test/perf/convperf/Makefile test/perf/normperf/Makefile test/perf/DateFmtPerf/Makefile test/perf/howExpensiveIs/Makefile test/perf/strsrchperf/Makefile test/perf/unisetperf/Makefile test/perf/usetperf/Makefile test/perf/ustrperf/Makefile test/perf/utfperf/Makefile test/perf/utrie2perf/Makefile test/perf/leperf/Makefile samples/Makefile samples/date/Makefile samples/cal/Makefile samples/layout/Makefile"
|
||||
ac_config_files="$ac_config_files icudefs.mk Makefile data/pkgdataMakefile config/Makefile.inc config/icu.pc config/pkgdataMakefile data/Makefile stubdata/Makefile common/Makefile i18n/Makefile layoutex/Makefile io/Makefile extra/Makefile extra/uconv/Makefile extra/uconv/pkgdataMakefile extra/scrptrun/Makefile tools/Makefile tools/ctestfw/Makefile tools/toolutil/Makefile tools/makeconv/Makefile tools/genrb/Makefile tools/genccode/Makefile tools/gencmn/Makefile tools/gencnval/Makefile tools/gendict/Makefile tools/gentest/Makefile tools/gennorm2/Makefile tools/genbrk/Makefile tools/gensprep/Makefile tools/icuinfo/Makefile tools/icupkg/Makefile tools/icuswap/Makefile tools/pkgdata/Makefile tools/tzcode/Makefile tools/gencfu/Makefile test/Makefile test/compat/Makefile test/testdata/Makefile test/testdata/pkgdataMakefile test/hdrtst/Makefile test/intltest/Makefile test/cintltst/Makefile test/iotest/Makefile test/letest/Makefile test/perf/Makefile test/perf/collationperf/Makefile test/perf/collperf/Makefile test/perf/collperf2/Makefile test/perf/dicttrieperf/Makefile test/perf/ubrkperf/Makefile test/perf/charperf/Makefile test/perf/convperf/Makefile test/perf/normperf/Makefile test/perf/DateFmtPerf/Makefile test/perf/howExpensiveIs/Makefile test/perf/strsrchperf/Makefile test/perf/unisetperf/Makefile test/perf/usetperf/Makefile test/perf/ustrperf/Makefile test/perf/utfperf/Makefile test/perf/utrie2perf/Makefile test/perf/leperf/Makefile samples/Makefile samples/date/Makefile samples/cal/Makefile samples/layout/Makefile"
|
||||
|
||||
cat >confcache <<\_ACEOF
|
||||
# This file is a shell script that caches the results of configure
|
||||
|
@ -8549,7 +8523,6 @@ do
|
|||
"stubdata/Makefile") CONFIG_FILES="$CONFIG_FILES stubdata/Makefile" ;;
|
||||
"common/Makefile") CONFIG_FILES="$CONFIG_FILES common/Makefile" ;;
|
||||
"i18n/Makefile") CONFIG_FILES="$CONFIG_FILES i18n/Makefile" ;;
|
||||
"layout/Makefile") CONFIG_FILES="$CONFIG_FILES layout/Makefile" ;;
|
||||
"layoutex/Makefile") CONFIG_FILES="$CONFIG_FILES layoutex/Makefile" ;;
|
||||
"io/Makefile") CONFIG_FILES="$CONFIG_FILES io/Makefile" ;;
|
||||
"extra/Makefile") CONFIG_FILES="$CONFIG_FILES extra/Makefile" ;;
|
||||
|
|
|
@ -1097,30 +1097,28 @@ AC_ARG_ENABLE(icuio,
|
|||
icuio=true)
|
||||
ICU_CONDITIONAL(ICUIO, test "$icuio" = true)
|
||||
|
||||
# Enable/disable layout
|
||||
AC_ARG_ENABLE(layout,
|
||||
[ --enable-layout build ICU's DEPRECATED layout library [default=yes]],
|
||||
[case "${enableval}" in
|
||||
yes) layout=true ;;
|
||||
no) layout=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-layout) ;;
|
||||
esac],
|
||||
layout=true)
|
||||
ICU_CONDITIONAL(LAYOUT, test "$layout" = true)
|
||||
|
||||
# Enable/disable layoutex
|
||||
AC_ARG_ENABLE(layoutex,
|
||||
[ --enable-layoutex build ICU's Paragraph Layout library [default=same-as-layout].
|
||||
If not building with the ICU Layout library, then icu-le-hb must be installed via pkg-config.
|
||||
See http://harfbuzz.org],
|
||||
[ --enable-layoutex build ICU's Paragraph Layout library [default=yes].
|
||||
icu-le-hb must be installed via pkg-config. See http://harfbuzz.org],
|
||||
[case "${enableval}" in
|
||||
yes) layoutex=true ;;
|
||||
yes) layoutex=$have_icu_le_hb ;;
|
||||
no) layoutex=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-layoutex) ;;
|
||||
esac],
|
||||
layoutex=$layout)
|
||||
layoutex=$have_icu_le_hb)
|
||||
ICU_CONDITIONAL(LAYOUTEX, test "$layoutex" = true)
|
||||
|
||||
# Enable/disable layout
|
||||
AC_ARG_ENABLE(layout,
|
||||
[],
|
||||
[case "${enableval}" in
|
||||
yes) AC_MSG_ERROR(The ICU Layout Engine has been removed.) ;;
|
||||
no) ;;
|
||||
*) ;;
|
||||
esac],
|
||||
)
|
||||
|
||||
# Enable/disable tools
|
||||
AC_ARG_ENABLE(tools,
|
||||
[ --enable-tools build ICU's tools [default=yes]],
|
||||
|
@ -1342,7 +1340,6 @@ AC_CONFIG_FILES([icudefs.mk \
|
|||
stubdata/Makefile \
|
||||
common/Makefile \
|
||||
i18n/Makefile \
|
||||
layout/Makefile \
|
||||
layoutex/Makefile \
|
||||
io/Makefile \
|
||||
extra/Makefile \
|
||||
|
|
|
@ -145,14 +145,6 @@
|
|||
<Project>{c2b04507-2521-4801-bf0d-5fd79d6d518c}</Project>
|
||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\layoutex\layoutex.vcxproj">
|
||||
<Project>{37fc2c7f-1904-4811-8955-2f478830ead1}</Project>
|
||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\layout\layout.vcxproj">
|
||||
<Project>{c920062a-0647-4553-a3b2-37c58065664b}</Project>
|
||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\stubdata\stubdata.vcxproj">
|
||||
<Project>{203ec78a-0531-43f0-a636-285439bde025}</Project>
|
||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||
|
@ -169,10 +161,6 @@
|
|||
<Project>{e4993e82-d68a-46ca-bae0-9d35e172e46f}</Project>
|
||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\test\letest\letest.vcxproj">
|
||||
<Project>{67351485-4d18-4245-be39-a7ef0675acd2}</Project>
|
||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\tools\ctestfw\ctestfw.vcxproj">
|
||||
<Project>{eca6b435-b4fa-4f9f-bf95-f451d078fc47}</Project>
|
||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||
|
|
|
@ -245,7 +245,6 @@ TOOLLIBDIR=$(LIBDIR)
|
|||
DATA_STUBNAME = data
|
||||
COMMON_STUBNAME = uc
|
||||
I18N_STUBNAME = i18n
|
||||
LAYOUT_STUBNAME = le
|
||||
LAYOUTEX_STUBNAME = lx
|
||||
IO_STUBNAME = io
|
||||
TOOLUTIL_STUBNAME = tu
|
||||
|
@ -264,8 +263,6 @@ else
|
|||
USING_ICULEHB=no
|
||||
ICULEHB_TRUE=#
|
||||
ICULEHB_FALSE=
|
||||
ICULIBS_LE = -l$(STATIC_PREFIX_WHEN_USED)$(ICUPREFIX)$(LAYOUT_STUBNAME)$(ICULIBSUFFIX)$(SO_TARGET_VERSION_SUFFIX)
|
||||
ICULE_CFLAGS=-I$(top_srcdir)
|
||||
endif
|
||||
|
||||
# Just the libs.
|
||||
|
|
|
@ -1,48 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "LEGlyphFilter.h"
|
||||
#include "OpenTypeTables.h"
|
||||
#include "GlyphSubstitutionTables.h"
|
||||
#include "AlternateSubstSubtables.h"
|
||||
#include "GlyphIterator.h"
|
||||
#include "LESwaps.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
le_uint32 AlternateSubstitutionSubtable::process(const LEReferenceTo<AlternateSubstitutionSubtable> &base,
|
||||
GlyphIterator *glyphIterator, LEErrorCode &success, const LEGlyphFilter *filter) const
|
||||
{
|
||||
// NOTE: For now, we'll just pick the first alternative...
|
||||
LEGlyphID glyph = glyphIterator->getCurrGlyphID();
|
||||
le_int32 coverageIndex = getGlyphCoverage(base, glyph, success);
|
||||
|
||||
if (coverageIndex >= 0 && LE_SUCCESS(success)) {
|
||||
le_uint16 altSetCount = SWAPW(alternateSetCount);
|
||||
|
||||
if (coverageIndex < altSetCount) {
|
||||
Offset alternateSetTableOffset = SWAPW(alternateSetTableOffsetArray[coverageIndex]);
|
||||
const LEReferenceTo<AlternateSetTable> alternateSetTable(base, success,
|
||||
(const AlternateSetTable *) ((char *) this + alternateSetTableOffset));
|
||||
TTGlyphID alternate = SWAPW(alternateSetTable->alternateArray[0]);
|
||||
|
||||
if (filter == NULL || filter->accept(LE_SET_GLYPH(glyph, alternate))) {
|
||||
glyphIterator->setCurrGlyphID(SWAPW(alternateSetTable->alternateArray[0]));
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// XXXX If we get here, the table's mal-formed...
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
|
@ -1,44 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __ALTERNATESUBSTITUTIONSUBTABLES_H
|
||||
#define __ALTERNATESUBSTITUTIONSUBTABLES_H
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \internal
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "LEGlyphFilter.h"
|
||||
#include "OpenTypeTables.h"
|
||||
#include "GlyphSubstitutionTables.h"
|
||||
#include "GlyphIterator.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
struct AlternateSetTable
|
||||
{
|
||||
le_uint16 glyphCount;
|
||||
TTGlyphID alternateArray[ANY_NUMBER];
|
||||
};
|
||||
|
||||
LE_VAR_ARRAY(AlternateSetTable, alternateArray)
|
||||
|
||||
struct AlternateSubstitutionSubtable : GlyphSubstitutionSubtable
|
||||
{
|
||||
le_uint16 alternateSetCount;
|
||||
Offset alternateSetTableOffsetArray[ANY_NUMBER];
|
||||
|
||||
le_uint32 process(const LEReferenceTo<AlternateSubstitutionSubtable> &base, GlyphIterator *glyphIterator, LEErrorCode &success, const LEGlyphFilter *filter = NULL) const;
|
||||
};
|
||||
|
||||
LE_VAR_ARRAY(AlternateSubstitutionSubtable, alternateSetTableOffsetArray)
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
|
@ -1,108 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "LEFontInstance.h"
|
||||
#include "DeviceTables.h"
|
||||
#include "AnchorTables.h"
|
||||
#include "LESwaps.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
void AnchorTable::getAnchor(LEGlyphID glyphID, const LEFontInstance *fontInstance,
|
||||
LEPoint &anchor) const
|
||||
{
|
||||
switch(SWAPW(anchorFormat)) {
|
||||
case 1:
|
||||
{
|
||||
const Format1AnchorTable *f1 = (const Format1AnchorTable *) this;
|
||||
|
||||
f1->getAnchor(fontInstance, anchor);
|
||||
break;
|
||||
}
|
||||
|
||||
case 2:
|
||||
{
|
||||
const Format2AnchorTable *f2 = (const Format2AnchorTable *) this;
|
||||
|
||||
f2->getAnchor(glyphID, fontInstance, anchor);
|
||||
break;
|
||||
}
|
||||
|
||||
case 3:
|
||||
{
|
||||
const Format3AnchorTable *f3 = (const Format3AnchorTable *) this;
|
||||
|
||||
f3->getAnchor(fontInstance, anchor);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
// unknown format: just use x, y coordinate, like format 1...
|
||||
const Format1AnchorTable *f1 = (const Format1AnchorTable *) this;
|
||||
|
||||
f1->getAnchor(fontInstance, anchor);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Format1AnchorTable::getAnchor(const LEFontInstance *fontInstance, LEPoint &anchor) const
|
||||
{
|
||||
le_int16 x = SWAPW(xCoordinate);
|
||||
le_int16 y = SWAPW(yCoordinate);
|
||||
LEPoint pixels;
|
||||
|
||||
fontInstance->transformFunits(x, y, pixels);
|
||||
|
||||
fontInstance->pixelsToUnits(pixels, anchor);
|
||||
}
|
||||
|
||||
void Format2AnchorTable::getAnchor(LEGlyphID glyphID, const LEFontInstance *fontInstance, LEPoint &anchor) const
|
||||
{
|
||||
LEPoint point;
|
||||
|
||||
if (! fontInstance->getGlyphPoint(glyphID, SWAPW(anchorPoint), point)) {
|
||||
le_int16 x = SWAPW(xCoordinate);
|
||||
le_int16 y = SWAPW(yCoordinate);
|
||||
|
||||
fontInstance->transformFunits(x, y, point);
|
||||
}
|
||||
|
||||
|
||||
fontInstance->pixelsToUnits(point, anchor);
|
||||
}
|
||||
|
||||
void Format3AnchorTable::getAnchor(const LEFontInstance *fontInstance, LEPoint &anchor) const
|
||||
{
|
||||
le_int16 x = SWAPW(xCoordinate);
|
||||
le_int16 y = SWAPW(yCoordinate);
|
||||
LEPoint pixels;
|
||||
Offset dtxOffset = SWAPW(xDeviceTableOffset);
|
||||
Offset dtyOffset = SWAPW(yDeviceTableOffset);
|
||||
|
||||
fontInstance->transformFunits(x, y, pixels);
|
||||
|
||||
if (dtxOffset != 0) {
|
||||
const DeviceTable *dtx = (const DeviceTable *) ((char *) this + dtxOffset);
|
||||
le_int16 adjx = dtx->getAdjustment((le_int16) fontInstance->getXPixelsPerEm());
|
||||
|
||||
pixels.fX += adjx;
|
||||
}
|
||||
|
||||
if (dtyOffset != 0) {
|
||||
const DeviceTable *dty = (const DeviceTable *) ((char *) this + dtyOffset);
|
||||
le_int16 adjy = dty->getAdjustment((le_int16) fontInstance->getYPixelsPerEm());
|
||||
|
||||
pixels.fY += adjy;
|
||||
}
|
||||
|
||||
fontInstance->pixelsToUnits(pixels, anchor);
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __ANCHORTABLES_H
|
||||
#define __ANCHORTABLES_H
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \internal
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "LEFontInstance.h"
|
||||
#include "OpenTypeTables.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
struct AnchorTable
|
||||
{
|
||||
le_uint16 anchorFormat;
|
||||
le_int16 xCoordinate;
|
||||
le_int16 yCoordinate;
|
||||
|
||||
void getAnchor(LEGlyphID glyphID, const LEFontInstance *fontInstance,
|
||||
LEPoint &anchor) const;
|
||||
};
|
||||
|
||||
struct Format1AnchorTable : AnchorTable
|
||||
{
|
||||
void getAnchor(const LEFontInstance *fontInstance, LEPoint &anchor) const;
|
||||
};
|
||||
|
||||
struct Format2AnchorTable : AnchorTable
|
||||
{
|
||||
le_uint16 anchorPoint;
|
||||
|
||||
void getAnchor(LEGlyphID glyphID, const LEFontInstance *fontInstance, LEPoint &anchor) const;
|
||||
};
|
||||
|
||||
struct Format3AnchorTable : AnchorTable
|
||||
{
|
||||
Offset xDeviceTableOffset;
|
||||
Offset yDeviceTableOffset;
|
||||
|
||||
void getAnchor(const LEFontInstance *fontInstance, LEPoint &anchor) const;
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
||||
|
||||
|
|
@ -1,221 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "LEScripts.h"
|
||||
#include "LEGlyphFilter.h"
|
||||
#include "LEGlyphStorage.h"
|
||||
#include "LayoutEngine.h"
|
||||
#include "OpenTypeLayoutEngine.h"
|
||||
#include "ArabicLayoutEngine.h"
|
||||
#include "ScriptAndLanguageTags.h"
|
||||
#include "CharSubstitutionFilter.h"
|
||||
|
||||
#include "GlyphSubstitutionTables.h"
|
||||
#include "GlyphDefinitionTables.h"
|
||||
#include "GlyphPositioningTables.h"
|
||||
|
||||
#include "GDEFMarkFilter.h"
|
||||
|
||||
#include "ArabicShaping.h"
|
||||
#include "CanonShaping.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
le_bool CharSubstitutionFilter::accept(LEGlyphID glyph) const
|
||||
{
|
||||
return fFontInstance->canDisplay((LEUnicode) glyph);
|
||||
}
|
||||
|
||||
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ArabicOpenTypeLayoutEngine)
|
||||
|
||||
ArabicOpenTypeLayoutEngine::ArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode,
|
||||
le_int32 languageCode, le_int32 typoFlags,
|
||||
const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTable,
|
||||
LEErrorCode &success)
|
||||
: OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success)
|
||||
{
|
||||
fFeatureMap = ArabicShaping::getFeatureMap(fFeatureMapCount);
|
||||
fFeatureOrder = TRUE;
|
||||
}
|
||||
|
||||
ArabicOpenTypeLayoutEngine::ArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode,
|
||||
le_int32 languageCode,
|
||||
le_int32 typoFlags, LEErrorCode &success)
|
||||
: OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success)
|
||||
{
|
||||
fFeatureMap = ArabicShaping::getFeatureMap(fFeatureMapCount);
|
||||
|
||||
// NOTE: We don't need to set fFeatureOrder to TRUE here
|
||||
// because this constructor is only called by the constructor
|
||||
// for UnicodeArabicOpenTypeLayoutEngine, which uses a pre-built
|
||||
// GSUB table that has the features in the correct order.
|
||||
|
||||
//fFeatureOrder = TRUE;
|
||||
}
|
||||
|
||||
ArabicOpenTypeLayoutEngine::~ArabicOpenTypeLayoutEngine()
|
||||
{
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
// Input: characters
|
||||
// Output: characters, char indices, tags
|
||||
// Returns: output character count
|
||||
le_int32 ArabicOpenTypeLayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 offset, le_int32 count,
|
||||
le_int32 max, le_bool rightToLeft, LEUnicode *&outChars,
|
||||
LEGlyphStorage &glyphStorage, LEErrorCode &success)
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (chars == NULL || offset < 0 || count < 0 || max < 0 || offset >= max || offset + count > max) {
|
||||
success = LE_ILLEGAL_ARGUMENT_ERROR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
outChars = LE_NEW_ARRAY(LEUnicode, count);
|
||||
|
||||
if (outChars == NULL) {
|
||||
success = LE_MEMORY_ALLOCATION_ERROR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
glyphStorage.allocateGlyphArray(count, rightToLeft, success);
|
||||
glyphStorage.allocateAuxData(success);
|
||||
|
||||
if (LE_FAILURE(success)) {
|
||||
LE_DELETE_ARRAY(outChars);
|
||||
return 0;
|
||||
}
|
||||
|
||||
CanonShaping::reorderMarks(&chars[offset], count, rightToLeft, outChars, glyphStorage);
|
||||
|
||||
// Note: This processes the *original* character array so we can get context
|
||||
// for the first and last characters. This is OK because only the marks
|
||||
// will have been reordered, and they don't contribute to shaping.
|
||||
ArabicShaping::shape(chars, offset, count, max, rightToLeft, glyphStorage);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
void ArabicOpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse,
|
||||
LEGlyphStorage &glyphStorage, LEErrorCode &success)
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (chars == NULL || offset < 0 || count < 0) {
|
||||
success = LE_ILLEGAL_ARGUMENT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!fGPOSTable.isEmpty()) {
|
||||
OpenTypeLayoutEngine::adjustGlyphPositions(chars, offset, count, reverse, glyphStorage, success);
|
||||
} else if (!fGDEFTable.isEmpty()) {
|
||||
GDEFMarkFilter filter(fGDEFTable, success);
|
||||
adjustMarkGlyphs(glyphStorage, &filter, success);
|
||||
} else {
|
||||
LEReferenceTo<GlyphDefinitionTableHeader> gdefTable(CanonShaping::glyphDefinitionTable, CanonShaping::glyphDefinitionTableLen);
|
||||
GDEFMarkFilter filter(gdefTable, success);
|
||||
|
||||
adjustMarkGlyphs(&chars[offset], count, reverse, glyphStorage, &filter, success);
|
||||
}
|
||||
}
|
||||
|
||||
UnicodeArabicOpenTypeLayoutEngine::UnicodeArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, le_int32 typoFlags, LEErrorCode &success)
|
||||
: ArabicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags | LE_CHAR_FILTER_FEATURE_FLAG, success)
|
||||
{
|
||||
fGSUBTable = (const GlyphSubstitutionTableHeader *) CanonShaping::glyphSubstitutionTable;
|
||||
fGDEFTable = (const GlyphDefinitionTableHeader *) CanonShaping::glyphDefinitionTable;
|
||||
/* OpenTypeLayoutEngine will allocate a substitution filter */
|
||||
}
|
||||
|
||||
UnicodeArabicOpenTypeLayoutEngine::~UnicodeArabicOpenTypeLayoutEngine()
|
||||
{
|
||||
/* OpenTypeLayoutEngine will cleanup the substitution filter */
|
||||
}
|
||||
|
||||
// "glyphs", "indices" -> glyphs, indices
|
||||
le_int32 UnicodeArabicOpenTypeLayoutEngine::glyphPostProcessing(LEGlyphStorage &tempGlyphStorage, LEGlyphStorage &glyphStorage, LEErrorCode &success)
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// FIXME: we could avoid the memory allocation and copy if we
|
||||
// made a clone of mapCharsToGlyphs which took the fake glyphs
|
||||
// directly.
|
||||
le_int32 tempGlyphCount = tempGlyphStorage.getGlyphCount();
|
||||
LEUnicode *tempChars = LE_NEW_ARRAY(LEUnicode, tempGlyphCount);
|
||||
|
||||
if (tempChars == NULL) {
|
||||
success = LE_MEMORY_ALLOCATION_ERROR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (le_int32 i = 0; i < tempGlyphCount; i += 1) {
|
||||
tempChars[i] = (LEUnicode) LE_GET_GLYPH(tempGlyphStorage[i]);
|
||||
}
|
||||
|
||||
glyphStorage.adoptCharIndicesArray(tempGlyphStorage);
|
||||
|
||||
ArabicOpenTypeLayoutEngine::mapCharsToGlyphs(tempChars, 0, tempGlyphCount, FALSE, TRUE, glyphStorage, success);
|
||||
|
||||
LE_DELETE_ARRAY(tempChars);
|
||||
|
||||
return tempGlyphCount;
|
||||
}
|
||||
|
||||
void UnicodeArabicOpenTypeLayoutEngine::mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse, le_bool /*mirror*/, LEGlyphStorage &glyphStorage, LEErrorCode &success)
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (chars == NULL || offset < 0 || count < 0) {
|
||||
success = LE_ILLEGAL_ARGUMENT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
le_int32 i, dir = 1, out = 0;
|
||||
|
||||
if (reverse) {
|
||||
out = count - 1;
|
||||
dir = -1;
|
||||
}
|
||||
|
||||
glyphStorage.allocateGlyphArray(count, reverse, success);
|
||||
|
||||
for (i = 0; i < count; i += 1, out += dir) {
|
||||
glyphStorage[out] = (LEGlyphID) chars[offset + i];
|
||||
}
|
||||
}
|
||||
|
||||
void UnicodeArabicOpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse,
|
||||
LEGlyphStorage &glyphStorage, LEErrorCode &success)
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (chars == NULL || offset < 0 || count < 0) {
|
||||
success = LE_ILLEGAL_ARGUMENT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
GDEFMarkFilter filter(fGDEFTable, success);
|
||||
|
||||
adjustMarkGlyphs(&chars[offset], count, reverse, glyphStorage, &filter, success);
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
|
@ -1,243 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2014 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __ARABICLAYOUTENGINE_H
|
||||
#define __ARABICLAYOUTENGINE_H
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "LEFontInstance.h"
|
||||
#include "LEGlyphFilter.h"
|
||||
#include "LayoutEngine.h"
|
||||
#include "OpenTypeLayoutEngine.h"
|
||||
|
||||
#include "GlyphSubstitutionTables.h"
|
||||
#include "GlyphDefinitionTables.h"
|
||||
#include "GlyphPositioningTables.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
/**
|
||||
* This class implements OpenType layout for Arabic fonts. It overrides
|
||||
* the characerProcessing method to assign the correct OpenType feature
|
||||
* tags for the Arabic contextual forms. It also overrides the adjustGlyphPositions
|
||||
* method to guarantee that all vowel and accent glyphs have zero advance width.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class ArabicOpenTypeLayoutEngine : public OpenTypeLayoutEngine
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This is the main constructor. It constructs an instance of ArabicOpenTypeLayoutEngine for
|
||||
* a particular font, script and language. It takes the GSUB table as a parameter since
|
||||
* LayoutEngine::layoutEngineFactory has to read the GSUB table to know that it has an
|
||||
* Indic OpenType font.
|
||||
*
|
||||
* @param fontInstance - the font
|
||||
* @param scriptCode - the script
|
||||
* @param langaugeCode - the language
|
||||
* @param gsubTable - the GSUB table
|
||||
* @param success - set to an error code if the operation fails
|
||||
*
|
||||
* @see LayoutEngine::layoutEngineFactory
|
||||
* @see OpenTypeLayoutEngine
|
||||
* @see ScriptAndLanguageTags.h for script and language codes
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
ArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
|
||||
le_int32 typoFlags, const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTable, LEErrorCode &success);
|
||||
|
||||
/**
|
||||
* This constructor is used when the font requires a "canned" GSUB table which can't be known
|
||||
* until after this constructor has been invoked.
|
||||
*
|
||||
* @param fontInstance - the font
|
||||
* @param scriptCode - the script
|
||||
* @param langaugeCode - the language
|
||||
* @param success - set to an error code if the operation fails
|
||||
*
|
||||
* @see OpenTypeLayoutEngine
|
||||
* @see ScriptAndLanguageTags.h for script and language codes
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
ArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
|
||||
le_int32 typoFlags, LEErrorCode &success);
|
||||
|
||||
/**
|
||||
* The destructor, virtual for correct polymorphic invocation.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
virtual ~ArabicOpenTypeLayoutEngine();
|
||||
|
||||
/**
|
||||
* ICU "poor man's RTTI", returns a UClassID for the actual class.
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
virtual UClassID getDynamicClassID() const;
|
||||
|
||||
/**
|
||||
* ICU "poor man's RTTI", returns a UClassID for this class.
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
static UClassID getStaticClassID();
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* This method does Arabic OpenType character processing. It assigns the OpenType feature
|
||||
* tags to the characters to generate the correct contextual forms and ligatures.
|
||||
*
|
||||
* Input parameters:
|
||||
* @param chars - the input character context
|
||||
* @param offset - the index of the first character to process
|
||||
* @param count - the number of characters to process
|
||||
* @param max - the number of characters in the input context
|
||||
* @param rightToLeft - <code>TRUE</code> if the characters are in a right to left directional run
|
||||
*
|
||||
* Output parameters:
|
||||
* @param outChars - the output character arrayt
|
||||
* @param charIndices - the output character index array
|
||||
* @param featureTags - the output feature tag array
|
||||
* @param success - set to an error code if the operation fails
|
||||
*
|
||||
* @return the output character count
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
virtual le_int32 characterProcessing(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft,
|
||||
LEUnicode *&outChars, LEGlyphStorage &glyphStorage, LEErrorCode &success);
|
||||
|
||||
/**
|
||||
* This method applies the GPOS table if it is present, otherwise it ensures that all vowel
|
||||
* and accent glyphs have a zero advance width by calling the adjustMarkGlyphs method.
|
||||
* If the font contains a GDEF table, that is used to identify voewls and accents. Otherwise
|
||||
* the character codes are used.
|
||||
*
|
||||
* @param chars - the input character context
|
||||
* @param offset - the offset of the first character to process
|
||||
* @param count - the number of characters to process
|
||||
* @param reverse - <code>TRUE</code> if the glyphs in the glyph array have been reordered
|
||||
* @param glyphs - the input glyph array
|
||||
* @param glyphCount - the number of glyphs
|
||||
* @param positions - the position array, will be updated as needed
|
||||
* @param success - output parameter set to an error code if the operation fails
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
virtual void adjustGlyphPositions(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse, LEGlyphStorage &glyphStorage, LEErrorCode &success);
|
||||
|
||||
// static void adjustMarkGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool rightToLeft, LEGlyphStorage &glyphStorage, LEErrorCode &success);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* The class implements OpenType layout for Arabic fonts which don't
|
||||
* contain a GSUB table, using a canned GSUB table based on Unicode
|
||||
* Arabic Presentation Forms. It overrides the mapCharsToGlyphs method
|
||||
* to use the Presentation Forms as logical glyph indices. It overrides the
|
||||
* glyphPostProcessing method to convert the Presentation Forms to actual
|
||||
* glyph indices.
|
||||
*
|
||||
* @see ArabicOpenTypeLayoutEngine
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class UnicodeArabicOpenTypeLayoutEngine : public ArabicOpenTypeLayoutEngine
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This constructs an instance of UnicodeArabicOpenTypeLayoutEngine for a specific font,
|
||||
* script and language.
|
||||
*
|
||||
* @param fontInstance - the font
|
||||
* @param scriptCode - the script
|
||||
* @param languageCode - the language
|
||||
* @param success - set to an error code if the operation fails
|
||||
*
|
||||
* @see LEFontInstance
|
||||
* @see ScriptAndLanguageTags.h for script and language codes
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
UnicodeArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
|
||||
le_int32 typoFlags, LEErrorCode &success);
|
||||
|
||||
/**
|
||||
* The destructor, virtual for correct polymorphic invocation.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
virtual ~UnicodeArabicOpenTypeLayoutEngine();
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* This method converts the Arabic Presentation Forms in the temp glyph array
|
||||
* into actual glyph indices using ArabicOpenTypeLayoutEngine::mapCharsToGlyps.
|
||||
*
|
||||
* Input paramters:
|
||||
* @param tempGlyphs - the input presentation forms
|
||||
* @param tempCharIndices - the input character index array
|
||||
* @param tempGlyphCount - the number of Presentation Froms
|
||||
*
|
||||
* Output parameters:
|
||||
* @param glyphs - the output glyph index array
|
||||
* @param charIndices - the output character index array
|
||||
* @param success - set to an error code if the operation fails
|
||||
*
|
||||
* @return the number of glyph indices in the output glyph index array
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
virtual le_int32 glyphPostProcessing(LEGlyphStorage &tempGlyphStorage, LEGlyphStorage &glyphStorage, LEErrorCode &success);
|
||||
|
||||
/**
|
||||
* This method copies the input characters into the output glyph index array,
|
||||
* for use by the canned GSUB table. It also generates the character index array.
|
||||
*
|
||||
* Input parameters:
|
||||
* @param chars - the input character context
|
||||
* @param offset - the offset of the first character to be mapped
|
||||
* @param count - the number of characters to be mapped
|
||||
* @param reverse - if <code>TRUE</code>, the output will be in reverse order
|
||||
* @param mirror - if <code>TRUE</code>, do character mirroring
|
||||
* @param glyphStorage - the glyph storage object. Glyph and char index arrays will be updated.
|
||||
*
|
||||
* @param success - set to an error code if the operation fails
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
virtual void mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse, le_bool mirror,
|
||||
LEGlyphStorage &glyphStorage, LEErrorCode &success);
|
||||
|
||||
/**
|
||||
* This method ensures that all vowel and accent glyphs have a zero advance width by calling
|
||||
* the adjustMarkGlyphs method. The character codes are used to identify the vowel and mark
|
||||
* glyphs.
|
||||
*
|
||||
* @param chars - the input character context
|
||||
* @param offset - the offset of the first character to process
|
||||
* @param count - the number of characters to process
|
||||
* @param reverse - <code>TRUE</code> if the glyphs in the glyph array have been reordered
|
||||
* @param glyphStorage - the glyph storage object. The glyph positions will be updated as needed.
|
||||
* @param success - output parameter set to an error code if the operation fails
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
virtual void adjustGlyphPositions(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse, LEGlyphStorage &glyphStorage, LEErrorCode &success);
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
||||
|
|
@ -1,214 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "OpenTypeTables.h"
|
||||
#include "ArabicShaping.h"
|
||||
#include "LEGlyphStorage.h"
|
||||
#include "ClassDefinitionTables.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
// This table maps Unicode joining types to
|
||||
// ShapeTypes.
|
||||
const ArabicShaping::ShapeType ArabicShaping::shapeTypes[] =
|
||||
{
|
||||
ArabicShaping::ST_NOSHAPE_NONE, // [U]
|
||||
ArabicShaping::ST_NOSHAPE_DUAL, // [C]
|
||||
ArabicShaping::ST_DUAL, // [D]
|
||||
ArabicShaping::ST_LEFT, // [L]
|
||||
ArabicShaping::ST_RIGHT, // [R]
|
||||
ArabicShaping::ST_TRANSPARENT // [T]
|
||||
};
|
||||
|
||||
/*
|
||||
shaping array holds types for Arabic chars between 0610 and 0700
|
||||
other values are either unshaped, or transparent if a mark or format
|
||||
code, except for format codes 200c (zero-width non-joiner) and 200d
|
||||
(dual-width joiner) which are both unshaped and non_joining or
|
||||
dual-joining, respectively.
|
||||
*/
|
||||
ArabicShaping::ShapeType ArabicShaping::getShapeType(LEUnicode c)
|
||||
{
|
||||
LEErrorCode success = LE_NO_ERROR;
|
||||
const LEReferenceTo<ClassDefinitionTable> joiningTypes((const ClassDefinitionTable *) ArabicShaping::shapingTypeTable,
|
||||
ArabicShaping::shapingTypeTableLen);
|
||||
le_int32 joiningType = joiningTypes->getGlyphClass(joiningTypes, c, success);
|
||||
|
||||
if (joiningType >= 0 && joiningType < ArabicShaping::JT_COUNT && LE_SUCCESS(success)) {
|
||||
return ArabicShaping::shapeTypes[joiningType];
|
||||
}
|
||||
|
||||
return ArabicShaping::ST_NOSHAPE_NONE;
|
||||
}
|
||||
|
||||
#define isolFeatureTag LE_ISOL_FEATURE_TAG
|
||||
#define initFeatureTag LE_INIT_FEATURE_TAG
|
||||
#define mediFeatureTag LE_MEDI_FEATURE_TAG
|
||||
#define finaFeatureTag LE_FINA_FEATURE_TAG
|
||||
#define ligaFeatureTag LE_LIGA_FEATURE_TAG
|
||||
#define msetFeatureTag LE_MSET_FEATURE_TAG
|
||||
#define markFeatureTag LE_MARK_FEATURE_TAG
|
||||
#define ccmpFeatureTag LE_CCMP_FEATURE_TAG
|
||||
#define rligFeatureTag LE_RLIG_FEATURE_TAG
|
||||
#define caltFeatureTag LE_CALT_FEATURE_TAG
|
||||
#define dligFeatureTag LE_DLIG_FEATURE_TAG
|
||||
#define cswhFeatureTag LE_CSWH_FEATURE_TAG
|
||||
#define cursFeatureTag LE_CURS_FEATURE_TAG
|
||||
#define kernFeatureTag LE_KERN_FEATURE_TAG
|
||||
#define mkmkFeatureTag LE_MKMK_FEATURE_TAG
|
||||
|
||||
// NOTE:
|
||||
// The isol, fina, init and medi features must be
|
||||
// defined in the above order, and have masks that
|
||||
// are all in the same nibble.
|
||||
#define isolFeatureMask 0x80000000UL
|
||||
#define finaFeatureMask 0x40000000UL
|
||||
#define initFeatureMask 0x20000000UL
|
||||
#define mediFeatureMask 0x10000000UL
|
||||
#define ccmpFeatureMask 0x08000000UL
|
||||
#define rligFeatureMask 0x04000000UL
|
||||
#define caltFeatureMask 0x02000000UL
|
||||
#define ligaFeatureMask 0x01000000UL
|
||||
#define dligFeatureMask 0x00800000UL
|
||||
#define cswhFeatureMask 0x00400000UL
|
||||
#define msetFeatureMask 0x00200000UL
|
||||
#define cursFeatureMask 0x00100000UL
|
||||
#define kernFeatureMask 0x00080000UL
|
||||
#define markFeatureMask 0x00040000UL
|
||||
#define mkmkFeatureMask 0x00020000UL
|
||||
|
||||
#define NO_FEATURES 0
|
||||
#define ISOL_FEATURES (isolFeatureMask | ligaFeatureMask | msetFeatureMask | markFeatureMask | ccmpFeatureMask | rligFeatureMask | caltFeatureMask | dligFeatureMask | cswhFeatureMask | cursFeatureMask | kernFeatureMask | mkmkFeatureMask)
|
||||
|
||||
#define SHAPE_MASK 0xF0000000UL
|
||||
|
||||
static const FeatureMap featureMap[] = {
|
||||
{ccmpFeatureTag, ccmpFeatureMask},
|
||||
{isolFeatureTag, isolFeatureMask},
|
||||
{finaFeatureTag, finaFeatureMask},
|
||||
{mediFeatureTag, mediFeatureMask},
|
||||
{initFeatureTag, initFeatureMask},
|
||||
{rligFeatureTag, rligFeatureMask},
|
||||
{caltFeatureTag, caltFeatureMask},
|
||||
{ligaFeatureTag, ligaFeatureMask},
|
||||
{dligFeatureTag, dligFeatureMask},
|
||||
{cswhFeatureTag, cswhFeatureMask},
|
||||
{msetFeatureTag, msetFeatureMask},
|
||||
{cursFeatureTag, cursFeatureMask},
|
||||
{kernFeatureTag, kernFeatureMask},
|
||||
{markFeatureTag, markFeatureMask},
|
||||
{mkmkFeatureTag, mkmkFeatureMask}
|
||||
};
|
||||
|
||||
const FeatureMap *ArabicShaping::getFeatureMap(le_int32 &count)
|
||||
{
|
||||
count = LE_ARRAY_SIZE(featureMap);
|
||||
|
||||
return featureMap;
|
||||
}
|
||||
|
||||
void ArabicShaping::adjustTags(le_int32 outIndex, le_int32 shapeOffset, LEGlyphStorage &glyphStorage)
|
||||
{
|
||||
LEErrorCode success = LE_NO_ERROR;
|
||||
FeatureMask featureMask = (FeatureMask) glyphStorage.getAuxData(outIndex, success);
|
||||
FeatureMask shape = featureMask & SHAPE_MASK;
|
||||
|
||||
shape >>= shapeOffset;
|
||||
|
||||
glyphStorage.setAuxData(outIndex, ((featureMask & ~SHAPE_MASK) | shape), success);
|
||||
}
|
||||
|
||||
void ArabicShaping::shape(const LEUnicode *chars, le_int32 offset, le_int32 charCount, le_int32 charMax,
|
||||
le_bool rightToLeft, LEGlyphStorage &glyphStorage)
|
||||
{
|
||||
// iterate in logical order, store tags in visible order
|
||||
//
|
||||
// the effective right char is the most recently encountered
|
||||
// non-transparent char
|
||||
//
|
||||
// four boolean states:
|
||||
// the effective right char shapes
|
||||
// the effective right char causes left shaping
|
||||
// the current char shapes
|
||||
// the current char causes right shaping
|
||||
//
|
||||
// if both cause shaping, then
|
||||
// shaper.shape(errout, 2) (isolate to initial, or final to medial)
|
||||
// shaper.shape(out, 1) (isolate to final)
|
||||
|
||||
ShapeType rightType = ST_NOSHAPE_NONE, leftType = ST_NOSHAPE_NONE;
|
||||
LEErrorCode success = LE_NO_ERROR;
|
||||
le_int32 i;
|
||||
|
||||
for (i = offset - 1; i >= 0; i -= 1) {
|
||||
rightType = getShapeType(chars[i]);
|
||||
|
||||
if (rightType != ST_TRANSPARENT) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = offset + charCount; i < charMax; i += 1) {
|
||||
leftType = getShapeType(chars[i]);
|
||||
|
||||
if (leftType != ST_TRANSPARENT) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// erout is effective right logical index
|
||||
le_int32 erout = -1;
|
||||
le_bool rightShapes = FALSE;
|
||||
le_bool rightCauses = (rightType & MASK_SHAPE_LEFT) != 0;
|
||||
le_int32 in, e, out = 0, dir = 1;
|
||||
|
||||
if (rightToLeft) {
|
||||
out = charCount - 1;
|
||||
erout = charCount;
|
||||
dir = -1;
|
||||
}
|
||||
|
||||
for (in = offset, e = offset + charCount; in < e; in += 1, out += dir) {
|
||||
LEUnicode c = chars[in];
|
||||
ShapeType t = getShapeType(c);
|
||||
|
||||
if (t == ST_NOSHAPE_NONE) {
|
||||
glyphStorage.setAuxData(out, NO_FEATURES, success);
|
||||
} else {
|
||||
glyphStorage.setAuxData(out, ISOL_FEATURES, success);
|
||||
}
|
||||
|
||||
if ((t & MASK_TRANSPARENT) != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
le_bool curShapes = (t & MASK_NOSHAPE) == 0;
|
||||
le_bool curCauses = (t & MASK_SHAPE_RIGHT) != 0;
|
||||
|
||||
if (rightCauses && curCauses) {
|
||||
if (rightShapes) {
|
||||
adjustTags(erout, 2, glyphStorage);
|
||||
}
|
||||
|
||||
if (curShapes) {
|
||||
adjustTags(out, 1, glyphStorage);
|
||||
}
|
||||
}
|
||||
|
||||
rightShapes = curShapes;
|
||||
rightCauses = (t & MASK_SHAPE_LEFT) != 0;
|
||||
erout = out;
|
||||
}
|
||||
|
||||
if (rightShapes && rightCauses && (leftType & MASK_SHAPE_RIGHT) != 0) {
|
||||
adjustTags(erout, 2, glyphStorage);
|
||||
}
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
|
@ -1,81 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __ARABICSHAPING_H
|
||||
#define __ARABICSHAPING_H
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \internal
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "OpenTypeTables.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class LEGlyphStorage;
|
||||
|
||||
class ArabicShaping /* not : public UObject because all methods are static */ {
|
||||
public:
|
||||
// Joining types
|
||||
enum JoiningTypes
|
||||
{
|
||||
JT_NON_JOINING = 0,
|
||||
JT_JOIN_CAUSING = 1,
|
||||
JT_DUAL_JOINING = 2,
|
||||
JT_LEFT_JOINING = 3,
|
||||
JT_RIGHT_JOINING = 4,
|
||||
JT_TRANSPARENT = 5,
|
||||
JT_COUNT = 6
|
||||
};
|
||||
|
||||
// shaping bit masks
|
||||
enum ShapingBitMasks
|
||||
{
|
||||
MASK_SHAPE_RIGHT = 1, // if this bit set, shapes to right
|
||||
MASK_SHAPE_LEFT = 2, // if this bit set, shapes to left
|
||||
MASK_TRANSPARENT = 4, // if this bit set, is transparent (ignore other bits)
|
||||
MASK_NOSHAPE = 8 // if this bit set, don't shape this char, i.e. tatweel
|
||||
};
|
||||
|
||||
// shaping values
|
||||
enum ShapeTypeValues
|
||||
{
|
||||
ST_NONE = 0,
|
||||
ST_RIGHT = MASK_SHAPE_RIGHT,
|
||||
ST_LEFT = MASK_SHAPE_LEFT,
|
||||
ST_DUAL = MASK_SHAPE_RIGHT | MASK_SHAPE_LEFT,
|
||||
ST_TRANSPARENT = MASK_TRANSPARENT,
|
||||
ST_NOSHAPE_DUAL = MASK_NOSHAPE | ST_DUAL,
|
||||
ST_NOSHAPE_NONE = MASK_NOSHAPE
|
||||
};
|
||||
|
||||
typedef le_int32 ShapeType;
|
||||
|
||||
static void shape(const LEUnicode *chars, le_int32 offset, le_int32 charCount, le_int32 charMax,
|
||||
le_bool rightToLeft, LEGlyphStorage &glyphStorage);
|
||||
|
||||
static const FeatureMap *getFeatureMap(le_int32 &count);
|
||||
|
||||
private:
|
||||
// forbid instantiation
|
||||
ArabicShaping();
|
||||
|
||||
static ShapeType getShapeType(LEUnicode c);
|
||||
|
||||
static const le_uint8 shapingTypeTable[];
|
||||
static const size_t shapingTypeTableLen;
|
||||
|
||||
static const ShapeType shapeTypes[];
|
||||
|
||||
static void adjustTags(le_int32 outIndex, le_int32 shapeOffset, LEGlyphStorage &glyphStorage);
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
|
@ -1,44 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __ATTACHMENTPOSITIONINGSUBTABLES_H
|
||||
#define __ATTACHMENTPOSITIONINGSUBTABLES_H
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \internal
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "OpenTypeTables.h"
|
||||
#include "GlyphPositioningTables.h"
|
||||
#include "ValueRecords.h"
|
||||
#include "GlyphIterator.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
struct AttachmentPositioningSubtable : GlyphPositioningSubtable
|
||||
{
|
||||
Offset baseCoverageTableOffset;
|
||||
le_uint16 classCount;
|
||||
Offset markArrayOffset;
|
||||
Offset baseArrayOffset;
|
||||
|
||||
inline le_int32 getBaseCoverage(const LETableReference &base, LEGlyphID baseGlyphId, LEErrorCode &success) const;
|
||||
|
||||
le_uint32 process(GlyphIterator *glyphIterator) const;
|
||||
};
|
||||
|
||||
inline le_int32 AttachmentPositioningSubtable::getBaseCoverage(const LETableReference &base, LEGlyphID baseGlyphID, LEErrorCode &success) const
|
||||
{
|
||||
return getGlyphCoverage(base, baseCoverageTableOffset, baseGlyphID, success);
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load diff
|
@ -1,83 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "LEGlyphStorage.h"
|
||||
#include "CanonShaping.h"
|
||||
#include "GlyphDefinitionTables.h"
|
||||
#include "ClassDefinitionTables.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
void CanonShaping::sortMarks(le_int32 *indices, const le_int32 *combiningClasses, le_int32 index, le_int32 limit)
|
||||
{
|
||||
for (le_int32 j = index + 1; j < limit; j += 1) {
|
||||
le_int32 i;
|
||||
le_int32 v = indices[j];
|
||||
le_int32 c = combiningClasses[v];
|
||||
|
||||
for (i = j - 1; i >= index; i -= 1) {
|
||||
if (c >= combiningClasses[indices[i]]) {
|
||||
break;
|
||||
}
|
||||
|
||||
indices[i + 1] = indices[i];
|
||||
}
|
||||
|
||||
indices[i + 1] = v;
|
||||
}
|
||||
}
|
||||
|
||||
void CanonShaping::reorderMarks(const LEUnicode *inChars, le_int32 charCount, le_bool rightToLeft,
|
||||
LEUnicode *outChars, LEGlyphStorage &glyphStorage)
|
||||
{
|
||||
LEErrorCode success = LE_NO_ERROR;
|
||||
LEReferenceTo<GlyphDefinitionTableHeader> gdefTable(CanonShaping::glyphDefinitionTable, CanonShaping::glyphDefinitionTableLen);
|
||||
LEReferenceTo<ClassDefinitionTable> classTable = gdefTable->getMarkAttachClassDefinitionTable(gdefTable, success);
|
||||
le_int32 *combiningClasses = LE_NEW_ARRAY(le_int32, charCount);
|
||||
le_int32 *indices = LE_NEW_ARRAY(le_int32, charCount);
|
||||
le_int32 i;
|
||||
|
||||
for (i = 0; i < charCount; i += 1) {
|
||||
combiningClasses[i] = classTable->getGlyphClass(classTable, (LEGlyphID) inChars[i], success);
|
||||
indices[i] = i;
|
||||
}
|
||||
|
||||
for (i = 0; i < charCount; i += 1) {
|
||||
if (combiningClasses[i] != 0) {
|
||||
le_int32 mark;
|
||||
|
||||
for (mark = i; mark < charCount; mark += 1) {
|
||||
if (combiningClasses[mark] == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
sortMarks(indices, combiningClasses, i, mark);
|
||||
}
|
||||
}
|
||||
|
||||
le_int32 out = 0, dir = 1;
|
||||
|
||||
if (rightToLeft) {
|
||||
out = charCount - 1;
|
||||
dir = -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < charCount; i += 1, out += dir) {
|
||||
le_int32 index = indices[i];
|
||||
|
||||
outChars[i] = inChars[index];
|
||||
glyphStorage.setCharIndex(out, index, success);
|
||||
}
|
||||
|
||||
LE_DELETE_ARRAY(indices);
|
||||
LE_DELETE_ARRAY(combiningClasses);
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
|
@ -1,34 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __CANONSHAPING_H
|
||||
#define __CANONSHAPING_H
|
||||
|
||||
#include "LETypes.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class LEGlyphStorage;
|
||||
|
||||
class U_LAYOUT_API CanonShaping /* not : public UObject because all members are static */
|
||||
{
|
||||
public:
|
||||
static const le_uint8 glyphSubstitutionTable[];
|
||||
static const size_t glyphSubstitutionTableLen;
|
||||
static const le_uint8 glyphDefinitionTable[];
|
||||
static const size_t glyphDefinitionTableLen;
|
||||
|
||||
static void reorderMarks(const LEUnicode *inChars, le_int32 charCount, le_bool rightToLeft,
|
||||
LEUnicode *outChars, LEGlyphStorage &glyphStorage);
|
||||
|
||||
private:
|
||||
static void sortMarks(le_int32 *indices, const le_int32 *combiningClasses, le_int32 index, le_int32 limit);
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
|
@ -1,83 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __CHARSUBSTITUTIONFILTER_H
|
||||
#define __CHARSUBSTITUTIONFILTER_H
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "LEGlyphFilter.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class LEFontInstance;
|
||||
|
||||
/**
|
||||
* This filter is used by character-based GSUB processors. It
|
||||
* accepts only those characters which the given font can display.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class CharSubstitutionFilter : public UMemory, public LEGlyphFilter
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* Holds the font which is used to test the characters.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
const LEFontInstance *fFontInstance;
|
||||
|
||||
/**
|
||||
* The copy constructor. Not allowed!
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
CharSubstitutionFilter(const CharSubstitutionFilter &other); // forbid copying of this class
|
||||
|
||||
/**
|
||||
* The replacement operator. Not allowed!
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
CharSubstitutionFilter &operator=(const CharSubstitutionFilter &other); // forbid copying of this class
|
||||
|
||||
public:
|
||||
/**
|
||||
* The constructor.
|
||||
*
|
||||
* @param fontInstance - the font to use to test the characters.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
CharSubstitutionFilter(const LEFontInstance *fontInstance);
|
||||
|
||||
/**
|
||||
* The destructor.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
~CharSubstitutionFilter();
|
||||
|
||||
/**
|
||||
* This method is used to test if a particular
|
||||
* character can be displayed by the filter's
|
||||
* font.
|
||||
*
|
||||
* @param glyph - the Unicode character code to be tested
|
||||
*
|
||||
* @return TRUE if the filter's font can display this character.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
le_bool accept(LEGlyphID glyph) const;
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
||||
|
||||
|
|
@ -1,134 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "OpenTypeTables.h"
|
||||
#include "OpenTypeUtilities.h"
|
||||
#include "ClassDefinitionTables.h"
|
||||
#include "LESwaps.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
le_int32 ClassDefinitionTable::getGlyphClass(const LETableReference& base, LEGlyphID glyphID, LEErrorCode &success) const
|
||||
{
|
||||
LEReferenceTo<ClassDefinitionTable> thisRef(base, success);
|
||||
if (LE_FAILURE(success)) return 0;
|
||||
|
||||
switch(SWAPW(classFormat)) {
|
||||
case 0:
|
||||
return 0;
|
||||
|
||||
case 1:
|
||||
{
|
||||
const LEReferenceTo<ClassDefFormat1Table> f1Table(thisRef, success);
|
||||
return f1Table->getGlyphClass(f1Table, glyphID, success);
|
||||
}
|
||||
|
||||
case 2:
|
||||
{
|
||||
const LEReferenceTo<ClassDefFormat2Table> f2Table(thisRef, success);
|
||||
return f2Table->getGlyphClass(f2Table, glyphID, success);
|
||||
}
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
le_bool ClassDefinitionTable::hasGlyphClass(const LETableReference &base, le_int32 glyphClass, LEErrorCode &success) const
|
||||
{
|
||||
LEReferenceTo<ClassDefinitionTable> thisRef(base, success);
|
||||
if (LE_FAILURE(success)) return 0;
|
||||
|
||||
switch(SWAPW(classFormat)) {
|
||||
case 0:
|
||||
return 0;
|
||||
|
||||
case 1:
|
||||
{
|
||||
const LEReferenceTo<ClassDefFormat1Table> f1Table(thisRef, success);
|
||||
return f1Table->hasGlyphClass(f1Table, glyphClass, success);
|
||||
}
|
||||
|
||||
case 2:
|
||||
{
|
||||
const LEReferenceTo<ClassDefFormat2Table> f2Table(thisRef, success);
|
||||
return f2Table->hasGlyphClass(f2Table, glyphClass, success);
|
||||
}
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
le_int32 ClassDefFormat1Table::getGlyphClass(const LETableReference& base, LEGlyphID glyphID, LEErrorCode &success) const
|
||||
{
|
||||
if(LE_FAILURE(success)) return 0;
|
||||
|
||||
le_uint16 count = SWAPW(glyphCount);
|
||||
LEReferenceToArrayOf<le_uint16> classValueArrayRef(base, success, &classValueArray[0], count);
|
||||
TTGlyphID ttGlyphID = (TTGlyphID) LE_GET_GLYPH(glyphID);
|
||||
TTGlyphID firstGlyph = SWAPW(startGlyph);
|
||||
TTGlyphID lastGlyph = firstGlyph + count;
|
||||
|
||||
if (LE_SUCCESS(success) && ttGlyphID >= firstGlyph && ttGlyphID < lastGlyph) {
|
||||
return SWAPW( classValueArrayRef(ttGlyphID - firstGlyph, success) );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
le_bool ClassDefFormat1Table::hasGlyphClass(const LETableReference &base, le_int32 glyphClass, LEErrorCode &success) const
|
||||
{
|
||||
if(LE_FAILURE(success)) return 0;
|
||||
le_uint16 count = SWAPW(glyphCount);
|
||||
LEReferenceToArrayOf<le_uint16> classValueArrayRef(base, success, &classValueArray[0], count);
|
||||
int i;
|
||||
|
||||
for (i = 0; LE_SUCCESS(success)&& (i < count); i += 1) {
|
||||
if (SWAPW(classValueArrayRef(i,success)) == glyphClass) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
le_int32 ClassDefFormat2Table::getGlyphClass(const LETableReference& base, LEGlyphID glyphID, LEErrorCode &success) const
|
||||
{
|
||||
if(LE_FAILURE(success)) return 0;
|
||||
TTGlyphID ttGlyph = (TTGlyphID) LE_GET_GLYPH(glyphID);
|
||||
le_uint16 rangeCount = SWAPW(classRangeCount);
|
||||
LEReferenceToArrayOf<GlyphRangeRecord> classRangeRecordArrayRef(base, success, &classRangeRecordArray[0], rangeCount);
|
||||
le_int32 rangeIndex =
|
||||
OpenTypeUtilities::getGlyphRangeIndex(ttGlyph, classRangeRecordArrayRef, success);
|
||||
|
||||
if (rangeIndex < 0 || LE_FAILURE(success)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return SWAPW(classRangeRecordArrayRef(rangeIndex, success).rangeValue);
|
||||
}
|
||||
|
||||
le_bool ClassDefFormat2Table::hasGlyphClass(const LETableReference &base, le_int32 glyphClass, LEErrorCode &success) const
|
||||
{
|
||||
if(LE_FAILURE(success)) return 0;
|
||||
le_uint16 rangeCount = SWAPW(classRangeCount);
|
||||
LEReferenceToArrayOf<GlyphRangeRecord> classRangeRecordArrayRef(base, success, &classRangeRecordArray[0], rangeCount);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < rangeCount && LE_SUCCESS(success); i += 1) {
|
||||
if (SWAPW(classRangeRecordArrayRef(i,success).rangeValue) == glyphClass) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
|
@ -1,72 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __CLASSDEFINITIONTABLES_H
|
||||
#define __CLASSDEFINITIONTABLES_H
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \internal
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "OpenTypeTables.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
struct ClassDefinitionTable
|
||||
{
|
||||
le_uint16 classFormat;
|
||||
|
||||
le_int32 getGlyphClass(const LETableReference &base, LEGlyphID glyphID, LEErrorCode &success) const;
|
||||
le_bool hasGlyphClass(const LETableReference &base, le_int32 glyphClass, LEErrorCode &success) const;
|
||||
|
||||
le_int32 getGlyphClass(LEGlyphID glyphID) const {
|
||||
LETableReference base((const le_uint8*)this);
|
||||
LEErrorCode ignored = LE_NO_ERROR;
|
||||
return getGlyphClass(base,glyphID,ignored);
|
||||
}
|
||||
|
||||
le_bool hasGlyphClass(le_int32 glyphClass) const {
|
||||
LETableReference base((const le_uint8*)this);
|
||||
LEErrorCode ignored = LE_NO_ERROR;
|
||||
return hasGlyphClass(base,glyphClass,ignored);
|
||||
}
|
||||
};
|
||||
|
||||
struct ClassDefFormat1Table : ClassDefinitionTable
|
||||
{
|
||||
TTGlyphID startGlyph;
|
||||
le_uint16 glyphCount;
|
||||
le_uint16 classValueArray[ANY_NUMBER];
|
||||
|
||||
le_int32 getGlyphClass(const LETableReference &base, LEGlyphID glyphID, LEErrorCode &success) const;
|
||||
le_bool hasGlyphClass(const LETableReference &base, le_int32 glyphClass, LEErrorCode &success) const;
|
||||
};
|
||||
LE_VAR_ARRAY(ClassDefFormat1Table, classValueArray)
|
||||
|
||||
|
||||
struct ClassRangeRecord
|
||||
{
|
||||
TTGlyphID start;
|
||||
TTGlyphID end;
|
||||
le_uint16 classValue;
|
||||
};
|
||||
|
||||
struct ClassDefFormat2Table : ClassDefinitionTable
|
||||
{
|
||||
le_uint16 classRangeCount;
|
||||
GlyphRangeRecord classRangeRecordArray[ANY_NUMBER];
|
||||
|
||||
le_int32 getGlyphClass(const LETableReference &base, LEGlyphID glyphID, LEErrorCode &success) const;
|
||||
le_bool hasGlyphClass(const LETableReference &base, le_int32 glyphClass, LEErrorCode &success) const;
|
||||
};
|
||||
LE_VAR_ARRAY(ClassDefFormat2Table, classRangeRecordArray)
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
|
@ -1,59 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/**
|
||||
*
|
||||
* (C) Copyright IBM Corp. and Others 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __CONTEXTUALGLYPHINSERTION_H
|
||||
#define __CONTEXTUALGLYPHINSERTION_H
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \internal
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "LayoutTables.h"
|
||||
#include "StateTables.h"
|
||||
#include "MorphTables.h"
|
||||
#include "MorphStateTables.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
struct ContextualGlyphInsertionHeader : MorphStateTableHeader
|
||||
{
|
||||
};
|
||||
|
||||
struct ContextualGlyphInsertionHeader2 : MorphStateTableHeader2
|
||||
{
|
||||
le_uint32 insertionTableOffset;
|
||||
};
|
||||
|
||||
enum ContextualGlyphInsertionFlags
|
||||
{
|
||||
cgiSetMark = 0x8000,
|
||||
cgiDontAdvance = 0x4000,
|
||||
cgiCurrentIsKashidaLike = 0x2000,
|
||||
cgiMarkedIsKashidaLike = 0x1000,
|
||||
cgiCurrentInsertBefore = 0x0800,
|
||||
cgiMarkInsertBefore = 0x0400,
|
||||
cgiCurrentInsertCountMask = 0x03E0,
|
||||
cgiMarkedInsertCountMask = 0x001F
|
||||
};
|
||||
|
||||
struct ContextualGlyphInsertionStateEntry : StateEntry
|
||||
{
|
||||
ByteOffset currentInsertionListOffset;
|
||||
ByteOffset markedInsertionListOffset;
|
||||
};
|
||||
|
||||
struct ContextualGlyphInsertionStateEntry2 : StateEntry2
|
||||
{
|
||||
le_uint16 currentInsertionListIndex;
|
||||
le_uint16 markedInsertionListIndex;
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
|
@ -1,116 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "MorphTables.h"
|
||||
#include "StateTables.h"
|
||||
#include "MorphStateTables.h"
|
||||
#include "SubtableProcessor2.h"
|
||||
#include "StateTableProcessor2.h"
|
||||
#include "ContextualGlyphInsertionProc2.h"
|
||||
#include "LEGlyphStorage.h"
|
||||
#include "LESwaps.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ContextualGlyphInsertionProcessor2)
|
||||
|
||||
ContextualGlyphInsertionProcessor2::ContextualGlyphInsertionProcessor2(
|
||||
const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success)
|
||||
: StateTableProcessor2(morphSubtableHeader, success)
|
||||
{
|
||||
contextualGlyphHeader = LEReferenceTo<ContextualGlyphInsertionHeader2>(morphSubtableHeader, success);
|
||||
if(LE_FAILURE(success) || !contextualGlyphHeader.isValid()) return;
|
||||
le_uint32 insertionTableOffset = SWAPL(contextualGlyphHeader->insertionTableOffset);
|
||||
insertionTable = LEReferenceToArrayOf<le_uint16>(stHeader, success, insertionTableOffset, LE_UNBOUNDED_ARRAY);
|
||||
entryTable = LEReferenceToArrayOf<ContextualGlyphInsertionStateEntry2>(stHeader, success, entryTableOffset, LE_UNBOUNDED_ARRAY);
|
||||
}
|
||||
|
||||
ContextualGlyphInsertionProcessor2::~ContextualGlyphInsertionProcessor2()
|
||||
{
|
||||
}
|
||||
|
||||
void ContextualGlyphInsertionProcessor2::beginStateTable()
|
||||
{
|
||||
markGlyph = 0;
|
||||
}
|
||||
|
||||
void ContextualGlyphInsertionProcessor2::doInsertion(LEGlyphStorage &glyphStorage,
|
||||
le_int16 atGlyph,
|
||||
le_int16 &index,
|
||||
le_int16 count,
|
||||
le_bool /* isKashidaLike */,
|
||||
le_bool isBefore,
|
||||
LEErrorCode &success) {
|
||||
LEGlyphID *insertGlyphs = glyphStorage.insertGlyphs(atGlyph, count + 1, success);
|
||||
|
||||
if(LE_FAILURE(success) || insertGlyphs==NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Note: Kashida vs Split Vowel seems to only affect selection and highlighting.
|
||||
// We note the flag, but do not layout different.
|
||||
// https://developer.apple.com/fonts/TTRefMan/RM06/Chap6mort.html
|
||||
|
||||
le_int16 targetIndex = 0;
|
||||
if(isBefore) {
|
||||
// insert at beginning
|
||||
insertGlyphs[targetIndex++] = glyphStorage[atGlyph];
|
||||
} else {
|
||||
// insert at end
|
||||
insertGlyphs[count] = glyphStorage[atGlyph];
|
||||
}
|
||||
|
||||
while(count--) {
|
||||
insertGlyphs[targetIndex++] = insertionTable.getObject(index++, success);
|
||||
}
|
||||
glyphStorage.applyInsertions();
|
||||
}
|
||||
|
||||
le_uint16 ContextualGlyphInsertionProcessor2::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph,
|
||||
EntryTableIndex2 index, LEErrorCode &success)
|
||||
{
|
||||
const ContextualGlyphInsertionStateEntry2 *entry = entryTable.getAlias(index, success);
|
||||
|
||||
if(LE_FAILURE(success)) return 0; // TODO- which state?
|
||||
|
||||
le_uint16 newState = SWAPW(entry->newStateIndex);
|
||||
le_uint16 flags = SWAPW(entry->flags);
|
||||
|
||||
le_int16 markIndex = SWAPW(entry->markedInsertionListIndex);
|
||||
if (markIndex > 0) {
|
||||
le_int16 count = (flags & cgiMarkedInsertCountMask) >> 5;
|
||||
le_bool isKashidaLike = (flags & cgiMarkedIsKashidaLike);
|
||||
le_bool isBefore = (flags & cgiMarkInsertBefore);
|
||||
doInsertion(glyphStorage, markGlyph, markIndex, count, isKashidaLike, isBefore, success);
|
||||
}
|
||||
|
||||
le_int16 currIndex = SWAPW(entry->currentInsertionListIndex);
|
||||
if (currIndex > 0) {
|
||||
le_int16 count = flags & cgiCurrentInsertCountMask;
|
||||
le_bool isKashidaLike = (flags & cgiCurrentIsKashidaLike);
|
||||
le_bool isBefore = (flags & cgiCurrentInsertBefore);
|
||||
doInsertion(glyphStorage, currGlyph, currIndex, count, isKashidaLike, isBefore, success);
|
||||
}
|
||||
|
||||
if (flags & cgiSetMark) {
|
||||
markGlyph = currGlyph;
|
||||
}
|
||||
|
||||
if (!(flags & cgiDontAdvance)) {
|
||||
currGlyph += dir;
|
||||
}
|
||||
|
||||
return newState;
|
||||
}
|
||||
|
||||
void ContextualGlyphInsertionProcessor2::endStateTable()
|
||||
{
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
|
@ -1,83 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. and others 2013-2014 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __CONTEXTUALGLYPHINSERTIONPROCESSOR2_H
|
||||
#define __CONTEXTUALGLYPHINSERTIONPROCESSOR2_H
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \internal
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "MorphTables.h"
|
||||
#include "SubtableProcessor2.h"
|
||||
#include "StateTableProcessor2.h"
|
||||
#include "ContextualGlyphInsertionProc2.h"
|
||||
#include "ContextualGlyphInsertion.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class LEGlyphStorage;
|
||||
|
||||
class ContextualGlyphInsertionProcessor2 : public StateTableProcessor2
|
||||
{
|
||||
public:
|
||||
virtual void beginStateTable();
|
||||
|
||||
virtual le_uint16 processStateEntry(LEGlyphStorage &glyphStorage,
|
||||
le_int32 &currGlyph, EntryTableIndex2 index, LEErrorCode &success);
|
||||
|
||||
virtual void endStateTable();
|
||||
|
||||
ContextualGlyphInsertionProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success);
|
||||
virtual ~ContextualGlyphInsertionProcessor2();
|
||||
|
||||
/**
|
||||
* ICU "poor man's RTTI", returns a UClassID for the actual class.
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
virtual UClassID getDynamicClassID() const;
|
||||
|
||||
/**
|
||||
* ICU "poor man's RTTI", returns a UClassID for this class.
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
static UClassID getStaticClassID();
|
||||
|
||||
private:
|
||||
ContextualGlyphInsertionProcessor2();
|
||||
|
||||
/**
|
||||
* Perform the actual insertion
|
||||
* @param atGlyph index of glyph to insert at
|
||||
* @param index index into the insertionTable (in/out)
|
||||
* @param count number of insertions
|
||||
* @param isKashidaLike Kashida like (vs Split Vowel like). No effect currently.
|
||||
* @param isBefore if true, insert extra glyphs before the marked glyph
|
||||
*/
|
||||
void doInsertion(LEGlyphStorage &glyphStorage,
|
||||
le_int16 atGlyph,
|
||||
le_int16 &index,
|
||||
le_int16 count,
|
||||
le_bool isKashidaLike,
|
||||
le_bool isBefore,
|
||||
LEErrorCode &success);
|
||||
|
||||
|
||||
protected:
|
||||
le_int32 markGlyph;
|
||||
LEReferenceToArrayOf<le_uint16> insertionTable;
|
||||
LEReferenceToArrayOf<ContextualGlyphInsertionStateEntry2> entryTable;
|
||||
LEReferenceTo<ContextualGlyphInsertionHeader2> contextualGlyphHeader;
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
|
@ -1,85 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "MorphTables.h"
|
||||
#include "StateTables.h"
|
||||
#include "MorphStateTables.h"
|
||||
#include "SubtableProcessor.h"
|
||||
#include "StateTableProcessor.h"
|
||||
#include "ContextualGlyphSubstProc.h"
|
||||
#include "LEGlyphStorage.h"
|
||||
#include "LESwaps.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ContextualGlyphSubstitutionProcessor)
|
||||
|
||||
ContextualGlyphSubstitutionProcessor::ContextualGlyphSubstitutionProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success)
|
||||
: StateTableProcessor(morphSubtableHeader, success), entryTable(), contextualGlyphSubstitutionHeader(morphSubtableHeader, success)
|
||||
{
|
||||
contextualGlyphSubstitutionHeader.orphan();
|
||||
substitutionTableOffset = SWAPW(contextualGlyphSubstitutionHeader->substitutionTableOffset);
|
||||
|
||||
|
||||
entryTable = LEReferenceToArrayOf<ContextualGlyphSubstitutionStateEntry>(stateTableHeader, success,
|
||||
(const ContextualGlyphSubstitutionStateEntry*)(&stateTableHeader->stHeader),
|
||||
entryTableOffset, LE_UNBOUNDED_ARRAY);
|
||||
int16Table = LEReferenceToArrayOf<le_int16>(stateTableHeader, success, (const le_int16*)(&stateTableHeader->stHeader),
|
||||
0, LE_UNBOUNDED_ARRAY); // rest of the table as le_int16s
|
||||
}
|
||||
|
||||
ContextualGlyphSubstitutionProcessor::~ContextualGlyphSubstitutionProcessor()
|
||||
{
|
||||
}
|
||||
|
||||
void ContextualGlyphSubstitutionProcessor::beginStateTable()
|
||||
{
|
||||
markGlyph = 0;
|
||||
}
|
||||
|
||||
ByteOffset ContextualGlyphSubstitutionProcessor::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index)
|
||||
{
|
||||
LEErrorCode success = LE_NO_ERROR;
|
||||
const ContextualGlyphSubstitutionStateEntry *entry = entryTable.getAlias(index, success);
|
||||
ByteOffset newState = SWAPW(entry->newStateOffset);
|
||||
le_int16 flags = SWAPW(entry->flags);
|
||||
WordOffset markOffset = SWAPW(entry->markOffset);
|
||||
WordOffset currOffset = SWAPW(entry->currOffset);
|
||||
|
||||
if (markOffset != 0 && LE_SUCCESS(success)) {
|
||||
LEGlyphID mGlyph = glyphStorage[markGlyph];
|
||||
TTGlyphID newGlyph = SWAPW(int16Table.getObject(markOffset + LE_GET_GLYPH(mGlyph), success)); // whew.
|
||||
|
||||
glyphStorage[markGlyph] = LE_SET_GLYPH(mGlyph, newGlyph);
|
||||
}
|
||||
|
||||
if (currOffset != 0) {
|
||||
LEGlyphID thisGlyph = glyphStorage[currGlyph];
|
||||
TTGlyphID newGlyph = SWAPW(int16Table.getObject(currOffset + LE_GET_GLYPH(thisGlyph), success)); // whew.
|
||||
|
||||
glyphStorage[currGlyph] = LE_SET_GLYPH(thisGlyph, newGlyph);
|
||||
}
|
||||
|
||||
if (flags & cgsSetMark) {
|
||||
markGlyph = currGlyph;
|
||||
}
|
||||
|
||||
if (!(flags & cgsDontAdvance)) {
|
||||
// should handle reverse too!
|
||||
currGlyph += 1;
|
||||
}
|
||||
|
||||
return newState;
|
||||
}
|
||||
|
||||
void ContextualGlyphSubstitutionProcessor::endStateTable()
|
||||
{
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
|
@ -1,67 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2014 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __CONTEXTUALGLYPHSUBSTITUTIONPROCESSOR_H
|
||||
#define __CONTEXTUALGLYPHSUBSTITUTIONPROCESSOR_H
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \internal
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "MorphTables.h"
|
||||
#include "SubtableProcessor.h"
|
||||
#include "StateTableProcessor.h"
|
||||
#include "ContextualGlyphSubstitution.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class LEGlyphStorage;
|
||||
|
||||
class ContextualGlyphSubstitutionProcessor : public StateTableProcessor
|
||||
{
|
||||
public:
|
||||
virtual void beginStateTable();
|
||||
|
||||
virtual ByteOffset processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index);
|
||||
|
||||
virtual void endStateTable();
|
||||
|
||||
ContextualGlyphSubstitutionProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success);
|
||||
virtual ~ContextualGlyphSubstitutionProcessor();
|
||||
|
||||
/**
|
||||
* ICU "poor man's RTTI", returns a UClassID for the actual class.
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
virtual UClassID getDynamicClassID() const;
|
||||
|
||||
/**
|
||||
* ICU "poor man's RTTI", returns a UClassID for this class.
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
static UClassID getStaticClassID();
|
||||
|
||||
private:
|
||||
ContextualGlyphSubstitutionProcessor();
|
||||
|
||||
protected:
|
||||
ByteOffset substitutionTableOffset;
|
||||
LEReferenceToArrayOf<ContextualGlyphSubstitutionStateEntry> entryTable;
|
||||
LEReferenceToArrayOf<le_int16> int16Table;
|
||||
le_int32 markGlyph;
|
||||
|
||||
LEReferenceTo<ContextualGlyphSubstitutionHeader> contextualGlyphSubstitutionHeader;
|
||||
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
|
@ -1,147 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. and others 1998-2016 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "MorphTables.h"
|
||||
#include "StateTables.h"
|
||||
#include "MorphStateTables.h"
|
||||
#include "SubtableProcessor2.h"
|
||||
#include "StateTableProcessor2.h"
|
||||
#include "ContextualGlyphSubstProc2.h"
|
||||
#include "LEGlyphStorage.h"
|
||||
#include "LESwaps.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ContextualGlyphSubstitutionProcessor2)
|
||||
|
||||
ContextualGlyphSubstitutionProcessor2::ContextualGlyphSubstitutionProcessor2(
|
||||
const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success)
|
||||
: StateTableProcessor2(morphSubtableHeader, success), contextualGlyphHeader(morphSubtableHeader, success)
|
||||
{
|
||||
if(LE_FAILURE(success)) return;
|
||||
le_uint32 perGlyphTableOffset = SWAPL(contextualGlyphHeader->perGlyphTableOffset);
|
||||
perGlyphTable = LEReferenceToArrayOf<le_uint32> (stHeader, success, perGlyphTableOffset, LE_UNBOUNDED_ARRAY);
|
||||
entryTable = LEReferenceToArrayOf<ContextualGlyphStateEntry2>(stHeader, success, entryTableOffset, LE_UNBOUNDED_ARRAY);
|
||||
}
|
||||
|
||||
ContextualGlyphSubstitutionProcessor2::~ContextualGlyphSubstitutionProcessor2()
|
||||
{
|
||||
}
|
||||
|
||||
void ContextualGlyphSubstitutionProcessor2::beginStateTable()
|
||||
{
|
||||
markGlyph = 0;
|
||||
}
|
||||
|
||||
le_uint16 ContextualGlyphSubstitutionProcessor2::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph,
|
||||
EntryTableIndex2 index, LEErrorCode &success)
|
||||
{
|
||||
if(LE_FAILURE(success)) return 0;
|
||||
const ContextualGlyphStateEntry2 *entry = entryTable.getAlias(index, success);
|
||||
if(LE_FAILURE(success)) return 0;
|
||||
le_uint16 newState = SWAPW(entry->newStateIndex);
|
||||
le_uint16 flags = SWAPW(entry->flags);
|
||||
le_int16 markIndex = SWAPW(entry->markIndex);
|
||||
le_int16 currIndex = SWAPW(entry->currIndex);
|
||||
|
||||
if (markIndex != -1) {
|
||||
le_uint32 offset = SWAPL(perGlyphTable(markIndex, success));
|
||||
LEGlyphID mGlyph = glyphStorage[markGlyph];
|
||||
TTGlyphID newGlyph = lookup(offset, mGlyph, success);
|
||||
glyphStorage[markGlyph] = LE_SET_GLYPH(mGlyph, newGlyph);
|
||||
}
|
||||
|
||||
if (currIndex != -1) {
|
||||
le_uint32 offset = SWAPL(perGlyphTable(currIndex, success));
|
||||
LEGlyphID thisGlyph = glyphStorage[currGlyph];
|
||||
TTGlyphID newGlyph = lookup(offset, thisGlyph, success);
|
||||
glyphStorage[currGlyph] = LE_SET_GLYPH(thisGlyph, newGlyph);
|
||||
}
|
||||
|
||||
if (flags & cgsSetMark) {
|
||||
markGlyph = currGlyph;
|
||||
}
|
||||
|
||||
if (!(flags & cgsDontAdvance)) {
|
||||
currGlyph += dir;
|
||||
}
|
||||
|
||||
return newState;
|
||||
}
|
||||
|
||||
TTGlyphID ContextualGlyphSubstitutionProcessor2::lookup(le_uint32 offset, LEGlyphID gid, LEErrorCode &success)
|
||||
{
|
||||
TTGlyphID newGlyph = 0xFFFF;
|
||||
if(LE_FAILURE(success)) return newGlyph;
|
||||
LEReferenceTo<LookupTableBase> lookupTable(perGlyphTable, success, offset);
|
||||
if(LE_FAILURE(success)) return newGlyph;
|
||||
le_int16 format = SWAPW(lookupTable->format);
|
||||
|
||||
switch (format) {
|
||||
case ltfSimpleArray: {
|
||||
#ifdef TEST_FORMAT
|
||||
// Disabled pending for design review
|
||||
LEReferenceTo<SimpleArrayLookupTable> lookupTable0(lookupTable, success);
|
||||
LEReferenceToArrayOf<LookupValue> valueArray(lookupTable0, success, &lookupTable0->valueArray[0], LE_UNBOUNDED_ARRAY);
|
||||
if(LE_FAILURE(success)) return newGlyph;
|
||||
TTGlyphID glyphCode = (TTGlyphID) LE_GET_GLYPH(gid);
|
||||
newGlyph = SWAPW(lookupTable0->valueArray(glyphCode, success));
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case ltfSegmentSingle: {
|
||||
#ifdef TEST_FORMAT
|
||||
// Disabled pending for design review
|
||||
LEReferenceTo<SegmentSingleLookupTable> lookupTable2 = (SegmentSingleLookupTable *) lookupTable;
|
||||
const LookupSegment *segment = lookupTable2->lookupSegment(lookupTable2->segments, gid);
|
||||
if (segment != NULL) {
|
||||
newGlyph = SWAPW(segment->value);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case ltfSegmentArray: {
|
||||
//printf("Context Lookup Table Format4: specific interpretation needed!\n");
|
||||
break;
|
||||
}
|
||||
case ltfSingleTable:
|
||||
{
|
||||
#ifdef TEST_FORMAT
|
||||
// Disabled pending for design review
|
||||
LEReferenceTo<SingleTableLookupTable> lookupTable6 = (SingleTableLookupTable *) lookupTable;
|
||||
const LEReferenceTo<LookupSingle> segment = lookupTable6->lookupSingle(lookupTable6->entries, gid);
|
||||
if (segment != NULL) {
|
||||
newGlyph = SWAPW(segment->value);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case ltfTrimmedArray: {
|
||||
LEReferenceTo<TrimmedArrayLookupTable> lookupTable8(lookupTable, success);
|
||||
if (LE_FAILURE(success)) return newGlyph;
|
||||
TTGlyphID firstGlyph = SWAPW(lookupTable8->firstGlyph);
|
||||
TTGlyphID glyphCount = SWAPW(lookupTable8->glyphCount);
|
||||
TTGlyphID lastGlyph = firstGlyph + glyphCount;
|
||||
TTGlyphID glyphCode = (TTGlyphID) LE_GET_GLYPH(gid);
|
||||
if ((glyphCode >= firstGlyph) && (glyphCode < lastGlyph)) {
|
||||
LEReferenceToArrayOf<LookupValue> valueArray(lookupTable8, success, &lookupTable8->valueArray[0], glyphCount);
|
||||
newGlyph = SWAPW(valueArray(glyphCode - firstGlyph, success));
|
||||
}
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return newGlyph;
|
||||
}
|
||||
|
||||
void ContextualGlyphSubstitutionProcessor2::endStateTable()
|
||||
{
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
|
@ -1,69 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. and others 1998-2014 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __CONTEXTUALGLYPHSUBSTITUTIONPROCESSOR2_H
|
||||
#define __CONTEXTUALGLYPHSUBSTITUTIONPROCESSOR2_H
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \internal
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "MorphTables.h"
|
||||
#include "SubtableProcessor2.h"
|
||||
#include "StateTableProcessor2.h"
|
||||
#include "ContextualGlyphSubstitution.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class LEGlyphStorage;
|
||||
|
||||
class ContextualGlyphSubstitutionProcessor2 : public StateTableProcessor2
|
||||
{
|
||||
public:
|
||||
virtual void beginStateTable();
|
||||
|
||||
virtual le_uint16 processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex2 index, LEErrorCode &success);
|
||||
|
||||
virtual void endStateTable();
|
||||
|
||||
ContextualGlyphSubstitutionProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success);
|
||||
virtual ~ContextualGlyphSubstitutionProcessor2();
|
||||
|
||||
/**
|
||||
* ICU "poor man's RTTI", returns a UClassID for the actual class.
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
virtual UClassID getDynamicClassID() const;
|
||||
|
||||
/**
|
||||
* ICU "poor man's RTTI", returns a UClassID for this class.
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
static UClassID getStaticClassID();
|
||||
|
||||
private:
|
||||
ContextualGlyphSubstitutionProcessor2();
|
||||
TTGlyphID lookup(le_uint32 offset, LEGlyphID gid, LEErrorCode &success);
|
||||
|
||||
protected:
|
||||
LEReferenceToArrayOf<le_uint32> perGlyphTable;
|
||||
LEReferenceToArrayOf<ContextualGlyphStateEntry2> entryTable;
|
||||
|
||||
le_int16 perGlyphTableFormat;
|
||||
le_int32 markGlyph;
|
||||
|
||||
LEReferenceTo<ContextualGlyphHeader2> contextualGlyphHeader;
|
||||
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
|
@ -1,55 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. and others 1998-2016 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __CONTEXTUALGLYPHSUBSTITUTION_H
|
||||
#define __CONTEXTUALGLYPHSUBSTITUTION_H
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \internal
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "LayoutTables.h"
|
||||
#include "MorphStateTables.h"
|
||||
#include "MorphTables.h"
|
||||
#include "StateTables.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
struct ContextualGlyphSubstitutionHeader : MorphStateTableHeader
|
||||
{
|
||||
ByteOffset substitutionTableOffset;
|
||||
};
|
||||
|
||||
struct ContextualGlyphHeader2 : MorphStateTableHeader2
|
||||
{
|
||||
le_uint32 perGlyphTableOffset; // no more substitution tables
|
||||
};
|
||||
|
||||
enum ContextualGlyphSubstitutionFlags
|
||||
{
|
||||
cgsSetMark = 0x8000,
|
||||
cgsDontAdvance = 0x4000,
|
||||
cgsReserved = 0x3FFF
|
||||
};
|
||||
|
||||
struct ContextualGlyphSubstitutionStateEntry : StateEntry
|
||||
{
|
||||
WordOffset markOffset;
|
||||
WordOffset currOffset;
|
||||
};
|
||||
|
||||
struct ContextualGlyphStateEntry2 : StateEntry2
|
||||
{
|
||||
le_uint16 markIndex;
|
||||
le_uint16 currIndex;
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
|
@ -1,577 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
* (C) Copyright IBM Corp. 1998-2015 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "LEFontInstance.h"
|
||||
#include "OpenTypeTables.h"
|
||||
#include "GlyphSubstitutionTables.h"
|
||||
#include "ContextualSubstSubtables.h"
|
||||
#include "GlyphIterator.h"
|
||||
#include "LookupProcessor.h"
|
||||
#include "CoverageTables.h"
|
||||
#include "LESwaps.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
/*
|
||||
NOTE: This could be optimized somewhat by keeping track
|
||||
of the previous sequenceIndex in the loop and doing next()
|
||||
or prev() of the delta between that and the current
|
||||
sequenceIndex instead of always resetting to the front.
|
||||
*/
|
||||
void ContextualSubstitutionBase::applySubstitutionLookups(
|
||||
const LookupProcessor *lookupProcessor,
|
||||
const SubstitutionLookupRecord *substLookupRecordArray,
|
||||
le_uint16 substCount,
|
||||
GlyphIterator *glyphIterator,
|
||||
const LEFontInstance *fontInstance,
|
||||
le_int32 position,
|
||||
LEErrorCode& success)
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return;
|
||||
}
|
||||
|
||||
GlyphIterator tempIterator(*glyphIterator);
|
||||
|
||||
for (le_int16 subst = 0; subst < substCount && LE_SUCCESS(success); subst += 1) {
|
||||
le_uint16 sequenceIndex = SWAPW(substLookupRecordArray[subst].sequenceIndex);
|
||||
le_uint16 lookupListIndex = SWAPW(substLookupRecordArray[subst].lookupListIndex);
|
||||
|
||||
tempIterator.setCurrStreamPosition(position);
|
||||
tempIterator.next(sequenceIndex);
|
||||
|
||||
lookupProcessor->applySingleLookup(lookupListIndex, &tempIterator, fontInstance, success);
|
||||
}
|
||||
}
|
||||
|
||||
le_bool ContextualSubstitutionBase::matchGlyphIDs(const TTGlyphID *glyphArray, le_uint16 glyphCount,
|
||||
GlyphIterator *glyphIterator, le_bool backtrack)
|
||||
{
|
||||
le_int32 direction = 1;
|
||||
le_int32 match = 0;
|
||||
|
||||
if (backtrack) {
|
||||
match = glyphCount -1;
|
||||
direction = -1;
|
||||
}
|
||||
|
||||
while (glyphCount > 0) {
|
||||
if (! glyphIterator->next()) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
TTGlyphID glyph = (TTGlyphID) glyphIterator->getCurrGlyphID();
|
||||
|
||||
if (glyph != SWAPW(glyphArray[match])) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
glyphCount -= 1;
|
||||
match += direction;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
le_bool ContextualSubstitutionBase::matchGlyphClasses(const le_uint16 *classArray, le_uint16 glyphCount,
|
||||
GlyphIterator *glyphIterator,
|
||||
const ClassDefinitionTable *classDefinitionTable,
|
||||
le_bool backtrack)
|
||||
{
|
||||
le_int32 direction = 1;
|
||||
le_int32 match = 0;
|
||||
|
||||
if (backtrack) {
|
||||
match = glyphCount - 1;
|
||||
direction = -1;
|
||||
}
|
||||
|
||||
while (glyphCount > 0) {
|
||||
if (! glyphIterator->next()) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
LEGlyphID glyph = glyphIterator->getCurrGlyphID();
|
||||
le_int32 glyphClass = classDefinitionTable->getGlyphClass(glyph);
|
||||
le_int32 matchClass = SWAPW(classArray[match]);
|
||||
|
||||
if (glyphClass != matchClass) {
|
||||
// Some fonts, e.g. Traditional Arabic, have classes
|
||||
// in the class array which aren't in the class definition
|
||||
// table. If we're looking for such a class, pretend that
|
||||
// we found it.
|
||||
if (classDefinitionTable->hasGlyphClass(matchClass)) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
glyphCount -= 1;
|
||||
match += direction;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
le_bool ContextualSubstitutionBase::matchGlyphCoverages(const Offset *coverageTableOffsetArray, le_uint16 glyphCount,
|
||||
GlyphIterator *glyphIterator, const char *offsetBase, le_bool backtrack)
|
||||
{
|
||||
le_int32 direction = 1;
|
||||
le_int32 glyph = 0;
|
||||
|
||||
if (backtrack) {
|
||||
glyph = glyphCount - 1;
|
||||
direction = -1;
|
||||
}
|
||||
|
||||
while (glyphCount > 0) {
|
||||
Offset coverageTableOffset = SWAPW(coverageTableOffsetArray[glyph]);
|
||||
const CoverageTable *coverageTable = (const CoverageTable *) (offsetBase + coverageTableOffset);
|
||||
|
||||
if (! glyphIterator->next()) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (coverageTable->getGlyphCoverage((LEGlyphID) glyphIterator->getCurrGlyphID()) < 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
glyphCount -= 1;
|
||||
glyph += direction;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
le_uint32 ContextualSubstitutionSubtable::process(const LookupProcessor *lookupProcessor,
|
||||
GlyphIterator *glyphIterator,
|
||||
const LEFontInstance *fontInstance,
|
||||
LEErrorCode& success) const
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch(SWAPW(subtableFormat))
|
||||
{
|
||||
case 0:
|
||||
return 0;
|
||||
|
||||
case 1:
|
||||
{
|
||||
const ContextualSubstitutionFormat1Subtable *subtable = (const ContextualSubstitutionFormat1Subtable *) this;
|
||||
return subtable->process(lookupProcessor, glyphIterator, fontInstance, success);
|
||||
}
|
||||
|
||||
case 2:
|
||||
{
|
||||
const ContextualSubstitutionFormat2Subtable *subtable = (const ContextualSubstitutionFormat2Subtable *) this;
|
||||
return subtable->process(lookupProcessor, glyphIterator, fontInstance, success);
|
||||
}
|
||||
|
||||
case 3:
|
||||
{
|
||||
const ContextualSubstitutionFormat3Subtable *subtable = (const ContextualSubstitutionFormat3Subtable *) this;
|
||||
return subtable->process(lookupProcessor, glyphIterator, fontInstance, success);
|
||||
}
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
le_uint32 ContextualSubstitutionFormat1Subtable::process(const LookupProcessor *lookupProcessor,
|
||||
GlyphIterator *glyphIterator,
|
||||
const LEFontInstance *fontInstance,
|
||||
LEErrorCode& success) const
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
LEGlyphID glyph = glyphIterator->getCurrGlyphID();
|
||||
le_int32 coverageIndex = getGlyphCoverage(lookupProcessor->getReference(), glyph, success);
|
||||
|
||||
if (coverageIndex >= 0) {
|
||||
le_uint16 srSetCount = SWAPW(subRuleSetCount);
|
||||
|
||||
if (coverageIndex < srSetCount) {
|
||||
Offset subRuleSetTableOffset = SWAPW(subRuleSetTableOffsetArray[coverageIndex]);
|
||||
const SubRuleSetTable *subRuleSetTable =
|
||||
(const SubRuleSetTable *) ((char *) this + subRuleSetTableOffset);
|
||||
le_uint16 subRuleCount = SWAPW(subRuleSetTable->subRuleCount);
|
||||
le_int32 position = glyphIterator->getCurrStreamPosition();
|
||||
|
||||
for (le_uint16 subRule = 0; subRule < subRuleCount; subRule += 1) {
|
||||
Offset subRuleTableOffset =
|
||||
SWAPW(subRuleSetTable->subRuleTableOffsetArray[subRule]);
|
||||
const SubRuleTable *subRuleTable =
|
||||
(const SubRuleTable *) ((char *) subRuleSetTable + subRuleTableOffset);
|
||||
le_uint16 matchCount = SWAPW(subRuleTable->glyphCount) - 1;
|
||||
le_uint16 substCount = SWAPW(subRuleTable->substCount);
|
||||
|
||||
if (matchGlyphIDs(subRuleTable->inputGlyphArray, matchCount, glyphIterator)) {
|
||||
const SubstitutionLookupRecord *substLookupRecordArray =
|
||||
(const SubstitutionLookupRecord *) &subRuleTable->inputGlyphArray[matchCount];
|
||||
|
||||
applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position, success);
|
||||
|
||||
return matchCount + 1;
|
||||
}
|
||||
|
||||
glyphIterator->setCurrStreamPosition(position);
|
||||
}
|
||||
}
|
||||
|
||||
// XXX If we get here, the table is mal-formed...
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
le_uint32 ContextualSubstitutionFormat2Subtable::process(const LookupProcessor *lookupProcessor,
|
||||
GlyphIterator *glyphIterator,
|
||||
const LEFontInstance *fontInstance,
|
||||
LEErrorCode& success) const
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
LEGlyphID glyph = glyphIterator->getCurrGlyphID();
|
||||
le_int32 coverageIndex = getGlyphCoverage(lookupProcessor->getReference(), glyph, success);
|
||||
|
||||
if (coverageIndex >= 0) {
|
||||
const ClassDefinitionTable *classDefinitionTable =
|
||||
(const ClassDefinitionTable *) ((char *) this + SWAPW(classDefTableOffset));
|
||||
le_uint16 scSetCount = SWAPW(subClassSetCount);
|
||||
le_int32 setClass = classDefinitionTable->getGlyphClass(glyphIterator->getCurrGlyphID());
|
||||
|
||||
if (setClass < scSetCount && subClassSetTableOffsetArray[setClass] != 0) {
|
||||
Offset subClassSetTableOffset = SWAPW(subClassSetTableOffsetArray[setClass]);
|
||||
const SubClassSetTable *subClassSetTable =
|
||||
(const SubClassSetTable *) ((char *) this + subClassSetTableOffset);
|
||||
le_uint16 subClassRuleCount = SWAPW(subClassSetTable->subClassRuleCount);
|
||||
le_int32 position = glyphIterator->getCurrStreamPosition();
|
||||
|
||||
for (le_uint16 scRule = 0; scRule < subClassRuleCount; scRule += 1) {
|
||||
Offset subClassRuleTableOffset =
|
||||
SWAPW(subClassSetTable->subClassRuleTableOffsetArray[scRule]);
|
||||
const SubClassRuleTable *subClassRuleTable =
|
||||
(const SubClassRuleTable *) ((char *) subClassSetTable + subClassRuleTableOffset);
|
||||
le_uint16 matchCount = SWAPW(subClassRuleTable->glyphCount) - 1;
|
||||
le_uint16 substCount = SWAPW(subClassRuleTable->substCount);
|
||||
|
||||
if (matchGlyphClasses(subClassRuleTable->classArray, matchCount, glyphIterator, classDefinitionTable)) {
|
||||
const SubstitutionLookupRecord *substLookupRecordArray =
|
||||
(const SubstitutionLookupRecord *) &subClassRuleTable->classArray[matchCount];
|
||||
|
||||
applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position, success);
|
||||
|
||||
return matchCount + 1;
|
||||
}
|
||||
|
||||
glyphIterator->setCurrStreamPosition(position);
|
||||
}
|
||||
}
|
||||
|
||||
// XXX If we get here, the table is mal-formed...
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
le_uint32 ContextualSubstitutionFormat3Subtable::process(const LookupProcessor *lookupProcessor,
|
||||
GlyphIterator *glyphIterator,
|
||||
const LEFontInstance *fontInstance,
|
||||
LEErrorCode& success)const
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
le_uint16 gCount = SWAPW(glyphCount);
|
||||
le_uint16 subCount = SWAPW(substCount);
|
||||
le_int32 position = glyphIterator->getCurrStreamPosition();
|
||||
|
||||
// Back up the glyph iterator so that we
|
||||
// can call next() before the check, which
|
||||
// will leave it pointing at the last glyph
|
||||
// that matched when we're done.
|
||||
glyphIterator->prev();
|
||||
|
||||
if (ContextualSubstitutionBase::matchGlyphCoverages(coverageTableOffsetArray, gCount, glyphIterator, (const char *) this)) {
|
||||
const SubstitutionLookupRecord *substLookupRecordArray =
|
||||
(const SubstitutionLookupRecord *) &coverageTableOffsetArray[gCount];
|
||||
|
||||
ContextualSubstitutionBase::applySubstitutionLookups(lookupProcessor, substLookupRecordArray, subCount, glyphIterator, fontInstance, position, success);
|
||||
|
||||
return gCount + 1;
|
||||
}
|
||||
|
||||
glyphIterator->setCurrStreamPosition(position);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
le_uint32 ChainingContextualSubstitutionSubtable::process(const LookupProcessor *lookupProcessor,
|
||||
GlyphIterator *glyphIterator,
|
||||
const LEFontInstance *fontInstance,
|
||||
LEErrorCode& success) const
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch(SWAPW(subtableFormat))
|
||||
{
|
||||
case 0:
|
||||
return 0;
|
||||
|
||||
case 1:
|
||||
{
|
||||
const ChainingContextualSubstitutionFormat1Subtable *subtable = (const ChainingContextualSubstitutionFormat1Subtable *) this;
|
||||
return subtable->process(lookupProcessor, glyphIterator, fontInstance, success);
|
||||
}
|
||||
|
||||
case 2:
|
||||
{
|
||||
const ChainingContextualSubstitutionFormat2Subtable *subtable = (const ChainingContextualSubstitutionFormat2Subtable *) this;
|
||||
return subtable->process(lookupProcessor, glyphIterator, fontInstance, success);
|
||||
}
|
||||
|
||||
case 3:
|
||||
{
|
||||
const ChainingContextualSubstitutionFormat3Subtable *subtable = (const ChainingContextualSubstitutionFormat3Subtable *) this;
|
||||
return subtable->process(lookupProcessor, glyphIterator, fontInstance, success);
|
||||
}
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: This could be a #define, but that seems to confuse
|
||||
// the Visual Studio .NET 2003 compiler on the calls to the
|
||||
// GlyphIterator constructor. It somehow can't decide if
|
||||
// emptyFeatureList matches an le_uint32 or an le_uint16...
|
||||
static const FeatureMask emptyFeatureList = 0x00000000UL;
|
||||
|
||||
le_uint32 ChainingContextualSubstitutionFormat1Subtable::process(const LookupProcessor *lookupProcessor,
|
||||
GlyphIterator *glyphIterator,
|
||||
const LEFontInstance *fontInstance,
|
||||
LEErrorCode& success) const
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
LEGlyphID glyph = glyphIterator->getCurrGlyphID();
|
||||
le_int32 coverageIndex = getGlyphCoverage(lookupProcessor->getReference(), glyph, success);
|
||||
|
||||
if (coverageIndex >= 0) {
|
||||
le_uint16 srSetCount = SWAPW(chainSubRuleSetCount);
|
||||
|
||||
if (coverageIndex < srSetCount) {
|
||||
Offset chainSubRuleSetTableOffset = SWAPW(chainSubRuleSetTableOffsetArray[coverageIndex]);
|
||||
const ChainSubRuleSetTable *chainSubRuleSetTable =
|
||||
(const ChainSubRuleSetTable *) ((char *) this + chainSubRuleSetTableOffset);
|
||||
le_uint16 chainSubRuleCount = SWAPW(chainSubRuleSetTable->chainSubRuleCount);
|
||||
le_int32 position = glyphIterator->getCurrStreamPosition();
|
||||
GlyphIterator tempIterator(*glyphIterator, emptyFeatureList);
|
||||
|
||||
for (le_uint16 subRule = 0; subRule < chainSubRuleCount; subRule += 1) {
|
||||
Offset chainSubRuleTableOffset =
|
||||
SWAPW(chainSubRuleSetTable->chainSubRuleTableOffsetArray[subRule]);
|
||||
const ChainSubRuleTable *chainSubRuleTable =
|
||||
(const ChainSubRuleTable *) ((char *) chainSubRuleSetTable + chainSubRuleTableOffset);
|
||||
le_uint16 backtrackGlyphCount = SWAPW(chainSubRuleTable->backtrackGlyphCount);
|
||||
le_uint16 inputGlyphCount = (le_uint16) SWAPW(chainSubRuleTable->backtrackGlyphArray[backtrackGlyphCount]) - 1;
|
||||
const TTGlyphID *inputGlyphArray = &chainSubRuleTable->backtrackGlyphArray[backtrackGlyphCount + 1];
|
||||
le_uint16 lookaheadGlyphCount = (le_uint16) SWAPW(inputGlyphArray[inputGlyphCount]);
|
||||
const TTGlyphID *lookaheadGlyphArray = &inputGlyphArray[inputGlyphCount + 1];
|
||||
le_uint16 substCount = (le_uint16) SWAPW(lookaheadGlyphArray[lookaheadGlyphCount]);
|
||||
|
||||
tempIterator.setCurrStreamPosition(position);
|
||||
|
||||
if (! tempIterator.prev(backtrackGlyphCount)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
tempIterator.prev();
|
||||
if (! matchGlyphIDs(chainSubRuleTable->backtrackGlyphArray, backtrackGlyphCount, &tempIterator, TRUE)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
tempIterator.setCurrStreamPosition(position);
|
||||
tempIterator.next(inputGlyphCount);
|
||||
if (!matchGlyphIDs(lookaheadGlyphArray, lookaheadGlyphCount, &tempIterator)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (matchGlyphIDs(inputGlyphArray, inputGlyphCount, glyphIterator)) {
|
||||
const SubstitutionLookupRecord *substLookupRecordArray =
|
||||
(const SubstitutionLookupRecord *) &lookaheadGlyphArray[lookaheadGlyphCount + 1];
|
||||
|
||||
applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position, success);
|
||||
|
||||
return inputGlyphCount + 1;
|
||||
}
|
||||
|
||||
glyphIterator->setCurrStreamPosition(position);
|
||||
}
|
||||
}
|
||||
|
||||
// XXX If we get here, the table is mal-formed...
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
le_uint32 ChainingContextualSubstitutionFormat2Subtable::process(const LookupProcessor *lookupProcessor,
|
||||
GlyphIterator *glyphIterator,
|
||||
const LEFontInstance *fontInstance,
|
||||
LEErrorCode& success) const
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
LEGlyphID glyph = glyphIterator->getCurrGlyphID();
|
||||
le_int32 coverageIndex = getGlyphCoverage(lookupProcessor->getReference(), glyph, success);
|
||||
|
||||
if (coverageIndex >= 0) {
|
||||
const ClassDefinitionTable *backtrackClassDefinitionTable =
|
||||
(const ClassDefinitionTable *) ((char *) this + SWAPW(backtrackClassDefTableOffset));
|
||||
const ClassDefinitionTable *inputClassDefinitionTable =
|
||||
(const ClassDefinitionTable *) ((char *) this + SWAPW(inputClassDefTableOffset));
|
||||
const ClassDefinitionTable *lookaheadClassDefinitionTable =
|
||||
(const ClassDefinitionTable *) ((char *) this + SWAPW(lookaheadClassDefTableOffset));
|
||||
le_uint16 scSetCount = SWAPW(chainSubClassSetCount);
|
||||
le_int32 setClass = inputClassDefinitionTable->getGlyphClass(glyphIterator->getCurrGlyphID());
|
||||
|
||||
if (setClass < scSetCount && chainSubClassSetTableOffsetArray[setClass] != 0) {
|
||||
Offset chainSubClassSetTableOffset = SWAPW(chainSubClassSetTableOffsetArray[setClass]);
|
||||
const ChainSubClassSetTable *chainSubClassSetTable =
|
||||
(const ChainSubClassSetTable *) ((char *) this + chainSubClassSetTableOffset);
|
||||
le_uint16 chainSubClassRuleCount = SWAPW(chainSubClassSetTable->chainSubClassRuleCount);
|
||||
le_int32 position = glyphIterator->getCurrStreamPosition();
|
||||
GlyphIterator tempIterator(*glyphIterator, emptyFeatureList);
|
||||
|
||||
for (le_uint16 scRule = 0; scRule < chainSubClassRuleCount; scRule += 1) {
|
||||
Offset chainSubClassRuleTableOffset =
|
||||
SWAPW(chainSubClassSetTable->chainSubClassRuleTableOffsetArray[scRule]);
|
||||
const ChainSubClassRuleTable *chainSubClassRuleTable =
|
||||
(const ChainSubClassRuleTable *) ((char *) chainSubClassSetTable + chainSubClassRuleTableOffset);
|
||||
le_uint16 backtrackGlyphCount = SWAPW(chainSubClassRuleTable->backtrackGlyphCount);
|
||||
|
||||
// TODO: Ticket #11557 - enable this check, originally from ticket #11525.
|
||||
// Depends on other, more extensive, changes.
|
||||
// LEReferenceToArrayOf<le_uint16> backtrackClassArray(base, success, chainSubClassRuleTable->backtrackClassArray, backtrackGlyphCount);
|
||||
if( LE_FAILURE(success) ) { return 0; }
|
||||
|
||||
le_uint16 inputGlyphCount = SWAPW(chainSubClassRuleTable->backtrackClassArray[backtrackGlyphCount]) - 1;
|
||||
const le_uint16 *inputClassArray = &chainSubClassRuleTable->backtrackClassArray[backtrackGlyphCount + 1];
|
||||
le_uint16 lookaheadGlyphCount = SWAPW(inputClassArray[inputGlyphCount]);
|
||||
const le_uint16 *lookaheadClassArray = &inputClassArray[inputGlyphCount + 1];
|
||||
le_uint16 substCount = SWAPW(lookaheadClassArray[lookaheadGlyphCount]);
|
||||
|
||||
|
||||
tempIterator.setCurrStreamPosition(position);
|
||||
|
||||
if (! tempIterator.prev(backtrackGlyphCount)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
tempIterator.prev();
|
||||
if (! matchGlyphClasses(chainSubClassRuleTable->backtrackClassArray, backtrackGlyphCount,
|
||||
&tempIterator, backtrackClassDefinitionTable, TRUE)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
tempIterator.setCurrStreamPosition(position);
|
||||
tempIterator.next(inputGlyphCount);
|
||||
if (! matchGlyphClasses(lookaheadClassArray, lookaheadGlyphCount, &tempIterator, lookaheadClassDefinitionTable)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (matchGlyphClasses(inputClassArray, inputGlyphCount, glyphIterator, inputClassDefinitionTable)) {
|
||||
const SubstitutionLookupRecord *substLookupRecordArray =
|
||||
(const SubstitutionLookupRecord *) &lookaheadClassArray[lookaheadGlyphCount + 1];
|
||||
|
||||
applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position, success);
|
||||
|
||||
return inputGlyphCount + 1;
|
||||
}
|
||||
|
||||
glyphIterator->setCurrStreamPosition(position);
|
||||
}
|
||||
}
|
||||
|
||||
// XXX If we get here, the table is mal-formed...
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
le_uint32 ChainingContextualSubstitutionFormat3Subtable::process(const LookupProcessor *lookupProcessor,
|
||||
GlyphIterator *glyphIterator,
|
||||
const LEFontInstance *fontInstance,
|
||||
LEErrorCode & success) const
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
le_uint16 backtrkGlyphCount = SWAPW(backtrackGlyphCount);
|
||||
le_uint16 inputGlyphCount = (le_uint16) SWAPW(backtrackCoverageTableOffsetArray[backtrkGlyphCount]);
|
||||
const Offset *inputCoverageTableOffsetArray = &backtrackCoverageTableOffsetArray[backtrkGlyphCount + 1];
|
||||
const le_uint16 lookaheadGlyphCount = (le_uint16) SWAPW(inputCoverageTableOffsetArray[inputGlyphCount]);
|
||||
const Offset *lookaheadCoverageTableOffsetArray = &inputCoverageTableOffsetArray[inputGlyphCount + 1];
|
||||
le_uint16 substCount = (le_uint16) SWAPW(lookaheadCoverageTableOffsetArray[lookaheadGlyphCount]);
|
||||
le_int32 position = glyphIterator->getCurrStreamPosition();
|
||||
GlyphIterator tempIterator(*glyphIterator, emptyFeatureList);
|
||||
|
||||
if (! tempIterator.prev(backtrkGlyphCount)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
tempIterator.prev();
|
||||
if (! ContextualSubstitutionBase::matchGlyphCoverages(backtrackCoverageTableOffsetArray,
|
||||
backtrkGlyphCount, &tempIterator, (const char *) this, TRUE)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
tempIterator.setCurrStreamPosition(position);
|
||||
tempIterator.next(inputGlyphCount - 1);
|
||||
if (! ContextualSubstitutionBase::matchGlyphCoverages(lookaheadCoverageTableOffsetArray,
|
||||
lookaheadGlyphCount, &tempIterator, (const char *) this)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Back up the glyph iterator so that we
|
||||
// can call next() before the check, which
|
||||
// will leave it pointing at the last glyph
|
||||
// that matched when we're done.
|
||||
glyphIterator->prev();
|
||||
|
||||
if (ContextualSubstitutionBase::matchGlyphCoverages(inputCoverageTableOffsetArray,
|
||||
inputGlyphCount, glyphIterator, (const char *) this)) {
|
||||
const SubstitutionLookupRecord *substLookupRecordArray =
|
||||
(const SubstitutionLookupRecord *) &lookaheadCoverageTableOffsetArray[lookaheadGlyphCount + 1];
|
||||
|
||||
ContextualSubstitutionBase::applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position, success);
|
||||
|
||||
return inputGlyphCount;
|
||||
}
|
||||
|
||||
glyphIterator->setCurrStreamPosition(position);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
|
@ -1,229 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __CONTEXTUALSUBSTITUTIONSUBTABLES_H
|
||||
#define __CONTEXTUALSUBSTITUTIONSUBTABLES_H
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \internal
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "LEFontInstance.h"
|
||||
#include "OpenTypeTables.h"
|
||||
#include "GlyphSubstitutionTables.h"
|
||||
#include "GlyphIterator.h"
|
||||
#include "LookupProcessor.h"
|
||||
#include "LETableReference.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
struct SubstitutionLookupRecord
|
||||
{
|
||||
le_uint16 sequenceIndex;
|
||||
le_uint16 lookupListIndex;
|
||||
};
|
||||
|
||||
struct ContextualSubstitutionBase : GlyphSubstitutionSubtable
|
||||
{
|
||||
static le_bool matchGlyphIDs(
|
||||
const TTGlyphID *glyphArray, le_uint16 glyphCount, GlyphIterator *glyphIterator,
|
||||
le_bool backtrack = FALSE);
|
||||
|
||||
static le_bool matchGlyphClasses(
|
||||
const le_uint16 *classArray, le_uint16 glyphCount, GlyphIterator *glyphIterator,
|
||||
const ClassDefinitionTable *classDefinitionTable, le_bool backtrack = FALSE);
|
||||
|
||||
static le_bool matchGlyphCoverages(
|
||||
const Offset *coverageTableOffsetArray, le_uint16 glyphCount,
|
||||
GlyphIterator *glyphIterator, const char *offsetBase, le_bool backtrack = FALSE);
|
||||
|
||||
static void applySubstitutionLookups(
|
||||
const LookupProcessor *lookupProcessor,
|
||||
const SubstitutionLookupRecord *substLookupRecordArray,
|
||||
le_uint16 substCount,
|
||||
GlyphIterator *glyphIterator,
|
||||
const LEFontInstance *fontInstance,
|
||||
le_int32 position,
|
||||
LEErrorCode& success);
|
||||
};
|
||||
|
||||
struct ContextualSubstitutionSubtable : ContextualSubstitutionBase
|
||||
{
|
||||
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
|
||||
};
|
||||
|
||||
struct ContextualSubstitutionFormat1Subtable : ContextualSubstitutionSubtable
|
||||
{
|
||||
le_uint16 subRuleSetCount;
|
||||
Offset subRuleSetTableOffsetArray[ANY_NUMBER];
|
||||
|
||||
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
|
||||
};
|
||||
LE_VAR_ARRAY(ContextualSubstitutionFormat1Subtable, subRuleSetTableOffsetArray)
|
||||
|
||||
|
||||
struct SubRuleSetTable
|
||||
{
|
||||
le_uint16 subRuleCount;
|
||||
Offset subRuleTableOffsetArray[ANY_NUMBER];
|
||||
|
||||
};
|
||||
LE_VAR_ARRAY(SubRuleSetTable, subRuleTableOffsetArray)
|
||||
|
||||
// NOTE: Multiple variable size arrays!!
|
||||
struct SubRuleTable
|
||||
{
|
||||
le_uint16 glyphCount;
|
||||
le_uint16 substCount;
|
||||
TTGlyphID inputGlyphArray[ANY_NUMBER];
|
||||
//SubstitutionLookupRecord substLookupRecordArray[ANY_NUMBER];
|
||||
};
|
||||
LE_VAR_ARRAY(SubRuleTable, inputGlyphArray)
|
||||
|
||||
struct ContextualSubstitutionFormat2Subtable : ContextualSubstitutionSubtable
|
||||
{
|
||||
Offset classDefTableOffset;
|
||||
le_uint16 subClassSetCount;
|
||||
Offset subClassSetTableOffsetArray[ANY_NUMBER];
|
||||
|
||||
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
|
||||
};
|
||||
LE_VAR_ARRAY(ContextualSubstitutionFormat2Subtable, subClassSetTableOffsetArray)
|
||||
|
||||
|
||||
struct SubClassSetTable
|
||||
{
|
||||
le_uint16 subClassRuleCount;
|
||||
Offset subClassRuleTableOffsetArray[ANY_NUMBER];
|
||||
};
|
||||
LE_VAR_ARRAY(SubClassSetTable, subClassRuleTableOffsetArray)
|
||||
|
||||
|
||||
// NOTE: Multiple variable size arrays!!
|
||||
struct SubClassRuleTable
|
||||
{
|
||||
le_uint16 glyphCount;
|
||||
le_uint16 substCount;
|
||||
le_uint16 classArray[ANY_NUMBER];
|
||||
//SubstitutionLookupRecord substLookupRecordArray[ANY_NUMBER];
|
||||
};
|
||||
LE_VAR_ARRAY(SubClassRuleTable, classArray)
|
||||
|
||||
|
||||
// NOTE: This isn't a subclass of GlyphSubstitutionSubtable 'cause
|
||||
// it has an array of coverage tables instead of a single coverage table...
|
||||
//
|
||||
// NOTE: Multiple variable size arrays!!
|
||||
struct ContextualSubstitutionFormat3Subtable
|
||||
{
|
||||
le_uint16 substFormat;
|
||||
le_uint16 glyphCount;
|
||||
le_uint16 substCount;
|
||||
Offset coverageTableOffsetArray[ANY_NUMBER];
|
||||
//SubstitutionLookupRecord substLookupRecord[ANY_NUMBER];
|
||||
|
||||
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
|
||||
};
|
||||
LE_VAR_ARRAY(ContextualSubstitutionFormat3Subtable, coverageTableOffsetArray)
|
||||
|
||||
struct ChainingContextualSubstitutionSubtable : ContextualSubstitutionBase
|
||||
{
|
||||
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
|
||||
};
|
||||
|
||||
struct ChainingContextualSubstitutionFormat1Subtable : ChainingContextualSubstitutionSubtable
|
||||
{
|
||||
le_uint16 chainSubRuleSetCount;
|
||||
Offset chainSubRuleSetTableOffsetArray[ANY_NUMBER];
|
||||
|
||||
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
|
||||
};
|
||||
LE_VAR_ARRAY(ChainingContextualSubstitutionFormat1Subtable, chainSubRuleSetTableOffsetArray)
|
||||
|
||||
|
||||
struct ChainSubRuleSetTable
|
||||
{
|
||||
le_uint16 chainSubRuleCount;
|
||||
Offset chainSubRuleTableOffsetArray[ANY_NUMBER];
|
||||
|
||||
};
|
||||
LE_VAR_ARRAY(ChainSubRuleSetTable, chainSubRuleTableOffsetArray)
|
||||
|
||||
// NOTE: Multiple variable size arrays!!
|
||||
struct ChainSubRuleTable
|
||||
{
|
||||
le_uint16 backtrackGlyphCount;
|
||||
TTGlyphID backtrackGlyphArray[ANY_NUMBER];
|
||||
//le_uint16 inputGlyphCount;
|
||||
//TTGlyphID inputGlyphArray[ANY_NUMBER];
|
||||
//le_uint16 lookaheadGlyphCount;
|
||||
//TTGlyphID lookaheadGlyphArray[ANY_NUMBER];
|
||||
//le_uint16 substCount;
|
||||
//SubstitutionLookupRecord substLookupRecordArray[ANY_NUMBER];
|
||||
};
|
||||
LE_VAR_ARRAY(ChainSubRuleTable, backtrackGlyphArray)
|
||||
|
||||
struct ChainingContextualSubstitutionFormat2Subtable : ChainingContextualSubstitutionSubtable
|
||||
{
|
||||
Offset backtrackClassDefTableOffset;
|
||||
Offset inputClassDefTableOffset;
|
||||
Offset lookaheadClassDefTableOffset;
|
||||
le_uint16 chainSubClassSetCount;
|
||||
Offset chainSubClassSetTableOffsetArray[ANY_NUMBER];
|
||||
|
||||
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
|
||||
};
|
||||
LE_VAR_ARRAY(ChainingContextualSubstitutionFormat2Subtable, chainSubClassSetTableOffsetArray)
|
||||
|
||||
struct ChainSubClassSetTable
|
||||
{
|
||||
le_uint16 chainSubClassRuleCount;
|
||||
Offset chainSubClassRuleTableOffsetArray[ANY_NUMBER];
|
||||
};
|
||||
LE_VAR_ARRAY(ChainSubClassSetTable, chainSubClassRuleTableOffsetArray)
|
||||
|
||||
|
||||
// NOTE: Multiple variable size arrays!!
|
||||
struct ChainSubClassRuleTable
|
||||
{
|
||||
le_uint16 backtrackGlyphCount;
|
||||
le_uint16 backtrackClassArray[ANY_NUMBER];
|
||||
//le_uint16 inputGlyphCount;
|
||||
//le_uint16 inputClassArray[ANY_NUMBER];
|
||||
//le_uint16 lookaheadGlyphCount;
|
||||
//le_uint16 lookaheadClassArray[ANY_NUMBER];
|
||||
//le_uint16 substCount;
|
||||
//SubstitutionLookupRecord substLookupRecordArray[ANY_NUMBER];
|
||||
};
|
||||
LE_VAR_ARRAY(ChainSubClassRuleTable, backtrackClassArray)
|
||||
|
||||
// NOTE: This isn't a subclass of GlyphSubstitutionSubtable 'cause
|
||||
// it has arrays of coverage tables instead of a single coverage table...
|
||||
//
|
||||
// NOTE: Multiple variable size arrays!!
|
||||
struct ChainingContextualSubstitutionFormat3Subtable
|
||||
{
|
||||
le_uint16 substFormat;
|
||||
le_uint16 backtrackGlyphCount;
|
||||
Offset backtrackCoverageTableOffsetArray[ANY_NUMBER];
|
||||
//le_uint16 inputGlyphCount;
|
||||
//Offset inputCoverageTableOffsetArray[ANY_NUMBER];
|
||||
//le_uint16 lookaheadGlyphCount;
|
||||
//le_uint16 lookaheadCoverageTableOffsetArray[ANY_NUMBER];
|
||||
//le_uint16 substCount;
|
||||
//SubstitutionLookupRecord substLookupRecord[ANY_NUMBER];
|
||||
|
||||
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
|
||||
};
|
||||
LE_VAR_ARRAY(ChainingContextualSubstitutionFormat3Subtable, backtrackCoverageTableOffsetArray)
|
||||
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
|
@ -1,93 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2006 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "OpenTypeTables.h"
|
||||
#include "OpenTypeUtilities.h"
|
||||
#include "CoverageTables.h"
|
||||
#include "LESwaps.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
le_int32 CoverageTable::getGlyphCoverage(LEGlyphID glyphID) const
|
||||
{
|
||||
switch(SWAPW(coverageFormat))
|
||||
{
|
||||
case 0:
|
||||
return -1;
|
||||
|
||||
case 1:
|
||||
{
|
||||
const CoverageFormat1Table *f1Table = (const CoverageFormat1Table *) this;
|
||||
|
||||
return f1Table->getGlyphCoverage(glyphID);
|
||||
}
|
||||
|
||||
case 2:
|
||||
{
|
||||
const CoverageFormat2Table *f2Table = (const CoverageFormat2Table *) this;
|
||||
|
||||
return f2Table->getGlyphCoverage(glyphID);
|
||||
}
|
||||
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
le_int32 CoverageFormat1Table::getGlyphCoverage(LEGlyphID glyphID) const
|
||||
{
|
||||
TTGlyphID ttGlyphID = (TTGlyphID) LE_GET_GLYPH(glyphID);
|
||||
le_uint16 count = SWAPW(glyphCount);
|
||||
le_uint8 bit = OpenTypeUtilities::highBit(count);
|
||||
le_uint16 power = 1 << bit;
|
||||
le_uint16 extra = count - power;
|
||||
le_uint16 probe = power;
|
||||
le_uint16 index = 0;
|
||||
|
||||
if (count == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (SWAPW(glyphArray[extra]) <= ttGlyphID) {
|
||||
index = extra;
|
||||
}
|
||||
|
||||
while (probe > (1 << 0)) {
|
||||
probe >>= 1;
|
||||
|
||||
if (SWAPW(glyphArray[index + probe]) <= ttGlyphID) {
|
||||
index += probe;
|
||||
}
|
||||
}
|
||||
|
||||
if (SWAPW(glyphArray[index]) == ttGlyphID) {
|
||||
return index;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
le_int32 CoverageFormat2Table::getGlyphCoverage(LEGlyphID glyphID) const
|
||||
{
|
||||
TTGlyphID ttGlyphID = (TTGlyphID) LE_GET_GLYPH(glyphID);
|
||||
le_uint16 count = SWAPW(rangeCount);
|
||||
le_int32 rangeIndex =
|
||||
OpenTypeUtilities::getGlyphRangeIndex(ttGlyphID, rangeRecordArray, count);
|
||||
|
||||
if (rangeIndex < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
TTGlyphID firstInRange = SWAPW(rangeRecordArray[rangeIndex].firstGlyph);
|
||||
le_uint16 startCoverageIndex = SWAPW(rangeRecordArray[rangeIndex].rangeValue);
|
||||
|
||||
return startCoverageIndex + (ttGlyphID - firstInRange);
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
|
@ -1,49 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __COVERAGETABLES_H
|
||||
#define __COVERAGETABLES_H
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \internal
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "OpenTypeTables.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
struct CoverageTable
|
||||
{
|
||||
le_uint16 coverageFormat;
|
||||
|
||||
le_int32 getGlyphCoverage(LEGlyphID glyphID) const;
|
||||
};
|
||||
|
||||
struct CoverageFormat1Table : CoverageTable
|
||||
{
|
||||
le_uint16 glyphCount;
|
||||
TTGlyphID glyphArray[ANY_NUMBER];
|
||||
|
||||
le_int32 getGlyphCoverage(LEGlyphID glyphID) const;
|
||||
};
|
||||
LE_VAR_ARRAY(CoverageFormat1Table, glyphArray)
|
||||
|
||||
|
||||
struct CoverageFormat2Table : CoverageTable
|
||||
{
|
||||
le_uint16 rangeCount;
|
||||
GlyphRangeRecord rangeRecordArray[ANY_NUMBER];
|
||||
|
||||
le_int32 getGlyphCoverage(LEGlyphID glyphID) const;
|
||||
};
|
||||
LE_VAR_ARRAY(CoverageFormat2Table, rangeRecordArray)
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
|
@ -1,58 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
* (C) Copyright IBM Corp. 1998 - 2015 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "OpenTypeTables.h"
|
||||
#include "GlyphPositioningTables.h"
|
||||
#include "CursiveAttachmentSubtables.h"
|
||||
#include "AnchorTables.h"
|
||||
#include "GlyphIterator.h"
|
||||
#include "OpenTypeUtilities.h"
|
||||
#include "LESwaps.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
le_uint32 CursiveAttachmentSubtable::process(const LEReferenceTo<CursiveAttachmentSubtable> &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const
|
||||
{
|
||||
LEGlyphID glyphID = glyphIterator->getCurrGlyphID();
|
||||
le_int32 coverageIndex = getGlyphCoverage(base, glyphID, success);
|
||||
le_uint16 eeCount = SWAPW(entryExitCount);
|
||||
|
||||
LEReferenceToArrayOf<EntryExitRecord>
|
||||
entryExitRecordsArrayRef(base, success, entryExitRecords, coverageIndex);
|
||||
|
||||
if (coverageIndex < 0 || coverageIndex >= eeCount || LE_FAILURE(success)) {
|
||||
glyphIterator->setCursiveGlyph();
|
||||
return 0;
|
||||
}
|
||||
|
||||
LEPoint entryAnchor, exitAnchor;
|
||||
Offset entryOffset = SWAPW(entryExitRecords[coverageIndex].entryAnchor);
|
||||
Offset exitOffset = SWAPW(entryExitRecords[coverageIndex].exitAnchor);
|
||||
|
||||
if (entryOffset != 0) {
|
||||
const AnchorTable *entryAnchorTable = (const AnchorTable *) ((char *) this + entryOffset);
|
||||
|
||||
entryAnchorTable->getAnchor(glyphID, fontInstance, entryAnchor);
|
||||
glyphIterator->setCursiveEntryPoint(entryAnchor);
|
||||
} else {
|
||||
//glyphIterator->clearCursiveEntryPoint();
|
||||
}
|
||||
|
||||
if (exitOffset != 0) {
|
||||
const AnchorTable *exitAnchorTable = (const AnchorTable *) ((char *) this + exitOffset);
|
||||
|
||||
exitAnchorTable->getAnchor(glyphID, fontInstance, exitAnchor);
|
||||
glyphIterator->setCursiveExitPoint(exitAnchor);
|
||||
} else {
|
||||
//glyphIterator->clearCursiveExitPoint();
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
|
@ -1,44 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __CURSIVEATTACHMENTSUBTABLES_H
|
||||
#define __CURSIVEATTACHMENTSUBTABLES_H
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \internal
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "OpenTypeTables.h"
|
||||
#include "GlyphPositioningTables.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class LEFontInstance;
|
||||
class GlyphIterator;
|
||||
|
||||
struct EntryExitRecord
|
||||
{
|
||||
Offset entryAnchor;
|
||||
Offset exitAnchor;
|
||||
};
|
||||
|
||||
struct CursiveAttachmentSubtable : GlyphPositioningSubtable
|
||||
{
|
||||
le_uint16 entryExitCount;
|
||||
EntryExitRecord entryExitRecords[ANY_NUMBER];
|
||||
|
||||
le_uint32 process(const LEReferenceTo<CursiveAttachmentSubtable> &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const;
|
||||
};
|
||||
LE_VAR_ARRAY(CursiveAttachmentSubtable, entryExitRecords)
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
||||
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
* (C) Copyright IBM Corp. 1998-2007 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __DEFAULTCHARMAPPER_H
|
||||
#define __DEFAULTCHARMAPPER_H
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \internal
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "LEFontInstance.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
/**
|
||||
* This class is an instance of LECharMapper which
|
||||
* implements control character filtering and bidi
|
||||
* mirroring.
|
||||
*
|
||||
* @see LECharMapper
|
||||
*/
|
||||
class DefaultCharMapper : public UMemory, public LECharMapper
|
||||
{
|
||||
private:
|
||||
le_bool fFilterControls;
|
||||
le_bool fMirror;
|
||||
|
||||
static const LEUnicode32 controlChars[];
|
||||
|
||||
static const le_int32 controlCharsCount;
|
||||
|
||||
static const LEUnicode32 mirroredChars[];
|
||||
static const LEUnicode32 srahCderorrim[];
|
||||
|
||||
static const le_int32 mirroredCharsCount;
|
||||
|
||||
public:
|
||||
DefaultCharMapper(le_bool filterControls, le_bool mirror)
|
||||
: fFilterControls(filterControls), fMirror(mirror)
|
||||
{
|
||||
// nothing
|
||||
};
|
||||
|
||||
~DefaultCharMapper()
|
||||
{
|
||||
// nada
|
||||
};
|
||||
|
||||
LEUnicode32 mapChar(LEUnicode32 ch) const;
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
|
@ -1,48 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
* @(#)DeviceTables.cpp 1.5 00/03/15
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998 - 2006 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "OpenTypeTables.h"
|
||||
#include "DeviceTables.h"
|
||||
#include "LESwaps.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
const le_uint16 DeviceTable::fieldMasks[] = {0x0003, 0x000F, 0x00FF};
|
||||
const le_uint16 DeviceTable::fieldSignBits[] = {0x0002, 0x0008, 0x0080};
|
||||
const le_uint16 DeviceTable::fieldBits[] = { 2, 4, 8};
|
||||
|
||||
#define FORMAT_COUNT LE_ARRAY_SIZE(fieldBits)
|
||||
|
||||
le_int16 DeviceTable::getAdjustment(le_uint16 ppem) const
|
||||
{
|
||||
le_uint16 start = SWAPW(startSize);
|
||||
le_uint16 format = SWAPW(deltaFormat) - 1;
|
||||
le_int16 result = 0;
|
||||
|
||||
if (ppem >= start && ppem <= SWAPW(endSize) && format < FORMAT_COUNT) {
|
||||
le_uint16 sizeIndex = ppem - start;
|
||||
le_uint16 bits = fieldBits[format];
|
||||
le_uint16 count = 16 / bits;
|
||||
le_uint16 word = SWAPW(deltaValues[sizeIndex / count]);
|
||||
le_uint16 fieldIndex = sizeIndex % count;
|
||||
le_uint16 shift = 16 - (bits * (fieldIndex + 1));
|
||||
le_uint16 field = (word >> shift) & fieldMasks[format];
|
||||
|
||||
result = field;
|
||||
|
||||
if ((field & fieldSignBits[format]) != 0) {
|
||||
result |= ~ fieldMasks[format];
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
|
@ -1,42 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
* @(#)DeviceTables.h 1.5 00/03/15
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __DEVICETABLES_H
|
||||
#define __DEVICETABLES_H
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \internal
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "OpenTypeTables.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
struct DeviceTable
|
||||
{
|
||||
le_uint16 startSize;
|
||||
le_uint16 endSize;
|
||||
le_uint16 deltaFormat;
|
||||
le_uint16 deltaValues[ANY_NUMBER];
|
||||
|
||||
le_int16 getAdjustment(le_uint16 ppem) const;
|
||||
|
||||
private:
|
||||
static const le_uint16 fieldMasks[];
|
||||
static const le_uint16 fieldSignBits[];
|
||||
static const le_uint16 fieldBits[];
|
||||
};
|
||||
LE_VAR_ARRAY(DeviceTable, deltaValues)
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
||||
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
* %W% %E%
|
||||
*
|
||||
* (C) Copyright IBM Corp. 2008-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "OpenTypeTables.h"
|
||||
#include "GlyphSubstitutionTables.h"
|
||||
#include "LookupProcessor.h"
|
||||
#include "ExtensionSubtables.h"
|
||||
#include "GlyphIterator.h"
|
||||
#include "LESwaps.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
// read a 32-bit value that might only be 16-bit-aligned in memory
|
||||
static inline le_uint32 READ_LONG(le_uint32 code) {
|
||||
le_uint16* first = ((le_uint16*)&code);
|
||||
le_uint16* second = (((le_uint16*)&code) + 1);
|
||||
return (le_uint32)((SWAPW(*first) << 16) + SWAPW(*second));
|
||||
}
|
||||
|
||||
// FIXME: should look at the format too... maybe have a sub-class for it?
|
||||
le_uint32 ExtensionSubtable::process(const LookupProcessor *lookupProcessor, le_uint16 lookupType,
|
||||
GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const
|
||||
{
|
||||
const LEReferenceTo<ExtensionSubtable> thisRef(lookupProcessor->getReference(), success); // create a reference to this
|
||||
|
||||
if (LE_FAILURE(success)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
le_uint16 elt = SWAPW(extensionLookupType);
|
||||
|
||||
if (elt != lookupType) {
|
||||
le_uint32 extOffset = READ_LONG(extensionOffset);
|
||||
LEReferenceTo<LookupSubtable> subtable(thisRef, success, extOffset);
|
||||
|
||||
if(LE_SUCCESS(success)) {
|
||||
return lookupProcessor->applySubtable(subtable, elt, glyphIterator, fontInstance, success);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
|
@ -1,37 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
* %W% %E%
|
||||
*
|
||||
* (C) Copyright IBM Corp. 2002-2008 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __EXTENSIONSUBTABLES_H
|
||||
#define __EXTENSIONSUBTABLES_H
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \internal
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "OpenTypeTables.h"
|
||||
#include "GlyphSubstitutionTables.h"
|
||||
#include "LookupProcessor.h"
|
||||
#include "GlyphIterator.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
struct ExtensionSubtable //: GlyphSubstitutionSubtable
|
||||
{
|
||||
le_uint16 substFormat;
|
||||
le_uint16 extensionLookupType;
|
||||
le_uint32 extensionOffset;
|
||||
|
||||
le_uint32 process(const LookupProcessor *lookupProcessor, le_uint16 lookupType,
|
||||
GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
|
@ -1,68 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
* @(#)Features.cpp 1.4 00/03/15
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2015 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "OpenTypeUtilities.h"
|
||||
#include "OpenTypeTables.h"
|
||||
#include "ICUFeatures.h"
|
||||
#include "LESwaps.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
LEReferenceTo<FeatureTable> FeatureListTable::getFeatureTable(const LETableReference &base, le_uint16 featureIndex, LETag *featureTag, LEErrorCode &success) const
|
||||
{
|
||||
LEReferenceToArrayOf<FeatureRecord>
|
||||
featureRecordArrayRef(base, success, featureRecordArray, featureIndex+1);
|
||||
|
||||
if (featureIndex >= SWAPW(featureCount) || LE_FAILURE(success)) {
|
||||
return LEReferenceTo<FeatureTable>();
|
||||
}
|
||||
|
||||
Offset featureTableOffset = featureRecordArray[featureIndex].featureTableOffset;
|
||||
|
||||
*featureTag = SWAPT(featureRecordArray[featureIndex].featureTag);
|
||||
|
||||
return LEReferenceTo<FeatureTable>(base, success, SWAPW(featureTableOffset));
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* Note: according to the OpenType Spec. v 1.4, the entries in the Feature
|
||||
* List Table are sorted alphabetically by feature tag; however, there seem
|
||||
* to be some fonts which have an unsorted list; that's why the binary search
|
||||
* is #if 0'd out and replaced by a linear search.
|
||||
*
|
||||
* Also note: as of ICU 2.6, this method isn't called anyhow...
|
||||
*/
|
||||
const FeatureTable *FeatureListTable::getFeatureTable(LETag featureTag) const
|
||||
{
|
||||
#if 0
|
||||
Offset featureTableOffset =
|
||||
OpenTypeUtilities::getTagOffset(featureTag, (TagAndOffsetRecord *) featureRecordArray, SWAPW(featureCount));
|
||||
|
||||
if (featureTableOffset == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (const FeatureTable *) ((char *) this + SWAPW(featureTableOffset));
|
||||
#else
|
||||
int count = SWAPW(featureCount);
|
||||
|
||||
for (int i = 0; i < count; i += 1) {
|
||||
if (SWAPT(featureRecordArray[i].featureTag) == featureTag) {
|
||||
return (const FeatureTable *) ((char *) this + SWAPW(featureRecordArray[i].featureTableOffset));
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
U_NAMESPACE_END
|
|
@ -1,36 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998 - 2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "LEGlyphFilter.h"
|
||||
#include "GDEFMarkFilter.h"
|
||||
#include "GlyphDefinitionTables.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
GDEFMarkFilter::GDEFMarkFilter(const LEReferenceTo<GlyphDefinitionTableHeader> &gdefTable, LEErrorCode &success)
|
||||
: classDefTable(gdefTable->getGlyphClassDefinitionTable(gdefTable, success))
|
||||
{
|
||||
if(!classDefTable.isValid()) {
|
||||
success = LE_INTERNAL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
GDEFMarkFilter::~GDEFMarkFilter()
|
||||
{
|
||||
// nothing to do?
|
||||
}
|
||||
|
||||
le_bool GDEFMarkFilter::accept(LEGlyphID glyph) const
|
||||
{
|
||||
le_int32 glyphClass = classDefTable->getGlyphClass(glyph);
|
||||
|
||||
return glyphClass == gcdMarkGlyph;
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
|
@ -1,39 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __GDEFMARKFILTER__H
|
||||
#define __GDEFMARKFILTER__H
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \internal
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "LEGlyphFilter.h"
|
||||
#include "GlyphDefinitionTables.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class GDEFMarkFilter : public UMemory, public LEGlyphFilter
|
||||
{
|
||||
private:
|
||||
const LEReferenceTo<GlyphClassDefinitionTable> classDefTable;
|
||||
|
||||
GDEFMarkFilter(const GDEFMarkFilter &other); // forbid copying of this class
|
||||
GDEFMarkFilter &operator=(const GDEFMarkFilter &other); // forbid copying of this class
|
||||
|
||||
public:
|
||||
GDEFMarkFilter(const LEReferenceTo<GlyphDefinitionTableHeader> &gdefTable, LEErrorCode &success);
|
||||
virtual ~GDEFMarkFilter();
|
||||
|
||||
virtual le_bool accept(LEGlyphID glyph) const;
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
|
@ -1,72 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "LayoutEngine.h"
|
||||
#include "GXLayoutEngine.h"
|
||||
#include "LEGlyphStorage.h"
|
||||
|
||||
#include "MorphTables.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(GXLayoutEngine)
|
||||
|
||||
GXLayoutEngine::GXLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, const LEReferenceTo<MorphTableHeader> &morphTable, LEErrorCode &success)
|
||||
: LayoutEngine(fontInstance, scriptCode, languageCode, 0, success), fMorphTable(morphTable)
|
||||
{
|
||||
fMorphTable.orphan();
|
||||
// nothing else to do?
|
||||
}
|
||||
|
||||
GXLayoutEngine::~GXLayoutEngine()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
// apply 'mort' table
|
||||
le_int32 GXLayoutEngine::computeGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft, LEGlyphStorage &glyphStorage, LEErrorCode &success)
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (chars == NULL || offset < 0 || count < 0 || max < 0 || offset >= max || offset + count > max) {
|
||||
success = LE_ILLEGAL_ARGUMENT_ERROR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
mapCharsToGlyphs(chars, offset, count, FALSE, rightToLeft, glyphStorage, success);
|
||||
|
||||
if (LE_FAILURE(success)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
fMorphTable->process(fMorphTable, glyphStorage, success);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
// apply positional tables
|
||||
void GXLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool /*reverse*/,
|
||||
LEGlyphStorage &/*glyphStorage*/, LEErrorCode &success)
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (chars == NULL || offset < 0 || count < 0) {
|
||||
success = LE_ILLEGAL_ARGUMENT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
// FIXME: no positional processing yet...
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
|
@ -1,128 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2014 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __GXLAYOUTENGINE_H
|
||||
#define __GXLAYOUTENGINE_H
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "LayoutEngine.h"
|
||||
|
||||
#include "MorphTables.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class LEFontInstance;
|
||||
class LEGlyphStorage;
|
||||
|
||||
/**
|
||||
* This class implements layout for QuickDraw GX or Apple Advanced Typograyph (AAT)
|
||||
* fonts. A font is a GX or AAT font if it contains a 'mort' table. See Apple's
|
||||
* TrueType Reference Manual (http://fonts.apple.com/TTRefMan/index.html) for details.
|
||||
* Information about 'mort' tables is in the chapter titled "Font Files."
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class GXLayoutEngine : public LayoutEngine
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This is the main constructor. It constructs an instance of GXLayoutEngine for
|
||||
* a particular font, script and language. It takes the 'mort' table as a parameter since
|
||||
* LayoutEngine::layoutEngineFactory has to read the 'mort' table to know that it has a
|
||||
* GX font.
|
||||
*
|
||||
* Note: GX and AAT fonts don't contain any script and language specific tables, so
|
||||
* the script and language are ignored.
|
||||
*
|
||||
* @param fontInstance - the font
|
||||
* @param scriptCode - the script
|
||||
* @param langaugeCode - the language
|
||||
* @param morphTable - the 'mort' table
|
||||
* @param success - set to an error code if the operation fails
|
||||
*
|
||||
* @see LayoutEngine::layoutEngineFactory
|
||||
* @see ScriptAndLangaugeTags.h for script and language codes
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
GXLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, const LEReferenceTo<MorphTableHeader> &morphTable, LEErrorCode &success);
|
||||
|
||||
/**
|
||||
* The destructor, virtual for correct polymorphic invocation.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
virtual ~GXLayoutEngine();
|
||||
|
||||
/**
|
||||
* ICU "poor man's RTTI", returns a UClassID for the actual class.
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
virtual UClassID getDynamicClassID() const;
|
||||
|
||||
/**
|
||||
* ICU "poor man's RTTI", returns a UClassID for this class.
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
static UClassID getStaticClassID();
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* The address of the 'mort' table
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
LEReferenceTo<MorphTableHeader> fMorphTable;
|
||||
|
||||
/**
|
||||
* This method does GX layout using the font's 'mort' table. It converts the
|
||||
* input character codes to glyph indices using mapCharsToGlyphs, and then
|
||||
* applies the 'mort' table.
|
||||
*
|
||||
* Input parameters:
|
||||
* @param chars - the input character context
|
||||
* @param offset - the index of the first character to process
|
||||
* @param count - the number of characters to process
|
||||
* @param max - the number of characters in the input context
|
||||
* @param rightToLeft - <code>TRUE</code> if the text is in a right to left directional run
|
||||
* @param glyphStorage - the glyph storage object. The glyph and char index arrays will be set.
|
||||
*
|
||||
* Output parameters:
|
||||
* @param success - set to an error code if the operation fails
|
||||
*
|
||||
* @return the number of glyphs in the glyph index array
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
virtual le_int32 computeGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft,
|
||||
LEGlyphStorage &glyphStorage, LEErrorCode &success);
|
||||
|
||||
/**
|
||||
* This method adjusts the glyph positions using the font's
|
||||
* 'kern', 'trak', 'bsln', 'opbd' and 'just' tables.
|
||||
*
|
||||
* Input parameters:
|
||||
* @param glyphStorage - the object holding the glyph storage. The positions will be updated as needed.
|
||||
*
|
||||
* Output parameters:
|
||||
* @param success - set to an error code if the operation fails
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
virtual void adjustGlyphPositions(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse,
|
||||
LEGlyphStorage &glyphStorage, LEErrorCode &success);
|
||||
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
||||
|
|
@ -1,68 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "LayoutEngine.h"
|
||||
#include "GXLayoutEngine2.h"
|
||||
#include "LEGlyphStorage.h"
|
||||
#include "MorphTables.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(GXLayoutEngine2)
|
||||
|
||||
GXLayoutEngine2::GXLayoutEngine2(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, const LEReferenceTo<MorphTableHeader2> &morphTable, le_int32 typoFlags, LEErrorCode &success)
|
||||
: LayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success), fMorphTable(morphTable)
|
||||
{
|
||||
// nothing else to do?
|
||||
}
|
||||
|
||||
GXLayoutEngine2::~GXLayoutEngine2()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
// apply 'morx' table
|
||||
le_int32 GXLayoutEngine2::computeGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft, LEGlyphStorage &glyphStorage, LEErrorCode &success)
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (chars == NULL || offset < 0 || count < 0 || max < 0 || offset >= max || offset + count > max) {
|
||||
success = LE_ILLEGAL_ARGUMENT_ERROR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
mapCharsToGlyphs(chars, offset, count, rightToLeft, rightToLeft, glyphStorage, success);
|
||||
|
||||
if (LE_FAILURE(success)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
fMorphTable->process(fMorphTable, glyphStorage, fTypoFlags, success);
|
||||
return count;
|
||||
}
|
||||
|
||||
// apply positional tables
|
||||
void GXLayoutEngine2::adjustGlyphPositions(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool /*reverse*/,
|
||||
LEGlyphStorage &/*glyphStorage*/, LEErrorCode &success)
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (chars == NULL || offset < 0 || count < 0) {
|
||||
success = LE_ILLEGAL_ARGUMENT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
// FIXME: no positional processing yet...
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
|
@ -1,127 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. and others 1998-2014 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __GXLAYOUTENGINE2_H
|
||||
#define __GXLAYOUTENGINE2_H
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "LayoutEngine.h"
|
||||
|
||||
#include "MorphTables.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class LEFontInstance;
|
||||
class LEGlyphStorage;
|
||||
|
||||
/**
|
||||
* This class implements layout for QuickDraw GX or Apple Advanced Typograyph (AAT)
|
||||
* fonts. A font is a GX or AAT font if it contains a 'mort' table. See Apple's
|
||||
* TrueType Reference Manual (http://fonts.apple.com/TTRefMan/index.html) for details.
|
||||
* Information about 'mort' tables is in the chapter titled "Font Files."
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class GXLayoutEngine2 : public LayoutEngine
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This is the main constructor. It constructs an instance of GXLayoutEngine for
|
||||
* a particular font, script and language. It takes the 'mort' table as a parameter since
|
||||
* LayoutEngine::layoutEngineFactory has to read the 'mort' table to know that it has a
|
||||
* GX font.
|
||||
*
|
||||
* Note: GX and AAT fonts don't contain any script and language specific tables, so
|
||||
* the script and language are ignored.
|
||||
*
|
||||
* @param fontInstance - the font
|
||||
* @param scriptCode - the script
|
||||
* @param langaugeCode - the language
|
||||
* @param morphTable - the 'mort' table
|
||||
* @param success - set to an error code if the operation fails
|
||||
*
|
||||
* @see LayoutEngine::layoutEngineFactory
|
||||
* @see ScriptAndLangaugeTags.h for script and language codes
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
GXLayoutEngine2(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, const LEReferenceTo<MorphTableHeader2> &morphTable, le_int32 typoFlags, LEErrorCode &success);
|
||||
|
||||
/**
|
||||
* The destructor, virtual for correct polymorphic invocation.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
virtual ~GXLayoutEngine2();
|
||||
|
||||
/**
|
||||
* ICU "poor man's RTTI", returns a UClassID for the actual class.
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
virtual UClassID getDynamicClassID() const;
|
||||
|
||||
/**
|
||||
* ICU "poor man's RTTI", returns a UClassID for this class.
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
static UClassID getStaticClassID();
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* The address of the 'mort' table
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
const LEReferenceTo<MorphTableHeader2> fMorphTable;
|
||||
|
||||
/**
|
||||
* This method does GX layout using the font's 'mort' table. It converts the
|
||||
* input character codes to glyph indices using mapCharsToGlyphs, and then
|
||||
* applies the 'mort' table.
|
||||
*
|
||||
* Input parameters:
|
||||
* @param chars - the input character context
|
||||
* @param offset - the index of the first character to process
|
||||
* @param count - the number of characters to process
|
||||
* @param max - the number of characters in the input context
|
||||
* @param rightToLeft - <code>TRUE</code> if the text is in a right to left directional run
|
||||
* @param glyphStorage - the glyph storage object. The glyph and char index arrays will be set.
|
||||
*
|
||||
* Output parameters:
|
||||
* @param success - set to an error code if the operation fails
|
||||
*
|
||||
* @return the number of glyphs in the glyph index array
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
virtual le_int32 computeGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft,
|
||||
LEGlyphStorage &glyphStorage, LEErrorCode &success);
|
||||
|
||||
/**
|
||||
* This method adjusts the glyph positions using the font's
|
||||
* 'kern', 'trak', 'bsln', 'opbd' and 'just' tables.
|
||||
*
|
||||
* Input parameters:
|
||||
* @param glyphStorage - the object holding the glyph storage. The positions will be updated as needed.
|
||||
*
|
||||
* Output parameters:
|
||||
* @param success - set to an error code if the operation fails
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
virtual void adjustGlyphPositions(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse,
|
||||
LEGlyphStorage &glyphStorage, LEErrorCode &success);
|
||||
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998 - 2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "OpenTypeTables.h"
|
||||
#include "GlyphDefinitionTables.h"
|
||||
#include "LESwaps.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
const LEReferenceTo<GlyphClassDefinitionTable>
|
||||
GlyphDefinitionTableHeader::getGlyphClassDefinitionTable(const LEReferenceTo<GlyphDefinitionTableHeader>& base,
|
||||
LEErrorCode &success) const
|
||||
{
|
||||
if(LE_FAILURE(success)) return LEReferenceTo<GlyphClassDefinitionTable>();
|
||||
return LEReferenceTo<GlyphClassDefinitionTable>(base, success, SWAPW(glyphClassDefOffset));
|
||||
}
|
||||
|
||||
const LEReferenceTo<AttachmentListTable>
|
||||
GlyphDefinitionTableHeader::getAttachmentListTable(const LEReferenceTo<GlyphDefinitionTableHeader>& base,
|
||||
LEErrorCode &success) const
|
||||
{
|
||||
if(LE_FAILURE(success)) return LEReferenceTo<AttachmentListTable>();
|
||||
return LEReferenceTo<AttachmentListTable>(base, success, SWAPW(attachListOffset));
|
||||
}
|
||||
|
||||
const LEReferenceTo<LigatureCaretListTable>
|
||||
GlyphDefinitionTableHeader::getLigatureCaretListTable(const LEReferenceTo<GlyphDefinitionTableHeader>& base,
|
||||
LEErrorCode &success) const
|
||||
{
|
||||
if(LE_FAILURE(success)) return LEReferenceTo<LigatureCaretListTable>();
|
||||
return LEReferenceTo<LigatureCaretListTable>(base, success, SWAPW(ligCaretListOffset));
|
||||
}
|
||||
|
||||
const LEReferenceTo<MarkAttachClassDefinitionTable>
|
||||
GlyphDefinitionTableHeader::getMarkAttachClassDefinitionTable(const LEReferenceTo<GlyphDefinitionTableHeader>& base,
|
||||
LEErrorCode &success) const
|
||||
{
|
||||
if(LE_FAILURE(success)) return LEReferenceTo<MarkAttachClassDefinitionTable>();
|
||||
return LEReferenceTo<MarkAttachClassDefinitionTable>(base, success, SWAPW(MarkAttachClassDefOffset));
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
|
@ -1,110 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __GLYPHDEFINITIONTABLES_H
|
||||
#define __GLYPHDEFINITIONTABLES_H
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \internal
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "OpenTypeTables.h"
|
||||
#include "ClassDefinitionTables.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
typedef ClassDefinitionTable GlyphClassDefinitionTable;
|
||||
|
||||
enum GlyphClassDefinitions
|
||||
{
|
||||
gcdNoGlyphClass = 0,
|
||||
gcdSimpleGlyph = 1,
|
||||
gcdLigatureGlyph = 2,
|
||||
gcdMarkGlyph = 3,
|
||||
gcdComponentGlyph = 4
|
||||
};
|
||||
|
||||
struct AttachmentListTable
|
||||
{
|
||||
Offset coverageTableOffset;
|
||||
le_uint16 glyphCount;
|
||||
Offset attachPointTableOffsetArray[ANY_NUMBER];
|
||||
};
|
||||
LE_VAR_ARRAY(AttachmentListTable, attachPointTableOffsetArray)
|
||||
|
||||
struct AttachPointTable
|
||||
{
|
||||
le_uint16 pointCount;
|
||||
le_uint16 pointIndexArray[ANY_NUMBER];
|
||||
};
|
||||
LE_VAR_ARRAY(AttachPointTable, pointIndexArray)
|
||||
|
||||
struct LigatureCaretListTable
|
||||
{
|
||||
Offset coverageTableOffset;
|
||||
le_uint16 ligGlyphCount;
|
||||
Offset ligGlyphTableOffsetArray[ANY_NUMBER];
|
||||
};
|
||||
LE_VAR_ARRAY(LigatureCaretListTable, ligGlyphTableOffsetArray)
|
||||
|
||||
struct LigatureGlyphTable
|
||||
{
|
||||
le_uint16 caretCount;
|
||||
Offset caretValueTableOffsetArray[ANY_NUMBER];
|
||||
};
|
||||
LE_VAR_ARRAY(LigatureGlyphTable, caretValueTableOffsetArray)
|
||||
|
||||
struct CaretValueTable
|
||||
{
|
||||
le_uint16 caretValueFormat;
|
||||
};
|
||||
|
||||
struct CaretValueFormat1Table : CaretValueTable
|
||||
{
|
||||
le_int16 coordinate;
|
||||
};
|
||||
|
||||
struct CaretValueFormat2Table : CaretValueTable
|
||||
{
|
||||
le_uint16 caretValuePoint;
|
||||
};
|
||||
|
||||
struct CaretValueFormat3Table : CaretValueTable
|
||||
{
|
||||
le_int16 coordinate;
|
||||
Offset deviceTableOffset;
|
||||
};
|
||||
|
||||
typedef ClassDefinitionTable MarkAttachClassDefinitionTable;
|
||||
|
||||
struct GlyphDefinitionTableHeader
|
||||
{
|
||||
fixed32 version;
|
||||
Offset glyphClassDefOffset;
|
||||
Offset attachListOffset;
|
||||
Offset ligCaretListOffset;
|
||||
Offset MarkAttachClassDefOffset;
|
||||
|
||||
const LEReferenceTo<GlyphClassDefinitionTable>
|
||||
getGlyphClassDefinitionTable(const LEReferenceTo<GlyphDefinitionTableHeader>& base,
|
||||
LEErrorCode &success) const;
|
||||
const LEReferenceTo<AttachmentListTable>
|
||||
getAttachmentListTable(const LEReferenceTo<GlyphDefinitionTableHeader>& base,
|
||||
LEErrorCode &success)const ;
|
||||
const LEReferenceTo<LigatureCaretListTable>
|
||||
getLigatureCaretListTable(const LEReferenceTo<GlyphDefinitionTableHeader>& base,
|
||||
LEErrorCode &success) const;
|
||||
const LEReferenceTo<MarkAttachClassDefinitionTable>
|
||||
getMarkAttachClassDefinitionTable(const LEReferenceTo<GlyphDefinitionTableHeader>& base,
|
||||
LEErrorCode &success) const;
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
|
@ -1,537 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "OpenTypeTables.h"
|
||||
#include "GlyphDefinitionTables.h"
|
||||
#include "GlyphPositionAdjustments.h"
|
||||
#include "GlyphIterator.h"
|
||||
#include "LEGlyphStorage.h"
|
||||
#include "Lookups.h"
|
||||
#include "LESwaps.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
GlyphIterator::GlyphIterator(LEGlyphStorage &theGlyphStorage, GlyphPositionAdjustments *theGlyphPositionAdjustments, le_bool rightToLeft, le_uint16 theLookupFlags,
|
||||
FeatureMask theFeatureMask, const LEReferenceTo<GlyphDefinitionTableHeader> &theGlyphDefinitionTableHeader)
|
||||
: direction(1), position(-1), nextLimit(-1), prevLimit(-1),
|
||||
glyphStorage(theGlyphStorage), glyphPositionAdjustments(theGlyphPositionAdjustments),
|
||||
srcIndex(-1), destIndex(-1), lookupFlags(theLookupFlags), featureMask(theFeatureMask), glyphGroup(0),
|
||||
glyphClassDefinitionTable(), markAttachClassDefinitionTable()
|
||||
|
||||
{
|
||||
LEErrorCode success = LE_NO_ERROR; // TODO
|
||||
le_int32 glyphCount = glyphStorage.getGlyphCount();
|
||||
|
||||
if (theGlyphDefinitionTableHeader.isValid()) {
|
||||
glyphClassDefinitionTable = theGlyphDefinitionTableHeader
|
||||
-> getGlyphClassDefinitionTable(theGlyphDefinitionTableHeader, success);
|
||||
markAttachClassDefinitionTable = theGlyphDefinitionTableHeader
|
||||
->getMarkAttachClassDefinitionTable(theGlyphDefinitionTableHeader, success);
|
||||
}
|
||||
|
||||
nextLimit = glyphCount;
|
||||
|
||||
if (rightToLeft) {
|
||||
direction = -1;
|
||||
position = glyphCount;
|
||||
nextLimit = -1;
|
||||
prevLimit = glyphCount;
|
||||
}
|
||||
filterResetCache();
|
||||
}
|
||||
|
||||
GlyphIterator::GlyphIterator(GlyphIterator &that)
|
||||
: glyphStorage(that.glyphStorage)
|
||||
{
|
||||
direction = that.direction;
|
||||
position = that.position;
|
||||
nextLimit = that.nextLimit;
|
||||
prevLimit = that.prevLimit;
|
||||
|
||||
glyphPositionAdjustments = that.glyphPositionAdjustments;
|
||||
srcIndex = that.srcIndex;
|
||||
destIndex = that.destIndex;
|
||||
lookupFlags = that.lookupFlags;
|
||||
featureMask = that.featureMask;
|
||||
glyphGroup = that.glyphGroup;
|
||||
glyphClassDefinitionTable = that.glyphClassDefinitionTable;
|
||||
markAttachClassDefinitionTable = that.markAttachClassDefinitionTable;
|
||||
filterResetCache();
|
||||
}
|
||||
|
||||
GlyphIterator::GlyphIterator(GlyphIterator &that, FeatureMask newFeatureMask)
|
||||
: glyphStorage(that.glyphStorage)
|
||||
{
|
||||
direction = that.direction;
|
||||
position = that.position;
|
||||
nextLimit = that.nextLimit;
|
||||
prevLimit = that.prevLimit;
|
||||
|
||||
glyphPositionAdjustments = that.glyphPositionAdjustments;
|
||||
srcIndex = that.srcIndex;
|
||||
destIndex = that.destIndex;
|
||||
lookupFlags = that.lookupFlags;
|
||||
featureMask = newFeatureMask;
|
||||
glyphGroup = 0;
|
||||
glyphClassDefinitionTable = that.glyphClassDefinitionTable;
|
||||
markAttachClassDefinitionTable = that.markAttachClassDefinitionTable;
|
||||
filterResetCache();
|
||||
}
|
||||
|
||||
GlyphIterator::GlyphIterator(GlyphIterator &that, le_uint16 newLookupFlags)
|
||||
: glyphStorage(that.glyphStorage)
|
||||
{
|
||||
direction = that.direction;
|
||||
position = that.position;
|
||||
nextLimit = that.nextLimit;
|
||||
prevLimit = that.prevLimit;
|
||||
|
||||
glyphPositionAdjustments = that.glyphPositionAdjustments;
|
||||
srcIndex = that.srcIndex;
|
||||
destIndex = that.destIndex;
|
||||
lookupFlags = newLookupFlags;
|
||||
featureMask = that.featureMask;
|
||||
glyphGroup = that.glyphGroup;
|
||||
glyphClassDefinitionTable = that.glyphClassDefinitionTable;
|
||||
markAttachClassDefinitionTable = that.markAttachClassDefinitionTable;
|
||||
filterResetCache();
|
||||
}
|
||||
|
||||
GlyphIterator::~GlyphIterator()
|
||||
{
|
||||
// nothing to do, right?
|
||||
}
|
||||
|
||||
void GlyphIterator::reset(le_uint16 newLookupFlags, FeatureMask newFeatureMask)
|
||||
{
|
||||
position = prevLimit;
|
||||
featureMask = newFeatureMask;
|
||||
glyphGroup = 0;
|
||||
lookupFlags = newLookupFlags;
|
||||
filterResetCache();
|
||||
}
|
||||
|
||||
LEGlyphID *GlyphIterator::insertGlyphs(le_int32 count, LEErrorCode& success)
|
||||
{
|
||||
return glyphStorage.insertGlyphs(position, count, success);
|
||||
}
|
||||
|
||||
le_int32 GlyphIterator::applyInsertions()
|
||||
{
|
||||
le_int32 newGlyphCount = glyphStorage.applyInsertions();
|
||||
|
||||
if (direction < 0) {
|
||||
prevLimit = newGlyphCount;
|
||||
} else {
|
||||
nextLimit = newGlyphCount;
|
||||
}
|
||||
|
||||
return newGlyphCount;
|
||||
}
|
||||
|
||||
le_int32 GlyphIterator::getCurrStreamPosition() const
|
||||
{
|
||||
return position;
|
||||
}
|
||||
|
||||
le_bool GlyphIterator::isRightToLeft() const
|
||||
{
|
||||
return direction < 0;
|
||||
}
|
||||
|
||||
le_bool GlyphIterator::ignoresMarks() const
|
||||
{
|
||||
return (lookupFlags & lfIgnoreMarks) != 0;
|
||||
}
|
||||
|
||||
le_bool GlyphIterator::baselineIsLogicalEnd() const
|
||||
{
|
||||
return (lookupFlags & lfBaselineIsLogicalEnd) != 0;
|
||||
}
|
||||
|
||||
LEGlyphID GlyphIterator::getCurrGlyphID() const
|
||||
{
|
||||
if (direction < 0) {
|
||||
if (position <= nextLimit || position >= prevLimit) {
|
||||
return 0xFFFF;
|
||||
}
|
||||
} else {
|
||||
if (position <= prevLimit || position >= nextLimit) {
|
||||
return 0xFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
return glyphStorage[position];
|
||||
}
|
||||
|
||||
void GlyphIterator::getCursiveEntryPoint(LEPoint &entryPoint) const
|
||||
{
|
||||
if (direction < 0) {
|
||||
if (position <= nextLimit || position >= prevLimit) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (position <= prevLimit || position >= nextLimit) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
glyphPositionAdjustments->getEntryPoint(position, entryPoint);
|
||||
}
|
||||
|
||||
void GlyphIterator::getCursiveExitPoint(LEPoint &exitPoint) const
|
||||
{
|
||||
if (direction < 0) {
|
||||
if (position <= nextLimit || position >= prevLimit) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (position <= prevLimit || position >= nextLimit) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
glyphPositionAdjustments->getExitPoint(position, exitPoint);
|
||||
}
|
||||
|
||||
void GlyphIterator::setCurrGlyphID(TTGlyphID glyphID)
|
||||
{
|
||||
LEGlyphID glyph = glyphStorage[position];
|
||||
|
||||
glyphStorage[position] = LE_SET_GLYPH(glyph, glyphID);
|
||||
}
|
||||
|
||||
void GlyphIterator::setCurrStreamPosition(le_int32 newPosition)
|
||||
{
|
||||
if (direction < 0) {
|
||||
if (newPosition >= prevLimit) {
|
||||
position = prevLimit;
|
||||
return;
|
||||
}
|
||||
|
||||
if (newPosition <= nextLimit) {
|
||||
position = nextLimit;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (newPosition <= prevLimit) {
|
||||
position = prevLimit;
|
||||
return;
|
||||
}
|
||||
|
||||
if (newPosition >= nextLimit) {
|
||||
position = nextLimit;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
position = newPosition - direction;
|
||||
next();
|
||||
}
|
||||
|
||||
void GlyphIterator::setCurrGlyphBaseOffset(le_int32 baseOffset)
|
||||
{
|
||||
if (direction < 0) {
|
||||
if (position <= nextLimit || position >= prevLimit) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (position <= prevLimit || position >= nextLimit) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
glyphPositionAdjustments->setBaseOffset(position, baseOffset);
|
||||
}
|
||||
|
||||
void GlyphIterator::adjustCurrGlyphPositionAdjustment(float xPlacementAdjust, float yPlacementAdjust,
|
||||
float xAdvanceAdjust, float yAdvanceAdjust)
|
||||
{
|
||||
if (direction < 0) {
|
||||
if (position <= nextLimit || position >= prevLimit) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (position <= prevLimit || position >= nextLimit) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
glyphPositionAdjustments->adjustXPlacement(position, xPlacementAdjust);
|
||||
glyphPositionAdjustments->adjustYPlacement(position, yPlacementAdjust);
|
||||
glyphPositionAdjustments->adjustXAdvance(position, xAdvanceAdjust);
|
||||
glyphPositionAdjustments->adjustYAdvance(position, yAdvanceAdjust);
|
||||
}
|
||||
|
||||
void GlyphIterator::setCurrGlyphPositionAdjustment(float xPlacementAdjust, float yPlacementAdjust,
|
||||
float xAdvanceAdjust, float yAdvanceAdjust)
|
||||
{
|
||||
if (direction < 0) {
|
||||
if (position <= nextLimit || position >= prevLimit) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (position <= prevLimit || position >= nextLimit) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
glyphPositionAdjustments->setXPlacement(position, xPlacementAdjust);
|
||||
glyphPositionAdjustments->setYPlacement(position, yPlacementAdjust);
|
||||
glyphPositionAdjustments->setXAdvance(position, xAdvanceAdjust);
|
||||
glyphPositionAdjustments->setYAdvance(position, yAdvanceAdjust);
|
||||
}
|
||||
|
||||
void GlyphIterator::clearCursiveEntryPoint()
|
||||
{
|
||||
if (direction < 0) {
|
||||
if (position <= nextLimit || position >= prevLimit) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (position <= prevLimit || position >= nextLimit) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
glyphPositionAdjustments->clearEntryPoint(position);
|
||||
}
|
||||
|
||||
void GlyphIterator::clearCursiveExitPoint()
|
||||
{
|
||||
if (direction < 0) {
|
||||
if (position <= nextLimit || position >= prevLimit) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (position <= prevLimit || position >= nextLimit) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
glyphPositionAdjustments->clearExitPoint(position);
|
||||
}
|
||||
|
||||
void GlyphIterator::setCursiveEntryPoint(LEPoint &entryPoint)
|
||||
{
|
||||
if (direction < 0) {
|
||||
if (position <= nextLimit || position >= prevLimit) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (position <= prevLimit || position >= nextLimit) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
glyphPositionAdjustments->setEntryPoint(position, entryPoint, baselineIsLogicalEnd());
|
||||
}
|
||||
|
||||
void GlyphIterator::setCursiveExitPoint(LEPoint &exitPoint)
|
||||
{
|
||||
if (direction < 0) {
|
||||
if (position <= nextLimit || position >= prevLimit) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (position <= prevLimit || position >= nextLimit) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
glyphPositionAdjustments->setExitPoint(position, exitPoint, baselineIsLogicalEnd());
|
||||
}
|
||||
|
||||
void GlyphIterator::setCursiveGlyph()
|
||||
{
|
||||
if (direction < 0) {
|
||||
if (position <= nextLimit || position >= prevLimit) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (position <= prevLimit || position >= nextLimit) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
glyphPositionAdjustments->setCursiveGlyph(position, baselineIsLogicalEnd());
|
||||
}
|
||||
|
||||
void GlyphIterator::filterResetCache(void) {
|
||||
filterCacheValid = FALSE;
|
||||
}
|
||||
|
||||
le_bool GlyphIterator::filterGlyph(le_uint32 index)
|
||||
{
|
||||
LEGlyphID glyphID = glyphStorage[index];
|
||||
|
||||
if (!filterCacheValid || filterCache.id != glyphID) {
|
||||
filterCache.id = glyphID;
|
||||
|
||||
le_bool &filterResult = filterCache.result; // NB: Making this a reference to accept the updated value, in case
|
||||
// we want more fancy cacheing in the future.
|
||||
if (LE_GET_GLYPH(glyphID) >= 0xFFFE) {
|
||||
filterResult = TRUE;
|
||||
} else {
|
||||
LEErrorCode success = LE_NO_ERROR;
|
||||
le_int32 glyphClass = gcdNoGlyphClass;
|
||||
if (glyphClassDefinitionTable.isValid()) {
|
||||
glyphClass = glyphClassDefinitionTable->getGlyphClass(glyphClassDefinitionTable, glyphID, success);
|
||||
}
|
||||
switch (glyphClass) {
|
||||
case gcdNoGlyphClass:
|
||||
filterResult = FALSE;
|
||||
break;
|
||||
|
||||
case gcdSimpleGlyph:
|
||||
filterResult = (lookupFlags & lfIgnoreBaseGlyphs) != 0;
|
||||
break;
|
||||
|
||||
case gcdLigatureGlyph:
|
||||
filterResult = (lookupFlags & lfIgnoreLigatures) != 0;
|
||||
break;
|
||||
|
||||
case gcdMarkGlyph:
|
||||
if ((lookupFlags & lfIgnoreMarks) != 0) {
|
||||
filterResult = TRUE;
|
||||
} else {
|
||||
le_uint16 markAttachType = (lookupFlags & lfMarkAttachTypeMask) >> lfMarkAttachTypeShift;
|
||||
|
||||
if ((markAttachType != 0) && (markAttachClassDefinitionTable.isValid())) {
|
||||
filterResult = (markAttachClassDefinitionTable
|
||||
-> getGlyphClass(markAttachClassDefinitionTable, glyphID, success) != markAttachType);
|
||||
} else {
|
||||
filterResult = FALSE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case gcdComponentGlyph:
|
||||
filterResult = ((lookupFlags & lfIgnoreBaseGlyphs) != 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
filterResult = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
filterCacheValid = TRUE;
|
||||
}
|
||||
|
||||
return filterCache.result;
|
||||
}
|
||||
|
||||
le_bool GlyphIterator::hasFeatureTag(le_bool matchGroup) const
|
||||
{
|
||||
if (featureMask == 0) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
LEErrorCode success = LE_NO_ERROR;
|
||||
FeatureMask fm = glyphStorage.getAuxData(position, success);
|
||||
|
||||
return ((fm & featureMask) == featureMask) && (!matchGroup || (le_int32)(fm & LE_GLYPH_GROUP_MASK) == glyphGroup);
|
||||
}
|
||||
|
||||
le_bool GlyphIterator::findFeatureTag()
|
||||
{
|
||||
//glyphGroup = 0;
|
||||
|
||||
while (nextInternal()) {
|
||||
if (hasFeatureTag(FALSE)) {
|
||||
LEErrorCode success = LE_NO_ERROR;
|
||||
|
||||
glyphGroup = (glyphStorage.getAuxData(position, success) & LE_GLYPH_GROUP_MASK);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
le_bool GlyphIterator::nextInternal(le_uint32 delta)
|
||||
{
|
||||
le_int32 newPosition = position;
|
||||
|
||||
while (newPosition != nextLimit && delta > 0) {
|
||||
do {
|
||||
newPosition += direction;
|
||||
//fprintf(stderr,"%s:%d:%s: newPosition = %d, delta = %d\n", __FILE__, __LINE__, __FUNCTION__, newPosition, delta);
|
||||
} while (newPosition != nextLimit && filterGlyph(newPosition));
|
||||
|
||||
delta -= 1;
|
||||
}
|
||||
|
||||
position = newPosition;
|
||||
|
||||
//fprintf(stderr,"%s:%d:%s: exit position = %d, delta = %d\n", __FILE__, __LINE__, __FUNCTION__, position, delta);
|
||||
return position != nextLimit;
|
||||
}
|
||||
|
||||
le_bool GlyphIterator::next(le_uint32 delta)
|
||||
{
|
||||
return nextInternal(delta) && hasFeatureTag(TRUE);
|
||||
}
|
||||
|
||||
le_bool GlyphIterator::prevInternal(le_uint32 delta)
|
||||
{
|
||||
le_int32 newPosition = position;
|
||||
|
||||
while (newPosition != prevLimit && delta > 0) {
|
||||
do {
|
||||
newPosition -= direction;
|
||||
//fprintf(stderr,"%s:%d:%s: newPosition = %d, delta = %d\n", __FILE__, __LINE__, __FUNCTION__, newPosition, delta);
|
||||
} while (newPosition != prevLimit && filterGlyph(newPosition));
|
||||
|
||||
delta -= 1;
|
||||
}
|
||||
|
||||
position = newPosition;
|
||||
|
||||
//fprintf(stderr,"%s:%d:%s: exit position = %d, delta = %d\n", __FILE__, __LINE__, __FUNCTION__, position, delta);
|
||||
return position != prevLimit;
|
||||
}
|
||||
|
||||
le_bool GlyphIterator::prev(le_uint32 delta)
|
||||
{
|
||||
return prevInternal(delta) && hasFeatureTag(TRUE);
|
||||
}
|
||||
|
||||
le_int32 GlyphIterator::getMarkComponent(le_int32 markPosition) const
|
||||
{
|
||||
le_int32 component = 0;
|
||||
le_int32 posn;
|
||||
|
||||
for (posn = position; posn != markPosition; posn += direction) {
|
||||
if (glyphStorage[posn] == 0xFFFE) {
|
||||
component += 1;
|
||||
}
|
||||
}
|
||||
|
||||
return component;
|
||||
}
|
||||
|
||||
// This is basically prevInternal except that it
|
||||
// doesn't take a delta argument, and it doesn't
|
||||
// filter out 0xFFFE glyphs.
|
||||
le_bool GlyphIterator::findMark2Glyph()
|
||||
{
|
||||
le_int32 newPosition = position;
|
||||
|
||||
do {
|
||||
newPosition -= direction;
|
||||
} while (newPosition != prevLimit && glyphStorage[newPosition] != 0xFFFE && filterGlyph(newPosition));
|
||||
|
||||
position = newPosition;
|
||||
|
||||
return position != prevLimit;
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
|
@ -1,112 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __GLYPHITERATOR_H
|
||||
#define __GLYPHITERATOR_H
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \internal
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "OpenTypeTables.h"
|
||||
#include "GlyphDefinitionTables.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class LEGlyphStorage;
|
||||
class GlyphPositionAdjustments;
|
||||
|
||||
class GlyphIterator : public UMemory {
|
||||
public:
|
||||
GlyphIterator(LEGlyphStorage &theGlyphStorage, GlyphPositionAdjustments *theGlyphPositionAdjustments, le_bool rightToLeft, le_uint16 theLookupFlags,
|
||||
FeatureMask theFeatureMask, const LEReferenceTo<GlyphDefinitionTableHeader> &theGlyphDefinitionTableHeader);
|
||||
|
||||
GlyphIterator(GlyphIterator &that);
|
||||
|
||||
GlyphIterator(GlyphIterator &that, FeatureMask newFeatureMask);
|
||||
|
||||
GlyphIterator(GlyphIterator &that, le_uint16 newLookupFlags);
|
||||
|
||||
virtual ~GlyphIterator();
|
||||
|
||||
void reset(le_uint16 newLookupFlags, LETag newFeatureTag);
|
||||
|
||||
le_bool next(le_uint32 delta = 1);
|
||||
le_bool prev(le_uint32 delta = 1);
|
||||
le_bool findFeatureTag();
|
||||
|
||||
le_bool isRightToLeft() const;
|
||||
le_bool ignoresMarks() const;
|
||||
|
||||
le_bool baselineIsLogicalEnd() const;
|
||||
|
||||
LEGlyphID getCurrGlyphID() const;
|
||||
le_int32 getCurrStreamPosition() const;
|
||||
|
||||
le_int32 getMarkComponent(le_int32 markPosition) const;
|
||||
le_bool findMark2Glyph();
|
||||
|
||||
void getCursiveEntryPoint(LEPoint &entryPoint) const;
|
||||
void getCursiveExitPoint(LEPoint &exitPoint) const;
|
||||
|
||||
void setCurrGlyphID(TTGlyphID glyphID);
|
||||
void setCurrStreamPosition(le_int32 position);
|
||||
void setCurrGlyphBaseOffset(le_int32 baseOffset);
|
||||
void adjustCurrGlyphPositionAdjustment(float xPlacementAdjust, float yPlacementAdjust,
|
||||
float xAdvanceAdjust, float yAdvanceAdjust);
|
||||
|
||||
void setCurrGlyphPositionAdjustment(float xPlacementAdjust, float yPlacementAdjust,
|
||||
float xAdvanceAdjust, float yAdvanceAdjust);
|
||||
|
||||
void clearCursiveEntryPoint();
|
||||
void clearCursiveExitPoint();
|
||||
void setCursiveEntryPoint(LEPoint &entryPoint);
|
||||
void setCursiveExitPoint(LEPoint &exitPoint);
|
||||
void setCursiveGlyph();
|
||||
|
||||
LEGlyphID *insertGlyphs(le_int32 count, LEErrorCode& success);
|
||||
le_int32 applyInsertions();
|
||||
|
||||
private:
|
||||
le_bool filterGlyph(le_uint32 index);
|
||||
le_bool hasFeatureTag(le_bool matchGroup) const;
|
||||
le_bool nextInternal(le_uint32 delta = 1);
|
||||
le_bool prevInternal(le_uint32 delta = 1);
|
||||
|
||||
le_int32 direction;
|
||||
le_int32 position;
|
||||
le_int32 nextLimit;
|
||||
le_int32 prevLimit;
|
||||
|
||||
LEGlyphStorage &glyphStorage;
|
||||
GlyphPositionAdjustments *glyphPositionAdjustments;
|
||||
|
||||
le_int32 srcIndex;
|
||||
le_int32 destIndex;
|
||||
le_uint16 lookupFlags;
|
||||
FeatureMask featureMask;
|
||||
le_int32 glyphGroup;
|
||||
|
||||
LEReferenceTo<GlyphClassDefinitionTable> glyphClassDefinitionTable;
|
||||
LEReferenceTo<MarkAttachClassDefinitionTable> markAttachClassDefinitionTable;
|
||||
|
||||
GlyphIterator &operator=(const GlyphIterator &other); // forbid copying of this class
|
||||
|
||||
struct {
|
||||
LEGlyphID id;
|
||||
le_bool result;
|
||||
} filterCache;
|
||||
le_bool filterCacheValid;
|
||||
|
||||
void filterResetCache(void);
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
|
@ -1,35 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "OpenTypeTables.h"
|
||||
#include "ScriptAndLanguage.h"
|
||||
#include "GlyphLookupTables.h"
|
||||
#include "LESwaps.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
le_bool GlyphLookupTableHeader::coversScript(const LETableReference &base, LETag scriptTag, LEErrorCode &success) const
|
||||
{
|
||||
LEReferenceTo<ScriptListTable> scriptListTable(base, success, SWAPW(scriptListOffset));
|
||||
|
||||
return (scriptListOffset != 0) && scriptListTable->findScript(scriptListTable, scriptTag, success) .isValid();
|
||||
}
|
||||
|
||||
le_bool GlyphLookupTableHeader::coversScriptAndLanguage(const LETableReference &base, LETag scriptTag, LETag languageTag, LEErrorCode &success, le_bool exactMatch) const
|
||||
{
|
||||
LEReferenceTo<ScriptListTable> scriptListTable(base, success, SWAPW(scriptListOffset));
|
||||
LEReferenceTo<LangSysTable> langSysTable = scriptListTable->findLanguage(scriptListTable,
|
||||
scriptTag, languageTag, success, exactMatch);
|
||||
|
||||
// FIXME: could check featureListOffset, lookupListOffset, and lookup count...
|
||||
// Note: don't have to SWAPW langSysTable->featureCount to check for non-zero.
|
||||
return LE_SUCCESS(success)&&langSysTable.isValid() && langSysTable->featureCount != 0;
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
|
@ -1,36 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __GLYPHLOOKUPTABLES_H
|
||||
#define __GLYPHLOOKUPTABLES_H
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \internal
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "OpenTypeTables.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
struct GlyphLookupTableHeader
|
||||
{
|
||||
fixed32 version;
|
||||
Offset scriptListOffset;
|
||||
Offset featureListOffset;
|
||||
Offset lookupListOffset;
|
||||
|
||||
le_bool coversScript(const LETableReference &base, LETag scriptTag, LEErrorCode &success) const;
|
||||
le_bool coversScriptAndLanguage(const LETableReference &base, LETag scriptTag, LETag languageTag, LEErrorCode &success, le_bool exactMatch = FALSE) const;
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
||||
#endif
|
||||
|
|
@ -1,187 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "GlyphPositionAdjustments.h"
|
||||
#include "LEGlyphStorage.h"
|
||||
#include "LEFontInstance.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
#define CHECK_ALLOCATE_ARRAY(array, type, size) \
|
||||
if (array == NULL) { \
|
||||
array = (type *) new type[size]; \
|
||||
}
|
||||
|
||||
GlyphPositionAdjustments::GlyphPositionAdjustments(le_int32 glyphCount)
|
||||
: fGlyphCount(glyphCount), fEntryExitPoints(NULL), fAdjustments(NULL)
|
||||
{
|
||||
fAdjustments = (Adjustment *) new Adjustment[glyphCount];
|
||||
}
|
||||
|
||||
GlyphPositionAdjustments::~GlyphPositionAdjustments()
|
||||
{
|
||||
delete[] fEntryExitPoints;
|
||||
delete[] fAdjustments;
|
||||
}
|
||||
|
||||
const LEPoint *GlyphPositionAdjustments::getEntryPoint(le_int32 index, LEPoint &entryPoint) const
|
||||
{
|
||||
if (fEntryExitPoints == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return fEntryExitPoints[index].getEntryPoint(entryPoint);
|
||||
}
|
||||
|
||||
const LEPoint *GlyphPositionAdjustments::getExitPoint(le_int32 index, LEPoint &exitPoint)const
|
||||
{
|
||||
if (fEntryExitPoints == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return fEntryExitPoints[index].getExitPoint(exitPoint);
|
||||
}
|
||||
|
||||
void GlyphPositionAdjustments::clearEntryPoint(le_int32 index)
|
||||
{
|
||||
CHECK_ALLOCATE_ARRAY(fEntryExitPoints, EntryExitPoint, fGlyphCount);
|
||||
|
||||
fEntryExitPoints[index].clearEntryPoint();
|
||||
}
|
||||
|
||||
void GlyphPositionAdjustments::clearExitPoint(le_int32 index)
|
||||
{
|
||||
CHECK_ALLOCATE_ARRAY(fEntryExitPoints, EntryExitPoint, fGlyphCount);
|
||||
|
||||
fEntryExitPoints[index].clearExitPoint();
|
||||
}
|
||||
|
||||
void GlyphPositionAdjustments::setEntryPoint(le_int32 index, LEPoint &newEntryPoint, le_bool baselineIsLogicalEnd)
|
||||
{
|
||||
CHECK_ALLOCATE_ARRAY(fEntryExitPoints, EntryExitPoint, fGlyphCount);
|
||||
|
||||
fEntryExitPoints[index].setEntryPoint(newEntryPoint, baselineIsLogicalEnd);
|
||||
}
|
||||
|
||||
void GlyphPositionAdjustments::setExitPoint(le_int32 index, LEPoint &newExitPoint, le_bool baselineIsLogicalEnd)
|
||||
{
|
||||
CHECK_ALLOCATE_ARRAY(fEntryExitPoints, EntryExitPoint, fGlyphCount);
|
||||
|
||||
fEntryExitPoints[index].setExitPoint(newExitPoint, baselineIsLogicalEnd);
|
||||
}
|
||||
|
||||
void GlyphPositionAdjustments::setCursiveGlyph(le_int32 index, le_bool baselineIsLogicalEnd)
|
||||
{
|
||||
CHECK_ALLOCATE_ARRAY(fEntryExitPoints, EntryExitPoint, fGlyphCount);
|
||||
|
||||
fEntryExitPoints[index].setCursiveGlyph(baselineIsLogicalEnd);
|
||||
}
|
||||
|
||||
void GlyphPositionAdjustments::applyCursiveAdjustments(LEGlyphStorage &glyphStorage, le_bool rightToLeft, const LEFontInstance *fontInstance)
|
||||
{
|
||||
if (! hasCursiveGlyphs()) {
|
||||
return;
|
||||
}
|
||||
|
||||
le_int32 start = 0, end = fGlyphCount, dir = 1;
|
||||
le_int32 firstExitPoint = -1, lastExitPoint = -1;
|
||||
LEPoint entryAnchor, exitAnchor, pixels;
|
||||
LEGlyphID lastExitGlyphID = 0;
|
||||
float baselineAdjustment = 0;
|
||||
|
||||
// This removes a possible warning about
|
||||
// using exitAnchor before it's been initialized.
|
||||
exitAnchor.fX = exitAnchor.fY = 0;
|
||||
|
||||
if (rightToLeft) {
|
||||
start = fGlyphCount - 1;
|
||||
end = -1;
|
||||
dir = -1;
|
||||
}
|
||||
|
||||
for (le_int32 i = start; i != end; i += dir) {
|
||||
LEGlyphID glyphID = glyphStorage[i];
|
||||
|
||||
if (isCursiveGlyph(i)) {
|
||||
if (lastExitPoint >= 0 && getEntryPoint(i, entryAnchor) != NULL) {
|
||||
float anchorDiffX = exitAnchor.fX - entryAnchor.fX;
|
||||
float anchorDiffY = exitAnchor.fY - entryAnchor.fY;
|
||||
|
||||
baselineAdjustment += anchorDiffY;
|
||||
adjustYPlacement(i, baselineAdjustment);
|
||||
|
||||
if (rightToLeft) {
|
||||
LEPoint secondAdvance;
|
||||
|
||||
fontInstance->getGlyphAdvance(glyphID, pixels);
|
||||
fontInstance->pixelsToUnits(pixels, secondAdvance);
|
||||
|
||||
adjustXAdvance(i, -(anchorDiffX + secondAdvance.fX));
|
||||
} else {
|
||||
LEPoint firstAdvance;
|
||||
|
||||
fontInstance->getGlyphAdvance(lastExitGlyphID, pixels);
|
||||
fontInstance->pixelsToUnits(pixels, firstAdvance);
|
||||
|
||||
adjustXAdvance(lastExitPoint, anchorDiffX - firstAdvance.fX);
|
||||
}
|
||||
}
|
||||
|
||||
lastExitPoint = i;
|
||||
|
||||
if (getExitPoint(i, exitAnchor) != NULL) {
|
||||
if (firstExitPoint < 0) {
|
||||
firstExitPoint = i;
|
||||
}
|
||||
|
||||
lastExitGlyphID = glyphID;
|
||||
} else {
|
||||
if (baselineIsLogicalEnd(i) && firstExitPoint >= 0 && lastExitPoint >= 0) {
|
||||
le_int32 limit = lastExitPoint /*+ dir*/;
|
||||
LEPoint dummyAnchor;
|
||||
|
||||
if (getEntryPoint(i, dummyAnchor) != NULL) {
|
||||
limit += dir;
|
||||
}
|
||||
|
||||
for (le_int32 j = firstExitPoint; j != limit; j += dir) {
|
||||
if (isCursiveGlyph(j)) {
|
||||
adjustYPlacement(j, -baselineAdjustment);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
firstExitPoint = lastExitPoint = -1;
|
||||
baselineAdjustment = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LEPoint *GlyphPositionAdjustments::EntryExitPoint::getEntryPoint(LEPoint &entryPoint) const
|
||||
{
|
||||
if (fFlags & EEF_HAS_ENTRY_POINT) {
|
||||
entryPoint = fEntryPoint;
|
||||
return &entryPoint;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LEPoint *GlyphPositionAdjustments::EntryExitPoint::getExitPoint(LEPoint &exitPoint) const
|
||||
{
|
||||
if (fFlags & EEF_HAS_EXIT_POINT) {
|
||||
exitPoint = fExitPoint;
|
||||
return &exitPoint;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
|
@ -1,378 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2007 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __GLYPHPOSITIONADJUSTMENTS_H
|
||||
#define __GLYPHPOSITIONADJUSTMENTS_H
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \internal
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "OpenTypeTables.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class LEGlyphStorage;
|
||||
class LEFontInstance;
|
||||
|
||||
class GlyphPositionAdjustments : public UMemory
|
||||
{
|
||||
private:
|
||||
class Adjustment : public UMemory {
|
||||
public:
|
||||
|
||||
inline Adjustment();
|
||||
inline Adjustment(float xPlace, float yPlace, float xAdv, float yAdv, le_int32 baseOff = -1);
|
||||
inline ~Adjustment();
|
||||
|
||||
inline float getXPlacement() const;
|
||||
inline float getYPlacement() const;
|
||||
inline float getXAdvance() const;
|
||||
inline float getYAdvance() const;
|
||||
|
||||
inline le_int32 getBaseOffset() const;
|
||||
|
||||
inline void setXPlacement(float newXPlacement);
|
||||
inline void setYPlacement(float newYPlacement);
|
||||
inline void setXAdvance(float newXAdvance);
|
||||
inline void setYAdvance(float newYAdvance);
|
||||
|
||||
inline void setBaseOffset(le_int32 newBaseOffset);
|
||||
|
||||
inline void adjustXPlacement(float xAdjustment);
|
||||
inline void adjustYPlacement(float yAdjustment);
|
||||
inline void adjustXAdvance(float xAdjustment);
|
||||
inline void adjustYAdvance(float yAdjustment);
|
||||
|
||||
private:
|
||||
float xPlacement;
|
||||
float yPlacement;
|
||||
float xAdvance;
|
||||
float yAdvance;
|
||||
|
||||
le_int32 baseOffset;
|
||||
|
||||
// allow copying of this class because all of its fields are simple types
|
||||
};
|
||||
|
||||
class EntryExitPoint : public UMemory
|
||||
{
|
||||
public:
|
||||
inline EntryExitPoint();
|
||||
inline ~EntryExitPoint();
|
||||
|
||||
inline le_bool isCursiveGlyph() const;
|
||||
inline le_bool baselineIsLogicalEnd() const;
|
||||
|
||||
LEPoint *getEntryPoint(LEPoint &entryPoint) const;
|
||||
LEPoint *getExitPoint(LEPoint &exitPoint) const;
|
||||
|
||||
inline void clearEntryPoint();
|
||||
inline void clearExitPoint();
|
||||
inline void setEntryPoint(LEPoint &newEntryPoint, le_bool baselineIsLogicalEnd);
|
||||
inline void setExitPoint(LEPoint &newExitPoint, le_bool baselineIsLogicalEnd);
|
||||
inline void setCursiveGlyph(le_bool baselineIsLogicalEnd);
|
||||
|
||||
private:
|
||||
enum EntryExitFlags
|
||||
{
|
||||
EEF_HAS_ENTRY_POINT = 0x80000000L,
|
||||
EEF_HAS_EXIT_POINT = 0x40000000L,
|
||||
EEF_IS_CURSIVE_GLYPH = 0x20000000L,
|
||||
EEF_BASELINE_IS_LOGICAL_END = 0x10000000L
|
||||
};
|
||||
|
||||
le_uint32 fFlags;
|
||||
LEPoint fEntryPoint;
|
||||
LEPoint fExitPoint;
|
||||
};
|
||||
|
||||
le_int32 fGlyphCount;
|
||||
EntryExitPoint *fEntryExitPoints;
|
||||
Adjustment *fAdjustments;
|
||||
|
||||
GlyphPositionAdjustments();
|
||||
|
||||
public:
|
||||
GlyphPositionAdjustments(le_int32 glyphCount);
|
||||
~GlyphPositionAdjustments();
|
||||
|
||||
inline le_bool hasCursiveGlyphs() const;
|
||||
inline le_bool isCursiveGlyph(le_int32 index) const;
|
||||
inline le_bool baselineIsLogicalEnd(le_int32 index) const;
|
||||
|
||||
const LEPoint *getEntryPoint(le_int32 index, LEPoint &entryPoint) const;
|
||||
const LEPoint *getExitPoint(le_int32 index, LEPoint &exitPoint) const;
|
||||
|
||||
inline float getXPlacement(le_int32 index) const;
|
||||
inline float getYPlacement(le_int32 index) const;
|
||||
inline float getXAdvance(le_int32 index) const;
|
||||
inline float getYAdvance(le_int32 index) const;
|
||||
|
||||
inline le_int32 getBaseOffset(le_int32 index) const;
|
||||
|
||||
inline void setXPlacement(le_int32 index, float newXPlacement);
|
||||
inline void setYPlacement(le_int32 index, float newYPlacement);
|
||||
inline void setXAdvance(le_int32 index, float newXAdvance);
|
||||
inline void setYAdvance(le_int32 index, float newYAdvance);
|
||||
|
||||
inline void setBaseOffset(le_int32 index, le_int32 newBaseOffset);
|
||||
|
||||
inline void adjustXPlacement(le_int32 index, float xAdjustment);
|
||||
inline void adjustYPlacement(le_int32 index, float yAdjustment);
|
||||
inline void adjustXAdvance(le_int32 index, float xAdjustment);
|
||||
inline void adjustYAdvance(le_int32 index, float yAdjustment);
|
||||
|
||||
void clearEntryPoint(le_int32 index);
|
||||
void clearExitPoint(le_int32 index);
|
||||
void setEntryPoint(le_int32 index, LEPoint &newEntryPoint, le_bool baselineIsLogicalEnd);
|
||||
void setExitPoint(le_int32 index, LEPoint &newExitPoint, le_bool baselineIsLogicalEnd);
|
||||
void setCursiveGlyph(le_int32 index, le_bool baselineIsLogicalEnd);
|
||||
|
||||
void applyCursiveAdjustments(LEGlyphStorage &glyphStorage, le_bool rightToLeft, const LEFontInstance *fontInstance);
|
||||
};
|
||||
|
||||
inline GlyphPositionAdjustments::Adjustment::Adjustment()
|
||||
: xPlacement(0), yPlacement(0), xAdvance(0), yAdvance(0), baseOffset(-1)
|
||||
{
|
||||
// nothing else to do!
|
||||
}
|
||||
|
||||
inline GlyphPositionAdjustments::Adjustment::Adjustment(float xPlace, float yPlace, float xAdv, float yAdv, le_int32 baseOff)
|
||||
: xPlacement(xPlace), yPlacement(yPlace), xAdvance(xAdv), yAdvance(yAdv), baseOffset(baseOff)
|
||||
{
|
||||
// nothing else to do!
|
||||
}
|
||||
|
||||
inline GlyphPositionAdjustments::Adjustment::~Adjustment()
|
||||
{
|
||||
// nothing to do!
|
||||
}
|
||||
|
||||
inline float GlyphPositionAdjustments::Adjustment::getXPlacement() const
|
||||
{
|
||||
return xPlacement;
|
||||
}
|
||||
|
||||
inline float GlyphPositionAdjustments::Adjustment::getYPlacement() const
|
||||
{
|
||||
return yPlacement;
|
||||
}
|
||||
|
||||
inline float GlyphPositionAdjustments::Adjustment::getXAdvance() const
|
||||
{
|
||||
return xAdvance;
|
||||
}
|
||||
|
||||
inline float GlyphPositionAdjustments::Adjustment::getYAdvance() const
|
||||
{
|
||||
return yAdvance;
|
||||
}
|
||||
|
||||
inline le_int32 GlyphPositionAdjustments::Adjustment::getBaseOffset() const
|
||||
{
|
||||
return baseOffset;
|
||||
}
|
||||
|
||||
inline void GlyphPositionAdjustments::Adjustment::setXPlacement(float newXPlacement)
|
||||
{
|
||||
xPlacement = newXPlacement;
|
||||
}
|
||||
|
||||
inline void GlyphPositionAdjustments::Adjustment::setYPlacement(float newYPlacement)
|
||||
{
|
||||
yPlacement = newYPlacement;
|
||||
}
|
||||
|
||||
inline void GlyphPositionAdjustments::Adjustment::setXAdvance(float newXAdvance)
|
||||
{
|
||||
xAdvance = newXAdvance;
|
||||
}
|
||||
|
||||
inline void GlyphPositionAdjustments::Adjustment::setYAdvance(float newYAdvance)
|
||||
{
|
||||
yAdvance = newYAdvance;
|
||||
}
|
||||
|
||||
inline void GlyphPositionAdjustments::Adjustment::setBaseOffset(le_int32 newBaseOffset)
|
||||
{
|
||||
baseOffset = newBaseOffset;
|
||||
}
|
||||
|
||||
inline void GlyphPositionAdjustments::Adjustment::adjustXPlacement(float xAdjustment)
|
||||
{
|
||||
xPlacement += xAdjustment;
|
||||
}
|
||||
|
||||
inline void GlyphPositionAdjustments::Adjustment::adjustYPlacement(float yAdjustment)
|
||||
{
|
||||
yPlacement += yAdjustment;
|
||||
}
|
||||
|
||||
inline void GlyphPositionAdjustments::Adjustment::adjustXAdvance(float xAdjustment)
|
||||
{
|
||||
xAdvance += xAdjustment;
|
||||
}
|
||||
|
||||
inline void GlyphPositionAdjustments::Adjustment::adjustYAdvance(float yAdjustment)
|
||||
{
|
||||
yAdvance += yAdjustment;
|
||||
}
|
||||
|
||||
inline GlyphPositionAdjustments::EntryExitPoint::EntryExitPoint()
|
||||
: fFlags(0)
|
||||
{
|
||||
fEntryPoint.fX = fEntryPoint.fY = fExitPoint.fX = fExitPoint.fY = 0;
|
||||
}
|
||||
|
||||
inline GlyphPositionAdjustments::EntryExitPoint::~EntryExitPoint()
|
||||
{
|
||||
// nothing special to do
|
||||
}
|
||||
|
||||
inline le_bool GlyphPositionAdjustments::EntryExitPoint::isCursiveGlyph() const
|
||||
{
|
||||
return (fFlags & EEF_IS_CURSIVE_GLYPH) != 0;
|
||||
}
|
||||
|
||||
inline le_bool GlyphPositionAdjustments::EntryExitPoint::baselineIsLogicalEnd() const
|
||||
{
|
||||
return (fFlags & EEF_BASELINE_IS_LOGICAL_END) != 0;
|
||||
}
|
||||
|
||||
inline void GlyphPositionAdjustments::EntryExitPoint::clearEntryPoint()
|
||||
{
|
||||
fFlags &= ~EEF_HAS_ENTRY_POINT;
|
||||
}
|
||||
|
||||
inline void GlyphPositionAdjustments::EntryExitPoint::clearExitPoint()
|
||||
{
|
||||
fFlags &= ~EEF_HAS_EXIT_POINT;
|
||||
}
|
||||
|
||||
inline void GlyphPositionAdjustments::EntryExitPoint::setEntryPoint(LEPoint &newEntryPoint, le_bool baselineIsLogicalEnd)
|
||||
{
|
||||
if (baselineIsLogicalEnd) {
|
||||
fFlags |= (EEF_HAS_ENTRY_POINT | EEF_IS_CURSIVE_GLYPH | EEF_BASELINE_IS_LOGICAL_END);
|
||||
} else {
|
||||
fFlags |= (EEF_HAS_ENTRY_POINT | EEF_IS_CURSIVE_GLYPH);
|
||||
}
|
||||
|
||||
fEntryPoint = newEntryPoint;
|
||||
}
|
||||
|
||||
inline void GlyphPositionAdjustments::EntryExitPoint::setExitPoint(LEPoint &newExitPoint, le_bool baselineIsLogicalEnd)
|
||||
{
|
||||
if (baselineIsLogicalEnd) {
|
||||
fFlags |= (EEF_HAS_EXIT_POINT | EEF_IS_CURSIVE_GLYPH | EEF_BASELINE_IS_LOGICAL_END);
|
||||
} else {
|
||||
fFlags |= (EEF_HAS_EXIT_POINT | EEF_IS_CURSIVE_GLYPH);
|
||||
}
|
||||
|
||||
fExitPoint = newExitPoint;
|
||||
}
|
||||
|
||||
inline void GlyphPositionAdjustments::EntryExitPoint::setCursiveGlyph(le_bool baselineIsLogicalEnd)
|
||||
{
|
||||
if (baselineIsLogicalEnd) {
|
||||
fFlags |= (EEF_IS_CURSIVE_GLYPH | EEF_BASELINE_IS_LOGICAL_END);
|
||||
} else {
|
||||
fFlags |= EEF_IS_CURSIVE_GLYPH;
|
||||
}
|
||||
}
|
||||
|
||||
inline le_bool GlyphPositionAdjustments::isCursiveGlyph(le_int32 index) const
|
||||
{
|
||||
return fEntryExitPoints != NULL && fEntryExitPoints[index].isCursiveGlyph();
|
||||
}
|
||||
|
||||
inline le_bool GlyphPositionAdjustments::baselineIsLogicalEnd(le_int32 index) const
|
||||
{
|
||||
return fEntryExitPoints != NULL && fEntryExitPoints[index].baselineIsLogicalEnd();
|
||||
}
|
||||
|
||||
inline float GlyphPositionAdjustments::getXPlacement(le_int32 index) const
|
||||
{
|
||||
return fAdjustments[index].getXPlacement();
|
||||
}
|
||||
|
||||
inline float GlyphPositionAdjustments::getYPlacement(le_int32 index) const
|
||||
{
|
||||
return fAdjustments[index].getYPlacement();
|
||||
}
|
||||
|
||||
inline float GlyphPositionAdjustments::getXAdvance(le_int32 index) const
|
||||
{
|
||||
return fAdjustments[index].getXAdvance();
|
||||
}
|
||||
|
||||
inline float GlyphPositionAdjustments::getYAdvance(le_int32 index) const
|
||||
{
|
||||
return fAdjustments[index].getYAdvance();
|
||||
}
|
||||
|
||||
|
||||
inline le_int32 GlyphPositionAdjustments::getBaseOffset(le_int32 index) const
|
||||
{
|
||||
return fAdjustments[index].getBaseOffset();
|
||||
}
|
||||
|
||||
inline void GlyphPositionAdjustments::setXPlacement(le_int32 index, float newXPlacement)
|
||||
{
|
||||
fAdjustments[index].setXPlacement(newXPlacement);
|
||||
}
|
||||
|
||||
inline void GlyphPositionAdjustments::setYPlacement(le_int32 index, float newYPlacement)
|
||||
{
|
||||
fAdjustments[index].setYPlacement(newYPlacement);
|
||||
}
|
||||
|
||||
inline void GlyphPositionAdjustments::setXAdvance(le_int32 index, float newXAdvance)
|
||||
{
|
||||
fAdjustments[index].setXAdvance(newXAdvance);
|
||||
}
|
||||
|
||||
inline void GlyphPositionAdjustments::setYAdvance(le_int32 index, float newYAdvance)
|
||||
{
|
||||
fAdjustments[index].setYAdvance(newYAdvance);
|
||||
}
|
||||
|
||||
inline void GlyphPositionAdjustments::setBaseOffset(le_int32 index, le_int32 newBaseOffset)
|
||||
{
|
||||
fAdjustments[index].setBaseOffset(newBaseOffset);
|
||||
}
|
||||
|
||||
inline void GlyphPositionAdjustments::adjustXPlacement(le_int32 index, float xAdjustment)
|
||||
{
|
||||
fAdjustments[index].adjustXPlacement(xAdjustment);
|
||||
}
|
||||
|
||||
inline void GlyphPositionAdjustments::adjustYPlacement(le_int32 index, float yAdjustment)
|
||||
{
|
||||
fAdjustments[index].adjustYPlacement(yAdjustment);
|
||||
}
|
||||
|
||||
inline void GlyphPositionAdjustments::adjustXAdvance(le_int32 index, float xAdjustment)
|
||||
{
|
||||
fAdjustments[index].adjustXAdvance(xAdjustment);
|
||||
}
|
||||
|
||||
inline void GlyphPositionAdjustments::adjustYAdvance(le_int32 index, float yAdjustment)
|
||||
{
|
||||
fAdjustments[index].adjustYAdvance(yAdjustment);
|
||||
}
|
||||
|
||||
inline le_bool GlyphPositionAdjustments::hasCursiveGlyphs() const
|
||||
{
|
||||
return fEntryExitPoints != NULL;
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
|
@ -1,40 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "LEFontInstance.h"
|
||||
#include "OpenTypeTables.h"
|
||||
#include "Lookups.h"
|
||||
#include "GlyphDefinitionTables.h"
|
||||
#include "GlyphPositioningTables.h"
|
||||
#include "GlyphPosnLookupProc.h"
|
||||
#include "CursiveAttachmentSubtables.h"
|
||||
#include "LEGlyphStorage.h"
|
||||
#include "GlyphPositionAdjustments.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
void GlyphPositioningTableHeader::process(const LEReferenceTo<GlyphPositioningTableHeader> &base, LEGlyphStorage &glyphStorage, GlyphPositionAdjustments *glyphPositionAdjustments, le_bool rightToLeft,
|
||||
LETag scriptTag, LETag languageTag,
|
||||
const LEReferenceTo<GlyphDefinitionTableHeader> &glyphDefinitionTableHeader, LEErrorCode &success,
|
||||
const LEFontInstance *fontInstance, const FeatureMap *featureMap, le_int32 featureMapCount, le_bool featureOrder) const
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return;
|
||||
}
|
||||
|
||||
GlyphPositioningLookupProcessor processor(base, scriptTag, languageTag, featureMap, featureMapCount, featureOrder, success);
|
||||
if (LE_FAILURE(success)) {
|
||||
return;
|
||||
}
|
||||
|
||||
processor.process(glyphStorage, glyphPositionAdjustments, rightToLeft, glyphDefinitionTableHeader, fontInstance, success);
|
||||
|
||||
glyphPositionAdjustments->applyCursiveAdjustments(glyphStorage, rightToLeft, fontInstance);
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
|
@ -1,54 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __GLYPHPOSITIONINGTABLES_H
|
||||
#define __GLYPHPOSITIONINGTABLES_H
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \internal
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "OpenTypeTables.h"
|
||||
#include "Lookups.h"
|
||||
#include "GlyphLookupTables.h"
|
||||
#include "LETableReference.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class LEFontInstance;
|
||||
class LEGlyphStorage;
|
||||
class LEGlyphFilter;
|
||||
class GlyphPositionAdjustments;
|
||||
struct GlyphDefinitionTableHeader;
|
||||
|
||||
struct GlyphPositioningTableHeader : public GlyphLookupTableHeader
|
||||
{
|
||||
void process(const LEReferenceTo<GlyphPositioningTableHeader> &base, LEGlyphStorage &glyphStorage, GlyphPositionAdjustments *glyphPositionAdjustments,
|
||||
le_bool rightToLeft, LETag scriptTag, LETag languageTag,
|
||||
const LEReferenceTo<GlyphDefinitionTableHeader> &glyphDefinitionTableHeader, LEErrorCode &success,
|
||||
const LEFontInstance *fontInstance, const FeatureMap *featureMap, le_int32 featureMapCount, le_bool featureOrder) const;
|
||||
};
|
||||
|
||||
enum GlyphPositioningSubtableTypes
|
||||
{
|
||||
gpstSingle = 1,
|
||||
gpstPair = 2,
|
||||
gpstCursive = 3,
|
||||
gpstMarkToBase = 4,
|
||||
gpstMarkToLigature = 5,
|
||||
gpstMarkToMark = 6,
|
||||
gpstContext = 7,
|
||||
gpstChainedContext = 8,
|
||||
gpstExtension = 9
|
||||
};
|
||||
|
||||
typedef LookupSubtable GlyphPositioningSubtable;
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
|
@ -1,163 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
* (C) Copyright IBM Corp. 1998 - 2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "LEFontInstance.h"
|
||||
#include "OpenTypeTables.h"
|
||||
#include "ICUFeatures.h"
|
||||
#include "Lookups.h"
|
||||
#include "ScriptAndLanguage.h"
|
||||
#include "GlyphDefinitionTables.h"
|
||||
#include "GlyphPositioningTables.h"
|
||||
#include "SinglePositioningSubtables.h"
|
||||
#include "PairPositioningSubtables.h"
|
||||
#include "CursiveAttachmentSubtables.h"
|
||||
#include "MarkToBasePosnSubtables.h"
|
||||
#include "MarkToLigaturePosnSubtables.h"
|
||||
#include "MarkToMarkPosnSubtables.h"
|
||||
//#include "ContextualPositioningSubtables.h"
|
||||
#include "ContextualSubstSubtables.h"
|
||||
#include "ExtensionSubtables.h"
|
||||
#include "LookupProcessor.h"
|
||||
#include "GlyphPosnLookupProc.h"
|
||||
#include "LESwaps.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
// Aside from the names, the contextual positioning subtables are
|
||||
// the same as the contextual substitution subtables.
|
||||
typedef ContextualSubstitutionSubtable ContextualPositioningSubtable;
|
||||
typedef ChainingContextualSubstitutionSubtable ChainingContextualPositioningSubtable;
|
||||
|
||||
GlyphPositioningLookupProcessor::GlyphPositioningLookupProcessor(
|
||||
const LEReferenceTo<GlyphPositioningTableHeader> &glyphPositioningTableHeader,
|
||||
LETag scriptTag,
|
||||
LETag languageTag,
|
||||
const FeatureMap *featureMap,
|
||||
le_int32 featureMapCount,
|
||||
le_bool featureOrder,
|
||||
LEErrorCode& success)
|
||||
: LookupProcessor(
|
||||
glyphPositioningTableHeader,
|
||||
SWAPW(glyphPositioningTableHeader->scriptListOffset),
|
||||
SWAPW(glyphPositioningTableHeader->featureListOffset),
|
||||
SWAPW(glyphPositioningTableHeader->lookupListOffset),
|
||||
scriptTag,
|
||||
languageTag,
|
||||
featureMap,
|
||||
featureMapCount,
|
||||
featureOrder,
|
||||
success
|
||||
)
|
||||
{
|
||||
// anything?
|
||||
}
|
||||
|
||||
GlyphPositioningLookupProcessor::GlyphPositioningLookupProcessor()
|
||||
{
|
||||
}
|
||||
|
||||
le_uint32 GlyphPositioningLookupProcessor::applySubtable(const LEReferenceTo<LookupSubtable> &lookupSubtable, le_uint16 lookupType,
|
||||
GlyphIterator *glyphIterator,
|
||||
const LEFontInstance *fontInstance,
|
||||
LEErrorCode& success) const
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
le_uint32 delta = 0;
|
||||
|
||||
switch(lookupType)
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
|
||||
case gpstSingle:
|
||||
{
|
||||
LEReferenceTo<SinglePositioningSubtable> subtable(lookupSubtable, success);
|
||||
|
||||
delta = subtable->process(subtable, glyphIterator, fontInstance, success);
|
||||
break;
|
||||
}
|
||||
|
||||
case gpstPair:
|
||||
{
|
||||
LEReferenceTo<PairPositioningSubtable> subtable(lookupSubtable, success);
|
||||
|
||||
delta = subtable->process(subtable, glyphIterator, fontInstance, success);
|
||||
break;
|
||||
}
|
||||
|
||||
case gpstCursive:
|
||||
{
|
||||
LEReferenceTo<CursiveAttachmentSubtable> subtable(lookupSubtable, success);
|
||||
|
||||
delta = subtable->process(subtable, glyphIterator, fontInstance, success);
|
||||
break;
|
||||
}
|
||||
|
||||
case gpstMarkToBase:
|
||||
{
|
||||
LEReferenceTo<MarkToBasePositioningSubtable> subtable(lookupSubtable, success);
|
||||
|
||||
delta = subtable->process(subtable, glyphIterator, fontInstance, success);
|
||||
break;
|
||||
}
|
||||
|
||||
case gpstMarkToLigature:
|
||||
{
|
||||
LEReferenceTo<MarkToLigaturePositioningSubtable> subtable(lookupSubtable, success);
|
||||
|
||||
delta = subtable->process(subtable, glyphIterator, fontInstance, success);
|
||||
break;
|
||||
}
|
||||
|
||||
case gpstMarkToMark:
|
||||
{
|
||||
LEReferenceTo<MarkToMarkPositioningSubtable> subtable(lookupSubtable, success);
|
||||
|
||||
delta = subtable->process(subtable, glyphIterator, fontInstance, success);
|
||||
break;
|
||||
}
|
||||
|
||||
case gpstContext:
|
||||
{
|
||||
LEReferenceTo<ContextualPositioningSubtable> subtable(lookupSubtable, success);
|
||||
|
||||
delta = subtable->process(this, glyphIterator, fontInstance, success);
|
||||
break;
|
||||
}
|
||||
|
||||
case gpstChainedContext:
|
||||
{
|
||||
LEReferenceTo<ChainingContextualPositioningSubtable> subtable(lookupSubtable, success);
|
||||
|
||||
delta = subtable->process(this, glyphIterator, fontInstance, success);
|
||||
break;
|
||||
}
|
||||
|
||||
case gpstExtension:
|
||||
{
|
||||
LEReferenceTo<ExtensionSubtable> subtable(lookupSubtable, success);
|
||||
|
||||
delta = subtable->process(this, lookupType, glyphIterator, fontInstance, success);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return delta;
|
||||
}
|
||||
|
||||
GlyphPositioningLookupProcessor::~GlyphPositioningLookupProcessor()
|
||||
{
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
|
@ -1,54 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __GLYPHPOSITIONINGLOOKUPPROCESSOR_H
|
||||
#define __GLYPHPOSITIONINGLOOKUPPROCESSOR_H
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \internal
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "LEFontInstance.h"
|
||||
#include "OpenTypeTables.h"
|
||||
#include "Lookups.h"
|
||||
#include "ICUFeatures.h"
|
||||
#include "GlyphDefinitionTables.h"
|
||||
#include "GlyphPositioningTables.h"
|
||||
#include "GlyphIterator.h"
|
||||
#include "LookupProcessor.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class GlyphPositioningLookupProcessor : public LookupProcessor
|
||||
{
|
||||
public:
|
||||
GlyphPositioningLookupProcessor(const LEReferenceTo<GlyphPositioningTableHeader> &glyphPositioningTableHeader,
|
||||
LETag scriptTag,
|
||||
LETag languageTag,
|
||||
const FeatureMap *featureMap,
|
||||
le_int32 featureMapCount,
|
||||
le_bool featureOrder,
|
||||
LEErrorCode& success);
|
||||
|
||||
virtual ~GlyphPositioningLookupProcessor();
|
||||
|
||||
virtual le_uint32 applySubtable(const LEReferenceTo<LookupSubtable> &lookupSubtable, le_uint16 lookupType, GlyphIterator *glyphIterator,
|
||||
const LEFontInstance *fontInstance, LEErrorCode& success) const;
|
||||
|
||||
protected:
|
||||
GlyphPositioningLookupProcessor();
|
||||
|
||||
private:
|
||||
|
||||
GlyphPositioningLookupProcessor(const GlyphPositioningLookupProcessor &other); // forbid copying of this class
|
||||
GlyphPositioningLookupProcessor &operator=(const GlyphPositioningLookupProcessor &other); // forbid copying of this class
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
|
@ -1,134 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "LEGlyphFilter.h"
|
||||
#include "LEFontInstance.h"
|
||||
#include "OpenTypeTables.h"
|
||||
#include "ICUFeatures.h"
|
||||
#include "Lookups.h"
|
||||
#include "ScriptAndLanguage.h"
|
||||
#include "GlyphDefinitionTables.h"
|
||||
#include "GlyphSubstitutionTables.h"
|
||||
#include "SingleSubstitutionSubtables.h"
|
||||
#include "MultipleSubstSubtables.h"
|
||||
#include "AlternateSubstSubtables.h"
|
||||
#include "LigatureSubstSubtables.h"
|
||||
#include "ContextualSubstSubtables.h"
|
||||
#include "ExtensionSubtables.h"
|
||||
#include "LookupProcessor.h"
|
||||
#include "GlyphSubstLookupProc.h"
|
||||
#include "LESwaps.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
GlyphSubstitutionLookupProcessor::GlyphSubstitutionLookupProcessor(
|
||||
const LEReferenceTo<GlyphSubstitutionTableHeader> &glyphSubstitutionTableHeader,
|
||||
LETag scriptTag,
|
||||
LETag languageTag,
|
||||
const LEGlyphFilter *filter,
|
||||
const FeatureMap *featureMap,
|
||||
le_int32 featureMapCount,
|
||||
le_bool featureOrder,
|
||||
LEErrorCode& success)
|
||||
: LookupProcessor(
|
||||
glyphSubstitutionTableHeader,
|
||||
SWAPW(glyphSubstitutionTableHeader->scriptListOffset),
|
||||
SWAPW(glyphSubstitutionTableHeader->featureListOffset),
|
||||
SWAPW(glyphSubstitutionTableHeader->lookupListOffset),
|
||||
scriptTag, languageTag, featureMap, featureMapCount, featureOrder, success), fFilter(filter)
|
||||
{
|
||||
// anything?
|
||||
}
|
||||
|
||||
GlyphSubstitutionLookupProcessor::GlyphSubstitutionLookupProcessor()
|
||||
{
|
||||
}
|
||||
|
||||
le_uint32 GlyphSubstitutionLookupProcessor::applySubtable(const LEReferenceTo<LookupSubtable> &lookupSubtable, le_uint16 lookupType,
|
||||
GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
le_uint32 delta = 0;
|
||||
|
||||
switch(lookupType)
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
|
||||
case gsstSingle:
|
||||
{
|
||||
const LEReferenceTo<SingleSubstitutionSubtable> subtable(lookupSubtable, success);
|
||||
|
||||
delta = subtable->process(subtable, glyphIterator, success, fFilter);
|
||||
break;
|
||||
}
|
||||
|
||||
case gsstMultiple:
|
||||
{
|
||||
const LEReferenceTo<MultipleSubstitutionSubtable> subtable(lookupSubtable, success);
|
||||
|
||||
delta = subtable->process(subtable, glyphIterator, success, fFilter);
|
||||
break;
|
||||
}
|
||||
|
||||
case gsstAlternate:
|
||||
{
|
||||
const LEReferenceTo<AlternateSubstitutionSubtable> subtable(lookupSubtable, success);
|
||||
|
||||
delta = subtable->process(subtable, glyphIterator, success, fFilter);
|
||||
break;
|
||||
}
|
||||
|
||||
case gsstLigature:
|
||||
{
|
||||
const LEReferenceTo<LigatureSubstitutionSubtable> subtable(lookupSubtable, success);
|
||||
|
||||
delta = subtable->process(subtable, glyphIterator, success, fFilter);
|
||||
break;
|
||||
}
|
||||
|
||||
case gsstContext:
|
||||
{
|
||||
const LEReferenceTo<ContextualSubstitutionSubtable> subtable(lookupSubtable, success);
|
||||
|
||||
delta = subtable->process(this, glyphIterator, fontInstance, success);
|
||||
break;
|
||||
}
|
||||
|
||||
case gsstChainingContext:
|
||||
{
|
||||
const LEReferenceTo<ChainingContextualSubstitutionSubtable> subtable(lookupSubtable, success);
|
||||
|
||||
delta = subtable->process(this, glyphIterator, fontInstance, success);
|
||||
break;
|
||||
}
|
||||
|
||||
case gsstExtension:
|
||||
{
|
||||
const LEReferenceTo<ExtensionSubtable> subtable(lookupSubtable, success);
|
||||
|
||||
delta = subtable->process(this, lookupType, glyphIterator, fontInstance, success);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return delta;
|
||||
}
|
||||
|
||||
GlyphSubstitutionLookupProcessor::~GlyphSubstitutionLookupProcessor()
|
||||
{
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
|
@ -1,57 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __GLYPHSUBSTITUTIONLOOKUPPROCESSOR_H
|
||||
#define __GLYPHSUBSTITUTIONLOOKUPPROCESSOR_H
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \internal
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "LEGlyphFilter.h"
|
||||
#include "LEFontInstance.h"
|
||||
#include "OpenTypeTables.h"
|
||||
#include "Lookups.h"
|
||||
#include "ICUFeatures.h"
|
||||
#include "GlyphDefinitionTables.h"
|
||||
#include "GlyphSubstitutionTables.h"
|
||||
#include "GlyphIterator.h"
|
||||
#include "LookupProcessor.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class GlyphSubstitutionLookupProcessor : public LookupProcessor
|
||||
{
|
||||
public:
|
||||
GlyphSubstitutionLookupProcessor(const LEReferenceTo<GlyphSubstitutionTableHeader> &glyphSubstitutionTableHeader,
|
||||
LETag scriptTag,
|
||||
LETag languageTag,
|
||||
const LEGlyphFilter *filter,
|
||||
const FeatureMap *featureMap,
|
||||
le_int32 featureMapCount,
|
||||
le_bool featureOrder,
|
||||
LEErrorCode& success);
|
||||
|
||||
virtual ~GlyphSubstitutionLookupProcessor();
|
||||
|
||||
virtual le_uint32 applySubtable(const LEReferenceTo<LookupSubtable> &lookupSubtable, le_uint16 lookupType, GlyphIterator *glyphIterator,
|
||||
const LEFontInstance *fontInstance, LEErrorCode& success) const;
|
||||
|
||||
protected:
|
||||
GlyphSubstitutionLookupProcessor();
|
||||
|
||||
private:
|
||||
const LEGlyphFilter *fFilter;
|
||||
|
||||
GlyphSubstitutionLookupProcessor(const GlyphSubstitutionLookupProcessor &other); // forbid copying of this class
|
||||
GlyphSubstitutionLookupProcessor &operator=(const GlyphSubstitutionLookupProcessor &other); // forbid copying of this class
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
|
@ -1,42 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "LEGlyphFilter.h"
|
||||
#include "OpenTypeTables.h"
|
||||
#include "Lookups.h"
|
||||
#include "GlyphDefinitionTables.h"
|
||||
#include "GlyphSubstitutionTables.h"
|
||||
#include "GlyphSubstLookupProc.h"
|
||||
#include "ScriptAndLanguage.h"
|
||||
#include "LEGlyphStorage.h"
|
||||
#include "LESwaps.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
le_int32 GlyphSubstitutionTableHeader::process(const LEReferenceTo<GlyphSubstitutionTableHeader> &base,
|
||||
LEGlyphStorage &glyphStorage,
|
||||
le_bool rightToLeft,
|
||||
LETag scriptTag,
|
||||
LETag languageTag,
|
||||
const LEReferenceTo<GlyphDefinitionTableHeader> &glyphDefinitionTableHeader,
|
||||
const LEGlyphFilter *filter,
|
||||
const FeatureMap *featureMap,
|
||||
le_int32 featureMapCount,
|
||||
le_bool featureOrder,
|
||||
LEErrorCode &success) const
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
GlyphSubstitutionLookupProcessor processor(base, scriptTag, languageTag, filter, featureMap, featureMapCount, featureOrder, success);
|
||||
return processor.process(glyphStorage, NULL, rightToLeft, glyphDefinitionTableHeader, NULL, success);
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
|
@ -1,58 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __GLYPHSUBSTITUTIONTABLES_H
|
||||
#define __GLYPHSUBSTITUTIONTABLES_H
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \internal
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "OpenTypeTables.h"
|
||||
#include "Lookups.h"
|
||||
#include "GlyphLookupTables.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class LEGlyphStorage;
|
||||
class LEGlyphFilter;
|
||||
struct GlyphDefinitionTableHeader;
|
||||
|
||||
struct GlyphSubstitutionTableHeader : public GlyphLookupTableHeader
|
||||
{
|
||||
le_int32 process(const LEReferenceTo<GlyphSubstitutionTableHeader> &base,
|
||||
LEGlyphStorage &glyphStorage,
|
||||
le_bool rightToLeft,
|
||||
LETag scriptTag,
|
||||
LETag languageTag,
|
||||
const LEReferenceTo<GlyphDefinitionTableHeader> &glyphDefinitionTableHeader,
|
||||
const LEGlyphFilter *filter,
|
||||
const FeatureMap *featureMap,
|
||||
le_int32 featureMapCount,
|
||||
le_bool featureOrder,
|
||||
LEErrorCode &success) const;
|
||||
};
|
||||
|
||||
enum GlyphSubstitutionSubtableTypes
|
||||
{
|
||||
gsstSingle = 1,
|
||||
gsstMultiple = 2,
|
||||
gsstAlternate = 3,
|
||||
gsstLigature = 4,
|
||||
gsstContext = 5,
|
||||
gsstChainingContext = 6,
|
||||
gsstExtension = 7,
|
||||
gsstReverseChaining = 8
|
||||
};
|
||||
|
||||
typedef LookupSubtable GlyphSubstitutionSubtable;
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
|
@ -1,86 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
* HanLayoutEngine.cpp: OpenType processing for Han fonts.
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved.
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "LEScripts.h"
|
||||
#include "LELanguages.h"
|
||||
|
||||
#include "LayoutEngine.h"
|
||||
#include "OpenTypeLayoutEngine.h"
|
||||
#include "HanLayoutEngine.h"
|
||||
#include "ScriptAndLanguageTags.h"
|
||||
#include "LEGlyphStorage.h"
|
||||
#include "OpenTypeTables.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(HanOpenTypeLayoutEngine)
|
||||
|
||||
#define loclFeatureTag LE_LOCL_FEATURE_TAG
|
||||
#define smplFeatureTag LE_SMPL_FEATURE_TAG
|
||||
#define tradFeatureTag LE_TRAD_FEATURE_TAG
|
||||
|
||||
#define loclFeatureMask 0x80000000UL
|
||||
#define smplFeatureMask 0x40000000UL
|
||||
#define tradFeatureMask 0x20000000UL
|
||||
|
||||
static const FeatureMap featureMap[] =
|
||||
{
|
||||
{loclFeatureTag, loclFeatureMask},
|
||||
{smplFeatureTag, smplFeatureMask},
|
||||
{tradFeatureTag, tradFeatureMask}
|
||||
};
|
||||
|
||||
static const le_int32 featureMapCount = LE_ARRAY_SIZE(featureMap);
|
||||
|
||||
#define features (loclFeatureMask)
|
||||
|
||||
HanOpenTypeLayoutEngine::HanOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
|
||||
le_int32 typoFlags, const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTable, LEErrorCode &success)
|
||||
: OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success)
|
||||
{
|
||||
fFeatureMap = featureMap;
|
||||
fFeatureMapCount = featureMapCount;
|
||||
}
|
||||
|
||||
HanOpenTypeLayoutEngine::~HanOpenTypeLayoutEngine()
|
||||
{
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
le_int32 HanOpenTypeLayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool /*rightToLeft*/,
|
||||
LEUnicode *&/*outChars*/, LEGlyphStorage &glyphStorage, LEErrorCode &success)
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (chars == NULL || offset < 0 || count < 0 || max < 0 || offset >= max || offset + count > max) {
|
||||
success = LE_ILLEGAL_ARGUMENT_ERROR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
glyphStorage.allocateGlyphArray(count, FALSE, success);
|
||||
glyphStorage.allocateAuxData(success);
|
||||
|
||||
if (LE_FAILURE(success)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// FIXME: do we want to add the 'trad' feature for 'ZHT' and the
|
||||
// 'smpl' feature for 'ZHS'? If we do this, we can remove the exact
|
||||
// flag from the language tag lookups, so we can use these features
|
||||
// with the default LangSys...
|
||||
for (le_int32 i = 0; i < count; i += 1) {
|
||||
glyphStorage.setAuxData(i, features, success);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
|
@ -1,107 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
|
||||
/*
|
||||
* HanLayoutEngine.h: OpenType processing for Han fonts.
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2014 - All Rights Reserved.
|
||||
*/
|
||||
|
||||
#ifndef __HANLAYOUTENGINE_H
|
||||
#define __HANLAYOUTENGINE_H
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "LEFontInstance.h"
|
||||
#include "LayoutEngine.h"
|
||||
#include "OpenTypeLayoutEngine.h"
|
||||
|
||||
#include "GlyphSubstitutionTables.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class LEGlyphStorage;
|
||||
|
||||
/**
|
||||
* This class implements OpenType layout for Han fonts. It overrides
|
||||
* the characerProcessing method to assign the correct OpenType feature
|
||||
* tags for the CJK language-specific forms.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class HanOpenTypeLayoutEngine : public OpenTypeLayoutEngine
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This is the main constructor. It constructs an instance of HanOpenTypeLayoutEngine for
|
||||
* a particular font, script and language. It takes the GSUB table as a parameter since
|
||||
* LayoutEngine::layoutEngineFactory has to read the GSUB table to know that it has a
|
||||
* Han OpenType font.
|
||||
*
|
||||
* @param fontInstance - the font
|
||||
* @param scriptCode - the script
|
||||
* @param langaugeCode - the language
|
||||
* @param gsubTable - the GSUB table
|
||||
* @param success - set to an error code if the operation fails
|
||||
*
|
||||
* @see LayoutEngine::layoutEngineFactory
|
||||
* @see OpenTypeLayoutEngine
|
||||
* @see ScriptAndLangaugeTags.h for script and language codes
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
HanOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
|
||||
le_int32 typoFlags, const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTablem, LEErrorCode &success);
|
||||
|
||||
|
||||
/**
|
||||
* The destructor, virtual for correct polymorphic invocation.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
virtual ~HanOpenTypeLayoutEngine();
|
||||
|
||||
/**
|
||||
* ICU "poor man's RTTI", returns a UClassID for the actual class.
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
virtual UClassID getDynamicClassID() const;
|
||||
|
||||
/**
|
||||
* ICU "poor man's RTTI", returns a UClassID for this class.
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
static UClassID getStaticClassID();
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* This method does Han OpenType character processing. It assigns the OpenType feature
|
||||
* tags to the characters to generate the correct language-specific variants.
|
||||
*
|
||||
* Input parameters:
|
||||
* @param chars - the input character context
|
||||
* @param offset - the index of the first character to process
|
||||
* @param count - the number of characters to process
|
||||
* @param max - the number of characters in the input context
|
||||
* @param rightToLeft - <code>TRUE</code> if the characters are in a right to left directional run
|
||||
* @param glyphStorage - the object holding the glyph storage. The char index and auxillary data arrays will be set.
|
||||
*
|
||||
* Output parameters:
|
||||
* @param outChars - the output character arrayt
|
||||
* @param charIndices - the output character index array
|
||||
* @param featureTags - the output feature tag array
|
||||
* @param success - set to an error code if the operation fails
|
||||
*
|
||||
* @return the output character count
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
virtual le_int32 characterProcessing(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft,
|
||||
LEUnicode *&outChars, LEGlyphStorage &glyphStorage, LEErrorCode &success);
|
||||
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
|
@ -1,340 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
* HangulLayoutEngine.cpp: OpenType processing for Han fonts.
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved.
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "LEScripts.h"
|
||||
#include "LELanguages.h"
|
||||
|
||||
#include "LayoutEngine.h"
|
||||
#include "OpenTypeLayoutEngine.h"
|
||||
#include "HangulLayoutEngine.h"
|
||||
#include "ScriptAndLanguageTags.h"
|
||||
#include "LEGlyphStorage.h"
|
||||
#include "OpenTypeTables.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(HangulOpenTypeLayoutEngine)
|
||||
|
||||
|
||||
#define FEATURE_MAP(name) {name ## FeatureTag, name ## FeatureMask}
|
||||
|
||||
#define LJMO_FIRST 0x1100
|
||||
#define LJMO_LAST 0x1159
|
||||
#define LJMO_FILL 0x115F
|
||||
#define LJMO_COUNT 19
|
||||
|
||||
#define VJMO_FIRST 0x1161
|
||||
#define VJMO_LAST 0x11A2
|
||||
#define VJMO_FILL 0x1160
|
||||
#define VJMO_COUNT 21
|
||||
|
||||
#define TJMO_FIRST 0x11A7
|
||||
#define TJMO_LAST 0x11F9
|
||||
#define TJMO_COUNT 28
|
||||
|
||||
#define HSYL_FIRST 0xAC00
|
||||
#define HSYL_COUNT 11172
|
||||
#define HSYL_LVCNT (VJMO_COUNT * TJMO_COUNT)
|
||||
|
||||
// Character classes
|
||||
enum
|
||||
{
|
||||
CC_L = 0,
|
||||
CC_V,
|
||||
CC_T,
|
||||
CC_LV,
|
||||
CC_LVT,
|
||||
CC_X,
|
||||
CC_COUNT
|
||||
};
|
||||
|
||||
// Action flags
|
||||
#define AF_L 1
|
||||
#define AF_V 2
|
||||
#define AF_T 4
|
||||
|
||||
// Actions
|
||||
#define a_N 0
|
||||
#define a_L (AF_L)
|
||||
#define a_V (AF_V)
|
||||
#define a_T (AF_T)
|
||||
#define a_VT (AF_V | AF_T)
|
||||
#define a_LV (AF_L | AF_V)
|
||||
#define a_LVT (AF_L | AF_V | AF_T)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int32_t newState;
|
||||
int32_t actionFlags;
|
||||
} StateTransition;
|
||||
|
||||
static const StateTransition stateTable[][CC_COUNT] =
|
||||
{
|
||||
// L V T LV LVT X
|
||||
{ {1, a_L}, {2, a_LV}, {3, a_LVT}, {2, a_LV}, {3, a_LVT}, {4, a_T}}, // 0 - start
|
||||
{ {1, a_L}, {2, a_V}, {3, a_VT}, {2, a_LV}, {3, a_LVT}, {-1, a_V}}, // 1 - L+
|
||||
{{-1, a_N}, {2, a_V}, {3, a_T}, {-1, a_N}, {-1, a_N}, {-1, a_N}}, // 2 - L+V+
|
||||
{{-1, a_N}, {-1, a_N}, {3, a_T}, {-1, a_N}, {-1, a_N}, {-1, a_N}}, // 3 - L+V+T*
|
||||
{{-1, a_N}, {-1, a_N}, {-1, a_N}, {-1, a_N}, {-1, a_N}, {4, a_T}} // 4 - X+
|
||||
};
|
||||
|
||||
|
||||
#define ccmpFeatureTag LE_CCMP_FEATURE_TAG
|
||||
#define ljmoFeatureTag LE_LJMO_FEATURE_TAG
|
||||
#define vjmoFeatureTag LE_VJMO_FEATURE_TAG
|
||||
#define tjmoFeatureTag LE_TJMO_FEATURE_TAG
|
||||
|
||||
#define ccmpFeatureMask 0x80000000UL
|
||||
#define ljmoFeatureMask 0x40000000UL
|
||||
#define vjmoFeatureMask 0x20000000UL
|
||||
#define tjmoFeatureMask 0x10000000UL
|
||||
|
||||
static const FeatureMap featureMap[] =
|
||||
{
|
||||
{ccmpFeatureTag, ccmpFeatureMask},
|
||||
{ljmoFeatureTag, ljmoFeatureMask},
|
||||
{vjmoFeatureTag, vjmoFeatureMask},
|
||||
{tjmoFeatureTag, tjmoFeatureMask}
|
||||
};
|
||||
|
||||
static const le_int32 featureMapCount = LE_ARRAY_SIZE(featureMap);
|
||||
|
||||
#define nullFeatures 0
|
||||
#define ljmoFeatures (ccmpFeatureMask | ljmoFeatureMask)
|
||||
#define vjmoFeatures (ccmpFeatureMask | vjmoFeatureMask | ljmoFeatureMask | tjmoFeatureMask)
|
||||
#define tjmoFeatures (ccmpFeatureMask | tjmoFeatureMask | ljmoFeatureMask | vjmoFeatureMask)
|
||||
|
||||
static le_int32 compose(LEUnicode lead, LEUnicode vowel, LEUnicode trail, LEUnicode &syllable)
|
||||
{
|
||||
le_int32 lIndex = lead - LJMO_FIRST;
|
||||
le_int32 vIndex = vowel - VJMO_FIRST;
|
||||
le_int32 tIndex = trail - TJMO_FIRST;
|
||||
le_int32 result = 3;
|
||||
|
||||
if ((lIndex < 0 || lIndex >= LJMO_COUNT ) || (vIndex < 0 || vIndex >= VJMO_COUNT)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (tIndex <= 0 || tIndex >= TJMO_COUNT) {
|
||||
tIndex = 0;
|
||||
result = 2;
|
||||
}
|
||||
|
||||
syllable = (LEUnicode) ((lIndex * VJMO_COUNT + vIndex) * TJMO_COUNT + tIndex + HSYL_FIRST);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static le_int32 decompose(LEUnicode syllable, LEUnicode &lead, LEUnicode &vowel, LEUnicode &trail)
|
||||
{
|
||||
le_int32 sIndex = syllable - HSYL_FIRST;
|
||||
|
||||
if (sIndex < 0 || sIndex >= HSYL_COUNT) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
lead = LJMO_FIRST + (sIndex / HSYL_LVCNT);
|
||||
vowel = VJMO_FIRST + (sIndex % HSYL_LVCNT) / TJMO_COUNT;
|
||||
trail = TJMO_FIRST + (sIndex % TJMO_COUNT);
|
||||
|
||||
if (trail == TJMO_FIRST) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
return 3;
|
||||
}
|
||||
|
||||
static le_int32 getCharClass(LEUnicode ch, LEUnicode &lead, LEUnicode &vowel, LEUnicode &trail)
|
||||
{
|
||||
lead = LJMO_FILL;
|
||||
vowel = VJMO_FILL;
|
||||
trail = TJMO_FIRST;
|
||||
|
||||
if (ch >= LJMO_FIRST && ch <= LJMO_LAST) {
|
||||
lead = ch;
|
||||
return CC_L;
|
||||
}
|
||||
|
||||
if (ch >= VJMO_FIRST && ch <= VJMO_LAST) {
|
||||
vowel = ch;
|
||||
return CC_V;
|
||||
}
|
||||
|
||||
if (ch > TJMO_FIRST && ch <= TJMO_LAST) {
|
||||
trail = ch;
|
||||
return CC_T;
|
||||
}
|
||||
|
||||
le_int32 c = decompose(ch, lead, vowel, trail);
|
||||
|
||||
if (c == 2) {
|
||||
return CC_LV;
|
||||
}
|
||||
|
||||
if (c == 3) {
|
||||
return CC_LVT;
|
||||
}
|
||||
|
||||
trail = ch;
|
||||
return CC_X;
|
||||
}
|
||||
|
||||
HangulOpenTypeLayoutEngine::HangulOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 /*languageCode*/,
|
||||
le_int32 typoFlags, const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTable, LEErrorCode &success)
|
||||
: OpenTypeLayoutEngine(fontInstance, scriptCode, korLanguageCode, typoFlags, gsubTable, success)
|
||||
{
|
||||
fFeatureMap = featureMap;
|
||||
fFeatureMapCount = featureMapCount;
|
||||
fFeatureOrder = TRUE;
|
||||
}
|
||||
|
||||
HangulOpenTypeLayoutEngine::HangulOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 /*languageCode*/,
|
||||
le_int32 typoFlags, LEErrorCode &success)
|
||||
: OpenTypeLayoutEngine(fontInstance, scriptCode, korLanguageCode, typoFlags, success)
|
||||
{
|
||||
fFeatureMap = featureMap;
|
||||
fFeatureMapCount = featureMapCount;
|
||||
fFeatureOrder = TRUE;
|
||||
}
|
||||
|
||||
HangulOpenTypeLayoutEngine::~HangulOpenTypeLayoutEngine()
|
||||
{
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
le_int32 HangulOpenTypeLayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft,
|
||||
LEUnicode *&outChars, LEGlyphStorage &glyphStorage, LEErrorCode &success)
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (chars == NULL || offset < 0 || count < 0 || max < 0 || offset >= max || offset + count > max) {
|
||||
success = LE_ILLEGAL_ARGUMENT_ERROR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
le_int32 worstCase = count * 3;
|
||||
|
||||
outChars = LE_NEW_ARRAY(LEUnicode, worstCase);
|
||||
|
||||
if (outChars == NULL) {
|
||||
success = LE_MEMORY_ALLOCATION_ERROR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
glyphStorage.allocateGlyphArray(worstCase, rightToLeft, success);
|
||||
glyphStorage.allocateAuxData(success);
|
||||
|
||||
if (LE_FAILURE(success)) {
|
||||
LE_DELETE_ARRAY(outChars);
|
||||
return 0;
|
||||
}
|
||||
|
||||
le_int32 outCharCount = 0;
|
||||
le_int32 limit = offset + count;
|
||||
le_int32 i = offset;
|
||||
|
||||
while (i < limit) {
|
||||
le_int32 state = 0;
|
||||
le_int32 inStart = i;
|
||||
le_int32 outStart = outCharCount;
|
||||
|
||||
while( i < limit) {
|
||||
LEUnicode lead = 0;
|
||||
LEUnicode vowel = 0;
|
||||
LEUnicode trail = 0;
|
||||
int32_t chClass = getCharClass(chars[i], lead, vowel, trail);
|
||||
const StateTransition transition = stateTable[state][chClass];
|
||||
|
||||
if (chClass == CC_X) {
|
||||
/* Any character of type X will be stored as a trail jamo */
|
||||
if ((transition.actionFlags & AF_T) != 0) {
|
||||
outChars[outCharCount] = trail;
|
||||
glyphStorage.setCharIndex(outCharCount, i-offset, success);
|
||||
glyphStorage.setAuxData(outCharCount++, nullFeatures, success);
|
||||
}
|
||||
} else {
|
||||
/* Any Hangul will be fully decomposed. Output the decomposed characters. */
|
||||
if ((transition.actionFlags & AF_L) != 0) {
|
||||
outChars[outCharCount] = lead;
|
||||
glyphStorage.setCharIndex(outCharCount, i-offset, success);
|
||||
glyphStorage.setAuxData(outCharCount++, ljmoFeatures, success);
|
||||
}
|
||||
|
||||
if ((transition.actionFlags & AF_V) != 0) {
|
||||
outChars[outCharCount] = vowel;
|
||||
glyphStorage.setCharIndex(outCharCount, i-offset, success);
|
||||
glyphStorage.setAuxData(outCharCount++, vjmoFeatures, success);
|
||||
}
|
||||
|
||||
if ((transition.actionFlags & AF_T) != 0) {
|
||||
outChars[outCharCount] = trail;
|
||||
glyphStorage.setCharIndex(outCharCount, i-offset, success);
|
||||
glyphStorage.setAuxData(outCharCount++, tjmoFeatures, success);
|
||||
}
|
||||
}
|
||||
|
||||
state = transition.newState;
|
||||
|
||||
/* Negative next state means stop. */
|
||||
if (state < 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
i += 1;
|
||||
}
|
||||
|
||||
le_int32 inLength = i - inStart;
|
||||
le_int32 outLength = outCharCount - outStart;
|
||||
|
||||
/*
|
||||
* See if the syllable can be composed into a single character. There are 5
|
||||
* possible cases:
|
||||
*
|
||||
* Input Decomposed to Compose to
|
||||
* LV L, V LV
|
||||
* LVT L, V, T LVT
|
||||
* L, V L, V LV, DEL
|
||||
* LV, T L, V, T LVT, DEL
|
||||
* L, V, T L, V, T LVT, DEL, DEL
|
||||
*/
|
||||
if ((inLength >= 1 && inLength <= 3) && (outLength == 2 || outLength == 3)) {
|
||||
LEUnicode syllable = 0x0000;
|
||||
LEUnicode lead = outChars[outStart];
|
||||
LEUnicode vowel = outChars[outStart + 1];
|
||||
LEUnicode trail = outLength == 3? outChars[outStart + 2] : TJMO_FIRST;
|
||||
|
||||
/*
|
||||
* If the composition consumes the whole decomposed syllable,
|
||||
* we can use it.
|
||||
*/
|
||||
if (compose(lead, vowel, trail, syllable) == outLength) {
|
||||
outCharCount = outStart;
|
||||
outChars[outCharCount] = syllable;
|
||||
glyphStorage.setCharIndex(outCharCount, inStart-offset, success);
|
||||
glyphStorage.setAuxData(outCharCount++, nullFeatures, success);
|
||||
|
||||
/*
|
||||
* Replace the rest of the input characters with DEL.
|
||||
*/
|
||||
for(le_int32 d = inStart + 1; d < i; d += 1) {
|
||||
outChars[outCharCount] = 0xFFFF;
|
||||
glyphStorage.setCharIndex(outCharCount, d - offset, success);
|
||||
glyphStorage.setAuxData(outCharCount++, nullFeatures, success);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
glyphStorage.adoptGlyphCount(outCharCount);
|
||||
return outCharCount;
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
|
@ -1,129 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2014 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __HANGULAYOUTENGINE_H
|
||||
#define __HANGULAYOUTENGINE_H
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "LEFontInstance.h"
|
||||
#include "LEGlyphFilter.h"
|
||||
#include "LayoutEngine.h"
|
||||
#include "OpenTypeLayoutEngine.h"
|
||||
|
||||
#include "GlyphSubstitutionTables.h"
|
||||
#include "GlyphDefinitionTables.h"
|
||||
#include "GlyphPositioningTables.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class MPreFixups;
|
||||
class LEGlyphStorage;
|
||||
|
||||
/**
|
||||
* This class implements OpenType layout for Old Hangul OpenType fonts, as
|
||||
* specified by Microsoft in "Creating and Supporting OpenType Fonts for
|
||||
* The Korean Hangul Script" (http://www.microsoft.com/typography/otfntdev/hangulot/default.htm)
|
||||
*
|
||||
* This class overrides the characterProcessing method to do Hangul character processing.
|
||||
* (See the MS spec. for more details)
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class HangulOpenTypeLayoutEngine : public OpenTypeLayoutEngine
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This is the main constructor. It constructs an instance of HangulOpenTypeLayoutEngine for
|
||||
* a particular font, script and language. It takes the GSUB table as a parameter since
|
||||
* LayoutEngine::layoutEngineFactory has to read the GSUB table to know that it has an
|
||||
* Hangul OpenType font.
|
||||
*
|
||||
* @param fontInstance - the font
|
||||
* @param scriptCode - the script
|
||||
* @param langaugeCode - the language
|
||||
* @param gsubTable - the GSUB table
|
||||
* @param success - set to an error code if the operation fails
|
||||
*
|
||||
* @see LayoutEngine::layoutEngineFactory
|
||||
* @see OpenTypeLayoutEngine
|
||||
* @see ScriptAndLangaugeTags.h for script and language codes
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
HangulOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
|
||||
le_int32 typoFlags, const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTable, LEErrorCode &success);
|
||||
|
||||
/**
|
||||
* This constructor is used when the font requires a "canned" GSUB table which can't be known
|
||||
* until after this constructor has been invoked.
|
||||
*
|
||||
* @param fontInstance - the font
|
||||
* @param scriptCode - the script
|
||||
* @param langaugeCode - the language
|
||||
* @param success - set to an error code if the operation fails
|
||||
*
|
||||
* @see OpenTypeLayoutEngine
|
||||
* @see ScriptAndLangaugeTags.h for script and language codes
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
HangulOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
|
||||
le_int32 typoFlags, LEErrorCode &success);
|
||||
|
||||
/**
|
||||
* The destructor, virtual for correct polymorphic invocation.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
virtual ~HangulOpenTypeLayoutEngine();
|
||||
|
||||
/**
|
||||
* ICU "poor man's RTTI", returns a UClassID for the actual class.
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
virtual UClassID getDynamicClassID() const;
|
||||
|
||||
/**
|
||||
* ICU "poor man's RTTI", returns a UClassID for this class.
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
static UClassID getStaticClassID();
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* This method does Hangul OpenType character processing. It assigns the OpenType feature
|
||||
* tags to the characters, and may compose a character sequence into a modern Hangul syllable,
|
||||
* or decompose a modern Hangul syllable if it forms part of an old Hangul syllable.
|
||||
*
|
||||
* Input parameters:
|
||||
* @param chars - the input character context
|
||||
* @param offset - the index of the first character to process
|
||||
* @param count - the number of characters to process
|
||||
* @param max - the number of characters in the input context
|
||||
* @param rightToLeft - <code>TRUE</code> if the characters are in a right to left directional run
|
||||
* @param glyphStorage - the glyph storage object. The glyph and character index arrays will be set.
|
||||
* the auxillary data array will be set to the feature tags.
|
||||
*
|
||||
* Output parameters:
|
||||
* @param success - set to an error code if the operation fails
|
||||
*
|
||||
* @return the output character count
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
virtual le_int32 characterProcessing(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft,
|
||||
LEUnicode *&outChars, LEGlyphStorage &glyphStorage, LEErrorCode &success);
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __ICUFEATURES_H
|
||||
#define __ICUFEATURES_H
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \internal
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "OpenTypeTables.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
struct FeatureRecord
|
||||
{
|
||||
ATag featureTag;
|
||||
Offset featureTableOffset;
|
||||
};
|
||||
|
||||
struct FeatureTable
|
||||
{
|
||||
Offset featureParamsOffset;
|
||||
le_uint16 lookupCount;
|
||||
le_uint16 lookupListIndexArray[ANY_NUMBER];
|
||||
};
|
||||
LE_VAR_ARRAY(FeatureTable, lookupListIndexArray)
|
||||
|
||||
struct FeatureListTable
|
||||
{
|
||||
le_uint16 featureCount;
|
||||
FeatureRecord featureRecordArray[ANY_NUMBER];
|
||||
|
||||
LEReferenceTo<FeatureTable> getFeatureTable(const LETableReference &base, le_uint16 featureIndex, LETag *featureTag, LEErrorCode &success) const;
|
||||
|
||||
#if 0
|
||||
const LEReferenceTo<FeatureTable> getFeatureTable(const LETableReference &base, LETag featureTag, LEErrorCode &success) const;
|
||||
#endif
|
||||
};
|
||||
|
||||
LE_VAR_ARRAY(FeatureListTable, featureRecordArray)
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
|
@ -1,470 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2014 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "LEScripts.h"
|
||||
#include "OpenTypeTables.h"
|
||||
#include "OpenTypeUtilities.h"
|
||||
#include "IndicReordering.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
// Split matra table indices
|
||||
#define _x1 (1 << CF_INDEX_SHIFT)
|
||||
#define _x2 (2 << CF_INDEX_SHIFT)
|
||||
#define _x3 (3 << CF_INDEX_SHIFT)
|
||||
#define _x4 (4 << CF_INDEX_SHIFT)
|
||||
#define _x5 (5 << CF_INDEX_SHIFT)
|
||||
#define _x6 (6 << CF_INDEX_SHIFT)
|
||||
#define _x7 (7 << CF_INDEX_SHIFT)
|
||||
#define _x8 (8 << CF_INDEX_SHIFT)
|
||||
#define _x9 (9 << CF_INDEX_SHIFT)
|
||||
|
||||
// simple classes
|
||||
#define _xx (CC_RESERVED)
|
||||
#define _ma (CC_VOWEL_MODIFIER | CF_POS_ABOVE)
|
||||
#define _mp (CC_VOWEL_MODIFIER | CF_POS_AFTER)
|
||||
#define _sa (CC_STRESS_MARK | CF_POS_ABOVE)
|
||||
#define _sb (CC_STRESS_MARK | CF_POS_BELOW)
|
||||
#define _iv (CC_INDEPENDENT_VOWEL)
|
||||
#define _i2 (CC_INDEPENDENT_VOWEL_2)
|
||||
#define _i3 (CC_INDEPENDENT_VOWEL_3)
|
||||
#define _ct (CC_CONSONANT | CF_CONSONANT)
|
||||
#define _cn (CC_CONSONANT_WITH_NUKTA | CF_CONSONANT)
|
||||
#define _nu (CC_NUKTA)
|
||||
#define _dv (CC_DEPENDENT_VOWEL)
|
||||
#define _dl (_dv | CF_POS_BEFORE)
|
||||
#define _db (_dv | CF_POS_BELOW)
|
||||
#define _da (_dv | CF_POS_ABOVE)
|
||||
#define _dr (_dv | CF_POS_AFTER)
|
||||
#define _lm (_dv | CF_LENGTH_MARK)
|
||||
#define _l1 (CC_SPLIT_VOWEL_PIECE_1 | CF_POS_BEFORE)
|
||||
#define _a1 (CC_SPLIT_VOWEL_PIECE_1 | CF_POS_ABOVE)
|
||||
#define _b2 (CC_SPLIT_VOWEL_PIECE_2 | CF_POS_BELOW)
|
||||
#define _r2 (CC_SPLIT_VOWEL_PIECE_2 | CF_POS_AFTER)
|
||||
#define _m2 (CC_SPLIT_VOWEL_PIECE_2 | CF_LENGTH_MARK)
|
||||
#define _m3 (CC_SPLIT_VOWEL_PIECE_3 | CF_LENGTH_MARK)
|
||||
#define _vr (CC_VIRAMA)
|
||||
#define _al (CC_AL_LAKUNA)
|
||||
|
||||
// split matras
|
||||
#define _s1 (_dv | _x1)
|
||||
#define _s2 (_dv | _x2)
|
||||
#define _s3 (_dv | _x3)
|
||||
#define _s4 (_dv | _x4)
|
||||
#define _s5 (_dv | _x5)
|
||||
#define _s6 (_dv | _x6)
|
||||
#define _s7 (_dv | _x7)
|
||||
#define _s8 (_dv | _x8)
|
||||
#define _s9 (_dv | _x9)
|
||||
|
||||
// consonants with special forms
|
||||
// NOTE: this assumes that no consonants with nukta have
|
||||
// special forms... (Bengali RA?)
|
||||
#define _bb (_ct | CF_BELOW_BASE)
|
||||
#define _pb (_ct | CF_POST_BASE)
|
||||
#define _fb (_ct | CF_PRE_BASE)
|
||||
#define _vt (_bb | CF_VATTU)
|
||||
#define _rv (_vt | CF_REPH)
|
||||
#define _rp (_pb | CF_REPH)
|
||||
#define _rb (_bb | CF_REPH)
|
||||
|
||||
//
|
||||
// Character class tables
|
||||
//
|
||||
static const IndicClassTable::CharClass devaCharClasses[] =
|
||||
{
|
||||
_xx, _ma, _ma, _mp, _iv, _iv, _iv, _iv, _iv, _iv, _iv, _iv, _iv, _iv, _iv, _iv, // 0900 - 090F
|
||||
_iv, _iv, _iv, _iv, _iv, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, // 0910 - 091F
|
||||
_ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _cn, _ct, _ct, _ct, _ct, _ct, _ct, // 0920 - 092F
|
||||
_rv, _cn, _ct, _ct, _cn, _ct, _ct, _ct, _ct, _ct, _xx, _xx, _nu, _xx, _dr, _dl, // 0930 - 093F
|
||||
_dr, _db, _db, _db, _db, _da, _da, _da, _da, _dr, _dr, _dr, _dr, _vr, _xx, _xx, // 0940 - 094F
|
||||
_xx, _sa, _sb, _sa, _sa, _xx, _xx, _xx, _cn, _cn, _cn, _cn, _cn, _cn, _cn, _cn, // 0950 - 095F
|
||||
_iv, _iv, _db, _db, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, // 0960 - 096F
|
||||
_xx // 0970
|
||||
};
|
||||
|
||||
static const IndicClassTable::CharClass bengCharClasses[] =
|
||||
{
|
||||
_xx, _ma, _mp, _mp, _xx, _i2, _iv, _iv, _iv, _iv, _iv, _iv, _iv, _xx, _xx, _i2, // 0980 - 098F
|
||||
_iv, _xx, _xx, _iv, _iv, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, // 0990 - 099F
|
||||
_ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _xx, _ct, _ct, _bb, _ct, _ct, _pb, // 09A0 - 09AF
|
||||
_rv, _xx, _ct, _xx, _xx, _xx, _ct, _ct, _ct, _ct, _xx, _xx, _nu, _xx, _r2, _dl, // 09B0 - 09BF
|
||||
_dr, _db, _db, _db, _db, _xx, _xx, _l1, _dl, _xx, _xx, _s1, _s2, _vr, _xx, _xx, // 09C0 - 09CF
|
||||
_xx, _xx, _xx, _xx, _xx, _xx, _xx, _m2, _xx, _xx, _xx, _xx, _cn, _cn, _xx, _cn, // 09D0 - 09DF
|
||||
_iv, _iv, _dv, _dv, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, // 09E0 - 09EF
|
||||
_rv, _ct, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx // 09F0 - 09FA
|
||||
};
|
||||
|
||||
static const IndicClassTable::CharClass punjCharClasses[] =
|
||||
{
|
||||
_xx, _ma, _ma, _mp, _xx, _iv, _iv, _iv, _iv, _iv, _iv, _xx, _xx, _xx, _xx, _iv, // 0A00 - 0A0F
|
||||
_iv, _xx, _xx, _i3, _iv, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, // 0A10 - 0A1F
|
||||
_ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _xx, _ct, _ct, _ct, _ct, _ct, _bb, // 0A20 - 0A2F
|
||||
_vt, _xx, _ct, _cn, _xx, _bb, _cn, _xx, _ct, _bb, _xx, _xx, _nu, _xx, _dr, _dl, // 0A30 - 0A3F
|
||||
_dr, _b2, _db, _xx, _xx, _xx, _xx, _da, _da, _xx, _xx, _a1, _da, _vr, _xx, _xx, // 0A40 - 0A4F
|
||||
_xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _cn, _cn, _cn, _ct, _xx, _cn, _xx, // 0A50 - 0A5F
|
||||
_xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, // 0A60 - 0A6F
|
||||
_ma, _ma, _xx, _xx, _xx // 0A70 - 0A74
|
||||
};
|
||||
|
||||
static const IndicClassTable::CharClass gujrCharClasses[] =
|
||||
{
|
||||
_xx, _ma, _ma, _mp, _xx, _iv, _iv, _iv, _iv, _iv, _iv, _iv, _xx, _iv, _xx, _iv, // 0A80 - 0A8F
|
||||
_iv, _iv, _xx, _iv, _iv, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, // 0A90 - 0A9F
|
||||
_ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _xx, _ct, _ct, _ct, _ct, _ct, _ct, // 0AA0 - 0AAF
|
||||
_rv, _xx, _ct, _ct, _xx, _ct, _ct, _ct, _ct, _ct, _xx, _xx, _nu, _xx, _dr, _dl, // 0AB0 - 0ABF
|
||||
_dr, _db, _db, _db, _db, _da, _xx, _da, _da, _dr, _xx, _dr, _dr, _vr, _xx, _xx, // 0AC0 - 0ACF
|
||||
_xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, // 0AD0 - 0ADF
|
||||
_iv, _iv, _db, _db, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx // 0AE0 - 0AEF
|
||||
};
|
||||
|
||||
#if 1
|
||||
static const IndicClassTable::CharClass oryaCharClasses[] =
|
||||
{
|
||||
_xx, _ma, _mp, _mp, _xx, _iv, _iv, _iv, _iv, _iv, _iv, _iv, _iv, _xx, _xx, _iv, /* 0B00 - 0B0F */
|
||||
_iv, _xx, _xx, _iv, _iv, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _ct, _bb, /* 0B10 - 0B1F */
|
||||
_bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _xx, _bb, _bb, _bb, _bb, _bb, _pb, /* 0B20 - 0B2F */
|
||||
_rb, _xx, _bb, _bb, _xx, _bb, _bb, _bb, _bb, _bb, _xx, _xx, _nu, _xx, _dr, _da, /* 0B30 - 0B3F */
|
||||
_dr, _db, _db, _db, _xx, _xx, _xx, _dl, _s1, _xx, _xx, _s2, _s3, _vr, _xx, _xx, /* 0B40 - 0B4F */
|
||||
_xx, _xx, _xx, _xx, _xx, _xx, _da, _dr, _xx, _xx, _xx, _xx, _cn, _cn, _xx, _pb, /* 0B50 - 0B5F */
|
||||
_iv, _iv, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, /* 0B60 - 0B6F */
|
||||
_xx, _bb /* 0B70 - 0B71 */
|
||||
};
|
||||
#else
|
||||
static const IndicClassTable::CharClass oryaCharClasses[] =
|
||||
{
|
||||
_xx, _ma, _mp, _mp, _xx, _iv, _iv, _iv, _iv, _iv, _iv, _iv, _iv, _xx, _xx, _iv, // 0B00 - 0B0F
|
||||
_iv, _xx, _xx, _iv, _iv, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, // 0B10 - 0B1F
|
||||
_ct, _ct, _ct, _ct, _bb, _ct, _ct, _ct, _bb, _xx, _ct, _ct, _bb, _bb, _bb, _pb, // 0B20 - 0B2F
|
||||
_rb, _xx, _bb, _bb, _xx, _ct, _ct, _ct, _ct, _ct, _xx, _xx, _nu, _xx, _r2, _da, // 0B30 - 0B3F
|
||||
_dr, _db, _db, _db, _xx, _xx, _xx, _l1, _s1, _xx, _xx, _s2, _s3, _vr, _xx, _xx, // 0B40 - 0B4F
|
||||
_xx, _xx, _xx, _xx, _xx, _xx, _m2, _m2, _xx, _xx, _xx, _xx, _cn, _cn, _xx, _cn, // 0B50 - 0B5F
|
||||
_iv, _iv, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, // 0B60 - 0B6F
|
||||
_xx, _ct // 0B70 - 0B71
|
||||
};
|
||||
#endif
|
||||
|
||||
static const IndicClassTable::CharClass tamlCharClasses[] =
|
||||
{
|
||||
_xx, _xx, _ma, _xx, _xx, _iv, _iv, _iv, _iv, _iv, _iv, _xx, _xx, _xx, _iv, _iv, // 0B80 - 0B8F
|
||||
_iv, _xx, _iv, _iv, _iv, _ct, _xx, _xx, _xx, _ct, _ct, _xx, _ct, _xx, _ct, _ct, // 0B90 - 0B9F
|
||||
_xx, _xx, _xx, _ct, _ct, _xx, _xx, _xx, _ct, _ct, _ct, _xx, _xx, _xx, _ct, _ct, // 0BA0 - 0BAF
|
||||
_ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _xx, _xx, _xx, _xx, _r2, _dr, // 0BB0 - 0BBF
|
||||
_da, _dr, _dr, _xx, _xx, _xx, _l1, _l1, _dl, _xx, _s1, _s2, _s3, _vr, _xx, _xx, // 0BC0 - 0BCF
|
||||
_xx, _xx, _xx, _xx, _xx, _xx, _xx, _m2, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, // 0BD0 - 0BDF
|
||||
_xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, // 0BE0 - 0BEF
|
||||
_xx, _xx, _xx // 0BF0 - 0BF2
|
||||
};
|
||||
|
||||
// FIXME: Should some of the bb's be pb's? (KA, NA, MA, YA, VA, etc. (approx 13))
|
||||
// U+C43 and U+C44 are _lm here not _dr. Similar to the situation with U+CC3 and
|
||||
// U+CC4 in Kannada below.
|
||||
static const IndicClassTable::CharClass teluCharClasses[] =
|
||||
{
|
||||
_xx, _mp, _mp, _mp, _xx, _iv, _iv, _iv, _iv, _iv, _iv, _iv, _iv, _xx, _iv, _iv, // 0C00 - 0C0F
|
||||
_iv, _xx, _iv, _iv, _iv, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, // 0C10 - 0C1F
|
||||
_bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _xx, _bb, _bb, _bb, _bb, _bb, _bb, // 0C20 - 0C2F
|
||||
_bb, _bb, _bb, _bb, _xx, _bb, _bb, _bb, _bb, _bb, _xx, _xx, _xx, _xx, _da, _da, // 0C30 - 0C3F
|
||||
_da, _dr, _dr, _lm, _lm, _xx, _a1, _da, _s1, _xx, _da, _da, _da, _vr, _xx, _xx, // 0C40 - 0C4F
|
||||
_xx, _xx, _xx, _xx, _xx, _da, _m2, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, // 0C50 - 0C5F
|
||||
_iv, _iv, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx // 0C60 - 0C6F
|
||||
};
|
||||
|
||||
// U+CC3 and U+CC4 are _lm here not _dr since the Kannada rendering
|
||||
// rules want them below and to the right of the entire cluster
|
||||
//
|
||||
// There's some information about this in:
|
||||
//
|
||||
// http://brahmi.sourceforge.net/docs/KannadaComputing.html
|
||||
static const IndicClassTable::CharClass kndaCharClasses[] =
|
||||
{
|
||||
_xx, _xx, _mp, _mp, _xx, _iv, _iv, _iv, _iv, _iv, _iv, _iv, _iv, _xx, _iv, _iv, // 0C80 - 0C8F
|
||||
_iv, _xx, _iv, _iv, _iv, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, // 0C90 - 0C9F
|
||||
_bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _xx, _bb, _bb, _bb, _bb, _bb, _bb, // 0CA0 - 0CAF
|
||||
_rb, _ct, _bb, _bb, _xx, _bb, _bb, _bb, _bb, _bb, _xx, _xx, _xx, _xx, _dr, _da, // 0CB0 - 0CBF
|
||||
_s1, _dr, _r2, _lm, _lm, _xx, _a1, _s2, _s3, _xx, _s4, _s5, _da, _vr, _xx, _xx, // 0CC0 - 0CCF
|
||||
_xx, _xx, _xx, _xx, _xx, _m3, _m2, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _ct, _xx, // 0CD0 - 0CDF
|
||||
_iv, _iv, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx // 0CE0 - 0CEF
|
||||
};
|
||||
|
||||
// FIXME: this is correct for old-style Malayalam (MAL) but not for reformed Malayalam (MLR)
|
||||
// FIXME: should there be a REPH for old-style Malayalam?
|
||||
static const IndicClassTable::CharClass mlymCharClasses[] =
|
||||
{
|
||||
_xx, _xx, _mp, _mp, _xx, _iv, _iv, _iv, _iv, _iv, _iv, _iv, _iv, _xx, _iv, _iv, // 0D00 - 0D0F
|
||||
_iv, _xx, _iv, _iv, _iv, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, // 0D10 - 0D1F
|
||||
_ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _xx, _ct, _ct, _ct, _ct, _ct, _pb, // 0D20 - 0D2F
|
||||
_fb, _fb, _bb, _ct, _ct, _pb, _ct, _ct, _ct, _ct, _xx, _xx, _xx, _xx, _r2, _dr, // 0D30 - 0D3F
|
||||
_dr, _dr, _dr, _dr, _xx, _xx, _l1, _l1, _dl, _xx, _s1, _s2, _s3, _vr, _xx, _xx, // 0D40 - 0D4F
|
||||
_xx, _xx, _xx, _xx, _xx, _xx, _xx, _m2, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, // 0D50 - 0D5F
|
||||
_iv, _iv, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx // 0D60 - 0D6F
|
||||
};
|
||||
|
||||
static const IndicClassTable::CharClass sinhCharClasses[] =
|
||||
{
|
||||
_xx, _xx, _mp, _mp, _xx, _iv, _iv, _iv, _iv, _iv, _iv, _iv, _iv, _iv, _iv, _iv, // 0D80 - 0D8F
|
||||
_iv, _iv, _iv, _iv, _iv, _iv, _iv, _xx, _xx, _xx, _ct, _ct, _ct, _ct, _ct, _ct, // 0D90 - 0D9F
|
||||
_ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, // 0DA0 - 0DAF
|
||||
_ct, _ct, _xx, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _xx, _ct, _xx, _xx, // 0DB0 - 0DBF
|
||||
_ct, _ct, _ct, _ct, _ct, _ct, _ct, _xx, _xx, _xx, _al, _xx, _xx, _xx, _xx, _dr, // 0DC0 - 0DCF
|
||||
_dr, _dr, _da, _da, _db, _xx, _db, _xx, _dr, _dl, _s1, _dl, _s2, _s3, _s4, _dr, // 0DD0 - 0DDF
|
||||
_xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, // 0DE0 - 0DEF
|
||||
_xx, _xx, _dr, _dr, _xx // 0DF0 - 0DF4
|
||||
};
|
||||
|
||||
//
|
||||
// Split matra tables
|
||||
//
|
||||
static const SplitMatra bengSplitTable[] = {{0x09C7, 0x09BE}, {0x09C7, 0x09D7}};
|
||||
|
||||
static const SplitMatra oryaSplitTable[] = {{0x0B47, 0x0B56}, {0x0B47, 0x0B3E}, {0x0B47, 0x0B57}};
|
||||
|
||||
static const SplitMatra tamlSplitTable[] = {{0x0BC6, 0x0BBE}, {0x0BC7, 0x0BBE}, {0x0BC6, 0x0BD7}};
|
||||
|
||||
static const SplitMatra teluSplitTable[] = {{0x0C46, 0x0C56}};
|
||||
|
||||
static const SplitMatra kndaSplitTable[] = {{0x0CBF, 0x0CD5}, {0x0CC6, 0x0CD5}, {0x0CC6, 0x0CD6}, {0x0CC6, 0x0CC2},
|
||||
{0x0CC6, 0x0CC2, 0x0CD5}};
|
||||
|
||||
static const SplitMatra mlymSplitTable[] = {{0x0D46, 0x0D3E}, {0x0D47, 0x0D3E}, {0x0D46, 0x0D57}};
|
||||
|
||||
|
||||
static const SplitMatra sinhSplitTable[] = {{0x0DD9, 0x0DCA}, {0x0DD9, 0x0DCF}, {0x0DD9, 0x0DCF, 0x0DCA},
|
||||
{0x0DD9, 0x0DDF}};
|
||||
//
|
||||
// Script Flags
|
||||
//
|
||||
|
||||
// FIXME: post 'GSUB' reordering of MATRA_PRE's for Malayalam and Tamil
|
||||
// FIXME: reformed Malayalam needs to reorder VATTU to before base glyph...
|
||||
// FIXME: not sure passing ZWJ/ZWNJ is best way to render Malayalam Cillu...
|
||||
// FIXME: eyelash RA only for Devanagari??
|
||||
#define DEVA_SCRIPT_FLAGS (SF_EYELASH_RA | SF_NO_POST_BASE_LIMIT | SF_FILTER_ZERO_WIDTH)
|
||||
#define BENG_SCRIPT_FLAGS (SF_REPH_AFTER_BELOW | SF_NO_POST_BASE_LIMIT | SF_FILTER_ZERO_WIDTH)
|
||||
#define PUNJ_SCRIPT_FLAGS (SF_NO_POST_BASE_LIMIT | SF_FILTER_ZERO_WIDTH)
|
||||
#define GUJR_SCRIPT_FLAGS (SF_NO_POST_BASE_LIMIT | SF_FILTER_ZERO_WIDTH)
|
||||
#define ORYA_SCRIPT_FLAGS (SF_REPH_AFTER_BELOW | SF_NO_POST_BASE_LIMIT | SF_FILTER_ZERO_WIDTH)
|
||||
#define TAML_SCRIPT_FLAGS (SF_MPRE_FIXUP | SF_NO_POST_BASE_LIMIT | SF_FILTER_ZERO_WIDTH)
|
||||
#define TELU_SCRIPT_FLAGS (SF_MATRAS_AFTER_BASE | SF_FILTER_ZERO_WIDTH | 3)
|
||||
#define KNDA_SCRIPT_FLAGS (SF_MATRAS_AFTER_BASE | SF_FILTER_ZERO_WIDTH | 3)
|
||||
#define MLYM_SCRIPT_FLAGS (SF_MPRE_FIXUP | SF_NO_POST_BASE_LIMIT /*| SF_FILTER_ZERO_WIDTH*/)
|
||||
#define SINH_SCRIPT_FLAGS (SF_NO_POST_BASE_LIMIT)
|
||||
|
||||
//
|
||||
// Indic Class Tables
|
||||
//
|
||||
static const IndicClassTable devaClassTable = {0x0900, 0x0970, 2, DEVA_SCRIPT_FLAGS, devaCharClasses, NULL};
|
||||
|
||||
static const IndicClassTable bengClassTable = {0x0980, 0x09FA, 3, BENG_SCRIPT_FLAGS, bengCharClasses, bengSplitTable};
|
||||
|
||||
static const IndicClassTable punjClassTable = {0x0A00, 0x0A74, 2, PUNJ_SCRIPT_FLAGS, punjCharClasses, NULL};
|
||||
|
||||
static const IndicClassTable gujrClassTable = {0x0A80, 0x0AEF, 2, GUJR_SCRIPT_FLAGS, gujrCharClasses, NULL};
|
||||
|
||||
static const IndicClassTable oryaClassTable = {0x0B00, 0x0B71, 3, ORYA_SCRIPT_FLAGS, oryaCharClasses, oryaSplitTable};
|
||||
|
||||
static const IndicClassTable tamlClassTable = {0x0B80, 0x0BF2, 3, TAML_SCRIPT_FLAGS, tamlCharClasses, tamlSplitTable};
|
||||
|
||||
static const IndicClassTable teluClassTable = {0x0C00, 0x0C6F, 3, TELU_SCRIPT_FLAGS, teluCharClasses, teluSplitTable};
|
||||
|
||||
static const IndicClassTable kndaClassTable = {0x0C80, 0x0CEF, 4, KNDA_SCRIPT_FLAGS, kndaCharClasses, kndaSplitTable};
|
||||
|
||||
static const IndicClassTable mlymClassTable = {0x0D00, 0x0D6F, 4, MLYM_SCRIPT_FLAGS, mlymCharClasses, mlymSplitTable};
|
||||
|
||||
static const IndicClassTable sinhClassTable = {0x0D80, 0x0DF4, 4, SINH_SCRIPT_FLAGS, sinhCharClasses, sinhSplitTable};
|
||||
|
||||
//
|
||||
// IndicClassTable addresses
|
||||
//
|
||||
static const IndicClassTable * const indicClassTables[scriptCodeCount] = {
|
||||
NULL, /* 'zyyy' (COMMON) */
|
||||
NULL, /* 'qaai' (INHERITED) */
|
||||
NULL, /* 'arab' (ARABIC) */
|
||||
NULL, /* 'armn' (ARMENIAN) */
|
||||
&bengClassTable, /* 'beng' (BENGALI) */
|
||||
NULL, /* 'bopo' (BOPOMOFO) */
|
||||
NULL, /* 'cher' (CHEROKEE) */
|
||||
NULL, /* 'copt' (COPTIC) */
|
||||
NULL, /* 'cyrl' (CYRILLIC) */
|
||||
NULL, /* 'dsrt' (DESERET) */
|
||||
&devaClassTable, /* 'deva' (DEVANAGARI) */
|
||||
NULL, /* 'ethi' (ETHIOPIC) */
|
||||
NULL, /* 'geor' (GEORGIAN) */
|
||||
NULL, /* 'goth' (GOTHIC) */
|
||||
NULL, /* 'grek' (GREEK) */
|
||||
&gujrClassTable, /* 'gujr' (GUJARATI) */
|
||||
&punjClassTable, /* 'guru' (GURMUKHI) */
|
||||
NULL, /* 'hani' (HAN) */
|
||||
NULL, /* 'hang' (HANGUL) */
|
||||
NULL, /* 'hebr' (HEBREW) */
|
||||
NULL, /* 'hira' (HIRAGANA) */
|
||||
&kndaClassTable, /* 'knda' (KANNADA) */
|
||||
NULL, /* 'kata' (KATAKANA) */
|
||||
NULL, /* 'khmr' (KHMER) */
|
||||
NULL, /* 'laoo' (LAO) */
|
||||
NULL, /* 'latn' (LATIN) */
|
||||
&mlymClassTable, /* 'mlym' (MALAYALAM) */
|
||||
NULL, /* 'mong' (MONGOLIAN) */
|
||||
NULL, /* 'mymr' (MYANMAR) */
|
||||
NULL, /* 'ogam' (OGHAM) */
|
||||
NULL, /* 'ital' (OLD-ITALIC) */
|
||||
&oryaClassTable, /* 'orya' (ORIYA) */
|
||||
NULL, /* 'runr' (RUNIC) */
|
||||
&sinhClassTable, /* 'sinh' (SINHALA) */
|
||||
NULL, /* 'syrc' (SYRIAC) */
|
||||
&tamlClassTable, /* 'taml' (TAMIL) */
|
||||
&teluClassTable, /* 'telu' (TELUGU) */
|
||||
NULL, /* 'thaa' (THAANA) */
|
||||
NULL, /* 'thai' (THAI) */
|
||||
NULL, /* 'tibt' (TIBETAN) */
|
||||
NULL, /* 'cans' (CANADIAN-ABORIGINAL) */
|
||||
NULL, /* 'yiii' (YI) */
|
||||
NULL, /* 'tglg' (TAGALOG) */
|
||||
NULL, /* 'hano' (HANUNOO) */
|
||||
NULL, /* 'buhd' (BUHID) */
|
||||
NULL, /* 'tagb' (TAGBANWA) */
|
||||
NULL, /* 'brai' (BRAILLE) */
|
||||
NULL, /* 'cprt' (CYPRIOT) */
|
||||
NULL, /* 'limb' (LIMBU) */
|
||||
NULL, /* 'linb' (LINEAR_B) */
|
||||
NULL, /* 'osma' (OSMANYA) */
|
||||
NULL, /* 'shaw' (SHAVIAN) */
|
||||
NULL, /* 'tale' (TAI_LE) */
|
||||
NULL, /* 'ugar' (UGARITIC) */
|
||||
NULL, /* 'hrkt' (KATAKANA_OR_HIRAGANA) */
|
||||
NULL, /* 'bugi' (BUGINESE) */
|
||||
NULL, /* 'glag' (GLAGOLITIC) */
|
||||
NULL, /* 'khar' (KHAROSHTHI) */
|
||||
NULL, /* 'sylo' (SYLOTI_NAGRI) */
|
||||
NULL, /* 'talu' (NEW_TAI_LUE) */
|
||||
NULL, /* 'tfng' (TIFINAGH) */
|
||||
NULL, /* 'xpeo' (OLD_PERSIAN) */
|
||||
NULL, /* 'bali' (BALINESE) */
|
||||
NULL, /* 'batk' (BATK) */
|
||||
NULL, /* 'blis' (BLIS) */
|
||||
NULL, /* 'brah' (BRAH) */
|
||||
NULL, /* 'cham' (CHAM) */
|
||||
NULL, /* 'cirt' (CIRT) */
|
||||
NULL, /* 'cyrs' (CYRS) */
|
||||
NULL, /* 'egyd' (EGYD) */
|
||||
NULL, /* 'egyh' (EGYH) */
|
||||
NULL, /* 'egyp' (EGYP) */
|
||||
NULL, /* 'geok' (GEOK) */
|
||||
NULL, /* 'hans' (HANS) */
|
||||
NULL, /* 'hant' (HANT) */
|
||||
NULL, /* 'hmng' (HMNG) */
|
||||
NULL, /* 'hung' (HUNG) */
|
||||
NULL, /* 'inds' (INDS) */
|
||||
NULL, /* 'java' (JAVA) */
|
||||
NULL, /* 'kali' (KALI) */
|
||||
NULL, /* 'latf' (LATF) */
|
||||
NULL, /* 'latg' (LATG) */
|
||||
NULL, /* 'lepc' (LEPC) */
|
||||
NULL, /* 'lina' (LINA) */
|
||||
NULL, /* 'mand' (MAND) */
|
||||
NULL, /* 'maya' (MAYA) */
|
||||
NULL, /* 'mero' (MERO) */
|
||||
NULL, /* 'nko ' (NKO) */
|
||||
NULL, /* 'orkh' (ORKH) */
|
||||
NULL, /* 'perm' (PERM) */
|
||||
NULL, /* 'phag' (PHAGS_PA) */
|
||||
NULL, /* 'phnx' (PHOENICIAN) */
|
||||
NULL, /* 'plrd' (PLRD) */
|
||||
NULL, /* 'roro' (RORO) */
|
||||
NULL, /* 'sara' (SARA) */
|
||||
NULL, /* 'syre' (SYRE) */
|
||||
NULL, /* 'syrj' (SYRJ) */
|
||||
NULL, /* 'syrn' (SYRN) */
|
||||
NULL, /* 'teng' (TENG) */
|
||||
NULL, /* 'vai ' (VAII) */
|
||||
NULL, /* 'visp' (VISP) */
|
||||
NULL, /* 'xsux' (CUNEIFORM) */
|
||||
NULL, /* 'zxxx' (ZXXX) */
|
||||
NULL, /* 'zzzz' (UNKNOWN) */
|
||||
NULL, /* 'cari' (CARI) */
|
||||
NULL, /* 'jpan' (JPAN) */
|
||||
NULL, /* 'lana' (LANA) */
|
||||
NULL, /* 'lyci' (LYCI) */
|
||||
NULL, /* 'lydi' (LYDI) */
|
||||
NULL, /* 'olck' (OLCK) */
|
||||
NULL, /* 'rjng' (RJNG) */
|
||||
NULL, /* 'saur' (SAUR) */
|
||||
NULL, /* 'sgnw' (SGNW) */
|
||||
NULL, /* 'sund' (SUND) */
|
||||
NULL, /* 'moon' (MOON) */
|
||||
NULL, /* 'mtei' (MTEI) */
|
||||
NULL, /* 'armi' (ARMI) */
|
||||
NULL, /* 'avst' (AVST) */
|
||||
NULL, /* 'cakm' (CAKM) */
|
||||
NULL, /* 'kore' (KORE) */
|
||||
NULL, /* 'kthi' (KTHI) */
|
||||
NULL, /* 'mani' (MANI) */
|
||||
NULL, /* 'phli' (PHLI) */
|
||||
NULL, /* 'phlp' (PHLP) */
|
||||
NULL, /* 'phlv' (PHLV) */
|
||||
NULL, /* 'prti' (PRTI) */
|
||||
NULL, /* 'samr' (SAMR) */
|
||||
NULL, /* 'tavt' (TAVT) */
|
||||
NULL, /* 'zmth' (ZMTH) */
|
||||
NULL, /* 'zsym' (ZSYM) */
|
||||
NULL, /* 'bamu' (BAMUM) */
|
||||
NULL, /* 'lisu' (LISU) */
|
||||
NULL, /* 'nkgb' (NKGB) */
|
||||
NULL /* 'sarb' (OLD_SOUTH_ARABIAN) */
|
||||
};
|
||||
|
||||
IndicClassTable::CharClass IndicClassTable::getCharClass(LEUnicode ch) const
|
||||
{
|
||||
if (ch == C_SIGN_ZWJ) {
|
||||
return CF_CONSONANT | CC_ZERO_WIDTH_MARK;
|
||||
}
|
||||
|
||||
if (ch == C_SIGN_ZWNJ) {
|
||||
return CC_ZERO_WIDTH_MARK;
|
||||
}
|
||||
|
||||
if (ch < firstChar || ch > lastChar) {
|
||||
return CC_RESERVED;
|
||||
}
|
||||
|
||||
return classTable[ch - firstChar];
|
||||
}
|
||||
|
||||
const IndicClassTable *IndicClassTable::getScriptClassTable(le_int32 scriptCode)
|
||||
{
|
||||
if (scriptCode < 0 || scriptCode >= scriptCodeCount) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return indicClassTables[scriptCode];
|
||||
}
|
||||
|
||||
le_int32 IndicReordering::getWorstCaseExpansion(le_int32 scriptCode)
|
||||
{
|
||||
const IndicClassTable *classTable = IndicClassTable::getScriptClassTable(scriptCode);
|
||||
|
||||
if (classTable == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return classTable->getWorstCaseExpansion();
|
||||
}
|
||||
|
||||
le_bool IndicReordering::getFilterZeroWidth(le_int32 scriptCode)
|
||||
{
|
||||
const IndicClassTable *classTable = IndicClassTable::getScriptClassTable(scriptCode);
|
||||
|
||||
if (classTable == NULL) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return classTable->getFilterZeroWidth();
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
|
@ -1,137 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "LayoutEngine.h"
|
||||
#include "OpenTypeLayoutEngine.h"
|
||||
#include "IndicLayoutEngine.h"
|
||||
#include "ScriptAndLanguageTags.h"
|
||||
|
||||
#include "GlyphSubstitutionTables.h"
|
||||
#include "GlyphDefinitionTables.h"
|
||||
#include "GlyphPositioningTables.h"
|
||||
|
||||
#include "GDEFMarkFilter.h"
|
||||
#include "LEGlyphStorage.h"
|
||||
|
||||
#include "IndicReordering.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(IndicOpenTypeLayoutEngine)
|
||||
|
||||
IndicOpenTypeLayoutEngine::IndicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
|
||||
le_int32 typoFlags, le_bool version2, const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTable, LEErrorCode &success)
|
||||
: OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success), fMPreFixups(NULL)
|
||||
{
|
||||
if ( version2 ) {
|
||||
fFeatureMap = IndicReordering::getv2FeatureMap(fFeatureMapCount);
|
||||
} else {
|
||||
fFeatureMap = IndicReordering::getFeatureMap(fFeatureMapCount);
|
||||
}
|
||||
fFeatureOrder = TRUE;
|
||||
fVersion2 = version2;
|
||||
fFilterZeroWidth = IndicReordering::getFilterZeroWidth(fScriptCode);
|
||||
}
|
||||
|
||||
IndicOpenTypeLayoutEngine::IndicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, le_int32 typoFlags, LEErrorCode &success)
|
||||
: OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success), fMPreFixups(NULL)
|
||||
{
|
||||
fFeatureMap = IndicReordering::getFeatureMap(fFeatureMapCount);
|
||||
fFeatureOrder = TRUE;
|
||||
fVersion2 = FALSE;
|
||||
}
|
||||
|
||||
IndicOpenTypeLayoutEngine::~IndicOpenTypeLayoutEngine()
|
||||
{
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
// Input: characters, tags
|
||||
// Output: glyphs, char indices
|
||||
le_int32 IndicOpenTypeLayoutEngine::glyphProcessing(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft,
|
||||
LEGlyphStorage &glyphStorage, LEErrorCode &success)
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (chars == NULL || offset < 0 || count < 0 || max < 0 || offset >= max || offset + count > max) {
|
||||
success = LE_ILLEGAL_ARGUMENT_ERROR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
le_int32 retCount = OpenTypeLayoutEngine::glyphProcessing(chars, offset, count, max, rightToLeft, glyphStorage, success);
|
||||
|
||||
if (LE_FAILURE(success)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (fVersion2) {
|
||||
IndicReordering::finalReordering(glyphStorage,retCount);
|
||||
IndicReordering::applyPresentationForms(glyphStorage,retCount);
|
||||
OpenTypeLayoutEngine::glyphSubstitution(count,max, rightToLeft, glyphStorage, success);
|
||||
} else {
|
||||
IndicReordering::adjustMPres(fMPreFixups, glyphStorage, success);
|
||||
}
|
||||
return retCount;
|
||||
}
|
||||
|
||||
// Input: characters
|
||||
// Output: characters, char indices, tags
|
||||
// Returns: output character count
|
||||
le_int32 IndicOpenTypeLayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft,
|
||||
LEUnicode *&outChars, LEGlyphStorage &glyphStorage, LEErrorCode &success)
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (chars == NULL || offset < 0 || count < 0 || max < 0 || offset >= max || offset + count > max) {
|
||||
success = LE_ILLEGAL_ARGUMENT_ERROR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
le_int32 worstCase = count * IndicReordering::getWorstCaseExpansion(fScriptCode);
|
||||
|
||||
outChars = LE_NEW_ARRAY(LEUnicode, worstCase);
|
||||
|
||||
if (outChars == NULL) {
|
||||
success = LE_MEMORY_ALLOCATION_ERROR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
glyphStorage.allocateGlyphArray(worstCase, rightToLeft, success);
|
||||
glyphStorage.allocateAuxData(success);
|
||||
|
||||
if (LE_FAILURE(success)) {
|
||||
LE_DELETE_ARRAY(outChars);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// NOTE: assumes this allocates featureTags...
|
||||
// (probably better than doing the worst case stuff here...)
|
||||
|
||||
le_int32 outCharCount;
|
||||
if (fVersion2) {
|
||||
outCharCount = IndicReordering::v2process(&chars[offset], count, fScriptCode, outChars, glyphStorage);
|
||||
} else {
|
||||
outCharCount = IndicReordering::reorder(&chars[offset], count, fScriptCode, outChars, glyphStorage, &fMPreFixups, success);
|
||||
}
|
||||
|
||||
if (LE_FAILURE(success)) {
|
||||
LE_DELETE_ARRAY(outChars);
|
||||
return 0;
|
||||
}
|
||||
|
||||
glyphStorage.adoptGlyphCount(outCharCount);
|
||||
return outCharCount;
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
|
@ -1,169 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2014 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __INDICLAYOUTENGINE_H
|
||||
#define __INDICLAYOUTENGINE_H
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "LEFontInstance.h"
|
||||
#include "LEGlyphFilter.h"
|
||||
#include "LayoutEngine.h"
|
||||
#include "OpenTypeLayoutEngine.h"
|
||||
|
||||
#include "GlyphSubstitutionTables.h"
|
||||
#include "GlyphDefinitionTables.h"
|
||||
#include "GlyphPositioningTables.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class MPreFixups;
|
||||
class LEGlyphStorage;
|
||||
|
||||
/**
|
||||
* This class implements OpenType layout for Indic OpenType fonts, as
|
||||
* specified by Microsoft in "Creating and Supporting OpenType Fonts for
|
||||
* Indic Scripts" (http://www.microsoft.com/typography/otspec/indicot/default.htm)
|
||||
*
|
||||
* This class overrides the characterProcessing method to do Indic character processing
|
||||
* and reordering, and the glyphProcessing method to implement post-GSUB processing for
|
||||
* left matras. (See the MS spec. for more details)
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class IndicOpenTypeLayoutEngine : public OpenTypeLayoutEngine
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This is the main constructor. It constructs an instance of IndicOpenTypeLayoutEngine for
|
||||
* a particular font, script and language. It takes the GSUB table as a parameter since
|
||||
* LayoutEngine::layoutEngineFactory has to read the GSUB table to know that it has an
|
||||
* Indic OpenType font.
|
||||
*
|
||||
* @param fontInstance - the font
|
||||
* @param scriptCode - the script
|
||||
* @param langaugeCode - the language
|
||||
* @param gsubTable - the GSUB table
|
||||
* @param success - set to an error code if the operation fails
|
||||
*
|
||||
* @see LayoutEngine::layoutEngineFactory
|
||||
* @see OpenTypeLayoutEngine
|
||||
* @see ScriptAndLangaugeTags.h for script and language codes
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IndicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
|
||||
le_int32 typoFlags, le_bool version2, const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTable, LEErrorCode &success);
|
||||
|
||||
/**
|
||||
* This constructor is used when the font requires a "canned" GSUB table which can't be known
|
||||
* until after this constructor has been invoked.
|
||||
*
|
||||
* @param fontInstance - the font
|
||||
* @param scriptCode - the script
|
||||
* @param langaugeCode - the language
|
||||
* @param success - set to an error code if the operation fails
|
||||
*
|
||||
* @see OpenTypeLayoutEngine
|
||||
* @see ScriptAndLangaugeTags.h for script and language codes
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
IndicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
|
||||
le_int32 typoFlags, LEErrorCode &success);
|
||||
|
||||
/**
|
||||
* The destructor, virtual for correct polymorphic invocation.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
virtual ~IndicOpenTypeLayoutEngine();
|
||||
|
||||
/**
|
||||
* ICU "poor man's RTTI", returns a UClassID for the actual class.
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
virtual UClassID getDynamicClassID() const;
|
||||
|
||||
/**
|
||||
* ICU "poor man's RTTI", returns a UClassID for this class.
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
static UClassID getStaticClassID();
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* This method does Indic OpenType character processing. It assigns the OpenType feature
|
||||
* tags to the characters, and may generate output characters which have been reordered. For
|
||||
* some Indic scripts, it may also split some vowels, resulting in more output characters
|
||||
* than input characters.
|
||||
*
|
||||
* Input parameters:
|
||||
* @param chars - the input character context
|
||||
* @param offset - the index of the first character to process
|
||||
* @param count - the number of characters to process
|
||||
* @param max - the number of characters in the input context
|
||||
* @param rightToLeft - <code>TRUE</code> if the characters are in a right to left directional run
|
||||
* @param glyphStorage - the glyph storage object. The glyph and character index arrays will be set.
|
||||
* the auxillary data array will be set to the feature tags.
|
||||
*
|
||||
* Output parameters:
|
||||
* @param success - set to an error code if the operation fails
|
||||
*
|
||||
* @return the output character count
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
virtual le_int32 characterProcessing(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft,
|
||||
LEUnicode *&outChars, LEGlyphStorage &glyphStorage, LEErrorCode &success);
|
||||
|
||||
/**
|
||||
* This method does character to glyph mapping, applies the GSUB table and applies
|
||||
* any post GSUB fixups for left matras. It calls OpenTypeLayoutEngine::glyphProcessing
|
||||
* to do the character to glyph mapping, and apply the GSUB table.
|
||||
*
|
||||
* Note that in the case of "canned" GSUB tables, the output glyph indices may be
|
||||
* "fake" glyph indices that need to be converted to "real" glyph indices by the
|
||||
* glyphPostProcessing method.
|
||||
*
|
||||
* Input parameters:
|
||||
* @param chars - the input character context
|
||||
* @param offset - the index of the first character to process
|
||||
* @param count - the number of characters to process
|
||||
* @param max - the number of characters in the input context
|
||||
* @param rightToLeft - <code>TRUE</code> if the characters are in a right to left directional run
|
||||
* @param featureTags - the feature tag array
|
||||
* @param glyphStorage - the glyph storage object. The glyph and char index arrays will be set.
|
||||
*
|
||||
* Output parameters:
|
||||
* @param success - set to an error code if the operation fails
|
||||
*
|
||||
* @return the number of glyphs in the output glyph index array
|
||||
*
|
||||
* Note: if the character index array was already set by the characterProcessing
|
||||
* method, this method won't change it.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
virtual le_int32 glyphProcessing(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft,
|
||||
LEGlyphStorage &glyphStorage, LEErrorCode &success);
|
||||
|
||||
le_bool fVersion2;
|
||||
|
||||
private:
|
||||
|
||||
MPreFixups *fMPreFixups;
|
||||
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
||||
|
|
@ -1,75 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. and Others 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __INDICREARRANGEMENT_H
|
||||
#define __INDICREARRANGEMENT_H
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \internal
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "LayoutTables.h"
|
||||
#include "StateTables.h"
|
||||
#include "MorphTables.h"
|
||||
#include "MorphStateTables.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
struct IndicRearrangementSubtableHeader : MorphStateTableHeader
|
||||
{
|
||||
};
|
||||
|
||||
struct IndicRearrangementSubtableHeader2 : MorphStateTableHeader2
|
||||
{
|
||||
};
|
||||
|
||||
enum IndicRearrangementFlags
|
||||
{
|
||||
irfMarkFirst = 0x8000,
|
||||
irfDontAdvance = 0x4000,
|
||||
irfMarkLast = 0x2000,
|
||||
irfReserved = 0x1FF0,
|
||||
irfVerbMask = 0x000F
|
||||
};
|
||||
|
||||
enum IndicRearrangementVerb
|
||||
{
|
||||
irvNoAction = 0x0000, /* no action */
|
||||
irvxA = 0x0001, /* Ax => xA */
|
||||
irvDx = 0x0002, /* xD => Dx */
|
||||
irvDxA = 0x0003, /* AxD => DxA */
|
||||
|
||||
irvxAB = 0x0004, /* ABx => xAB */
|
||||
irvxBA = 0x0005, /* ABx => xBA */
|
||||
irvCDx = 0x0006, /* xCD => CDx */
|
||||
irvDCx = 0x0007, /* xCD => DCx */
|
||||
|
||||
irvCDxA = 0x0008, /* AxCD => CDxA */
|
||||
irvDCxA = 0x0009, /* AxCD => DCxA */
|
||||
irvDxAB = 0x000A, /* ABxD => DxAB */
|
||||
irvDxBA = 0x000B, /* ABxD => DxBA */
|
||||
|
||||
irvCDxAB = 0x000C, /* ABxCD => CDxAB */
|
||||
irvCDxBA = 0x000D, /* ABxCD => CDxBA */
|
||||
irvDCxAB = 0x000E, /* ABxCD => DCxAB */
|
||||
irvDCxBA = 0x000F /* ABxCD => DCxBA */
|
||||
};
|
||||
|
||||
struct IndicRearrangementStateEntry : StateEntry
|
||||
{
|
||||
};
|
||||
|
||||
struct IndicRearrangementStateEntry2 : StateEntry2
|
||||
{
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
||||
|
|
@ -1,476 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2016 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "MorphTables.h"
|
||||
#include "StateTables.h"
|
||||
#include "MorphStateTables.h"
|
||||
#include "SubtableProcessor.h"
|
||||
#include "StateTableProcessor.h"
|
||||
#include "IndicRearrangementProcessor.h"
|
||||
#include "LEGlyphStorage.h"
|
||||
#include "LESwaps.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(IndicRearrangementProcessor)
|
||||
|
||||
IndicRearrangementProcessor::IndicRearrangementProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success)
|
||||
: StateTableProcessor(morphSubtableHeader, success),
|
||||
indicRearrangementSubtableHeader(morphSubtableHeader, success),
|
||||
entryTable(stateTableHeader, success, (const IndicRearrangementStateEntry*)(&stateTableHeader->stHeader),
|
||||
entryTableOffset, LE_UNBOUNDED_ARRAY),
|
||||
int16Table(stateTableHeader, success, (const le_int16*)entryTable.getAlias(), 0, LE_UNBOUNDED_ARRAY)
|
||||
|
||||
{
|
||||
}
|
||||
|
||||
IndicRearrangementProcessor::~IndicRearrangementProcessor()
|
||||
{
|
||||
}
|
||||
|
||||
void IndicRearrangementProcessor::beginStateTable()
|
||||
{
|
||||
firstGlyph = 0;
|
||||
lastGlyph = 0;
|
||||
}
|
||||
|
||||
ByteOffset IndicRearrangementProcessor::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index)
|
||||
{
|
||||
LEErrorCode success = LE_NO_ERROR; // todo- make a param?
|
||||
const IndicRearrangementStateEntry *entry = entryTable.getAlias(index,success);
|
||||
ByteOffset newState = SWAPW(entry->newStateOffset);
|
||||
IndicRearrangementFlags flags = (IndicRearrangementFlags) SWAPW(entry->flags);
|
||||
|
||||
if (flags & irfMarkFirst) {
|
||||
firstGlyph = (le_uint32)currGlyph;
|
||||
}
|
||||
|
||||
if (flags & irfMarkLast) {
|
||||
lastGlyph = (le_uint32)currGlyph;
|
||||
}
|
||||
|
||||
doRearrangementAction(glyphStorage, (IndicRearrangementVerb) (flags & irfVerbMask), success);
|
||||
|
||||
if (!(flags & irfDontAdvance)) {
|
||||
// XXX: Should handle reverse too...
|
||||
currGlyph += 1;
|
||||
}
|
||||
|
||||
return newState;
|
||||
}
|
||||
|
||||
void IndicRearrangementProcessor::endStateTable()
|
||||
{
|
||||
}
|
||||
|
||||
void IndicRearrangementProcessor::doRearrangementAction(LEGlyphStorage &glyphStorage, IndicRearrangementVerb verb, LEErrorCode &success) const
|
||||
{
|
||||
LEGlyphID a, b, c, d;
|
||||
le_int32 ia, ib, ic, id, ix, x;
|
||||
|
||||
if (LE_FAILURE(success)) return;
|
||||
|
||||
if (verb == irvNoAction) {
|
||||
return;
|
||||
}
|
||||
if (firstGlyph > lastGlyph) {
|
||||
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
switch(verb)
|
||||
{
|
||||
case irvxA:
|
||||
if (firstGlyph == lastGlyph) break;
|
||||
if (firstGlyph + 1 < firstGlyph) {
|
||||
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
|
||||
break;
|
||||
}
|
||||
a = glyphStorage[firstGlyph];
|
||||
ia = glyphStorage.getCharIndex(firstGlyph, success);
|
||||
x = firstGlyph + 1;
|
||||
|
||||
while (x <= (int32_t)lastGlyph) {
|
||||
glyphStorage[x - 1] = glyphStorage[x];
|
||||
ix = glyphStorage.getCharIndex(x, success);
|
||||
glyphStorage.setCharIndex(x - 1, ix, success);
|
||||
x += 1;
|
||||
}
|
||||
|
||||
glyphStorage[lastGlyph] = a;
|
||||
glyphStorage.setCharIndex(lastGlyph, ia, success);
|
||||
break;
|
||||
|
||||
case irvDx:
|
||||
if (firstGlyph == lastGlyph) break;
|
||||
if (lastGlyph - 1 > lastGlyph) {
|
||||
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
|
||||
break;
|
||||
}
|
||||
d = glyphStorage[lastGlyph];
|
||||
id = glyphStorage.getCharIndex(lastGlyph, success);
|
||||
x = lastGlyph - 1;
|
||||
|
||||
while (x >= (int32_t)firstGlyph) {
|
||||
glyphStorage[x + 1] = glyphStorage[x];
|
||||
ix = glyphStorage.getCharIndex(x, success);
|
||||
glyphStorage.setCharIndex(x + 1, ix, success);
|
||||
x -= 1;
|
||||
}
|
||||
|
||||
glyphStorage[firstGlyph] = d;
|
||||
glyphStorage.setCharIndex(firstGlyph, id, success);
|
||||
break;
|
||||
|
||||
case irvDxA:
|
||||
a = glyphStorage[firstGlyph];
|
||||
ia = glyphStorage.getCharIndex(firstGlyph, success);
|
||||
id = glyphStorage.getCharIndex(lastGlyph, success);
|
||||
|
||||
glyphStorage[firstGlyph] = glyphStorage[lastGlyph];
|
||||
glyphStorage[lastGlyph] = a;
|
||||
|
||||
glyphStorage.setCharIndex(firstGlyph, id, success);
|
||||
glyphStorage.setCharIndex(lastGlyph, ia, success);
|
||||
break;
|
||||
|
||||
case irvxAB:
|
||||
if ((firstGlyph + 2 < firstGlyph) ||
|
||||
(lastGlyph - firstGlyph < 1)) { // difference == 1 is a no-op, < 1 is an error.
|
||||
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
|
||||
break;
|
||||
}
|
||||
a = glyphStorage[firstGlyph];
|
||||
b = glyphStorage[firstGlyph + 1];
|
||||
ia = glyphStorage.getCharIndex(firstGlyph, success);
|
||||
ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
|
||||
x = firstGlyph + 2;
|
||||
|
||||
while (x <= (int32_t)lastGlyph) {
|
||||
glyphStorage[x - 2] = glyphStorage[x];
|
||||
ix = glyphStorage.getCharIndex(x, success);
|
||||
glyphStorage.setCharIndex(x - 2, ix, success);
|
||||
x += 1;
|
||||
}
|
||||
|
||||
glyphStorage[lastGlyph - 1] = a;
|
||||
glyphStorage[lastGlyph] = b;
|
||||
|
||||
glyphStorage.setCharIndex(lastGlyph - 1, ia, success);
|
||||
glyphStorage.setCharIndex(lastGlyph, ib, success);
|
||||
break;
|
||||
|
||||
case irvxBA:
|
||||
if ((firstGlyph + 2 < firstGlyph) ||
|
||||
(lastGlyph - firstGlyph < 1)) {
|
||||
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
|
||||
break;
|
||||
}
|
||||
a = glyphStorage[firstGlyph];
|
||||
b = glyphStorage[firstGlyph + 1];
|
||||
ia = glyphStorage.getCharIndex(firstGlyph, success);
|
||||
ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
|
||||
x = firstGlyph + 2;
|
||||
|
||||
while (x <= (int32_t)lastGlyph) {
|
||||
glyphStorage[x - 2] = glyphStorage[x];
|
||||
ix = glyphStorage.getCharIndex(x, success);
|
||||
glyphStorage.setCharIndex(x - 2, ix, success);
|
||||
x += 1;
|
||||
}
|
||||
|
||||
glyphStorage[lastGlyph - 1] = b;
|
||||
glyphStorage[lastGlyph] = a;
|
||||
|
||||
glyphStorage.setCharIndex(lastGlyph - 1, ib, success);
|
||||
glyphStorage.setCharIndex(lastGlyph, ia, success);
|
||||
break;
|
||||
|
||||
case irvCDx:
|
||||
if ((lastGlyph - 2 > lastGlyph) ||
|
||||
(lastGlyph - firstGlyph < 1)) {
|
||||
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
|
||||
break;
|
||||
}
|
||||
c = glyphStorage[lastGlyph - 1];
|
||||
d = glyphStorage[lastGlyph];
|
||||
ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
|
||||
id = glyphStorage.getCharIndex(lastGlyph, success);
|
||||
x = lastGlyph - 2;
|
||||
|
||||
while (x >= (int32_t)firstGlyph) {
|
||||
glyphStorage[x + 2] = glyphStorage[x];
|
||||
ix = glyphStorage.getCharIndex(x, success);
|
||||
glyphStorage.setCharIndex(x + 2, ix, success);
|
||||
x -= 1;
|
||||
}
|
||||
|
||||
glyphStorage[firstGlyph] = c;
|
||||
glyphStorage[firstGlyph + 1] = d;
|
||||
|
||||
glyphStorage.setCharIndex(firstGlyph, ic, success);
|
||||
glyphStorage.setCharIndex(firstGlyph + 1, id, success);
|
||||
break;
|
||||
|
||||
case irvDCx:
|
||||
if ((lastGlyph - 2 > lastGlyph) ||
|
||||
(lastGlyph - firstGlyph < 1)) {
|
||||
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
|
||||
break;
|
||||
}
|
||||
c = glyphStorage[lastGlyph - 1];
|
||||
d = glyphStorage[lastGlyph];
|
||||
ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
|
||||
id = glyphStorage.getCharIndex(lastGlyph, success);
|
||||
x = lastGlyph - 2;
|
||||
|
||||
while (x >= (int32_t)firstGlyph) {
|
||||
glyphStorage[x + 2] = glyphStorage[x];
|
||||
ix = glyphStorage.getCharIndex(x, success);
|
||||
glyphStorage.setCharIndex(x + 2, ix, success);
|
||||
x -= 1;
|
||||
}
|
||||
|
||||
glyphStorage[firstGlyph] = d;
|
||||
glyphStorage[firstGlyph + 1] = c;
|
||||
|
||||
glyphStorage.setCharIndex(firstGlyph, id, success);
|
||||
glyphStorage.setCharIndex(firstGlyph + 1, ic, success);
|
||||
break;
|
||||
|
||||
case irvCDxA:
|
||||
if ((lastGlyph - 2 > lastGlyph) ||
|
||||
(lastGlyph - firstGlyph < 2)) {
|
||||
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
|
||||
break;
|
||||
}
|
||||
a = glyphStorage[firstGlyph];
|
||||
c = glyphStorage[lastGlyph - 1];
|
||||
d = glyphStorage[lastGlyph];
|
||||
ia = glyphStorage.getCharIndex(firstGlyph, success);
|
||||
ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
|
||||
id = glyphStorage.getCharIndex(lastGlyph, success);
|
||||
x = lastGlyph - 2;
|
||||
|
||||
while (x > (int32_t)firstGlyph) {
|
||||
glyphStorage[x + 1] = glyphStorage[x];
|
||||
ix = glyphStorage.getCharIndex(x, success);
|
||||
glyphStorage.setCharIndex(x + 1, ix, success);
|
||||
x -= 1;
|
||||
}
|
||||
|
||||
glyphStorage[firstGlyph] = c;
|
||||
glyphStorage[firstGlyph + 1] = d;
|
||||
glyphStorage[lastGlyph] = a;
|
||||
|
||||
glyphStorage.setCharIndex(firstGlyph, ic, success);
|
||||
glyphStorage.setCharIndex(firstGlyph + 1, id, success);
|
||||
glyphStorage.setCharIndex(lastGlyph, ia, success);
|
||||
break;
|
||||
|
||||
case irvDCxA:
|
||||
if ((lastGlyph - 2 > lastGlyph) ||
|
||||
(lastGlyph - firstGlyph < 2)) {
|
||||
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
|
||||
break;
|
||||
}
|
||||
a = glyphStorage[firstGlyph];
|
||||
c = glyphStorage[lastGlyph - 1];
|
||||
d = glyphStorage[lastGlyph];
|
||||
ia = glyphStorage.getCharIndex(firstGlyph, success);
|
||||
ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
|
||||
id = glyphStorage.getCharIndex(lastGlyph, success);
|
||||
x = lastGlyph - 2;
|
||||
|
||||
while (x > (int32_t)firstGlyph) {
|
||||
glyphStorage[x + 1] = glyphStorage[x];
|
||||
ix = glyphStorage.getCharIndex(x, success);
|
||||
glyphStorage.setCharIndex(x + 1, ix, success);
|
||||
x -= 1;
|
||||
}
|
||||
|
||||
glyphStorage[firstGlyph] = d;
|
||||
glyphStorage[firstGlyph + 1] = c;
|
||||
glyphStorage[lastGlyph] = a;
|
||||
|
||||
glyphStorage.setCharIndex(firstGlyph, id, success);
|
||||
glyphStorage.setCharIndex(firstGlyph + 1, ic, success);
|
||||
glyphStorage.setCharIndex(lastGlyph, ia, success);
|
||||
break;
|
||||
|
||||
case irvDxAB:
|
||||
if ((firstGlyph + 2 < firstGlyph) ||
|
||||
(lastGlyph - firstGlyph < 2)) {
|
||||
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
|
||||
break;
|
||||
}
|
||||
a = glyphStorage[firstGlyph];
|
||||
b = glyphStorage[firstGlyph + 1];
|
||||
d = glyphStorage[lastGlyph];
|
||||
ia = glyphStorage.getCharIndex(firstGlyph, success);
|
||||
ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
|
||||
id = glyphStorage.getCharIndex(lastGlyph, success);
|
||||
x = firstGlyph + 2;
|
||||
|
||||
while (x < (int32_t)lastGlyph) {
|
||||
glyphStorage[x - 2] = glyphStorage[x];
|
||||
ix = glyphStorage.getCharIndex(x, success);
|
||||
glyphStorage.setCharIndex(x - 2, ix, success);
|
||||
x += 1;
|
||||
}
|
||||
|
||||
glyphStorage[firstGlyph] = d;
|
||||
glyphStorage[lastGlyph - 1] = a;
|
||||
glyphStorage[lastGlyph] = b;
|
||||
|
||||
glyphStorage.setCharIndex(firstGlyph, id, success);
|
||||
glyphStorage.setCharIndex(lastGlyph - 1, ia, success);
|
||||
glyphStorage.setCharIndex(lastGlyph, ib, success);
|
||||
break;
|
||||
|
||||
case irvDxBA:
|
||||
if ((firstGlyph + 2 < firstGlyph) ||
|
||||
(lastGlyph - firstGlyph < 2)) {
|
||||
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
|
||||
break;
|
||||
}
|
||||
a = glyphStorage[firstGlyph];
|
||||
b = glyphStorage[firstGlyph + 1];
|
||||
d = glyphStorage[lastGlyph];
|
||||
ia = glyphStorage.getCharIndex(firstGlyph, success);
|
||||
ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
|
||||
id = glyphStorage.getCharIndex(lastGlyph, success);
|
||||
x = firstGlyph + 2;
|
||||
|
||||
while (x < (int32_t)lastGlyph) {
|
||||
glyphStorage[x - 2] = glyphStorage[x];
|
||||
ix = glyphStorage.getCharIndex(x, success);
|
||||
glyphStorage.setCharIndex(x - 2, ix, success);
|
||||
x += 1;
|
||||
}
|
||||
|
||||
glyphStorage[firstGlyph] = d;
|
||||
glyphStorage[lastGlyph - 1] = b;
|
||||
glyphStorage[lastGlyph] = a;
|
||||
|
||||
glyphStorage.setCharIndex(firstGlyph, id, success);
|
||||
glyphStorage.setCharIndex(lastGlyph - 1, ib, success);
|
||||
glyphStorage.setCharIndex(lastGlyph, ia, success);
|
||||
break;
|
||||
|
||||
case irvCDxAB:
|
||||
if (lastGlyph - firstGlyph < 3) {
|
||||
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
|
||||
break;
|
||||
}
|
||||
a = glyphStorage[firstGlyph];
|
||||
b = glyphStorage[firstGlyph + 1];
|
||||
|
||||
glyphStorage[firstGlyph] = glyphStorage[lastGlyph - 1];
|
||||
glyphStorage[firstGlyph + 1] = glyphStorage[lastGlyph];
|
||||
|
||||
glyphStorage[lastGlyph - 1] = a;
|
||||
glyphStorage[lastGlyph] = b;
|
||||
|
||||
ia = glyphStorage.getCharIndex(firstGlyph, success);
|
||||
ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
|
||||
ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
|
||||
id = glyphStorage.getCharIndex(lastGlyph, success);
|
||||
|
||||
glyphStorage.setCharIndex(firstGlyph, ic, success);
|
||||
glyphStorage.setCharIndex(firstGlyph + 1, id, success);
|
||||
|
||||
glyphStorage.setCharIndex(lastGlyph - 1, ia, success);
|
||||
glyphStorage.setCharIndex(lastGlyph, ib, success);
|
||||
break;
|
||||
|
||||
case irvCDxBA:
|
||||
if (lastGlyph - firstGlyph < 3) {
|
||||
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
|
||||
break;
|
||||
}
|
||||
a = glyphStorage[firstGlyph];
|
||||
b = glyphStorage[firstGlyph + 1];
|
||||
|
||||
glyphStorage[firstGlyph] = glyphStorage[lastGlyph - 1];
|
||||
glyphStorage[firstGlyph + 1] = glyphStorage[lastGlyph];
|
||||
|
||||
glyphStorage[lastGlyph - 1] = b;
|
||||
glyphStorage[lastGlyph] = a;
|
||||
|
||||
ia = glyphStorage.getCharIndex(firstGlyph, success);
|
||||
ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
|
||||
ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
|
||||
id = glyphStorage.getCharIndex(lastGlyph, success);
|
||||
|
||||
glyphStorage.setCharIndex(firstGlyph, ic, success);
|
||||
glyphStorage.setCharIndex(firstGlyph + 1, id, success);
|
||||
|
||||
glyphStorage.setCharIndex(lastGlyph - 1, ib, success);
|
||||
glyphStorage.setCharIndex(lastGlyph, ia, success);
|
||||
break;
|
||||
|
||||
case irvDCxAB:
|
||||
if (lastGlyph - firstGlyph < 3) {
|
||||
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
|
||||
break;
|
||||
}
|
||||
a = glyphStorage[firstGlyph];
|
||||
b = glyphStorage[firstGlyph + 1];
|
||||
|
||||
glyphStorage[firstGlyph] = glyphStorage[lastGlyph];
|
||||
glyphStorage[firstGlyph + 1] = glyphStorage[lastGlyph - 1];
|
||||
|
||||
glyphStorage[lastGlyph - 1] = a;
|
||||
glyphStorage[lastGlyph] = b;
|
||||
|
||||
ia = glyphStorage.getCharIndex(firstGlyph, success);
|
||||
ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
|
||||
ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
|
||||
id = glyphStorage.getCharIndex(lastGlyph, success);
|
||||
|
||||
glyphStorage.setCharIndex(firstGlyph, id, success);
|
||||
glyphStorage.setCharIndex(firstGlyph + 1, ic, success);
|
||||
|
||||
glyphStorage.setCharIndex(lastGlyph - 1, ia, success);
|
||||
glyphStorage.setCharIndex(lastGlyph, ib, success);
|
||||
break;
|
||||
|
||||
case irvDCxBA:
|
||||
if (lastGlyph - firstGlyph < 3) {
|
||||
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
|
||||
break;
|
||||
}
|
||||
a = glyphStorage[firstGlyph];
|
||||
b = glyphStorage[firstGlyph + 1];
|
||||
|
||||
glyphStorage[firstGlyph] = glyphStorage[lastGlyph];
|
||||
glyphStorage[firstGlyph + 1] = glyphStorage[lastGlyph - 1];
|
||||
|
||||
glyphStorage[lastGlyph - 1] = b;
|
||||
glyphStorage[lastGlyph] = a;
|
||||
|
||||
ia = glyphStorage.getCharIndex(firstGlyph, success);
|
||||
ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
|
||||
ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
|
||||
id = glyphStorage.getCharIndex(lastGlyph, success);
|
||||
|
||||
glyphStorage.setCharIndex(firstGlyph, id, success);
|
||||
glyphStorage.setCharIndex(firstGlyph + 1, ic, success);
|
||||
|
||||
glyphStorage.setCharIndex(lastGlyph - 1, ib, success);
|
||||
glyphStorage.setCharIndex(lastGlyph, ia, success);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
|
@ -1,66 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2015 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __INDICREARRANGEMENTPROCESSOR_H
|
||||
#define __INDICREARRANGEMENTPROCESSOR_H
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \internal
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "MorphTables.h"
|
||||
#include "SubtableProcessor.h"
|
||||
#include "StateTableProcessor.h"
|
||||
#include "IndicRearrangement.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class LEGlyphStorage;
|
||||
|
||||
class IndicRearrangementProcessor : public StateTableProcessor
|
||||
{
|
||||
public:
|
||||
virtual void beginStateTable();
|
||||
|
||||
virtual ByteOffset processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index);
|
||||
|
||||
virtual void endStateTable();
|
||||
|
||||
void doRearrangementAction(LEGlyphStorage &glyphStorage, IndicRearrangementVerb verb, LEErrorCode &success) const;
|
||||
|
||||
IndicRearrangementProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success);
|
||||
virtual ~IndicRearrangementProcessor();
|
||||
|
||||
/**
|
||||
* ICU "poor man's RTTI", returns a UClassID for the actual class.
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
virtual UClassID getDynamicClassID() const;
|
||||
|
||||
/**
|
||||
* ICU "poor man's RTTI", returns a UClassID for this class.
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
static UClassID getStaticClassID();
|
||||
|
||||
protected:
|
||||
le_uint32 firstGlyph;
|
||||
le_uint32 lastGlyph;
|
||||
|
||||
LEReferenceTo<IndicRearrangementSubtableHeader> indicRearrangementSubtableHeader;
|
||||
LEReferenceToArrayOf<IndicRearrangementStateEntry> entryTable;
|
||||
LEReferenceToArrayOf<le_int16> int16Table;
|
||||
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
|
@ -1,474 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. and others 1998-2016 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "MorphTables.h"
|
||||
#include "StateTables.h"
|
||||
#include "MorphStateTables.h"
|
||||
#include "SubtableProcessor2.h"
|
||||
#include "StateTableProcessor2.h"
|
||||
#include "IndicRearrangementProcessor2.h"
|
||||
#include "LEGlyphStorage.h"
|
||||
#include "LESwaps.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(IndicRearrangementProcessor2)
|
||||
|
||||
IndicRearrangementProcessor2::IndicRearrangementProcessor2(
|
||||
const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success)
|
||||
: StateTableProcessor2(morphSubtableHeader, success), entryTable(stHeader, success, entryTableOffset, LE_UNBOUNDED_ARRAY),
|
||||
indicRearrangementSubtableHeader(morphSubtableHeader, success)
|
||||
{
|
||||
}
|
||||
|
||||
IndicRearrangementProcessor2::~IndicRearrangementProcessor2()
|
||||
{
|
||||
}
|
||||
|
||||
void IndicRearrangementProcessor2::beginStateTable()
|
||||
{
|
||||
firstGlyph = 0;
|
||||
lastGlyph = 0;
|
||||
}
|
||||
|
||||
le_uint16 IndicRearrangementProcessor2::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph,
|
||||
EntryTableIndex2 index, LEErrorCode &success)
|
||||
{
|
||||
const IndicRearrangementStateEntry2 *entry = entryTable.getAlias(index, success);
|
||||
if (LE_FAILURE(success)) return 0; // TODO - what to return in bad state?
|
||||
le_uint16 newState = SWAPW(entry->newStateIndex); // index to the new state
|
||||
IndicRearrangementFlags flags = (IndicRearrangementFlags) SWAPW(entry->flags);
|
||||
|
||||
if (flags & irfMarkFirst) {
|
||||
firstGlyph = (le_uint32)currGlyph;
|
||||
}
|
||||
|
||||
if (flags & irfMarkLast) {
|
||||
lastGlyph = (le_uint32)currGlyph;
|
||||
}
|
||||
|
||||
doRearrangementAction(glyphStorage, (IndicRearrangementVerb) (flags & irfVerbMask), success);
|
||||
|
||||
if (!(flags & irfDontAdvance)) {
|
||||
currGlyph += dir;
|
||||
}
|
||||
|
||||
return newState; // index to new state
|
||||
}
|
||||
|
||||
void IndicRearrangementProcessor2::endStateTable()
|
||||
{
|
||||
}
|
||||
|
||||
void IndicRearrangementProcessor2::doRearrangementAction(LEGlyphStorage &glyphStorage, IndicRearrangementVerb verb, LEErrorCode &success) const
|
||||
{
|
||||
LEGlyphID a, b, c, d;
|
||||
le_int32 ia, ib, ic, id, ix, x;
|
||||
|
||||
if (LE_FAILURE(success)) return;
|
||||
|
||||
if (verb == irvNoAction) {
|
||||
return;
|
||||
}
|
||||
if (firstGlyph > lastGlyph) {
|
||||
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
switch(verb)
|
||||
{
|
||||
case irvxA:
|
||||
if (firstGlyph == lastGlyph) break;
|
||||
if (firstGlyph + 1 < firstGlyph) {
|
||||
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
|
||||
break;
|
||||
}
|
||||
a = glyphStorage[firstGlyph];
|
||||
ia = glyphStorage.getCharIndex(firstGlyph, success);
|
||||
x = firstGlyph + 1;
|
||||
|
||||
while (x <= (int32_t)lastGlyph) {
|
||||
glyphStorage[x - 1] = glyphStorage[x];
|
||||
ix = glyphStorage.getCharIndex(x, success);
|
||||
glyphStorage.setCharIndex(x - 1, ix, success);
|
||||
x += 1;
|
||||
}
|
||||
|
||||
glyphStorage[lastGlyph] = a;
|
||||
glyphStorage.setCharIndex(lastGlyph, ia, success);
|
||||
break;
|
||||
|
||||
case irvDx:
|
||||
if (firstGlyph == lastGlyph) break;
|
||||
if (lastGlyph - 1 > lastGlyph) {
|
||||
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
|
||||
break;
|
||||
}
|
||||
d = glyphStorage[lastGlyph];
|
||||
id = glyphStorage.getCharIndex(lastGlyph, success);
|
||||
x = lastGlyph - 1;
|
||||
|
||||
while (x >= (int32_t)firstGlyph) {
|
||||
glyphStorage[x + 1] = glyphStorage[x];
|
||||
ix = glyphStorage.getCharIndex(x, success);
|
||||
glyphStorage.setCharIndex(x + 1, ix, success);
|
||||
x -= 1;
|
||||
}
|
||||
|
||||
glyphStorage[firstGlyph] = d;
|
||||
glyphStorage.setCharIndex(firstGlyph, id, success);
|
||||
break;
|
||||
|
||||
case irvDxA:
|
||||
a = glyphStorage[firstGlyph];
|
||||
ia = glyphStorage.getCharIndex(firstGlyph, success);
|
||||
id = glyphStorage.getCharIndex(lastGlyph, success);
|
||||
|
||||
glyphStorage[firstGlyph] = glyphStorage[lastGlyph];
|
||||
glyphStorage[lastGlyph] = a;
|
||||
|
||||
glyphStorage.setCharIndex(firstGlyph, id, success);
|
||||
glyphStorage.setCharIndex(lastGlyph, ia, success);
|
||||
break;
|
||||
|
||||
case irvxAB:
|
||||
if ((firstGlyph + 2 < firstGlyph) ||
|
||||
(lastGlyph - firstGlyph < 1)) { // difference == 1 is a no-op, < 1 is an error.
|
||||
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
|
||||
break;
|
||||
}
|
||||
a = glyphStorage[firstGlyph];
|
||||
b = glyphStorage[firstGlyph + 1];
|
||||
ia = glyphStorage.getCharIndex(firstGlyph, success);
|
||||
ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
|
||||
x = firstGlyph + 2;
|
||||
|
||||
while (x <= (int32_t)lastGlyph) {
|
||||
glyphStorage[x - 2] = glyphStorage[x];
|
||||
ix = glyphStorage.getCharIndex(x, success);
|
||||
glyphStorage.setCharIndex(x - 2, ix, success);
|
||||
x += 1;
|
||||
}
|
||||
|
||||
glyphStorage[lastGlyph - 1] = a;
|
||||
glyphStorage[lastGlyph] = b;
|
||||
|
||||
glyphStorage.setCharIndex(lastGlyph - 1, ia, success);
|
||||
glyphStorage.setCharIndex(lastGlyph, ib, success);
|
||||
break;
|
||||
|
||||
case irvxBA:
|
||||
if ((firstGlyph + 2 < firstGlyph) ||
|
||||
(lastGlyph - firstGlyph < 1)) {
|
||||
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
|
||||
break;
|
||||
}
|
||||
a = glyphStorage[firstGlyph];
|
||||
b = glyphStorage[firstGlyph + 1];
|
||||
ia = glyphStorage.getCharIndex(firstGlyph, success);
|
||||
ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
|
||||
x = firstGlyph + 2;
|
||||
|
||||
while (x <= (int32_t)lastGlyph) {
|
||||
glyphStorage[x - 2] = glyphStorage[x];
|
||||
ix = glyphStorage.getCharIndex(x, success);
|
||||
glyphStorage.setCharIndex(x - 2, ix, success);
|
||||
x += 1;
|
||||
}
|
||||
|
||||
glyphStorage[lastGlyph - 1] = b;
|
||||
glyphStorage[lastGlyph] = a;
|
||||
|
||||
glyphStorage.setCharIndex(lastGlyph - 1, ib, success);
|
||||
glyphStorage.setCharIndex(lastGlyph, ia, success);
|
||||
break;
|
||||
|
||||
case irvCDx:
|
||||
if ((lastGlyph - 2 > lastGlyph) ||
|
||||
(lastGlyph - firstGlyph < 1)) {
|
||||
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
|
||||
break;
|
||||
}
|
||||
c = glyphStorage[lastGlyph - 1];
|
||||
d = glyphStorage[lastGlyph];
|
||||
ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
|
||||
id = glyphStorage.getCharIndex(lastGlyph, success);
|
||||
x = lastGlyph - 2;
|
||||
|
||||
while (x >= (int32_t)firstGlyph) {
|
||||
glyphStorage[x + 2] = glyphStorage[x];
|
||||
ix = glyphStorage.getCharIndex(x, success);
|
||||
glyphStorage.setCharIndex(x + 2, ix, success);
|
||||
x -= 1;
|
||||
}
|
||||
|
||||
glyphStorage[firstGlyph] = c;
|
||||
glyphStorage[firstGlyph + 1] = d;
|
||||
|
||||
glyphStorage.setCharIndex(firstGlyph, ic, success);
|
||||
glyphStorage.setCharIndex(firstGlyph + 1, id, success);
|
||||
break;
|
||||
|
||||
case irvDCx:
|
||||
if ((lastGlyph - 2 > lastGlyph) ||
|
||||
(lastGlyph - firstGlyph < 1)) {
|
||||
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
|
||||
break;
|
||||
}
|
||||
c = glyphStorage[lastGlyph - 1];
|
||||
d = glyphStorage[lastGlyph];
|
||||
ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
|
||||
id = glyphStorage.getCharIndex(lastGlyph, success);
|
||||
x = lastGlyph - 2;
|
||||
|
||||
while (x >= (int32_t)firstGlyph) {
|
||||
glyphStorage[x + 2] = glyphStorage[x];
|
||||
ix = glyphStorage.getCharIndex(x, success);
|
||||
glyphStorage.setCharIndex(x + 2, ix, success);
|
||||
x -= 1;
|
||||
}
|
||||
|
||||
glyphStorage[firstGlyph] = d;
|
||||
glyphStorage[firstGlyph + 1] = c;
|
||||
|
||||
glyphStorage.setCharIndex(firstGlyph, id, success);
|
||||
glyphStorage.setCharIndex(firstGlyph + 1, ic, success);
|
||||
break;
|
||||
|
||||
case irvCDxA:
|
||||
if ((lastGlyph - 2 > lastGlyph) ||
|
||||
(lastGlyph - firstGlyph < 2)) {
|
||||
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
|
||||
break;
|
||||
}
|
||||
a = glyphStorage[firstGlyph];
|
||||
c = glyphStorage[lastGlyph - 1];
|
||||
d = glyphStorage[lastGlyph];
|
||||
ia = glyphStorage.getCharIndex(firstGlyph, success);
|
||||
ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
|
||||
id = glyphStorage.getCharIndex(lastGlyph, success);
|
||||
x = lastGlyph - 2;
|
||||
|
||||
while (x > (int32_t)firstGlyph) {
|
||||
glyphStorage[x + 1] = glyphStorage[x];
|
||||
ix = glyphStorage.getCharIndex(x, success);
|
||||
glyphStorage.setCharIndex(x + 1, ix, success);
|
||||
x -= 1;
|
||||
}
|
||||
|
||||
glyphStorage[firstGlyph] = c;
|
||||
glyphStorage[firstGlyph + 1] = d;
|
||||
glyphStorage[lastGlyph] = a;
|
||||
|
||||
glyphStorage.setCharIndex(firstGlyph, ic, success);
|
||||
glyphStorage.setCharIndex(firstGlyph + 1, id, success);
|
||||
glyphStorage.setCharIndex(lastGlyph, ia, success);
|
||||
break;
|
||||
|
||||
case irvDCxA:
|
||||
if ((lastGlyph - 2 > lastGlyph) ||
|
||||
(lastGlyph - firstGlyph < 2)) {
|
||||
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
|
||||
break;
|
||||
}
|
||||
a = glyphStorage[firstGlyph];
|
||||
c = glyphStorage[lastGlyph - 1];
|
||||
d = glyphStorage[lastGlyph];
|
||||
ia = glyphStorage.getCharIndex(firstGlyph, success);
|
||||
ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
|
||||
id = glyphStorage.getCharIndex(lastGlyph, success);
|
||||
x = lastGlyph - 2;
|
||||
|
||||
while (x > (int32_t)firstGlyph) {
|
||||
glyphStorage[x + 1] = glyphStorage[x];
|
||||
ix = glyphStorage.getCharIndex(x, success);
|
||||
glyphStorage.setCharIndex(x + 1, ix, success);
|
||||
x -= 1;
|
||||
}
|
||||
|
||||
glyphStorage[firstGlyph] = d;
|
||||
glyphStorage[firstGlyph + 1] = c;
|
||||
glyphStorage[lastGlyph] = a;
|
||||
|
||||
glyphStorage.setCharIndex(firstGlyph, id, success);
|
||||
glyphStorage.setCharIndex(firstGlyph + 1, ic, success);
|
||||
glyphStorage.setCharIndex(lastGlyph, ia, success);
|
||||
break;
|
||||
|
||||
case irvDxAB:
|
||||
if ((firstGlyph + 2 < firstGlyph) ||
|
||||
(lastGlyph - firstGlyph < 2)) {
|
||||
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
|
||||
break;
|
||||
}
|
||||
a = glyphStorage[firstGlyph];
|
||||
b = glyphStorage[firstGlyph + 1];
|
||||
d = glyphStorage[lastGlyph];
|
||||
ia = glyphStorage.getCharIndex(firstGlyph, success);
|
||||
ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
|
||||
id = glyphStorage.getCharIndex(lastGlyph, success);
|
||||
x = firstGlyph + 2;
|
||||
|
||||
while (x < (int32_t)lastGlyph) {
|
||||
glyphStorage[x - 2] = glyphStorage[x];
|
||||
ix = glyphStorage.getCharIndex(x, success);
|
||||
glyphStorage.setCharIndex(x - 2, ix, success);
|
||||
x += 1;
|
||||
}
|
||||
|
||||
glyphStorage[firstGlyph] = d;
|
||||
glyphStorage[lastGlyph - 1] = a;
|
||||
glyphStorage[lastGlyph] = b;
|
||||
|
||||
glyphStorage.setCharIndex(firstGlyph, id, success);
|
||||
glyphStorage.setCharIndex(lastGlyph - 1, ia, success);
|
||||
glyphStorage.setCharIndex(lastGlyph, ib, success);
|
||||
break;
|
||||
|
||||
case irvDxBA:
|
||||
if ((firstGlyph + 2 < firstGlyph) ||
|
||||
(lastGlyph - firstGlyph < 2)) {
|
||||
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
|
||||
break;
|
||||
}
|
||||
a = glyphStorage[firstGlyph];
|
||||
b = glyphStorage[firstGlyph + 1];
|
||||
d = glyphStorage[lastGlyph];
|
||||
ia = glyphStorage.getCharIndex(firstGlyph, success);
|
||||
ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
|
||||
id = glyphStorage.getCharIndex(lastGlyph, success);
|
||||
x = firstGlyph + 2;
|
||||
|
||||
while (x < (int32_t)lastGlyph) {
|
||||
glyphStorage[x - 2] = glyphStorage[x];
|
||||
ix = glyphStorage.getCharIndex(x, success);
|
||||
glyphStorage.setCharIndex(x - 2, ix, success);
|
||||
x += 1;
|
||||
}
|
||||
|
||||
glyphStorage[firstGlyph] = d;
|
||||
glyphStorage[lastGlyph - 1] = b;
|
||||
glyphStorage[lastGlyph] = a;
|
||||
|
||||
glyphStorage.setCharIndex(firstGlyph, id, success);
|
||||
glyphStorage.setCharIndex(lastGlyph - 1, ib, success);
|
||||
glyphStorage.setCharIndex(lastGlyph, ia, success);
|
||||
break;
|
||||
|
||||
case irvCDxAB:
|
||||
if (lastGlyph - firstGlyph < 3) {
|
||||
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
|
||||
break;
|
||||
}
|
||||
a = glyphStorage[firstGlyph];
|
||||
b = glyphStorage[firstGlyph + 1];
|
||||
|
||||
glyphStorage[firstGlyph] = glyphStorage[lastGlyph - 1];
|
||||
glyphStorage[firstGlyph + 1] = glyphStorage[lastGlyph];
|
||||
|
||||
glyphStorage[lastGlyph - 1] = a;
|
||||
glyphStorage[lastGlyph] = b;
|
||||
|
||||
ia = glyphStorage.getCharIndex(firstGlyph, success);
|
||||
ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
|
||||
ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
|
||||
id = glyphStorage.getCharIndex(lastGlyph, success);
|
||||
|
||||
glyphStorage.setCharIndex(firstGlyph, ic, success);
|
||||
glyphStorage.setCharIndex(firstGlyph + 1, id, success);
|
||||
|
||||
glyphStorage.setCharIndex(lastGlyph - 1, ia, success);
|
||||
glyphStorage.setCharIndex(lastGlyph, ib, success);
|
||||
break;
|
||||
|
||||
case irvCDxBA:
|
||||
if (lastGlyph - firstGlyph < 3) {
|
||||
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
|
||||
break;
|
||||
}
|
||||
a = glyphStorage[firstGlyph];
|
||||
b = glyphStorage[firstGlyph + 1];
|
||||
|
||||
glyphStorage[firstGlyph] = glyphStorage[lastGlyph - 1];
|
||||
glyphStorage[firstGlyph + 1] = glyphStorage[lastGlyph];
|
||||
|
||||
glyphStorage[lastGlyph - 1] = b;
|
||||
glyphStorage[lastGlyph] = a;
|
||||
|
||||
ia = glyphStorage.getCharIndex(firstGlyph, success);
|
||||
ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
|
||||
ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
|
||||
id = glyphStorage.getCharIndex(lastGlyph, success);
|
||||
|
||||
glyphStorage.setCharIndex(firstGlyph, ic, success);
|
||||
glyphStorage.setCharIndex(firstGlyph + 1, id, success);
|
||||
|
||||
glyphStorage.setCharIndex(lastGlyph - 1, ib, success);
|
||||
glyphStorage.setCharIndex(lastGlyph, ia, success);
|
||||
break;
|
||||
|
||||
case irvDCxAB:
|
||||
if (lastGlyph - firstGlyph < 3) {
|
||||
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
|
||||
break;
|
||||
}
|
||||
a = glyphStorage[firstGlyph];
|
||||
b = glyphStorage[firstGlyph + 1];
|
||||
|
||||
glyphStorage[firstGlyph] = glyphStorage[lastGlyph];
|
||||
glyphStorage[firstGlyph + 1] = glyphStorage[lastGlyph - 1];
|
||||
|
||||
glyphStorage[lastGlyph - 1] = a;
|
||||
glyphStorage[lastGlyph] = b;
|
||||
|
||||
ia = glyphStorage.getCharIndex(firstGlyph, success);
|
||||
ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
|
||||
ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
|
||||
id = glyphStorage.getCharIndex(lastGlyph, success);
|
||||
|
||||
glyphStorage.setCharIndex(firstGlyph, id, success);
|
||||
glyphStorage.setCharIndex(firstGlyph + 1, ic, success);
|
||||
|
||||
glyphStorage.setCharIndex(lastGlyph - 1, ia, success);
|
||||
glyphStorage.setCharIndex(lastGlyph, ib, success);
|
||||
break;
|
||||
|
||||
case irvDCxBA:
|
||||
if (lastGlyph - firstGlyph < 3) {
|
||||
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
|
||||
break;
|
||||
}
|
||||
a = glyphStorage[firstGlyph];
|
||||
b = glyphStorage[firstGlyph + 1];
|
||||
|
||||
glyphStorage[firstGlyph] = glyphStorage[lastGlyph];
|
||||
glyphStorage[firstGlyph + 1] = glyphStorage[lastGlyph - 1];
|
||||
|
||||
glyphStorage[lastGlyph - 1] = b;
|
||||
glyphStorage[lastGlyph] = a;
|
||||
|
||||
ia = glyphStorage.getCharIndex(firstGlyph, success);
|
||||
ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
|
||||
ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
|
||||
id = glyphStorage.getCharIndex(lastGlyph, success);
|
||||
|
||||
glyphStorage.setCharIndex(firstGlyph, id, success);
|
||||
glyphStorage.setCharIndex(firstGlyph + 1, ic, success);
|
||||
|
||||
glyphStorage.setCharIndex(lastGlyph - 1, ib, success);
|
||||
glyphStorage.setCharIndex(lastGlyph, ia, success);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
|
@ -1,65 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. and others 1998-2015 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __INDICREARRANGEMENTPROCESSOR2_H
|
||||
#define __INDICREARRANGEMENTPROCESSOR2_H
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \internal
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "MorphTables.h"
|
||||
#include "SubtableProcessor.h"
|
||||
#include "StateTableProcessor2.h"
|
||||
#include "IndicRearrangement.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class LEGlyphStorage;
|
||||
|
||||
class IndicRearrangementProcessor2 : public StateTableProcessor2
|
||||
{
|
||||
public:
|
||||
virtual void beginStateTable();
|
||||
|
||||
virtual le_uint16 processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex2 index, LEErrorCode &success);
|
||||
|
||||
virtual void endStateTable();
|
||||
|
||||
void doRearrangementAction(LEGlyphStorage &glyphStorage, IndicRearrangementVerb verb, LEErrorCode &success) const;
|
||||
|
||||
IndicRearrangementProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success);
|
||||
virtual ~IndicRearrangementProcessor2();
|
||||
|
||||
/**
|
||||
* ICU "poor man's RTTI", returns a UClassID for the actual class.
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
virtual UClassID getDynamicClassID() const;
|
||||
|
||||
/**
|
||||
* ICU "poor man's RTTI", returns a UClassID for this class.
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
static UClassID getStaticClassID();
|
||||
|
||||
protected:
|
||||
le_uint32 firstGlyph;
|
||||
le_uint32 lastGlyph;
|
||||
|
||||
LEReferenceToArrayOf<IndicRearrangementStateEntry2> entryTable;
|
||||
LEReferenceTo<IndicRearrangementSubtableHeader2> indicRearrangementSubtableHeader;
|
||||
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
File diff suppressed because it is too large
Load diff
|
@ -1,360 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2011 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __INDICREORDERING_H
|
||||
#define __INDICREORDERING_H
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \internal
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "OpenTypeTables.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
// Characters that get refered to by name...
|
||||
#define C_SIGN_ZWNJ 0x200C
|
||||
#define C_SIGN_ZWJ 0x200D
|
||||
|
||||
// Character class values
|
||||
#define CC_RESERVED 0U
|
||||
#define CC_VOWEL_MODIFIER 1U
|
||||
#define CC_STRESS_MARK 2U
|
||||
#define CC_INDEPENDENT_VOWEL 3U
|
||||
#define CC_INDEPENDENT_VOWEL_2 4U
|
||||
#define CC_INDEPENDENT_VOWEL_3 5U
|
||||
#define CC_CONSONANT 6U
|
||||
#define CC_CONSONANT_WITH_NUKTA 7U
|
||||
#define CC_NUKTA 8U
|
||||
#define CC_DEPENDENT_VOWEL 9U
|
||||
#define CC_SPLIT_VOWEL_PIECE_1 10U
|
||||
#define CC_SPLIT_VOWEL_PIECE_2 11U
|
||||
#define CC_SPLIT_VOWEL_PIECE_3 12U
|
||||
#define CC_VIRAMA 13U
|
||||
#define CC_ZERO_WIDTH_MARK 14U
|
||||
#define CC_AL_LAKUNA 15U
|
||||
#define CC_COUNT 16U
|
||||
|
||||
// Character class flags
|
||||
#define CF_CLASS_MASK 0x0000FFFFU
|
||||
|
||||
#define CF_CONSONANT 0x80000000U
|
||||
|
||||
#define CF_REPH 0x40000000U
|
||||
#define CF_VATTU 0x20000000U
|
||||
#define CF_BELOW_BASE 0x10000000U
|
||||
#define CF_POST_BASE 0x08000000U
|
||||
#define CF_LENGTH_MARK 0x04000000U
|
||||
#define CF_PRE_BASE 0x02000000U
|
||||
|
||||
#define CF_POS_BEFORE 0x00300000U
|
||||
#define CF_POS_BELOW 0x00200000U
|
||||
#define CF_POS_ABOVE 0x00100000U
|
||||
#define CF_POS_AFTER 0x00000000U
|
||||
#define CF_POS_MASK 0x00300000U
|
||||
|
||||
#define CF_INDEX_MASK 0x000F0000U
|
||||
#define CF_INDEX_SHIFT 16
|
||||
|
||||
// Script flag bits
|
||||
#define SF_MATRAS_AFTER_BASE 0x80000000U
|
||||
#define SF_REPH_AFTER_BELOW 0x40000000U
|
||||
#define SF_EYELASH_RA 0x20000000U
|
||||
#define SF_MPRE_FIXUP 0x10000000U
|
||||
#define SF_FILTER_ZERO_WIDTH 0x08000000U
|
||||
|
||||
#define SF_POST_BASE_LIMIT_MASK 0x0000FFFFU
|
||||
#define SF_NO_POST_BASE_LIMIT 0x00007FFFU
|
||||
|
||||
#define SM_MAX_PIECES 3
|
||||
|
||||
typedef LEUnicode SplitMatra[SM_MAX_PIECES];
|
||||
|
||||
class MPreFixups;
|
||||
class LEGlyphStorage;
|
||||
|
||||
// Dynamic Properties ( v2 fonts only )
|
||||
typedef le_uint32 DynamicProperties;
|
||||
|
||||
#define DP_REPH 0x80000000U
|
||||
#define DP_HALF 0x40000000U
|
||||
#define DP_PREF 0x20000000U
|
||||
#define DP_BLWF 0x10000000U
|
||||
#define DP_PSTF 0x08000000U
|
||||
|
||||
struct IndicClassTable
|
||||
{
|
||||
typedef le_uint32 CharClass;
|
||||
typedef le_uint32 ScriptFlags;
|
||||
|
||||
LEUnicode firstChar;
|
||||
LEUnicode lastChar;
|
||||
le_int32 worstCaseExpansion;
|
||||
ScriptFlags scriptFlags;
|
||||
const CharClass *classTable;
|
||||
const SplitMatra *splitMatraTable;
|
||||
|
||||
inline le_int32 getWorstCaseExpansion() const;
|
||||
inline le_bool getFilterZeroWidth() const;
|
||||
|
||||
CharClass getCharClass(LEUnicode ch) const;
|
||||
|
||||
inline const SplitMatra *getSplitMatra(CharClass charClass) const;
|
||||
|
||||
inline le_bool isVowelModifier(LEUnicode ch) const;
|
||||
inline le_bool isStressMark(LEUnicode ch) const;
|
||||
inline le_bool isConsonant(LEUnicode ch) const;
|
||||
inline le_bool isReph(LEUnicode ch) const;
|
||||
inline le_bool isVirama(LEUnicode ch) const;
|
||||
inline le_bool isAlLakuna(LEUnicode ch) const;
|
||||
inline le_bool isNukta(LEUnicode ch) const;
|
||||
inline le_bool isVattu(LEUnicode ch) const;
|
||||
inline le_bool isMatra(LEUnicode ch) const;
|
||||
inline le_bool isSplitMatra(LEUnicode ch) const;
|
||||
inline le_bool isLengthMark(LEUnicode ch) const;
|
||||
inline le_bool hasPostOrBelowBaseForm(LEUnicode ch) const;
|
||||
inline le_bool hasPostBaseForm(LEUnicode ch) const;
|
||||
inline le_bool hasBelowBaseForm(LEUnicode ch) const;
|
||||
inline le_bool hasAboveBaseForm(LEUnicode ch) const;
|
||||
inline le_bool hasPreBaseForm(LEUnicode ch) const;
|
||||
|
||||
inline static le_bool isVowelModifier(CharClass charClass);
|
||||
inline static le_bool isStressMark(CharClass charClass);
|
||||
inline static le_bool isConsonant(CharClass charClass);
|
||||
inline static le_bool isReph(CharClass charClass);
|
||||
inline static le_bool isVirama(CharClass charClass);
|
||||
inline static le_bool isAlLakuna(CharClass charClass);
|
||||
inline static le_bool isNukta(CharClass charClass);
|
||||
inline static le_bool isVattu(CharClass charClass);
|
||||
inline static le_bool isMatra(CharClass charClass);
|
||||
inline static le_bool isSplitMatra(CharClass charClass);
|
||||
inline static le_bool isLengthMark(CharClass charClass);
|
||||
inline static le_bool hasPostOrBelowBaseForm(CharClass charClass);
|
||||
inline static le_bool hasPostBaseForm(CharClass charClass);
|
||||
inline static le_bool hasBelowBaseForm(CharClass charClass);
|
||||
inline static le_bool hasAboveBaseForm(CharClass charClass);
|
||||
inline static le_bool hasPreBaseForm(CharClass charClass);
|
||||
|
||||
static const IndicClassTable *getScriptClassTable(le_int32 scriptCode);
|
||||
};
|
||||
|
||||
class IndicReordering /* not : public UObject because all methods are static */ {
|
||||
public:
|
||||
static le_int32 getWorstCaseExpansion(le_int32 scriptCode);
|
||||
|
||||
static le_bool getFilterZeroWidth(le_int32 scriptCode);
|
||||
|
||||
static le_int32 reorder(const LEUnicode *theChars, le_int32 charCount, le_int32 scriptCode,
|
||||
LEUnicode *outChars, LEGlyphStorage &glyphStorage,
|
||||
MPreFixups **outMPreFixups, LEErrorCode& success);
|
||||
|
||||
static void adjustMPres(MPreFixups *mpreFixups, LEGlyphStorage &glyphStorage, LEErrorCode& success);
|
||||
|
||||
static le_int32 v2process(const LEUnicode *theChars, le_int32 charCount, le_int32 scriptCode,
|
||||
LEUnicode *outChars, LEGlyphStorage &glyphStorage);
|
||||
|
||||
static const FeatureMap *getFeatureMap(le_int32 &count);
|
||||
|
||||
static const FeatureMap *getv2FeatureMap(le_int32 &count);
|
||||
|
||||
static void applyPresentationForms(LEGlyphStorage &glyphStorage, le_int32 count);
|
||||
|
||||
static void finalReordering(LEGlyphStorage &glyphStorage, le_int32 count);
|
||||
|
||||
static void getDynamicProperties(DynamicProperties *dProps, const IndicClassTable *classTable);
|
||||
|
||||
private:
|
||||
// do not instantiate
|
||||
IndicReordering();
|
||||
|
||||
static le_int32 findSyllable(const IndicClassTable *classTable, const LEUnicode *chars, le_int32 prev, le_int32 charCount);
|
||||
|
||||
};
|
||||
|
||||
inline le_int32 IndicClassTable::getWorstCaseExpansion() const
|
||||
{
|
||||
return worstCaseExpansion;
|
||||
}
|
||||
|
||||
inline le_bool IndicClassTable::getFilterZeroWidth() const
|
||||
{
|
||||
return (scriptFlags & SF_FILTER_ZERO_WIDTH) != 0;
|
||||
}
|
||||
|
||||
inline const SplitMatra *IndicClassTable::getSplitMatra(CharClass charClass) const
|
||||
{
|
||||
le_int32 index = (charClass & CF_INDEX_MASK) >> CF_INDEX_SHIFT;
|
||||
|
||||
return &splitMatraTable[index - 1];
|
||||
}
|
||||
|
||||
inline le_bool IndicClassTable::isVowelModifier(CharClass charClass)
|
||||
{
|
||||
return (charClass & CF_CLASS_MASK) == CC_VOWEL_MODIFIER;
|
||||
}
|
||||
|
||||
inline le_bool IndicClassTable::isStressMark(CharClass charClass)
|
||||
{
|
||||
return (charClass & CF_CLASS_MASK) == CC_STRESS_MARK;
|
||||
}
|
||||
|
||||
inline le_bool IndicClassTable::isConsonant(CharClass charClass)
|
||||
{
|
||||
return (charClass & CF_CONSONANT) != 0;
|
||||
}
|
||||
|
||||
inline le_bool IndicClassTable::isReph(CharClass charClass)
|
||||
{
|
||||
return (charClass & CF_REPH) != 0;
|
||||
}
|
||||
|
||||
inline le_bool IndicClassTable::isNukta(CharClass charClass)
|
||||
{
|
||||
return (charClass & CF_CLASS_MASK) == CC_NUKTA;
|
||||
}
|
||||
|
||||
inline le_bool IndicClassTable::isVirama(CharClass charClass)
|
||||
{
|
||||
return (charClass & CF_CLASS_MASK) == CC_VIRAMA;
|
||||
}
|
||||
|
||||
inline le_bool IndicClassTable::isAlLakuna(CharClass charClass)
|
||||
{
|
||||
return (charClass & CF_CLASS_MASK) == CC_AL_LAKUNA;
|
||||
}
|
||||
|
||||
inline le_bool IndicClassTable::isVattu(CharClass charClass)
|
||||
{
|
||||
return (charClass & CF_VATTU) != 0;
|
||||
}
|
||||
|
||||
inline le_bool IndicClassTable::isMatra(CharClass charClass)
|
||||
{
|
||||
charClass &= CF_CLASS_MASK;
|
||||
|
||||
return charClass >= CC_DEPENDENT_VOWEL && charClass <= CC_SPLIT_VOWEL_PIECE_3;
|
||||
}
|
||||
|
||||
inline le_bool IndicClassTable::isSplitMatra(CharClass charClass)
|
||||
{
|
||||
return (charClass & CF_INDEX_MASK) != 0;
|
||||
}
|
||||
|
||||
inline le_bool IndicClassTable::isLengthMark(CharClass charClass)
|
||||
{
|
||||
return (charClass & CF_LENGTH_MARK) != 0;
|
||||
}
|
||||
|
||||
inline le_bool IndicClassTable::hasPostOrBelowBaseForm(CharClass charClass)
|
||||
{
|
||||
return (charClass & (CF_POST_BASE | CF_BELOW_BASE)) != 0;
|
||||
}
|
||||
|
||||
inline le_bool IndicClassTable::hasPostBaseForm(CharClass charClass)
|
||||
{
|
||||
return (charClass & CF_POST_BASE) != 0;
|
||||
}
|
||||
|
||||
inline le_bool IndicClassTable::hasPreBaseForm(CharClass charClass)
|
||||
{
|
||||
return (charClass & CF_PRE_BASE) != 0;
|
||||
}
|
||||
|
||||
inline le_bool IndicClassTable::hasBelowBaseForm(CharClass charClass)
|
||||
{
|
||||
return (charClass & CF_BELOW_BASE) != 0;
|
||||
}
|
||||
|
||||
inline le_bool IndicClassTable::hasAboveBaseForm(CharClass charClass)
|
||||
{
|
||||
return ((charClass & CF_POS_MASK) == CF_POS_ABOVE);
|
||||
}
|
||||
|
||||
inline le_bool IndicClassTable::isVowelModifier(LEUnicode ch) const
|
||||
{
|
||||
return isVowelModifier(getCharClass(ch));
|
||||
}
|
||||
|
||||
inline le_bool IndicClassTable::isStressMark(LEUnicode ch) const
|
||||
{
|
||||
return isStressMark(getCharClass(ch));
|
||||
}
|
||||
|
||||
inline le_bool IndicClassTable::isConsonant(LEUnicode ch) const
|
||||
{
|
||||
return isConsonant(getCharClass(ch));
|
||||
}
|
||||
|
||||
inline le_bool IndicClassTable::isReph(LEUnicode ch) const
|
||||
{
|
||||
return isReph(getCharClass(ch));
|
||||
}
|
||||
|
||||
inline le_bool IndicClassTable::isVirama(LEUnicode ch) const
|
||||
{
|
||||
return isVirama(getCharClass(ch));
|
||||
}
|
||||
|
||||
inline le_bool IndicClassTable::isAlLakuna(LEUnicode ch) const
|
||||
{
|
||||
return isAlLakuna(getCharClass(ch));
|
||||
}
|
||||
|
||||
inline le_bool IndicClassTable::isNukta(LEUnicode ch) const
|
||||
{
|
||||
return isNukta(getCharClass(ch));
|
||||
}
|
||||
|
||||
inline le_bool IndicClassTable::isVattu(LEUnicode ch) const
|
||||
{
|
||||
return isVattu(getCharClass(ch));
|
||||
}
|
||||
|
||||
inline le_bool IndicClassTable::isMatra(LEUnicode ch) const
|
||||
{
|
||||
return isMatra(getCharClass(ch));
|
||||
}
|
||||
|
||||
inline le_bool IndicClassTable::isSplitMatra(LEUnicode ch) const
|
||||
{
|
||||
return isSplitMatra(getCharClass(ch));
|
||||
}
|
||||
|
||||
inline le_bool IndicClassTable::isLengthMark(LEUnicode ch) const
|
||||
{
|
||||
return isLengthMark(getCharClass(ch));
|
||||
}
|
||||
|
||||
inline le_bool IndicClassTable::hasPostOrBelowBaseForm(LEUnicode ch) const
|
||||
{
|
||||
return hasPostOrBelowBaseForm(getCharClass(ch));
|
||||
}
|
||||
|
||||
inline le_bool IndicClassTable::hasPostBaseForm(LEUnicode ch) const
|
||||
{
|
||||
return hasPostBaseForm(getCharClass(ch));
|
||||
}
|
||||
|
||||
inline le_bool IndicClassTable::hasBelowBaseForm(LEUnicode ch) const
|
||||
{
|
||||
return hasBelowBaseForm(getCharClass(ch));
|
||||
}
|
||||
|
||||
inline le_bool IndicClassTable::hasPreBaseForm(LEUnicode ch) const
|
||||
{
|
||||
return hasPreBaseForm(getCharClass(ch));
|
||||
}
|
||||
|
||||
inline le_bool IndicClassTable::hasAboveBaseForm(LEUnicode ch) const
|
||||
{
|
||||
return hasAboveBaseForm(getCharClass(ch));
|
||||
}
|
||||
U_NAMESPACE_END
|
||||
#endif
|
|
@ -1,259 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
* @(#)KernTable.cpp 1.1 04/10/13
|
||||
*
|
||||
* (C) Copyright IBM Corp. 2004-2014 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#include "KernTable.h"
|
||||
#include "LEFontInstance.h"
|
||||
#include "LEGlyphStorage.h"
|
||||
|
||||
#include "LESwaps.h"
|
||||
#include "OpenTypeUtilities.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define KERNTABLE_DEBUG 0
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
struct PairInfo {
|
||||
le_uint16 left; // left glyph of kern pair
|
||||
le_uint16 right; // right glyph of kern pair
|
||||
le_int16 value; // fword, kern value in funits
|
||||
};
|
||||
#define KERN_PAIRINFO_SIZE 6
|
||||
LE_CORRECT_SIZE(PairInfo, KERN_PAIRINFO_SIZE)
|
||||
|
||||
#define SWAP_KEY(p) (((le_uint32) SWAPW((p)->left) << 16) | SWAPW((p)->right))
|
||||
|
||||
struct Subtable_0 {
|
||||
le_uint16 nPairs;
|
||||
le_uint16 searchRange;
|
||||
le_uint16 entrySelector;
|
||||
le_uint16 rangeShift;
|
||||
};
|
||||
#define KERN_SUBTABLE_0_HEADER_SIZE 8
|
||||
LE_CORRECT_SIZE(Subtable_0, KERN_SUBTABLE_0_HEADER_SIZE)
|
||||
|
||||
// Kern table version 0 only
|
||||
struct SubtableHeader {
|
||||
le_uint16 version;
|
||||
le_uint16 length;
|
||||
le_uint16 coverage;
|
||||
};
|
||||
#define KERN_SUBTABLE_HEADER_SIZE 6
|
||||
LE_CORRECT_SIZE(SubtableHeader, KERN_SUBTABLE_HEADER_SIZE)
|
||||
|
||||
// Version 0 only, version 1 has different layout
|
||||
struct KernTableHeader {
|
||||
le_uint16 version;
|
||||
le_uint16 nTables;
|
||||
};
|
||||
#define KERN_TABLE_HEADER_SIZE 4
|
||||
LE_CORRECT_SIZE(KernTableHeader, KERN_TABLE_HEADER_SIZE)
|
||||
|
||||
#define COVERAGE_HORIZONTAL 0x1
|
||||
#define COVERAGE_MINIMUM 0x2
|
||||
#define COVERAGE_CROSS 0x4
|
||||
#define COVERAGE_OVERRIDE 0x8
|
||||
|
||||
/*
|
||||
* This implementation has support for only one subtable, so if the font has
|
||||
* multiple subtables, only the first will be used. If this turns out to
|
||||
* be a problem in practice we should add it.
|
||||
*
|
||||
* This also supports only version 0 of the kern table header, only
|
||||
* Apple supports the latter.
|
||||
*
|
||||
* This implementation isn't careful about the kern table flags, and
|
||||
* might invoke kerning when it is not supposed to. That too I'm
|
||||
* leaving for a bug fix.
|
||||
*
|
||||
* TODO: support multiple subtables
|
||||
* TODO: respect header flags
|
||||
*/
|
||||
KernTable::KernTable(const LETableReference& base, LEErrorCode &success)
|
||||
: pairs(), fTable(base)
|
||||
{
|
||||
if(LE_FAILURE(success) || fTable.isEmpty()) {
|
||||
#if KERNTABLE_DEBUG
|
||||
fprintf(stderr, "no kern data\n");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
LEReferenceTo<KernTableHeader> header(fTable, success);
|
||||
|
||||
#if KERNTABLE_DEBUG
|
||||
// dump first 32 bytes of header
|
||||
for (int i = 0; i < 64; ++i) {
|
||||
fprintf(stderr, "%0.2x ", ((const char*)header.getAlias())[i]&0xff);
|
||||
if (((i+1)&0xf) == 0) {
|
||||
fprintf(stderr, "\n");
|
||||
} else if (((i+1)&0x7) == 0) {
|
||||
fprintf(stderr, " ");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if(LE_FAILURE(success)) return;
|
||||
|
||||
if (!header.isEmpty() && header->version == 0 && SWAPW(header->nTables) > 0) {
|
||||
LEReferenceTo<SubtableHeader> subhead(header, success, KERN_TABLE_HEADER_SIZE);
|
||||
|
||||
if (LE_SUCCESS(success) && !subhead.isEmpty() && subhead->version == 0) {
|
||||
coverage = SWAPW(subhead->coverage);
|
||||
|
||||
if (coverage & COVERAGE_HORIZONTAL) { // only handle horizontal kerning
|
||||
LEReferenceTo<Subtable_0> table(subhead, success, KERN_SUBTABLE_HEADER_SIZE);
|
||||
|
||||
if(table.isEmpty() || LE_FAILURE(success)) return;
|
||||
|
||||
nPairs = SWAPW(table->nPairs);
|
||||
|
||||
#if 0 // some old fonts have bad values here...
|
||||
searchRange = SWAPW(table->searchRange);
|
||||
entrySelector = SWAPW(table->entrySelector);
|
||||
rangeShift = SWAPW(table->rangeShift);
|
||||
#else
|
||||
entrySelector = OpenTypeUtilities::highBit(nPairs);
|
||||
searchRange = (1 << entrySelector) * KERN_PAIRINFO_SIZE;
|
||||
rangeShift = (nPairs * KERN_PAIRINFO_SIZE) - searchRange;
|
||||
#endif
|
||||
|
||||
if(LE_SUCCESS(success) && nPairs>0) {
|
||||
// pairs is an instance member, and table is on the stack.
|
||||
// set 'pairs' based on table.getAlias(). This will range check it.
|
||||
|
||||
pairs = LEReferenceToArrayOf<PairInfo>(fTable, // based on overall table
|
||||
success,
|
||||
(const PairInfo*)table.getAlias(), // subtable 0 + ..
|
||||
KERN_SUBTABLE_0_HEADER_SIZE, // .. offset of header size
|
||||
nPairs); // count
|
||||
}
|
||||
|
||||
#if 0
|
||||
fprintf(stderr, "coverage: %0.4x nPairs: %d pairs %p\n", coverage, nPairs, pairs.getAlias());
|
||||
fprintf(stderr, " searchRange: %d entrySelector: %d rangeShift: %d\n", searchRange, entrySelector, rangeShift);
|
||||
fprintf(stderr, "[[ ignored font table entries: range %d selector %d shift %d ]]\n", SWAPW(table->searchRange), SWAPW(table->entrySelector), SWAPW(table->rangeShift));
|
||||
#endif
|
||||
#if KERNTABLE_DEBUG
|
||||
fprintf(stderr, "coverage: %0.4x nPairs: %d pairs 0x%x\n", coverage, nPairs, pairs);
|
||||
fprintf(stderr, " searchRange: %d entrySelector: %d rangeShift: %d\n", searchRange, entrySelector, rangeShift);
|
||||
|
||||
if(LE_SUCCESS(success) {
|
||||
// dump part of the pair list
|
||||
char ids[256];
|
||||
|
||||
for (int i = 256; --i >= 0;) {
|
||||
LEGlyphID id = font->mapCharToGlyph(i);
|
||||
|
||||
if (id < 256) {
|
||||
ids[id] = (char)i;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < nPairs; ++i) {
|
||||
const PairInfo& p = pairs[i, success];
|
||||
|
||||
le_uint16 left = p->left;
|
||||
le_uint16 right = p->right;
|
||||
|
||||
|
||||
if (left < 256 && right < 256) {
|
||||
char c = ids[left];
|
||||
|
||||
if (c > 0x20 && c < 0x7f) {
|
||||
fprintf(stderr, "%c/", c & 0xff);
|
||||
} else {
|
||||
printf(stderr, "%0.2x/", c & 0xff);
|
||||
}
|
||||
|
||||
c = ids[right];
|
||||
if (c > 0x20 && c < 0x7f) {
|
||||
fprintf(stderr, "%c ", c & 0xff);
|
||||
} else {
|
||||
fprintf(stderr, "%0.2x ", c & 0xff);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Process the glyph positions. The positions array has two floats for each
|
||||
g * glyph, plus a trailing pair to mark the end of the last glyph.
|
||||
*/
|
||||
void KernTable::process(LEGlyphStorage& storage, LEErrorCode &success)
|
||||
{
|
||||
if (LE_SUCCESS(success) && !pairs.isEmpty()) {
|
||||
|
||||
le_uint32 key = storage[0]; // no need to mask off high bits
|
||||
float adjust = 0;
|
||||
|
||||
for (int i = 1, e = storage.getGlyphCount(); LE_SUCCESS(success)&& i < e; ++i) {
|
||||
key = key << 16 | (storage[i] & 0xffff);
|
||||
|
||||
// argh, to do a binary search, we need to have the pair list in sorted order
|
||||
// but it is not in sorted order on win32 platforms because of the endianness difference
|
||||
// so either I have to swap the element each time I examine it, or I have to swap
|
||||
// all the elements ahead of time and store them in the font
|
||||
|
||||
const PairInfo *p = pairs.getAlias(0, success);
|
||||
|
||||
LEReferenceTo<PairInfo> tpRef(pairs, success, rangeShift); // ((char*)pairs) + rangeShift
|
||||
const PairInfo *tp = tpRef.getAlias();
|
||||
if(LE_FAILURE(success)) return; // get out.
|
||||
|
||||
if (key > SWAP_KEY(tp)) {
|
||||
p = tp;
|
||||
}
|
||||
|
||||
#if KERNTABLE_DEBUG
|
||||
fprintf(stderr, "binary search for %0.8x\n", key);
|
||||
#endif
|
||||
|
||||
le_uint32 probe = searchRange;
|
||||
|
||||
while (probe > KERN_PAIRINFO_SIZE && LE_SUCCESS(success)) {
|
||||
probe >>= 1;
|
||||
tpRef = LEReferenceTo<PairInfo>(pairs, success, p, probe); // (char*)p + probe
|
||||
tp = tpRef.getAlias();
|
||||
le_uint32 tkey = SWAP_KEY(tp);
|
||||
if(LE_FAILURE(success)) break;
|
||||
#if KERNTABLE_DEBUG
|
||||
fprintf(stdout, " %.3d (%0.8x)\n", ((char*)tp - (char*)pairs)/KERN_PAIRINFO_SIZE, tkey);
|
||||
#endif
|
||||
if (tkey <= key && LE_SUCCESS(success)) {
|
||||
if (tkey == key) {
|
||||
le_int16 value = SWAPW(tp->value);
|
||||
#if KERNTABLE_DEBUG
|
||||
fprintf(stdout, "binary found kerning pair %x:%x at %d, value: 0x%x (%g)\n",
|
||||
storage[i-1], storage[i], i, value & 0xffff, font->xUnitsToPoints(value));
|
||||
fflush(stdout);
|
||||
#endif
|
||||
adjust += fTable.getFont()->xUnitsToPoints(value);
|
||||
break;
|
||||
}
|
||||
|
||||
p = tp;
|
||||
}
|
||||
}
|
||||
|
||||
storage.adjustPosition(i, adjust, 0, success);
|
||||
}
|
||||
|
||||
storage.adjustPosition(storage.getGlyphCount(), adjust, 0, success);
|
||||
}
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
* @(#)KernTable.h 1.1 04/10/13
|
||||
*
|
||||
* (C) Copyright IBM Corp. 2004-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __KERNTABLE_H
|
||||
#define __KERNTABLE_H
|
||||
|
||||
#ifndef __LETYPES_H
|
||||
#include "LETypes.h"
|
||||
#endif
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "LETableReference.h"
|
||||
//#include "LEFontInstance.h"
|
||||
//#include "LEGlyphStorage.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
struct PairInfo;
|
||||
class LEFontInstance;
|
||||
class LEGlyphStorage;
|
||||
|
||||
/**
|
||||
* Windows type 0 kerning table support only for now.
|
||||
*/
|
||||
class U_LAYOUT_API KernTable
|
||||
{
|
||||
private:
|
||||
le_uint16 coverage;
|
||||
le_uint16 nPairs;
|
||||
LEReferenceToArrayOf<PairInfo> pairs;
|
||||
const LETableReference &fTable;
|
||||
le_uint16 searchRange;
|
||||
le_uint16 entrySelector;
|
||||
le_uint16 rangeShift;
|
||||
|
||||
public:
|
||||
KernTable(const LETableReference &table, LEErrorCode &success);
|
||||
|
||||
/*
|
||||
* Process the glyph positions.
|
||||
*/
|
||||
void process(LEGlyphStorage& storage, LEErrorCode &success);
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
||||
#endif
|
|
@ -1,83 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
|
||||
/*
|
||||
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
|
||||
*
|
||||
* This file is a modification of the ICU file IndicLayoutEngine.cpp
|
||||
* by Jens Herden and Javier Sola for Khmer language
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "OpenTypeLayoutEngine.h"
|
||||
#include "KhmerLayoutEngine.h"
|
||||
#include "LEGlyphStorage.h"
|
||||
#include "KhmerReordering.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(KhmerOpenTypeLayoutEngine)
|
||||
|
||||
KhmerOpenTypeLayoutEngine::KhmerOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
|
||||
le_int32 typoFlags, const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTable, LEErrorCode &success)
|
||||
: OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success)
|
||||
{
|
||||
fFeatureMap = KhmerReordering::getFeatureMap(fFeatureMapCount);
|
||||
fFeatureOrder = TRUE;
|
||||
}
|
||||
|
||||
KhmerOpenTypeLayoutEngine::KhmerOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
|
||||
le_int32 typoFlags, LEErrorCode &success)
|
||||
: OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success)
|
||||
{
|
||||
fFeatureMap = KhmerReordering::getFeatureMap(fFeatureMapCount);
|
||||
fFeatureOrder = TRUE;
|
||||
}
|
||||
|
||||
KhmerOpenTypeLayoutEngine::~KhmerOpenTypeLayoutEngine()
|
||||
{
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
// Input: characters
|
||||
// Output: characters, char indices, tags
|
||||
// Returns: output character count
|
||||
le_int32 KhmerOpenTypeLayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft,
|
||||
LEUnicode *&outChars, LEGlyphStorage &glyphStorage, LEErrorCode &success)
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (chars == NULL || offset < 0 || count < 0 || max < 0 || offset >= max || offset + count > max) {
|
||||
success = LE_ILLEGAL_ARGUMENT_ERROR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
le_int32 worstCase = count * 3; // worst case is 3 for Khmer TODO check if 2 is enough
|
||||
|
||||
outChars = LE_NEW_ARRAY(LEUnicode, worstCase);
|
||||
|
||||
if (outChars == NULL) {
|
||||
success = LE_MEMORY_ALLOCATION_ERROR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
glyphStorage.allocateGlyphArray(worstCase, rightToLeft, success);
|
||||
glyphStorage.allocateAuxData(success);
|
||||
|
||||
if (LE_FAILURE(success)) {
|
||||
LE_DELETE_ARRAY(outChars);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// NOTE: assumes this allocates featureTags...
|
||||
// (probably better than doing the worst case stuff here...)
|
||||
le_int32 outCharCount = KhmerReordering::reorder(&chars[offset], count, fScriptCode, outChars, glyphStorage);
|
||||
|
||||
glyphStorage.adoptGlyphCount(outCharCount);
|
||||
return outCharCount;
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
|
@ -1,131 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2016 - All Rights Reserved
|
||||
*
|
||||
* This file is a modification of the ICU file IndicLayoutEngine.h
|
||||
* by Jens Herden and Javier Sola for Khmer language
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __KHMERLAYOUTENGINE_H
|
||||
#define __KHMERLAYOUTENGINE_H
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "LEFontInstance.h"
|
||||
#include "LEGlyphFilter.h"
|
||||
#include "LayoutEngine.h"
|
||||
#include "OpenTypeLayoutEngine.h"
|
||||
|
||||
#include "GlyphSubstitutionTables.h"
|
||||
#include "GlyphDefinitionTables.h"
|
||||
#include "GlyphPositioningTables.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class MPreFixups;
|
||||
class LEGlyphStorage;
|
||||
|
||||
/**
|
||||
* This class implements OpenType layout for Khmer OpenType fonts, as
|
||||
* specified by Microsoft in "Creating and Supporting OpenType Fonts for
|
||||
* Khmer Scripts" (http://www.microsoft.com/typography/otspec/indicot/default.htm) TODO: change url
|
||||
*
|
||||
* This class overrides the characterProcessing method to do Khmer character processing
|
||||
* and reordering (See the MS spec. for more details)
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class KhmerOpenTypeLayoutEngine : public OpenTypeLayoutEngine
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This is the main constructor. It constructs an instance of KhmerOpenTypeLayoutEngine for
|
||||
* a particular font, script and language. It takes the GSUB table as a parameter since
|
||||
* LayoutEngine::layoutEngineFactory has to read the GSUB table to know that it has an
|
||||
* Khmer OpenType font.
|
||||
*
|
||||
* @param fontInstance - the font
|
||||
* @param scriptCode - the script
|
||||
* @param langaugeCode - the language
|
||||
* @param gsubTable - the GSUB table
|
||||
* @param success - set to an error code if the operation fails
|
||||
*
|
||||
* @see LayoutEngine::layoutEngineFactory
|
||||
* @see OpenTypeLayoutEngine
|
||||
* @see ScriptAndLangaugeTags.h for script and language codes
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
KhmerOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
|
||||
le_int32 typoFlags, const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTable, LEErrorCode &success);
|
||||
|
||||
/**
|
||||
* This constructor is used when the font requires a "canned" GSUB table which can't be known
|
||||
* until after this constructor has been invoked.
|
||||
*
|
||||
* @param fontInstance - the font
|
||||
* @param scriptCode - the script
|
||||
* @param langaugeCode - the language
|
||||
* @param success - set to an error code if the operation fails
|
||||
*
|
||||
* @see OpenTypeLayoutEngine
|
||||
* @see ScriptAndLangaugeTags.h for script and language codes
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
KhmerOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
|
||||
le_int32 typoFlags, LEErrorCode &success);
|
||||
|
||||
/**
|
||||
* The destructor, virtual for correct polymorphic invocation.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
virtual ~KhmerOpenTypeLayoutEngine();
|
||||
|
||||
/**
|
||||
* ICU "poor man's RTTI", returns a UClassID for the actual class.
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
virtual UClassID getDynamicClassID() const;
|
||||
|
||||
/**
|
||||
* ICU "poor man's RTTI", returns a UClassID for this class.
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
static UClassID getStaticClassID();
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* This method does Khmer OpenType character processing. It assigns the OpenType feature
|
||||
* tags to the characters, and may generate output characters which have been reordered.
|
||||
* It may also split some vowels, resulting in more output characters than input characters.
|
||||
*
|
||||
* Input parameters:
|
||||
* @param chars - the input character context
|
||||
* @param offset - the index of the first character to process
|
||||
* @param count - the number of characters to process
|
||||
* @param max - the number of characters in the input context
|
||||
* @param rightToLeft - <code>TRUE</code> if the characters are in a right to left directional run
|
||||
* @param glyphStorage - the glyph storage object. The glyph and character index arrays will be set.
|
||||
* the auxillary data array will be set to the feature tags.
|
||||
*
|
||||
* Output parameters:
|
||||
* @param success - set to an error code if the operation fails
|
||||
*
|
||||
* @return the output character count
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
virtual le_int32 characterProcessing(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft,
|
||||
LEUnicode *&outChars, LEGlyphStorage &glyphStorage, LEErrorCode &success);
|
||||
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
|
@ -1,501 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2007 - All Rights Reserved
|
||||
*
|
||||
* This file is a modification of the ICU file IndicReordering.cpp
|
||||
* by Jens Herden and Javier Sola for Khmer language
|
||||
*
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "OpenTypeTables.h"
|
||||
#include "KhmerReordering.h"
|
||||
#include "LEGlyphStorage.h"
|
||||
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
// Characters that get refered to by name...
|
||||
enum
|
||||
{
|
||||
C_SIGN_ZWNJ = 0x200C,
|
||||
C_SIGN_ZWJ = 0x200D,
|
||||
C_DOTTED_CIRCLE = 0x25CC,
|
||||
C_RO = 0x179A,
|
||||
C_VOWEL_AA = 0x17B6,
|
||||
C_SIGN_NIKAHIT = 0x17C6,
|
||||
C_VOWEL_E = 0x17C1,
|
||||
C_COENG = 0x17D2
|
||||
};
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
// 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 independtly displayed, should be displayed with a dotted-circle to
|
||||
// indicate error in syllable construction
|
||||
_xx = KhmerClassTable::CC_RESERVED,
|
||||
_sa = KhmerClassTable::CC_SIGN_ABOVE | KhmerClassTable::CF_DOTTED_CIRCLE | KhmerClassTable::CF_POS_ABOVE,
|
||||
_sp = KhmerClassTable::CC_SIGN_AFTER | KhmerClassTable::CF_DOTTED_CIRCLE| KhmerClassTable::CF_POS_AFTER,
|
||||
_c1 = KhmerClassTable::CC_CONSONANT | KhmerClassTable::CF_CONSONANT,
|
||||
_c2 = KhmerClassTable::CC_CONSONANT2 | KhmerClassTable::CF_CONSONANT,
|
||||
_c3 = KhmerClassTable::CC_CONSONANT3 | KhmerClassTable::CF_CONSONANT,
|
||||
_rb = KhmerClassTable::CC_ROBAT | KhmerClassTable::CF_POS_ABOVE | KhmerClassTable::CF_DOTTED_CIRCLE,
|
||||
_cs = KhmerClassTable::CC_CONSONANT_SHIFTER | KhmerClassTable::CF_DOTTED_CIRCLE | KhmerClassTable::CF_SHIFTER,
|
||||
_dl = KhmerClassTable::CC_DEPENDENT_VOWEL | KhmerClassTable::CF_POS_BEFORE | KhmerClassTable::CF_DOTTED_CIRCLE,
|
||||
_db = KhmerClassTable::CC_DEPENDENT_VOWEL | KhmerClassTable::CF_POS_BELOW | KhmerClassTable::CF_DOTTED_CIRCLE,
|
||||
_da = KhmerClassTable::CC_DEPENDENT_VOWEL | KhmerClassTable::CF_POS_ABOVE | KhmerClassTable::CF_DOTTED_CIRCLE | KhmerClassTable::CF_ABOVE_VOWEL,
|
||||
_dr = KhmerClassTable::CC_DEPENDENT_VOWEL | KhmerClassTable::CF_POS_AFTER | KhmerClassTable::CF_DOTTED_CIRCLE,
|
||||
_co = KhmerClassTable::CC_COENG | KhmerClassTable::CF_COENG | KhmerClassTable::CF_DOTTED_CIRCLE,
|
||||
|
||||
// split vowel
|
||||
_va = _da | KhmerClassTable::CF_SPLIT_VOWEL,
|
||||
_vr = _dr | KhmerClassTable::CF_SPLIT_VOWEL
|
||||
};
|
||||
|
||||
|
||||
// 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 wich the first part is before the base and the second one above the base
|
||||
// _vr Khmer split vowel in wich the first part is before the base and the second one behind (right of) the base
|
||||
|
||||
static const KhmerClassTable::CharClass 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
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Khmer Class Tables
|
||||
//
|
||||
|
||||
//
|
||||
// The range of characters defined in the above table is defined here. FOr Khmer 1780 to 17DF
|
||||
// Even if the Khmer range is bigger, all other characters are not combinable, and therefore treated
|
||||
// as _xx
|
||||
static const KhmerClassTable khmerClassTable = {0x1780, 0x17df, khmerCharClasses};
|
||||
|
||||
|
||||
// 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
|
||||
KhmerClassTable::CharClass KhmerClassTable::getCharClass(LEUnicode ch) const
|
||||
{
|
||||
|
||||
if (ch == C_SIGN_ZWJ) {
|
||||
return CC_ZERO_WIDTH_J_MARK;
|
||||
}
|
||||
|
||||
if (ch == C_SIGN_ZWNJ) {
|
||||
return CC_ZERO_WIDTH_NJ_MARK;
|
||||
}
|
||||
|
||||
if (ch < firstChar || ch > lastChar) {
|
||||
return CC_RESERVED;
|
||||
}
|
||||
|
||||
return classTable[ch - firstChar];
|
||||
}
|
||||
|
||||
const KhmerClassTable *KhmerClassTable::getKhmerClassTable()
|
||||
{
|
||||
return &khmerClassTable;
|
||||
}
|
||||
|
||||
|
||||
|
||||
class KhmerReorderingOutput : public UMemory {
|
||||
private:
|
||||
le_int32 fSyllableCount;
|
||||
le_int32 fOutIndex;
|
||||
LEUnicode *fOutChars;
|
||||
|
||||
LEGlyphStorage &fGlyphStorage;
|
||||
|
||||
|
||||
public:
|
||||
KhmerReorderingOutput(LEUnicode *outChars, LEGlyphStorage &glyphStorage)
|
||||
: fSyllableCount(0), fOutIndex(0), fOutChars(outChars), fGlyphStorage(glyphStorage)
|
||||
{
|
||||
// nothing else to do...
|
||||
}
|
||||
|
||||
~KhmerReorderingOutput()
|
||||
{
|
||||
// nothing to do here...
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
fSyllableCount += 1;
|
||||
}
|
||||
|
||||
void writeChar(LEUnicode ch, le_uint32 charIndex, FeatureMask charFeatures)
|
||||
{
|
||||
LEErrorCode success = LE_NO_ERROR;
|
||||
|
||||
fOutChars[fOutIndex] = ch;
|
||||
|
||||
fGlyphStorage.setCharIndex(fOutIndex, charIndex, success);
|
||||
fGlyphStorage.setAuxData(fOutIndex, charFeatures | (fSyllableCount & LE_GLYPH_GROUP_MASK), success);
|
||||
|
||||
fOutIndex += 1;
|
||||
}
|
||||
|
||||
le_int32 getOutputIndex()
|
||||
{
|
||||
return fOutIndex;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#define blwfFeatureTag LE_BLWF_FEATURE_TAG
|
||||
#define pstfFeatureTag LE_PSTF_FEATURE_TAG
|
||||
#define presFeatureTag LE_PRES_FEATURE_TAG
|
||||
#define blwsFeatureTag LE_BLWS_FEATURE_TAG
|
||||
#define abvsFeatureTag LE_ABVS_FEATURE_TAG
|
||||
#define pstsFeatureTag LE_PSTS_FEATURE_TAG
|
||||
|
||||
#define blwmFeatureTag LE_BLWM_FEATURE_TAG
|
||||
#define abvmFeatureTag LE_ABVM_FEATURE_TAG
|
||||
#define distFeatureTag LE_DIST_FEATURE_TAG
|
||||
|
||||
#define prefFeatureTag LE_PREF_FEATURE_TAG
|
||||
#define abvfFeatureTag LE_ABVF_FEATURE_TAG
|
||||
#define cligFeatureTag LE_CLIG_FEATURE_TAG
|
||||
#define mkmkFeatureTag LE_MKMK_FEATURE_TAG
|
||||
|
||||
#define prefFeatureMask 0x80000000UL
|
||||
#define blwfFeatureMask 0x40000000UL
|
||||
#define abvfFeatureMask 0x20000000UL
|
||||
#define pstfFeatureMask 0x10000000UL
|
||||
#define presFeatureMask 0x08000000UL
|
||||
#define blwsFeatureMask 0x04000000UL
|
||||
#define abvsFeatureMask 0x02000000UL
|
||||
#define pstsFeatureMask 0x01000000UL
|
||||
#define cligFeatureMask 0x00800000UL
|
||||
#define distFeatureMask 0x00400000UL
|
||||
#define blwmFeatureMask 0x00200000UL
|
||||
#define abvmFeatureMask 0x00100000UL
|
||||
#define mkmkFeatureMask 0x00080000UL
|
||||
|
||||
#define tagPref (prefFeatureMask | presFeatureMask | cligFeatureMask | distFeatureMask)
|
||||
#define tagAbvf (abvfFeatureMask | abvsFeatureMask | cligFeatureMask | distFeatureMask | abvmFeatureMask | mkmkFeatureMask)
|
||||
#define tagPstf (blwfFeatureMask | blwsFeatureMask | prefFeatureMask | presFeatureMask | pstfFeatureMask | pstsFeatureMask | cligFeatureMask | distFeatureMask | blwmFeatureMask)
|
||||
#define tagBlwf (blwfFeatureMask | blwsFeatureMask | cligFeatureMask | distFeatureMask | blwmFeatureMask | mkmkFeatureMask)
|
||||
#define tagDefault (prefFeatureMask | blwfFeatureMask | presFeatureMask | blwsFeatureMask | cligFeatureMask | distFeatureMask | abvmFeatureMask | blwmFeatureMask | mkmkFeatureMask)
|
||||
|
||||
|
||||
|
||||
// These are in the order in which the features need to be applied
|
||||
// for correct processing
|
||||
static const FeatureMap featureMap[] =
|
||||
{
|
||||
// Shaping features
|
||||
{prefFeatureTag, prefFeatureMask},
|
||||
{blwfFeatureTag, blwfFeatureMask},
|
||||
{abvfFeatureTag, abvfFeatureMask},
|
||||
{pstfFeatureTag, pstfFeatureMask},
|
||||
{presFeatureTag, presFeatureMask},
|
||||
{blwsFeatureTag, blwsFeatureMask},
|
||||
{abvsFeatureTag, abvsFeatureMask},
|
||||
{pstsFeatureTag, pstsFeatureMask},
|
||||
{cligFeatureTag, cligFeatureMask},
|
||||
|
||||
// Positioning features
|
||||
{distFeatureTag, distFeatureMask},
|
||||
{blwmFeatureTag, blwmFeatureMask},
|
||||
{abvmFeatureTag, abvmFeatureMask},
|
||||
{mkmkFeatureTag, mkmkFeatureMask},
|
||||
};
|
||||
|
||||
static const le_int32 featureMapCount = LE_ARRAY_SIZE(featureMap);
|
||||
|
||||
// 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 in KhmerReordering.h 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 le_int8 khmerStateTable[][KhmerClassTable::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
|
||||
|
||||
};
|
||||
|
||||
|
||||
const FeatureMap *KhmerReordering::getFeatureMap(le_int32 &count)
|
||||
{
|
||||
count = featureMapCount;
|
||||
|
||||
return featureMap;
|
||||
}
|
||||
|
||||
|
||||
// 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.
|
||||
le_int32 KhmerReordering::findSyllable(const KhmerClassTable *classTable, const LEUnicode *chars, le_int32 prev, le_int32 charCount)
|
||||
{
|
||||
le_int32 cursor = prev;
|
||||
le_int8 state = 0;
|
||||
|
||||
while (cursor < charCount) {
|
||||
KhmerClassTable::CharClass charClass = (classTable->getCharClass(chars[cursor]) & KhmerClassTable::CF_CLASS_MASK);
|
||||
|
||||
state = khmerStateTable[state][charClass];
|
||||
|
||||
if (state < 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
cursor += 1;
|
||||
}
|
||||
|
||||
return cursor;
|
||||
}
|
||||
|
||||
|
||||
// This is the real reordering function as applied to the Khmer language
|
||||
|
||||
le_int32 KhmerReordering::reorder(const LEUnicode *chars, le_int32 charCount, le_int32 /*scriptCode*/,
|
||||
LEUnicode *outChars, LEGlyphStorage &glyphStorage)
|
||||
{
|
||||
const KhmerClassTable *classTable = KhmerClassTable::getKhmerClassTable();
|
||||
|
||||
KhmerReorderingOutput output(outChars, glyphStorage);
|
||||
KhmerClassTable::CharClass charClass;
|
||||
le_int32 i, prev = 0, coengRo;
|
||||
|
||||
|
||||
// This loop only exits when we reach the end of a run, which may contain
|
||||
// several syllables.
|
||||
while (prev < charCount) {
|
||||
le_int32 syllable = findSyllable(classTable, chars, prev, charCount);
|
||||
|
||||
output.reset();
|
||||
|
||||
// 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 = prev; i < syllable; i += 1) {
|
||||
charClass = classTable->getCharClass(chars[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 & KhmerClassTable::CF_SPLIT_VOWEL) {
|
||||
output.writeChar(C_VOWEL_E, i, tagPref);
|
||||
break; // there can be only one vowel
|
||||
}
|
||||
|
||||
// if a vowel with pos before write it out
|
||||
if (charClass & KhmerClassTable::CF_POS_BEFORE) {
|
||||
output.writeChar(chars[i], i, tagPref);
|
||||
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 & KhmerClassTable::CF_COENG) && (i + 1 < syllable) &&
|
||||
( (classTable->getCharClass(chars[i + 1]) & KhmerClassTable::CF_CLASS_MASK) == KhmerClassTable::CC_CONSONANT2) )
|
||||
{
|
||||
coengRo = i;
|
||||
}
|
||||
}
|
||||
|
||||
// write coeng + ro if found
|
||||
if (coengRo > -1) {
|
||||
output.writeChar(C_COENG, coengRo, tagPref);
|
||||
output.writeChar(C_RO, coengRo + 1, tagPref);
|
||||
}
|
||||
|
||||
// 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 (classTable->getCharClass(chars[prev]) & KhmerClassTable::CF_DOTTED_CIRCLE) {
|
||||
output.writeChar(C_DOTTED_CIRCLE, prev, tagDefault);
|
||||
}
|
||||
|
||||
// copy what is left to the output, skipping before vowels and coeng Ro if they are present
|
||||
for (i = prev; i < syllable; i += 1) {
|
||||
charClass = classTable->getCharClass(chars[i]);
|
||||
|
||||
// skip a before vowel, it was already processed
|
||||
if (charClass & KhmerClassTable::CF_POS_BEFORE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// skip coeng + ro, it was already processed
|
||||
if (i == coengRo) {
|
||||
i += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (charClass & KhmerClassTable::CF_POS_MASK) {
|
||||
case KhmerClassTable::CF_POS_ABOVE :
|
||||
output.writeChar(chars[i], i, tagAbvf);
|
||||
break;
|
||||
|
||||
case KhmerClassTable::CF_POS_AFTER :
|
||||
output.writeChar(chars[i], i, tagPstf);
|
||||
break;
|
||||
|
||||
case KhmerClassTable::CF_POS_BELOW :
|
||||
output.writeChar(chars[i], i, tagBlwf);
|
||||
break;
|
||||
|
||||
default:
|
||||
// assign the correct flags to a coeng consonant
|
||||
// Consonants of type 3 are taged as Post forms and those type 1 as below forms
|
||||
if ( (charClass & KhmerClassTable::CF_COENG) && i + 1 < syllable ) {
|
||||
if ( (classTable->getCharClass(chars[i + 1]) & KhmerClassTable::CF_CLASS_MASK)
|
||||
== KhmerClassTable::CC_CONSONANT3) {
|
||||
output.writeChar(chars[i], i, tagPstf);
|
||||
i += 1;
|
||||
output.writeChar(chars[i], i, tagPstf);
|
||||
}
|
||||
else {
|
||||
output.writeChar(chars[i], i, tagBlwf);
|
||||
i += 1;
|
||||
output.writeChar(chars[i], i, tagBlwf);
|
||||
}
|
||||
break;
|
||||
}
|
||||
// if a shifter is followed by an above vowel change the shifter to below form,
|
||||
// an above vowel can have two possible positions i + 1 or i + 3
|
||||
// (position i+1 corresponds to unicode 3, position i+3 to Unicode 4)
|
||||
// and there is an extra rule for C_VOWEL_AA + C_SIGN_NIKAHIT also for two
|
||||
// different positions, right after the shifter or after a vowel (Unicode 4)
|
||||
if ( (charClass & KhmerClassTable::CF_SHIFTER) && (i + 1 < syllable) ) {
|
||||
if ((classTable->getCharClass(chars[i + 1]) & KhmerClassTable::CF_ABOVE_VOWEL)
|
||||
|| (i + 2 < syllable
|
||||
&& ( (classTable->getCharClass(chars[i + 1]) & KhmerClassTable::CF_CLASS_MASK) == C_VOWEL_AA)
|
||||
&& ( (classTable->getCharClass(chars[i + 2]) & KhmerClassTable::CF_CLASS_MASK) == C_SIGN_NIKAHIT))
|
||||
|| (i + 3 < syllable && (classTable->getCharClass(chars[i + 3]) & KhmerClassTable::CF_ABOVE_VOWEL))
|
||||
|| (i + 4 < syllable
|
||||
&& ( (classTable->getCharClass(chars[i + 3]) & KhmerClassTable::CF_CLASS_MASK) == C_VOWEL_AA)
|
||||
&& ( (classTable->getCharClass(chars[i + 4]) & KhmerClassTable::CF_CLASS_MASK) == C_SIGN_NIKAHIT) ) )
|
||||
{
|
||||
output.writeChar(chars[i], i, tagBlwf);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
// default - any other characters
|
||||
output.writeChar(chars[i], i, tagDefault);
|
||||
break;
|
||||
} // switch
|
||||
} // for
|
||||
|
||||
prev = syllable; // move the pointer to the start of next syllable
|
||||
}
|
||||
|
||||
return output.getOutputIndex();
|
||||
}
|
||||
|
||||
|
||||
U_NAMESPACE_END
|
|
@ -1,134 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
* (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved
|
||||
*
|
||||
* This file is a modification of the ICU file IndicReordering.h
|
||||
* by Jens Herden and Javier Sola for Khmer language
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __KHMERREORDERING_H
|
||||
#define __KHMERREORDERING_H
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \internal
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "OpenTypeTables.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class LEGlyphStorage;
|
||||
|
||||
// Vocabulary
|
||||
// Base -> A consonant or an independent vowel in its full (not subscript) form. It is the
|
||||
// center of the syllable, it can be souranded 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.
|
||||
//
|
||||
//
|
||||
|
||||
struct KhmerClassTable // This list must include all types of components that can be used inside a syllable
|
||||
{
|
||||
enum CharClassValues // order is important here! This order must be the same that is found in each horizontal
|
||||
// line in the statetable for Khmer (file KhmerReordering.cpp).
|
||||
{
|
||||
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 CharClassFlags
|
||||
{
|
||||
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
|
||||
};
|
||||
|
||||
typedef le_uint32 CharClass;
|
||||
|
||||
typedef le_int32 ScriptFlags;
|
||||
|
||||
LEUnicode firstChar; // for Khmer this will become x1780
|
||||
LEUnicode lastChar; // and this x17DF
|
||||
const CharClass *classTable;
|
||||
|
||||
CharClass getCharClass(LEUnicode ch) const;
|
||||
|
||||
static const KhmerClassTable *getKhmerClassTable();
|
||||
};
|
||||
|
||||
|
||||
class KhmerReordering /* not : public UObject because all methods are static */ {
|
||||
public:
|
||||
static le_int32 reorder(const LEUnicode *theChars, le_int32 charCount, le_int32 scriptCode,
|
||||
LEUnicode *outChars, LEGlyphStorage &glyphStorage);
|
||||
|
||||
static const FeatureMap *getFeatureMap(le_int32 &count);
|
||||
|
||||
private:
|
||||
// do not instantiate
|
||||
KhmerReordering();
|
||||
|
||||
static le_int32 findSyllable(const KhmerClassTable *classTable, const LEUnicode *chars, le_int32 prev, le_int32 charCount);
|
||||
|
||||
};
|
||||
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
|
@ -1,151 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
*******************************************************************************
|
||||
*
|
||||
* Copyright (C) 1999-2007, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
*
|
||||
*******************************************************************************
|
||||
* file name: LEFontInstance.cpp
|
||||
*
|
||||
* created on: 02/06/2003
|
||||
* created by: Eric R. Mader
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "LEScripts.h"
|
||||
#include "LEFontInstance.h"
|
||||
#include "LEGlyphStorage.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(LEFontInstance)
|
||||
|
||||
LECharMapper::~LECharMapper()
|
||||
{
|
||||
// nothing to do.
|
||||
}
|
||||
|
||||
LEFontInstance::~LEFontInstance()
|
||||
{
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
const LEFontInstance *LEFontInstance::getSubFont(const LEUnicode chars[], le_int32 *offset, le_int32 limit,
|
||||
le_int32 script, LEErrorCode &success) const
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (chars == NULL || *offset < 0 || limit < 0 || *offset >= limit || script < 0 || script >= scriptCodeCount) {
|
||||
success = LE_ILLEGAL_ARGUMENT_ERROR;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*offset = limit;
|
||||
return this;
|
||||
}
|
||||
|
||||
void LEFontInstance::mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count,
|
||||
le_bool reverse, const LECharMapper *mapper, le_bool filterZeroWidth, LEGlyphStorage &glyphStorage) const
|
||||
{
|
||||
le_int32 i, out = 0, dir = 1;
|
||||
|
||||
if (reverse) {
|
||||
out = count - 1;
|
||||
dir = -1;
|
||||
}
|
||||
|
||||
for (i = offset; i < offset + count; i += 1, out += dir) {
|
||||
LEUnicode16 high = chars[i];
|
||||
LEUnicode32 code = high;
|
||||
|
||||
if (i < offset + count - 1 && high >= 0xD800 && high <= 0xDBFF) {
|
||||
LEUnicode16 low = chars[i + 1];
|
||||
|
||||
if (low >= 0xDC00 && low <= 0xDFFF) {
|
||||
code = (high - 0xD800) * 0x400 + low - 0xDC00 + 0x10000;
|
||||
}
|
||||
}
|
||||
|
||||
glyphStorage[out] = mapCharToGlyph(code, mapper, filterZeroWidth);
|
||||
|
||||
if (code >= 0x10000) {
|
||||
i += 1;
|
||||
glyphStorage[out += dir] = 0xFFFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LEGlyphID LEFontInstance::mapCharToGlyph(LEUnicode32 ch, const LECharMapper *mapper) const
|
||||
{
|
||||
return mapCharToGlyph(ch, mapper, TRUE);
|
||||
}
|
||||
|
||||
LEGlyphID LEFontInstance::mapCharToGlyph(LEUnicode32 ch, const LECharMapper *mapper, le_bool filterZeroWidth) const
|
||||
{
|
||||
LEUnicode32 mappedChar = mapper->mapChar(ch);
|
||||
|
||||
if (mappedChar == 0xFFFE || mappedChar == 0xFFFF) {
|
||||
return 0xFFFF;
|
||||
}
|
||||
|
||||
if (filterZeroWidth && (mappedChar == 0x200C || mappedChar == 0x200D)) {
|
||||
return canDisplay(mappedChar)? 0x0001 : 0xFFFF;
|
||||
}
|
||||
|
||||
return mapCharToGlyph(mappedChar);
|
||||
}
|
||||
|
||||
le_bool LEFontInstance::canDisplay(LEUnicode32 ch) const
|
||||
{
|
||||
return LE_GET_GLYPH(mapCharToGlyph(ch)) != 0;
|
||||
}
|
||||
|
||||
float LEFontInstance::xUnitsToPoints(float xUnits) const
|
||||
{
|
||||
return (xUnits * getXPixelsPerEm()) / (float) getUnitsPerEM();
|
||||
}
|
||||
|
||||
float LEFontInstance::yUnitsToPoints(float yUnits) const
|
||||
{
|
||||
return (yUnits * getYPixelsPerEm()) / (float) getUnitsPerEM();
|
||||
}
|
||||
|
||||
void LEFontInstance::unitsToPoints(LEPoint &units, LEPoint &points) const
|
||||
{
|
||||
points.fX = xUnitsToPoints(units.fX);
|
||||
points.fY = yUnitsToPoints(units.fY);
|
||||
}
|
||||
|
||||
float LEFontInstance::xPixelsToUnits(float xPixels) const
|
||||
{
|
||||
return (xPixels * getUnitsPerEM()) / (float) getXPixelsPerEm();
|
||||
}
|
||||
|
||||
float LEFontInstance::yPixelsToUnits(float yPixels) const
|
||||
{
|
||||
return (yPixels * getUnitsPerEM()) / (float) getYPixelsPerEm();
|
||||
}
|
||||
|
||||
void LEFontInstance::pixelsToUnits(LEPoint &pixels, LEPoint &units) const
|
||||
{
|
||||
units.fX = xPixelsToUnits(pixels.fX);
|
||||
units.fY = yPixelsToUnits(pixels.fY);
|
||||
}
|
||||
|
||||
void LEFontInstance::transformFunits(float xFunits, float yFunits, LEPoint &pixels) const
|
||||
{
|
||||
pixels.fX = xUnitsToPoints(xFunits) * getScaleFactorX();
|
||||
pixels.fY = yUnitsToPoints(yFunits) * getScaleFactorY();
|
||||
}
|
||||
|
||||
le_int32 LEFontInstance::getLineHeight() const
|
||||
{
|
||||
return getAscent() + getDescent() + getLeading();
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
|
@ -1,526 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2015 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __LEFONTINSTANCE_H
|
||||
#define __LEFONTINSTANCE_H
|
||||
|
||||
#include "LETypes.h"
|
||||
/**
|
||||
* \file
|
||||
* \brief C++ API: Layout Engine Font Instance object
|
||||
*/
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
/**
|
||||
* Instances of this class are used by <code>LEFontInstance::mapCharsToGlyphs</code> and
|
||||
* <code>LEFontInstance::mapCharToGlyph</code> to adjust character codes before the character
|
||||
* to glyph mapping process. Examples of this are filtering out control characters
|
||||
* and character mirroring - replacing a character which has both a left and a right
|
||||
* hand form with the opposite form.
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
class LECharMapper /* not : public UObject because this is an interface/mixin class */
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Destructor.
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
virtual ~LECharMapper();
|
||||
|
||||
/**
|
||||
* This method does the adjustments.
|
||||
*
|
||||
* @param ch - the input character
|
||||
*
|
||||
* @return the adjusted character
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
virtual LEUnicode32 mapChar(LEUnicode32 ch) const = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* This is a forward reference to the class which holds the per-glyph
|
||||
* storage.
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
class LEGlyphStorage;
|
||||
|
||||
/**
|
||||
* This is a virtual base class that serves as the interface between a LayoutEngine
|
||||
* and the platform font environment. It allows a LayoutEngine to access font tables, do
|
||||
* character to glyph mapping, and obtain metrics information without knowing any platform
|
||||
* specific details. There are also a few utility methods for converting between points,
|
||||
* pixels and funits. (font design units)
|
||||
*
|
||||
* An instance of an <code>LEFontInstance</code> represents a font at a particular point
|
||||
* size. Each instance can represent either a single physical font, or a composite font.
|
||||
* A composite font is a collection of physical fonts, each of which contains a subset of
|
||||
* the characters contained in the composite font.
|
||||
*
|
||||
* Note: with the exception of <code>getSubFont</code>, the methods in this class only
|
||||
* make sense for a physical font. If you have an <code>LEFontInstance</code> which
|
||||
* represents a composite font you should only call the methods below which have
|
||||
* an <code>LEGlyphID</code>, an <code>LEUnicode</code> or an <code>LEUnicode32</code>
|
||||
* as one of the arguments because these can be used to select a particular subfont.
|
||||
*
|
||||
* Subclasses which implement composite fonts should supply an implementation of these
|
||||
* methods with some default behavior such as returning constant values, or using the
|
||||
* values from the first subfont.
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
class U_LAYOUT_API LEFontInstance : public UObject
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* This virtual destructor is here so that the subclass
|
||||
* destructors can be invoked through the base class.
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
virtual ~LEFontInstance();
|
||||
|
||||
/**
|
||||
* Get a physical font which can render the given text. For composite fonts,
|
||||
* if there is no single physical font which can render all of the text,
|
||||
* return a physical font which can render an initial substring of the text,
|
||||
* and set the <code>offset</code> parameter to the end of that substring.
|
||||
*
|
||||
* Internally, the LayoutEngine works with runs of text all in the same
|
||||
* font and script, so it is best to call this method with text which is
|
||||
* in a single script, passing the script code in as a hint. If you don't
|
||||
* know the script of the text, you can use zero, which is the script code
|
||||
* for characters used in more than one script.
|
||||
*
|
||||
* The default implementation of this method is intended for instances of
|
||||
* <code>LEFontInstance</code> which represent a physical font. It returns
|
||||
* <code>this</code> and indicates that the entire string can be rendered.
|
||||
*
|
||||
* This method will return a valid <code>LEFontInstance</code> unless you
|
||||
* have passed illegal parameters, or an internal error has been encountered.
|
||||
* For composite fonts, it may return the warning <code>LE_NO_SUBFONT_WARNING</code>
|
||||
* to indicate that the returned font may not be able to render all of
|
||||
* the text. Whenever a valid font is returned, the <code>offset</code> parameter
|
||||
* will be advanced by at least one.
|
||||
*
|
||||
* Subclasses which implement composite fonts must override this method.
|
||||
* Where it makes sense, they should use the script code as a hint to render
|
||||
* characters from the COMMON script in the font which is used for the given
|
||||
* script. For example, if the input text is a series of Arabic words separated
|
||||
* by spaces, and the script code passed in is <code>arabScriptCode</code> you
|
||||
* should return the font used for Arabic characters for all of the input text,
|
||||
* including the spaces. If, on the other hand, the input text contains characters
|
||||
* which cannot be rendered by the font used for Arabic characters, but which can
|
||||
* be rendered by another font, you should return that font for those characters.
|
||||
*
|
||||
* @param chars - the array of Unicode characters.
|
||||
* @param offset - a pointer to the starting offset in the text. On exit this
|
||||
* will be set the the limit offset of the text which can be
|
||||
* rendered using the returned font.
|
||||
* @param limit - the limit offset for the input text.
|
||||
* @param script - the script hint.
|
||||
* @param success - set to an error code if the arguments are illegal, or no font
|
||||
* can be returned for some reason. May also be set to
|
||||
* <code>LE_NO_SUBFONT_WARNING</code> if the subfont which
|
||||
* was returned cannot render all of the text.
|
||||
*
|
||||
* @return an <code>LEFontInstance</code> for the sub font which can render the characters, or
|
||||
* <code>NULL</code> if there is an error.
|
||||
*
|
||||
* @see LEScripts.h
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
virtual const LEFontInstance *getSubFont(const LEUnicode chars[], le_int32 *offset, le_int32 limit, le_int32 script, LEErrorCode &success) const;
|
||||
|
||||
//
|
||||
// Font file access
|
||||
//
|
||||
|
||||
/**
|
||||
* This method reads a table from the font. Note that in general,
|
||||
* it only makes sense to call this method on an <code>LEFontInstance</code>
|
||||
* which represents a physical font - i.e. one which has been returned by
|
||||
* <code>getSubFont()</code>. This is because each subfont in a composite font
|
||||
* will have different tables, and there's no way to know which subfont to access.
|
||||
*
|
||||
* Subclasses which represent composite fonts should always return <code>NULL</code>.
|
||||
*
|
||||
* @param tableTag - the four byte table tag. (e.g. 'cmap')
|
||||
* @param length - ignored on entry, on exit will be the length of the table if known, or -1 if unknown.
|
||||
* @return the address of the table in memory, or <code>NULL</code>
|
||||
* if the table doesn't exist.
|
||||
* @deprecated ICU 54. See {@link LayoutEngine}
|
||||
*/
|
||||
virtual const void* getFontTable(LETag tableTag, size_t &length) const = 0;
|
||||
|
||||
/**
|
||||
* This method is used to determine if the font can
|
||||
* render the given character. This can usually be done
|
||||
* by looking the character up in the font's character
|
||||
* to glyph mapping.
|
||||
*
|
||||
* The default implementation of this method will return
|
||||
* <code>TRUE</code> if <code>mapCharToGlyph(ch)</code>
|
||||
* returns a non-zero value.
|
||||
*
|
||||
* @param ch - the character to be tested
|
||||
*
|
||||
* @return <code>TRUE</code> if the font can render ch.
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
virtual le_bool canDisplay(LEUnicode32 ch) const;
|
||||
|
||||
/**
|
||||
* This method returns the number of design units in
|
||||
* the font's EM square.
|
||||
*
|
||||
* @return the number of design units pre EM.
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
virtual le_int32 getUnitsPerEM() const = 0;
|
||||
|
||||
/**
|
||||
* This method maps an array of character codes to an array of glyph
|
||||
* indices, using the font's character to glyph map.
|
||||
*
|
||||
* The default implementation iterates over all of the characters and calls
|
||||
* <code>mapCharToGlyph(ch, mapper)</code> on each one. It also handles surrogate
|
||||
* characters, storing the glyph ID for the high surrogate, and a deleted glyph (0xFFFF)
|
||||
* for the low surrogate.
|
||||
*
|
||||
* Most sublcasses will not need to implement this method.
|
||||
*
|
||||
* @param chars - the character array
|
||||
* @param offset - the index of the first character
|
||||
* @param count - the number of characters
|
||||
* @param reverse - if <code>TRUE</code>, store the glyph indices in reverse order.
|
||||
* @param mapper - the character mapper.
|
||||
* @param filterZeroWidth - <code>TRUE</code> if ZWJ / ZWNJ characters should map to a glyph w/ no contours.
|
||||
* @param glyphStorage - the object which contains the output glyph array
|
||||
*
|
||||
* @see LECharMapper
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
virtual void mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse, const LECharMapper *mapper, le_bool filterZeroWidth, LEGlyphStorage &glyphStorage) const;
|
||||
|
||||
/**
|
||||
* This method maps a single character to a glyph index, using the
|
||||
* font's character to glyph map. The default implementation of this
|
||||
* method calls the mapper, and then calls <code>mapCharToGlyph(mappedCh)</code>.
|
||||
*
|
||||
* @param ch - the character
|
||||
* @param mapper - the character mapper
|
||||
* @param filterZeroWidth - <code>TRUE</code> if ZWJ / ZWNJ characters should map to a glyph w/ no contours.
|
||||
*
|
||||
* @return the glyph index
|
||||
*
|
||||
* @see LECharMapper
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
virtual LEGlyphID mapCharToGlyph(LEUnicode32 ch, const LECharMapper *mapper, le_bool filterZeroWidth) const;
|
||||
|
||||
/**
|
||||
* This method maps a single character to a glyph index, using the
|
||||
* font's character to glyph map. The default implementation of this
|
||||
* method calls the mapper, and then calls <code>mapCharToGlyph(mappedCh)</code>.
|
||||
*
|
||||
* @param ch - the character
|
||||
* @param mapper - the character mapper
|
||||
*
|
||||
* @return the glyph index
|
||||
*
|
||||
* @see LECharMapper
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
virtual LEGlyphID mapCharToGlyph(LEUnicode32 ch, const LECharMapper *mapper) const;
|
||||
|
||||
/**
|
||||
* This method maps a single character to a glyph index, using the
|
||||
* font's character to glyph map. There is no default implementation
|
||||
* of this method because it requires information about the platform
|
||||
* font implementation.
|
||||
*
|
||||
* @param ch - the character
|
||||
*
|
||||
* @return the glyph index
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
virtual LEGlyphID mapCharToGlyph(LEUnicode32 ch) const = 0;
|
||||
|
||||
//
|
||||
// Metrics
|
||||
//
|
||||
|
||||
/**
|
||||
* This method gets the X and Y advance of a particular glyph, in pixels.
|
||||
*
|
||||
* @param glyph - the glyph index
|
||||
* @param advance - the X and Y pixel values will be stored here
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
virtual void getGlyphAdvance(LEGlyphID glyph, LEPoint &advance) const = 0;
|
||||
|
||||
/**
|
||||
* This method gets the hinted X and Y pixel coordinates of a particular
|
||||
* point in the outline of the given glyph.
|
||||
*
|
||||
* @param glyph - the glyph index
|
||||
* @param pointNumber - the number of the point
|
||||
* @param point - the point's X and Y pixel values will be stored here
|
||||
*
|
||||
* @return <code>TRUE</code> if the point coordinates could be stored.
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
virtual le_bool getGlyphPoint(LEGlyphID glyph, le_int32 pointNumber, LEPoint &point) const = 0;
|
||||
|
||||
/**
|
||||
* This method returns the width of the font's EM square
|
||||
* in pixels.
|
||||
*
|
||||
* @return the pixel width of the EM square
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
virtual float getXPixelsPerEm() const = 0;
|
||||
|
||||
/**
|
||||
* This method returns the height of the font's EM square
|
||||
* in pixels.
|
||||
*
|
||||
* @return the pixel height of the EM square
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
virtual float getYPixelsPerEm() const = 0;
|
||||
|
||||
/**
|
||||
* This method converts font design units in the
|
||||
* X direction to points.
|
||||
*
|
||||
* @param xUnits - design units in the X direction
|
||||
*
|
||||
* @return points in the X direction
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
virtual float xUnitsToPoints(float xUnits) const;
|
||||
|
||||
/**
|
||||
* This method converts font design units in the
|
||||
* Y direction to points.
|
||||
*
|
||||
* @param yUnits - design units in the Y direction
|
||||
*
|
||||
* @return points in the Y direction
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
virtual float yUnitsToPoints(float yUnits) const;
|
||||
|
||||
/**
|
||||
* This method converts font design units to points.
|
||||
*
|
||||
* @param units - X and Y design units
|
||||
* @param points - set to X and Y points
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
virtual void unitsToPoints(LEPoint &units, LEPoint &points) const;
|
||||
|
||||
/**
|
||||
* This method converts pixels in the
|
||||
* X direction to font design units.
|
||||
*
|
||||
* @param xPixels - pixels in the X direction
|
||||
*
|
||||
* @return font design units in the X direction
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
virtual float xPixelsToUnits(float xPixels) const;
|
||||
|
||||
/**
|
||||
* This method converts pixels in the
|
||||
* Y direction to font design units.
|
||||
*
|
||||
* @param yPixels - pixels in the Y direction
|
||||
*
|
||||
* @return font design units in the Y direction
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
virtual float yPixelsToUnits(float yPixels) const;
|
||||
|
||||
/**
|
||||
* This method converts pixels to font design units.
|
||||
*
|
||||
* @param pixels - X and Y pixel
|
||||
* @param units - set to X and Y font design units
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
virtual void pixelsToUnits(LEPoint &pixels, LEPoint &units) const;
|
||||
|
||||
/**
|
||||
* Get the X scale factor from the font's transform. The default
|
||||
* implementation of <code>transformFunits()</code> will call this method.
|
||||
*
|
||||
* @return the X scale factor.
|
||||
*
|
||||
*
|
||||
* @see transformFunits
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
virtual float getScaleFactorX() const = 0;
|
||||
|
||||
/**
|
||||
* Get the Y scale factor from the font's transform. The default
|
||||
* implementation of <code>transformFunits()</code> will call this method.
|
||||
*
|
||||
* @return the Yscale factor.
|
||||
*
|
||||
* @see transformFunits
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
virtual float getScaleFactorY() const = 0;
|
||||
|
||||
/**
|
||||
* This method transforms an X, Y point in font design units to a
|
||||
* pixel coordinate, applying the font's transform. The default
|
||||
* implementation of this method calls <code>getScaleFactorX()</code>
|
||||
* and <code>getScaleFactorY()</code>.
|
||||
*
|
||||
* @param xFunits - the X coordinate in font design units
|
||||
* @param yFunits - the Y coordinate in font design units
|
||||
* @param pixels - the tranformed co-ordinate in pixels
|
||||
*
|
||||
* @see getScaleFactorX
|
||||
* @see getScaleFactorY
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
virtual void transformFunits(float xFunits, float yFunits, LEPoint &pixels) const;
|
||||
|
||||
/**
|
||||
* This is a convenience method used to convert
|
||||
* values in a 16.16 fixed point format to floating point.
|
||||
*
|
||||
* @param fixed - the fixed point value
|
||||
*
|
||||
* @return the floating point value
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
static inline float fixedToFloat(le_int32 fixed);
|
||||
|
||||
/**
|
||||
* This is a convenience method used to convert
|
||||
* floating point values to 16.16 fixed point format.
|
||||
*
|
||||
* @param theFloat - the floating point value
|
||||
*
|
||||
* @return the fixed point value
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
static inline le_int32 floatToFixed(float theFloat);
|
||||
|
||||
//
|
||||
// These methods won't ever be called by the LayoutEngine,
|
||||
// but are useful for clients of <code>LEFontInstance</code> who
|
||||
// need to render text.
|
||||
//
|
||||
|
||||
/**
|
||||
* Get the font's ascent.
|
||||
*
|
||||
* @return the font's ascent, in points. This value
|
||||
* will always be positive.
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
virtual le_int32 getAscent() const = 0;
|
||||
|
||||
/**
|
||||
* Get the font's descent.
|
||||
*
|
||||
* @return the font's descent, in points. This value
|
||||
* will always be positive.
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
virtual le_int32 getDescent() const = 0;
|
||||
|
||||
/**
|
||||
* Get the font's leading.
|
||||
*
|
||||
* @return the font's leading, in points. This value
|
||||
* will always be positive.
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
virtual le_int32 getLeading() const = 0;
|
||||
|
||||
/**
|
||||
* Get the line height required to display text in
|
||||
* this font. The default implementation of this method
|
||||
* returns the sum of the ascent, descent, and leading.
|
||||
*
|
||||
* @return the line height, in points. This vaule will
|
||||
* always be positive.
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
virtual le_int32 getLineHeight() const;
|
||||
|
||||
/**
|
||||
* ICU "poor man's RTTI", returns a UClassID for the actual class.
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
virtual UClassID getDynamicClassID() const;
|
||||
|
||||
/**
|
||||
* ICU "poor man's RTTI", returns a UClassID for this class.
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
static UClassID getStaticClassID();
|
||||
|
||||
};
|
||||
|
||||
inline float LEFontInstance::fixedToFloat(le_int32 fixed)
|
||||
{
|
||||
return (float) (fixed / 65536.0);
|
||||
}
|
||||
|
||||
inline le_int32 LEFontInstance::floatToFixed(float theFloat)
|
||||
{
|
||||
return (le_int32) (theFloat * 65536.0);
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
|
@ -1,47 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2011 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __LEGLYPHFILTER__H
|
||||
#define __LEGLYPHFILTER__H
|
||||
|
||||
#include "LETypes.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
#ifndef U_HIDE_INTERNAL_API
|
||||
/**
|
||||
* This is a helper class that is used to
|
||||
* recognize a set of glyph indices.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class LEGlyphFilter /* not : public UObject because this is an interface/mixin class */ {
|
||||
public:
|
||||
/**
|
||||
* Destructor.
|
||||
* @internal
|
||||
*/
|
||||
virtual ~LEGlyphFilter();
|
||||
|
||||
/**
|
||||
* This method is used to test a particular
|
||||
* glyph index to see if it is in the set
|
||||
* recognized by the filter.
|
||||
*
|
||||
* @param glyph - the glyph index to be tested
|
||||
*
|
||||
* @return TRUE if the glyph index is in the set.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
virtual le_bool accept(LEGlyphID glyph) const = 0;
|
||||
};
|
||||
#endif /* U_HIDE_INTERNAL_API */
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
|
@ -1,668 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
**********************************************************************
|
||||
* Copyright (C) 1998-2009, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "LEInsertionList.h"
|
||||
#include "LEGlyphStorage.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(LEGlyphStorage)
|
||||
|
||||
LEInsertionCallback::~LEInsertionCallback()
|
||||
{
|
||||
// nothing to do...
|
||||
}
|
||||
|
||||
LEGlyphStorage::LEGlyphStorage()
|
||||
: fGlyphCount(0), fGlyphs(NULL), fCharIndices(NULL), fPositions(NULL),
|
||||
fAuxData(NULL), fInsertionList(NULL), fSrcIndex(0), fDestIndex(0)
|
||||
{
|
||||
// nothing else to do!
|
||||
}
|
||||
|
||||
LEGlyphStorage::~LEGlyphStorage()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
void LEGlyphStorage::reset()
|
||||
{
|
||||
fGlyphCount = 0;
|
||||
|
||||
if (fPositions != NULL) {
|
||||
LE_DELETE_ARRAY(fPositions);
|
||||
fPositions = NULL;
|
||||
}
|
||||
|
||||
if (fAuxData != NULL) {
|
||||
LE_DELETE_ARRAY(fAuxData);
|
||||
fAuxData = NULL;
|
||||
}
|
||||
|
||||
if (fInsertionList != NULL) {
|
||||
delete fInsertionList;
|
||||
fInsertionList = NULL;
|
||||
}
|
||||
|
||||
if (fCharIndices != NULL) {
|
||||
LE_DELETE_ARRAY(fCharIndices);
|
||||
fCharIndices = NULL;
|
||||
}
|
||||
|
||||
if (fGlyphs != NULL) {
|
||||
LE_DELETE_ARRAY(fGlyphs);
|
||||
fGlyphs = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: This might get called more than once, for various reasons. Is
|
||||
// testing for pre-existing glyph and charIndices arrays good enough?
|
||||
void LEGlyphStorage::allocateGlyphArray(le_int32 initialGlyphCount, le_bool rightToLeft, LEErrorCode &success)
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (initialGlyphCount <= 0) {
|
||||
success = LE_ILLEGAL_ARGUMENT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
if (fGlyphs == NULL) {
|
||||
fGlyphCount = initialGlyphCount;
|
||||
fGlyphs = LE_NEW_ARRAY(LEGlyphID, fGlyphCount);
|
||||
|
||||
if (fGlyphs == NULL) {
|
||||
success = LE_MEMORY_ALLOCATION_ERROR;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (fCharIndices == NULL) {
|
||||
fCharIndices = LE_NEW_ARRAY(le_int32, fGlyphCount);
|
||||
|
||||
if (fCharIndices == NULL) {
|
||||
LE_DELETE_ARRAY(fGlyphs);
|
||||
fGlyphs = NULL;
|
||||
success = LE_MEMORY_ALLOCATION_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
// Initialize the charIndices array
|
||||
le_int32 i, count = fGlyphCount, dir = 1, out = 0;
|
||||
|
||||
if (rightToLeft) {
|
||||
out = fGlyphCount - 1;
|
||||
dir = -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i += 1, out += dir) {
|
||||
fCharIndices[out] = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (fInsertionList == NULL) {
|
||||
// FIXME: check this for failure?
|
||||
fInsertionList = new LEInsertionList(rightToLeft);
|
||||
if (fInsertionList == NULL) {
|
||||
LE_DELETE_ARRAY(fCharIndices);
|
||||
fCharIndices = NULL;
|
||||
|
||||
LE_DELETE_ARRAY(fGlyphs);
|
||||
fGlyphs = NULL;
|
||||
|
||||
success = LE_MEMORY_ALLOCATION_ERROR;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: do we want to initialize the positions to [0, 0]?
|
||||
le_int32 LEGlyphStorage::allocatePositions(LEErrorCode &success)
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fPositions != NULL) {
|
||||
success = LE_INTERNAL_ERROR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
fPositions = LE_NEW_ARRAY(float, 2 * (fGlyphCount + 1));
|
||||
|
||||
if (fPositions == NULL) {
|
||||
success = LE_MEMORY_ALLOCATION_ERROR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return fGlyphCount;
|
||||
}
|
||||
|
||||
// FIXME: do we want to initialize the aux data to NULL?
|
||||
le_int32 LEGlyphStorage::allocateAuxData(LEErrorCode &success)
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fAuxData != NULL) {
|
||||
success = LE_INTERNAL_ERROR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
fAuxData = LE_NEW_ARRAY(le_uint32, fGlyphCount);
|
||||
|
||||
if (fAuxData == NULL) {
|
||||
success = LE_MEMORY_ALLOCATION_ERROR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return fGlyphCount;
|
||||
}
|
||||
|
||||
void LEGlyphStorage::getCharIndices(le_int32 charIndices[], le_int32 indexBase, LEErrorCode &success) const
|
||||
{
|
||||
le_int32 i;
|
||||
|
||||
if (LE_FAILURE(success)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (charIndices == NULL) {
|
||||
success = LE_ILLEGAL_ARGUMENT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
if (fCharIndices == NULL) {
|
||||
success = LE_NO_LAYOUT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < fGlyphCount; i += 1) {
|
||||
charIndices[i] = fCharIndices[i] + indexBase;
|
||||
}
|
||||
}
|
||||
|
||||
void LEGlyphStorage::getCharIndices(le_int32 charIndices[], LEErrorCode &success) const
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (charIndices == NULL) {
|
||||
success = LE_ILLEGAL_ARGUMENT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
if (fCharIndices == NULL) {
|
||||
success = LE_NO_LAYOUT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
LE_ARRAY_COPY(charIndices, fCharIndices, fGlyphCount);
|
||||
}
|
||||
|
||||
// Copy the glyphs into caller's (32-bit) glyph array, OR in extraBits
|
||||
void LEGlyphStorage::getGlyphs(le_uint32 glyphs[], le_uint32 extraBits, LEErrorCode &success) const
|
||||
{
|
||||
le_int32 i;
|
||||
|
||||
if (LE_FAILURE(success)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (glyphs == NULL) {
|
||||
success = LE_ILLEGAL_ARGUMENT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
if (fGlyphs == NULL) {
|
||||
success = LE_NO_LAYOUT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < fGlyphCount; i += 1) {
|
||||
glyphs[i] = fGlyphs[i] | extraBits;
|
||||
}
|
||||
}
|
||||
|
||||
void LEGlyphStorage::getGlyphs(LEGlyphID glyphs[], LEErrorCode &success) const
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (glyphs == NULL) {
|
||||
success = LE_ILLEGAL_ARGUMENT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
if (fGlyphs == NULL) {
|
||||
success = LE_NO_LAYOUT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
LE_ARRAY_COPY(glyphs, fGlyphs, fGlyphCount);
|
||||
}
|
||||
|
||||
LEGlyphID LEGlyphStorage::getGlyphID(le_int32 glyphIndex, LEErrorCode &success) const
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return 0xFFFF;
|
||||
}
|
||||
|
||||
if (fGlyphs == NULL) {
|
||||
success = LE_NO_LAYOUT_ERROR;
|
||||
return 0xFFFF;
|
||||
}
|
||||
|
||||
if (glyphIndex < 0 || glyphIndex >= fGlyphCount) {
|
||||
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
|
||||
return 0xFFFF;
|
||||
}
|
||||
|
||||
return fGlyphs[glyphIndex];
|
||||
}
|
||||
|
||||
void LEGlyphStorage::setGlyphID(le_int32 glyphIndex, LEGlyphID glyphID, LEErrorCode &success)
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (fGlyphs == NULL) {
|
||||
success = LE_NO_LAYOUT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
if (glyphIndex < 0 || glyphIndex >= fGlyphCount) {
|
||||
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
fGlyphs[glyphIndex] = glyphID;
|
||||
}
|
||||
|
||||
le_int32 LEGlyphStorage::getCharIndex(le_int32 glyphIndex, LEErrorCode &success) const
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fCharIndices == NULL) {
|
||||
success = LE_NO_LAYOUT_ERROR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (glyphIndex < 0 || glyphIndex >= fGlyphCount) {
|
||||
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return fCharIndices[glyphIndex];
|
||||
}
|
||||
|
||||
void LEGlyphStorage::setCharIndex(le_int32 glyphIndex, le_int32 charIndex, LEErrorCode &success)
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (fCharIndices == NULL) {
|
||||
success = LE_NO_LAYOUT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
if (glyphIndex < 0 || glyphIndex >= fGlyphCount) {
|
||||
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
fCharIndices[glyphIndex] = charIndex;
|
||||
}
|
||||
|
||||
void LEGlyphStorage::getAuxData(le_uint32 auxData[], LEErrorCode &success) const
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (auxData == NULL) {
|
||||
success = LE_ILLEGAL_ARGUMENT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
if (fAuxData == NULL) {
|
||||
success = LE_NO_LAYOUT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
LE_ARRAY_COPY(auxData, fAuxData, fGlyphCount);
|
||||
}
|
||||
|
||||
le_uint32 LEGlyphStorage::getAuxData(le_int32 glyphIndex, LEErrorCode &success) const
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (fAuxData == NULL) {
|
||||
success = LE_NO_LAYOUT_ERROR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (glyphIndex < 0 || glyphIndex >= fGlyphCount) {
|
||||
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return fAuxData[glyphIndex];
|
||||
}
|
||||
|
||||
void LEGlyphStorage::setAuxData(le_int32 glyphIndex, le_uint32 auxData, LEErrorCode &success)
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (fAuxData == NULL) {
|
||||
success = LE_NO_LAYOUT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
if (glyphIndex < 0 || glyphIndex >= fGlyphCount) {
|
||||
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
fAuxData[glyphIndex] = auxData;
|
||||
}
|
||||
|
||||
void LEGlyphStorage::getGlyphPositions(float positions[], LEErrorCode &success) const
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (positions == NULL) {
|
||||
success = LE_ILLEGAL_ARGUMENT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
if (fPositions == NULL) {
|
||||
success = LE_NO_LAYOUT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
LE_ARRAY_COPY(positions, fPositions, fGlyphCount * 2 + 2);
|
||||
}
|
||||
|
||||
void LEGlyphStorage::getGlyphPosition(le_int32 glyphIndex, float &x, float &y, LEErrorCode &success) const
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (glyphIndex < 0 || glyphIndex > fGlyphCount) {
|
||||
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
if (fPositions == NULL) {
|
||||
success = LE_NO_LAYOUT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
x = fPositions[glyphIndex * 2];
|
||||
y = fPositions[glyphIndex * 2 + 1];
|
||||
}
|
||||
|
||||
void LEGlyphStorage::setPosition(le_int32 glyphIndex, float x, float y, LEErrorCode &success)
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (glyphIndex < 0 || glyphIndex > fGlyphCount) {
|
||||
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
fPositions[glyphIndex * 2] = x;
|
||||
fPositions[glyphIndex * 2 + 1] = y;
|
||||
}
|
||||
|
||||
void LEGlyphStorage::adjustPosition(le_int32 glyphIndex, float xAdjust, float yAdjust, LEErrorCode &success)
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (glyphIndex < 0 || glyphIndex > fGlyphCount) {
|
||||
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
fPositions[glyphIndex * 2] += xAdjust;
|
||||
fPositions[glyphIndex * 2 + 1] += yAdjust;
|
||||
}
|
||||
|
||||
void LEGlyphStorage::adoptGlyphArray(LEGlyphStorage &from)
|
||||
{
|
||||
if (fGlyphs != NULL) {
|
||||
LE_DELETE_ARRAY(fGlyphs);
|
||||
}
|
||||
|
||||
fGlyphs = from.fGlyphs;
|
||||
from.fGlyphs = NULL;
|
||||
|
||||
if (fInsertionList != NULL) {
|
||||
delete fInsertionList;
|
||||
}
|
||||
|
||||
fInsertionList = from.fInsertionList;
|
||||
from.fInsertionList = NULL;
|
||||
}
|
||||
|
||||
void LEGlyphStorage::adoptCharIndicesArray(LEGlyphStorage &from)
|
||||
{
|
||||
if (fCharIndices != NULL) {
|
||||
LE_DELETE_ARRAY(fCharIndices);
|
||||
}
|
||||
|
||||
fCharIndices = from.fCharIndices;
|
||||
from.fCharIndices = NULL;
|
||||
}
|
||||
|
||||
void LEGlyphStorage::adoptPositionArray(LEGlyphStorage &from)
|
||||
{
|
||||
if (fPositions != NULL) {
|
||||
LE_DELETE_ARRAY(fPositions);
|
||||
}
|
||||
|
||||
fPositions = from.fPositions;
|
||||
from.fPositions = NULL;
|
||||
}
|
||||
|
||||
void LEGlyphStorage::adoptAuxDataArray(LEGlyphStorage &from)
|
||||
{
|
||||
if (fAuxData != NULL) {
|
||||
LE_DELETE_ARRAY(fAuxData);
|
||||
}
|
||||
|
||||
fAuxData = from.fAuxData;
|
||||
from.fAuxData = NULL;
|
||||
}
|
||||
|
||||
void LEGlyphStorage::adoptGlyphCount(LEGlyphStorage &from)
|
||||
{
|
||||
fGlyphCount = from.fGlyphCount;
|
||||
}
|
||||
|
||||
void LEGlyphStorage::adoptGlyphCount(le_int32 newGlyphCount)
|
||||
{
|
||||
fGlyphCount = newGlyphCount;
|
||||
}
|
||||
|
||||
// Move a glyph to a different position in the LEGlyphStorage ( used for Indic v2 processing )
|
||||
|
||||
void LEGlyphStorage::moveGlyph(le_int32 fromPosition, le_int32 toPosition, le_uint32 marker )
|
||||
{
|
||||
|
||||
LEErrorCode success = LE_NO_ERROR;
|
||||
|
||||
LEGlyphID holdGlyph = getGlyphID(fromPosition,success);
|
||||
le_int32 holdCharIndex = getCharIndex(fromPosition,success);
|
||||
le_uint32 holdAuxData = getAuxData(fromPosition,success);
|
||||
|
||||
if ( fromPosition < toPosition ) {
|
||||
for ( le_int32 i = fromPosition ; i < toPosition ; i++ ) {
|
||||
setGlyphID(i,getGlyphID(i+1,success),success);
|
||||
setCharIndex(i,getCharIndex(i+1,success),success);
|
||||
setAuxData(i,getAuxData(i+1,success),success);
|
||||
}
|
||||
} else {
|
||||
for ( le_int32 i = toPosition ; i > fromPosition ; i-- ) {
|
||||
setGlyphID(i,getGlyphID(i-1,success),success);
|
||||
setCharIndex(i,getCharIndex(i-1,success),success);
|
||||
setAuxData(i,getAuxData(i-1,success),success);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
setGlyphID(toPosition,holdGlyph,success);
|
||||
setCharIndex(toPosition,holdCharIndex,success);
|
||||
setAuxData(toPosition,holdAuxData | marker,success);
|
||||
|
||||
}
|
||||
|
||||
// Glue code for existing stable API
|
||||
LEGlyphID *LEGlyphStorage::insertGlyphs(le_int32 atIndex, le_int32 insertCount)
|
||||
{
|
||||
LEErrorCode ignored = LE_NO_LAYOUT_ERROR;
|
||||
return insertGlyphs(atIndex, insertCount, ignored);
|
||||
}
|
||||
|
||||
// FIXME: add error checking?
|
||||
LEGlyphID *LEGlyphStorage::insertGlyphs(le_int32 atIndex, le_int32 insertCount, LEErrorCode& success)
|
||||
{
|
||||
return fInsertionList->insert(atIndex, insertCount, success);
|
||||
}
|
||||
|
||||
le_int32 LEGlyphStorage::applyInsertions()
|
||||
{
|
||||
le_int32 growAmount = fInsertionList->getGrowAmount();
|
||||
|
||||
if (growAmount == 0) {
|
||||
return fGlyphCount;
|
||||
}
|
||||
|
||||
le_int32 newGlyphCount = fGlyphCount + growAmount;
|
||||
|
||||
LEGlyphID *newGlyphs = (LEGlyphID *) LE_GROW_ARRAY(fGlyphs, newGlyphCount);
|
||||
if (newGlyphs == NULL) {
|
||||
// Could not grow the glyph array
|
||||
return fGlyphCount;
|
||||
}
|
||||
fGlyphs = newGlyphs;
|
||||
|
||||
le_int32 *newCharIndices = (le_int32 *) LE_GROW_ARRAY(fCharIndices, newGlyphCount);
|
||||
if (newCharIndices == NULL) {
|
||||
// Could not grow the glyph array
|
||||
return fGlyphCount;
|
||||
}
|
||||
fCharIndices = newCharIndices;
|
||||
|
||||
if (fAuxData != NULL) {
|
||||
le_uint32 *newAuxData = (le_uint32 *) LE_GROW_ARRAY(fAuxData, newGlyphCount);
|
||||
if (newAuxData == NULL) {
|
||||
// could not grow the aux data array
|
||||
return fGlyphCount;
|
||||
}
|
||||
fAuxData = (le_uint32 *)newAuxData;
|
||||
}
|
||||
|
||||
fSrcIndex = fGlyphCount - 1;
|
||||
fDestIndex = newGlyphCount - 1;
|
||||
|
||||
#if 0
|
||||
// If the current position is at the end of the array
|
||||
// update it to point to the end of the new array. The
|
||||
// insertion callback will handle all other cases.
|
||||
// FIXME: this is left over from GlyphIterator, but there's no easy
|
||||
// way to implement this here... it seems that GlyphIterator doesn't
|
||||
// really need it 'cause the insertions don't get applied until after a
|
||||
// complete pass over the glyphs, after which the iterator gets reset anyhow...
|
||||
// probably better to just document that for LEGlyphStorage and GlyphIterator...
|
||||
if (position == glyphCount) {
|
||||
position = newGlyphCount;
|
||||
}
|
||||
#endif
|
||||
|
||||
fInsertionList->applyInsertions(this);
|
||||
|
||||
fInsertionList->reset();
|
||||
|
||||
return fGlyphCount = newGlyphCount;
|
||||
}
|
||||
|
||||
le_bool LEGlyphStorage::applyInsertion(le_int32 atPosition, le_int32 count, LEGlyphID newGlyphs[])
|
||||
{
|
||||
#if 0
|
||||
// if the current position is within the block we're shifting
|
||||
// it needs to be updated to the current glyph's
|
||||
// new location.
|
||||
// FIXME: this is left over from GlyphIterator, but there's no easy
|
||||
// way to implement this here... it seems that GlyphIterator doesn't
|
||||
// really need it 'cause the insertions don't get applied until after a
|
||||
// complete pass over the glyphs, after which the iterator gets reset anyhow...
|
||||
// probably better to just document that for LEGlyphStorage and GlyphIterator...
|
||||
if (position >= atPosition && position <= fSrcIndex) {
|
||||
position += fDestIndex - fSrcIndex;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (fAuxData != NULL) {
|
||||
le_int32 src = fSrcIndex, dest = fDestIndex;
|
||||
|
||||
while (src > atPosition) {
|
||||
fAuxData[dest--] = fAuxData[src--];
|
||||
}
|
||||
|
||||
for (le_int32 i = count - 1; i >= 0; i -= 1) {
|
||||
fAuxData[dest--] = fAuxData[atPosition];
|
||||
}
|
||||
}
|
||||
|
||||
while (fSrcIndex > atPosition) {
|
||||
fGlyphs[fDestIndex] = fGlyphs[fSrcIndex];
|
||||
fCharIndices[fDestIndex] = fCharIndices[fSrcIndex];
|
||||
|
||||
fDestIndex -= 1;
|
||||
fSrcIndex -= 1;
|
||||
}
|
||||
|
||||
for (le_int32 i = count - 1; i >= 0; i -= 1) {
|
||||
fGlyphs[fDestIndex] = newGlyphs[i];
|
||||
fCharIndices[fDestIndex] = fCharIndices[atPosition];
|
||||
|
||||
fDestIndex -= 1;
|
||||
}
|
||||
|
||||
// the source glyph we're pointing at
|
||||
// just got replaced by the insertion
|
||||
fSrcIndex -= 1;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
|
@ -1,548 +0,0 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
**********************************************************************
|
||||
* Copyright (C) 1998-2014, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
#ifndef __LEGLYPHSTORAGE_H
|
||||
#define __LEGLYPHSTORAGE_H
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "LEInsertionList.h"
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \brief C++ API: This class encapsulates the per-glyph storage used by the ICU LayoutEngine.
|
||||
*/
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
/**
|
||||
* This class encapsulates the per-glyph storage used by the ICU LayoutEngine.
|
||||
* For each glyph it holds the glyph ID, the index of the backing store character
|
||||
* which produced the glyph, the X and Y position of the glyph and an auxillary data
|
||||
* pointer.
|
||||
*
|
||||
* The storage is growable using the <code>LEInsertionList</code> class.
|
||||
*
|
||||
*
|
||||
* @see LEInsertionList.h
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
class U_LAYOUT_API LEGlyphStorage : public UObject, protected LEInsertionCallback
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* The number of entries in the per-glyph arrays.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
le_int32 fGlyphCount;
|
||||
|
||||
/**
|
||||
* The glyph ID array.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
LEGlyphID *fGlyphs;
|
||||
|
||||
/**
|
||||
* The char indices array.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
le_int32 *fCharIndices;
|
||||
|
||||
/**
|
||||
* The glyph positions array.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
float *fPositions;
|
||||
|
||||
/**
|
||||
* The auxillary data array.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
le_uint32 *fAuxData;
|
||||
|
||||
|
||||
/**
|
||||
* The insertion list, used to grow the above arrays.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
LEInsertionList *fInsertionList;
|
||||
|
||||
/**
|
||||
* The source index while growing the data arrays.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
le_int32 fSrcIndex;
|
||||
|
||||
/**
|
||||
* The destination index used while growing the data arrays.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
le_int32 fDestIndex;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* This implements <code>LEInsertionCallback</code>. The <code>LEInsertionList</code>
|
||||
* will call this method once for each insertion.
|
||||
*
|
||||
* @param atPosition the position of the insertion
|
||||
* @param count the number of glyphs being inserted
|
||||
* @param newGlyphs the address of the new glyph IDs
|
||||
*
|
||||
* @return <code>true</code> if <code>LEInsertionList</code> should stop
|
||||
* processing the insertion list after this insertion.
|
||||
*
|
||||
* @see LEInsertionList.h
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
virtual le_bool applyInsertion(le_int32 atPosition, le_int32 count, LEGlyphID newGlyphs[]);
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Allocates an empty <code>LEGlyphStorage</code> object. You must call
|
||||
* <code>allocateGlyphArray, allocatePositions and allocateAuxData</code>
|
||||
* to allocate the data.
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
LEGlyphStorage();
|
||||
|
||||
/**
|
||||
* The destructor. This will deallocate all of the arrays.
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
~LEGlyphStorage();
|
||||
|
||||
/**
|
||||
* This method returns the number of glyphs in the glyph array.
|
||||
*
|
||||
* @return the number of glyphs in the glyph array
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
inline le_int32 getGlyphCount() const;
|
||||
|
||||
/**
|
||||
* This method copies the glyph array into a caller supplied array.
|
||||
* The caller must ensure that the array is large enough to hold all
|
||||
* the glyphs.
|
||||
*
|
||||
* @param glyphs - the destiniation glyph array
|
||||
* @param success - set to an error code if the operation fails
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
void getGlyphs(LEGlyphID glyphs[], LEErrorCode &success) const;
|
||||
|
||||
/**
|
||||
* This method copies the glyph array into a caller supplied array,
|
||||
* ORing in extra bits. (This functionality is needed by the JDK,
|
||||
* which uses 32 bits pre glyph idex, with the high 16 bits encoding
|
||||
* the composite font slot number)
|
||||
*
|
||||
* @param glyphs - the destination (32 bit) glyph array
|
||||
* @param extraBits - this value will be ORed with each glyph index
|
||||
* @param success - set to an error code if the operation fails
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
void getGlyphs(le_uint32 glyphs[], le_uint32 extraBits, LEErrorCode &success) const;
|
||||
|
||||
/**
|
||||
* This method copies the character index array into a caller supplied array.
|
||||
* The caller must ensure that the array is large enough to hold a
|
||||
* character index for each glyph.
|
||||
*
|
||||
* @param charIndices - the destiniation character index array
|
||||
* @param success - set to an error code if the operation fails
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
void getCharIndices(le_int32 charIndices[], LEErrorCode &success) const;
|
||||
|
||||
/**
|
||||
* This method copies the character index array into a caller supplied array.
|
||||
* The caller must ensure that the array is large enough to hold a
|
||||
* character index for each glyph.
|
||||
*
|
||||
* @param charIndices - the destiniation character index array
|
||||
* @param indexBase - an offset which will be added to each index
|
||||
* @param success - set to an error code if the operation fails
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
void getCharIndices(le_int32 charIndices[], le_int32 indexBase, LEErrorCode &success) const;
|
||||
|
||||
/**
|
||||
* This method copies the position array into a caller supplied array.
|
||||
* The caller must ensure that the array is large enough to hold an
|
||||
* X and Y position for each glyph, plus an extra X and Y for the
|
||||
* advance of the last glyph.
|
||||
*
|
||||
* @param positions - the destiniation position array
|
||||
* @param success - set to an error code if the operation fails
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
void getGlyphPositions(float positions[], LEErrorCode &success) const;
|
||||
|
||||
/**
|
||||
* This method returns the X and Y position of the glyph at
|
||||
* the given index.
|
||||
*
|
||||
* Input parameters:
|
||||
* @param glyphIndex - the index of the glyph
|
||||
*
|
||||
* Output parameters:
|
||||
* @param x - the glyph's X position
|
||||
* @param y - the glyph's Y position
|
||||
* @param success - set to an error code if the operation fails
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
void getGlyphPosition(le_int32 glyphIndex, float &x, float &y, LEErrorCode &success) const;
|
||||
|
||||
/**
|
||||
* This method allocates the glyph array, the char indices array and the insertion list. You
|
||||
* must call this method before using the object. This method also initializes the char indices
|
||||
* array.
|
||||
*
|
||||
* @param initialGlyphCount the initial size of the glyph and char indices arrays.
|
||||
* @param rightToLeft <code>true</code> if the original input text is right to left.
|
||||
* @param success set to an error code if the storage cannot be allocated of if the initial
|
||||
* glyph count is not positive.
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
void allocateGlyphArray(le_int32 initialGlyphCount, le_bool rightToLeft, LEErrorCode &success);
|
||||
|
||||
/**
|
||||
* This method allocates the storage for the glyph positions. It allocates one extra X, Y
|
||||
* position pair for the position just after the last glyph.
|
||||
*
|
||||
* @param success set to an error code if the positions array cannot be allocated.
|
||||
*
|
||||
* @return the number of X, Y position pairs allocated.
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
le_int32 allocatePositions(LEErrorCode &success);
|
||||
|
||||
/**
|
||||
* This method allocates the storage for the auxillary glyph data.
|
||||
*
|
||||
* @param success set to an error code if the aulillary data array cannot be allocated.
|
||||
*
|
||||
* @return the size of the auxillary data array.
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
le_int32 allocateAuxData(LEErrorCode &success);
|
||||
|
||||
/**
|
||||
* Copy the entire auxillary data array.
|
||||
*
|
||||
* @param auxData the auxillary data array will be copied to this address
|
||||
* @param success set to an error code if the data cannot be copied
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
void getAuxData(le_uint32 auxData[], LEErrorCode &success) const;
|
||||
|
||||
/**
|
||||
* Get the glyph ID for a particular glyph.
|
||||
*
|
||||
* @param glyphIndex the index into the glyph array
|
||||
* @param success set to an error code if the glyph ID cannot be retrieved.
|
||||
*
|
||||
* @return the glyph ID
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
LEGlyphID getGlyphID(le_int32 glyphIndex, LEErrorCode &success) const;
|
||||
|
||||
/**
|
||||
* Get the char index for a particular glyph.
|
||||
*
|
||||
* @param glyphIndex the index into the glyph array
|
||||
* @param success set to an error code if the char index cannot be retrieved.
|
||||
*
|
||||
* @return the character index
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
le_int32 getCharIndex(le_int32 glyphIndex, LEErrorCode &success) const;
|
||||
|
||||
|
||||
/**
|
||||
* Get the auxillary data for a particular glyph.
|
||||
*
|
||||
* @param glyphIndex the index into the glyph array
|
||||
* @param success set to an error code if the auxillary data cannot be retrieved.
|
||||
*
|
||||
* @return the auxillary data
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
le_uint32 getAuxData(le_int32 glyphIndex, LEErrorCode &success) const;
|
||||
|
||||
/**
|
||||
* This operator allows direct access to the glyph array
|
||||
* using the index operator.
|
||||
*
|
||||
* @param glyphIndex the index into the glyph array
|
||||
*
|
||||
* @return a reference to the given location in the glyph array
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
inline LEGlyphID &operator[](le_int32 glyphIndex) const;
|
||||
|
||||
/**
|
||||
* Call this method to replace a single glyph in the glyph array
|
||||
* with multiple glyphs. This method uses the <code>LEInsertionList</code>
|
||||
* to do the insertion. It returns the address of storage where the new
|
||||
* glyph IDs can be stored. They will not actually be inserted into the
|
||||
* glyph array until <code>applyInsertions</code> is called.
|
||||
*
|
||||
* @param atIndex the index of the glyph to be replaced
|
||||
* @param insertCount the number of glyphs to replace it with
|
||||
* @param success set to an error code if the auxillary data cannot be retrieved.
|
||||
*
|
||||
* @return the address at which to store the replacement glyphs.
|
||||
*
|
||||
* @see LEInsertionList.h
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
LEGlyphID *insertGlyphs(le_int32 atIndex, le_int32 insertCount, LEErrorCode& success);
|
||||
|
||||
/**
|
||||
* Call this method to replace a single glyph in the glyph array
|
||||
* with multiple glyphs. This method uses the <code>LEInsertionList</code>
|
||||
* to do the insertion. It returns the address of storage where the new
|
||||
* glyph IDs can be stored. They will not actually be inserted into the
|
||||
* glyph array until <code>applyInsertions</code> is called.
|
||||
*
|
||||
* Note: Don't use this version, use the other version of this function which has an error code.
|
||||
*
|
||||
* @param atIndex the index of the glyph to be replaced
|
||||
* @param insertCount the number of glyphs to replace it with
|
||||
*
|
||||
* @return the address at which to store the replacement glyphs.
|
||||
*
|
||||
* @see LEInsertionList.h
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
LEGlyphID *insertGlyphs(le_int32 atIndex, le_int32 insertCount);
|
||||
|
||||
/**
|
||||
* This method is used to reposition glyphs during Indic v2 processing. It moves
|
||||
* all of the relevant glyph information ( glyph, indices, positions, and auxData ),
|
||||
* from the source position to the target position, and also allows for a marker bit
|
||||
* to be set in the target glyph's auxData so that it won't be reprocessed later in the
|
||||
* cycle.
|
||||
*
|
||||
* @param fromPosition - position of the glyph to be moved
|
||||
* @param toPosition - target position of the glyph
|
||||
* @param marker marker bit
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
void moveGlyph(le_int32 fromPosition, le_int32 toPosition, le_uint32 marker);
|
||||
|
||||
/**
|
||||
* This method causes all of the glyph insertions recorded by
|
||||
* <code>insertGlyphs</code> to be applied to the glyph array. The
|
||||
* new slots in the char indices and the auxillary data arrays
|
||||
* will be filled in with the values for the glyph being replaced.
|
||||
*
|
||||
* @return the new size of the glyph array
|
||||
*
|
||||
* @see LEInsertionList.h
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
le_int32 applyInsertions();
|
||||
|
||||
/**
|
||||
* Set the glyph ID for a particular glyph.
|
||||
*
|
||||
* @param glyphIndex the index of the glyph
|
||||
* @param glyphID the new glyph ID
|
||||
* @param success will be set to an error code if the glyph ID cannot be set.
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
void setGlyphID(le_int32 glyphIndex, LEGlyphID glyphID, LEErrorCode &success);
|
||||
|
||||
/**
|
||||
* Set the char index for a particular glyph.
|
||||
*
|
||||
* @param glyphIndex the index of the glyph
|
||||
* @param charIndex the new char index
|
||||
* @param success will be set to an error code if the char index cannot be set.
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
void setCharIndex(le_int32 glyphIndex, le_int32 charIndex, LEErrorCode &success);
|
||||
|
||||
/**
|
||||
* Set the X, Y position for a particular glyph.
|
||||
*
|
||||
* @param glyphIndex the index of the glyph
|
||||
* @param x the new X position
|
||||
* @param y the new Y position
|
||||
* @param success will be set to an error code if the position cannot be set.
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
void setPosition(le_int32 glyphIndex, float x, float y, LEErrorCode &success);
|
||||
|
||||
/**
|
||||
* Adjust the X, Y position for a particular glyph.
|
||||
*
|
||||
* @param glyphIndex the index of the glyph
|
||||
* @param xAdjust the adjustment to the glyph's X position
|
||||
* @param yAdjust the adjustment to the glyph's Y position
|
||||
* @param success will be set to an error code if the glyph's position cannot be adjusted.
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
void adjustPosition(le_int32 glyphIndex, float xAdjust, float yAdjust, LEErrorCode &success);
|
||||
|
||||
/**
|
||||
* Set the auxillary data for a particular glyph.
|
||||
*
|
||||
* @param glyphIndex the index of the glyph
|
||||
* @param auxData the new auxillary data
|
||||
* @param success will be set to an error code if the auxillary data cannot be set.
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
void setAuxData(le_int32 glyphIndex, le_uint32 auxData, LEErrorCode &success);
|
||||
|
||||
/**
|
||||
* Delete the glyph array and replace it with the one
|
||||
* in <code>from</code>. Set the glyph array pointer
|
||||
* in <code>from</code> to <code>NULL</code>.
|
||||
*
|
||||
* @param from the <code>LEGlyphStorage</code> object from which
|
||||
* to get the new glyph array.
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
void adoptGlyphArray(LEGlyphStorage &from);
|
||||
|
||||
/**
|
||||
* Delete the char indices array and replace it with the one
|
||||
* in <code>from</code>. Set the char indices array pointer
|
||||
* in <code>from</code> to <code>NULL</code>.
|
||||
*
|
||||
* @param from the <code>LEGlyphStorage</code> object from which
|
||||
* to get the new char indices array.
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
void adoptCharIndicesArray(LEGlyphStorage &from);
|
||||
|
||||
/**
|
||||
* Delete the position array and replace it with the one
|
||||
* in <code>from</code>. Set the position array pointer
|
||||
* in <code>from</code> to <code>NULL</code>.
|
||||
*
|
||||
* @param from the <code>LEGlyphStorage</code> object from which
|
||||
* to get the new position array.
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
void adoptPositionArray(LEGlyphStorage &from);
|
||||
|
||||
/**
|
||||
* Delete the auxillary data array and replace it with the one
|
||||
* in <code>from</code>. Set the auxillary data array pointer
|
||||
* in <code>from</code> to <code>NULL</code>.
|
||||
*
|
||||
* @param from the <code>LEGlyphStorage</code> object from which
|
||||
* to get the new auxillary data array.
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
void adoptAuxDataArray(LEGlyphStorage &from);
|
||||
|
||||
/**
|
||||
* Change the glyph count of this object to be the same
|
||||
* as the one in <code>from</code>.
|
||||
*
|
||||
* @param from the <code>LEGlyphStorage</code> object from which
|
||||
* to get the new glyph count.
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
void adoptGlyphCount(LEGlyphStorage &from);
|
||||
|
||||
/**
|
||||
* Change the glyph count of this object to the given value.
|
||||
*
|
||||
* @param newGlyphCount the new glyph count.
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
void adoptGlyphCount(le_int32 newGlyphCount);
|
||||
|
||||
/**
|
||||
* This method frees the glyph, character index, position and
|
||||
* auxillary data arrays so that the LayoutEngine can be reused
|
||||
* to layout a different characer array. (This method is also called
|
||||
* by the destructor)
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
void reset();
|
||||
|
||||
/**
|
||||
* ICU "poor man's RTTI", returns a UClassID for the actual class.
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
virtual UClassID getDynamicClassID() const;
|
||||
|
||||
/**
|
||||
* ICU "poor man's RTTI", returns a UClassID for this class.
|
||||
*
|
||||
* @deprecated ICU 54. See {@link icu::LayoutEngine}
|
||||
*/
|
||||
static UClassID getStaticClassID();
|
||||
};
|
||||
|
||||
inline le_int32 LEGlyphStorage::getGlyphCount() const
|
||||
{
|
||||
return fGlyphCount;
|
||||
}
|
||||
|
||||
inline LEGlyphID &LEGlyphStorage::operator[](le_int32 glyphIndex) const
|
||||
{
|
||||
return fGlyphs[glyphIndex];
|
||||
}
|
||||
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
||||
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue