ICU-12708 bye bye layout engine

X-SVN-Rev: 39176
This commit is contained in:
Steven R. Loomis 2016-09-09 21:28:18 +00:00
parent 78e91a274f
commit 4136a2f257
211 changed files with 209 additions and 32161 deletions
.gitignore
icu4c
readme.html
source
Makefile.inaclocal.m4
allinone
config
configureconfigure.ac
data
icudefs.mk.in
layout
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
View file

@ -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

View file

@ -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 &amp;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", &amp;errorCode)</code>
@ -442,11 +428,6 @@
analysis, and transliteration.</td>
</tr>
<tr>
<td><i>&lt;ICU&gt;</i>/source/<b>layout</b>/</td>
<td>Contains the ICU complex text layout engine. (Deprecated)</td>
</tr>
<tr>
<td><i>&lt;ICU&gt;</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>

View file

@ -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),)

View file

@ -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])

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -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)

View file

@ -76,9 +76,6 @@
.BI "\-\-ldflags"
]
[
.BI "\-\-ldflags\-layout"
]
[
.BI "\-\-ldflags\-libsonly"
]
[

View file

@ -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.

View file

@ -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.

View file

@ -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

View file

@ -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

View file

@ -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" ;;

View file

@ -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 \

View file

@ -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>

View file

@ -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.

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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