summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Turner <david@freetype.org>2004-04-05 22:16:12 +0000
committerDavid Turner <david@freetype.org>2004-04-05 22:16:12 +0000
commita5f7fcdf56f084c3882b743890eca0832e5eaceb (patch)
treed614335abac047ce15c4a5cdf64843c6c89c71c3
parentcad0775afe78ea49fefb2384a94c845e83bbc2d3 (diff)
downloadfreetype2-a5f7fcdf56f084c3882b743890eca0832e5eaceb.tar.gz
initial import of the FreeType Layout sources
-rw-r--r--docs/modules.txt2
-rw-r--r--ftlayout.txt291
-rw-r--r--include/freetype/config/ftheader.h14
-rw-r--r--include/freetype/config/ftmodule.h2
-rw-r--r--include/freetype/config/ftstdlib.h1
-rw-r--r--include/freetype/freetype.h18
-rw-r--r--include/freetype/fterrdef.h8
-rw-r--r--include/freetype/ftlayout.h515
-rw-r--r--include/freetype/ftmoderr.h2
-rw-r--r--include/freetype/gxlayout.h363
-rw-r--r--include/freetype/internal/ftltypes.h85
-rw-r--r--include/freetype/internal/ftserv.h3
-rw-r--r--include/freetype/internal/fttrace.h11
-rw-r--r--include/freetype/internal/internal.h2
-rw-r--r--include/freetype/internal/services/svlayout.h84
-rw-r--r--include/freetype/internal/services/svttcmap.h6
-rw-r--r--include/freetype/otlayout.h79
-rw-r--r--include/freetype/tttags.h21
-rw-r--r--src/base/Jamfile2
-rw-r--r--src/base/ftlayout.c496
-rw-r--r--src/base/rules.mk3
-rw-r--r--src/gxlayout/Jamfile23
-rw-r--r--src/gxlayout/demo.mk70
-rw-r--r--src/gxlayout/fi.c159
-rw-r--r--src/gxlayout/gx.c42
-rw-r--r--src/gxlayout/gxaccess.c1034
-rw-r--r--src/gxlayout/gxaccess.h112
-rw-r--r--src/gxlayout/gxdemo.c1217
-rw-r--r--src/gxlayout/gxdriver.c101
-rw-r--r--src/gxlayout/gxdriver.h42
-rw-r--r--src/gxlayout/gxdump.c2818
-rw-r--r--src/gxlayout/gxdump.h71
-rw-r--r--src/gxlayout/gxerrors.h46
-rw-r--r--src/gxlayout/gxfeatreg.c456
-rw-r--r--src/gxlayout/gxfeatreg.h45
-rw-r--r--src/gxlayout/gxlayout.c762
-rw-r--r--src/gxlayout/gxlfeatreg.c87
-rw-r--r--src/gxlayout/gxlfeatreg.h42
-rw-r--r--src/gxlayout/gxload.c4327
-rw-r--r--src/gxlayout/gxload.h112
-rw-r--r--src/gxlayout/gxlookuptbl.c691
-rw-r--r--src/gxlayout/gxlookuptbl.h125
-rw-r--r--src/gxlayout/gxltypes.h119
-rw-r--r--src/gxlayout/gxobjs.c335
-rw-r--r--src/gxlayout/gxobjs.h53
-rw-r--r--src/gxlayout/gxstatetbl.c765
-rw-r--r--src/gxlayout/gxstatetbl.h128
-rw-r--r--src/gxlayout/gxtypes.h1238
-rw-r--r--src/gxlayout/gxutils.c129
-rw-r--r--src/gxlayout/gxutils.h73
-rw-r--r--src/gxlayout/gxvm.c1794
-rw-r--r--src/gxlayout/gxvm.h99
-rw-r--r--src/gxlayout/module.mk33
-rw-r--r--src/gxlayout/rules.mk96
-rw-r--r--src/otlayout/README145
-rw-r--r--src/otlayout/demo.mk41
-rw-r--r--src/otlayout/fterrcompat.h89
-rw-r--r--src/otlayout/ftxgdef.c1214
-rw-r--r--src/otlayout/ftxgdef.h224
-rw-r--r--src/otlayout/ftxgpos.c6327
-rw-r--r--src/otlayout/ftxgpos.h859
-rw-r--r--src/otlayout/ftxgsub.c4582
-rw-r--r--src/otlayout/ftxgsub.h613
-rw-r--r--src/otlayout/ftxopen.c1520
-rw-r--r--src/otlayout/ftxopen.h314
-rw-r--r--src/otlayout/ftxopenf.h163
-rw-r--r--src/otlayout/module.mk22
-rw-r--r--src/otlayout/ot-array.c93
-rw-r--r--src/otlayout/ot-array.h50
-rw-r--r--src/otlayout/ot-info.c762
-rw-r--r--src/otlayout/ot-info.h103
-rw-r--r--src/otlayout/ot-ruleset.c312
-rw-r--r--src/otlayout/ot-ruleset.h64
-rw-r--r--src/otlayout/ot-types.h39
-rw-r--r--src/otlayout/ot-unicode.c8359
-rw-r--r--src/otlayout/ot-unicode.h39
-rw-r--r--src/otlayout/ot.c42
-rw-r--r--src/otlayout/otdemo.c211
-rw-r--r--src/otlayout/otdriver.c100
-rw-r--r--src/otlayout/otdriver.h41
-rw-r--r--src/otlayout/oterrors.h45
-rw-r--r--src/otlayout/otlayout.c269
-rw-r--r--src/otlayout/otltypes.h77
-rw-r--r--src/otlayout/otobjs.c189
-rw-r--r--src/otlayout/otobjs.h52
-rw-r--r--src/otlayout/rules.mk98
86 files changed, 46305 insertions, 5 deletions
diff --git a/docs/modules.txt b/docs/modules.txt
index 04f4d120a..0815338db 100644
--- a/docs/modules.txt
+++ b/docs/modules.txt
@@ -12,3 +12,5 @@ Note that the use of `psnames' can be controlled in ftconfig.h
type42 truetype
psaux psnames
sfnt psnames
+ gx truetype
+ ot truetype
diff --git a/ftlayout.txt b/ftlayout.txt
new file mode 100644
index 000000000..d1623fb6a
--- /dev/null
+++ b/ftlayout.txt
@@ -0,0 +1,291 @@
+About FTLayout
+==============
+FTLayout is a layout engine stacked on FreeType2. Currently
+TrueTypeGX/AAT is supported as a file format. OpenType is also
+supported, but highly experimental.
+
+FTLayout provides an generic interface which is shared by a layout
+engine(GXLayout) for TrueTypeGX/AAT and a layout engine(OTLayout)for
+OpenType for glyph substitution, one of the text layout function.
+
+See "The TureType Font File"
+(http://developer.apple.com/fonts/TTRefMan/RM06/Chap6.html)
+about TrueTypeGX/AAT.
+
+About GXLayout
+==============
+GXLayout provides interface for mort, morx, lcar, format 0, 2 3 kern,
+feat TrueTypeGX/AAT tables.
+
+We tested GXLayout against "Non-contextual glyph substitution" and
+"Ligature substitution" in kochigx-substitute-20040218
+fonts. "Non-contextual glyph substitution" in
+kochigx-substitute-20040218 fonts represents "vertical
+substitution". "Ligature substitution" in kochigx-substitute-20040218
+fonts represents "Non-contextual glyph substitution".
+
+We tested GXLayout against "fi" ligature("Ligature substitution") in
+MacOSX's dfonts.
+
+It seems that Pfaedit can generate TrueTypeGX/AAT font. However, we
+have not tested GXLayout against fonts generated by Pfaedit yet.
+
+About OTLayout
+==============
+(Different from GXLayout)OTLayout is not written from scratch; it
+is just applied existing implementation to FTLayout, a newly designed
+interface. The existing implementation stands for:
+
+ The code ported by the author of Pango to FreeType2 for using
+ the code in Pango from TrueTypeOpen code in FreeType1
+ implemented by FreeType developers.
+
+What we have done is to make fit the existing implementation to
+new FTLayout glyph substitution interface. As written above, OTLayout
+in FTLayout is highly experimental. We have tested only punctuation
+substitution in Japanese vertical writing. Currently OpenType/TrueType
+is supported; OpenType/CFF is not supported. Hereafter in this
+document we focus on GXLayout.
+
+Install
+=======
+You have not changed the install procedure. However we recommend to
+give --prefix=/somewhere-different-from-/usr-or-/usr/local to
+configure command if FreeType2 is already installed on your system.
+e.g. --prefix=/opt
+
+We have taken care that we do not change the source/binary interfaces
+of FreeType2. However FTLayout development is based on the FreeType
+code of HEAD in FreeType2's CVS repository(as of Mon Feb 23 14:30:49
+2004). If source/binary interfaces are not compatible between in
+FreeType2 on your system and that of HEAD, installing FreeType2 with
+FTLayout into /usr/lib or /usr/local/lib will be trouble. Take care.
+
+Demo program
+============
+fi and gxdemo are bundled as GXLayout demo programs. To build the demo
+programs, type following command line in src/gxlayout after installing
+FreeType2 with FTLayout:
+
+ $ make -f demo.mk
+
+fi and gxdemo will be built.
+
+ - fi command
+ With rules defined in a font file specified as the first argument
+ for fi, try to substitute "fi" glyph string; and print the result
+ to stdout. The default value defined in feat table is used as font
+ feature settings in substitution. If you want to try different
+ settings, gxdemo is suitable.
+
+ Example:
+
+ $ ./fi /Library/Fonts/Zapfino.dfont
+ -------------------
+ File: /Library/Fonts/Zapfino.dfont
+ Name: Zapfino
+ [IN]f: 536, i: 552
+ [OUT]f: 1089, i: 65535<empty>
+
+ This output stands for
+ - [IN] is input glyph string,
+ - [OUT] substituted glyph string,
+ - ([IN])the glyph id for `f' is 536,
+ - ([IN])the glyph id for `i' is 552, and
+ - ([OUT])as the result of substitution, we get single glyph which
+ is 1089. 536, 552 are ligature into 1089.
+
+ Only FreeType2 with FTLayout and standard C library are used in
+ fi.
+
+ - gxdemo
+ gxdemo is a tool to inspect tables in a TrueTypeGX/AAT font and
+ the behavior of GXLayout with GUI.
+
+ Run gxdemo with a target TrueTypeGX/AAT font file from a terminal.
+ gxdemo's window has multiple tabs.
+
+ In "Features" tab, you can change the feature settings. Pressing
+ "Reset" button and the settings are reset; setting are set to the
+ default values defined in feat table. With "Run" button, you can
+ try to substitute glyphs under the setting given in this "Features"
+ tab. Pressing "Run" button, "Input: " prompt is appeared in the
+ terminal. Give the glyph ids separated by space and type return key
+ at the end of input glyph ids. Then substituted glyph ids are
+ printed on the terminal.
+
+ Example:
+ $ ./gxdemo ~/.fonts/kochigx-mincho-subst.ttf
+ Input: 200 19 20 300
+ Substituted: 200 14571 65535<empty> 300
+
+ In "Glyph" tab, you can render a glyph by giving a glyph id.
+
+ In "Dump" tab, you can dump the TrueTypeGX/AAT tables of the font
+ in pseudo XML format with pressing "Dump Font Tables" button. Also
+ with pressing "Dump Feature Request" button, you can dump the
+ current font feature settings in "Features" tab in a text format.
+
+ Batch dump mode is also available. To dump mort and feat from a
+ terminal, type
+
+ $ ./gxdemo --batch --table=mort:feat font.ttf
+
+ We, FTLayout developers used
+ mlview(http://www.freespiders.org/projects/gmlview/) to browse
+ the XML formated dump datum.
+
+ In "Trace" tab, you can set FreeType2's trace level. To examine
+ the process of glyph substitution, set "gxvm" and "gxchain" to 3.
+
+ Different from fi, gxdemo uses gtk+ GUI toolkit. To build gxdemo,
+ following libraries are needed:
+ - glib-2.0
+ - gtk+-2.0
+ - libgnomecanvas-2.0
+ - popt
+ At least Red Hat Linux 9 includes these libraries.
+
+Using FTLayout and GXLayout
+===========================
+To do glyph substitution in your program, you have to use both
+FTLayout interface(as generic interface) and GXLayout interface(as
+concrete interface). The symbols in FTLayout have "FTL" as prefix.
+The symbols in GXLayout have "GXL" as prefix. Symbols in FTLayout
+are declared in include/freetype/ftlayout.h. Symbols in GXLayout
+are declared in include/freetype/gxlayout.h. To include these header
+files in your source file, you have to obey to the way of FreeType2;
+you have to specify the header files in symbols:
+
+ #include<ft2build.h>
+ ...
+ #include FT_LAYOUT_H
+ #include FT_GXLAYOUT_H
+
+
+The outlines of usage are:
+
+ 1. Create a face
+ This procedure is the same as before.
+ Create a `face' from the target font file after
+ initialize the library itself.
+
+ 2. Check the existence of substitution tables
+ You can check the existence of substitution table
+ in the target font by the logical AND operation between
+ face::face_flags and FT_FACE_FLAG_GLYPH_SUBSTITUTION.
+
+ 3. Check the type of layout engine
+ You can check whether the type of text layout engine
+ is GXLayout or OTLayout by invoking FTL_Query_EngineType.
+ Hereafter, we assume the engine type is GXLayout.
+
+ 4. Create a request
+ A `request' is needed in FTLayout to specify the
+ font feature settings in substitution. You can create more
+ than one requests against one face and specify the font
+ feature settings independently each of them; and activate
+ one of them. Invoke FTL_New_FeaturesRequest with a face to
+ create a requests. Invoke FTL_Done_FeaturesRequest to release a
+ request.
+
+ 5. Set the features and settings to the request
+ Concrete text layout engine(GXLayout)'s interface is used to
+ specify the font feature settings to a request. Following
+ functions are available to specify:
+
+ - GXL_FeaturesRequest_Get_Feature returns a object(feature)
+ which represents Nth feature of a face.
+
+ - GXL_FeaturesRequest_Get_Feature_Count returns the number of
+ features in a face.
+
+ - GXL_Feature_Get_Setting returns a object(setting) which
+ requests Nth setting of a feature.
+
+ - GXL_Feature_Get_Setting_Count returns the number of settings
+ in a feature.
+
+ - GXL_Feature_Get_Name returns the name of given feature.
+
+ - GXL_Setting_Get_State returns the state (enable or disable)
+ of given setting.
+
+ - GXL_Setting_Get_Name returns the name of given setting.
+
+ - GXL_Feature_Is_Setting_Exclusive returns whether given
+ setting is exclusive or not.
+
+ These functions may be useful to construct GUI thorough which
+ application users can specify the font features settings.
+ "Features" tab of gxdemo may be good example to construct
+ GUI.
+
+ The writing direction(vertical or horizontal) have to be
+ specified also in FTLayout level. Use
+
+ FTL_Set_FeaturesRequest_Direction
+
+ to specify. Whether you have to specify the direction in
+ GXLayout level or not depends on the target font file.
+
+ 6. Activate request
+ After setting a request by functions explained in 5.,
+ You have to activate it. Use
+
+ FTL_Activate_FeaturesRequest
+
+ to activate a face. (Only one request is active for
+ a face at the same time.)
+
+ 7. Create input/output glyph array
+ FTL_New_Glyphs_Array is used to create a glyph array.
+ To substitute two glyph arrays are needed to store
+ input glyphs(input) and substituted result(output).
+
+ About the input, you have to set the length and fill the array
+ with glyphs by your self. Use
+
+
+ FTL_Set_Glyphs_Array_Length
+
+ to set the length of glyph array. Use `gid' field of glyph
+ array to fill the input glyphs.
+
+ The length of output are automatically set by FTLayout.
+
+ 8. Substitute
+ Invoke
+
+ FTL_Substitute_Glyphs
+
+ with a face, input and output.
+
+Other than 5. are procedures are done in fi command. Therefore fi.c
+may be good simple example to substitute glyphs.
+
+TODO
+====
+- lazy table loading
+- verification table data during loading not in
+ substitution time
+- more detailing error codes and using them
+
+
+License
+=======
+The licenses of FTLayout and GXLayout are the same as that
+of FreeType2. About OTLayout, see src/otlayout/README.
+
+Acknowledgments
+===============
+This development is supported by Information-technology Promotion
+Agency, Japan(IPA). We would like to appreciate the supports.
+
+Mitsuru Oka advised us about OpenType and Pango. We would like to
+appreciate his advices.
+
+Contact
+=======
+Masatake YAMATO
+<yamato@redhat.com> or <jet@gyve.org>
diff --git a/include/freetype/config/ftheader.h b/include/freetype/config/ftheader.h
index b996a7a6f..b4ccabfe1 100644
--- a/include/freetype/config/ftheader.h
+++ b/include/freetype/config/ftheader.h
@@ -529,6 +529,17 @@
/* */
#define FT_SFNT_NAMES_H <freetype/ftsnames.h>
+ /*************************************************************************/
+ /* */
+ /* @macro: */
+ /* FT_LAYOUT_H */
+ /* */
+ /* @description: */
+ /* A macro used in #include statements to name the file containing */
+ /* FreeType Layout API. */
+ /* */
+#define FT_LAYOUT_H <freetype/ftlayout.h>
+
/* */
#define FT_TRIGONOMETRY_H <freetype/fttrigon.h>
@@ -550,6 +561,9 @@
#define FT_INCREMENTAL_H <freetype/ftincrem.h>
+#define FT_GXLAYOUT_H <freetype/gxlayout.h>
+#define FT_OTLAYOUT_H <freetype/otlayout.h>
+
#define FT_TRUETYPE_UNPATENTED_H <freetype/ttunpat.h>
/* now include internal headers definitions from <freetype/internal/...> */
diff --git a/include/freetype/config/ftmodule.h b/include/freetype/config/ftmodule.h
index d0e6f16a3..005aa7f38 100644
--- a/include/freetype/config/ftmodule.h
+++ b/include/freetype/config/ftmodule.h
@@ -11,6 +11,8 @@ FT_USE_MODULE(sfnt_module_class)
FT_USE_MODULE(ft_smooth_renderer_class)
FT_USE_MODULE(ft_smooth_lcd_renderer_class)
FT_USE_MODULE(ft_smooth_lcdv_renderer_class)
+FT_USE_MODULE(gx_driver_class)
+FT_USE_MODULE(ot_driver_class)
FT_USE_MODULE(tt_driver_class)
FT_USE_MODULE(t1_driver_class)
FT_USE_MODULE(t42_driver_class)
diff --git a/include/freetype/config/ftstdlib.h b/include/freetype/config/ftstdlib.h
index 297d6f017..4131e09f4 100644
--- a/include/freetype/config/ftstdlib.h
+++ b/include/freetype/config/ftstdlib.h
@@ -110,6 +110,7 @@
#include <stdlib.h>
#define ft_qsort qsort
+#define ft_bsearch bsearch
#define ft_exit exit /* only used to exit from unhandled exceptions */
#define ft_atol atol
diff --git a/include/freetype/freetype.h b/include/freetype/freetype.h
index 02195b26b..af6b1b0fa 100644
--- a/include/freetype/freetype.h
+++ b/include/freetype/freetype.h
@@ -1028,6 +1028,13 @@ FT_BEGIN_HEADER
/* provided by the client application and should not be destroyed */
/* when @FT_Done_Face is called. Don't read or test this flag. */
/* */
+ /* FT_FACE_FLAG_GLYPH_SUBSTITUTION :: */
+ /* Indicates that the face contains glyph substitution information. */
+ /* If set, GSUB(otlayout) or mort/morx(gxlayout) is existed in the */
+ /* face. You can use glyph substitution functions declared in */
+ /* ftlayout.h */
+ /* */
+
#define FT_FACE_FLAG_SCALABLE ( 1L << 0 )
#define FT_FACE_FLAG_FIXED_SIZES ( 1L << 1 )
#define FT_FACE_FLAG_FIXED_WIDTH ( 1L << 2 )
@@ -1039,6 +1046,7 @@ FT_BEGIN_HEADER
#define FT_FACE_FLAG_MULTIPLE_MASTERS ( 1L << 8 )
#define FT_FACE_FLAG_GLYPH_NAMES ( 1L << 9 )
#define FT_FACE_FLAG_EXTERNAL_STREAM ( 1L << 10 )
+#define FT_FACE_FLAG_GLYPH_SUBSTITUTION ( 1L << 20 )
/* */
@@ -1188,6 +1196,16 @@ FT_BEGIN_HEADER
#define FT_HAS_MULTIPLE_MASTERS( face ) \
( face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS )
+ /*************************************************************************/
+ /* */
+ /* @macro: */
+ /* FT_HAS_GLYPH_SUBSTITUTION( face ) */
+ /* */
+ /* @description: */
+ /* TODO */
+ /* */
+#define FT_HAS_GLYPH_SUBSTITUTION( face ) \
+ ( face->face_flags & FT_FACE_FLAG_GLYPH_SUBSTITUTION )
/*************************************************************************/
/* */
diff --git a/include/freetype/fterrdef.h b/include/freetype/fterrdef.h
index 2f73c0858..de35ad1cd 100644
--- a/include/freetype/fterrdef.h
+++ b/include/freetype/fterrdef.h
@@ -227,5 +227,13 @@
FT_ERRORDEF_( Missing_Bbx_Field, 0xB6, \
"`BBX' field missing" )
+ /* GX errors */
+ FT_ERRORDEF_( Old_Kerning_Table, 0xC0, \
+ "too old kerning format" )
+ FT_ERRORDEF_( Missing_Glyph_Substitution_Data, 0xC1, \
+ "glyph substitution data is missing" )
+ FT_ERRORDEF_( Busy_Extra_Data, 0xC2, \
+ "TT_Face extra data field is busy" )
+
/* END */
diff --git a/include/freetype/ftlayout.h b/include/freetype/ftlayout.h
new file mode 100644
index 000000000..e7ce1d4df
--- /dev/null
+++ b/include/freetype/ftlayout.h
@@ -0,0 +1,515 @@
+/***************************************************************************/
+/* */
+/* ftltypes.h */
+/* */
+/* FreeType Layout API (specification) */
+/* */
+/* Copyright 2003 by */
+/* Masatake YAMATO and Redhat K.K. */
+/* */
+/* This file may only be used, */
+/* modified, and distributed under the terms of the FreeType project */
+/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
+/* this file you indicate that you have read the license and */
+/* understand and accept it fully. */
+/* */
+/***************************************************************************/
+
+/***************************************************************************/
+/* Development of the code in this file is support of */
+/* Information-technology Promotion Agency, Japan. */
+/***************************************************************************/
+
+#ifndef __FTL_LAYOUT_H_
+#define __FTL_LAYOUT_H_
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+
+FT_BEGIN_HEADER
+
+ /*************************************************************************/
+ /* */
+ /* <Section> */
+ /* text_layout */
+ /* */
+ /* <Title> */
+ /* Text Layout */
+ /* */
+ /* <Abstract> */
+ /* Generic text layout functions. */
+ /* */
+ /* <Description> */
+ /* The following types and functions are used in text layout. */
+ /* FTLayout is a layout engine stacked on FreeType2. Currently */
+ /* TrueTypeGX/AAT is supported as a file format. OpenType is also */
+ /* supported, but highly experimental. */
+ /* FTLayout provides an abstract interface which is shared by a */
+ /* layout engine(GXLayout) for TrueTypeGX/AAT and a layout engine */
+ /* (OTLayout)for OpenType for glyph substitution, one of the text */
+ /* layout function. */
+ /* */
+ /*************************************************************************/
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* FTL_FeaturesRequest */
+ /* */
+ /* <Description> */
+ /* An opaque data type to specify which font features are used in */
+ /* text layout. */
+ /* */
+ /* Use @FTL_New_FeaturesRequest to create from a face and */
+ /* @FTL_Done_FeaturesRequest to discard. The way to specify the font */
+ /* features' settting depenes on the concrete font engine behind the */
+ /* face. */
+ /* */
+ typedef struct FTL_FeaturesRequestRec_ * FTL_FeaturesRequest;
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* FTL_Glyphs_Array */
+ /* */
+ /* <Description> */
+ /* Data type represents glyphs array used in glyph substitution. */
+ /* See @FTL_GlyphRec for more detail. */
+ /* */
+ typedef struct FTL_Glyphs_ArrayRec_ * FTL_Glyphs_Array;
+
+ /*************************************************************************/
+ /* */
+ /* <Enum> */
+ /* FTL_EngineType */
+ /* */
+ /* <Description> */
+ /* An enumeration representing the concrete text layout engine type. */
+ /* You can get the value for a given face, use @FTL_Query_EngineType. */
+ /* */
+ /* <Values> */
+ /* FTL_NO_ENGINE :: */
+ /* No text layout engine behind the face. */
+ /* */
+ /* FTL_OPENTYPE_ENGINE :: */
+ /* OpneType layout engine. You should use the interface declared in */
+ /* otlayout.h. */
+ /* */
+ /* FTL_TRUETYPEGX_ENGINE :: */
+ /* TrueTypeGX/AAT layout engine. You should use the interface */
+ /* declared in gxlayout.h. */
+ /* */
+ typedef enum
+ {
+ FTL_NO_ENGINE = 0,
+ FTL_OPENTYPE_ENGINE = 1, /* Use otlayout.h */
+ FTL_TRUETYPEGX_ENGINE = 2 /* Use gxlayout.h */
+ } FTL_EngineType;
+
+ /*************************************************************************/
+ /* */
+ /* <Enum> */
+ /* FTL_Direction */
+ /* */
+ /* <Description> */
+ /* An enumeration representing the text layout direction. */
+ /* */
+ /* You can set the direction value to a features request by */
+ /* @FTL_Set_FeaturesRequest_Direction. You can get the direction */
+ /* value from a features request by */
+ /* @FTL_Get_FeaturesRequest_Direction. */
+ /* */
+ /* <Values> */
+ /* FTL_HORIZONTAL :: */
+ /* Value representing horizontal writing. */
+ /* */
+ /* FTL_VERTICAL :: */
+ /* Value representing vertical writing. */
+ /* */
+ typedef enum
+ {
+ FTL_HORIZONTAL = 0,
+ FTL_VERTICAL = 1
+ } FTL_Direction;
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* FTL_GlyphRec */
+ /* */
+ /* <Description> */
+ /* Data type represents a glyph id used in glyph substitution. */
+ /* */
+ /* <Fields> */
+ /* gid :: The glyph id. If gid is 0xFFFF, this element in an */
+ /* glyph array should be ignored. */
+ /* */
+ /* ot_prop :: Glyph's property used in OTLayout substitution. */
+ /* GXLayout does not use this field. */
+ /* */
+ typedef struct FTL_GlyphRec_
+ {
+ FT_UShort gid;
+ FT_UShort reserved1;
+ FT_ULong ot_prop;
+ FT_ULong reserved2;
+ } FTL_GlyphRec, * FTL_Glyph;
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* FTL_Glyph_ArrayRec_ */
+ /* */
+ /* <Description> */
+ /* Data type represents glyphs array used in glyph substitution. */
+ /* */
+ /* This data type is used as input and output arguments for */
+ /* @FTL_Substitute_Glyphs. */
+ /* @FTL_New_Glyphs_Array allocates 0 length FTL_GlyphRec object. */
+ /* @FTL_Set_Glyphs_Array_Length sets the length of FTL_GlyphRec */
+ /* object. You have to set the length to create an input glyph array */
+ /* for substitution. */
+ /* */
+ /* <Fields> */
+ /* memory :: The current memory object which handles the glyph */
+ /* arrray. */
+ /* */
+ /* glyphs :: Glyphs ids' array. */
+ /* */
+ /* length :: The valid length of glyphs. */
+ /* */
+ /* allocated :: The allocation size of glyphs. The client should not */
+ /* refer this field. */
+ /* */
+ typedef struct FTL_Glyphs_ArrayRec_
+ {
+ FT_Memory memory;
+ FTL_Glyph glyphs;
+ /* FT_ULong pos; */
+ FT_ULong reserved1;
+ FT_ULong length;
+ FT_ULong allocated;
+ } FTL_Glyphs_ArrayRec;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FTL_Query_EngineType */
+ /* */
+ /* <Description> */
+ /* Returns the text layout engine type behind a face. */
+ /* */
+ /* <Input> */
+ /* face :: The target face. */
+ /* */
+ /* <Output> */
+ /* engine_type :: The type of text layout engine for the face. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ FT_EXPORT( FT_Error )
+ FTL_Query_EngineType ( FT_Face face,
+ FTL_EngineType * engine_type);
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FTL_New_FeaturesRequest */
+ /* */
+ /* <Description> */
+ /* Creates a new features request for a face. */
+ /* */
+ /* <Input> */
+ /* face :: The target face. */
+ /* */
+ /* <Output> */
+ /* request :: A features request for a face. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* When the target face is discarded by @FT_Done_Face, all features */
+ /* requests corresponding to the face are also discardeded */
+ /* automatically. */
+ /* */
+ FT_EXPORT( FT_Error )
+ FTL_New_FeaturesRequest ( FT_Face face,
+ FTL_FeaturesRequest* request);
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FTL_Done_FeaturesRequest */
+ /* */
+ /* <Description> */
+ /* Discards a features request. */
+ /* */
+ /* <Input> */
+ /* request :: A features request. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ FT_EXPORT( FT_Error )
+ FTL_Done_FeaturesRequest ( FTL_FeaturesRequest request );
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FTL_Activate_FeaturesRequest */
+ /* */
+ /* <Description> */
+ /* Even though it is possible to create serveral features request */
+ /* object for a given face (see @FTL_New_FeaturesRequest), */
+ /* @FTL_Substitute_Glyphs only use the last activated request. */
+ /* With this function, a features request can be activated. */
+ /* */
+ /* <Input> */
+ /* request :: A features request to be activated. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ FT_EXPORT ( FT_Error )
+ FTL_Activate_FeaturesRequest ( FTL_FeaturesRequest request );
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FTL_Copy_FeaturesRequest */
+ /* */
+ /* <Description> */
+ /* Copy the setting of one features request to another. */
+ /* */
+ /* <Input> */
+ /* from :: The source features request. */
+ /* */
+ /* <Output> */
+ /* to :: The destination features request. This must be created by */
+ /* @FTL_New_FeaturesRequest before copying. */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* from and to must be created from the same face. */
+ /* */
+ FT_EXPORT( FT_Error )
+ FTL_Copy_FeaturesRequest ( FTL_FeaturesRequest from,
+ FTL_FeaturesRequest to );
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FTL_Reset_FeaturesRequest */
+ /* */
+ /* <Description> */
+ /* Resets the settings of a features request. In other word set a */
+ /* features request to default settings. */
+ /* */
+ /* <Input> */
+ /* request :: A features request to be reseted. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ FT_EXPORT( FT_Error )
+ FTL_Reset_FeaturesRequest ( FTL_FeaturesRequest request );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FTL_Get_FeaturesRequest_Direction */
+ /* */
+ /* <Description> */
+ /* Returns the writing direction in a features request. */
+ /* */
+ /* <Input> */
+ /* request :: A features request. */
+ /* */
+ /* <Return> */
+ /* The writing direction. */
+ /* */
+ FT_EXPORT ( FTL_Direction )
+ FTL_Get_FeaturesRequest_Direction ( FTL_FeaturesRequest request );
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FTL_Set_FeaturesRequest_Direction */
+ /* */
+ /* <Description> */
+ /* Sets the writing direction to a features request. */
+ /* */
+ /* <Input> */
+ /* request :: A features request. */
+ /* */
+ /* direction :: Writing direction. */
+ /* */
+ FT_EXPORT ( void )
+ FTL_Set_FeaturesRequest_Direction ( FTL_FeaturesRequest request,
+ FTL_Direction direction);
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FTL_New_Glyphs_Array */
+ /* */
+ /* <Description> */
+ /* Creates an empty glyphs array. */
+ /* */
+ /* <Input> */
+ /* momory :: A memory object from which a glyphs array is allocated. */
+ /* */
+ /* <Output> */
+ /* garray :: A glyphs array. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* The lengoth of newly allocated glyphs array is 0. Set the length */
+ /* by @FTL_Set_Glyphs_Array_Length after allocating if you need. */
+ /* */
+ FT_EXPORT( FT_Error )
+ FTL_New_Glyphs_Array ( FT_Memory memory,
+ FTL_Glyphs_Array * garray );
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FTL_Set_Glyphs_Array_Length */
+ /* */
+ /* <Description> */
+ /* Sets the length of a glyphs array. */
+ /* */
+ /* <Input> */
+ /* length :: New glyphs array length. */
+ /* */
+ /* <InOut> */
+ /* garray :: A glyphs array. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ FT_EXPORT( FT_Error )
+ FTL_Set_Glyphs_Array_Length ( FTL_Glyphs_Array garray,
+ FT_ULong new_length );
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FTL_Copy_Glyphs_Array */
+ /* */
+ /* <Description> */
+ /* Copies glyphs array. */
+ /* */
+ /* <Input> */
+ /* in :: The source glyphs array. */
+ /* */
+ /* <Output> */
+ /* out :: The destination glyphs array. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ FT_EXPORT( FT_Error )
+ FTL_Copy_Glyphs_Array ( FTL_Glyphs_Array in,
+ FTL_Glyphs_Array out );
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FTL_Done_Glyphs_Array */
+ /* */
+ /* <Description> */
+ /* Discards a glyphs array. */
+ /* */
+ /* <Input> */
+ /* garray :: A glyphs array. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ FT_EXPORT( FT_Error )
+ FTL_Done_Glyphs_Array ( FTL_Glyphs_Array garray );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FTL_Substitute_Glyphs */
+ /* */
+ /* <Description> */
+ /* Substitutes glyphs based on the rule specified by the current */
+ /* activated features request. */
+ /* */
+ /* <Input> */
+ /* face :: A face which has substitution tables. */
+ /* */
+ /* in :: Input glyphs array. */
+ /* */
+ /* <Output> */
+ /* out :: Output(substituted) glyphs array. The length of glyphs */
+ /* are automatically extended. */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ FT_EXPORT( FT_Error )
+ FTL_Substitute_Glyphs ( FT_Face face,
+ FTL_Glyphs_Array in,
+ FTL_Glyphs_Array out );
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FTL_Get_LigatureCaret_Count */
+ /* */
+ /* <Description> */
+ /* Returns the number of ligature divisions for a given glyph. */
+ /* */
+ /* <Input> */
+ /* face :: A face. */
+ /* */
+ /* glyphID :: The target glyph's id. */
+ /* */
+ /* <Return> */
+ /* The number of ligature divisions. If the glyph is not ligatured */
+ /* glyph, returns 0. */
+ /* */
+ FT_EXPORT( FT_UShort )
+ FTL_Get_LigatureCaret_Count ( FT_Face face, FT_UShort glyphID );
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FTL_Get_LigatureCaret_Division */
+ /* */
+ /* <Description> */
+ /* Returns the point of Nth ligature divisions for a given glyph. */
+ /* */
+ /* <Input> */
+ /* face :: A face. */
+ /* */
+ /* glyphID :: The target glyph's id. */
+ /* */
+ /* nth :: The index of ligature divisions. */
+ /* */
+ /* <Return> */
+ /* The point of a ligature division. If the glyph is not ligatured */
+ /* glyph, returns 0. */
+ /* */
+ FT_EXPORT( FT_UShort )
+ FTL_Get_LigatureCaret_Division ( FT_Face face,
+ FT_UShort glyphID,
+ FT_UShort nth );
+
+FT_END_HEADER
+
+#endif /* Not def: __FTL_LAYOUT_H_ */
+
+
+/* END */
diff --git a/include/freetype/ftmoderr.h b/include/freetype/ftmoderr.h
index d190167fa..70ec0f9fa 100644
--- a/include/freetype/ftmoderr.h
+++ b/include/freetype/ftmoderr.h
@@ -122,6 +122,8 @@
FT_MODERRDEF( Type1, 0x1100, "Type 1 module" )
FT_MODERRDEF( Type42, 0x1200, "Type 42 module" )
FT_MODERRDEF( Winfonts, 0x1300, "Windows FON/FNT module" )
+ FT_MODERRDEF( GX, 0x1400, "AAT/TrueTypeGX module" )
+ FT_MODERRDEF( OT, 0x1500, "OpenType module" )
#ifdef FT_MODERR_END_LIST
diff --git a/include/freetype/gxlayout.h b/include/freetype/gxlayout.h
new file mode 100644
index 000000000..eb0f344b3
--- /dev/null
+++ b/include/freetype/gxlayout.h
@@ -0,0 +1,363 @@
+/***************************************************************************/
+/* */
+/* gxlayout.h */
+/* */
+/* AAT/TrueTypeGX based layout engine(specification). */
+/* */
+/* Copyright 2003 by */
+/* Masatake YAMATO and Redhat K.K. */
+/* */
+/* This file may only be used, */
+/* modified, and distributed under the terms of the FreeType project */
+/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
+/* this file you indicate that you have read the license and */
+/* understand and accept it fully. */
+/* */
+/***************************************************************************/
+
+/***************************************************************************/
+/* Development of the code in this file is support of */
+/* Information-technology Promotion Agency, Japan. */
+/***************************************************************************/
+
+#ifndef __GXLAYOUT_H__
+#define __GXLAYOUT_H__
+
+
+#include <ft2build.h>
+#include FT_SFNT_NAMES_H
+
+FT_BEGIN_HEADER
+
+ /*************************************************************************/
+ /* */
+ /* <Section> */
+ /* gx_text_layout */
+ /* */
+ /* <Title> */
+ /* GX Text Layout */
+ /* */
+ /* <Abstract> */
+ /* TrueTypeGX/AAT text layout types and functions. */
+ /* */
+ /* <Description> */
+ /* The following types and functions(interface) are used in text */
+ /* layout with TrueTypeGX/AAT font. You have to use combination with */
+ /* this GXLayout interface and generic FTLayout interface. */
+ /* You have to use GXLayout interface to get the font features */
+ /* defined in `feat' table; and specify settings to the features */
+ /* request created by @FTL_New_FeaturesRequest. */
+ /* */
+ /*************************************************************************/
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* GXL_FeaturesRequest */
+ /* */
+ /* <Description> */
+ /* GXLayout level representation of FTL_FeaturesRequest. */
+ /* */
+ /* GXLayout functions dealing in features requests requires */
+ /* arguments typed to GXL_FeaturesRequest instead of */
+ /* FTL_FeaturesRequest. */
+ /* */
+ typedef struct GXL_FeaturesRequestRec_ *GXL_FeaturesRequest;
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* GXL_Feature */
+ /* */
+ /* <Description> */
+ /* An opaque data type representing a feature of TrueTypeGX/AAT font. */
+ /* */
+ /* @GXL_FeaturesRequest_Get_Feature_Count returns the number of */
+ /* in a font. @GXL_FeaturesRequest_Get_Feature returns Nth feature */
+ /* object in a font. */
+ /* */
+ typedef struct GXL_FeatureRec_ *GXL_Feature;
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* GXL_Setting */
+ /* */
+ /* <Description> */
+ /* An opaque data type representing a setting of a feature. */
+ /* */
+ /* @GXL_Feature_Get_Setting_Count returns the number of settings in a */
+ /* feature. @GXL_Feature_Get_Setting returns Nth setting in a */
+ /* feature. */
+ /* */
+ typedef struct GXL_SettingRec_ *GXL_Setting;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Enum> */
+ /* GXL_Initial_State */
+ /* */
+ /* <Description> */
+ /* An enumeration for the initial state of GX glyph substitution */
+ /* automaton. */
+ /* */
+ /* You can set/get these value to/from a features request by */
+ /* @GXL_FeaturesRequest_Set_Initial_State and */
+ /* @GXL_FeaturesRequest_Set_Initial_State. */
+ /* */
+ /* <Values> */
+ /* GXL_START_OF_TEXT_STATE :: */
+ /* State of text start. */
+ /* */
+ /* GXL_START_OF_LINE_STATE :: */
+ /* State of line start. */
+ /* */
+ typedef enum
+ {
+ GXL_START_OF_TEXT_STATE = 0,
+ GXL_START_OF_LINE_STATE = 1
+ } GXL_Initial_State;
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* GXL_FeaturesRequest_Set_Initial_State */
+ /* */
+ /* <Description> */
+ /* Sets a initial state for glyph the initial state of GX glyph */
+ /* substitution automaton to a features request. */
+ /* */
+ /* <Input> */
+ /* request :: a Target features request. */
+ /* */
+ /* initial_state :: The initial state. */
+ /* */
+ FT_EXPORT ( void )
+ GXL_FeaturesRequest_Set_Initial_State ( GXL_FeaturesRequest request,
+ GXL_Initial_State initial_state );
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* GXL_FeaturesRequest_Get_Initial_State */
+ /* */
+ /* <Description> */
+ /* Returns a initial state for glyph the initial state of GX glyph */
+ /* substitution automaton in a features request. */
+ /* */
+ /* <Input> */
+ /* request :: A target features request. */
+ /* */
+ /* <Return> */
+ /* An initial state value typed to @GXL_Initial_State. */
+ /* */
+ FT_EXPORT ( GXL_Initial_State )
+ GXL_FeaturesRequest_Get_Initial_State ( GXL_FeaturesRequest request );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* GXL_FeaturesRequest_Get_Feature_Count */
+ /* */
+ /* <Description> */
+ /* Returns the number of features in a features request. */
+ /* */
+ /* <Input> */
+ /* request :: A target features request. */
+ /* */
+ /* <Return> */
+ /* The number of features. */
+ /* */
+ FT_EXPORT ( FT_ULong )
+ GXL_FeaturesRequest_Get_Feature_Count ( GXL_FeaturesRequest request );
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* GXL_FeaturesRequest_Get_Feature */
+ /* */
+ /* <Description> */
+ /* Returns Nth font feature object from a features request. */
+ /* */
+ /* <Input> */
+ /* request :: A target features request. */
+ /* */
+ /* index :: The index of feature. */
+ /* */
+ /* <Return> */
+ /* A feature object. */
+ /* */
+ /* <Note> */
+ /* Use @GXL_FeaturesRequest_Get_Feature_Count to get the number of */
+ /* available features. */
+ /* */
+ FT_EXPORT ( GXL_Feature )
+ GXL_FeaturesRequest_Get_Feature ( GXL_FeaturesRequest request,
+ FT_ULong index);
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* GXL_Feature_Get_Name */
+ /* */
+ /* <Description> */
+ /* Gets the name for a feature. */
+ /* */
+ /* <Input> */
+ /* feature :: A target feature. */
+ /* */
+ /* platform_id :: Platform ID for the name. 0 is wild-card. */
+ /* */
+ /* encoding_id :: Encoding ID for the name. 0 is wild-card. */
+ /* */
+ /* language_id :: Language ID for the name. 0 is wild-card. */
+ /* */
+ /* <Output> */
+ /* aname :: The name of a setting. The memory area must be */
+ /* allocated by the client. The pointer to a object */
+ /* on a stack is ok. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ FT_EXPORT( FT_Error )
+ GXL_Feature_Get_Name ( GXL_Feature feature ,
+ FT_UShort platform_id,
+ FT_UShort pencoding_id,
+ FT_UShort language_id,
+ FT_SfntName *aname );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* GXL_Feature_Get_Setting_Count */
+ /* */
+ /* <Description> */
+ /* Returns the number of settings in a feature */
+ /* */
+ /* <Input> */
+ /* request :: A target feature. */
+ /* */
+ /* <Return> */
+ /* The number of settings. */
+ /* */
+ FT_EXPORT( FT_UShort )
+ GXL_Feature_Get_Setting_Count ( GXL_Feature feature );
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* GXL_Feature_Get_Setting */
+ /* */
+ /* <Description> */
+ /* Returns Nth setting object from a feature. */
+ /* */
+ /* <Input> */
+ /* feature :: A target feature. */
+ /* */
+ /* index :: The index of setting. */
+ /* */
+ /* <Return> */
+ /* A setting object. */
+ /* */
+ /* <Note> */
+ /* Use @GXL_Feature_Get_Setting_Count to get the number of available */
+ /* settings. */
+ /* */
+ FT_EXPORT( GXL_Setting )
+ GXL_Feature_Get_Setting ( GXL_Feature feature,
+ FT_ULong index );
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* GXL_Feature_Is_Setting_Exclusive */
+ /* */
+ /* <Description> */
+ /* Returns whether a feature's setting is exclusive or not. */
+ /* */
+ /* <Input> */
+ /* feature :: A target feature. */
+ /* */
+ /* <Return> */
+ /* True if a feature's setting is exclusive. False if not. */
+ /* */
+ FT_EXPORT( FT_Bool )
+ GXL_Feature_Is_Setting_Exclusive ( GXL_Feature feature );
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* GXL_Setting_Get_Name */
+ /* */
+ /* <Description> */
+ /* Gets the name for a setting. */
+ /* */
+ /* <Input> */
+ /* setting :: A target setting. */
+ /* */
+ /* platform_id :: Platform ID for the name. 0 is wild-card. */
+ /* */
+ /* encoding_id :: Encoding ID for the name. 0 is wild-card. */
+ /* */
+ /* language_id :: Language ID for the name. 0 is wild-card. */
+ /* */
+ /* <Output> */
+ /* aname :: The name of a setting. The memory area must be */
+ /* allocated by the client. The pointer to a object */
+ /* on a stack is ok. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ FT_EXPORT( FT_Error )
+ GXL_Setting_Get_Name ( GXL_Setting setting,
+ FT_UShort platform_id,
+ FT_UShort encoding_id,
+ FT_UShort language_id,
+ FT_SfntName *aname );
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* GXL_Setting_Get_State */
+ /* */
+ /* <Description> */
+ /* Returns whether a setting is enabled or disabled. */
+ /* */
+ /* <Input> */
+ /* setting :: A target setting. */
+ /* */
+ /* <Return> */
+ /* True if a setting is enabled. False if disabled. */
+ /* */
+ FT_EXPORT( FT_Bool )
+ GXL_Setting_Get_State ( GXL_Setting setting );
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* GXL_Setting_Set_State */
+ /* */
+ /* <Description> */
+ /* Make a setting enable or disable. */
+ /* */
+ /* <Input> */
+ /* setting :: A target setting. */
+ /* */
+ /* state :: A state to set. If this is true, the setting is */
+ /* enabled. If this is false, the setting is disabled. */
+ /* */
+ FT_EXPORT( void )
+ GXL_Setting_Set_State ( GXL_Setting setting,
+ FT_Bool state );
+
+FT_END_HEADER
+
+#endif /* Not def: __GXLAYOUT_H__ */
+
+
+
diff --git a/include/freetype/internal/ftltypes.h b/include/freetype/internal/ftltypes.h
new file mode 100644
index 000000000..faebac08a
--- /dev/null
+++ b/include/freetype/internal/ftltypes.h
@@ -0,0 +1,85 @@
+/***************************************************************************/
+/* */
+/* ftltypes.h */
+/* */
+/* Types used in the layout engine stacked on ft2 (specification) */
+/* */
+/* Copyright 2003 by */
+/* Masatake YAMATO and Redhat K.K. */
+/* */
+/* This file may only be used, */
+/* modified, and distributed under the terms of the FreeType project */
+/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
+/* this file you indicate that you have read the license and */
+/* understand and accept it fully. */
+/* */
+/***************************************************************************/
+
+/***************************************************************************/
+/* Development of the code in this file is support of */
+/* Information-technology Promotion Agency, Japan. */
+/***************************************************************************/
+
+#ifndef __FTL_TYPES_H__
+#define __FTL_TYPES_H__
+
+#include <ft2build.h>
+#include FT_LAYOUT_H
+
+FT_BEGIN_HEADER
+
+#define FTL_FONT( x ) ((FTL_Font)(x))
+#define FTL_FONT_FACE( x ) (FTL_FONT( x )->face)
+#define FTL_FEATURES_REQUEST( x ) ((FTL_FeaturesRequest)( x ))
+#define FTL_FEATURES_REQUEST_FONT( x )(FTL_FEATURES_REQUEST( x )->font)
+
+ typedef struct FTL_FontRec_ * FTL_Font;
+ typedef struct FTL_FeaturesRequestRec_
+ {
+ FTL_Font font;
+ FTL_Direction direction;
+ } FTL_FeaturesRequestRec;
+
+ typedef struct FTL_FontRec_
+ {
+ FT_Face face;
+
+ /* This one is used as active features request. */
+ FTL_FeaturesRequest features_request;
+ FT_ListRec features_requests_list;
+ } FTL_FontRec;
+
+ FT_EXPORT( FT_Error )
+ FTL_Font_Init ( FTL_Font font,
+ FT_Face face );
+ FT_EXPORT( FT_Error )
+ FTL_Font_Finalize ( FTL_Font font );
+
+ FT_EXPORT( FT_Error )
+ FTL_FeaturesRequest_Init ( FT_Face face,
+ FTL_FeaturesRequest request);
+ FT_EXPORT( FT_Error )
+ FTL_FeaturesRequest_Finalize ( FTL_FeaturesRequest request );
+
+ FT_EXPORT_DEF( FT_Error )
+ FTL_FeaturesRequest_Copy ( FTL_FeaturesRequest from,
+ FTL_FeaturesRequest to );
+
+ FT_EXPORT( FT_Error )
+ FTL_Font_Get_Default_FeaturesRequest ( FTL_Font font,
+ FTL_FeaturesRequest * request );
+
+ FT_EXPORT( FT_Error )
+ FTL_Font_Get_Current_FeaturesRequest ( FTL_Font font,
+ FTL_FeaturesRequest * request );
+
+ FT_EXPORT( FT_Error )
+ FTL_Get_Font ( FT_Face face,
+ FTL_Font * font );
+
+FT_END_HEADER
+
+#endif /* Not def: __FTL_TYPES_H__ */
+
+
+/* END */
diff --git a/include/freetype/internal/ftserv.h b/include/freetype/internal/ftserv.h
index e5ed8895b..d93e33da3 100644
--- a/include/freetype/internal/ftserv.h
+++ b/include/freetype/internal/ftserv.h
@@ -167,7 +167,7 @@ FT_BEGIN_HEADER
FT_Pointer service_GLYPH_DICT;
FT_Pointer service_PFR_METRICS;
FT_Pointer service_WINFNT;
-
+ FT_Pointer service_LAYOUT;
} FT_ServiceCacheRec, *FT_ServiceCache;
@@ -248,6 +248,7 @@ FT_BEGIN_HEADER
#define FT_SERVICE_SFNT_H <freetype/internal/services/svsfnt.h>
#define FT_SERVICE_PFR_H <freetype/internal/services/svpfr.h>
#define FT_SERVICE_WINFNT_H <freetype/internal/services/svwinfnt.h>
+#define FT_SERVICE_LAYOUT_H <freetype/internal/services/svlayout.h>
#define FT_SERVICE_TT_CMAP_H <freetype/internal/services/svttcmap.h>
/* */
diff --git a/include/freetype/internal/fttrace.h b/include/freetype/internal/fttrace.h
index dffe9cfee..c3fb2b77c 100644
--- a/include/freetype/internal/fttrace.h
+++ b/include/freetype/internal/fttrace.h
@@ -103,5 +103,16 @@ FT_TRACE_DEF( bdflib )
/* PFR fonts component */
FT_TRACE_DEF( pfr )
+/* GX driver component */
+FT_TRACE_DEF( gxdriver )
+FT_TRACE_DEF( gxobjs )
+FT_TRACE_DEF( gxlayout )
+FT_TRACE_DEF( gxload )
+FT_TRACE_DEF( gxchain )
+FT_TRACE_DEF( gxvm )
+
+/* OT driver component */
+FT_TRACE_DEF( otdriver )
+FT_TRACE_DEF( otobjs )
/* END */
diff --git a/include/freetype/internal/internal.h b/include/freetype/internal/internal.h
index 1e5ac44d5..9e4d25a69 100644
--- a/include/freetype/internal/internal.h
+++ b/include/freetype/internal/internal.h
@@ -45,5 +45,7 @@
#define FT_INTERNAL_AUTOHINT_H <freetype/internal/autohint.h>
+#define FT_INTERNAL_FTL_TYPES_H <freetype/internal/ftltypes.h>
+
/* END */
diff --git a/include/freetype/internal/services/svlayout.h b/include/freetype/internal/services/svlayout.h
new file mode 100644
index 000000000..060e708fc
--- /dev/null
+++ b/include/freetype/internal/services/svlayout.h
@@ -0,0 +1,84 @@
+/***************************************************************************/
+/* */
+/* svlayout.h */
+/* */
+/* The FreeType Layout services (specification). */
+/* */
+/* Copyright 2003 by */
+/* Masatake YAMATO and Redhat K.K. */
+/* */
+/* This file may only be used, */
+/* modified, and distributed under the terms of the FreeType project */
+/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
+/* this file you indicate that you have read the license and */
+/* understand and accept it fully. */
+/* */
+/***************************************************************************/
+
+/***************************************************************************/
+/* Development of the code in this file is support of */
+/* Information-technology Promotion Agency, Japan. */
+/***************************************************************************/
+
+#ifndef __SVLAYOUT_H__
+#define __SVLAYOUT_H__
+
+#include FT_INTERNAL_SERVICE_H
+#include FT_LAYOUT_H
+#include FT_INTERNAL_FTL_TYPES_H
+
+FT_BEGIN_HEADER
+
+#define FT_SERVICE_ID_LAYOUT "layout"
+
+ typedef FT_Error
+ (*FTL_Get_Font_Func)( FT_Face face,
+ FTL_Font* font );
+
+ typedef FTL_EngineType
+ (*FTL_Get_EngineType_Func) ( FT_Face face );
+
+ typedef FT_Error
+ (*FTL_New_FeaturesRequest_Func)( FT_Face face,
+ FTL_FeaturesRequest* request );
+ typedef FT_Error
+ (*FTL_Done_FeaturesRequest_Func)( FTL_FeaturesRequest request );
+
+ typedef FT_Error
+ (*FTL_Copy_FeaturesRequest_Func)( FTL_FeaturesRequest from,
+ FTL_FeaturesRequest to );
+
+ typedef FT_UShort
+ (*FTL_Get_LigatureCaret_Count_Func) ( FT_Face face, FT_UShort glyphID );
+
+ typedef FT_UShort
+ (*FTL_Get_LigatureCaret_Division_Func) ( FT_Face face,
+ FT_UShort glyphID,
+ FT_UShort nth );
+ typedef FT_Error
+ (*FTL_Substitute_Glyphs_Func) ( FT_Face face,
+ FTL_FeaturesRequest request,
+ FTL_Glyphs_Array in,
+ FTL_Glyphs_Array out );
+
+ FT_DEFINE_SERVICE( Layout )
+ {
+ FTL_Get_Font_Func get_font;
+ FTL_Get_EngineType_Func get_engine_type;
+ FTL_New_FeaturesRequest_Func new_features_request;
+ FTL_Done_FeaturesRequest_Func done_features_request;
+ FTL_Copy_FeaturesRequest_Func copy_features_request;
+ FTL_Get_LigatureCaret_Count_Func get_ligature_caret_count;
+ FTL_Get_LigatureCaret_Division_Func get_ligature_caret_division;
+ FTL_Substitute_Glyphs_Func substitute_glyphs;
+ };
+
+ /* */
+
+
+FT_END_HEADER
+
+#endif /* __SVLAYOUT_H__ */
+
+
+/* END */
diff --git a/include/freetype/internal/services/svttcmap.h b/include/freetype/internal/services/svttcmap.h
index f92fcd0e2..2304ef434 100644
--- a/include/freetype/internal/services/svttcmap.h
+++ b/include/freetype/internal/services/svttcmap.h
@@ -18,8 +18,10 @@
/* */
/***************************************************************************/
-/* Development of this service is support of
- Information-technology Promotion Agency, Japan. */
+/***************************************************************************/
+/* Development of the code in this file is support of */
+/* Information-technology Promotion Agency, Japan. */
+/***************************************************************************/
#ifndef __SVTTCMAP_H__
#define __SVTTCMAP_H__
diff --git a/include/freetype/otlayout.h b/include/freetype/otlayout.h
new file mode 100644
index 000000000..5f2873afc
--- /dev/null
+++ b/include/freetype/otlayout.h
@@ -0,0 +1,79 @@
+/***************************************************************************/
+/* */
+/* otlayout.h */
+/* */
+/* OpenType based layout engine */
+/* (For application developers, specification only). */
+/* */
+/***************************************************************************/
+
+
+#ifndef __OTLAYOUT_H__
+#define __OTLAYOUT_H__
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+FT_BEGIN_HEADER
+
+ typedef FT_ULong OTTag;
+ typedef enum {
+ OT_TABLE_GSUB,
+ OT_TABLE_GPOS
+ } OTTableType;
+
+ typedef struct OTL_FeaturesRequestRec_ *OTL_FeaturesRequest;
+ typedef struct OTL_Tag_ListRec_
+ {
+ OTL_FeaturesRequest request;
+ OTTag * tags; /* 0 is terminator. */
+ } OTL_Tag_ListRec, *OTL_Tag_List;
+
+ FT_EXPORT( FT_Bool )
+ OTL_FeaturesRequest_Find_Script ( OTL_FeaturesRequest request,
+ OTTableType table_type,
+ OTTag script_tag,
+ FT_UInt *script_index);
+
+ FT_EXPORT( FT_Bool )
+ OTL_FeaturesRequest_Find_Language ( OTL_FeaturesRequest request,
+ OTTableType table_type,
+ FT_UInt script_index,
+ OTTag language_tag,
+ FT_UInt *language_index,
+ FT_UInt *required_feature_index );
+
+ FT_EXPORT ( FT_Bool )
+ OTL_FeaturesRequest_Find_Feature ( OTL_FeaturesRequest request,
+ OTTableType table_type,
+ OTTag feature_tag,
+ FT_UInt script_index,
+ FT_UInt language_index,
+ FT_UInt *feature_index );
+
+ FT_EXPORT ( OTL_Tag_List )
+ OTL_FeaturesRequest_List_Scripts ( OTL_FeaturesRequest request,
+ OTTableType table_type );
+
+ FT_EXPORT ( OTL_Tag_List )
+ OTL_FeaturesRequest_List_Languages ( OTL_FeaturesRequest request,
+ OTTableType table_type,
+ FT_UInt script_index );
+
+ FT_EXPORT ( OTL_Tag_List )
+ OTL_FeaturesRequest_List_Features ( OTL_FeaturesRequest request,
+ OTTableType table_type,
+ FT_UInt script_index,
+ FT_UInt language_index );
+
+ FT_EXPORT ( FT_Error )
+ OTL_Tag_List_Done ( OTL_Tag_List taglist );
+
+ FT_EXPORT ( FT_Error )
+ OTL_FeaturesRequest_Add_Feature ( OTL_FeaturesRequest request,
+ OTTableType table_type,
+ FT_UInt feature_index,
+ FT_ULong property_bit);
+
+FT_END_HEADER
+
+#endif /* Not def: __OTLAYOUT_H__ */
diff --git a/include/freetype/tttags.h b/include/freetype/tttags.h
index ac64758b1..445e0b8e3 100644
--- a/include/freetype/tttags.h
+++ b/include/freetype/tttags.h
@@ -71,6 +71,27 @@ FT_BEGIN_HEADER
#define TTAG_vhea FT_MAKE_TAG( 'v', 'h', 'e', 'a' )
#define TTAG_vmtx FT_MAKE_TAG( 'v', 'm', 't', 'x' )
+#define TTAG_trak FT_MAKE_TAG( 't', 'r', 'a', 'k' )
+#define TTAG_feat FT_MAKE_TAG( 'f', 'e', 'a', 't' )
+#define TTAG_prop FT_MAKE_TAG( 'p', 'r', 'o', 'p' )
+#define TTAG_lcar FT_MAKE_TAG( 'l', 'c', 'a', 'r' )
+#define TTAG_opbd FT_MAKE_TAG( 'o', 'p', 'b', 'd' )
+#define TTAG_bsln FT_MAKE_TAG( 'b', 's', 'l', 'n' )
+#define TTAG_mort FT_MAKE_TAG( 'm', 'o', 'r', 't' )
+#define TTAG_morx FT_MAKE_TAG( 'm', 'o', 'r', 'x' )
+#define TTAG_fmtx FT_MAKE_TAG( 'f', 'm', 't', 'x' )
+
+#define TTAG_fdsc FT_MAKE_TAG( 'f', 'd', 's', 'c' )
+#define TTAG_wght FT_MAKE_TAG( 'w', 'g', 'h', 't' )
+#define TTAG_wdth FT_MAKE_TAG( 'w', 'd', 't', 'h' )
+#define TTAG_slnt FT_MAKE_TAG( 's', 'l', 'n', 't' )
+#define TTAG_opsz FT_MAKE_TAG( 'o', 'p', 's', 'z' )
+#define TTAG_nalf FT_MAKE_TAG( 'n', 'a', 'l', 'f' )
+
+#define TTAG_just FT_MAKE_TAG( 'j', 'u', 's', 't' )
+#define TTAG_cvar FT_MAKE_TAG( 'c', 'v', 'a', 'r' )
+#define TTAG_gvar FT_MAKE_TAG( 'g', 'v', 'a', 'r' )
+
FT_END_HEADER
diff --git a/src/base/Jamfile b/src/base/Jamfile
index d82e65d6d..f3b02ba07 100644
--- a/src/base/Jamfile
+++ b/src/base/Jamfile
@@ -24,7 +24,7 @@ SubDir FT2_TOP $(FT2_SRC_DIR) base ;
#
Library $(FT2_LIB) : ftsystem.c ftinit.c ftglyph.c ftmm.c ftbdf.c
ftbbox.c ftdebug.c ftxf86.c fttype1.c ftpfr.c
- ftstroke.c ftwinfnt.c ;
+ ftstroke.c ftwinfnt.c ftlayout.c ;
# Add Macintosh-specific file to the library when necessary.
#
diff --git a/src/base/ftlayout.c b/src/base/ftlayout.c
new file mode 100644
index 000000000..a7fa5f89d
--- /dev/null
+++ b/src/base/ftlayout.c
@@ -0,0 +1,496 @@
+/***************************************************************************/
+/* */
+/* ftltypes.h */
+/* */
+/* Implementation of FreeType Layout API (body) */
+/* */
+/* Copyright 2003 by */
+/* Masatake YAMATO and Redhat K.K. */
+/* */
+/* This file may only be used, */
+/* modified, and distributed under the terms of the FreeType project */
+/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
+/* this file you indicate that you have read the license and */
+/* understand and accept it fully. */
+/* */
+/***************************************************************************/
+
+/***************************************************************************/
+/* Development of the code in this file is support of */
+/* Information-technology Promotion Agency, Japan. */
+/***************************************************************************/
+
+
+#include <ft2build.h>
+#include FT_LAYOUT_H
+#include FT_INTERNAL_FTL_TYPES_H
+#include FT_INTERNAL_DEBUG_H
+#include FT_INTERNAL_OBJECTS_H
+#include FT_SERVICE_LAYOUT_H
+#include FT_LIST_H
+
+ static void
+ destroy_feaatures_requests ( FT_Memory memory,
+ void * data,
+ void * user );
+
+ static FT_Error
+ ft_face_get_layout_service( FT_Face face,
+ FT_Service_Layout *aservice )
+ {
+ FT_Error error;
+
+ *aservice = NULL;
+
+ if ( !face )
+ return FT_Err_Invalid_Face_Handle;
+
+ error = FT_Err_Invalid_Argument;
+
+
+ FT_FACE_LOOKUP_SERVICE( face,
+ *aservice,
+ LAYOUT );
+
+ if ( *aservice )
+ error = FT_Err_Ok;
+
+ return error;
+ }
+
+ FT_EXPORT_DEF( FT_Error )
+ FTL_Get_Font ( FT_Face face,
+ FTL_Font * font )
+ {
+ FT_Error error;
+ FT_Service_Layout service;
+
+ if (( error = ft_face_get_layout_service( face, &service ) ))
+ return error;
+
+ error = FT_Err_Invalid_Argument;
+ if ( service->get_font )
+ error = service->get_font ( face, font );
+ return error;
+ }
+
+ FT_EXPORT_DEF( FT_Error )
+ FTL_Query_EngineType ( FT_Face face,
+ FTL_EngineType * engine_type)
+ {
+ FT_Error error;
+ FT_Service_Layout service;
+
+ if ( !face )
+ return FT_Err_Invalid_Argument;
+
+ if (( error = ft_face_get_layout_service( face, &service ) ))
+ return error;
+
+ error = FT_Err_Invalid_Argument;
+ if ( service->get_engine_type )
+ {
+ error = FT_Err_Ok;
+ *engine_type = service->get_engine_type( face );
+ }
+ return error;
+ }
+
+ FT_EXPORT_DEF( FT_Error )
+ FTL_New_FeaturesRequest ( FT_Face face,
+ FTL_FeaturesRequest* request)
+ {
+ FT_Error error;
+ FT_Service_Layout service;
+ FTL_FeaturesRequest arequest = NULL;
+ FT_ListNode node = NULL;
+ FT_Memory memory;
+ FTL_Font font;
+
+ memory = face->driver->root.memory;
+
+ if ( FT_NEW( node ) )
+ goto Exit;
+
+ if (( error = ft_face_get_layout_service( face, &service ) ))
+ goto Exit;
+
+ if ( service->get_font )
+ {
+ if (( error = service->get_font( face, &font ) ))
+ goto Failure;
+ }
+
+ if ( service->new_features_request )
+ {
+ if (( error = service->new_features_request( face, &arequest ) ))
+ goto Failure;
+ }
+ else
+ {
+ if ( FT_NEW( arequest ) )
+ goto Exit;
+ if (( error = FTL_FeaturesRequest_Init ( face, arequest ) ))
+ {
+ FT_FREE( arequest );
+ goto Failure;
+ }
+ }
+ *request = arequest;
+ node->data = arequest;
+ FT_List_Add( &font->features_requests_list, node );
+ if ( !font->features_request )
+ font->features_request = arequest;
+ error = FT_Err_Ok;
+ Exit:
+ return error;
+ Failure:
+ if ( arequest )
+ FT_FREE ( arequest );
+ if ( node )
+ FT_FREE( node );
+ return error;
+ }
+
+ FT_EXPORT_DEF( FT_Error )
+ FTL_FeaturesRequest_Init ( FT_Face face,
+ FTL_FeaturesRequest request)
+ {
+ FT_Error error;
+ FTL_Font font;
+
+ if ( ( error = FTL_Get_Font( face, &font ) ) )
+ return error;
+ request->font = font;
+ request->direction = FTL_HORIZONTAL;
+ return error;
+ }
+
+ FT_EXPORT_DEF( FT_Error )
+ FTL_Done_FeaturesRequest ( FTL_FeaturesRequest request )
+ {
+ FT_Error error;
+ FTL_Font font;
+ FT_Face face;
+ FT_Memory memory;
+ FT_ListNode node;
+ FT_Service_Layout service;
+
+ font = request->font;
+ FT_ASSERT(font);
+ face = font->face;
+ FT_ASSERT(face);
+ memory = face->driver->root.memory;
+
+ if (( error = ft_face_get_layout_service( face, &service ) ))
+ return error;
+
+ node = FT_List_Find( &font->features_requests_list, request );
+ FT_ASSERT(node);
+ FT_List_Remove ( &font->features_requests_list, node );
+ FT_FREE( node );
+ if ( font->features_request == request )
+ {
+ font->features_request = NULL;
+ if ( font->features_requests_list.head )
+ font->features_request = (FTL_FeaturesRequest)(font->features_requests_list.head->data);
+ }
+ if ( service->done_features_request )
+ error = service->done_features_request( request );
+ else
+ {
+ error = FTL_FeaturesRequest_Finalize( request );
+ FT_FREE( request ); /* TODO */
+ }
+ return error;
+ }
+
+ FT_EXPORT_DEF( FT_Error )
+ FTL_FeaturesRequest_Finalize ( FTL_FeaturesRequest request )
+ {
+ return FT_Err_Ok;
+ }
+
+
+ FT_EXPORT_DEF ( FTL_Direction )
+ FTL_Get_FeaturesRequest_Direction ( FTL_FeaturesRequest request )
+ {
+ FT_ASSERT( request );
+ return request->direction;
+ }
+
+ FT_EXPORT_DEF ( void )
+ FTL_Set_FeaturesRequest_Direction ( FTL_FeaturesRequest request,
+ FTL_Direction direction)
+ {
+ FT_ASSERT( request );
+ request->direction = direction;
+ }
+
+ FT_EXPORT_DEF ( FT_Error )
+ FTL_Activate_FeaturesRequest ( FTL_FeaturesRequest request )
+ {
+ FTL_Font font;
+
+ if ( !request )
+ return FT_Err_Invalid_Argument;
+
+ font = request->font;
+ if ( !font )
+ return FT_Err_Invalid_Argument;
+ font->features_request = request;
+ return FT_Err_Ok;
+ }
+
+ FT_EXPORT_DEF( FT_Error )
+ FTL_Copy_FeaturesRequest ( FTL_FeaturesRequest from, FTL_FeaturesRequest to )
+ {
+ FT_Error error;
+ FT_Service_Layout service;
+
+ if ( from->font != to->font )
+ return FT_Err_Invalid_Argument;
+ if ( from == to )
+ return FT_Err_Ok;
+
+ FT_ASSERT(from->font->face);
+ if (( error = ft_face_get_layout_service( from->font->face, &service ) ))
+ return error;
+
+ if ( service->copy_features_request )
+ error = service->copy_features_request( from, to );
+ else
+ error = FTL_FeaturesRequest_Copy ( from, to );
+ return error;
+ }
+
+ FT_EXPORT_DEF( FT_Error )
+ FTL_FeaturesRequest_Copy ( FTL_FeaturesRequest from, FTL_FeaturesRequest to )
+ {
+ FTL_Set_FeaturesRequest_Direction(to,
+ FTL_Get_FeaturesRequest_Direction(to));
+ return FT_Err_Ok;
+ }
+
+ FT_EXPORT_DEF( FT_Error )
+ FTL_Reset_FeaturesRequest ( FTL_FeaturesRequest request )
+ {
+ FTL_Font font;
+ FTL_FeaturesRequest default_request;
+
+ if ( !request )
+ return FT_Err_Invalid_Argument;
+
+ font = request->font;
+ FT_ASSERT( font );
+ FTL_Font_Get_Default_FeaturesRequest( font, &default_request );
+ return FTL_Copy_FeaturesRequest( (FTL_FeaturesRequest)default_request,
+ (FTL_FeaturesRequest)request );
+
+ }
+
+ FT_EXPORT_DEF( FT_Error )
+ FTL_Font_Init ( FTL_Font font,
+ FT_Face face )
+ {
+ if ( (!font) || (!face) )
+ return FT_Err_Invalid_Argument;
+ font->face = face;
+ font->features_request = NULL;
+ font->features_requests_list.head = NULL;
+ font->features_requests_list.tail = NULL;
+ return FT_Err_Ok;
+ }
+
+ FT_EXPORT_DEF( FT_Error )
+ FTL_Font_Finalize ( FTL_Font font )
+ {
+ FT_Face face = font->face;
+ FT_Memory memory = face->driver->root.memory;
+
+ if ( !font )
+ return FT_Err_Invalid_Argument;
+
+ FT_List_Finalize( &font->features_requests_list,
+ (FT_List_Destructor)destroy_feaatures_requests,
+ memory,
+ NULL );
+
+ font->features_requests_list.head = NULL;
+ font->features_requests_list.tail = NULL;
+ font->features_request = NULL;
+ font->face = NULL;
+ return FT_Err_Ok;
+ }
+
+ static void
+ destroy_feaatures_requests ( FT_Memory memory,
+ void * data,
+ void * user )
+ {
+ FTL_Font font;
+ FT_Face face;
+ FTL_FeaturesRequest request = data;
+ FT_Service_Layout service = NULL;
+
+ FT_UNUSED(user);
+
+ font = request->font;
+ FT_ASSERT(font);
+ face = font->face;
+ FT_ASSERT(face);
+
+ ft_face_get_layout_service( face, &service );
+
+ if ( service && service->done_features_request )
+ service->done_features_request( request );
+ else
+ {
+ FTL_FeaturesRequest_Finalize( request );
+ FT_FREE( request );
+ }
+ }
+
+ FT_EXPORT_DEF( FT_Error )
+ FTL_Font_Get_Default_FeaturesRequest ( FTL_Font font,
+ FTL_FeaturesRequest * request )
+ {
+ FT_ListNode node;
+
+ if ( !font )
+ return FT_Err_Invalid_Argument;
+ node = font->features_requests_list.head;
+ *request = node->data;
+ return FT_Err_Ok;
+ }
+
+ FT_EXPORT_DEF( FT_Error )
+ FTL_Font_Get_Current_FeaturesRequest ( FTL_Font font,
+ FTL_FeaturesRequest * request )
+ {
+ *request = font->features_request;
+ FT_ASSERT ( *request );
+ return FT_Err_Ok;
+ }
+
+ FT_EXPORT_DEF( FT_UShort )
+ FTL_Get_LigatureCaret_Count ( FT_Face face, FT_UShort glyphID )
+ {
+ FT_Error error;
+ FT_Service_Layout service;
+
+ if (( error = ft_face_get_layout_service( face, &service ) ))
+ return 0;
+
+ if ( service->get_ligature_caret_count )
+ return service->get_ligature_caret_count( face, glyphID );
+ else
+ return 0;
+ }
+
+ FT_EXPORT_DEF( FT_UShort )
+ FTL_Get_LigatureCaret_Division ( FT_Face face,
+ FT_UShort glyphID,
+ FT_UShort nth )
+ {
+ FT_Error error;
+ FT_Service_Layout service;
+
+ if (( error = ft_face_get_layout_service( face, &service ) ))
+ return 0;
+
+ if ( service->get_ligature_caret_division )
+ return service->get_ligature_caret_division( face, glyphID, nth );
+ else
+ return 0;
+ }
+
+ FT_EXPORT_DEF( FT_Error )
+ FTL_New_Glyphs_Array ( FT_Memory memory,
+ FTL_Glyphs_Array * garray )
+ {
+ FT_Error error;
+ FTL_Glyphs_Array agarray;
+
+ if ( FT_NEW( agarray ) )
+ return error;
+
+ agarray->memory = memory;
+ agarray->glyphs = NULL;
+ agarray->length = 0;
+ agarray->allocated = 0;
+
+ *garray = agarray;
+ return FT_Err_Ok;
+ }
+
+ FT_EXPORT_DEF( FT_Error )
+ FTL_Set_Glyphs_Array_Length ( FTL_Glyphs_Array garray,
+ FT_ULong new_length )
+ {
+ FT_Error error;
+ FT_Memory memory = garray->memory;
+
+ if ( new_length > garray->allocated )
+ {
+ if ( FT_RENEW_ARRAY( garray->glyphs, garray->allocated, new_length ) )
+ return error;
+ garray->allocated = new_length;
+ garray->length = new_length;
+ }
+ return FT_Err_Ok;
+ }
+
+ FT_EXPORT_DEF( FT_Error )
+ FTL_Copy_Glyphs_Array ( FTL_Glyphs_Array in,
+ FTL_Glyphs_Array out )
+ {
+ FT_Error error;
+ FT_ULong i;
+
+ if (( error = FTL_Set_Glyphs_Array_Length( out, in->length ) ))
+ return error;
+
+ for ( i = 0; i < in->length; i++ )
+ out->glyphs[i] = in->glyphs[i];
+ return FT_Err_Ok;
+ }
+
+ FT_EXPORT_DEF( FT_Error )
+ FTL_Done_Glyphs_Array ( FTL_Glyphs_Array garray )
+ {
+ FT_Memory memory = garray->memory;
+ FT_FREE( garray->glyphs );
+ FT_FREE( garray );
+ return FT_Err_Ok;
+ }
+
+
+ FT_EXPORT_DEF( FT_Error )
+ FTL_Substitute_Glyphs ( FT_Face face,
+ FTL_Glyphs_Array in,
+ FTL_Glyphs_Array out )
+ {
+ FT_Error error;
+ FT_Service_Layout service;
+ FTL_Font font;
+ FTL_FeaturesRequest request;
+
+ if (( error = ft_face_get_layout_service( face, &service ) ))
+ return error;
+
+ if ( ( error = FTL_Get_Font ( face, &font ) ) )
+ return error;
+
+ if ( ( error = FTL_Font_Get_Current_FeaturesRequest ( font,
+ &request ) ) )
+ return error;
+
+ if ( service->substitute_glyphs )
+ return service->substitute_glyphs( face, request, in, out );
+ else
+ return FTL_Copy_Glyphs_Array(in, out);
+ }
+
+
+/* END */
diff --git a/src/base/rules.mk b/src/base/rules.mk
index 8017e8589..2d7e3b37d 100644
--- a/src/base/rules.mk
+++ b/src/base/rules.mk
@@ -58,7 +58,8 @@ BASE_EXT_SRC := $(BASE_DIR)/ftbbox.c \
$(BASE_DIR)/ftstroke.c \
$(BASE_DIR)/fttype1.c \
$(BASE_DIR)/ftwinfnt.c \
- $(BASE_DIR)/ftxf86.c
+ $(BASE_DIR)/ftxf86.c \
+ $(BASE_DIR)/ftlayout.c
# Default extensions objects
#
diff --git a/src/gxlayout/Jamfile b/src/gxlayout/Jamfile
new file mode 100644
index 000000000..24bfe15e4
--- /dev/null
+++ b/src/gxlayout/Jamfile
@@ -0,0 +1,23 @@
+# Copyied from src/gx.
+##
+## FreeType 2 src/gx Jamfile (c) 2003 RedHat K.K.
+##
+
+SubDir FT2_TOP $(FT2_SRC_DIR) gxlayout ;
+
+{
+ local _sources ;
+
+ if $(FT2_MULTI)
+ {
+ _sources = gxdriver gxload gxobjs gxlayout gxaccess gxfeatreg gxlfeatreg gxstatetbl gxlookuptbl gxvm gxutils
+ }
+ else
+ {
+ _sources = gx ;
+ }
+
+ Library $(FT2_LIB) : $(_sources).c ;
+}
+
+# end of src/gx Jamfile
diff --git a/src/gxlayout/demo.mk b/src/gxlayout/demo.mk
new file mode 100644
index 000000000..4c3bd7c87
--- /dev/null
+++ b/src/gxlayout/demo.mk
@@ -0,0 +1,70 @@
+#
+# demo.mk --- Makefile for GX driver demo program
+#
+# Copyright 2004 by Masatake YAMATO and RedHat K.K.
+#
+# This file is part of the FreeType project, and may only be used, modified,
+# and distributed under the terms of the FreeType project license,
+# LICENSE.TXT. By continuing to use, modify, or distribute this file you
+# indicate that you have read the license and understand and accept it
+# fully.
+#
+########################################################################
+
+# Development of the code in demo.mk is support of
+# Information-technology Promotion Agency, Japan.
+
+SHELL=/bin/bash
+
+GLIB_CFLAGS=`pkg-config --cflags glib-2.0 gobject-2.0`
+GLIB_LIBS=`pkg-config --libs glib-2.0 gobject-2.0`
+GTK_CFLAGS=`pkg-config --cflags gtk+-2.0`
+GTK_LIBS=`pkg-config --libs gtk+-2.0`
+POPT_LIBS=-lpopt
+GCANVAS_CFLAGS=`pkg-config --cflags libgnomecanvas-2.0`
+GCANVAS_LDFLAGS=`pkg-config --libs libgnomecanvas-2.0`
+
+GUI_CFLAGS=$(GTK_CFLAGS) $(GLIB_CFLAGS) $(GCANVAS_CFLAGS)
+GUI_LIBS=$(GTK_LIBS) $(POPT_LIBS) $(GLIB_LIBS) $(GCANVAS_LDFLAGS)
+
+BASE_CFLAGS=-c -O0 -g -I../../include -Wall -std=c99
+BASE_LIBS=-Xlinker -rpath -Xlinker ../../objs/.libs -lz
+########################################################################
+GXOBJ=../../objs/.libs/libfreetype.so
+
+DEMO=gxdemo
+DEMOBIN=$(DEMO)
+DEMOOBJ=$(DEMO).o
+DEMOSRC=$(DEMO).c
+DEMO_CFLAGS=$(BASE_CFLAGS) $(GUI_CFLAGS)
+DEMO_LIBS=$(BASE_LIBS) $(GUI_LIBS)
+
+FI=fi
+FIBIN=$(FI)
+FIOBJ=$(FI).o
+FISRC=$(FI).c
+FI_CFLAGS=$(BASE_CFLAGS)
+FI_LIBS=$(BASE_LIBS)
+
+########################################################################
+all: $(DEMO) $(FI)
+$(GXOBJ): *.c *.h
+ (cd ../../; make)
+clean:
+ rm -f $(DEMOBIN) $(DEMOOBJ) $(FIBIN) $(FIOBJ) core.*
+
+########################################################################
+$(DEMOBIN): $(GXOBJ) $(DEMOOBJ)
+ $(CC) -o $(@) $(DEMO_LIBS) $^
+
+$(DEMOOBJ): $(DEMOSRC) $(GXOBJ)
+ $(CC) $(DEMO_CFLAGS) $(DEMOSRC)
+
+########################################################################
+$(FIBIN): $(GXOBJ) $(FIOBJ)
+ $(CC) -o $(@) $(FI_LIBS) $^
+
+$(FIOBJ): $(FISRC) $(GXOBJ)
+ $(CC) $(FI_CFLAGS) $(FISRC)
+
+########################################################################
diff --git a/src/gxlayout/fi.c b/src/gxlayout/fi.c
new file mode 100644
index 000000000..266707681
--- /dev/null
+++ b/src/gxlayout/fi.c
@@ -0,0 +1,159 @@
+/***************************************************************************/
+/* */
+/* fi.c */
+/* */
+/* 2 characters ligature test program for AAT/TrueTypeGX font driver. */
+/* */
+/* Copyright 2004 by */
+/* Masatake YAMATO and Redhat K.K. */
+/* */
+/* This file may only be used, */
+/* modified, and distributed under the terms of the FreeType project */
+/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
+/* this file you indicate that you have read the license and */
+/* understand and accept it fully. */
+/* */
+/***************************************************************************/
+
+/***************************************************************************/
+/* Development of the code in this file is support of */
+/* Information-technology Promotion Agency, Japan. */
+/***************************************************************************/
+
+/* "fi" is the typical alphabet ligature. *
+ * "fl" is another good candidate to be tried. */
+
+const char * target = "fi";
+
+#include <ft2build.h>
+#include FT_LAYOUT_H
+#include FT_GXLAYOUT_H
+#include FT_INTERNAL_OBJECTS_H /* for FT_FACE_MEMORY */
+
+#include <stdio.h>
+
+FT_Error try_lig(FT_Face face, char a, char b);
+
+int
+main(int argc, char ** argv)
+{
+ FT_Error error;
+ int result = 0;
+ FT_Library library;
+ FT_Face face;
+
+ if ( argc != 2 )
+ {
+ fprintf(stderr, "Usage: %s fontfile\n", argv[0]);
+ return 1;
+ }
+
+ error = FT_Init_FreeType ( &library );
+ if ( error )
+ {
+ fprintf(stderr, "Abort: Fail to initialize FT2\n");
+ result = 1;
+ goto Fail;
+ }
+
+ error = FT_New_Face (library, argv[1], 0, &face);
+ if ( error )
+ {
+ fprintf(stderr, "Abort: Fail to open the file\n");
+ result = 1;
+ goto Fail;
+ }
+ if ( !( face->face_flags & FT_FACE_FLAG_GLYPH_SUBSTITUTION) )
+ {
+ fprintf(stderr, "Abort: No substitution table for the face\n");
+ result = 1;
+ goto Fail;
+ }
+
+ fprintf(stdout, "-------------------\n");
+ fprintf(stdout,
+ "File: %s\nName: %s\n",
+ argv[1],
+ ((FT_Face)face)->family_name);
+
+ error = try_lig( face, target[0], target[1] );
+ if ( error )
+ {
+ fprintf(stderr, "Abort: Fail to substitute\n");
+ result = 1;
+ }
+
+ FT_Done_Face ( face );
+
+ Fail:
+ FT_Done_FreeType (library);
+ return result;
+}
+
+FT_Error
+try_lig( FT_Face face, char c1, char c2 )
+{
+ FT_Error error = FT_Err_Ok;
+ FTL_EngineType engine_type;
+ FTL_Glyphs_Array in, out;
+ FTL_FeaturesRequest request;
+
+ /* Get the engine type */
+ if (( error = FTL_Query_EngineType( face, &engine_type ) ))
+ goto Fail;
+
+ /* Ignore if the engine type is not GX. */
+ if ( engine_type != FTL_TRUETYPEGX_ENGINE )
+ {
+ fprintf(stderr, "Abort: Not GX font.\n");
+ goto Fail;
+ }
+
+ /* Allocate input and output glyphs arrays.
+ The lenght for input has already been known: 2 */
+ FTL_New_Glyphs_Array ( FT_FACE_MEMORY(face), &in );
+ FTL_New_Glyphs_Array ( FT_FACE_MEMORY(face), &out );
+ FTL_Set_Glyphs_Array_Length ( in, 2 );
+
+ /* Get glyph id for c1 and c2 */
+ in->glyphs[0].gid = FT_Get_Char_Index( face, c1 );
+ in->glyphs[1].gid = FT_Get_Char_Index( face, c2 );
+ fprintf(stdout, "[IN]%c: %u, %c: %u\n",
+ c1, in->glyphs[0].gid,
+ c2, in->glyphs[1].gid);
+
+ /* Create a features-request. */
+ FTL_New_FeaturesRequest ( face, &request );
+
+ /* -------------------------------------
+ * YOU CAN SET SOME LAYOUT SETTINGS HERE
+ * -------------------------------------
+ * In this program, just use default.
+ * -------------------------------------
+ */
+
+ /* Activeate the features request */
+ FTL_Activate_FeaturesRequest( request );
+
+ /* Do substitute the glyphs */
+ FTL_Substitute_Glyphs( face, in, out );
+
+ /* Free the features-request */
+ FTL_Done_FeaturesRequest ( request );
+
+ fprintf(stdout,
+ "[OUT]%c: %u, %c: %u%s\n",
+ c1, out->glyphs[0].gid,
+ c2, out->glyphs[1].gid,
+ (out->glyphs[1].gid == 0xFFFF)? "<empty>": "");
+
+ /* Free glyphs arrays */
+ FTL_Done_Glyphs_Array ( in );
+ FTL_Done_Glyphs_Array ( out );
+
+ Fail:
+ return error;
+}
+
+
+/* END */
diff --git a/src/gxlayout/gx.c b/src/gxlayout/gx.c
new file mode 100644
index 000000000..861099eac
--- /dev/null
+++ b/src/gxlayout/gx.c
@@ -0,0 +1,42 @@
+/***************************************************************************/
+/* */
+/* gx.c */
+/* */
+/* FreeType AAT/TrueTypeGX driver component (body only). */
+/* */
+/* Copyright 2003 by */
+/* Masatake YAMATO and Redhat K.K. */
+/* */
+/* This file may only be used, */
+/* modified, and distributed under the terms of the FreeType project */
+/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
+/* this file you indicate that you have read the license and */
+/* understand and accept it fully. */
+/* */
+/***************************************************************************/
+
+/***************************************************************************/
+/* Development of the code in this file is support of */
+/* Information-technology Promotion Agency, Japan. */
+/***************************************************************************/
+#define FT_MAKE_OPTION_SINGLE_OBJECT
+
+#include <ft2build.h>
+
+#include "gxdriver.c" /* low level driver interface */
+#include "gxobjs.c" /* low level object manager */
+#include "gxload.c" /* tables loader */
+
+#include "gxlookuptbl.c"
+#include "gxstatetbl.c"
+#include "gxaccess.c"
+#include "gxutils.c"
+#include "gxfeatreg.c"
+
+#include "gxlayout.c"
+#include "gxlfeatreg.c"
+#include "gxvm.c"
+
+#include "gxdump.c" /* only for debug */
+
+/* END */
diff --git a/src/gxlayout/gxaccess.c b/src/gxlayout/gxaccess.c
new file mode 100644
index 000000000..5f8440fae
--- /dev/null
+++ b/src/gxlayout/gxaccess.c
@@ -0,0 +1,1034 @@
+/***************************************************************************/
+/* */
+/* gxaccess.c */
+/* */
+/* AAT/TrueTypeGX private data accessor implementation(body). */
+/* */
+/* Copyright 2003 by */
+/* Masatake YAMATO and Redhat K.K. */
+/* */
+/* This file may only be used, */
+/* modified, and distributed under the terms of the FreeType project */
+/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
+/* this file you indicate that you have read the license and */
+/* understand and accept it fully. */
+/* */
+/***************************************************************************/
+
+/***************************************************************************/
+/* Development of the code in this file is support of */
+/* Information-technology Promotion Agency, Japan. */
+/***************************************************************************/
+
+#include <ft2build.h>
+#include FT_INTERNAL_DEBUG_H
+#include FT_INTERNAL_CALC_H
+#include "gxlookuptbl.h"
+#include "gxstatetbl.h"
+#include "gxutils.h"
+#include "gxaccess.h"
+#include "gxobjs.h"
+#include "gxerrors.h"
+#include "gxvm.h"
+#include "gxltypes.h"
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+ /**** ****/
+ /**** ****/
+ /**** Features ****/
+ /**** ****/
+ /**** ****/
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+
+
+FT_LOCAL_DEF ( FT_Bool )
+gx_feat_has_feature_type ( GX_Feat feat, FT_UShort feature_type )
+{
+ FT_Int i;
+ for ( i = 0; i < feat->featureNameCount; i++ )
+ {
+ if ( feat->names[i].feature == feature_type )
+ return 1;
+ }
+ return 0;
+}
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+ /**** ****/
+ /**** ****/
+ /**** Glyph Properties ****/
+ /**** ****/
+ /**** ****/
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+
+FT_LOCAL_DEF ( FT_UShort )
+gx_prop_get( GX_Prop prop, FT_Long glyph )
+{
+ GX_LookupTable lookup_table = &prop->lookup_data;
+ FT_UShort default_properties = prop->default_properties;
+ FT_UShort properties = 0;
+ GX_LookupResultRec result;
+ FT_UShort * segment_array;
+ FT_Long index_in_segment;
+
+
+ result = gx_LookupTable_lookup( lookup_table, glyph );
+
+ if ( result.value == NULL )
+ properties = default_properties;
+ else if ( result.firstGlyph == GX_LOOKUP_RESULT_NO_FIRST_GLYPH )
+ properties = result.value->raw.s;
+ else
+ {
+ index_in_segment = glyph - result.firstGlyph;
+ segment_array = result.value->extra.word;
+ properties = segment_array[index_in_segment];
+ }
+ return properties;
+}
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+ /**** ****/
+ /**** ****/
+ /**** Ligature Carret ****/
+ /**** ****/
+ /**** ****/
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+
+FT_LOCAL_DEF ( GX_LigCaretClassEntry )
+gx_lcar_get ( GX_Lcar lcar, FT_UShort glyphID )
+{ /* TODO: We could put cache mechanism here. */
+ GX_LookupResultRec result;
+
+ result = gx_LookupTable_lookup ( &lcar->lookup, glyphID );
+ if ( result.value == NULL )
+ return NULL;
+ else if ( result.firstGlyph == GX_LOOKUP_RESULT_NO_FIRST_GLYPH )
+ return result.value->extra.lcar_class_entry;
+ else
+ return &result.value->extra.lcar_segment->class_entry[glyphID - result.firstGlyph];
+}
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+ /**** ****/
+ /**** ****/
+ /**** Glyph Metamorphosis ****/
+ /**** ****/
+ /**** ****/
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+
+#undef FT_COMPONENT
+#define FT_COMPONENT trace_gxchain
+
+FT_LOCAL_DEF ( FT_Error )
+gx_mort_foreach_feature ( GX_Mort mort, GX_Mort_Feature_Func func, FT_Pointer user )
+{
+ FT_Error error = GX_Err_Ok;
+ FT_Int i, j;
+ GX_MetamorphosisChain chain;
+ GX_MetamorphosisFeatureTable feat_Subtbl;
+ for ( i = 0; i < mort->nChains; i++ )
+ {
+ chain = &mort->chain[i];
+ for ( j = 0; j < chain->header.nFeatureEntries; j++ )
+ {
+ feat_Subtbl = &chain->feat_Subtbl[j];
+ if (( error = func ( feat_Subtbl, user ) ))
+ return error;
+ }
+ }
+ return error;
+}
+
+#define GX_MORT_COUNT_FEAT_DATA_ZERO {0, NULL}
+typedef struct gx_mort_count_feat_data_rec_
+{
+ FT_UShort count;
+ GX_Feat feat;
+} gx_mort_count_feat_data_rec, *gx_mort_count_feat_data;
+
+static FT_Error
+gx_mort_count_feat_not_in_feat_cb ( GX_MetamorphosisFeatureTable feat_Subtbl, FT_Pointer user )
+{
+ gx_mort_count_feat_data data = user;
+ FT_UShort featureType = feat_Subtbl->featureType;
+ if ( !gx_feat_has_feature_type ( data->feat, featureType ) )
+ data->count++;
+ return GX_Err_Ok;
+}
+
+FT_LOCAL_DEF ( FT_UShort )
+gx_mort_count_feat_not_in_feat ( GX_Mort mort, GX_Feat feat )
+{
+ gx_mort_count_feat_data_rec data;
+ data.count = 0;
+ data.feat = feat;
+ gx_mort_foreach_feature ( mort, gx_mort_count_feat_not_in_feat_cb, &data );
+ return data.count;
+}
+
+static FT_ULong
+gx_chain_calc_selector ( GX_MetamorphosisChain chain, GXL_FeaturesRequest request)
+{
+ FT_ULong j_features;
+ FT_ULong result;
+ GX_MetamorphosisFeatureTable feat_Subtbl;
+ GXL_Feature feature;
+
+ result = chain->header.defaultFlags;
+ for ( j_features = 0; j_features < chain->header.nFeatureEntries; j_features++ )
+ {
+ feat_Subtbl = &chain->feat_Subtbl[j_features];
+ feature = gxl_features_request_get_feature_by_type(request,
+ feat_Subtbl->featureType);
+ if ( !feature )
+ continue ;
+
+ if ( gxl_feature_get_setting_by_value(feature,
+ feat_Subtbl->featureSetting ) )
+ {
+ result &= feat_Subtbl->disableFlags;
+ result |= feat_Subtbl->enableFlags ;
+ }
+ }
+ return result;
+}
+
+FT_LOCAL_DEF( FT_Error )
+gx_mort_substitute_glyph ( GX_Mort mort,
+ GXL_FeaturesRequest request,
+ FTL_Glyphs_Array in,
+ FTL_Glyphs_Array out )
+{
+ FT_Error error = GX_Err_Ok;
+ GX_MetamorphosisChain chain;
+ FT_ULong i_chain, k_subtbl;
+ FT_ULong selector;
+ GX_MetamorphosisSubtable chain_Subtbl;
+ FT_UShort coverage;
+ FT_UShort subtable_type;
+ GXL_Order order;
+
+ if (( error = FTL_Copy_Glyphs_Array ( in, out ) ))
+ return error;
+
+
+ for ( i_chain = 0; i_chain < mort->nChains; i_chain++ )
+ {
+ chain = &mort->chain[i_chain];
+ selector = gx_chain_calc_selector( chain, request );
+
+ FT_TRACE2(( "Mort Chain No.%d, Address 0x%p\n", i_chain, chain ));
+
+ for ( k_subtbl = 0; k_subtbl < chain->header.nSubtables; k_subtbl++ )
+ {
+ chain_Subtbl = &chain->chain_Subtbl[k_subtbl];
+ if ( !(chain_Subtbl->header.subFeatureFlags & selector) )
+ continue;
+
+ coverage = chain_Subtbl->header.coverage;
+ if ( ( !(coverage & GX_MORT_COVERAGE_ORIENTATION_INDEPENDENT) )
+ /* Orientation dependent */
+ && ((( coverage & GX_MORT_COVERAGE_HORIZONTAL_OR_VERTICAL_TEXT )
+ /* Vertical only */
+ && (FTL_Get_FeaturesRequest_Direction(&request->root) != FTL_VERTICAL)
+ /* But the request is NOT vertical */)
+ || (!( coverage & GX_MORT_COVERAGE_HORIZONTAL_OR_VERTICAL_TEXT )
+ /* Horizontal only */
+ && (FTL_Get_FeaturesRequest_Direction(&request->root) != FTL_HORIZONTAL)
+ /* But the request is NOT horizontal */)))
+ continue;
+
+ order = (coverage & GX_MORT_COVERAGE_ORDER_OF_PROCESSING_GLYPH_ARRAY)
+ ? GXL_DESCENDING
+ : GXL_ASCENDING;
+ if ( order == GXL_DESCENDING )
+ gx_glyphs_array_reverse( out->glyphs, out->length );
+
+ subtable_type = coverage & GX_MORT_COVERAGE_SUBTABLE_TYPE;
+ FT_TRACE2(( "\tSubtable No.%d, Address 0x%p, Type %d\n",
+ k_subtbl, chain_Subtbl, subtable_type ));
+
+ switch ( subtable_type )
+ {
+ case GX_MORT_REARRANGEMENT_SUBTABLE:
+ gx_rearrangement_subst( chain_Subtbl->body.rearrangement,
+ request->initial_state,
+ out );
+ break;
+ case GX_MORT_CONTEXTUAL_SUBTABLE:
+ error = gx_contextual_subst( chain_Subtbl->body.contextual,
+ request->initial_state,
+ out );
+ break;
+ case GX_MORT_LIGATURE_SUBTABLE:
+ error = gx_ligature_subst( chain_Subtbl->body.ligature,
+ request->initial_state,
+ out );
+ break;
+ case GX_MORT_RESERVED_SUBTABLE:
+ FT_ERROR(("Reserved\n"));
+ break;
+ case GX_MORT_NONCONTEXTUAL_SUBTABLE:
+ error = gx_xnoncontextual_subst( chain_Subtbl->body.noncontextual, out );
+ break;
+ case GX_MORT_INSERTION_SUBTABLE:
+ error = gx_insertion_subst( chain_Subtbl->body.insertion,
+ request->initial_state,
+ out );
+ break;
+ }
+
+ if ( order == GXL_DESCENDING )
+ gx_glyphs_array_reverse( out->glyphs, out->length );
+ }
+ }
+ return error;
+}
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+ /**** ****/
+ /**** ****/
+ /**** Extended Glyph Metamorphosis ****/
+ /**** ****/
+ /**** ****/
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+
+FT_LOCAL_DEF ( FT_Error )
+gx_morx_foreach_feature ( GX_Morx morx, GX_Morx_Feature_Func func, FT_Pointer user )
+{
+ FT_Error error = GX_Err_Ok;
+ FT_Int i, j;
+ GX_XMetamorphosisChain chain;
+ GX_XMetamorphosisFeatureTable feat_Subtbl;
+ for ( i = 0; i < morx->nChains; i++ )
+ {
+ chain = &morx->chain[i];
+ for ( j = 0; j < chain->header.nFeatureEntries; j++ )
+ {
+ feat_Subtbl = &chain->feat_Subtbl[j];
+ if (( error = func ( feat_Subtbl, user ) ))
+ return error;
+
+ }
+ }
+ return error;
+}
+
+#define GX_MORT_COUNT_FEAT_DATA_ZERO {0, NULL}
+typedef struct gx_morx_count_feat_data_rec_
+{
+ FT_UShort count;
+ GX_Feat feat;
+} gx_morx_count_feat_data_rec, *gx_morx_count_feat_data;
+
+static FT_Error
+gx_morx_count_feat_not_in_feat_cb ( GX_MetamorphosisFeatureTable feat_Subtbl, FT_Pointer user )
+{
+ gx_morx_count_feat_data data = user;
+ FT_UShort featureType = feat_Subtbl->featureType;
+ if ( !gx_feat_has_feature_type ( data->feat, featureType ) )
+ data->count++;
+ return GX_Err_Ok;
+}
+
+FT_LOCAL_DEF ( FT_UShort )
+gx_morx_count_feat_not_in_feat ( GX_Morx morx, GX_Feat feat )
+{
+ gx_morx_count_feat_data_rec data;
+ data.count = 0;
+ data.feat = feat;
+ gx_morx_foreach_feature ( morx, gx_morx_count_feat_not_in_feat_cb, &data );
+ return data.count;
+}
+
+static FT_ULong
+gx_xchain_calc_selector ( GX_XMetamorphosisChain chain, GXL_FeaturesRequest request)
+{
+ FT_ULong j_features;
+ FT_ULong result;
+ GX_MetamorphosisFeatureTable feat_Subtbl;
+ GXL_Feature feature;
+
+ result = chain->header.defaultFlags;
+ for ( j_features = 0; j_features < chain->header.nFeatureEntries; j_features++ )
+ {
+ feat_Subtbl = &chain->feat_Subtbl[j_features];
+ feature = gxl_features_request_get_feature_by_type(request,
+ feat_Subtbl->featureType);
+ if ( !feature )
+ continue ;
+
+ if ( gxl_feature_get_setting_by_value(feature,
+ feat_Subtbl->featureSetting ) )
+ {
+ result &= feat_Subtbl->disableFlags;
+ result |= feat_Subtbl->enableFlags;
+ }
+ }
+ return result;
+}
+
+FT_LOCAL_DEF( FT_Error )
+gx_morx_substitute_glyph ( GX_Morx morx,
+ GXL_FeaturesRequest request,
+ FTL_Glyphs_Array in,
+ FTL_Glyphs_Array out )
+{
+ FT_Error error = GX_Err_Ok;
+ GX_XMetamorphosisChain xchain;
+ FT_ULong i_chain, k_subtbl;
+ FT_ULong selector;
+ GX_XMetamorphosisSubtable xchain_Subtbl;
+ FT_UShort coverage;
+ FT_UShort subtable_type;
+ GXL_Order order;
+
+ if (( error = FTL_Copy_Glyphs_Array ( in, out ) ))
+ return error;
+
+ for ( i_chain = 0; i_chain < morx->nChains; i_chain++ )
+ {
+ xchain = &morx->chain[i_chain];
+ selector = gx_xchain_calc_selector( xchain, request );
+
+ FT_TRACE2(( "Morx Chain No.%d, Address 0x%p\n", i_chain, xchain ));
+
+ for ( k_subtbl = 0; k_subtbl < xchain->header.nSubtables; k_subtbl++ )
+ {
+ xchain_Subtbl = &xchain->chain_Subtbl[k_subtbl];
+ if ( !(xchain_Subtbl->header.subFeatureFlags & selector) )
+ continue;
+
+ coverage = xchain_Subtbl->header.coverage;
+ if ( ( !(coverage & GX_MORX_COVERAGE_ORIENTATION_INDEPENDENT) )
+ /* Orientation dependent */
+ && ((( coverage & GX_MORX_COVERAGE_HORIZONTAL_OR_VERTICAL_TEXT )
+ /* Vertical only */
+ && (FTL_Get_FeaturesRequest_Direction(&request->root) != FTL_VERTICAL)
+ /* But the request is NOT vertical */)
+ || (!( coverage & GX_MORX_COVERAGE_HORIZONTAL_OR_VERTICAL_TEXT )
+ /* Horizontal only */
+ && (FTL_Get_FeaturesRequest_Direction(&request->root) != FTL_HORIZONTAL)
+ /* But the request is NOT horizontal */)))
+ continue;
+ order = (coverage & GX_MORX_COVERAGE_ORDER_OF_PROCESSING_GLYPH_ARRAY)
+ ? GXL_DESCENDING
+ : GXL_ASCENDING;
+ if ( order == GXL_DESCENDING )
+ gx_glyphs_array_reverse( out->glyphs, out->length );
+
+ subtable_type = coverage & GX_MORX_COVERAGE_SUBTABLE_TYPE;
+ FT_TRACE2(( "\tSubtable No.%d, Address 0x%p, Type %d\n",
+ k_subtbl, xchain_Subtbl, subtable_type ));
+ switch ( subtable_type )
+ {
+ case GX_MORX_REARRANGEMENT_SUBTABLE:
+ error = gx_xrearrangement_subst( xchain_Subtbl->body.rearrangement,
+ request->initial_state,
+ out );
+ break;
+ case GX_MORX_CONTEXTUAL_SUBTABLE:
+ error = gx_xcontextual_subst( xchain_Subtbl->body.contextual,
+ request->initial_state,
+ out );
+ break;
+ case GX_MORX_LIGATURE_SUBTABLE:
+ error = gx_xligature_subst( xchain_Subtbl->body.ligature,
+ request->initial_state,
+ out );
+ break;
+ case GX_MORX_RESERVED_SUBTABLE:
+ FT_ERROR(("Reserved format\n"));
+ break;
+ case GX_MORX_NONCONTEXTUAL_SUBTABLE:
+ error = gx_xnoncontextual_subst( xchain_Subtbl->body.noncontextual, out );
+ break;
+ case GX_MORX_INSERTION_SUBTABLE:
+ error = gx_xinsertion_subst ( xchain_Subtbl->body.insertion,
+ request->initial_state,
+ out );
+ break;
+ }
+ if ( order == GXL_DESCENDING )
+ gx_glyphs_array_reverse( out->glyphs, out->length );
+ }
+ }
+ return FT_Err_Ok;
+}
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+ /**** ****/
+ /**** ****/
+ /**** Kerning ****/
+ /**** ****/
+ /**** ****/
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+
+#undef PAIR_TAG
+#define PAIR_TAG( left, right ) ( ( (FT_ULong)left << 16 ) | \
+ (FT_ULong)right )
+
+static FT_Pos gx_kern_get_fmt0( GX_KerningSubtableFormat0Body fmt0,
+ FT_UShort left_glyph,
+ FT_UShort right_glyph );
+static int gx_kern_fmt0_compar ( const void * a, const void * b);
+
+static FT_Pos gx_kern_get_fmt1( GX_KerningSubtableFormat1Body fmt1,
+ FT_UShort left_glyph,
+ FT_UShort right_glyph );
+static FT_Pos gx_kern_get_fmt2( GX_KerningSubtableFormat2Body fmt2,
+ FT_UShort left_glyph,
+ FT_UShort right_glyph );
+static FT_Pos gx_kern_get_fmt3( GX_KerningSubtableFormat3Body fmt3,
+ FT_UShort left_glyph,
+ FT_UShort right_glyph );
+
+FT_LOCAL_DEF( FT_Error )
+gx_kern_get_pair_kerning ( GX_Kern kern,
+ FT_UShort left_glyph,
+ FT_UShort right_glyph,
+ FTL_Direction dir,
+ FT_Vector* kerning )
+{
+ FT_Error error = GX_Err_Ok;
+ FT_ULong i;
+ GX_KerningSubtable subtable;
+ GX_KerningSubtableHeader header;
+ FT_UShort coverage;
+ GX_KerningFormat fmt;
+ GX_KerningSubtableBody body;
+ FT_Pos * value;
+
+ kerning->x = 0;
+ kerning->y = 0;
+
+ for ( i = 0; i < kern->nTables; i++ )
+ {
+ subtable = &(kern->subtables[i]);
+ header = &subtable->header;
+ coverage = header->coverage;
+ if ( coverage & GX_KERN_COVERAGE_VERTICAL )
+ {
+ if ( dir != FTL_VERTICAL )
+ continue;
+ if ( coverage & GX_KERN_COVERAGE_CROSS_STREAM )
+ value = &kerning->x;
+ else
+ value = &kerning->y;
+ }
+ else
+ {
+ if ( dir != FTL_HORIZONTAL )
+ continue;
+ if ( coverage & GX_KERN_COVERAGE_CROSS_STREAM )
+ value = &kerning->y;
+ else
+ value = &kerning->x;
+ }
+
+ fmt = coverage & GX_KERN_COVERAGE_FORMAT_MASK;
+ body = &subtable->body;
+ switch ( fmt )
+ {
+ case GX_KERN_FMT_ORDERED_LIST_OF_KERNING_PAIRS:
+ *value += gx_kern_get_fmt0 ( body->fmt0, left_glyph, right_glyph );
+ break;
+ case GX_KERN_FMT_STATE_TABLE_FOR_CONTEXTUAL_KERNING:
+ *value += gx_kern_get_fmt1 ( body->fmt1, left_glyph, right_glyph );
+ break;
+ case GX_KERN_FMT_SIMPLE_NXM_ARRAY_OF_KERNING_VALUES:
+ *value += gx_kern_get_fmt2 ( body->fmt2, left_glyph, right_glyph );
+ break;
+ case GX_KERN_FMT_SIMPLE_NXM_ARRAY_OF_KERNING_INDICES:
+ *value += gx_kern_get_fmt3 ( body->fmt3, left_glyph, right_glyph );
+ break;
+ default:
+ break;
+ }
+ }
+ return error;
+}
+
+static FT_Pos
+gx_kern_get_fmt0( GX_KerningSubtableFormat0Body fmt0,
+ FT_UShort left_glyph,
+ FT_UShort right_glyph )
+{
+ GX_KerningSubtableFormat0Entry entry;
+ FT_ULong search_tag = PAIR_TAG( left_glyph, right_glyph );
+ if ( !fmt0->nPairs )
+ return 0;
+
+ entry = ft_bsearch(&search_tag,
+ fmt0->entries,
+ fmt0->nPairs,
+ sizeof(*fmt0->entries),
+ gx_kern_fmt0_compar);
+
+ if ( entry )
+ return entry->value;
+ else
+ return 0;
+}
+
+static int
+gx_kern_fmt0_compar ( const void * search_tag, const void * entry)
+{
+ FT_ULong tag;
+ tag = PAIR_TAG( ((GX_KerningSubtableFormat0Entry)entry)->left,
+ ((GX_KerningSubtableFormat0Entry)entry)->right );
+ if ( *(FT_ULong*)search_tag < tag )
+ return -1;
+ else if ( *(FT_ULong*)search_tag > tag )
+ return 1;
+ else
+ return 0;
+}
+
+static FT_Pos
+gx_kern_get_fmt1( GX_KerningSubtableFormat1Body fmt1,
+ FT_UShort left_glyph, FT_UShort right_glyph )
+{
+ return 0; /* Do nothing */
+}
+
+static FT_Pos
+gx_kern_get_fmt2( GX_KerningSubtableFormat2Body fmt2,
+ FT_UShort left_glyph, FT_UShort right_glyph )
+{
+ GX_KerningSubtableFormat2ClassTable left_class, right_class;
+ FT_UShort left_index, right_index;
+ FT_Byte kern_index;
+
+ left_class = &fmt2->leftClass;
+ right_class = &fmt2->rightClass;
+
+ if (( left_class->firstGlyph > left_glyph )
+ || ( !( left_class->firstGlyph + left_class->nGlyphs > left_glyph ) ))
+ return 0;
+ if (( right_class->firstGlyph > right_glyph )
+ || ( !( right_class->firstGlyph + right_class->nGlyphs > right_glyph ) ))
+ return 0;
+
+ left_index = left_glyph - left_class->firstGlyph;
+ right_index = right_glyph - right_class->firstGlyph;
+
+ FT_ASSERT( left_index < left_class->max_class );
+ FT_ASSERT( right_index < right_class->max_class );
+
+ kern_index = left_class->classes[left_index]
+ + right_class->classes[right_index];
+ return fmt2->values[kern_index];
+}
+
+static FT_Pos
+gx_kern_get_fmt3( GX_KerningSubtableFormat3Body fmt3,
+ FT_UShort left_glyph, FT_UShort right_glyph )
+{
+ FT_Byte left_class, right_class;
+ FT_Byte kern_index;
+
+ if ( !( fmt3->glyphCount > left_glyph ) &&
+ ( fmt3->glyphCount > right_glyph ) )
+ return 0;
+
+ left_class = fmt3->leftClass[left_glyph];
+ right_class = fmt3->rightClass[right_glyph];
+ kern_index = fmt3->kernIndex[left_class * fmt3->rightClassCount + right_class];
+ FT_ASSERT ( kern_index < fmt3->kernValueCount );
+ return fmt3->kernValue[kern_index];
+}
+
+FT_LOCAL_DEF( FT_Error )
+gx_kern_get_contextual_kerning( GX_Kern kern,
+ FTL_Glyphs_Array garray,
+ FTL_Direction dir,
+ GXL_Initial_State initial_state,
+ FT_Vector * kerning )
+{
+ GX_KerningSubtable subtable;
+ GX_KerningSubtableHeader header;
+ FT_UShort coverage;
+ GX_KerningFormat fmt;
+ GX_KerningSubtableFormat1Body fmt1;
+ FT_Bool cross_stream = 0;
+
+ FT_ULong i;
+
+ for ( i = 0; i < kern->nTables; i++ )
+ {
+ subtable = &(kern->subtables[i]);
+ header = &subtable->header;
+ coverage = header->coverage;
+ if ( coverage & GX_KERN_COVERAGE_VERTICAL )
+ {
+ if ( dir != FTL_VERTICAL )
+ continue;
+ if ( coverage & GX_KERN_COVERAGE_CROSS_STREAM )
+ cross_stream = 1;
+ }
+ else
+ {
+ if ( dir != FTL_HORIZONTAL )
+ continue;
+ if ( coverage & GX_KERN_COVERAGE_CROSS_STREAM )
+ cross_stream = 1;
+ }
+ fmt = coverage & GX_KERN_COVERAGE_FORMAT_MASK;
+ if ( fmt != GX_KERN_FMT_STATE_TABLE_FOR_CONTEXTUAL_KERNING )
+ continue;
+ fmt1 = subtable->body.fmt1;
+ gx_contextual_kerning_calc( fmt1,
+ garray, dir, cross_stream, initial_state,
+ kerning );
+ }
+ return FT_Err_Ok;
+}
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+ /**** ****/
+ /**** ****/
+ /**** Tracking ****/
+ /**** ****/
+ /**** ****/
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+
+typedef enum track_interpolation_range_ {
+ TRACK_NO_INTERPOLATION = 0,
+ TRACK_INTERPOLATION,
+ TRACK_EXTRAPOLATION_SMALLER,
+ TRACK_EXTRAPOLATION_LARGER
+} track_interpolation_range;
+
+
+static track_interpolation_range track_find_entry ( GX_TrackData track_data,
+ FT_Fixed track,
+ GX_TrackTableEntry * smaller_entry,
+ GX_TrackTableEntry * larger_entry );
+static track_interpolation_range track_find_size ( GX_TrackData track_data,
+ FT_Fixed size,
+ FT_Fixed *smaller_size, FT_UShort *smaller_size_index,
+ FT_Fixed *larger_size, FT_UShort *larger_size_index );
+
+static FT_FWord track_interpolate( FT_Fixed x_t,
+ FT_Fixed x_p, FT_Fixed x_q,
+ FT_FWord y_p, FT_FWord y_q );
+
+
+
+FT_LOCAL_DEF( FT_Error )
+gx_trak_get( GX_Trak trak, FT_Fixed track, FT_Fixed size, FTL_Direction dir, FT_FWord* value )
+{
+ GX_TrackData track_data = ( dir == FTL_HORIZONTAL )
+ ? (&trak->horizData)
+ : (&trak->vertData);
+
+ GX_TrackTableEntry larger_entry = NULL, smaller_entry;
+ FT_Fixed larger_track, smaller_track;
+ track_interpolation_range entry_range;
+
+ FT_UShort larger_size_index, smaller_size_index;
+ FT_Fixed larger_size = 0, smaller_size;
+ track_interpolation_range size_range;
+
+ FT_FWord a, b, c, d;
+ FT_FWord p, q;
+
+ if ( !track_data )
+ {
+ *value = 0;
+ return FT_Err_Ok;
+ }
+
+
+ entry_range = track_find_entry ( track_data, track, &smaller_entry, &larger_entry );
+ larger_track = larger_entry->track;
+ smaller_track = smaller_entry->track;
+
+ size_range = track_find_size ( track_data, size,
+ &smaller_size, &smaller_size_index,
+ &larger_size, &larger_size_index );
+
+ a = smaller_entry->tracking_value[smaller_size_index];
+ b = smaller_entry->tracking_value[larger_size_index];
+ c = larger_entry->tracking_value[smaller_size_index];
+ d = larger_entry->tracking_value[larger_size_index];
+
+ /* -------------------------------------------------------------------
+
+ ^ size
+ |
+ B | D
+ |
+ A | C
+ --------------+---------------> track
+ O|
+
+ A = ( smaller_track, smaller_size, a )
+ B = ( smaller_track, larger_size, b )
+ C = ( larger_track, smaller_size, c )
+ D = ( larger_track, larger_size, d )
+ -----------V---------------------------
+ P = ( track, smaller_size, p )
+ Q = ( track larger_size, q )
+ --------------------------V------------
+ T = ( track, size, *value)
+
+ ------------------------------------------------------------------- */
+
+ if ( entry_range == TRACK_NO_INTERPOLATION )
+ {
+ p = a;
+ q = b;
+ }
+ else
+ {
+ p = track_interpolate ( track,
+ smaller_track, larger_track,
+ a, c );
+ q = track_interpolate ( track,
+ smaller_track, larger_track,
+ b, d );
+ }
+
+ if ( size_range == TRACK_NO_INTERPOLATION )
+ *value = p;
+ else
+ *value = track_interpolate( size,
+ smaller_size, larger_size,
+ p, q );
+ return FT_Err_Ok;
+}
+
+static track_interpolation_range
+track_find_entry ( GX_TrackData track_data,
+ FT_Fixed track,
+ GX_TrackTableEntry * smaller_entry,
+ GX_TrackTableEntry * larger_entry )
+{
+ FT_UShort i;
+ track_interpolation_range range;
+ FT_Bool extrapolation = FALSE;
+
+ if ( track < track_data->trackTable[0].track )
+ {
+ i = 0;
+ range = TRACK_EXTRAPOLATION_SMALLER;
+ extrapolation = TRUE;
+ }
+ else if ( track_data->trackTable[track_data->nTracks - 1].track < track )
+ {
+ i = track_data->nTracks - 2;
+ range = TRACK_EXTRAPOLATION_LARGER;
+ extrapolation = TRUE;
+ }
+
+ if ( extrapolation )
+ {
+ *smaller_entry = &track_data->trackTable[i];
+ *larger_entry = &track_data->trackTable[i + 1];
+ return range;
+ }
+
+
+ for ( i = 0; i < track_data->nTracks; i++ )
+ {
+ *smaller_entry = *larger_entry;
+ *larger_entry = &track_data->trackTable[i];
+ if ( track == (*larger_entry)->track )
+ {
+ *smaller_entry = *larger_entry;
+ return TRACK_NO_INTERPOLATION;
+ }
+ else if ( track < (*larger_entry)->track )
+ return TRACK_INTERPOLATION;
+ }
+ GX_ASSERT_NOT_REACHED();
+ return TRACK_INTERPOLATION;
+}
+
+static track_interpolation_range
+track_find_size ( GX_TrackData track_data,
+ FT_Fixed size,
+ FT_Fixed *smaller_size, FT_UShort *smaller_size_index,
+ FT_Fixed *larger_size, FT_UShort *larger_size_index)
+{
+ FT_UShort i;
+ track_interpolation_range range;
+ FT_Bool extrapolation = FALSE;
+
+ if ( size < track_data->sizeTable[0] )
+ {
+ i = 0;
+ range = TRACK_EXTRAPOLATION_SMALLER;
+ extrapolation = TRUE;
+ }
+ else if ( track_data->sizeTable[track_data->nSizes - 1] < size )
+ {
+ i = track_data->nSizes - 2;
+ range = TRACK_EXTRAPOLATION_LARGER;
+ extrapolation = TRUE;
+ }
+ if ( extrapolation )
+ {
+ *smaller_size = track_data->sizeTable[i];
+ *smaller_size_index = i;
+ *larger_size = track_data->sizeTable[i + 1];
+ *larger_size_index = i + 1;
+ return range;
+ }
+
+ for ( i = 0; i < track_data->nSizes; i++ )
+ {
+ *smaller_size = *larger_size;
+ *smaller_size_index = *larger_size_index;
+ *larger_size = track_data->sizeTable[i];
+ *larger_size_index = i;
+ if ( size == *larger_size )
+ {
+ *smaller_size = *larger_size;
+ *smaller_size_index = *larger_size_index;
+ return TRACK_NO_INTERPOLATION;
+ }
+ else if ( size < *larger_size )
+ return TRACK_INTERPOLATION;
+ }
+ GX_ASSERT_NOT_REACHED();
+ return TRACK_INTERPOLATION;
+}
+
+static FT_FWord
+track_interpolate( FT_Fixed x_t,
+ FT_Fixed x_p, FT_Fixed x_q,
+ FT_FWord y_p, FT_FWord y_q )
+{
+ FT_FWord y_t;
+
+ /* TODO: better to use FT_MulDiv_No_Round. */
+ y_t = ( y_q * ( x_t - x_p ) + y_p * ( x_q - x_t )) / (x_q - x_p);
+ return y_t;
+}
+
+FT_LOCAL_DEF( FT_UShort )
+gx_trak_count_name_index( GX_Trak trak )
+{
+ GX_TrackData track_data;
+ GX_TrackTableEntry track_table;
+ FT_UShort nTracks;
+ FT_UShort i;
+
+ FT_UShort h = 0;
+ FT_UShort v = 0;
+
+ /*
+ * Horiz
+ */
+ track_data = &trak->horizData;
+ nTracks = track_data->nTracks;
+ for ( i = 0; i < nTracks; i++ )
+ {
+ track_table = &track_data->trackTable[i];
+ if ( track_table->nameIndex )
+ h++;
+ }
+
+ /*
+ * Vert
+ */
+ track_data = &trak->vertData;
+ nTracks = track_data->nTracks;
+ for ( i = 0; i < nTracks; i++ )
+ {
+ track_table = &track_data->trackTable[i];
+ if ( track_table->nameIndex )
+ h++;
+ }
+
+ return h + v;
+}
+
+FT_LOCAL( FT_Error )
+gx_trak_get_name ( GX_Trak trak,
+ FT_UShort index,
+ FT_UShort * name_index,
+ FTL_Direction * dir,
+ FT_Fixed * track )
+{
+ GX_TrackData track_data;
+ GX_TrackTableEntry track_table;
+ FT_UShort i;
+
+ /*
+ * Horiz
+ */
+ track_data = &trak->horizData;
+ for ( i = 0; i < track_data->nTracks; i++ )
+ {
+ track_table = &track_data->trackTable[i];
+ if ( track_table->nameIndex == 0 )
+ continue ;
+
+ if ( index == 0 )
+ goto Set_Values;
+ else
+ index--;
+ }
+
+ /*
+ * Vert
+ */
+ track_data = &trak->vertData;
+ for ( i = 0; i < track_data->nTracks; i++ )
+ {
+ track_table = &track_data->trackTable[i];
+ if ( track_table->nameIndex == 0 )
+ continue ;
+
+ if ( index == 0 )
+ goto Set_Values;
+ else
+ index--;
+ }
+
+ return GX_Err_Invalid_Argument;
+
+ Set_Values:
+ *name_index = track_table->nameIndex;
+ *dir = ( track_data = &trak->horizData )
+ ? FTL_HORIZONTAL
+ : FTL_VERTICAL;
+ *track = track_table->track;
+ return FT_Err_Ok;
+}
diff --git a/src/gxlayout/gxaccess.h b/src/gxlayout/gxaccess.h
new file mode 100644
index 000000000..5bed3e8bb
--- /dev/null
+++ b/src/gxlayout/gxaccess.h
@@ -0,0 +1,112 @@
+/***************************************************************************/
+/* */
+/* gxaccess.h */
+/* */
+/* AAT/TrueTypeGX private data accessor (specification only). */
+/* */
+/* Copyright 2003 by */
+/* Masatake YAMATO and Redhat K.K. */
+/* */
+/* This file may only be used, */
+/* modified, and distributed under the terms of the FreeType project */
+/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
+/* this file you indicate that you have read the license and */
+/* understand and accept it fully. */
+/* */
+/***************************************************************************/
+
+/***************************************************************************/
+/* Development of the code in this file is support of */
+/* Information-technology Promotion Agency, Japan. */
+/***************************************************************************/
+
+#ifndef __GXACCESS_H__
+#define __GXACCESS_H__
+
+#include <ft2build.h>
+#include FT_TYPES_H
+
+#include "gxltypes.h"
+#include "gxtypes.h"
+
+FT_BEGIN_HEADER
+
+/* feat */
+ FT_LOCAL ( FT_Bool )
+ gx_feat_has_feature_type ( GX_Feat feat,
+ FT_UShort feature_type );
+
+/* prop */
+ FT_LOCAL ( FT_UShort )
+ gx_prop_get( GX_Prop prop,
+ FT_Long glyph );
+
+/* lcar */
+ FT_LOCAL( GX_LigCaretClassEntry )
+ gx_lcar_get ( GX_Lcar lcar,
+ FT_UShort glyphID );
+
+/* mort */
+ typedef FT_Error (* GX_Mort_Feature_Func)( GX_MetamorphosisFeatureTable feat_Subtbl,
+ FT_Pointer user );
+ FT_LOCAL( FT_Error ) gx_mort_foreach_feature ( GX_Mort mort,
+ GX_Mort_Feature_Func func,
+ FT_Pointer user );
+ FT_LOCAL( FT_UShort )
+ gx_mort_count_feat_not_in_feat ( GX_Mort mort,
+ GX_Feat feat );
+ FT_LOCAL( FT_Error )
+ gx_mort_substitute_glyph ( GX_Mort mort,
+ GXL_FeaturesRequest request,
+ FTL_Glyphs_Array in,
+ FTL_Glyphs_Array out );
+
+/* morx */
+ typedef FT_Error (* GX_Morx_Feature_Func)( GX_XMetamorphosisFeatureTable feat_Subtbl,
+ FT_Pointer user );
+ FT_LOCAL( FT_Error )
+ gx_morx_foreach_feature ( GX_Morx morx,
+ GX_Morx_Feature_Func func,
+ FT_Pointer user );
+
+ FT_LOCAL( FT_UShort )
+ gx_morx_count_feat_not_in_feat ( GX_Morx morx,
+ GX_Feat feat );
+ FT_LOCAL( FT_Error )
+ gx_morx_substitute_glyph ( GX_Morx morx,
+ GXL_FeaturesRequest request,
+ FTL_Glyphs_Array in,
+ FTL_Glyphs_Array out );
+
+/* kern */
+ FT_LOCAL( FT_Error ) gx_kern_get_pair_kerning ( GX_Kern kern,
+ FT_UShort left_glyph,
+ FT_UShort right_glyph,
+ FTL_Direction dir,
+ FT_Vector* kerning );
+
+ FT_LOCAL( FT_Error ) gx_kern_get_contextual_kerning( GX_Kern kern,
+ FTL_Glyphs_Array garray,
+ FTL_Direction dir,
+ GXL_Initial_State initial_state,
+ FT_Vector * kerning );
+
+/* trak */
+ FT_LOCAL( FT_Error ) gx_trak_get( GX_Trak trak,
+ FT_Fixed track,
+ FT_Fixed size,
+ FTL_Direction dir,
+ FT_FWord* value );
+
+ FT_LOCAL( FT_UShort ) gx_trak_count_name_index( GX_Trak trak );
+ FT_LOCAL( FT_Error ) gx_trak_get_name ( GX_Trak trak,
+ FT_UShort index,
+ FT_UShort * name_index,
+ FTL_Direction * dir,
+ FT_Fixed * track );
+FT_END_HEADER
+
+#endif /* Not def: __GXACCESS_H__ */
+
+
+/* END */
diff --git a/src/gxlayout/gxdemo.c b/src/gxlayout/gxdemo.c
new file mode 100644
index 000000000..713da8e5c
--- /dev/null
+++ b/src/gxlayout/gxdemo.c
@@ -0,0 +1,1217 @@
+/***************************************************************************/
+/* */
+/* gxdemo.c */
+/* */
+/* Demo program for AAT/TrueTypeGX font driver implementation (body). */
+/* */
+/* Copyright 2003 by */
+/* Masatake YAMATO and Redhat K.K. */
+/* */
+/* This file may only be used, */
+/* modified, and distributed under the terms of the FreeType project */
+/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
+/* this file you indicate that you have read the license and */
+/* understand and accept it fully. */
+/* */
+/***************************************************************************/
+
+/***************************************************************************/
+/* Development of the code in this file is support of */
+/* Information-technology Promotion Agency, Japan. */
+/***************************************************************************/
+
+#define _XOPEN_SOURCE
+#include <stdlib.h>
+
+#include <ft2build.h>
+#include FT_GXLAYOUT_H
+#include FT_BBOX_H
+#include FT_OUTLINE_H
+#include FT_INTERNAL_DEBUG_H
+
+#include <stdio.h>
+#include <popt.h>
+#include <glib.h>
+#include <glib/gslist.h>
+#include <glib-object.h>
+#include <gtk/gtk.h>
+#include <errno.h>
+#include <libgnomecanvas/libgnomecanvas.h>
+
+#include "gxdump.h"
+#include "gxfeatreg.h"
+#include "gxtypes.h"
+#include "gxload.h"
+#include "gxaccess.h"
+
+#define DEFAULT_UNIT 1024
+#define BUFFER_LENGTH 1024
+
+static char buffer[BUFFER_LENGTH];
+static GHashTable * setting_buttons = NULL;
+static gulong dump_flags = GX_DUMP_mort|GX_DUMP_morx|GX_DUMP_feat|GX_DUMP_kern;
+static gboolean dump_glyph_metrics = FALSE;
+static GtkAdjustment * gid_spinner_adj;
+static GtkWidget *glyph_canvas;
+
+static GnomeCanvasItem *root_rect_item = NULL;
+static GnomeCanvasItem *bbox_item = NULL;
+static GnomeCanvasItem *h_advance_item = NULL;
+static GnomeCanvasItem *v_advance_item = NULL;
+static GnomeCanvasItem *pixbuf_item = NULL;
+static GSList *div_items = NULL;
+
+static int default_gid = 19;
+
+void create_window ( GX_Face face );
+void destroy_window ( GtkObject * unused, GXL_FeaturesRequest request );
+
+void radio_toggled( GtkToggleButton * toggle, gpointer setting );
+void check_toggled( GtkToggleButton * toggle, gpointer setting);
+void run_layout_engine ( GtkButton * button, gpointer request );
+void reset_feature_request( GtkButton * button, gpointer request );
+void check_table ( GtkToggleButton * toggle_button, gpointer flag);
+void dump_feature_request( GtkButton * button, gpointer request );
+void dump_feature_registry( GtkButton * button, gpointer request );
+void dump_language_id ( GtkButton * button, gpointer face );
+
+void horizontal_radio_toggled( GtkToggleButton * toggle, gpointer request );
+void vertical_radio_toggled( GtkToggleButton * toggle, gpointer request );
+
+void dump_file(FT_Library library, const char * file, gint verbose);
+void dump_face(FT_Face face, const char* file, gint verbose);
+void dump_glyph(FT_Face face, FT_UShort gid, FTL_Direction direction);
+
+void activate_chain_trace( void );
+
+void set_dump_glyph_metrics ( GtkWidget * check_button, gpointer data );
+void render_glyph ( GtkWidget * button, gpointer request );
+
+void set_trace_level( GtkAdjustment * adj, gpointer trace );
+
+#define DUMP_DESC "Supported tables are mort,morx,feat,prop,trak,kern,just,lcar,opbd,bsln,fmtx,fdsc,fvar"
+static const GDebugKey dump_keys[] = {
+ {"mort", GX_DUMP_mort},
+ {"morx", GX_DUMP_morx},
+ {"feat", GX_DUMP_feat},
+ {"prop", GX_DUMP_prop},
+ {"trak", GX_DUMP_trak},
+ {"kern", GX_DUMP_kern},
+ {"just", GX_DUMP_just},
+ {"lcar", GX_DUMP_lcar},
+ {"opbd", GX_DUMP_opbd},
+ {"bsln", GX_DUMP_bsln},
+ {"fmtx", GX_DUMP_fmtx},
+ {"fdsc", GX_DUMP_fdsc},
+ {"fvar", GX_DUMP_fvar}
+};
+
+int
+main(int argc, char ** argv)
+{
+ FT_Library library;
+ FT_Face face;
+ poptContext optCon;
+ int rc;
+ const char * file;
+
+ static char* arg_debug = NULL;
+ static int arg_batch = 0;
+ static int arg_memprof = 0;
+ static int arg_verbose = 0;
+ static int arg_trace_chain = 0;
+
+ const int ndump_keys = sizeof(dump_keys)/sizeof(GDebugKey);
+ struct poptOption optTable [] = {
+ { "trace-chain", '\0', POPT_ARG_NONE, &arg_trace_chain, 0, "Dump chains selection", ""},
+ { "default-gid", '\0', POPT_ARG_INT, &default_gid, 0, "Default GID", ""},
+ { "batch", 'b', POPT_ARG_NONE, &arg_batch, 0, "batch mode", ""},
+ { "table", 't', POPT_ARG_STRING, &arg_debug, 0, DUMP_DESC, "tableName"},
+ { "memprof", 'm', POPT_ARG_NONE, &arg_memprof, 0, "Enter to infinite loop to run under memprof", ""},
+ { "verbose", 'v', POPT_ARG_NONE, &arg_verbose, 0, "Print extra infomation to stdout", ""},
+ POPT_AUTOHELP
+ POPT_TABLEEND
+ };
+ FTL_EngineType engine_type;
+
+ gtk_init(&argc, &argv);
+ optCon = poptGetContext(argv[0], argc, (const char **)argv, optTable, 0);
+ poptSetOtherOptionHelp(optCon, "[options] gxfont\n");
+ rc = poptReadDefaultConfig (optCon, 0);
+ if (rc < 0)
+ {
+ fprintf(stderr, "Fail to read .popt config file: %s\n",
+ poptStrerror(rc));
+ exit (1);
+ }
+ while ((rc = poptGetNextOpt(optCon)) > 0)
+ if (rc != -1)
+ {
+ fprintf(stderr, "Bad argument %s: %s\n",
+ poptBadOption(optCon, POPT_BADOPTION_NOALIAS),
+ poptStrerror(rc));
+ exit (1);
+ }
+
+ if (arg_trace_chain)
+ activate_chain_trace();
+
+ if (FT_Init_FreeType (&library))
+ {
+ fprintf(stderr, "Error in %s\n", "FT_Init_FreeType");
+ exit (1);
+ }
+
+ if (arg_debug)
+ dump_flags = g_parse_debug_string (arg_debug,
+ (GDebugKey *) dump_keys,
+ ndump_keys);
+
+ file = poptGetArg(optCon);
+ if (!file)
+ {
+ poptPrintHelp(optCon, stderr, 0);
+ exit(1);
+ }
+
+ if ( arg_batch )
+ {
+ fprintf(stdout, "<meta>\n");
+ do {
+ dump_file( library, file, arg_verbose );
+ file = poptGetArg(optCon);
+ } while (file);
+ fprintf(stdout, "</meta>\n");
+ goto Exit;
+ }
+
+ if ( FT_New_Face (library, file, 0, &face) )
+ {
+ fprintf(stderr, "Error in %s: %s\n", "FT_New_Face", file);
+ exit (1);
+ }
+
+#if 0
+ if ( FT_HAS_VERTICAL(face) )
+ fprintf(stdout, "Face has vertical infomation\n");
+ else
+ fprintf(stdout, "Face does not have vertical infomation\n");
+#endif /* 0 */
+
+ if (( FTL_Query_EngineType( face, &engine_type ) )
+ || ( engine_type != FTL_TRUETYPEGX_ENGINE ))
+ {
+ fprintf(stderr, "No GX table is existed: %s\n", file);
+ exit ( 1 );
+ }
+ setting_buttons = g_hash_table_new(NULL, NULL);
+ create_window( (GX_Face)face );
+
+ if ( FT_Done_Face ( face ) )
+ fprintf(stderr, "Error in %s: %s\n", "FT_Done_Face", file);
+
+ Exit:
+ if ( FT_Done_FreeType (library) )
+ {
+ fprintf(stderr, "Error in %s\n", "FT_Done_FreeType");
+ exit(1);
+ }
+ if ( arg_memprof || getenv("_MEMPROF_SOCKET") )
+ {
+ fprintf(stderr, "Enter infinite loop for memprof\n");
+ while (1);
+ }
+ return 0;
+}
+
+GtkWidget * create_gx_window( GX_Face face );
+GtkWidget * create_feat_area( GXL_FeaturesRequest request );
+GtkWidget * create_dump_area( GX_Face face,
+ GXL_FeaturesRequest request );
+GtkWidget * create_trace_area(void);
+
+void
+create_window (GX_Face face)
+{
+ GtkWidget * window;
+
+ window = create_gx_window ( face );
+ gtk_widget_show(window);
+ gtk_window_resize( GTK_WINDOW(window), 1, 400);
+ gtk_window_set_title (GTK_WINDOW( window ), ((FT_Face)face)->family_name);
+ gtk_main();
+}
+
+GtkWidget *
+create_gx_window( GX_Face face )
+{
+
+ GtkWidget * window;
+ GtkWidget * feat;
+ GtkWidget * dump;
+ GtkWidget * trace;
+ GtkWidget * vbox;
+ GtkWidget * hbox;
+ GtkWidget * button;
+ GtkWidget * notebook;
+ GtkWidget * label;
+ GXL_FeaturesRequest request;
+ GtkWidget *gid_spinner;
+
+ FTL_New_FeaturesRequest ( (FT_Face)face,
+ (FTL_FeaturesRequest*)&request );
+
+ window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ g_signal_connect (G_OBJECT (window), "destroy",
+ G_CALLBACK ( destroy_window ), request);
+ gtk_container_set_border_width (GTK_CONTAINER (window), 4);
+ notebook = gtk_notebook_new ();
+ gtk_widget_show( notebook );
+ gtk_container_add ( GTK_CONTAINER( window ),
+ notebook );
+
+ /* Features */
+ vbox = gtk_vbox_new ( FALSE, 8 );
+ label = gtk_label_new("Features");
+ gtk_notebook_append_page ( GTK_NOTEBOOK(notebook),
+ vbox,
+ label );
+
+ gtk_widget_show( vbox );
+
+ feat = create_feat_area ( request );
+ gtk_box_pack_start ( GTK_BOX ( vbox ),
+ feat,
+ TRUE,
+ TRUE,
+ 4 );
+ hbox = gtk_hbox_new ( TRUE, 4 );
+ gtk_box_pack_start ( GTK_BOX ( vbox ),
+ hbox,
+ FALSE,
+ TRUE,
+ 4 );
+ gtk_widget_show( hbox );
+
+ button = gtk_button_new_with_label ("Reset");
+ gtk_widget_show ( button );
+ g_signal_connect ( G_OBJECT( button ), "clicked",
+ G_CALLBACK ( reset_feature_request ), request );
+ gtk_box_pack_start ( GTK_BOX ( hbox ),
+ button,
+ TRUE,
+ TRUE,
+ 4 );
+
+ button = gtk_button_new_with_label ("Run");
+ gtk_widget_show ( button );
+ g_signal_connect ( G_OBJECT( button ), "clicked",
+ G_CALLBACK ( run_layout_engine ), request );
+ gtk_box_pack_start ( GTK_BOX ( hbox ),
+ button,
+ TRUE,
+ TRUE,
+ 4 );
+
+ /* Glyph */
+ vbox = gtk_vbox_new ( FALSE, 8 );
+ label = gtk_label_new("Glyph");
+ gtk_notebook_append_page ( GTK_NOTEBOOK(notebook),
+ vbox,
+ label );
+ gtk_widget_show ( vbox );
+ hbox = gtk_hbox_new ( TRUE, 4 );
+ gtk_box_pack_start ( GTK_BOX ( vbox ),
+ hbox,
+ FALSE,
+ TRUE,
+ 0 );
+ gtk_widget_show ( hbox );
+ gid_spinner_adj = (GtkAdjustment *) gtk_adjustment_new ((gdouble)default_gid, 0.0, (gdouble)0xFFFF,
+ 1.0, 5.0, 5.0);
+ gid_spinner = gtk_spin_button_new (gid_spinner_adj, 1.0, 0);
+ gtk_box_pack_start ( GTK_BOX ( hbox ),
+ gid_spinner,
+ FALSE,
+ TRUE,
+ 0 );
+ gtk_widget_show(gid_spinner);
+
+ button = gtk_button_new_with_label("Render");
+ gtk_box_pack_start ( GTK_BOX ( hbox ),
+ button,
+ FALSE,
+ TRUE,
+ 0 );
+ g_signal_connect( button,
+ "clicked",
+ G_CALLBACK( render_glyph ),
+ request );
+
+ gtk_widget_push_visual (gdk_rgb_get_visual ());
+ gtk_widget_push_colormap (gdk_rgb_get_cmap ());
+ glyph_canvas = gnome_canvas_new_aa ();
+ gtk_widget_pop_colormap ();
+ gtk_widget_pop_visual ();
+ gtk_box_pack_start ( GTK_BOX ( vbox ),
+ glyph_canvas,
+ TRUE,
+ TRUE,
+ 4 );
+ gnome_canvas_set_pixels_per_unit(GNOME_CANVAS(glyph_canvas),0.2);
+ gnome_canvas_set_scroll_region(GNOME_CANVAS(glyph_canvas),0.0,0.0,
+ (double)DEFAULT_UNIT,
+ (double)-DEFAULT_UNIT );
+ gtk_widget_show( glyph_canvas );
+
+ gtk_widget_show ( button );
+
+ /* Styles */
+ vbox = gtk_vbox_new ( FALSE, 8 );
+ label = gtk_label_new("Styles");
+ gtk_notebook_append_page ( GTK_NOTEBOOK(notebook),
+ vbox,
+ label );
+
+ gtk_widget_show ( vbox );
+
+ /* Variations */
+ vbox = gtk_vbox_new ( FALSE, 8 );
+ label = gtk_label_new("Variations");
+ gtk_notebook_append_page ( GTK_NOTEBOOK(notebook),
+ vbox,
+ label );
+ /* gtk_widget_show ( vbox ); */
+
+ /* Dump */
+ dump = create_dump_area( face, request );
+ label = gtk_label_new("Dump");
+ gtk_notebook_append_page ( GTK_NOTEBOOK(notebook),
+ dump,
+ label );
+ gtk_widget_show ( dump );
+
+ /* Trace */
+ trace = create_trace_area();
+ label = gtk_label_new("Trace");
+ gtk_notebook_append_page ( GTK_NOTEBOOK(notebook),
+ trace,
+ label );
+ gtk_widget_show ( trace );
+
+ return window;
+}
+
+GtkWidget *
+create_feat_area( GXL_FeaturesRequest request )
+{
+ GtkWidget * features_vbox;
+ GtkWidget * feature_frame;
+ GtkWidget * settings_vbox;
+ GtkWidget * setting_toggle;
+ GtkWidget * setting_radio;
+ GtkWidget * scrolled;
+ GtkWidget * sep;
+
+ gint i_feat, j_string, k_setting;
+ gint nFeatures = GXL_FeaturesRequest_Get_Feature_Count ( request );
+ GXL_Feature feature;
+ FT_SfntName feature_name;
+
+ gint nSettings;
+ GXL_Setting setting;
+ FT_SfntName setting_name;
+
+ char * c_string;
+
+ static GSList * group = NULL;
+
+ scrolled = gtk_scrolled_window_new(NULL, NULL);
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (scrolled),
+ GTK_POLICY_NEVER,
+ GTK_POLICY_AUTOMATIC );
+ features_vbox = gtk_vbox_new( FALSE, 4 );
+ gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW( scrolled ),
+ features_vbox );
+
+ feature_frame = gtk_frame_new ( "Direction" );
+ gtk_box_pack_start( GTK_BOX( features_vbox ),
+ feature_frame,
+ FALSE,
+ FALSE,
+ 2 );
+ settings_vbox = gtk_vbox_new( FALSE, 4 );
+ gtk_container_add( GTK_CONTAINER( feature_frame ),
+ settings_vbox );
+
+ setting_radio = gtk_radio_button_new_with_label( group, "Horizontal" );
+ gtk_box_pack_start( GTK_BOX(settings_vbox),
+ setting_radio,
+ FALSE,
+ FALSE,
+ 0 );
+ g_signal_connect ( setting_radio,
+ "toggled",
+ G_CALLBACK(horizontal_radio_toggled),
+ request );
+ group = gtk_radio_button_get_group( GTK_RADIO_BUTTON (setting_radio) );
+
+ setting_radio = gtk_radio_button_new_with_label( group, "Vertical" );
+ gtk_box_pack_start( GTK_BOX(settings_vbox),
+ setting_radio,
+ FALSE,
+ FALSE,
+ 0 );
+ g_signal_connect ( setting_radio,
+ "toggled",
+ G_CALLBACK(vertical_radio_toggled),
+ request );
+
+ sep = gtk_hseparator_new();
+ gtk_box_pack_start( GTK_BOX(features_vbox),
+ sep,
+ FALSE,
+ FALSE,
+ 0 );
+
+ for ( i_feat = 0; i_feat < nFeatures; i_feat++ )
+ {
+ group = NULL;
+ feature = GXL_FeaturesRequest_Get_Feature ( request, i_feat );
+ if ( GXL_Feature_Get_Name ( feature, 0, 0, 0, &feature_name ) )
+ {
+ fprintf(stderr, "Cannot find name\n");
+ exit (1);
+ }
+
+ c_string = g_new(char, feature_name.string_len + 1 );
+ c_string[feature_name.string_len] = '\0';
+ for (j_string = 0; j_string < feature_name.string_len; j_string++)
+ c_string[j_string] = feature_name.string[j_string];
+ feature_frame = gtk_frame_new ( c_string );
+ g_free(c_string);
+ gtk_box_pack_start( GTK_BOX( features_vbox ),
+ feature_frame,
+ FALSE,
+ FALSE,
+ 2 );
+ settings_vbox = gtk_vbox_new( FALSE, 4 );
+ gtk_container_add( GTK_CONTAINER( feature_frame ),
+ settings_vbox );
+ nSettings = GXL_Feature_Get_Setting_Count( feature );
+ for ( k_setting = 0; k_setting < nSettings; k_setting++ )
+ {
+ setting = GXL_Feature_Get_Setting( feature, k_setting );
+ if ( GXL_Setting_Get_Name ( setting, 0, 0, 0, &setting_name ) )
+ {
+ fprintf (stderr, "Cannot find setting name\n");
+ exit (1);
+ }
+ c_string = g_new(char, setting_name.string_len + 1 );
+ c_string[setting_name.string_len] = '\0';
+ for (j_string = 0; j_string < setting_name.string_len; j_string++)
+ c_string[j_string] = setting_name.string[j_string];
+ if ( GXL_Feature_Is_Setting_Exclusive (feature) )
+ {
+ setting_radio = gtk_radio_button_new_with_label(group, c_string);
+ group = gtk_radio_button_get_group( GTK_RADIO_BUTTON (setting_radio) );
+ g_free(c_string);
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(setting_radio),
+ GXL_Setting_Get_State (setting) );
+ g_signal_connect ( setting_radio,
+ "toggled",
+ G_CALLBACK(radio_toggled),
+ setting );
+ gtk_box_pack_start( GTK_BOX(settings_vbox),
+ setting_radio,
+ FALSE,
+ FALSE,
+ 0 );
+ gtk_container_set_border_width (GTK_CONTAINER (setting_radio), 2);
+ g_hash_table_insert ( setting_buttons, setting_radio, setting );
+ }
+ else
+ {
+ setting_toggle = gtk_check_button_new_with_label(c_string);
+ g_free(c_string);
+ gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON(setting_toggle),
+ GXL_Setting_Get_State (setting) );
+ g_signal_connect ( setting_toggle,
+ "toggled",
+ G_CALLBACK(check_toggled),
+ setting );
+ gtk_box_pack_start( GTK_BOX(settings_vbox),
+ setting_toggle,
+ FALSE,
+ FALSE,
+ 0 );
+ gtk_container_set_border_width (GTK_CONTAINER (setting_toggle), 2);
+ g_hash_table_insert ( setting_buttons, setting_toggle, setting );
+ }
+ }
+ group = NULL;
+ }
+ gtk_widget_show_all(scrolled);
+ return scrolled;
+}
+
+void dump_face_cb( GtkButton * button, gpointer face );
+
+GtkWidget *
+create_dump_area( GX_Face face,
+ GXL_FeaturesRequest request )
+
+{
+ GtkWidget * vbox = gtk_vbox_new ( FALSE, 0 );
+ GtkWidget * button;
+ GtkWidget * frame;
+ GtkWidget * dump_face_vbox;
+ GtkWidget * dump_tables_vbox;
+ GtkWidget * check_button;
+
+ /* Language ID */
+ button = gtk_button_new_with_label("Dump Language ID");
+ gtk_box_pack_start ( GTK_BOX ( vbox ),
+ button,
+ FALSE,
+ TRUE,
+ 0 );
+ g_signal_connect ( G_OBJECT( button ), "clicked",
+ G_CALLBACK ( dump_language_id ), face );
+ gtk_widget_show ( button );
+
+ /* Feature Request */
+ button = gtk_button_new_with_label("Dump Feature Request");
+ gtk_box_pack_start ( GTK_BOX ( vbox ),
+ button,
+ FALSE,
+ TRUE,
+ 0 );
+ g_signal_connect ( G_OBJECT( button ), "clicked",
+ G_CALLBACK ( dump_feature_request ), request );
+ gtk_widget_show ( button );
+
+
+ /* Feature Registry */
+ button = gtk_button_new_with_label("Dump Feature Registry");
+ gtk_box_pack_start ( GTK_BOX ( vbox ),
+ button,
+ FALSE,
+ TRUE,
+ 0 );
+ g_signal_connect ( G_OBJECT( button ), "clicked",
+ G_CALLBACK ( dump_feature_registry ), NULL );
+ gtk_widget_show ( button );
+
+ /* Dump Glyph Metrics */
+ button = gtk_check_button_new_with_label ("Enable to Dump Glyph Metrics");
+ gtk_box_pack_start ( GTK_BOX ( vbox ),
+ button,
+ FALSE,
+ TRUE,
+ 0 );
+ g_signal_connect ( G_OBJECT( button ), "toggled",
+ G_CALLBACK ( set_dump_glyph_metrics ), &dump_glyph_metrics );
+ gtk_widget_show ( button );
+
+ /* Dump tables */
+ frame = gtk_frame_new ( "Dump Tables" );
+ gtk_box_pack_start( GTK_BOX( vbox ), frame, FALSE, FALSE, 2 );
+ dump_face_vbox = gtk_vbox_new ( FALSE, 0 );
+ gtk_container_add( GTK_CONTAINER( frame ), dump_face_vbox );
+ dump_tables_vbox = gtk_vbox_new ( FALSE, 0 );
+ gtk_container_add( GTK_CONTAINER( dump_face_vbox ), dump_tables_vbox );
+
+#define MAKE_CHECK_BUTTON(tag) \
+ check_button = gtk_check_button_new_with_label(#tag); \
+ gtk_container_add( GTK_CONTAINER( dump_tables_vbox ), check_button ); \
+ gtk_widget_show(check_button); \
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(check_button), \
+ ( dump_flags & GX_DUMP_##tag )? TRUE: FALSE ); \
+ g_signal_connect ( G_OBJECT( check_button ), \
+ "toggled", \
+ G_CALLBACK(check_table), \
+ GINT_TO_POINTER(GX_DUMP_##tag) )
+
+ MAKE_CHECK_BUTTON(mort);
+ MAKE_CHECK_BUTTON(morx);
+ MAKE_CHECK_BUTTON(feat);
+ MAKE_CHECK_BUTTON(prop);
+ MAKE_CHECK_BUTTON(trak);
+ MAKE_CHECK_BUTTON(kern);
+ MAKE_CHECK_BUTTON(just);
+ MAKE_CHECK_BUTTON(lcar);
+ MAKE_CHECK_BUTTON(opbd);
+ MAKE_CHECK_BUTTON(bsln);
+ MAKE_CHECK_BUTTON(fmtx);
+ MAKE_CHECK_BUTTON(fdsc);
+ MAKE_CHECK_BUTTON(fvar);
+
+ button = gtk_button_new_with_label("Dump Font Tables");
+ g_signal_connect (G_OBJECT (button), "clicked",
+ G_CALLBACK ( dump_face_cb ), face);
+ gtk_container_add( GTK_CONTAINER( dump_face_vbox ), button );
+ gtk_widget_show ( button );
+
+ gtk_widget_show ( dump_tables_vbox );
+ gtk_widget_show ( dump_face_vbox );
+ gtk_widget_show ( frame );
+
+ return vbox;
+}
+
+GtkWidget*
+create_trace_area(void)
+{
+ int count = FT_Trace_Get_Count();
+ int i;
+ GtkWidget * vbox, *hbox;
+ GtkWidget * label;
+ GtkWidget * scrolled;
+ const char * label_string;
+ GtkObject * adj;
+ GtkWidget * spinner;
+ int level;
+
+ scrolled = gtk_scrolled_window_new(NULL, NULL);
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (scrolled),
+ GTK_POLICY_NEVER,
+ GTK_POLICY_AUTOMATIC );
+
+ vbox = gtk_vbox_new ( TRUE, 1 );
+ for ( i = 0; i < count; i++ )
+ {
+ hbox = gtk_hbox_new( TRUE, 2 );
+ label_string = FT_Trace_Get_Name( i );
+ label = gtk_label_new( label_string );
+ gtk_container_add(GTK_CONTAINER(hbox), label);
+ gtk_widget_show(label);
+
+#ifdef FT_DEBUG_LEVEL_TRACE
+ level = (gdouble)ft_trace_levels[i];
+#else
+ level = 0;
+#endif /* FT_DEBUG_LEVEL_TRACE */
+
+ adj = gtk_adjustment_new(level,
+ 0.0, (gdouble)7, 1.0, 1.0, 1.0);
+ spinner = gtk_spin_button_new( GTK_ADJUSTMENT(adj), 1.0, 0 );
+ gtk_spin_button_set_range(GTK_SPIN_BUTTON(spinner), 0.0, 7.0);
+ gtk_box_pack_end( GTK_BOX(hbox), spinner, FALSE, TRUE, 0 );
+ gtk_widget_show(spinner);
+ g_signal_connect( G_OBJECT(adj),
+ "value_changed",
+ G_CALLBACK(set_trace_level),
+ GINT_TO_POINTER(i));
+ gtk_container_add( GTK_CONTAINER(vbox), hbox);
+ gtk_widget_show(hbox);
+ }
+ gtk_widget_show(vbox);
+ gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW( scrolled ),
+ vbox );
+ return scrolled;
+}
+
+void
+dump_face_cb( GtkButton * button, gpointer face )
+{
+ dump_face( face, ((FT_Face)face)->family_name, 1);
+}
+
+void
+check_table ( GtkToggleButton * toggle_button, gpointer flag)
+{
+ if ( gtk_toggle_button_get_active( toggle_button ) )
+ dump_flags |= GPOINTER_TO_INT(flag);
+ else
+ dump_flags &= (~(GPOINTER_TO_INT(flag)));
+}
+
+void
+destroy_window ( GtkObject * unused, GXL_FeaturesRequest request )
+{
+ FTL_Done_FeaturesRequest ( (FTL_FeaturesRequest)request );
+ gtk_main_quit();
+}
+
+void
+radio_toggled( GtkToggleButton * toggle, gpointer setting )
+{
+ gboolean state = gtk_toggle_button_get_active(toggle);
+ GXL_Setting_Set_State( setting, state );
+}
+
+void
+check_toggled( GtkToggleButton * toggle, gpointer setting )
+{
+ gboolean state = gtk_toggle_button_get_active(toggle);
+ GXL_Setting_Set_State( setting, state );
+}
+
+void
+run_layout_engine ( GtkButton * button, gpointer request )
+{
+ FTL_Glyphs_Array in, out;
+ FT_Face face = ((FTL_FeaturesRequest)request)->font->face;
+ FT_Memory memory = face->driver->root.memory;
+
+ char * tmp, *next;
+ long value, length = 0, i;
+
+ printf( "Input: ");
+ tmp = fgets(buffer, BUFFER_LENGTH, stdin);
+ if ( !tmp )
+ {
+ fprintf(stderr, "Fail to read string\n");
+ return;
+ }
+
+ FTL_New_Glyphs_Array ( memory, &in );
+ FTL_New_Glyphs_Array ( memory, &out );
+
+ tmp = buffer;
+ while ( 1 )
+ {
+ value = strtol(tmp, &next, 10);
+ if (( value == 0 ) && ( tmp == next ))
+ break;
+ else
+ {
+ length++;
+ tmp = next;
+ }
+ }
+ FTL_Set_Glyphs_Array_Length ( in, length );
+
+ tmp = buffer;
+ for ( i = 0; i < length; i++ )
+ in->glyphs[i].gid = (FT_UShort)strtol(tmp, &tmp, 10);
+
+ FTL_Activate_FeaturesRequest( request );
+ FTL_Substitute_Glyphs ( face, in, out );
+
+ fprintf(stdout, "Substituted: ");
+ for ( i = 0; i < length; i++ )
+ fprintf(stdout, "%u%s ", out->glyphs[i].gid,
+ (out->glyphs[i].gid == 0xFFFF)? "<empty>": "");
+ fprintf(stdout, "\n");
+
+ if ( dump_glyph_metrics )
+ {
+ fprintf(stdout, "\nGlyph Metrics\n");
+ fprintf(stdout, "---------------\n");
+ for ( i = 0; i < length; i++ )
+ dump_glyph(face,
+ out->glyphs[i].gid,
+ FTL_Get_FeaturesRequest_Direction((FTL_FeaturesRequest)request));
+ }
+
+ FTL_Done_Glyphs_Array ( in );
+ FTL_Done_Glyphs_Array ( out );
+}
+
+void
+reflect_request ( gpointer key, gpointer value, gpointer user_data );
+void
+reset_feature_request( GtkButton * button, gpointer request )
+{
+ FTL_Reset_FeaturesRequest( request );
+ g_hash_table_foreach(setting_buttons, reflect_request, NULL);
+}
+void
+reflect_request ( gpointer key, gpointer value, gpointer user_data )
+{
+ GtkWidget * button = GTK_WIDGET(key);
+ GXL_Setting setting = value;
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(button),
+ GXL_Setting_Get_State (setting) );
+}
+
+void
+dump_feature_request( GtkButton * button, gpointer request )
+{
+ gxl_features_request_dump(request, stdout);
+}
+
+void
+dump_feature_registry( GtkButton * button, gpointer request )
+{
+ fprintf(stdout, "Contents of registry data base\n");
+ fprintf(stdout, "------------------------------\n");
+ gx_feature_registory_dump(stdout);
+}
+
+void
+horizontal_radio_toggled( GtkToggleButton * toggle,
+ gpointer request )
+{
+ if ( gtk_toggle_button_get_active( toggle ) )
+ FTL_Set_FeaturesRequest_Direction ( request,
+ FTL_HORIZONTAL );
+
+}
+
+void
+vertical_radio_toggled( GtkToggleButton * toggle,
+ gpointer request )
+{
+ if ( gtk_toggle_button_get_active( toggle ) )
+ FTL_Set_FeaturesRequest_Direction ( request,
+ FTL_VERTICAL );
+
+}
+
+void
+dump_face( FT_Face face, const char * file, gint verbose)
+{
+ FT_Bool gx_p;
+ FTL_EngineType engine_type;
+
+ gx_p = !((FTL_Query_EngineType (face, &engine_type))
+ || (engine_type != FTL_TRUETYPEGX_ENGINE));
+ if ( verbose )
+ {
+ if ( gx_p )
+ fprintf(stderr, "ok\n");
+ else if (((TT_Face)face)->extra.data)
+ fprintf(stderr, "failed(no gx, cff)\n");
+ else
+ fprintf(stderr, "failed(no gx)\n");
+ }
+
+ if ( gx_p )
+ gx_face_dump(face, dump_flags, file);
+
+ fflush ( stdout );
+}
+
+void
+dump_file( FT_Library library, const char * file, gint verbose)
+{
+ FT_Face face;
+
+ if ( FT_New_Face (library, file, 0, &face) )
+ {
+ fprintf(stderr, "Error in %s: %s\n", "FT_New_Face", file);
+ return;
+ }
+
+ if ( verbose )
+ fprintf(stderr, "loading %s...", file);
+ /* dump_language_id( NULL, face ); */
+ dump_face( face, file, verbose );
+ if ( FT_Done_Face ( face ) )
+ fprintf(stderr, "Error in %s: %s\n", "FT_Done_Face", file);
+}
+
+void
+dump_language_id ( GtkButton * unused, gpointer face )
+{
+ /* See ttnameid.h */
+ FT_CharMap * charmaps = ((FT_Face)face)->charmaps;
+ FT_Int i, num_charmaps = ((FT_Face)face)->num_charmaps;
+ FT_ULong langid;
+
+ fprintf(stdout, "Laguage ID for the charmaps in the face(see ttnameid.h)\n");
+ fprintf(stdout, "---------------------------------------\n");
+
+ for ( i = 0; i < num_charmaps; i++ )
+ {
+ langid = FT_Get_CMap_Language_ID ( charmaps[i] );
+ switch ( i )
+ {
+ case 0:
+ fprintf(stdout, "Laguage ID for the 1st charmap: %lu\n", langid );
+ break;
+ case 1:
+ fprintf(stdout, "Laguage ID for the 2nd charmap: %lu\n", langid );
+ break;
+ case 2:
+ fprintf(stdout, "Laguage ID for the 3rd charmap: %lu\n", langid );
+ break;
+ default:
+ fprintf(stdout, "Laguage ID for the %dth charmap: %lu\n", i, langid );
+ }
+ }
+}
+
+void
+activate_chain_trace( void )
+{
+ char * tmp = getenv("FT2_DEBUG");
+ if ( !tmp )
+ tmp = g_strdup("FT2_DEBUG=gxchain:6");
+ else
+ tmp = g_strconcat (tmp, " gxchain:6", NULL);
+ putenv(tmp);
+}
+
+void
+dump_glyph(FT_Face face, FT_UShort gid, FTL_Direction dir)
+{
+ FT_Int32 vmask;
+ FT_BBox bbox;
+ FT_UShort i, ligcount, div, new_div;
+
+ fprintf(stdout, "gid: %u\n", gid);
+
+ if ( gid == 0xFFFF )
+ {
+ fprintf(stdout, "\t<null glyph>\n");
+ return ;
+ }
+
+ ligcount = FTL_Get_LigatureCaret_Count ( face, gid );
+ vmask = (dir == FTL_VERTICAL)? FT_LOAD_VERTICAL_LAYOUT: 0;
+ FT_Load_Glyph (face, gid,
+ vmask | FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP);
+
+ FT_Outline_Get_CBox (&face->glyph->outline, &bbox);
+
+ if ( ligcount == 0 )
+ {
+ fprintf(stdout, "\twidth: %g\n\theight: %g\n",
+ (double)bbox.xMax - (double)bbox.xMin,
+ (double)bbox.yMax - (double)bbox.yMin );
+ fprintf(stdout, "\tbbox: [xmin: %g ymin: %g xmax: %g ymax: %g]\n",
+ (double)bbox.xMin, (double)bbox.yMin, (double)bbox.xMax, (double)bbox.yMax);
+ }
+ else
+ {
+ div = bbox.xMin;
+ for ( i = 0; i < ligcount; i++ )
+ {
+ new_div = FTL_Get_LigatureCaret_Division( face, gid, i );
+ fprintf(stdout, "\twidth[%d]: %u\n\theight[%d]: %g\n",
+ i, new_div - div,
+ i, (double)bbox.yMax - (double)bbox.yMin );
+ fprintf(stdout, "\tbbox[%d]: [xmin: %g ymin: %g xmax: %g ymax: %g]\n",
+ i, (double)div, (double)bbox.yMin, (double)new_div, (double)bbox.yMax);
+ div = new_div;
+ fprintf(stdout, "\t----------------\n");
+ }
+ fprintf(stdout, "\twidth[%d]: %g\n\theight[%d]: %g\n",
+ i, (double)bbox.xMax - (double)div,
+ i, (double)bbox.yMax - (double)bbox.yMin );
+ fprintf(stdout, "\tbbox[%d]: [xmin: %g ymin: %g xmax: %g ymax: %g]\n",
+ i, (double)div, (double)bbox.yMin, (double)bbox.xMax, (double)bbox.yMax);
+ }
+}
+
+void
+set_dump_glyph_metrics ( GtkWidget * check_button, gpointer data )
+{
+ *(gboolean*)data = gtk_toggle_button_get_active ( GTK_TOGGLE_BUTTON(check_button) );
+}
+
+void
+render_glyph ( GtkWidget * button, gpointer request )
+{
+ FT_Error error;
+ GnomeCanvasGroup *root = gnome_canvas_root(GNOME_CANVAS(glyph_canvas));
+ GnomeCanvasItem *div_item;
+ GdkPixbuf *pixbuf;
+
+ FT_Face face = ((FTL_FeaturesRequest)request)->font->face;
+ FTL_Direction dir = FTL_Get_FeaturesRequest_Direction((FTL_FeaturesRequest)request);
+ FT_UShort gid = (FT_UShort)gtk_adjustment_get_value(gid_spinner_adj);
+
+ FT_Int32 vmask;
+ FT_BBox bbox;
+ FT_UShort i, ligcount, div;
+ double affine[6] = {1.0, 0.0, 0.0, -1.0, 0.0, 0.0};
+ double affine_with_bearing[6] = {1.0, 0.0, 0.0, 1.0, 0.0, 0.0};
+ double factor = (double)DEFAULT_UNIT/(double)face->units_per_EM;
+
+ if ( dump_glyph_metrics )
+ dump_glyph ( face, gid, dir );
+
+ if ( pixbuf_item )
+ {
+ gtk_object_destroy( GTK_OBJECT(pixbuf_item) );
+ pixbuf_item = NULL;
+ }
+ if ( root_rect_item )
+ gtk_object_destroy( GTK_OBJECT(root_rect_item) );
+ if ( bbox_item )
+ gtk_object_destroy( GTK_OBJECT(bbox_item) );
+ if ( h_advance_item )
+ gtk_object_destroy( GTK_OBJECT(h_advance_item) );
+ if ( v_advance_item )
+ gtk_object_destroy( GTK_OBJECT(v_advance_item) );
+
+ if ( div_items )
+ {
+ GSList * tmp;
+ for ( tmp = div_items; tmp; tmp = tmp->next )
+ gtk_object_destroy( tmp->data );
+ g_slist_free ( div_items );
+ div_items = NULL;
+ }
+
+ error = FT_Set_Pixel_Sizes(face, 0, DEFAULT_UNIT );
+ if ( error )
+ {
+ fprintf(stderr, "Fail in FT_Set_Pixel_Sizes\n");
+ return ;
+ }
+ vmask = (dir == FTL_VERTICAL)? FT_LOAD_VERTICAL_LAYOUT: 0;
+ error = FT_Load_Glyph (face, gid,
+ vmask | FT_LOAD_NO_BITMAP);
+ if ( error )
+ {
+ fprintf(stderr, "Fail in FT_Load_Glyph[0]\n");
+ return ;
+ }
+ error = FT_Render_Glyph( face->glyph, FT_RENDER_MODE_NORMAL );
+ if ( error )
+ {
+ fprintf(stderr, "Fail in FT_Render_Glyph\n");
+ return ;
+ }
+#if 0
+ fprintf(stdout, "gid: %d row: %d, width: %d, pitch: %d\n",
+ gid,
+ face->glyph->bitmap.rows, face->glyph->bitmap.width,
+ face->glyph->bitmap.pitch);
+#endif /* 0 */
+
+ if ( face->glyph->bitmap.width == 0 )
+ goto IGNORE_PIXBUF;
+
+ pixbuf = gdk_pixbuf_new( GDK_COLORSPACE_RGB,
+ TRUE,
+ 8,
+ face->glyph->bitmap.width,
+ face->glyph->bitmap.rows );
+
+ {
+ int x, y;
+ unsigned char src;
+ unsigned char* src_buffer;
+ guchar *dist_buffer = gdk_pixbuf_get_pixels (pixbuf);
+ guchar * dist;
+ int rowstride = gdk_pixbuf_get_rowstride (pixbuf);
+
+ for ( y = 0; y < face->glyph->bitmap.rows; y++ )
+ {
+ src_buffer = &(face->glyph->bitmap.buffer[y*face->glyph->bitmap.pitch]);
+ for (x = 0; x < face->glyph->bitmap.width; x++ )
+ {
+ src = src_buffer[x];
+ dist = dist_buffer + y * rowstride + x * 4;
+ dist[0] = dist[1] = dist[2] = 255 - src;
+
+ if (255 - src)
+ dist[3] = 0;
+ else
+ dist[3] = 255;
+ }
+ }
+ }
+ pixbuf_item = gnome_canvas_item_new(root,
+ GNOME_TYPE_CANVAS_PIXBUF,
+ "pixbuf", pixbuf,
+ NULL);
+ g_object_unref(pixbuf);
+
+ IGNORE_PIXBUF:
+ error = FT_Load_Glyph (face, gid,
+ vmask | FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP);
+ if ( error )
+ {
+ fprintf(stderr, "Fail in FT_Load_Glyph[1]\n");
+ return ;
+ }
+
+ FT_Outline_Get_CBox (&face->glyph->outline, &bbox);
+ if ( error )
+ {
+ fprintf(stderr, "Fail in FT_Outline_Get_CBox\n");
+ return ;
+ }
+
+ root_rect_item = gnome_canvas_item_new(root,
+ GNOME_TYPE_CANVAS_RECT,
+ "x1", (double)0,
+ "y1", (double)0,
+ "x2", (double)DEFAULT_UNIT,
+ "y2", (double)DEFAULT_UNIT,
+ "outline_color", "black",
+ NULL);
+ gnome_canvas_item_affine_relative( root_rect_item, affine );
+
+ affine[0] *= factor;
+ affine[3] *= factor;
+
+ h_advance_item = gnome_canvas_item_new( root,
+ GNOME_TYPE_CANVAS_RECT,
+ "x1", (double)0,
+ "y1", (double)0,
+ "x2", (double)face->glyph->metrics.horiAdvance,
+ "y2", (double)0,
+ "outline_color", "red",
+ NULL);
+ gnome_canvas_item_affine_relative( h_advance_item, affine );
+
+ {
+ /* Next line is workaround against libart(?)'s bug */
+ double vertAdvance = ((face->glyph->metrics.vertAdvance)/2)*2.0;
+ v_advance_item = gnome_canvas_item_new( root,
+ GNOME_TYPE_CANVAS_RECT,
+ "x1", (double)0,
+ "y1", (double)0,
+ "x2", (double)0,
+ "y2", (double)vertAdvance,
+ "outline_color", "red",
+ NULL);
+ }
+ gnome_canvas_item_affine_relative( v_advance_item, affine );
+
+ bbox_item = gnome_canvas_item_new(root,
+ GNOME_TYPE_CANVAS_RECT,
+ "x1", (double)bbox.xMin,
+ "y1", (double)bbox.yMin,
+ "x2", (double)bbox.xMax,
+ "y2", (double)bbox.yMax,
+ "outline_color", "blue",
+ NULL);
+ gnome_canvas_item_affine_relative( bbox_item, affine );
+
+ ligcount = FTL_Get_LigatureCaret_Count ( face, gid );
+ for ( i = 0; i < ligcount; i++ )
+ {
+ /* Here, we will ignore the direction. */
+ div = FTL_Get_LigatureCaret_Division( face, gid, i );
+ div_item = gnome_canvas_item_new(gnome_canvas_root(GNOME_CANVAS(glyph_canvas)),
+ GNOME_TYPE_CANVAS_RECT,
+ "x1", (double)div,
+ "y1", (double)0,
+ "x2", (double)div,
+ "y2", (double)DEFAULT_UNIT,
+ "outline_color", "red",
+ NULL);
+ gnome_canvas_item_affine_relative( div_item, affine );
+ div_items = g_slist_append ( div_items, div_item );
+ }
+
+ if ( pixbuf_item )
+ {
+ affine_with_bearing[4] = (double)bbox.xMin * factor;
+ affine_with_bearing[5] = -(double)bbox.yMax * factor;
+ gnome_canvas_item_affine_relative( pixbuf_item, affine_with_bearing );
+ }
+}
+
+void
+set_trace_level( GtkAdjustment * adj, gpointer trace )
+{
+ gint index = GPOINTER_TO_INT(trace);
+ gint level = (gint)gtk_adjustment_get_value(adj);
+#ifdef FT_DEBUG_LEVEL_TRACE
+ ft_trace_levels[index] = level;
+#endif /* FT_DEBUG_LEVEL_TRACE */
+}
+
+
+/* END */
diff --git a/src/gxlayout/gxdriver.c b/src/gxlayout/gxdriver.c
new file mode 100644
index 000000000..c369ca32d
--- /dev/null
+++ b/src/gxlayout/gxdriver.c
@@ -0,0 +1,101 @@
+/***************************************************************************/
+/* */
+/* gxdriver.c */
+/* */
+/* AAT/TrueTypeGX font driver implementation (body). */
+/* */
+/* Copyright 2003 by */
+/* Masatake YAMATO and Redhat K.K. */
+/* */
+/* This file may only be used, */
+/* modified, and distributed under the terms of the FreeType project */
+/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
+/* this file you indicate that you have read the license and */
+/* understand and accept it fully. */
+/* */
+/***************************************************************************/
+
+/***************************************************************************/
+/* Development of the code in this file is support of */
+/* Information-technology Promotion Agency, Japan. */
+/***************************************************************************/
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include FT_INTERNAL_DEBUG_H
+#include "gxdriver.h"
+#include "gxobjs.h"
+
+ /*************************************************************************/
+ /* */
+ /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
+ /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
+ /* messages during execution. */
+ /* */
+#undef FT_COMPONENT
+#define FT_COMPONENT trace_gxdriver
+
+ /*************************************************************************
+ * gx_driver_class is not initialized statically but dynamically.
+ * -----------------------------------------------------------------------
+ * Almost all fields should be initialized in gxobjs.c::gx_driver_init.
+ *************************************************************************/
+
+ FT_CALLBACK_TABLE_DEF
+ const FT_Driver_ClassRec gx_driver_class =
+ {
+ /* FT_Module_Class */
+ {
+ /* module_flags, copyied from ttdriver.c */
+ FT_MODULE_FONT_DRIVER |
+ FT_MODULE_DRIVER_SCALABLE |
+#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
+ FT_MODULE_DRIVER_HAS_HINTER,
+#else
+ 0,
+#endif
+ /* module_size, copyied from ttdriver.c */
+ sizeof (GX_DriverRec),
+ /* module_name */
+ "gx",
+ /* module_version */
+ 0x10000L,
+ /* module_requires */
+ 0x20000L,
+
+ /* module_interface */
+ NULL,
+
+ /* module_init */
+ (FT_Module_Constructor) gx_driver_init,
+
+ /* module_done */
+ (FT_Module_Destructor) NULL,
+
+ /* get_interface */
+ (FT_Module_Requester) NULL,
+ },
+
+ /* now the specific driver fields */
+ 0,
+ 0,
+ 0,
+
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+
+ NULL,
+ NULL,
+
+ NULL,
+
+ NULL,
+ NULL,
+ NULL,
+ };
+
+/* END */
diff --git a/src/gxlayout/gxdriver.h b/src/gxlayout/gxdriver.h
new file mode 100644
index 000000000..94b768685
--- /dev/null
+++ b/src/gxlayout/gxdriver.h
@@ -0,0 +1,42 @@
+/***************************************************************************/
+/* */
+/* gxdriver.h */
+/* */
+/* High-level AAT/TrueTypeGX driver interface (specification). */
+/* */
+/* Copyright 2003 by */
+/* Masatake YAMATO and Redhat K.K. */
+/* */
+/* This file may only be used, */
+/* modified, and distributed under the terms of the FreeType project */
+/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
+/* this file you indicate that you have read the license and */
+/* understand and accept it fully. */
+/* */
+/***************************************************************************/
+
+/***************************************************************************/
+/* Development of the code in this file is support of */
+/* Information-technology Promotion Agency, Japan. */
+/***************************************************************************/
+
+#ifndef __GXDRIVER_H__
+#define __GXDRIVER_H__
+
+
+#include <ft2build.h>
+#include FT_INTERNAL_DRIVER_H
+
+
+FT_BEGIN_HEADER
+
+
+ FT_CALLBACK_TABLE
+ const FT_Driver_ClassRec gx_driver_class;
+
+FT_END_HEADER
+
+#endif /* __GXDRIVER_H__ */
+
+
+/* END */
diff --git a/src/gxlayout/gxdump.c b/src/gxlayout/gxdump.c
new file mode 100644
index 000000000..0ba9db03b
--- /dev/null
+++ b/src/gxlayout/gxdump.c
@@ -0,0 +1,2818 @@
+/***************************************************************************/
+/* */
+/* gxdump.c */
+/* */
+/* Debug functions for AAT/TrueTypeGX driver (body). */
+/* */
+/* Copyright 2003 by */
+/* Masatake YAMATO and Redhat K.K. */
+/* */
+/* This file may only be used, */
+/* modified, and distributed under the terms of the FreeType project */
+/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
+/* this file you indicate that you have read the license and */
+/* understand and accept it fully. */
+/* */
+/***************************************************************************/
+
+/***************************************************************************/
+/* Development of the code in this file is support of */
+/* Information-technology Promotion Agency, Japan. */
+/***************************************************************************/
+
+#define GX_DEBUG_MORT_LIGATURE_TABLE_LAYOUT 0
+#define GX_DEBUG_MORX_LIGATURE_TABLE_LAYOUT 0
+
+#define FEATREG_MAX 200
+#define SETTING_MAX 30
+
+#include <ft2build.h>
+#include <stdio.h>
+
+#include FT_TYPES_H
+#include FT_FREETYPE_H
+#include FT_TRUETYPE_TAGS_H
+#include FT_INTERNAL_DEBUG_H
+#include FT_SFNT_NAMES_H
+#include FT_INTERNAL_TRUETYPE_TYPES_H
+
+#include "gxtypes.h"
+#include "gxobjs.h"
+#include "gxutils.h"
+#include "gxdump.h"
+#include "gxlookuptbl.h"
+#include "gxstatetbl.h"
+#include "gxaccess.h"
+#include "gxltypes.h"
+
+FT_UShort mort_tmp_firstGlyph = 0;
+FT_UShort mort_tmp_nGlyphs = 0;
+FT_UShort mort_tmp_ligActionTable = 0;
+FT_UShort mort_tmp_componentTable = 0;
+FT_UShort mort_tmp_ligatureTable = 0;
+
+FT_UShort morx_tmp_firstGlyph = 0;
+FT_UShort morx_tmp_nGlyphs = 0;
+FT_UShort morx_tmp_nLigature = 0;
+FT_ULong morx_tmp_ligatureTable = 0;
+FT_UShort morx_tmp_format = 0;
+
+#define GX_XML_FORMAT
+#ifdef GX_XML_FORMAT
+#define INDENT(t) do { \
+ int ttt; \
+ for ( ttt = 2*t; ttt > 0; ttt-- ) \
+ putc(' ', stdout); \
+ } while (0)
+#define INDENTPP(t) do{ INDENT(t); (t)++; } while (0)
+#define INDENTMM(t) do{ (t)--; INDENT(t); } while (0)
+#define NEWLINE() fprintf(stdout, "\n")
+#define NEWLINE10(t, i) do { \
+ if ( (i%10) == 0 ) \
+ { \
+ if ( i != 0 ) \
+ NEWLINE(); \
+ INDENT(t); \
+ } \
+ } while(0);
+
+#define NEWLINEX(t, i, x) do { \
+ if ( (i%x) == 0 ) \
+ { \
+ if ( i != 0 ) \
+ NEWLINE(); \
+ INDENT(t); \
+ } \
+ } while(0);
+
+#define POPEN(t,tag) do { \
+ INDENTPP(t); \
+ fprintf(stdout, "<" #tag ">"); \
+ NEWLINE(); \
+ } while (0)
+
+#define POPEN1(t,tag,prop,val,format) do { \
+ INDENTPP(t); \
+ fprintf(stdout, "<" #tag " " \
+ #prop "=\"" #format "\"" ">\n", val); \
+ } while (0)
+
+#define POPEN2(t,tag,prop1,val1,format1,prop2,val2,format2) do { \
+ INDENTPP(t); \
+ fprintf(stdout, "<" #tag " " \
+ #prop1 "=\"" #format1 "\"" " " \
+ #prop2 "=\"" #format2 "\"" " " \
+ ">\n", val1, val2); \
+ } while (0)
+
+#define POPEN3(t,tag,prop1,val1,format1,prop2,val2,format2,prop3,val3,format3) do { \
+ INDENTPP(t); \
+ fprintf(stdout, "<" #tag " " \
+ #prop1 "=\"" #format1 "\"" " " \
+ #prop2 "=\"" #format2 "\"" " " \
+ #prop3 "=\"" #format3 "\"" " " \
+ ">\n", val1, val2, val3); \
+ } while (0)
+
+#define PCLOSE(t,tag) do { \
+ INDENTMM(t); \
+ fprintf(stdout, "</" #tag ">\n"); \
+ } while (0)
+
+#define PTAG(t,xmltag,valuetag) do { \
+ INDENT(t); \
+ fprintf(stdout, "<" #xmltag ">" "%c%c%c%c" "</" #xmltag ">\n", \
+ (char)(0xff & (valuetag >> 24)), \
+ (char)(0xff & (valuetag >> 16)), \
+ (char)(0xff & (valuetag >> 8)), \
+ (char)(0xff & (valuetag >> 0))); \
+ } while (0)
+
+#define PFIELD(t,base,field,format) \
+PVALUE(t,field,base->field,format)
+
+#define PVALUE(t,tag,value,format) do { \
+ INDENT(t); \
+ fprintf(stdout, "<" #tag ">" #format "</" #tag ">\n", value); \
+ } while (0)
+
+#define PFIELD1(t,base,field,format,prop,pval,pform) \
+ PVALUE1(t,field,base->field,format,prop,pval,pform)
+
+#define PFIELD2(t,base,field,format,prop1,pval1,pform1,prop2,pval2,pform2) \
+ PVALUE2(t,field,base->field,format,prop1,pval1,pform1,prop2,pval2,pform2)
+
+#define PFIELD3(t,base,field,format,prop1,pval1,pform1,prop2,pval2,pform2,prop3,pval3,pform3) \
+ PVALUE3(t,field,base->field,format,prop1,pval1,pform1,prop2,pval2,pform2,prop3,pval3,pform3)
+
+#define PVALUE1(t,tag,value,format,prop1,pval1,pform1) do { \
+ INDENT(t); \
+ fprintf(stdout, "<" #tag " " \
+ #prop1 "=\"" #pform1 "\" " \
+ ">" #format "</" #tag ">\n", \
+ pval1, value); \
+ } while (0)
+
+#define PVALUE2(t,tag,value,format,prop1,pval1,pform1,prop2,pval2,pform2) do { \
+ INDENT(t); \
+ fprintf(stdout, "<" #tag " " \
+ #prop1 "=\"" #pform1 "\" " \
+ #prop2 "=\"" #pform2 "\" " \
+ ">" #format "</" #tag ">\n", \
+ pval1, pval2, value); \
+ } while (0)
+
+#define PVALUE3(t,tag,value,format,prop1,pval1,pform1,prop2,pval2,pform2,prop3,pval3,pform3) do { \
+ INDENT(t); \
+ fprintf(stdout, "<" #tag " " \
+ #prop1 "=\"" #pform1 "\" " \
+ #prop2 "=\"" #pform2 "\" " \
+ #prop3 "=\"" #pform3 "\" " \
+ ">" #format "</" #tag ">\n", \
+ pval1, pval2, pval3, value); \
+ } while (0)
+
+#define PVALUE4(t,tag,value,format,prop1,pval1,pform1,prop2,pval2,pform2,prop3,pval3,pform3,prop4,pval4,pform4) do { \
+ INDENT(t); \
+ fprintf(stdout, "<" #tag " " \
+ #prop1 "=\"" #pform1 "\" " \
+ #prop2 "=\"" #pform2 "\" " \
+ #prop3 "=\"" #pform3 "\" " \
+ #prop4 "=\"" #pform4 "\" " \
+ ">" #format "</" #tag ">\n", \
+ pval1, pval2, pval3, pval4, value); \
+ } while (0)
+
+#define PVALUE5(t,tag,value,format,prop1,pval1,pform1,prop2,pval2,pform2,prop3,pval3,pform3,prop4,pval4,pform4,prop5,pval5,pform5) do { \
+ INDENT(t); \
+ fprintf(stdout, "<" #tag " " \
+ #prop1 "=\"" #pform1 "\" " \
+ #prop2 "=\"" #pform2 "\" " \
+ #prop3 "=\"" #pform3 "\" " \
+ #prop4 "=\"" #pform4 "\" " \
+ #prop5 "=\"" #pform5 "\" " \
+ ">" #format "</" #tag ">\n", \
+ pval1, pval2, pval3, pval4, pval5, value); \
+ } while (0)
+
+#define COMMDENT(t, comment) do { \
+ INDENT(t); \
+ fprintf(stdout, " <!-- %s --> ", comment); \
+ } while (0)
+#define COMMDENTNL(t, comment) do { \
+ COMMDENT(t, commdent); \
+ fprintf(stdout, "\n"); \
+ } while (0)
+
+
+#endif /* Def: GX_XML_FORMAT */
+
+static void dump_table_info(GX_Table table, int n);
+
+void gx_face_dump_trak(GX_Face face, GX_Trak trak);
+void gx_face_dump_feat(GX_Face face, GX_Feat feat);
+void gx_face_dump_prop(GX_Face face, GX_Prop prop);
+void gx_face_dump_opbd(GX_Face face, GX_Opbd opbd);
+void gx_face_dump_lcar(GX_Face face, GX_Lcar lcar);
+void gx_face_dump_bsln(GX_Face face, GX_Bsln bsln);
+void gx_face_dump_mort(GX_Face face, GX_Mort mort);
+void gx_face_dump_fmtx(GX_Face face, GX_Fmtx fmtx);
+void gx_face_dump_fdsc(GX_Face face, GX_Fdsc fdsc);
+void gx_face_dump_morx(GX_Face face, GX_Morx morx);
+void gx_face_dump_just(GX_Face face, GX_Just just);
+void gx_face_dump_kern(GX_Face face, GX_Kern kern);
+void gx_face_dump_fvar(GX_Face face, GX_Fvar fvar);
+
+static FT_Error generic_dump_lookup_table_generic ( GX_LookupTable_Format format,
+ GX_LookupValue value,
+ FT_Pointer user );
+static FT_Error
+generic_dump_lookup_table_segment( GX_LookupTable_Format format,
+ FT_UShort lastGlyph,
+ FT_UShort firstGlyph,
+ GX_LookupValue value,
+ FT_Pointer user );
+
+GX_LookupTable_FuncsRec generic_lookup_table_funcs = {
+ generic_dump_lookup_table_generic, /* generic_func */
+ NULL, /* simple_array_func */
+ NULL, /* segment_single_func */
+ generic_dump_lookup_table_segment, /* segment_array_func */
+ NULL, /* single_table_func */
+ NULL /* trimmed_array_func */
+};
+
+/* ACTION must dump GX_EntrySubtable::flags and its following
+ items(if they exist.) A pointer to an int which means indent value
+ is passed to ACTION as the 2nd argument USER. */
+static void gx_face_dump_state_table ( GX_Face face,
+ GX_StateTable state_table,
+ GX_StateTable_Entry_Action action,
+ int t );
+static void gx_face_dump_xstate_table ( GX_Face face,
+ GX_XStateTable state_table,
+ GX_XStateTable_Entry_Action action,
+ int t );
+
+/* If funcs is NULL or funcs->generic_func is NULL,
+ dump_lookup_table_generic is used. */
+static void gx_face_dump_LookupTable_low( GX_Face face,
+ GX_LookupTable lookup_table,
+ GX_LookupTable_Funcs funcs,
+ int t);
+
+static void gx_face_dump_LookupTable_high( GX_Face face,
+ GX_LookupTable lookup_table,
+ GX_LookupTable_Glyph_Func func,
+ int t );
+
+FT_EXPORT_DEF ( FT_Error )
+gx_face_dump( FT_Face face, FT_ULong tables, const char * fname )
+{
+ GXL_Font gx_font;
+ int count = 0;
+ int t = 0;
+
+ if ( FTL_Get_Font(face, (FTL_Font*)&gx_font) )
+ return FT_Err_Invalid_Argument;
+
+#define COUNT(x) \
+ if ((tables & GX_DUMP_##x) && gx_font->x) count++
+
+#define DUMP(x) \
+ if (tables & GX_DUMP_##x) \
+ { \
+ int t = 1; \
+ GX_Table table; \
+ if (gx_font->x) \
+ { \
+ POPEN(t, x); \
+ table = (GX_Table)gx_font->x; \
+ dump_table_info(table, t); \
+ gx_face_dump_##x((GX_Face)face, (void*)table); \
+ PCLOSE(t,x); \
+ } \
+ }
+ COUNT(mort);
+ COUNT(morx);
+ COUNT(trak);
+ COUNT(kern);
+ COUNT(feat);
+ COUNT(just);
+ COUNT(prop);
+ COUNT(lcar);
+ COUNT(opbd);
+ COUNT(bsln);
+ COUNT(fmtx);
+ COUNT(fdsc);
+ COUNT(fvar);
+ POPEN2(t,gxdump,name,fname,%s,count,count,%d);
+ DUMP(mort);
+ DUMP(morx);
+ DUMP(trak);
+ DUMP(kern);
+ DUMP(feat);
+ DUMP(just);
+ DUMP(prop);
+ DUMP(lcar);
+ DUMP(opbd);
+ DUMP(bsln);
+ DUMP(fmtx);
+ DUMP(fdsc);
+ DUMP(fvar);
+ PCLOSE(t,gxdump);
+ return FT_Err_Ok;
+}
+
+
+/******************************TRAK************************************/
+void gx_face_dump_trak_data(GX_Face face, GX_TrackData data, int t);
+void gx_face_dump_trak_data_table_entry(GX_Face face, GX_TrackTableEntry table_entry, FT_UShort nSizes, int t);
+
+void
+gx_face_dump_trak(GX_Face face, GX_Trak trak)
+{
+ int t = 2;
+ PFIELD(t, trak, version, 0x%08lx);
+ PFIELD(t, trak, format, %u);
+ PFIELD(t, trak, horizOffset, %u);
+ PFIELD(t, trak, vertOffset, %u);
+ PFIELD(t, trak, reserved, %u);
+ POPEN(t, horizData);
+ if (trak->horizOffset)
+ gx_face_dump_trak_data(face, &trak->horizData, t);
+ PCLOSE(t, horizData);
+ POPEN(t, vertData);
+ if (trak->vertOffset)
+ gx_face_dump_trak_data(face, &trak->vertData, t);
+ PCLOSE(t, vertData);
+}
+
+void
+gx_face_dump_trak_data(GX_Face face, GX_TrackData data, int t)
+{
+ int i;
+
+ PFIELD(t,data,nTracks,%u);
+ PFIELD(t,data,nSizes,%u);
+ PFIELD(t,data,sizeTableOffset,%lu);
+ POPEN(t,tableEntries);
+ for ( i = 0; i < data->nTracks; i++ )
+ {
+ POPEN1(t, tableEntry, index,i,%d);
+ gx_face_dump_trak_data_table_entry(face, &(data->trackTable[i]), data->nSizes, t);
+ PCLOSE(t, tableEntry);
+ }
+ PCLOSE(t,tableEntries);
+ POPEN(t,sizes);
+ for ( i = 0; i < data->nSizes; i++ )
+ {
+ NEWLINE10(t, i);
+ fprintf(stdout, "0x%08lx[%d] ", data->sizeTable[i], i);
+ }
+ NEWLINE();
+ PCLOSE(t,sizes);
+
+}
+
+void
+gx_face_dump_trak_data_table_entry(GX_Face face, GX_TrackTableEntry table_entry, FT_UShort nSizes, int t)
+{
+ FT_Error error;
+ FT_Memory memory = face->root.driver->root.memory;
+ FT_SfntName sfnt_name;
+ FT_String * string;
+ int i;
+ PFIELD(t, table_entry,track,0x%08lx);
+
+ if (( error = gx_get_name_from_id((FT_Face)face,
+ table_entry->nameIndex,
+ 0, 0, 0,
+ &sfnt_name) ))
+ PFIELD(t,table_entry,nameIndex,%u);
+ else
+ {
+ if ( FT_NEW_ARRAY(string, sfnt_name.string_len + 1) )
+ goto NameFailure;
+
+ string[sfnt_name.string_len] = '\0';
+ for ( i = 0; i < sfnt_name.string_len; i++)
+ string[i] = sfnt_name.string[i];
+ PFIELD1(t, table_entry,nameIndex,%u,name,string,%s);
+ FT_FREE(string);
+ }
+
+ PFIELD(t, table_entry, offset,%d);
+ POPEN(t,trackingValue);
+ for (i = 0; i < nSizes; i++)
+ {
+ NEWLINE10(t, i);
+ fprintf(stdout, "%d[%d] ", table_entry->tracking_value[i], i);
+ }
+ NEWLINE();
+ PCLOSE(t,trackingValue);
+ return;
+
+ NameFailure:
+ fprintf(stderr, "[%s:trak]Error in name index\n", face->root.family_name);
+ exit(error);
+}
+
+
+/******************************FEAT************************************/
+void gx_face_dump_feat_names(GX_Face face, GX_FeatureName names, int t);
+void gx_face_dump_feat_settingName(GX_Face face, GX_FeatureSettingName settingName, int i, int t);
+
+void
+gx_face_dump_feat(GX_Face face, GX_Feat feat)
+{
+ int i, t = 2;
+ PFIELD(t, feat, version, 0x%08lx);
+ PFIELD(t, feat, featureNameCount, %u);
+ PFIELD(t, feat, reserved1, %u);
+ PFIELD(t, feat, reserved2, %lu);
+ POPEN(t, names);
+ for ( i = 0; i < feat->featureNameCount; i++)
+ gx_face_dump_feat_names(face, &(feat->names[i]), t);
+ PCLOSE(t, names);
+}
+
+void
+gx_face_dump_feat_names(GX_Face face, GX_FeatureName names, int t)
+{
+ FT_Error error;
+ FT_Memory memory = face->root.driver->root.memory;
+ FT_SfntName sfnt_name;
+ FT_String * string;
+ int i;
+ POPEN(t,name);
+ PFIELD(t,names,feature,%u);
+ PFIELD(t,names,nSettings,%u);
+ PFIELD(t,names,settingTable,%lu);
+ POPEN(t,featureFlags);
+ PVALUE(t,value,names->featureFlags,%08x);
+ PVALUE(t,exclusive,(names->featureFlags & GX_FEAT_MASK_EXCLUSIVE_SETTINGS),%04x);
+ PVALUE(t,dynamicDefault,(names->featureFlags & GX_FEAT_MASK_DYNAMIC_DEFAULT),%04x);
+ PVALUE(t,unused,(names->featureFlags & GX_FEAT_MASK_UNUSED),%04x);
+ PVALUE(t,defaultSetting,(names->featureFlags & GX_FEAT_MASK_DEFAULT_SETTING),%04x);
+ PCLOSE(t,featureFlags);
+ if (( error = gx_get_name_from_id((FT_Face)face,
+ names->nameIndex,
+ 0, 0, 0,
+ &sfnt_name) ))
+ PFIELD(t,names,nameIndex,%u);
+ else
+ {
+ if ( FT_NEW_ARRAY(string, sfnt_name.string_len + 1) )
+ goto NameFailure;
+
+ string[sfnt_name.string_len] = '\0';
+ for ( i = 0; i < sfnt_name.string_len; i++)
+ string[i] = sfnt_name.string[i];
+ PFIELD1(t, names,nameIndex,%u,name,string,%s);
+ FT_FREE(string);
+ }
+ POPEN(t,settingNames);
+ for (i = 0; i < names->nSettings; i++)
+ gx_face_dump_feat_settingName(face, &(names->settingName[i]), i, t);
+ PCLOSE(t,settingNames);
+ PCLOSE(t,name);
+ return ;
+ NameFailure:
+ exit(error);
+}
+
+void
+gx_face_dump_feat_settingName(GX_Face face, GX_FeatureSettingName settingName, int i, int t)
+{
+ FT_Error error;
+ FT_Memory memory = face->root.driver->root.memory;
+ FT_SfntName sfnt_name;
+ FT_String * string;
+ int j;
+
+ if (( error = gx_get_name_from_id((FT_Face)face,
+ settingName->nameIndex,
+ 0, 0, 0,
+ &sfnt_name) ))
+ {
+ PFIELD1(t,settingName,setting,%u,index,i,%d);
+ PFIELD1(t,settingName,nameIndex,%u,index,i,%d);
+ }
+ else
+ {
+ if ( FT_NEW_ARRAY(string, sfnt_name.string_len + 1) )
+ goto NameFailure;
+
+ string[sfnt_name.string_len] = '\0';
+ for ( j = 0; j < sfnt_name.string_len; j++)
+ {
+ /* Don't use '&' in pseudo XML file.
+ Here I replace '&' with '|'. */
+ if ( sfnt_name.string[j] == '&' )
+ string[j] = '|' ;
+ else
+ string[j] = sfnt_name.string[j];
+ }
+ PFIELD1(t,settingName,setting,%u,index,i,%d);
+ PFIELD2(t,settingName,nameIndex,%u,index,i,%d,name,string,%s);
+ FT_FREE(string);
+ }
+ return;
+ NameFailure:
+ exit(error);
+}
+
+
+
+/******************************PROP************************************/
+static void
+prop_dump_prop( FT_UShort value, int index, int t )
+{
+ if ( index < 0 )
+ {
+ POPEN(t, prop);
+ INDENT(t);
+ fprintf(stdout,
+ "floater: %u hang-off-left-top: %u hang-off-right-bottom: %u complementary-bracket: %u complementary-bracket-offset: %u attaching-to-right: %u reserved: %u directionality-class: %u\n",
+ value & GX_PROP_MASK_FLOATER,
+ value & GX_PROP_MASK_HANG_OFF_LEFT_TOP,
+ value & GX_PROP_MASK_HANG_OFF_RIGHT_BOTTOM,
+ value & GX_PROP_MASK_USE_COMPLEMENTARY_BRACKET,
+ value & GX_PROP_MASK_COMPLEMENTARY_BRACKET_OFFSET,
+ value & GX_PROP_MASK_ATTACHING_TO_RIGHT,
+ value & GX_PROP_MASK_RESERVED,
+ value & GX_PROP_MASK_DIRECTIONALITY_CLASS);
+ PCLOSE(t, prop);
+ }
+ else
+ {
+ POPEN1(t,prop,index,index,%d);
+ INDENT(t);
+ fprintf(stdout,
+ "floater: %u hang-off-left-top: %u hang-off-right-bottom: %u complementary-bracket: %u complementary-bracket-offset: %u attaching-to-right: %u reserved: %u directionality-class: %u\n",
+ value & GX_PROP_MASK_FLOATER,
+ value & GX_PROP_MASK_HANG_OFF_LEFT_TOP,
+ value & GX_PROP_MASK_HANG_OFF_RIGHT_BOTTOM,
+ value & GX_PROP_MASK_USE_COMPLEMENTARY_BRACKET,
+ value & GX_PROP_MASK_COMPLEMENTARY_BRACKET_OFFSET,
+ value & GX_PROP_MASK_ATTACHING_TO_RIGHT,
+ value & GX_PROP_MASK_RESERVED,
+ value & GX_PROP_MASK_DIRECTIONALITY_CLASS);
+ PCLOSE(t, prop);
+ }
+}
+
+static FT_Error
+prop_dump_lookup_table_segment ( GX_LookupTable_Format format,
+ FT_UShort lastGlyph,
+ FT_UShort firstGlyph,
+ GX_LookupValue value,
+ FT_Pointer user )
+{
+ FT_UShort segment_count = lastGlyph - firstGlyph;
+ FT_UShort * extra = value->extra.word;
+ FT_Int * t = (FT_Int*) user;
+ int i;
+ POPEN(*t, segmentArrayElement);
+ PFIELD(*t,value,raw.s,%d);
+ PVALUE(*t,lastGlyph,lastGlyph,%u);
+ PVALUE(*t,firstGlyph,firstGlyph,%u);
+ POPEN(*t, extra);
+ for ( i = 0; i < segment_count; i++ )
+ prop_dump_prop(extra[i], i, *t);
+ PCLOSE(*t, extra);
+ PCLOSE(*t, segmentArrayElement);
+ return FT_Err_Ok;
+}
+
+static FT_Error
+prop_dump_lookup_table_generic ( GX_LookupTable_Format format,
+ GX_LookupValue value,
+ FT_Pointer user )
+{ /* TODO? more things here? learn freetype more. */
+ FT_Int *t = (FT_Int*) user;
+ prop_dump_prop(value->raw.s, -1, *t);
+ return FT_Err_Ok;
+}
+
+GX_LookupTable_FuncsRec prop_dump_lookup_table_funcs = {
+ prop_dump_lookup_table_generic,
+ NULL,
+ NULL,
+ prop_dump_lookup_table_segment,
+ NULL,
+ NULL
+};
+
+
+void
+gx_face_dump_prop(GX_Face face, GX_Prop prop)
+{
+ int t = 2;
+ PFIELD(t,prop,version,0x%08lx);
+ PFIELD(t,prop,format,%u);
+ PFIELD(t,prop,default_properties,%u);
+ gx_face_dump_LookupTable_low( face, &(prop->lookup_data), &prop_dump_lookup_table_funcs, t);
+}
+
+/******************************OPBD************************************/
+static FT_Error
+opbd_dump_data(FT_UShort raw, GX_OpticalBoundsData data, GX_OpticalBoundsFormat fmt, int t)
+{
+ if (fmt == GX_OPBD_DISTANCE)
+ {
+#define DUMP_DISTANCE(side) \
+ if (data->distance.side##_side == GX_OPBD_NO_OPTICAL_EDGE) \
+ fprintf(stdout, "%s: empty ",#side); \
+ else \
+ fprintf(stdout, "%s: %d ", #side, data->distance.side##_side); /* %d??? */
+ POPEN1(t,distance,raw,raw,%u);
+ INDENT(t);
+ DUMP_DISTANCE(left);
+ DUMP_DISTANCE(top);
+ DUMP_DISTANCE(right);
+ DUMP_DISTANCE(bottom);
+ NEWLINE();
+ PCLOSE(t,distance);
+ }
+ else
+ {
+ POPEN1(t,control-points,raw,raw,%u);
+ INDENT(t);
+ fprintf(stdout, "left: %u top: %u right: %u bottom: %u ",
+ data->control_points.left_side,
+ data->control_points.top_side,
+ data->control_points.right_side,
+ data->control_points.bottom_side);
+ NEWLINE();
+ PCLOSE(t,control-points);
+ }
+ return FT_Err_Ok;
+}
+
+static FT_Error
+opbd_dump_lookup_table_distance_generic ( GX_LookupTable_Format format,
+ GX_LookupValue value,
+ FT_Pointer user )
+{
+ FT_Int *t = (FT_Int*) user;
+ opbd_dump_data(value->raw.s, value->extra.opbd_data, GX_OPBD_DISTANCE, *t);
+ return FT_Err_Ok;
+}
+
+static FT_Error
+opbd_dump_lookup_table_ctlpoint_generic ( GX_LookupTable_Format format,
+ GX_LookupValue value,
+ FT_Pointer user )
+{
+ FT_Int *t = (FT_Int*) user;
+ opbd_dump_data(value->raw.s, value->extra.opbd_data, GX_OPBD_DISTANCE, *t);
+ return FT_Err_Ok;
+}
+
+static FT_Error
+opbd_dump_lookup_table_distance_segment ( GX_LookupTable_Format format,
+ FT_UShort lastGlyph,
+ FT_UShort firstGlyph,
+ GX_LookupValue value,
+ FT_Pointer user )
+{
+ FT_UShort segment_count = lastGlyph - firstGlyph;
+ GX_OpticalBoundsData extra = value->extra.opbd_data;
+ FT_Int * t = (FT_Int*) user;
+ int i;
+ POPEN(*t, segmentArrayElement);
+ PFIELD(*t,value,raw.s,%d);
+ PVALUE(*t,lastGlyph,lastGlyph,%u);
+ PVALUE(*t,firstGlyph,firstGlyph,%u);
+ POPEN(*t, extra);
+ for ( i = 0; i < segment_count; i++ )
+ opbd_dump_data(value->raw.s,&extra[i], GX_OPBD_DISTANCE, *t);
+ PCLOSE(*t, extra);
+ PCLOSE(*t, segmentArrayElement);
+ return FT_Err_Ok;
+}
+
+static FT_Error
+opbd_dump_lookup_table_ctlpoint_segment ( GX_LookupTable_Format format,
+ FT_UShort lastGlyph,
+ FT_UShort firstGlyph,
+ GX_LookupValue value,
+ FT_Pointer user )
+{
+ FT_UShort segment_count = lastGlyph - firstGlyph;
+ GX_OpticalBoundsData extra = value->extra.opbd_data;
+ FT_Int * t = (FT_Int*) user;
+ int i;
+ POPEN(*t, segmentArrayElement);
+ PFIELD(*t,value,raw.s,%d);
+ PVALUE(*t,lastGlyph,lastGlyph,%u);
+ PVALUE(*t,firstGlyph,firstGlyph,%u);
+ POPEN(*t, extra);
+ for ( i = 0; i < segment_count; i++ )
+ opbd_dump_data(value->raw.s,&extra[i], GX_OPBD_CONTROL_POINTS, *t);
+ PCLOSE(*t, extra);
+ PCLOSE(*t, segmentArrayElement);
+ return FT_Err_Ok;
+}
+
+GX_LookupTable_FuncsRec opbd_dump_lookup_table_distance_funcs = {
+ opbd_dump_lookup_table_distance_generic, /* generic_func */
+ NULL, /* simple_array_func */
+ NULL, /* segment_single_func */
+ opbd_dump_lookup_table_distance_segment, /* segment_array_func */
+ NULL,
+ NULL
+};
+
+GX_LookupTable_FuncsRec opbd_dump_lookup_table_ctlpoint_funcs = {
+ opbd_dump_lookup_table_ctlpoint_generic,
+ NULL,
+ NULL,
+ opbd_dump_lookup_table_ctlpoint_segment,
+ NULL,
+ NULL
+};
+
+void
+gx_face_dump_opbd(GX_Face face, GX_Opbd opbd)
+{
+ int t = 2;
+ PFIELD(t,opbd,version,0x%08lx);
+ PFIELD(t,opbd,format,%u);
+ if (opbd->format == GX_OPBD_DISTANCE)
+ gx_face_dump_LookupTable_low( face, &(opbd->lookup_data),
+ &opbd_dump_lookup_table_distance_funcs,
+ t);
+ else
+ gx_face_dump_LookupTable_low( face, &(opbd->lookup_data),
+ &opbd_dump_lookup_table_ctlpoint_funcs,
+ t);
+}
+
+
+/******************************LCAR************************************/
+#if 0
+
+static FT_Error
+lcar_dump_data(FT_UShort raw, GX_LigCaretClassEntry entry, GX_LigCaretFormat fmt, int t)
+{
+ int i;
+ if (fmt == GX_LCAR_DISTANCE)
+ {
+ POPEN2(t,distance,raw,raw,%u,count,entry->count,%u);
+ for ( i = 0; i < entry->count; i++ )
+ {
+ NEWLINE10(t,i);
+ fprintf(stdout, "%d[%d] ", entry->partials[i], i);
+ }
+ NEWLINE();
+ PCLOSE(t,distance);
+ }
+ else
+ {
+ POPEN2(t,control-points,raw,raw,%u,count,entry->count,%u);
+ for ( i = 0; i < entry->count; i++ )
+ {
+ NEWLINE10(t,i);
+ fprintf(stdout, "%d[%d] ", entry->partials[i], i);
+ }
+ NEWLINE();
+ PCLOSE(t,control-points);
+ }
+ return FT_Err_Ok;
+}
+
+static FT_Error
+lcar_dump_lookup_table_distance_generic ( GX_LookupTable_Format format,
+ GX_LookupValue value,
+ FT_Pointer user )
+{
+ FT_Int *t = (FT_Int*) user;
+ lcar_dump_data(value->raw.s, value->extra.lcar_class_entry, GX_LCAR_DISTANCE, *t);
+ return FT_Err_Ok;
+}
+
+static FT_Error
+lcar_dump_lookup_table_ctlpoint_generic ( GX_LookupTable_Format format,
+ GX_LookupValue value,
+ FT_Pointer user )
+{
+ FT_Int *t = (FT_Int*) user;
+ lcar_dump_data(value->raw.s, value->extra.lcar_class_entry, GX_LCAR_DISTANCE, *t);
+ return FT_Err_Ok;
+}
+
+static FT_Error
+lcar_dump_lookup_table_generic_segment ( FT_UShort lastGlyph,
+ FT_UShort firstGlyph,
+ GX_LookupValue value,
+ GX_LigCaretFormat lcar_format,
+ FT_Pointer user )
+{
+ FT_UShort segment_count = lastGlyph - firstGlyph;
+ GX_LigCaretSegment extra = value->extra.lcar_segment;
+ FT_Int * t = (FT_Int*) user;
+ int i;
+ POPEN(*t, segmentArrayElement);
+ PFIELD(*t,value,raw.s,%d);
+ PVALUE(*t,lastGlyph,lastGlyph,%u);
+ PVALUE(*t,firstGlyph,firstGlyph,%u);
+ POPEN(*t, extra);
+ for ( i = 0; i < segment_count; i++ )
+ {
+ POPEN1(*t,LigCaretSegment,offset,extra->offset,%u);
+ lcar_dump_data(value->raw.s,extra[i].class_entry, lcar_format, *t);
+ PCLOSE(*t,LigCaretSegment);
+ }
+ PCLOSE(*t, extra);
+ PCLOSE(*t, segmentArrayElement);
+ return FT_Err_Ok;
+}
+
+static FT_Error
+lcar_dump_lookup_table_distance_segment ( GX_LookupTable_Format format,
+ FT_UShort lastGlyph,
+ FT_UShort firstGlyph,
+ GX_LookupValue value,
+ FT_Pointer user )
+{
+ return lcar_dump_lookup_table_generic_segment(lastGlyph,
+ firstGlyph,
+ value,
+ GX_LCAR_DISTANCE,
+ user);
+}
+
+static FT_Error
+lcar_dump_lookup_table_ctlpoint_segment ( GX_LookupTable_Format format,
+ FT_UShort lastGlyph,
+ FT_UShort firstGlyph,
+ GX_LookupValue value,
+ FT_Pointer user )
+{
+ return lcar_dump_lookup_table_generic_segment(lastGlyph,
+ firstGlyph,
+ value,
+ GX_LCAR_CONTROL_POINTS,
+ user);
+}
+
+
+GX_LookupTable_FuncsRec lcar_dump_lookup_table_distance_funcs = {
+ lcar_dump_lookup_table_distance_generic,
+ NULL,
+ NULL,
+ lcar_dump_lookup_table_distance_segment,
+ NULL,
+ NULL
+};
+
+GX_LookupTable_FuncsRec lcar_dump_lookup_table_ctlpoint_funcs = {
+ lcar_dump_lookup_table_ctlpoint_generic,
+ NULL,
+ NULL,
+ lcar_dump_lookup_table_ctlpoint_segment,
+ NULL,
+ NULL
+};
+
+void
+gx_face_dump_lcar(GX_Face face, GX_Lcar lcar)
+{
+ int t = 2;
+ PFIELD(t,lcar,version,0x%08lx);
+ PFIELD(t,lcar,format,%u);
+ if (lcar->format == GX_LCAR_DISTANCE)
+ gx_face_dump_LookupTable_low( face, &(lcar->lookup),
+ &lcar_dump_lookup_table_distance_funcs,
+ t);
+ else
+ gx_face_dump_LookupTable_low( face, &(lcar->lookup),
+ &lcar_dump_lookup_table_ctlpoint_funcs,
+ t);
+}
+
+#endif /* Not def: 0 */
+
+
+static FT_Error
+lcar_dump_data(FT_UShort glyph, FT_UShort raw, GX_LigCaretClassEntry entry, GX_LigCaretFormat fmt, int t)
+{
+ int i;
+ if (fmt == GX_LCAR_DISTANCE)
+ {
+ POPEN2(t,distance,glyph,glyph,%u,count,entry->count,%u);
+ for ( i = 0; i < entry->count; i++ )
+ {
+ NEWLINE10(t,i);
+ fprintf(stdout, "%d[%d] ", entry->partials[i], i);
+ }
+ NEWLINE();
+ PCLOSE(t,distance);
+ }
+ else
+ {
+ POPEN2(t,control-points,glyph,glyph,%u,count,entry->count,%u);
+ for ( i = 0; i < entry->count; i++ )
+ {
+ NEWLINE10(t,i);
+ fprintf(stdout, "%d[%d] ", entry->partials[i], i);
+ }
+ NEWLINE();
+ PCLOSE(t,control-points);
+ }
+ return FT_Err_Ok;
+}
+
+static FT_Error
+lcar_dump_lookup_table_distance_funcs ( FT_UShort glyph,
+ GX_LookupValue value,
+ FT_Long firstGlyph,
+ FT_Pointer user )
+{
+ FT_Int *t = (FT_Int*)user;
+ GX_LigCaretSegment extra = value->extra.lcar_segment;
+ if ( firstGlyph == GX_LOOKUP_RESULT_NO_FIRST_GLYPH )
+ lcar_dump_data(glyph, value->raw.s, value->extra.lcar_class_entry, GX_LCAR_DISTANCE, *t);
+ else
+ lcar_dump_data(glyph, value->raw.s,extra[glyph - firstGlyph].class_entry, GX_LCAR_DISTANCE, *t);
+ return FT_Err_Ok;
+}
+
+static FT_Error
+lcar_dump_lookup_table_ctlpoint_funcs ( FT_UShort glyph,
+ GX_LookupValue value,
+ FT_Long firstGlyph,
+ FT_Pointer user )
+{
+ FT_Int *t = (FT_Int*)user;
+ GX_LigCaretSegment extra = value->extra.lcar_segment;
+ if ( firstGlyph == GX_LOOKUP_RESULT_NO_FIRST_GLYPH )
+ lcar_dump_data(glyph, value->raw.s, value->extra.lcar_class_entry, GX_LCAR_CONTROL_POINTS, *t);
+ else
+ lcar_dump_data(glyph, value->raw.s,extra[glyph - firstGlyph].class_entry, GX_LCAR_CONTROL_POINTS, *t);
+ return FT_Err_Ok;
+}
+
+void
+gx_face_dump_lcar(GX_Face face, GX_Lcar lcar)
+{
+ int t = 2;
+ PFIELD(t,lcar,version,0x%08lx);
+ PFIELD(t,lcar,format,%u);
+ if (lcar->format == GX_LCAR_DISTANCE)
+ gx_face_dump_LookupTable_high( face, &(lcar->lookup),
+ &lcar_dump_lookup_table_distance_funcs,
+ t);
+ else
+ gx_face_dump_LookupTable_high( face, &(lcar->lookup),
+ &lcar_dump_lookup_table_ctlpoint_funcs,
+ t);
+}
+
+
+/******************************BSLN************************************/
+static void
+gx_bsln_dump_deltas(FT_UShort deltas[], int t)
+{
+ int i;
+ POPEN(t,deltas);
+ for ( i = 0; i < GX_BSLN_VALUE_COUNT; i++ )
+ {
+ NEWLINE10(t,i);
+ fprintf(stdout, "%u[%d] ", deltas[i], i);
+ }
+ NEWLINE();
+ PCLOSE(t,deltas);
+}
+
+static void
+gx_bsln_dump_ctlPoints(FT_UShort ctlPoints[], int t)
+{
+ int i;
+ POPEN(t,ctlPoints);
+ INDENT(t);
+ for (i = 0; i < GX_BSLN_VALUE_COUNT; i++ )
+ {
+ if ( ctlPoints[i] == GX_BSLN_VALUE_EMPTY )
+ fprintf(stdout, "%s[%d] ", "empty", i);
+ else
+ fprintf(stdout, "%u[%d] ", ctlPoints[i], i);
+ }
+ NEWLINE();
+ PCLOSE(t,deltas);
+}
+
+void
+gx_face_dump_bsln(GX_Face face, GX_Bsln bsln)
+{
+ int t = 2;
+ GX_BaselineFormat0Part f0part;
+ GX_BaselineFormat1Part f1part;
+ GX_BaselineFormat2Part f2part;
+ GX_BaselineFormat3Part f3part;
+
+ PFIELD(t,bsln,version,0x%08lx);
+ PFIELD(t,bsln,format,%u);
+ PFIELD(t,bsln,defaultBaseline,%u);
+ switch ( bsln->format )
+ {
+ case GX_BSLN_FMT_DISTANCE_NO_MAPPING:
+ f0part = bsln->parts.fmt0;
+ gx_bsln_dump_deltas(f0part->deltas, t);
+ break;
+ case GX_BSLN_FMT_DISTANCE_WITH_MAPPING:
+ f1part = bsln->parts.fmt1;
+ gx_bsln_dump_deltas(f1part->deltas, t);
+ gx_face_dump_LookupTable_low(face, &f1part->mappingData,
+ &generic_lookup_table_funcs, t);
+ break;
+ case GX_BSLN_FMT_CONTROL_POINT_NO_MAPPING:
+ f2part = bsln->parts.fmt2;
+ PFIELD(t,f2part,stdGlyph,%u);
+ gx_bsln_dump_ctlPoints(f2part->ctlPoints, t);
+ break;
+ case GX_BSLN_FMT_CONTROL_POINT_WITH_MAPPING:
+ f3part = bsln->parts.fmt3;
+ PFIELD(t,f3part,stdGlyph,%u);
+ gx_bsln_dump_ctlPoints(f3part->ctlPoints, t);
+ gx_face_dump_LookupTable_low(face, &f3part->mappingData,
+ &generic_lookup_table_funcs, t);
+ }
+}
+
+
+/******************************MORT************************************/
+#if 1
+static FT_Error
+mort_dump_lookup_table_segment ( GX_LookupTable_Format format,
+ FT_UShort lastGlyph,
+ FT_UShort firstGlyph,
+ GX_LookupValue value,
+ FT_Pointer user )
+{
+ FT_Int * t = (FT_Int*) user;
+ POPEN(*t, segmentArrayElement);
+ PFIELD(*t,value,raw.s,%d);
+ PVALUE(*t,lastGlyph,lastGlyph,%u);
+ PVALUE(*t,firstGlyph,firstGlyph,%u);
+ PCLOSE(*t, segmentArrayElement);
+ return FT_Err_Ok;
+}
+
+static FT_Error
+mort_dump_lookup_table_single ( GX_LookupTable_Format format,
+ FT_UShort glyph,
+ GX_LookupValue value,
+ FT_Pointer user )
+{
+ FT_Int * t = (FT_Int*) user;
+ PVALUE1(*t,value,value->raw.s,%d,glyph,glyph,%u);
+ return FT_Err_Ok;
+}
+
+
+GX_LookupTable_FuncsRec mort_dump_lookup_table_funcs = {
+ NULL,
+ NULL,
+ NULL,
+ mort_dump_lookup_table_segment,
+ mort_dump_lookup_table_single,
+ NULL
+};
+#endif /* 1 */
+
+
+static FT_Error
+mort_dump_lookup_table_func( FT_UShort glyph,
+ GX_LookupValue value,
+ FT_Long firstGlyph,
+ FT_Pointer user )
+{
+ FT_Int * t = (FT_Int*) user;
+ if ( firstGlyph == GX_LOOKUP_RESULT_NO_FIRST_GLYPH )
+ PVALUE1(*t,value,value->raw.u,%u,glyph,glyph,%u);
+ else
+ PVALUE1(*t,value,value->extra.word[glyph - firstGlyph],%u,glyph,glyph,%u);
+ return FT_Err_Ok;
+}
+
+static void
+gx_face_dump_mort_subtable_type(GX_Face face, FT_UShort subtype, int t)
+{
+ POPEN(t, subtableType);
+ PVALUE(t,value,subtype,%u);
+ switch(subtype)
+ {
+ case GX_MORT_REARRANGEMENT_SUBTABLE:
+ PVALUE(t,symbol,"rearrangement", %s);
+ break;
+ case GX_MORT_CONTEXTUAL_SUBTABLE:
+ PVALUE(t,symbol,"contextual", %s);
+ break;
+ case GX_MORT_LIGATURE_SUBTABLE:
+ PVALUE(t,symbol,"ligature", %s);
+ break;
+ case GX_MORT_RESERVED_SUBTABLE:
+ PVALUE(t,symbol,"reserved", %s);
+ break;
+ case GX_MORT_NONCONTEXTUAL_SUBTABLE:
+ PVALUE(t,symbol,"noncontextual", %s);
+ break;
+ case GX_MORT_INSERTION_SUBTABLE:
+ PVALUE(t,symbol,"insertion", %s);
+ break;
+ default:
+ PVALUE(t,symbol,"**UNKNOWN**", %s);
+ break;
+ }
+ PCLOSE(t, subtableType);
+}
+
+static void
+gx_face_dump_mort_subtable_header_coverage(GX_Face face,
+ FT_UShort coverage, int t)
+{
+ POPEN(t, coverage);
+ PVALUE(t,value,coverage,0x%04x);
+ PVALUE(t,horiz-or-vertical,
+ coverage&GX_MORT_COVERAGE_HORIZONTAL_OR_VERTICAL_TEXT, %u);
+ PVALUE(t,oreder-of-processing-glyph-array,
+ coverage&GX_MORT_COVERAGE_ORDER_OF_PROCESSING_GLYPH_ARRAY, %u);
+ PVALUE(t,orientation-indepedent,
+ coverage&GX_MORT_COVERAGE_ORIENTATION_INDEPENDENT, %u);
+ PVALUE(t,reserved,
+ coverage&GX_MORT_COVERAGE_RESERVED, %u);
+ gx_face_dump_mort_subtable_type(face, coverage&GX_MORT_COVERAGE_SUBTABLE_TYPE, t);
+ PCLOSE(t, coverage);
+}
+
+static void
+gx_face_dump_mort_subtable_header(GX_Face face, GX_MetamorphosisSubtableHeader header, int t)
+{
+ POPEN1(t, header,
+ position,header->position,%lu);
+ PFIELD(t,header,length,%u);
+ gx_face_dump_mort_subtable_header_coverage(face, header->coverage, t);
+ PFIELD(t,header,subFeatureFlags,%lu);
+ PCLOSE(t, header);
+}
+
+static FT_Error
+gx_face_dump_mort_rearrangement_entry( GX_EntrySubtable entry_subtable,
+ FT_Pointer user )
+{
+ int t = *(int *)user;
+ char * verbString = "";
+ switch (entry_subtable->flags&GX_MORT_REARRANGEMENT_FLAGS_VERB)
+ {
+ case GX_MORT_REARRANGEMENT_VERB_NO_CHANGE: verbString = "NO CHANGE"; break;
+#define GENCASE(x) case GX_MORT_REARRANGEMENT_VERB_##x: verbString = #x; break
+ GENCASE(Ax2xA);
+ GENCASE(xD2Dx);
+ GENCASE(AxD2DxA);
+ GENCASE(ABx2xAB);
+ GENCASE(ABx2xBA);
+ GENCASE(xCD2CDx);
+ GENCASE(xCD2DCx);
+ GENCASE(AxCD2CDxA);
+ GENCASE(AxCD2DCxA);
+ GENCASE(ABxD2DxAB);
+ GENCASE(ABxD2DxBA);
+ GENCASE(ABxCD2CDxAB);
+ GENCASE(ABxCD2CDxBA);
+ GENCASE(ABxCD2DCxAB);
+ GENCASE(ABxCD2DCxBA);
+ default:
+ fprintf(stderr, "Error in gx_face_dump_mort_rearrangement_entry\n");
+ exit(1);
+ };
+ PVALUE5(t,flags,entry_subtable->flags,%u,
+ markFirst,entry_subtable->flags&GX_MORT_REARRANGEMENT_FLAGS_MARK_FIRST,0x%x,
+ dontAdvance,entry_subtable->flags&GX_MORT_REARRANGEMENT_FLAGS_DONT_ADVANCE,0x%x,
+ markLast,entry_subtable->flags&GX_MORT_REARRANGEMENT_FLAGS_MARK_FIRST,0x%x,
+ verb,entry_subtable->flags&GX_MORT_REARRANGEMENT_FLAGS_VERB,0x%x,
+ verbString,verbString,%s);
+ return FT_Err_Ok;
+}
+
+static void
+gx_face_dump_mort_rearrangement_subtable(GX_Face face,
+ GX_MetamorphosisRearrangementBody body,
+ int t)
+{
+ GX_StateTable state_table;
+ state_table = &body->state_table;
+ POPEN(t, rearrangementSubtable);
+ gx_face_dump_state_table(face, state_table,
+ gx_face_dump_mort_rearrangement_entry,
+ t);
+ PCLOSE(t, rearrangementSubtable);
+
+}
+
+static FT_Error
+gx_face_dump_mort_contextual_entry( GX_EntrySubtable entry_subtable,
+ FT_Pointer user )
+{
+ int t = *(int *)user;
+ GX_MetamorphosisContextualPerGlyph per_glyph = entry_subtable->glyphOffsets.contextual;
+
+ PVALUE2(t,flags,entry_subtable->flags,%u,
+ setMark,entry_subtable->flags&GX_MORT_CONTEXTUAL_FLAGS_SET_MARK,0x%x,
+ dontAdvance,entry_subtable->flags&GX_MORT_CONTEXTUAL_FLAGS_DONT_ADVANCE,0x%x);
+
+ POPEN2(t,glyphOffsets,
+ markOffset,per_glyph->markOffset,%d, /* Was:FT_UShort, see gxtype.h. */
+ currentOffset,per_glyph->currentOffset,%d /* Was:FT_UShort, see gxtype.h. */
+ );
+ PCLOSE(t,glyphOffsets);
+ return FT_Err_Ok;
+}
+
+static void
+gx_face_dump_mort_contextual_substitution_table( GX_Face face,
+ GX_MetamorphosisContextualSubstitutionTable substitutionTable,
+ int t)
+{
+ int i;
+ POPEN2(t,substitutionTable,
+ offset,substitutionTable->offset,%u,
+ nGlyphIndexes,substitutionTable->nGlyphIndexes,%u);
+ for( i = 0; i < substitutionTable->nGlyphIndexes; i++ )
+ {
+ NEWLINE10(t,i);
+ fprintf(stdout, "%u[%d] ", substitutionTable->glyph_indexes[i], i);
+ }
+ NEWLINE();
+ PCLOSE(t,substitutionTable);
+}
+
+static void
+gx_face_dump_mort_contextual_subtable(GX_Face face,
+ GX_MetamorphosisContextualBody body,
+ int t)
+{
+ GX_StateTable state_table;
+ state_table = &body->state_table;
+ POPEN(t, contextualSubtable);
+ gx_face_dump_state_table(face, state_table,
+ gx_face_dump_mort_contextual_entry,
+ t);
+ gx_face_dump_mort_contextual_substitution_table(face,
+ &body->substitutionTable,
+ t);
+ PCLOSE(t, contextualSubtable);
+}
+
+static FT_Error
+gx_face_dump_mort_ligature_entry( GX_EntrySubtable entry_subtable,
+ FT_Pointer user )
+{
+ int t = *(int *)user;
+ FT_UShort offset = entry_subtable->flags&GX_MORT_LIGATURE_FLAGS_OFFSET;
+ PVALUE3(t,flags,entry_subtable->flags,%u,
+ setComponent,entry_subtable->flags&GX_MORT_LIGATURE_FLAGS_SET_COMPONENT,0x%x,
+ dontAdvance,entry_subtable->flags&GX_MORT_LIGATURE_FLAGS_DONT_ADVANCE,0x%x,
+ offset,offset,%u);
+ return FT_Err_Ok;
+}
+
+static void
+gx_face_dump_mort_ligature_action_table(GX_Face face,
+ GX_MetamorphosisLigatureActionTable ligActionTable,
+ int t)
+{
+ int i;
+ FT_ULong offset;
+ FT_Long soffset;
+ FT_Long bsoffset;
+ FT_Long nbsoffset;
+ mort_tmp_ligActionTable = ligActionTable->offset;
+
+ POPEN2(t,ligActionTable,
+ offset,ligActionTable->offset,%u,
+ nActions,ligActionTable->nActions,%u);
+ for ( i = 0; i < ligActionTable->nActions; i++ )
+ {
+ offset = ligActionTable->body[i]&GX_MORT_LIGATURE_ACTION_OFFSET;
+ soffset = gx_sign_extend(offset,GX_MORT_LIGATURE_ACTION_OFFSET);
+
+ PVALUE5(t,action,ligActionTable->body[i],%lu,
+ actionIndexX4,4*i,%d,
+ last,ligActionTable->body[i]&GX_MORT_LIGATURE_ACTION_LAST,0x%lx,
+ store,ligActionTable->body[i]&GX_MORT_LIGATURE_ACTION_STORE,0x%lx,
+ offset,offset,%lu,
+ offsetSE,(2*soffset),%ld);
+
+ bsoffset = 2*(mort_tmp_firstGlyph + soffset);
+ nbsoffset = 2*(mort_tmp_firstGlyph + mort_tmp_nGlyphs + soffset);
+
+#if GX_DEBUG_MORT_LIGATURE_TABLE_LAYOUT
+ /* TODO: tables order are not considered. */
+ if (!(((mort_tmp_componentTable <= bsoffset) &&
+ (bsoffset < mort_tmp_ligatureTable )) ||
+ ((mort_tmp_componentTable <= nbsoffset) &&
+ (nbsoffset < mort_tmp_ligatureTable )) ||
+ ((bsoffset < mort_tmp_componentTable) &&
+ mort_tmp_ligatureTable <= nbsoffset)
+ ))
+ fprintf(stderr, "range out: componentTable: %u, offset: %ld[%d+%d=%ld], ligatureTable: %u\n",
+ mort_tmp_componentTable,
+ bsoffset,
+ mort_tmp_firstGlyph, mort_tmp_nGlyphs, nbsoffset,
+ mort_tmp_ligatureTable);
+ else
+ fprintf(stderr, "ok: offset: %ld[%d+%d=%ld], \n",
+ bsoffset,
+ mort_tmp_firstGlyph, mort_tmp_nGlyphs, nbsoffset);
+#endif /* GX_DEBUG_MORT_LIGATURE_TABLE_LAYOUT */
+ }
+
+ PCLOSE(t,ligActionTable);
+
+}
+
+static void
+gx_face_dump_mort_component_table( GX_Face face,
+ GX_MetamorphosisComponentTable componentTable,
+ int t)
+{
+ int i;
+ POPEN2(t, componentTable,
+ offset,componentTable->offset,%u,
+ nComponent,componentTable->nComponent,%u);
+ for ( i = 0; i < componentTable->nComponent; i++ )
+ {
+ NEWLINE10(t,i);
+ fprintf(stdout, "%u[%d] ", componentTable->body[i], i);
+ }
+ NEWLINE();
+ PCLOSE(t, componentTable);
+}
+
+static void
+gx_face_dump_mort_ligature_table( GX_Face face,
+ GX_MetamorphosisLigatureTable ligatureTable,
+ int t)
+{
+ int i;
+ POPEN2(t, ligatureTable,
+ offset,ligatureTable->offset,%u,
+ nLigature,ligatureTable->nLigature,%u);
+ for ( i = 0; i < ligatureTable->nLigature; i++ )
+ {
+ NEWLINE10(t,i);
+ fprintf(stdout, "%u[%d] ", ligatureTable->body[i], i);
+ }
+ NEWLINE();
+ PCLOSE(t, ligatureTable);
+}
+
+static void
+gx_face_dump_mort_ligature_subtable (GX_Face face,
+ GX_MetamorphosisLigatureBody body,
+ int t)
+{
+ GX_StateTable state_table;
+ state_table = &body->state_table;
+ mort_tmp_componentTable = body->componentTable.offset;
+ mort_tmp_ligatureTable = body->ligatureTable.offset;
+
+ POPEN(t, ligatureSubtable);
+ gx_face_dump_state_table(face, state_table,
+ gx_face_dump_mort_ligature_entry, t);
+ gx_face_dump_mort_ligature_action_table(face, &body->ligActionTable, t);
+ gx_face_dump_mort_component_table(face, &body->componentTable, t);
+ gx_face_dump_mort_ligature_table(face, &body->ligatureTable, t);
+ PCLOSE(t,ligatureSubtable);
+}
+
+static void
+gx_face_dump_mort_noncontextual_subtable (GX_Face face,
+ GX_MetamorphosisNoncontextualBody body,
+ int t)
+{
+#if 1
+ gx_face_dump_LookupTable_low(face,
+ &body->lookup_table,
+ &mort_dump_lookup_table_funcs,
+ t);
+#else
+ gx_face_dump_LookupTable_high( face,
+ &body->lookup_table,
+ &mort_dump_lookup_table_func,
+ t );
+#endif /* 0 */
+}
+
+static FT_Error
+gx_face_dump_mort_insertion_entry ( GX_EntrySubtable entry_subtable,
+ FT_Pointer user )
+{
+ int t = *(int *)user;
+ int i;
+ GX_MetamorphosisInsertionPerGlyph per_glyph = entry_subtable->glyphOffsets.insertion;
+ GX_MetamorphosisInsertionList currentInsertList = &per_glyph->currentInsertList;
+ GX_MetamorphosisInsertionList markedInsertList = &per_glyph->markedInsertList;
+
+ FT_UShort current_count = gx_mask_zero_shift(entry_subtable->flags,
+ GX_MORT_INSERTION_FLAGS_CURRENT_INSERT_COUNT);
+ FT_UShort marked_count = gx_mask_zero_shift(entry_subtable->flags,
+ GX_MORT_INSERTION_FLAGS_MARKED_INSERT_COUNT);
+
+ POPEN1(t,flags,value,entry_subtable->flags,%u);
+ PVALUE(t,setMark,entry_subtable->flags&GX_MORT_INSERTION_FLAGS_SET_MARK,%u);
+ PVALUE(t,dontAdvance,entry_subtable->flags&GX_MORT_INSERTION_FLAGS_DONT_ADVANCE,%u);
+ PVALUE(t,currentIsKashidaLike,entry_subtable->flags&GX_MORT_INSERTION_FLAGS_CURRENT_IS_KASHIDA_LIKE,%u);
+ PVALUE(t,markedIsKashidaLike,entry_subtable->flags&GX_MORT_INSERTION_FLAGS_MARKED_IS_KASHIDA_LIKE,%u);
+ PVALUE(t,currentInsertBefore,entry_subtable->flags&GX_MORT_INSERTION_FLAGS_CURRENT_INSERT_BEFORE,%u);
+ PVALUE(t,markedInsertBefore,entry_subtable->flags&GX_MORT_INSERTION_FLAGS_MARKED_INSERT_BEFORE,%u);
+ PVALUE(t,currentInsertCount,entry_subtable->flags&GX_MORT_INSERTION_FLAGS_CURRENT_INSERT_COUNT,%u);
+ PVALUE(t,markedInsertCount,entry_subtable->flags&GX_MORT_INSERTION_FLAGS_MARKED_INSERT_COUNT,%u);
+ PCLOSE(t,flags);
+
+ POPEN1(t,currentInsertList,offset,currentInsertList->offset,%u);
+ for ( i = 0; i < current_count; i++ )
+ {
+ NEWLINE10(t,i);
+ fprintf(stdout, "%u[%d] ", currentInsertList->glyphcodes[i], i);
+ }
+ NEWLINE();
+ PCLOSE(t,currentInsertList);
+
+ POPEN1(t,markedInsertList,offset,markedInsertList->offset,%u);
+ for ( i = 0; i < marked_count; i++ )
+ {
+ NEWLINE10(t,i);
+ fprintf(stdout, "%u[%d] ", markedInsertList->glyphcodes[i], i);
+ }
+ NEWLINE();
+ PCLOSE(t,markedInsertList);
+
+ return FT_Err_Ok;
+}
+
+static void
+gx_face_dump_mort_insertion_subtable (GX_Face face,
+ GX_MetamorphosisInsertionBody body,
+ int t)
+{
+ GX_StateTable state_table;
+ state_table = &body->state_table;
+ POPEN(t, insertionSubtable);
+ gx_face_dump_state_table(face, state_table,
+ gx_face_dump_mort_insertion_entry, t);
+ PCLOSE(t, insertionSubtable);
+}
+
+static void
+gx_face_dump_mort_subtable(GX_Face face, GX_MetamorphosisSubtable subtable,
+ FT_UShort nSubtables, int t)
+{
+ GX_MetamorphosisSubtable psubtable;
+ int n;
+ POPEN(t, SubTables);
+ for ( n = 0; n < nSubtables; n++ )
+ {
+ POPEN(t, chainSubtable);
+ psubtable = &subtable[n];
+ gx_face_dump_mort_subtable_header(face, &psubtable->header, t);
+ switch(psubtable->header.coverage&GX_MORT_COVERAGE_SUBTABLE_TYPE)
+ {
+ case GX_MORT_REARRANGEMENT_SUBTABLE:
+ gx_face_dump_mort_rearrangement_subtable(face,
+ psubtable->body.rearrangement,
+ t);
+ break;
+ case GX_MORT_CONTEXTUAL_SUBTABLE:
+ gx_face_dump_mort_contextual_subtable(face,
+ psubtable->body.contextual,
+ t);
+ break;
+ case GX_MORT_LIGATURE_SUBTABLE:
+ gx_face_dump_mort_ligature_subtable(face,
+ psubtable->body.ligature,
+ t);
+ break;
+ case GX_MORT_RESERVED_SUBTABLE:
+ PVALUE(t,error,"**RESERVED**", %s);
+ break;
+ case GX_MORT_NONCONTEXTUAL_SUBTABLE:
+ gx_face_dump_mort_noncontextual_subtable(face,
+ psubtable->body.noncontextual,
+ t);
+ break;
+ case GX_MORT_INSERTION_SUBTABLE:
+ gx_face_dump_mort_insertion_subtable(face,
+ psubtable->body.insertion,
+ t);
+ break;
+ default:
+ PVALUE(t,error,"**UNKNOWN**", %s);
+ break;
+ }
+ PCLOSE(t, chainSubtable);
+ }
+ PCLOSE(t, SubTables);
+}
+
+static void
+gx_face_dump_mort_chain_header(GX_Face face, GX_MetamorphosisChainHeader header, int t)
+ {
+ POPEN(t, header);
+ PFIELD(t,header,defaultFlags,%lu);
+ PFIELD(t,header,chainLength,%lu);
+ PFIELD(t,header,nFeatureEntries,%d);
+ PFIELD(t,header,nSubtables,%d);
+ PCLOSE(t,header);
+ }
+
+static void
+gx_face_dump_mort_feature_table(GX_Face face,
+ GX_MetamorphosisFeatureTable tbl,
+ FT_UShort nFeatureEntries,
+ int t)
+{
+ GX_MetamorphosisFeatureTable ptbl;
+ int n;
+
+ POPEN(t, FeatureTables);
+ for ( n = 0; n < nFeatureEntries; n++ )
+ {
+ ptbl = &tbl[n];
+ POPEN(t, FeatureTable);
+ PFIELD(t, ptbl, featureType, %u);
+
+ PFIELD(t, ptbl, featureSetting, %u);
+ PFIELD(t, ptbl, enableFlags, 0x%08lx);
+ PFIELD(t, ptbl, disableFlags, 0x%08lx);
+ PCLOSE(t, FeatureTable);
+ }
+ PCLOSE(t, FeatureTables);
+}
+
+static void
+gx_face_dump_mort_chain(GX_Face face, GX_MetamorphosisChain chain, int t)
+{
+ POPEN(t,chain);
+ gx_face_dump_mort_chain_header(face, &chain->header, t);
+ gx_face_dump_mort_feature_table(face, chain->feat_Subtbl, chain->header.nFeatureEntries, t);
+ gx_face_dump_mort_subtable(face, chain->chain_Subtbl, chain->header.nSubtables, t);
+ PCLOSE(t,chain);
+}
+
+void
+gx_face_dump_mort(GX_Face face, GX_Mort mort)
+{
+ int i, t = 2;
+ PFIELD(t,mort,version,0x%08lx);
+ PFIELD(t,mort,nChains,%lu);
+ POPEN(t, chains);
+ for ( i = 0; i < mort->nChains; i++ )
+ gx_face_dump_mort_chain(face, &mort->chain[i], t);
+ PCLOSE(t, chains);
+}
+
+/******************************FMTX************************************/
+void
+gx_face_dump_fmtx(GX_Face face, GX_Fmtx fmtx)
+{
+ int t = 2;
+ PFIELD(t,fmtx,version,0x%08lx);
+ PFIELD(t,fmtx,glyphIndex,%lu);
+ PFIELD(t,fmtx,horizontalBefore,%u);
+ PFIELD(t,fmtx,horizontalAfter,%u);
+ PFIELD(t,fmtx,horizontalCaretHead,%u);
+ PFIELD(t,fmtx,horizontalCaretBase,%u);
+ PFIELD(t,fmtx,verticalBefore,%u);
+ PFIELD(t,fmtx,verticalAfter,%u);
+ PFIELD(t,fmtx,verticalCaretHead,%u);
+ PFIELD(t,fmtx,verticalCaretBase,%u);
+}
+
+/******************************FDSC************************************/
+void
+gx_face_dump_fdsc(GX_Face face, GX_Fdsc fdsc)
+{
+ int i, t = 2;
+ GX_FontDescriptor desc;
+ char * string_tag = NULL;
+
+ PFIELD(t,fdsc,version,0x%08lx);
+ PFIELD(t,fdsc,descriptorCount,%lu);
+ POPEN(t, descriptors);
+ for ( i = 0; i < fdsc->descriptorCount; i++ )
+ {
+ desc = &(fdsc->descriptor[i]);
+ switch ( desc->tag )
+ {
+ case TTAG_wght:
+ string_tag = "wght";
+ break;
+ case TTAG_wdth:
+ string_tag = "wdth";
+ break;
+ case TTAG_slnt:
+ string_tag = "slnt";
+ break;
+ case TTAG_opsz:
+ string_tag = "opsz";
+ break;
+ case TTAG_nalf:
+ string_tag = "nalf";
+ break;
+ }
+ POPEN(t, descriptor);
+ if ( string_tag )
+ PVALUE(t,tag,string_tag,%s);
+ else
+ PVALUE(t,tag,desc->tag,%lx);
+ PFIELD(t,desc,value,%lu);
+ PCLOSE(t, descriptor);
+ }
+ PCLOSE(t, descriptors);
+}
+
+
+
+/******************************MORX************************************/
+#define gx_face_dump_morx_subtable_type gx_face_dump_mort_subtable_type
+#define gx_face_dump_morx_feature_table gx_face_dump_mort_feature_table
+#define gx_face_dump_morx_noncontextual_subtable gx_face_dump_mort_noncontextual_subtable
+#define gx_face_dump_morx_rearrangement_entry gx_face_dump_mort_rearrangement_entry
+#define gx_face_dump_morx_insertion_entry gx_face_dump_mort_insertion_entry
+#define morx_dump_lookup_table_func mort_dump_lookup_table_func
+static void
+gx_face_dump_morx_chain_header(GX_Face face, GX_XMetamorphosisChainHeader header, int t)
+{
+ POPEN(t,header);
+ PFIELD(t,header,defaultFlags,%lu);
+ PFIELD(t,header,chainLength,%lu);
+ PFIELD(t,header,nFeatureEntries,%lu);
+ PFIELD(t,header,nSubtables,%lu);
+ PCLOSE(t,header);
+}
+
+static void
+gx_face_dump_morx_subtable_header_coverage( GX_Face face,
+ FT_ULong coverage,
+ int t )
+{
+ POPEN(t, coverage);
+ PVALUE(t,value,coverage,0x%08lx);
+ PVALUE(t,horiz-or-vertical,
+ coverage&GX_MORX_COVERAGE_HORIZONTAL_OR_VERTICAL_TEXT, %lu);
+ PVALUE(t,oreder-of-processing-glyph-array,
+ coverage&GX_MORX_COVERAGE_ORDER_OF_PROCESSING_GLYPH_ARRAY, %lu);
+ PVALUE(t,orientation-indepedent,
+ coverage&GX_MORX_COVERAGE_ORIENTATION_INDEPENDENT, %lu);
+ PVALUE(t,reserved,
+ coverage&GX_MORX_COVERAGE_RESERVED, %lu);
+ gx_face_dump_morx_subtable_type(face, coverage&GX_MORX_COVERAGE_SUBTABLE_TYPE, t);
+ PCLOSE(t, coverage);
+}
+
+static void
+gx_face_dump_morx_subtable_header(GX_Face face,
+ GX_XMetamorphosisSubtableHeader header, int t)
+{
+ POPEN1(t, header,
+ position,header->position,%lu);
+ PFIELD(t,header,length,%lu);
+ gx_face_dump_morx_subtable_header_coverage(face, header->coverage, t);
+ PFIELD(t,header,subFeatureFlags,%lu);
+ PCLOSE(t, header);
+}
+
+static void
+gx_face_dump_morx_rearrangement_subtable( GX_Face face,
+ GX_XMetamorphosisRearrangementBody body,
+ int t )
+{
+ GX_XStateTable state_table;
+ state_table = &body->state_table;
+ POPEN(t, rearrangementSubtable);
+ gx_face_dump_xstate_table(face, state_table,
+ gx_face_dump_morx_rearrangement_entry,
+ t);
+ PCLOSE(t, rearrangementSubtable);
+}
+
+static FT_Error
+gx_face_dump_morx_contextual_entry( GX_EntrySubtable entry_subtable,
+ FT_Pointer user )
+{
+ int t = *(int *)user;
+ GX_XMetamorphosisContextualPerGlyph per_glyph = entry_subtable->glyphOffsets.xcontextual;
+
+ PVALUE2(t,flags,entry_subtable->flags,%u,
+ setMark,entry_subtable->flags&GX_MORX_CONTEXTUAL_FLAGS_SET_MARK,0x%x,
+ dontAdvance,entry_subtable->flags&GX_MORX_CONTEXTUAL_FLAGS_DONT_ADVANCE,0x%x);
+ if ( !per_glyph )
+ POPEN(t,glyphIndexes);
+ else if ( per_glyph->markIndex == GX_MORX_NO_SUBSTITUTION )
+ {
+ if ( per_glyph->currentIndex == GX_MORX_NO_SUBSTITUTION )
+ POPEN2(t,glyphIndexes,
+ markIndex,"no substitution",%s,
+ currentInsert,"no substitution",%s);
+ else
+ POPEN2(t,glyphIndexes,
+ markIndex,"no substitution",%s,
+ currentIndex,per_glyph->currentIndex,%u);
+ }
+ else if ( per_glyph->currentIndex == GX_MORX_NO_SUBSTITUTION )
+ POPEN2(t,glyphIndexes,
+ markIndex,per_glyph->markIndex,%u,
+ currentInsert,"no substitution",%s);
+ else
+ POPEN2(t,glyphIndexes,
+ markIndex,per_glyph->markIndex,%u,
+ currentIndex,per_glyph->currentIndex,%u);
+ PCLOSE(t,glyphIndexes);
+ return FT_Err_Ok;
+}
+
+
+static void
+gx_face_dump_morx_contextual_substitution_table( GX_Face face,
+ GX_XMetamorphosisContextualSubstitutionTable substitutionTable,
+ int t)
+{
+ FT_ULong i;
+ POPEN2(t,substitutionTable,
+ offset,substitutionTable->offset,%lu,
+ nTables,substitutionTable->nTables,%u);
+ for( i = 0; i < substitutionTable->nTables; i++ )
+ {
+ POPEN1(t,lookupTables,index,i,%lu);
+ if ( substitutionTable->lookupTables[i] )
+ {
+ gx_face_dump_LookupTable_low ( face,
+ substitutionTable->lookupTables[i],
+ NULL, /* use default */
+ t );
+ }
+ PCLOSE(t,lookupTables);
+ }
+ PCLOSE(t,substitutionTable);
+}
+
+static void
+gx_face_dump_morx_contextual_subtable(GX_Face face,
+ GX_XMetamorphosisContextualBody body,
+ int t)
+{
+ GX_XStateTable state_table;
+ state_table = &body->state_table;
+ POPEN(t, contextualSubtable);
+ gx_face_dump_xstate_table(face, state_table,
+ gx_face_dump_morx_contextual_entry,
+ t);
+ gx_face_dump_morx_contextual_substitution_table(face,
+ &body->substitutionTable,
+ t);
+ PCLOSE(t, contextualSubtable);
+}
+
+static FT_Error
+gx_face_dump_morx_ligature_entry( GX_EntrySubtable entry_subtable,
+ FT_Pointer user )
+{
+ int t = *(int *)user;
+ GX_EntrySubtablePerGlyph per_glyph = &entry_subtable->glyphOffsets;
+ PVALUE4(t,flags,entry_subtable->flags,%u,
+ setComponent,entry_subtable->flags&GX_MORX_LIGATURE_FLAGS_SET_COMPONENT,0x%x,
+ dontAdvance,entry_subtable->flags&GX_MORX_LIGATURE_FLAGS_DONT_ADVANCE,0x%x,
+ performAction,entry_subtable->flags&GX_MORX_LIGATURE_FLAGS_PERFORM_ACTION,0x%x,
+ ligActionIndex,per_glyph->ligActionIndex,%u);
+ return FT_Err_Ok;
+}
+
+static void
+gx_face_dump_morx_ligature_action_table(GX_Face face,
+ GX_XMetamorphosisLigatureActionTable ligActionTable,
+ int t)
+{
+ int i;
+ FT_Long index;
+ FT_Long sindex;
+
+ FT_ULong bsindex;
+ FT_ULong nbsindex;
+ FT_ULong area;
+
+ POPEN2(t,ligActionTable,
+ offset,ligActionTable->offset,%lu,
+ nActions,ligActionTable->nActions,%u);
+ for ( i = 0; i < ligActionTable->nActions; i++ )
+ {
+ index = ligActionTable->body[i]&GX_MORX_LIGATURE_ACTION_OFFSET;
+ sindex = gx_sign_extend(index,GX_MORX_LIGATURE_ACTION_OFFSET);
+
+ PVALUE5(t,action,ligActionTable->body[i],%lu,
+ actionIndex,i,%d,
+ last,ligActionTable->body[i]&GX_MORX_LIGATURE_ACTION_LAST,0x%lx,
+ store,ligActionTable->body[i]&GX_MORX_LIGATURE_ACTION_STORE,0x%lx,
+ index,index,%lu,
+ indexSE,sindex,%ld);
+
+ bsindex = (morx_tmp_firstGlyph + sindex);
+ nbsindex = (morx_tmp_firstGlyph + morx_tmp_nGlyphs + sindex);
+ area = morx_tmp_nLigature;
+#if GX_DEBUG_MORX_LIGATURE_TABLE_LAYOUT
+ if ( area < bsindex )
+ 1 && fprintf ( stderr, "[MAX: %d I: %d]range out[bsindex is too large: %lu > area: %lu]\n",
+ ligActionTable->nActions, i,
+ bsindex, area);
+ else
+ 1 && fprintf ( stderr, "[MAX: %d I: %d]ok[bsindex: %lu nbsindex: %lu area: %lu]\n",
+ ligActionTable->nActions, i,
+ bsindex, nbsindex, area);
+#endif /* GX_DEBUG_MORX_LIGATURE_TABLE_LAYOUT */
+ }
+
+ PCLOSE(t,ligActionTable);
+}
+
+static void
+gx_face_dump_morx_component_table( GX_Face face,
+ GX_XMetamorphosisComponentTable componentTable,
+ int t)
+{
+ int i;
+ POPEN2(t, componentTable,
+ offset,componentTable->offset,%lu,
+ nComponent,componentTable->nComponent,%u);
+ for ( i = 0; i < componentTable->nComponent; i++ )
+ {
+ NEWLINE10(t,i);
+ fprintf(stdout, "%u[%d] ", componentTable->body[i], i);
+ }
+ NEWLINE();
+ PCLOSE(t, componentTable);
+}
+
+static void
+gx_face_dump_morx_ligature_table( GX_Face face,
+ GX_XMetamorphosisLigatureTable ligatureTable,
+ int t)
+{
+ int i;
+ POPEN2(t, ligatureTable,
+ offset,ligatureTable->offset,%lu,
+ nLigature,ligatureTable->nLigature,%u);
+ for ( i = 0; i < ligatureTable->nLigature; i++ )
+ {
+ NEWLINE10(t,i);
+ fprintf(stdout, "%u[%d] ", ligatureTable->body[i], i);
+ }
+ NEWLINE();
+ PCLOSE(t, ligatureTable);
+}
+
+static void
+gx_face_dump_morx_ligature_subtable( GX_Face face,
+ GX_XMetamorphosisLigatureBody body,
+ int t )
+{
+ GX_XStateTable state_table;
+ state_table = &body->state_table;
+
+ morx_tmp_nLigature = body->ligatureTable.nLigature;
+ morx_tmp_ligatureTable = body->ligatureTable.offset;
+
+ POPEN(t, ligatureSubtable);
+ gx_face_dump_xstate_table(face, state_table,
+ gx_face_dump_morx_ligature_entry,
+ t);
+ gx_face_dump_morx_ligature_action_table(face, &body->ligActionTable, t);
+ gx_face_dump_morx_component_table (face, &body->componentTable, t);
+ gx_face_dump_morx_ligature_table (face, &body->ligatureTable, t);
+ PCLOSE(t, ligatureSubtable);
+}
+
+static void
+gx_face_dump_morx_insertion_subtable ( GX_Face face,
+ GX_XMetamorphosisInsertionBody body,
+ int t )
+{
+ GX_XStateTable state_table;
+ state_table = &body->state_table;
+ POPEN(t, insertionSubtable);
+ gx_face_dump_xstate_table(face, state_table,
+ gx_face_dump_morx_insertion_entry,
+ t);
+ PCLOSE(t, insertionSubtable);
+}
+
+static void
+gx_face_dump_morx_subtable(GX_Face face, GX_XMetamorphosisSubtable subtable,
+ FT_ULong nSubtables, int t)
+{
+ GX_XMetamorphosisSubtable psubtable;
+ int n;
+ POPEN(t, SubTables);
+ for ( n = 0; n < nSubtables; n++ )
+ {
+ POPEN(t, chainSubtable);
+ psubtable = &subtable[n];
+ gx_face_dump_morx_subtable_header(face, &psubtable->header, t);
+ switch(psubtable->header.coverage&GX_MORX_COVERAGE_SUBTABLE_TYPE)
+ {
+ case GX_MORX_REARRANGEMENT_SUBTABLE:
+ gx_face_dump_morx_rearrangement_subtable(face,
+ psubtable->body.rearrangement,
+ t);
+ break;
+ case GX_MORX_CONTEXTUAL_SUBTABLE:
+ gx_face_dump_morx_contextual_subtable(face,
+ psubtable->body.contextual,
+ t);
+ break;
+ case GX_MORX_LIGATURE_SUBTABLE:
+ gx_face_dump_morx_ligature_subtable(face,
+ psubtable->body.ligature,
+ t);
+ break;
+ case GX_MORX_RESERVED_SUBTABLE:
+ PVALUE(t,error,"**RESERVED**", %s);
+ break;
+ case GX_MORX_NONCONTEXTUAL_SUBTABLE:
+ gx_face_dump_morx_noncontextual_subtable ( face,
+ psubtable->body.noncontextual,
+ t );
+ break;
+ case GX_MORX_INSERTION_SUBTABLE:
+ gx_face_dump_morx_insertion_subtable(face,
+ psubtable->body.insertion,
+ t);
+ break;
+ default:
+ PVALUE(t,error,"**UNKNOWN**", %s);
+ break;
+ }
+ PCLOSE(t, chainSubtable);
+ }
+ PCLOSE(t, SubTables);
+}
+
+static void
+gx_face_dump_morx_chain(GX_Face face, GX_XMetamorphosisChain chain, int t)
+{
+ POPEN(t,chain);
+ gx_face_dump_morx_chain_header(face, &chain->header, t);
+ gx_face_dump_morx_feature_table(face, chain->feat_Subtbl, chain->header.nFeatureEntries, t);
+ gx_face_dump_morx_subtable(face, chain->chain_Subtbl, chain->header.nSubtables, t);
+ PCLOSE(t,chain);
+}
+
+void
+gx_face_dump_morx(GX_Face face, GX_Morx morx)
+{
+ int i, t = 2;
+ PFIELD(t,morx,version,0x%08lx);
+ PFIELD(t,morx,nChains,%lu);
+ POPEN(t, chains);
+ for ( i = 0; i < morx->nChains; i++ )
+ gx_face_dump_morx_chain(face, &morx->chain[i], t);
+ PCLOSE(t, chains);
+}
+
+
+
+/******************************JUST************************************/
+void
+gx_face_dump_just(GX_Face face, GX_Just just)
+{
+ int t = 2;
+ PFIELD(t, just, version, 0x%08lx);
+ PFIELD(t, just, format, %u);
+ PFIELD(t, just, horizOffset, %u);
+ PFIELD(t, just, vertOffset, %u);
+}
+
+
+/******************************KERN************************************/
+void
+gx_face_dump_kern_subtable_header_coverage(GX_Face face,
+ FT_UShort coverage, int t)
+{
+ POPEN(t, coverage);
+ PVALUE(t, value, coverage, 0x%04x);
+ PVALUE(t, vertical, coverage&GX_KERN_COVERAGE_VERTICAL, %u);
+ PVALUE(t, corss-stream, coverage&GX_KERN_COVERAGE_CROSS_STREAM, %u);
+ PVALUE(t, variation, coverage&GX_KERN_COVERAGE_VARIATION, %u);
+ PVALUE(t, format, coverage&GX_KERN_COVERAGE_FORMAT_MASK, %u);
+ PCLOSE(t, coverage);
+}
+void
+gx_face_dump_kern_sutable_header(GX_Face face, GX_KerningSubtableHeader header, int t)
+{
+ POPEN(t, header);
+ PFIELD(t, header, length, %lu);
+ gx_face_dump_kern_subtable_header_coverage(face, header->coverage, t);
+ PFIELD(t, header, tupleIndex, %u);
+ PCLOSE(t, header);
+}
+
+void
+gx_face_dump_kern_fmt0_subtable(GX_Face face, GX_KerningSubtableFormat0Body fmt0, int t)
+{
+ int i;
+ POPEN(t, fmt0);
+ PFIELD(t, fmt0, nPairs, %u);
+ PFIELD(t, fmt0, searchRange, %u);
+ PFIELD(t, fmt0, entrySelector, %u);
+ PFIELD(t, fmt0, rangeShift, %u);
+ POPEN (t, pairs);
+ for ( i = 0; i < fmt0->nPairs; i++ )
+ PVALUE3(t,
+ value,fmt0->entries[i].value,%d,
+ index,i,%d,
+ left,fmt0->entries[i].left,%u,
+ right,fmt0->entries[i].right,%u);
+ PCLOSE(t, pairs);
+ PCLOSE(t, fmt0);
+}
+
+
+static FT_Error
+gx_face_dump_kern_fmt1_entry( GX_EntrySubtable entry_subtable,
+ FT_Pointer user )
+{
+ int t = *(int *)user;
+ POPEN1(t,flags,value,entry_subtable->flags,%u);
+ PVALUE(t,push,entry_subtable->flags&GX_KERN_ACTION_PUSH,%u);
+ PVALUE(t,dontAdvance,entry_subtable->flags&GX_KERN_ACTION_DONT_ADVANCE,%u);
+ PVALUE(t,valueOffset,entry_subtable->flags&GX_KERN_ACTION_VALUE_OFFSET,%u);
+ PCLOSE(t,flags);
+ return FT_Err_Ok;
+}
+
+void
+gx_face_dump_kern_fmt1_subtable( GX_Face face, GX_KerningSubtableFormat1Body fmt1, int t)
+{
+ FT_ULong i;
+ POPEN (t, fmt1);
+ gx_face_dump_state_table ( face, &fmt1->state_table,
+ gx_face_dump_kern_fmt1_entry, t);
+ PFIELD(t,fmt1,valueTable,%u);
+ PFIELD(t,fmt1,value_absolute_pos,%lu);
+ PFIELD(t,fmt1,nValues,%lu);
+ POPEN2(t, values,
+ absolutePosition, fmt1->value_absolute_pos, %lu,
+ nValues, fmt1->nValues, %lu );
+ for ( i = 0; i < fmt1->nValues; i++ )
+ {
+ NEWLINE10(t,i);
+ fprintf(stdout, "%u[%lu] ", fmt1->values[i], i);
+ }
+ NEWLINE();
+ PCLOSE(t,values);
+ PCLOSE (t, fmt1);
+}
+
+void
+gx_face_dump_kern_fmt2_class_table ( GX_Face face,
+ GX_KerningSubtableFormat2ClassTable class_table, int t)
+{
+ int i;
+ PFIELD(t, class_table, firstGlyph, %u );
+ PFIELD(t, class_table, nGlyphs, %u );
+ POPEN1(t, classes, max, class_table->max_class,%d);
+ for ( i = 0; i < class_table->nGlyphs; i++ )
+ {
+ NEWLINE10(t,i);
+ fprintf(stdout, "%u[%d] ", class_table->classes[i], i);
+ }
+ NEWLINE();
+ PCLOSE(t, classes);
+}
+
+void
+gx_face_dump_kern_fmt2_subtable( GX_Face face, GX_KerningSubtableFormat2Body fmt2, int t)
+{
+ int i;
+ POPEN(t, fmt2);
+ PFIELD(t, fmt2, rowWidth, %u);
+ PFIELD(t, fmt2, leftClassTable, %u);
+ PFIELD(t, fmt2, rightClassTable, %u);
+ PFIELD(t, fmt2, array, %u);
+ POPEN(t, leftClass);
+ gx_face_dump_kern_fmt2_class_table( face, &fmt2->leftClass, t );
+ PCLOSE(t, leftClass);
+ POPEN(t, rightClass);
+ gx_face_dump_kern_fmt2_class_table( face, &fmt2->rightClass, t );
+ PCLOSE(t, rightClass);
+
+ POPEN(t, values);
+ for ( i = 0; i < fmt2->leftClass.max_class + fmt2->rightClass.max_class; i++ )
+ {
+ NEWLINE10(t, i);
+ fprintf(stdout, "%d[%d] ", fmt2->values[i], i);
+ }
+ NEWLINE();
+ PCLOSE(t, values);
+ PCLOSE(t, fmt3);
+}
+
+void
+gx_face_dump_kern_fmt3_subtable( GX_Face face, GX_KerningSubtableFormat3Body fmt3, int t)
+{
+ int i;
+ POPEN(t, fmt3);
+ PFIELD(t, fmt3, glyphCount, %u);
+ PFIELD(t, fmt3, kernValueCount, %u);
+ PFIELD(t, fmt3, leftClassCount, %u);
+ PFIELD(t, fmt3, rightClassCount, %u);
+ PFIELD(t, fmt3, flags, %u);
+
+ POPEN(t, kernValue);
+ for ( i = 0; i < fmt3->kernValueCount; i++ )
+ {
+ NEWLINE10(t, i);
+ fprintf(stdout, "%d[%d] ", fmt3->kernValue[i], i);
+ }
+ NEWLINE();
+ PCLOSE(t,kernValue);
+
+ POPEN(t, leftClass);
+ for ( i = 0; i < fmt3->glyphCount; i++ )
+ {
+ NEWLINE10(t, i);
+ fprintf(stdout, "%u[%d] ", fmt3->leftClass[i], i);
+ }
+ NEWLINE();
+ PCLOSE(t,leftClass);
+
+ POPEN(t, rightClass);
+ for ( i = 0; i < fmt3->glyphCount; i++ )
+ {
+ NEWLINE10(t, i);
+ fprintf(stdout, "%u[%d] ", fmt3->rightClass[i], i);
+ }
+ NEWLINE();
+ PCLOSE(t,rightClass);
+
+ POPEN(t, kernIndex);
+ for ( i = 0; i < fmt3->leftClassCount * fmt3->rightClassCount ; i++ )
+ {
+ NEWLINE10(t, i);
+ fprintf(stdout, "%u[%d] ", fmt3->kernIndex[i], i);
+ }
+ NEWLINE();
+ PCLOSE(t,kernIndex);
+ PCLOSE(t, fmt3);
+}
+
+void
+gx_face_dump_kern_sutable(GX_Face face, GX_KerningSubtable subtable, int t)
+{
+ GX_KerningFormat format = subtable->header.coverage&GX_KERN_COVERAGE_FORMAT_MASK;
+ POPEN(t, subtable);
+ gx_face_dump_kern_sutable_header(face, &subtable->header, t);
+ switch ( format )
+ {
+ case GX_KERN_FMT_ORDERED_LIST_OF_KERNING_PAIRS:
+ gx_face_dump_kern_fmt0_subtable(face, subtable->body.fmt0, t);
+ break;
+ case GX_KERN_FMT_STATE_TABLE_FOR_CONTEXTUAL_KERNING:
+ gx_face_dump_kern_fmt1_subtable(face, subtable->body.fmt1, t);
+ break;
+ case GX_KERN_FMT_SIMPLE_NXM_ARRAY_OF_KERNING_VALUES:
+ gx_face_dump_kern_fmt2_subtable(face, subtable->body.fmt2, t);
+ break;
+ case GX_KERN_FMT_SIMPLE_NXM_ARRAY_OF_KERNING_INDICES:
+ gx_face_dump_kern_fmt3_subtable(face, subtable->body.fmt3, t);
+ break;
+ }
+ PCLOSE(t, subtable);
+}
+void
+gx_face_dump_kern(GX_Face face, GX_Kern kern)
+{
+ int i, t = 2;
+ PFIELD(t, kern, version, 0x%08lx);
+ PFIELD(t, kern, nTables, %lu);
+ POPEN(t, subtables);
+ for ( i = 0; i < kern->nTables; i++ )
+ gx_face_dump_kern_sutable(face, &kern->subtables[i], t);
+ PCLOSE(t, subtables);
+}
+
+/******************************FVAR************************************/
+
+static void
+gx_face_dump_fvar_sfnt_variation_axis( GX_Face face,
+ GX_FontVariationsSFNTVariationAxis axis,
+ int t);
+static void
+gx_face_dump_fvar_sfnt_instance( GX_Face face,
+ FT_UShort axis_count,
+ GX_FontVariationsSFNTInstance instance,
+ int t);
+
+void
+gx_face_dump_fvar(GX_Face face, GX_Fvar fvar)
+{
+ int i, t = 2;
+
+ PFIELD(t, fvar, version, 0x%08lx);
+ PFIELD(t, fvar, offsetToData, %u);
+ PFIELD(t, fvar, countSizePairs, %u);
+ PFIELD(t, fvar, axisCount, %u);
+ PFIELD(t, fvar, axisSize, %u);
+ PFIELD(t, fvar, instanceCount, %u);
+ PFIELD(t, fvar, instanceSize, %u);
+ for ( i = 0; i < fvar->axisCount; i++ )
+ {
+ POPEN1(t, axis, index, i, %d);
+ gx_face_dump_fvar_sfnt_variation_axis(face,
+ &fvar->axis[i],
+ t);
+ PCLOSE(t, axis);
+ }
+
+ for ( i = 0; i < fvar->instanceCount; i++ )
+ {
+ POPEN1(t, instance, index, i, %d);
+ gx_face_dump_fvar_sfnt_instance(face,
+ fvar->axisCount,
+ &fvar->instance[i],
+ t);
+ PCLOSE(t, instance);
+ }
+}
+
+static void
+gx_face_dump_fvar_sfnt_variation_axis( GX_Face face,
+ GX_FontVariationsSFNTVariationAxis axis,
+ int t)
+{
+ FT_Error error;
+ FT_Memory memory = face->root.driver->root.memory;
+ FT_SfntName sfnt_name;
+ FT_String * string;
+ int j;
+
+ PTAG(t, axisTag, axis->axisTag);
+ PFIELD(t, axis, minValue, %ld);
+ PFIELD(t, axis, defaultValue, %ld);
+ PFIELD(t, axis, maxValue, %ld);
+ PFIELD(t, axis, flags, %u);
+
+ if (( error = gx_get_name_from_id((FT_Face)face,
+ axis->nameID,
+ 0, 0, 0,
+ &sfnt_name) ))
+ PFIELD(t, axis, nameID, %u);
+ else
+ {
+ if ( FT_NEW_ARRAY(string, sfnt_name.string_len + 1) )
+ goto NameFailure;
+ string[sfnt_name.string_len] = '\0';
+ for ( j = 0; j < sfnt_name.string_len; j++)
+ {
+ /* Don't use '&' in pseudo XML file.
+ Here I replace '&' with '|'. */
+ if ( sfnt_name.string[j] == '&' )
+ string[j] = '|' ;
+ else
+ string[j] = sfnt_name.string[j];
+ }
+ PFIELD1(t,axis,nameID,%u,name,string,%s);
+ FT_FREE(string);
+ }
+ return;
+ NameFailure:
+ exit(1);
+}
+
+static void
+gx_face_dump_fvar_sfnt_instance( GX_Face face,
+ FT_UShort axis_count,
+ GX_FontVariationsSFNTInstance instance,
+ int t)
+{
+ FT_Error error;
+ int i;
+ FT_Memory memory = face->root.driver->root.memory;
+ FT_SfntName sfnt_name;
+ FT_String * string;
+ int j;
+
+ if (( error = gx_get_name_from_id((FT_Face)face,
+ instance->nameID,
+ 0, 0, 0, &sfnt_name) ))
+ PFIELD(t, instance, nameID, %u);
+ else
+ {
+ if ( FT_NEW_ARRAY(string, sfnt_name.string_len + 1) )
+ goto NameFailure;
+ string[sfnt_name.string_len] = '\0';
+ for ( j = 0; j < sfnt_name.string_len; j++)
+ {
+ /* Don't use '&' in pseudo XML file.
+ Here I replace '&' with '|'. */
+ if ( sfnt_name.string[j] == '&' )
+ string[j] = '|' ;
+ else
+ string[j] = sfnt_name.string[j];
+ }
+ PFIELD1(t,instance,nameID,%u,name,string,%s);
+ FT_FREE(string);
+ }
+
+ PFIELD(t, instance, flags, %u);
+ POPEN (t, coord);
+ for ( i = 0; i < axis_count; i++ )
+ {
+ NEWLINE10(t, i);
+ fprintf(stdout, "%ld[%d] ", instance->coord[i], i);
+ }
+ NEWLINE();
+ PCLOSE(t, coord);
+ return ;
+ NameFailure:
+ exit(error);
+}
+
+
+/****************************State***********************************/
+static void
+gx_face_dump_state_header(GX_Face face, GX_StateHeader header, int t)
+{
+ POPEN(t,header);
+ PFIELD(t,header,position,%lu);
+ PFIELD(t,header,stateSize,%u);
+ PFIELD(t,header,classTable,%u);
+ PFIELD(t,header,stateArray,%u);
+ PFIELD(t,header,entryTable,%u);
+ PCLOSE(t,header);
+}
+
+static void
+gx_face_dump_class_subtable(GX_Face face, GX_ClassSubtable subtbl, FT_UShort stateSize, int t)
+{
+ int i;
+ POPEN(t,classSubtable);
+ PFIELD(t,subtbl,firstGlyph,%u);
+ mort_tmp_firstGlyph = subtbl->firstGlyph;
+ PFIELD(t,subtbl,nGlyphs,%u);
+ mort_tmp_nGlyphs = subtbl->nGlyphs;
+ POPEN(t,classArray);
+ for ( i = 0; i < subtbl->nGlyphs; i++ )
+ {
+ NEWLINEX(t,i,stateSize);
+ fprintf(stdout, "%u[%d] ", subtbl->classArray[i], i);
+ }
+ NEWLINE();
+ PCLOSE(t,classArray);
+ PCLOSE(t,classSubtable);
+}
+
+static void
+gx_face_dump_entry_table( GX_Face face, FT_Byte nEntries, GX_EntrySubtable subtbl,
+ GX_StateTable_Entry_Action action, int t)
+{
+ int i;
+ POPEN1(t,EntrySubtables, nEntries,nEntries,%u);
+ for ( i = 0; i < nEntries; i++ )
+ {
+ POPEN(t,EntrySubtable);
+ PFIELD(t,(&(subtbl[i])),newState,%u);
+ if (action)
+ action((&(subtbl[i])), &t);
+ else
+ PFIELD(t,(&(subtbl[i])),flags,%u);
+ PCLOSE(t,EntrySubtable);
+ }
+ PCLOSE(t,EntrySubtables);
+}
+
+static void
+gx_face_dump_state_array(GX_Face face,
+ FT_ULong nStates, FT_UShort state_size,
+ FT_Byte * state_array, FT_UShort start, int t)
+{
+ int i, j;
+ FT_Byte * row;
+ POPEN(t, stateArray);
+ for ( i = 0; i < nStates; i++ )
+ {
+ row = state_array + (i * state_size);
+ POPEN2(t,row,
+ state,i,%d,
+ offset,start+(i * state_size),%d);
+ for (j = 0; j < state_size; j++)
+ {
+ NEWLINE10(t, j);
+ fprintf(stdout, "%u[%d] ", row[j], j);
+ }
+ NEWLINE();
+ PCLOSE(t,row);
+ }
+ PCLOSE(t, stateArray);
+}
+static void
+gx_face_dump_state_table ( GX_Face face,
+ GX_StateTable state_table,
+ GX_StateTable_Entry_Action action,
+ int t )
+{
+ POPEN(t, stateTable);
+ gx_face_dump_state_header(face, &state_table->header, t);
+ gx_face_dump_class_subtable(face,&state_table->class_subtable,
+ state_table->header.stateSize, t);
+ gx_face_dump_state_array(face,
+ state_table->nStates, state_table->header.stateSize,
+ state_table->state_array,
+ state_table->header.stateArray,
+ t);
+ gx_face_dump_entry_table(face,state_table->nEntries,state_table->entry_subtable,
+ action, t);
+ PCLOSE(t, stateTable);
+}
+
+
+/****************************XState***********************************/
+static void
+gx_face_dump_xstate_header(GX_Face face, GX_XStateHeader header, int t)
+{
+ POPEN(t,header);
+ PFIELD(t,header,position,%lu);
+ PFIELD(t,header,nClasses,%lu);
+ PFIELD(t,header,classTableOffset,%lu);
+ PFIELD(t,header,stateArrayOffset,%lu);
+ PFIELD(t,header,entryTableOffset,%lu);
+ PCLOSE(t,header);
+}
+
+static void
+gx_face_dump_xstate_array( GX_Face face,
+ FT_ULong nStates, FT_ULong nClasses,
+ FT_UShort * state_array, int t )
+{
+ unsigned long i, j;
+ FT_UShort * row;
+ POPEN(t, stateArray);
+ for ( i = 0; i < nStates; i++ )
+ {
+ row = state_array + (i * nClasses);
+ POPEN1(t,row,
+ state,i,%lu);
+ INDENT(t);
+ for (j = 0; j < nClasses; j++)
+ fprintf(stdout, "%u[%lu] ", row[j], j);
+ NEWLINE();
+ PCLOSE(t,row);
+ }
+ PCLOSE(t, stateArray);
+}
+
+static FT_Error
+tmp_morx_simple_array_count_glyph( GX_LookupTable_Format format,
+ FT_UShort index,
+ GX_LookupValue value,
+ FT_Pointer user )
+{
+ if ( morx_tmp_firstGlyph == 0 )
+ morx_tmp_firstGlyph = index;
+ if ( morx_tmp_firstGlyph > index )
+ morx_tmp_firstGlyph = index;
+ if ( ( index - morx_tmp_firstGlyph ) > morx_tmp_nGlyphs )
+ morx_tmp_nGlyphs = ( index - morx_tmp_firstGlyph );
+ return FT_Err_Ok;
+}
+
+static FT_Error
+tmp_morx_segment_single_count_glyph( GX_LookupTable_Format format,
+ FT_UShort lastGlyph,
+ FT_UShort firstGlyph,
+ GX_LookupValue value,
+ FT_Pointer user )
+{
+ morx_tmp_firstGlyph = firstGlyph;
+ morx_tmp_nGlyphs = lastGlyph - firstGlyph;
+ return FT_Err_Ok;
+}
+
+static FT_Error
+tmp_morx_segment_array_count_glyph( GX_LookupTable_Format format,
+ FT_UShort lastGlyph,
+ FT_UShort firstGlyph,
+ GX_LookupValue value,
+ FT_Pointer user )
+{
+ morx_tmp_firstGlyph = firstGlyph;
+ morx_tmp_nGlyphs = lastGlyph - firstGlyph;
+ return FT_Err_Ok;
+}
+
+static FT_Error
+tmp_morx_single_table_count_glyph( GX_LookupTable_Format format,
+ FT_UShort glyph,
+ GX_LookupValue value,
+ FT_Pointer user )
+{
+ /* fprintf(stderr, "format 6: glyph: %u\n", glyph ); */
+ if ( morx_tmp_firstGlyph == 0 )
+ morx_tmp_firstGlyph = glyph;
+ if ( morx_tmp_firstGlyph > glyph )
+ morx_tmp_firstGlyph = glyph;
+ if ( ( glyph - morx_tmp_firstGlyph ) > morx_tmp_nGlyphs )
+ morx_tmp_nGlyphs = ( glyph - morx_tmp_firstGlyph );
+ return FT_Err_Ok;
+}
+
+static FT_Error
+tmp_morx_trimmed_array_count_glyph( GX_LookupTable_Format format,
+ FT_UShort index,
+ FT_UShort firstGlyph,
+ FT_UShort lastGlyph,
+ GX_LookupValue value,
+ FT_Pointer user )
+{
+ morx_tmp_firstGlyph = firstGlyph;
+ morx_tmp_nGlyphs = lastGlyph - firstGlyph;
+ return FT_Err_Ok;
+}
+
+static void
+gx_face_dump_xstate_table ( GX_Face face,
+ GX_XStateTable state_table,
+ GX_XStateTable_Entry_Action action,
+ int t )
+{
+ GX_LookupTable_FuncsRec tmp_funcs = {
+ NULL,
+ tmp_morx_simple_array_count_glyph,
+ tmp_morx_segment_single_count_glyph,
+ tmp_morx_segment_array_count_glyph,
+ tmp_morx_single_table_count_glyph,
+ tmp_morx_trimmed_array_count_glyph
+ };
+
+ POPEN(t, XstateTable);
+ gx_face_dump_xstate_header(face, &state_table->header, t);
+
+ morx_tmp_firstGlyph = 0;
+ morx_tmp_nGlyphs = 0;
+ morx_tmp_format = state_table->class_subtable.format;
+ gx_LookupTable_traverse_low( &state_table->class_subtable, &tmp_funcs, NULL );
+#if 1
+ gx_face_dump_LookupTable_low(face, &state_table->class_subtable,
+ &generic_lookup_table_funcs, t);
+#else
+ gx_face_dump_LookupTable_high(face, &state_table->class_subtable,
+ &morx_dump_lookup_table_func, t);
+#endif /* 0 */
+
+ gx_face_dump_xstate_array(face,
+ state_table->nStates, state_table->header.nClasses,
+ state_table->state_array, t);
+ gx_face_dump_entry_table(face, state_table->nEntries, state_table->entry_subtable,
+ action, t);
+ PCLOSE(t, XstateTable);
+}
+
+/****************************GENERIC***********************************/
+static void
+dump_table_info(GX_Table table_info, int n)
+{
+ POPEN(n,tableInfo);
+ PFIELD(n,table_info,position,%lu);
+ PFIELD(n,table_info,length,%lu);
+ PCLOSE(n,tableInfo);
+}
+
+static FT_Error
+generic_dump_lookup_table_generic ( GX_LookupTable_Format format,
+ GX_LookupValue value,
+ FT_Pointer user )
+{
+ FT_Int * t = (FT_Int*) user;
+ PFIELD(*t,value,raw.s,%d);
+ return FT_Err_Ok;
+}
+
+static FT_Error
+generic_dump_lookup_table_segment( GX_LookupTable_Format format,
+ FT_UShort lastGlyph,
+ FT_UShort firstGlyph,
+ GX_LookupValue value,
+ FT_Pointer user )
+{
+ FT_UShort segment_count = lastGlyph - firstGlyph;
+ FT_UShort * extra = value->extra.word;
+ FT_Int * t = (FT_Int*) user;
+ int i;
+ POPEN(*t, segmentArrayElement);
+ PFIELD(*t,value,raw.s,%d);
+ PVALUE(*t,lastGlyph,lastGlyph,%u);
+ PVALUE(*t,firstGlyph,firstGlyph,%u);
+ POPEN(*t, extra);
+ for ( i = 0; i < segment_count; i++ )
+ {
+ NEWLINE10(*t, i);
+ fprintf(stdout, "%u[%d] ", extra[i], i);
+ }
+ NEWLINE();
+ PCLOSE(*t, extra);
+ PCLOSE((*t), segmentArrayElement);
+ return FT_Err_Ok;
+}
+
+static void
+gx_face_dump_binSrchHeader( GX_Face face,
+ GX_BinSrchHeader binSrchHeader,
+ int t)
+{
+ POPEN(t, binSrchHeader);
+ PFIELD(t,binSrchHeader,unitSize,%u);
+ PFIELD(t,binSrchHeader,nUnits,%u);
+ PFIELD(t,binSrchHeader,searchRange,%u);
+ PFIELD(t,binSrchHeader,entrySelector,%u);
+ PFIELD(t,binSrchHeader,rangeShift,%u);
+ PCLOSE(t, binSrchHeader);
+}
+static void
+gx_face_dump_LookupTable_low( GX_Face face,
+ GX_LookupTable lookup_table,
+ GX_LookupTable_Funcs funcs,
+ int t)
+{
+ GX_LookupTable_Trimmed_Array trimmed_array ;
+ GX_LookupTable_BinSrch binsrch;
+ GX_LookupTable_FuncsRec default_funcs = {
+ generic_dump_lookup_table_generic,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ };
+
+ if (!funcs)
+ funcs = &default_funcs;
+
+ if (!funcs->generic_func)
+ funcs->generic_func = generic_dump_lookup_table_generic;
+
+ POPEN2(t,lookupTable,
+ position,lookup_table->position,%lu,
+ format,lookup_table->format,%u);
+
+ switch ( lookup_table->format )
+ {
+ case GX_LOOKUPTABLE_SIMPLE_ARRAY:
+ /* DO NOTHING */
+ break;
+ case GX_LOOKUPTABLE_SEGMENT_SINGLE:
+ case GX_LOOKUPTABLE_SEGMENT_ARRAY:
+ case GX_LOOKUPTABLE_SINGLE_TABLE:
+ binsrch = lookup_table->fsHeader.bin_srch;
+ gx_face_dump_binSrchHeader( face, &binsrch->binSrchHeader, t );
+ break;
+ case GX_LOOKUPTABLE_TRIMMED_ARRAY:
+ trimmed_array = lookup_table->fsHeader.trimmed_array;
+ PFIELD(t,trimmed_array, firstGlyph, %u);
+ PFIELD(t,trimmed_array, glyphCount, %u);
+ break;
+ }
+ POPEN(t,values);
+ gx_LookupTable_traverse_low( lookup_table, funcs, &t );
+ PCLOSE(t,values);
+ PCLOSE(t,lookupTable);
+}
+
+static void
+gx_face_dump_LookupTable_high( GX_Face face,
+ GX_LookupTable lookup_table,
+ GX_LookupTable_Glyph_Func func,
+ int t )
+{
+ GX_LookupTable_Trimmed_Array trimmed_array ;
+ GX_LookupTable_BinSrch binsrch;
+
+ FT_ASSERT(func);
+
+ POPEN2(t,lookupTable,
+ position,lookup_table->position,%lu,
+ format,lookup_table->format,%u);
+
+ switch ( lookup_table->format )
+ {
+ case GX_LOOKUPTABLE_SIMPLE_ARRAY:
+ /* DO NOTHING */
+ break;
+ case GX_LOOKUPTABLE_SEGMENT_SINGLE:
+ case GX_LOOKUPTABLE_SEGMENT_ARRAY:
+ case GX_LOOKUPTABLE_SINGLE_TABLE:
+ binsrch = lookup_table->fsHeader.bin_srch;
+ gx_face_dump_binSrchHeader( face, &binsrch->binSrchHeader, t );
+ break;
+ case GX_LOOKUPTABLE_TRIMMED_ARRAY:
+ trimmed_array = lookup_table->fsHeader.trimmed_array;
+ PFIELD(t,trimmed_array, firstGlyph, %u);
+ PFIELD(t,trimmed_array, glyphCount, %u);
+ break;
+ }
+ POPEN(t,values);
+ gx_LookupTable_traverse_high( lookup_table, func, &t );
+ PCLOSE(t,values);
+ PCLOSE(t,lookupTable);
+}
+
+
+FT_EXPORT_DEF ( void )
+gxl_features_request_dump ( GXL_FeaturesRequest request, FILE * stream )
+{
+ FTL_Direction dir;
+ unsigned long i;
+ if ( !stream )
+ stream = stderr;
+ fprintf(stream, "Features Request: \n");
+ dir = FTL_Get_FeaturesRequest_Direction((FTL_FeaturesRequest)request);
+ fprintf(stream, "\tDirection: %s\n", (dir == FTL_HORIZONTAL)? "horizontal": "vertical");
+ for ( i = 0; i < request->nFeatures; i++ )
+ gxl_feature_dump ( &request->feature[i], stream );
+}
+
+FT_EXPORT ( void )
+gx_feature_registory_dump ( FILE * stream )
+{
+ int i, j;
+ GX_Feature_Registry featreg;
+ const FT_String * setting_name;
+
+ if ( !stream )
+ stream = stderr;
+
+ for ( i = 0; i < FEATREG_MAX ; i++ )
+ {
+ featreg = gx_get_feature_registry( i );
+ if ( !featreg )
+ continue ;
+ fprintf(stdout, "[%d]: %s, %s\n",
+ i,
+ gx_feature_registry_get_name(featreg),
+ gx_feature_registry_is_setting_exclusive( featreg )? "exclusive": "non-exclusive");
+ for ( j = 0; j < SETTING_MAX; j++ )
+ {
+ setting_name = gx_feature_registry_get_setting_name( featreg, j );
+ if ( !setting_name )
+ break;
+ fprintf(stdout, "\t%s\n", setting_name );
+ }
+ }
+}
+
+FT_EXPORT_DEF ( void )
+gxl_feature_dump ( GXL_Feature feature, FILE * stream )
+{
+ unsigned i;
+ FT_SfntName feature_name;
+
+ if ( !stream )
+ stream = stderr;
+
+ fprintf(stream, "\tFeatures: name=\"");
+ GXL_Feature_Get_Name ( feature, 0, 0, 0, &feature_name );
+ for ( i = 0; i < feature_name.string_len; i++ )
+ fputc(feature_name.string[i], stream);
+ fprintf(stream, "\" ");
+ fprintf(stream, "value=%u ", feature->value);
+ if ( feature->exclusive.exclusive )
+ fprintf(stream, "exclusive=%u", feature->exclusive.setting->value);
+ fprintf(stream, "\n");
+
+ for ( i = 0; i < feature->nSettings; i++ )
+ gxl_setting_dump(&feature->setting[i], stream);
+
+}
+
+FT_EXPORT_DEF ( void )
+gxl_setting_dump ( GXL_Setting setting, FILE * stream )
+{
+ unsigned i;
+ FT_SfntName setting_name;
+
+ if ( !stream )
+ stream = stderr;
+
+ GXL_Setting_Get_Name ( setting, 0, 0, 0, &setting_name );
+
+ fprintf(stream, "\t\tSetting: name=\"");
+ for ( i = 0; i < setting_name.string_len; i++ )
+ fputc(setting_name.string[i], stream);
+ fprintf(stream, "\" ");
+ fprintf(stream, "value=%u(%s)\n", setting->value,
+ GXL_Setting_Get_State(setting)? "on": "off");
+}
+
+/* END */
diff --git a/src/gxlayout/gxdump.h b/src/gxlayout/gxdump.h
new file mode 100644
index 000000000..b0d5d57e5
--- /dev/null
+++ b/src/gxlayout/gxdump.h
@@ -0,0 +1,71 @@
+/***************************************************************************/
+/* */
+/* gxdump.h */
+/* */
+/* Debug functions for AAT/TrueTypeGX driver (specification). */
+/* */
+/* Copyright 2003 by */
+/* Masatake YAMATO and Redhat K.K. */
+/* */
+/* This file may only be used, */
+/* modified, and distributed under the terms of the FreeType project */
+/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
+/* this file you indicate that you have read the license and */
+/* understand and accept it fully. */
+/* */
+/***************************************************************************/
+
+/***************************************************************************/
+/* Development of the code in this file is support of */
+/* Information-technology Promotion Agency, Japan. */
+/***************************************************************************/
+
+#ifndef __GXDUMP_H__
+#define __GXDUMP_H__
+
+#include <ft2build.h>
+#include FT_GXLAYOUT_H
+#include <stdio.h>
+
+FT_BEGIN_HEADER
+
+ typedef enum {
+ GX_DUMP_mort = 1 << 0,
+ GX_DUMP_morx = 1 << 1,
+ GX_DUMP_feat = 1 << 2,
+ GX_DUMP_prop = 1 << 3,
+ GX_DUMP_trak = 1 << 4,
+ GX_DUMP_kern = 1 << 5,
+ GX_DUMP_just = 1 << 6,
+ GX_DUMP_lcar = 1 << 7,
+ GX_DUMP_opbd = 1 << 8,
+ GX_DUMP_bsln = 1 << 9,
+ GX_DUMP_fmtx = 1 << 10,
+ GX_DUMP_fdsc = 1 << 11,
+ GX_DUMP_fvar = 1 << 12,
+ GX_DUMP_ALL = 0x7FFFFFFFUL /* gcc warns if I set this to 0xFFFFFFFFUL. */
+ } GXDumpFlag;
+
+ FT_EXPORT( FT_Error )
+ gx_face_dump( FT_Face face, FT_ULong tables, const char * fname );
+
+/* If STREAM is NULL, stderr is used as output stream. */
+ FT_EXPORT ( void )
+ gxl_features_request_dump ( GXL_FeaturesRequest request, FILE * stream );
+
+
+ FT_EXPORT ( void )
+ gx_feature_registory_dump ( FILE * stream );
+
+ FT_EXPORT ( void )
+ gxl_feature_dump ( GXL_Feature feature, FILE * stream );
+
+ FT_EXPORT ( void )
+ gxl_setting_dump ( GXL_Setting setting, FILE * stream );
+
+FT_END_HEADER
+
+#endif /* Not def: __GXDUMP_H__ */
+
+
+/* END */
diff --git a/src/gxlayout/gxerrors.h b/src/gxlayout/gxerrors.h
new file mode 100644
index 000000000..33a98de71
--- /dev/null
+++ b/src/gxlayout/gxerrors.h
@@ -0,0 +1,46 @@
+/***************************************************************************/
+/* */
+/* gxerrors.h */
+/* */
+/* AAT/TrueTypeGX error codes (specification only). */
+/* */
+/* Copyright 2003 by */
+/* Masatake YAMATO and Redhat K.K. */
+/* */
+/* This file may only be used, */
+/* modified, and distributed under the terms of the FreeType project */
+/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
+/* this file you indicate that you have read the license and */
+/* understand and accept it fully. */
+/* */
+/***************************************************************************/
+
+/***************************************************************************/
+/* Development of the code in this file is support of */
+/* Information-technology Promotion Agency, Japan. */
+/***************************************************************************/
+
+ /*************************************************************************/
+ /* */
+ /* This file is used to define the AAT/TrueTypeGX error */
+ /* enumeration constants. */
+ /* */
+ /*************************************************************************/
+
+#ifndef __GXERRORS_H__
+#define __GXERRORS_H__
+
+#include FT_MODULE_ERRORS_H
+
+#undef __FTERRORS_H__
+
+#define FT_ERR_PREFIX GX_Err_
+#define FT_ERR_BASE FT_Mod_Err_GX
+
+
+#include FT_ERRORS_H
+
+#endif /* __GXERRORS_H__ */
+
+
+/* END */
diff --git a/src/gxlayout/gxfeatreg.c b/src/gxlayout/gxfeatreg.c
new file mode 100644
index 000000000..f585568e7
--- /dev/null
+++ b/src/gxlayout/gxfeatreg.c
@@ -0,0 +1,456 @@
+/***************************************************************************/
+/* */
+/* gxfeatreg.c */
+/* */
+/* Database of font features pre-defined by Apple Computer, Inc. */
+/* http://developer.apple.com/fonts/Registry/ */
+/* (body). */
+/* */
+/* Copyright 2003 by */
+/* Masatake YAMATO and Redhat K.K. */
+/* */
+/* This file may only be used, */
+/* modified, and distributed under the terms of the FreeType project */
+/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
+/* this file you indicate that you have read the license and */
+/* understand and accept it fully. */
+/* */
+/***************************************************************************/
+
+/***************************************************************************/
+/* Development of the code in this file is support of */
+/* Information-technology Promotion Agency, Japan. */
+/***************************************************************************/
+
+#include "gxfeatreg.h"
+
+#define EMPTYFEAT {0, 0, {NULL}}
+
+/***************************************************************************/
+/* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING */
+/***************************************************************************/
+/*
+ * If you add a new setting to a feature, check the number of setting
+ * in the feature. If the number is greater than value defined as
+ * FEATREG_MAX_SETTING, update the value. Nor you cannot initialize
+ * featreg_table.
+ * This program is written in C.
+ */
+/***************************************************************************/
+/* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING */
+/***************************************************************************/
+
+#define FEATREG_MAX_SETTING 12
+
+typedef struct GX_Feature_RegistryRec_
+{
+ const FT_String * feat_name;
+ FT_Bool exclusive;
+ FT_String *setting_name[FEATREG_MAX_SETTING];
+ FT_UShort feature_type; /* Initialized on the fly. Thread unsafe? */
+} GX_Feature_RegistryRec;
+
+static GX_Feature_RegistryRec featreg_table [] = {
+ { /* 0 */
+ "All Typographic Features",
+ 0,
+ {
+ "All Type Features",
+ NULL
+ }
+ }, { /* 1 */
+ "Ligatures",
+ 0,
+ {
+ "Required Ligatures",
+ "Common Ligatures",
+ "Rare Ligatures",
+ "Logos",
+ "Rebus Pictures",
+ "Diphthong Ligatures",
+ "Squared Ligatures",
+ "Squared Ligatures, Abbreviated",
+ NULL
+ }
+ }, { /* 2 */
+ "Cursive Connection",
+ 1,
+ {
+ "Unconnected",
+ "Partially Connected",
+ "Cursive",
+ NULL
+ }
+ }, { /* 3 */
+ "Letter Case",
+ 1,
+ {
+ "Upper & Lower Case",
+ "All Caps",
+ "All Lower Case",
+ "Small Caps",
+ "Initial Caps",
+ "Initial Caps & Small Caps",
+ NULL
+ }
+ }, { /* 4 */
+ "Vertical Substitution",
+ 0,
+ {
+ /* "Substitute Vertical Forms", */
+ "Turns on the feature",
+ NULL
+ }
+ }, { /* 5 */
+ "Linguistic Rearrangement",
+ 0,
+ {
+ /* "Linguistic Rearrangement", */
+ "Turns on the feature",
+ NULL
+ }
+ }, { /* 6 */
+ "Number Spacing",
+ 1,
+ {
+ "Monospaced Numbers",
+ "Proportional Numbers",
+ NULL
+ }
+ }, { /* 7 */
+ "Apple Reserved 1",
+ 0,
+ {NULL}
+ }, { /* 8 */
+ "Smart Swashes",
+ 0,
+ {
+ "Word Initial Swashes",
+ "Word Final Swashes",
+ "Line Initial Swashes",
+ "Line Final Swashes",
+ "Non-Final Swashes",
+ NULL
+ }
+ }, { /* 9 */
+ "Diacritics",
+ 1,
+ {
+ "Show Diacritics",
+ "Hide Diacritics",
+ "Decompose Diacritics",
+ NULL
+ }
+ }, { /* 10 */
+ "Vertical Position",
+ 1,
+ {
+ /* "Normal Position", */
+ "No Vertical Position",
+ "Superiors",
+ "Inferiors",
+ "Ordinals",
+ NULL
+ }
+ }, { /* 11 */
+ "Fractions",
+ 1,
+ {
+ "No Fractions",
+ "Vertical Fractions",
+ "Diagonal Fractions",
+ NULL
+ }
+ }, { /* 12 */
+ "Apple Reserved 2",
+ 0,
+ {NULL}
+ }, { /* 13 */
+ "Overlapping Characters",
+ 0,
+ {
+ /* "Prevent Overlap", */
+ "Turns on the feature",
+ NULL
+ }
+ }, { /* 14 */
+ "Typographic Extras",
+ 0,
+ {
+ "Hyphens to Em Dash",
+ "Hyphens to En Dash",
+ "Unslashed Zero",
+ "Form Interrobang",
+ "Smart Quotes",
+ "Periods to Ellipsis",
+ NULL
+ }
+ }, { /* 15 */
+ "Mathematical Extras",
+ 0,
+ {
+ "Hyphens to Minus",
+ "Asterisk to Multiply",
+ "Slash to Divide",
+ "Inequality Ligatures",
+ "Exponents",
+ NULL
+ }
+ }, { /* 16 */
+ "Ornament Sets",
+ 1,
+ {
+ "No Ornaments",
+ "Dingbats",
+ "Pi Characters",
+ "Fleurons",
+ "Decorative Borders",
+ "International Symbols",
+ "Math Symbols",
+ NULL
+ }
+ }, { /* 17 */
+ "Character Alternatives",
+ 1,
+ {
+ "No Alternates",
+ /* TODO */
+ NULL
+ }
+ }, { /* 18 */
+ "Design Complexity",
+ 1,
+ {
+ "Design Level 1",
+ "Design Level 2",
+ "Design Level 3",
+ "Design Level 4",
+ "Design Level 5",
+ /* TODO */
+ NULL
+ }
+ }, { /* 19 */
+ "Style Options",
+ 1,
+ {
+ "No Style Options",
+ "Display Text",
+ "Engraved Text",
+ "Illuminated Caps",
+ "Tilling Caps",
+ "Tall Caps",
+ NULL
+ }
+ }, { /* 20 */
+ "Character Shape",
+ 1,
+ {
+ "Traditional Characters",
+ "Simplified Characters",
+ "JIS 1978 Characters",
+ "JIS 1983 Characters",
+ "JIS 1990 Characters",
+ "Traditional Characters, Alternative Set 1",
+ "Traditional Characters, Alternative Set 2",
+ "Traditional Characters, Alternative Set 3",
+ "Traditional Characters, Alternative Set 4",
+ "Traditional Characters, Alternative Set 5",
+ "Expert Characters",
+ NULL /* count=>12 */
+ }
+ }, { /* 21 */
+ "Number Case",
+ 1,
+ {
+ "Lower Case Numbers",
+ "Upper Case Numbers",
+ NULL
+ }
+ }, { /* 22 */
+ "Text Spacing",
+ 1,
+ {
+ "Proportional",
+ "Monospaced",
+ "Half-width",
+ "Normal",
+ NULL
+ }
+ }, /* Here after Newer */ { /* 23 */
+ "Transliteration",
+ 1,
+ {
+ "No Transliteration",
+ "Hanja To Hangul",
+ "Hiragana to Katakana",
+ "Katakana to Hiragana",
+ "Kana to Romanization",
+ "Romanization to Hiragana",
+ "Romanization to Katakana",
+ "Hanja to Hangul, Alternative Set 1",
+ "Hanja to Hangul, Alternative Set 2",
+ "Hanja to Hangul, Alternative Set 3",
+ NULL
+ }
+ }, { /* 24 */
+ "Annotation",
+ 1,
+ {
+ "No Annotation",
+ "Box Annotation",
+ "Rounded Box Annotation",
+ "Circle Annotation",
+ "Inverted Circle Annotation",
+ "Parenthesis Annotation",
+ "Period Annotation",
+ "Roman Numeral Annotation",
+ "Diamond Annotation",
+ NULL
+ }
+ }, { /* 25 */
+ "Kana Spacing",
+ 1,
+ {
+ "Full Width",
+ "Proportional",
+ NULL
+ }
+ }, { /* 26 */
+ "Ideographic Spacing",
+ 1,
+ {
+ "Full Width",
+ "Proportional",
+ NULL
+ }
+ }, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, /* 27-30 */
+ EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, /* 31-35 */
+ EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, /* 36-40 */
+ EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, /* 40-45 */
+ EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, /* 46-50 */
+ EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, /* 51-55 */
+ EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, /* 56-60 */
+ EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, /* 61-65 */
+ EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, /* 66-70 */
+ EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, /* 71-75 */
+ EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, /* 76-80 */
+ EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, /* 81-85 */
+ EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, /* 86-90 */
+ EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, /* 91-95 */
+ EMPTYFEAT, EMPTYFEAT, EMPTYFEAT, /* 96-98 */
+ EMPTYFEAT, /* 99 */ { /* 100 => 22*/
+ "Text Spacing",
+ 1,
+ {
+ "Proportional",
+ "Monospaced",
+ "Half-width",
+ "Normal",
+ NULL
+ }
+ }, { /* 101 => 25 */
+ "Kana Spacing",
+ 1,
+ {
+ "Full Width",
+ "Proportional",
+ NULL
+ }
+ }, { /* 102 => 26 */
+ "Ideographic Spacing",
+ 1,
+ {
+ "Full Width",
+ "Proportional",
+ NULL
+ }
+ }, { /* 103 */
+ "CJK Roman Spacing",
+ 1,
+ {
+ "Half-width",
+ "Proportional",
+ "Default Roman",
+ "Full-width Roman",
+ NULL
+ }
+ }, { /* 104 => 1 */
+ "All Typographic Features",
+ 0,
+ {
+ "All Type Features",
+ NULL
+ }
+ }
+#define FEATREG_MAX_INDEX 104
+};
+
+
+
+FT_LOCAL_DEF( GX_Feature_Registry )
+gx_get_feature_registry( FT_UShort feature_type )
+{
+ GX_Feature_Registry featreg;
+
+ if ( feature_type > FEATREG_MAX_INDEX )
+ return NULL;
+
+ featreg = &featreg_table[feature_type];
+ if ( featreg->feat_name == 0 )
+ return NULL;
+
+ featreg->feature_type = feature_type;
+ return featreg;
+}
+
+FT_LOCAL_DEF( const FT_String * )
+gx_feature_registry_get_name( GX_Feature_Registry featreg )
+{
+ if ( featreg )
+ return featreg->feat_name;
+ else
+ return NULL;
+}
+
+FT_LOCAL_DEF ( FT_Bool )
+gx_feature_registry_is_setting_exclusive( GX_Feature_Registry featreg )
+{
+ if ( featreg )
+ return featreg->exclusive;
+ else
+ return 0;
+}
+
+FT_LOCAL_DEF ( const FT_String * )
+gx_feature_registry_get_setting_name( GX_Feature_Registry featreg, FT_UShort nth )
+{
+ FT_UShort max;
+ if ( !featreg )
+ return NULL;
+
+ max = gx_feature_registry_count_setting ( featreg );
+ if ( nth < max )
+ return featreg->setting_name[nth];
+ else
+ return NULL;
+}
+
+FT_LOCAL_DEF ( FT_UShort )
+gx_feature_registry_count_setting ( GX_Feature_Registry featreg )
+{
+ FT_Int i;
+ if ( !featreg )
+ return 0;
+
+ for ( i = 0; featreg->setting_name[i]; i++ )
+ ; /* Do nothing */
+ return (FT_UShort)i;
+}
+
+FT_LOCAL_DEF( FT_UShort )
+gx_feature_registry_get_value(GX_Feature_Registry featreg)
+{
+ return featreg->feature_type;
+}
+
+/* END */
diff --git a/src/gxlayout/gxfeatreg.h b/src/gxlayout/gxfeatreg.h
new file mode 100644
index 000000000..c049ab7e3
--- /dev/null
+++ b/src/gxlayout/gxfeatreg.h
@@ -0,0 +1,45 @@
+/***************************************************************************/
+/* */
+/* gxfeatreg.h */
+/* */
+/* Database of font features pre-defined by Apple Computer, Inc. */
+/* http://developer.apple.com/fonts/Registry/ */
+/* (specification only). */
+/* */
+/* Copyright 2003 by */
+/* Masatake YAMATO and Redhat K.K. */
+/* */
+/* This file may only be used, */
+/* modified, and distributed under the terms of the FreeType project */
+/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
+/* this file you indicate that you have read the license and */
+/* understand and accept it fully. */
+/* */
+/***************************************************************************/
+
+/***************************************************************************/
+/* Development of the code in this file is support of */
+/* Information-technology Promotion Agency, Japan. */
+/***************************************************************************/
+
+#ifndef __GXFEATREG_H__
+#define __GXFEATREG_H__
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+
+FT_BEGIN_HEADER
+
+typedef struct GX_Feature_RegistryRec_ *GX_Feature_Registry;
+
+FT_LOCAL( GX_Feature_Registry ) gx_get_feature_registry( FT_UShort feature_type );
+FT_LOCAL( FT_UShort ) gx_feature_registry_get_value(GX_Feature_Registry featreg);
+FT_LOCAL( const FT_String * ) gx_feature_registry_get_name( GX_Feature_Registry featreg );
+FT_LOCAL( FT_Bool ) gx_feature_registry_is_setting_exclusive( GX_Feature_Registry featreg );
+FT_LOCAL( const FT_String * ) gx_feature_registry_get_setting_name( GX_Feature_Registry featreg, FT_UShort nth );
+FT_LOCAL( FT_UShort ) gx_feature_registry_count_setting ( GX_Feature_Registry featreg );
+
+FT_END_HEADER
+#endif /* Not def: __GXFEATREG_H__ */
+
+/* END */
diff --git a/src/gxlayout/gxlayout.c b/src/gxlayout/gxlayout.c
new file mode 100644
index 000000000..3c619541f
--- /dev/null
+++ b/src/gxlayout/gxlayout.c
@@ -0,0 +1,762 @@
+/***************************************************************************/
+/* */
+/* gxlayout.c */
+/* */
+/* AAT/TrueTypeGX based layout engine(body). */
+/* */
+/* Copyright 2003 by */
+/* Masatake YAMATO and Redhat K.K. */
+/* */
+/* This file may only be used, */
+/* modified, and distributed under the terms of the FreeType project */
+/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
+/* this file you indicate that you have read the license and */
+/* understand and accept it fully. */
+/* */
+/***************************************************************************/
+
+/***************************************************************************/
+/* Development of the code in this file is support of */
+/* Information-technology Promotion Agency, Japan. */
+/***************************************************************************/
+
+#include <ft2build.h>
+
+#include FT_LIST_H
+#include FT_GXLAYOUT_H
+#include FT_INTERNAL_FTL_TYPES_H
+
+#include "gxltypes.h"
+#include "gxtypes.h"
+#include "gxaccess.h"
+#include "gxutils.h"
+#include "gxlookuptbl.h"
+#include "gxfeatreg.h"
+#include "gxlfeatreg.h"
+#include "gxerrors.h"
+
+static int gxl_feature_compare (const void * a, const void * b);
+static FT_Error gxl_feature_initialize_for_mort ( GXL_Feature feature,
+ FT_Memory memory,
+ GX_Mort mort,
+ GX_Feat feat,
+ FT_UShort * index );
+static FT_Error gxl_feature_initialize_for_morx ( GXL_Feature feature,
+ FT_Memory memory,
+ GX_Morx morx,
+ GX_Feat feat,
+ FT_UShort * index );
+/*
+ * FEAT
+ */
+FT_LOCAL_DEF ( GXL_Setting )
+gxl_feature_get_setting_by_value (GXL_Feature feature, FT_UShort value)
+{
+ FT_Int i;
+ if ( feature->exclusive.exclusive )
+ {
+ if ( value == feature->exclusive.setting->value )
+ return feature->exclusive.setting;
+ }
+ else
+ {
+ for ( i = 0; i < feature->nSettings; i++ )
+ {
+ if ( value == feature->setting[i].value )
+ return &feature->setting[i];
+ }
+ }
+ return NULL;
+}
+
+FT_LOCAL_DEF ( GXL_Feature )
+gxl_features_request_get_feature_by_type ( GXL_FeaturesRequest request,
+ FT_UShort featureType )
+{
+ GXL_Feature feature = NULL;
+ int i;
+ for ( i = 0; i < request->nFeatures; i++ )
+ {
+ if ( request->feature[i].value == featureType )
+ {
+ feature = &request->feature[i];
+ break;
+ }
+ }
+ return feature;
+}
+
+FT_LOCAL_DEF ( void )
+gxl_features_request_free( GXL_FeaturesRequest request, FT_Memory memory )
+{
+ FT_Int i;
+ GXL_Feature feature;
+
+ for ( i = request->nFeatures; i > 0; i-- )
+ {
+ feature = &(request->feature[i - 1]);
+ FT_FREE( feature->setting );
+ }
+ FT_FREE ( request->feature );
+ FT_FREE ( request );
+}
+
+static GXL_Setting
+gxl_setting_get_exclusive_setting( GXL_Setting setting )
+{
+ return setting->feature->exclusive.setting;
+}
+
+static void
+gxl_setting_set_exclusive_setting( GXL_Setting setting )
+{
+ setting->feature->exclusive.setting = setting;
+}
+
+static void
+gxl_setting_set_exclusive_state( GXL_Setting setting , FT_Bool state )
+{
+ if ( state )
+ gxl_setting_set_exclusive_setting ( setting );
+}
+
+static FT_Bool
+gxl_setting_get_exclusive_state ( GXL_Setting setting )
+{
+ if ( gxl_setting_get_exclusive_setting (setting) == setting )
+ return 1;
+ else
+ return 0;
+}
+
+FT_EXPORT ( void )
+GXL_FeaturesRequest_Set_Initial_State ( GXL_FeaturesRequest request,
+ GXL_Initial_State initial_state )
+{
+ FT_ASSERT( request );
+ request->initial_state = initial_state;
+}
+
+FT_EXPORT ( GXL_Initial_State )
+GXL_FeaturesRequest_Get_Initial_State ( GXL_FeaturesRequest request )
+{
+ FT_ASSERT( request );
+ return request->initial_state;
+}
+
+FT_EXPORT_DEF ( FT_ULong )
+GXL_FeaturesRequest_Get_Feature_Count ( GXL_FeaturesRequest request )
+{
+ if ( request )
+ return request->nFeatures;
+ else
+ return 0;
+}
+
+FT_EXPORT_DEF ( GXL_Feature )
+GXL_FeaturesRequest_Get_Feature ( GXL_FeaturesRequest request,
+ FT_ULong index)
+{
+ GXL_Feature feature = NULL;
+ if ( index < GXL_FeaturesRequest_Get_Feature_Count ( request ) )
+ feature = &(request->feature[index]);
+ return feature;
+}
+
+FT_EXPORT_DEF( FT_Error )
+GXL_Feature_Get_Name ( GXL_Feature feature,
+ FT_UShort platform_id,
+ FT_UShort encoding_id,
+ FT_UShort language_id,
+ FT_SfntName *aname )
+{
+ GXL_Font font;
+ FT_Face face;
+ font = (GXL_Font)feature->request->root.font;
+ face = font->root.face;
+
+ if ( ! face )
+ return GX_Err_Invalid_Face_Handle;
+
+ if ( ! feature->name.string )
+ return gx_get_name_from_id ( face,
+ feature->name.index,
+ platform_id, encoding_id, language_id,
+ aname );
+ else
+ {
+ aname->platform_id = 0;
+ aname->encoding_id = 0;
+ aname->language_id = 0;
+ aname->name_id = 0;
+ aname->string = (FT_Byte*)feature->name.string;
+ aname->string_len = ft_strlen ( feature->name.string );
+ return GX_Err_Ok;
+ }
+}
+
+FT_EXPORT_DEF( FT_UShort )
+GXL_Feature_Get_Setting_Count ( GXL_Feature feature )
+{
+ return feature->nSettings;
+}
+
+
+FT_EXPORT_DEF( GXL_Setting )
+GXL_Feature_Get_Setting ( GXL_Feature feature,
+ FT_ULong index )
+{
+ GXL_Setting setting = NULL;
+ if ( index < feature->nSettings )
+ setting = &feature->setting[index];
+ return setting;
+}
+
+FT_EXPORT_DEF ( FT_Bool )
+GXL_Feature_Is_Setting_Exclusive ( GXL_Feature feature )
+{
+ return feature->exclusive.exclusive;
+}
+
+
+FT_EXPORT_DEF( FT_Bool )
+GXL_Setting_Get_State ( GXL_Setting setting )
+{
+ GXL_Feature feature = setting->feature;
+ if ( GXL_Feature_Is_Setting_Exclusive ( feature ) )
+ return gxl_setting_get_exclusive_state ( setting );
+ else
+ return gx_feat_setting_state(setting->value);
+}
+
+FT_EXPORT_DEF( FT_Error )
+GXL_Setting_Get_Name ( GXL_Setting setting,
+ FT_UShort platform_id,
+ FT_UShort encoding_id,
+ FT_UShort language_id,
+ FT_SfntName *aname )
+{
+ GXL_Font font = (GXL_Font)setting->feature->request->root.font;
+ FT_Face face = font->root.face;
+
+ if ( ! setting->name.string )
+ return gx_get_name_from_id ( face,
+ setting->name.index,
+ platform_id, encoding_id, language_id,
+ aname );
+ else
+ {
+ aname->platform_id = 0;
+ aname->encoding_id = 0;
+ aname->language_id = 0;
+ aname->name_id = 0;
+ aname->string = (FT_Byte*)setting->name.string;
+ aname->string_len = ft_strlen ( setting->name.string );
+ return GX_Err_Ok;
+ }
+}
+
+FT_EXPORT_DEF( void )
+GXL_Setting_Set_State ( GXL_Setting setting,
+ FT_Bool state )
+{
+ if ( setting->feature->exclusive.exclusive )
+ gxl_setting_set_exclusive_state( setting, state );
+ else if ( state )
+ setting->value = gx_feat_setting_on( setting->value );
+ else
+ setting->value = gx_feat_setting_off( setting->value );
+}
+
+/*
+ * Substitution
+ */
+static int
+gxl_feature_compare (const void * a, const void * b)
+{
+ return (FT_Long)((GXL_Feature)a)->value - (FT_Long)((GXL_Feature)b)->value;
+}
+
+typedef struct gxl_feature_initialize_for_mort_data_rec_
+{
+ FT_Int count;
+ GXL_Feature feature;
+ GX_Feat feat;
+ FT_Memory memory;
+} gxl_feature_initialize_for_mort_data_rec, *gxl_feature_initialize_for_mort_data;
+
+
+static FT_Error
+gxl_feature_initialize_for_mort_cb ( GX_MetamorphosisFeatureTable feat_Subtbl, FT_Pointer user )
+{
+ FT_Error error;
+ GX_Feature_Registry featreg;
+ gxl_feature_initialize_for_mort_data data = user;
+ FT_Int i;
+
+ if ( gx_feat_has_feature_type ( data->feat, feat_Subtbl->featureType ) )
+ { /* In feat table? */
+ return GX_Err_Ok;
+ }
+
+ for ( i = 0; i < data->count; i ++ )
+ { /* Duplication check */
+ if ( data->feature[i].value == feat_Subtbl->featureType )
+ return GX_Err_Ok;
+ }
+
+ if (!( featreg = gx_get_feature_registry ( feat_Subtbl->featureType ) ))
+ { /* Not in feature_registry */
+ return GX_Err_Ok;
+ }
+
+ error = gxl_feature_registry_fill_feature( featreg, data->memory, &(data->feature[data->count]) );
+ if ( error )
+ goto Exit;
+ data->count++;
+ Exit:
+ return error;
+}
+
+static FT_Error
+gxl_feature_initialize_for_mort ( GXL_Feature feature,
+ FT_Memory memory,
+ GX_Mort mort,
+ GX_Feat feat,
+ FT_UShort * index )
+{
+ FT_Error error;
+ FT_Int i;
+ gxl_feature_initialize_for_mort_data_rec data;
+ data.count = 0;
+ data.feature = feature;
+ data.feat = feat;
+ data.memory = memory;
+
+ error = gx_mort_foreach_feature ( mort, gxl_feature_initialize_for_mort_cb, &data );
+ if ( error )
+ {
+ for ( i = data.count; i > 0; i-- )
+ FT_FREE (feature[i - 1].setting);
+ return error;
+ }
+ else
+ {
+ *index = data.count;
+ return GX_Err_Ok ;
+ }
+}
+
+typedef struct gxl_feature_initialize_for_morx_data_rec_
+{
+ FT_Int count;
+ GXL_Feature feature;
+ GX_Feat feat;
+ FT_Memory memory;
+} gxl_feature_initialize_for_morx_data_rec, *gxl_feature_initialize_for_morx_data;
+
+
+static FT_Error
+gxl_feature_initialize_for_morx_cb ( GX_MetamorphosisFeatureTable feat_Subtbl, FT_Pointer user )
+{
+ FT_Error error;
+ GX_Feature_Registry featreg;
+ gxl_feature_initialize_for_morx_data data = user;
+ FT_Int i;
+
+ if ( gx_feat_has_feature_type ( data->feat, feat_Subtbl->featureType ) )
+ return GX_Err_Ok;
+
+ for ( i = 0; i < data->count; i ++ )
+ { /* Duplication check */
+ if ( data->feature[i].value == feat_Subtbl->featureType )
+ return GX_Err_Ok;
+ }
+
+ featreg = gx_get_feature_registry ( feat_Subtbl->featureType );
+ if ( ! featreg )
+ return GX_Err_Ok;
+
+ error = gxl_feature_registry_fill_feature( featreg, data->memory, &(data->feature[data->count]) );
+ if ( error )
+ return error;
+ data->count++;
+ return GX_Err_Ok;
+}
+
+static FT_Error
+gxl_feature_initialize_for_morx ( GXL_Feature feature,
+ FT_Memory memory,
+ GX_Morx morx,
+ GX_Feat feat,
+ FT_UShort * index )
+{
+ FT_Error error;
+ FT_Int i;
+ gxl_feature_initialize_for_morx_data_rec data;
+ data.count = 0;
+ data.feature = feature;
+ data.feat = feat;
+ data.memory = memory;
+ error = gx_morx_foreach_feature ( morx, gxl_feature_initialize_for_morx_cb, &data );
+ if ( error )
+ {
+ for ( i = data.count; i > 0; i-- )
+ FT_FREE (feature[i - 1].setting);
+ return error;
+ }
+ else
+ {
+ *index = data.count;
+ return GX_Err_Ok ;
+ }
+}
+
+
+ FT_LOCAL_DEF ( FT_Error )
+ gxl_get_font ( FT_Face face, FTL_Font * font)
+ {
+ *font = ((GX_Face)face)->extra.data;
+
+ if ( *font )
+ return FT_Err_Ok;
+ else
+ return GX_Err_Invalid_Face_Handle;
+ }
+
+ FT_LOCAL_DEF ( FTL_EngineType )
+ gxl_get_engine_type ( FT_Face face )
+ {
+ return FTL_TRUETYPEGX_ENGINE;
+ }
+
+ FT_LOCAL_DEF ( FT_Error )
+ gxl_new_features_request( FT_Face face, FTL_FeaturesRequest * ftl_request)
+ {
+ FT_Memory memory = face->driver->root.memory;
+ FT_Error error;
+ GXL_Font font;
+ GXL_FeaturesRequest request;
+
+ GX_Feat feat;
+ GX_Mort mort;
+ GX_Morx morx;
+
+ GXL_Feature feature;
+ GXL_Setting setting;
+ FT_UShort default_setting_index;
+ GXL_Setting default_setting;
+ FT_UShort infeat_feat_count, inmort_feat_count = 0, inmorx_feat_count = 0;
+
+ FT_Int i_feat, i_setting, j_feat, i_mort, i_morx;
+
+ if (( error = gxl_get_font ( face, (FTL_Font*)&font ) ))
+ return error;
+
+ if ( FT_NEW ( request ) )
+ goto Exit;
+ if (( error = FTL_FeaturesRequest_Init ( face, (FTL_FeaturesRequest)request ) ))
+ {
+ FT_FREE( request );
+ goto Exit;
+ }
+
+ request->initial_state = GXL_START_OF_TEXT_STATE;
+
+ feat = font->feat;
+ mort = font->mort;
+ morx = font->morx;
+
+ if ( !feat )
+ {
+ error = FT_Err_Ok;
+ (request)->nFeatures = 0;
+ (request)->feature = NULL;
+ *ftl_request = (FTL_FeaturesRequest)request;
+ goto Exit;
+ }
+
+ if ( mort )
+ inmort_feat_count = gx_mort_count_feat_not_in_feat( mort, feat );
+
+ if ( morx )
+ inmorx_feat_count = gx_morx_count_feat_not_in_feat( morx, feat );
+
+ if ( ( mort == NULL ) && ( morx == NULL ) )
+ {
+ error = GX_Err_Missing_Glyph_Substitution_Data;
+ goto Failure_request;
+ }
+
+ infeat_feat_count = feat->featureNameCount;
+ request->nFeatures = infeat_feat_count + inmort_feat_count + inmorx_feat_count;
+
+ if ( FT_NEW_ARRAY ( request->feature, request->nFeatures ) )
+ goto Failure_request;
+ for ( i_feat = 0; i_feat < infeat_feat_count; i_feat++ )
+ {
+ feature = (&request->feature[i_feat]);
+ feature->value = feat->names[i_feat].feature;
+ feature->exclusive.exclusive = ((feat->names[i_feat].featureFlags)
+ & GX_FEAT_MASK_EXCLUSIVE_SETTINGS)
+ ? 1: 0;
+ feature->exclusive.setting = NULL; /* dummy */
+ feature->name.index = feat->names[i_feat].nameIndex;
+ feature->name.string = NULL;
+ feature->request = request;
+ feature->nSettings = feat->names[i_feat].nSettings;
+ if ( FT_NEW_ARRAY ( feature->setting, feature->nSettings ) )
+ goto Failure_loop_feat;
+ for ( i_setting = 0; i_setting < feature->nSettings; i_setting++ )
+ {
+ setting = &feature->setting[i_setting];
+ setting->value = feat->names[i_feat].settingName[i_setting].setting;
+ setting->name.index = feat->names[i_feat].settingName[i_setting].nameIndex;
+ setting->name.string = NULL;
+ setting->feature = feature;
+ }
+ if ( feature->exclusive.exclusive )
+ {
+ default_setting_index = 0;
+ if ( (feat->names[i_feat].featureFlags)&GX_FEAT_MASK_DYNAMIC_DEFAULT )
+ default_setting_index = (feat->names[i_feat].featureFlags)&GX_FEAT_MASK_DEFAULT_SETTING;
+ default_setting = &feature->setting[default_setting_index];
+ if ( default_setting_index >= feature->nSettings )
+ {
+ error = GX_Err_Invalid_File_Format;
+ goto Failure_loop_feat;
+ }
+ GXL_Setting_Set_State ( default_setting, 1 );
+ }
+ else if ( feat->names[i_feat].featureFlags&GX_FEAT_MASK_DYNAMIC_DEFAULT )
+ {
+ FT_Bool state;
+ default_setting_index = feat->names[i_feat].featureFlags&GX_FEAT_MASK_DEFAULT_SETTING;
+
+ if ( default_setting_index < feature->nSettings )
+ {
+ default_setting = &feature->setting[default_setting_index];
+ state = 1;
+ }
+ else if ( default_setting_index == 1 )
+ {
+ /* If default_setting_index is 1 but nSettings is also 1,
+ there is not setting for default_setting_index in the
+ font file. In this case setting[0] should be off. */
+ default_setting = &feature->setting[0];
+ state = 0;
+ }
+ else
+ {
+ error = GX_Err_Invalid_File_Format;
+ goto Failure_loop_feat;
+ }
+ GXL_Setting_Set_State ( default_setting, state );
+ }
+ else
+ { /* TODO: getting from mort's and morx's default? */
+ default_setting_index = 0;
+ default_setting = &feature->setting[default_setting_index];
+ GXL_Setting_Set_State ( default_setting, 1 );
+ }
+ }
+
+ if ( inmort_feat_count )
+ {
+ inmort_feat_count = 0;
+ feature = (&request->feature[i_feat]);
+ if (( error = gxl_feature_initialize_for_mort (feature, memory, mort, feat, &inmort_feat_count) ))
+ goto Failure_loop_feat;
+
+ for ( i_mort = 0; i_mort < inmort_feat_count; i_mort++ )
+ feature[i_mort].request = request;
+
+ i_feat += inmort_feat_count;
+ request->nFeatures = i_feat;
+ feature = (&request->feature[inmort_feat_count]);
+ }
+
+ if ( inmorx_feat_count )
+ {
+ inmorx_feat_count = 0;
+ feature = (&(request)->feature[i_feat]);
+ if (( error = gxl_feature_initialize_for_morx (feature, memory, morx, feat, &inmorx_feat_count) ))
+ goto Failure_loop_feat;
+
+ for ( i_morx = 0; i_morx < inmorx_feat_count; i_morx++ )
+ feature[i_morx].request = request;
+ i_feat += inmorx_feat_count;
+ request->nFeatures = i_feat;
+ }
+
+ if ( inmort_feat_count || inmorx_feat_count )
+ {
+ ft_qsort(request->feature,
+ request->nFeatures,
+ sizeof (*(request->feature)),
+ gxl_feature_compare );
+ for ( i_feat = 0; i_feat < request->nFeatures; i_feat++ )
+ {
+ feature = &request->feature[i_feat];
+ for ( i_setting = 0; i_setting < feature->nSettings; i_setting++ )
+ feature->setting[i_setting].feature = feature;
+ }
+ }
+ *ftl_request = (FTL_FeaturesRequest)request;
+ Exit:
+ return error;
+ Failure_loop_feat:
+ for ( j_feat = i_feat; j_feat > 0; j_feat-- )
+ FT_FREE( request->feature[j_feat - 1].setting );
+ Failure_request:
+ FT_FREE(request);
+ return error;
+ }
+
+ FT_LOCAL_DEF ( FT_Error )
+ gxl_done_features_request( FTL_FeaturesRequest request)
+ {
+ FTL_Font font;
+ FT_Face face;
+
+ FT_Memory memory;
+
+ FT_ASSERT( request );
+ font = request->font;
+ FT_ASSERT( font );
+ face = font->face;
+ if ( !face )
+ return GX_Err_Invalid_Argument;
+ memory = face->driver->root.memory;
+ gxl_features_request_free( (GXL_FeaturesRequest)request, memory );
+ return FTL_FeaturesRequest_Finalize ( request );
+ }
+
+ FT_LOCAL_DEF ( FT_Error )
+ gxl_copy_features_request( FTL_FeaturesRequest from,
+ FTL_FeaturesRequest to)
+ {
+ FT_Error error;
+ FT_Int i_feat, i_setting;
+ GXL_Feature from_feature, to_feature;
+ GXL_Setting from_setting, to_setting;
+
+ if (( error = FTL_FeaturesRequest_Copy( from, to ) ))
+ return error;
+
+ for ( i_feat = 0; i_feat < ((GXL_FeaturesRequest)from)->nFeatures; i_feat++ )
+ {
+ from_feature = GXL_FeaturesRequest_Get_Feature((GXL_FeaturesRequest)from,
+ i_feat);
+ to_feature = GXL_FeaturesRequest_Get_Feature((GXL_FeaturesRequest)to,
+ i_feat);
+
+ for ( i_setting = 0;
+ i_setting < GXL_Feature_Get_Setting_Count(from_feature);
+ i_setting++ )
+ {
+ from_setting = GXL_Feature_Get_Setting ( from_feature, i_setting );
+ to_setting = GXL_Feature_Get_Setting ( to_feature, i_setting );
+ GXL_Setting_Set_State(to_setting,
+ GXL_Setting_Get_State(from_setting));
+ }
+ }
+ return GX_Err_Ok;
+ }
+
+ FT_LOCAL_DEF ( FT_UShort )
+ gxl_get_ligature_caret_count ( FT_Face face,
+ FT_UShort glyphID )
+ {
+ FTL_Font font;
+ GX_Lcar lcar;
+ GX_LigCaretClassEntry class_entry;
+
+ if ( FTL_Get_Font( face, &font ) )
+ return 0;
+ lcar = ((GXL_Font)font)->lcar;
+ if ( !lcar )
+ return 0;
+ class_entry = gx_lcar_get( lcar, glyphID );
+ if ( class_entry )
+ return class_entry->count;
+ else
+ return 0;
+ }
+
+/* TODO: return an error */
+ FT_LOCAL_DEF ( FT_UShort )
+ gxl_get_ligature_caret_division( FT_Face face,
+ FT_UShort glyph_id,
+ FT_UShort nth )
+ {
+ FTL_Font font;
+ GX_Lcar lcar;
+ GX_LigCaretClassEntry class_entry;
+ FT_UShort partials;
+ FTL_Direction direction;
+ FT_Outline *outline;
+ FT_Vector point;
+ if ( FTL_Get_Font( face, &font ) )
+ return 0;
+
+ lcar = ((GXL_Font)font)->lcar;
+ if ( !lcar )
+ return 0;
+
+ class_entry = gx_lcar_get( lcar, glyph_id );
+ if ( !class_entry )
+ return 0;
+ if ( nth >= class_entry->count )
+ return 0;
+
+ partials = class_entry->partials[nth];
+ if ( lcar->format == GX_LCAR_DISTANCE )
+ return partials;
+
+ /* font -> feature_requst -> direction */
+ direction = FTL_Get_FeaturesRequest_Direction ( font->features_request );
+
+ /* glyph_id -> glyph -> outline -> point -> x or y */
+ if ( FT_Load_Glyph ( face, glyph_id,
+ FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP ) )
+ return 0;
+
+ outline = &face->glyph->outline;
+ if ( ! ( partials < outline->n_points ) )
+ return 0;
+ point = outline->points[partials];
+
+ /* TODO: Are the unit for the outline and that
+ for ligature caret same? */
+ if ( direction == FTL_HORIZONTAL )
+ return (FT_UShort)point.x;
+ else
+ return (FT_UShort)point.y;
+ }
+
+ FT_LOCAL_DEF ( FT_Error )
+ gxl_substitute_glyphs ( FT_Face face,
+ FTL_FeaturesRequest request,
+ FTL_Glyphs_Array in,
+ FTL_Glyphs_Array out )
+ {
+ FT_Error error;
+ GXL_Font font;
+ GX_Mort mort;
+ GX_Morx morx;
+
+ if (( error = FTL_Get_Font ( face, (FTL_Font*)&font )))
+ return error;
+
+ mort = font->mort;
+ morx = font->morx;
+ if ( mort )
+ return gx_mort_substitute_glyph(mort, (GXL_FeaturesRequest)request, in, out );
+ else if ( morx )
+ return gx_morx_substitute_glyph(morx, (GXL_FeaturesRequest)request, in, out );
+ else
+ return FT_Err_Invalid_Argument;
+ }
+
+/* END */
diff --git a/src/gxlayout/gxlfeatreg.c b/src/gxlayout/gxlfeatreg.c
new file mode 100644
index 000000000..61912c966
--- /dev/null
+++ b/src/gxlayout/gxlfeatreg.c
@@ -0,0 +1,87 @@
+/***************************************************************************/
+/* */
+/* gxlfeatreg.c */
+/* */
+/* High level interface for the font feature registry(body) */
+/* */
+/* Copyright 2003 by */
+/* Masatake YAMATO and Redhat K.K. */
+/* */
+/* This file may only be used, */
+/* modified, and distributed under the terms of the FreeType project */
+/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
+/* this file you indicate that you have read the license and */
+/* understand and accept it fully. */
+/* */
+/***************************************************************************/
+
+/***************************************************************************/
+/* Development of the code in this file is support of */
+/* Information-technology Promotion Agency, Japan. */
+/***************************************************************************/
+
+#include "gxlfeatreg.h"
+#include "gxltypes.h"
+#include "gxaccess.h"
+
+#undef FT_COMPONENT
+#define FT_COMPONENT trace_gxlayout
+
+FT_LOCAL_DEF( FT_Error )
+gxl_feature_registry_fill_feature(GX_Feature_Registry featreg,
+ FT_Memory memory,
+ GXL_Feature feature)
+{
+ FT_Error error = GX_Err_Ok;
+ FT_Int i;
+
+ feature->value = gx_feature_registry_get_value( featreg );
+ feature->request = NULL; /* for debug */
+ feature->name.string = gx_feature_registry_get_name( featreg );
+ if ( !feature->name.string )
+ {
+ FT_ERROR(("Broken feature is used to lookup feature registry\n"));
+ error = GX_Err_Invalid_Argument;
+ goto Exit;
+ }
+ FT_TRACE3(("Name from feature registry: %s\n", feature->name.string));
+ feature->name.index = 0; /* for debug */
+ feature->nSettings = gx_feature_registry_count_setting ( featreg );
+ if ( FT_NEW_ARRAY( feature->setting, feature->nSettings ) )
+ goto Exit;
+
+ feature->exclusive.exclusive = gx_feature_registry_is_setting_exclusive ( featreg );
+
+ for ( i = 0; i < feature->nSettings; i++ )
+ {
+ if ( feature->exclusive.exclusive )
+ feature->setting[i].value = i;
+ else
+ {
+ feature->setting[i].value = 2*i;
+ if ( i != 0)
+ feature->setting[i].value = gx_feat_setting_off ( feature->setting[i].value );
+ }
+ feature->setting[i].name.string = gx_feature_registry_get_setting_name( featreg, i );
+ if ( ! feature->setting[i].name.string )
+ {
+ FT_ERROR(("Broken setting is used to lookup feature registry: feature=%s\n",
+ feature->name.string));
+ error = GX_Err_Invalid_Argument;
+ goto Failure;
+ }
+ feature->setting[i].name.index = 0; /* for debug */
+ feature->setting[i].feature = feature;
+ }
+ if ( feature->exclusive.exclusive )
+ feature->exclusive.setting = &feature->setting[0];
+ else
+ feature->exclusive.setting = NULL;
+ Exit:
+ return error;
+ Failure:
+ FT_FREE( feature->setting );
+ return error;
+}
+
+/* END */
diff --git a/src/gxlayout/gxlfeatreg.h b/src/gxlayout/gxlfeatreg.h
new file mode 100644
index 000000000..6f7c1306b
--- /dev/null
+++ b/src/gxlayout/gxlfeatreg.h
@@ -0,0 +1,42 @@
+/***************************************************************************/
+/* */
+/* gxlfeatreg.h */
+/* */
+/* High level interface for the font feature registry(specification) */
+/* */
+/* Copyright 2003 by */
+/* Masatake YAMATO and Redhat K.K. */
+/* */
+/* This file may only be used, */
+/* modified, and distributed under the terms of the FreeType project */
+/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
+/* this file you indicate that you have read the license and */
+/* understand and accept it fully. */
+/* */
+/***************************************************************************/
+
+/***************************************************************************/
+/* Development of the code in this file is support of */
+/* Information-technology Promotion Agency, Japan. */
+/***************************************************************************/
+
+#ifndef __GXLFEATREG_H__
+#define __GXLFEATREG_H__
+
+#include <ft2build.h>
+#include FT_TYPES_H
+#include "gxltypes.h"
+#include "gxfeatreg.h"
+
+
+FT_BEGIN_HEADER
+
+FT_LOCAL( FT_Error ) gxl_feature_registry_fill_feature(GX_Feature_Registry featreg,
+ FT_Memory memory,
+ GXL_Feature feature);
+
+FT_END_HEADER
+
+#endif /* Not def: __GXLFEATREG_H__ */
+
+/* END */
diff --git a/src/gxlayout/gxload.c b/src/gxlayout/gxload.c
new file mode 100644
index 000000000..85ffc685a
--- /dev/null
+++ b/src/gxlayout/gxload.c
@@ -0,0 +1,4327 @@
+/***************************************************************************/
+/* */
+/* gxload.c */
+/* */
+/* Functions load AAT/TrueTypeGX tables(body) */
+/* */
+/* Copyright 2003 by */
+/* Masatake YAMATO and Redhat K.K. */
+/* */
+/* This file may only be used, */
+/* modified, and distributed under the terms of the FreeType project */
+/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
+/* this file you indicate that you have read the license and */
+/* understand and accept it fully. */
+/* */
+/***************************************************************************/
+
+/***************************************************************************/
+/* Development of the code in this file is support of */
+/* Information-technology Promotion Agency, Japan. */
+/***************************************************************************/
+
+/* TODO: cleanup: use variable to get the size of type instead of type */
+
+#include <ft2build.h>
+
+#include FT_INTERNAL_DEBUG_H
+#include FT_INTERNAL_STREAM_H
+#include FT_INTERNAL_MEMORY_H
+#include FT_TRUETYPE_TAGS_H
+
+#include "gxtypes.h"
+#include "gxload.h"
+#include "gxlookuptbl.h"
+#include "gxstatetbl.h"
+#include "gxutils.h"
+#include "gxerrors.h"
+#include "gxaccess.h"
+
+#undef FT_COMPONENT
+#define FT_COMPONENT trace_gxload
+
+ static void
+ gx_feat_done( GX_Feat feat,
+ FT_Memory memory );
+ static void
+ gx_trak_done( GX_Trak trak,
+ FT_Memory memory );
+
+ static void
+ gx_kern_done( GX_Kern kern,
+ FT_Memory memory );
+
+ static void
+ gx_prop_done( GX_Prop prop,
+ FT_Memory memory );
+
+ static void
+ gx_opbd_done( GX_Opbd opbd,
+ FT_Memory memory );
+
+ static void
+ gx_lcar_done( GX_Lcar lcar,
+ FT_Memory memory );
+
+ static void
+ gx_bsln_done( GX_Bsln bsln,
+ FT_Memory memory );
+
+ static void
+ gx_mort_done( GX_Mort mort,
+ FT_Memory memory );
+
+ static void
+ gx_morx_done( GX_Morx morx,
+ FT_Memory memory );
+
+ static void
+ gx_fmtx_done( GX_Fmtx fmtx,
+ FT_Memory memory );
+
+ static void
+ gx_fdsc_done( GX_Fdsc fdsc,
+ FT_Memory memory );
+
+ static void
+ gx_just_done( GX_Just just,
+ FT_Memory memory );
+
+ static void
+ gx_fvar_done( GX_Fvar fvar,
+ FT_Memory memory );
+
+#define GENERIC_LOOKUP_TABLE_CB_DATA_ZERO {NULL, NULL, NULL, 0, NULL}
+typedef struct generic_lookup_table_cb_data_rec_
+{
+ GX_Face face;
+ FT_Stream stream;
+ GX_LookupTable lookup_table;
+ /* From the spec file:
+ If TABLE_TAG == 0, "The value of each lookupSegment is a 16-bit
+ offset from the start of the lookup table to an array of 16-bit
+ property values, one for each glyph in the segment. "
+ If not "the value of each lookupSingle is a 16-bit offset from
+ the start of the table " specified by TABLE_TAG. */
+ FT_Int table_tag;
+ FT_Pointer extra;
+} generic_lookup_table_cb_data_rec, *generic_lookup_table_cb_data;
+
+static FT_Error
+generic_lookup_table_segment_array_loader ( GX_LookupTable_Format format,
+ FT_UShort lastGlyph,
+ FT_UShort firstGlyph,
+ GX_LookupValue value,
+ FT_Pointer user );
+static FT_Error
+generic_lookup_table_segment_array_finalizer ( GX_LookupTable_Format format,
+ FT_UShort lastGlyph,
+ FT_UShort firstGlyph,
+ GX_LookupValue value,
+ FT_Pointer user );
+
+#define GENERIC_STATE_TABLE_CB_DATA_ZERO {0, 0, NULL, NULL, NULL}
+#define GENERIC_XSTATE_TABLE_CB_DATA_ZERO {0, 0, NULL, NULL, NULL}
+typedef struct generic_state_table_cb_data_rec_
+{
+ FT_ULong base;
+ FT_ULong table_offset;
+ FT_Stream stream;
+ GX_Face face;
+ FT_Pointer extra;
+} generic_state_table_cb_data_rec,
+ generic_xstate_table_cb_data_rec,
+ *generic_state_table_cb_data,
+ *generic_xstate_table_cb_data;
+
+static FT_Error
+generic_load_noncontextual_subtable ( GX_Face face,
+ FT_Stream stream,
+ FT_UShort length,
+ GX_MetamorphosisSubtableBody body,
+ FT_Int tag );
+
+static void
+generic_triple_offset_diff ( FT_ULong ligActionTable_offset,
+ FT_ULong componentTable_offset,
+ FT_ULong ligatureTable_offset,
+ FT_ULong length,
+ FT_UShort *ligActionTable_nAction,
+ FT_UShort *componentTable_nComponent,
+ FT_UShort *ligatureTable_nLigature );
+
+static FT_Error
+gx_table_init(GX_Table table_info,
+ GX_Face face,
+ FT_ULong tag,
+ FT_Stream stream,
+ GX_Table_Done_Func done_table);
+
+
+/******************************TRAK************************************/
+ static FT_Error
+ gx_face_load_trak_data( GX_Face face,
+ FT_Stream stream,
+ FT_UShort offset,
+ GX_TrackData data );
+ static FT_Error
+ gx_face_load_trak_values ( GX_Face face, FT_Stream stream,
+ FT_UShort nTracks, FT_UShort nSizes,
+ GX_TrackTableEntry trackTable );
+ static FT_Error
+ gx_face_load_trak_table_entry ( GX_Face face,
+ FT_Stream stream,
+ FT_UShort nTracks,
+ GX_TrackTableEntry * table_entry );
+ static FT_Error
+ gx_face_load_trak_size_table ( GX_Face face,
+ FT_Stream stream,
+ FT_UShort nSizes,
+ FT_ULong sizeTableOffset,
+ FT_Long **sizeTable );
+
+ static void
+ gx_trak_done_values ( FT_Memory memory,
+ FT_UShort nTracks,
+ GX_TrackTableEntry trackTable );
+
+ static void
+ gx_trak_done_data(FT_Memory memory, GX_TrackData data);
+
+ static FT_Error
+ gx_face_load_trak_values ( GX_Face face, FT_Stream stream,
+ FT_UShort nTracks, FT_UShort nSizes,
+ GX_TrackTableEntry trackTable )
+ {
+ FT_Int i, j;
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+ FT_FWord * base_value;
+ FT_ULong table_offset;
+
+ if ( FT_NEW_ARRAY ( base_value, nTracks * nSizes ) )
+ return error;
+
+ /* assert -> nTracks != 0, nSizes != 0 */
+
+ if ( ( error = face->goto_table( face, TTAG_trak, stream, 0 ) ) )
+ return error;
+ table_offset = FT_STREAM_POS();
+
+ for ( i = 0; i < nTracks; i++ )
+ {
+ trackTable[i].tracking_value = base_value + (i * nSizes);
+ if ( FT_STREAM_SEEK( table_offset + trackTable[i].offset ) ||
+ FT_FRAME_ENTER ( sizeof(FT_UShort) * nSizes ) )
+ goto Failure;
+
+ for ( j = 0; j < nSizes; j++ )
+ trackTable[i].tracking_value[j] = FT_GET_SHORT();
+
+ FT_FRAME_EXIT();
+ }
+ return GX_Err_Ok;
+ Failure:
+ gx_trak_done_values ( memory, nTracks, trackTable );
+ return error;
+ }
+
+ static void
+ gx_trak_done_values ( FT_Memory memory,
+ FT_UShort nTracks,
+ GX_TrackTableEntry trackTable )
+ {
+ FT_Int i;
+ FT_FREE (trackTable[0].tracking_value);
+ for ( i = 0; i < nTracks; i++ )
+ trackTable[i].tracking_value = NULL;
+ }
+
+ static FT_Error
+ gx_face_load_trak_table_entry ( GX_Face face,
+ FT_Stream stream,
+ FT_UShort nTracks,
+ GX_TrackTableEntry * table_entry )
+ {
+ FT_Int i;
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ const FT_Frame_Field track_table_entry_fields [] =
+ {
+#undef FT_STRUCTURE
+#define FT_STRUCTURE GX_TrackTableEntryRec
+ FT_FRAME_START ( 8 ),
+ FT_FRAME_LONG (track),
+ FT_FRAME_USHORT (nameIndex),
+ FT_FRAME_USHORT (offset),
+ FT_FRAME_END
+ };
+
+ if ( FT_NEW_ARRAY( *table_entry, nTracks ) )
+ return error;
+
+ for ( i = 0; i < nTracks ; i++ )
+ {
+ (*table_entry)[i].tracking_value = NULL;
+ if ( FT_STREAM_READ_FIELDS( track_table_entry_fields,
+ &(*table_entry)[i] ) )
+ goto Failure;
+ }
+ return GX_Err_Ok;
+ Failure:
+ FT_FREE(*table_entry);
+ *table_entry = NULL;
+ return error;
+ }
+
+ static FT_Error
+ gx_face_load_trak_size_table ( GX_Face face,
+ FT_Stream stream,
+ FT_UShort nSizes,
+ FT_ULong sizeTableOffset,
+ FT_Long **sizeTable )
+ {
+ FT_Int i;
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ if ( (error = face->goto_table( face, TTAG_trak, stream, 0 )) ||
+ FT_STREAM_SKIP( sizeTableOffset ) )
+ goto Exit;
+
+ *sizeTable = NULL;
+
+ if ( FT_NEW_ARRAY( *sizeTable, nSizes ) )
+ goto Exit;
+
+ if ( FT_FRAME_ENTER ( sizeof( **sizeTable ) * nSizes ) )
+ goto Failure;
+ for ( i = 0; i < nSizes; i++)
+ (*sizeTable)[i] = FT_GET_ULONG();
+ FT_FRAME_EXIT();
+
+ Exit:
+ return error;
+ Failure:
+ FT_FREE(*sizeTable);
+ return error;
+ }
+
+ static FT_Error
+ gx_face_load_trak_data( GX_Face face,
+ FT_Stream stream,
+ FT_UShort offset,
+ GX_TrackData data )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ const FT_Frame_Field track_data_fields [] =
+ {
+#undef FT_STRUCTURE
+#define FT_STRUCTURE GX_TrackDataRec
+ FT_FRAME_START( 8 ),
+ FT_FRAME_USHORT ( nTracks ),
+ FT_FRAME_USHORT ( nSizes ),
+ FT_FRAME_ULONG ( sizeTableOffset ),
+ FT_FRAME_END
+ };
+
+ if ( ( error = face->goto_table( face, TTAG_trak, stream, 0 ) ) ||
+ FT_STREAM_SKIP( offset ) ||
+ FT_STREAM_READ_FIELDS( track_data_fields, data ) )
+ goto Exit;
+
+ if ( data->nTracks < 3 )
+ {
+ FT_TRACE2(( " Too few nTracks in kern\n" ));
+ error = GX_Err_Invalid_File_Format;
+ goto Exit;
+ }
+ if ( data->nSizes < 2 )
+ {
+ FT_TRACE2(( " Too few nSizes in kern\n" ));
+ error = GX_Err_Invalid_File_Format;
+ goto Exit;
+ }
+
+ if ( ( error = gx_face_load_trak_table_entry ( face, stream,
+ data->nTracks,
+ &data->trackTable ) ))
+ goto Exit;
+
+ if ( ( error = gx_face_load_trak_values ( face, stream,
+ data->nTracks, data->nSizes,
+ data->trackTable ) ) )
+ goto Failure;
+
+
+ if ( ( error = gx_face_load_trak_size_table ( face, stream,
+ data->nSizes,
+ data->sizeTableOffset,
+ &data->sizeTable ) ) )
+
+ {
+ gx_trak_done_values( memory, data->nTracks, data->trackTable);
+ goto Failure;
+ }
+
+ Exit:
+ return error;
+ Failure:
+ FT_FREE(data->trackTable);
+ data->trackTable = NULL;
+ return error;
+ }
+
+ static void
+ gx_trak_done_data(FT_Memory memory, GX_TrackData data)
+ {
+ gx_trak_done_values(memory, data->nTracks, data->trackTable);
+ FT_FREE(data->sizeTable);
+ data->sizeTable = NULL;
+ FT_FREE(data->trackTable);
+ data->trackTable = NULL;
+ }
+
+
+ FT_LOCAL_DEF ( FT_Error )
+ gx_face_load_trak( GX_Face face,
+ FT_Stream stream,
+ GX_Trak trak )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ const FT_Frame_Field trak_fields[] =
+ {
+#undef FT_STRUCTURE
+#define FT_STRUCTURE GX_TrakRec
+ FT_FRAME_START( 12 ),
+ FT_FRAME_ULONG ( version ),
+ FT_FRAME_USHORT ( format ),
+ FT_FRAME_USHORT ( horizOffset ),
+ FT_FRAME_USHORT ( vertOffset ),
+ FT_FRAME_USHORT ( reserved ),
+ FT_FRAME_END
+ };
+
+ if (( error = gx_table_init( &(trak->root), face, TTAG_trak, stream,
+ (GX_Table_Done_Func)gx_trak_done) ))
+ goto Exit;
+
+ if ( FT_STREAM_READ_FIELDS( trak_fields, trak ) )
+ goto Exit;
+
+ if ( trak->horizOffset &&
+ ( error = gx_face_load_trak_data (face, stream,
+ trak->horizOffset,
+ &trak->horizData) ))
+ goto Exit;
+
+
+ if ( trak->vertOffset &&
+ ( error = gx_face_load_trak_data (face, stream,
+ trak->vertOffset,
+ &trak->vertData) ))
+ goto Failure;
+ /* FT_TRACE2(( "loaded\n" )); */
+ Exit:
+ return error;
+ Failure:
+ gx_trak_done_data(memory, &trak->horizData);
+ return error;
+ }
+
+
+ FT_LOCAL_DEF ( void )
+ gx_trak_done( GX_Trak trak,
+ FT_Memory memory )
+ {
+ if ( trak->horizOffset )
+ gx_trak_done_data(memory, &trak->horizData);
+ if ( trak->vertOffset )
+ gx_trak_done_data(memory, &trak->vertData);
+ }
+
+
+/******************************FEAT************************************/
+ FT_Error
+ gx_face_load_feat_settingName ( GX_Face face,
+ FT_Stream stream,
+ FT_ULong settingTable,
+ FT_UShort nSettings,
+ GX_FeatureSettingName settingName )
+ {
+ FT_Error error;
+ FT_Int i;
+
+ const FT_Frame_Field feature_settingName_fields [] =
+ {
+#undef FT_STRUCTURE
+#define FT_STRUCTURE GX_FeatureSettingNameRec
+ FT_FRAME_START ( 4 ),
+ FT_FRAME_USHORT (setting),
+ FT_FRAME_SHORT (nameIndex),
+ FT_FRAME_END
+ };
+
+ error = face->goto_table( face, TTAG_feat, stream, 0 );
+ if ( error ||
+ FT_STREAM_SKIP( settingTable ) )
+ goto Exit;
+
+ for ( i = 0; i < nSettings; i++ )
+ if ( FT_STREAM_READ_FIELDS( feature_settingName_fields,
+ &(settingName[i]) ))
+ goto Exit;
+ Exit:
+ return error;
+ }
+
+ FT_Error
+ gx_face_load_feat_names( GX_Face face,
+ FT_Stream stream,
+ FT_UShort featureNameCount,
+ GX_FeatureName names)
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+ FT_Int total_nSettings, offset;
+ GX_FeatureSettingName settingName;
+ FT_Int i;
+
+ const FT_Frame_Field feature_name_fields [] =
+ {
+#undef FT_STRUCTURE
+#define FT_STRUCTURE GX_FeatureNameRec
+ FT_FRAME_START ( 12 ),
+ FT_FRAME_USHORT ( feature ),
+ FT_FRAME_USHORT ( nSettings ),
+ FT_FRAME_ULONG ( settingTable ),
+ FT_FRAME_USHORT ( featureFlags ),
+ FT_FRAME_SHORT ( nameIndex ),
+ FT_FRAME_END
+ };
+
+ for ( i = 0, total_nSettings = 0; i < featureNameCount; i++ )
+ {
+ if ( FT_STREAM_READ_FIELDS( feature_name_fields, &(names[i]) ) )
+ return error;
+ total_nSettings += names[i].nSettings;
+ }
+
+
+ if ( FT_NEW_ARRAY ( settingName, total_nSettings ) )
+ return error;
+
+ for ( i = 0, offset = 0; i < featureNameCount; i++ )
+ {
+ names[i].settingName = settingName + offset;
+ offset += names[i].nSettings;
+ }
+
+ for ( i = 0; i < featureNameCount; i++ )
+ {
+ error = gx_face_load_feat_settingName(face,
+ stream,
+ names[i].settingTable,
+ names[i].nSettings,
+ names[i].settingName);
+ if ( error )
+ {
+ FT_FREE( settingName );
+ for ( i = 0; i < featureNameCount; i++ )
+ names[i].settingName = NULL;
+ return error;
+ }
+ }
+ return error;
+ }
+
+ static void
+ gx_feat_done_names( FT_Memory memory,
+ FT_UShort featureNameCount,
+ GX_FeatureName names)
+ {
+ GX_FeatureSettingName settingName;
+ FT_Int i;
+
+ settingName = names[0].settingName;
+ for ( i = 0; i < featureNameCount; i++ )
+ names[i].settingName = NULL;
+ FT_FREE(settingName);
+ }
+
+ FT_LOCAL_DEF ( FT_Error )
+ gx_face_load_feat( GX_Face face,
+ FT_Stream stream,
+ GX_Feat feat )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ const FT_Frame_Field feat_fields[] =
+ {
+#undef FT_STRUCTURE
+#define FT_STRUCTURE GX_FeatRec
+ FT_FRAME_START ( 12 ),
+ FT_FRAME_LONG ( version ),
+ FT_FRAME_USHORT ( featureNameCount ),
+ FT_FRAME_USHORT ( reserved1 ),
+ FT_FRAME_ULONG ( reserved2 ),
+ FT_FRAME_END
+ };
+
+ /* FT_TRACE2(( "Feature " )); */
+ if (( error = gx_table_init( &(feat->root), face, TTAG_feat, stream,
+ (GX_Table_Done_Func) gx_feat_done) ))
+ goto Exit;
+
+ if ( FT_STREAM_READ_FIELDS( feat_fields, feat ) )
+ goto Exit; /* err? */
+
+ /* FT_TRACE3(( "\n version: 0x%8x" "(0x00010000 is expected)\n", */
+ /* feat->version )); */
+
+ if ( feat->featureNameCount == 0 )
+ {
+ feat->names = NULL;
+ goto Exit;
+ }
+
+ if ( FT_NEW_ARRAY( feat->names, feat->featureNameCount ) )
+ goto Exit;
+
+ error = gx_face_load_feat_names ( face, stream,
+ feat->featureNameCount,
+ feat->names );
+ if ( error )
+ {
+ FT_FREE( feat->names );
+ feat->names = NULL;
+ goto Exit;
+ }
+
+ Exit:
+ return error;
+ }
+
+ FT_LOCAL_DEF ( void )
+ gx_feat_done( GX_Feat feat,
+ FT_Memory memory )
+
+ {
+ GX_FeatureName names;
+
+ names = feat->names;
+ if ( feat->names )
+ {
+ gx_feat_done_names (memory, feat->featureNameCount, feat->names);
+ feat->names = NULL;
+ FT_FREE(names);
+ }
+ }
+
+/******************************PROP************************************/
+ FT_LOCAL_DEF ( FT_Error )
+ gx_face_load_prop( GX_Face face,
+ FT_Stream stream,
+ GX_Prop prop )
+ {
+ FT_Error error;
+ GX_LookupTable lookup_table = &prop->lookup_data;
+
+ const FT_Frame_Field prop_fields[] =
+ {
+#undef FT_STRUCTURE
+#define FT_STRUCTURE GX_PropRec
+ FT_FRAME_START ( 8 ),
+ FT_FRAME_ULONG ( version ), /* LONG? */
+ FT_FRAME_USHORT ( format ),
+ FT_FRAME_USHORT ( default_properties ),
+ FT_FRAME_END
+ };
+
+ GX_LookupTable_FuncsRec funcs = GX_LOOKUP_TABLE_FUNC_ZERO;
+ generic_lookup_table_cb_data_rec user_data = GENERIC_LOOKUP_TABLE_CB_DATA_ZERO;
+
+ funcs.segment_array_func = generic_lookup_table_segment_array_loader;
+ user_data.face = face;
+ user_data.stream = stream;
+ user_data.lookup_table = lookup_table;
+ user_data.table_tag = 0;
+ /* FT_TRACE2(( "Glyph Properties " )); */
+
+ if (( error = gx_table_init( &(prop->root), face, TTAG_prop, stream,
+ (GX_Table_Done_Func)gx_prop_done) ))
+ goto Exit;
+
+ if ( FT_STREAM_READ_FIELDS( prop_fields, prop ) )
+ goto Exit; /* err? */
+ /* FT_TRACE3(( "\n version: 0x%8x\n", prop->version )); */
+
+ if ( prop->format == 0)
+ {
+ /* NO LOOKUP DATA */
+ lookup_table->format = 0;
+ lookup_table->fsHeader.any = 0;
+ goto Exit;
+ }
+
+ if (( error = gx_face_load_LookupTable ( face, stream, lookup_table )))
+ goto Exit;
+ if ( lookup_table->format == GX_LOOKUPTABLE_SEGMENT_ARRAY )
+ {
+ if (( error = gx_LookupTable_traverse_low( lookup_table,
+ &funcs,
+ &user_data ) ))
+ goto Failure;
+ }
+ Exit:
+ return error;
+ Failure:
+ gx_LookupTable_free( lookup_table, face->root.driver->root.memory );
+ return error;
+ }
+
+ FT_LOCAL_DEF( void )
+ gx_prop_done( GX_Prop prop,
+ FT_Memory memory )
+
+ {
+ GX_LookupTable lookup_table = &prop->lookup_data;
+ GX_LookupTable_FuncsRec funcs = GX_LOOKUP_TABLE_FUNC_ZERO;
+
+ funcs.segment_array_func = generic_lookup_table_segment_array_finalizer;
+
+ if ( prop->format != 0)
+ {
+ if ( lookup_table->format == GX_LOOKUPTABLE_SEGMENT_ARRAY )
+ gx_LookupTable_traverse_low( lookup_table,
+ &funcs,
+ memory );
+ gx_LookupTable_free ( lookup_table, memory );
+ }
+ }
+
+
+/******************************OPBD************************************/
+ static FT_Error
+ gx_opbd_load_data ( GX_Face face,
+ FT_Stream stream,
+ FT_ULong offset,
+ FT_UShort format,
+ GX_OpticalBoundsData data )
+ {
+ FT_Error error;
+ const FT_Frame_Field opbd_distance_fields[] =
+ {
+#undef FT_STRUCTURE
+#define FT_STRUCTURE GX_OpticalBoundsDataRec
+ FT_FRAME_START ( 8 ),
+ FT_FRAME_SHORT (distance.left_side),
+ FT_FRAME_SHORT (distance.top_side),
+ FT_FRAME_SHORT (distance.right_side),
+ FT_FRAME_SHORT (distance.bottom_side),
+ FT_FRAME_END
+ };
+ const FT_Frame_Field opbd_control_points_fields[] =
+ {
+#undef FT_STRUCTURE
+#define FT_STRUCTURE GX_OpticalBoundsDataRec
+ FT_FRAME_START ( 8 ),
+ FT_FRAME_USHORT (control_points.left_side),
+ FT_FRAME_USHORT (control_points.top_side),
+ FT_FRAME_USHORT (control_points.right_side),
+ FT_FRAME_USHORT (control_points.bottom_side),
+ FT_FRAME_END
+ };
+
+ if ( FT_STREAM_SEEK(offset) )
+ return error;
+
+ if ( format == GX_OPBD_DISTANCE )
+ {
+ if ( FT_STREAM_READ_FIELDS( opbd_distance_fields, data ) )
+ return error;
+ }
+ else
+ {
+ if ( FT_STREAM_READ_FIELDS( opbd_control_points_fields, data ) )
+ return error;
+ }
+ return error;
+ }
+
+ static FT_Error
+ opbd_lookup_table_generic_loader( GX_LookupTable_Format format,
+ GX_LookupValue value,
+ FT_Pointer user )
+ {
+ FT_Error error;
+ GX_Face face = ((generic_lookup_table_cb_data)user)->face;
+ FT_Pointer extra = ((generic_lookup_table_cb_data)user)->extra;
+ FT_UShort data_format = *(FT_UShort*)extra;
+ FT_Stream stream = ((generic_lookup_table_cb_data)user)->stream;
+ FT_Memory memory = stream->memory;
+ FT_Short offset = value->raw.s;
+ GX_OpticalBoundsData opbd_data;
+
+ if ( ( error = face->goto_table(face, TTAG_opbd, stream, 0 ) ) )
+ return error;
+
+ if ( FT_MEM_NEW(opbd_data) )
+ return error;
+
+ if ( ( error = gx_opbd_load_data( face,
+ stream,
+ FT_STREAM_POS() + offset,
+ data_format,
+ opbd_data ) ) )
+ goto Failure;
+ value->extra.opbd_data = opbd_data;
+ return error;
+ Failure:
+ FT_FREE(opbd_data);
+ return error;
+ }
+
+ static FT_Error
+ opbd_lookup_table_segment_array_loader ( GX_LookupTable_Format format,
+ FT_UShort lastGlyph,
+ FT_UShort firstGlyph,
+ GX_LookupValue value,
+ FT_Pointer user )
+ {
+ FT_Error error;
+ FT_UShort segment_count = lastGlyph - firstGlyph + 1;
+
+ GX_Face face = ((generic_lookup_table_cb_data)user)->face;
+ FT_Pointer extra = ((generic_lookup_table_cb_data)user)->extra;
+ FT_UShort data_format = *(FT_UShort*)extra;
+ FT_Stream stream = ((generic_lookup_table_cb_data)user)->stream;
+ FT_Memory memory = stream->memory;
+ FT_Short offset = value->raw.s;
+ GX_OpticalBoundsData opbd_data;
+
+ FT_ULong base_offset;
+ FT_Int opbd_data_advance = 4 * sizeof(FT_Short);
+ FT_Int i;
+
+ /* Offset from the start of opbd table (written in spec) */
+ if ( ( error = face->goto_table(face, TTAG_opbd, stream, 0 ) ) )
+ goto Exit;
+
+ if ( ( FT_NEW_ARRAY ( opbd_data, segment_count ) ) )
+ goto Exit;
+
+ base_offset = FT_STREAM_POS() + offset;
+
+ for ( i = 0; i < segment_count; i++ )
+ {
+ if ( ( error = gx_opbd_load_data( face,
+ stream,
+ base_offset + i * opbd_data_advance,
+ data_format,
+ &(opbd_data[i]) ) ) )
+ goto Failure;
+ }
+ value->extra.opbd_data = opbd_data;
+ Exit:
+ return error;
+ Failure:
+ FT_FREE(opbd_data);
+ return error;
+ }
+
+ FT_LOCAL_DEF( FT_Error )
+ gx_face_load_opbd( GX_Face face,
+ FT_Stream stream,
+ GX_Opbd opbd )
+ {
+ FT_Error error;
+ const FT_Frame_Field opbd_fields[] =
+ {
+#undef FT_STRUCTURE
+#define FT_STRUCTURE GX_OpbdRec
+ FT_FRAME_START ( 6 ),
+ FT_FRAME_ULONG ( version ),
+ FT_FRAME_USHORT( format ),
+ FT_FRAME_END
+ };
+ GX_LookupTable_FuncsRec funcs = GX_LOOKUP_TABLE_FUNC_ZERO;
+ generic_lookup_table_cb_data_rec callback_data = GENERIC_LOOKUP_TABLE_CB_DATA_ZERO;
+
+ funcs.generic_func = opbd_lookup_table_generic_loader;
+ funcs.segment_array_func = opbd_lookup_table_segment_array_loader;
+ callback_data.face = face;
+ callback_data.stream = stream;
+
+ /* FT_TRACE2(( "Optical Bounds" )); */
+ if (( error = gx_table_init( &(opbd->root), face, TTAG_opbd, stream,
+ (GX_Table_Done_Func)gx_opbd_done) ))
+ goto Exit;
+
+ if ( FT_STREAM_READ_FIELDS( opbd_fields, opbd ) )
+ goto Exit;
+ error = gx_face_load_LookupTable( face, stream, &(opbd->lookup_data) );
+ if ( error )
+ goto Exit;
+
+ callback_data.extra = &opbd->format;
+ error = gx_LookupTable_traverse_low( &(opbd->lookup_data),
+ &funcs,
+ &callback_data );
+ Exit:
+ return error;
+ }
+
+ static FT_Error
+ opbd_lookup_table_generic_finalizer( GX_LookupTable_Format format,
+ GX_LookupValue value,
+ FT_Pointer user )
+ {
+ FT_Memory memory = user;
+ GX_OpticalBoundsData opbd_data;
+
+ if ( !value->extra.opbd_data )
+ return GX_Err_Ok;
+
+ opbd_data = value->extra.opbd_data;
+ FT_FREE(opbd_data);
+ value->extra.opbd_data = NULL;
+ return GX_Err_Ok;
+ }
+
+ FT_LOCAL_DEF ( void )
+ gx_opbd_done( GX_Opbd opbd,
+ FT_Memory memory )
+ {
+ GX_LookupTable_FuncsRec funcs = GX_LOOKUP_TABLE_FUNC_ZERO;
+
+ funcs.generic_func = opbd_lookup_table_generic_finalizer;
+ funcs.segment_array_func = generic_lookup_table_segment_array_finalizer;
+
+ gx_LookupTable_traverse_low( &(opbd->lookup_data),
+ &funcs,
+ memory );
+ gx_LookupTable_free ( &(opbd->lookup_data), memory );
+ }
+
+
+/******************************LCAR************************************/
+ static FT_Error
+ gx_lcar_load_partials ( FT_Stream stream,
+ FT_UShort count,
+ FT_Short *partials)
+ {
+ FT_Error error;
+ FT_Int i;
+
+ if ( FT_FRAME_ENTER ( sizeof( *partials ) * count ) )
+ goto Exit;
+
+ for ( i = 0; i < count; i++ )
+ partials[i] = FT_GET_USHORT();
+
+ FT_FRAME_EXIT();
+ Exit:
+ return error;
+ }
+
+ static FT_Error
+ gx_lcar_load_class_entry ( GX_Face face,
+ FT_Stream stream,
+ FT_ULong offset,
+ GX_LigCaretClassEntry * class_entry )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+ FT_UShort count;
+ FT_Int base_size = sizeof (**class_entry);
+
+ if ( FT_STREAM_SEEK(offset) )
+ goto Exit;
+
+ if ( FT_READ_USHORT(count) )
+ goto Exit;
+
+ if (count == 0)
+ {
+ *class_entry = NULL;
+ return GX_Err_Ok;
+ }
+
+ if ( FT_ALLOC ( *class_entry,
+ base_size + count * sizeof(*(*class_entry)->partials) ) )
+ goto Exit;
+
+ (*class_entry)->count = count;
+ (*class_entry)->partials = (FT_Short *)(((char *)*class_entry) + base_size);
+
+ error = gx_lcar_load_partials(stream,
+ (*class_entry)->count,
+ (*class_entry)->partials);
+ if ( error )
+ goto Failure;
+ Exit:
+ return error;
+ Failure:
+ FT_FREE(*class_entry);
+ *class_entry = NULL;
+ return error;
+
+ }
+
+ static void
+ gx_lcar_free_class_entry ( FT_Memory memory,
+ GX_LigCaretClassEntry class_entry )
+ {
+ class_entry->count = 0; /* Overkill? */
+ class_entry->partials = NULL;
+ FT_FREE( class_entry );
+ }
+
+ static FT_Error
+ lcar_lookup_table_generic_loader( GX_LookupTable_Format format,
+ GX_LookupValue value,
+ FT_Pointer user )
+ {
+ FT_Error error;
+ GX_Face face = ((generic_lookup_table_cb_data)user)->face;
+ FT_Stream stream = ((generic_lookup_table_cb_data)user)->stream;
+ FT_Short offset = value->raw.s;
+ GX_LigCaretClassEntry class_entry;
+
+
+ if ( ( error = face->goto_table( face, TTAG_lcar, stream, 0 ) ) )
+ return error;
+
+ if ( ( error = gx_lcar_load_class_entry ( face,
+ stream,
+ FT_STREAM_POS() + offset,
+ &class_entry ) ) )
+ return error;
+ value->extra.lcar_class_entry = class_entry;
+ return error;
+ }
+
+ static FT_Error
+ lcar_lookup_table_segment_array_loader ( GX_LookupTable_Format format,
+ FT_UShort lastGlyph,
+ FT_UShort firstGlyph,
+ GX_LookupValue value,
+ FT_Pointer user )
+
+ {
+ FT_Error error;
+ GX_Face face = ((generic_lookup_table_cb_data)user)->face;
+ FT_Stream stream = ((generic_lookup_table_cb_data)user)->stream;
+ FT_Memory memory = stream->memory;
+
+ FT_Short value_offset = value->raw.s;
+ FT_ULong table_offset;
+
+ FT_UShort segment_count = lastGlyph - firstGlyph + 1;
+ GX_LigCaretSegment segment;
+
+ FT_Int i, j;
+
+ /* disk seek chain:
+ 1. table_offset -> 2. value_offset -> 3. class_entry_offset */
+
+ /* 1. table_offset */
+ if ( (error = face->goto_table( face, TTAG_lcar, stream, 0 )) )
+ goto Exit;
+ table_offset = FT_STREAM_POS();
+
+ /* 2. value_offset
+ * -----------------------------------------------------------------
+ * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
+ * Pfaedit will not work?
+ * In spec: "Sometimes they are 16-bit offsets from the start of
+ * the table to the data. " The table? Is the table the lookup table
+ * or a table that uses the lookup table?
+ * Here I assume the table is the table that uses the lookup table.
+ * However, I have no conviction.
+ * As far as reading spec(fonts.apple.com/TTRefMan/RM06/Chap6lcar.html),
+ * table_offset + value_offset is correct. It seems that pfaedit uses
+ * lookup_table_offset + value_offset.
+ * -----------------------------------------------------------------*/
+ if ( FT_STREAM_SEEK( table_offset + value_offset ) )
+ goto Exit;
+
+ if ( FT_NEW_ARRAY ( segment, segment_count ) )
+ goto Exit;
+
+ if ( FT_FRAME_ENTER ( sizeof( segment[0].offset ) * segment_count ) )
+ goto Failure;
+ for ( i = 0; i < segment_count; i++ )
+ segment[i].offset = FT_GET_USHORT();
+ FT_FRAME_EXIT();
+
+ /* 3. class_entry_offset */
+ for ( i = 0; i < segment_count; i++ )
+ {
+ segment[i].class_entry = NULL;
+ if (( error = gx_lcar_load_class_entry(face, stream,
+ table_offset + segment[i].offset,
+ &(segment[i].class_entry)) ))
+ {
+ /* Rewind to free the resources */
+ for ( j = i - 1; j >= 0; j-- )
+ {
+ gx_lcar_free_class_entry (memory, segment[j].class_entry);
+ segment[j].class_entry = NULL;
+ }
+ goto Failure;
+ }
+ }
+ value->extra.lcar_segment = segment;
+ error = GX_Err_Ok;
+ Exit:
+ return error;
+ Failure:
+ FT_FREE( segment );
+ return error;
+ }
+
+
+ FT_LOCAL_DEF( FT_Error )
+ gx_face_load_lcar( GX_Face face,
+ FT_Stream stream,
+ GX_Lcar lcar )
+ {
+ FT_Error error;
+ const FT_Frame_Field lcar_fields[] =
+ {
+#undef FT_STRUCTURE
+#define FT_STRUCTURE GX_LcarRec
+ FT_FRAME_START ( 6 ),
+ FT_FRAME_ULONG ( version ),
+ FT_FRAME_USHORT ( format ),
+ FT_FRAME_END
+ };
+ GX_LookupTable_FuncsRec funcs = GX_LOOKUP_TABLE_FUNC_ZERO;
+ generic_lookup_table_cb_data_rec callback_data = GENERIC_LOOKUP_TABLE_CB_DATA_ZERO;
+
+ funcs.generic_func = lcar_lookup_table_generic_loader;
+ funcs.segment_array_func = lcar_lookup_table_segment_array_loader;
+ callback_data.face = face;
+ callback_data.stream = stream;
+
+ /* FT_TRACE2(( "Ligature Caret" )); */
+ if (( error = gx_table_init( &(lcar->root), face, TTAG_lcar, stream,
+ (GX_Table_Done_Func)gx_lcar_done) ))
+ goto Exit;
+
+ if ( FT_STREAM_READ_FIELDS( lcar_fields, lcar ) )
+ goto Exit;
+ error = gx_face_load_LookupTable ( face, stream, &(lcar->lookup) );
+ if ( error )
+ goto Exit;
+ error = gx_LookupTable_traverse_low( &(lcar->lookup),
+ &funcs,
+ &callback_data );
+ Exit:
+ return error;
+ }
+
+ static FT_Error
+ lcar_lookup_table_generic_finalizer( GX_LookupTable_Format format,
+ GX_LookupValue value,
+ FT_Pointer user )
+ {
+ FT_Memory memory = user;
+ GX_LigCaretClassEntry class_entry;
+
+ if ( !value->extra.lcar_class_entry )
+ return GX_Err_Ok;
+
+ class_entry = value->extra.lcar_class_entry;
+ gx_lcar_free_class_entry(memory, class_entry);
+ value->extra.lcar_class_entry = NULL;
+ return GX_Err_Ok;
+ }
+
+ static FT_Error
+ lcar_lookup_table_segment_array_finalizer( GX_LookupTable_Format format,
+ FT_UShort lastGlyph,
+ FT_UShort firstGlyph,
+ GX_LookupValue value,
+ FT_Pointer user )
+ {
+ FT_Memory memory = user;
+ GX_LigCaretSegment segment = value->extra.lcar_segment;
+ FT_UShort segment_count = lastGlyph - firstGlyph;
+ FT_Long i;
+
+ if ( !segment )
+ return GX_Err_Ok;
+
+ value->extra.lcar_segment = NULL;
+
+ for ( i = 0; i < segment_count; i++ )
+ {
+ gx_lcar_free_class_entry(memory, segment[i].class_entry);
+ segment[i].class_entry = NULL;
+ }
+ FT_FREE(segment);
+ return GX_Err_Ok;
+ }
+
+ FT_LOCAL_DEF ( void )
+ gx_lcar_done( GX_Lcar lcar,
+ FT_Memory memory )
+
+ {
+ GX_LookupTable_FuncsRec funcs = GX_LOOKUP_TABLE_FUNC_ZERO;
+
+ funcs.generic_func = lcar_lookup_table_generic_finalizer;
+ funcs.segment_array_func = lcar_lookup_table_segment_array_finalizer;
+
+ gx_LookupTable_traverse_low( &(lcar->lookup), &funcs, memory );
+ gx_LookupTable_free ( &(lcar->lookup), memory );
+ }
+
+
+/******************************BSLN************************************/
+ typedef FT_Error (* gx_bsln_perfmt_loader)( GX_Face face,
+ FT_Stream stream,
+ GX_BaselineParts parts );
+
+ static FT_Error
+ gx_bsln_load_32_ushort( GX_Face face,
+ FT_Stream stream,
+ FT_UShort slots[GX_BSLN_VALUE_COUNT] )
+ {
+ FT_Error error;
+ FT_Int i;
+
+ if ( FT_FRAME_ENTER ( sizeof( *slots ) * GX_BSLN_VALUE_COUNT) )
+ return error;
+ for ( i = 0; i < GX_BSLN_VALUE_COUNT; i++ )
+ slots[i] = FT_GET_USHORT();
+ FT_FRAME_EXIT();
+ return error;
+ }
+
+ static FT_Error
+ gx_bsln_load_fmt_distance_no_mapping ( GX_Face face,
+ FT_Stream stream,
+ GX_BaselineParts parts )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+ GX_BaselineFormat0Part fmt0part;
+
+ if ( FT_NEW( fmt0part ) )
+ goto Exit;
+
+ if (( error = gx_bsln_load_32_ushort( face, stream, fmt0part->deltas ) ))
+ goto Failure;
+ parts->fmt0 = fmt0part;
+ Exit:
+ return error;
+ Failure:
+ FT_FREE(fmt0part);
+ return error;
+ }
+
+ static FT_Error
+ gx_bsln_load_fmt_distance_with_mapping( GX_Face face,
+ FT_Stream stream,
+ GX_BaselineParts parts )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+ GX_BaselineFormat1Part fmt1part;
+ GX_LookupTable lookup_table;
+ GX_LookupTable_FuncsRec funcs = GX_LOOKUP_TABLE_FUNC_ZERO;
+ generic_lookup_table_cb_data_rec user_data = GENERIC_LOOKUP_TABLE_CB_DATA_ZERO;
+
+ funcs.segment_array_func = generic_lookup_table_segment_array_loader;
+ user_data.face = face;
+ user_data.stream = stream;
+ user_data.lookup_table = NULL;
+ user_data.table_tag = 0;
+
+ if ( FT_NEW ( fmt1part ) )
+ goto Exit;
+
+ if (( error = gx_bsln_load_32_ushort( face, stream,
+ fmt1part->deltas ) ))
+ goto Failure;
+
+ lookup_table = &(fmt1part->mappingData);
+ if (( error = gx_face_load_LookupTable ( face, stream,
+ lookup_table ) ))
+ goto Failure;
+ if ( lookup_table->format == GX_LOOKUPTABLE_SEGMENT_ARRAY )
+ {
+ user_data.lookup_table = lookup_table;
+ if (( error = gx_LookupTable_traverse_low( lookup_table,
+ &funcs, &user_data ) ))
+ goto Failure_Lookup_Table;
+ }
+ parts->fmt1 = fmt1part;
+ Exit:
+ return error;
+ Failure_Lookup_Table:
+ gx_LookupTable_free( lookup_table, memory );
+ Failure:
+ FT_FREE ( fmt1part );
+ return error;
+ }
+
+ static FT_Error
+ gx_bsln_load_fmt_control_point_no_mapping( GX_Face face,
+ FT_Stream stream,
+ GX_BaselineParts parts )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+ GX_BaselineFormat2Part fmt2part;
+ FT_UShort stdGlyph;
+
+ if ( FT_READ_USHORT(stdGlyph) )
+ goto Exit;
+
+ if ( FT_NEW( fmt2part ) )
+ goto Exit;
+
+ fmt2part->stdGlyph = stdGlyph;
+ if (( error = gx_bsln_load_32_ushort( face, stream,
+ fmt2part->ctlPoints ) ))
+ goto Failure;
+ parts->fmt2 = fmt2part;
+ Exit:
+ return error;
+ Failure:
+ FT_FREE(fmt2part);
+ return error;
+ }
+
+ static FT_Error
+ gx_bsln_load_fmt_control_point_with_mapping( GX_Face face,
+ FT_Stream stream,
+ GX_BaselineParts parts )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+ GX_BaselineFormat3Part fmt3part;
+ FT_UShort stdGlyph;
+
+ GX_LookupTable lookup_table;
+
+ GX_LookupTable_FuncsRec funcs = GX_LOOKUP_TABLE_FUNC_ZERO;
+ generic_lookup_table_cb_data_rec user_data = GENERIC_LOOKUP_TABLE_CB_DATA_ZERO;
+
+ funcs.segment_array_func = generic_lookup_table_segment_array_loader;
+ user_data.face = face;
+ user_data.stream = stream;
+
+ if ( FT_READ_USHORT(stdGlyph) )
+ goto Exit;
+
+ if ( FT_NEW( fmt3part ) )
+ goto Exit;
+
+ fmt3part->stdGlyph = stdGlyph;
+ if (( error = gx_bsln_load_32_ushort( face, stream,
+ fmt3part->ctlPoints ) ))
+ goto Failure;
+
+ lookup_table = &(fmt3part->mappingData);
+ if (( error = gx_face_load_LookupTable ( face, stream,
+ lookup_table ) ))
+ goto Failure;
+ if ( lookup_table->format == GX_LOOKUPTABLE_SEGMENT_ARRAY )
+ {
+ user_data.lookup_table = lookup_table;
+ if (( error = gx_LookupTable_traverse_low( lookup_table,
+ &funcs, &user_data ) ))
+ goto Failure_Lookup_Table;
+ }
+ parts->fmt3 = fmt3part;
+ Exit:
+ return error;
+ Failure_Lookup_Table:
+ gx_LookupTable_free( lookup_table, memory );
+ Failure:
+ FT_FREE(fmt3part);
+ return error;
+ }
+
+
+ FT_LOCAL_DEF( FT_Error )
+ gx_face_load_bsln( GX_Face face,
+ FT_Stream stream,
+ GX_Bsln bsln )
+ {
+ FT_Error error;
+ gx_bsln_perfmt_loader fmt_loader;
+
+ const FT_Frame_Field bsln_fields[] =
+ {
+#undef FT_STRUCTURE
+#define FT_STRUCTURE GX_BslnRec
+ FT_FRAME_START ( 8 ),
+ FT_FRAME_ULONG ( version ),
+ FT_FRAME_USHORT ( format ),
+ FT_FRAME_USHORT ( defaultBaseline ),
+ FT_FRAME_END
+ };
+ /* FT_TRACE2(( "Baseline" ));*/
+
+ if (( error = gx_table_init( &(bsln->root), face, TTAG_bsln, stream,
+ (GX_Table_Done_Func)gx_bsln_done) ))
+ goto Exit;
+
+ if ( FT_STREAM_READ_FIELDS( bsln_fields, bsln ) )
+ goto Exit;
+
+ switch ( bsln->format )
+ {
+ case GX_BSLN_FMT_DISTANCE_NO_MAPPING:
+ fmt_loader = gx_bsln_load_fmt_distance_no_mapping;
+ break;
+ case GX_BSLN_FMT_DISTANCE_WITH_MAPPING:
+ fmt_loader = gx_bsln_load_fmt_distance_with_mapping;
+ break;
+ case GX_BSLN_FMT_CONTROL_POINT_NO_MAPPING:
+ fmt_loader = gx_bsln_load_fmt_control_point_no_mapping;
+ break;
+ case GX_BSLN_FMT_CONTROL_POINT_WITH_MAPPING:
+ fmt_loader = gx_bsln_load_fmt_control_point_with_mapping;
+ break;
+ default:
+ fmt_loader = NULL;
+ }
+ FT_ASSERT(fmt_loader);
+ error = fmt_loader(face, stream, &(bsln->parts));
+ Exit:
+ return error;
+ }
+
+ FT_LOCAL_DEF ( void )
+ gx_bsln_done( GX_Bsln bsln,
+ FT_Memory memory )
+
+ {
+ GX_BaselineParts parts = &bsln->parts;
+ GX_LookupTable mappingData = NULL;
+ GX_LookupTable_FuncsRec funcs = GX_LOOKUP_TABLE_FUNC_ZERO;
+
+ funcs.segment_array_func = generic_lookup_table_segment_array_finalizer;
+
+ if ( bsln->format == GX_BSLN_FMT_DISTANCE_WITH_MAPPING )
+ mappingData = &(parts->fmt1->mappingData);
+ else if ( bsln->format == GX_BSLN_FMT_CONTROL_POINT_WITH_MAPPING )
+ mappingData = &(parts->fmt3->mappingData);
+
+ if (mappingData)
+ {
+ if ( mappingData->format == GX_LOOKUPTABLE_SEGMENT_ARRAY )
+ gx_LookupTable_traverse_low ( mappingData, &funcs, memory );
+ gx_LookupTable_free ( mappingData, memory );
+ }
+ FT_FREE(parts->any);
+ bsln->parts.any = NULL;
+ }
+
+
+/******************************MORT************************************/
+ typedef FT_Error (* gx_mort_subtable_loader) ( GX_Face face,
+ FT_Stream stream,
+ FT_UShort length,
+ GX_MetamorphosisSubtableBody body );
+
+ static FT_Error
+ gx_mort_load_rearrangement_subtable( GX_Face face,
+ FT_Stream stream,
+ FT_UShort length,
+ GX_MetamorphosisSubtableBody body )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+ GX_MetamorphosisRearrangementBody rearrangement_body;
+
+ if ( FT_NEW( rearrangement_body ) )
+ goto Exit;
+
+ if (( error = gx_face_load_StateTable ( face, stream,
+ &rearrangement_body->state_table,
+ NULL, NULL )))
+ goto Failure;
+ body->rearrangement = rearrangement_body;
+ Exit:
+ return error;
+ Failure:
+ FT_FREE( rearrangement_body );
+ body->rearrangement = NULL;
+ return error;
+
+ }
+
+ static void
+ gx_mort_free_rearrangement_subtable( FT_Memory memory,
+ GX_MetamorphosisRearrangementBody rearrangement_body )
+ {
+ gx_StateTable_free ( &rearrangement_body->state_table, memory, NULL, NULL );
+ FT_FREE( rearrangement_body );
+ }
+
+ static FT_Error
+ gx_mort_load_contextual_subtable_entry( GX_Face face,
+ FT_Stream stream,
+ GX_EntrySubtable entry_subtable,
+ FT_Pointer user )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+ GX_MetamorphosisContextualPerGlyph per_glyph;
+
+ const FT_Frame_Field contextual_subtable_entry_fields[] =
+ {
+#undef FT_STRUCTURE
+#define FT_STRUCTURE GX_MetamorphosisContextualPerGlyphRec
+ FT_FRAME_START ( 4 ),
+ FT_FRAME_SHORT ( markOffset ), /* Was:FT_UShort, see gxtype.h */
+ FT_FRAME_SHORT ( currentOffset ), /* Was:FT_UShort */
+ FT_FRAME_END
+ };
+
+ if ( FT_NEW ( per_glyph ) )
+ goto Exit;
+
+ if ( FT_STREAM_READ_FIELDS ( contextual_subtable_entry_fields,
+ per_glyph ) )
+ goto Failure;
+
+ entry_subtable->glyphOffsets.contextual = per_glyph;
+ Exit:
+ return error;
+ Failure:
+ FT_FREE( per_glyph );
+ entry_subtable->glyphOffsets.contextual = NULL;
+ return error;
+ }
+
+ static void
+ gx_mort_free_contextual_subtable_entry( FT_Memory memory,
+ GX_EntrySubtable entry_subtable,
+ FT_Pointer user )
+ {
+ FT_FREE( entry_subtable->glyphOffsets );
+ entry_subtable->glyphOffsets.contextual = NULL;
+ }
+
+ static FT_Error
+ gx_mort_load_contextual_subtable( GX_Face face,
+ FT_Stream stream,
+ FT_UShort length,
+ GX_MetamorphosisSubtableBody body )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+ GX_MetamorphosisContextualBody contextual_body;
+ GX_StateHeader state_header;
+ GX_MetamorphosisContextualSubstitutionTable substitutionTable;
+ GX_StateTable_Entry_Load_FuncsRec funcs = GX_STATE_TABLE_ENTRY_LOAD_FUNCS_ZERO;
+ FT_Int i;
+
+ funcs.loader = gx_mort_load_contextual_subtable_entry;
+ funcs.finalizer = gx_mort_free_contextual_subtable_entry;
+
+ if ( FT_NEW( contextual_body ) )
+ goto Exit;
+
+ if (( error = gx_face_load_StateTable ( face, stream,
+ &contextual_body->state_table,
+ &funcs, NULL) ))
+ goto Failure;
+
+ state_header = &contextual_body->state_table.header;
+ substitutionTable = &contextual_body->substitutionTable;
+ if ( FT_STREAM_SEEK( state_header->position + GX_STATE_HEADER_ADVANCE ) ||
+ FT_READ_USHORT(substitutionTable->offset))
+ goto Failure_stateTable;
+
+ substitutionTable->nGlyphIndexes = (length - substitutionTable->offset)/2;
+
+ substitutionTable->glyph_indexes = NULL;
+ if ( FT_NEW_ARRAY( substitutionTable->glyph_indexes,
+ substitutionTable->nGlyphIndexes ) )
+ goto Failure_stateTable;
+ if ( FT_STREAM_SEEK( state_header->position
+ + substitutionTable->offset ) )
+ goto Failure_substitutionTable;
+ if ( FT_FRAME_ENTER( substitutionTable->nGlyphIndexes * sizeof( substitutionTable->glyph_indexes[0] ) ))
+ goto Failure_substitutionTable;
+
+ for ( i = 0; i < substitutionTable->nGlyphIndexes; i++ )
+ substitutionTable->glyph_indexes[i] = FT_GET_USHORT();
+ FT_FRAME_EXIT();
+ body->contextual = contextual_body;
+ Exit:
+ return error;
+ Failure_substitutionTable:
+ fprintf(stderr,"hell: 0x%x\n", (substitutionTable->nGlyphIndexes - 1));
+ FT_FREE( substitutionTable->glyph_indexes );
+ substitutionTable->glyph_indexes = NULL;
+ Failure_stateTable:
+ gx_StateTable_free( &contextual_body->state_table, memory, funcs.finalizer, NULL );
+ Failure:
+ FT_FREE( contextual_body );
+ body->contextual = NULL;
+ return error;
+
+ }
+
+ static void
+ gx_mort_free_contextual_subtable ( FT_Memory memory,
+ GX_MetamorphosisContextualBody contextual_body )
+ {
+ GX_MetamorphosisContextualSubstitutionTable substitutionTable;
+
+ substitutionTable = &contextual_body->substitutionTable;;
+ FT_FREE( substitutionTable->glyph_indexes );
+ substitutionTable->glyph_indexes = NULL;
+ gx_StateTable_free( &contextual_body->state_table,
+ memory,
+ gx_mort_free_contextual_subtable_entry,
+ NULL );
+ FT_FREE( contextual_body );
+ }
+
+#if 0
+ static FT_Error
+ mort_max_ligAction_offset( GX_EntrySubtable entry_subtable,
+ FT_Pointer user )
+ {
+ FT_UShort * max_offset = (FT_UShort *)user;
+ FT_UShort offset = entry_subtable->flags & GX_MORT_LIGATURE_FLAGS_OFFSET;
+ if ( *max_offset < offset )
+ *max_offset = offset;
+ return GX_Err_Ok;
+ }
+
+ static FT_UShort
+ gx_mort_count_ligAction_entry(GX_Face face,
+ GX_MetamorphosisLigatureBody ligature_body)
+ {
+ FT_UShort max_offset = 0;
+ gx_StateTable_traverse_entries( &ligature_body->state_table,
+ mort_max_ligAction_offset,
+ &max_offset );
+ /* Because ligActionTable is an array of FT_ULong, we devide the offset by
+ sizeof(FT_ULong) here. */
+ return max_offset
+ ?(((max_offset - ligature_body->ligActionTable.offset)/sizeof(FT_ULong)) + 1)
+ : max_offset;
+ }
+#endif /* 0 */
+ static FT_Error
+ gx_mort_load_ligature_subtable( GX_Face face,
+ FT_Stream stream,
+ FT_UShort length,
+ GX_MetamorphosisSubtableBody body )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+ GX_MetamorphosisLigatureBody ligature_body;
+ GX_StateHeader state_header;
+ GX_MetamorphosisLigatureActionTable ligActionTable;
+ GX_MetamorphosisComponentTable componentTable;
+ GX_MetamorphosisLigatureTable ligatureTable;
+
+ FT_Int i;
+
+ if ( FT_NEW( ligature_body ) )
+ goto Exit;
+
+ if (( error = gx_face_load_StateTable( face, stream,
+ &ligature_body->state_table,
+ NULL, NULL )))
+ goto Failure;
+
+ state_header = &ligature_body->state_table.header;
+ ligActionTable = &ligature_body->ligActionTable;
+ componentTable = &ligature_body->componentTable;
+ ligatureTable = &ligature_body->ligatureTable;
+ if ( FT_STREAM_SEEK( state_header->position + GX_STATE_HEADER_ADVANCE ) ||
+ FT_FRAME_ENTER( sizeof( ligActionTable->offset )
+ + sizeof( componentTable->offset )
+ + sizeof( ligatureTable->offset )))
+ goto Failure_stateTable;
+ ligActionTable->offset = FT_GET_USHORT();
+ componentTable->offset = FT_GET_USHORT();
+ ligatureTable->offset = FT_GET_USHORT();
+ FT_FRAME_EXIT();
+
+ /* -----------------------------------------------------------------
+ * Calculate the order of tables: ligActionTable, componentTable and
+ * ligatureTable
+ * ----------------------------------------------------------------- */
+ generic_triple_offset_diff(ligActionTable->offset, componentTable->offset, ligatureTable->offset,
+ length,
+ &ligActionTable->nActions, &componentTable->nComponent, &ligatureTable->nLigature);
+
+ /* Load ligActionTable */
+#if 0
+ ligActionTable->nActions = gx_mort_count_ligAction_entry( face,
+ ligature_body );
+#endif /* 0 */
+
+ ligActionTable->body = NULL;
+ if ( FT_NEW_ARRAY( ligActionTable->body, ligActionTable->nActions ) )
+ goto Failure_stateTable;
+ if ( FT_STREAM_SEEK( state_header->position + ligActionTable->offset ) ||
+ FT_FRAME_ENTER( ligActionTable->nActions * sizeof( ligActionTable->body[0] ) ) )
+ goto Failure_ligActionTable;
+ for ( i = 0; i < ligActionTable->nActions; i++ )
+ ligActionTable->body[i] = FT_GET_ULONG();
+ FT_FRAME_EXIT();
+
+
+ /* Load componentTable */
+ componentTable->body = NULL;
+ if ( FT_NEW_ARRAY ( componentTable->body, componentTable->nComponent ) )
+ goto Failure_ligActionTable;
+ if ( FT_STREAM_SEEK ( state_header->position + componentTable->offset ) ||
+ FT_FRAME_ENTER ( componentTable->nComponent * sizeof ( componentTable->body[0] ) ) )
+ goto Failure_componentTable;
+ for ( i = 0; i < componentTable->nComponent; i++ )
+ componentTable->body[i] = FT_GET_USHORT();
+ FT_FRAME_EXIT();
+
+ /* Load ligatureTable */
+ ligatureTable->body = NULL;
+ if ( FT_NEW_ARRAY ( ligatureTable->body, ligatureTable->nLigature ) )
+ goto Failure_componentTable;
+ if ( FT_STREAM_SEEK ( state_header->position + ligatureTable->offset ) ||
+ FT_FRAME_ENTER ( ligatureTable->nLigature * sizeof ( ligatureTable->body[0] ) ) )
+ goto Failure_ligatureTable;
+ for ( i = 0; i < ligatureTable->nLigature; i++ )
+ ligatureTable->body[i] = FT_GET_USHORT();
+ FT_FRAME_EXIT();
+ body->ligature = ligature_body;
+ Exit:
+ return error;
+ Failure_ligatureTable:
+ FT_FREE (ligatureTable->body);
+ ligatureTable->body = NULL;
+ Failure_componentTable:
+ FT_FREE (componentTable->body);
+ componentTable->body = NULL;
+ Failure_ligActionTable:
+ FT_FREE (ligActionTable->body);
+ ligActionTable->body = NULL;
+ Failure_stateTable:
+ gx_StateTable_free( &ligature_body->state_table,
+ memory,
+ NULL, /* CHECK, Thu Oct 23 14:14:43 2003 */
+ NULL);
+ Failure:
+ FT_FREE( ligature_body );
+ return error;
+ }
+
+ static void
+ gx_mort_free_ligature_subtable ( FT_Memory memory,
+ GX_MetamorphosisLigatureBody ligature_body )
+ {
+ GX_MetamorphosisLigatureActionTable ligActionTable = &ligature_body->ligActionTable;
+ GX_MetamorphosisComponentTable componentTable = &ligature_body->componentTable;
+ GX_MetamorphosisLigatureTable ligatureTable = &ligature_body->ligatureTable;
+
+ FT_FREE (ligatureTable->body);
+ ligatureTable->body = NULL;
+ FT_FREE (componentTable->body);
+ componentTable->body = NULL;
+ FT_FREE (ligActionTable->body);
+ ligActionTable->body = NULL;
+ gx_StateTable_free( &ligature_body->state_table,
+ memory,
+ NULL, /* CHECK, Thu Oct 23 14:14:43 2003 */
+ NULL );
+ FT_FREE( ligature_body );
+ }
+
+ static FT_Error
+ gx_mort_load_noncontextual_subtable ( GX_Face face,
+ FT_Stream stream,
+ FT_UShort length,
+ GX_MetamorphosisSubtableBody body )
+ {
+ return generic_load_noncontextual_subtable( face, stream, length, body, TTAG_mort );
+ }
+
+ static void
+ gx_mort_free_noncontextual_subtable( FT_Memory memory,
+ GX_MetamorphosisNoncontextualBody noncontextual_body )
+ {
+ GX_LookupTable lookup_table = &noncontextual_body->lookup_table;
+
+ GX_LookupTable_FuncsRec funcs = GX_LOOKUP_TABLE_FUNC_ZERO;
+
+ funcs.segment_array_func = generic_lookup_table_segment_array_finalizer;
+
+ if ( lookup_table->format == GX_LOOKUPTABLE_SEGMENT_ARRAY )
+ gx_LookupTable_traverse_low( lookup_table, &funcs, memory);
+
+ gx_LookupTable_free( lookup_table, memory );
+ FT_FREE(noncontextual_body);
+ }
+
+ static FT_Error
+ gx_mort_load_insertion_glyphcodes ( GX_Face face,
+ FT_Stream stream,
+ FT_ULong pos,
+ FT_UShort count,
+ FT_UShort * glyphcodes )
+ {
+ FT_Error error;
+ FT_Int i;
+ if ( FT_STREAM_SEEK( pos ) )
+ return error;
+
+ if (FT_FRAME_ENTER( sizeof ( glyphcodes[0] ) * count ) )
+ return error;
+ for ( i = 0; i < count; i++ )
+ glyphcodes[i] = FT_GET_USHORT();
+ FT_FRAME_EXIT();
+
+ return GX_Err_Ok;;
+ }
+
+ static FT_Error
+ gx_mort_load_insertion_subtable_entry( GX_Face face,
+ FT_Stream stream,
+ GX_EntrySubtable entry_subtable,
+ FT_Pointer user )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ GX_MetamorphosisInsertionBody insertion_body = user;
+ GX_StateTable state_table = &(insertion_body->state_table);
+ GX_StateHeader state_header = &(state_table->header);
+
+ GX_MetamorphosisInsertionPerGlyph per_glyph;
+ FT_UShort current_count = gx_mask_zero_shift(entry_subtable->flags,
+ GX_MORT_INSERTION_FLAGS_CURRENT_INSERT_COUNT);
+ FT_UShort marked_count = gx_mask_zero_shift(entry_subtable->flags,
+ GX_MORT_INSERTION_FLAGS_MARKED_INSERT_COUNT);
+ GX_MetamorphosisInsertionList currentInsertList;
+ GX_MetamorphosisInsertionList markedInsertList;
+ FT_ULong tmp_pos;
+
+ const FT_Frame_Field insertion_subtable_entry_fields[] =
+ {
+#undef FT_STRUCTURE
+#define FT_STRUCTURE GX_MetamorphosisInsertionPerGlyphRec
+ FT_FRAME_START ( 4 ),
+ FT_FRAME_USHORT ( currentInsertList.offset ),
+ FT_FRAME_USHORT ( markedInsertList.offset ),
+ FT_FRAME_END
+ };
+
+ if ( FT_ALLOC ( per_glyph,
+ sizeof(per_glyph) +
+ (current_count * sizeof(currentInsertList->glyphcodes[0]) ) +
+ (marked_count * sizeof(markedInsertList->glyphcodes[0]) )) )
+ goto Exit;
+
+ currentInsertList = &per_glyph->currentInsertList;
+ markedInsertList = &per_glyph->markedInsertList;
+ currentInsertList->glyphcodes = (FT_UShort *)(((char *)per_glyph) + sizeof(per_glyph));
+ markedInsertList->glyphcodes = currentInsertList->glyphcodes + current_count;
+
+ if ( FT_STREAM_READ_FIELDS ( insertion_subtable_entry_fields,
+ per_glyph ) )
+ goto Failure;
+
+
+ /* TODO: Should optimize.
+ Being `offset' zero means, there is no insertion.
+ But we can know whether the `offset' is zero or not after reading fields.
+ Some memory area(->glyphcodes) allocated before reading fields are wasted. */
+ if ( !per_glyph->currentInsertList.offset )
+ current_count = 0;
+ if ( !per_glyph->markedInsertList.offset )
+ marked_count = 0;
+
+ tmp_pos = FT_STREAM_POS();
+ if ( (error = gx_mort_load_insertion_glyphcodes ( face,
+ stream,
+ state_header->position + currentInsertList->offset,
+ current_count,
+ currentInsertList->glyphcodes ) ) )
+ goto Failure;
+ if ( (error = gx_mort_load_insertion_glyphcodes (face,
+ stream,
+ state_header->position + markedInsertList->offset,
+ marked_count,
+ markedInsertList->glyphcodes) ) )
+ goto Failure;
+
+ if ( FT_STREAM_SEEK( tmp_pos ) )
+ goto Failure;
+ entry_subtable->glyphOffsets.insertion = per_glyph;
+ Exit:
+ return error;
+ Failure:
+ FT_FREE( per_glyph );
+ entry_subtable->glyphOffsets.insertion = NULL;
+ return error;
+ }
+
+ static void
+ gx_mort_free_insertion_subtable_entry( FT_Memory memory,
+ GX_EntrySubtable entry_subtable,
+ FT_Pointer user )
+ {
+ FT_FREE( entry_subtable->glyphOffsets.insertion );
+ entry_subtable->glyphOffsets.insertion = NULL;
+ }
+
+ static FT_Error
+ gx_mort_load_insertion_subtable( GX_Face face,
+ FT_Stream stream,
+ FT_UShort length,
+ GX_MetamorphosisSubtableBody body )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+ GX_MetamorphosisInsertionBody insertion_body;
+ GX_StateTable_Entry_Load_FuncsRec funcs = GX_STATE_TABLE_ENTRY_LOAD_FUNCS_ZERO;
+
+ funcs.loader = gx_mort_load_insertion_subtable_entry;
+ funcs.finalizer = gx_mort_free_insertion_subtable_entry;
+
+ if ( FT_NEW( insertion_body ) )
+ goto Exit;
+
+ if (( error = gx_face_load_StateTable( face, stream,
+ &insertion_body->state_table,
+ &funcs, insertion_body ) ))
+ goto Failure;
+ body->insertion = insertion_body;
+ Exit:
+ return error;
+ Failure:
+ FT_FREE(insertion_body);
+ body->insertion = NULL;
+ return error;
+
+ }
+
+ static void
+ gx_mort_free_insertion_subtable ( FT_Memory memory,
+ GX_MetamorphosisInsertionBody insertion_body )
+ {
+ gx_StateTable_free( &insertion_body->state_table,
+ memory,
+ gx_mort_free_insertion_subtable_entry,
+ NULL );
+ FT_FREE(insertion_body);
+ }
+
+ static FT_Error
+ gx_mort_load_subtable_header( GX_Face face,
+ FT_Stream stream,
+ GX_MetamorphosisSubtableHeader header )
+ {
+ FT_Error error;
+ const FT_Frame_Field mort_subtable_header_fileds[] =
+ {
+#undef FT_STRUCTURE
+#define FT_STRUCTURE GX_MetamorphosisSubtableHeaderRec
+ FT_FRAME_START ( 8 ),
+ FT_FRAME_USHORT ( length ),
+ FT_FRAME_USHORT ( coverage ),
+ FT_FRAME_ULONG ( subFeatureFlags ),
+ FT_FRAME_END
+ };
+ header->position = FT_STREAM_POS();
+ return FT_STREAM_READ_FIELDS( mort_subtable_header_fileds, header );
+ }
+
+ static FT_Error
+ gx_mort_load_subtable( GX_Face face,
+ FT_Stream stream,
+ FT_ULong pos,
+ GX_MetamorphosisSubtable chain_Subtbl )
+ {
+ FT_Error error;
+ GX_MetamorphosisSubtableHeader header;
+ FT_UShort subtable_type;
+ gx_mort_subtable_loader loader;
+ FT_UShort header_size = sizeof(header->length)
+ + sizeof(header->coverage)
+ + sizeof(header->subFeatureFlags);
+
+ if ( FT_STREAM_SEEK ( pos ) )
+ goto Exit;
+
+ header = &chain_Subtbl->header;
+ if (( error = gx_mort_load_subtable_header ( face,
+ stream,
+ header )))
+ goto Exit;
+
+ subtable_type = header->coverage & GX_MORT_COVERAGE_SUBTABLE_TYPE;
+ FT_TRACE2(( " mort subtable format %d\n", subtable_type ));
+ switch ( subtable_type )
+ {
+ case GX_MORT_REARRANGEMENT_SUBTABLE: /* StHeader, newState */
+ loader = gx_mort_load_rearrangement_subtable;
+ break;
+ case GX_MORT_CONTEXTUAL_SUBTABLE: /* StHeader++, newState++ */
+ loader = gx_mort_load_contextual_subtable;
+ break;
+ case GX_MORT_LIGATURE_SUBTABLE: /* StHeader++,, newState */
+ loader = gx_mort_load_ligature_subtable;
+ break;
+ case GX_MORT_NONCONTEXTUAL_SUBTABLE: /* Lookup table */
+ loader = gx_mort_load_noncontextual_subtable;
+ break;
+ case GX_MORT_INSERTION_SUBTABLE: /* StHeader, newState++ */
+ loader = gx_mort_load_insertion_subtable;
+ break;
+ default:
+ loader = NULL;
+ break;
+ }
+ FT_ASSERT(loader);
+ error = (*loader)(face, stream, header->length - header_size, &chain_Subtbl->body);
+ Exit:
+ return error;
+ }
+
+ static void
+ gx_mort_free_subtable( FT_Memory memory, GX_MetamorphosisSubtable chain_Subtbl )
+ {
+ GX_MetamorphosisSubtableHeader header;
+ FT_UShort subtable_type;
+
+ header = &chain_Subtbl->header;
+ subtable_type = header->coverage & GX_MORT_COVERAGE_SUBTABLE_TYPE;
+ switch ( subtable_type )
+ {
+ case GX_MORT_REARRANGEMENT_SUBTABLE:
+ gx_mort_free_rearrangement_subtable( memory, chain_Subtbl->body.rearrangement );
+ break;
+ case GX_MORT_CONTEXTUAL_SUBTABLE:
+ gx_mort_free_contextual_subtable ( memory, chain_Subtbl->body.contextual );
+ break;
+ case GX_MORT_LIGATURE_SUBTABLE:
+ gx_mort_free_ligature_subtable ( memory, chain_Subtbl->body.ligature );
+ break;
+ case GX_MORT_NONCONTEXTUAL_SUBTABLE:
+ gx_mort_free_noncontextual_subtable( memory, chain_Subtbl->body.noncontextual );
+ break;
+ case GX_MORT_INSERTION_SUBTABLE:
+ gx_mort_free_insertion_subtable ( memory, chain_Subtbl->body.insertion );
+ break;
+ default:
+ break;
+ }
+ chain_Subtbl->body.any = NULL;
+ }
+
+
+ static FT_Error
+ gx_mort_load_feature_table( GX_Face face,
+ FT_Stream stream,
+ GX_MetamorphosisFeatureTable feat_Subtbl )
+ {
+ FT_Error error;
+ const FT_Frame_Field mort_feature_table_fileds[] =
+ {
+#undef FT_STRUCTURE
+#define FT_STRUCTURE GX_MetamorphosisFeatureTableRec
+ FT_FRAME_START ( 12 ),
+ FT_FRAME_USHORT ( featureType ),
+ FT_FRAME_USHORT ( featureSetting ),
+ FT_FRAME_ULONG ( enableFlags ),
+ FT_FRAME_ULONG ( disableFlags ),
+ FT_FRAME_END
+ };
+
+ return FT_STREAM_READ_FIELDS( mort_feature_table_fileds, feat_Subtbl );
+ }
+
+ static FT_Error
+ gx_mort_load_chain_header( GX_Face face,
+ FT_Stream stream,
+ GX_MetamorphosisChainHeader header )
+ {
+ FT_Error error;
+
+ const FT_Frame_Field mort_chain_header_fields[] =
+ {
+#undef FT_STRUCTURE
+#define FT_STRUCTURE GX_MetamorphosisChainHeaderRec
+ FT_FRAME_START ( 12 ),
+ FT_FRAME_ULONG ( defaultFlags ),
+ FT_FRAME_ULONG ( chainLength ),
+ FT_FRAME_USHORT ( nFeatureEntries ),
+ FT_FRAME_USHORT ( nSubtables ),
+ FT_FRAME_END
+ };
+
+ return FT_STREAM_READ_FIELDS(mort_chain_header_fields, header);
+ }
+
+ static FT_Error
+ gx_mort_load_chain( GX_Face face,
+ FT_Stream stream,
+ FT_ULong pos,
+ GX_MetamorphosisChain chain )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+ GX_MetamorphosisChainHeader header;
+ GX_MetamorphosisFeatureTable feat_Subtbl = NULL;
+ GX_MetamorphosisSubtable chain_Subtbl = NULL;
+ FT_ULong subtbl_start;
+ FT_Int i, j;
+
+ header = &(chain->header);
+ if ( FT_STREAM_SEEK ( pos ) ||
+ ( error = gx_mort_load_chain_header(face, stream, header )) ||
+ FT_NEW_ARRAY ( feat_Subtbl, header->nFeatureEntries ) )
+ goto Exit;
+
+ for ( i = 0; i < header->nFeatureEntries; i++ )
+ {
+ if (( error = gx_mort_load_feature_table( face, stream,
+ &feat_Subtbl[i] ) ))
+ goto Failure;
+ }
+
+ subtbl_start = FT_STREAM_POS();
+ if ( FT_NEW_ARRAY ( chain_Subtbl, header->nSubtables ) )
+ goto Failure;
+
+ for ( i = 0; i < header->nSubtables; i++ )
+ {
+ if (( error = gx_mort_load_subtable( face, stream, subtbl_start,
+ &chain_Subtbl[i]) ))
+ {
+ for ( j = i - 1; j >= 0; j-- )
+ gx_mort_free_subtable( memory, &chain_Subtbl[j] );
+ goto Failure;
+ }
+ subtbl_start += chain_Subtbl[i].header.length;
+ }
+ chain->feat_Subtbl = feat_Subtbl;
+ chain->chain_Subtbl = chain_Subtbl;
+ Exit:
+ return error;
+ Failure:
+ chain->feat_Subtbl = NULL;
+ chain->chain_Subtbl = NULL;
+ if ( feat_Subtbl )
+ FT_FREE ( feat_Subtbl );
+ if ( chain_Subtbl )
+ FT_FREE ( chain_Subtbl );
+ return error;
+ }
+
+ static void
+ gx_mort_free_chain( FT_Memory memory,
+ GX_MetamorphosisChain chain )
+ {
+ GX_MetamorphosisChainHeader header;
+ FT_Int i;
+
+ header = &(chain->header);
+ for ( i = header->nSubtables; i > 0 ; i-- )
+ gx_mort_free_subtable(memory, &chain->chain_Subtbl[i - 1]);
+ FT_FREE(chain->chain_Subtbl);
+ chain->chain_Subtbl = NULL;
+ FT_FREE(chain->feat_Subtbl);
+ chain->feat_Subtbl = NULL;
+ }
+
+ FT_LOCAL_DEF ( FT_Error )
+ gx_face_load_mort( GX_Face face,
+ FT_Stream stream,
+ GX_Mort mort )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+ GX_MetamorphosisChain chain;
+
+ FT_ULong chain_start_pos;
+ FT_Int i, j;
+ const FT_Frame_Field mort_fields[] =
+ {
+#undef FT_STRUCTURE
+#define FT_STRUCTURE GX_MortRec
+ FT_FRAME_START ( 8 ),
+ FT_FRAME_LONG ( version ),
+ FT_FRAME_ULONG ( nChains ),
+ FT_FRAME_END
+ };
+ /* FT_TRACE2(( "Metamorphosis Table" )); */
+ if (( error = gx_table_init( &(mort->root), face, TTAG_mort, stream,
+ (GX_Table_Done_Func)gx_mort_done) ))
+ goto Exit;
+
+ mort->chain = NULL;
+ if ( FT_STREAM_READ_FIELDS( mort_fields, mort ) )
+ goto Exit;
+
+ if ( FT_NEW_ARRAY ( chain, mort->nChains ) )
+ goto Exit;
+
+ chain_start_pos = FT_STREAM_POS();
+ for ( i = 0; i < mort->nChains; i++ )
+ {
+ if (( error = gx_mort_load_chain( face,
+ stream, chain_start_pos,
+ &chain[i] ) ))
+ {
+ for ( j = i - 1; j >= 0; j-- )
+ gx_mort_free_chain( memory, &chain[j] );
+ goto Failure;
+ }
+ chain_start_pos += chain[i].header.chainLength;
+ }
+ mort->chain = chain;
+ Exit:
+ return error;
+ Failure:
+ FT_FREE( chain );
+ return error;
+ }
+
+ FT_LOCAL_DEF ( void )
+ gx_mort_done( GX_Mort mort,
+ FT_Memory memory )
+
+ {
+ FT_Int i;
+
+ for ( i = 0; i < mort->nChains; i++ )
+ gx_mort_free_chain( memory, &mort->chain[i] );
+ FT_FREE( mort->chain );
+ mort->chain = NULL;
+ }
+
+
+/******************************MORX************************************/
+/* Protype declaration */
+static void gx_morx_free_chain( FT_Memory memory, GX_XMetamorphosisChain chain );
+static void gx_morx_free_subtable( FT_Memory memory, GX_XMetamorphosisSubtable chain_Subtbl );
+
+#define gx_morx_load_feature_table gx_mort_load_feature_table
+#define gx_morx_free_feature_table gx_mort_free_feature_table
+
+ typedef FT_Error (* gx_morx_subtable_loader) ( GX_Face face,
+ FT_Stream stream,
+ FT_ULong length,
+ GX_XMetamorphosisSubtableBody body );
+
+ static FT_Error
+ gx_morx_load_chain_header( GX_Face face,
+ FT_Stream stream,
+ GX_XMetamorphosisChainHeader header )
+ {
+ FT_Error error;
+
+ const FT_Frame_Field morx_chain_header_fields[] =
+ {
+#undef FT_STRUCTURE
+#define FT_STRUCTURE GX_XMetamorphosisChainHeaderRec
+ FT_FRAME_START ( 16 ),
+ FT_FRAME_ULONG ( defaultFlags ),
+ FT_FRAME_ULONG ( chainLength ),
+ FT_FRAME_ULONG ( nFeatureEntries ),
+ FT_FRAME_ULONG ( nSubtables ),
+ FT_FRAME_END
+ };
+
+ return FT_STREAM_READ_FIELDS(morx_chain_header_fields, header);
+ }
+
+ static FT_Error
+ gx_morx_load_rearrangement_subtable( GX_Face face,
+ FT_Stream stream,
+ FT_ULong length,
+ GX_XMetamorphosisSubtableBody body )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+ GX_XMetamorphosisRearrangementBody rearrangement_body;
+
+ if ( FT_NEW( rearrangement_body ) )
+ goto Exit;
+
+ if (( error = gx_face_load_XStateTable ( face, stream,
+ &rearrangement_body->state_table,
+ NULL,
+ NULL ) ))
+ goto Failure;
+ body->rearrangement = rearrangement_body;
+ Exit:
+ return error;
+ Failure:
+ FT_FREE( rearrangement_body );
+ body->rearrangement = NULL;
+ return error;
+ }
+
+/*
+ * Contextual
+ */
+ static FT_Error
+ gx_morx_load_contextual_subtable_entry( GX_Face face,
+ FT_Stream stream,
+ GX_EntrySubtable entry_subtable,
+ FT_Pointer user )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ GX_XMetamorphosisContextualPerGlyph per_glyph;
+ const FT_Frame_Field contextual_subtable_entry_fields[] =
+ {
+#undef FT_STRUCTURE
+#define FT_STRUCTURE GX_XMetamorphosisContextualPerGlyphRec
+ FT_FRAME_START ( 4 ),
+ FT_FRAME_USHORT ( markIndex ),
+ FT_FRAME_USHORT ( currentIndex ),
+ FT_FRAME_END
+ };
+
+ if ( FT_NEW( per_glyph ) )
+ goto Exit;
+
+ if ( FT_STREAM_READ_FIELDS ( contextual_subtable_entry_fields,
+ per_glyph ) )
+ goto Failure;
+
+ entry_subtable->glyphOffsets.xcontextual = per_glyph;
+ Exit:
+ return error;
+ Failure:
+ FT_FREE( per_glyph );
+ entry_subtable->glyphOffsets.xcontextual = NULL;
+ return error;
+ }
+
+ static void
+ gx_morx_free_contextual_subtable_entry( FT_Memory memory,
+ GX_EntrySubtable entry_subtable,
+ FT_Pointer user )
+ {
+ FT_FREE( entry_subtable->glyphOffsets.xcontextual );
+ entry_subtable->glyphOffsets.xcontextual = NULL;
+ }
+
+
+ static FT_Error
+ morx_max_lookup_table_index( GX_EntrySubtable entry_subtable,
+ FT_Pointer user )
+ {
+ FT_Long * max_index = (FT_Long *)user;
+ FT_UShort local_max_index;
+ GX_XMetamorphosisContextualPerGlyph per_glyph = entry_subtable->glyphOffsets.xcontextual;
+ FT_UShort markIndex = per_glyph->markIndex;
+ FT_UShort currentIndex = per_glyph->currentIndex;
+
+ if ( markIndex == GX_MORX_NO_SUBSTITUTION )
+ markIndex = 0;
+ if ( currentIndex == GX_MORX_NO_SUBSTITUTION )
+ currentIndex = 0;
+
+ if ( markIndex < currentIndex )
+ local_max_index = currentIndex;
+ else
+ local_max_index = markIndex;
+
+ if ( *max_index < local_max_index )
+ *max_index = local_max_index;
+ return GX_Err_Ok;
+ }
+
+ static FT_UShort
+ gx_morx_count_lookup_table (GX_Face face,
+ GX_XStateTable state_table)
+ {
+ FT_Long max_index = -1;
+ gx_XStateTable_traverse_entries ( state_table,
+ morx_max_lookup_table_index,
+ &max_index );
+ return (FT_UShort)(max_index + 1);
+ }
+
+ static FT_Error
+ gx_morx_load_lookup_table( GX_Face face,
+ FT_Stream stream,
+ FT_ULong pos,
+ GX_LookupTable * lookup_table )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+ GX_LookupTable local_lookup_table = NULL;
+ GX_LookupTable_FuncsRec funcs = GX_LOOKUP_TABLE_FUNC_ZERO;
+ generic_lookup_table_cb_data_rec user_data = GENERIC_LOOKUP_TABLE_CB_DATA_ZERO;
+
+ funcs.segment_array_func = generic_lookup_table_segment_array_loader;
+ user_data.face = face;
+ user_data.stream = stream;
+ /* -----------------------------------------------------------------
+ * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
+ * Next code is correct?
+ * ----------------------------------------------------------------- */
+ user_data.table_tag = 0;
+
+ *lookup_table = NULL;
+
+ if ( FT_STREAM_SEEK(pos) )
+ goto Exit;
+
+ if ( FT_NEW(local_lookup_table) )
+ goto Exit;
+
+ if (( error = gx_face_load_LookupTable( face, stream, local_lookup_table )))
+ goto Failure;
+
+ if ( local_lookup_table->format == GX_LOOKUPTABLE_SEGMENT_ARRAY )
+ {
+ if (( error = gx_LookupTable_traverse_low( local_lookup_table,
+ &funcs,
+ &user_data )))
+ goto Failure_Lookup_Table;
+ }
+
+ *lookup_table = local_lookup_table;
+ Exit:
+ return error;
+ Failure_Lookup_Table:
+ gx_LookupTable_free( local_lookup_table, memory );
+ Failure:
+ FT_FREE(local_lookup_table);
+ return error;
+ }
+
+ static void
+ gx_morx_free_lookup_table( FT_Memory memory,
+ GX_LookupTable lookup_table )
+ {
+ GX_LookupTable_FuncsRec funcs = GX_LOOKUP_TABLE_FUNC_ZERO;
+
+ funcs.segment_array_func = generic_lookup_table_segment_array_finalizer;
+
+ if ( lookup_table->format == GX_LOOKUPTABLE_SEGMENT_ARRAY )
+ gx_LookupTable_traverse_low ( lookup_table,
+ &funcs,
+ memory );
+ gx_LookupTable_free ( lookup_table, memory );
+ FT_FREE(lookup_table);
+ }
+
+ static FT_Error
+ morx_load_lookup_table ( GX_EntrySubtable entry_subtable,
+ FT_Pointer user )
+ {
+ generic_xstate_table_cb_data data = user;
+ FT_Error error = GX_Err_Ok;
+ FT_Stream stream = data->stream;
+ GX_XMetamorphosisContextualSubstitutionTable substitution_table = data->extra;
+
+ GX_XMetamorphosisContextualPerGlyph per_glyph = entry_subtable->glyphOffsets.xcontextual;
+ FT_UShort markIndex = per_glyph->markIndex;
+ FT_UShort currentIndex = per_glyph->currentIndex;
+
+ GX_LookupTable mark_table = NULL;
+ GX_LookupTable current_table = NULL;
+ FT_ULong pos;
+
+ if ( ( markIndex != GX_MORX_NO_SUBSTITUTION ) &&
+ (! substitution_table->lookupTables[markIndex] ) )
+ {
+ pos = data->base + data->table_offset + (sizeof(mark_table->position) * markIndex);
+ if (( error = gx_morx_load_lookup_table ( data->face, stream, pos, &mark_table )))
+ goto Exit;
+ }
+
+ if ( currentIndex == markIndex )
+ current_table = mark_table;
+ else if (( currentIndex != GX_MORX_NO_SUBSTITUTION ) &&
+ (! substitution_table->lookupTables[currentIndex] ))
+ {
+ pos = data->base + data->table_offset + (sizeof(mark_table->position) * currentIndex);
+ if (( error = gx_morx_load_lookup_table ( data->face, stream, pos, &current_table )))
+ goto Failure;
+ }
+ if ( mark_table )
+ substitution_table->lookupTables[markIndex] = mark_table;
+ if ( current_table )
+ substitution_table->lookupTables[currentIndex] = current_table;
+ Exit:
+ return error;
+ Failure:
+ /* Be care if currentIndex == markIndex */
+ if ( mark_table )
+ {
+ gx_morx_free_lookup_table( stream->memory, mark_table );
+ mark_table = NULL;
+ }
+ return error;
+ }
+
+ static FT_Error
+ gx_morx_load_contextual_substitution_table( GX_Face face,
+ FT_Stream stream,
+ GX_XStateTable state_table,
+ GX_XMetamorphosisContextualSubstitutionTable substitution_table )
+ {
+ FT_Error error;
+ generic_xstate_table_cb_data_rec cb_data = GENERIC_XSTATE_TABLE_CB_DATA_ZERO;
+ FT_Int i;
+ cb_data.base = state_table->header.position;
+ cb_data.table_offset = substitution_table->offset;
+ cb_data.stream = stream;
+ cb_data.face = face;
+ cb_data.extra = substitution_table;
+
+ if (( error = gx_XStateTable_traverse_entries ( state_table,
+ morx_load_lookup_table,
+ &cb_data )))
+ goto Failure;
+ return error;
+ Failure:
+ for ( i = 0; i < substitution_table->nTables; i++ )
+ {
+ gx_morx_free_lookup_table ( stream->memory, substitution_table->lookupTables[i] );
+ substitution_table->lookupTables[i] = NULL;
+ }
+ return error;
+ }
+
+ static FT_Error
+ gx_morx_load_contextual_subtable( GX_Face face,
+ FT_Stream stream,
+ FT_ULong length,
+ GX_XMetamorphosisSubtableBody body )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+ GX_XStateTable state_table;
+ GX_XMetamorphosisContextualBody contextual_body;
+ GX_XStateTable_Entry_Load_FuncsRec funcs = GX_XSTATE_TABLE_ENTRY_LOAD_FUNCS_ZERO;
+ FT_ULong pos;
+ GX_XMetamorphosisContextualSubstitutionTable substitution_table;
+ FT_ULong i;
+
+ funcs.loader = gx_morx_load_contextual_subtable_entry;
+ funcs.finalizer = gx_morx_free_contextual_subtable_entry;
+
+ if ( FT_NEW( contextual_body ) )
+ goto Exit;
+
+ state_table = &contextual_body->state_table;
+ if (( error = gx_face_load_XStateTable( face, stream,
+ state_table,
+ &funcs,
+ NULL ) ))
+ goto Failure;
+
+ substitution_table = &contextual_body->substitutionTable;
+ pos = state_table->header.position + GX_XSTATE_HEADER_ADVANCE;
+ if ( FT_STREAM_SEEK ( pos ) )
+ goto Failure_XStateTable;
+ if ( FT_READ_ULONG ( substitution_table->offset ) )
+ goto Failure_XStateTable;
+
+ substitution_table->nTables = gx_morx_count_lookup_table(face,
+ state_table);
+ if ( FT_NEW_ARRAY ( substitution_table->lookupTables,
+ substitution_table->nTables ) )
+ goto Failure_XStateTable;
+ for ( i = 0; i < substitution_table->nTables; i++ )
+ substitution_table->lookupTables[i] = NULL;
+
+ if (( error = gx_morx_load_contextual_substitution_table( face,
+ stream,
+ state_table,
+ substitution_table ) ))
+ goto Failure_LookupTables;
+ body->contextual = contextual_body;
+ Exit:
+ return error;
+ Failure_LookupTables:
+ FT_FREE( substitution_table->lookupTables );
+ substitution_table->lookupTables = NULL;
+ Failure_XStateTable:
+ gx_XStateTable_free( &contextual_body->state_table,
+ memory,
+ gx_morx_free_contextual_subtable_entry,
+ NULL );
+ Failure:
+ FT_FREE( contextual_body );
+ body->contextual = NULL;
+ return error;
+ }
+
+
+ static FT_Error
+ gx_morx_load_ligature_subtable_entry ( GX_Face face,
+ FT_Stream stream,
+ GX_EntrySubtable entry_subtable,
+ FT_Pointer user )
+ {
+ FT_Error error;
+ FT_UShort per_glyph;
+
+ /* -----------------------------------------------------------------
+ * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
+ * Should I read ushort even if entry_subtable->flags&GX_MORX_LIGATURE_FLAGS_PERFORM_ACTION
+ * is 0?
+ * ----------------------------------------------------------------- */
+ if ( FT_READ_USHORT ( per_glyph ) )
+ goto Exit;
+ entry_subtable->glyphOffsets.ligActionIndex = per_glyph;
+ Exit:
+ return error;
+ }
+
+#if 0
+ static FT_Error
+ morx_max_ligAction_index( GX_EntrySubtable entry_subtable,
+ FT_Pointer user )
+ {
+ FT_Long * max_index = (FT_Long *)user;
+ if ( ( entry_subtable->flags & GX_MORX_LIGATURE_FLAGS_PERFORM_ACTION ) &&
+ (*max_index < entry_subtable->glyphOffsets.ligActionIndex ) )
+ *max_index = (FT_Long)entry_subtable->glyphOffsets.ligActionIndex;
+ return GX_Err_Ok;
+ }
+
+ static FT_UShort
+ gx_morx_count_ligAction_entry(GX_Face face,
+ GX_XMetamorphosisLigatureBody ligature_body)
+ {
+ FT_Long max_index = -1;
+ gx_XStateTable_traverse_entries( &ligature_body->state_table,
+ morx_max_ligAction_index,
+ &max_index );
+
+ return (FT_UShort)(max_index + 1);
+ }
+#endif /* 0 */
+
+ static FT_Error
+ gx_morx_load_ligature_subtable( GX_Face face,
+ FT_Stream stream,
+ FT_ULong length,
+ GX_XMetamorphosisSubtableBody body )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+ GX_XMetamorphosisLigatureBody ligature_body;
+ GX_XStateHeader state_header;
+ GX_XStateTable_Entry_Load_FuncsRec funcs = GX_XSTATE_TABLE_ENTRY_LOAD_FUNCS_ZERO;
+ GX_XMetamorphosisLigatureActionTable ligActionTable;
+ GX_XMetamorphosisComponentTable componentTable;
+ GX_XMetamorphosisLigatureTable ligatureTable;
+ FT_Int i;
+
+ funcs.loader = gx_morx_load_ligature_subtable_entry;
+
+ if ( FT_NEW( ligature_body ) )
+ goto Exit;
+
+ if (( error = gx_face_load_XStateTable( face, stream,
+ &ligature_body->state_table,
+ &funcs,
+ NULL )))
+ goto Failure;
+ state_header = &ligature_body->state_table.header;
+ ligActionTable = &ligature_body->ligActionTable;
+ componentTable = &ligature_body->componentTable;
+ ligatureTable = &ligature_body->ligatureTable;
+ if ( FT_STREAM_SEEK( state_header->position + GX_XSTATE_HEADER_ADVANCE ) ||
+ FT_FRAME_ENTER( sizeof ( ligActionTable->offset )
+ + sizeof ( componentTable->offset )
+ + sizeof ( ligatureTable->offset ) ) )
+ goto Failure_xStateTable;
+ ligActionTable->offset = FT_GET_ULONG();
+ componentTable->offset = FT_GET_ULONG();
+ ligatureTable->offset = FT_GET_ULONG();
+ FT_FRAME_EXIT();
+
+ generic_triple_offset_diff( ligActionTable->offset,
+ componentTable->offset,
+ ligatureTable->offset,
+ length,
+ & ligActionTable->nActions,
+ & componentTable->nComponent,
+ & ligatureTable->nLigature );
+
+ /* Load ligActionTable */
+#if 0
+ ligActionTable->nActions = gx_morx_count_ligAction_entry( face,
+ ligature_body );
+
+#endif /* 0 */
+
+ ligActionTable->body = NULL;
+ if ( FT_NEW_ARRAY( ligActionTable->body, ligActionTable->nActions ) )
+ goto Failure_xStateTable;
+ if ( FT_STREAM_SEEK( state_header->position + ligActionTable->offset ) ||
+ FT_FRAME_ENTER( ligActionTable->nActions * sizeof( ligActionTable->body[0] ) ) )
+ goto Failure_ligActionTable;
+ for ( i = 0; i < ligActionTable->nActions; i++ )
+ ligActionTable->body[i] = FT_GET_ULONG();
+ FT_FRAME_EXIT();
+
+ /* Load componentTable */
+ componentTable->body = NULL;
+ if ( FT_NEW_ARRAY ( componentTable->body, componentTable->nComponent ) )
+ goto Failure_ligActionTable;
+ if ( FT_STREAM_SEEK ( state_header->position + componentTable->offset ) ||
+ FT_FRAME_ENTER ( componentTable->nComponent * sizeof ( componentTable->body[0] ) ) )
+ goto Failure_componentTable;
+ for ( i = 0; i < componentTable->nComponent; i++ )
+ componentTable->body[i] = FT_GET_USHORT();
+ FT_FRAME_EXIT();
+
+ /* Load ligatureTable */
+
+ ligatureTable->body = NULL;
+ if ( FT_NEW_ARRAY ( ligatureTable->body, ligatureTable->nLigature ) )
+ goto Failure_componentTable;
+ if ( FT_STREAM_SEEK ( state_header->position + ligatureTable->offset ) )
+ goto Failure_ligatureTable;
+ if ( FT_FRAME_ENTER ( ligatureTable->nLigature * sizeof ( ligatureTable->body[0] ) ) )
+ {
+ /* NOTE: morx tables of two ttf fonts in /Library/Fonts/ of
+ MacOSX-10.3 may be broken. The length of extended state
+ table is incorrect. The length is larger than the font file
+ size. This is the kluge. 6 may be the size of header of
+ chain subtable. */
+ ligatureTable->nLigature -= 6;
+ if ( FT_FRAME_ENTER ( ligatureTable->nLigature * sizeof ( ligatureTable->body[i] ) ))
+ goto Failure_ligatureTable;
+ }
+ for ( i = 0; i < ligatureTable->nLigature; i++ )
+ ligatureTable->body[i] = FT_GET_USHORT();
+ FT_FRAME_EXIT();
+ body->ligature = ligature_body;
+ Exit:
+ return error;
+ Failure_ligatureTable:
+ FT_FREE ( ligatureTable->body );
+ ligatureTable->body = NULL;
+ Failure_componentTable:
+ FT_FREE (componentTable->body);
+ componentTable->body = NULL;
+ Failure_ligActionTable:
+ FT_FREE (ligActionTable->body);
+ ligActionTable->body = NULL;
+ Failure_xStateTable:
+ gx_XStateTable_free( &ligature_body->state_table, memory, NULL, NULL);
+ Failure:
+ FT_FREE(ligature_body);
+ return error;
+ }
+
+/*
+ * Noncontextual
+ */
+ static FT_Error
+ gx_morx_load_noncontextual_subtable( GX_Face face,
+ FT_Stream stream,
+ FT_ULong length,
+ GX_XMetamorphosisSubtableBody body )
+ {
+ FT_Error error;
+ GX_MetamorphosisSubtableBodyDesc mort_body;
+
+ if (( error = generic_load_noncontextual_subtable ( face,
+ stream,
+ length,
+ &mort_body,
+ TTAG_morx) ))
+ goto Exit;
+ body->noncontextual = mort_body.noncontextual;
+ Exit:
+ return error;
+ }
+
+
+/*
+ * Insertion
+ */
+ static FT_Error
+ gx_morx_load_insertion_subtable_entry( GX_Face face,
+ FT_Stream stream,
+ GX_EntrySubtable entry_subtable,
+ FT_Pointer user )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+ GX_XMetamorphosisInsertionPerGlyph per_glyph;
+ FT_UShort current_count = gx_mask_zero_shift(entry_subtable->flags,
+ GX_MORX_INSERTION_FLAGS_CURRENT_INSERT_COUNT);
+ FT_UShort marked_count = gx_mask_zero_shift(entry_subtable->flags,
+ GX_MORX_INSERTION_FLAGS_MARKED_INSERT_COUNT);
+ GX_XMetamorphosisInsertionList currentInsertList;
+ GX_XMetamorphosisInsertionList markedInsertList;
+
+ const FT_Frame_Field insertion_subtable_entry_fields[] =
+ {
+#undef FT_STRUCTURE
+#define FT_STRUCTURE GX_XMetamorphosisInsertionPerGlyphRec
+ FT_FRAME_START ( 4 ),
+ FT_FRAME_USHORT ( currentInsertList.offset ),
+ FT_FRAME_USHORT ( markedInsertList.offset ),
+ FT_FRAME_END
+ };
+
+ /* TODO: Should optimize.
+ Being `offset' GX_MORX_NO_INSERTION means, there is no insertion.
+ But we can know whether the `offset' is GX_MORX_NO_INSERTION or not after
+ reading fields. Some memory area(->glyphcodes) allocated before reading
+ fields are wasted. See also `morx_load_insertion_glyphcodes'. */
+ if ( FT_ALLOC ( per_glyph,
+ sizeof(per_glyph) +
+ current_count * sizeof(currentInsertList->glyphcodes[0]) +
+ marked_count * sizeof(markedInsertList->glyphcodes[0])) )
+ goto Exit;
+
+ currentInsertList = &per_glyph->currentInsertList;
+ markedInsertList = &per_glyph->markedInsertList;
+ currentInsertList->glyphcodes = (FT_UShort *)(((char *)per_glyph) + sizeof(per_glyph));
+ markedInsertList->glyphcodes = currentInsertList->glyphcodes + current_count;
+
+ if ( FT_STREAM_READ_FIELDS ( insertion_subtable_entry_fields,
+ per_glyph ) )
+ goto Failure;
+
+ entry_subtable->glyphOffsets.insertion = per_glyph;
+ Exit:
+ return error;
+ Failure:
+ FT_FREE( per_glyph );
+ entry_subtable->glyphOffsets.insertion = NULL;
+ return error;
+ }
+
+ static void
+ gx_morx_free_insertion_subtable_entry( FT_Memory memory,
+ GX_EntrySubtable entry_subtable,
+ FT_Pointer user )
+ {
+ entry_subtable->glyphOffsets.insertion->currentInsertList.glyphcodes = NULL;
+ entry_subtable->glyphOffsets.insertion->markedInsertList.glyphcodes = NULL;
+ FT_FREE( entry_subtable->glyphOffsets.insertion );
+ entry_subtable->glyphOffsets.insertion = NULL;
+ }
+
+ static FT_Error
+ morx_load_insertion_glyphcodes( GX_EntrySubtable entry_subtable,
+ FT_Pointer user )
+ {
+ FT_Error error;
+ generic_xstate_table_cb_data data = user;
+ FT_Stream stream = data->stream;
+ FT_ULong pos = data->base + data->table_offset;
+ GX_XMetamorphosisInsertionPerGlyph per_glyph = entry_subtable->glyphOffsets.insertion;
+ GX_XMetamorphosisInsertionList currentInsertList = &per_glyph->currentInsertList;
+ GX_XMetamorphosisInsertionList markedInsertList = &per_glyph->markedInsertList;
+ FT_UShort current_count = gx_mask_zero_shift(entry_subtable->flags,
+ GX_MORX_INSERTION_FLAGS_CURRENT_INSERT_COUNT);
+ FT_UShort marked_count = gx_mask_zero_shift(entry_subtable->flags,
+ GX_MORX_INSERTION_FLAGS_MARKED_INSERT_COUNT);
+ FT_Int i;
+
+ /* Dirty hack here. See */
+ if ( per_glyph->currentInsertList.offset == GX_MORX_NO_INSERTION )
+ current_count = 0;
+ if ( per_glyph->markedInsertList.offset == GX_MORX_NO_INSERTION )
+ marked_count = 0;
+
+ if ( FT_STREAM_SEEK( pos + currentInsertList->offset ) )
+ return error;
+ for ( i = 0; i < current_count; i++ )
+ {
+ if ( FT_READ_USHORT ( currentInsertList->glyphcodes[i] ) )
+ return error;
+ }
+
+ if ( FT_STREAM_SEEK( pos + markedInsertList->offset ) )
+ return error;
+ for ( i = 0; i < marked_count; i++ )
+ {
+ if ( FT_READ_USHORT ( markedInsertList->glyphcodes[i] ) )
+ return error;
+ }
+ return error;
+ }
+
+ static FT_Error
+ gx_morx_load_insertion_subtable( GX_Face face,
+ FT_Stream stream,
+ FT_ULong length,
+ GX_XMetamorphosisSubtableBody body )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+ GX_XMetamorphosisInsertionBody insertion_body;
+ GX_XStateTable state_table;
+ GX_XStateHeader state_header;
+ GX_XStateTable_Entry_Load_FuncsRec funcs;
+ generic_xstate_table_cb_data_rec traverse_data = GENERIC_XSTATE_TABLE_CB_DATA_ZERO;
+
+ funcs.loader = gx_morx_load_insertion_subtable_entry;
+ funcs.finalizer = gx_morx_free_insertion_subtable_entry;
+
+ if ( FT_NEW( insertion_body ) )
+ goto Exit;
+
+ state_table = &insertion_body->state_table;
+ state_header = &(state_table->header);
+ if (( error = gx_face_load_XStateTable( face, stream,
+ state_table,
+ &funcs,
+ NULL ) ))
+ goto Failure;
+ if ( FT_STREAM_SEEK( state_header->position + GX_XSTATE_HEADER_ADVANCE ) ||
+ FT_READ_ULONG( insertion_body->insertion_glyph_table ) )
+ goto Failure;
+
+ traverse_data.base = state_table->header.position;
+ traverse_data.table_offset = insertion_body->insertion_glyph_table;
+ traverse_data.stream = stream;
+ traverse_data.face = face;
+ traverse_data.extra = NULL;
+ if (( error = gx_XStateTable_traverse_entries ( state_table,
+ morx_load_insertion_glyphcodes,
+ &traverse_data ) ))
+ goto Failure_XStateTable;
+ body->insertion = insertion_body;
+ Exit:
+ return error;
+ Failure_XStateTable:
+ gx_XStateTable_free( &insertion_body->state_table,
+ memory,
+ gx_morx_free_insertion_subtable_entry,
+ NULL );
+ Failure:
+ FT_FREE(insertion_body);
+ body->insertion = NULL;
+ return error;
+ }
+
+ static FT_Error
+ gx_morx_load_subtable_header( GX_Face face,
+ FT_Stream stream,
+ GX_XMetamorphosisSubtableHeader header )
+ {
+ FT_Error error;
+ const FT_Frame_Field morx_subtable_header_fileds[] =
+ {
+#undef FT_STRUCTURE
+#define FT_STRUCTURE GX_XMetamorphosisSubtableHeaderRec
+ FT_FRAME_START ( 12 ),
+ FT_FRAME_ULONG ( length ),
+ FT_FRAME_ULONG ( coverage ),
+ FT_FRAME_ULONG ( subFeatureFlags ),
+ FT_FRAME_END
+ };
+ header->position = FT_STREAM_POS();
+ return FT_STREAM_READ_FIELDS( morx_subtable_header_fileds, header );
+ }
+
+ static FT_Error
+ gx_morx_load_subtable( GX_Face face,
+ FT_Stream stream,
+ FT_ULong pos,
+ GX_XMetamorphosisSubtable chain_Subtbl )
+ {
+ FT_Error error;
+ GX_XMetamorphosisSubtableHeader header;
+ FT_UShort header_size = sizeof(header->length)
+ + sizeof(header->coverage)
+ + sizeof(header->subFeatureFlags);
+ FT_ULong subtable_type;
+ gx_morx_subtable_loader loader;
+
+ if ( FT_STREAM_SEEK ( pos ) )
+ goto Exit;
+
+ header = &chain_Subtbl->header;
+ if (( error = gx_morx_load_subtable_header ( face,
+ stream,
+ header )))
+ goto Exit;
+ subtable_type = header->coverage & GX_MORX_COVERAGE_SUBTABLE_TYPE;
+ FT_TRACE2(( " morx subtable format %d\n", subtable_type ));
+ switch ( subtable_type )
+ {
+ case GX_MORX_REARRANGEMENT_SUBTABLE: /* XStHeader, newState */
+ loader = gx_morx_load_rearrangement_subtable;
+ break;
+ case GX_MORX_CONTEXTUAL_SUBTABLE: /* StHeader++, newState++ */
+ loader = gx_morx_load_contextual_subtable;
+ break;
+ case GX_MORX_LIGATURE_SUBTABLE: /* StHeader++,, newState */
+ loader = gx_morx_load_ligature_subtable;
+ break;
+ case GX_MORX_NONCONTEXTUAL_SUBTABLE: /* Lookup table */
+ loader = gx_morx_load_noncontextual_subtable;
+ break;
+ case GX_MORX_INSERTION_SUBTABLE: /* StHeader, newState++ */
+ loader = gx_morx_load_insertion_subtable;
+ break;
+ default:
+ loader = NULL;
+ break;
+ }
+ chain_Subtbl->body.any = NULL;
+ if ( !loader )
+ {
+ error = GX_Err_Invalid_File_Format;
+ goto Exit;
+ }
+ error = (*loader)(face, stream, header->length - header_size, &chain_Subtbl->body);
+ Exit:
+ return error;
+ }
+
+ static FT_Error
+ gx_morx_load_chain( GX_Face face,
+ FT_Stream stream,
+ FT_ULong pos,
+ GX_XMetamorphosisChain chain )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+ GX_XMetamorphosisChainHeader header;
+ GX_XMetamorphosisFeatureTable feat_Subtbl = NULL;
+ GX_XMetamorphosisSubtable chain_Subtbl = NULL;
+ FT_ULong subtbl_start;
+ FT_Int i, j;
+
+ header = &(chain->header);
+ if ( FT_STREAM_SEEK ( pos ) )
+ goto Exit;
+ if ( ( error = gx_morx_load_chain_header( face, stream, header ) ) )
+ goto Exit;
+ if ( FT_NEW_ARRAY ( feat_Subtbl, header->nFeatureEntries ) )
+ goto Exit;
+
+ for ( i = 0; i < header->nFeatureEntries; i++ )
+ {
+ if (( error = gx_morx_load_feature_table ( face, stream,
+ &feat_Subtbl[i] ) ))
+ goto Failure;
+ }
+
+ subtbl_start = FT_STREAM_POS();
+ if ( FT_NEW_ARRAY ( chain_Subtbl, header->nSubtables ) )
+ goto Failure;
+ for ( i = 0; i < header->nSubtables; i++ )
+ {
+ if (( error = gx_morx_load_subtable( face, stream, subtbl_start,
+ &chain_Subtbl[i]) ))
+ {
+ for ( j = i - 1; j >= 0; j-- )
+ gx_morx_free_subtable( memory, &chain_Subtbl[j] );
+ goto Failure;
+ }
+ subtbl_start += chain_Subtbl[i].header.length;
+ }
+ chain->feat_Subtbl = feat_Subtbl;
+ chain->chain_Subtbl = chain_Subtbl;
+ Exit:
+ return error;
+ Failure:
+ chain->feat_Subtbl = NULL;
+ chain->chain_Subtbl = NULL;
+ if ( feat_Subtbl )
+ FT_FREE ( feat_Subtbl );
+ if ( chain_Subtbl )
+ FT_FREE ( chain_Subtbl );
+ return error;
+ }
+
+ FT_LOCAL_DEF( FT_Error )
+ gx_face_load_morx( GX_Face face,
+ FT_Stream stream,
+ GX_Morx morx )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+ GX_XMetamorphosisChain chain;
+
+ FT_ULong chain_start_pos;
+ const FT_Frame_Field morx_fields[] =
+ {
+#undef FT_STRUCTURE
+#define FT_STRUCTURE GX_MorxRec
+ FT_FRAME_START ( 8 ),
+ FT_FRAME_LONG ( version ),
+ FT_FRAME_ULONG ( nChains ),
+ FT_FRAME_END
+ };
+ FT_ULong i, j;
+
+ /* FT_TRACE2(( "MetamorphosisX Table" )); */
+ if (( error = gx_table_init( &(morx->root), face, TTAG_morx, stream,
+ (GX_Table_Done_Func)gx_morx_done) ))
+ goto Exit;
+
+ morx->chain = NULL;
+
+ if ( FT_STREAM_READ_FIELDS( morx_fields, morx ) )
+ goto Exit;
+
+ if ( FT_NEW_ARRAY( chain, morx->nChains ) )
+ goto Exit;
+
+ chain_start_pos = FT_STREAM_POS();
+ for ( i = 0; i < morx->nChains; i++ )
+ {
+ if (( error = gx_morx_load_chain( face,
+ stream,
+ chain_start_pos,
+ &chain[i] ) ))
+ {
+ /* Rewind to free the resources */
+ for ( j = i ; j > 0; j-- )
+ gx_morx_free_chain ( memory, &chain[j - 1] );
+ goto Failure;
+ }
+ chain_start_pos += chain[i].header.chainLength;
+ }
+ morx->chain = chain;
+ Exit:
+ return error;
+ Failure:
+ FT_FREE( chain );
+ return error;
+ }
+
+ static void
+ gx_morx_free_rearrangement_subtable ( FT_Memory memory, GX_XMetamorphosisSubtableBody body )
+ {
+ GX_XMetamorphosisRearrangementBody rearrangement_body = body->rearrangement;
+ gx_XStateTable_free( &rearrangement_body->state_table, memory, NULL, NULL );
+ FT_FREE(rearrangement_body);
+ body->rearrangement = NULL;
+ }
+
+ static void
+ gx_morx_free_contextual_substitution_table ( FT_Memory memory, GX_XMetamorphosisContextualSubstitutionTable substitution_table )
+ {
+ FT_Int i;
+
+ for ( i = substitution_table->nTables; i > 0; i-- )
+ {
+ if ( !substitution_table->lookupTables[i - 1] )
+ continue ;
+ else
+ {
+ gx_morx_free_lookup_table ( memory, substitution_table->lookupTables[i - 1] );
+ substitution_table->lookupTables[i - 1] = NULL;
+ }
+ }
+ }
+
+ static void
+ gx_morx_free_contextual_subtable ( FT_Memory memory, GX_XMetamorphosisSubtableBody body )
+ {
+ GX_XMetamorphosisContextualBody contextual_body = body->contextual;
+ GX_XMetamorphosisContextualSubstitutionTable substitutionTable = &contextual_body->substitutionTable;
+ GX_LookupTable * lookup_tables = substitutionTable->lookupTables;
+ gx_morx_free_contextual_substitution_table ( memory,
+ substitutionTable );
+ substitutionTable->lookupTables = NULL;
+ FT_FREE( lookup_tables );
+ gx_XStateTable_free( &contextual_body->state_table,
+ memory,
+ gx_morx_free_contextual_subtable_entry,
+ NULL );
+ FT_FREE( contextual_body );
+ body->contextual = NULL;
+ }
+
+ static void
+ gx_morx_free_ligature_subtable ( FT_Memory memory, GX_XMetamorphosisSubtableBody body )
+ {
+ GX_XMetamorphosisLigatureBody ligature_body = body->ligature;
+ GX_XMetamorphosisLigatureActionTable ligActionTable = &ligature_body->ligActionTable;
+ GX_XMetamorphosisComponentTable componentTable = &ligature_body->componentTable;
+ GX_XMetamorphosisLigatureTable ligatureTable = &ligature_body->ligatureTable;
+
+ FT_FREE (ligatureTable->body);
+ ligatureTable->body = NULL;
+ FT_FREE (componentTable->body);
+ componentTable->body = NULL;
+ FT_FREE (ligActionTable->body);
+ ligActionTable->body = NULL;
+ gx_XStateTable_free( &ligature_body->state_table,
+ memory,
+ NULL, /* CHECK, Thu Oct 23 14:14:43 2003 */
+ NULL);
+ FT_FREE( ligature_body );
+ }
+
+ static void
+ gx_morx_free_noncontextual_subtable ( FT_Memory memory, GX_XMetamorphosisSubtableBody body )
+ {
+ GX_XMetamorphosisNoncontextualBody noncontextual_body = body->noncontextual;
+
+ gx_mort_free_noncontextual_subtable ( memory, noncontextual_body );
+ body->noncontextual = NULL;
+ }
+
+ static void
+ gx_morx_free_insertion_subtable ( FT_Memory memory, GX_XMetamorphosisSubtableBody body )
+ {
+ GX_XMetamorphosisInsertionBody insertion_body = body->insertion;
+ GX_XStateTable state_table = &insertion_body->state_table;
+
+ gx_XStateTable_free( state_table,
+ memory,
+ gx_morx_free_insertion_subtable_entry,
+ NULL );
+ FT_FREE(insertion_body);
+ body->insertion = NULL;
+ }
+
+ static void
+ gx_morx_free_subtable( FT_Memory memory, GX_XMetamorphosisSubtable chain_Subtbl )
+ {
+ GX_XMetamorphosisSubtableHeader header;
+ FT_ULong subtable_type;
+
+ header = &chain_Subtbl->header;
+ subtable_type = header->coverage & GX_MORX_COVERAGE_SUBTABLE_TYPE;
+ switch ( subtable_type )
+ {
+ case GX_MORX_REARRANGEMENT_SUBTABLE:
+ gx_morx_free_rearrangement_subtable ( memory, &chain_Subtbl->body );
+ break;
+ case GX_MORX_CONTEXTUAL_SUBTABLE:
+ gx_morx_free_contextual_subtable ( memory, &chain_Subtbl->body );
+ break;
+ case GX_MORX_LIGATURE_SUBTABLE:
+ gx_morx_free_ligature_subtable ( memory, &chain_Subtbl->body );
+ break;
+ case GX_MORX_NONCONTEXTUAL_SUBTABLE:
+ gx_morx_free_noncontextual_subtable ( memory, &chain_Subtbl->body );
+ break;
+ case GX_MORX_INSERTION_SUBTABLE:
+ gx_morx_free_insertion_subtable ( memory, &chain_Subtbl->body );
+ break;
+ default:
+ break;
+ }
+ chain_Subtbl->body.any = NULL;
+ }
+
+ static void
+ gx_morx_free_chain( FT_Memory memory,
+ GX_XMetamorphosisChain chain )
+ {
+ GX_XMetamorphosisChainHeader header;
+ FT_ULong i;
+
+ header = &(chain->header);
+ for ( i = header->nSubtables; i > 0; i-- )
+ gx_morx_free_subtable( memory,
+ &chain->chain_Subtbl[i - 1] );
+ FT_FREE(chain->chain_Subtbl);
+ chain->chain_Subtbl = NULL;
+
+ FT_FREE(chain->feat_Subtbl);
+ chain->feat_Subtbl = NULL;
+ }
+
+ FT_LOCAL_DEF ( void )
+ gx_morx_done( GX_Morx morx,
+ FT_Memory memory )
+
+ {
+ FT_ULong i;
+
+ for ( i = morx->nChains ; i > 0 ; i-- )
+ gx_morx_free_chain( memory, &morx->chain[i - 1] );
+ FT_FREE( morx->chain );
+ morx->chain = NULL;
+ }
+
+
+/******************************FMTX************************************/
+ FT_LOCAL_DEF ( FT_Error )
+ gx_face_load_fmtx( GX_Face face,
+ FT_Stream stream,
+ GX_Fmtx fmtx )
+ {
+ FT_Error error;
+
+ const FT_Frame_Field fmtx_fields[] =
+ {
+#undef FT_STRUCTURE
+#define FT_STRUCTURE GX_FmtxRec
+ FT_FRAME_START ( 16 ),
+ FT_FRAME_LONG ( version ),
+ FT_FRAME_ULONG ( glyphIndex ),
+ FT_FRAME_BYTE ( horizontalBefore ),
+ FT_FRAME_BYTE ( horizontalAfter ),
+ FT_FRAME_BYTE ( horizontalCaretHead ),
+ FT_FRAME_BYTE ( horizontalCaretBase ),
+ FT_FRAME_BYTE ( verticalBefore ),
+ FT_FRAME_BYTE ( verticalAfter ),
+ FT_FRAME_BYTE ( verticalCaretHead ),
+ FT_FRAME_BYTE ( verticalCaretBase ),
+ FT_FRAME_END
+ };
+ /* FT_TRACE2(( "Font Metrics Table" )); */
+ if (( error = gx_table_init( &(fmtx->root), face, TTAG_fmtx, stream,
+ (GX_Table_Done_Func)gx_fmtx_done) ))
+ goto Exit;
+
+ if ( FT_STREAM_READ_FIELDS( fmtx_fields, fmtx ) )
+ goto Exit;
+ Exit:
+ return error;
+ }
+
+ FT_LOCAL_DEF ( void )
+ gx_fmtx_done( GX_Fmtx fmtx,
+ FT_Memory memory )
+
+ {
+ /* DO NOTHING */
+ }
+
+/******************************FDSC************************************/
+ static FT_Error
+ gx_fdsc_load_descriptor( GX_Face face,
+ FT_Stream stream,
+ FT_ULong count,
+ GX_FontDescriptor desc )
+ {
+ FT_Error error = GX_Err_Ok;
+ const FT_Frame_Field fdsc_desc_fields[] =
+ {
+#undef FT_STRUCTURE
+#define FT_STRUCTURE GX_FontDescriptorRec
+ FT_FRAME_START ( 8 ),
+ FT_FRAME_ULONG( tag ),
+ FT_FRAME_LONG ( value ),
+ FT_FRAME_END
+ };
+
+ FT_Int i;
+
+ for ( i = 0; i < count; i++ )
+ {
+ if ( FT_STREAM_READ_FIELDS( fdsc_desc_fields, &desc[i] ) )
+ goto Exit;
+ }
+ Exit:
+ return error;
+ }
+
+ FT_LOCAL_DEF( FT_Error )
+ gx_face_load_fdsc( GX_Face face,
+ FT_Stream stream,
+ GX_Fdsc fdsc )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ GX_FontDescriptor desc;
+
+ const FT_Frame_Field fdsc_fields[] =
+ {
+#undef FT_STRUCTURE
+#define FT_STRUCTURE GX_FdscRec
+ FT_FRAME_START ( 8 ),
+ FT_FRAME_LONG ( version ),
+ FT_FRAME_ULONG ( descriptorCount ),
+ FT_FRAME_END
+ };
+
+ /* FT_TRACE2(( "Font Descriptors Table" )); */
+ if (( error = gx_table_init( &(fdsc->root), face, TTAG_fdsc, stream,
+ (GX_Table_Done_Func)gx_fdsc_done) ))
+ goto Exit;
+
+ if ( FT_STREAM_READ_FIELDS( fdsc_fields, fdsc ) )
+ goto Exit;
+
+ if ( FT_NEW_ARRAY(desc, fdsc->descriptorCount) )
+ goto Exit;
+
+ if (( error = gx_fdsc_load_descriptor(face, stream,
+ fdsc->descriptorCount, desc )))
+ goto Failure;
+
+ fdsc->descriptor = desc;
+ Exit:
+ return error;
+ Failure:
+ FT_FREE(desc);
+ return error;
+ }
+
+ FT_LOCAL_DEF( void )
+ gx_fdsc_done( GX_Fdsc fdsc,
+ FT_Memory memory )
+
+ {
+ if ( fdsc->descriptorCount )
+ {
+ FT_FREE( fdsc->descriptor );
+ fdsc->descriptor = NULL;
+ }
+
+ }
+
+
+
+/****************************JUST***********************************/
+ FT_LOCAL_DEF ( FT_Error )
+ gx_face_load_just( GX_Face face,
+ FT_Stream stream,
+ GX_Just just )
+ {
+ FT_Error error;
+
+ const FT_Frame_Field just_fields[] =
+ {
+#undef FT_STRUCTURE
+#define FT_STRUCTURE GX_JustRec
+ FT_FRAME_START( 10 ),
+ FT_FRAME_ULONG( version ),
+ FT_FRAME_USHORT ( format ),
+ FT_FRAME_USHORT ( horizOffset ),
+ FT_FRAME_USHORT ( vertOffset ),
+ FT_FRAME_END
+ };
+
+ /* FT_TRACE2(( "Justification " )); */
+ if (( error = gx_table_init( &(just->root), face, TTAG_just, stream,
+ (GX_Table_Done_Func)gx_just_done) ))
+ goto Exit;
+
+ if ( FT_STREAM_READ_FIELDS( just_fields, just ) )
+ goto Exit;
+ /* TODO: just */
+ /* FT_TRACE2(( "loaded\n" )); */
+ Exit:
+ return error;
+ }
+
+ FT_LOCAL_DEF ( void )
+ gx_just_done( GX_Just just,
+ FT_Memory memory )
+
+ {
+ /* TODO */
+ }
+
+
+/****************************KERN***********************************/
+
+ static FT_Error
+ gx_kern_load_sutable_header ( GX_Face face,
+ FT_Stream stream,
+ GX_KerningSubtableHeader header )
+ {
+ FT_Error error;
+
+ const FT_Frame_Field kern_subtable_header_fields[] =
+ {
+#undef FT_STRUCTURE
+#define FT_STRUCTURE GX_KerningSubtableHeaderRec
+ FT_FRAME_START( 8 ),
+ FT_FRAME_ULONG( length ),
+ FT_FRAME_USHORT( coverage ),
+ FT_FRAME_USHORT( tupleIndex ),
+ FT_FRAME_END
+ };
+
+ header->position = FT_STREAM_POS();
+ if ( FT_STREAM_READ_FIELDS( kern_subtable_header_fields,
+ header ) )
+ goto Exit;
+ Exit:
+ return error;
+ }
+
+ static FT_Error
+ gx_kern_load_fmt0_subtable ( GX_Face face, FT_Stream stream,
+ GX_KerningSubtableHeader header,
+ GX_KerningSubtableFormat0Body fmt0 )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+ GX_KerningSubtableFormat0Entry entries;
+ FT_Int i;
+
+ const FT_Frame_Field kern_fmt0_subtable_fields [] =
+ {
+#undef FT_STRUCTURE
+#define FT_STRUCTURE GX_KerningSubtableFormat0BodyRec
+ FT_FRAME_START ( 8 ),
+ FT_FRAME_USHORT ( nPairs ),
+ FT_FRAME_USHORT ( searchRange ),
+ FT_FRAME_USHORT ( entrySelector ),
+ FT_FRAME_USHORT ( rangeShift ),
+ FT_FRAME_END
+ };
+
+ const FT_Frame_Field kern_fmt0_entry_fields [] =
+ {
+#undef FT_STRUCTURE
+#define FT_STRUCTURE GX_KerningSubtableFormat0EntryRec
+ FT_FRAME_START ( 6 ),
+ FT_FRAME_USHORT( left ),
+ FT_FRAME_USHORT( right ),
+ FT_FRAME_SHORT ( value ),
+ FT_FRAME_END
+ };
+
+ if ( FT_STREAM_READ_FIELDS( kern_fmt0_subtable_fields,
+ fmt0 ) )
+ goto Exit;
+
+ if ( FT_NEW_ARRAY ( entries, fmt0->nPairs ) )
+ goto Exit;
+ for ( i = 0; i < fmt0->nPairs; i++ )
+ {
+ if ( FT_STREAM_READ_FIELDS( kern_fmt0_entry_fields,
+ &entries[i] ) )
+ goto Failure;
+ }
+ fmt0->entries = entries;
+ Exit:
+ return error;
+ Failure:
+ FT_FREE( entries );
+ fmt0->entries = NULL;
+ return error;
+ }
+
+ static void
+ gx_kern_free_fmt0_subtable( FT_Memory memory, GX_KerningSubtableFormat0Body fmt0 )
+ {
+ FT_FREE ( fmt0->entries );
+ }
+
+
+#if 0
+ static FT_Error
+ kern_max_value_offset( GX_EntrySubtable entry_subtable,
+ FT_Pointer user )
+ {
+ FT_UShort * max_value_offset = user;
+ FT_UShort tmp;
+ tmp = entry_subtable->flags & GX_KERN_ACTION_VALUE_OFFSET;
+ if (*max_value_offset < tmp )
+ *max_value_offset = tmp;
+ return FT_Err_Ok;
+ }
+#endif /* 0 */
+
+ static FT_Error
+ gx_kern_load_fmt1_subtable ( GX_Face face, FT_Stream stream,
+ GX_KerningSubtableHeader header,
+ GX_KerningSubtableFormat1Body fmt1 )
+ {
+ FT_Error error;
+ FT_Memory memory = face->root.driver->root.memory;
+ FT_ULong state_table_pos;
+ FT_ULong value_table_length; /* in bytes */
+ FT_ULong i;
+
+ fmt1->values = NULL;
+ state_table_pos = FT_STREAM_POS();
+ if (( error = gx_face_load_StateTable ( face, stream,
+ &fmt1->state_table,
+ NULL, NULL )))
+ goto Exit;
+
+ if ( FT_STREAM_SEEK( state_table_pos + GX_STATE_HEADER_ADVANCE ) )
+ goto Failure;
+ if ( FT_READ_USHORT ( fmt1->valueTable ) )
+ goto Failure;
+
+#if 0
+ FT_UShort max_value_offset;
+ max_value = 0;
+ gx_StateTable_traverse_entries ( &fmt1->state_table,
+ kern_max_value_offset,
+ &max_value_offset );
+#endif /* 0 */
+ fmt1->value_absolute_pos = fmt1->valueTable + state_table_pos;
+ value_table_length = header->length + header->position;
+ fmt1->nValues = value_table_length / sizeof (*(fmt1->values));
+ value_table_length = fmt1->nValues * sizeof (*(fmt1->values)); /* rounding */
+
+ if ( FT_NEW_ARRAY ( fmt1->values, fmt1->nValues ) )
+ goto Failure;
+ if ( FT_FRAME_ENTER( value_table_length ) )
+ goto Failure;
+
+ for ( i = 0; i < fmt1->nValues; i++ )
+ fmt1->values[i] = FT_GET_USHORT();
+ FT_FRAME_EXIT();
+ Exit:
+ return error;
+ Failure:
+ if ( fmt1->values )
+ FT_FREE ( fmt1->values );
+ gx_StateTable_free ( &fmt1->state_table, memory, NULL, NULL);
+ return error;
+ }
+
+ static void
+ gx_kern_free_fmt1_subtable( FT_Memory memory, GX_KerningSubtableFormat1Body fmt1 )
+ {
+ FT_FREE ( fmt1->values );
+ gx_StateTable_free ( &fmt1->state_table, memory, NULL, NULL);
+ }
+
+ static FT_Error
+ gx_kern_load_fmt2_class_table ( GX_Face face, FT_Stream stream,
+ FT_ULong pos, GX_KerningSubtableFormat2ClassTable class_table)
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+ FT_Int i;
+
+ const FT_Frame_Field kern_fmt2_class_table_fields[] =
+ {
+#undef FT_STRUCTURE
+#define FT_STRUCTURE GX_KerningSubtableFormat2ClassTableRec
+ FT_FRAME_START ( 4 ),
+ FT_FRAME_USHORT ( firstGlyph ),
+ FT_FRAME_USHORT ( nGlyphs ),
+ FT_FRAME_END
+ };
+
+ if ( FT_STREAM_SEEK ( pos ) )
+ goto Exit;
+
+ if ( FT_STREAM_READ_FIELDS( kern_fmt2_class_table_fields,
+ class_table ) )
+ goto Exit;
+
+ if ( FT_NEW_ARRAY( class_table->classes, class_table->nGlyphs ) )
+ goto Exit;
+
+ class_table->max_class = 0;
+ if ( FT_FRAME_ENTER( class_table->classes[0] * class_table->nGlyphs ) )
+ goto Failure_classes;
+ for ( i = 0; i < class_table->nGlyphs; i++ )
+ {
+ class_table->classes[i] = FT_GET_BYTE();
+ if ( class_table->max_class < class_table->classes[i] )
+ class_table->max_class = class_table->classes[i];
+ }
+ FT_FRAME_EXIT();
+ Exit:
+ return error;
+ Failure_classes:
+ FT_FREE( class_table->classes );
+ return error;
+ }
+
+ static void
+ gx_kern_free_fmt2_class_table ( FT_Memory memory, GX_KerningSubtableFormat2ClassTable class_table)
+ {
+ FT_FREE(class_table->classes);
+ }
+
+ static FT_Error
+ gx_kern_load_fmt2_subtable ( GX_Face face, FT_Stream stream,
+ GX_KerningSubtableHeader header,
+ GX_KerningSubtableFormat2Body fmt2 )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+ FT_ULong pos;
+ FT_Int i;
+ FT_Int max_value_index;
+ const FT_Frame_Field kern_fmt2_subtable_fields [] =
+ {
+#undef FT_STRUCTURE
+#define FT_STRUCTURE GX_KerningSubtableFormat2BodyRec
+ FT_FRAME_START( 8 ),
+ FT_FRAME_USHORT ( rowWidth ),
+ FT_FRAME_USHORT ( leftClassTable ),
+ FT_FRAME_USHORT ( rightClassTable ),
+ FT_FRAME_USHORT ( array ),
+ FT_FRAME_END
+ };
+
+
+ fmt2->leftClass.classes = NULL;
+ fmt2->rightClass.classes = NULL;
+ fmt2->values = NULL;
+
+ if ( FT_STREAM_READ_FIELDS( kern_fmt2_subtable_fields,
+ fmt2 ) )
+ goto Exit;
+
+ pos = header->position + fmt2->leftClassTable;
+ if ( ( error = gx_kern_load_fmt2_class_table ( face, stream,
+ pos, & fmt2->leftClass ) ) )
+ goto Exit;
+
+ pos = header->position + fmt2->rightClassTable;
+ if ( ( error = gx_kern_load_fmt2_class_table ( face, stream,
+ pos, & fmt2->rightClass ) ) )
+ goto Failure_leftClass;
+
+ pos = header->position + fmt2->array;
+ if ( FT_STREAM_SEEK( pos ) )
+ goto Failure_rightClass;
+ max_value_index = fmt2->leftClass.max_class + fmt2->rightClass.max_class;
+ if ( FT_NEW_ARRAY ( fmt2->values, max_value_index ) )
+ goto Failure_rightClass;
+ if ( FT_FRAME_ENTER( sizeof( *fmt2->values ) * max_value_index ) )
+ goto Failure_values;
+ for ( i = 0; i < max_value_index; i++ )
+ fmt2->values[i] = FT_GET_SHORT();
+ FT_FRAME_EXIT();
+ Exit:
+ return error;
+ Failure_values:
+ FT_FREE(fmt2->values);
+ Failure_rightClass:
+ gx_kern_free_fmt2_class_table( memory, & fmt2->rightClass );
+ Failure_leftClass:
+ gx_kern_free_fmt2_class_table( memory, & fmt2->leftClass );
+ return error;
+ }
+
+ static void
+ gx_kern_free_fmt2_subtable( FT_Memory memory, GX_KerningSubtableFormat2Body fmt2 )
+ {
+ FT_FREE(fmt2->values);
+ gx_kern_free_fmt2_class_table( memory, & fmt2->rightClass );
+ gx_kern_free_fmt2_class_table( memory, & fmt2->leftClass );
+ }
+
+ static FT_Error
+ gx_kern_load_fmt3_subtable ( GX_Face face, FT_Stream stream,
+ GX_KerningSubtableHeader header,
+ GX_KerningSubtableFormat3Body fmt3 )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+ FT_Int i;
+ FT_FWord * kernValue; /* [kernValueCount] */
+ FT_Byte * leftClass; /* [glyphCount] */
+ FT_Byte * rightClass; /* [glyphCount] */
+ FT_Byte * kernIndex; /* [leftClassCount * rightClassCount] */
+ FT_ULong byte_count;
+ const FT_Frame_Field kern_fmt3_subtable_fields [] =
+ {
+#undef FT_STRUCTURE
+#define FT_STRUCTURE GX_KerningSubtableFormat3BodyRec
+ FT_FRAME_START ( 6 ),
+ FT_FRAME_USHORT (glyphCount),
+ FT_FRAME_BYTE (kernValueCount),
+ FT_FRAME_BYTE (leftClassCount),
+ FT_FRAME_BYTE (rightClassCount),
+ FT_FRAME_BYTE (flags),
+ FT_FRAME_END
+ };
+
+ if ( FT_STREAM_READ_FIELDS( kern_fmt3_subtable_fields,
+ fmt3 ) )
+ goto Exit;
+
+ byte_count = sizeof(kernValue[0]) * fmt3->kernValueCount
+ + sizeof(FT_Byte) * (fmt3->glyphCount
+ + fmt3->glyphCount
+ + (fmt3->leftClassCount
+ * fmt3->rightClassCount));
+ if ( FT_ALLOC ( kernValue , byte_count ) )
+ goto Exit;
+
+ leftClass = (FT_Byte *)(kernValue + fmt3->kernValueCount);
+ rightClass = leftClass+fmt3->glyphCount;
+ kernIndex = rightClass+fmt3->glyphCount;
+
+ if ( FT_FRAME_ENTER( byte_count ) )
+ goto Failure;
+ for ( i = 0; i < fmt3->kernValueCount; i++ )
+ kernValue[i] = FT_GET_SHORT();
+ for ( i = 0; i < fmt3->glyphCount; i++ )
+ leftClass[i] = FT_GET_BYTE();
+ for ( i = 0; i < fmt3->glyphCount; i++ )
+ rightClass[i] = FT_GET_BYTE();
+ for ( i = 0; i < fmt3->leftClassCount * fmt3->rightClassCount; i++ )
+ kernIndex[i] = FT_GET_BYTE();
+ FT_FRAME_EXIT();
+ fmt3->kernValue = kernValue;
+ fmt3->leftClass = leftClass;
+ fmt3->rightClass = rightClass;
+ fmt3->kernIndex = kernIndex;
+ Exit:
+ return error;
+ Failure:
+ FT_FREE( kernValue );
+ fmt3->kernValue = NULL;
+ fmt3->leftClass = NULL;
+ fmt3->rightClass = NULL;
+ fmt3->kernIndex = NULL;
+ return error;
+ }
+
+ static void
+ gx_kern_free_fmt3_subtable( FT_Memory memory, GX_KerningSubtableFormat3Body fmt3 )
+ {
+ FT_FREE ( fmt3->kernValue );
+ fmt3->kernValue = NULL;
+ fmt3->leftClass = NULL;
+ fmt3->rightClass = NULL;
+ fmt3->kernIndex = NULL;
+ }
+
+ static FT_Error
+ gx_kern_load_subtable( GX_Face face,
+ FT_Stream stream,
+ FT_ULong pos,
+ GX_KerningSubtable subtable )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+ GX_KerningFormat format;
+ GX_KerningSubtableHeader header = &subtable->header;
+ GX_KerningSubtableFormat0Body fmt0;
+ GX_KerningSubtableFormat1Body fmt1;
+ GX_KerningSubtableFormat2Body fmt2;
+ GX_KerningSubtableFormat3Body fmt3;
+
+ if ( FT_STREAM_SEEK( pos ) )
+ goto Exit;
+ if (( error = gx_kern_load_sutable_header ( face,
+ stream,
+ header ) ))
+ goto Exit;
+
+#define KERN_FMT_LOAD(fmt) do { \
+ if ( FT_NEW ( fmt ) ) \
+ goto Exit; \
+ if ( ( error = gx_kern_load_##fmt##_subtable ( face, stream, header, fmt ) ) ) \
+ { \
+ FT_FREE(fmt); \
+ goto Exit; \
+ } \
+ subtable->body.fmt = fmt; \
+ } while (0)
+
+ format = header->coverage&GX_KERN_COVERAGE_FORMAT_MASK;
+ switch ( format )
+ {
+ case GX_KERN_FMT_ORDERED_LIST_OF_KERNING_PAIRS:
+ KERN_FMT_LOAD(fmt0);
+ break;
+ case GX_KERN_FMT_STATE_TABLE_FOR_CONTEXTUAL_KERNING:
+ KERN_FMT_LOAD(fmt1);
+ break;
+ case GX_KERN_FMT_SIMPLE_NXM_ARRAY_OF_KERNING_VALUES:
+ KERN_FMT_LOAD(fmt2);
+ break;
+ case GX_KERN_FMT_SIMPLE_NXM_ARRAY_OF_KERNING_INDICES:
+ KERN_FMT_LOAD(fmt3);
+ break;
+ }
+ Exit:
+ return error;
+ }
+
+ static void
+ gx_kern_free_subtable( FT_Memory memory,
+ GX_KerningSubtable subtable )
+ {
+ GX_KerningSubtableHeader header = &subtable->header;
+ GX_KerningFormat format = header->coverage&GX_KERN_COVERAGE_FORMAT_MASK;
+#define KERN_FMT_FREE(fmt) do { \
+ gx_kern_free_##fmt##_subtable( memory, subtable->body.fmt ); \
+ FT_FREE(subtable->body.fmt); \
+ } while (0)
+ switch ( format )
+ {
+ case GX_KERN_FMT_ORDERED_LIST_OF_KERNING_PAIRS:
+ KERN_FMT_FREE(fmt0);
+ break;
+ case GX_KERN_FMT_STATE_TABLE_FOR_CONTEXTUAL_KERNING:
+ KERN_FMT_FREE(fmt1);
+ break;
+ case GX_KERN_FMT_SIMPLE_NXM_ARRAY_OF_KERNING_VALUES:
+ KERN_FMT_FREE(fmt2);
+ break;
+ case GX_KERN_FMT_SIMPLE_NXM_ARRAY_OF_KERNING_INDICES:
+ KERN_FMT_FREE(fmt3);
+ break;
+ }
+ subtable->body.any = NULL;
+ }
+
+ FT_LOCAL_DEF ( FT_Error )
+ gx_face_load_kern( GX_Face face,
+ FT_Stream stream,
+ GX_Kern kern )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+ GX_KerningSubtable subtables;
+ FT_ULong subtable_start_pos;
+ const FT_Frame_Field kern_fields[] =
+ {
+#undef FT_STRUCTURE
+#define FT_STRUCTURE GX_KernRec
+ FT_FRAME_START( 8 ),
+ FT_FRAME_ULONG( version ),
+ FT_FRAME_ULONG ( nTables ),
+ FT_FRAME_END
+ };
+ FT_Int i, j;
+
+ /* FT_TRACE2(( "Kerning " )); */
+ if (( error = gx_table_init( &(kern->root), face, TTAG_kern, stream,
+ (GX_Table_Done_Func)gx_kern_done) ))
+ goto Exit;
+
+ if ( FT_STREAM_READ_FIELDS( kern_fields, kern ) )
+ goto Exit;
+ if ( kern->version < 0x00010000 )
+ {
+ error = GX_Err_Old_Kerning_Table;
+ goto Exit; /* old style kern */
+ }
+
+ if ( FT_NEW_ARRAY( subtables, kern->nTables ) )
+ goto Exit;
+
+ subtable_start_pos = FT_STREAM_POS();
+ for ( i = 0; i < kern->nTables; i++ )
+ {
+ if ( ( error = gx_kern_load_subtable( face,
+ stream,
+ subtable_start_pos,
+ &subtables[i] ) ) )
+ goto Failure;
+ subtable_start_pos += subtables[i].header.length;
+ }
+ kern->subtables = subtables;
+ /* FT_TRACE2(( "loaded\n" )); */
+ Exit:
+ return error;
+ Failure:
+ for ( j = i; j > 0; j-- )
+ gx_kern_free_subtable( memory, &subtables[j - 1] );
+ FT_FREE(subtables);
+ kern->subtables = NULL;
+ return error;
+ }
+
+ FT_LOCAL_DEF ( void )
+ gx_kern_done( GX_Kern kern,
+ FT_Memory memory )
+
+ {
+ FT_Int i;
+
+ for ( i = kern->nTables; i > 0; i-- )
+ gx_kern_free_subtable( memory, &kern->subtables[i - 1] );
+ FT_FREE(kern->subtables);
+ kern->subtables = NULL;
+ }
+
+
+/****************************FVAR***********************************/
+
+ static FT_Error gx_fvar_load_sfnt_instance ( GX_Face face, FT_Stream stream,
+ FT_UShort axis_count,
+ GX_FontVariationsSFNTInstance instance );
+ static void gx_fvar_free_sfnt_instance ( FT_Memory memory,
+ GX_FontVariationsSFNTInstance instance );
+
+ FT_LOCAL ( FT_Error )
+ gx_face_load_fvar ( GX_Face face,
+ FT_Stream stream,
+ GX_Fvar fvar )
+ {
+ FT_Error error;
+ FT_UShort i, j;
+ FT_Memory memory = stream->memory;
+
+ const FT_Frame_Field fvar_fields[] =
+ {
+#undef FT_STRUCTURE
+#define FT_STRUCTURE GX_FvarRec
+ FT_FRAME_START ( 14 ),
+ FT_FRAME_LONG ( version ),
+ FT_FRAME_USHORT ( offsetToData ),
+ FT_FRAME_USHORT ( countSizePairs ),
+ FT_FRAME_USHORT ( axisCount ),
+ FT_FRAME_USHORT ( axisSize ),
+ FT_FRAME_USHORT ( instanceCount ),
+ FT_FRAME_USHORT ( instanceSize ),
+ FT_FRAME_END
+ };
+
+ const FT_Frame_Field fvar_axis_fields[] =
+ {
+#undef FT_STRUCTURE
+#define FT_STRUCTURE GX_FontVariationsSFNTVariationAxisRec
+ FT_FRAME_START ( 20 ),
+ FT_FRAME_ULONG ( axisTag ),
+ FT_FRAME_LONG ( minValue ),
+ FT_FRAME_LONG ( defaultValue ),
+ FT_FRAME_LONG ( maxValue ),
+ FT_FRAME_USHORT( flags ),
+ FT_FRAME_USHORT( nameID ),
+ FT_FRAME_END
+ };
+
+ if (( error = gx_table_init( &(fvar->root), face, TTAG_fvar, stream,
+ (GX_Table_Done_Func)gx_fvar_done) ))
+ goto Failure;
+
+ if ( FT_STREAM_READ_FIELDS( fvar_fields, fvar ) )
+ goto Failure;
+
+ if ( FT_STREAM_SEEK( fvar->root.position + fvar->offsetToData ) )
+ goto Failure;
+
+ if ( FT_NEW_ARRAY( fvar->axis, fvar->axisCount ) )
+ goto Failure;
+
+ if ( FT_NEW_ARRAY( fvar->instance, fvar->instanceCount ) )
+ goto Failure;
+
+ for ( i = 0; i < fvar->axisCount; i++ )
+ {
+ if ( FT_STREAM_READ_FIELDS( fvar_axis_fields, &fvar->axis[i] ) )
+ goto Failure;
+ }
+
+ for ( i = 0; i < fvar->instanceCount; i++ )
+ {
+ if (( error = gx_fvar_load_sfnt_instance( face,
+ stream,
+ fvar->axisCount,
+ &fvar->instance[i]) ))
+ {
+ for ( j = i; j > 0; j-- )
+ gx_fvar_free_sfnt_instance( memory,
+ &fvar->instance[j - 1] );
+ goto Failure;
+ }
+ }
+ return error;
+ Failure:
+ if ( fvar->axis )
+ FT_FREE( fvar->axis );
+ if ( fvar->instanceCount )
+ FT_FREE ( fvar->instance );
+ return error;
+ }
+
+ static FT_Error
+ gx_fvar_load_sfnt_instance ( GX_Face face,
+ FT_Stream stream,
+ FT_UShort axis_count,
+ GX_FontVariationsSFNTInstance instance )
+ {
+ FT_Error error;
+ FT_UShort i;
+ FT_Memory memory = stream->memory;
+
+ const FT_Frame_Field fvar_sfnt_instance_fields[] =
+ {
+#undef FT_STRUCTURE
+#define FT_STRUCTURE GX_FontVariationsSFNTInstanceRec
+ FT_FRAME_START ( 4 ),
+ FT_FRAME_USHORT ( nameID ),
+ FT_FRAME_USHORT ( flags ),
+ FT_FRAME_END,
+ };
+
+ if (( FT_NEW_ARRAY( instance->coord, axis_count ) ))
+ goto Failure;
+
+ if ( FT_STREAM_READ_FIELDS( fvar_sfnt_instance_fields,
+ instance ) )
+ goto Failure;
+
+ if ( FT_FRAME_ENTER ( axis_count * sizeof( FT_Fixed) ) )
+ goto Failure;
+
+ for ( i = 0; i < axis_count; i++ )
+ instance->coord[i] = FT_GET_LONG();
+
+ FT_FRAME_EXIT();
+
+ return error;
+ Failure:
+ if ( instance->coord )
+ FT_FREE( instance->coord );
+ return error;
+ }
+ static void
+ gx_fvar_free_sfnt_instance ( FT_Memory memory,
+ GX_FontVariationsSFNTInstance instance )
+ {
+ FT_FREE( instance->coord );
+ }
+
+ static void
+ gx_fvar_done( GX_Fvar fvar,
+ FT_Memory memory )
+ {
+ FT_UShort i;
+
+ for ( i = fvar->instanceCount; i > 0; i-- )
+ gx_fvar_free_sfnt_instance(memory, &fvar->instance[i - 1] );
+
+ FT_FREE ( fvar->instance );
+ FT_FREE ( fvar->axis );
+ }
+
+
+/****************************GENERIC***********************************/
+ static FT_Error
+ generic_lookup_table_segment_array_loader ( GX_LookupTable_Format format,
+ FT_UShort lastGlyph,
+ FT_UShort firstGlyph,
+ GX_LookupValue value,
+ FT_Pointer user )
+ {
+ FT_Error error;
+ generic_lookup_table_cb_data lookup_data = user;
+ GX_Face face = lookup_data->face;
+ FT_Stream stream = lookup_data->stream;
+ GX_LookupTable lookup_table = lookup_data->lookup_table;
+ FT_Int table_tag = lookup_data->table_tag;
+
+ FT_Memory memory = stream->memory;
+
+ FT_Short value_offset = value->raw.s;
+
+ FT_UShort segment_count = lastGlyph - firstGlyph + 1;
+ FT_UShort * segment;
+
+ FT_Int i;
+
+ if ( table_tag )
+ {
+ if ( (error = face->goto_table( face, table_tag, stream, 0 )) ||
+ FT_STREAM_SEEK( FT_STREAM_POS() + value_offset ) )
+ goto Exit;
+ }
+ else
+ {
+ if (FT_STREAM_SEEK( lookup_table->position + value_offset ) )
+ goto Exit;
+ }
+
+ if ( FT_NEW_ARRAY(segment, segment_count ) )
+ goto Exit;
+
+ if ( FT_FRAME_ENTER ( sizeof( segment[0] ) * segment_count ) )
+ goto Failure;
+ for ( i = 0; i < segment_count; i++ )
+ segment[i] = FT_GET_USHORT();
+ FT_FRAME_EXIT();
+ value->extra.word = segment;
+ Exit:
+ return error;
+ Failure:
+ /* TODO
+ --------------------------------------------------------------
+ Other value->extra.wordS loaded before the visitation to this
+ value->extra.word must be freed if an error is occurred during
+ traverse. */
+ FT_FREE(segment);
+ return error;
+ }
+
+ static FT_Error
+ generic_lookup_table_segment_array_finalizer ( GX_LookupTable_Format format,
+ FT_UShort lastGlyph,
+ FT_UShort firstGlyph,
+ GX_LookupValue value,
+ FT_Pointer user )
+ {
+ FT_Memory memory = user;
+ FT_UShort * segment = value->extra.word;
+ if ( !segment )
+ return GX_Err_Ok;
+
+ value->extra.word = NULL;
+ FT_FREE(segment);
+ return GX_Err_Ok;
+ }
+
+ static FT_Error
+ generic_load_noncontextual_subtable ( GX_Face face,
+ FT_Stream stream,
+ FT_UShort length,
+ GX_MetamorphosisSubtableBody body,
+ FT_Int tag )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+ GX_MetamorphosisNoncontextualBody noncontextual_body;
+ GX_LookupTable lookup_table;
+ GX_LookupTable_FuncsRec funcs = GX_LOOKUP_TABLE_FUNC_ZERO;
+ generic_lookup_table_cb_data_rec user_data = GENERIC_LOOKUP_TABLE_CB_DATA_ZERO;
+
+ funcs.segment_array_func = generic_lookup_table_segment_array_loader;
+ user_data.face = face;
+ user_data.stream = stream;
+ /* -----------------------------------------------------------------
+ * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
+ * This code is correct?
+ * In spec: "Sometimes they are 16-bit offsets from the start of
+ * the table to the data. " The table? Is the table the lookup table
+ * or a table that uses the lookup table?
+ * Here I assume the table is the lookup table.
+ *
+ * The 11th chainSubtable in /Library/Fonts/GujaratiMT.ttf in MacOSX
+ * is format 4 lookup table; and it expects the table is the lookup
+ * table.
+ * It seems that pfaedit uses lookup_table_offset + value_offset.
+ * ----------------------------------------------------------------- */
+ /* user_data.table_tag = tag; */
+ user_data.table_tag = 0;
+
+ if ( FT_NEW ( noncontextual_body ) )
+ goto Exit;
+ lookup_table = &noncontextual_body->lookup_table;
+ user_data.lookup_table = lookup_table;
+ if (( error = gx_face_load_LookupTable( face, stream,
+ lookup_table )))
+ goto Failure;
+
+ if ( lookup_table->format == GX_LOOKUPTABLE_SEGMENT_ARRAY )
+ {
+ if (( error = gx_LookupTable_traverse_low( lookup_table, &funcs, &user_data ) ))
+ goto Failure_Lookup_Table;
+ }
+ body->noncontextual = noncontextual_body;
+ Exit:
+ return error;
+ Failure_Lookup_Table:
+ gx_LookupTable_free( lookup_table, memory );
+ Failure:
+ FT_FREE( noncontextual_body );
+ body->noncontextual = NULL;
+ return error;
+ }
+
+ static void
+ generic_triple_offset_diff ( FT_ULong ligActionTable_offset,
+ FT_ULong componentTable_offset,
+ FT_ULong ligatureTable_offset,
+ FT_ULong length,
+ FT_UShort *ligActionTable_nAction,
+ FT_UShort *componentTable_nComponent,
+ FT_UShort *ligatureTable_nLigature )
+ {
+ if (( ligActionTable_offset < componentTable_offset ) &&
+ ( ligActionTable_offset < ligatureTable_offset ) )
+ { /* 1st: ligActionTable */
+ if ( componentTable_offset < ligatureTable_offset )
+ { /* 2nd: componentTable, 3rd: ligatureTable */
+ /* 2nd - 1st */
+ *ligActionTable_nAction = (componentTable_offset- ligActionTable_offset)/4;
+ *componentTable_nComponent = (ligatureTable_offset - componentTable_offset)/2;
+ *ligatureTable_nLigature = (length - ligatureTable_offset)/2;
+ }
+ else
+ { /* 2nd: ligatureTable, 3rd: componentTable */
+ /* 2nd - 1st */
+ *ligActionTable_nAction = (ligatureTable_offset - ligActionTable_offset)/4;
+ *componentTable_nComponent = (length - componentTable_offset)/2;
+ *ligatureTable_nLigature = (componentTable_offset - ligatureTable_offset)/2;
+ }
+ }
+ else if (( componentTable_offset < ligActionTable_offset) &&
+ ( componentTable_offset < ligatureTable_offset ))
+ { /* 1st: componentTable */
+ if ( ligActionTable_offset < ligatureTable_offset )
+ { /* 2nd: ligActionTable, 3rd: ligatureTable */
+ /* 3rd - 2nd */
+ *ligActionTable_nAction = (ligatureTable_offset - ligActionTable_offset)/4;
+ *componentTable_nComponent = (componentTable_offset - ligActionTable_offset)/2;
+ *ligatureTable_nLigature = (length - ligatureTable_offset)/2;
+ }
+ else
+ { /* 2nd: ligatureTable, 3rd: ligActionTable */
+ /* length - 3rd */
+ *ligActionTable_nAction = (length - ligActionTable_offset)/4;
+ *componentTable_nComponent = (componentTable_offset - ligatureTable_offset)/2;
+ *ligatureTable_nLigature = (ligActionTable_offset - ligatureTable_offset)/2;
+ }
+ }
+ else
+ { /* 1st: ligatureTable */
+ if ( ligActionTable_offset < componentTable_offset )
+ { /* 2nd: ligActionTable, 3rd: componentTable */
+ /* 3rd - 2nd */
+ *ligActionTable_nAction = (componentTable_offset - ligActionTable_offset)/4;
+ *componentTable_nComponent = (length - componentTable_offset)/2;
+ *ligatureTable_nLigature = (ligActionTable_offset - ligatureTable_offset)/2;
+ }
+ else
+ { /* 2nd: componentTable, 3rd: ligActionTable */
+ /* length - 3rd */
+ *ligActionTable_nAction = (length - ligActionTable_offset)/4;
+ *componentTable_nComponent = (ligActionTable_offset - componentTable_offset)/2;
+ *ligatureTable_nLigature = (length - ligatureTable_offset)/2;
+ }
+ }
+
+ }
+
+ static FT_Error
+ gx_table_init(GX_Table table_info,
+ GX_Face face, FT_ULong tag, FT_Stream stream, GX_Table_Done_Func done_table)
+ {
+ FT_Error error;
+ if (( error = face->goto_table( face, tag, stream,
+ &table_info->length) ))
+ return error;
+ table_info->position = FT_STREAM_POS();
+ table_info->font = NULL;
+ table_info->done_table = done_table;
+ return error;
+ }
+
+ FT_LOCAL ( FT_Error )
+ gx_table_done ( GX_Table table, FT_Memory memory )
+ {
+ if ( table && table->done_table)
+ table->done_table( table, memory );
+ return FT_Err_Ok;
+ }
+
+/* END */
diff --git a/src/gxlayout/gxload.h b/src/gxlayout/gxload.h
new file mode 100644
index 000000000..34c1aabaa
--- /dev/null
+++ b/src/gxlayout/gxload.h
@@ -0,0 +1,112 @@
+/***************************************************************************/
+/* */
+/* gxload.h */
+/* */
+/* Functions load AAT/TrueTypeGX tables(specification) */
+/* */
+/* Copyright 2003 by */
+/* Masatake YAMATO and Redhat K.K. */
+/* */
+/* This file may only be used, */
+/* modified, and distributed under the terms of the FreeType project */
+/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
+/* this file you indicate that you have read the license and */
+/* understand and accept it fully. */
+/* */
+/***************************************************************************/
+
+/***************************************************************************/
+/* Development of the code in this file is support of */
+/* Information-technology Promotion Agency, Japan. */
+/***************************************************************************/
+
+#ifndef __GXLOAD_H__
+#define __GXLOAD_H__
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include "gxtypes.h"
+#include "gxltypes.h"
+
+FT_BEGIN_HEADER
+
+#define gx_table_load(face,stream,tag,FONT) \
+ (error = gx_face_load_##tag (face, stream, FONT->tag), \
+ FONT->tag->root.font = (error? NULL: FONT), \
+ FONT->tag->root.done_table = (error? NULL: FONT->tag->root.done_table), \
+ error)
+
+ FT_LOCAL ( FT_Error )
+ gx_table_done ( GX_Table table, FT_Memory memory );
+
+ FT_LOCAL ( FT_Error )
+ gx_face_load_feat( GX_Face face,
+ FT_Stream stream,
+ GX_Feat feat );
+
+ FT_LOCAL ( FT_Error )
+ gx_face_load_trak( GX_Face face,
+ FT_Stream stream,
+ GX_Trak trak );
+
+ FT_LOCAL ( FT_Error )
+ gx_face_load_kern( GX_Face face,
+ FT_Stream stream,
+ GX_Kern kern );
+
+ FT_LOCAL ( FT_Error )
+ gx_face_load_prop( GX_Face face,
+ FT_Stream stream,
+ GX_Prop prop );
+
+ FT_LOCAL ( FT_Error )
+ gx_face_load_opbd( GX_Face face,
+ FT_Stream stream,
+ GX_Opbd opbd );
+
+ FT_LOCAL ( FT_Error )
+ gx_face_load_lcar( GX_Face face,
+ FT_Stream stream,
+ GX_Lcar lcar );
+
+ FT_LOCAL ( FT_Error )
+ gx_face_load_bsln( GX_Face face,
+ FT_Stream stream,
+ GX_Bsln bsln );
+
+ FT_LOCAL ( FT_Error )
+ gx_face_load_mort( GX_Face face,
+ FT_Stream stream,
+ GX_Mort mort );
+
+ FT_LOCAL ( FT_Error )
+ gx_face_load_morx( GX_Face face,
+ FT_Stream stream,
+ GX_Morx morx );
+
+ FT_LOCAL ( FT_Error )
+ gx_face_load_fmtx( GX_Face face,
+ FT_Stream stream,
+ GX_Fmtx fmtx );
+
+ FT_LOCAL ( FT_Error )
+ gx_face_load_fdsc( GX_Face face,
+ FT_Stream stream,
+ GX_Fdsc fdsc );
+
+ FT_LOCAL ( FT_Error )
+ gx_face_load_just( GX_Face face,
+ FT_Stream stream,
+ GX_Just just );
+
+ FT_LOCAL ( FT_Error )
+ gx_face_load_fvar ( GX_Face face,
+ FT_Stream stream,
+ GX_Fvar fvar );
+
+FT_END_HEADER
+
+#endif /* Not def: __GXLOAD_H__ */
+
+
+/* END */
diff --git a/src/gxlayout/gxlookuptbl.c b/src/gxlayout/gxlookuptbl.c
new file mode 100644
index 000000000..20c2128ce
--- /dev/null
+++ b/src/gxlayout/gxlookuptbl.c
@@ -0,0 +1,691 @@
+/***************************************************************************/
+/* */
+/* gxlookuptbl.c */
+/* */
+/* AAT/TrueTypeGX lookup table related types and functions */
+/* (body) */
+/* */
+/* Copyright 2003 by */
+/* Masatake YAMATO and Redhat K.K. */
+/* */
+/* This file may only be used, */
+/* modified, and distributed under the terms of the FreeType project */
+/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
+/* this file you indicate that you have read the license and */
+/* understand and accept it fully. */
+/* */
+/***************************************************************************/
+
+/***************************************************************************/
+/* Development of the code in this file is support of */
+/* Information-technology Promotion Agency, Japan. */
+/***************************************************************************/
+
+#include <ft2build.h>
+#include FT_INTERNAL_STREAM_H
+#include FT_INTERNAL_DEBUG_H
+#include "gxlookuptbl.h"
+#include "gxerrors.h"
+
+ typedef FT_Error (*gx_LookupTable_loader) ( GX_LookupTable lookup_table,
+ FT_Stream stream );
+ typedef void (*gx_LookupTable_finalizer) ( FT_Memory memory,
+ GX_LookupTable lookup_table );
+ typedef FT_Error (*gx_LookupTable_traverser) ( GX_LookupTable lookup_table,
+ GX_LookupTable_Funcs funcs,
+ FT_Pointer user );
+
+ static FT_Error
+ gx_load_BinSrchHeader( FT_Stream stream,
+ GX_BinSrchHeader header )
+ {
+ FT_Error error;
+ const FT_Frame_Field fields[] =
+ {
+#undef FT_STRUCTURE
+#define FT_STRUCTURE GX_BinSrchHeaderRec
+ FT_FRAME_START( 10 ),
+ FT_FRAME_USHORT (unitSize),
+ FT_FRAME_USHORT (nUnits),
+ FT_FRAME_USHORT (searchRange),
+ FT_FRAME_USHORT (entrySelector),
+ FT_FRAME_USHORT (rangeShift),
+ FT_FRAME_END
+ };
+
+ FT_STREAM_READ_FIELDS( fields, header );
+ return error;
+ }
+
+ static FT_Error
+ gx_LookupTable_load_raw_values ( FT_Stream stream,
+ FT_Long value_count,
+ GX_LookupValue value_slot )
+ {
+ FT_Error error;
+ FT_Long i;
+
+ for ( i = 0; i < value_count; i++)
+ {
+ value_slot[i].extra.any = NULL;
+ error = FT_READ_SHORT(value_slot[i].raw.s);
+ if ( error )
+ return error;
+ }
+ return error;
+ }
+
+ static FT_Error
+ gx_LookupTable_load_segment_generic( GX_LookupTable lookup_table,
+ FT_Stream stream )
+
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+ GX_LookupTable_Segment segment_table = lookup_table->fsHeader.segment_generic;
+ GX_BinSrchHeaderRec binSrchHeader = segment_table->binSrchHeader;
+ GX_LookupSegment segment;
+ FT_Long i;
+
+ if ( FT_NEW_ARRAY( segment, binSrchHeader.nUnits ) )
+ return error;
+
+ for ( i = 0; i < binSrchHeader.nUnits; i++ )
+ {
+ error = FT_READ_USHORT(segment[i].lastGlyph);
+ if ( error )
+ goto Failure;
+
+ error = FT_READ_USHORT(segment[i].firstGlyph);
+ if ( error )
+ goto Failure;
+
+ error = gx_LookupTable_load_raw_values(stream, 1, &(segment[i].value));
+ if ( error )
+ goto Failure;
+ }
+ segment_table->segments = segment;
+ return error;
+ Failure:
+ FT_FREE(segment);
+ return error;
+ }
+
+ static void
+ gx_LookupTable_free_segment_generic( FT_Memory memory,
+ GX_LookupTable lookup_table )
+ {
+ GX_LookupTable_Segment segment_table = lookup_table->fsHeader.segment_generic;
+ FT_FREE(segment_table->segments);
+ segment_table->segments = NULL;
+ }
+
+
+ static FT_Error
+ gx_LookupTable_load_single_table( GX_LookupTable lookup_table,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+ GX_LookupTable_Single_Table single_table = lookup_table->fsHeader.single_table;
+ GX_BinSrchHeaderRec binSrchHeader = single_table->binSrchHeader;
+ GX_LookupSingle single;
+ FT_Long i;
+
+ if ( FT_NEW_ARRAY( single, binSrchHeader.nUnits ) )
+ return error;
+
+ for ( i = 0; i < binSrchHeader.nUnits; i++ )
+ {
+ error = FT_READ_USHORT(single[i].glyph);
+ if ( error )
+ goto Failure;
+
+ gx_LookupTable_load_raw_values(stream, 1, &(single[i].value));
+ if ( error )
+ goto Failure;
+ }
+ single_table->entries = single;
+
+ return error;
+ Failure:
+ FT_FREE(single);
+ single_table->entries = NULL;
+ return error;
+ }
+
+ static void
+ gx_LookupTable_free_single_table( FT_Memory memory,
+ GX_LookupTable lookup_table )
+ {
+ GX_LookupTable_Single_Table single_table = lookup_table->fsHeader.single_table;
+
+ FT_FREE(single_table->entries);
+ single_table->entries = NULL;
+ }
+
+ static FT_Error
+ gx_LookupTable_load_binSrch( GX_LookupTable lookup_table,
+ FT_Stream stream )
+ {
+ FT_Error error = GX_Err_Ok;
+ FT_Memory memory = stream->memory;
+ GX_LookupTable_BinSrch binSrch;
+ gx_LookupTable_loader lookuptable_loader;
+
+ switch (lookup_table->format)
+ {
+ case GX_LOOKUPTABLE_SEGMENT_SINGLE:
+ case GX_LOOKUPTABLE_SEGMENT_ARRAY:
+ lookuptable_loader = gx_LookupTable_load_segment_generic;
+ break;
+ case GX_LOOKUPTABLE_SINGLE_TABLE:
+ lookuptable_loader = gx_LookupTable_load_single_table;
+ break;
+ default:
+ return GX_Err_Invalid_Table;
+ }
+
+ if ( FT_MEM_NEW (binSrch) )
+ return error;
+
+ binSrch->dummy = NULL;
+ error = gx_load_BinSrchHeader( stream, &(binSrch->binSrchHeader) );
+ if ( error )
+ goto Failure;
+
+ lookup_table->fsHeader.bin_srch = binSrch;
+ error = lookuptable_loader ( lookup_table, stream );
+ if ( error )
+ {
+ lookup_table->fsHeader.bin_srch = NULL;
+ goto Failure;
+ }
+
+ return error;
+
+ Failure:
+ FT_FREE ( binSrch );
+ return error;
+ }
+
+ static void
+ gx_LookupTable_free_binSrch ( FT_Memory memory,
+ GX_LookupTable lookup_table )
+ {
+ GX_LookupTable_BinSrch binSrch = lookup_table->fsHeader.bin_srch;
+ gx_LookupTable_finalizer finalizer;
+
+ switch (lookup_table->format)
+ {
+ case GX_LOOKUPTABLE_SEGMENT_SINGLE:
+ case GX_LOOKUPTABLE_SEGMENT_ARRAY:
+ finalizer = gx_LookupTable_free_segment_generic;
+ break;
+ case GX_LOOKUPTABLE_SINGLE_TABLE:
+ finalizer = gx_LookupTable_free_single_table;
+ break;
+ default:
+ finalizer = NULL;
+ }
+ FT_ASSERT(finalizer);
+
+ finalizer ( memory, lookup_table );
+ binSrch->dummy = NULL;
+ FT_FREE ( lookup_table->fsHeader.bin_srch );
+ lookup_table->fsHeader.bin_srch = NULL;
+ }
+
+ static FT_Error
+ gx_LookupTable_load_simple_array( GX_LookupTable lookup_table,
+ FT_Stream stream )
+
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+ GX_LookupValue value_slot;
+
+ if ( FT_NEW_ARRAY (value_slot, lookup_table->num_glyphs) )
+ return error;
+ error = gx_LookupTable_load_raw_values ( stream,
+ lookup_table->num_glyphs,
+ value_slot );
+ if ( error )
+ goto Failure;
+
+ lookup_table->fsHeader.simple_array = value_slot;
+ return error;
+
+ Failure:
+ FT_FREE( value_slot );
+ return error;
+ }
+
+ static void
+ gx_LookupTable_free_simple_array( FT_Memory memory,
+ GX_LookupTable lookup_table )
+ {
+ FT_FREE ( lookup_table->fsHeader.simple_array );
+ lookup_table->fsHeader.simple_array = NULL;
+ }
+
+ static FT_Error
+ gx_LookupTable_load_trimmed_array( GX_LookupTable lookup_table,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+ FT_Short firstGlyph, glyphCount;
+ GX_LookupTable_Trimmed_Array trimmed_array;
+ GX_LookupValue value_slot;
+
+ error = FT_READ_USHORT(firstGlyph);
+ if ( error )
+ return error;
+
+ error = FT_READ_USHORT(glyphCount);
+ if ( error )
+ return error;
+
+ if ( FT_ALLOC (trimmed_array,
+ sizeof (*trimmed_array) + sizeof(*trimmed_array->valueArray) * glyphCount) )
+ return error;
+ trimmed_array->firstGlyph = firstGlyph;
+ trimmed_array->glyphCount = glyphCount;
+ trimmed_array->valueArray = NULL;
+ value_slot =(GX_LookupValue)(((char *)trimmed_array) + sizeof (*trimmed_array));
+ error = gx_LookupTable_load_raw_values ( stream, glyphCount, value_slot );
+ if ( error )
+ goto Failure;
+
+ lookup_table->fsHeader.trimmed_array = trimmed_array;
+ trimmed_array->valueArray = value_slot;
+ return error;
+
+ Failure:
+ FT_FREE( trimmed_array );
+ lookup_table->fsHeader.trimmed_array = NULL;
+ return error;
+ }
+
+ static void
+ gx_LookupTable_free_trimmed_array( FT_Memory memory,
+ GX_LookupTable lookup_table )
+ {
+ GX_LookupTable_Trimmed_Array trimmed_array;
+
+ trimmed_array = lookup_table->fsHeader.trimmed_array;
+ trimmed_array->valueArray = NULL;
+ FT_FREE(trimmed_array);
+ lookup_table->fsHeader.trimmed_array = NULL;
+ }
+
+
+ FT_LOCAL_DEF( FT_Error )
+ gx_face_load_LookupTable ( GX_Face face,
+ FT_Stream stream,
+ GX_LookupTable lookup_table )
+ {
+ FT_Error error;
+ gx_LookupTable_loader loader;
+
+ lookup_table->position = FT_STREAM_POS();
+ lookup_table->num_glyphs = face->root.num_glyphs;
+ lookup_table->fsHeader.any = NULL;
+ error = FT_READ_SHORT(lookup_table->format);
+ if ( error )
+ return error;
+
+ switch ( lookup_table->format )
+ {
+ case GX_LOOKUPTABLE_SIMPLE_ARRAY:
+ loader = gx_LookupTable_load_simple_array;
+ break;
+ case GX_LOOKUPTABLE_TRIMMED_ARRAY:
+ loader = gx_LookupTable_load_trimmed_array;
+ break;
+ default:
+ loader = gx_LookupTable_load_binSrch;
+ }
+
+ error = (*loader)( lookup_table, stream );
+ return error;
+ }
+
+ FT_LOCAL_DEF ( void )
+ gx_LookupTable_free ( GX_LookupTable lookup_table,
+ FT_Memory memory )
+ {
+ gx_LookupTable_finalizer finalizer;
+
+ switch ( lookup_table->format )
+ {
+ case GX_LOOKUPTABLE_SIMPLE_ARRAY:
+ finalizer = gx_LookupTable_free_simple_array;
+ break;
+ case GX_LOOKUPTABLE_TRIMMED_ARRAY:
+ finalizer = gx_LookupTable_free_trimmed_array;
+ break;
+ default:
+ finalizer = gx_LookupTable_free_binSrch;
+ }
+ finalizer ( memory, lookup_table );
+ }
+
+
+ static FT_Error
+ gx_LookupTable_traverse_simple_array( GX_LookupTable lookup_table,
+ GX_LookupTable_Funcs funcs,
+ FT_Pointer user )
+ {
+ FT_Long i;
+ FT_Error error = GX_Err_Ok;
+
+ if ( funcs->simple_array_func )
+ {
+ for ( i = 0; i < lookup_table->num_glyphs; i++ )
+ {
+ error = (* funcs->simple_array_func)(lookup_table->format,
+ i,
+ &((lookup_table->fsHeader.simple_array)[i]),
+ user);
+ if ( error )
+ return error;
+ }
+ }
+ else if ( funcs->generic_func )
+ {
+ for ( i = 0; i < lookup_table->num_glyphs; i++ )
+ {
+ error = (* funcs->generic_func)(lookup_table->format,
+ &((lookup_table->fsHeader.simple_array)[i]),
+ user);
+ if ( error )
+ return error;
+ }
+ }
+ else
+ error = GX_Err_Ok;
+ return error;
+ }
+
+ static FT_Error
+ gx_LookupTable_traverse_segment_generic( GX_LookupTable lookup_table,
+ GX_LookupTable_Funcs funcs,
+ FT_Pointer user )
+ {
+ FT_Error error = GX_Err_Ok;
+ GX_LookupTable_Segment segment_table = lookup_table->fsHeader.segment_generic;
+ GX_BinSrchHeader header = &(segment_table->binSrchHeader);
+ GX_LookupSegment segment;
+ GX_LookupTable_Segment_Func segment_func;
+ FT_Long i;
+
+ if ( lookup_table->format == GX_LOOKUPTABLE_SEGMENT_SINGLE )
+ segment_func = funcs->segment_single_func;
+ else if ( lookup_table->format == GX_LOOKUPTABLE_SEGMENT_ARRAY)
+ segment_func = funcs->segment_array_func;
+ else
+ segment_func = NULL;
+
+ if ( segment_func )
+ {
+ for ( i = 0; i < header->nUnits; i++ )
+ {
+ segment = &(segment_table->segments[i]);
+ error = (*segment_func)( lookup_table->format,
+ segment->lastGlyph,
+ segment->firstGlyph,
+ &(segment->value),
+ user );
+ if ( error )
+ return error;
+ }
+ }
+ else if ( funcs->generic_func )
+ {
+ for ( i = 0; i < header->nUnits; i++ )
+ {
+ segment = &(segment_table->segments[i]);
+ error = (*funcs->generic_func)( lookup_table->format,
+ &(segment->value),
+ user );
+ if ( error )
+ return error;
+ }
+ }
+ else
+ error = GX_Err_Ok;
+ return error;
+ }
+
+ static FT_Error
+ gx_LookupTable_traverse_single_table ( GX_LookupTable lookup_table,
+ GX_LookupTable_Funcs funcs,
+ FT_Pointer user )
+ {
+ FT_Error error = GX_Err_Ok;
+ GX_LookupTable_Single_Table single_table;
+ GX_LookupSingle entries;
+ GX_BinSrchHeader binSrchHeader;
+ FT_Long i;
+
+ single_table = lookup_table->fsHeader.single_table;
+ entries = single_table->entries;
+ binSrchHeader = &(single_table->binSrchHeader);
+
+ if ( funcs->single_table_func )
+ {
+ for ( i = 0; i < binSrchHeader->nUnits; i++ )
+ {
+ error = (*funcs->single_table_func) ( lookup_table->format,
+ entries[i].glyph,
+ &(entries[i].value),
+ user );
+ if ( error )
+ return error;
+ }
+ }
+ else if ( funcs->generic_func )
+ {
+ for ( i = 0; i < binSrchHeader->nUnits; i++ )
+ {
+ error = (* funcs->generic_func) ( lookup_table->format,
+ &(entries[i].value),
+ user );
+ if ( error )
+ return error;
+ }
+ }
+ else
+ error = GX_Err_Ok;
+ return error;
+ }
+
+ static FT_Error
+ gx_LookupTable_traverse_trimmed_array( GX_LookupTable lookup_table,
+ GX_LookupTable_Funcs funcs,
+ FT_Pointer user )
+ {
+ FT_Error error = GX_Err_Ok;
+ FT_Long i;
+ GX_LookupTable_Trimmed_Array trimmed_array = lookup_table->fsHeader.trimmed_array;
+
+ if ( funcs->trimmed_array_func )
+ {
+ for ( i = 0; i < trimmed_array->glyphCount; i++ )
+ {
+ error = (* funcs->trimmed_array_func)(lookup_table->format,
+ i,
+ trimmed_array->firstGlyph,
+ trimmed_array->glyphCount,
+ &(trimmed_array->valueArray[i]),
+ user);
+ if ( error )
+ return error;
+ }
+ }
+ else if ( funcs->generic_func )
+ {
+ for ( i = 0; i < trimmed_array->glyphCount; i++ )
+ {
+ error = (* funcs->generic_func)(lookup_table->format,
+ &(trimmed_array->valueArray[i]),
+ user);
+ if ( error )
+ return error;
+ }
+ }
+ else
+ error = GX_Err_Ok;
+ return error;
+ }
+
+ FT_LOCAL_DEF ( FT_Error )
+ gx_LookupTable_traverse_low( GX_LookupTable lookup_table,
+ GX_LookupTable_Funcs funcs,
+ FT_Pointer user )
+ {
+ gx_LookupTable_traverser traverser;
+
+ switch (lookup_table->format)
+ {
+ case GX_LOOKUPTABLE_SIMPLE_ARRAY:
+ traverser = gx_LookupTable_traverse_simple_array;
+ break;
+ case GX_LOOKUPTABLE_SEGMENT_SINGLE:
+ case GX_LOOKUPTABLE_SEGMENT_ARRAY:
+ traverser = gx_LookupTable_traverse_segment_generic;
+ break;
+ case GX_LOOKUPTABLE_SINGLE_TABLE:
+ traverser = gx_LookupTable_traverse_single_table;
+ break;
+ case GX_LOOKUPTABLE_TRIMMED_ARRAY:
+ traverser = gx_LookupTable_traverse_trimmed_array;
+ break;
+ default:
+ traverser = NULL;
+ }
+ FT_ASSERT(traverser);
+ return (*traverser) ( lookup_table, funcs, user );
+ }
+
+ static int
+ lookup_lookup_segment (const void *keyval, const void *datum)
+ {
+ const GX_LookupSegment segment = (const GX_LookupSegment)datum;
+ FT_UShort glyph = *(FT_UShort*)keyval;
+
+ if ( glyph < segment->firstGlyph )
+ return -1;
+ else if ( segment->lastGlyph < glyph )
+ return 1;
+ else
+ return 0;
+ }
+
+
+ static int
+ lookup_lookup_single(const void *keyval, const void *datum)
+ {
+ const GX_LookupSingle entry = (const GX_LookupSingle)datum;
+ FT_UShort glyph = *(FT_UShort*)keyval;
+ if ( glyph < entry->glyph )
+ return -1;
+ else if ( entry->glyph < glyph )
+ return 1;
+ else
+ return 0;
+ }
+
+ FT_LOCAL_DEF( GX_LookupResultRec )
+ gx_LookupTable_lookup ( GX_LookupTable lookup_table,
+ FT_UShort glyph )
+ {
+ GX_LookupResultRec result;
+
+ GX_LookupTable_Segment segment_table;
+ GX_LookupSegment segment;
+
+ GX_LookupTable_Single_Table single_table;
+ GX_LookupSingle entry;
+
+ GX_LookupTable_Trimmed_Array trimmed_array;
+ FT_Long trimmed_index;
+
+ void * bs_key = &glyph;
+ void * bs_base;
+ size_t bs_n;
+ size_t bs_size;
+
+ int (* bs_cmp)(const void* keyval, const void* datum);
+
+ result.firstGlyph = GX_LOOKUP_RESULT_NO_FIRST_GLYPH;
+ result.value = NULL;
+ switch ( lookup_table->format )
+ {
+ case GX_LOOKUPTABLE_SIMPLE_ARRAY:
+ if ( glyph < lookup_table->num_glyphs )
+ result.value = &((lookup_table->fsHeader.simple_array) [glyph]);
+ break;
+ case GX_LOOKUPTABLE_SEGMENT_SINGLE:
+ case GX_LOOKUPTABLE_SEGMENT_ARRAY:
+ segment_table = lookup_table->fsHeader.segment_generic;
+ bs_base = segment_table->segments;
+ bs_n = segment_table->binSrchHeader.nUnits;
+ bs_size = sizeof (*segment_table->segments);
+ bs_cmp = lookup_lookup_segment;
+ segment = ft_bsearch( bs_key, bs_base, bs_n, bs_size, bs_cmp );
+ if ( segment )
+ {
+ result.value = &segment->value;
+ if ( ( lookup_table->format == GX_LOOKUPTABLE_SEGMENT_ARRAY ) )
+ result.firstGlyph = segment->firstGlyph;
+ }
+ return result;
+ case GX_LOOKUPTABLE_SINGLE_TABLE:
+ single_table = lookup_table->fsHeader.single_table;
+ bs_base = single_table->entries;
+ bs_n = single_table->binSrchHeader.nUnits;
+ bs_size = sizeof (*single_table->entries);
+ bs_cmp = lookup_lookup_single;
+ entry = ft_bsearch( bs_key, bs_base, bs_n, bs_size, bs_cmp );
+ if ( entry )
+ result.value = &(entry->value);
+ break;
+ case GX_LOOKUPTABLE_TRIMMED_ARRAY:
+ trimmed_array = lookup_table->fsHeader.trimmed_array;
+ if ( glyph < trimmed_array->firstGlyph )
+ break;
+
+ trimmed_index = glyph - trimmed_array->firstGlyph;
+ if ( trimmed_index < trimmed_array->glyphCount )
+ result.value = &(trimmed_array->valueArray[trimmed_index]);
+ break;
+ }
+ return result;
+ }
+
+ FT_LOCAL ( FT_Error )
+ gx_LookupTable_traverse_high ( GX_LookupTable lookup_table,
+ GX_LookupTable_Glyph_Func func,
+ FT_Pointer user)
+ {
+ FT_Error error;
+ FT_UShort glyph;
+ GX_LookupResultRec result;
+
+ for ( glyph = 0; glyph < 0xFFFF; glyph++ )
+ {
+ result = gx_LookupTable_lookup ( lookup_table, glyph );
+ if ( result.value == NULL)
+ continue ;
+
+ if (( error = func( glyph, result.value, result.firstGlyph, user ) ))
+ return error;
+ }
+ return FT_Err_Ok;
+ }
+
+
+/* END */
diff --git a/src/gxlayout/gxlookuptbl.h b/src/gxlayout/gxlookuptbl.h
new file mode 100644
index 000000000..88be6910d
--- /dev/null
+++ b/src/gxlayout/gxlookuptbl.h
@@ -0,0 +1,125 @@
+/***************************************************************************/
+/* */
+/* gxlookuptbl.h */
+/* */
+/* AAT/TrueTypeGX lookup table related types and functions */
+/* (specification) */
+/* */
+/* Copyright 2003 by */
+/* Masatake YAMATO and Redhat K.K. */
+/* */
+/* This file may only be used, */
+/* modified, and distributed under the terms of the FreeType project */
+/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
+/* this file you indicate that you have read the license and */
+/* understand and accept it fully. */
+/* */
+/***************************************************************************/
+
+/***************************************************************************/
+/* Development of the code in this file is support of */
+/* Information-technology Promotion Agency, Japan. */
+/***************************************************************************/
+
+#ifndef __GXLOOKUPTBL_H__
+#define __GXLOOKUPTBL_H__
+
+#include <ft2build.h>
+#include FT_INTERNAL_TRUETYPE_TYPES_H
+#include "gxtypes.h"
+
+FT_BEGIN_HEADER
+
+
+ typedef FT_Error
+ (* GX_LookupTable_Generic_Func) ( GX_LookupTable_Format format,
+ GX_LookupValue value,
+ FT_Pointer user );
+
+ typedef FT_Error
+ (* GX_LookupTable_Simple_Array_Func) ( GX_LookupTable_Format format,
+ FT_UShort index,
+ GX_LookupValue value,
+ FT_Pointer user );
+ typedef FT_Error
+ (* GX_LookupTable_Segment_Func) ( GX_LookupTable_Format format,
+ FT_UShort lastGlyph,
+ FT_UShort firstGlyph,
+ GX_LookupValue value,
+ FT_Pointer user );
+ typedef FT_Error
+ (* GX_LookupTable_Single_Table_Func) ( GX_LookupTable_Format format,
+ FT_UShort glyph,
+ GX_LookupValue value,
+ FT_Pointer user );
+ typedef FT_Error
+ (* GX_LookupTable_Trimmed_Array_Func) ( GX_LookupTable_Format format,
+ FT_UShort index,
+ FT_UShort firstGlyph,
+ FT_UShort lastGlyph,
+ GX_LookupValue value,
+ FT_Pointer user );
+
+#define GX_LOOKUP_TABLE_FUNC_ZERO {NULL, NULL, NULL, NULL, NULL, NULL}
+ typedef struct GX_LookupTable_FuncsRec_
+ {
+ /* If a function suitable for the lookup format is given, use
+ it. If not, use `generic_func'. If both a function suitable for
+ the lookup format and `generic_func' are not given(= NULL), do
+ nothing */
+ GX_LookupTable_Generic_Func generic_func;
+ /* -------------------------------------------------------------- */
+ GX_LookupTable_Simple_Array_Func simple_array_func;
+ GX_LookupTable_Segment_Func segment_single_func;
+ GX_LookupTable_Segment_Func segment_array_func;
+ GX_LookupTable_Single_Table_Func single_table_func;
+ GX_LookupTable_Trimmed_Array_Func trimmed_array_func;
+ } GX_LookupTable_FuncsRec, *GX_LookupTable_Funcs;
+
+ typedef struct GX_LookupResultRec_
+ {
+ /* `value' is NULL if a value for the glyph cannot be found. */
+ GX_LookupValue value;
+
+ /* `firstGlyph' is given only if the target lookup table
+ format is Segement array. If the format is other than
+ Segement array, GX_LOOKUP_RESULT_NO_FIRST_GLYPH is set
+ to `firstGlyph'. */
+#define GX_LOOKUP_RESULT_NO_FIRST_GLYPH -1
+ FT_Long firstGlyph;
+ } GX_LookupResultRec, *GX_LookupResult;
+
+ typedef FT_Error
+ (* GX_LookupTable_Glyph_Func) ( FT_UShort glyph,
+ GX_LookupValue value,
+ FT_Long firstGlyph,
+ FT_Pointer user );
+
+ FT_LOCAL( FT_Error )
+ gx_face_load_LookupTable ( GX_Face face,
+ FT_Stream stream,
+ GX_LookupTable lookup_table );
+
+ FT_LOCAL( void )
+ gx_LookupTable_free ( GX_LookupTable lookup_table,
+ FT_Memory memory );
+
+ FT_LOCAL ( FT_Error )
+ gx_LookupTable_traverse_low( GX_LookupTable lookup_table,
+ GX_LookupTable_Funcs funcs,
+ FT_Pointer user);
+
+ FT_LOCAL ( GX_LookupResultRec )
+ gx_LookupTable_lookup ( GX_LookupTable lookup_table,
+ FT_UShort glyph );
+
+ FT_LOCAL ( FT_Error )
+ gx_LookupTable_traverse_high ( GX_LookupTable lookup_table,
+ GX_LookupTable_Glyph_Func func,
+ FT_Pointer user);
+
+FT_END_HEADER
+
+#endif /* Not def: __GXLOOKUPTBL_H__ */
+
+/* END */
diff --git a/src/gxlayout/gxltypes.h b/src/gxlayout/gxltypes.h
new file mode 100644
index 000000000..cc385a4dd
--- /dev/null
+++ b/src/gxlayout/gxltypes.h
@@ -0,0 +1,119 @@
+/***************************************************************************/
+/* */
+/* gxltypes.h */
+/* */
+/* Data types of AAT/TrueTypeGX based layout engine */
+/* (specification) */
+/* */
+/* Copyright 2003 by */
+/* Masatake YAMATO and Redhat K.K. */
+/* */
+/* This file may only be used, */
+/* modified, and distributed under the terms of the FreeType project */
+/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
+/* this file you indicate that you have read the license and */
+/* understand and accept it fully. */
+/* */
+/***************************************************************************/
+
+/***************************************************************************/
+/* Development of the code in this file is support of */
+/* Information-technology Promotion Agency, Japan. */
+/***************************************************************************/
+
+#ifndef __GXLTYPES_H__
+#define __GXLTYPES_H__
+
+#include <ft2build.h>
+#include FT_INTERNAL_TRUETYPE_TYPES_H
+#include FT_INTERNAL_FTL_TYPES_H
+#include FT_GXLAYOUT_H
+
+FT_BEGIN_HEADER
+
+ typedef enum
+ {
+ GXL_ASCENDING = 0,
+ GXL_DESCENDING = 1
+ } GXL_Order;
+
+ typedef struct GXL_Feature_ExclusiveRec_
+ {
+ FT_Bool exclusive;
+ GXL_Setting setting;
+ } GXL_Feature_ExclusiveRec, *GXL_Feature_Exclusive;
+
+ typedef struct GXL_NameRec_
+ {
+ const FT_String * string;
+ FT_Short index;
+ } GXL_NameRec, *GXL_Name;
+
+ typedef struct GXL_SettingRec_
+ {
+ FT_UShort value;
+ GXL_NameRec name;
+ GXL_Feature feature;
+ } GXL_SettingRec; /* *GXL_Setting; */
+
+ typedef struct GXL_FeatureRec_
+ {
+ GXL_FeaturesRequest request;
+ FT_UShort value;
+ GXL_Feature_ExclusiveRec exclusive;
+ GXL_NameRec name;
+ FT_UShort nSettings;
+ GXL_Setting setting;
+ } GXL_FeatureRec; /* , * GXL_Feature; */
+
+ typedef struct GXL_FeaturesRequestRec_
+ {
+ FTL_FeaturesRequestRec root;
+ GXL_Initial_State initial_state;
+ FT_ULong nFeatures;
+ GXL_Feature feature;
+ } GXL_FeaturesRequestRec; /* , *GXL_FeaturesRequest; */
+
+
+ FT_LOCAL ( void )
+ gxl_features_request_free( GXL_FeaturesRequest request, FT_Memory memory );
+
+ FT_LOCAL ( GXL_Setting )
+ gxl_feature_get_setting_by_value (GXL_Feature feature, FT_UShort value);
+
+ FT_LOCAL ( GXL_Feature )
+ gxl_features_request_get_feature_by_type ( GXL_FeaturesRequest request,
+ FT_UShort featureType );
+
+ FT_LOCAL ( FT_Error )
+ gxl_get_font ( FT_Face face, FTL_Font * font);
+
+ FT_LOCAL ( FTL_EngineType )
+ gxl_get_engine_type ( FT_Face face );
+
+ FT_LOCAL ( FT_Error )
+ gxl_new_features_request( FT_Face face, FTL_FeaturesRequest * request);
+ FT_LOCAL ( FT_Error )
+ gxl_done_features_request( FTL_FeaturesRequest request);
+ FT_LOCAL ( FT_Error )
+ gxl_copy_features_request( FTL_FeaturesRequest from,
+ FTL_FeaturesRequest to);
+ FT_LOCAL ( FT_UShort )
+ gxl_get_ligature_caret_count ( FT_Face face,
+ FT_UShort glyphID );
+ FT_LOCAL ( FT_UShort )
+ gxl_get_ligature_caret_division( FT_Face face,
+ FT_UShort glyphID,
+ FT_UShort nth );
+ FT_LOCAL ( FT_Error )
+ gxl_substitute_glyphs ( FT_Face face,
+ FTL_FeaturesRequest request,
+ FTL_Glyphs_Array in,
+ FTL_Glyphs_Array out );
+
+FT_END_HEADER
+
+#endif /* Not def: __GXLTYPES_H__ */
+
+
+/* END */
diff --git a/src/gxlayout/gxobjs.c b/src/gxlayout/gxobjs.c
new file mode 100644
index 000000000..526210d3e
--- /dev/null
+++ b/src/gxlayout/gxobjs.c
@@ -0,0 +1,335 @@
+/***************************************************************************/
+/* */
+/* gxobjs.c */
+/* */
+/* AAT/TrueTypeGX objects manager (body). */
+/* */
+/* Copyright 2003 by */
+/* Masatake YAMATO and Redhat K.K. */
+/* */
+/* This file may only be used, */
+/* modified, and distributed under the terms of the FreeType project */
+/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
+/* this file you indicate that you have read the license and */
+/* understand and accept it fully. */
+/* */
+/***************************************************************************/
+
+/***************************************************************************/
+/* Development of the code in this file is support of */
+/* Information-technology Promotion Agency, Japan. */
+/***************************************************************************/
+
+#include <ft2build.h>
+#include FT_INTERNAL_DEBUG_H
+#include FT_INTERNAL_STREAM_H
+#include FT_TRUETYPE_TAGS_H
+#include FT_LIST_H
+#include FT_ERRORS_H
+#include FT_LAYOUT_H
+#include FT_INTERNAL_OBJECTS_H
+#include FT_SERVICE_LAYOUT_H
+#include FT_GXLAYOUT_H
+#include "gxobjs.h"
+#include "gxload.h"
+#include "gxerrors.h"
+#include "gxdriver.h"
+#include "gxaccess.h"
+#include "gxltypes.h"
+
+
+ extern const FT_Driver_ClassRec tt_driver_class;
+
+ /*************************************************************************/
+ /* */
+ /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
+ /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
+ /* messages during execution. */
+ /* */
+#undef FT_COMPONENT
+#define FT_COMPONENT trace_gxobjs
+
+ static FT_Error
+ gx_face_init( FT_Stream stream,
+ GX_Face face,
+ FT_Int face_index,
+ FT_Int num_params,
+ FT_Parameter* params );
+
+ static FT_Error
+ gx_font_load ( GX_Face face );
+
+ static void
+ gx_font_done( void * object );
+
+ static FT_Module_Interface
+ gx_module_get_interface ( FT_Module module,
+ const char* gx_interface );
+
+ static FT_Error
+ gx_face_get_kerning( FT_Face face,
+ FT_UInt left_glyph,
+ FT_UInt right_glyph,
+ FT_Vector* kerning );
+
+ static const FT_Service_LayoutRec gx_service_layout =
+ {
+ (FTL_Get_Font_Func) gxl_get_font,
+ (FTL_Get_EngineType_Func) gxl_get_engine_type,
+ (FTL_New_FeaturesRequest_Func) gxl_new_features_request,
+ (FTL_Done_FeaturesRequest_Func) gxl_done_features_request,
+ (FTL_Copy_FeaturesRequest_Func) gxl_copy_features_request,
+ (FTL_Get_LigatureCaret_Count_Func) gxl_get_ligature_caret_count,
+ (FTL_Get_LigatureCaret_Division_Func) gxl_get_ligature_caret_division,
+ (FTL_Substitute_Glyphs_Func) gxl_substitute_glyphs
+ };
+
+ static const FT_ServiceDescRec gx_services[] =
+ {
+ { FT_SERVICE_ID_LAYOUT, &gx_service_layout },
+ { NULL, NULL }
+ };
+
+ FT_LOCAL_DEF( FT_Error )
+ gx_driver_init( GX_Driver driver )
+ {
+ FT_Error error;
+
+ const void * module_name;
+ FT_Driver gx_driver_root = &driver->root;
+ FT_Driver_Class gx_driver_class = gx_driver_root->clazz;
+
+ module_name = gx_driver_class->root.module_name;
+
+ *gx_driver_class = tt_driver_class;
+ driver->root.clazz->root.module_name = module_name;
+
+ if (( error = ((FT_Module_Class*)gx_driver_class)->module_init( (FT_Module)driver ) ))
+ return error;
+
+ gx_driver_class->init_face = (FT_Face_InitFunc)gx_face_init;
+ gx_driver_class->get_kerning = gx_face_get_kerning;
+ ((FT_Module_Class*)gx_driver_class)->get_interface = gx_module_get_interface;
+
+ return GX_Err_Ok;
+ }
+
+ static FT_Error
+ gx_face_init( FT_Stream stream,
+ GX_Face face,
+ FT_Int face_index,
+ FT_Int num_params,
+ FT_Parameter* params )
+ {
+ FT_Error error;
+
+ /* TODO */
+ error = tt_driver_class.init_face ( stream, (FT_Face)face, face_index, num_params, params );
+ if ( error )
+ goto Exit;
+
+ error = gx_font_load ( face );
+ if ( error )
+ goto Exit;
+ Exit:
+ return error;
+ }
+
+#define NEW_TABLE(tag) \
+ do \
+ { \
+ if ( FT_NEW( font->tag ) ) \
+ goto Exit; \
+ \
+ FT_TRACE2 (( "\tloading %s...", #tag )); \
+ error = gx_table_load(face,stream,tag,font); \
+ if ( error ) \
+ { \
+ if ( !(face->goto_table( face, TTAG_##tag, stream, 0 )) ) \
+ FT_TRACE2(("no table\n")); \
+ else if ( (TTAG_kern == TTAG_##tag) && \
+ (font->kern->version == 1) ) \
+ FT_TRACE2(("old kern\n")); \
+ else \
+ FT_TRACE2(("failed\n")); \
+ FT_FREE ( font->tag ); \
+ } \
+ else \
+ { \
+ FT_TRACE2(("successful\n")); \
+ tables[set_index++] = (GX_Table)font->tag; \
+ } \
+ } while (0)
+
+#define DONE_TABLE(tag) \
+ do \
+ { \
+ if ( font->tag ) \
+ { \
+ gx_table_done ( (GX_Table)font->tag, memory ); \
+ FT_FREE(font->tag); \
+ } \
+ } while ( 0 )
+
+
+ static FT_Error
+ gx_font_load( GX_Face face )
+ {
+ FT_Error error;
+ FT_Stream stream = face->root.stream;
+ FT_Memory memory = stream->memory;
+ GXL_Font font;
+
+#define nTABLES 12
+ GX_Table tables[nTABLES];
+ FT_Int init_index, set_index = 0;
+
+ GXL_FeaturesRequest features_request;
+
+ for ( init_index = 0; init_index < nTABLES; init_index++ )
+ tables[init_index] = NULL;
+
+ if ( face->extra.data )
+ {
+ error = GX_Err_Busy_Extra_Data;
+ goto Exit;
+ }
+
+ if ( FT_NEW(font) )
+ goto Exit;
+
+ if (( error = FTL_Font_Init ( (FTL_Font)font, (FT_Face)face ) ))
+ goto Failure;
+
+ NEW_TABLE(feat);
+ NEW_TABLE(mort);
+ NEW_TABLE(morx);
+
+ NEW_TABLE(trak);
+ NEW_TABLE(kern);
+ NEW_TABLE(prop);
+ NEW_TABLE(lcar);
+ NEW_TABLE(opbd);
+ NEW_TABLE(bsln);
+ NEW_TABLE(fmtx);
+ NEW_TABLE(fdsc);
+ NEW_TABLE(just);
+
+ NEW_TABLE(fvar);
+
+ error = FT_Err_Unknown_File_Format;
+
+ if ((( font->mort ) || ( font->morx ))
+ && ( font->feat ))
+ {
+ face->root.face_flags |= FT_FACE_FLAG_GLYPH_SUBSTITUTION;
+ error = GX_Err_Ok;
+ }
+ if ( font->kern )
+ {
+ face->root.face_flags |= FT_FACE_FLAG_KERNING;
+ error = GX_Err_Ok;
+ }
+
+ if ( error == GX_Err_Ok )
+ {
+ face->extra.finalizer = gx_font_done;
+ face->extra.data = font;
+ if (( error = FTL_New_FeaturesRequest ( (FT_Face)face,
+ (FTL_FeaturesRequest*)(&features_request) ) ))
+ goto Failure;
+ }
+ else
+ goto Failure;
+ Exit:
+ return error;
+ Failure:
+ for ( ; set_index > 0; set_index--)
+ {
+ if ( tables[set_index - 1] )
+ {
+ gx_table_done(tables[set_index - 1], memory);
+ FT_FREE(tables[set_index - 1]);
+ }
+ }
+ FT_FREE(font);
+ face->extra.finalizer = NULL;
+ face->extra.data = NULL;
+ return error;
+ }
+
+ static void
+ gx_font_done( void * object )
+ {
+ GXL_Font font = object;
+ FT_Face face = font->root.face;
+ FT_Memory memory = face->driver->root.memory; /* TODO */
+
+ DONE_TABLE(mort);
+ DONE_TABLE(morx);
+ DONE_TABLE(feat);
+ DONE_TABLE(trak);
+ DONE_TABLE(kern);
+ DONE_TABLE(prop);
+ DONE_TABLE(bsln);
+ DONE_TABLE(lcar);
+ DONE_TABLE(opbd);
+ DONE_TABLE(fmtx);
+ DONE_TABLE(fdsc);
+ DONE_TABLE(just);
+ DONE_TABLE(fvar);
+
+ FTL_Font_Finalize((FTL_Font)font);
+ FT_FREE(object);
+ }
+
+ static FT_Module_Interface
+ gx_module_get_interface( FT_Module module,
+ const char* gx_interface )
+ {
+ FT_Module_Interface gx;
+
+ gx = ft_service_list_lookup( gx_services, gx_interface );
+ if ( gx )
+ return gx;
+
+ /* TODO */
+ if ( tt_driver_class.root.get_interface )
+ return tt_driver_class.root.get_interface( module, gx_interface );
+ return NULL;
+ }
+
+ static FT_Error
+ gx_face_get_kerning( FT_Face face,
+ FT_UInt left_glyph,
+ FT_UInt right_glyph,
+ FT_Vector* kerning )
+ {
+ FT_Error error;
+ FTL_Font font;
+ GX_Kern kern;
+ FTL_Direction dir;
+ FTL_FeaturesRequest request;
+
+ kerning->x = 0;
+ kerning->y = 0;
+
+ if (( error = FTL_Get_Font ( face, &font ) ))
+ return error;
+
+ kern = ((GXL_Font)font)->kern;
+ if ( !kern )
+ /* Run old kerning handler */
+ return tt_driver_class.get_kerning ( face, left_glyph, right_glyph, kerning );
+
+ FTL_Font_Get_Current_FeaturesRequest( font, &request );
+ dir = FTL_Get_FeaturesRequest_Direction ( request );
+
+ return gx_kern_get_pair_kerning(kern,
+ left_glyph, right_glyph,
+ dir,
+ kerning);
+ }
+
+
+/* END */
diff --git a/src/gxlayout/gxobjs.h b/src/gxlayout/gxobjs.h
new file mode 100644
index 000000000..3fe865669
--- /dev/null
+++ b/src/gxlayout/gxobjs.h
@@ -0,0 +1,53 @@
+/***************************************************************************/
+/* */
+/* gxobjs.h */
+/* */
+/* AAT/TrueTypeGX objects manager (specification). */
+/* */
+/* Copyright 2003 by */
+/* Masatake YAMATO and Redhat K.K. */
+/* */
+/* This file may only be used, */
+/* modified, and distributed under the terms of the FreeType project */
+/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
+/* this file you indicate that you have read the license and */
+/* understand and accept it fully. */
+/* */
+/***************************************************************************/
+
+/***************************************************************************/
+/* Development of the code in this file is support of */
+/* Information-technology Promotion Agency, Japan. */
+/***************************************************************************/
+
+
+#ifndef __GXOBJS_H__
+#define __GXOBJS_H__
+
+#include <ft2build.h>
+#include FT_INTERNAL_OBJECTS_H
+#include FT_INTERNAL_TRUETYPE_TYPES_H
+
+FT_BEGIN_HEADER
+
+ typedef struct GX_DriverRec_
+ {
+ FT_DriverRec root;
+ TT_ExecContext context;
+ TT_GlyphZoneRec zone;
+ void* extension_component;
+ } GX_DriverRec, *GX_Driver;
+
+ /*************************************************************************/
+ /* */
+ /* Driver functions */
+ /* */
+ FT_LOCAL( FT_Error )
+ gx_driver_init( GX_Driver driver );
+
+FT_END_HEADER
+
+#endif /* __GXOBJS_H__ */
+
+
+/* END */
diff --git a/src/gxlayout/gxstatetbl.c b/src/gxlayout/gxstatetbl.c
new file mode 100644
index 000000000..53dafefd8
--- /dev/null
+++ b/src/gxlayout/gxstatetbl.c
@@ -0,0 +1,765 @@
+/***************************************************************************/
+/* */
+/* gxstatetbl.c */
+/* */
+/* AAT/TrueTypeGX state table related types and functions */
+/* (body). */
+/* */
+/* Copyright 2003 by */
+/* Masatake YAMATO and Redhat K.K. */
+/* */
+/* This file may only be used, */
+/* modified, and distributed under the terms of the FreeType project */
+/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
+/* this file you indicate that you have read the license and */
+/* understand and accept it fully. */
+/* */
+/***************************************************************************/
+
+/***************************************************************************/
+/* Development of the code in this file is support of */
+/* Information-technology Promotion Agency, Japan. */
+/***************************************************************************/
+
+#include <ft2build.h>
+
+#include FT_INTERNAL_STREAM_H
+#include FT_INTERNAL_MEMORY_H
+
+#include "gxstatetbl.h"
+#include "gxlookuptbl.h"
+#include "gxerrors.h"
+
+ static FT_Error
+ gx_StateTable_load_header( GX_Face face,
+ FT_Stream stream,
+ GX_StateHeader header )
+ {
+ FT_Error error;
+ const FT_Frame_Field state_header_fields[] =
+ {
+#undef FT_STRUCTURE
+#define FT_STRUCTURE GX_StateHeaderRec
+ FT_FRAME_START ( 8 ),
+ FT_FRAME_USHORT ( stateSize ),
+ FT_FRAME_USHORT ( classTable ),
+ FT_FRAME_USHORT ( stateArray ),
+ FT_FRAME_USHORT ( entryTable ),
+ FT_FRAME_END
+ };
+ header->position = FT_STREAM_POS();
+ return FT_STREAM_READ_FIELDS( state_header_fields, header );
+ }
+
+ static FT_Error
+ gx_StateTable_load_class_subtable( GX_Face face,
+ FT_Stream stream,
+ FT_ULong pos,
+ GX_ClassSubtable subtable )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+ FT_Byte * classArray;
+ FT_Int i;
+ const FT_Frame_Field class_subtable_fields[] =
+ {
+#undef FT_STRUCTURE
+#define FT_STRUCTURE GX_ClassSubtableRec
+ FT_FRAME_START ( 4 ),
+ FT_FRAME_USHORT ( firstGlyph ),
+ FT_FRAME_USHORT ( nGlyphs ),
+ FT_FRAME_END
+ };
+
+ subtable->classArray = NULL;
+
+ if ( FT_STREAM_SEEK(pos) )
+ goto Exit;
+
+ if ( FT_STREAM_READ_FIELDS ( class_subtable_fields, subtable ) )
+ goto Exit;
+
+ if ( FT_NEW_ARRAY ( classArray, subtable->nGlyphs ) )
+ goto Exit;
+
+ if ( FT_FRAME_ENTER( sizeof (classArray[0]) * subtable->nGlyphs ) )
+ goto Failure;
+
+ for ( i = 0; i < subtable->nGlyphs; i++ )
+ classArray[i] = FT_GET_BYTE();
+
+ FT_FRAME_EXIT();
+ subtable->classArray = classArray;
+ Exit:
+ return error;
+ Failure:
+ FT_FREE( classArray );
+ return error;
+ }
+
+ static void
+ gx_StateTable_free_class_subtable( FT_Memory memory,
+ GX_ClassSubtable subtable )
+ {
+ FT_FREE(subtable->classArray);
+ subtable->classArray = NULL;
+ }
+
+ static FT_Error
+ gx_StateTable_load_state_array( GX_Face face,
+ FT_Stream stream,
+ FT_ULong pos,
+ FT_UShort length,
+ FT_Byte * state_array )
+ {
+ FT_Error error;
+ FT_Int i;
+
+ if ( FT_STREAM_SEEK(pos) )
+ goto Exit;
+
+ if ( FT_FRAME_ENTER( sizeof (state_array[0]) * length ) )
+ goto Exit;
+
+ for ( i = 0; i < length; i++ )
+ state_array[i] = FT_GET_BYTE();
+
+ FT_FRAME_EXIT();
+ Exit:
+ return error;
+ }
+
+/* - gx_StateTable_load_entry_subtable
+ I assume FUNCS is not NULL. Set any kind of dummy in the caller if
+ necessary.
+ To support both a state table and an extended state table, the type of nEntries
+ is FT_ULong. */
+ static FT_Error
+ gx_StateTable_load_entry_subtable ( GX_Face face,
+ FT_Stream stream,
+ FT_ULong pos,
+ FT_ULong nEntries,
+ GX_EntrySubtable entry_subtable,
+ GX_StateTable_Entry_Load_Funcs funcs,
+ FT_Pointer user )
+ {
+ FT_Error error;
+ FT_Memory memory = face->root.driver->root.memory;
+ FT_ULong i, j;
+
+ const FT_Frame_Field entry_subtable_fields[] =
+ {
+#undef FT_STRUCTURE
+#define FT_STRUCTURE GX_EntrySubtableRec
+ FT_FRAME_START ( 4 ),
+ FT_FRAME_USHORT ( newState ),
+ FT_FRAME_USHORT ( flags ),
+ FT_FRAME_END
+ };
+
+ if ( FT_STREAM_SEEK( pos ) )
+ goto Exit;
+
+ for ( i = 0; i < nEntries; i++ )
+ {
+ if ( FT_STREAM_READ_FIELDS ( entry_subtable_fields, &entry_subtable[i] ) )
+ goto Failure;
+ if (( error = funcs->loader(face, stream, &entry_subtable[i], user) ))
+ goto Failure;
+ }
+ Exit:
+ return error;
+ Failure:
+ for ( j = i; j > 0; j-- )
+ funcs->finalizer(memory, &entry_subtable[j - 1], user);
+ return error;
+ }
+
+ static void
+ gx_StateTable_free_entry_subtable ( FT_Memory memory,
+ FT_Byte nEntries,
+ GX_EntrySubtable entry_subtable,
+ GX_StateTable_Entry_Finalizer finalizer,
+ FT_Pointer user )
+ {
+ FT_Int i;
+ for ( i = 0; i < nEntries; i++ )
+ finalizer(memory, &entry_subtable[i], user);
+ }
+
+ static FT_Error
+ gx_StateTable_Entry_default_loader ( GX_Face face,
+ FT_Stream stream,
+ GX_EntrySubtable entry_subtable,
+ FT_Pointer user )
+ {
+ entry_subtable->glyphOffsets.any = NULL;
+ return GX_Err_Ok;
+ }
+
+ static void
+ gx_StateTable_Entry_default_finalizer ( FT_Memory memory,
+ GX_EntrySubtable entry_subtable,
+ FT_Pointer user )
+ {
+ /* Do nothing */;
+ }
+
+ static FT_Byte
+ gx_StateTable_find_state_array_max_index (FT_UShort array_length, FT_Byte state_array[])
+ {
+ FT_Int i;
+ FT_Byte max_index = 0;
+ for ( i = 0; i < array_length; i++ )
+ {
+ /* fprintf(stderr, "->%u\n", state_array[i]); */
+ if ( state_array[i] > max_index )
+ max_index = state_array [i];
+ }
+ return max_index;
+ }
+
+ FT_LOCAL_DEF ( FT_Error )
+ gx_face_load_StateTable ( GX_Face face,
+ FT_Stream stream,
+ GX_StateTable state_table,
+ GX_StateTable_Entry_Load_Funcs funcs,
+ FT_Pointer user )
+
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+ GX_StateHeader header;
+ GX_ClassSubtable class_subtable;
+ FT_Byte * state_array = NULL;
+ FT_UShort state_array_len;
+ GX_EntrySubtable entry_subtable = NULL;
+ FT_ULong pos;
+ GX_StateTable_Entry_Load_FuncsRec default_funcs = GX_STATE_TABLE_ENTRY_LOAD_FUNCS_ZERO;
+
+ default_funcs.loader = gx_StateTable_Entry_default_loader;
+ default_funcs.finalizer = gx_StateTable_Entry_default_finalizer;
+
+ state_table->state_array = NULL;
+ state_table->entry_subtable = NULL;
+
+ /* 1. Header */
+ header = &state_table->header;
+ if (( error = gx_StateTable_load_header( face, stream,
+ header ) ))
+ goto Exit;
+
+ /* 2. class subtable */
+ pos = header->position + header->classTable;
+ class_subtable = &state_table->class_subtable;
+ if (( error = gx_StateTable_load_class_subtable( face,
+ stream,
+ pos,
+ class_subtable ) ))
+ goto Exit;
+
+
+ /* 3. state array */
+ /* To calculate the length of stateArray, we assume
+ the order of fields placement is classTable, stateArray,
+ entryTable */
+ FT_ASSERT( header->classTable < header->stateArray );
+ FT_ASSERT( header->stateArray < header->entryTable );
+
+ pos = header->position + header->stateArray;
+ state_array_len = header->entryTable - header->stateArray;
+ state_table->nStates = state_array_len / header->stateSize;
+ /* Calculate state_array_len again.
+ state_array_len must be a multiple of header->stateSize. */
+ state_array_len = state_table->nStates * header->stateSize;
+ if (( FT_NEW_ARRAY ( state_array, state_array_len ) ))
+ goto Failure;
+
+ if (( error = gx_StateTable_load_state_array( face,
+ stream,
+ pos,
+ state_array_len,
+ state_array ) ))
+ goto Failure;
+
+ /* 4. entry subtable */
+ if ( funcs )
+ {
+ if (! funcs->loader )
+ funcs->loader = gx_StateTable_Entry_default_loader;
+ if (! funcs->finalizer )
+ funcs->finalizer = gx_StateTable_Entry_default_finalizer;
+ }
+ else
+ funcs = &default_funcs;
+
+ pos = header->position + header->entryTable;
+ /* gx_StateTable_find_state_array_max_index returns the max index into an array
+ which starts from 0. By adding 1 to the max index, get the length of the array. */
+ state_table->nEntries = 1+ gx_StateTable_find_state_array_max_index(state_array_len,
+ state_array);
+
+ if (( FT_NEW_ARRAY( entry_subtable, state_table->nEntries) ))
+ goto Failure;
+ if (( error = gx_StateTable_load_entry_subtable( face,
+ stream,
+ pos,
+ state_table->nEntries,
+ entry_subtable,
+ funcs,
+ user) ))
+ goto Failure;
+
+ state_table->state_array = state_array;
+ state_table->entry_subtable = entry_subtable;
+ Exit:
+ return error;
+ Failure:
+ if ( entry_subtable )
+ FT_FREE ( entry_subtable );
+ if ( state_array )
+ FT_FREE(state_array);
+ gx_StateTable_free_class_subtable (memory, class_subtable);
+ return error;
+ }
+
+ FT_LOCAL_DEF ( void )
+ gx_StateTable_free ( GX_StateTable state_table,
+ FT_Memory memory,
+ GX_StateTable_Entry_Finalizer finalizer,
+ FT_Pointer user )
+ {
+ if ( finalizer == NULL )
+ finalizer = gx_StateTable_Entry_default_finalizer;
+ gx_StateTable_free_entry_subtable ( memory,
+ state_table->nEntries,
+ state_table->entry_subtable,
+ finalizer,
+ user );
+ FT_FREE( state_table->entry_subtable );
+ state_table->entry_subtable = NULL;
+
+ FT_FREE( state_table->state_array );
+ state_table->state_array = NULL;
+
+ gx_StateTable_free_class_subtable( memory, &state_table->class_subtable );
+ }
+
+ static FT_Error
+ gx_EntrySubtable_traverse( GX_EntrySubtable entries,
+ FT_Long nEntries,
+ GX_StateTable_Entry_Action action,
+ FT_Pointer user )
+ {
+ FT_Error error = GX_Err_Ok;
+ FT_Int i;
+
+ if (!action)
+ return error;
+
+ for ( i = 0; i < nEntries; i++ )
+ {
+ error = action( &entries[i], user );
+ if ( error )
+ return error;
+ }
+ return error;
+ }
+
+#if 0
+ FT_LOCAL_DEF ( FT_Error )
+ gx_StateTable_traverse_entries( GX_StateTable state_table,
+ GX_StateTable_Entry_Action action,
+ FT_Pointer user )
+ {
+ return gx_EntrySubtable_traverse( state_table->entry_subtable,
+ state_table->nEntries,
+ action,
+ user );
+ }
+#endif /* 0 */
+
+ FT_LOCAL_DEF ( FT_Byte )
+ gx_StateTable_get_class ( GX_StateTable state_table,
+ FT_UShort glyph )
+ {
+ GX_ClassSubtable class_subtable;
+ FT_Byte class_code;
+ FT_UShort first_glyph, last_glyph;
+
+ class_subtable = &state_table->class_subtable;
+ first_glyph = class_subtable->firstGlyph;
+ last_glyph = first_glyph + class_subtable->nGlyphs;
+
+ if ( glyph == GX_DELETED_GLYPH_INDEX )
+ class_code = GX_CLASS_DELETED_GLYPH;
+ else if ( ( first_glyph <= glyph ) && ( glyph < last_glyph ) )
+ class_code = class_subtable->classArray[glyph - first_glyph];
+ else
+ class_code = GX_CLASS_OUT_OF_BOUNDS;
+ return class_code;
+ }
+
+ FT_LOCAL_DEF ( GX_EntrySubtable )
+ gx_StateTable_get_entry_subtable ( GX_StateTable state_table,
+ FT_UShort current_state,
+ FT_Byte class_code )
+ {
+ GX_StateHeader header = &state_table->header;
+ FT_Byte * state_array = state_table->state_array;
+ GX_EntrySubtable entry_subtable = state_table->entry_subtable;
+ FT_Byte * state_array_for_current_state;
+ FT_Byte entry_index;
+
+ state_array_for_current_state = &state_array[current_state - header->stateArray];
+ entry_index = state_array_for_current_state[class_code];
+ return &entry_subtable[entry_index];
+ }
+
+/*
+ * Extended State Table
+ */
+
+#define gx_XStateTable_load_entry_subtable gx_StateTable_load_entry_subtable
+#define gx_XStateTable_free_entry_subtable gx_StateTable_free_entry_subtable
+
+#define gx_XStateTable_Entry_default_loader gx_StateTable_Entry_default_loader
+#define gx_XStateTable_Entry_default_finalizer gx_StateTable_Entry_default_finalizer
+#define gx_XStateTable_Entry_default_finalizer gx_StateTable_Entry_default_finalizer
+
+ static FT_Error
+ gx_XStateTable_load_header( GX_Face face,
+ FT_Stream stream,
+ GX_XStateHeader header )
+ {
+ FT_Error error;
+ const FT_Frame_Field xstate_header_fields[] =
+ {
+#undef FT_STRUCTURE
+#define FT_STRUCTURE GX_XStateHeaderRec
+ FT_FRAME_START ( 16 ),
+ FT_FRAME_ULONG( nClasses ),
+ FT_FRAME_ULONG( classTableOffset ),
+ FT_FRAME_ULONG( stateArrayOffset ),
+ FT_FRAME_ULONG( entryTableOffset ),
+ FT_FRAME_END
+ };
+ header->position = FT_STREAM_POS();
+ return FT_STREAM_READ_FIELDS( xstate_header_fields, header );
+ }
+
+ static FT_Error
+ gx_XStateTable_load_state_array( GX_Face face,
+ FT_Stream stream,
+ FT_ULong pos,
+ FT_ULong length,
+ FT_UShort* state_array )
+ {
+ FT_Error error;
+ FT_Int i;
+
+ if ( FT_STREAM_SEEK(pos) )
+ goto Exit;
+
+ if ( FT_FRAME_ENTER( sizeof (state_array[0]) * length ) )
+ goto Exit;
+
+ for ( i = 0; i < length; i++ )
+ state_array[i] = FT_GET_USHORT();
+
+ FT_FRAME_EXIT();
+ Exit:
+ return error;
+ }
+
+ static FT_UShort
+ gx_XStateTable_find_state_array_max_index (FT_ULong array_length, FT_UShort state_array[])
+ {
+ FT_ULong i;
+ FT_UShort max_index = 0;
+ for ( i = 0; i < array_length; i++ )
+ {
+ if ( state_array[i] > max_index )
+ max_index = state_array [i];
+ }
+ return max_index;
+ }
+
+#define LOOKUP_TABLE_CB_DATA_ZERO {NULL, NULL}
+ typedef struct lookup_table_cb_data_rec_
+ {
+ FT_Stream stream;
+ GX_LookupTable lookup_table;
+ FT_Long table_end;
+ } lookup_table_cb_data_rec, *lookup_table_cb_data;
+
+ static FT_Error
+ gx_XStateTable_LookupTable_segment_array_loader( GX_LookupTable_Format format,
+ FT_UShort lastGlyph,
+ FT_UShort firstGlyph,
+ GX_LookupValue value,
+ FT_Pointer user )
+ {
+ /* generic_lookup_table_segment_array_loader */
+ FT_Error error;
+ lookup_table_cb_data lookup_data = user;
+ FT_Stream stream = lookup_data->stream;
+ GX_LookupTable lookup_table = lookup_data->lookup_table;
+ FT_Memory memory = stream->memory;
+ FT_Short value_offset = value->raw.s;
+ FT_UShort segment_count = lastGlyph - firstGlyph + 1;
+ FT_UShort * segment;
+
+ FT_Int i;
+
+ /* -----------------------------------------------------------------
+ * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
+ * This code is correct?
+ * In spec: "Sometimes they are 16-bit offsets from the start of
+ * the table to the data. " The table? Is the table the lookup table
+ * or a table that uses the lookup table?
+ * Here I assume the table is the table that uses the lookup table.
+ * However, I have no conviction.
+ * It seems that pfaedit uses lookup_table_offset + value_offset.
+ * ----------------------------------------------------------------- */
+ FT_ASSERT(lookup_table->position + value_offset < lookup_data->table_end);
+ if (FT_STREAM_SEEK( lookup_table->position + value_offset ) )
+ goto Exit;
+
+ if ( FT_NEW_ARRAY(segment, segment_count ) )
+ goto Exit;
+
+ if ( FT_FRAME_ENTER ( sizeof( segment[0] ) * segment_count ) )
+ goto Failure;
+ for ( i = 0; i < segment_count; i++ )
+ segment[i] = FT_GET_USHORT();
+ FT_FRAME_EXIT();
+ value->extra.word = segment;
+ Exit:
+ return error;
+ Failure:
+ /* TODO
+ Other value->extra.wordS loaded before the visitation to this
+ value->extra.word must be freed if an error is occurred during
+ traverse. */
+ FT_FREE(segment);
+ return error;
+ }
+
+ FT_LOCAL_DEF ( FT_Error )
+ gx_face_load_XStateTable ( GX_Face face,
+ FT_Stream stream,
+ GX_XStateTable state_table,
+ GX_XStateTable_Entry_Load_Funcs funcs,
+ FT_Pointer user )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+ GX_XStateHeader header;
+ FT_ULong state_array_len; /* in word */
+ FT_UShort * state_array = NULL;
+ GX_EntrySubtable entry_subtable = NULL;
+ FT_ULong pos;
+ GX_XStateTable_Entry_Load_FuncsRec default_XStateTable_funcs = GX_XSTATE_TABLE_ENTRY_LOAD_FUNCS_ZERO;
+ GX_LookupTable_FuncsRec default_LookupTable_funcs = GX_LOOKUP_TABLE_FUNC_ZERO;
+ lookup_table_cb_data_rec lookup_table_cb_data = LOOKUP_TABLE_CB_DATA_ZERO;
+
+ default_XStateTable_funcs.loader = gx_XStateTable_Entry_default_loader;
+ default_XStateTable_funcs.finalizer = gx_XStateTable_Entry_default_finalizer;
+
+ default_LookupTable_funcs.segment_array_func = gx_XStateTable_LookupTable_segment_array_loader;
+
+ state_table->state_array = NULL;
+ state_table->entry_subtable = NULL;
+
+
+ /* 1. Header */
+ header = &state_table->header;
+ if (( error = gx_XStateTable_load_header( face, stream, header ) ))
+ goto Exit;
+
+ /* 2. class subtable */
+ pos = header->position + header->classTableOffset;
+ if ( FT_STREAM_SEEK( pos ) )
+ goto Exit;
+
+ if (( error = gx_face_load_LookupTable( face,
+ stream,
+ &state_table->class_subtable ) ))
+ goto Exit;
+
+ if ( state_table->class_subtable.format == GX_LOOKUPTABLE_SEGMENT_ARRAY )
+ {
+
+ lookup_table_cb_data.stream = stream;
+ lookup_table_cb_data.lookup_table = &state_table->class_subtable;
+ lookup_table_cb_data.table_end = header->position + header->stateArrayOffset;
+ if (( error = gx_LookupTable_traverse_low( & state_table->class_subtable,
+ & default_LookupTable_funcs,
+ & lookup_table_cb_data ) ))
+ goto Failure;
+ }
+
+ /* 3. state array */
+ /* To calculate the length of stateArray, we assume
+ the order of fields placement is classTable, stateArray,
+ entryTable */
+ FT_ASSERT( header->classTableOffset < header->stateArrayOffset );
+ FT_ASSERT( header->stateArrayOffset < header->entryTableOffset );
+
+ pos = header->position + header->stateArrayOffset;
+ state_array_len = (header->entryTableOffset - header->stateArrayOffset) / sizeof( state_array[0] );
+ state_table->nStates = state_array_len / header->nClasses;
+ /* Calculate state_array_len again.
+ state_array_len must be a multiple of header->nClasses. */
+ state_array_len = state_table->nStates * header->nClasses;
+
+ if (( FT_NEW_ARRAY ( state_array, state_array_len ) ))
+ goto Failure;
+
+ if (( error = gx_XStateTable_load_state_array( face,
+ stream,
+ pos,
+ state_array_len,
+ state_array ) ))
+ goto Failure;
+
+ /* 4. entry subtable */
+ if ( funcs )
+ {
+ if (! funcs->loader )
+ funcs->loader = gx_XStateTable_Entry_default_loader;
+ if (! funcs->finalizer )
+ funcs->finalizer = gx_XStateTable_Entry_default_finalizer;
+ }
+ else
+ funcs = &default_XStateTable_funcs;
+
+ pos = header->position + header->entryTableOffset;
+ state_table->nEntries = 1+ gx_XStateTable_find_state_array_max_index( state_array_len,
+ state_array );
+ if (( FT_NEW_ARRAY( entry_subtable, state_table->nEntries) ))
+ goto Failure;
+ if (( error = gx_XStateTable_load_entry_subtable( face,
+ stream,
+ pos,
+ state_table->nEntries,
+ entry_subtable,
+ funcs,
+ user) ))
+ goto Failure;
+ state_table->state_array = state_array;
+ state_table->entry_subtable = entry_subtable;
+ Exit:
+ return error;
+ Failure:
+ if ( entry_subtable )
+ FT_FREE ( entry_subtable );
+ if ( state_array )
+ FT_FREE(state_array);
+ gx_LookupTable_free( & state_table->class_subtable, memory );
+ return error;
+ }
+
+ FT_LOCAL_DEF ( FT_Error )
+ gx_XStateTable_traverse_entries( GX_XStateTable state_table,
+ GX_XStateTable_Entry_Action action,
+ FT_Pointer user )
+ {
+ return gx_EntrySubtable_traverse( state_table->entry_subtable,
+ state_table->nEntries,
+ action,
+ user );
+ }
+
+ static FT_Error
+ gx_XStateTable_LookupTable_segment_array_finalizer ( GX_LookupTable_Format format,
+ FT_UShort lastGlyph,
+ FT_UShort firstGlyph,
+ GX_LookupValue value,
+ FT_Pointer user )
+ {
+ /* TODO: Merge generic_lookup_table_segment_array_finalizer */
+ FT_Memory memory = user;
+ FT_UShort * segment = value->extra.word;
+ if ( !segment )
+ return GX_Err_Ok;
+
+ value->extra.word = NULL;
+ FT_FREE(segment);
+ return GX_Err_Ok;
+ }
+
+ FT_LOCAL_DEF ( void )
+ gx_XStateTable_free ( GX_XStateTable state_table,
+ FT_Memory memory,
+ GX_XStateTable_Entry_Finalizer finalizer,
+ FT_Pointer user )
+ {
+ GX_LookupTable_FuncsRec lookup_table_funcs = GX_LOOKUP_TABLE_FUNC_ZERO;
+
+ lookup_table_funcs.segment_array_func = gx_XStateTable_LookupTable_segment_array_finalizer;
+
+ if ( finalizer == NULL )
+ finalizer = gx_StateTable_Entry_default_finalizer;
+ gx_XStateTable_free_entry_subtable ( memory,
+ state_table->nEntries,
+ state_table->entry_subtable,
+ finalizer,
+ user );
+ FT_FREE( state_table->entry_subtable );
+ state_table->entry_subtable = NULL;
+
+ FT_FREE( state_table->state_array );
+ state_table->state_array = NULL;
+
+
+ if ( state_table->class_subtable.format == GX_LOOKUPTABLE_SEGMENT_ARRAY )
+ gx_LookupTable_traverse_low( & state_table->class_subtable,
+ &lookup_table_funcs,
+ memory );
+ gx_LookupTable_free( & state_table->class_subtable, memory );
+ }
+
+ FT_LOCAL_DEF ( FT_UShort )
+ gx_XStateTable_get_class ( GX_XStateTable state_table,
+ FT_UShort glyph )
+ {
+ GX_LookupTable class_subtable;
+ GX_LookupResultRec result;
+ FT_UShort class_code;
+
+ class_subtable = &state_table->class_subtable;
+ result = gx_LookupTable_lookup ( class_subtable,
+ glyph );
+
+ if ( result.value == NULL )
+ class_code = GX_CLASS_OUT_OF_BOUNDS;
+ else if ( result.firstGlyph == GX_LOOKUP_RESULT_NO_FIRST_GLYPH )
+ class_code = result.value->raw.u;
+ else
+ class_code = result.value->extra.word[glyph - result.firstGlyph];
+ return class_code;
+ }
+
+ FT_LOCAL ( GX_EntrySubtable )
+ gx_XStateTable_get_entry_subtable ( GX_XStateTable state_table,
+ FT_UShort current_state,
+ FT_UShort class_code )
+ {
+ GX_XStateHeader header = &state_table->header;
+ FT_UShort * state_array = state_table->state_array;
+ FT_UShort * state_array_for_current_state;
+ FT_UShort entry_index;
+ GX_EntrySubtable entry_subtable;
+
+ FT_ASSERT( current_state < state_table->nStates );
+ FT_ASSERT( class_code < header->nClasses );
+ state_array_for_current_state = &state_array[current_state * header->nClasses];
+ entry_index = state_array_for_current_state[class_code];
+ FT_ASSERT( entry_index < state_table->nEntries );
+ entry_subtable = &state_table->entry_subtable[entry_index];
+ return entry_subtable;
+ }
+
+/* END */
diff --git a/src/gxlayout/gxstatetbl.h b/src/gxlayout/gxstatetbl.h
new file mode 100644
index 000000000..0ccbf88b9
--- /dev/null
+++ b/src/gxlayout/gxstatetbl.h
@@ -0,0 +1,128 @@
+/***************************************************************************/
+/* */
+/* gxstatetbl.h */
+/* */
+/* AAT/TrueTypeGX state table related types and functions */
+/* (specification). */
+/* */
+/* Copyright 2003 by */
+/* Masatake YAMATO and Redhat K.K. */
+/* */
+/* This file may only be used, */
+/* modified, and distributed under the terms of the FreeType project */
+/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
+/* this file you indicate that you have read the license and */
+/* understand and accept it fully. */
+/* */
+/***************************************************************************/
+
+/***************************************************************************/
+/* Development of the code in this file is support of */
+/* Information-technology Promotion Agency, Japan. */
+/***************************************************************************/
+
+
+#ifndef __GXSTATETBL_H_
+#define __GXSTATETBL_H_
+
+#include <ft2build.h>
+#include FT_TYPES_H
+#include "gxtypes.h"
+
+FT_BEGIN_HEADER
+
+/* - GX_StateTable_Entry_Loader
+ Fill entry_subtable->glyphOffsets and
+ update stream to read next entry_subtable. */
+ typedef FT_Error
+ (* GX_StateTable_Entry_Loader) ( GX_Face face,
+ FT_Stream stream,
+ GX_EntrySubtable entry_subtable,
+ FT_Pointer user );
+ typedef void
+ (* GX_StateTable_Entry_Finalizer) ( FT_Memory memory,
+ GX_EntrySubtable entry_subtable,
+ FT_Pointer user );
+
+ typedef FT_Error
+ (* GX_StateTable_Entry_Action) ( GX_EntrySubtable entry_subtable,
+ FT_Pointer user );
+
+#define GX_STATE_TABLE_ENTRY_LOAD_FUNCS_ZERO {NULL, NULL}
+ typedef struct GX_StateTable_Entry_Load_FuncsRec_
+ {
+ GX_StateTable_Entry_Loader loader;
+ GX_StateTable_Entry_Finalizer finalizer;
+ } GX_StateTable_Entry_Load_FuncsRec, *GX_StateTable_Entry_Load_Funcs;
+
+ FT_LOCAL ( FT_Error )
+ gx_face_load_StateTable ( GX_Face face,
+ FT_Stream stream,
+ GX_StateTable state_table,
+ GX_StateTable_Entry_Load_Funcs funcs,
+ FT_Pointer user );
+
+ FT_LOCAL ( void )
+ gx_StateTable_free ( GX_StateTable state_table,
+ FT_Memory memory,
+ GX_StateTable_Entry_Finalizer finalizer,
+ FT_Pointer user );
+
+/* If action returns value other than FT_Err_Ok, the traverse stops
+ at that point and returns. */
+#if 0
+ FT_LOCAL ( FT_Error )
+ gx_StateTable_traverse_entries( GX_StateTable state_table,
+ GX_StateTable_Entry_Action action,
+ FT_Pointer user );
+#endif /* 0 */
+
+
+ FT_LOCAL ( FT_Byte )
+ gx_StateTable_get_class ( GX_StateTable state_table,
+ FT_UShort glyph );
+
+ FT_LOCAL ( GX_EntrySubtable )
+ gx_StateTable_get_entry_subtable ( GX_StateTable state_table,
+ FT_UShort current_state,
+ FT_Byte class_code );
+
+#define GX_XSTATE_TABLE_ENTRY_LOAD_FUNCS_ZERO {NULL, NULL}
+ typedef GX_StateTable_Entry_Load_FuncsRec GX_XStateTable_Entry_Load_FuncsRec;
+ typedef GX_StateTable_Entry_Load_Funcs GX_XStateTable_Entry_Load_Funcs;
+ typedef GX_StateTable_Entry_Loader GX_XStateTable_Entry_Loader;
+ typedef GX_StateTable_Entry_Finalizer GX_XStateTable_Entry_Finalizer;
+ typedef GX_StateTable_Entry_Action GX_XStateTable_Entry_Action;
+
+ FT_LOCAL ( FT_Error )
+ gx_face_load_XStateTable ( GX_Face face,
+ FT_Stream stream,
+ GX_XStateTable state_table,
+ GX_XStateTable_Entry_Load_Funcs funcs,
+ FT_Pointer user );
+
+ FT_LOCAL ( FT_Error )
+ gx_XStateTable_traverse_entries( GX_XStateTable state_table,
+ GX_XStateTable_Entry_Action action,
+ FT_Pointer user );
+
+ FT_LOCAL ( void )
+ gx_XStateTable_free ( GX_XStateTable state_table,
+ FT_Memory memory,
+ GX_XStateTable_Entry_Finalizer finalizer,
+ FT_Pointer user );
+
+ FT_LOCAL ( FT_UShort )
+ gx_XStateTable_get_class ( GX_XStateTable state_table,
+ FT_UShort glyph );
+
+ FT_LOCAL ( GX_EntrySubtable )
+ gx_XStateTable_get_entry_subtable ( GX_XStateTable state_table,
+ FT_UShort current_state,
+ FT_UShort class_code );
+
+FT_END_HEADER
+
+#endif /* Not def: __GXSTATETBL_H_ */
+
+/* END */
diff --git a/src/gxlayout/gxtypes.h b/src/gxlayout/gxtypes.h
new file mode 100644
index 000000000..fa9879afc
--- /dev/null
+++ b/src/gxlayout/gxtypes.h
@@ -0,0 +1,1238 @@
+/***************************************************************************/
+/* */
+/* gxtypes.h */
+/* */
+/* AAT/TrueTypeGX lower level type definitions */
+/* (specification). */
+/* */
+/* Copyright 2003 by */
+/* Masatake YAMATO and Redhat K.K. */
+/* */
+/* This file may only be used, */
+/* modified, and distributed under the terms of the FreeType project */
+/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
+/* this file you indicate that you have read the license and */
+/* understand and accept it fully. */
+/* */
+/***************************************************************************/
+
+/***************************************************************************/
+/* Development of the code in this file is support of */
+/* Information-technology Promotion Agency, Japan. */
+/***************************************************************************/
+
+#ifndef __GXTYPES_H__
+#define __GXTYPES_H__
+
+#include <ft2build.h>
+#include FT_TYPES_H
+#include FT_INTERNAL_TRUETYPE_TYPES_H
+#include FT_INTERNAL_FTL_TYPES_H
+
+FT_BEGIN_HEADER
+
+/***************************************************************************/
+/* Forward Declarations */
+/***************************************************************************/
+typedef TT_Face GX_Face;
+typedef struct GXL_FontRec_ * GXL_Font;
+typedef struct GX_TableRec_ * GX_Table;
+
+typedef struct GX_MetamorphosisContextualPerGlyphRec_ *GX_MetamorphosisContextualPerGlyph;
+typedef struct GX_MetamorphosisInsertionPerGlyphRec_ *GX_MetamorphosisInsertionPerGlyph;
+typedef struct GX_XMetamorphosisContextualPerGlyphRec_ *GX_XMetamorphosisContextualPerGlyph;
+typedef union GX_OpticalBoundsDataRec_ *GX_OpticalBoundsData;
+typedef struct GX_LigCaretClassEntryRec_ *GX_LigCaretClassEntry;
+typedef struct GX_LigCaretSegmentRec_ *GX_LigCaretSegment;
+
+/***************************************************************************/
+/* BinSrchHeader */
+/***************************************************************************/
+ typedef struct GX_BinSrchHeaderRec_
+ {
+ FT_UShort unitSize;
+ FT_UShort nUnits;
+ FT_UShort searchRange;
+ FT_UShort entrySelector;
+ FT_UShort rangeShift;
+ } GX_BinSrchHeaderRec, *GX_BinSrchHeader;
+
+/***************************************************************************/
+/* LookupTable */
+/***************************************************************************/
+ typedef union GX_LookupValueExtraDesc_
+ {
+ GX_OpticalBoundsData opbd_data;
+ GX_LigCaretClassEntry lcar_class_entry;
+ GX_LigCaretSegment lcar_segment;
+ FT_UShort *word;
+ FT_Pointer any;
+ } GX_LookupValueExtraDesc, *GX_LookupValueExtra;
+ typedef union GX_LookupValueRawDesc_
+ {
+ FT_UShort u;
+ FT_Short s;
+ } GX_LookupValueRawDesc, *GX_LookupValueRaw;
+
+ typedef struct GX_LookupValueRec_
+ {
+ GX_LookupValueRawDesc raw;
+ GX_LookupValueExtraDesc extra;
+ } GX_LookupValueRec, *GX_LookupValue;
+
+ typedef enum
+ {
+ GX_LOOKUPTABLE_SIMPLE_ARRAY = 0,
+ GX_LOOKUPTABLE_SEGMENT_SINGLE = 2,
+ GX_LOOKUPTABLE_SEGMENT_ARRAY = 4,
+ GX_LOOKUPTABLE_SINGLE_TABLE = 6,
+ GX_LOOKUPTABLE_TRIMMED_ARRAY = 8
+ } GX_LookupTable_Format;
+
+ typedef struct GX_LookupSegmentRec_
+ {
+ FT_UShort lastGlyph;
+ FT_UShort firstGlyph;
+ GX_LookupValueRec value;
+ } GX_LookupSegmentRec, *GX_LookupSegment;
+
+ typedef struct GX_LookupSingleRec_
+ {
+ FT_UShort glyph;
+ GX_LookupValueRec value;
+ } GX_LookupSingleRec, *GX_LookupSingle;
+
+ typedef struct GX_LookupTable_BinSrchRec_
+ {
+ GX_BinSrchHeaderRec binSrchHeader;
+ FT_Pointer dummy;
+ } GX_LookupTable_BinSrchRec, *GX_LookupTable_BinSrch;
+
+ typedef struct GX_LookupTable_SegmentRec_
+ {
+ GX_BinSrchHeaderRec binSrchHeader;
+ GX_LookupSegment segments;
+ } GX_LookupTable_SegmentRec, *GX_LookupTable_Segment;
+
+ typedef struct GX_LookupTable_Single_TableRec_
+ {
+ GX_BinSrchHeaderRec binSrchHeader;
+ GX_LookupSingle entries;
+ } GX_LookupTable_Single_TableRec, *GX_LookupTable_Single_Table;
+
+ typedef struct GX_LookupTable_Trimmed_ArrayRec_
+ {
+ FT_UShort firstGlyph;
+ FT_UShort glyphCount;
+ GX_LookupValue valueArray;
+ } GX_LookupTable_Trimmed_ArrayRec, *GX_LookupTable_Trimmed_Array;
+
+ typedef union GX_LookupFormatSpecificDesc_
+ {
+ GX_LookupValue simple_array;
+ GX_LookupTable_BinSrch bin_srch;
+ GX_LookupTable_Segment segment_generic;
+ GX_LookupTable_Segment segment_single;
+ GX_LookupTable_Segment segment_array;
+ GX_LookupTable_Single_Table single_table;
+ GX_LookupTable_Trimmed_Array trimmed_array;
+ FT_Pointer any;
+ } GX_LookupFormatSpecificDesc, *GX_LookupFormatSpecific;
+
+ typedef struct GX_LookupTableRec_
+ {
+ FT_ULong position; /* The file position of lookup table.
+ not in the spec but necessary to access format 4 datum.
+ Not only for debug. */
+ FT_Long num_glyphs; /* not in the spec but necessary to access format 0 */
+ FT_UShort format;
+ GX_LookupFormatSpecificDesc fsHeader;
+ } GX_LookupTableRec, *GX_LookupTable;
+
+
+/***************************************************************************/
+/* StateTable */
+/***************************************************************************/
+#define GX_STATE_HEADER_ADVANCE 8
+ typedef struct GX_StateHeaderRec_
+ {
+ FT_ULong position; /* The file position of state table. (not in the spec) */
+
+ FT_UShort stateSize;
+ FT_UShort classTable;
+ FT_UShort stateArray;
+ FT_UShort entryTable;
+ } GX_StateHeaderRec, *GX_StateHeader;
+
+#define GX_DELETED_GLYPH_INDEX 0xFFFF
+ typedef enum
+ {
+ GX_CLASS_END_OF_TEXT = 0,
+ GX_CLASS_OUT_OF_BOUNDS = 1,
+ GX_CLASS_DELETED_GLYPH = 2,
+ GX_CLASS_END_OF_LINE = 3,
+ GX_CLASS_YOURS_START = 4
+ } GX_Predefined_ClassCode;
+
+ typedef struct GX_ClassSubtableRec_
+ {
+ FT_UShort firstGlyph;
+ FT_UShort nGlyphs;
+ FT_Byte *classArray;
+ } GX_ClassSubtableRec, * GX_ClassSubtable;
+
+ typedef union GX_EntrySubtablePerGlyphDesc_
+ {
+ GX_MetamorphosisContextualPerGlyph contextual;
+ GX_MetamorphosisInsertionPerGlyph insertion;
+ GX_XMetamorphosisContextualPerGlyph xcontextual;
+ FT_UShort ligActionIndex; /* For morx::ligatureSubtable */
+ FT_Pointer any;
+ } GX_EntrySubtablePerGlyphDesc, * GX_EntrySubtablePerGlyph;
+
+ typedef struct GX_EntrySubtableRec_
+ {
+ FT_UShort newState;
+ FT_UShort flags;
+ GX_EntrySubtablePerGlyphDesc glyphOffsets;
+ } GX_EntrySubtableRec, *GX_EntrySubtable;
+
+
+ typedef struct GX_StateTableRec_
+ {
+ GX_StateHeaderRec header;
+ FT_ULong nStates; /* Number of States. (not in the spec) */
+ FT_Byte nEntries; /* Number of entries. (not in the spec) */
+ GX_ClassSubtableRec class_subtable;
+ FT_Byte * state_array;
+ GX_EntrySubtable entry_subtable;
+ } GX_StateTableRec, *GX_StateTable;
+
+/***************************************************************************/
+/* Extended StateTable */
+/***************************************************************************/
+#define GX_XSTATE_HEADER_ADVANCE 16
+ typedef struct GX_XStateHeaderRec_
+ {
+ FT_ULong position; /* The file position of X state table. (not in the spec) */
+
+ FT_ULong nClasses;
+ FT_ULong classTableOffset;
+ FT_ULong stateArrayOffset;
+ FT_ULong entryTableOffset;
+ } GX_XStateHeaderRec, *GX_XStateHeader;
+
+ typedef struct GX_XStateTableRec_
+ {
+ GX_XStateHeaderRec header;
+ FT_ULong nStates; /* Number of States. (not in the spec) */
+ FT_Long nEntries; /* Number of entries. (not in the spec) */
+ GX_LookupTableRec class_subtable;
+ FT_UShort * state_array;
+ GX_EntrySubtable entry_subtable;
+ } GX_XStateTableRec, *GX_XStateTable;
+
+
+/***************************************************************************/
+/* GX_Table */
+/***************************************************************************/
+ typedef void
+ (* GX_Table_Done_Func) ( GX_Table table, FT_Memory memory );
+
+ typedef struct GX_TableRec_
+ {
+ /* If the status of a tag is GX_LOAD_LAZY or
+ GX_LOAD_SUCCESSFUL, table position and length
+ should be available. The value might be useful
+ to debug.*/
+ GXL_Font font;
+ FT_ULong position;
+ FT_ULong length;
+ GX_Table_Done_Func done_table;
+ } GX_TableRec; /* , *GX_Table; */
+
+/***************************************************************************/
+/* FEAT */
+/***************************************************************************/
+ typedef enum
+ {
+ GX_FEAT_MASK_EXCLUSIVE_SETTINGS = 0x8000,
+ GX_FEAT_MASK_DYNAMIC_DEFAULT = 0x4000,
+ GX_FEAT_MASK_UNUSED = 0x3F00,
+ GX_FEAT_MASK_DEFAULT_SETTING = 0x00FF
+ } GX_FeatureFlagsMask ;
+
+ typedef struct GX_FeatureSettingNameRec_
+ {
+ FT_UShort setting;
+ FT_Short nameIndex;
+ } GX_FeatureSettingNameRec, *GX_FeatureSettingName;
+
+ typedef struct GX_FeatureNameRec_
+ {
+ FT_UShort feature;
+ FT_UShort nSettings;
+ FT_ULong settingTable;
+ FT_UShort featureFlags; /* use with GX_FeatureFlagsMask */
+ FT_Short nameIndex;
+ GX_FeatureSettingName settingName;
+ } GX_FeatureNameRec, *GX_FeatureName;
+
+ typedef struct GX_FeatRec_
+ {
+ GX_TableRec root;
+ FT_Fixed version;
+ FT_UShort featureNameCount;
+ FT_UShort reserved1;
+ FT_ULong reserved2;
+ GX_FeatureName names; /* names[featureNameCount] */
+ } GX_FeatRec, *GX_Feat;
+
+/***************************************************************************/
+/* TRAK */
+/***************************************************************************/
+ typedef struct GX_TrackTableEntryRec_
+ {
+ FT_Fixed track; /* MUST */
+ FT_UShort nameIndex; /* MUST */
+ FT_UShort offset; /* USED DURING LOADING */
+ FT_FWord *tracking_value; /* tracking_value[nSizes], MUST
+ * This field name, `tracking_value'
+ * is no appeared on the specification.
+ */
+ } GX_TrackTableEntryRec, *GX_TrackTableEntry;
+
+ typedef struct GX_TrackDataRec_
+ {
+ FT_UShort nTracks; /* MUST */
+ FT_UShort nSizes; /* MUST */
+ FT_ULong sizeTableOffset; /* USED DURING LOADING */
+ GX_TrackTableEntry trackTable; /* MUST */
+ FT_Fixed *sizeTable; /* MUST, ???fixed32 */
+
+ } GX_TrackDataRec, *GX_TrackData;
+
+ typedef struct GX_TrakRec_
+ {
+ GX_TableRec root;
+ FT_Fixed version; /* ???fixed */
+ FT_UShort format;
+ FT_UShort horizOffset; /* USED DURING LOADING */
+ FT_UShort vertOffset; /* USED DURING LOADING */
+ FT_UShort reserved; /* ??? */
+ GX_TrackDataRec horizData; /* MUST */
+ GX_TrackDataRec vertData; /* MUST */
+ } GX_TrakRec, *GX_Trak;
+
+/***************************************************************************/
+/* PROP */
+/***************************************************************************/
+ typedef enum
+ {
+ GX_PROP_MASK_FLOATER = 0x8000,
+ GX_PROP_MASK_HANG_OFF_LEFT_TOP = 0x4000,
+ GX_PROP_MASK_HANG_OFF_RIGHT_BOTTOM = 0x2000,
+ GX_PROP_MASK_USE_COMPLEMENTARY_BRACKET = 0x1000,
+ GX_PROP_MASK_COMPLEMENTARY_BRACKET_OFFSET = 0x0F00,
+ GX_PROP_MASK_ATTACHING_TO_RIGHT = 0x0080,
+ GX_PROP_MASK_RESERVED = 0x0060,
+ GX_PROP_MASK_DIRECTIONALITY_CLASS = 0x001F
+ } GX_PropertyMask ;
+
+ typedef struct GX_PropRec_
+ {
+ GX_TableRec root;
+ FT_Fixed version;
+ FT_UShort format;
+ FT_UShort default_properties;
+ GX_LookupTableRec lookup_data;
+ } GX_PropRec, *GX_Prop;
+
+/***************************************************************************/
+/* OPBD */
+/***************************************************************************/
+#define GX_OPBD_NO_OPTICAL_EDGE -1
+ typedef enum
+ {
+ GX_OPBD_DISTANCE = 0,
+ GX_OPBD_CONTROL_POINTS = 1
+ } GX_OpticalBoundsFormat ;
+
+ typedef struct GX_OpbdRec_
+ {
+ GX_TableRec root;
+ FT_Fixed version;
+ FT_UShort format;
+ GX_LookupTableRec lookup_data;
+ } GX_OpbdRec, *GX_Opbd;
+
+ typedef union GX_OpticalBoundsDataRec_
+ {
+ struct {
+ FT_FWord left_side;
+ FT_FWord top_side;
+ FT_FWord right_side;
+ FT_FWord bottom_side;
+ } distance;
+ struct {
+ FT_Short left_side;
+ FT_Short top_side;
+ FT_Short right_side;
+ FT_Short bottom_side;
+ } control_points;
+ } GX_OpticalBoundsDataRec;/*, *GX_OpticalBoundsData; */
+
+/***************************************************************************/
+/* LCAR */
+/***************************************************************************/
+ typedef enum
+ {
+ GX_LCAR_DISTANCE = 0,
+ GX_LCAR_CONTROL_POINTS = 1
+ } GX_LigCaretFormat ;
+
+ typedef struct GX_LcarRec_
+ {
+ GX_TableRec root;
+ FT_Fixed version;
+ FT_UShort format;
+ GX_LookupTableRec lookup;
+ } GX_LcarRec, *GX_Lcar;
+
+ /* Normally each value->extra in lookup points to GX_LigCaretClassEntry.
+ If lcar->format is GX_LOOKUPTABLE_SEGMENT_ARRAY, each value->extra
+ points to GX_LigCaretSegment data. */
+ typedef struct GX_LigCaretClassEntryRec_
+ {
+ FT_UShort count;
+ FT_Short *partials;
+ } GX_LigCaretClassEntryRec; /* , *GX_LigCaretClassEntry; */
+
+ typedef struct GX_LigCaretSegmentRec_
+ {
+ FT_UShort offset;
+ GX_LigCaretClassEntry class_entry;
+ } GX_LigCaretSegmentRec; /* , *GX_LigCaretSegment; */
+
+/***************************************************************************/
+/* BSLN */
+/***************************************************************************/
+#define GX_BSLN_VALUE_COUNT 32
+#define GX_BSLN_VALUE_EMPTY 0xFFFF
+
+ typedef enum
+ {
+ GX_BSLN_VALUE_ROMAN_BASELINE = 0,
+ GX_BSLN_VALUE_IDEOGRAPHIC_CENTERED_BASELINE = 1,
+ GX_BSLN_VALUE_IDEOGRAPHIC_LOW_BASELINE = 2,
+ GX_BSLN_VALUE_HANGING_BASELINE = 3,
+ GX_BSLN_VALUE_MATH_BASELINE = 4
+ } GX_BaselinePredefinedValue;
+
+ typedef enum
+ {
+ GX_BSLN_FMT_DISTANCE_NO_MAPPING = 0,
+ GX_BSLN_FMT_DISTANCE_WITH_MAPPING = 1,
+ GX_BSLN_FMT_CONTROL_POINT_NO_MAPPING = 2,
+ GX_BSLN_FMT_CONTROL_POINT_WITH_MAPPING = 3
+ } GX_BaselineFormat;
+
+ typedef struct GX_BaselineFormat0PartRec_
+ {
+ FT_UShort deltas[GX_BSLN_VALUE_COUNT];
+ } GX_BaselineFormat0PartRec, *GX_BaselineFormat0Part;
+
+ typedef struct GX_BaselineFormat1PartRec_
+ {
+ FT_UShort deltas[GX_BSLN_VALUE_COUNT];
+ GX_LookupTableRec mappingData;
+ } GX_BaselineFormat1PartRec, *GX_BaselineFormat1Part;
+
+ typedef struct GX_BaselineFormat2PartRec_
+ {
+ FT_UShort stdGlyph;
+ FT_UShort ctlPoints[GX_BSLN_VALUE_COUNT];
+ } GX_BaselineFormat2PartRec, *GX_BaselineFormat2Part;
+
+ typedef struct GX_BaselineFormat3PartRec_
+ {
+ FT_UShort stdGlyph;
+ FT_UShort ctlPoints[GX_BSLN_VALUE_COUNT];
+ GX_LookupTableRec mappingData;
+ } GX_BaselineFormat3PartRec, *GX_BaselineFormat3Part;
+
+ typedef union GX_BaselinePartsDesc_
+ {
+ GX_BaselineFormat0Part fmt0;
+ GX_BaselineFormat1Part fmt1;
+ GX_BaselineFormat2Part fmt2;
+ GX_BaselineFormat3Part fmt3;
+ FT_Pointer any;
+ } GX_BaselinePartsDesc, *GX_BaselineParts;
+
+ typedef struct GX_BslnRec_
+ {
+ GX_TableRec root;
+ FT_Fixed version;
+ FT_UShort format;
+ FT_UShort defaultBaseline;
+ GX_BaselinePartsDesc parts;
+ } GX_BslnRec, *GX_Bsln;
+
+/***************************************************************************/
+/* MORT */
+/***************************************************************************/
+
+ typedef enum
+ {
+ GX_MORT_COVERAGE_HORIZONTAL_OR_VERTICAL_TEXT = 0x8000,
+ GX_MORT_COVERAGE_ORDER_OF_PROCESSING_GLYPH_ARRAY = 0x4000,
+ GX_MORT_COVERAGE_ORIENTATION_INDEPENDENT = 0x2000,
+ GX_MORT_COVERAGE_RESERVED = 0x1FF8,
+ GX_MORT_COVERAGE_SUBTABLE_TYPE = 0x0007
+ } GX_MetamorphosisCoverageMask;
+
+ typedef enum
+ {
+ GX_MORT_REARRANGEMENT_SUBTABLE = 0,
+ GX_MORT_CONTEXTUAL_SUBTABLE = 1,
+ GX_MORT_LIGATURE_SUBTABLE = 2,
+ GX_MORT_RESERVED_SUBTABLE = 3,
+ GX_MORT_NONCONTEXTUAL_SUBTABLE = 4,
+ GX_MORT_INSERTION_SUBTABLE = 5
+ } GX_MetamorphosisSubtableType;
+
+ typedef enum
+ {
+ GX_MORT_LIGATURE_FLAGS_SET_COMPONENT = 0x8000,
+ GX_MORT_LIGATURE_FLAGS_DONT_ADVANCE = 0x4000,
+ GX_MORT_LIGATURE_FLAGS_OFFSET = 0x3FFF
+ } GX_MetamorphosisLigatureFlagsMask;
+
+#if 0
+ typedef enum
+ {
+ GX_MORT_LIGATURE_ACTION_LAST = 0x80000000,
+ GX_MORT_LIGATURE_ACTION_STORE = 0x40000000,
+ GX_MORT_LIGATURE_ACTION_OFFSET = 0x3FFFFFFF
+ } GX_MetamorphosisLigatureActionMask;
+#else
+ typedef FT_ULong GX_MetamorphosisLigatureActionMask;
+#define GX_MORT_LIGATURE_ACTION_LAST 0x80000000
+#define GX_MORT_LIGATURE_ACTION_STORE 0x40000000
+#define GX_MORT_LIGATURE_ACTION_OFFSET 0x3FFFFFFF
+#endif /* 0 */
+
+ typedef enum
+ {
+ GX_MORT_CONTEXTUAL_FLAGS_SET_MARK = 0x8000,
+ GX_MORT_CONTEXTUAL_FLAGS_DONT_ADVANCE = 0x4000,
+ GX_MORT_CONTEXTUAL_FLAGS_RESERVED = 0x3FFF
+ } GX_MetamorphosisContextualFlagsMask;
+
+ typedef enum
+ {
+ GX_MORT_REARRANGEMENT_FLAGS_MARK_FIRST = 0x8000,
+ GX_MORT_REARRANGEMENT_FLAGS_DONT_ADVANCE = 0x4000,
+ GX_MORT_REARRANGEMENT_FLAGS_MARK_LAST = 0x2000,
+ GX_MORT_REARRANGEMENT_FLAGS_RESERVED = 0x1FF0,
+ GX_MORT_REARRANGEMENT_FLAGS_VERB = 0x000F
+ } GX_MetamorphosisRearrangementFlagsMask;
+
+ typedef enum
+ {
+ GX_MORT_REARRANGEMENT_VERB_NO_CHANGE = 0,
+ GX_MORT_REARRANGEMENT_VERB_Ax2xA = 1,
+ GX_MORT_REARRANGEMENT_VERB_xD2Dx = 2,
+ GX_MORT_REARRANGEMENT_VERB_AxD2DxA = 3,
+ GX_MORT_REARRANGEMENT_VERB_ABx2xAB = 4,
+ GX_MORT_REARRANGEMENT_VERB_ABx2xBA = 5,
+ GX_MORT_REARRANGEMENT_VERB_xCD2CDx = 6,
+ GX_MORT_REARRANGEMENT_VERB_xCD2DCx = 7,
+ GX_MORT_REARRANGEMENT_VERB_AxCD2CDxA = 8,
+ GX_MORT_REARRANGEMENT_VERB_AxCD2DCxA = 9,
+ GX_MORT_REARRANGEMENT_VERB_ABxD2DxAB = 10,
+ GX_MORT_REARRANGEMENT_VERB_ABxD2DxBA = 11,
+ GX_MORT_REARRANGEMENT_VERB_ABxCD2CDxAB = 12,
+ GX_MORT_REARRANGEMENT_VERB_ABxCD2CDxBA = 13,
+ GX_MORT_REARRANGEMENT_VERB_ABxCD2DCxAB = 14,
+ GX_MORT_REARRANGEMENT_VERB_ABxCD2DCxBA = 15
+ } GX_MetamorphosisRearrangementVerb;
+
+ typedef enum
+ {
+ GX_MORT_INSERTION_FLAGS_SET_MARK = 0x8000,
+ GX_MORT_INSERTION_FLAGS_DONT_ADVANCE = 0x4000,
+ GX_MORT_INSERTION_FLAGS_CURRENT_IS_KASHIDA_LIKE = 0x2000,
+ GX_MORT_INSERTION_FLAGS_MARKED_IS_KASHIDA_LIKE = 0x1000,
+ GX_MORT_INSERTION_FLAGS_CURRENT_INSERT_BEFORE = 0x0800,
+ GX_MORT_INSERTION_FLAGS_MARKED_INSERT_BEFORE = 0x0400,
+ GX_MORT_INSERTION_FLAGS_CURRENT_INSERT_COUNT = 0x03E0,
+ GX_MORT_INSERTION_FLAGS_MARKED_INSERT_COUNT = 0x001F
+ } GX_MetamorphosisInsertionFlagsMask;
+
+/*
+ * Rearrangement
+ */
+ typedef struct GX_MetamorphosisRearrangementBodyRec_
+ {
+ GX_StateTableRec state_table;
+ } GX_MetamorphosisRearrangementBodyRec, *GX_MetamorphosisRearrangementBody;
+
+/*
+ * Contextual
+ */
+ typedef struct GX_MetamorphosisContextualSubstitutionTableRec_
+ {
+ FT_UShort offset; /* known as substitutionTable in the spec. */
+ FT_UShort nGlyphIndexes; /* Not in the spec */
+ FT_UShort * glyph_indexes;
+ } GX_MetamorphosisContextualSubstitutionTableRec, *GX_MetamorphosisContextualSubstitutionTable;
+
+ typedef struct GX_MetamorphosisContextualBodyRec_
+ {
+ GX_StateTableRec state_table;
+ GX_MetamorphosisContextualSubstitutionTableRec substitutionTable;
+ } GX_MetamorphosisContextualBodyRec, *GX_MetamorphosisContextualBody;
+
+ typedef struct GX_MetamorphosisContextualPerGlyphRec_
+ {
+ /* The spec says that the type of next two variable should be FT_UShort,
+ However the input gid [197 202] for /Library/Fonts/KufiStandarGK.ttf on MacOSX
+ are not substituted well; the substitution for the marked glyph si failed
+ because the `markOffset' is too large(65522). So I will change the type to
+ FT_Short. You can walk through all codes related to this type changing by
+
+ $ grep "Was:FT_UShort" *.c *.h
+
+ As far as my reading, ICU also does the same. */
+ FT_Short markOffset; /* Was:FT_UShort */
+ FT_Short currentOffset; /* Was:FT_UShort */
+ } GX_MetamorphosisContextualPerGlyphRec;/*, *GX_MetamorphosisContextualPerGlyph; */
+
+/*
+ * Ligature
+ */
+ typedef struct GX_MetamorphosisLigatureActionTableRec_
+ {
+ FT_UShort offset; /* known as ligActionTable in the spec. */
+ FT_UShort nActions;
+ FT_ULong *body;
+ } GX_MetamorphosisLigatureActionTableRec, *GX_MetamorphosisLigatureActionTable;
+
+ typedef struct GX_MetamorphosisComponentTableRec_
+ {
+ FT_UShort offset; /* known as componentTable in the spec. */
+ FT_UShort nComponent;
+ FT_UShort *body;
+ } GX_MetamorphosisComponentTableRec, *GX_MetamorphosisComponentTable;
+
+ typedef struct GX_MetamorphosisLigatureTableRec_
+ {
+ FT_UShort offset; /* known as ligatureTable in the spec. */
+ FT_UShort nLigature;
+ FT_UShort *body;
+ } GX_MetamorphosisLigatureTableRec, *GX_MetamorphosisLigatureTable;
+
+ typedef struct GX_MetamorphosisLigatureBodyRec_
+ {
+ GX_StateTableRec state_table;
+ GX_MetamorphosisLigatureActionTableRec ligActionTable;
+ GX_MetamorphosisComponentTableRec componentTable;
+ GX_MetamorphosisLigatureTableRec ligatureTable;
+ } GX_MetamorphosisLigatureBodyRec, *GX_MetamorphosisLigatureBody;
+
+/*
+ * Noncontextual
+ */
+ typedef struct GX_MetamorphosisNoncontextualBodyRec_
+ {
+ GX_LookupTableRec lookup_table;
+ } GX_MetamorphosisNoncontextualBodyRec, *GX_MetamorphosisNoncontextualBody;
+
+/*
+ * Insertion
+ */
+ typedef struct GX_MetamorphosisInsertionBodyRec_
+ {
+ GX_StateTableRec state_table;
+ } GX_MetamorphosisInsertionBodyRec, *GX_MetamorphosisInsertionBody;
+
+ typedef struct GX_MetamorphosisInsertionListRec_
+ {
+ FT_UShort offset; /* known as currentInsertList,
+ or makedInsertList in the sepc. */
+ FT_UShort * glyphcodes; /* Not in spec explicitly */
+ } GX_MetamorphosisInsertionListRec, *GX_MetamorphosisInsertionList;
+
+ typedef struct GX_MetamorphosisInsertionPerGlyphRec_
+ {
+ GX_MetamorphosisInsertionListRec currentInsertList;
+ GX_MetamorphosisInsertionListRec markedInsertList;
+ } GX_MetamorphosisInsertionPerGlyphRec;/*, *GX_MetamorphosisInsertionPerGlyph; */
+
+/*
+ * Generic
+ */
+ typedef struct GX_MetamorphosisSubtableHeaderRec_
+ {
+ FT_ULong position; /* not in the spec, just for DEBUG */
+ FT_UShort length;
+ FT_UShort coverage;
+ FT_ULong subFeatureFlags;
+ } GX_MetamorphosisSubtableHeaderRec, *GX_MetamorphosisSubtableHeader;
+
+ typedef union GX_MetamorphosisSubtableBodyDesc_
+ {
+ GX_MetamorphosisRearrangementBody rearrangement;
+ GX_MetamorphosisContextualBody contextual;
+ GX_MetamorphosisLigatureBody ligature;
+ GX_MetamorphosisNoncontextualBody noncontextual;
+ GX_MetamorphosisInsertionBody insertion;
+ FT_Pointer any;
+ } GX_MetamorphosisSubtableBodyDesc, *GX_MetamorphosisSubtableBody;
+ typedef struct GX_MetamorphosisSubtableRec_
+ {
+ GX_MetamorphosisSubtableHeaderRec header;
+ GX_MetamorphosisSubtableBodyDesc body;
+ } GX_MetamorphosisSubtableRec, *GX_MetamorphosisSubtable;
+
+ typedef struct GX_MetamorphosisFeatureTableRec_
+ {
+ FT_UShort featureType;
+ FT_UShort featureSetting;
+ FT_ULong enableFlags;
+ FT_ULong disableFlags;
+ } GX_MetamorphosisFeatureTableRec, *GX_MetamorphosisFeatureTable;
+
+ typedef struct GX_MetamorphosisChainHeaderRec_
+ {
+ FT_ULong defaultFlags;
+ FT_ULong chainLength;
+ FT_UShort nFeatureEntries;
+ FT_UShort nSubtables;
+ } GX_MetamorphosisChainHeaderRec, *GX_MetamorphosisChainHeader;
+
+ typedef struct GX_MetamorphosisChainRec_
+ {
+ GX_MetamorphosisChainHeaderRec header;
+ GX_MetamorphosisFeatureTable feat_Subtbl;
+ GX_MetamorphosisSubtable chain_Subtbl;
+ } GX_MetamorphosisChainRec, *GX_MetamorphosisChain;
+
+ typedef struct GX_MortRec_
+ {
+ GX_TableRec root;
+ FT_Fixed version;
+ FT_ULong nChains;
+ GX_MetamorphosisChain chain;
+ } GX_MortRec, *GX_Mort;
+
+
+/***************************************************************************/
+/* MORX */
+/***************************************************************************/
+
+#define GX_MORX_REARRANGEMENT_SUBTABLE GX_MORT_REARRANGEMENT_SUBTABLE
+#define GX_MORX_CONTEXTUAL_SUBTABLE GX_MORT_CONTEXTUAL_SUBTABLE
+#define GX_MORX_LIGATURE_SUBTABLE GX_MORT_LIGATURE_SUBTABLE
+#define GX_MORX_RESERVED_SUBTABLE GX_MORT_RESERVED_SUBTABLE
+#define GX_MORX_NONCONTEXTUAL_SUBTABLE GX_MORT_NONCONTEXTUAL_SUBTABLE
+#define GX_MORX_INSERTION_SUBTABLE GX_MORT_INSERTION_SUBTABLE
+
+ typedef GX_MetamorphosisFeatureTable GX_XMetamorphosisFeatureTable;
+ typedef GX_MetamorphosisFeatureTableRec GX_XMetamorphosisFeatureTableRec;
+ typedef GX_MetamorphosisSubtableType GX_XMetamorphosisSubtableType;
+
+#if 0
+ typedef enum
+ {
+ GX_MORX_COVERAGE_HORIZONTAL_OR_VERTICAL_TEXT = 0x80000000,
+ GX_MORX_COVERAGE_ORDER_OF_PROCESSING_GLYPH_ARRAY = 0x40000000,
+ GX_MORX_COVERAGE_ORIENTATION_INDEPENDENT = 0x20000000,
+ GX_MORX_COVERAGE_RESERVED = 0x1FFFFF00,
+ GX_MORX_COVERAGE_SUBTABLE_TYPE = 0x000000FF
+ } GX_XMetamorphosisCoverageMask;
+#else
+ typedef FT_ULong GX_XMetamorphosisCoverageMask;
+#define GX_MORX_COVERAGE_HORIZONTAL_OR_VERTICAL_TEXT 0x80000000
+#define GX_MORX_COVERAGE_ORDER_OF_PROCESSING_GLYPH_ARRAY 0x40000000
+#define GX_MORX_COVERAGE_ORIENTATION_INDEPENDENT 0x20000000
+#define GX_MORX_COVERAGE_RESERVED 0x1FFFFF00
+#define GX_MORX_COVERAGE_SUBTABLE_TYPE 0x000000FF
+#endif /* 0 */
+
+/*
+ * Rearrangement
+ */
+ typedef GX_MetamorphosisRearrangementVerb GX_XMetamorphosisRearrangementVerb;
+ typedef enum
+ {
+ GX_MORX_REARRANGEMENT_FLAGS_MARK_FIRST = GX_MORT_REARRANGEMENT_FLAGS_MARK_FIRST,
+ GX_MORX_REARRANGEMENT_FLAGS_DONT_ADVANCE = GX_MORT_REARRANGEMENT_FLAGS_DONT_ADVANCE,
+ GX_MORX_REARRANGEMENT_FLAGS_MARK_LAST = GX_MORT_REARRANGEMENT_FLAGS_MARK_LAST,
+ GX_MORX_REARRANGEMENT_FLAGS_RESERVED = GX_MORT_REARRANGEMENT_FLAGS_RESERVED,
+ GX_MORX_REARRANGEMENT_FLAGS_VERB = GX_MORT_REARRANGEMENT_FLAGS_VERB
+ } GX_XMetamorphosisRearrangementFlagsMask;
+
+ typedef struct GX_XMetamorphosisRearrangementBodyRec_
+ {
+ GX_XStateTableRec state_table;
+ } GX_XMetamorphosisRearrangementBodyRec, *GX_XMetamorphosisRearrangementBody;
+
+/*
+ * Contextual
+ */
+ typedef enum
+ {
+ GX_MORX_CONTEXTUAL_FLAGS_SET_MARK = GX_MORT_CONTEXTUAL_FLAGS_SET_MARK,
+ GX_MORX_CONTEXTUAL_FLAGS_DONT_ADVANCE = GX_MORT_CONTEXTUAL_FLAGS_DONT_ADVANCE,
+ GX_MORX_CONTEXTUAL_FLAGS_RESERVED = GX_MORT_CONTEXTUAL_FLAGS_RESERVED
+ } GX_XMetamorphosisContextualFlagsMask;
+
+
+ typedef struct GX_XMetamorphosisContextualSubstitutionTableRec_
+ {
+ FT_ULong offset;
+ FT_UShort nTables;
+ GX_LookupTable * lookupTables;
+ } GX_XMetamorphosisContextualSubstitutionTableRec, *GX_XMetamorphosisContextualSubstitutionTable;
+
+ typedef struct GX_XMetamorphosisContextualBodyRec_
+ {
+ GX_XStateTableRec state_table;
+ GX_XMetamorphosisContextualSubstitutionTableRec substitutionTable;
+ } GX_XMetamorphosisContextualBodyRec, *GX_XMetamorphosisContextualBody;
+
+ typedef struct GX_XMetamorphosisContextualPerGlyphRec_
+ {
+ FT_UShort markIndex;
+ FT_UShort currentIndex;
+ } GX_XMetamorphosisContextualPerGlyphRec;/*, *GX_XMetamorphosisContextualPerGlyph; */
+
+/*
+ * Ligature
+ */
+
+#if 0
+ typedef enum
+ {
+ GX_MORX_LIGATURE_ACTION_LAST = GX_MORT_LIGATURE_ACTION_LAST,
+ GX_MORX_LIGATURE_ACTION_STORE = GX_MORT_LIGATURE_ACTION_STORE,
+ GX_MORX_LIGATURE_ACTION_OFFSET = GX_MORT_LIGATURE_ACTION_OFFSET
+ } GX_XMetamorphosisLigatureActionMask;
+#else
+ typedef GX_MetamorphosisLigatureActionMask GX_XMetamorphosisLigatureActionMask;
+#define GX_MORX_LIGATURE_ACTION_LAST GX_MORT_LIGATURE_ACTION_LAST
+#define GX_MORX_LIGATURE_ACTION_STORE GX_MORT_LIGATURE_ACTION_STORE
+#define GX_MORX_LIGATURE_ACTION_OFFSET GX_MORT_LIGATURE_ACTION_OFFSET
+#endif /* 0 */
+
+ typedef enum
+ {
+ GX_MORX_LIGATURE_FLAGS_SET_COMPONENT = 0x8000,
+ GX_MORX_LIGATURE_FLAGS_DONT_ADVANCE = 0x4000,
+ GX_MORX_LIGATURE_FLAGS_PERFORM_ACTION = 0x2000,
+ GX_MORX_LIGATURE_FLAGS_RESERVED = 0x3FFF
+ } GX_XMetamorphosisLigatureFlagsMask;
+
+ typedef struct GX_XMetamorphosisLigatureActionTableRec_
+ {
+ FT_ULong offset; /* known as ligActionTable in the spec. */
+ FT_UShort nActions;
+ FT_ULong *body;
+ } GX_XMetamorphosisLigatureActionTableRec, *GX_XMetamorphosisLigatureActionTable;
+
+ typedef struct GX_XMetamorphosisComponentTableRec_
+ {
+ FT_ULong offset; /* known as componentTable in the spec. */
+ FT_UShort nComponent;
+ FT_UShort *body;
+ } GX_XMetamorphosisComponentTableRec, *GX_XMetamorphosisComponentTable;
+
+ typedef struct GX_XMetamorphosisLigatureTableRec_
+ {
+ FT_ULong offset; /* known as ligatureTable in the spec. */
+ FT_UShort nLigature;
+ FT_UShort *body;
+ } GX_XMetamorphosisLigatureTableRec, *GX_XMetamorphosisLigatureTable;
+
+ typedef struct GX_XMetamorphosisLigatureBodyRec_
+ {
+ GX_XStateTableRec state_table;
+ GX_XMetamorphosisLigatureActionTableRec ligActionTable;
+ GX_XMetamorphosisComponentTableRec componentTable;
+ GX_XMetamorphosisLigatureTableRec ligatureTable;
+ } GX_XMetamorphosisLigatureBodyRec, *GX_XMetamorphosisLigatureBody;
+
+/*
+ * Noncontextual
+ */
+ typedef GX_MetamorphosisNoncontextualBody GX_XMetamorphosisNoncontextualBody;
+
+/*
+ * Insertion
+ */
+#define GX_MORX_NO_INSERTION ((FT_UShort)-1)
+#define GX_MORX_NO_SUBSTITUTION ((FT_UShort)-1)
+
+ typedef GX_MetamorphosisInsertionPerGlyphRec GX_XMetamorphosisInsertionPerGlyphRec;
+ typedef GX_MetamorphosisInsertionPerGlyph GX_XMetamorphosisInsertionPerGlyph;
+ typedef GX_MetamorphosisInsertionListRec GX_XMetamorphosisInsertionListRec;
+ typedef GX_MetamorphosisInsertionList GX_XMetamorphosisInsertionList;
+
+ typedef struct GX_XMetamorphosisInsertionBodyRec_
+ {
+ GX_XStateTableRec state_table;
+ FT_ULong insertion_glyph_table;
+ } GX_XMetamorphosisInsertionBodyRec, * GX_XMetamorphosisInsertionBody;
+
+ typedef enum
+ {
+ GX_MORX_INSERTION_FLAGS_SET_MARK = GX_MORT_INSERTION_FLAGS_SET_MARK,
+ GX_MORX_INSERTION_FLAGS_DONT_ADVANCE = GX_MORT_INSERTION_FLAGS_DONT_ADVANCE,
+ GX_MORX_INSERTION_FLAGS_CURRENT_IS_KASHIDA_LIKE = GX_MORT_INSERTION_FLAGS_CURRENT_IS_KASHIDA_LIKE,
+ GX_MORX_INSERTION_FLAGS_MARKED_IS_KASHIDA_LIKE = GX_MORT_INSERTION_FLAGS_MARKED_IS_KASHIDA_LIKE,
+ GX_MORX_INSERTION_FLAGS_CURRENT_INSERT_BEFORE = GX_MORT_INSERTION_FLAGS_CURRENT_INSERT_BEFORE,
+ GX_MORX_INSERTION_FLAGS_MARKED_INSERT_BEFORE = GX_MORT_INSERTION_FLAGS_MARKED_INSERT_BEFORE,
+ GX_MORX_INSERTION_FLAGS_CURRENT_INSERT_COUNT = GX_MORT_INSERTION_FLAGS_CURRENT_INSERT_COUNT,
+ GX_MORX_INSERTION_FLAGS_MARKED_INSERT_COUNT = GX_MORT_INSERTION_FLAGS_MARKED_INSERT_COUNT
+ } GX_XMetamorphosisInsertionFlagsMask;
+
+/*
+ * Generic
+ */
+
+ typedef struct GX_XMetamorphosisSubtableHeaderRec_
+ {
+ FT_ULong position; /* not in the spec, just for DEBUG */
+ FT_ULong length;
+ FT_ULong coverage;
+ FT_ULong subFeatureFlags;
+ } GX_XMetamorphosisSubtableHeaderRec, *GX_XMetamorphosisSubtableHeader;
+
+ typedef union GX_XMetamorphosisSubtableBodyDesc_
+ {
+ GX_XMetamorphosisRearrangementBody rearrangement;
+ GX_XMetamorphosisContextualBody contextual;
+ GX_XMetamorphosisLigatureBody ligature;
+ GX_XMetamorphosisNoncontextualBody noncontextual;
+ GX_XMetamorphosisInsertionBody insertion;
+ FT_Pointer any;
+ } GX_XMetamorphosisSubtableBodyDesc, *GX_XMetamorphosisSubtableBody;
+
+ typedef struct GX_XMetamorphosisSubtableRec_
+ {
+ GX_XMetamorphosisSubtableHeaderRec header;
+ GX_XMetamorphosisSubtableBodyDesc body;
+ } GX_XMetamorphosisSubtableRec, *GX_XMetamorphosisSubtable;
+
+ typedef struct GX_XMetamorphosisChainHeaderRec_
+ {
+ FT_ULong defaultFlags;
+ FT_ULong chainLength;
+ FT_ULong nFeatureEntries;
+ FT_ULong nSubtables;
+ } GX_XMetamorphosisChainHeaderRec, *GX_XMetamorphosisChainHeader;
+
+ typedef struct GX_XMetamorphosisChainRec_
+ {
+ GX_XMetamorphosisChainHeaderRec header;
+ GX_XMetamorphosisFeatureTable feat_Subtbl;
+ GX_XMetamorphosisSubtable chain_Subtbl;
+ } GX_XMetamorphosisChainRec, *GX_XMetamorphosisChain;
+
+ typedef struct GX_MorxRec_
+ {
+ GX_TableRec root;
+ FT_Fixed version;
+ FT_ULong nChains;
+ GX_XMetamorphosisChain chain;
+ } GX_MorxRec, *GX_Morx;
+
+
+/***************************************************************************/
+/* FMTX */
+/***************************************************************************/
+
+ typedef struct GX_FmtxRec_
+ {
+ GX_TableRec root;
+ FT_Fixed version;
+ FT_ULong glyphIndex;
+ FT_Byte horizontalBefore;
+ FT_Byte horizontalAfter;
+ FT_Byte horizontalCaretHead;
+ FT_Byte horizontalCaretBase;
+ FT_Byte verticalBefore;
+ FT_Byte verticalAfter;
+ FT_Byte verticalCaretHead;
+ FT_Byte verticalCaretBase;
+ } GX_FmtxRec, *GX_Fmtx;
+
+
+/***************************************************************************/
+/* FDSC */
+/***************************************************************************/
+
+
+ typedef struct GX_FontDescriptorRec_
+ {
+ FT_ULong tag;
+ FT_Fixed value;
+ } GX_FontDescriptorRec, *GX_FontDescriptor;
+
+ typedef struct GX_FdscRec_
+ {
+ GX_TableRec root;
+ FT_Fixed version;
+ FT_ULong descriptorCount;
+ GX_FontDescriptor descriptor;
+ } GX_FdscRec, *GX_Fdsc;
+
+/***************************************************************************/
+/* JUST */
+/***************************************************************************/
+
+ typedef enum
+ {
+ GX_JUST_STATE_FLAGS_SET_MARK = 0x8000,
+ GX_JUST_STATE_FLAGS_DONT_ADVANCE = 0x4000,
+ GX_JUST_STATE_FLAGS_MARK_CLASS = 0x3F80,
+ GX_JUST_STATE_FLAGS_CURRENT_CLASS = 0x007F
+ } GX_JustificationStateFlagsMask;
+
+ typedef struct GX_JustificationClassStateTableRec_
+ {
+ GX_MetamorphosisSubtableHeaderRec morphHeader;
+ GX_StateHeaderRec stHeader;
+ } GX_JustificationClassStateTableRec, *GX_JustificationClassStateTable;
+
+ typedef struct GX_JustificationHeaderRec_
+ {
+ FT_UShort justClassTableOffset;
+ FT_UShort wdcTableOffset;
+ FT_UShort pcTableOffset;
+ GX_LookupTableRec lookup_table;
+ } GX_JustificationHeaderRec, *GX_JustificationHeader;
+ typedef struct GX_JustRec_
+ {
+ GX_TableRec root;
+ FT_Fixed version;
+ FT_UShort format;
+ FT_UShort horizOffset;
+ FT_UShort vertOffset;
+
+ } GX_JustRec, *GX_Just;
+
+/***************************************************************************/
+/* KERN */
+/***************************************************************************/
+ typedef enum
+ {
+ GX_KERN_COVERAGE_VERTICAL = 0x8000,
+ GX_KERN_COVERAGE_CROSS_STREAM = 0x4000,
+ GX_KERN_COVERAGE_VARIATION = 0x2000,
+ GX_KERN_COVERAGE_UNUSED_BITS = 0x1F00,
+ GX_KERN_COVERAGE_FORMAT_MASK = 0x00FF
+ } GX_KerningCoverageMask;
+
+ typedef enum
+ {
+ GX_KERN_FMT_ORDERED_LIST_OF_KERNING_PAIRS = 0,
+ GX_KERN_FMT_STATE_TABLE_FOR_CONTEXTUAL_KERNING = 1,
+ GX_KERN_FMT_SIMPLE_NXM_ARRAY_OF_KERNING_VALUES = 2,
+ GX_KERN_FMT_SIMPLE_NXM_ARRAY_OF_KERNING_INDICES = 3
+ } GX_KerningFormat;
+
+ typedef enum
+ {
+ GX_KERN_ACTION_PUSH = 0x8000,
+ GX_KERN_ACTION_DONT_ADVANCE = 0x4000,
+ GX_KERN_ACTION_VALUE_OFFSET = 0x3FFF
+ } GX_KerningFormat1Action;
+
+ typedef enum
+ {
+ GX_KERN_VALUE_END_LIST = 0x0001,
+ GX_KERN_VALUE_RESET_CROSS_STREAM = 0x8000
+ } GX_KerningFormat1ValueMask;
+
+ typedef struct GX_KerningSubtableHeaderRec_
+ {
+ FT_ULong position; /* Not in the spec but needed in fmt2 */
+ FT_ULong length;
+ FT_UShort coverage;
+ FT_UShort tupleIndex;
+ } GX_KerningSubtableHeaderRec, *GX_KerningSubtableHeader;
+
+ typedef struct GX_KerningSubtableFormat0EntryRec_
+ {
+ FT_UShort left;
+ FT_UShort right;
+ FT_Short value;
+ } GX_KerningSubtableFormat0EntryRec, *GX_KerningSubtableFormat0Entry;
+
+ typedef struct GX_KerningSubtableFormat0BodyRec_
+ {
+ FT_UShort nPairs;
+ FT_UShort searchRange;
+ FT_UShort entrySelector;
+ FT_UShort rangeShift;
+ GX_KerningSubtableFormat0Entry entries;
+ } GX_KerningSubtableFormat0BodyRec, * GX_KerningSubtableFormat0Body;
+
+ typedef struct GX_KerningSubtableFormat1BodyRec_
+ {
+ GX_StateTableRec state_table; /* stHeader written in the spec are included
+ in this field */
+ FT_UShort valueTable;
+ FT_ULong value_absolute_pos;
+ FT_ULong nValues; /* in FT_FWord counts */
+ FT_FWord *values;
+ } GX_KerningSubtableFormat1BodyRec, *GX_KerningSubtableFormat1Body;
+
+ typedef struct GX_KerningSubtableFormat2ClassTableRec_
+ {
+ FT_UShort firstGlyph;
+ FT_UShort nGlyphs;
+ FT_Byte max_class; /* Not in the spec but useful */
+ FT_Byte *classes;
+ } GX_KerningSubtableFormat2ClassTableRec, *GX_KerningSubtableFormat2ClassTable;
+
+ typedef struct GX_KerningSubtableFormat2BodyRec_
+ {
+ FT_UShort rowWidth;
+ FT_UShort leftClassTable;
+ FT_UShort rightClassTable;
+ FT_UShort array;
+ GX_KerningSubtableFormat2ClassTableRec leftClass;
+ GX_KerningSubtableFormat2ClassTableRec rightClass;
+ FT_FWord *values; /* The length is
+ leftClass.max_class + rightClass.max_class */
+ } GX_KerningSubtableFormat2BodyRec, *GX_KerningSubtableFormat2Body;
+
+ typedef struct GX_KerningSubtableFormat3BodyRec_
+ {
+ FT_UShort glyphCount;
+ FT_Byte kernValueCount;
+ FT_Byte leftClassCount;
+ FT_Byte rightClassCount;
+ FT_Byte flags;
+ FT_FWord *kernValue; /* [kernValueCount] */
+ FT_Byte *leftClass; /* [glyphCount] */
+ FT_Byte *rightClass; /* [glyphCount] */
+ FT_Byte *kernIndex; /* [leftClassCount * rightClassCount] */
+ } GX_KerningSubtableFormat3BodyRec, * GX_KerningSubtableFormat3Body;
+
+ typedef union GX_KerningSubtableBodyDesc_
+ {
+ GX_KerningSubtableFormat0Body fmt0;
+ GX_KerningSubtableFormat1Body fmt1;
+ GX_KerningSubtableFormat2Body fmt2;
+ GX_KerningSubtableFormat3Body fmt3;
+ FT_Pointer any;
+ } GX_KerningSubtableBodyDesc, *GX_KerningSubtableBody;
+
+ typedef struct GX_KerningSubtableRec_
+ {
+ GX_KerningSubtableHeaderRec header;
+ GX_KerningSubtableBodyDesc body;
+ } GX_KerningSubtableRec, *GX_KerningSubtable;
+
+ typedef struct GX_KernRec_
+ {
+ GX_TableRec root;
+ FT_Fixed version;
+ FT_ULong nTables;
+ GX_KerningSubtable subtables;
+ } GX_KernRec, *GX_Kern;
+
+/***************************************************************************/
+/* CVAR */
+/***************************************************************************/
+ typedef struct GX_GvarRec_
+ {
+ GX_TableRec root;
+ FT_Fixed version;
+ FT_UShort axisCount;
+ FT_UShort globalCoordCount;
+ FT_ULong offsetToCoord;
+ FT_UShort glyphCount;
+ FT_UShort flags;
+ FT_ULong offsetToData;
+ union {
+ FT_UShort * u16;
+ FT_ULong * u32;
+ } offset;
+ /* TODO */
+ } GX_GvarRec, *GX_Gvar;
+
+/***************************************************************************/
+/* GVAR */
+/***************************************************************************/
+/* TODO */
+
+/***************************************************************************/
+/* FVAR */
+/***************************************************************************/
+ typedef struct GX_FontVariationsSFNTVariationAxisRec_
+ {
+ FT_ULong axisTag;
+ FT_Fixed minValue;
+ FT_Fixed defaultValue;
+ FT_Fixed maxValue;
+ FT_UShort flags;
+ FT_UShort nameID;
+ } GX_FontVariationsSFNTVariationAxisRec, * GX_FontVariationsSFNTVariationAxis;
+
+ typedef struct GX_FontVariationsSFNTInstanceRec_
+ {
+ FT_UShort nameID;
+ FT_UShort flags;
+ FT_Fixed * coord; /* GX_FvarRec::axisCount */
+ } GX_FontVariationsSFNTInstanceRec, *GX_FontVariationsSFNTInstance;
+
+ typedef struct GX_FvarRec_
+ {
+ GX_TableRec root;
+ FT_Fixed version;
+ FT_UShort offsetToData;
+ FT_UShort countSizePairs;
+ FT_UShort axisCount ;
+ FT_UShort axisSize ;
+ FT_UShort instanceCount ;
+ FT_UShort instanceSize ;
+ GX_FontVariationsSFNTVariationAxis axis; /* axisCount */
+ GX_FontVariationsSFNTInstance instance; /* instanceCount */
+ } GX_FvarRec, *GX_Fvar;
+
+/***************************************************************************/
+/* Generic */
+/***************************************************************************/
+ typedef struct GXL_FontRec_
+ {
+ FTL_FontRec root;
+
+ GX_Feat feat;
+ GX_Mort mort;
+ GX_Morx morx;
+ GX_Trak trak;
+ GX_Kern kern;
+ GX_Prop prop;
+ GX_Lcar lcar;
+ GX_Opbd opbd;
+ GX_Bsln bsln;
+ GX_Fmtx fmtx;
+ GX_Fdsc fdsc;
+ GX_Just just;
+ GX_Fvar fvar;
+
+ } GXL_FontRec; /* *GX_Font; */
+
+FT_END_HEADER
+
+#endif /* Not def: __GXTYPES_H__ */
+
+
+/* END */
diff --git a/src/gxlayout/gxutils.c b/src/gxlayout/gxutils.c
new file mode 100644
index 000000000..9d21afe73
--- /dev/null
+++ b/src/gxlayout/gxutils.c
@@ -0,0 +1,129 @@
+/***************************************************************************/
+/* */
+/* gxutils.c */
+/* */
+/* AAT/TrueTypeGX private utility functions (body). */
+/* */
+/* Copyright 2003 by */
+/* Masatake YAMATO and Redhat K.K. */
+/* */
+/* This file may only be used, */
+/* modified, and distributed under the terms of the FreeType project */
+/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
+/* this file you indicate that you have read the license and */
+/* understand and accept it fully. */
+/* */
+/***************************************************************************/
+
+/***************************************************************************/
+/* Development of the code in this file is support of */
+/* Information-technology Promotion Agency, Japan. */
+/***************************************************************************/
+
+#include <ft2build.h>
+
+#include "gxerrors.h"
+#include "gxutils.h"
+#include "gxobjs.h"
+
+
+FT_LOCAL_DEF( FT_Int )
+gx_zero_shift_bits ( FT_ULong mask )
+{
+ FT_Int i = 0;
+ for ( i = 0; !(mask & (0x1L << i)); i++)
+ ; /* Do nothing */
+ return i;
+}
+
+FT_LOCAL_DEF( FT_Long )
+gx_mask_zero_shift ( FT_ULong value, FT_ULong mask )
+{
+ FT_Int shift_bits = gx_zero_shift_bits( mask );
+ return ((value & mask) >> shift_bits);
+}
+
+FT_LOCAL_DEF( FT_Long )
+gx_sign_extend ( FT_ULong value, FT_ULong mask )
+{
+ /* Copied from icu/source/layout/LigatureSubstProc.cpp */
+#define ExtendedComplement(m) ((FT_Long) (~((FT_ULong) (m))))
+#define SignBit(m) ((ExtendedComplement(m) >> 1) & (m))
+#define SignExtend(v,m) (((v) & SignBit(m))? ((v) | ExtendedComplement(m)): (v))
+ return SignExtend(value,mask);
+}
+
+
+/* Generic */
+FT_LOCAL_DEF( FT_Error )
+gx_get_name_from_id ( FT_Face face,
+ FT_UShort name_id,
+ FT_UShort platform_id,
+ FT_UShort encoding_id,
+ FT_UShort language_id,
+ FT_SfntName *aname )
+{
+ FT_Int i;
+ FT_UInt nnames = FT_Get_Sfnt_Name_Count ((FT_Face)face);
+ FT_Bool any_id = ( (platform_id == 0) &&
+ (encoding_id == 0) &&
+ (language_id == 0) )? 1: 0;
+ for ( i = 0; i < nnames; i++ )
+ {
+ if ( FT_Get_Sfnt_Name((FT_Face)face, i, aname) )
+ continue ;
+ if ( ( aname->name_id == name_id ) &&
+ ( any_id ||
+ ( ( aname->platform_id == platform_id ) &&
+ ( aname->encoding_id == encoding_id ) &&
+ ( aname->language_id == language_id ) )))
+ return GX_Err_Ok;
+ }
+ return GX_Err_Invalid_Argument;
+}
+
+
+FT_LOCAL_DEF ( FT_UShort )
+gx_feat_setting_on ( FT_UShort setting )
+{
+ if ( !gx_feat_setting_state ( setting ) )
+ return setting -1;
+ else
+ return setting;
+
+}
+
+FT_LOCAL_DEF ( FT_UShort )
+gx_feat_setting_off ( FT_UShort setting )
+{
+ if ( gx_feat_setting_state ( setting ) )
+ return setting + 1;
+ else
+ return setting;
+}
+
+FT_LOCAL_DEF ( FT_Bool )
+gx_feat_setting_state ( FT_UShort setting )
+{
+ /* odd => off */
+ if ( setting % 2 )
+ return 0; /* odd => off */
+ else
+ return 1; /* even => on */
+}
+
+FT_LOCAL_DEF ( void )
+gx_glyphs_array_reverse( FTL_Glyph glyphs, FT_ULong length )
+{
+ FT_ULong i, j;
+ FTL_GlyphRec tmp;
+ for ( i = 0, j = length -1; i < j; i++, j-- )
+ {
+ tmp = glyphs[i];
+ glyphs[i] = glyphs[j];
+ glyphs[j] = tmp;
+ }
+}
+
+
+/* END */
diff --git a/src/gxlayout/gxutils.h b/src/gxlayout/gxutils.h
new file mode 100644
index 000000000..f615da549
--- /dev/null
+++ b/src/gxlayout/gxutils.h
@@ -0,0 +1,73 @@
+/***************************************************************************/
+/* */
+/* gxutils.h */
+/* */
+/* AAT/TrueTypeGX private utility functions (specification). */
+/* */
+/* Copyright 2003 by */
+/* Masatake YAMATO and Redhat K.K. */
+/* */
+/* This file may only be used, */
+/* modified, and distributed under the terms of the FreeType project */
+/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
+/* this file you indicate that you have read the license and */
+/* understand and accept it fully. */
+/* */
+/***************************************************************************/
+
+/***************************************************************************/
+/* Development of the code in this file is support of */
+/* Information-technology Promotion Agency, Japan. */
+/***************************************************************************/
+
+#ifndef __GXUTILS_H__
+#define __GXUTILS_H__
+
+#include <ft2build.h>
+#include FT_TYPES_H
+#include FT_SFNT_NAMES_H
+#include FT_LAYOUT_H
+
+FT_BEGIN_HEADER
+
+FT_LOCAL( FT_Int ) gx_zero_shift_bits ( FT_ULong mask );
+FT_LOCAL( FT_Long ) gx_mask_zero_shift ( FT_ULong value,
+ FT_ULong mask );
+FT_LOCAL( FT_Long ) gx_sign_extend ( FT_ULong value,
+ FT_ULong mask );
+
+FT_LOCAL( FT_Error ) gx_get_name_from_id ( FT_Face face,
+ FT_UShort name_id,
+ FT_UShort platform_id,
+ FT_UShort encoding_id,
+ FT_UShort language_id,
+ FT_SfntName *aname );
+
+FT_LOCAL( FT_UShort ) gx_feat_setting_on ( FT_UShort setting );
+FT_LOCAL( FT_UShort ) gx_feat_setting_off ( FT_UShort setting );
+FT_LOCAL( FT_Bool ) gx_feat_setting_state ( FT_UShort setting );
+
+FT_LOCAL ( void ) gx_glyphs_array_reverse ( FTL_Glyph glyphs,
+ FT_ULong length );
+
+#ifdef FT_DEBUG_LEVEL_ERROR
+
+#define GX_ASSERT_NOT_REACHED() \
+ do \
+ { \
+ FT_Panic( "should not be reached to line %d of file %s\n", \
+ __LINE__, __FILE__ ); \
+ } while ( 0 )
+
+#else /* !FT_DEBUG_LEVEL_ERROR */
+
+#define GX_ASSERT_NOT_REACHED() do ; while ( 0 )
+
+#endif /* !FT_DEBUG_LEVEL_ERROR */
+
+FT_END_HEADER
+
+#endif /* Not def: __GXUTILS_H__ */
+
+
+/* END */
diff --git a/src/gxlayout/gxvm.c b/src/gxlayout/gxvm.c
new file mode 100644
index 000000000..0fe74b8cf
--- /dev/null
+++ b/src/gxlayout/gxvm.c
@@ -0,0 +1,1794 @@
+/***************************************************************************/
+/* */
+/* gxvm.c */
+/* */
+/* AAT/TrueTypeGX glyph substitution automaton (body). */
+/* */
+/* Copyright 2003 by */
+/* Masatake YAMATO and Redhat K.K. */
+/* */
+/* This file may only be used, */
+/* modified, and distributed under the terms of the FreeType project */
+/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
+/* this file you indicate that you have read the license and */
+/* understand and accept it fully. */
+/* */
+/***************************************************************************/
+
+/***************************************************************************/
+/* Development of the code in this file is support of */
+/* Information-technology Promotion Agency, Japan. */
+/***************************************************************************/
+
+#include <ft2build.h>
+#include FT_INTERNAL_DEBUG_H
+#include FT_LAYOUT_H
+#include FT_LIST_H
+#include "gxvm.h"
+#include "gxutils.h"
+#include "gxerrors.h"
+
+#undef FT_COMPONENT
+#define FT_COMPONENT trace_gxvm
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+ /**** ****/
+ /**** ****/
+ /**** Ligature Stack ****/
+ /**** ****/
+ /**** ****/
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+
+#define LIGATURE_STACK_DEPTH 16
+typedef struct LigatureStackRec_
+{
+ FT_Char depth;
+ FT_Char top;
+ FT_Char ligatured_top;
+ FT_ULong indexes[LIGATURE_STACK_DEPTH];
+ FT_ULong ligatured_indexes[LIGATURE_STACK_DEPTH];
+} LigatureStackRec, *LigatureStack;
+
+static void ligstack_init(LigatureStack stack);
+static void ligstack_push( LigatureStack stack,
+ FT_ULong index );
+static FT_ULong ligstack_pop( LigatureStack stack );
+static void ligstack_unify(LigatureStack stack);
+static void ligstack_ligatured_init(LigatureStack stack);
+static void ligstack_ligatured_push(LigatureStack stack,
+ FT_ULong index );
+
+static FT_Bool ligstack_ligatured_empty(LigatureStack stack);
+static FT_ULong ligstack_ligatured_pop(LigatureStack stack);
+
+
+
+static void
+ligstack_init(LigatureStack stack)
+{
+ FT_Int i;
+ stack->depth = LIGATURE_STACK_DEPTH;
+ stack->top = -1;
+ for ( i = 0; i < stack->depth; i++ )
+ stack->indexes[i] = 0;
+ ligstack_ligatured_init( stack );
+}
+
+static void
+ligstack_push( LigatureStack stack, FT_ULong index )
+{
+ stack->top++;
+ if ( stack->top >= stack->depth )
+ stack->top = 0;
+ stack->indexes[stack->top] = index;
+}
+
+static FT_ULong
+ligstack_pop( LigatureStack stack )
+{
+ FT_ULong index;
+
+ index = stack->indexes[stack->top];
+ stack->top--;
+ if ( stack->top < 0 )
+ stack->top= stack->depth - 1;
+ return index;
+}
+
+
+static void
+ligstack_unify(LigatureStack stack)
+{
+ FT_ULong index;
+ while ( !ligstack_ligatured_empty ( stack ) )
+ {
+ index = ligstack_ligatured_pop( stack );
+ ligstack_push( stack, index );
+ }
+}
+
+static void
+ligstack_ligatured_init(LigatureStack stack)
+{
+ stack->ligatured_top = -1;
+}
+
+static void
+ligstack_ligatured_push(LigatureStack stack,
+ FT_ULong index )
+{
+ stack->ligatured_top++;
+ if ( stack->ligatured_top >= stack->depth )
+ stack->ligatured_top = 0;
+ stack->ligatured_indexes[stack->ligatured_top] = index;
+}
+
+static FT_Bool
+ligstack_ligatured_empty(LigatureStack stack)
+{
+ return (stack->ligatured_top >= 0)? 0: 1;
+}
+
+static FT_ULong
+ligstack_ligatured_pop(LigatureStack stack)
+{
+ FT_ULong index;
+ /* ??? */
+ index = stack->ligatured_indexes[stack->ligatured_top];
+ if ( stack->ligatured_top > -1 )
+ stack->ligatured_top--;
+ return index;
+}
+
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+ /**** ****/
+ /**** ****/
+ /**** Glyphs List ****/
+ /**** ****/
+ /**** ****/
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+
+#define INSERTION_GLYPHS_MAX 31
+ typedef struct InsertionGlyphsRec_
+ {
+ FTL_GlyphRec glyphs[INSERTION_GLYPHS_MAX];
+ FT_UShort length;
+ } InsertionGlyphsRec, *InsertionGlyphs;
+
+ typedef struct GlyphNodeRec_
+ {
+ FT_ListNodeRec root;
+ FTL_GlyphRec glyph;
+ } GlyphNodeRec, *GlyphNode;
+
+
+ typedef struct GlyphsListRec_
+ {
+ FT_ListRec root;
+ GlyphNode current;
+ GlyphNode mark;
+ FT_Memory memory;
+ } GlyphsListRec, *GlyphsList;
+
+ typedef FT_Error
+ (* GList_InsertFunc)( GlyphsList glist,
+ InsertionGlyphs insertion,
+ FT_Bool before );
+
+ static void insertion_glyphs_init ( InsertionGlyphs glyphs );
+ static void insertion_glyphs_push ( InsertionGlyphs glyphs, FT_UShort gid );
+ static FT_Error insertion_glyphs_store ( InsertionGlyphs glyphs,
+ FT_Memory memory,
+ FT_List list );
+
+ static void
+ insertion_glyphs_init ( InsertionGlyphs glyphs )
+ {
+ glyphs->length = 0;
+ }
+ static void
+ insertion_glyphs_push ( InsertionGlyphs glyphs, FT_UShort gid )
+ {
+ if (!( glyphs->length < INSERTION_GLYPHS_MAX ))
+ glyphs->length = 0;
+ glyphs->glyphs[glyphs->length].gid = gid;
+ }
+
+ static FT_Error
+ insertion_glyphs_store ( InsertionGlyphs glyphs,
+ FT_Memory memory,
+ FT_List list )
+ {
+ FT_UShort i;
+ FT_Error error = FT_Err_Ok;
+ GlyphNode gnode;
+
+ for ( i = 0; i < glyphs->length; i++ )
+ {
+ if ( FT_NEW( gnode ) )
+ goto Failure;
+ gnode->glyph = glyphs->glyphs[i];
+ FT_List_Add( list, (FT_ListNode)gnode );
+ }
+ return error;
+ Failure:
+ FT_List_Finalize( list, NULL, memory, NULL );
+ return error;
+ }
+
+ static FT_Error glist_init ( FT_Memory memory,
+ GlyphsList glist,
+ FTL_Glyphs_Array garray );
+ static FT_Error glist_store ( GlyphsList glist,
+ FTL_Glyphs_Array garray );
+ static void glist_finalize ( GlyphsList glist );
+
+/*
+ * GList_InsertFunc
+ */
+ static FT_Error glist_insert_current ( GlyphsList glist,
+ InsertionGlyphs insertion,
+ FT_Bool before );
+ static FT_Error glist_insert_mark ( GlyphsList glist,
+ InsertionGlyphs insertion,
+ FT_Bool before );
+
+ static void glist_set_mark ( GlyphsList glist );
+ static FTL_Glyph glist_get_next ( GlyphsList glist );
+ static FTL_Glyph glist_get_current ( GlyphsList glist );
+
+/* glist function group local;
+ - glist_insert_before_*
+ - glist_insert_after_*
+ - glist_insert */
+ static FT_Error glist_insert_before_current( GlyphsList glist, InsertionGlyphs insertion );
+ static FT_Error glist_insert_after_current ( GlyphsList glist, InsertionGlyphs insertion );
+ static FT_Error glist_insert_before_mark ( GlyphsList glist, InsertionGlyphs insertion );
+ static FT_Error glist_insert_after_mark ( GlyphsList glist, InsertionGlyphs insertion );
+ static FT_Error glist_insert ( GlyphsList glist,
+ FT_ListNode before,
+ FT_ListNode after,
+ InsertionGlyphs insertion );
+
+ static FT_Error
+ glist_init ( FT_Memory memory, GlyphsList glist, FTL_Glyphs_Array garray )
+ {
+ FT_Error error;
+ FT_ULong i;
+ GlyphNode glyph_node;
+
+ ((FT_List)glist)->head = NULL;
+ ((FT_List)glist)->tail = NULL;
+ glist->mark = NULL;
+ glist->memory = memory;
+
+ for ( i = 0; i < garray->length; i++ )
+ {
+ if ( FT_NEW(glyph_node) )
+ goto Failure;
+ glyph_node->glyph = garray->glyphs[i];
+ FT_List_Add((FT_List)glist, (FT_ListNode)glyph_node);
+ }
+ glist->current = (GlyphNode)((FT_List)glist)->head;
+
+ return FT_Err_Ok;
+ Failure:
+ FT_List_Finalize( (FT_List)glist, NULL, memory, NULL );
+ return error;
+ }
+
+ static FT_Error
+ glist_store ( GlyphsList glist, FTL_Glyphs_Array garray )
+ {
+ FT_Error error;
+ FT_ULong length = 0, i;
+ FT_ListNode tmp;
+
+ tmp = glist->root.head;
+ while ( tmp )
+ {
+ length++;
+ tmp = tmp->next;
+ }
+
+ if (( error = FTL_Set_Glyphs_Array_Length( garray, length ) ))
+ return error;
+
+ tmp = glist->root.head;
+ for ( i = 0; i < length; i++ )
+ {
+ garray->glyphs[i] = ((GlyphNode)tmp)->glyph;
+ tmp = tmp->next;
+ }
+ return error;
+ }
+
+ static void
+ glist_finalize( GlyphsList glist )
+ {
+ FT_Memory memory = glist->memory;
+ FT_List_Finalize( (FT_List)glist, NULL, memory, NULL );
+ }
+
+ static FT_Error
+ glist_insert_current ( GlyphsList glist,
+ InsertionGlyphs insertion,
+ FT_Bool before )
+ {
+ return ( before
+ ? glist_insert_before_current( glist, insertion )
+ : glist_insert_after_current( glist, insertion ));
+ }
+
+ static FT_Error
+ glist_insert_mark ( GlyphsList glist,
+ InsertionGlyphs insertion,
+ FT_Bool before )
+ {
+ return ( before
+ ? glist_insert_before_mark( glist, insertion )
+ : glist_insert_after_mark( glist, insertion ));
+ }
+
+ static FT_Error
+ glist_insert_before_current( GlyphsList glist, InsertionGlyphs insertion )
+ {
+ FT_ListNode before, after;
+
+ after = (FT_ListNode)glist->current;
+ FT_ASSERT( after );
+ before = after->prev;
+ return glist_insert(glist, before, after, insertion);
+ }
+
+ static FT_Error
+ glist_insert_after_current ( GlyphsList glist, InsertionGlyphs insertion )
+ {
+ FT_ListNode before, after;
+
+ before = (FT_ListNode)glist->current;
+ FT_ASSERT( before );
+ after = before->next;
+ return glist_insert(glist, before, after, insertion);
+ }
+
+ static FT_Error
+ glist_insert_before_mark ( GlyphsList glist, InsertionGlyphs insertion )
+ {
+ FT_ListNode before, after;
+
+ after = (FT_ListNode)glist->mark;
+ FT_ASSERT( after );
+ before = after->prev;
+ return glist_insert(glist, before, after, insertion);
+ }
+
+ static FT_Error
+ glist_insert_after_mark ( GlyphsList glist, InsertionGlyphs insertion )
+ {
+ FT_ListNode before, after;
+
+ before = (FT_ListNode)glist->mark;
+ FT_ASSERT( before );
+ after = before->next;
+ return glist_insert(glist, before, after, insertion);
+ }
+
+ static FT_Error
+ glist_insert ( GlyphsList glist,
+ FT_ListNode before,
+ FT_ListNode after,
+ InsertionGlyphs insertion )
+ {
+ FT_Error error;
+ FT_ListRec insertion_list = {NULL, NULL};
+ FT_Memory memory = glist->memory;
+ FT_ListNode head, tail;
+
+ if (( error = insertion_glyphs_store( insertion,
+ memory,
+ &insertion_list ) ))
+ return error;
+ head = insertion_list.head;
+ tail = insertion_list.tail;
+
+ if ( (!head) && (!tail) )
+ return FT_Err_Ok;
+
+ FT_ASSERT( head );
+ FT_ASSERT( tail );
+
+
+ if ( before )
+ {
+ before->next = head;
+ head->prev = before;
+ }
+ else
+ {
+ glist->root.head = head;
+ head->prev = NULL;
+ }
+
+ if ( after )
+ {
+ after->prev = tail;
+ tail->next = after;
+ }
+ else
+ {
+ glist->root.tail = tail;
+ tail->next = NULL;
+ }
+ return FT_Err_Ok;
+ }
+
+ static void
+ glist_set_mark ( GlyphsList glist )
+ {
+ glist->mark = glist->current;
+ }
+
+ static FTL_Glyph
+ glist_get_next ( GlyphsList glist )
+ {
+ if ( !glist->current )
+ return NULL;
+
+ glist->current = ( GlyphNode )glist->current->root.next;
+ return glist_get_current ( glist );
+ }
+
+ static FTL_Glyph
+ glist_get_current ( GlyphsList glist )
+ {
+ return ( glist->current )? &(glist->current->glyph): NULL;
+ }
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+ /**** ****/
+ /**** ****/
+ /**** Glyph Metamorphosis ****/
+ /**** ****/
+ /**** ****/
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+
+
+/*************************************************************************
+ * Noncontextual
+ *************************************************************************/
+FT_LOCAL_DEF( FT_Error )
+gx_noncontextual_subst( GX_MetamorphosisNoncontextualBody body,
+ FTL_Glyphs_Array garray )
+{
+ FT_ULong i;
+ GX_LookupTable lookup_table = &body->lookup_table;
+ GX_LookupResultRec result;
+
+ FT_TRACE2(("Enter noncontextual\n"));
+ for ( i = 0; i < garray->length; i++ )
+ {
+ if ( garray->glyphs[i].gid == GX_DELETED_GLYPH_INDEX )
+ continue ;
+ result = gx_LookupTable_lookup ( lookup_table, garray->glyphs[i].gid );
+ if ( result.value == NULL )
+ continue;
+
+ if ( result.firstGlyph == GX_LOOKUP_RESULT_NO_FIRST_GLYPH )
+ {
+ FT_TRACE3((" Substitution[%lu] %u to %u\n",
+ i, garray->glyphs[i].gid, result.value->raw.u));
+ garray->glyphs[i].gid = result.value->raw.u;
+ }
+ else
+ {
+ FT_TRACE3(( " Substitution[%d] %u to %u\n",
+ i, garray->glyphs[i].gid,
+ result.value->extra.word[garray->glyphs[i].gid - result.firstGlyph] ));
+ garray->glyphs[i].gid = result.value->extra.word[garray->glyphs[i].gid - result.firstGlyph];
+ }
+ }
+ FT_TRACE2(("Leave noncontextual\n"));
+ return FT_Err_Ok;
+}
+
+
+/*************************************************************************
+ * Contextual
+ *************************************************************************/
+static FT_UShort contextual_lookup_glyph( GX_MetamorphosisContextualBody body,
+ FT_Short index, /* Was:FT_UShort, see gxtype.h */
+ FT_UShort gid );
+
+FT_LOCAL_DEF( FT_Error )
+gx_contextual_subst( GX_MetamorphosisContextualBody body,
+ GXL_Initial_State initial_state,
+ FTL_Glyphs_Array garray )
+{
+ FT_ULong glength = garray->length;
+ FTL_Glyph glyphs = garray->glyphs;
+ FT_UShort current_state;
+
+ FT_ULong current_glyph, mark_glyph;
+ FT_Byte class_code, final_class;
+ GX_EntrySubtable entry_subtable;
+
+ FT_Short markOffset, currentOffset; /* Was:FT_UShort, see gxtype.h */
+ FT_UShort tmp;
+
+ FT_TRACE2(("Enter contextual\n"));
+
+ current_glyph = 0;
+ mark_glyph = 0;
+ current_state = body->state_table.header.stateArray + (FT_Byte)initial_state;
+ final_class = ( initial_state == GXL_START_OF_TEXT_STATE )
+ ? GX_CLASS_END_OF_TEXT: GX_CLASS_END_OF_LINE;
+
+ while ( current_glyph <= glength )
+ {
+ FT_TRACE3((" glyph id: %u, glyph position: %lu/%lu\n",
+ current_glyph == glength? 0xFFFF: glyphs[current_glyph].gid,
+ current_glyph, glength ));
+
+ /* glyph -> class */
+ class_code = ( current_glyph == glength )
+ ? final_class: gx_StateTable_get_class ( &body->state_table,
+ glyphs[current_glyph].gid );
+ FT_TRACE3((" class code: %u current state: %u\n", class_code, current_state ));
+
+ /* class -> entry */
+ entry_subtable = gx_StateTable_get_entry_subtable ( &body->state_table,
+ current_state,
+ class_code );
+
+ /* action for entry */
+ currentOffset = entry_subtable->glyphOffsets.contextual->currentOffset;
+ markOffset = entry_subtable->glyphOffsets.contextual->markOffset;
+ if ( currentOffset )
+ {
+ FT_TRACE3((" currentOffset is given: %d\n", currentOffset)); /* Was:FT_UShort, see gxtype.h. */
+ tmp = glyphs[current_glyph].gid;
+ glyphs[current_glyph].gid = contextual_lookup_glyph(body, currentOffset, tmp);
+ FT_TRACE3((" Substitution[current %lu] %u to %u\n",
+ current_glyph, tmp, glyphs[current_glyph].gid ));
+ }
+ if ( markOffset )
+ {
+ FT_TRACE3((" markOffset is given: %d\n", markOffset)); /* Was:FT_UShort, see gxtype.h. */
+ tmp = glyphs[mark_glyph].gid;
+ glyphs[mark_glyph].gid = contextual_lookup_glyph(body, markOffset, tmp);
+ FT_TRACE3((" Substitution[current %lu] %u to %u\n",
+ mark_glyph, tmp, glyphs[current_glyph].gid ));
+ }
+
+ /* set mark */
+ if ( entry_subtable->flags & GX_MORT_CONTEXTUAL_FLAGS_SET_MARK )
+ {
+ mark_glyph = current_glyph;
+ FT_TRACE3((" %ld is marked.\n", mark_glyph ));
+ }
+
+ /* advance */
+ if ( !(entry_subtable->flags & GX_MORT_CONTEXTUAL_FLAGS_DONT_ADVANCE ) )
+ {
+ FT_TRACE3((" index++.\n"));
+ current_glyph++;
+ }
+
+ /* new state */
+ current_state = entry_subtable->newState;
+ }
+ FT_TRACE2(("Leave contextual\n"));
+ return FT_Err_Ok;
+}
+
+static FT_UShort
+contextual_lookup_glyph( GX_MetamorphosisContextualBody body,
+ FT_Short offset, /* Was:FT_UShort, see gxtype.h */
+ FT_UShort gid )
+{
+ GX_MetamorphosisContextualSubstitutionTable substitution_table = &body->substitutionTable;
+ FT_ULong index;
+
+ FT_TRACE2(("offset: %u substitution_table->offset %u\n",
+ offset, substitution_table->offset ));
+ index = (2 * offset - substitution_table->offset)/2 + gid;
+ FT_TRACE2(("index: %lu < substitution_table->nGlyphIndexes: %lu\n",
+ index, substitution_table->nGlyphIndexes));
+ FT_ASSERT( index < substitution_table->nGlyphIndexes );
+ return substitution_table->glyph_indexes[index];
+}
+
+/*************************************************************************
+ * Ligature
+ *************************************************************************/
+static FT_ULong * ligature_get_action( GX_MetamorphosisLigatureBody body,
+ FT_UShort action_offset );
+static FT_UShort ligature_get_component( GX_MetamorphosisLigatureBody body,
+ FT_Long component_offset,
+ FT_UShort gid );
+
+static FT_UShort ligature_get_ligature ( GX_MetamorphosisLigatureBody body,
+ FT_ULong action,
+ FT_Long accumulator );
+
+FT_LOCAL_DEF( FT_Error )
+gx_ligature_subst( GX_MetamorphosisLigatureBody body,
+ GXL_Initial_State initial_state,
+ FTL_Glyphs_Array garray )
+{
+ FT_ULong glength = garray->length;
+ FTL_Glyph glyphs = garray->glyphs;
+ FT_UShort current_state;
+
+ FT_ULong current_glyph, component_glyph;
+ FT_Byte class_code, final_class;
+ GX_EntrySubtable entry_subtable;
+
+ LigatureStackRec ligstack;
+ FT_UShort action_offset;
+ FT_ULong *action;
+
+ FT_UShort component;
+ FT_Long component_offset;
+ FT_Long component_accumulator;
+ FT_UShort tmp;
+
+ FT_TRACE2(("Enter ligature\n"));
+
+ current_glyph = 0;
+ current_state = body->state_table.header.stateArray + (FT_Byte)initial_state;
+ final_class = ( initial_state == GXL_START_OF_TEXT_STATE )
+ ? GX_CLASS_END_OF_TEXT: GX_CLASS_END_OF_LINE;
+ ligstack_init(&ligstack);
+ while ( current_glyph <= glength )
+ {
+ FT_TRACE3((" glyph id: %u, glyph position: %lu/%lu\n",
+ current_glyph == glength? 0xFFFF: glyphs[current_glyph].gid,
+ current_glyph, glength ));
+
+ /* glyph -> class */
+ class_code = ( current_glyph == glength )
+ ? final_class: gx_StateTable_get_class ( &body->state_table,
+ glyphs[current_glyph].gid );
+ FT_TRACE3((" class code: %u current state: %u\n", class_code, current_state ));
+
+ /* class -> entry */
+ entry_subtable = gx_StateTable_get_entry_subtable ( &body->state_table,
+ current_state,
+ class_code );
+
+ /* action for entry */
+ if ( entry_subtable->flags & GX_MORT_LIGATURE_FLAGS_SET_COMPONENT )
+ {
+ FT_TRACE3((" Push[current_glyph %lu] %lu to the stack\n",
+ current_glyph, glyphs[current_glyph] ));
+ ligstack_push(&ligstack, current_glyph);
+ }
+
+ /* action */
+ action_offset = entry_subtable->flags & GX_MORT_LIGATURE_FLAGS_OFFSET;
+ if ( action_offset )
+ {
+ action = ligature_get_action( body, action_offset ) - 1;
+ component_accumulator = 0;
+ ligstack_ligatured_init( &ligstack );
+
+ do {
+ action++;
+ component_glyph = ligstack_pop( &ligstack );
+ component_offset = (*action) & GX_MORT_LIGATURE_ACTION_OFFSET;
+ if ( component_offset )
+ {
+ component = ligature_get_component( body,
+ component_offset,
+ glyphs[component_glyph].gid );
+ component_accumulator += component;
+ tmp = ligature_get_ligature( body,
+ *action,
+ component_accumulator );
+ FT_TRACE3((" Substitution[component %lu] %u to %u\n",
+ component_glyph, glyphs[component_glyph].gid, tmp ));
+ glyphs[component_glyph].gid = tmp;
+ if (*action & ( GX_MORT_LIGATURE_ACTION_LAST |
+ GX_MORT_LIGATURE_ACTION_STORE ))
+ {
+ ligstack_ligatured_push( &ligstack, component_glyph );
+ component_accumulator = 0;
+ }
+ }
+ } while (! ((*action) & GX_MORT_LIGATURE_ACTION_LAST));
+ ligstack_unify ( &ligstack );
+ }
+
+ /* advance */
+ if ( !(entry_subtable->flags & GX_MORT_LIGATURE_FLAGS_DONT_ADVANCE ) )
+ {
+ FT_TRACE3((" index++.\n"));
+ current_glyph++;
+ }
+
+ /* new state */
+ current_state = entry_subtable->newState;
+ }
+ FT_TRACE2(("Leave ligature\n"));
+ return FT_Err_Ok;
+}
+
+static FT_ULong *
+ligature_get_action( GX_MetamorphosisLigatureBody body,
+ FT_UShort action_offset )
+{
+ FT_UShort action_index;
+ GX_MetamorphosisLigatureActionTable action_table = &body->ligActionTable;
+ FT_ASSERT( ((action_offset - action_table->offset)%4 == 0) );
+ action_index = (action_offset - action_table->offset)/4;
+ return &(action_table->body[action_index]);
+}
+
+static FT_UShort
+ligature_get_component( GX_MetamorphosisLigatureBody body,
+ FT_Long component_offset,
+ FT_UShort gid )
+{
+ FT_Long component_index;
+ GX_MetamorphosisComponentTable component_table = &body->componentTable;
+
+ component_offset = gx_sign_extend ( component_offset,
+ GX_MORT_LIGATURE_ACTION_OFFSET );
+ component_index = (2 * component_offset - component_table->offset)/2 + gid;
+ FT_ASSERT ( component_index < component_table->nComponent );
+ return component_table->body[component_index];
+}
+
+static FT_UShort
+ligature_get_ligature ( GX_MetamorphosisLigatureBody body,
+ FT_ULong action,
+ FT_Long accumulator )
+{
+ FT_Long ligature_index;
+ GX_MetamorphosisLigatureTable ligature_table = &body->ligatureTable;
+
+ ligature_index = (accumulator - ligature_table->offset)/2;
+ FT_ASSERT ( ligature_index < ligature_table->nLigature );
+
+ if (action & ( GX_MORT_LIGATURE_ACTION_LAST
+ | GX_MORT_LIGATURE_ACTION_STORE ))
+ return ligature_table->body[ligature_index];
+ else
+ return GX_DELETED_GLYPH_INDEX;
+}
+
+/*************************************************************************
+ * Insertion
+ *************************************************************************/
+
+static FT_Error
+insertion_insert ( GX_MetamorphosisInsertionList insertion,
+ FT_UShort flags,
+ FT_UShort count_mask,
+ FT_UShort pos_mask,
+ GList_InsertFunc insert,
+ GlyphsList glist );
+
+/* TODO: insert Tracer */
+FT_LOCAL_DEF( FT_Error )
+gx_insertion_subst( GX_MetamorphosisInsertionBody body,
+ GXL_Initial_State initial_state,
+ FTL_Glyphs_Array garray )
+{
+ FT_Error error;
+ FT_Memory memory = garray->memory;
+
+ GlyphsListRec glist;
+ FTL_Glyph current_glyph;
+ FT_UShort current_state;
+
+ FT_Byte class_code, final_class;
+ GX_EntrySubtable entry_subtable;
+
+ GX_MetamorphosisInsertionList current_insertion;
+ GX_MetamorphosisInsertionList marked_insertion;
+
+ FT_TRACE2(("Enter insertion\n"));
+
+ if (( error = glist_init(memory, &glist, garray) ))
+ return error;
+
+ current_state = body->state_table.header.stateArray + (FT_Byte)initial_state;
+ final_class = ( initial_state == GXL_START_OF_TEXT_STATE )
+ ? GX_CLASS_END_OF_TEXT: GX_CLASS_END_OF_LINE;
+
+ do {
+ current_glyph = glist_get_current(&glist);
+
+ /* glyph -> class */
+ class_code = ( current_glyph == NULL)
+ ? final_class: gx_StateTable_get_class( &body->state_table,
+ current_glyph->gid );
+ FT_TRACE3((" class code: %u current state: %u\n", class_code, current_state ));
+
+ /* class -> entry */
+ entry_subtable = gx_StateTable_get_entry_subtable( &body->state_table,
+ current_state,
+ class_code );
+ /* action for entry */
+ current_insertion = &entry_subtable->glyphOffsets.insertion->currentInsertList;
+ marked_insertion = &entry_subtable->glyphOffsets.insertion->markedInsertList;
+ if ( current_insertion->offset )
+ {
+ if (( error = insertion_insert ( current_insertion,
+ entry_subtable->flags,
+ GX_MORT_INSERTION_FLAGS_CURRENT_INSERT_COUNT,
+ GX_MORT_INSERTION_FLAGS_CURRENT_INSERT_BEFORE,
+ glist_insert_current,
+ &glist ) ))
+ goto Failure;
+ }
+
+ if ( marked_insertion->offset )
+ {
+ if (( error = insertion_insert ( marked_insertion,
+ entry_subtable->flags,
+ GX_MORT_INSERTION_FLAGS_MARKED_INSERT_COUNT,
+ GX_MORT_INSERTION_FLAGS_MARKED_INSERT_BEFORE,
+ glist_insert_mark,
+ &glist ) ))
+ goto Failure;
+ }
+
+ /* set mark */
+ if ( entry_subtable->flags & GX_MORT_INSERTION_FLAGS_SET_MARK )
+ glist_set_mark( &glist );
+
+ /* advance */
+ if (!( entry_subtable->flags & GX_MORT_INSERTION_FLAGS_DONT_ADVANCE ))
+ (void)glist_get_next( &glist );
+
+ /* new state */
+ current_state = entry_subtable->newState;
+ } while ( current_glyph );
+
+ FT_TRACE2(("Leave insertion\n"));
+ if (( error = glist_store ( &glist, garray ) ))
+ goto Failure;
+ glist_finalize( &glist );
+ return error;
+ Failure:
+ glist_finalize( &glist );
+ return error;
+}
+
+static FT_Error
+insertion_insert ( GX_MetamorphosisInsertionList insertion,
+ FT_UShort flags,
+ FT_UShort count_mask,
+ FT_UShort pos_mask,
+ GList_InsertFunc insert,
+ GlyphsList glist )
+{
+ FT_Int count, i;
+ FT_Bool before;
+ InsertionGlyphsRec glyphs;
+
+
+ count = gx_mask_zero_shift(flags, count_mask);
+ before = (flags & pos_mask) ? 1: 0;
+
+ insertion_glyphs_init ( &glyphs );
+ for ( i = 0; i < count; i++ )
+ insertion_glyphs_push( &glyphs, insertion->glyphcodes[i] );
+ /* TODO: kashida like or split vowels */
+ return insert( glist, &glyphs, before );
+}
+
+/*************************************************************************
+ * Rearrangement
+ *************************************************************************/
+static void rearrangement_rearrange( GX_MetamorphosisRearrangementVerb verb,
+ FT_ULong first_glyph,
+ FT_ULong last_glyph,
+ FTL_Glyphs_Array garray );
+FT_LOCAL( FT_Error )
+gx_rearrangement_subst ( GX_MetamorphosisRearrangementBody body,
+ GXL_Initial_State initial_state,
+ FTL_Glyphs_Array garray )
+{
+ FT_ULong glength = garray->length;
+ FTL_Glyph glyphs = garray->glyphs;
+ FT_UShort current_state;
+
+ FT_ULong current_glyph, first_glyph, last_glyph;
+ FT_Byte class_code, final_class;
+ GX_EntrySubtable entry_subtable;
+
+ GX_MetamorphosisRearrangementVerb verb;
+
+ FT_TRACE2(("Enter rearrangement\n"));
+ current_glyph = 0;
+ first_glyph = 0;
+ last_glyph = 0;
+ current_state = body->state_table.header.stateArray + (FT_Byte)initial_state;
+ final_class = ( initial_state == GXL_START_OF_TEXT_STATE )
+ ? GX_CLASS_END_OF_TEXT: GX_CLASS_END_OF_LINE;
+
+ while ( current_glyph <= glength )
+ {
+ FT_TRACE3((" glyph id: %u, glyph position: %lu/%lu\n",
+ current_glyph == glength? 0xFFFF: glyphs[current_glyph].gid,
+ current_glyph, glength ));
+
+ /* glyph -> class */
+ class_code = ( current_glyph == glength )
+ ? final_class: gx_StateTable_get_class ( &body->state_table,
+ glyphs[current_glyph].gid );
+ FT_TRACE3((" class code: %u current state: %u\n", class_code, current_state ));
+
+ /* class -> entry */
+ entry_subtable = gx_StateTable_get_entry_subtable ( &body->state_table,
+ current_state,
+ class_code );
+ /* action for entry */
+ if ( entry_subtable->flags & GX_MORT_REARRANGEMENT_FLAGS_MARK_FIRST )
+ {
+ FT_TRACE3(( " set %lu as first\n", current_glyph ));
+ first_glyph = current_glyph;
+ }
+ if ( entry_subtable->flags & GX_MORT_REARRANGEMENT_FLAGS_MARK_LAST )
+ {
+ FT_TRACE3(( " set %lu as last\n", current_glyph ));
+ last_glyph = current_glyph;
+ }
+
+ /* rearrange */
+ verb = entry_subtable->flags & GX_MORT_REARRANGEMENT_FLAGS_VERB;
+ FT_TRACE3((" verb %d\n", verb));
+ rearrangement_rearrange( verb, first_glyph, last_glyph, garray );
+
+ /* advance */
+ if ( !(entry_subtable->flags & GX_MORT_REARRANGEMENT_FLAGS_DONT_ADVANCE) )
+ {
+ FT_TRACE3((" index++.\n"));
+ current_glyph++;
+ }
+
+ /* new state */
+ current_state = entry_subtable->newState;
+ }
+ FT_TRACE2(("Leave rearrangement\n"));
+ return FT_Err_Ok;
+}
+
+static void
+rearrangement_rearrange( GX_MetamorphosisRearrangementVerb verb,
+ FT_ULong first_glyph,
+ FT_ULong last_glyph,
+ FTL_Glyphs_Array garray )
+{
+ FTL_Glyph glyphs = garray->glyphs;
+ FT_ULong glength = garray->length;
+
+ FTL_GlyphRec A, B, C, D;
+ FT_ULong x;
+
+
+ /* Treat VERB_NO_CHANGE as a special case; return
+ before "first_glyph <= last_glyph" assertion. */
+ if ( verb == GX_MORT_REARRANGEMENT_VERB_NO_CHANGE )
+ return ;
+
+ FT_ASSERT ( first_glyph <= last_glyph );
+ FT_ASSERT ( first_glyph < glength );
+ FT_ASSERT ( last_glyph < glength );
+
+ switch ( verb )
+ {
+ case GX_MORT_REARRANGEMENT_VERB_Ax2xA:
+ A = glyphs[first_glyph];
+ for ( x = first_glyph + 1; x <= last_glyph; x++ )
+ glyphs[x - 1] = glyphs[x];
+ glyphs[last_glyph] = A;
+ break;
+
+ case GX_MORT_REARRANGEMENT_VERB_xD2Dx:
+ D = glyphs[last_glyph];
+ for ( x = last_glyph - 1; x >= first_glyph; x-- )
+ glyphs[x + 1] = glyphs[x];
+ glyphs[first_glyph] = D;
+ break;
+
+ case GX_MORT_REARRANGEMENT_VERB_AxD2DxA:
+ A = glyphs[first_glyph];
+ D = glyphs[last_glyph];
+ glyphs[first_glyph] = D;
+ glyphs[last_glyph] = A;
+ break;
+
+ case GX_MORT_REARRANGEMENT_VERB_ABx2xAB:
+ FT_ASSERT( first_glyph + 1 < glength );
+ FT_ASSERT( first_glyph + 2 <= last_glyph );
+ FT_ASSERT( last_glyph - 1 >= 0 );
+
+ A = glyphs[first_glyph];
+ B = glyphs[first_glyph + 1];
+ for ( x = first_glyph + 2; x <= last_glyph; x++ )
+ glyphs[x - 2] = glyphs[x];
+ glyphs[last_glyph - 1] = A;
+ glyphs[last_glyph] = B;
+ break;
+
+ case GX_MORT_REARRANGEMENT_VERB_ABx2xBA:
+ FT_ASSERT( first_glyph + 1 < glength );
+ FT_ASSERT( first_glyph + 2 <= last_glyph );
+ FT_ASSERT( last_glyph - 1 >= 0 );
+
+ A = glyphs[first_glyph];
+ B = glyphs[first_glyph + 1];
+ for ( x = first_glyph + 2; x <= last_glyph; x++ )
+ glyphs[x - 2] = glyphs[x];
+
+ glyphs[last_glyph - 1] = B;
+ glyphs[last_glyph] = A;
+ break;
+
+ case GX_MORT_REARRANGEMENT_VERB_xCD2CDx:
+ FT_ASSERT( last_glyph - 1 >= 0 );
+ FT_ASSERT( first_glyph <= last_glyph - 2 );
+ FT_ASSERT( first_glyph + 1 < glength );
+ C = glyphs[last_glyph - 1];
+ D = glyphs[last_glyph];
+ for ( x = last_glyph - 2; x >= first_glyph; x-- )
+ glyphs[x + 2] = glyphs[x];
+
+ glyphs[first_glyph] = C;
+ glyphs[first_glyph + 1] = D;
+ break;
+
+ case GX_MORT_REARRANGEMENT_VERB_xCD2DCx:
+ FT_ASSERT( last_glyph - 1 >= 0 );
+ FT_ASSERT( first_glyph <= last_glyph - 2 );
+ FT_ASSERT( first_glyph + 1 < glength );
+ C = glyphs[last_glyph - 1];
+ D = glyphs[last_glyph];
+ for ( x = last_glyph - 2; x >= first_glyph; x-- )
+ glyphs[x + 2] = glyphs[x];
+
+ glyphs[first_glyph] = D;
+ glyphs[first_glyph + 1] = C;
+ break;
+
+ case GX_MORT_REARRANGEMENT_VERB_AxCD2CDxA:
+ FT_ASSERT( last_glyph - 2 >= 0 );
+ FT_ASSERT( first_glyph + 1 < glength );
+ A = glyphs[first_glyph];
+ C = glyphs[last_glyph - 1];
+ D = glyphs[last_glyph];
+ for ( x = last_glyph - 2; x > first_glyph; x-- )
+ glyphs[x + 1] = glyphs[x];
+ glyphs[first_glyph] = C;
+ glyphs[first_glyph + 1] = D;
+ glyphs[last_glyph] = A;
+ break;
+
+ case GX_MORT_REARRANGEMENT_VERB_AxCD2DCxA:
+ FT_ASSERT( last_glyph - 2 >= 0 );
+ FT_ASSERT( first_glyph + 1 < glength );
+ A = glyphs[first_glyph];
+ C = glyphs[last_glyph - 1];
+ D = glyphs[last_glyph];
+
+ for ( x = last_glyph - 2; x > first_glyph; x-- )
+ glyphs[x + 1] = glyphs[x];
+
+ glyphs[first_glyph] = D;
+ glyphs[first_glyph + 1] = C;
+ glyphs[last_glyph] = A;
+ break;
+
+ case GX_MORT_REARRANGEMENT_VERB_ABxD2DxAB:
+ FT_ASSERT ( first_glyph + 2 < glength );
+ FT_ASSERT ( last_glyph - 1 >= 0 );
+ A = glyphs[first_glyph];
+ B = glyphs[first_glyph + 1];
+ D = glyphs[last_glyph];
+ for ( x = first_glyph + 2; x < last_glyph; x++ )
+ glyphs[x - 2] = glyphs[x];
+ glyphs[first_glyph] = D;
+ glyphs[last_glyph - 1] = A;
+ glyphs[last_glyph] = B;
+ break;
+
+ case GX_MORT_REARRANGEMENT_VERB_ABxD2DxBA:
+ FT_ASSERT ( first_glyph + 2 < glength );
+ FT_ASSERT ( last_glyph - 1 >= 0 );
+ A = glyphs[first_glyph];
+ B = glyphs[first_glyph + 1];
+ D = glyphs[last_glyph];
+ for ( x = first_glyph + 2; x < last_glyph; x++ )
+ glyphs[x - 2] = glyphs[x];
+ glyphs[first_glyph] = D;
+ glyphs[last_glyph - 1] = B;
+ glyphs[last_glyph] = A;
+ break;
+
+ case GX_MORT_REARRANGEMENT_VERB_ABxCD2CDxAB:
+ FT_ASSERT( first_glyph + 1 < glength );
+ FT_ASSERT( last_glyph - 1 >= 0 );
+ A = glyphs[first_glyph];
+ B = glyphs[first_glyph + 1];
+ C = glyphs[last_glyph - 1];
+ D = glyphs[last_glyph];
+ glyphs[first_glyph] = C;
+ glyphs[first_glyph + 1] = D;
+ glyphs[last_glyph - 1] = A;
+ glyphs[last_glyph] = B;
+ break;
+
+ case GX_MORT_REARRANGEMENT_VERB_ABxCD2CDxBA:
+ FT_ASSERT( first_glyph + 1 < glength );
+ FT_ASSERT( last_glyph - 1 >= 0 );
+ A = glyphs[first_glyph];
+ B = glyphs[first_glyph + 1];
+ C = glyphs[last_glyph - 1];
+ D = glyphs[last_glyph];
+ glyphs[first_glyph] = C;
+ glyphs[first_glyph + 1] = D;
+ glyphs[last_glyph - 1] = B;
+ glyphs[last_glyph] = A;
+ break;
+
+ case GX_MORT_REARRANGEMENT_VERB_ABxCD2DCxAB:
+ FT_ASSERT( first_glyph + 1 < glength );
+ FT_ASSERT( last_glyph - 1 >= 0 );
+ A = glyphs[first_glyph];
+ B = glyphs[first_glyph + 1];
+ C = glyphs[last_glyph - 1];
+ D = glyphs[last_glyph];
+ glyphs[first_glyph] = D;
+ glyphs[first_glyph + 1] = C;
+ glyphs[last_glyph - 1] = A;
+ glyphs[last_glyph] = B;
+ break;
+ case GX_MORT_REARRANGEMENT_VERB_ABxCD2DCxBA:
+ FT_ASSERT( first_glyph + 1 < glength );
+ FT_ASSERT( last_glyph - 1 >= 0 );
+ A = glyphs[first_glyph];
+ B = glyphs[first_glyph + 1];
+ C = glyphs[last_glyph - 1];
+ D = glyphs[last_glyph];
+ glyphs[first_glyph] = D;
+ glyphs[first_glyph + 1] = C;
+ glyphs[last_glyph - 1] = B;
+ glyphs[last_glyph] = A;
+ break;
+ default:
+ break; /* TODO: Broken verb */
+ }
+}
+
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+ /**** ****/
+ /**** ****/
+ /**** Extended Glyph Metamorphosis ****/
+ /**** ****/
+ /**** ****/
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+
+/*************************************************************************
+ * Contextual
+ *************************************************************************/
+
+static FT_UShort xcontextual_lookup_glyph( GX_XMetamorphosisContextualBody body,
+ FT_UShort lookup_table_index,
+ FT_UShort glyph );
+
+FT_LOCAL_DEF( FT_Error )
+gx_xcontextual_subst( GX_XMetamorphosisContextualBody body,
+ GXL_Initial_State initial_state,
+ FTL_Glyphs_Array garray )
+{
+
+ FT_ULong glength = garray->length;
+ FTL_Glyph glyphs = garray->glyphs;
+ FT_UShort current_state;
+
+ FT_ULong current_glyph, mark_glyph;
+ FT_UShort class_code, final_class;
+ GX_EntrySubtable entry_subtable;
+
+ FT_UShort markIndex, currentIndex;
+ FT_UShort tmp;
+
+ FT_TRACE2(("Enter xcontextual\n"));
+
+ current_glyph = 0;
+ mark_glyph = 0;
+ current_state = 0;
+ final_class = ( initial_state == GXL_START_OF_TEXT_STATE )
+ ? GX_CLASS_END_OF_TEXT: GX_CLASS_END_OF_LINE;
+
+ while ( current_glyph <= glength )
+ {
+ FT_TRACE3((" glyph id: %u, glyph position: %lu/%lu\n",
+ current_glyph == glength? 0xFFFF: glyphs[current_glyph].gid,
+ current_glyph, glength ));
+
+
+ /* glyph -> class */
+ class_code = ( current_glyph == glength )
+ ? final_class: gx_XStateTable_get_class ( &body->state_table,
+ glyphs[current_glyph].gid );
+ FT_TRACE3((" class code: %u current state: %u\n", class_code, current_state ));
+
+ /* class -> entry */
+ entry_subtable = gx_XStateTable_get_entry_subtable ( &body->state_table,
+ current_state,
+ class_code );
+
+ currentIndex = entry_subtable->glyphOffsets.contextual->currentOffset;
+ markIndex = entry_subtable->glyphOffsets.contextual->markOffset;
+ if ( currentIndex != GX_MORX_NO_SUBSTITUTION )
+ {
+ tmp = glyphs[current_glyph].gid;
+ glyphs[current_glyph].gid = xcontextual_lookup_glyph( body,
+ currentIndex,
+ glyphs[current_glyph].gid );
+ FT_TRACE3((" Substitution[current %lu] %u to %u\n",
+ current_glyph, tmp, glyphs[current_glyph].gid ));
+ }
+ if ( markIndex != GX_MORX_NO_SUBSTITUTION )
+ {
+ tmp = glyphs[mark_glyph].gid;
+ glyphs[mark_glyph].gid = xcontextual_lookup_glyph( body,
+ markIndex,
+ glyphs[mark_glyph].gid );
+ FT_TRACE3((" Substitution[mark %lu] %u to %u\n",
+ mark_glyph, tmp, glyphs[mark_glyph].gid ));
+ }
+
+ if ( entry_subtable->flags & GX_MORX_CONTEXTUAL_FLAGS_SET_MARK )
+ {
+ mark_glyph = current_glyph;
+ FT_TRACE3((" %ld is marked.\n", mark_glyph ));
+ }
+
+ /* advance */
+ if ( !(entry_subtable->flags & GX_MORX_CONTEXTUAL_FLAGS_DONT_ADVANCE ) )
+ {
+ FT_TRACE3((" index++.\n"));
+ current_glyph++;
+ }
+ current_state = entry_subtable->newState;
+ }
+ FT_TRACE2(("Leave contextual\n"));
+ return FT_Err_Ok;
+}
+
+static FT_UShort
+xcontextual_lookup_glyph( GX_XMetamorphosisContextualBody body,
+ FT_UShort lookup_table_index,
+ FT_UShort glyph )
+{
+ GX_LookupTable * lookupTables;
+ GX_LookupResultRec result;
+ FT_ASSERT( lookup_table_index < body->substitutionTable.nTables );
+
+ lookupTables = body->substitutionTable.lookupTables;
+ result = gx_LookupTable_lookup( lookupTables[lookup_table_index], glyph );
+ if ( result.value == NULL )
+ return glyph; /* ??? */
+ else if ( result.firstGlyph == GX_LOOKUP_RESULT_NO_FIRST_GLYPH )
+ return result.value->raw.u;
+ else
+ return result.value->extra.word[glyph - result.firstGlyph];
+}
+
+/*************************************************************************
+ * Ligature
+ *************************************************************************/
+
+static FT_ULong * xligature_get_action( GX_XMetamorphosisLigatureBody body,
+ FT_UShort action_index );
+static FT_UShort xligature_get_component( GX_XMetamorphosisLigatureBody body,
+ FT_Long component_index_base,
+ FT_UShort gid );
+static FT_UShort xligature_get_ligature ( GX_XMetamorphosisLigatureBody body,
+ FT_ULong action,
+ FT_Long ligature_index );
+
+FT_LOCAL_DEF( FT_Error )
+gx_xligature_subst( GX_XMetamorphosisLigatureBody body,
+ GXL_Initial_State initial_state,
+ FTL_Glyphs_Array garray )
+{
+ FT_ULong glength = garray->length;
+ FTL_Glyph glyphs = garray->glyphs;
+ FT_UShort current_state;
+
+ FT_ULong current_glyph, component_glyph;
+ FT_UShort class_code, final_class;
+ GX_EntrySubtable entry_subtable;
+
+ LigatureStackRec ligstack;
+ FT_UShort action_index;
+ FT_ULong *action;
+
+ FT_UShort component;
+ FT_Long component_index_base;
+ FT_Long component_accumulator;
+ FT_UShort tmp;
+
+ FT_TRACE2(("Enter xligature\n"));
+
+ current_glyph = 0;
+ current_state = 0;
+ final_class = ( initial_state == GXL_START_OF_TEXT_STATE )
+ ? GX_CLASS_END_OF_TEXT: GX_CLASS_END_OF_LINE;
+
+ ligstack_init( &ligstack );
+ while ( current_glyph <= glength )
+ {
+ FT_TRACE3((" glyph id: %u, glyph position: %lu/%lu\n",
+ current_glyph == glength? 0xFFFF: glyphs[current_glyph].gid,
+ current_glyph, glength ));
+
+ /* glyph -> class */
+ class_code = ( current_glyph == glength )
+ ? final_class: gx_XStateTable_get_class ( &body->state_table,
+ glyphs[current_glyph].gid );
+ FT_TRACE3((" class code: %u current state: %u\n", class_code, current_state ));
+
+ /* class -> entry */
+ entry_subtable = gx_XStateTable_get_entry_subtable ( &body->state_table,
+ current_state,
+ class_code );
+
+ /* action for entry */
+ if ( entry_subtable->flags & GX_MORX_LIGATURE_FLAGS_SET_COMPONENT )
+ {
+ FT_TRACE3((" Push[current_glyph %lu] %lu to the stack\n",
+ current_glyph, glyphs[current_glyph] ));
+ ligstack_push(&ligstack, current_glyph);
+ }
+
+ if ( entry_subtable->flags & GX_MORX_LIGATURE_FLAGS_PERFORM_ACTION )
+ {
+ action_index = entry_subtable->glyphOffsets.ligActionIndex;
+ action = xligature_get_action( body, action_index ) - 1;
+ component_accumulator = 0;
+ ligstack_ligatured_init( &ligstack );
+
+ do {
+ action++;
+ component_glyph = ligstack_pop( &ligstack );
+ FT_TRACE3((" Pop[component_glyph %lu] %u from the stack\n",
+ component_glyph, glyphs[component_glyph].gid ));
+ FT_TRACE3((" Action[last %d, store %d]\n",
+ (*action & ( GX_MORX_LIGATURE_ACTION_LAST ))?1:0,
+ (*action & ( GX_MORX_LIGATURE_ACTION_STORE ))?1:0 ));
+ component_index_base = (*action) & GX_MORX_LIGATURE_ACTION_OFFSET;
+ component = xligature_get_component( body,
+ component_index_base,
+ glyphs[component_glyph].gid );
+ component_accumulator += component;
+ tmp = xligature_get_ligature( body,
+ *action,
+ component_accumulator );
+ FT_TRACE3((" Substitution[component %lu] %u to %u\n",
+ component_glyph, glyphs[component_glyph].gid, tmp ));
+ glyphs[component_glyph].gid = tmp;
+ if (*action & ( GX_MORX_LIGATURE_ACTION_LAST |
+ GX_MORX_LIGATURE_ACTION_STORE ))
+ {
+ ligstack_ligatured_push( &ligstack, component_glyph );
+ component_accumulator = 0;
+ }
+ } while (! ((*action) & GX_MORX_LIGATURE_ACTION_LAST));
+ ligstack_unify ( &ligstack );
+ }
+
+ /* advance */
+ if ( !(entry_subtable->flags & GX_MORX_LIGATURE_FLAGS_DONT_ADVANCE ) )
+ {
+ FT_TRACE3((" index++.\n"));
+ current_glyph++;
+ }
+
+ /* new state */
+ current_state = entry_subtable->newState;
+ }
+ FT_TRACE2(("Leave xligature\n"));
+ return FT_Err_Ok;
+}
+
+static FT_ULong *
+xligature_get_action( GX_XMetamorphosisLigatureBody body,
+ FT_UShort action_index )
+{
+ GX_XMetamorphosisLigatureActionTable action_table = &body->ligActionTable;
+ FT_ASSERT( (action_index < action_table->nActions ) );
+ return &(action_table->body[action_index]);
+}
+
+static FT_UShort
+xligature_get_component( GX_XMetamorphosisLigatureBody body,
+ FT_Long component_index_base,
+ FT_UShort gid )
+{
+ FT_Long component_index;
+ GX_XMetamorphosisComponentTable component_table = &body->componentTable;
+ component_index = gx_sign_extend ( component_index_base,
+ GX_MORX_LIGATURE_ACTION_OFFSET )
+ + gid;
+ FT_ASSERT ( component_index < component_table->nComponent );
+ return component_table->body[component_index];
+}
+
+static FT_UShort
+xligature_get_ligature ( GX_XMetamorphosisLigatureBody body,
+ FT_ULong action,
+ FT_Long ligature_index )
+{
+ GX_XMetamorphosisLigatureTable ligature_table = &body->ligatureTable;
+
+ FT_ASSERT ( ligature_index < ligature_table->nLigature );
+
+ if (action & ( GX_MORT_LIGATURE_ACTION_LAST
+ | GX_MORT_LIGATURE_ACTION_STORE ))
+ return ligature_table->body[ligature_index];
+ else
+ return GX_DELETED_GLYPH_INDEX;
+}
+
+/*************************************************************************
+ * Insertion
+ *************************************************************************/
+#define xinsertion_insert insertion_insert
+
+FT_LOCAL_DEF( FT_Error )
+gx_xinsertion_subst( GX_XMetamorphosisInsertionBody body,
+ GXL_Initial_State initial_state,
+ FTL_Glyphs_Array garray )
+{
+ FT_Error error;
+ FT_Memory memory = garray->memory;
+
+ GlyphsListRec glist;
+ FTL_Glyph current_glyph;
+ FT_UShort current_state;
+
+ FT_Byte class_code, final_class;
+ GX_EntrySubtable entry_subtable;
+
+ GX_MetamorphosisInsertionList current_insertion;
+ GX_MetamorphosisInsertionList marked_insertion;
+
+
+ FT_TRACE2(("Enter xinsertion\n"));
+
+ if (( error = glist_init(memory, &glist, garray) ))
+ return error;
+
+ current_state = 0;
+ final_class = ( initial_state == GXL_START_OF_TEXT_STATE )
+ ? GX_CLASS_END_OF_TEXT: GX_CLASS_END_OF_LINE;
+
+ do {
+ current_glyph = glist_get_current(&glist);
+
+ /* glyph -> class */
+ class_code = ( current_glyph == NULL)
+ ? final_class: gx_XStateTable_get_class( &body->state_table,
+ current_glyph->gid );
+ FT_TRACE3((" class code: %u current state: %u\n", class_code, current_state ));
+
+ /* class -> entry */
+ entry_subtable = gx_XStateTable_get_entry_subtable ( &body->state_table,
+ current_state,
+ class_code );
+
+ /* action for entry */
+ current_insertion = &entry_subtable->glyphOffsets.insertion->currentInsertList;
+ marked_insertion = &entry_subtable->glyphOffsets.insertion->markedInsertList;
+ if ( current_insertion->offset != GX_MORX_NO_INSERTION )
+ {
+ if (( error = xinsertion_insert( current_insertion,
+ entry_subtable->flags,
+ GX_MORX_INSERTION_FLAGS_CURRENT_INSERT_COUNT,
+ GX_MORX_INSERTION_FLAGS_CURRENT_INSERT_BEFORE,
+ glist_insert_current,
+ &glist )))
+ goto Failure;
+ }
+ if ( marked_insertion->offset != GX_MORX_NO_INSERTION )
+ {
+ if ((error = xinsertion_insert( marked_insertion,
+ entry_subtable->flags,
+ GX_MORX_INSERTION_FLAGS_MARKED_INSERT_COUNT,
+ GX_MORX_INSERTION_FLAGS_MARKED_INSERT_BEFORE,
+ glist_insert_mark,
+ &glist )))
+ goto Failure;
+ }
+ /* set mark */
+ if ( entry_subtable->flags & GX_MORX_INSERTION_FLAGS_SET_MARK )
+ glist_set_mark( &glist );
+
+ /* advance */
+ if ( !(entry_subtable->flags & GX_MORX_INSERTION_FLAGS_DONT_ADVANCE) )
+ (void)glist_get_next( &glist );
+
+ /* new state */
+ current_state = entry_subtable->newState;
+ } while ( current_glyph );
+
+ FT_TRACE2(("Leave xinsertion\n"));
+ if (( error = glist_store ( &glist, garray ) ))
+ goto Failure;
+ glist_finalize( &glist );
+ return error;
+ Failure:
+ glist_finalize( &glist );
+ return error;
+}
+
+/*************************************************************************
+ * Rearrangement
+ *************************************************************************/
+#define xrearrangement_rearrange rearrangement_rearrange
+
+FT_LOCAL( FT_Error )
+gx_xrearrangement_subst ( GX_XMetamorphosisRearrangementBody body,
+ GXL_Initial_State initial_state,
+ FTL_Glyphs_Array garray )
+
+{
+ FT_ULong glength = garray->length;
+ FTL_Glyph glyphs = garray->glyphs;
+ FT_UShort current_state;
+
+ FT_ULong current_glyph, first_glyph, last_glyph;
+ FT_UShort class_code, final_class;
+ GX_EntrySubtable entry_subtable;
+
+ GX_XMetamorphosisRearrangementVerb verb;
+
+ FT_TRACE2(("Enter xrearrangement\n"));
+
+ current_glyph = 0;
+ first_glyph = 0;
+ last_glyph = 0;
+ current_state = 0;
+ final_class = ( initial_state == GXL_START_OF_TEXT_STATE )
+ ? GX_CLASS_END_OF_TEXT: GX_CLASS_END_OF_LINE;
+
+ while ( current_glyph <= glength )
+ {
+ FT_TRACE3((" glyph id: %u, glyph position: %lu/%lu\n",
+ current_glyph == glength? 0xFFFF: glyphs[current_glyph].gid,
+ current_glyph, glength ));
+
+ /* glyph -> class */
+ class_code = ( current_glyph == glength )
+ ? final_class: gx_XStateTable_get_class ( &body->state_table,
+ glyphs[current_glyph].gid );
+ FT_TRACE3((" class code: %u current state: %u\n", class_code, current_state ));
+
+ /* class -> entry */
+ entry_subtable = gx_XStateTable_get_entry_subtable ( &body->state_table,
+ current_state,
+ class_code );
+ /* action for entry */
+ if ( entry_subtable->flags & GX_MORX_REARRANGEMENT_FLAGS_MARK_FIRST )
+ {
+ FT_TRACE3(( " set %lu as first\n", current_glyph ));
+ first_glyph = current_glyph;
+ }
+ if ( entry_subtable->flags & GX_MORX_REARRANGEMENT_FLAGS_MARK_LAST )
+ {
+ FT_TRACE3(( " set %lu as last\n", current_glyph ));
+ last_glyph = current_glyph;
+ }
+
+ /* rearrange */
+ verb = entry_subtable->flags & GX_MORX_REARRANGEMENT_FLAGS_VERB;
+ FT_TRACE3((" verb %d\n", verb));
+ xrearrangement_rearrange( verb, first_glyph, last_glyph, garray );
+
+ /* advance */
+ if ( !(entry_subtable->flags & GX_MORX_REARRANGEMENT_FLAGS_DONT_ADVANCE) )
+ {
+ FT_TRACE3((" index++.\n"));
+ current_glyph++;
+ }
+
+ /* new state */
+ current_state = entry_subtable->newState;
+ }
+ FT_TRACE2(("Leave xrearrangement\n"));
+ return FT_Err_Ok;
+}
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+ /**** ****/
+ /**** ****/
+ /**** Kerning Stack ****/
+ /**** ****/
+ /**** ****/
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+
+#define KERNING_STACK_DEPTH 8
+typedef LigatureStackRec KerningStackRec;
+typedef LigatureStack KerningStack;
+static void kernstack_init( KerningStack stack );
+#define kernstack_push ligstack_push
+#define kernstack_pop ligstack_pop
+static void
+kernstack_init( KerningStack stack )
+{
+ FT_Int i;
+ stack->depth = KERNING_STACK_DEPTH;
+ stack->top = -1;
+ for ( i = 0; i < stack->depth; i++ )
+ stack->indexes[i] = 0;
+}
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+ /**** ****/
+ /**** ****/
+ /**** Contextual Kerning ****/
+ /**** ****/
+ /**** ****/
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+
+FT_LOCAL_DEF( FT_Error )
+gx_contextual_kerning_calc ( GX_KerningSubtableFormat1Body kern_fmt1,
+ FTL_Glyphs_Array garray,
+ FTL_Direction dir,
+ FT_Bool cross_stream,
+ GXL_Initial_State initial_state,
+ FT_Vector * kerning )
+{
+ FT_ULong glength = garray->length;
+ FTL_Glyph glyphs = garray->glyphs;
+ FT_UShort current_state;
+
+ FT_ULong current_glyph, applied_glyph;
+ FT_Byte class_code, final_class;
+ GX_EntrySubtable entry_subtable;
+
+ KerningStackRec kernstack;
+ FT_UShort value_offset;
+ FT_UShort value_index;
+ FT_FWord raw_value, value;
+ FT_Pos total_cross_stream = 0;
+ FT_Pos * target;
+
+
+ current_glyph = 0;
+ current_state = kern_fmt1->state_table.header.stateArray + (FT_Byte)initial_state;
+ final_class = ( initial_state == GXL_START_OF_TEXT_STATE )
+ ? GX_CLASS_END_OF_TEXT: GX_CLASS_END_OF_LINE;
+
+ kernstack_init( &kernstack );
+ while ( current_glyph <= glength )
+ {
+ FT_TRACE3((" glyph id: %u, glyph position: %lu/%lu\n",
+ current_glyph == glength? 0xFFFF: glyphs[current_glyph].gid,
+ current_glyph, glength ));
+
+ /* glyph -> class */
+ class_code = ( current_glyph == glength )
+ ? final_class: gx_StateTable_get_class ( &kern_fmt1->state_table,
+ glyphs[current_glyph].gid );
+ FT_TRACE3((" class code: %u current state: %u\n", class_code, current_state ));
+
+ /* class -> entry */
+ entry_subtable = gx_StateTable_get_entry_subtable ( &kern_fmt1->state_table,
+ current_state,
+ class_code );
+
+ /* action for entry */
+ if ( entry_subtable->flags & GX_KERN_ACTION_PUSH )
+ {
+ FT_TRACE3((" Push[current_glyph %lu] %lu to the stack\n",
+ current_glyph, glyphs[current_glyph] ));
+ kernstack_push(&kernstack, current_glyph);
+ }
+
+ /* action */
+ value_offset = entry_subtable->flags & GX_KERN_ACTION_VALUE_OFFSET;
+ if ( value_offset )
+ {
+ value_index = ( value_offset - kern_fmt1->valueTable )
+ / sizeof (*(kern_fmt1->values));
+
+ FT_ASSERT ( value_index < kern_fmt1->nValues );
+
+ value_index--;
+ do {
+ value_index++;
+ FT_ASSERT ( value_index < kern_fmt1->nValues );
+
+ raw_value = kern_fmt1->values[value_index];
+ if ( raw_value & GX_KERN_VALUE_RESET_CROSS_STREAM )
+ {
+ FT_TRACE3((" Reset cross stream kerning\n"));
+ value = -total_cross_stream;
+ total_cross_stream = 0;
+ }
+ else if (value == GX_KERN_VALUE_END_LIST)
+ value = 0;
+ else
+ {
+ value = raw_value;
+ if ( cross_stream )
+ total_cross_stream += value;
+ }
+
+ applied_glyph = kernstack_pop( &kernstack );
+ if ( cross_stream )
+ {
+ if ( dir == FTL_HORIZONTAL )
+ target = &kerning[applied_glyph + 1].y;
+ else
+ target = &kerning[applied_glyph + 1].x;
+ }
+ else
+ {
+ if ( dir == FTL_HORIZONTAL )
+ target = &kerning[applied_glyph + 1].x;
+ else
+ target = &kerning[applied_glyph + 1].y;
+ }
+
+ *target = value;
+ } while ( !( raw_value & GX_KERN_VALUE_END_LIST ) );
+ }
+
+ /* advance */
+ if ( !(entry_subtable->flags & GX_KERN_ACTION_DONT_ADVANCE ) )
+ {
+ FT_TRACE3((" index++.\n"));
+ current_glyph++;
+ }
+
+ /* new state */
+ current_state = entry_subtable->newState;
+ }
+ FT_TRACE2(("Leave contextual kerning\n"));
+ return FT_Err_Ok;
+}
+
+/* END */
diff --git a/src/gxlayout/gxvm.h b/src/gxlayout/gxvm.h
new file mode 100644
index 000000000..0b54a3a92
--- /dev/null
+++ b/src/gxlayout/gxvm.h
@@ -0,0 +1,99 @@
+/***************************************************************************/
+/* */
+/* gxvm.h */
+/* */
+/* AAT/TrueTypeGX glyph substitution automaton (specification). */
+/* */
+/* Copyright 2003 by */
+/* Masatake YAMATO and Redhat K.K. */
+/* */
+/* This file may only be used, */
+/* modified, and distributed under the terms of the FreeType project */
+/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
+/* this file you indicate that you have read the license and */
+/* understand and accept it fully. */
+/* */
+/***************************************************************************/
+
+/***************************************************************************/
+/* Development of the code in this file is support of */
+/* Information-technology Promotion Agency, Japan. */
+/***************************************************************************/
+
+#ifndef __GX_VM_H__
+#define __GX_VM_H__
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include "gxtypes.h"
+
+FT_BEGIN_HEADER
+
+/*
+ * Mort
+ */
+FT_LOCAL( FT_Error )
+gx_rearrangement_subst ( GX_MetamorphosisRearrangementBody body,
+ GXL_Initial_State initial_state,
+ FTL_Glyphs_Array garray );
+
+FT_LOCAL( FT_Error )
+gx_contextual_subst( GX_MetamorphosisContextualBody body,
+ GXL_Initial_State initial_state,
+ FTL_Glyphs_Array garray );
+
+FT_LOCAL( FT_Error )
+gx_ligature_subst( GX_MetamorphosisLigatureBody body,
+ GXL_Initial_State initial_state,
+ FTL_Glyphs_Array garray );
+
+FT_LOCAL( FT_Error )
+gx_noncontextual_subst( GX_MetamorphosisNoncontextualBody body,
+ FTL_Glyphs_Array garray );
+
+FT_LOCAL( FT_Error )
+gx_insertion_subst( GX_MetamorphosisInsertionBody body,
+ GXL_Initial_State initial_state,
+ FTL_Glyphs_Array garray );
+
+/*
+ * Morx
+ */
+#define gx_xnoncontextual_subst gx_noncontextual_subst
+FT_LOCAL( FT_Error )
+gx_xcontextual_subst( GX_XMetamorphosisContextualBody body,
+ GXL_Initial_State initial_state,
+ FTL_Glyphs_Array garray );
+
+FT_LOCAL( FT_Error )
+gx_xligature_subst( GX_XMetamorphosisLigatureBody body,
+ GXL_Initial_State initial_state,
+ FTL_Glyphs_Array garray );
+
+FT_LOCAL( FT_Error )
+gx_xinsertion_subst( GX_XMetamorphosisInsertionBody body,
+ GXL_Initial_State initial_state,
+ FTL_Glyphs_Array garray );
+
+FT_LOCAL( FT_Error )
+gx_xrearrangement_subst ( GX_XMetamorphosisRearrangementBody body,
+ GXL_Initial_State initial_state,
+ FTL_Glyphs_Array garray );
+
+/*
+ * Kern
+ */
+FT_LOCAL( FT_Error )
+gx_contextual_kerning_calc ( GX_KerningSubtableFormat1Body kern_fmt1,
+ FTL_Glyphs_Array garray,
+ FTL_Direction dir,
+ FT_Bool cross_stream,
+ GXL_Initial_State initial_state,
+ FT_Vector * kerning );
+
+FT_END_HEADER
+
+#endif /* Not def: __GX_VM_H__ */
+
+
+/* END */
diff --git a/src/gxlayout/module.mk b/src/gxlayout/module.mk
new file mode 100644
index 000000000..b9f810aaa
--- /dev/null
+++ b/src/gxlayout/module.mk
@@ -0,0 +1,33 @@
+#
+# FreeType 2 AAT/TrueTypeGX module definition
+#
+
+# Copyright 2004 by RedHat K.K.
+# This file is derived from cff/module.mk.
+
+# ----------------------------------------------------------------------
+#
+# FreeType 2 CFF module definition
+#
+
+
+# Copyright 1996-2000 by
+# David Turner, Robert Wilhelm, and Werner Lemberg.
+#
+# This file is part of the FreeType project, and may only be used, modified,
+# and distributed under the terms of the FreeType project license,
+# LICENSE.TXT. By continuing to use, modify, or distribute this file you
+# indicate that you have read the license and understand and accept it
+# fully.
+# ----------------------------------------------------------------------
+
+# Development of the code in module.mk is support of
+# Information-technology Promotion Agency, Japan.
+
+make_module_list: add_gx_driver
+
+add_gx_driver:
+ $(OPEN_DRIVER)gx_driver_class$(CLOSE_DRIVER)
+ $(ECHO_DRIVER)gx $(ECHO_DRIVER_DESC)AAT/TrueTypeGX fonts$(ECHO_DRIVER_DONE)
+
+# EOF
diff --git a/src/gxlayout/rules.mk b/src/gxlayout/rules.mk
new file mode 100644
index 000000000..035863b35
--- /dev/null
+++ b/src/gxlayout/rules.mk
@@ -0,0 +1,96 @@
+#
+# FreeType 2 AAT/TrueTypeGX driver configuration rules
+#
+
+
+# Copyright 2004 by RedHat K.K.
+# This file is derived from cff/rules.mk.
+
+# ----------------------------------------------------------------------
+#
+# FreeType 2 OpenType/CFF driver configuration rules
+#
+
+# Copyright 1996-2000, 2001, 2003 by
+# David Turner, Robert Wilhelm, and Werner Lemberg.
+#
+# This file is part of the FreeType project, and may only be used, modified,
+# and distributed under the terms of the FreeType project license,
+# LICENSE.TXT. By continuing to use, modify, or distribute this file you
+# indicate that you have read the license and understand and accept it
+# fully.
+# ----------------------------------------------------------------------
+
+# Development of the code in rules.mk is support of
+# Information-technology Promotion Agency, Japan.
+
+# AAT/TrueTypeGX driver directory
+#
+GX_DIR := $(SRC_DIR)/gxlayout
+
+
+GX_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(GX_DIR))
+
+
+# GX driver sources (i.e., C files)
+#
+GX_DRV_SRC := $(GX_DIR)/gxobjs.c \
+ $(GX_DIR)/gxload.c \
+ $(GX_DIR)/gxdriver.c \
+ $(GX_DIR)/gxlookuptbl.c \
+ $(GX_DIR)/gxstatetbl.c \
+ $(GX_DIR)/gxutils.c \
+ $(GX_DIR)/gxlayout.c \
+ $(GX_DIR)/gxfeatreg.c \
+ $(GX_DIR)/gxlfeatreg.c \
+ $(GX_DIR)/gxaccess.c \
+ $(GX_DIR)/gxvm.c \
+ $(GX_DIR)/gxdump.c
+
+# GX driver headers
+#
+GX_DRV_H := $(GX_DIR)/gxdriver.h \
+ $(GX_DIR)/gxload.h \
+ $(GX_DIR)/gxlookuptbl.h \
+ $(GX_DIR)/gxobjs.h \
+ $(GX_DIR)/gxstatetbl.h \
+ $(GX_DIR)/gxutils.h \
+ $(GX_DIR)/gxfeatreg.h \
+ $(GX_DIR)/gxlfeatreg.h \
+ $(GX_DIR)/gxaccess.h \
+ $(GX_DIR)/gxerrors.h \
+ $(GX_DIR)/gxvm.h \
+ $(GX_DIR)/gxdump.h
+
+# GX driver object(s)
+#
+# GX_DRV_OBJ_M is used during `multi' builds
+# GX_DRV_OBJ_S is used during `single' builds
+#
+GX_DRV_OBJ_M := $(GX_DRV_SRC:$(GX_DIR)/%.c=$(OBJ_DIR)/%.$O)
+GX_DRV_OBJ_S := $(OBJ_DIR)/gx.$O
+
+# GX driver source file for single build
+#
+GX_DRV_SRC_S := $(GX_DIR)/gx.c
+
+
+# GX driver - single object
+#
+$(GX_DRV_OBJ_S): $(GX_DRV_SRC_S) $(GX_DRV_SRC) $(FREETYPE_H) $(GX_DRV_H)
+ $(GX_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(GX_DRV_SRC_S))
+
+
+# GX driver - multiple objects
+#
+$(OBJ_DIR)/%.$O: $(GX_DIR)/%.c $(FREETYPE_H) $(GX_DRV_H)
+ $(GX_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<)
+
+
+# update main driver object lists
+#
+DRV_OBJS_S += $(GX_DRV_OBJ_S)
+DRV_OBJS_M += $(GX_DRV_OBJ_M)
+
+
+# EOF
diff --git a/src/otlayout/README b/src/otlayout/README
new file mode 100644
index 000000000..6df10949b
--- /dev/null
+++ b/src/otlayout/README
@@ -0,0 +1,145 @@
+This directory contains new otlayout, opentype adapter for ftlayout
+interface. Old otlayout is developed by FreeType developers and not
+completed yet. This new otlayout is not completed but works.
+
+New otlayout supports only gsub table. the glyph substitution for
+Japanese vertical layout is tested. gpos table is not supported.
+The languages other than Japanese is not tested yet by us.
+
+The files in this directory are come from different places.
+
+1. FreeType1/TrueTypeOpen support (via pango)
+2. Pango/opentype
+3. developed at RedHat K.K. supported by Information Technology Promotion Agency, Japan.
+4. glib/gunicode.h
+5. freetype2/otlayout(old otlayout) directory in FreeType CVS repository
+
+The files in 5. are not used in new otlayout.
+
+This new otlayout is experimental in all aspects.
+One of the biggest issue is that the symbols coming from 1.
+and 2. have global scope; you cannot link gtk/pango library
+with new otlayout. The symbol may be conflicted.
+
+1. The file coming from FreeType1/TrueTypeOpen support (via pango)
+------------------------------------------------------------------------
+ * Copyright 1996-2000 by
+ * David Turner, Robert Wilhelm, and Werner Lemberg.
+ *
+ * This file is part of the FreeType project, and may only be used
+ * modified and distributed under the terms of the FreeType project
+ * license, LICENSE.TXT. By continuing to use, modify, or distribute
+ * this file you indicate that you have read the license and
+ * understand and accept it fully.
+
+ftxgdef.c
+ftxgdef.h
+ftxgpos.c
+ftxgpos.h
+ftxgsub.c
+ftxgsub.h
+ftxopen.c
+ftxopen.h
+ftxopenf.h
+
+2. The file coming from Pango/opentype
+------------------------------------------------------------------------
+ * Copyright (C) 2003 Red Hat, Inc
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+
+ot-array.c
+ot-array.h
+ot-info.c
+ot-info.h
+ot-ruleset.c
+ot-ruleset.h
+ot-types.h
+
+3. The file developed at RedHat K.K. supported by IPA
+------------------------------------------------------------------------
+/* Copyright 2003 by */
+/* Masatake YAMATO and Redhat K.K. */
+/* */
+/* This file may only be used, */
+/* modified, and distributed under the terms of the FreeType project */
+/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
+/* this file you indicate that you have read the license and */
+/* understand and accept it fully. */
+
+ot.c
+otdriver.c
+otdriver.h
+oterrors.h
+otlayout.c
+otobjs.c
+otobjs.h
+otltypes.h
+substmain.c
+rules.mk
+otdemo.c
+demo.mk
+
+4. glib/gunicode.h
+------------------------------------------------------------------------
+ * Copyright (C) 1999, 2000 Tom Tromey
+ * Copyright 2000 Red Hat, Inc.
+ *
+ * The Gnome Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * The Gnome Library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the Gnome Library; see the file COPYING.LIB. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+
+ot-unicode.c
+ot-unicode.h
+
+5. The file coming from old otlayout
+------------------------------------------------------------------------
+otlayout.h
+otlbase.c
+otlbase.h
+otlcommn.c
+otlcommn.h
+otlconf.h
+otlgdef.c
+otlgdef.h
+otlgpos.c
+otlgpos.h
+otlgsub.c
+otlgsub.h
+otljstf.c
+otljstf.h
+otlparse.c
+otlparse.h
+otltable.h
+otltags.h
+otlutils.h
+
+Sun Feb 1 18:24:10 2004
+Masatake YAMATO, RedHat K.K.
+<jet@gyve.org> or <yamato@redhat.com>
+
+
diff --git a/src/otlayout/demo.mk b/src/otlayout/demo.mk
new file mode 100644
index 000000000..2684f26ca
--- /dev/null
+++ b/src/otlayout/demo.mk
@@ -0,0 +1,41 @@
+#
+# demo.mk --- Makefile for OpenType driver demo program
+#
+# Copyright 2004 by Masatake YAMATO and RedHat K.K.
+#
+# This file is part of the FreeType project, and may only be used, modified,
+# and distributed under the terms of the FreeType project license,
+# LICENSE.TXT. By continuing to use, modify, or distribute this file you
+# indicate that you have read the license and understand and accept it
+# fully.
+#
+########################################################################
+
+# Development of the code in demo.mk is support of
+# Information-technology Promotion Agency, Japan.
+
+SHELL=/bin/bash
+
+POPT_LIBS=-lpopt
+
+CFLAGS=-c -O0 -g -I../../include -Wall -std=c99
+LIBS=-Xlinker -rpath -Xlinker ../../objs/.libs -lz $(POPT_LIBS)
+########################################################################
+OTOBJ=../../objs/.libs/libfreetype.so
+
+DEMOBIN=otdemo
+DEMOOBJ=otdemo.o
+DEMOSRC=otdemo.c
+
+########################################################################
+all: $(DEMOBIN)
+$(DEMOBIN): $(OTOBJ) $(DEMOOBJ)
+ $(CC) -o $(@) $(LIBS) $^
+
+$(DEMOOBJ): $(DEMOSRC) $(OTOBJ)
+
+$(OTOBJ): *.c *.h
+ (cd ../../; make)
+########################################################################
+clean:
+ rm -f $(DEMOBIN) $(DEMOOBJ) core.*
diff --git a/src/otlayout/fterrcompat.h b/src/otlayout/fterrcompat.h
new file mode 100644
index 000000000..568d032a9
--- /dev/null
+++ b/src/otlayout/fterrcompat.h
@@ -0,0 +1,89 @@
+
+#ifndef FTERRCOMPAT_H
+#define FTERRCOMPAT_H
+
+/* #include <config.h> */
+#define FREETYPE_MAJOR 2
+#define FREETYPE_MINOR 1
+
+#define TT_Err_Ok FT_Err_Ok
+#define TT_Err_Invalid_Argument FT_Err_Invalid_Argument
+#define TT_Err_Invalid_Face_Handle FT_Err_Invalid_Face_Handle
+#define TT_Err_Table_Missing FT_Err_Table_Missing
+
+/* Compat macros for name changes in FreeType 2.1.0
+ */
+#if (FREETYPE_MAJOR == 2) && (FREETYPE_MINOR >= 1)
+
+#define FILE_Pos() FT_STREAM_POS()
+#define FILE_Seek( position ) FT_STREAM_SEEK( position)
+
+#define ACCESS_Frame( size ) FT_FRAME_ENTER( size )
+#define FORGET_Frame() FT_FRAME_EXIT()
+
+#define GET_Char() FT_GET_CHAR()
+#define GET_Byte() FT_GET_BYTE()
+#define GET_Short() FT_GET_SHORT()
+#define GET_UShort() FT_GET_USHORT()
+#define GET_Offset() FT_GET_OFF3()
+#define GET_UOffset() FT_GET_UOFF3()
+#define GET_Long() FT_GET_LONG()
+#define GET_ULong() FT_GET_ULONG()
+#define GET_Tag4() FT_GET_TAG4()
+
+/* Macro definitions to avoid bogus warnings about strict
+ * aliasing. These make code generation worse, so we only
+ * use them when necessary
+ */
+#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)
+#define ALLOC_ARRAY( _pointer_, _count_, _type_ ) ({ \
+ int result; \
+ void *_tmp_; \
+ result = FT_SET_ERROR ( FT_MEM_ALLOC_ARRAY ( _tmp_, \
+ _count_, \
+ _type_ ) ); \
+ _pointer_ = _tmp_; \
+ result; \
+})
+
+/* FT_MEM_REALLOC macro broken in 2.1.0 */
+#define REALLOC_ARRAY( _pointer_, _old_, _new_, _type_ ) ({ \
+ int result; \
+ void *_tmp_ = _pointer_; \
+ result = FT_SET_ERROR ( FT_MEM_REALLOC( _tmp_, \
+ (_old_) * sizeof ( _type_ ), \
+ (_new_) * sizeof ( _type_ ) ) ); \
+ _pointer_ = _tmp_; \
+ result; \
+})
+
+#define FREE( _pointer_ ) ({ \
+ void *_tmp_ = _pointer_; \
+ FT_FREE ( _tmp_ ); \
+ _pointer_ = _tmp_; \
+})
+#define ALLOC( _pointer_, _size_ ) ({ \
+ int result; \
+ void *_tmp_; \
+ result = FT_ALLOC( _tmp_, _size_ ); \
+ _pointer_ = _tmp_; \
+ result; \
+})
+#else
+#define ALLOC_ARRAY( _pointer_, _count_, _type_ ) \
+ FT_SET_ERROR (FT_MEM_ALLOC_ARRAY( _pointer_, _count_, _type_))
+
+/* FT_MEM_REALLOC macro broken in 2.1.0 */
+#define REALLOC_ARRAY( _pointer_, _old_, _new_, _type_ ) \
+ FT_SET_ERROR ( FT_MEM_REALLOC( _pointer_, (_old_) * sizeof ( _type_ ), \
+ (_new_) * sizeof ( _type_ ) ) )
+
+#define FREE( _pointer_ ) FT_FREE( _pointer_ )
+#define ALLOC( _pointer_, _size_ ) FT_ALLOC( _pointer_, _size_ )
+#endif /* gcc >= 3.3 */
+
+#define MEM_Copy( dest, source, count ) FT_MEM_COPY( dest, source, count )
+
+#endif /* freetype >= 2.1.0 */
+
+#endif /* FTERRCOMPAT_H */
diff --git a/src/otlayout/ftxgdef.c b/src/otlayout/ftxgdef.c
new file mode 100644
index 000000000..f6ed36942
--- /dev/null
+++ b/src/otlayout/ftxgdef.c
@@ -0,0 +1,1214 @@
+/*******************************************************************
+ *
+ * ftxgdef.c
+ *
+ * TrueType Open GDEF table support.
+ *
+ * Copyright 1996-2000 by
+ * David Turner, Robert Wilhelm, and Werner Lemberg.
+ *
+ * This file is part of the FreeType project, and may only be used
+ * modified and distributed under the terms of the FreeType project
+ * license, LICENSE.TXT. By continuing to use, modify, or distribute
+ * this file you indicate that you have read the license and
+ * understand and accept it fully.
+ *
+ ******************************************************************/
+
+#include "ftxopen.h"
+#include "ftxopenf.h"
+
+#include "fterrcompat.h"
+
+#include FT_TRUETYPE_TAGS_H
+
+#include FT_INTERNAL_STREAM_H
+#include FT_INTERNAL_MEMORY_H
+#include FT_INTERNAL_TRUETYPE_TYPES_H
+
+#define TTAG_GDEF FT_MAKE_TAG( 'G', 'D', 'E', 'F' )
+
+ static FT_Error Load_AttachList( TTO_AttachList* al,
+ FT_Stream stream );
+ static FT_Error Load_LigCaretList( TTO_LigCaretList* lcl,
+ FT_Stream stream );
+
+ static void Free_AttachList( TTO_AttachList* al,
+ FT_Memory memory );
+ static void Free_LigCaretList( TTO_LigCaretList* lcl,
+ FT_Memory memory );
+
+ static void Free_NewGlyphClasses( TTO_GDEFHeader* gdef,
+ FT_Memory memory );
+
+
+
+ /**********************
+ * Extension Functions
+ **********************/
+
+#if 0
+#define GDEF_ID Build_Extension_ID( 'G', 'D', 'E', 'F' )
+
+
+ static FT_Error GDEF_Create( void* ext,
+ PFace face )
+ {
+ DEFINE_LOAD_LOCALS( face->stream );
+
+ TTO_GDEFHeader* gdef = (TTO_GDEFHeader*)ext;
+ Long table;
+
+
+ /* by convention */
+
+ if ( !gdef )
+ return TT_Err_Ok;
+
+ /* a null offset indicates that there is no GDEF table */
+
+ gdef->offset = 0;
+
+ /* we store the start offset and the size of the subtable */
+
+ table = TT_LookUp_Table( face, TTAG_GDEF );
+ if ( table < 0 )
+ return TT_Err_Ok; /* The table is optional */
+
+ if ( FILE_Seek( face->dirTables[table].Offset ) ||
+ ACCESS_Frame( 4L ) )
+ return error;
+
+ gdef->offset = FILE_Pos() - 4L; /* undo ACCESS_Frame() */
+ gdef->Version = GET_ULong();
+
+ FORGET_Frame();
+
+ gdef->loaded = FALSE;
+
+ return TT_Err_Ok;
+ }
+
+
+ static FT_Error GDEF_Destroy( void* ext,
+ PFace face )
+ {
+ TTO_GDEFHeader* gdef = (TTO_GDEFHeader*)ext;
+
+
+ /* by convention */
+
+ if ( !gdef )
+ return TT_Err_Ok;
+
+ if ( gdef->loaded )
+ {
+ Free_LigCaretList( &gdef->LigCaretList, memory );
+ Free_AttachList( &gdef->AttachList, memory );
+ Free_ClassDefinition( &gdef->GlyphClassDef, memory );
+ Free_ClassDefinition( &gdef->MarkAttachClassDef, memory );
+
+ Free_NewGlyphClasses( gdef, memory );
+ }
+
+ return TT_Err_Ok;
+ }
+
+
+ EXPORT_FUNC
+ FT_Error TT_Init_GDEF_Extension( TT_Engine engine )
+ {
+ PEngine_Instance _engine = HANDLE_Engine( engine );
+
+
+ if ( !_engine )
+ return TT_Err_Invalid_Engine;
+
+ return TT_Register_Extension( _engine,
+ GDEF_ID,
+ sizeof ( TTO_GDEFHeader ),
+ GDEF_Create,
+ GDEF_Destroy );
+ }
+#endif
+
+ EXPORT_FUNC
+ FT_Error TT_New_GDEF_Table( FT_Face face,
+ TTO_GDEFHeader** retptr )
+ {
+ FT_Error error;
+ FT_Memory memory = face->memory;
+
+ TTO_GDEFHeader* gdef;
+
+ if ( !retptr )
+ return TT_Err_Invalid_Argument;
+
+ if ( ALLOC( gdef, sizeof( *gdef ) ) )
+ return error;
+
+ gdef->memory = face->memory;
+
+ gdef->GlyphClassDef.loaded = FALSE;
+ gdef->AttachList.loaded = FALSE;
+ gdef->LigCaretList.loaded = FALSE;
+ gdef->MarkAttachClassDef_offset = 0;
+ gdef->MarkAttachClassDef.loaded = FALSE;
+
+ gdef->LastGlyph = 0;
+ gdef->NewGlyphClasses = NULL;
+
+ *retptr = gdef;
+
+ return TT_Err_Ok;
+ }
+
+ EXPORT_FUNC
+ FT_Error TT_Load_GDEF_Table( FT_Face face,
+ TTO_GDEFHeader** retptr )
+ {
+ FT_Error error;
+ FT_Memory memory = face->memory;
+ FT_Stream stream = face->stream;
+ TT_Face tt_face = (TT_Face)face;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_GDEFHeader* gdef;
+
+
+ if ( !retptr )
+ return TT_Err_Invalid_Argument;
+
+ if (( error = tt_face->goto_table( tt_face, TTAG_GDEF, stream, 0 ) ))
+ return error;
+
+ if (( error = TT_New_GDEF_Table ( face, &gdef ) ))
+ return error;
+
+ base_offset = FILE_Pos();
+
+ /* skip version */
+
+ if ( FILE_Seek( base_offset + 4L ) ||
+ ACCESS_Frame( 2L ) )
+ goto Fail0;
+
+ new_offset = GET_UShort();
+
+ FORGET_Frame();
+
+ /* all GDEF subtables are optional */
+
+ if ( new_offset )
+ {
+ new_offset += base_offset;
+
+ /* only classes 1-4 are allowed here */
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_ClassDefinition( &gdef->GlyphClassDef, 5,
+ stream ) ) != TT_Err_Ok )
+ goto Fail0;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail1;
+
+ new_offset = GET_UShort();
+
+ FORGET_Frame();
+
+ if ( new_offset )
+ {
+ new_offset += base_offset;
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_AttachList( &gdef->AttachList,
+ stream ) ) != TT_Err_Ok )
+ goto Fail1;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail2;
+
+ new_offset = GET_UShort();
+
+ FORGET_Frame();
+
+ if ( new_offset )
+ {
+ new_offset += base_offset;
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_LigCaretList( &gdef->LigCaretList,
+ stream ) ) != TT_Err_Ok )
+ goto Fail2;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ /* OpenType 1.2 has introduced the `MarkAttachClassDef' field. We
+ first have to scan the LookupFlag values to find out whether we
+ must load it or not. Here we only store the offset of the table. */
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail3;
+
+ new_offset = GET_UShort();
+
+ FORGET_Frame();
+
+ if ( new_offset )
+ gdef->MarkAttachClassDef_offset = new_offset + base_offset;
+ else
+ gdef->MarkAttachClassDef_offset = 0;
+
+ *retptr = gdef;
+
+ return TT_Err_Ok;
+
+ Fail3:
+ Free_LigCaretList( &gdef->LigCaretList, memory );
+
+ Fail2:
+ Free_AttachList( &gdef->AttachList, memory );
+
+ Fail1:
+ Free_ClassDefinition( &gdef->GlyphClassDef, memory );
+
+ Fail0:
+ FREE( gdef );
+
+ return error;
+ }
+
+ EXPORT_FUNC
+ FT_Error TT_Done_GDEF_Table ( TTO_GDEFHeader* gdef )
+ {
+ FT_Memory memory = gdef->memory;
+
+ Free_LigCaretList( &gdef->LigCaretList, memory );
+ Free_AttachList( &gdef->AttachList, memory );
+ Free_ClassDefinition( &gdef->GlyphClassDef, memory );
+ Free_ClassDefinition( &gdef->MarkAttachClassDef, memory );
+
+ Free_NewGlyphClasses( gdef, memory );
+
+ FREE( gdef );
+
+ return TT_Err_Ok;
+ }
+
+
+
+
+ /*******************************
+ * AttachList related functions
+ *******************************/
+
+
+ /* AttachPoint */
+
+ static FT_Error Load_AttachPoint( TTO_AttachPoint* ap,
+ FT_Stream stream )
+ {
+ FT_Memory memory = stream->memory;
+ FT_Error error;
+
+ FT_UShort n, count;
+ FT_UShort* pi;
+
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ count = ap->PointCount = GET_UShort();
+
+ FORGET_Frame();
+
+ ap->PointIndex = NULL;
+
+ if ( count )
+ {
+ if ( ALLOC_ARRAY( ap->PointIndex, count, FT_UShort ) )
+ return error;
+
+ pi = ap->PointIndex;
+
+ if ( ACCESS_Frame( count * 2L ) )
+ {
+ FREE( pi );
+ return error;
+ }
+
+ for ( n = 0; n < count; n++ )
+ pi[n] = GET_UShort();
+
+ FORGET_Frame();
+ }
+
+ return TT_Err_Ok;
+ }
+
+
+ static void Free_AttachPoint( TTO_AttachPoint* ap,
+ FT_Memory memory )
+ {
+ FREE( ap->PointIndex );
+ }
+
+
+ /* AttachList */
+
+ static FT_Error Load_AttachList( TTO_AttachList* al,
+ FT_Stream stream )
+ {
+ FT_Memory memory = stream->memory;
+ FT_Error error;
+
+ FT_UShort n, m, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_AttachPoint* ap;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Coverage( &al->Coverage, stream ) ) != TT_Err_Ok )
+ return error;
+ (void)FILE_Seek( cur_offset );
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail2;
+
+ count = al->GlyphCount = GET_UShort();
+
+ FORGET_Frame();
+
+ al->AttachPoint = NULL;
+
+ if ( ALLOC_ARRAY( al->AttachPoint, count, TTO_AttachPoint ) )
+ goto Fail2;
+
+ ap = al->AttachPoint;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail1;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_AttachPoint( &ap[n], stream ) ) != TT_Err_Ok )
+ goto Fail1;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ al->loaded = TRUE;
+
+ return TT_Err_Ok;
+
+ Fail1:
+ for ( m = 0; m < n; m++ )
+ Free_AttachPoint( &ap[m], memory );
+
+ FREE( ap );
+
+ Fail2:
+ Free_Coverage( &al->Coverage, memory );
+ return error;
+ }
+
+
+ static void Free_AttachList( TTO_AttachList* al,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_AttachPoint* ap;
+
+
+ if ( !al->loaded )
+ return;
+
+ if ( al->AttachPoint )
+ {
+ count = al->GlyphCount;
+ ap = al->AttachPoint;
+
+ for ( n = 0; n < count; n++ )
+ Free_AttachPoint( &ap[n], memory );
+
+ FREE( ap );
+ }
+
+ Free_Coverage( &al->Coverage, memory );
+ }
+
+
+
+ /*********************************
+ * LigCaretList related functions
+ *********************************/
+
+
+ /* CaretValueFormat1 */
+ /* CaretValueFormat2 */
+ /* CaretValueFormat3 */
+ /* CaretValueFormat4 */
+
+ static FT_Error Load_CaretValue( TTO_CaretValue* cv,
+ FT_Stream stream )
+ {
+ FT_Error error;
+
+ FT_ULong cur_offset, new_offset, base_offset;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ cv->CaretValueFormat = GET_UShort();
+
+ FORGET_Frame();
+
+ switch ( cv->CaretValueFormat )
+ {
+ case 1:
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ cv->cvf.cvf1.Coordinate = GET_Short();
+
+ FORGET_Frame();
+
+ break;
+
+ case 2:
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ cv->cvf.cvf2.CaretValuePoint = GET_UShort();
+
+ FORGET_Frame();
+
+ break;
+
+ case 3:
+ if ( ACCESS_Frame( 4L ) )
+ return error;
+
+ cv->cvf.cvf3.Coordinate = GET_Short();
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Device( &cv->cvf.cvf3.Device,
+ stream ) ) != TT_Err_Ok )
+ return error;
+ (void)FILE_Seek( cur_offset );
+
+ break;
+
+ case 4:
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ cv->cvf.cvf4.IdCaretValue = GET_UShort();
+
+ FORGET_Frame();
+ break;
+
+ default:
+ return TTO_Err_Invalid_GDEF_SubTable_Format;
+ }
+
+ return TT_Err_Ok;
+ }
+
+
+ static void Free_CaretValue( TTO_CaretValue* cv,
+ FT_Memory memory )
+ {
+ if ( cv->CaretValueFormat == 3 )
+ Free_Device( &cv->cvf.cvf3.Device, memory );
+ }
+
+
+ /* LigGlyph */
+
+ static FT_Error Load_LigGlyph( TTO_LigGlyph* lg,
+ FT_Stream stream )
+ {
+ FT_Memory memory = stream->memory;
+ FT_Error error;
+
+ FT_UShort n, m, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_CaretValue* cv;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ count = lg->CaretCount = GET_UShort();
+
+ FORGET_Frame();
+
+ lg->CaretValue = NULL;
+
+ if ( ALLOC_ARRAY( lg->CaretValue, count, TTO_CaretValue ) )
+ return error;
+
+ cv = lg->CaretValue;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_CaretValue( &cv[n], stream ) ) != TT_Err_Ok )
+ goto Fail;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ return TT_Err_Ok;
+
+ Fail:
+ for ( m = 0; m < n; m++ )
+ Free_CaretValue( &cv[m], memory );
+
+ FREE( cv );
+ return error;
+ }
+
+
+ static void Free_LigGlyph( TTO_LigGlyph* lg,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_CaretValue* cv;
+
+
+ if ( lg->CaretValue )
+ {
+ count = lg->CaretCount;
+ cv = lg->CaretValue;
+
+ for ( n = 0; n < count; n++ )
+ Free_CaretValue( &cv[n], memory );
+
+ FREE( cv );
+ }
+ }
+
+
+ /* LigCaretList */
+
+ static FT_Error Load_LigCaretList( TTO_LigCaretList* lcl,
+ FT_Stream stream )
+ {
+ FT_Memory memory = stream->memory;
+ FT_Error error;
+
+ FT_UShort m, n, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_LigGlyph* lg;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Coverage( &lcl->Coverage, stream ) ) != TT_Err_Ok )
+ return error;
+ (void)FILE_Seek( cur_offset );
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail2;
+
+ count = lcl->LigGlyphCount = GET_UShort();
+
+ FORGET_Frame();
+
+ lcl->LigGlyph = NULL;
+
+ if ( ALLOC_ARRAY( lcl->LigGlyph, count, TTO_LigGlyph ) )
+ goto Fail2;
+
+ lg = lcl->LigGlyph;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail1;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_LigGlyph( &lg[n], stream ) ) != TT_Err_Ok )
+ goto Fail1;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ lcl->loaded = TRUE;
+
+ return TT_Err_Ok;
+
+ Fail1:
+ for ( m = 0; m < n; m++ )
+ Free_LigGlyph( &lg[m], memory );
+
+ FREE( lg );
+
+ Fail2:
+ Free_Coverage( &lcl->Coverage, memory );
+ return error;
+ }
+
+
+ static void Free_LigCaretList( TTO_LigCaretList* lcl,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_LigGlyph* lg;
+
+
+ if ( !lcl->loaded )
+ return;
+
+ if ( lcl->LigGlyph )
+ {
+ count = lcl->LigGlyphCount;
+ lg = lcl->LigGlyph;
+
+ for ( n = 0; n < count; n++ )
+ Free_LigGlyph( &lg[n], memory );
+
+ FREE( lg );
+ }
+
+ Free_Coverage( &lcl->Coverage, memory );
+ }
+
+
+
+ /***********
+ * GDEF API
+ ***********/
+
+
+ static FT_UShort Get_New_Class( TTO_GDEFHeader* gdef,
+ FT_UShort glyphID,
+ FT_UShort index )
+ {
+ FT_UShort glyph_index, array_index;
+ FT_UShort byte, bits;
+
+ TTO_ClassRangeRecord* gcrr;
+ FT_UShort** ngc;
+
+
+ if ( glyphID >= gdef->LastGlyph )
+ return 0;
+
+ gcrr = gdef->GlyphClassDef.cd.cd2.ClassRangeRecord;
+ ngc = gdef->NewGlyphClasses;
+
+ if ( glyphID < gcrr[index].Start )
+ {
+ array_index = 0;
+ if ( index == 0 )
+ glyph_index = glyphID;
+ else
+ glyph_index = glyphID - gcrr[index - 1].End - 1;
+ }
+ else
+ {
+ array_index = index + 1;
+ glyph_index = glyphID - gcrr[index].End - 1;
+ }
+
+ byte = ngc[array_index][glyph_index / 4 + 1];
+ bits = byte >> ( 16 - ( glyph_index % 4 + 1 ) * 4 );
+
+ return bits & 0x000F;
+ }
+
+
+ EXPORT_FUNC
+ FT_Error TT_GDEF_Get_Glyph_Property( TTO_GDEFHeader* gdef,
+ FT_UShort glyphID,
+ FT_UShort* property )
+ {
+ FT_UShort class, index;
+
+ FT_Error error;
+
+
+ if ( !gdef || !property )
+ return TT_Err_Invalid_Argument;
+
+ /* first, we check for mark attach classes */
+
+ if ( gdef->MarkAttachClassDef.loaded )
+ {
+ error = Get_Class( &gdef->MarkAttachClassDef, glyphID, &class, &index );
+ if ( error && error != TTO_Err_Not_Covered )
+ return error;
+ if ( !error )
+ {
+ *property = class << 8;
+ return TT_Err_Ok;
+ }
+ }
+
+ error = Get_Class( &gdef->GlyphClassDef, glyphID, &class, &index );
+ if ( error && error != TTO_Err_Not_Covered )
+ return error;
+
+ /* if we have a constructed class table, check whether additional
+ values have been assigned */
+
+ if ( error == TTO_Err_Not_Covered && gdef->NewGlyphClasses )
+ class = Get_New_Class( gdef, glyphID, index );
+
+ switch ( class )
+ {
+ case UNCLASSIFIED_GLYPH:
+ *property = 0;
+ break;
+
+ case SIMPLE_GLYPH:
+ *property = TTO_BASE_GLYPH;
+ break;
+
+ case LIGATURE_GLYPH:
+ *property = TTO_LIGATURE;
+ break;
+
+ case MARK_GLYPH:
+ *property = TTO_MARK;
+ break;
+
+ case COMPONENT_GLYPH:
+ *property = TTO_COMPONENT;
+ break;
+ }
+
+ return TT_Err_Ok;
+ }
+
+
+ static FT_Error Make_ClassRange( TTO_ClassDefinition* cd,
+ FT_UShort start,
+ FT_UShort end,
+ FT_UShort class,
+ FT_Memory memory )
+ {
+ FT_Error error;
+ FT_UShort index;
+
+ TTO_ClassDefFormat2* cdf2;
+ TTO_ClassRangeRecord* crr;
+
+
+ cdf2 = &cd->cd.cd2;
+
+ if ( REALLOC_ARRAY( cdf2->ClassRangeRecord,
+ cdf2->ClassRangeCount,
+ cdf2->ClassRangeCount + 1 ,
+ TTO_ClassRangeRecord ) )
+ return error;
+
+ cdf2->ClassRangeCount++;
+
+ crr = cdf2->ClassRangeRecord;
+ index = cdf2->ClassRangeCount - 1;
+
+ crr[index].Start = start;
+ crr[index].End = end;
+ crr[index].Class = class;
+
+ cd->Defined[class] = TRUE;
+
+ return TT_Err_Ok;
+ }
+
+
+ EXPORT_FUNC
+ FT_Error TT_GDEF_Build_ClassDefinition( TTO_GDEFHeader* gdef,
+ FT_UShort num_glyphs,
+ FT_UShort glyph_count,
+ FT_UShort* glyph_array,
+ FT_UShort* class_array )
+ {
+ FT_UShort start, curr_glyph, curr_class;
+ FT_UShort n, m, count;
+ FT_Error error;
+ FT_Memory memory = gdef->memory;
+
+ TTO_ClassDefinition* gcd;
+ TTO_ClassRangeRecord* gcrr;
+ FT_UShort** ngc;
+
+
+ if ( !gdef || !glyph_array || !class_array )
+ return TT_Err_Invalid_Argument;
+
+ gcd = &gdef->GlyphClassDef;
+
+ /* We build a format 2 table */
+
+ gcd->ClassFormat = 2;
+
+ /* A GlyphClassDef table contains at most 5 different class values */
+
+ if ( ALLOC_ARRAY( gcd->Defined, 5, FT_Bool ) )
+ return error;
+
+ gcd->cd.cd2.ClassRangeCount = 0;
+ gcd->cd.cd2.ClassRangeRecord = NULL;
+
+ start = glyph_array[0];
+ curr_class = class_array[0];
+ curr_glyph = start;
+
+ if ( curr_class >= 5 )
+ {
+ error = TT_Err_Invalid_Argument;
+ goto Fail4;
+ }
+
+ glyph_count--;
+
+ for ( n = 0; n <= glyph_count; n++ )
+ {
+ if ( curr_glyph == glyph_array[n] && curr_class == class_array[n] )
+ {
+ if ( n == glyph_count )
+ {
+ if ( ( error = Make_ClassRange( gcd, start,
+ curr_glyph,
+ curr_class,
+ memory ) ) != TT_Err_Ok )
+ goto Fail3;
+ }
+ else
+ {
+ if ( curr_glyph == 0xFFFF )
+ {
+ error = TT_Err_Invalid_Argument;
+ goto Fail3;
+ }
+ else
+ curr_glyph++;
+ }
+ }
+ else
+ {
+ if ( ( error = Make_ClassRange( gcd, start,
+ curr_glyph - 1,
+ curr_class,
+ memory ) ) != TT_Err_Ok )
+ goto Fail3;
+
+ if ( curr_glyph > glyph_array[n] )
+ {
+ error = TT_Err_Invalid_Argument;
+ goto Fail3;
+ }
+
+ start = glyph_array[n];
+ curr_class = class_array[n];
+ curr_glyph = start;
+
+ if ( curr_class >= 5 )
+ {
+ error = TT_Err_Invalid_Argument;
+ goto Fail3;
+ }
+
+ if ( n == glyph_count )
+ {
+ if ( ( error = Make_ClassRange( gcd, start,
+ curr_glyph,
+ curr_class,
+ memory ) ) != TT_Err_Ok )
+ goto Fail3;
+ }
+ else
+ {
+ if ( curr_glyph == 0xFFFF )
+ {
+ error = TT_Err_Invalid_Argument;
+ goto Fail3;
+ }
+ else
+ curr_glyph++;
+ }
+ }
+ }
+
+ /* now prepare the arrays for class values assigned during the lookup
+ process */
+
+ if ( ALLOC_ARRAY( gdef->NewGlyphClasses,
+ gcd->cd.cd2.ClassRangeCount + 1, FT_UShort* ) )
+ goto Fail2;
+
+ count = gcd->cd.cd2.ClassRangeCount;
+ gcrr = gcd->cd.cd2.ClassRangeRecord;
+ ngc = gdef->NewGlyphClasses;
+
+ /* We allocate arrays for all glyphs not covered by the class range
+ records. Each element holds four class values. */
+
+ if ( gcrr[0].Start )
+ {
+ if ( ALLOC_ARRAY( ngc[0], gcrr[0].Start / 4 + 1, FT_UShort ) )
+ goto Fail1;
+ }
+
+ for ( n = 1; n < count; n++ )
+ {
+ if ( gcrr[n].Start - gcrr[n - 1].End > 1 )
+ if ( ALLOC_ARRAY( ngc[n],
+ ( gcrr[n].Start - gcrr[n - 1].End - 1 ) / 4 + 1,
+ FT_UShort ) )
+ goto Fail1;
+ }
+
+ if ( gcrr[count - 1].End != num_glyphs - 1 )
+ {
+ if ( ALLOC_ARRAY( ngc[count],
+ ( num_glyphs - gcrr[count - 1].End - 1 ) / 4
+ + (((( num_glyphs - gcrr[count - 1].End - 1 ) % 4) == 0)? 0: 1)
+ + 1,
+ FT_UShort ) )
+ goto Fail1;
+ }
+
+ gdef->LastGlyph = num_glyphs - 1;
+
+ gdef->MarkAttachClassDef_offset = 0L;
+ gdef->MarkAttachClassDef.loaded = FALSE;
+
+ gcd->loaded = TRUE; /* ??? */
+ return TT_Err_Ok;
+
+ Fail1:
+ for ( m = 0; m < n; m++ )
+ FREE( ngc[m] );
+
+ Fail2:
+ FREE( gdef->NewGlyphClasses );
+
+ Fail3:
+ FREE( gcd->cd.cd2.ClassRangeRecord );
+
+ Fail4:
+ FREE( gcd->Defined );
+ return error;
+ }
+
+
+ static void Free_NewGlyphClasses( TTO_GDEFHeader* gdef,
+ FT_Memory memory )
+ {
+ FT_UShort** ngc;
+ FT_UShort n, count;
+
+
+ if ( gdef->NewGlyphClasses )
+ {
+ count = gdef->GlyphClassDef.cd.cd2.ClassRangeCount + 1;
+ ngc = gdef->NewGlyphClasses;
+
+ for ( n = 0; n < count; n++ )
+ FREE( ngc[n] );
+
+ FREE( ngc );
+ }
+ }
+
+
+ FT_Error Add_Glyph_Property( TTO_GDEFHeader* gdef,
+ FT_UShort glyphID,
+ FT_UShort property )
+ {
+ FT_Error error;
+ FT_UShort class, new_class, index;
+ FT_UShort byte, bits, mask;
+ FT_UShort array_index, glyph_index;
+
+ TTO_ClassRangeRecord* gcrr;
+ FT_UShort** ngc;
+
+
+ error = Get_Class( &gdef->GlyphClassDef, glyphID, &class, &index );
+ if ( error && error != TTO_Err_Not_Covered )
+ return error;
+
+ /* we don't accept glyphs covered in `GlyphClassDef' */
+
+ if ( !error )
+ return TTO_Err_Not_Covered;
+
+ switch ( property )
+ {
+ case 0:
+ new_class = UNCLASSIFIED_GLYPH;
+ break;
+
+ case TTO_BASE_GLYPH:
+ new_class = SIMPLE_GLYPH;
+ break;
+
+ case TTO_LIGATURE:
+ new_class = LIGATURE_GLYPH;
+ break;
+
+ case TTO_MARK:
+ new_class = MARK_GLYPH;
+ break;
+
+ case TTO_COMPONENT:
+ new_class = COMPONENT_GLYPH;
+ break;
+
+ default:
+ return TT_Err_Invalid_Argument;
+ }
+
+ gcrr = gdef->GlyphClassDef.cd.cd2.ClassRangeRecord;
+ ngc = gdef->NewGlyphClasses;
+
+ if ( glyphID < gcrr[index].Start )
+ {
+ array_index = 0;
+ if ( index == 0 )
+ glyph_index = glyphID;
+ else
+ glyph_index = glyphID - gcrr[index - 1].End - 1;
+ }
+ else
+ {
+ array_index = index + 1;
+ glyph_index = glyphID - gcrr[index].End - 1;
+ }
+
+ byte = ngc[array_index][glyph_index / 4 + 1];
+ bits = byte >> ( 16 - ( glyph_index % 4 + 1 ) * 4 );
+ class = bits & 0x000F;
+
+ /* we don't overwrite existing entries */
+
+ if ( !class )
+ {
+ bits = new_class << ( 16 - ( glyph_index % 4 + 1 ) * 4 );
+ mask = ~( 0x000F << ( 16 - ( glyph_index % 4 + 1 ) * 4 ) );
+
+ ngc[array_index][glyph_index / 4 + 1] &= mask;
+ ngc[array_index][glyph_index / 4 + 1] |= bits;
+ }
+
+ return TT_Err_Ok;
+ }
+
+
+ FT_Error Check_Property( TTO_GDEFHeader* gdef,
+ FT_UShort index,
+ FT_UShort flags,
+ FT_UShort* property )
+ {
+ FT_Error error;
+
+
+ if ( gdef )
+ {
+ FT_UShort basic_glyph_class;
+ FT_UShort desired_attachment_class;
+
+ error = TT_GDEF_Get_Glyph_Property( gdef, index, property );
+ if ( error )
+ return error;
+
+ /* If the glyph was found in the MarkAttachmentClass table,
+ * then that class value is the high byte of the result,
+ * otherwise the low byte contains the basic type of the glyph
+ * as defined by the GlyphClassDef table.
+ */
+ if ( *property & IGNORE_SPECIAL_MARKS )
+ basic_glyph_class = TTO_MARK;
+ else
+ basic_glyph_class = *property;
+
+ /* Return Not_Covered, if, for example, basic_glyph_class
+ * is TTO_LIGATURE and LookFlags includes IGNORE_LIGATURES
+ */
+ if ( flags & basic_glyph_class )
+ return TTO_Err_Not_Covered;
+
+ /* The high byte of LookupFlags has the meaning
+ * "ignore marks of attachment type different than
+ * the attachment type specified."
+ */
+ desired_attachment_class = flags & IGNORE_SPECIAL_MARKS;
+ if ( desired_attachment_class )
+ {
+ if ( basic_glyph_class == TTO_MARK &&
+ *property != desired_attachment_class )
+ return TTO_Err_Not_Covered;
+ }
+ }
+
+ return TT_Err_Ok;
+ }
+
+
+/* END */
diff --git a/src/otlayout/ftxgdef.h b/src/otlayout/ftxgdef.h
new file mode 100644
index 000000000..f22438ebb
--- /dev/null
+++ b/src/otlayout/ftxgdef.h
@@ -0,0 +1,224 @@
+/*******************************************************************
+ *
+ * ftxgdef.h
+ *
+ * TrueType Open GDEF table support
+ *
+ * Copyright 1996-2000 by
+ * David Turner, Robert Wilhelm, and Werner Lemberg.
+ *
+ * This file is part of the FreeType project, and may only be used
+ * modified and distributed under the terms of the FreeType project
+ * license, LICENSE.TXT. By continuing to use, modify, or distribute
+ * this file you indicate that you have read the license and
+ * understand and accept it fully.
+ *
+ ******************************************************************/
+
+#ifndef FTXOPEN_H
+#error "Don't include this file! Use ftxopen.h instead."
+#endif
+
+#ifndef FTXGDEF_H
+#define FTXGDEF_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define TTO_Err_Invalid_GDEF_SubTable_Format 0x1030
+#define TTO_Err_Invalid_GDEF_SubTable 0x1031
+
+
+/* GDEF glyph classes */
+
+#define UNCLASSIFIED_GLYPH 0
+#define SIMPLE_GLYPH 1
+#define LIGATURE_GLYPH 2
+#define MARK_GLYPH 3
+#define COMPONENT_GLYPH 4
+
+/* GDEF glyph properties, corresponding to class values 1-4. Note that
+ TTO_COMPONENT has no corresponding flag in the LookupFlag field. */
+
+#define TTO_BASE_GLYPH 0x0002
+#define TTO_LIGATURE 0x0004
+#define TTO_MARK 0x0008
+#define TTO_COMPONENT 0x0010
+
+
+ /* Attachment related structures */
+
+ struct TTO_AttachPoint_
+ {
+ FT_UShort PointCount; /* size of the PointIndex array */
+ FT_UShort* PointIndex; /* array of contour points */
+ };
+
+ typedef struct TTO_AttachPoint_ TTO_AttachPoint;
+
+
+ struct TTO_AttachList_
+ {
+ FT_Bool loaded;
+
+ TTO_Coverage Coverage; /* Coverage table */
+ FT_UShort GlyphCount; /* number of glyphs with
+ attachments */
+ TTO_AttachPoint* AttachPoint; /* array of AttachPoint tables */
+ };
+
+ typedef struct TTO_AttachList_ TTO_AttachList;
+
+
+ /* Ligature Caret related structures */
+
+ struct TTO_CaretValueFormat1_
+ {
+ FT_Short Coordinate; /* x or y value (in design units) */
+ };
+
+ typedef struct TTO_CaretValueFormat1_ TTO_CaretValueFormat1;
+
+
+ struct TTO_CaretValueFormat2_
+ {
+ FT_UShort CaretValuePoint; /* contour point index on glyph */
+ };
+
+ typedef struct TTO_CaretValueFormat2_ TTO_CaretValueFormat2;
+
+
+ struct TTO_CaretValueFormat3_
+ {
+ FT_Short Coordinate; /* x or y value (in design units) */
+ TTO_Device Device; /* Device table for x or y value */
+ };
+
+ typedef struct TTO_CaretValueFormat3_ TTO_CaretValueFormat3;
+
+
+ struct TTO_CaretValueFormat4_
+ {
+ FT_UShort IdCaretValue; /* metric ID */
+ };
+
+ typedef struct TTO_CaretValueFormat4_ TTO_CaretValueFormat4;
+
+
+ struct TTO_CaretValue_
+ {
+ FT_UShort CaretValueFormat; /* 1, 2, 3, or 4 */
+
+ union
+ {
+ TTO_CaretValueFormat1 cvf1;
+ TTO_CaretValueFormat2 cvf2;
+ TTO_CaretValueFormat3 cvf3;
+ TTO_CaretValueFormat4 cvf4;
+ } cvf;
+ };
+
+ typedef struct TTO_CaretValue_ TTO_CaretValue;
+
+
+ struct TTO_LigGlyph_
+ {
+ FT_Bool loaded;
+
+ FT_UShort CaretCount; /* number of caret values */
+ TTO_CaretValue* CaretValue; /* array of caret values */
+ };
+
+ typedef struct TTO_LigGlyph_ TTO_LigGlyph;
+
+
+ struct TTO_LigCaretList_
+ {
+ FT_Bool loaded;
+
+ TTO_Coverage Coverage; /* Coverage table */
+ FT_UShort LigGlyphCount; /* number of ligature glyphs */
+ TTO_LigGlyph* LigGlyph; /* array of LigGlyph tables */
+ };
+
+ typedef struct TTO_LigCaretList_ TTO_LigCaretList;
+
+
+ /* The `NewGlyphClasses' field is not defined in the TTO specification.
+ We use it for fonts with a constructed `GlyphClassDef' structure
+ (i.e., which don't have a GDEF table) to collect glyph classes
+ assigned during the lookup process. The number of arrays in this
+ pointer array is GlyphClassDef->cd.cd2.ClassRangeCount+1; the nth
+ array then contains the glyph class values of the glyphs not covered
+ by the ClassRangeRecords structures with index n-1 and n. We store
+ glyph class values for four glyphs in a single array element.
+
+ `LastGlyph' is identical to the number of glyphs minus one in the
+ font; we need it only if `NewGlyphClasses' is not NULL (to have an
+ upper bound for the last array).
+
+ Note that we first store the file offset to the `MarkAttachClassDef'
+ field (which has been introduced in OpenType 1.2) -- since the
+ `Version' field value hasn't been increased to indicate that we have
+ one more field for some obscure reason, we must parse the GSUB table
+ to find out whether class values refer to this table. Only then we
+ can finally load the MarkAttachClassDef structure if necessary. */
+
+ struct TTO_GDEFHeader_
+ {
+ FT_Memory memory;
+ FT_ULong offset;
+
+ FT_Fixed Version;
+
+ TTO_ClassDefinition GlyphClassDef;
+ TTO_AttachList AttachList;
+ TTO_LigCaretList LigCaretList;
+ FT_ULong MarkAttachClassDef_offset;
+ TTO_ClassDefinition MarkAttachClassDef; /* new in OT 1.2 */
+
+ FT_UShort LastGlyph;
+ FT_UShort** NewGlyphClasses;
+ };
+
+ typedef struct TTO_GDEFHeader_ TTO_GDEFHeader;
+ typedef struct TTO_GDEFHeader_* TTO_GDEF;
+
+
+ /* finally, the GDEF API */
+
+ /* EXPORT_DEF
+ FT_Error TT_Init_GDEF_Extension( TT_Engine engine ); */
+
+ EXPORT_FUNC
+ FT_Error TT_New_GDEF_Table( FT_Face face,
+ TTO_GDEFHeader** retptr );
+
+ EXPORT_DEF
+ FT_Error TT_Load_GDEF_Table( FT_Face face,
+ TTO_GDEFHeader** gdef );
+
+ EXPORT_DEF
+ FT_Error TT_Done_GDEF_Table ( TTO_GDEFHeader* gdef );
+
+ EXPORT_DEF
+ FT_Error TT_GDEF_Get_Glyph_Property( TTO_GDEFHeader* gdef,
+ FT_UShort glyphID,
+ FT_UShort* property );
+ EXPORT_DEF
+ FT_Error TT_GDEF_Build_ClassDefinition( TTO_GDEFHeader* gdef,
+ FT_UShort num_glyphs,
+ FT_UShort glyph_count,
+ FT_UShort* glyph_array,
+ FT_UShort* class_array );
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* FTXGDEF_H */
+
+
+/* END */
diff --git a/src/otlayout/ftxgpos.c b/src/otlayout/ftxgpos.c
new file mode 100644
index 000000000..eafb5f64d
--- /dev/null
+++ b/src/otlayout/ftxgpos.c
@@ -0,0 +1,6327 @@
+/*******************************************************************
+ *
+ * ftxgpos.c
+ *
+ * TrueType Open GPOS table support.
+ *
+ * Copyright 1996-2000 by
+ * David Turner, Robert Wilhelm, and Werner Lemberg.
+ *
+ * This file is part of the FreeType project, and may only be used
+ * modified and distributed under the terms of the FreeType project
+ * license, LICENSE.TXT. By continuing to use, modify, or distribute
+ * this file you indicate that you have read the license and
+ * understand and accept it fully.
+ *
+ ******************************************************************/
+
+/* XXX There is *a lot* of duplicated code (cf. formats 7 and 8), but
+ I don't care currently. I believe that it would be possible to
+ save about 50% of TTO code by carefully designing the structures,
+ sharing as much as possible with extensive use of macros. This
+ is something for a volunteer :-) */
+
+#include "ftxopen.h"
+#include "ftxopenf.h"
+
+#include "fterrcompat.h"
+
+#include FT_TRUETYPE_TAGS_H
+
+#include FT_INTERNAL_STREAM_H
+#include FT_INTERNAL_MEMORY_H
+#include FT_INTERNAL_TRUETYPE_TYPES_H
+
+#define TTAG_GPOS FT_MAKE_TAG( 'G', 'P', 'O', 'S' )
+
+ struct GPOS_Instance_
+ {
+ TTO_GPOSHeader* gpos;
+ FT_Face face;
+ FT_Bool dvi;
+ FT_UShort load_flags; /* how the glyph should be loaded */
+ FT_Bool r2l;
+
+ FT_UShort first; /* the first glyph in a chain of
+ cursive connections */
+ FT_UShort last; /* the last valid glyph -- used
+ with cursive positioning */
+ FT_Pos anchor_x; /* the coordinates of the anchor point */
+ FT_Pos anchor_y; /* of the last valid glyph */
+ };
+
+ typedef struct GPOS_Instance_ GPOS_Instance;
+
+
+ static FT_Error gpos_Do_Glyph_Lookup( GPOS_Instance* gpi,
+ FT_UShort lookup_index,
+ TTO_GSUB_String* in,
+ TTO_GPOS_Data* out,
+ FT_UShort context_length,
+ int nesting_level );
+
+
+ /* the client application must replace this with something more
+ meaningful if multiple master fonts are to be supported. */
+
+ static FT_Error default_mmfunc( FT_Face face,
+ FT_UShort metric_id,
+ FT_Pos* metric_value,
+ void* data )
+ {
+ return TTO_Err_No_MM_Interpreter;
+ }
+
+
+#if 0
+#define GPOS_ID Build_Extension_ID( 'G', 'P', 'O', 'S' )
+
+ /**********************
+ * Extension Functions
+ **********************/
+
+ static FT_Error GPOS_Create( void* ext,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ TTO_GPOSHeader* gpos = (TTO_GPOSHeader*)ext;
+ FT_Long table;
+
+
+ /* by convention */
+
+ if ( !gpos )
+ return TT_Err_Ok;
+
+ /* a null offset indicates that there is no GPOS table */
+
+ gpos->offset = 0;
+
+ /* we store the start offset and the size of the subtable */
+
+ table = face->lookup_table ( face, TTAG_GPOS );
+ if ( table < 0 )
+ return TT_Err_Ok; /* The table is optional */
+
+ if ( FILE_Seek( face->dirTables[table].Offset ) ||
+ ACCESS_Frame( 4L ) )
+ return error;
+
+ gpos->offset = FILE_Pos() - 4L; /* undo ACCESS_Frame() */
+ gpos->Version = GET_ULong();
+
+ FORGET_Frame();
+
+ /* a default mmfunc() handler which just returns an error */
+
+ gpos->mmfunc = default_mmfunc;
+
+ /* the default glyph function is TT_Load_Glyph() */
+
+ gpos->gfunc = FT_Load_Glyph;
+
+ gpos->loaded = FALSE;
+
+ return TT_Err_Ok;
+ }
+
+
+ static FT_Error GPOS_Destroy( void* ext,
+ PFace face )
+ {
+ TTO_GPOSHeader* gpos = (TTO_GPOSHeader*)ext;
+
+
+ /* by convention */
+
+ if ( !gpos )
+ return TT_Err_Ok;
+
+ if ( gpos->loaded )
+ {
+ Free_LookupList( &gpos->LookupList, GPOS );
+ Free_FeatureList( &gpos->FeatureList );
+ Free_ScriptList( &gpos->ScriptList );
+ }
+
+ return TT_Err_Ok;
+ }
+
+
+ EXPORT_FUNC
+ FT_Error TT_Init_GPOS_Extension( TT_Engine engine )
+ {
+ PEngine_Instance _engine = HANDLE_Engine( engine );
+
+
+ if ( !_engine )
+ return TT_Err_Invalid_Engine;
+
+ return TT_Register_Extension( _engine,
+ GPOS_ID,
+ sizeof ( TTO_GPOSHeader ),
+ GPOS_Create,
+ GPOS_Destroy );
+ }
+#endif
+
+ EXPORT_FUNC
+ FT_Error TT_Load_GPOS_Table( FT_Face face,
+ TTO_GPOSHeader** retptr,
+ TTO_GDEFHeader* gdef )
+ {
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ FT_UShort i, num_lookups;
+ TTO_GPOSHeader* gpos;
+ TTO_Lookup* lo;
+ TT_Face tt_face = (TT_Face)face;
+
+ FT_Stream stream = face->stream;
+ FT_Error error;
+ FT_Memory memory = face->memory;
+
+
+ if ( !retptr )
+ return TT_Err_Invalid_Argument;
+
+ if ( !stream )
+ return TT_Err_Invalid_Face_Handle;
+
+ if (( error = tt_face->goto_table( tt_face, TTAG_GPOS, stream, 0 ) ))
+ return error;
+
+ base_offset = FILE_Pos();
+
+ if ( ALLOC ( gpos, sizeof( *gpos ) ) )
+ return error;
+
+ gpos->memory = memory;
+ gpos->gfunc = FT_Load_Glyph;
+ gpos->mmfunc = default_mmfunc;
+
+ /* skip version */
+
+ if ( FILE_Seek( base_offset + 4L ) ||
+ ACCESS_Frame( 2L ) )
+ goto Fail4;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_ScriptList( &gpos->ScriptList,
+ stream ) ) != TT_Err_Ok )
+ goto Fail4;
+ (void)FILE_Seek( cur_offset );
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail3;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_FeatureList( &gpos->FeatureList,
+ stream ) ) != TT_Err_Ok )
+ goto Fail3;
+ (void)FILE_Seek( cur_offset );
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail2;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_LookupList( &gpos->LookupList,
+ stream, GPOS ) ) != TT_Err_Ok )
+ goto Fail2;
+
+ gpos->gdef = gdef; /* can be NULL */
+
+ /* We now check the LookupFlags for values larger than 0xFF to find
+ out whether we need to load the `MarkAttachClassDef' field of the
+ GDEF table -- this hack is necessary for OpenType 1.2 tables since
+ the version field of the GDEF table hasn't been incremented.
+
+ For constructed GDEF tables, we only load it if
+ `MarkAttachClassDef_offset' is not zero (nevertheless, a build of
+ a constructed mark attach table is not supported currently). */
+
+ if ( gdef &&
+ gdef->MarkAttachClassDef_offset && !gdef->MarkAttachClassDef.loaded )
+ {
+ lo = gpos->LookupList.Lookup;
+ num_lookups = gpos->LookupList.LookupCount;
+
+ for ( i = 0; i < num_lookups; i++ )
+ {
+ if ( lo[i].LookupFlag & IGNORE_SPECIAL_MARKS )
+ {
+ if ( FILE_Seek( gdef->MarkAttachClassDef_offset ) ||
+ ( error = Load_ClassDefinition( &gdef->MarkAttachClassDef,
+ 256, stream ) ) != TT_Err_Ok )
+ goto Fail1;
+
+ break;
+ }
+ }
+ }
+
+ *retptr = gpos;
+
+ return TT_Err_Ok;
+
+ Fail1:
+ Free_LookupList( &gpos->LookupList, GPOS, memory );
+
+ Fail2:
+ Free_FeatureList( &gpos->FeatureList, memory );
+
+ Fail3:
+ Free_ScriptList( &gpos->ScriptList, memory );
+
+ Fail4:
+ FREE( gpos );
+
+ return error;
+ }
+
+ EXPORT_FUNC
+ FT_Error TT_Done_GPOS_Table( TTO_GPOSHeader* gpos )
+ {
+ FT_Memory memory = gpos->memory;
+
+ Free_LookupList( &gpos->LookupList, GPOS, memory );
+ Free_FeatureList( &gpos->FeatureList, memory );
+ Free_ScriptList( &gpos->ScriptList, memory );
+
+ return FT_Err_Ok;
+ }
+
+
+ /*****************************
+ * SubTable related functions
+ *****************************/
+
+ /* shared tables */
+
+ /* ValueRecord */
+
+ /* There is a subtle difference in the specs between a `table' and a
+ `record' -- offsets for device tables in ValueRecords are taken from
+ the parent table and not the parent record. */
+
+ static FT_Error Load_ValueRecord( TTO_ValueRecord* vr,
+ FT_UShort format,
+ FT_ULong base_offset,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_ULong cur_offset, new_offset;
+
+
+ if ( format & HAVE_X_PLACEMENT )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ vr->XPlacement = GET_Short();
+
+ FORGET_Frame();
+ }
+ else
+ vr->XPlacement = 0;
+
+ if ( format & HAVE_Y_PLACEMENT )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ vr->YPlacement = GET_Short();
+
+ FORGET_Frame();
+ }
+ else
+ vr->YPlacement = 0;
+
+ if ( format & HAVE_X_ADVANCE )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ vr->XAdvance = GET_Short();
+
+ FORGET_Frame();
+ }
+ else
+ vr->XAdvance = 0;
+
+ if ( format & HAVE_Y_ADVANCE )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ vr->YAdvance = GET_Short();
+
+ FORGET_Frame();
+ }
+ else
+ vr->YAdvance = 0;
+
+ if ( format & HAVE_X_PLACEMENT_DEVICE )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ new_offset = GET_UShort();
+
+ FORGET_Frame();
+
+ if ( new_offset )
+ {
+ new_offset += base_offset;
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Device( &vr->XPlacementDevice,
+ stream ) ) != TT_Err_Ok )
+ return error;
+ (void)FILE_Seek( cur_offset );
+ }
+ else
+ goto empty1;
+ }
+ else
+ {
+ empty1:
+ vr->XPlacementDevice.StartSize = 0;
+ vr->XPlacementDevice.EndSize = 0;
+ vr->XPlacementDevice.DeltaValue = NULL;
+ }
+
+ if ( format & HAVE_Y_PLACEMENT_DEVICE )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail3;
+
+ new_offset = GET_UShort();
+
+ FORGET_Frame();
+
+ if ( new_offset )
+ {
+ new_offset += base_offset;
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Device( &vr->YPlacementDevice,
+ stream ) ) != TT_Err_Ok )
+ goto Fail3;
+ (void)FILE_Seek( cur_offset );
+ }
+ else
+ goto empty2;
+ }
+ else
+ {
+ empty2:
+ vr->YPlacementDevice.StartSize = 0;
+ vr->YPlacementDevice.EndSize = 0;
+ vr->YPlacementDevice.DeltaValue = NULL;
+ }
+
+ if ( format & HAVE_X_ADVANCE_DEVICE )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail2;
+
+ new_offset = GET_UShort();
+
+ FORGET_Frame();
+
+ if ( new_offset )
+ {
+ new_offset += base_offset;
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Device( &vr->XAdvanceDevice,
+ stream ) ) != TT_Err_Ok )
+ goto Fail2;
+ (void)FILE_Seek( cur_offset );
+ }
+ else
+ goto empty3;
+ }
+ else
+ {
+ empty3:
+ vr->XAdvanceDevice.StartSize = 0;
+ vr->XAdvanceDevice.EndSize = 0;
+ vr->XAdvanceDevice.DeltaValue = NULL;
+ }
+
+ if ( format & HAVE_Y_ADVANCE_DEVICE )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail1;
+
+ new_offset = GET_UShort();
+
+ FORGET_Frame();
+
+ if ( new_offset )
+ {
+ new_offset += base_offset;
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Device( &vr->YAdvanceDevice,
+ stream ) ) != TT_Err_Ok )
+ goto Fail1;
+ (void)FILE_Seek( cur_offset );
+ }
+ else
+ goto empty4;
+ }
+ else
+ {
+ empty4:
+ vr->YAdvanceDevice.StartSize = 0;
+ vr->YAdvanceDevice.EndSize = 0;
+ vr->YAdvanceDevice.DeltaValue = NULL;
+ }
+
+ if ( format & HAVE_X_ID_PLACEMENT )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail1;
+
+ vr->XIdPlacement = GET_UShort();
+
+ FORGET_Frame();
+ }
+ else
+ vr->XIdPlacement = 0;
+
+ if ( format & HAVE_Y_ID_PLACEMENT )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail1;
+
+ vr->YIdPlacement = GET_UShort();
+
+ FORGET_Frame();
+ }
+ else
+ vr->YIdPlacement = 0;
+
+ if ( format & HAVE_X_ID_ADVANCE )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail1;
+
+ vr->XIdAdvance = GET_UShort();
+
+ FORGET_Frame();
+ }
+ else
+ vr->XIdAdvance = 0;
+
+ if ( format & HAVE_Y_ID_ADVANCE )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail1;
+
+ vr->YIdAdvance = GET_UShort();
+
+ FORGET_Frame();
+ }
+ else
+ vr->YIdAdvance = 0;
+
+ return TT_Err_Ok;
+
+ Fail1:
+ Free_Device( &vr->YAdvanceDevice, memory );
+
+ Fail2:
+ Free_Device( &vr->XAdvanceDevice, memory );
+
+ Fail3:
+ Free_Device( &vr->YPlacementDevice, memory );
+ return error;
+ }
+
+
+ static void Free_ValueRecord( TTO_ValueRecord* vr,
+ FT_UShort format,
+ FT_Memory memory )
+ {
+ if ( format & HAVE_Y_ADVANCE_DEVICE )
+ Free_Device( &vr->YAdvanceDevice, memory );
+ if ( format & HAVE_X_ADVANCE_DEVICE )
+ Free_Device( &vr->XAdvanceDevice, memory );
+ if ( format & HAVE_Y_PLACEMENT_DEVICE )
+ Free_Device( &vr->YPlacementDevice, memory );
+ if ( format & HAVE_X_PLACEMENT_DEVICE )
+ Free_Device( &vr->XPlacementDevice, memory );
+ }
+
+
+ static FT_Error Get_ValueRecord( GPOS_Instance* gpi,
+ TTO_ValueRecord* vr,
+ FT_UShort format,
+ TTO_GPOS_Data* gd )
+ {
+ FT_Pos value;
+ FT_Short pixel_value;
+ FT_Error error = TT_Err_Ok;
+ TTO_GPOSHeader* gpos = gpi->gpos;
+
+ FT_UShort x_ppem, y_ppem;
+ FT_Fixed x_scale, y_scale;
+
+
+ if ( !format )
+ return TT_Err_Ok;
+
+ x_ppem = gpi->face->size->metrics.x_ppem;
+ y_ppem = gpi->face->size->metrics.y_ppem;
+ x_scale = gpi->face->size->metrics.x_scale;
+ y_scale = gpi->face->size->metrics.y_scale;
+
+ /* design units -> fractional pixel */
+
+ if ( format & HAVE_X_PLACEMENT )
+ gd->x_pos += x_scale * vr->XPlacement / 0x10000;
+ if ( format & HAVE_Y_PLACEMENT )
+ gd->y_pos += y_scale * vr->YPlacement / 0x10000;
+ if ( format & HAVE_X_ADVANCE )
+ gd->x_advance += x_scale * vr->XAdvance / 0x10000;
+ if ( format & HAVE_Y_ADVANCE )
+ gd->y_advance += y_scale * vr->YAdvance / 0x10000;
+
+ if ( !gpi->dvi )
+ {
+ /* pixel -> fractional pixel */
+
+ if ( format & HAVE_X_PLACEMENT_DEVICE )
+ {
+ Get_Device( &vr->XPlacementDevice, x_ppem, &pixel_value );
+ gd->x_pos += pixel_value << 6;
+ }
+ if ( format & HAVE_Y_PLACEMENT_DEVICE )
+ {
+ Get_Device( &vr->YPlacementDevice, y_ppem, &pixel_value );
+ gd->y_pos += pixel_value << 6;
+ }
+ if ( format & HAVE_X_ADVANCE_DEVICE )
+ {
+ Get_Device( &vr->XAdvanceDevice, x_ppem, &pixel_value );
+ gd->x_advance += pixel_value << 6;
+ }
+ if ( format & HAVE_Y_ADVANCE_DEVICE )
+ {
+ Get_Device( &vr->YAdvanceDevice, y_ppem, &pixel_value );
+ gd->y_advance += pixel_value << 6;
+ }
+ }
+
+ /* values returned from mmfunc() are already in fractional pixels */
+
+ if ( format & HAVE_X_ID_PLACEMENT )
+ {
+ error = (gpos->mmfunc)( gpi->face, vr->XIdPlacement,
+ &value, gpos->data );
+ if ( error )
+ return error;
+ gd->x_pos += value;
+ }
+ if ( format & HAVE_Y_ID_PLACEMENT )
+ {
+ error = (gpos->mmfunc)( gpi->face, vr->YIdPlacement,
+ &value, gpos->data );
+ if ( error )
+ return error;
+ gd->y_pos += value;
+ }
+ if ( format & HAVE_X_ID_ADVANCE )
+ {
+ error = (gpos->mmfunc)( gpi->face, vr->XIdAdvance,
+ &value, gpos->data );
+ if ( error )
+ return error;
+ gd->x_advance += value;
+ }
+ if ( format & HAVE_Y_ID_ADVANCE )
+ {
+ error = (gpos->mmfunc)( gpi->face, vr->YIdAdvance,
+ &value, gpos->data );
+ if ( error )
+ return error;
+ gd->y_advance += value;
+ }
+
+ return error;
+ }
+
+
+ /* AnchorFormat1 */
+ /* AnchorFormat2 */
+ /* AnchorFormat3 */
+ /* AnchorFormat4 */
+
+ static FT_Error Load_Anchor( TTO_Anchor* an,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_ULong cur_offset, new_offset, base_offset;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ an->PosFormat = GET_UShort();
+
+ FORGET_Frame();
+
+ switch ( an->PosFormat )
+ {
+ case 1:
+ if ( ACCESS_Frame( 4L ) )
+ return error;
+
+ an->af.af1.XCoordinate = GET_Short();
+ an->af.af1.YCoordinate = GET_Short();
+
+ FORGET_Frame();
+ break;
+
+ case 2:
+ if ( ACCESS_Frame( 6L ) )
+ return error;
+
+ an->af.af2.XCoordinate = GET_Short();
+ an->af.af2.YCoordinate = GET_Short();
+ an->af.af2.AnchorPoint = GET_UShort();
+
+ FORGET_Frame();
+ break;
+
+ case 3:
+ if ( ACCESS_Frame( 6L ) )
+ return error;
+
+ an->af.af3.XCoordinate = GET_Short();
+ an->af.af3.YCoordinate = GET_Short();
+
+ new_offset = GET_UShort();
+
+ FORGET_Frame();
+
+ if ( new_offset )
+ {
+ new_offset += base_offset;
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Device( &an->af.af3.XDeviceTable,
+ stream ) ) != TT_Err_Ok )
+ return error;
+ (void)FILE_Seek( cur_offset );
+ }
+ else
+ {
+ an->af.af3.XDeviceTable.StartSize = 0;
+ an->af.af3.XDeviceTable.EndSize = 0;
+ an->af.af3.XDeviceTable.DeltaValue = 0;
+ }
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail;
+
+ new_offset = GET_UShort();
+
+ FORGET_Frame();
+
+ if ( new_offset )
+ {
+ new_offset += base_offset;
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Device( &an->af.af3.YDeviceTable,
+ stream ) ) != TT_Err_Ok )
+ goto Fail;
+ (void)FILE_Seek( cur_offset );
+ }
+ else
+ {
+ an->af.af3.YDeviceTable.StartSize = 0;
+ an->af.af3.YDeviceTable.EndSize = 0;
+ an->af.af3.YDeviceTable.DeltaValue = 0;
+ }
+ break;
+
+ case 4:
+ if ( ACCESS_Frame( 4L ) )
+ return error;
+
+ an->af.af4.XIdAnchor = GET_UShort();
+ an->af.af4.YIdAnchor = GET_UShort();
+
+ FORGET_Frame();
+ break;
+
+ default:
+ return TTO_Err_Invalid_GPOS_SubTable_Format;
+ }
+
+ return TT_Err_Ok;
+
+ Fail:
+ Free_Device( &an->af.af3.XDeviceTable, memory );
+ return error;
+ }
+
+
+ static void Free_Anchor( TTO_Anchor* an,
+ FT_Memory memory)
+ {
+ if ( an->PosFormat == 3 )
+ {
+ Free_Device( &an->af.af3.YDeviceTable, memory );
+ Free_Device( &an->af.af3.XDeviceTable, memory );
+ }
+ }
+
+
+ static FT_Error Get_Anchor( GPOS_Instance* gpi,
+ TTO_Anchor* an,
+ FT_UShort glyph_index,
+ FT_Pos* x_value,
+ FT_Pos* y_value )
+ {
+ FT_Error error = TT_Err_Ok;
+
+ FT_Outline outline;
+ TTO_GPOSHeader* gpos = gpi->gpos;
+ FT_UShort ap;
+
+ FT_Short pixel_value;
+ FT_UShort load_flags;
+
+ FT_UShort x_ppem, y_ppem;
+ FT_Fixed x_scale, y_scale;
+
+
+ x_ppem = gpi->face->size->metrics.x_ppem;
+ y_ppem = gpi->face->size->metrics.y_ppem;
+ x_scale = gpi->face->size->metrics.x_scale;
+ y_scale = gpi->face->size->metrics.y_scale;
+
+ switch ( an->PosFormat )
+ {
+ case 0:
+ /* The special case of an empty AnchorTable */
+
+ return TTO_Err_Not_Covered;
+
+ case 1:
+ *x_value = x_scale * an->af.af1.XCoordinate / 0x10000;
+ *y_value = y_scale * an->af.af1.YCoordinate / 0x10000;
+ break;
+
+ case 2:
+ /* glyphs must be scaled */
+
+ load_flags = gpi->load_flags & ~FT_LOAD_NO_SCALE;
+
+ if ( !gpi->dvi )
+ {
+ error = (gpos->gfunc)( gpi->face, glyph_index, load_flags );
+ if ( error )
+ return error;
+
+ if ( gpi->face->glyph->format != ft_glyph_format_outline )
+ return TTO_Err_Invalid_GPOS_SubTable;
+
+ ap = an->af.af2.AnchorPoint;
+
+ outline = gpi->face->glyph->outline;
+
+ /* if outline.n_points is set to zero by gfunc(), we use the
+ design coordinate value pair. This can happen e.g. for
+ sbit glyphs */
+
+ if ( !outline.n_points )
+ goto no_contour_point;
+
+ if ( ap >= outline.n_points )
+ return TTO_Err_Invalid_GPOS_SubTable;
+
+ *x_value = outline.points[ap].x;
+ *y_value = outline.points[ap].y;
+ }
+ else
+ {
+ no_contour_point:
+ *x_value = x_scale * an->af.af3.XCoordinate / 0x10000;
+ *y_value = y_scale * an->af.af3.YCoordinate / 0x10000;
+ }
+ break;
+
+ case 3:
+ if ( !gpi->dvi )
+ {
+ Get_Device( &an->af.af3.XDeviceTable, x_ppem, &pixel_value );
+ *x_value = pixel_value << 6;
+ Get_Device( &an->af.af3.YDeviceTable, y_ppem, &pixel_value );
+ *y_value = pixel_value << 6;
+ }
+ else
+ *x_value = *y_value = 0;
+
+ *x_value += x_scale * an->af.af3.XCoordinate / 0x10000;
+ *y_value += y_scale * an->af.af3.YCoordinate / 0x10000;
+ break;
+
+ case 4:
+ error = (gpos->mmfunc)( gpi->face, an->af.af4.XIdAnchor,
+ x_value, gpos->data );
+ if ( error )
+ return error;
+
+ error = (gpos->mmfunc)( gpi->face, an->af.af4.YIdAnchor,
+ y_value, gpos->data );
+ if ( error )
+ return error;
+ break;
+ }
+
+ return error;
+ }
+
+
+ /* MarkArray */
+
+ static FT_Error Load_MarkArray ( TTO_MarkArray* ma,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, m, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_MarkRecord* mr;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ count = ma->MarkCount = GET_UShort();
+
+ FORGET_Frame();
+
+ ma->MarkRecord = NULL;
+
+ if ( ALLOC_ARRAY( ma->MarkRecord, count, TTO_MarkRecord ) )
+ return error;
+
+ mr = ma->MarkRecord;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 4L ) )
+ goto Fail;
+
+ mr[n].Class = GET_UShort();
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Anchor( &mr[n].MarkAnchor, stream ) ) != TT_Err_Ok )
+ goto Fail;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ return TT_Err_Ok;
+
+ Fail:
+ for ( m = 0; m < n; m++ )
+ Free_Anchor( &mr[m].MarkAnchor, memory );
+
+ FREE( mr );
+ return error;
+ }
+
+
+ static void Free_MarkArray( TTO_MarkArray* ma,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_MarkRecord* mr;
+
+
+ if ( ma->MarkRecord )
+ {
+ count = ma->MarkCount;
+ mr = ma->MarkRecord;
+
+ for ( n = 0; n < count; n++ )
+ Free_Anchor( &mr[n].MarkAnchor, memory );
+
+ FREE( mr );
+ }
+ }
+
+
+ /* LookupType 1 */
+
+ /* SinglePosFormat1 */
+ /* SinglePosFormat2 */
+
+ FT_Error Load_SinglePos( TTO_SinglePos* sp,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, m, count, format;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_ValueRecord* vr;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 6L ) )
+ return error;
+
+ sp->PosFormat = GET_UShort();
+ new_offset = GET_UShort() + base_offset;
+
+ format = sp->ValueFormat = GET_UShort();
+
+ FORGET_Frame();
+
+ if ( !format )
+ return TTO_Err_Invalid_GPOS_SubTable;
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Coverage( &sp->Coverage, stream ) ) != TT_Err_Ok )
+ return error;
+ (void)FILE_Seek( cur_offset );
+
+ switch ( sp->PosFormat )
+ {
+ case 1:
+ error = Load_ValueRecord( &sp->spf.spf1.Value, format,
+ base_offset, stream );
+ if ( error )
+ goto Fail2;
+ break;
+
+ case 2:
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail2;
+
+ count = sp->spf.spf2.ValueCount = GET_UShort();
+
+ FORGET_Frame();
+
+ sp->spf.spf2.Value = NULL;
+
+ if ( ALLOC_ARRAY( sp->spf.spf2.Value, count, TTO_ValueRecord ) )
+ goto Fail2;
+
+ vr = sp->spf.spf2.Value;
+
+ for ( n = 0; n < count; n++ )
+ {
+ error = Load_ValueRecord( &vr[n], format, base_offset, stream );
+ if ( error )
+ goto Fail1;
+ }
+ break;
+
+ default:
+ return TTO_Err_Invalid_GPOS_SubTable_Format;
+ }
+
+ return TT_Err_Ok;
+
+ Fail1:
+ for ( m = 0; m < n; m++ )
+ Free_ValueRecord( &vr[m], format, memory );
+
+ FREE( vr );
+
+ Fail2:
+ Free_Coverage( &sp->Coverage, memory );
+ return error;
+ }
+
+
+ void Free_SinglePos( TTO_SinglePos* sp,
+ FT_Memory memory )
+ {
+ FT_UShort n, count, format;
+
+ TTO_ValueRecord* v;
+
+
+ format = sp->ValueFormat;
+
+ switch ( sp->PosFormat )
+ {
+ case 1:
+ Free_ValueRecord( &sp->spf.spf1.Value, format, memory );
+ break;
+
+ case 2:
+ if ( sp->spf.spf2.Value )
+ {
+ count = sp->spf.spf2.ValueCount;
+ v = sp->spf.spf2.Value;
+
+ for ( n = 0; n < count; n++ )
+ Free_ValueRecord( &v[n], format, memory );
+
+ FREE( v );
+ }
+ break;
+ }
+
+ Free_Coverage( &sp->Coverage, memory );
+ }
+
+
+ static FT_Error Lookup_SinglePos( GPOS_Instance* gpi,
+ TTO_SinglePos* sp,
+ TTO_GSUB_String* in,
+ TTO_GPOS_Data* out,
+ FT_UShort flags,
+ FT_UShort context_length )
+ {
+ FT_UShort index, property;
+ FT_Error error;
+ TTO_GPOSHeader* gpos = gpi->gpos;
+
+
+ if ( context_length != 0xFFFF && context_length < 1 )
+ return TTO_Err_Not_Covered;
+
+ if ( CHECK_Property( gpos->gdef, in->string[in->pos], flags, &property ) )
+ return error;
+
+ error = Coverage_Index( &sp->Coverage, in->string[in->pos], &index );
+ if ( error )
+ return error;
+
+ switch ( sp->PosFormat )
+ {
+ case 1:
+ error = Get_ValueRecord( gpi, &sp->spf.spf1.Value,
+ sp->ValueFormat, &out[in->pos] );
+ if ( error )
+ return error;
+ break;
+
+ case 2:
+ if ( index >= sp->spf.spf2.ValueCount )
+ return TTO_Err_Invalid_GPOS_SubTable;
+ error = Get_ValueRecord( gpi, &sp->spf.spf2.Value[index],
+ sp->ValueFormat, &out[in->pos] );
+ if ( error )
+ return error;
+ break;
+
+ default:
+ return TTO_Err_Invalid_GPOS_SubTable;
+ }
+
+ (in->pos)++;
+
+ return TT_Err_Ok;
+ }
+
+
+ /* LookupType 2 */
+
+ /* PairSet */
+
+ static FT_Error Load_PairSet ( TTO_PairSet* ps,
+ FT_UShort format1,
+ FT_UShort format2,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, m, count;
+ FT_ULong base_offset;
+
+ TTO_PairValueRecord* pvr;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ count = ps->PairValueCount = GET_UShort();
+
+ FORGET_Frame();
+
+ ps->PairValueRecord = NULL;
+
+ if ( ALLOC_ARRAY( ps->PairValueRecord, count, TTO_PairValueRecord ) )
+ return error;
+
+ pvr = ps->PairValueRecord;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail;
+
+ pvr[n].SecondGlyph = GET_UShort();
+
+ FORGET_Frame();
+
+ if ( format1 )
+ {
+ error = Load_ValueRecord( &pvr[n].Value1, format1,
+ base_offset, stream );
+ if ( error )
+ goto Fail;
+ }
+ if ( format2 )
+ {
+ error = Load_ValueRecord( &pvr[n].Value2, format2,
+ base_offset, stream );
+ if ( error )
+ {
+ if ( format1 )
+ Free_ValueRecord( &pvr[n].Value1, format1, memory );
+ goto Fail;
+ }
+ }
+ }
+
+ return TT_Err_Ok;
+
+ Fail:
+ for ( m = 0; m < n; m++ )
+ {
+ if ( format1 )
+ Free_ValueRecord( &pvr[m].Value1, format1, memory );
+ if ( format2 )
+ Free_ValueRecord( &pvr[m].Value2, format2, memory );
+ }
+
+ FREE( pvr );
+ return error;
+ }
+
+
+ static void Free_PairSet( TTO_PairSet* ps,
+ FT_UShort format1,
+ FT_UShort format2,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_PairValueRecord* pvr;
+
+
+ if ( ps->PairValueRecord )
+ {
+ count = ps->PairValueCount;
+ pvr = ps->PairValueRecord;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( format1 )
+ Free_ValueRecord( &pvr[n].Value1, format1, memory );
+ if ( format2 )
+ Free_ValueRecord( &pvr[n].Value2, format2, memory );
+ }
+
+ FREE( pvr );
+ }
+ }
+
+
+ /* PairPosFormat1 */
+
+ static FT_Error Load_PairPos1( TTO_PairPosFormat1* ppf1,
+ FT_UShort format1,
+ FT_UShort format2,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, m, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_PairSet* ps;
+
+
+ base_offset = FILE_Pos() - 8L;
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ count = ppf1->PairSetCount = GET_UShort();
+
+ FORGET_Frame();
+
+ ppf1->PairSet = NULL;
+
+ if ( ALLOC_ARRAY( ppf1->PairSet, count, TTO_PairSet ) )
+ return error;
+
+ ps = ppf1->PairSet;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_PairSet( &ps[n], format1,
+ format2, stream ) ) != TT_Err_Ok )
+ goto Fail;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ return TT_Err_Ok;
+
+ Fail:
+ for ( m = 0; m < n; m++ )
+ Free_PairSet( &ps[m], format1, format2, memory );
+
+ FREE( ps );
+ return error;
+ }
+
+
+ static void Free_PairPos1( TTO_PairPosFormat1* ppf1,
+ FT_UShort format1,
+ FT_UShort format2,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_PairSet* ps;
+
+
+ if ( ppf1->PairSet )
+ {
+ count = ppf1->PairSetCount;
+ ps = ppf1->PairSet;
+
+ for ( n = 0; n < count; n++ )
+ Free_PairSet( &ps[n], format1, format2, memory );
+
+ FREE( ps );
+ }
+ }
+
+
+ /* PairPosFormat2 */
+
+ static FT_Error Load_PairPos2( TTO_PairPosFormat2* ppf2,
+ FT_UShort format1,
+ FT_UShort format2,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort m, n, k, count1, count2;
+ FT_ULong cur_offset, new_offset1, new_offset2, base_offset;
+
+ TTO_Class1Record* c1r;
+ TTO_Class2Record* c2r;
+
+
+ base_offset = FILE_Pos() - 8L;
+
+ if ( ACCESS_Frame( 8L ) )
+ return error;
+
+ new_offset1 = GET_UShort() + base_offset;
+ new_offset2 = GET_UShort() + base_offset;
+
+ /* `Class1Count' and `Class2Count' are the upper limits for class
+ values, thus we read it now to make additional safety checks. */
+
+ count1 = ppf2->Class1Count = GET_UShort();
+ count2 = ppf2->Class2Count = GET_UShort();
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset1 ) ||
+ ( error = Load_ClassDefinition( &ppf2->ClassDef1, count1,
+ stream ) ) != TT_Err_Ok )
+ return error;
+ if ( FILE_Seek( new_offset2 ) ||
+ ( error = Load_ClassDefinition( &ppf2->ClassDef2, count2,
+ stream ) ) != TT_Err_Ok )
+ goto Fail3;
+ (void)FILE_Seek( cur_offset );
+
+ ppf2->Class1Record = NULL;
+
+ if ( ALLOC_ARRAY( ppf2->Class1Record, count1, TTO_Class1Record ) )
+ goto Fail2;
+
+ c1r = ppf2->Class1Record;
+
+ for ( m = 0; m < count1; m++ )
+ {
+ c1r[m].Class2Record = NULL;
+
+ if ( ALLOC_ARRAY( c1r[m].Class2Record, count2, TTO_Class2Record ) )
+ goto Fail1;
+
+ c2r = c1r[m].Class2Record;
+
+ for ( n = 0; n < count2; n++ )
+ {
+ if ( format1 )
+ {
+ error = Load_ValueRecord( &c2r[n].Value1, format1,
+ base_offset, stream );
+ if ( error )
+ goto Fail0;
+ }
+ if ( format2 )
+ {
+ error = Load_ValueRecord( &c2r[n].Value2, format2,
+ base_offset, stream );
+ if ( error )
+ {
+ if ( format1 )
+ Free_ValueRecord( &c2r[n].Value1, format1, memory );
+ goto Fail0;
+ }
+ }
+ }
+
+ continue;
+
+ Fail0:
+ for ( k = 0; k < n; k++ )
+ {
+ if ( format1 )
+ Free_ValueRecord( &c2r[k].Value1, format1, memory );
+ if ( format2 )
+ Free_ValueRecord( &c2r[k].Value2, format2, memory );
+ }
+ goto Fail1;
+ }
+
+ return TT_Err_Ok;
+
+ Fail1:
+ for ( k = 0; k < m; k++ )
+ {
+ c2r = c1r[k].Class2Record;
+
+ for ( n = 0; n < count2; n++ )
+ {
+ if ( format1 )
+ Free_ValueRecord( &c2r[n].Value1, format1, memory );
+ if ( format2 )
+ Free_ValueRecord( &c2r[n].Value2, format2, memory );
+ }
+
+ FREE( c2r );
+ }
+
+ FREE( c1r );
+ Fail2:
+
+ Free_ClassDefinition( &ppf2->ClassDef2, memory );
+
+ Fail3:
+ Free_ClassDefinition( &ppf2->ClassDef1, memory );
+ return error;
+ }
+
+
+ static void Free_PairPos2( TTO_PairPosFormat2* ppf2,
+ FT_UShort format1,
+ FT_UShort format2,
+ FT_Memory memory )
+ {
+ FT_UShort m, n, count1, count2;
+
+ TTO_Class1Record* c1r;
+ TTO_Class2Record* c2r;
+
+
+ if ( ppf2->Class1Record )
+ {
+ c1r = ppf2->Class1Record;
+ count1 = ppf2->Class1Count;
+ count2 = ppf2->Class2Count;
+
+ for ( m = 0; m < count1; m++ )
+ {
+ c2r = c1r[m].Class2Record;
+
+ for ( n = 0; n < count2; n++ )
+ {
+ if ( format1 )
+ Free_ValueRecord( &c2r[n].Value1, format1, memory );
+ if ( format2 )
+ Free_ValueRecord( &c2r[n].Value2, format2, memory );
+ }
+
+ FREE( c2r );
+ }
+
+ FREE( c1r );
+
+ Free_ClassDefinition( &ppf2->ClassDef2, memory );
+ Free_ClassDefinition( &ppf2->ClassDef1, memory );
+ }
+ }
+
+
+ FT_Error Load_PairPos( TTO_PairPos* pp,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort format1, format2;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 8L ) )
+ return error;
+
+ pp->PosFormat = GET_UShort();
+ new_offset = GET_UShort() + base_offset;
+
+ format1 = pp->ValueFormat1 = GET_UShort();
+ format2 = pp->ValueFormat2 = GET_UShort();
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Coverage( &pp->Coverage, stream ) ) != TT_Err_Ok )
+ return error;
+ (void)FILE_Seek( cur_offset );
+
+ switch ( pp->PosFormat )
+ {
+ case 1:
+ error = Load_PairPos1( &pp->ppf.ppf1, format1, format2, stream );
+ if ( error )
+ goto Fail;
+ break;
+
+ case 2:
+ error = Load_PairPos2( &pp->ppf.ppf2, format1, format2, stream );
+ if ( error )
+ goto Fail;
+ break;
+
+ default:
+ return TTO_Err_Invalid_GPOS_SubTable_Format;
+ }
+
+ return TT_Err_Ok;
+
+ Fail:
+ Free_Coverage( &pp->Coverage, memory );
+ return error;
+ }
+
+
+ void Free_PairPos( TTO_PairPos* pp,
+ FT_Memory memory )
+ {
+ FT_UShort format1, format2;
+
+
+ format1 = pp->ValueFormat1;
+ format2 = pp->ValueFormat2;
+
+ switch ( pp->PosFormat )
+ {
+ case 1:
+ Free_PairPos1( &pp->ppf.ppf1, format1, format2, memory );
+ break;
+
+ case 2:
+ Free_PairPos2( &pp->ppf.ppf2, format1, format2, memory );
+ break;
+ }
+
+ Free_Coverage( &pp->Coverage, memory );
+ }
+
+
+ static FT_Error Lookup_PairPos1( GPOS_Instance* gpi,
+ TTO_PairPosFormat1* ppf1,
+ TTO_GSUB_String* in,
+ TTO_GPOS_Data* out,
+ FT_UShort first_pos,
+ FT_UShort index,
+ FT_UShort format1,
+ FT_UShort format2 )
+ {
+ FT_Error error;
+ FT_UShort numpvr, glyph2;
+
+ TTO_PairValueRecord* pvr;
+
+
+ if ( index >= ppf1->PairSetCount )
+ return TTO_Err_Invalid_GPOS_SubTable;
+
+ pvr = ppf1->PairSet[index].PairValueRecord;
+ if ( !pvr )
+ return TTO_Err_Invalid_GPOS_SubTable;
+
+ glyph2 = in->string[in->pos];
+
+ for ( numpvr = ppf1->PairSet[index].PairValueCount;
+ numpvr;
+ numpvr--, pvr++ )
+ {
+ if ( glyph2 == pvr->SecondGlyph )
+ {
+ error = Get_ValueRecord( gpi, &pvr->Value1, format1,
+ &out[first_pos] );
+ if ( error )
+ return error;
+ return Get_ValueRecord( gpi, &pvr->Value2, format2,
+ &out[in->pos] );
+ }
+ }
+
+ return TTO_Err_Not_Covered;
+ }
+
+
+ static FT_Error Lookup_PairPos2( GPOS_Instance* gpi,
+ TTO_PairPosFormat2* ppf2,
+ TTO_GSUB_String* in,
+ TTO_GPOS_Data* out,
+ FT_UShort first_pos,
+ FT_UShort format1,
+ FT_UShort format2 )
+ {
+ FT_Error error;
+ FT_UShort cl1, cl2;
+
+ TTO_Class1Record* c1r;
+ TTO_Class2Record* c2r;
+
+
+ error = Get_Class( &ppf2->ClassDef1, in->string[first_pos],
+ &cl1, NULL );
+ if ( error && error != TTO_Err_Not_Covered )
+ return error;
+ error = Get_Class( &ppf2->ClassDef2, in->string[in->pos],
+ &cl2, NULL );
+ if ( error && error != TTO_Err_Not_Covered )
+ return error;
+
+ c1r = &ppf2->Class1Record[cl1];
+ if ( !c1r )
+ return TTO_Err_Invalid_GPOS_SubTable;
+ c2r = &c1r->Class2Record[cl2];
+
+ error = Get_ValueRecord( gpi, &c2r->Value1, format1, &out[first_pos] );
+ if ( error )
+ return error;
+ return Get_ValueRecord( gpi, &c2r->Value2, format2, &out[in->pos] );
+ }
+
+
+ static FT_Error Lookup_PairPos( GPOS_Instance* gpi,
+ TTO_PairPos* pp,
+ TTO_GSUB_String* in,
+ TTO_GPOS_Data* out,
+ FT_UShort flags,
+ FT_UShort context_length )
+ {
+ FT_Error error;
+ FT_UShort index, property, first_pos;
+ TTO_GPOSHeader* gpos = gpi->gpos;
+
+
+ if ( in->pos >= in->length - 1 )
+ return TTO_Err_Not_Covered; /* Not enough glyphs in stream */
+
+ if ( context_length != 0xFFFF && context_length < 2 )
+ return TTO_Err_Not_Covered;
+
+ if ( CHECK_Property( gpos->gdef, in->string[in->pos], flags, &property ) )
+ return error;
+
+ error = Coverage_Index( &pp->Coverage, in->string[in->pos], &index );
+ if ( error )
+ return error;
+
+ /* second glyph */
+
+ first_pos = in->pos;
+ (in->pos)++;
+
+ while ( CHECK_Property( gpos->gdef, in->string[in->pos],
+ flags, &property ) )
+ {
+ if ( error && error != TTO_Err_Not_Covered )
+ return error;
+
+ if ( in->pos < in->length )
+ (in->pos)++;
+ else
+ break;
+ }
+
+ switch ( pp->PosFormat )
+ {
+ case 1:
+ error = Lookup_PairPos1( gpi, &pp->ppf.ppf1, in, out,
+ first_pos, index,
+ pp->ValueFormat1, pp->ValueFormat2 );
+ break;
+
+ case 2:
+ error = Lookup_PairPos2( gpi, &pp->ppf.ppf2, in, out, first_pos,
+ pp->ValueFormat1, pp->ValueFormat2 );
+ break;
+
+ default:
+ return TTO_Err_Invalid_GPOS_SubTable_Format;
+ }
+
+ /* adjusting the `next' glyph */
+
+ if ( pp->ValueFormat2 )
+ (in->pos)++;
+
+ return error;
+ }
+
+
+ /* LookupType 3 */
+
+ /* CursivePosFormat1 */
+
+ FT_Error Load_CursivePos( TTO_CursivePos* cp,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, m, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_EntryExitRecord* eer;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 4L ) )
+ return error;
+
+ cp->PosFormat = GET_UShort();
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Coverage( &cp->Coverage, stream ) ) != TT_Err_Ok )
+ return error;
+ (void)FILE_Seek( cur_offset );
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail2;
+
+ count = cp->EntryExitCount = GET_UShort();
+
+ FORGET_Frame();
+
+ cp->EntryExitRecord = NULL;
+
+ if ( ALLOC_ARRAY( cp->EntryExitRecord, count, TTO_EntryExitRecord ) )
+ goto Fail2;
+
+ eer = cp->EntryExitRecord;
+
+ for ( n = 0; n < count; n++ )
+ {
+ FT_ULong entry_offset;
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ entry_offset = new_offset = GET_UShort();
+
+ FORGET_Frame();
+
+ if ( new_offset )
+ {
+ new_offset += base_offset;
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Anchor( &eer[n].EntryAnchor,
+ stream ) ) != TT_Err_Ok )
+ goto Fail1;
+ (void)FILE_Seek( cur_offset );
+ }
+ else
+ eer[n].EntryAnchor.PosFormat = 0;
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ new_offset = GET_UShort();
+
+ FORGET_Frame();
+
+ if ( new_offset )
+ {
+ new_offset += base_offset;
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Anchor( &eer[n].ExitAnchor,
+ stream ) ) != TT_Err_Ok )
+ {
+ if ( entry_offset )
+ Free_Anchor( &eer[n].EntryAnchor, memory );
+ goto Fail1;
+ }
+ (void)FILE_Seek( cur_offset );
+ }
+ else
+ eer[n].ExitAnchor.PosFormat = 0;
+ }
+
+ return TT_Err_Ok;
+
+ Fail1:
+ for ( m = 0; m < n; m++ )
+ {
+ Free_Anchor( &eer[m].EntryAnchor, memory );
+ Free_Anchor( &eer[m].ExitAnchor, memory );
+ }
+
+ FREE( eer );
+
+ Fail2:
+ Free_Coverage( &cp->Coverage, memory );
+ return error;
+ }
+
+
+ void Free_CursivePos( TTO_CursivePos* cp,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_EntryExitRecord* eer;
+
+
+ if ( cp->EntryExitRecord )
+ {
+ count = cp->EntryExitCount;
+ eer = cp->EntryExitRecord;
+
+ for ( n = 0; n < count; n++ )
+ {
+ Free_Anchor( &eer[n].EntryAnchor, memory );
+ Free_Anchor( &eer[n].ExitAnchor, memory );
+ }
+
+ FREE( eer );
+ }
+
+ Free_Coverage( &cp->Coverage, memory );
+ }
+
+
+ static FT_Error Lookup_CursivePos( GPOS_Instance* gpi,
+ TTO_CursivePos* cp,
+ TTO_GSUB_String* in,
+ TTO_GPOS_Data* out,
+ FT_UShort flags,
+ FT_UShort context_length )
+ {
+ FT_UShort index, property;
+ FT_Error error;
+ TTO_GPOSHeader* gpos = gpi->gpos;
+
+ TTO_EntryExitRecord* eer;
+ FT_Pos entry_x, entry_y;
+ FT_Pos exit_x, exit_y;
+
+
+ if ( context_length != 0xFFFF && context_length < 1 )
+ {
+ gpi->last = 0xFFFF;
+ return TTO_Err_Not_Covered;
+ }
+
+ /* Glyphs not having the right GDEF properties will be ignored, i.e.,
+ gpi->last won't be reset (contrary to user defined properties). */
+
+ if ( CHECK_Property( gpos->gdef, in->string[in->pos], flags, &property ) )
+ return error;
+
+ /* We don't handle mark glyphs here. According to Andrei, this isn't
+ possible, but who knows... */
+
+ if ( property == MARK_GLYPH )
+ {
+ gpi->last = 0xFFFF;
+ return TTO_Err_Not_Covered;
+ }
+
+ error = Coverage_Index( &cp->Coverage, in->string[in->pos], &index );
+ if ( error )
+ {
+ gpi->last = 0xFFFF;
+ return error;
+ }
+
+ if ( index >= cp->EntryExitCount )
+ return TTO_Err_Invalid_GPOS_SubTable;
+
+ eer = &cp->EntryExitRecord[index];
+
+ /* Now comes the messiest part of the whole OpenType
+ specification. At first glance, cursive connections seem easy
+ to understand, but there are pitfalls! The reason is that
+ the specs don't mention how to compute the advance values
+ resp. glyph offsets. I was told it would be an omission, to
+ be fixed in the next OpenType version... Again many thanks to
+ Andrei Burago <andreib@microsoft.com> for clarifications.
+
+ Consider the following example:
+
+ | xadv1 |
+ +---------+
+ | |
+ +-----+--+ 1 |
+ | | .| |
+ | 0+--+------+
+ | 2 |
+ | |
+ 0+--------+
+ | xadv2 |
+
+ glyph1: advance width = 12
+ anchor point = (3,1)
+
+ glyph2: advance width = 11
+ anchor point = (9,4)
+
+ LSB is 1 for both glyphs (so the boxes drawn above are glyph
+ bboxes). Writing direction is R2L; `0' denotes the glyph's
+ coordinate origin.
+
+ Now the surprising part: The advance width of the *left* glyph
+ (resp. of the *bottom* glyph) will be modified, no matter
+ whether the writing direction is L2R or R2L (resp. T2B or
+ B2T)! This assymetry is caused by the fact that the glyph's
+ coordinate origin is always the lower left corner for all
+ writing directions.
+
+ Continuing the above example, we can compute the new
+ (horizontal) advance width of glyph2 as
+
+ 9 - 3 = 6 ,
+
+ and the new vertical offset of glyph2 as
+
+ 1 - 4 = -3 .
+
+
+ Vertical writing direction is far more complicated:
+
+ a) Assuming that we recompute the advance height of the lower glyph:
+
+ --
+ +---------+
+ -- | |
+ +-----+--+ 1 | yadv1
+ | | .| |
+ yadv2 | 0+--+------+ -- BSB1 --
+ | 2 | -- -- y_offset
+ | |
+ BSB2 -- 0+--------+ --
+ -- --
+
+ glyph1: advance height = 6
+ anchor point = (3,1)
+
+ glyph2: advance height = 7
+ anchor point = (9,4)
+
+ TSB is 1 for both glyphs; writing direction is T2B.
+
+
+ BSB1 = yadv1 - (TSB1 + ymax1)
+ BSB2 = yadv2 - (TSB2 + ymax2)
+ y_offset = y2 - y1
+
+ vertical advance width of glyph2
+ = y_offset + BSB2 - BSB1
+ = (y2 - y1) + (yadv2 - (TSB2 + ymax2)) - (yadv1 - (TSB1 + ymax1))
+ = y2 - y1 + yadv2 - TSB2 - ymax2 - (yadv1 - TSB1 - ymax1)
+ = y2 - y1 + yadv2 - TSB2 - ymax2 - yadv1 + TSB1 + ymax1
+
+
+ b) Assuming that we recompute the advance height of the upper glyph:
+
+ -- --
+ +---------+ -- TSB1
+ -- -- | |
+ TSB2 -- +-----+--+ 1 | yadv1 ymax1
+ | | .| |
+ yadv2 | 0+--+------+ -- --
+ ymax2 | 2 | -- y_offset
+ | |
+ -- 0+--------+ --
+ --
+
+ glyph1: advance height = 6
+ anchor point = (3,1)
+
+ glyph2: advance height = 7
+ anchor point = (9,4)
+
+ TSB is 1 for both glyphs; writing direction is T2B.
+
+ y_offset = y2 - y1
+
+ vertical advance width of glyph2
+ = TSB1 + ymax1 + y_offset - (TSB2 + ymax2)
+ = TSB1 + ymax1 + y2 - y1 - TSB2 - ymax2
+
+
+ Comparing a) with b) shows that b) is easier to compute. I'll wait
+ for a reply from Andrei to see what should really be implemented...
+
+ Since horizontal advance widths or vertical advance heights
+ can be used alone but not together, no ambiguity occurs. */
+
+ if ( gpi->last == 0xFFFF )
+ goto end;
+
+ /* Get_Anchor() returns TTO_Err_Not_Covered if there is no anchor
+ table. */
+
+ error = Get_Anchor( gpi, &eer->EntryAnchor, in->string[in->pos],
+ &entry_x, &entry_y );
+ if ( error == TTO_Err_Not_Covered )
+ goto end;
+ if ( error )
+ return error;
+
+ if ( gpi->r2l )
+ {
+ out[in->pos].x_advance = entry_x - gpi->anchor_x;
+ out[in->pos].new_advance = TRUE;
+ }
+ else
+ {
+ out[gpi->last].x_advance = gpi->anchor_x - entry_x;
+ out[gpi->last].new_advance = TRUE;
+ }
+
+ out[in->pos].y_pos = gpi->anchor_y - entry_y + out[gpi->last].y_pos;
+
+ end:
+ error = Get_Anchor( gpi, &eer->ExitAnchor, in->string[in->pos],
+ &exit_x, &exit_y );
+ if ( error == TTO_Err_Not_Covered )
+ gpi->last = 0xFFFF;
+ else
+ {
+ if ( gpi->first == 0xFFFF )
+ gpi->first = in->pos;
+ gpi->last = in->pos;
+ gpi->anchor_x = exit_x;
+ gpi->anchor_y = exit_y;
+ }
+ if ( error )
+ return error;
+
+ (in->pos)++;
+
+ return TT_Err_Ok;
+ }
+
+
+ /* LookupType 4 */
+
+ /* BaseArray */
+
+ static FT_Error Load_BaseArray( TTO_BaseArray* ba,
+ FT_UShort num_classes,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort m, n, k, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_BaseRecord* br;
+ TTO_Anchor* ban;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ count = ba->BaseCount = GET_UShort();
+
+ FORGET_Frame();
+
+ ba->BaseRecord = NULL;
+
+ if ( ALLOC_ARRAY( ba->BaseRecord, count, TTO_BaseRecord ) )
+ return error;
+
+ br = ba->BaseRecord;
+
+ for ( m = 0; m < count; m++ )
+ {
+ br[m].BaseAnchor = NULL;
+
+ if ( ALLOC_ARRAY( br[m].BaseAnchor, num_classes, TTO_Anchor ) )
+ goto Fail;
+
+ ban = br[m].BaseAnchor;
+
+ for ( n = 0; n < num_classes; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail0;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Anchor( &ban[n], stream ) ) != TT_Err_Ok )
+ goto Fail0;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ continue;
+ Fail0:
+ for ( k = 0; k < n; k++ )
+ Free_Anchor( &ban[k], memory );
+ goto Fail;
+ }
+
+ return TT_Err_Ok;
+
+ Fail:
+ for ( k = 0; k < m; k++ )
+ {
+ ban = br[k].BaseAnchor;
+
+ for ( n = 0; n < num_classes; n++ )
+ Free_Anchor( &ban[n], memory );
+
+ FREE( ban );
+ }
+
+ FREE( br );
+ return error;
+ }
+
+
+ static void Free_BaseArray( TTO_BaseArray* ba,
+ FT_UShort num_classes,
+ FT_Memory memory )
+ {
+ FT_UShort m, n, count;
+
+ TTO_BaseRecord* br;
+ TTO_Anchor* ban;
+
+
+ if ( ba->BaseRecord )
+ {
+ count = ba->BaseCount;
+ br = ba->BaseRecord;
+
+ for ( m = 0; m < count; m++ )
+ {
+ ban = br[m].BaseAnchor;
+
+ for ( n = 0; n < num_classes; n++ )
+ Free_Anchor( &ban[n], memory );
+
+ FREE( ban );
+ }
+
+ FREE( br );
+ }
+ }
+
+
+ /* MarkBasePosFormat1 */
+
+ FT_Error Load_MarkBasePos( TTO_MarkBasePos* mbp,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_ULong cur_offset, new_offset, base_offset;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 4L ) )
+ return error;
+
+ mbp->PosFormat = GET_UShort();
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Coverage( &mbp->MarkCoverage, stream ) ) != TT_Err_Ok )
+ return error;
+ (void)FILE_Seek( cur_offset );
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail3;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Coverage( &mbp->BaseCoverage, stream ) ) != TT_Err_Ok )
+ goto Fail3;
+ (void)FILE_Seek( cur_offset );
+
+ if ( ACCESS_Frame( 4L ) )
+ goto Fail2;
+
+ mbp->ClassCount = GET_UShort();
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_MarkArray( &mbp->MarkArray, stream ) ) != TT_Err_Ok )
+ goto Fail2;
+ (void)FILE_Seek( cur_offset );
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail1;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_BaseArray( &mbp->BaseArray, mbp->ClassCount,
+ stream ) ) != TT_Err_Ok )
+ goto Fail1;
+
+ return TT_Err_Ok;
+
+ Fail1:
+ Free_MarkArray( &mbp->MarkArray, memory );
+
+ Fail2:
+ Free_Coverage( &mbp->BaseCoverage, memory );
+
+ Fail3:
+ Free_Coverage( &mbp->MarkCoverage, memory );
+ return error;
+ }
+
+
+ void Free_MarkBasePos( TTO_MarkBasePos* mbp,
+ FT_Memory memory )
+ {
+ Free_BaseArray( &mbp->BaseArray, mbp->ClassCount, memory );
+ Free_MarkArray( &mbp->MarkArray, memory );
+ Free_Coverage( &mbp->BaseCoverage, memory );
+ Free_Coverage( &mbp->MarkCoverage, memory );
+ }
+
+
+ static FT_Error Lookup_MarkBasePos( GPOS_Instance* gpi,
+ TTO_MarkBasePos* mbp,
+ TTO_GSUB_String* in,
+ TTO_GPOS_Data* out,
+ FT_UShort flags,
+ FT_UShort context_length )
+ {
+ FT_UShort i, j, mark_index, base_index, property, class;
+ FT_Pos x_mark_value, y_mark_value, x_base_value, y_base_value;
+ FT_Error error;
+ TTO_GPOSHeader* gpos = gpi->gpos;
+
+ TTO_MarkArray* ma;
+ TTO_BaseArray* ba;
+ TTO_BaseRecord* br;
+ TTO_Anchor* mark_anchor;
+ TTO_Anchor* base_anchor;
+
+ TTO_GPOS_Data* o;
+
+
+ if ( context_length != 0xFFFF && context_length < 1 )
+ return TTO_Err_Not_Covered;
+
+ if ( flags & IGNORE_BASE_GLYPHS )
+ return TTO_Err_Not_Covered;
+
+ if ( CHECK_Property( gpos->gdef, in->string[in->pos],
+ flags, &property ) )
+ return error;
+
+ error = Coverage_Index( &mbp->MarkCoverage, in->string[in->pos],
+ &mark_index );
+ if ( error )
+ return error;
+
+ /* now we search backwards for a non-mark glyph */
+
+ i = 1;
+ j = in->pos - 1;
+
+ while ( i <= in->pos )
+ {
+ error = TT_GDEF_Get_Glyph_Property( gpos->gdef, in->string[j],
+ &property );
+ if ( error )
+ return error;
+
+ if ( !( property == TTO_MARK || property & IGNORE_SPECIAL_MARKS ) )
+ break;
+
+ i++;
+ j--;
+ }
+
+ /* The following assertion is too strong -- at least for mangal.ttf. */
+#if 0
+ if ( property != TTO_BASE_GLYPH )
+ return TTO_Err_Not_Covered;
+#endif
+
+ if ( i > in->pos )
+ return TTO_Err_Not_Covered;
+
+ error = Coverage_Index( &mbp->BaseCoverage, in->string[j],
+ &base_index );
+ if ( error )
+ return error;
+
+ ma = &mbp->MarkArray;
+
+ if ( mark_index >= ma->MarkCount )
+ return TTO_Err_Invalid_GPOS_SubTable;
+
+ class = ma->MarkRecord[mark_index].Class;
+ mark_anchor = &ma->MarkRecord[mark_index].MarkAnchor;
+
+ if ( class >= mbp->ClassCount )
+ return TTO_Err_Invalid_GPOS_SubTable;
+
+ ba = &mbp->BaseArray;
+
+ if ( base_index >= ba->BaseCount )
+ return TTO_Err_Invalid_GPOS_SubTable;
+
+ br = &ba->BaseRecord[base_index];
+ base_anchor = &br->BaseAnchor[class];
+
+ error = Get_Anchor( gpi, mark_anchor, in->string[in->pos],
+ &x_mark_value, &y_mark_value );
+ if ( error )
+ return error;
+
+ error = Get_Anchor( gpi, base_anchor, in->string[j],
+ &x_base_value, &y_base_value );
+ if ( error )
+ return error;
+
+ /* anchor points are not cumulative */
+
+ o = &out[in->pos];
+
+ o->x_pos = x_base_value - x_mark_value;
+ o->y_pos = y_base_value - y_mark_value;
+ o->x_advance = 0;
+ o->y_advance = 0;
+ o->back = i;
+
+ (in->pos)++;
+
+ return TT_Err_Ok;
+ }
+
+
+ /* LookupType 5 */
+
+ /* LigatureAttach */
+
+ static FT_Error Load_LigatureAttach( TTO_LigatureAttach* lat,
+ FT_UShort num_classes,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort m, n, k, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_ComponentRecord* cr;
+ TTO_Anchor* lan;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ count = lat->ComponentCount = GET_UShort();
+
+ FORGET_Frame();
+
+ lat->ComponentRecord = NULL;
+
+ if ( ALLOC_ARRAY( lat->ComponentRecord, count, TTO_ComponentRecord ) )
+ return error;
+
+ cr = lat->ComponentRecord;
+
+ for ( m = 0; m < count; m++ )
+ {
+ cr[m].LigatureAnchor = NULL;
+
+ if ( ALLOC_ARRAY( cr[m].LigatureAnchor, num_classes, TTO_Anchor ) )
+ goto Fail;
+
+ lan = cr[m].LigatureAnchor;
+
+ for ( n = 0; n < num_classes; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail0;
+
+ new_offset = GET_UShort();
+
+ FORGET_Frame();
+
+ if ( new_offset )
+ {
+ new_offset += base_offset;
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Anchor( &lan[n], stream ) ) != TT_Err_Ok )
+ goto Fail0;
+ (void)FILE_Seek( cur_offset );
+ }
+ else
+ lan[n].PosFormat = 0;
+ }
+
+ continue;
+ Fail0:
+ for ( k = 0; k < n; k++ )
+ Free_Anchor( &lan[k], memory );
+ goto Fail;
+ }
+
+ return TT_Err_Ok;
+
+ Fail:
+ for ( k = 0; k < m; k++ )
+ {
+ lan = cr[k].LigatureAnchor;
+
+ for ( n = 0; n < num_classes; n++ )
+ Free_Anchor( &lan[n], memory );
+
+ FREE( lan );
+ }
+
+ FREE( cr );
+ return error;
+ }
+
+
+ static void Free_LigatureAttach( TTO_LigatureAttach* lat,
+ FT_UShort num_classes,
+ FT_Memory memory )
+ {
+ FT_UShort m, n, count;
+
+ TTO_ComponentRecord* cr;
+ TTO_Anchor* lan;
+
+
+ if ( lat->ComponentRecord )
+ {
+ count = lat->ComponentCount;
+ cr = lat->ComponentRecord;
+
+ for ( m = 0; m < count; m++ )
+ {
+ lan = cr[m].LigatureAnchor;
+
+ for ( n = 0; n < num_classes; n++ )
+ Free_Anchor( &lan[n], memory );
+
+ FREE( lan );
+ }
+
+ FREE( cr );
+ }
+ }
+
+
+ /* LigatureArray */
+
+ static FT_Error Load_LigatureArray( TTO_LigatureArray* la,
+ FT_UShort num_classes,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, m, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_LigatureAttach* lat;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ count = la->LigatureCount = GET_UShort();
+
+ FORGET_Frame();
+
+ la->LigatureAttach = NULL;
+
+ if ( ALLOC_ARRAY( la->LigatureAttach, count, TTO_LigatureAttach ) )
+ return error;
+
+ lat = la->LigatureAttach;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_LigatureAttach( &lat[n], num_classes,
+ stream ) ) != TT_Err_Ok )
+ goto Fail;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ return TT_Err_Ok;
+
+ Fail:
+ for ( m = 0; m < n; m++ )
+ Free_LigatureAttach( &lat[m], num_classes, memory );
+
+ FREE( lat );
+ return error;
+ }
+
+
+ static void Free_LigatureArray( TTO_LigatureArray* la,
+ FT_UShort num_classes,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_LigatureAttach* lat;
+
+
+ if ( la->LigatureAttach )
+ {
+ count = la->LigatureCount;
+ lat = la->LigatureAttach;
+
+ for ( n = 0; n < count; n++ )
+ Free_LigatureAttach( &lat[n], num_classes, memory );
+
+ FREE( lat );
+ }
+ }
+
+
+ /* MarkLigPosFormat1 */
+
+ FT_Error Load_MarkLigPos( TTO_MarkLigPos* mlp,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_ULong cur_offset, new_offset, base_offset;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 4L ) )
+ return error;
+
+ mlp->PosFormat = GET_UShort();
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Coverage( &mlp->MarkCoverage, stream ) ) != TT_Err_Ok )
+ return error;
+ (void)FILE_Seek( cur_offset );
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail3;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Coverage( &mlp->LigatureCoverage,
+ stream ) ) != TT_Err_Ok )
+ goto Fail3;
+ (void)FILE_Seek( cur_offset );
+
+ if ( ACCESS_Frame( 4L ) )
+ goto Fail2;
+
+ mlp->ClassCount = GET_UShort();
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_MarkArray( &mlp->MarkArray, stream ) ) != TT_Err_Ok )
+ goto Fail2;
+ (void)FILE_Seek( cur_offset );
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail1;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_LigatureArray( &mlp->LigatureArray, mlp->ClassCount,
+ stream ) ) != TT_Err_Ok )
+ goto Fail1;
+
+ return TT_Err_Ok;
+
+ Fail1:
+ Free_MarkArray( &mlp->MarkArray, memory );
+
+ Fail2:
+ Free_Coverage( &mlp->LigatureCoverage, memory );
+
+ Fail3:
+ Free_Coverage( &mlp->MarkCoverage, memory );
+ return error;
+ }
+
+
+ void Free_MarkLigPos( TTO_MarkLigPos* mlp,
+ FT_Memory memory)
+ {
+ Free_LigatureArray( &mlp->LigatureArray, mlp->ClassCount, memory );
+ Free_MarkArray( &mlp->MarkArray, memory );
+ Free_Coverage( &mlp->LigatureCoverage, memory );
+ Free_Coverage( &mlp->MarkCoverage, memory );
+ }
+
+
+ static FT_Error Lookup_MarkLigPos( GPOS_Instance* gpi,
+ TTO_MarkLigPos* mlp,
+ TTO_GSUB_String* in,
+ TTO_GPOS_Data* out,
+ FT_UShort flags,
+ FT_UShort context_length )
+ {
+ FT_UShort i, j, mark_index, lig_index, property, class;
+ FT_UShort mark_glyph;
+ FT_Pos x_mark_value, y_mark_value, x_lig_value, y_lig_value;
+ FT_Error error;
+ TTO_GPOSHeader* gpos = gpi->gpos;
+
+ TTO_MarkArray* ma;
+ TTO_LigatureArray* la;
+ TTO_LigatureAttach* lat;
+ TTO_ComponentRecord* cr;
+ FT_UShort comp_index;
+ TTO_Anchor* mark_anchor;
+ TTO_Anchor* lig_anchor;
+
+ TTO_GPOS_Data* o;
+
+
+ if ( context_length != 0xFFFF && context_length < 1 )
+ return TTO_Err_Not_Covered;
+
+ if ( flags & IGNORE_LIGATURES )
+ return TTO_Err_Not_Covered;
+
+ mark_glyph = in->string[in->pos];
+
+ if ( CHECK_Property( gpos->gdef, mark_glyph, flags, &property ) )
+ return error;
+
+ error = Coverage_Index( &mlp->MarkCoverage, mark_glyph, &mark_index );
+ if ( error )
+ return error;
+
+ /* now we search backwards for a non-mark glyph */
+
+ i = 1;
+ j = in->pos - 1;
+
+ while ( i <= in->pos )
+ {
+ error = TT_GDEF_Get_Glyph_Property( gpos->gdef, in->string[j],
+ &property );
+ if ( error )
+ return error;
+
+ if ( !( property == TTO_MARK || property & IGNORE_SPECIAL_MARKS ) )
+ break;
+
+ i++;
+ j--;
+ }
+
+ /* Similar to Lookup_MarkBasePos(), I suspect that this assertion is
+ too strong, thus it is commented out. */
+#if 0
+ if ( property != TTO_LIGATURE )
+ return TTO_Err_Not_Covered;
+#endif
+
+ if ( i > in->pos )
+ return TTO_Err_Not_Covered;
+
+ error = Coverage_Index( &mlp->LigatureCoverage, in->string[j],
+ &lig_index );
+ if ( error )
+ return error;
+
+ ma = &mlp->MarkArray;
+
+ if ( mark_index >= ma->MarkCount )
+ return TTO_Err_Invalid_GPOS_SubTable;
+
+ class = ma->MarkRecord[mark_index].Class;
+ mark_anchor = &ma->MarkRecord[mark_index].MarkAnchor;
+
+ if ( class >= mlp->ClassCount )
+ return TTO_Err_Invalid_GPOS_SubTable;
+
+ la = &mlp->LigatureArray;
+
+ if ( lig_index >= la->LigatureCount )
+ return TTO_Err_Invalid_GPOS_SubTable;
+
+ lat = &la->LigatureAttach[lig_index];
+
+ /* We must now check whether the ligature ID of the current mark glyph
+ is identical to the ligature ID of the found ligature. If yes, we
+ can directly use the component index. If not, we attach the mark
+ glyph to the last component of the ligature. */
+
+ if ( in->ligIDs && in->components &&
+ in->ligIDs[j] == in->ligIDs[in->pos] )
+ {
+ comp_index = in->components[in->pos];
+ if ( comp_index >= lat->ComponentCount )
+ return TTO_Err_Not_Covered;
+ }
+ else
+ comp_index = lat->ComponentCount - 1;
+
+ cr = &lat->ComponentRecord[comp_index];
+ lig_anchor = &cr->LigatureAnchor[class];
+
+ error = Get_Anchor( gpi, mark_anchor, in->string[in->pos],
+ &x_mark_value, &y_mark_value );
+ if ( error )
+ return error;
+ error = Get_Anchor( gpi, lig_anchor, in->string[j],
+ &x_lig_value, &y_lig_value );
+ if ( error )
+ return error;
+
+ /* anchor points are not cumulative */
+
+ o = &out[in->pos];
+
+ o->x_pos = x_lig_value - x_mark_value;
+ o->y_pos = y_lig_value - y_mark_value;
+ o->x_advance = 0;
+ o->y_advance = 0;
+ o->back = i;
+
+ (in->pos)++;
+
+ return TT_Err_Ok;
+ }
+
+
+ /* LookupType 6 */
+
+ /* Mark2Array */
+
+ static FT_Error Load_Mark2Array( TTO_Mark2Array* m2a,
+ FT_UShort num_classes,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort k, m, n, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_Mark2Record* m2r;
+ TTO_Anchor* m2an;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ count = m2a->Mark2Count = GET_UShort();
+
+ FORGET_Frame();
+
+ m2a->Mark2Record = NULL;
+
+ if ( ALLOC_ARRAY( m2a->Mark2Record, count, TTO_Mark2Record ) )
+ return error;
+
+ m2r = m2a->Mark2Record;
+
+ for ( m = 0; m < count; m++ )
+ {
+ m2r[m].Mark2Anchor = NULL;
+
+ if ( ALLOC_ARRAY( m2r[m].Mark2Anchor, num_classes, TTO_Anchor ) )
+ goto Fail;
+
+ m2an = m2r[m].Mark2Anchor;
+
+ for ( n = 0; n < num_classes; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail0;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Anchor( &m2an[n], stream ) ) != TT_Err_Ok )
+ goto Fail0;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ continue;
+ Fail0:
+ for ( k = 0; k < n; k++ )
+ Free_Anchor( &m2an[k], memory );
+ goto Fail;
+ }
+
+ return TT_Err_Ok;
+
+ Fail:
+ for ( k = 0; k < m; k++ )
+ {
+ m2an = m2r[k].Mark2Anchor;
+
+ for ( n = 0; n < num_classes; n++ )
+ Free_Anchor( &m2an[n], memory );
+
+ FREE( m2an );
+ }
+
+ FREE( m2r );
+ return error;
+ }
+
+
+ static void Free_Mark2Array( TTO_Mark2Array* m2a,
+ FT_UShort num_classes,
+ FT_Memory memory )
+ {
+ FT_UShort m, n, count;
+
+ TTO_Mark2Record* m2r;
+ TTO_Anchor* m2an;
+
+
+ if ( m2a->Mark2Record )
+ {
+ count = m2a->Mark2Count;
+ m2r = m2a->Mark2Record;
+
+ for ( m = 0; m < count; m++ )
+ {
+ m2an = m2r[m].Mark2Anchor;
+
+ for ( n = 0; n < num_classes; n++ )
+ Free_Anchor( &m2an[n], memory );
+
+ FREE( m2an );
+ }
+
+ FREE( m2r );
+ }
+ }
+
+
+ /* MarkMarkPosFormat1 */
+
+ FT_Error Load_MarkMarkPos( TTO_MarkMarkPos* mmp,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_ULong cur_offset, new_offset, base_offset;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 4L ) )
+ return error;
+
+ mmp->PosFormat = GET_UShort();
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Coverage( &mmp->Mark1Coverage,
+ stream ) ) != TT_Err_Ok )
+ return error;
+ (void)FILE_Seek( cur_offset );
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail3;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Coverage( &mmp->Mark2Coverage,
+ stream ) ) != TT_Err_Ok )
+ goto Fail3;
+ (void)FILE_Seek( cur_offset );
+
+ if ( ACCESS_Frame( 4L ) )
+ goto Fail2;
+
+ mmp->ClassCount = GET_UShort();
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_MarkArray( &mmp->Mark1Array, stream ) ) != TT_Err_Ok )
+ goto Fail2;
+ (void)FILE_Seek( cur_offset );
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail1;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Mark2Array( &mmp->Mark2Array, mmp->ClassCount,
+ stream ) ) != TT_Err_Ok )
+ goto Fail1;
+
+ return TT_Err_Ok;
+
+ Fail1:
+ Free_MarkArray( &mmp->Mark1Array, memory );
+
+ Fail2:
+ Free_Coverage( &mmp->Mark2Coverage, memory );
+
+ Fail3:
+ Free_Coverage( &mmp->Mark1Coverage, memory );
+ return error;
+ }
+
+
+ void Free_MarkMarkPos( TTO_MarkMarkPos* mmp,
+ FT_Memory memory)
+ {
+ Free_Mark2Array( &mmp->Mark2Array, mmp->ClassCount, memory );
+ Free_MarkArray( &mmp->Mark1Array, memory );
+ Free_Coverage( &mmp->Mark2Coverage, memory );
+ Free_Coverage( &mmp->Mark1Coverage, memory );
+ }
+
+
+ static FT_Error Lookup_MarkMarkPos( GPOS_Instance* gpi,
+ TTO_MarkMarkPos* mmp,
+ TTO_GSUB_String* in,
+ TTO_GPOS_Data* out,
+ FT_UShort flags,
+ FT_UShort context_length )
+ {
+ FT_UShort j, mark1_index, mark2_index, property, class;
+ FT_Pos x_mark1_value, y_mark1_value,
+ x_mark2_value, y_mark2_value;
+ FT_Error error;
+ TTO_GPOSHeader* gpos = gpi->gpos;
+
+ TTO_MarkArray* ma1;
+ TTO_Mark2Array* ma2;
+ TTO_Mark2Record* m2r;
+ TTO_Anchor* mark1_anchor;
+ TTO_Anchor* mark2_anchor;
+
+ TTO_GPOS_Data* o;
+
+
+ if ( context_length != 0xFFFF && context_length < 1 )
+ return TTO_Err_Not_Covered;
+
+ if ( flags & IGNORE_MARKS )
+ return TTO_Err_Not_Covered;
+
+ if ( CHECK_Property( gpos->gdef, in->string[in->pos],
+ flags, &property ) )
+ return error;
+
+ error = Coverage_Index( &mmp->Mark1Coverage, in->string[in->pos],
+ &mark1_index );
+ if ( error )
+ return error;
+
+ /* now we check the preceding glyph whether it is a suitable
+ mark glyph */
+
+ if ( in->pos == 0 )
+ return TTO_Err_Not_Covered;
+
+ j = in->pos - 1;
+ error = TT_GDEF_Get_Glyph_Property( gpos->gdef, in->string[j],
+ &property );
+ if ( error )
+ return error;
+
+ if ( flags & IGNORE_SPECIAL_MARKS )
+ {
+ if ( property != (flags & 0xFF00) )
+ return TTO_Err_Not_Covered;
+ }
+ else
+ {
+ if ( property != TTO_MARK )
+ return TTO_Err_Not_Covered;
+ }
+
+ error = Coverage_Index( &mmp->Mark2Coverage, in->string[j],
+ &mark2_index );
+ if ( error )
+ return error;
+
+ ma1 = &mmp->Mark1Array;
+
+ if ( mark1_index >= ma1->MarkCount )
+ return TTO_Err_Invalid_GPOS_SubTable;
+
+ class = ma1->MarkRecord[mark1_index].Class;
+ mark1_anchor = &ma1->MarkRecord[mark1_index].MarkAnchor;
+
+ if ( class >= mmp->ClassCount )
+ return TTO_Err_Invalid_GPOS_SubTable;
+
+ ma2 = &mmp->Mark2Array;
+
+ if ( mark2_index >= ma2->Mark2Count )
+ return TTO_Err_Invalid_GPOS_SubTable;
+
+ m2r = &ma2->Mark2Record[mark2_index];
+ mark2_anchor = &m2r->Mark2Anchor[class];
+
+ error = Get_Anchor( gpi, mark1_anchor, in->string[in->pos],
+ &x_mark1_value, &y_mark1_value );
+ if ( error )
+ return error;
+ error = Get_Anchor( gpi, mark2_anchor, in->string[j],
+ &x_mark2_value, &y_mark2_value );
+ if ( error )
+ return error;
+
+ /* anchor points are not cumulative */
+
+ o = &out[in->pos];
+
+ o->x_pos = x_mark2_value - x_mark1_value;
+ o->y_pos = y_mark2_value - y_mark1_value;
+ o->x_advance = 0;
+ o->y_advance = 0;
+ o->back = 1;
+
+ (in->pos)++;
+
+ return TT_Err_Ok;
+ }
+
+
+ /* Do the actual positioning for a context positioning (either format
+ 7 or 8). This is only called after we've determined that the stream
+ matches the subrule. */
+
+ static FT_Error Do_ContextPos( GPOS_Instance* gpi,
+ FT_UShort GlyphCount,
+ FT_UShort PosCount,
+ TTO_PosLookupRecord* pos,
+ TTO_GSUB_String* in,
+ TTO_GPOS_Data* out,
+ int nesting_level )
+ {
+ FT_Error error;
+ FT_UShort i, old_pos;
+
+
+ i = 0;
+
+ while ( i < GlyphCount )
+ {
+ if ( PosCount && i == pos->SequenceIndex )
+ {
+ old_pos = in->pos;
+
+ /* Do a positioning */
+
+ error = gpos_Do_Glyph_Lookup( gpi, pos->LookupListIndex, in, out,
+ GlyphCount, nesting_level );
+
+ if ( error )
+ return error;
+
+ pos++;
+ PosCount--;
+ i += in->pos - old_pos;
+ }
+ else
+ {
+ i++;
+ (in->pos)++;
+ }
+ }
+
+ return TT_Err_Ok;
+ }
+
+
+ /* LookupType 7 */
+
+ /* PosRule */
+
+ static FT_Error Load_PosRule( TTO_PosRule* pr,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, count;
+ FT_UShort* i;
+
+ TTO_PosLookupRecord* plr;
+
+
+ if ( ACCESS_Frame( 4L ) )
+ return error;
+
+ pr->GlyphCount = GET_UShort();
+ pr->PosCount = GET_UShort();
+
+ FORGET_Frame();
+
+ pr->Input = NULL;
+
+ count = pr->GlyphCount - 1; /* only GlyphCount - 1 elements */
+
+ if ( ALLOC_ARRAY( pr->Input, count, FT_UShort ) )
+ return error;
+
+ i = pr->Input;
+
+ if ( ACCESS_Frame( count * 2L ) )
+ goto Fail2;
+
+ for ( n = 0; n < count; n++ )
+ i[n] = GET_UShort();
+
+ FORGET_Frame();
+
+ pr->PosLookupRecord = NULL;
+
+ count = pr->PosCount;
+
+ if ( ALLOC_ARRAY( pr->PosLookupRecord, count, TTO_PosLookupRecord ) )
+ goto Fail2;
+
+ plr = pr->PosLookupRecord;
+
+ if ( ACCESS_Frame( count * 4L ) )
+ goto Fail1;
+
+ for ( n = 0; n < count; n++ )
+ {
+ plr[n].SequenceIndex = GET_UShort();
+ plr[n].LookupListIndex = GET_UShort();
+ }
+
+ FORGET_Frame();
+
+ return TT_Err_Ok;
+
+ Fail1:
+ FREE( plr );
+
+ Fail2:
+ FREE( i );
+ return error;
+ }
+
+
+ static void Free_PosRule( TTO_PosRule* pr,
+ FT_Memory memory )
+ {
+ FREE( pr->PosLookupRecord );
+ FREE( pr->Input );
+ }
+
+
+ /* PosRuleSet */
+
+ static FT_Error Load_PosRuleSet( TTO_PosRuleSet* prs,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, m, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_PosRule* pr;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ count = prs->PosRuleCount = GET_UShort();
+
+ FORGET_Frame();
+
+ prs->PosRule = NULL;
+
+ if ( ALLOC_ARRAY( prs->PosRule, count, TTO_PosRule ) )
+ return error;
+
+ pr = prs->PosRule;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_PosRule( &pr[n], stream ) ) != TT_Err_Ok )
+ goto Fail;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ return TT_Err_Ok;
+
+ Fail:
+ for ( m = 0; m < n; m++ )
+ Free_PosRule( &pr[m], memory );
+
+ FREE( pr );
+ return error;
+ }
+
+
+ static void Free_PosRuleSet( TTO_PosRuleSet* prs,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_PosRule* pr;
+
+
+ if ( prs->PosRule )
+ {
+ count = prs->PosRuleCount;
+ pr = prs->PosRule;
+
+ for ( n = 0; n < count; n++ )
+ Free_PosRule( &pr[n], memory );
+
+ FREE( pr );
+ }
+ }
+
+
+ /* ContextPosFormat1 */
+
+ static FT_Error Load_ContextPos1( TTO_ContextPosFormat1* cpf1,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, m, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_PosRuleSet* prs;
+
+
+ base_offset = FILE_Pos() - 2L;
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Coverage( &cpf1->Coverage, stream ) ) != TT_Err_Ok )
+ return error;
+ (void)FILE_Seek( cur_offset );
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail2;
+
+ count = cpf1->PosRuleSetCount = GET_UShort();
+
+ FORGET_Frame();
+
+ cpf1->PosRuleSet = NULL;
+
+ if ( ALLOC_ARRAY( cpf1->PosRuleSet, count, TTO_PosRuleSet ) )
+ goto Fail2;
+
+ prs = cpf1->PosRuleSet;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail1;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_PosRuleSet( &prs[n], stream ) ) != TT_Err_Ok )
+ goto Fail1;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ return TT_Err_Ok;
+
+ Fail1:
+ for ( m = 0; m < n; m++ )
+ Free_PosRuleSet( &prs[m], memory );
+
+ FREE( prs );
+
+ Fail2:
+ Free_Coverage( &cpf1->Coverage, memory );
+ return error;
+ }
+
+
+ static void gpos_Free_Context1( TTO_ContextPosFormat1* cpf1,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_PosRuleSet* prs;
+
+
+ if ( cpf1->PosRuleSet )
+ {
+ count = cpf1->PosRuleSetCount;
+ prs = cpf1->PosRuleSet;
+
+ for ( n = 0; n < count; n++ )
+ Free_PosRuleSet( &prs[n], memory );
+
+ FREE( prs );
+ }
+
+ Free_Coverage( &cpf1->Coverage, memory );
+ }
+
+
+ /* PosClassRule */
+
+ static FT_Error Load_PosClassRule( TTO_ContextPosFormat2* cpf2,
+ TTO_PosClassRule* pcr,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, count;
+
+ FT_UShort* c;
+ TTO_PosLookupRecord* plr;
+ FT_Bool* d;
+
+
+ if ( ACCESS_Frame( 4L ) )
+ return error;
+
+ pcr->GlyphCount = GET_UShort();
+ pcr->PosCount = GET_UShort();
+
+ FORGET_Frame();
+
+ if ( pcr->GlyphCount > cpf2->MaxContextLength )
+ cpf2->MaxContextLength = pcr->GlyphCount;
+
+ pcr->Class = NULL;
+
+ count = pcr->GlyphCount - 1; /* only GlyphCount - 1 elements */
+
+ if ( ALLOC_ARRAY( pcr->Class, count, FT_UShort ) )
+ return error;
+
+ c = pcr->Class;
+ d = cpf2->ClassDef.Defined;
+
+ if ( ACCESS_Frame( count * 2L ) )
+ goto Fail2;
+
+ for ( n = 0; n < count; n++ )
+ {
+ c[n] = GET_UShort();
+
+ /* We check whether the specific class is used at all. If not,
+ class 0 is used instead. */
+
+ if ( !d[c[n]] )
+ c[n] = 0;
+ }
+
+ FORGET_Frame();
+
+ pcr->PosLookupRecord = NULL;
+
+ count = pcr->PosCount;
+
+ if ( ALLOC_ARRAY( pcr->PosLookupRecord, count, TTO_PosLookupRecord ) )
+ goto Fail2;
+
+ plr = pcr->PosLookupRecord;
+
+ if ( ACCESS_Frame( count * 4L ) )
+ goto Fail1;
+
+ for ( n = 0; n < count; n++ )
+ {
+ plr[n].SequenceIndex = GET_UShort();
+ plr[n].LookupListIndex = GET_UShort();
+ }
+
+ FORGET_Frame();
+
+ return TT_Err_Ok;
+
+ Fail1:
+ FREE( plr );
+
+ Fail2:
+ FREE( c );
+ return error;
+ }
+
+
+ static void Free_PosClassRule( TTO_PosClassRule* pcr,
+ FT_Memory memory )
+ {
+ FREE( pcr->PosLookupRecord );
+ FREE( pcr->Class );
+ }
+
+
+ /* PosClassSet */
+
+ static FT_Error Load_PosClassSet( TTO_ContextPosFormat2* cpf2,
+ TTO_PosClassSet* pcs,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, m, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_PosClassRule* pcr;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ count = pcs->PosClassRuleCount = GET_UShort();
+
+ FORGET_Frame();
+
+ pcs->PosClassRule = NULL;
+
+ if ( ALLOC_ARRAY( pcs->PosClassRule, count, TTO_PosClassRule ) )
+ return error;
+
+ pcr = pcs->PosClassRule;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_PosClassRule( cpf2, &pcr[n],
+ stream ) ) != TT_Err_Ok )
+ goto Fail;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ return TT_Err_Ok;
+
+ Fail:
+ for ( m = 0; m < n; m++ )
+ Free_PosClassRule( &pcr[m], memory );
+
+ FREE( pcr );
+ return error;
+ }
+
+
+ static void Free_PosClassSet( TTO_PosClassSet* pcs,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_PosClassRule* pcr;
+
+
+ if ( pcs->PosClassRule )
+ {
+ count = pcs->PosClassRuleCount;
+ pcr = pcs->PosClassRule;
+
+ for ( n = 0; n < count; n++ )
+ Free_PosClassRule( &pcr[n], memory );
+
+ FREE( pcr );
+ }
+ }
+
+
+ /* ContextPosFormat2 */
+
+ static FT_Error Load_ContextPos2( TTO_ContextPosFormat2* cpf2,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, m, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_PosClassSet* pcs;
+
+
+ base_offset = FILE_Pos() - 2;
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Coverage( &cpf2->Coverage, stream ) ) != TT_Err_Ok )
+ return error;
+ (void)FILE_Seek( cur_offset );
+
+ if ( ACCESS_Frame( 4L ) )
+ goto Fail3;
+
+ new_offset = GET_UShort() + base_offset;
+
+ /* `PosClassSetCount' is the upper limit for class values, thus we
+ read it now to make an additional safety check. */
+
+ count = cpf2->PosClassSetCount = GET_UShort();
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_ClassDefinition( &cpf2->ClassDef, count,
+ stream ) ) != TT_Err_Ok )
+ goto Fail3;
+ (void)FILE_Seek( cur_offset );
+
+ cpf2->PosClassSet = NULL;
+ cpf2->MaxContextLength = 0;
+
+ if ( ALLOC_ARRAY( cpf2->PosClassSet, count, TTO_PosClassSet ) )
+ goto Fail2;
+
+ pcs = cpf2->PosClassSet;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail1;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ if ( new_offset != base_offset ) /* not a NULL offset */
+ {
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_PosClassSet( cpf2, &pcs[n],
+ stream ) ) != TT_Err_Ok )
+ goto Fail1;
+ (void)FILE_Seek( cur_offset );
+ }
+ else
+ {
+ /* we create a PosClassSet table with no entries */
+
+ cpf2->PosClassSet[n].PosClassRuleCount = 0;
+ cpf2->PosClassSet[n].PosClassRule = NULL;
+ }
+ }
+
+ return TT_Err_Ok;
+
+ Fail1:
+ for ( m = 0; m < n; n++ )
+ Free_PosClassSet( &pcs[m], memory );
+
+ FREE( pcs );
+
+ Fail2:
+ Free_ClassDefinition( &cpf2->ClassDef, memory );
+
+ Fail3:
+ Free_Coverage( &cpf2->Coverage, memory );
+ return error;
+ }
+
+
+ static void gpos_Free_Context2( TTO_ContextPosFormat2* cpf2,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_PosClassSet* pcs;
+
+
+ if ( cpf2->PosClassSet )
+ {
+ count = cpf2->PosClassSetCount;
+ pcs = cpf2->PosClassSet;
+
+ for ( n = 0; n < count; n++ )
+ Free_PosClassSet( &pcs[n], memory );
+
+ FREE( pcs );
+ }
+
+ Free_ClassDefinition( &cpf2->ClassDef, memory );
+ Free_Coverage( &cpf2->Coverage, memory );
+ }
+
+
+ /* ContextPosFormat3 */
+
+ static FT_Error Load_ContextPos3( TTO_ContextPosFormat3* cpf3,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_Coverage* c;
+ TTO_PosLookupRecord* plr;
+
+
+ base_offset = FILE_Pos() - 2L;
+
+ if ( ACCESS_Frame( 4L ) )
+ return error;
+
+ cpf3->GlyphCount = GET_UShort();
+ cpf3->PosCount = GET_UShort();
+
+ FORGET_Frame();
+
+ cpf3->Coverage = NULL;
+
+ count = cpf3->GlyphCount;
+
+ if ( ALLOC_ARRAY( cpf3->Coverage, count, TTO_Coverage ) )
+ return error;
+
+ c = cpf3->Coverage;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail2;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Coverage( &c[n], stream ) ) != TT_Err_Ok )
+ goto Fail2;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ cpf3->PosLookupRecord = NULL;
+
+ count = cpf3->PosCount;
+
+ if ( ALLOC_ARRAY( cpf3->PosLookupRecord, count, TTO_PosLookupRecord ) )
+ goto Fail2;
+
+ plr = cpf3->PosLookupRecord;
+
+ if ( ACCESS_Frame( count * 4L ) )
+ goto Fail1;
+
+ for ( n = 0; n < count; n++ )
+ {
+ plr[n].SequenceIndex = GET_UShort();
+ plr[n].LookupListIndex = GET_UShort();
+ }
+
+ FORGET_Frame();
+
+ return TT_Err_Ok;
+
+ Fail1:
+ FREE( plr );
+
+ Fail2:
+ for ( n = 0; n < count; n++ )
+ Free_Coverage( &c[n], memory );
+
+ FREE( c );
+ return error;
+ }
+
+
+ static void gpos_Free_Context3( TTO_ContextPosFormat3* cpf3,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_Coverage* c;
+
+
+ FREE( cpf3->PosLookupRecord );
+
+ if ( cpf3->Coverage )
+ {
+ count = cpf3->GlyphCount;
+ c = cpf3->Coverage;
+
+ for ( n = 0; n < count; n++ )
+ Free_Coverage( &c[n], memory );
+
+ FREE( c );
+ }
+ }
+
+
+ /* ContextPos */
+
+ FT_Error Load_ContextPos( TTO_ContextPos* cp,
+ FT_Stream stream )
+ {
+ FT_Error error;
+
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ cp->PosFormat = GET_UShort();
+
+ FORGET_Frame();
+
+ switch ( cp->PosFormat )
+ {
+ case 1:
+ return Load_ContextPos1( &cp->cpf.cpf1, stream );
+
+ case 2:
+ return Load_ContextPos2( &cp->cpf.cpf2, stream );
+
+ case 3:
+ return Load_ContextPos3( &cp->cpf.cpf3, stream );
+
+ default:
+ return TTO_Err_Invalid_GPOS_SubTable_Format;
+ }
+
+ return TT_Err_Ok; /* never reached */
+ }
+
+
+ void Free_ContextPos( TTO_ContextPos* cp,
+ FT_Memory memory )
+ {
+ switch ( cp->PosFormat )
+ {
+ case 1:
+ gpos_Free_Context1( &cp->cpf.cpf1, memory );
+ break;
+
+ case 2:
+ gpos_Free_Context2( &cp->cpf.cpf2, memory );
+ break;
+
+ case 3:
+ gpos_Free_Context3( &cp->cpf.cpf3, memory );
+ break;
+ }
+ }
+
+
+ static FT_Error Lookup_ContextPos1( GPOS_Instance* gpi,
+ TTO_ContextPosFormat1* cpf1,
+ TTO_GSUB_String* in,
+ TTO_GPOS_Data* out,
+ FT_UShort flags,
+ FT_UShort context_length,
+ int nesting_level )
+ {
+ FT_UShort index, property;
+ FT_UShort i, j, k, numpr;
+ FT_Error error;
+ FT_UShort* s_in;
+ TTO_GPOSHeader* gpos = gpi->gpos;
+
+ TTO_PosRule* pr;
+ TTO_GDEFHeader* gdef;
+
+
+ gdef = gpos->gdef;
+
+ if ( CHECK_Property( gdef, in->string[in->pos], flags, &property ) )
+ return error;
+
+ error = Coverage_Index( &cpf1->Coverage, in->string[in->pos], &index );
+ if ( error )
+ return error;
+
+ pr = cpf1->PosRuleSet[index].PosRule;
+ numpr = cpf1->PosRuleSet[index].PosRuleCount;
+
+ for ( k = 0; k < numpr; k++ )
+ {
+ if ( context_length != 0xFFFF && context_length < pr[k].GlyphCount )
+ continue;
+
+ if ( in->pos + pr[k].GlyphCount > in->length )
+ continue; /* context is too long */
+
+ s_in = &in->string[in->pos];
+
+ for ( i = 1, j = 1; i < pr[k].GlyphCount; i++, j++ )
+ {
+ while ( CHECK_Property( gdef, s_in[j], flags, &property ) )
+ {
+ if ( error && error != TTO_Err_Not_Covered )
+ return error;
+
+ if ( in->pos + j < in->length )
+ j++;
+ else
+ break;
+ }
+
+ if ( s_in[j] != pr[k].Input[i - 1] )
+ break;
+ }
+
+ if ( i == pr[k].GlyphCount )
+ return Do_ContextPos( gpi, pr[k].GlyphCount,
+ pr[k].PosCount, pr[k].PosLookupRecord,
+ in, out,
+ nesting_level );
+ }
+
+ return TTO_Err_Not_Covered;
+ }
+
+
+ static FT_Error Lookup_ContextPos2( GPOS_Instance* gpi,
+ TTO_ContextPosFormat2* cpf2,
+ TTO_GSUB_String* in,
+ TTO_GPOS_Data* out,
+ FT_UShort flags,
+ FT_UShort context_length,
+ int nesting_level )
+ {
+ FT_UShort index, property;
+ FT_Error error;
+ FT_Memory memory = gpi->face->memory;
+ FT_UShort i, j, k, known_classes;
+
+ FT_UShort* classes;
+ FT_UShort* s_in;
+ FT_UShort* cl;
+ TTO_GPOSHeader* gpos = gpi->gpos;
+
+ TTO_PosClassSet* pcs;
+ TTO_PosClassRule* pr;
+ TTO_GDEFHeader* gdef;
+
+
+ gdef = gpos->gdef;
+
+ if ( CHECK_Property( gdef, in->string[in->pos], flags, &property ) )
+ return error;
+
+ /* Note: The coverage table in format 2 doesn't give an index into
+ anything. It just lets us know whether or not we need to
+ do any lookup at all. */
+
+ error = Coverage_Index( &cpf2->Coverage, in->string[in->pos], &index );
+ if ( error )
+ return error;
+
+ if ( ALLOC_ARRAY( classes, cpf2->MaxContextLength, FT_UShort ) )
+ return error;
+
+ error = Get_Class( &cpf2->ClassDef, in->string[in->pos],
+ &classes[0], NULL );
+ if ( error && error != TTO_Err_Not_Covered )
+ goto End;
+ known_classes = 0;
+
+ pcs = &cpf2->PosClassSet[classes[0]];
+ if ( !pcs )
+ {
+ error = TTO_Err_Invalid_GPOS_SubTable;
+ goto End;
+ }
+
+ for ( k = 0; k < pcs->PosClassRuleCount; k++ )
+ {
+ pr = &pcs->PosClassRule[k];
+
+ if ( context_length != 0xFFFF && context_length < pr->GlyphCount )
+ continue;
+
+ if ( in->pos + pr->GlyphCount > in->length )
+ continue; /* context is too long */
+
+ s_in = &in->string[in->pos];
+ cl = pr->Class;
+
+ /* Start at 1 because [0] is implied */
+
+ for ( i = 1, j = 1; i < pr->GlyphCount; i++, j++ )
+ {
+ while ( CHECK_Property( gdef, s_in[j], flags, &property ) )
+ {
+ if ( error && error != TTO_Err_Not_Covered )
+ goto End;
+
+ if ( in->pos + j < in->length )
+ j++;
+ else
+ break;
+ }
+
+ if ( i > known_classes )
+ {
+ /* Keeps us from having to do this for each rule */
+
+ error = Get_Class( &cpf2->ClassDef, s_in[j], &classes[i], NULL );
+ if ( error && error != TTO_Err_Not_Covered )
+ goto End;
+ known_classes = i;
+ }
+
+ if ( cl[i - 1] != classes[i] )
+ break;
+ }
+
+ if ( i == pr->GlyphCount )
+ {
+ error = Do_ContextPos( gpi, pr->GlyphCount,
+ pr->PosCount, pr->PosLookupRecord,
+ in, out,
+ nesting_level );
+ goto End;
+ }
+ }
+
+ error = TTO_Err_Not_Covered;
+
+ End:
+ FREE( classes );
+ return error;
+ }
+
+
+ static FT_Error Lookup_ContextPos3( GPOS_Instance* gpi,
+ TTO_ContextPosFormat3* cpf3,
+ TTO_GSUB_String* in,
+ TTO_GPOS_Data* out,
+ FT_UShort flags,
+ FT_UShort context_length,
+ int nesting_level )
+ {
+ FT_Error error;
+ FT_UShort index, i, j, property;
+ FT_UShort* s_in;
+ TTO_GPOSHeader* gpos = gpi->gpos;
+
+ TTO_Coverage* c;
+ TTO_GDEFHeader* gdef;
+
+
+ gdef = gpos->gdef;
+
+ if ( CHECK_Property( gdef, in->string[in->pos], flags, &property ) )
+ return error;
+
+ if ( context_length != 0xFFFF && context_length < cpf3->GlyphCount )
+ return TTO_Err_Not_Covered;
+
+ if ( in->pos + cpf3->GlyphCount > in->length )
+ return TTO_Err_Not_Covered; /* context is too long */
+
+ s_in = &in->string[in->pos];
+ c = cpf3->Coverage;
+
+ for ( i = 1, j = 1; i < cpf3->GlyphCount; i++, j++ )
+ {
+ while ( CHECK_Property( gdef, s_in[j], flags, &property ) )
+ {
+ if ( error && error != TTO_Err_Not_Covered )
+ return error;
+
+ if ( in->pos + j < in->length )
+ j++;
+ else
+ return TTO_Err_Not_Covered;
+ }
+
+ error = Coverage_Index( &c[i], s_in[j], &index );
+ if ( error )
+ return error;
+ }
+
+ return Do_ContextPos( gpi, cpf3->GlyphCount,
+ cpf3->PosCount, cpf3->PosLookupRecord,
+ in, out,
+ nesting_level );
+ }
+
+
+ static FT_Error Lookup_ContextPos( GPOS_Instance* gpi,
+ TTO_ContextPos* cp,
+ TTO_GSUB_String* in,
+ TTO_GPOS_Data* out,
+ FT_UShort flags,
+ FT_UShort context_length,
+ int nesting_level )
+ {
+ switch ( cp->PosFormat )
+ {
+ case 1:
+ return Lookup_ContextPos1( gpi, &cp->cpf.cpf1, in, out,
+ flags, context_length, nesting_level );
+
+ case 2:
+ return Lookup_ContextPos2( gpi, &cp->cpf.cpf2, in, out,
+ flags, context_length, nesting_level );
+
+ case 3:
+ return Lookup_ContextPos3( gpi, &cp->cpf.cpf3, in, out,
+ flags, context_length, nesting_level );
+
+ default:
+ return TTO_Err_Invalid_GPOS_SubTable_Format;
+ }
+
+ return TT_Err_Ok; /* never reached */
+ }
+
+
+ /* LookupType 8 */
+
+ /* ChainPosRule */
+
+ static FT_Error Load_ChainPosRule( TTO_ChainPosRule* cpr,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, count;
+ FT_UShort* b;
+ FT_UShort* i;
+ FT_UShort* l;
+
+ TTO_PosLookupRecord* plr;
+
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ cpr->BacktrackGlyphCount = GET_UShort();
+
+ FORGET_Frame();
+
+ cpr->Backtrack = NULL;
+
+ count = cpr->BacktrackGlyphCount;
+
+ if ( ALLOC_ARRAY( cpr->Backtrack, count, FT_UShort ) )
+ return error;
+
+ b = cpr->Backtrack;
+
+ if ( ACCESS_Frame( count * 2L ) )
+ goto Fail4;
+
+ for ( n = 0; n < count; n++ )
+ b[n] = GET_UShort();
+
+ FORGET_Frame();
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail4;
+
+ cpr->InputGlyphCount = GET_UShort();
+
+ FORGET_Frame();
+
+ cpr->Input = NULL;
+
+ count = cpr->InputGlyphCount - 1; /* only InputGlyphCount - 1 elements */
+
+ if ( ALLOC_ARRAY( cpr->Input, count, FT_UShort ) )
+ goto Fail4;
+
+ i = cpr->Input;
+
+ if ( ACCESS_Frame( count * 2L ) )
+ goto Fail3;
+
+ for ( n = 0; n < count; n++ )
+ i[n] = GET_UShort();
+
+ FORGET_Frame();
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail3;
+
+ cpr->LookaheadGlyphCount = GET_UShort();
+
+ FORGET_Frame();
+
+ cpr->Lookahead = NULL;
+
+ count = cpr->LookaheadGlyphCount;
+
+ if ( ALLOC_ARRAY( cpr->Lookahead, count, FT_UShort ) )
+ goto Fail3;
+
+ l = cpr->Lookahead;
+
+ if ( ACCESS_Frame( count * 2L ) )
+ goto Fail2;
+
+ for ( n = 0; n < count; n++ )
+ l[n] = GET_UShort();
+
+ FORGET_Frame();
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail2;
+
+ cpr->PosCount = GET_UShort();
+
+ FORGET_Frame();
+
+ cpr->PosLookupRecord = NULL;
+
+ count = cpr->PosCount;
+
+ if ( ALLOC_ARRAY( cpr->PosLookupRecord, count, TTO_PosLookupRecord ) )
+ goto Fail2;
+
+ plr = cpr->PosLookupRecord;
+
+ if ( ACCESS_Frame( count * 4L ) )
+ goto Fail1;
+
+ for ( n = 0; n < count; n++ )
+ {
+ plr[n].SequenceIndex = GET_UShort();
+ plr[n].LookupListIndex = GET_UShort();
+ }
+
+ FORGET_Frame();
+
+ return TT_Err_Ok;
+
+ Fail1:
+ FREE( plr );
+
+ Fail2:
+ FREE( l );
+
+ Fail3:
+ FREE( i );
+
+ Fail4:
+ FREE( b );
+ return error;
+ }
+
+
+ static void Free_ChainPosRule( TTO_ChainPosRule* cpr,
+ FT_Memory memory )
+ {
+ FREE( cpr->PosLookupRecord );
+ FREE( cpr->Lookahead );
+ FREE( cpr->Input );
+ FREE( cpr->Backtrack );
+ }
+
+
+ /* ChainPosRuleSet */
+
+ static FT_Error Load_ChainPosRuleSet( TTO_ChainPosRuleSet* cprs,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, m, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_ChainPosRule* cpr;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ count = cprs->ChainPosRuleCount = GET_UShort();
+
+ FORGET_Frame();
+
+ cprs->ChainPosRule = NULL;
+
+ if ( ALLOC_ARRAY( cprs->ChainPosRule, count, TTO_ChainPosRule ) )
+ return error;
+
+ cpr = cprs->ChainPosRule;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_ChainPosRule( &cpr[n], stream ) ) != TT_Err_Ok )
+ goto Fail;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ return TT_Err_Ok;
+
+ Fail:
+ for ( m = 0; m < n; m++ )
+ Free_ChainPosRule( &cpr[m], memory );
+
+ FREE( cpr );
+ return error;
+ }
+
+
+ static void Free_ChainPosRuleSet( TTO_ChainPosRuleSet* cprs,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_ChainPosRule* cpr;
+
+
+ if ( cprs->ChainPosRule )
+ {
+ count = cprs->ChainPosRuleCount;
+ cpr = cprs->ChainPosRule;
+
+ for ( n = 0; n < count; n++ )
+ Free_ChainPosRule( &cpr[n], memory );
+
+ FREE( cpr );
+ }
+ }
+
+
+ /* ChainContextPosFormat1 */
+
+ static FT_Error Load_ChainContextPos1( TTO_ChainContextPosFormat1* ccpf1,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, m, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_ChainPosRuleSet* cprs;
+
+
+ base_offset = FILE_Pos() - 2L;
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Coverage( &ccpf1->Coverage, stream ) ) != TT_Err_Ok )
+ return error;
+ (void)FILE_Seek( cur_offset );
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail2;
+
+ count = ccpf1->ChainPosRuleSetCount = GET_UShort();
+
+ FORGET_Frame();
+
+ ccpf1->ChainPosRuleSet = NULL;
+
+ if ( ALLOC_ARRAY( ccpf1->ChainPosRuleSet, count, TTO_ChainPosRuleSet ) )
+ goto Fail2;
+
+ cprs = ccpf1->ChainPosRuleSet;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail1;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_ChainPosRuleSet( &cprs[n], stream ) ) != TT_Err_Ok )
+ goto Fail1;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ return TT_Err_Ok;
+
+ Fail1:
+ for ( m = 0; m < n; m++ )
+ Free_ChainPosRuleSet( &cprs[m], memory );
+
+ FREE( cprs );
+
+ Fail2:
+ Free_Coverage( &ccpf1->Coverage, memory );
+ return error;
+ }
+
+
+ static void gpos_Free_ChainContext1( TTO_ChainContextPosFormat1* ccpf1,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_ChainPosRuleSet* cprs;
+
+
+ if ( ccpf1->ChainPosRuleSet )
+ {
+ count = ccpf1->ChainPosRuleSetCount;
+ cprs = ccpf1->ChainPosRuleSet;
+
+ for ( n = 0; n < count; n++ )
+ Free_ChainPosRuleSet( &cprs[n], memory );
+
+ FREE( cprs );
+ }
+
+ Free_Coverage( &ccpf1->Coverage, memory );
+ }
+
+
+ /* ChainPosClassRule */
+
+ static FT_Error Load_ChainPosClassRule(
+ TTO_ChainContextPosFormat2* ccpf2,
+ TTO_ChainPosClassRule* cpcr,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, count;
+
+ FT_UShort* b;
+ FT_UShort* i;
+ FT_UShort* l;
+ TTO_PosLookupRecord* plr;
+ FT_Bool* d;
+
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ cpcr->BacktrackGlyphCount = GET_UShort();
+
+ FORGET_Frame();
+
+ if ( cpcr->BacktrackGlyphCount > ccpf2->MaxBacktrackLength )
+ ccpf2->MaxBacktrackLength = cpcr->BacktrackGlyphCount;
+
+ cpcr->Backtrack = NULL;
+
+ count = cpcr->BacktrackGlyphCount;
+
+ if ( ALLOC_ARRAY( cpcr->Backtrack, count, FT_UShort ) )
+ return error;
+
+ b = cpcr->Backtrack;
+ d = ccpf2->BacktrackClassDef.Defined;
+
+ if ( ACCESS_Frame( count * 2L ) )
+ goto Fail4;
+
+ for ( n = 0; n < count; n++ )
+ {
+ b[n] = GET_UShort();
+
+ /* We check whether the specific class is used at all. If not,
+ class 0 is used instead. */
+
+ if ( !d[b[n]] )
+ b[n] = 0;
+ }
+
+ FORGET_Frame();
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail4;
+
+ cpcr->InputGlyphCount = GET_UShort();
+
+ if ( cpcr->InputGlyphCount > ccpf2->MaxInputLength )
+ ccpf2->MaxInputLength = cpcr->InputGlyphCount;
+
+ FORGET_Frame();
+
+ cpcr->Input = NULL;
+
+ count = cpcr->InputGlyphCount - 1; /* only InputGlyphCount - 1 elements */
+
+ if ( ALLOC_ARRAY( cpcr->Input, count, FT_UShort ) )
+ goto Fail4;
+
+ i = cpcr->Input;
+ d = ccpf2->InputClassDef.Defined;
+
+ if ( ACCESS_Frame( count * 2L ) )
+ goto Fail3;
+
+ for ( n = 0; n < count; n++ )
+ {
+ i[n] = GET_UShort();
+
+ if ( !d[i[n]] )
+ i[n] = 0;
+ }
+
+ FORGET_Frame();
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail3;
+
+ cpcr->LookaheadGlyphCount = GET_UShort();
+
+ FORGET_Frame();
+
+ if ( cpcr->LookaheadGlyphCount > ccpf2->MaxLookaheadLength )
+ ccpf2->MaxLookaheadLength = cpcr->LookaheadGlyphCount;
+
+ cpcr->Lookahead = NULL;
+
+ count = cpcr->LookaheadGlyphCount;
+
+ if ( ALLOC_ARRAY( cpcr->Lookahead, count, FT_UShort ) )
+ goto Fail3;
+
+ l = cpcr->Lookahead;
+ d = ccpf2->LookaheadClassDef.Defined;
+
+ if ( ACCESS_Frame( count * 2L ) )
+ goto Fail2;
+
+ for ( n = 0; n < count; n++ )
+ {
+ l[n] = GET_UShort();
+
+ if ( !d[l[n]] )
+ l[n] = 0;
+ }
+
+ FORGET_Frame();
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail2;
+
+ cpcr->PosCount = GET_UShort();
+
+ FORGET_Frame();
+
+ cpcr->PosLookupRecord = NULL;
+
+ count = cpcr->PosCount;
+
+ if ( ALLOC_ARRAY( cpcr->PosLookupRecord, count, TTO_PosLookupRecord ) )
+ goto Fail2;
+
+ plr = cpcr->PosLookupRecord;
+
+ if ( ACCESS_Frame( count * 4L ) )
+ goto Fail1;
+
+ for ( n = 0; n < count; n++ )
+ {
+ plr[n].SequenceIndex = GET_UShort();
+ plr[n].LookupListIndex = GET_UShort();
+ }
+
+ FORGET_Frame();
+
+ return TT_Err_Ok;
+
+ Fail1:
+ FREE( plr );
+
+ Fail2:
+ FREE( l );
+
+ Fail3:
+ FREE( i );
+
+ Fail4:
+ FREE( b );
+ return error;
+ }
+
+
+ static void Free_ChainPosClassRule( TTO_ChainPosClassRule* cpcr,
+ FT_Memory memory )
+ {
+ FREE( cpcr->PosLookupRecord );
+ FREE( cpcr->Lookahead );
+ FREE( cpcr->Input );
+ FREE( cpcr->Backtrack );
+ }
+
+
+ /* PosClassSet */
+
+ static FT_Error Load_ChainPosClassSet(
+ TTO_ChainContextPosFormat2* ccpf2,
+ TTO_ChainPosClassSet* cpcs,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, m, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_ChainPosClassRule* cpcr;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ count = cpcs->ChainPosClassRuleCount = GET_UShort();
+
+ FORGET_Frame();
+
+ cpcs->ChainPosClassRule = NULL;
+
+ if ( ALLOC_ARRAY( cpcs->ChainPosClassRule, count,
+ TTO_ChainPosClassRule ) )
+ return error;
+
+ cpcr = cpcs->ChainPosClassRule;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_ChainPosClassRule( ccpf2, &cpcr[n],
+ stream ) ) != TT_Err_Ok )
+ goto Fail;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ return TT_Err_Ok;
+
+ Fail:
+ for ( m = 0; m < n; m++ )
+ Free_ChainPosClassRule( &cpcr[m], memory );
+
+ FREE( cpcr );
+ return error;
+ }
+
+
+ static void Free_ChainPosClassSet( TTO_ChainPosClassSet* cpcs,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_ChainPosClassRule* cpcr;
+
+
+ if ( cpcs->ChainPosClassRule )
+ {
+ count = cpcs->ChainPosClassRuleCount;
+ cpcr = cpcs->ChainPosClassRule;
+
+ for ( n = 0; n < count; n++ )
+ Free_ChainPosClassRule( &cpcr[n], memory );
+
+ FREE( cpcr );
+ }
+ }
+
+
+ static FT_Error gpos_Load_EmptyOrClassDefinition( TTO_ClassDefinition* cd,
+ FT_UShort limit,
+ FT_ULong class_offset,
+ FT_ULong base_offset,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_ULong cur_offset;
+
+ cur_offset = FILE_Pos();
+
+ if ( class_offset )
+ {
+ if ( !FILE_Seek( class_offset + base_offset ) )
+ error = Load_ClassDefinition( cd, limit, stream );
+ }
+ else
+ error = Load_EmptyClassDefinition ( cd, stream );
+
+ if (error == TT_Err_Ok)
+ (void)FILE_Seek( cur_offset ); /* Changes error as a side-effect */
+
+ return error;
+ }
+
+ /* ChainContextPosFormat2 */
+
+ static FT_Error Load_ChainContextPos2( TTO_ChainContextPosFormat2* ccpf2,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, m, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+ FT_ULong backtrack_offset, input_offset, lookahead_offset;
+
+ TTO_ChainPosClassSet* cpcs;
+
+
+ base_offset = FILE_Pos() - 2;
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Coverage( &ccpf2->Coverage, stream ) ) != TT_Err_Ok )
+ return error;
+ (void)FILE_Seek( cur_offset );
+
+ if ( ACCESS_Frame( 8L ) )
+ goto Fail5;
+
+ backtrack_offset = GET_UShort();
+ input_offset = GET_UShort();
+ lookahead_offset = GET_UShort();
+
+ /* `ChainPosClassSetCount' is the upper limit for input class values,
+ thus we read it now to make an additional safety check. No limit
+ is known or needed for the other two class definitions */
+
+ count = ccpf2->ChainPosClassSetCount = GET_UShort();
+
+ FORGET_Frame();
+
+ if ( ( error = gpos_Load_EmptyOrClassDefinition( &ccpf2->BacktrackClassDef, 65535,
+ backtrack_offset, base_offset,
+ stream ) ) != TT_Err_Ok )
+ goto Fail5;
+ if ( ( error = gpos_Load_EmptyOrClassDefinition( &ccpf2->InputClassDef, count,
+ input_offset, base_offset,
+ stream ) ) != TT_Err_Ok )
+ goto Fail4;
+ if ( ( error = gpos_Load_EmptyOrClassDefinition( &ccpf2->LookaheadClassDef, 65535,
+ lookahead_offset, base_offset,
+ stream ) ) != TT_Err_Ok )
+ goto Fail3;
+
+ ccpf2->ChainPosClassSet = NULL;
+ ccpf2->MaxBacktrackLength = 0;
+ ccpf2->MaxInputLength = 0;
+ ccpf2->MaxLookaheadLength = 0;
+
+ if ( ALLOC_ARRAY( ccpf2->ChainPosClassSet, count, TTO_ChainPosClassSet ) )
+ goto Fail2;
+
+ cpcs = ccpf2->ChainPosClassSet;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail1;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ if ( new_offset != base_offset ) /* not a NULL offset */
+ {
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_ChainPosClassSet( ccpf2, &cpcs[n],
+ stream ) ) != TT_Err_Ok )
+ goto Fail1;
+ (void)FILE_Seek( cur_offset );
+ }
+ else
+ {
+ /* we create a ChainPosClassSet table with no entries */
+
+ ccpf2->ChainPosClassSet[n].ChainPosClassRuleCount = 0;
+ ccpf2->ChainPosClassSet[n].ChainPosClassRule = NULL;
+ }
+ }
+
+ return TT_Err_Ok;
+
+ Fail1:
+ for ( m = 0; m < n; m++ )
+ Free_ChainPosClassSet( &cpcs[m], memory );
+
+ FREE( cpcs );
+
+ Fail2:
+ Free_ClassDefinition( &ccpf2->LookaheadClassDef, memory );
+
+ Fail3:
+ Free_ClassDefinition( &ccpf2->InputClassDef, memory );
+
+ Fail4:
+ Free_ClassDefinition( &ccpf2->BacktrackClassDef, memory );
+
+ Fail5:
+ Free_Coverage( &ccpf2->Coverage, memory );
+ return error;
+ }
+
+
+ static void gpos_Free_ChainContext2( TTO_ChainContextPosFormat2* ccpf2,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_ChainPosClassSet* cpcs;
+
+
+ if ( ccpf2->ChainPosClassSet )
+ {
+ count = ccpf2->ChainPosClassSetCount;
+ cpcs = ccpf2->ChainPosClassSet;
+
+ for ( n = 0; n < count; n++ )
+ Free_ChainPosClassSet( &cpcs[n], memory );
+
+ FREE( cpcs );
+ }
+
+ Free_ClassDefinition( &ccpf2->LookaheadClassDef, memory );
+ Free_ClassDefinition( &ccpf2->InputClassDef, memory );
+ Free_ClassDefinition( &ccpf2->BacktrackClassDef, memory );
+
+ Free_Coverage( &ccpf2->Coverage, memory );
+ }
+
+
+ /* ChainContextPosFormat3 */
+
+ static FT_Error Load_ChainContextPos3( TTO_ChainContextPosFormat3* ccpf3,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, nb, ni, nl, m, count;
+ FT_UShort backtrack_count, input_count, lookahead_count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_Coverage* b;
+ TTO_Coverage* i;
+ TTO_Coverage* l;
+ TTO_PosLookupRecord* plr;
+
+
+ base_offset = FILE_Pos() - 2L;
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ ccpf3->BacktrackGlyphCount = GET_UShort();
+
+ FORGET_Frame();
+
+ ccpf3->BacktrackCoverage = NULL;
+
+ backtrack_count = ccpf3->BacktrackGlyphCount;
+
+ if ( ALLOC_ARRAY( ccpf3->BacktrackCoverage, backtrack_count,
+ TTO_Coverage ) )
+ return error;
+
+ b = ccpf3->BacktrackCoverage;
+
+ for ( nb = 0; nb < backtrack_count; nb++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail4;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Coverage( &b[nb], stream ) ) != TT_Err_Ok )
+ goto Fail4;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail4;
+
+ ccpf3->InputGlyphCount = GET_UShort();
+
+ FORGET_Frame();
+
+ ccpf3->InputCoverage = NULL;
+
+ input_count = ccpf3->InputGlyphCount;
+
+ if ( ALLOC_ARRAY( ccpf3->InputCoverage, input_count, TTO_Coverage ) )
+ goto Fail4;
+
+ i = ccpf3->InputCoverage;
+
+ for ( ni = 0; ni < input_count; ni++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail3;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Coverage( &i[ni], stream ) ) != TT_Err_Ok )
+ goto Fail3;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail3;
+
+ ccpf3->LookaheadGlyphCount = GET_UShort();
+
+ FORGET_Frame();
+
+ ccpf3->LookaheadCoverage = NULL;
+
+ lookahead_count = ccpf3->LookaheadGlyphCount;
+
+ if ( ALLOC_ARRAY( ccpf3->LookaheadCoverage, lookahead_count,
+ TTO_Coverage ) )
+ goto Fail3;
+
+ l = ccpf3->LookaheadCoverage;
+
+ for ( nl = 0; nl < lookahead_count; nl++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail2;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Coverage( &l[nl], stream ) ) != TT_Err_Ok )
+ goto Fail2;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail2;
+
+ ccpf3->PosCount = GET_UShort();
+
+ FORGET_Frame();
+
+ ccpf3->PosLookupRecord = NULL;
+
+ count = ccpf3->PosCount;
+
+ if ( ALLOC_ARRAY( ccpf3->PosLookupRecord, count, TTO_PosLookupRecord ) )
+ goto Fail2;
+
+ plr = ccpf3->PosLookupRecord;
+
+ if ( ACCESS_Frame( count * 4L ) )
+ goto Fail1;
+
+ for ( n = 0; n < count; n++ )
+ {
+ plr[n].SequenceIndex = GET_UShort();
+ plr[n].LookupListIndex = GET_UShort();
+ }
+
+ FORGET_Frame();
+
+ return TT_Err_Ok;
+
+ Fail1:
+ FREE( plr );
+
+ Fail2:
+ for ( m = 0; m < nl; nl++ )
+ Free_Coverage( &l[m], memory );
+
+ FREE( l );
+
+ Fail3:
+ for ( m = 0; m < ni; n++ )
+ Free_Coverage( &i[m], memory );
+
+ FREE( i );
+
+ Fail4:
+ for ( m = 0; m < nb; n++ )
+ Free_Coverage( &b[m], memory );
+
+ FREE( b );
+ return error;
+ }
+
+
+ static void gpos_Free_ChainContext3( TTO_ChainContextPosFormat3* ccpf3,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_Coverage* c;
+
+
+ FREE( ccpf3->PosLookupRecord );
+
+ if ( ccpf3->LookaheadCoverage )
+ {
+ count = ccpf3->LookaheadGlyphCount;
+ c = ccpf3->LookaheadCoverage;
+
+ for ( n = 0; n < count; n++ )
+ Free_Coverage( &c[n], memory );
+
+ FREE( c );
+ }
+
+ if ( ccpf3->InputCoverage )
+ {
+ count = ccpf3->InputGlyphCount;
+ c = ccpf3->InputCoverage;
+
+ for ( n = 0; n < count; n++ )
+ Free_Coverage( &c[n], memory );
+
+ FREE( c );
+ }
+
+ if ( ccpf3->BacktrackCoverage )
+ {
+ count = ccpf3->BacktrackGlyphCount;
+ c = ccpf3->BacktrackCoverage;
+
+ for ( n = 0; n < count; n++ )
+ Free_Coverage( &c[n], memory );
+
+ FREE( c );
+ }
+ }
+
+
+ /* ChainContextPos */
+
+ FT_Error Load_ChainContextPos( TTO_ChainContextPos* ccp,
+ FT_Stream stream )
+ {
+ FT_Error error;
+
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ ccp->PosFormat = GET_UShort();
+
+ FORGET_Frame();
+
+ switch ( ccp->PosFormat )
+ {
+ case 1:
+ return Load_ChainContextPos1( &ccp->ccpf.ccpf1, stream );
+
+ case 2:
+ return Load_ChainContextPos2( &ccp->ccpf.ccpf2, stream );
+
+ case 3:
+ return Load_ChainContextPos3( &ccp->ccpf.ccpf3, stream );
+
+ default:
+ return TTO_Err_Invalid_GPOS_SubTable_Format;
+ }
+
+ return TT_Err_Ok; /* never reached */
+ }
+
+
+ void Free_ChainContextPos( TTO_ChainContextPos* ccp,
+ FT_Memory memory )
+ {
+ switch ( ccp->PosFormat )
+ {
+ case 1:
+ gpos_Free_ChainContext1( &ccp->ccpf.ccpf1, memory );
+ break;
+
+ case 2:
+ gpos_Free_ChainContext2( &ccp->ccpf.ccpf2, memory );
+ break;
+
+ case 3:
+ gpos_Free_ChainContext3( &ccp->ccpf.ccpf3, memory );
+ break;
+ }
+ }
+
+
+ static FT_Error Lookup_ChainContextPos1(
+ GPOS_Instance* gpi,
+ TTO_ChainContextPosFormat1* ccpf1,
+ TTO_GSUB_String* in,
+ TTO_GPOS_Data* out,
+ FT_UShort flags,
+ FT_UShort context_length,
+ int nesting_level )
+ {
+ FT_UShort index, property;
+ FT_UShort i, j, k, num_cpr, curr_pos;
+ FT_UShort bgc, igc, lgc;
+ FT_Error error;
+ FT_UShort* s_in;
+ TTO_GPOSHeader* gpos = gpi->gpos;
+
+ TTO_ChainPosRule* cpr;
+ TTO_ChainPosRule curr_cpr;
+ TTO_GDEFHeader* gdef;
+
+
+ gdef = gpos->gdef;
+
+ if ( CHECK_Property( gdef, in->string[in->pos], flags, &property ) )
+ return error;
+
+ error = Coverage_Index( &ccpf1->Coverage, in->string[in->pos], &index );
+ if ( error )
+ return error;
+
+ cpr = ccpf1->ChainPosRuleSet[index].ChainPosRule;
+ num_cpr = ccpf1->ChainPosRuleSet[index].ChainPosRuleCount;
+
+ for ( k = 0; k < num_cpr; k++ )
+ {
+ curr_cpr = cpr[k];
+ bgc = curr_cpr.BacktrackGlyphCount;
+ igc = curr_cpr.InputGlyphCount;
+ lgc = curr_cpr.LookaheadGlyphCount;
+
+ if ( context_length != 0xFFFF && context_length < igc )
+ continue;
+
+ /* check whether context is too long; it is a first guess only */
+
+ if ( bgc > in->pos || in->pos + igc + lgc > in->length )
+ continue;
+
+ if ( bgc )
+ {
+ /* Since we don't know in advance the number of glyphs to inspect,
+ we search backwards for matches in the backtrack glyph array */
+
+ curr_pos = 0;
+ s_in = &in->string[curr_pos];
+
+ for ( i = 0, j = in->pos - 1; i < bgc; i++, j-- )
+ {
+ while ( CHECK_Property( gdef, s_in[j], flags, &property ) )
+ {
+ if ( error && error != TTO_Err_Not_Covered )
+ return error;
+
+ if ( j > curr_pos )
+ j--;
+ else
+ break;
+ }
+
+ /* In OpenType 1.3, it is undefined whether the offsets of
+ backtrack glyphs is in logical order or not. Version 1.4
+ will clarify this:
+
+ Logical order - a b c d e f g h i j
+ i
+ Input offsets - 0 1
+ Backtrack offsets - 3 2 1 0
+ Lookahead offsets - 0 1 2 3 */
+
+ if ( s_in[j] != curr_cpr.Backtrack[i] )
+ break;
+ }
+
+ if ( i != bgc )
+ continue;
+ }
+
+ curr_pos = in->pos;
+ s_in = &in->string[curr_pos];
+
+ /* Start at 1 because [0] is implied */
+
+ for ( i = 1, j = 1; i < igc; i++, j++ )
+ {
+ while ( CHECK_Property( gdef, s_in[j], flags, &property ) )
+ {
+ if ( error && error != TTO_Err_Not_Covered )
+ return error;
+
+ if ( curr_pos + j < in->length )
+ j++;
+ else
+ break;
+ }
+
+ if ( s_in[j] != curr_cpr.Input[i - 1] )
+ break;
+ }
+
+ if ( i != igc )
+ continue;
+
+ /* we are starting to check for lookahead glyphs right after the
+ last context glyph */
+
+ curr_pos += j;
+ s_in = &in->string[curr_pos];
+
+ for ( i = 0, j = 0; i < lgc; i++, j++ )
+ {
+ while ( CHECK_Property( gdef, s_in[j], flags, &property ) )
+ {
+ if ( error && error != TTO_Err_Not_Covered )
+ return error;
+
+ if ( curr_pos + j < in->length )
+ j++;
+ else
+ break;
+ }
+
+ if ( s_in[j] != curr_cpr.Lookahead[i] )
+ break;
+ }
+
+ if ( i == lgc )
+ return Do_ContextPos( gpi, igc,
+ curr_cpr.PosCount,
+ curr_cpr.PosLookupRecord,
+ in, out,
+ nesting_level );
+ }
+
+ return TTO_Err_Not_Covered;
+ }
+
+
+ static FT_Error Lookup_ChainContextPos2(
+ GPOS_Instance* gpi,
+ TTO_ChainContextPosFormat2* ccpf2,
+ TTO_GSUB_String* in,
+ TTO_GPOS_Data* out,
+ FT_UShort flags,
+ FT_UShort context_length,
+ int nesting_level )
+ {
+ FT_UShort index, property;
+ FT_Memory memory = gpi->face->memory;
+ FT_Error error;
+ FT_UShort i, j, k, curr_pos;
+ FT_UShort bgc, igc, lgc;
+ FT_UShort known_backtrack_classes,
+ known_input_classes,
+ known_lookahead_classes;
+
+ FT_UShort* backtrack_classes;
+ FT_UShort* input_classes;
+ FT_UShort* lookahead_classes;
+
+ FT_UShort* s_in;
+
+ FT_UShort* bc;
+ FT_UShort* ic;
+ FT_UShort* lc;
+ TTO_GPOSHeader* gpos = gpi->gpos;
+
+ TTO_ChainPosClassSet* cpcs;
+ TTO_ChainPosClassRule cpcr;
+ TTO_GDEFHeader* gdef;
+
+
+ gdef = gpos->gdef;
+
+ if ( CHECK_Property( gdef, in->string[in->pos], flags, &property ) )
+ return error;
+
+ /* Note: The coverage table in format 2 doesn't give an index into
+ anything. It just lets us know whether or not we need to
+ do any lookup at all. */
+
+ error = Coverage_Index( &ccpf2->Coverage, in->string[in->pos], &index );
+ if ( error )
+ return error;
+
+ if ( ALLOC_ARRAY( backtrack_classes, ccpf2->MaxBacktrackLength, FT_UShort ) )
+ return error;
+ known_backtrack_classes = 0;
+
+ if ( ALLOC_ARRAY( input_classes, ccpf2->MaxInputLength, FT_UShort ) )
+ goto End3;
+ known_input_classes = 1;
+
+ if ( ALLOC_ARRAY( lookahead_classes, ccpf2->MaxLookaheadLength, FT_UShort ) )
+ goto End2;
+ known_lookahead_classes = 0;
+
+ error = Get_Class( &ccpf2->InputClassDef, in->string[in->pos],
+ &input_classes[0], NULL );
+ if ( error && error != TTO_Err_Not_Covered )
+ goto End1;
+
+ cpcs = &ccpf2->ChainPosClassSet[input_classes[0]];
+ if ( !cpcs )
+ {
+ error = TTO_Err_Invalid_GPOS_SubTable;
+ goto End1;
+ }
+
+ for ( k = 0; k < cpcs->ChainPosClassRuleCount; k++ )
+ {
+ cpcr = cpcs->ChainPosClassRule[k];
+ bgc = cpcr.BacktrackGlyphCount;
+ igc = cpcr.InputGlyphCount;
+ lgc = cpcr.LookaheadGlyphCount;
+
+ if ( context_length != 0xFFFF && context_length < igc )
+ continue;
+
+ /* check whether context is too long; it is a first guess only */
+
+ if ( bgc > in->pos || in->pos + igc + lgc > in->length )
+ continue;
+
+ if ( bgc )
+ {
+ /* Since we don't know in advance the number of glyphs to inspect,
+ we search backwards for matches in the backtrack glyph array.
+ Note that `known_backtrack_classes' starts at index 0. */
+
+ curr_pos = 0;
+ s_in = &in->string[curr_pos];
+ bc = cpcr.Backtrack;
+
+ for ( i = 0, j = in->pos - 1; i < bgc; i++, j-- )
+ {
+ while ( CHECK_Property( gdef, s_in[j], flags, &property ) )
+ {
+ if ( error && error != TTO_Err_Not_Covered )
+ goto End1;
+
+ if ( j > curr_pos )
+ j--;
+ else
+ break;
+ }
+
+ if ( i >= known_backtrack_classes )
+ {
+ /* Keeps us from having to do this for each rule */
+
+ error = Get_Class( &ccpf2->BacktrackClassDef, s_in[j],
+ &backtrack_classes[i], NULL );
+ if ( error && error != TTO_Err_Not_Covered )
+ goto End1;
+ known_backtrack_classes = i;
+ }
+
+ if ( bc[i] != backtrack_classes[i] )
+ break;
+ }
+
+ if ( i != bgc )
+ continue;
+ }
+
+ curr_pos = in->pos;
+ s_in = &in->string[curr_pos];
+ ic = cpcr.Input;
+
+ /* Start at 1 because [0] is implied */
+
+ for ( i = 1, j = 1; i < igc; i++, j++ )
+ {
+ while ( CHECK_Property( gdef, s_in[j], flags, &property ) )
+ {
+ if ( error && error != TTO_Err_Not_Covered )
+ goto End1;
+
+ if ( curr_pos + j < in->length )
+ j++;
+ else
+ break;
+ }
+
+ if ( i >= known_input_classes )
+ {
+ error = Get_Class( &ccpf2->InputClassDef, s_in[j],
+ &input_classes[i], NULL );
+ if ( error && error != TTO_Err_Not_Covered )
+ goto End1;
+ known_input_classes = i;
+ }
+
+ if ( ic[i - 1] != input_classes[i] )
+ break;
+ }
+
+ if ( i != igc )
+ continue;
+
+ /* we are starting to check for lookahead glyphs right after the
+ last context glyph */
+
+ curr_pos += j;
+ s_in = &in->string[curr_pos];
+ lc = cpcr.Lookahead;
+
+ for ( i = 0, j = 0; i < lgc; i++, j++ )
+ {
+ while ( CHECK_Property( gdef, s_in[j], flags, &property ) )
+ {
+ if ( error && error != TTO_Err_Not_Covered )
+ goto End1;
+
+ if ( curr_pos + j < in->length )
+ j++;
+ else
+ break;
+ }
+
+ if ( i >= known_lookahead_classes )
+ {
+ error = Get_Class( &ccpf2->LookaheadClassDef, s_in[j],
+ &lookahead_classes[i], NULL );
+ if ( error && error != TTO_Err_Not_Covered )
+ goto End1;
+ known_lookahead_classes = i;
+ }
+
+ if ( lc[i] != lookahead_classes[i] )
+ break;
+ }
+
+ if ( i == lgc )
+ {
+ error = Do_ContextPos( gpi, igc,
+ cpcr.PosCount,
+ cpcr.PosLookupRecord,
+ in, out,
+ nesting_level );
+ goto End1;
+ }
+ }
+
+ error = TTO_Err_Not_Covered;
+
+ End1:
+ FREE( lookahead_classes );
+
+ End2:
+ FREE( input_classes );
+
+ End3:
+ FREE( backtrack_classes );
+ return error;
+ }
+
+
+ static FT_Error Lookup_ChainContextPos3(
+ GPOS_Instance* gpi,
+ TTO_ChainContextPosFormat3* ccpf3,
+ TTO_GSUB_String* in,
+ TTO_GPOS_Data* out,
+ FT_UShort flags,
+ FT_UShort context_length,
+ int nesting_level )
+ {
+ FT_UShort index, i, j, curr_pos, property;
+ FT_UShort bgc, igc, lgc;
+ FT_Error error;
+ FT_UShort* s_in;
+ TTO_GPOSHeader* gpos = gpi->gpos;
+
+ TTO_Coverage* bc;
+ TTO_Coverage* ic;
+ TTO_Coverage* lc;
+ TTO_GDEFHeader* gdef;
+
+
+ gdef = gpos->gdef;
+
+ if ( CHECK_Property( gdef, in->string[in->pos], flags, &property ) )
+ return error;
+
+ bgc = ccpf3->BacktrackGlyphCount;
+ igc = ccpf3->InputGlyphCount;
+ lgc = ccpf3->LookaheadGlyphCount;
+
+ if ( context_length != 0xFFFF && context_length < igc )
+ return TTO_Err_Not_Covered;
+
+ /* check whether context is too long; it is a first guess only */
+
+ if ( bgc > in->pos || in->pos + igc + lgc > in->length )
+ return TTO_Err_Not_Covered;
+
+ if ( bgc )
+ {
+ /* Since we don't know in advance the number of glyphs to inspect,
+ we search backwards for matches in the backtrack glyph array */
+
+ curr_pos = 0;
+ s_in = &in->string[curr_pos];
+ bc = ccpf3->BacktrackCoverage;
+
+ for ( i = 0, j = in->pos - 1; i < bgc; i++, j-- )
+ {
+ while ( CHECK_Property( gdef, s_in[j], flags, &property ) )
+ {
+ if ( error && error != TTO_Err_Not_Covered )
+ return error;
+
+ if ( j > curr_pos )
+ j--;
+ else
+ return TTO_Err_Not_Covered;
+ }
+
+ error = Coverage_Index( &bc[i], s_in[j], &index );
+ if ( error )
+ return error;
+ }
+ }
+
+ curr_pos = in->pos;
+ s_in = &in->string[curr_pos];
+ ic = ccpf3->InputCoverage;
+
+ for ( i = 0, j = 0; i < igc; i++, j++ )
+ {
+ /* We already called CHECK_Property for s_in[0] */
+ while ( j > 0 && CHECK_Property( gdef, s_in[j], flags, &property ) )
+ {
+ if ( error && error != TTO_Err_Not_Covered )
+ return error;
+
+ if ( curr_pos + j < in->length )
+ j++;
+ else
+ return TTO_Err_Not_Covered;
+ }
+
+ error = Coverage_Index( &ic[i], s_in[j], &index );
+ if ( error )
+ return error;
+ }
+
+ /* we are starting to check for lookahead glyphs right after the
+ last context glyph */
+
+ curr_pos += j;
+ s_in = &in->string[curr_pos];
+ lc = ccpf3->LookaheadCoverage;
+
+ for ( i = 0, j = 0; i < lgc; i++, j++ )
+ {
+ while ( CHECK_Property( gdef, s_in[j], flags, &property ) )
+ {
+ if ( error && error != TTO_Err_Not_Covered )
+ return error;
+
+ if ( curr_pos + j < in->length )
+ j++;
+ else
+ return TTO_Err_Not_Covered;
+ }
+
+ error = Coverage_Index( &lc[i], s_in[j], &index );
+ if ( error )
+ return error;
+ }
+
+ return Do_ContextPos( gpi, igc,
+ ccpf3->PosCount,
+ ccpf3->PosLookupRecord,
+ in, out,
+ nesting_level );
+ }
+
+
+ static FT_Error Lookup_ChainContextPos(
+ GPOS_Instance* gpi,
+ TTO_ChainContextPos* ccp,
+ TTO_GSUB_String* in,
+ TTO_GPOS_Data* out,
+ FT_UShort flags,
+ FT_UShort context_length,
+ int nesting_level )
+ {
+ switch ( ccp->PosFormat )
+ {
+ case 1:
+ return Lookup_ChainContextPos1( gpi, &ccp->ccpf.ccpf1, in, out,
+ flags, context_length,
+ nesting_level );
+
+ case 2:
+ return Lookup_ChainContextPos2( gpi, &ccp->ccpf.ccpf2, in, out,
+ flags, context_length,
+ nesting_level );
+
+ case 3:
+ return Lookup_ChainContextPos3( gpi, &ccp->ccpf.ccpf3, in, out,
+ flags, context_length,
+ nesting_level );
+
+ default:
+ return TTO_Err_Invalid_GPOS_SubTable_Format;
+ }
+
+ return TT_Err_Ok; /* never reached */
+ }
+
+
+
+ /***********
+ * GPOS API
+ ***********/
+
+
+ EXPORT_FUNC
+ FT_Error TT_GPOS_Select_Script( TTO_GPOSHeader* gpos,
+ FT_ULong script_tag,
+ FT_UShort* script_index )
+ {
+ FT_UShort n;
+
+ TTO_ScriptList* sl;
+ TTO_ScriptRecord* sr;
+
+
+ if ( !gpos || !script_index )
+ return TT_Err_Invalid_Argument;
+
+ sl = &gpos->ScriptList;
+ sr = sl->ScriptRecord;
+
+ for ( n = 0; n < sl->ScriptCount; n++ )
+ if ( script_tag == sr[n].ScriptTag )
+ {
+ *script_index = n;
+
+ return TT_Err_Ok;
+ }
+
+ return TTO_Err_Not_Covered;
+ }
+
+
+ EXPORT_FUNC
+ FT_Error TT_GPOS_Select_Language( TTO_GPOSHeader* gpos,
+ FT_ULong language_tag,
+ FT_UShort script_index,
+ FT_UShort* language_index,
+ FT_UShort* req_feature_index )
+ {
+ FT_UShort n;
+
+ TTO_ScriptList* sl;
+ TTO_ScriptRecord* sr;
+ TTO_Script* s;
+ TTO_LangSysRecord* lsr;
+
+
+ if ( !gpos || !language_index || !req_feature_index )
+ return TT_Err_Invalid_Argument;
+
+ sl = &gpos->ScriptList;
+ sr = sl->ScriptRecord;
+
+ if ( script_index >= sl->ScriptCount )
+ return TT_Err_Invalid_Argument;
+
+ s = &sr[script_index].Script;
+ lsr = s->LangSysRecord;
+
+ for ( n = 0; n < s->LangSysCount; n++ )
+ if ( language_tag == lsr[n].LangSysTag )
+ {
+ *language_index = n;
+ *req_feature_index = lsr[n].LangSys.ReqFeatureIndex;
+
+ return TT_Err_Ok;
+ }
+
+ return TTO_Err_Not_Covered;
+ }
+
+
+ /* selecting 0xFFFF for language_index asks for the values of the
+ default language (DefaultLangSys) */
+
+ EXPORT_FUNC
+ FT_Error TT_GPOS_Select_Feature( TTO_GPOSHeader* gpos,
+ FT_ULong feature_tag,
+ FT_UShort script_index,
+ FT_UShort language_index,
+ FT_UShort* feature_index )
+ {
+ FT_UShort n;
+
+ TTO_ScriptList* sl;
+ TTO_ScriptRecord* sr;
+ TTO_Script* s;
+ TTO_LangSysRecord* lsr;
+ TTO_LangSys* ls;
+ FT_UShort* fi;
+
+ TTO_FeatureList* fl;
+ TTO_FeatureRecord* fr;
+
+
+ if ( !gpos || !feature_index )
+ return TT_Err_Invalid_Argument;
+
+ sl = &gpos->ScriptList;
+ sr = sl->ScriptRecord;
+
+ fl = &gpos->FeatureList;
+ fr = fl->FeatureRecord;
+
+ if ( script_index >= sl->ScriptCount )
+ return TT_Err_Invalid_Argument;
+
+ s = &sr[script_index].Script;
+ lsr = s->LangSysRecord;
+
+ if ( language_index == 0xFFFF )
+ ls = &s->DefaultLangSys;
+ else
+ {
+ if ( language_index >= s->LangSysCount )
+ return TT_Err_Invalid_Argument;
+
+ ls = &lsr[language_index].LangSys;
+ }
+
+ fi = ls->FeatureIndex;
+
+ for ( n = 0; n < ls->FeatureCount; n++ )
+ {
+ if ( fi[n] >= fl->FeatureCount )
+ return TTO_Err_Invalid_GPOS_SubTable_Format;
+
+ if ( feature_tag == fr[fi[n]].FeatureTag )
+ {
+ *feature_index = fi[n];
+
+ return TT_Err_Ok;
+ }
+ }
+
+ return TTO_Err_Not_Covered;
+ }
+
+
+ /* The next three functions return a null-terminated list */
+
+ EXPORT_FUNC
+ FT_Error TT_GPOS_Query_Scripts( TTO_GPOSHeader* gpos,
+ FT_ULong** script_tag_list )
+ {
+ FT_Error error;
+ FT_Memory memory = gpos->memory;
+ FT_UShort n;
+ FT_ULong* stl;
+
+ TTO_ScriptList* sl;
+ TTO_ScriptRecord* sr;
+
+
+ if ( !gpos || !script_tag_list )
+ return TT_Err_Invalid_Argument;
+
+ sl = &gpos->ScriptList;
+ sr = sl->ScriptRecord;
+
+ if ( ALLOC_ARRAY( stl, sl->ScriptCount + 1, FT_ULong ) )
+ return error;
+
+ for ( n = 0; n < sl->ScriptCount; n++ )
+ stl[n] = sr[n].ScriptTag;
+ stl[n] = 0;
+
+ *script_tag_list = stl;
+
+ return TT_Err_Ok;
+ }
+
+
+ EXPORT_FUNC
+ FT_Error TT_GPOS_Query_Languages( TTO_GPOSHeader* gpos,
+ FT_UShort script_index,
+ FT_ULong** language_tag_list )
+ {
+ FT_Error error;
+ FT_Memory memory = gpos->memory;
+ FT_UShort n;
+ FT_ULong* ltl;
+
+ TTO_ScriptList* sl;
+ TTO_ScriptRecord* sr;
+ TTO_Script* s;
+ TTO_LangSysRecord* lsr;
+
+
+ if ( !gpos || !language_tag_list )
+ return TT_Err_Invalid_Argument;
+
+ sl = &gpos->ScriptList;
+ sr = sl->ScriptRecord;
+
+ if ( script_index >= sl->ScriptCount )
+ return TT_Err_Invalid_Argument;
+
+ s = &sr[script_index].Script;
+ lsr = s->LangSysRecord;
+
+ if ( ALLOC_ARRAY( ltl, s->LangSysCount + 1, FT_ULong ) )
+ return error;
+
+ for ( n = 0; n < s->LangSysCount; n++ )
+ ltl[n] = lsr[n].LangSysTag;
+ ltl[n] = 0;
+
+ *language_tag_list = ltl;
+
+ return TT_Err_Ok;
+ }
+
+
+ /* selecting 0xFFFF for language_index asks for the values of the
+ default language (DefaultLangSys) */
+
+ EXPORT_FUNC
+ FT_Error TT_GPOS_Query_Features( TTO_GPOSHeader* gpos,
+ FT_UShort script_index,
+ FT_UShort language_index,
+ FT_ULong** feature_tag_list )
+ {
+ FT_UShort n;
+ FT_Error error;
+ FT_Memory memory = gpos->memory;
+ FT_ULong* ftl;
+
+ TTO_ScriptList* sl;
+ TTO_ScriptRecord* sr;
+ TTO_Script* s;
+ TTO_LangSysRecord* lsr;
+ TTO_LangSys* ls;
+ FT_UShort* fi;
+
+ TTO_FeatureList* fl;
+ TTO_FeatureRecord* fr;
+
+
+ if ( !gpos || !feature_tag_list )
+ return TT_Err_Invalid_Argument;
+
+ sl = &gpos->ScriptList;
+ sr = sl->ScriptRecord;
+
+ fl = &gpos->FeatureList;
+ fr = fl->FeatureRecord;
+
+ if ( script_index >= sl->ScriptCount )
+ return TT_Err_Invalid_Argument;
+
+ s = &sr[script_index].Script;
+ lsr = s->LangSysRecord;
+
+ if ( language_index == 0xFFFF )
+ ls = &s->DefaultLangSys;
+ else
+ {
+ if ( language_index >= s->LangSysCount )
+ return TT_Err_Invalid_Argument;
+
+ ls = &lsr[language_index].LangSys;
+ }
+
+ fi = ls->FeatureIndex;
+
+ if ( ALLOC_ARRAY( ftl, ls->FeatureCount + 1, FT_ULong ) )
+ return error;
+
+ for ( n = 0; n < ls->FeatureCount; n++ )
+ {
+ if ( fi[n] >= fl->FeatureCount )
+ {
+ FREE( ftl );
+ return TTO_Err_Invalid_GPOS_SubTable_Format;
+ }
+ ftl[n] = fr[fi[n]].FeatureTag;
+ }
+ ftl[n] = 0;
+
+ *feature_tag_list = ftl;
+
+ return TT_Err_Ok;
+ }
+
+
+ /* Do an individual subtable lookup. Returns TT_Err_Ok if positioning
+ has been done, or TTO_Err_Not_Covered if not. */
+
+ static FT_Error gpos_Do_Glyph_Lookup( GPOS_Instance* gpi,
+ FT_UShort lookup_index,
+ TTO_GSUB_String* in,
+ TTO_GPOS_Data* out,
+ FT_UShort context_length,
+ int nesting_level )
+ {
+ FT_Error error = TT_Err_Ok;
+ FT_UShort i, flags;
+ TTO_GPOSHeader* gpos = gpi->gpos;
+ TTO_Lookup* lo;
+
+
+ nesting_level++;
+
+ if ( nesting_level > TTO_MAX_NESTING_LEVEL )
+ return TTO_Err_Too_Many_Nested_Contexts;
+
+ lo = &gpos->LookupList.Lookup[lookup_index];
+ flags = lo->LookupFlag;
+
+ for ( i = 0; i < lo->SubTableCount; i++ )
+ {
+ switch ( lo->LookupType )
+ {
+ case GPOS_LOOKUP_SINGLE:
+ error = Lookup_SinglePos( gpi,
+ &lo->SubTable[i].st.gpos.single,
+ in, out,
+ flags, context_length );
+ break;
+
+ case GPOS_LOOKUP_PAIR:
+ error = Lookup_PairPos( gpi,
+ &lo->SubTable[i].st.gpos.pair,
+ in, out,
+ flags, context_length );
+ break;
+
+ case GPOS_LOOKUP_CURSIVE:
+ error = Lookup_CursivePos( gpi,
+ &lo->SubTable[i].st.gpos.cursive,
+ in, out,
+ flags, context_length );
+ break;
+
+ case GPOS_LOOKUP_MARKBASE:
+ error = Lookup_MarkBasePos( gpi,
+ &lo->SubTable[i].st.gpos.markbase,
+ in, out,
+ flags, context_length );
+ break;
+
+ case GPOS_LOOKUP_MARKLIG:
+ error = Lookup_MarkLigPos( gpi,
+ &lo->SubTable[i].st.gpos.marklig,
+ in, out,
+ flags, context_length );
+ break;
+
+ case GPOS_LOOKUP_MARKMARK:
+ error = Lookup_MarkMarkPos( gpi,
+ &lo->SubTable[i].st.gpos.markmark,
+ in, out,
+ flags, context_length );
+ break;
+
+ case GPOS_LOOKUP_CONTEXT:
+ error = Lookup_ContextPos( gpi,
+ &lo->SubTable[i].st.gpos.context,
+ in, out,
+ flags, context_length,
+ nesting_level );
+ break;
+
+ case GPOS_LOOKUP_CHAIN:
+ error = Lookup_ChainContextPos( gpi,
+ &lo->SubTable[i].st.gpos.chain,
+ in, out,
+ flags, context_length,
+ nesting_level );
+ break;
+ }
+
+ /* Check whether we have a successful positioning or an error other
+ than TTO_Err_Not_Covered */
+
+ if ( error != TTO_Err_Not_Covered )
+ return error;
+ }
+
+ return TTO_Err_Not_Covered;
+ }
+
+
+ /* apply one lookup to the input string object */
+
+ static FT_Error gpos_Do_String_Lookup( GPOS_Instance* gpi,
+ FT_UShort lookup_index,
+ TTO_GSUB_String* in,
+ TTO_GPOS_Data* out )
+ {
+ FT_Error error, retError = TTO_Err_Not_Covered;
+ TTO_GPOSHeader* gpos = gpi->gpos;
+
+ FT_UShort* properties = gpos->LookupList.Properties;
+ FT_UShort* p_in = in->properties;
+
+ int nesting_level = 0;
+ FT_UShort i;
+ FT_Pos offset;
+
+
+ gpi->first = 0xFFFF;
+ gpi->last = 0xFFFF; /* no last valid glyph for cursive pos. */
+
+ in->pos = 0;
+
+ while ( in->pos < in->length )
+ {
+ if ( ~p_in[in->pos] & properties[lookup_index] )
+ {
+ /* 0xFFFF indicates that we don't have a context length yet. */
+
+ /* Note that the connection between mark and base glyphs hold
+ exactly one (string) lookup. For example, it would be possible
+ that in the first lookup, mark glyph X is attached to base
+ glyph A, and in the next lookup it is attached to base glyph B.
+ It is up to the font designer to provide meaningful lookups and
+ lookup order. */
+
+ error = gpos_Do_Glyph_Lookup( gpi, lookup_index, in, out,
+ 0xFFFF, nesting_level );
+ if ( error && error != TTO_Err_Not_Covered )
+ return error;
+ }
+ else
+ {
+ /* Contrary to properties defined in GDEF, user-defined properties
+ will always stop a possible cursive positioning. */
+ gpi->last = 0xFFFF;
+
+ error = TTO_Err_Not_Covered;
+ }
+
+ /* test whether we have to adjust the offsets for cursive connections */
+
+ if ( gpi->first != 0xFFFF && gpi->last == 0xFFFF &&
+ gpos->LookupList.Lookup[lookup_index].LookupFlag & RIGHT_TO_LEFT )
+ {
+ offset = out[in->pos].y_pos;
+
+ /* no horizontal offsets (for vertical writing direction)
+ supported yet */
+
+ for ( i = gpi->first; i <= in->pos; i++ )
+ out[i].y_pos -= offset;
+
+ gpi->first = 0xFFFF;
+ }
+
+ if ( error == TTO_Err_Not_Covered )
+ (in->pos)++;
+ else
+ retError = error;
+ }
+
+ return retError;
+ }
+
+
+ EXPORT_FUNC
+ FT_Error TT_GPOS_Add_Feature( TTO_GPOSHeader* gpos,
+ FT_UShort feature_index,
+ FT_UShort property )
+ {
+ FT_UShort i;
+
+ TTO_Feature feature;
+ FT_UShort* properties;
+ FT_UShort* index;
+
+
+ if ( !gpos ||
+ feature_index >= gpos->FeatureList.FeatureCount )
+ return TT_Err_Invalid_Argument;
+
+ properties = gpos->LookupList.Properties;
+
+ feature = gpos->FeatureList.FeatureRecord[feature_index].Feature;
+ index = feature.LookupListIndex;
+
+ for ( i = 0; i < feature.LookupListCount; i++ )
+ properties[index[i]] |= property;
+
+ return TT_Err_Ok;
+ }
+
+
+ EXPORT_FUNC
+ FT_Error TT_GPOS_Clear_Features( TTO_GPOSHeader* gpos )
+ {
+ FT_UShort i;
+
+ FT_UShort* properties;
+
+
+ if ( !gpos )
+ return TT_Err_Invalid_Argument;
+
+ properties = gpos->LookupList.Properties;
+
+ for ( i = 0; i < gpos->LookupList.LookupCount; i++ )
+ properties[i] = 0;
+
+ return TT_Err_Ok;
+ }
+
+
+ EXPORT_FUNC
+ FT_Error TT_GPOS_Register_Glyph_Function( TTO_GPOSHeader* gpos,
+ TTO_GlyphFunction gfunc )
+ {
+ if ( !gpos )
+ return TT_Err_Invalid_Argument;
+
+ gpos->gfunc = gfunc;
+
+ return TT_Err_Ok;
+ }
+
+
+ EXPORT_FUNC
+ FT_Error TT_GPOS_Register_MM_Function( TTO_GPOSHeader* gpos,
+ TTO_MMFunction mmfunc,
+ void* data )
+ {
+ if ( !gpos )
+ return TT_Err_Invalid_Argument;
+
+ gpos->mmfunc = mmfunc;
+ gpos->data = data;
+
+ return TT_Err_Ok;
+ }
+
+
+ /* If `dvi' is TRUE, glyph contour points for anchor points and device
+ tables are ignored -- you will get device independent values. */
+
+ EXPORT_FUNC
+ FT_Error TT_GPOS_Apply_String( FT_Face face,
+ TTO_GPOSHeader* gpos,
+ FT_UShort load_flags,
+ TTO_GSUB_String* in,
+ TTO_GPOS_Data** out,
+ FT_Bool dvi,
+ FT_Bool r2l )
+ {
+ FT_Memory memory = gpos->memory;
+ FT_Error error, retError = TTO_Err_Not_Covered;
+ GPOS_Instance gpi;
+
+ FT_UShort j;
+
+ FT_UShort* properties;
+
+
+ if ( !face || !gpos ||
+ !in || in->length == 0 || in->pos >= in->length )
+ return TT_Err_Invalid_Argument;
+
+ properties = gpos->LookupList.Properties;
+
+ gpi.face = face;
+ gpi.gpos = gpos;
+ gpi.load_flags = load_flags;
+ gpi.r2l = r2l;
+ gpi.dvi = dvi;
+
+ if ( *out )
+ FREE( *out );
+ if ( ALLOC_ARRAY( *out, in->length, TTO_GPOS_Data ) )
+ return error;
+
+ for ( j = 0; j < gpos->LookupList.LookupCount; j++ )
+ if ( !properties || properties[j] )
+ {
+ error = gpos_Do_String_Lookup( &gpi, j, in, *out );
+ if ( error )
+ {
+ if ( error != TTO_Err_Not_Covered )
+ return error;
+ }
+ else
+ retError = error;
+ }
+
+ return retError;
+ }
+
+/* END */
diff --git a/src/otlayout/ftxgpos.h b/src/otlayout/ftxgpos.h
new file mode 100644
index 000000000..408bcb0ae
--- /dev/null
+++ b/src/otlayout/ftxgpos.h
@@ -0,0 +1,859 @@
+/*******************************************************************
+ *
+ * ftxgpos.h
+ *
+ * TrueType Open GPOS table support
+ *
+ * Copyright 1996-2000 by
+ * David Turner, Robert Wilhelm, and Werner Lemberg.
+ *
+ * This file is part of the FreeType project, and may only be used
+ * modified and distributed under the terms of the FreeType project
+ * license, LICENSE.TXT. By continuing to use, modify, or distribute
+ * this file you indicate that you have read the license and
+ * understand and accept it fully.
+ *
+ ******************************************************************/
+
+#ifndef FTXOPEN_H
+#error "Don't include this file! Use ftxopen.h instead."
+#endif
+
+#ifndef FTXGPOS_H
+#define FTXGPOS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define TTO_Err_Invalid_GPOS_SubTable_Format 0x1020
+#define TTO_Err_Invalid_GPOS_SubTable 0x1021
+
+
+/* Lookup types for glyph positioning */
+
+#define GPOS_LOOKUP_SINGLE 1
+#define GPOS_LOOKUP_PAIR 2
+#define GPOS_LOOKUP_CURSIVE 3
+#define GPOS_LOOKUP_MARKBASE 4
+#define GPOS_LOOKUP_MARKLIG 5
+#define GPOS_LOOKUP_MARKMARK 6
+#define GPOS_LOOKUP_CONTEXT 7
+#define GPOS_LOOKUP_CHAIN 8
+#define GPOS_LOOKUP_EXTENSION 9
+
+
+ /* A pointer to a function which loads a glyph. Its parameters are
+ the same as in a call to TT_Load_Glyph() -- if no glyph loading
+ function will be registered with TTO_GPOS_Register_Glyph_Function(),
+ TT_Load_Glyph() will be called indeed. The purpose of this function
+ pointer is to provide a hook for caching glyph outlines and sbits
+ (using the instance's generic pointer to hold the data).
+
+ If for some reason no outline data is available (e.g. for an
+ embedded bitmap glyph), _glyph->outline.n_points should be set to
+ zero. _glyph can be computed with
+
+ _glyph = HANDLE_Glyph( glyph ) */
+
+ typedef FT_Error (*TTO_GlyphFunction)(FT_Face face,
+ FT_UInt glyphIndex,
+ FT_Int loadFlags );
+
+
+ /* A pointer to a function which accesses the PostScript interpreter.
+ Multiple Master fonts need this interface to convert a metric ID
+ (as stored in an OpenType font version 1.2 or higher) `metric_id'
+ into a metric value (returned in `metric_value').
+
+ `data' points to the user-defined structure specified during a
+ call to TT_GPOS_Register_MM_Function().
+
+ `metric_value' must be returned as a scaled value (but shouldn't
+ be rounded). */
+
+ typedef FT_Error (*TTO_MMFunction)(FT_Face face,
+ FT_UShort metric_id,
+ FT_Pos* metric_value,
+ void* data );
+
+
+ struct TTO_GPOSHeader_
+ {
+ FT_Memory memory;
+
+ FT_Fixed Version;
+
+ TTO_ScriptList ScriptList;
+ TTO_FeatureList FeatureList;
+ TTO_LookupList LookupList;
+
+ TTO_GDEFHeader* gdef;
+
+ /* the next field is used for a callback function to get the
+ glyph outline. */
+
+ TTO_GlyphFunction gfunc;
+
+ /* this is OpenType 1.2 -- Multiple Master fonts need this
+ callback function to get various metric values from the
+ PostScript interpreter. */
+
+ TTO_MMFunction mmfunc;
+ void* data;
+ };
+
+ typedef struct TTO_GPOSHeader_ TTO_GPOSHeader;
+ typedef struct TTO_GPOSHeader_* TTO_GPOS;
+
+
+ /* shared tables */
+
+ struct TTO_ValueRecord_
+ {
+ FT_Short XPlacement; /* horizontal adjustment for
+ placement */
+ FT_Short YPlacement; /* vertical adjustment for
+ placement */
+ FT_Short XAdvance; /* horizontal adjustment for
+ advance */
+ FT_Short YAdvance; /* vertical adjustment for
+ advance */
+ TTO_Device XPlacementDevice; /* device table for horizontal
+ placement */
+ TTO_Device YPlacementDevice; /* device table for vertical
+ placement */
+ TTO_Device XAdvanceDevice; /* device table for horizontal
+ advance */
+ TTO_Device YAdvanceDevice; /* device table for vertical
+ advance */
+ FT_UShort XIdPlacement; /* horizontal placement metric ID */
+ FT_UShort YIdPlacement; /* vertical placement metric ID */
+ FT_UShort XIdAdvance; /* horizontal advance metric ID */
+ FT_UShort YIdAdvance; /* vertical advance metric ID */
+ };
+
+ typedef struct TTO_ValueRecord_ TTO_ValueRecord;
+
+
+/* Mask values to scan the value format of the ValueRecord structure.
+ We always expand compressed ValueRecords of the font. */
+
+#define HAVE_X_PLACEMENT 0x0001
+#define HAVE_Y_PLACEMENT 0x0002
+#define HAVE_X_ADVANCE 0x0004
+#define HAVE_Y_ADVANCE 0x0008
+#define HAVE_X_PLACEMENT_DEVICE 0x0010
+#define HAVE_Y_PLACEMENT_DEVICE 0x0020
+#define HAVE_X_ADVANCE_DEVICE 0x0040
+#define HAVE_Y_ADVANCE_DEVICE 0x0080
+#define HAVE_X_ID_PLACEMENT 0x0100
+#define HAVE_Y_ID_PLACEMENT 0x0200
+#define HAVE_X_ID_ADVANCE 0x0400
+#define HAVE_Y_ID_ADVANCE 0x0800
+
+
+ struct TTO_AnchorFormat1_
+ {
+ FT_Short XCoordinate; /* horizontal value */
+ FT_Short YCoordinate; /* vertical value */
+ };
+
+ typedef struct TTO_AnchorFormat1_ TTO_AnchorFormat1;
+
+
+ struct TTO_AnchorFormat2_
+ {
+ FT_Short XCoordinate; /* horizontal value */
+ FT_Short YCoordinate; /* vertical value */
+ FT_UShort AnchorPoint; /* index to glyph contour point */
+ };
+
+ typedef struct TTO_AnchorFormat2_ TTO_AnchorFormat2;
+
+
+ struct TTO_AnchorFormat3_
+ {
+ FT_Short XCoordinate; /* horizontal value */
+ FT_Short YCoordinate; /* vertical value */
+ TTO_Device XDeviceTable; /* device table for X coordinate */
+ TTO_Device YDeviceTable; /* device table for Y coordinate */
+ };
+
+ typedef struct TTO_AnchorFormat3_ TTO_AnchorFormat3;
+
+
+ struct TTO_AnchorFormat4_
+ {
+ FT_UShort XIdAnchor; /* horizontal metric ID */
+ FT_UShort YIdAnchor; /* vertical metric ID */
+ };
+
+ typedef struct TTO_AnchorFormat4_ TTO_AnchorFormat4;
+
+
+ struct TTO_Anchor_
+ {
+ FT_UShort PosFormat; /* 1, 2, 3, or 4 -- 0 indicates
+ that there is no Anchor table */
+
+ union
+ {
+ TTO_AnchorFormat1 af1;
+ TTO_AnchorFormat2 af2;
+ TTO_AnchorFormat3 af3;
+ TTO_AnchorFormat4 af4;
+ } af;
+ };
+
+ typedef struct TTO_Anchor_ TTO_Anchor;
+
+
+ struct TTO_MarkRecord_
+ {
+ FT_UShort Class; /* mark class */
+ TTO_Anchor MarkAnchor; /* anchor table */
+ };
+
+ typedef struct TTO_MarkRecord_ TTO_MarkRecord;
+
+
+ struct TTO_MarkArray_
+ {
+ FT_UShort MarkCount; /* number of MarkRecord tables */
+ TTO_MarkRecord* MarkRecord; /* array of MarkRecord tables */
+ };
+
+ typedef struct TTO_MarkArray_ TTO_MarkArray;
+
+
+ /* LookupType 1 */
+
+ struct TTO_SinglePosFormat1_
+ {
+ TTO_ValueRecord Value; /* ValueRecord for all covered
+ glyphs */
+ };
+
+ typedef struct TTO_SinglePosFormat1_ TTO_SinglePosFormat1;
+
+
+ struct TTO_SinglePosFormat2_
+ {
+ FT_UShort ValueCount; /* number of ValueRecord tables */
+ TTO_ValueRecord* Value; /* array of ValueRecord tables */
+ };
+
+ typedef struct TTO_SinglePosFormat2_ TTO_SinglePosFormat2;
+
+
+ struct TTO_SinglePos_
+ {
+ FT_UShort PosFormat; /* 1 or 2 */
+ TTO_Coverage Coverage; /* Coverage table */
+
+ FT_UShort ValueFormat; /* format of ValueRecord table */
+
+ union
+ {
+ TTO_SinglePosFormat1 spf1;
+ TTO_SinglePosFormat2 spf2;
+ } spf;
+ };
+
+ typedef struct TTO_SinglePos_ TTO_SinglePos;
+
+
+ /* LookupType 2 */
+
+ struct TTO_PairValueRecord_
+ {
+ FT_UShort SecondGlyph; /* glyph ID for second glyph */
+ TTO_ValueRecord Value1; /* pos. data for first glyph */
+ TTO_ValueRecord Value2; /* pos. data for second glyph */
+ };
+
+ typedef struct TTO_PairValueRecord_ TTO_PairValueRecord;
+
+
+ struct TTO_PairSet_
+ {
+ FT_UShort PairValueCount;
+ /* number of PairValueRecord tables */
+ TTO_PairValueRecord* PairValueRecord;
+ /* array of PairValueRecord tables */
+ };
+
+ typedef struct TTO_PairSet_ TTO_PairSet;
+
+
+ struct TTO_PairPosFormat1_
+ {
+ FT_UShort PairSetCount; /* number of PairSet tables */
+ TTO_PairSet* PairSet; /* array of PairSet tables */
+ };
+
+ typedef struct TTO_PairPosFormat1_ TTO_PairPosFormat1;
+
+
+ struct TTO_Class2Record_
+ {
+ TTO_ValueRecord Value1; /* pos. data for first glyph */
+ TTO_ValueRecord Value2; /* pos. data for second glyph */
+ };
+
+ typedef struct TTO_Class2Record_ TTO_Class2Record;
+
+
+ struct TTO_Class1Record_
+ {
+ TTO_Class2Record* Class2Record; /* array of Class2Record tables */
+ };
+
+ typedef struct TTO_Class1Record_ TTO_Class1Record;
+
+
+ struct TTO_PairPosFormat2_
+ {
+ TTO_ClassDefinition ClassDef1; /* class def. for first glyph */
+ TTO_ClassDefinition ClassDef2; /* class def. for second glyph */
+ FT_UShort Class1Count; /* number of classes in ClassDef1
+ table */
+ FT_UShort Class2Count; /* number of classes in ClassDef2
+ table */
+ TTO_Class1Record* Class1Record; /* array of Class1Record tables */
+ };
+
+ typedef struct TTO_PairPosFormat2_ TTO_PairPosFormat2;
+
+
+ struct TTO_PairPos_
+ {
+ FT_UShort PosFormat; /* 1 or 2 */
+ TTO_Coverage Coverage; /* Coverage table */
+ FT_UShort ValueFormat1; /* format of ValueRecord table
+ for first glyph */
+ FT_UShort ValueFormat2; /* format of ValueRecord table
+ for second glyph */
+
+ union
+ {
+ TTO_PairPosFormat1 ppf1;
+ TTO_PairPosFormat2 ppf2;
+ } ppf;
+ };
+
+ typedef struct TTO_PairPos_ TTO_PairPos;
+
+
+ /* LookupType 3 */
+
+ struct TTO_EntryExitRecord_
+ {
+ TTO_Anchor EntryAnchor; /* entry Anchor table */
+ TTO_Anchor ExitAnchor; /* exit Anchor table */
+ };
+
+
+ typedef struct TTO_EntryExitRecord_ TTO_EntryExitRecord;
+
+ struct TTO_CursivePos_
+ {
+ FT_UShort PosFormat; /* always 1 */
+ TTO_Coverage Coverage; /* Coverage table */
+ FT_UShort EntryExitCount;
+ /* number of EntryExitRecord tables */
+ TTO_EntryExitRecord* EntryExitRecord;
+ /* array of EntryExitRecord tables */
+ };
+
+ typedef struct TTO_CursivePos_ TTO_CursivePos;
+
+
+ /* LookupType 4 */
+
+ struct TTO_BaseRecord_
+ {
+ TTO_Anchor* BaseAnchor; /* array of base glyph anchor
+ tables */
+ };
+
+ typedef struct TTO_BaseRecord_ TTO_BaseRecord;
+
+
+ struct TTO_BaseArray_
+ {
+ FT_UShort BaseCount; /* number of BaseRecord tables */
+ TTO_BaseRecord* BaseRecord; /* array of BaseRecord tables */
+ };
+
+ typedef struct TTO_BaseArray_ TTO_BaseArray;
+
+
+ struct TTO_MarkBasePos_
+ {
+ FT_UShort PosFormat; /* always 1 */
+ TTO_Coverage MarkCoverage; /* mark glyph coverage table */
+ TTO_Coverage BaseCoverage; /* base glyph coverage table */
+ FT_UShort ClassCount; /* number of mark classes */
+ TTO_MarkArray MarkArray; /* mark array table */
+ TTO_BaseArray BaseArray; /* base array table */
+ };
+
+ typedef struct TTO_MarkBasePos_ TTO_MarkBasePos;
+
+
+ /* LookupType 5 */
+
+ struct TTO_ComponentRecord_
+ {
+ TTO_Anchor* LigatureAnchor; /* array of ligature glyph anchor
+ tables */
+ };
+
+ typedef struct TTO_ComponentRecord_ TTO_ComponentRecord;
+
+
+ struct TTO_LigatureAttach_
+ {
+ FT_UShort ComponentCount;
+ /* number of ComponentRecord tables */
+ TTO_ComponentRecord* ComponentRecord;
+ /* array of ComponentRecord tables */
+ };
+
+ typedef struct TTO_LigatureAttach_ TTO_LigatureAttach;
+
+
+ struct TTO_LigatureArray_
+ {
+ FT_UShort LigatureCount; /* number of LigatureAttach tables */
+ TTO_LigatureAttach* LigatureAttach;
+ /* array of LigatureAttach tables */
+ };
+
+ typedef struct TTO_LigatureArray_ TTO_LigatureArray;
+
+
+ struct TTO_MarkLigPos_
+ {
+ FT_UShort PosFormat; /* always 1 */
+ TTO_Coverage MarkCoverage; /* mark glyph coverage table */
+ TTO_Coverage LigatureCoverage;
+ /* ligature glyph coverage table */
+ FT_UShort ClassCount; /* number of mark classes */
+ TTO_MarkArray MarkArray; /* mark array table */
+ TTO_LigatureArray LigatureArray; /* ligature array table */
+ };
+
+ typedef struct TTO_MarkLigPos_ TTO_MarkLigPos;
+
+
+ /* LookupType 6 */
+
+ struct TTO_Mark2Record_
+ {
+ TTO_Anchor* Mark2Anchor; /* array of mark glyph anchor
+ tables */
+ };
+
+ typedef struct TTO_Mark2Record_ TTO_Mark2Record;
+
+
+ struct TTO_Mark2Array_
+ {
+ FT_UShort Mark2Count; /* number of Mark2Record tables */
+ TTO_Mark2Record* Mark2Record; /* array of Mark2Record tables */
+ };
+
+ typedef struct TTO_Mark2Array_ TTO_Mark2Array;
+
+
+ struct TTO_MarkMarkPos_
+ {
+ FT_UShort PosFormat; /* always 1 */
+ TTO_Coverage Mark1Coverage; /* first mark glyph coverage table */
+ TTO_Coverage Mark2Coverage; /* second mark glyph coverave table */
+ FT_UShort ClassCount; /* number of combining mark classes */
+ TTO_MarkArray Mark1Array; /* MarkArray table for first mark */
+ TTO_Mark2Array Mark2Array; /* MarkArray table for second mark */
+ };
+
+ typedef struct TTO_MarkMarkPos_ TTO_MarkMarkPos;
+
+
+ /* needed by both lookup type 7 and 8 */
+
+ struct TTO_PosLookupRecord_
+ {
+ FT_UShort SequenceIndex; /* index into current
+ glyph sequence */
+ FT_UShort LookupListIndex; /* Lookup to apply to that pos. */
+ };
+
+ typedef struct TTO_PosLookupRecord_ TTO_PosLookupRecord;
+
+
+ /* LookupType 7 */
+
+ struct TTO_PosRule_
+ {
+ FT_UShort GlyphCount; /* total number of input glyphs */
+ FT_UShort PosCount; /* number of PosLookupRecord tables */
+ FT_UShort* Input; /* array of input glyph IDs */
+ TTO_PosLookupRecord* PosLookupRecord;
+ /* array of PosLookupRecord tables */
+ };
+
+ typedef struct TTO_PosRule_ TTO_PosRule;
+
+
+ struct TTO_PosRuleSet_
+ {
+ FT_UShort PosRuleCount; /* number of PosRule tables */
+ TTO_PosRule* PosRule; /* array of PosRule tables */
+ };
+
+ typedef struct TTO_PosRuleSet_ TTO_PosRuleSet;
+
+
+ struct TTO_ContextPosFormat1_
+ {
+ TTO_Coverage Coverage; /* Coverage table */
+ FT_UShort PosRuleSetCount; /* number of PosRuleSet tables */
+ TTO_PosRuleSet* PosRuleSet; /* array of PosRuleSet tables */
+ };
+
+ typedef struct TTO_ContextPosFormat1_ TTO_ContextPosFormat1;
+
+
+ struct TTO_PosClassRule_
+ {
+ FT_UShort GlyphCount; /* total number of context classes */
+ FT_UShort PosCount; /* number of PosLookupRecord tables */
+ FT_UShort* Class; /* array of classes */
+ TTO_PosLookupRecord* PosLookupRecord;
+ /* array of PosLookupRecord tables */
+ };
+
+ typedef struct TTO_PosClassRule_ TTO_PosClassRule;
+
+
+ struct TTO_PosClassSet_
+ {
+ FT_UShort PosClassRuleCount;
+ /* number of PosClassRule tables */
+ TTO_PosClassRule* PosClassRule; /* array of PosClassRule tables */
+ };
+
+ typedef struct TTO_PosClassSet_ TTO_PosClassSet;
+
+
+ /* The `MaxContextLength' field is not defined in the TTO specification
+ but simplifies the implementation of this format. It holds the
+ maximal context length used in the context rules. */
+
+ struct TTO_ContextPosFormat2_
+ {
+ FT_UShort MaxContextLength;
+ /* maximal context length */
+ TTO_Coverage Coverage; /* Coverage table */
+ TTO_ClassDefinition ClassDef; /* ClassDef table */
+ FT_UShort PosClassSetCount;
+ /* number of PosClassSet tables */
+ TTO_PosClassSet* PosClassSet; /* array of PosClassSet tables */
+ };
+
+ typedef struct TTO_ContextPosFormat2_ TTO_ContextPosFormat2;
+
+
+ struct TTO_ContextPosFormat3_
+ {
+ FT_UShort GlyphCount; /* number of input glyphs */
+ FT_UShort PosCount; /* number of PosLookupRecord tables */
+ TTO_Coverage* Coverage; /* array of Coverage tables */
+ TTO_PosLookupRecord* PosLookupRecord;
+ /* array of PosLookupRecord tables */
+ };
+
+ typedef struct TTO_ContextPosFormat3_ TTO_ContextPosFormat3;
+
+
+ struct TTO_ContextPos_
+ {
+ FT_UShort PosFormat; /* 1, 2, or 3 */
+
+ union
+ {
+ TTO_ContextPosFormat1 cpf1;
+ TTO_ContextPosFormat2 cpf2;
+ TTO_ContextPosFormat3 cpf3;
+ } cpf;
+ };
+
+ typedef struct TTO_ContextPos_ TTO_ContextPos;
+
+
+ /* LookupType 8 */
+
+ struct TTO_ChainPosRule_
+ {
+ FT_UShort BacktrackGlyphCount;
+ /* total number of backtrack glyphs */
+ FT_UShort* Backtrack; /* array of backtrack glyph IDs */
+ FT_UShort InputGlyphCount;
+ /* total number of input glyphs */
+ FT_UShort* Input; /* array of input glyph IDs */
+ FT_UShort LookaheadGlyphCount;
+ /* total number of lookahead glyphs */
+ FT_UShort* Lookahead; /* array of lookahead glyph IDs */
+ FT_UShort PosCount; /* number of PosLookupRecords */
+ TTO_PosLookupRecord* PosLookupRecord;
+ /* array of PosLookupRecords */
+ };
+
+ typedef struct TTO_ChainPosRule_ TTO_ChainPosRule;
+
+
+ struct TTO_ChainPosRuleSet_
+ {
+ FT_UShort ChainPosRuleCount;
+ /* number of ChainPosRule tables */
+ TTO_ChainPosRule* ChainPosRule; /* array of ChainPosRule tables */
+ };
+
+ typedef struct TTO_ChainPosRuleSet_ TTO_ChainPosRuleSet;
+
+
+ struct TTO_ChainContextPosFormat1_
+ {
+ TTO_Coverage Coverage; /* Coverage table */
+ FT_UShort ChainPosRuleSetCount;
+ /* number of ChainPosRuleSet tables */
+ TTO_ChainPosRuleSet* ChainPosRuleSet;
+ /* array of ChainPosRuleSet tables */
+ };
+
+ typedef struct TTO_ChainContextPosFormat1_ TTO_ChainContextPosFormat1;
+
+
+ struct TTO_ChainPosClassRule_
+ {
+ FT_UShort BacktrackGlyphCount;
+ /* total number of backtrack
+ classes */
+ FT_UShort* Backtrack; /* array of backtrack classes */
+ FT_UShort InputGlyphCount;
+ /* total number of context classes */
+ FT_UShort* Input; /* array of context classes */
+ FT_UShort LookaheadGlyphCount;
+ /* total number of lookahead
+ classes */
+ FT_UShort* Lookahead; /* array of lookahead classes */
+ FT_UShort PosCount; /* number of PosLookupRecords */
+ TTO_PosLookupRecord* PosLookupRecord;
+ /* array of substitution lookups */
+ };
+
+ typedef struct TTO_ChainPosClassRule_ TTO_ChainPosClassRule;
+
+
+ struct TTO_ChainPosClassSet_
+ {
+ FT_UShort ChainPosClassRuleCount;
+ /* number of ChainPosClassRule
+ tables */
+ TTO_ChainPosClassRule* ChainPosClassRule;
+ /* array of ChainPosClassRule
+ tables */
+ };
+
+ typedef struct TTO_ChainPosClassSet_ TTO_ChainPosClassSet;
+
+
+ /* The `MaxXXXLength' fields are not defined in the TTO specification
+ but simplifies the implementation of this format. It holds the
+ maximal context length used in the specific context rules. */
+
+ struct TTO_ChainContextPosFormat2_
+ {
+ TTO_Coverage Coverage; /* Coverage table */
+
+ FT_UShort MaxBacktrackLength;
+ /* maximal backtrack length */
+ TTO_ClassDefinition BacktrackClassDef;
+ /* BacktrackClassDef table */
+ FT_UShort MaxInputLength;
+ /* maximal input length */
+ TTO_ClassDefinition InputClassDef;
+ /* InputClassDef table */
+ FT_UShort MaxLookaheadLength;
+ /* maximal lookahead length */
+ TTO_ClassDefinition LookaheadClassDef;
+ /* LookaheadClassDef table */
+
+ FT_UShort ChainPosClassSetCount;
+ /* number of ChainPosClassSet
+ tables */
+ TTO_ChainPosClassSet* ChainPosClassSet;
+ /* array of ChainPosClassSet
+ tables */
+ };
+
+ typedef struct TTO_ChainContextPosFormat2_ TTO_ChainContextPosFormat2;
+
+
+ struct TTO_ChainContextPosFormat3_
+ {
+ FT_UShort BacktrackGlyphCount;
+ /* number of backtrack glyphs */
+ TTO_Coverage* BacktrackCoverage;
+ /* array of backtrack Coverage
+ tables */
+ FT_UShort InputGlyphCount;
+ /* number of input glyphs */
+ TTO_Coverage* InputCoverage;
+ /* array of input coverage
+ tables */
+ FT_UShort LookaheadGlyphCount;
+ /* number of lookahead glyphs */
+ TTO_Coverage* LookaheadCoverage;
+ /* array of lookahead coverage
+ tables */
+ FT_UShort PosCount; /* number of PosLookupRecords */
+ TTO_PosLookupRecord* PosLookupRecord;
+ /* array of substitution lookups */
+ };
+
+ typedef struct TTO_ChainContextPosFormat3_ TTO_ChainContextPosFormat3;
+
+
+ struct TTO_ChainContextPos_
+ {
+ FT_UShort PosFormat; /* 1, 2, or 3 */
+
+ union
+ {
+ TTO_ChainContextPosFormat1 ccpf1;
+ TTO_ChainContextPosFormat2 ccpf2;
+ TTO_ChainContextPosFormat3 ccpf3;
+ } ccpf;
+ };
+
+ typedef struct TTO_ChainContextPos_ TTO_ChainContextPos;
+
+
+ union TTO_GPOS_SubTable_
+ {
+ TTO_SinglePos single;
+ TTO_PairPos pair;
+ TTO_CursivePos cursive;
+ TTO_MarkBasePos markbase;
+ TTO_MarkLigPos marklig;
+ TTO_MarkMarkPos markmark;
+ TTO_ContextPos context;
+ TTO_ChainContextPos chain;
+ };
+
+ typedef union TTO_GPOS_SubTable_ TTO_GPOS_SubTable;
+
+
+ /* This `string object' is much simpler compared to TTO_GSUB_String.
+ A call to TTO_GPOS_Apply_String() will allocate it. */
+
+ struct TTO_GPOS_Data_
+ {
+ FT_Pos x_pos;
+ FT_Pos y_pos;
+ FT_Pos x_advance;
+ FT_Pos y_advance;
+ FT_UShort back; /* number of glyphs to go back
+ for drawing current glyph */
+ FT_Bool new_advance; /* if set, the advance width values are
+ absolute, i.e., they won't be
+ added to the original glyph's value
+ but rather replace them. */
+ };
+
+ typedef struct TTO_GPOS_Data_ TTO_GPOS_Data;
+
+
+ /* finally, the GPOS API */
+
+ /* EXPORT_DEF
+ FT_Export ( FT_Error ) TT_Init_GPOS_Extension( TT_Engine engine ); */
+
+ EXPORT_DEF
+ FT_Error TT_Load_GPOS_Table( FT_Face face,
+ TTO_GPOSHeader** gpos,
+ TTO_GDEFHeader* gdef );
+
+ EXPORT_DEF
+ FT_Error TT_Done_GPOS_Table( TTO_GPOSHeader* gpos );
+
+ EXPORT_DEF
+ FT_Error TT_GPOS_Select_Script( TTO_GPOSHeader* gpos,
+ FT_ULong script_tag,
+ FT_UShort* script_index );
+ EXPORT_DEF
+ FT_Error TT_GPOS_Select_Language( TTO_GPOSHeader* gpos,
+ FT_ULong language_tag,
+ FT_UShort script_index,
+ FT_UShort* language_index,
+ FT_UShort* req_feature_index );
+ EXPORT_DEF
+ FT_Error TT_GPOS_Select_Feature( TTO_GPOSHeader* gpos,
+ FT_ULong feature_tag,
+ FT_UShort script_index,
+ FT_UShort language_index,
+ FT_UShort* feature_index );
+
+ EXPORT_DEF
+ FT_Error TT_GPOS_Query_Scripts( TTO_GPOSHeader* gpos,
+ FT_ULong** script_tag_list );
+ EXPORT_DEF
+ FT_Error TT_GPOS_Query_Languages( TTO_GPOSHeader* gpos,
+ FT_UShort script_index,
+ FT_ULong** language_tag_list );
+ EXPORT_DEF
+ FT_Error TT_GPOS_Query_Features( TTO_GPOSHeader* gpos,
+ FT_UShort script_index,
+ FT_UShort language_index,
+ FT_ULong** feature_tag_list );
+
+ EXPORT_DEF
+ FT_Error TT_GPOS_Add_Feature( TTO_GPOSHeader* gpos,
+ FT_UShort feature_index,
+ FT_UShort property );
+ EXPORT_DEF
+ FT_Error TT_GPOS_Clear_Features( TTO_GPOSHeader* gpos );
+
+ EXPORT_DEF
+ FT_Error TT_GPOS_Register_Glyph_Function( TTO_GPOSHeader* gpos,
+ TTO_GlyphFunction gfunc );
+
+ EXPORT_DEF
+ FT_Error TT_GPOS_Register_MM_Function( TTO_GPOSHeader* gpos,
+ TTO_MMFunction mmfunc,
+ void* data );
+
+ /* If `dvi' is TRUE, glyph contour points for anchor points and device
+ tables are ignored -- you will get device independent values. */
+
+ EXPORT_DEF
+ FT_Error TT_GPOS_Apply_String( FT_Face face,
+ TTO_GPOSHeader* gpos,
+ FT_UShort load_flags,
+ TTO_GSUB_String* in,
+ TTO_GPOS_Data** out,
+ FT_Bool dvi,
+ FT_Bool r2l );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* FTXGPOS_H */
+
+
+/* END */
diff --git a/src/otlayout/ftxgsub.c b/src/otlayout/ftxgsub.c
new file mode 100644
index 000000000..f8ff72407
--- /dev/null
+++ b/src/otlayout/ftxgsub.c
@@ -0,0 +1,4582 @@
+/*******************************************************************
+ *
+ * ftxgsub.c
+ *
+ * TrueType Open GSUB table support.
+ *
+ * Copyright 1996-2000 by
+ * David Turner, Robert Wilhelm, and Werner Lemberg.
+ *
+ * This file is part of the FreeType project, and may only be used
+ * modified and distributed under the terms of the FreeType project
+ * license, LICENSE.TXT. By continuing to use, modify, or distribute
+ * this file you indicate that you have read the license and
+ * understand and accept it fully.
+ *
+ ******************************************************************/
+
+/* XXX There is *a lot* of duplicated code (cf. formats 5 and 6), but
+ I don't care currently. I believe that it would be possible to
+ save about 50% of TTO code by carefully designing the structures,
+ sharing as much as possible with extensive use of macros. This
+ is something for a volunteer :-) */
+
+#define EXPORT_FUNC static
+
+#include "ftxopen.h"
+#include "ftxopenf.h"
+
+#include "fterrcompat.h"
+
+#include FT_TRUETYPE_TAGS_H
+
+#include FT_INTERNAL_STREAM_H
+#include FT_INTERNAL_MEMORY_H
+#include FT_INTERNAL_TRUETYPE_TYPES_H
+
+
+#define GSUB_ID Build_Extension_ID( 'G', 'S', 'U', 'B' )
+
+
+#define ADD_String( in, num_in, out, num_out, glyph_data, component, ligID ) \
+ ( ( error = TT_GSUB_Add_String( (in), (num_in), \
+ (out), (num_out), \
+ (glyph_data), (component), (ligID) \
+ ) ) != TT_Err_Ok )
+
+
+ static FT_Error gsub_Do_Glyph_Lookup( TTO_GSUBHeader* gsub,
+ FT_UShort lookup_index,
+ TTO_GSUB_String* in,
+ TTO_GSUB_String* out,
+ FT_UShort context_length,
+ int nesting_level );
+
+
+
+ /**********************
+ * Auxiliary functions
+ **********************/
+
+
+ /* The following function copies `num_out' elements from `glyph_data'
+ to `out', advancing the array pointer in the `in' structure by
+ `num_in' elements, and in `out' by `num_out' elements. If the
+ string (resp. the properties) array in `out' is empty or too
+ small, it allocates resp. reallocates the string (and properties)
+ array. Finally, it sets the `length' field of `out' equal to
+ `pos' of the `out' structure.
+
+ If `component' is 0xFFFF, the value `in->component[in->pos]'
+ will be copied `num_out' times, otherwise `component' itself will
+ be used to fill `out->component'.
+
+ If `ligID' is 0xFFFF, the value `in->lig_IDs[in->pos]' will be
+ copied `num_out' times, otherwise `ligID' itself will be used to
+ fill `out->ligIDs'.
+
+ The properties (if defined) for all replaced glyphs are taken
+ from the glyph at position `in->pos'.
+
+ The logClusters[] value for the glyph at position in->pos is used
+ for all replacement glyphs */
+
+ EXPORT_FUNC
+ FT_Error TT_GSUB_Add_String( TTO_GSUB_String* in,
+ FT_UShort num_in,
+ TTO_GSUB_String* out,
+ FT_UShort num_out,
+ FT_UShort* glyph_data,
+ FT_UShort component,
+ FT_UShort ligID )
+ {
+ FT_Memory memory = in->memory;
+ FT_Error error;
+ FT_UShort i;
+ FT_UShort p_in;
+ FT_UShort*p_out;
+
+
+ /* sanity check */
+
+ if ( !in || !out ||
+ in->length == 0 || in->pos >= in->length ||
+ in->length < in->pos + num_in )
+ return TT_Err_Invalid_Argument;
+
+ if ( out->pos + num_out >= out->allocated )
+ {
+ FT_ULong size = out->pos + num_out + 256L;
+
+
+ /* The following works because all fields in `out' must be
+ initialized to zero (including the `string' field) for the
+ first use. */
+
+ if ( REALLOC_ARRAY( out->string, out->allocated, size, FT_UShort ) )
+ return error;
+ if ( REALLOC_ARRAY( out->components, out->allocated, size, FT_UShort ) )
+ return error;
+ if ( REALLOC_ARRAY( out->ligIDs, out->allocated, size, FT_UShort ) )
+ return error;
+ if ( in->properties )
+ if ( REALLOC_ARRAY( out->properties, out->allocated, size, FT_UShort ) )
+ return error;
+ if ( REALLOC_ARRAY( out->logClusters, out->allocated, size, FT_Int ) )
+ return error;
+
+ out->allocated = size;
+ }
+
+ if ( num_out )
+ {
+ MEM_Copy( &out->string[out->pos], glyph_data,
+ num_out * sizeof ( FT_UShort ) );
+
+ if ( component == 0xFFFF )
+ component = in->components[in->pos];
+
+ p_out = out->components;
+
+ for ( i = out->pos; i < out->pos + num_out; i++ )
+ p_out[i] = component;
+
+ p_out = out->ligIDs;
+
+ if ( ligID == 0xFFFF )
+ ligID = in->ligIDs[in->pos];
+
+ for ( i = out->pos; i < out->pos + num_out; i++ )
+ p_out[i] = ligID;
+
+ if ( in->properties )
+ {
+ p_in = in->properties[in->pos];
+ p_out = out->properties;
+
+ for ( i = out->pos; i < out->pos + num_out; i++ )
+ p_out[i] = p_in;
+ }
+
+ for ( i = out->pos; i < out->pos + num_out; i++ )
+ out->logClusters[i] = in->logClusters[in->pos];
+ }
+
+ in->pos += num_in;
+ out->pos += num_out;
+
+ out->length = out->pos;
+
+ return TT_Err_Ok;
+ }
+
+
+#if 0
+
+ /**********************
+ * Extension Functions
+ **********************/
+
+
+ static FT_Error GSUB_Create( void* ext,
+ PFace face )
+ {
+ DEFINE_LOAD_LOCALS( face->stream );
+
+ TTO_GSUBHeader* gsub = (TTO_GSUBHeader*)ext;
+ Long table;
+
+
+ /* by convention */
+
+ if ( !gsub )
+ return TT_Err_Ok;
+
+ /* a null offset indicates that there is no GSUB table */
+
+ gsub->offset = 0;
+
+ /* we store the start offset and the size of the subtable */
+
+ table = TT_LookUp_Table( face, TTAG_GSUB );
+ if ( table < 0 )
+ return TT_Err_Ok; /* The table is optional */
+
+ if ( FILE_Seek( face->dirTables[table].Offset ) ||
+ ACCESS_Frame( 4L ) )
+ return error;
+
+ gsub->offset = FILE_Pos() - 4L; /* undo ACCESS_Frame() */
+ gsub->Version = GET_ULong();
+
+ FORGET_Frame();
+
+ gsub->loaded = FALSE;
+
+ return TT_Err_Ok;
+ }
+
+
+ static FT_Error GSUB_Destroy( void* ext,
+ PFace face )
+ {
+ TTO_GSUBHeader* gsub = (TTO_GSUBHeader*)ext;
+
+
+ /* by convention */
+
+ if ( !gsub )
+ return TT_Err_Ok;
+
+ if ( gsub->loaded )
+ {
+ Free_LookupList( &gsub->LookupList, GSUB, memory );
+ Free_FeatureList( &gsub->FeatureList, memory );
+ Free_ScriptList( &gsub->ScriptList, memory );
+ }
+
+ return TT_Err_Ok;
+ }
+
+
+ EXPORT_FUNC
+ FT_Error TT_Init_GSUB_Extension( TT_Engine engine )
+ {
+ PEngine_Instance _engine = HANDLE_Engine( engine );
+
+
+ if ( !_engine )
+ return TT_Err_Invalid_Engine;
+
+ return TT_Register_Extension( _engine,
+ GSUB_ID,
+ sizeof ( TTO_GSUBHeader ),
+ GSUB_Create,
+ GSUB_Destroy );
+ }
+#endif
+
+ EXPORT_FUNC
+ FT_Error TT_Load_GSUB_Table( FT_Face face,
+ TTO_GSUBHeader** retptr,
+ TTO_GDEFHeader* gdef )
+ {
+ FT_Stream stream = face->stream;
+ FT_Memory memory = face->memory;
+ FT_Error error;
+ FT_ULong cur_offset, new_offset, base_offset;
+ TT_Face tt_face = (TT_Face)face;
+
+ FT_UShort i, num_lookups;
+ TTO_GSUBHeader* gsub;
+ TTO_Lookup* lo;
+
+ if ( !retptr )
+ return TT_Err_Invalid_Argument;
+
+ if (( error = tt_face->goto_table( tt_face, TTAG_GSUB, stream, 0 ) ))
+ return error;
+
+ base_offset = FILE_Pos();
+
+ if ( ALLOC ( gsub, sizeof( *gsub ) ) )
+ return error;
+
+ gsub->memory = memory;
+
+ /* skip version */
+
+ if ( FILE_Seek( base_offset + 4L ) ||
+ ACCESS_Frame( 2L ) )
+ goto Fail4;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_ScriptList( &gsub->ScriptList,
+ stream ) ) != TT_Err_Ok )
+ goto Fail4;
+ (void)FILE_Seek( cur_offset );
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail3;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_FeatureList( &gsub->FeatureList,
+ stream ) ) != TT_Err_Ok )
+ goto Fail3;
+ (void)FILE_Seek( cur_offset );
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail2;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_LookupList( &gsub->LookupList,
+ stream, GSUB ) ) != TT_Err_Ok )
+ goto Fail2;
+
+ gsub->gdef = gdef; /* can be NULL */
+
+ /* We now check the LookupFlags for values larger than 0xFF to find
+ out whether we need to load the `MarkAttachClassDef' field of the
+ GDEF table -- this hack is necessary for OpenType 1.2 tables since
+ the version field of the GDEF table hasn't been incremented.
+
+ For constructed GDEF tables, we only load it if
+ `MarkAttachClassDef_offset' is not zero (nevertheless, a build of
+ a constructed mark attach table is not supported currently). */
+
+ if ( gdef &&
+ gdef->MarkAttachClassDef_offset && !gdef->MarkAttachClassDef.loaded )
+ {
+ lo = gsub->LookupList.Lookup;
+ num_lookups = gsub->LookupList.LookupCount;
+
+ for ( i = 0; i < num_lookups; i++ )
+ {
+
+ if ( lo[i].LookupFlag & IGNORE_SPECIAL_MARKS )
+ {
+ if ( FILE_Seek( gdef->MarkAttachClassDef_offset ) ||
+ ( error = Load_ClassDefinition( &gdef->MarkAttachClassDef,
+ 256, stream ) ) != TT_Err_Ok )
+ goto Fail1;
+
+ break;
+ }
+ }
+ }
+
+ *retptr = gsub;
+
+ return TT_Err_Ok;
+
+ Fail1:
+ Free_LookupList( &gsub->LookupList, GSUB, memory );
+
+ Fail2:
+ Free_FeatureList( &gsub->FeatureList, memory );
+
+ Fail3:
+ Free_ScriptList( &gsub->ScriptList, memory );
+
+ Fail4:
+ FREE ( gsub );
+
+
+ return error;
+ }
+
+ EXPORT_FUNC
+ FT_Error TT_Done_GSUB_Table( TTO_GSUBHeader* gsub )
+ {
+ FT_Memory memory = gsub->memory;
+
+ Free_LookupList( &gsub->LookupList, GSUB, memory );
+ Free_FeatureList( &gsub->FeatureList, memory );
+ Free_ScriptList( &gsub->ScriptList, memory );
+
+ FREE( gsub );
+
+ return TT_Err_Ok;
+ }
+
+ /*****************************
+ * SubTable related functions
+ *****************************/
+
+
+ /* LookupType 1 */
+
+ /* SingleSubstFormat1 */
+ /* SingleSubstFormat2 */
+
+ FT_Error Load_SingleSubst( TTO_SingleSubst* ss,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ FT_UShort* s;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 4L ) )
+ return error;
+
+ ss->SubstFormat = GET_UShort();
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Coverage( &ss->Coverage, stream ) ) != TT_Err_Ok )
+ return error;
+ (void)FILE_Seek( cur_offset );
+
+ switch ( ss->SubstFormat )
+ {
+ case 1:
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail2;
+
+ ss->ssf.ssf1.DeltaGlyphID = GET_UShort();
+
+ FORGET_Frame();
+
+ break;
+
+ case 2:
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail2;
+
+ count = ss->ssf.ssf2.GlyphCount = GET_UShort();
+
+ FORGET_Frame();
+
+ ss->ssf.ssf2.Substitute = NULL;
+
+ if ( ALLOC_ARRAY( ss->ssf.ssf2.Substitute, count, FT_UShort ) )
+ goto Fail2;
+
+ s = ss->ssf.ssf2.Substitute;
+
+ if ( ACCESS_Frame( count * 2L ) )
+ goto Fail1;
+
+ for ( n = 0; n < count; n++ )
+ s[n] = GET_UShort();
+
+ FORGET_Frame();
+
+ break;
+
+ default:
+ return TTO_Err_Invalid_GSUB_SubTable_Format;
+ }
+
+ return TT_Err_Ok;
+
+ Fail1:
+ FREE( s );
+
+ Fail2:
+ Free_Coverage( &ss->Coverage, memory );
+ return error;
+ }
+
+
+ void Free_SingleSubst( TTO_SingleSubst* ss,
+ FT_Memory memory )
+ {
+ switch ( ss->SubstFormat )
+ {
+ case 1:
+ break;
+
+ case 2:
+ FREE( ss->ssf.ssf2.Substitute );
+ break;
+ }
+
+ Free_Coverage( &ss->Coverage, memory );
+ }
+
+
+ static FT_Error Lookup_SingleSubst( TTO_SingleSubst* ss,
+ TTO_GSUB_String* in,
+ TTO_GSUB_String* out,
+ FT_UShort flags,
+ FT_UShort context_length,
+ TTO_GDEFHeader* gdef )
+ {
+ FT_UShort index, value[1], property;
+ FT_Error error;
+
+
+ if ( context_length != 0xFFFF && context_length < 1 )
+ return TTO_Err_Not_Covered;
+
+ if ( CHECK_Property( gdef, in->string[in->pos], flags, &property ) )
+ return error;
+
+ error = Coverage_Index( &ss->Coverage, in->string[in->pos], &index );
+ if ( error )
+ return error;
+
+ switch ( ss->SubstFormat )
+ {
+ case 1:
+ value[0] = ( in->string[in->pos] + ss->ssf.ssf1.DeltaGlyphID ) & 0xFFFF;
+ if ( ADD_String( in, 1, out, 1, value, 0xFFFF, 0xFFFF ) )
+ return error;
+ break;
+
+ case 2:
+ if ( index >= ss->ssf.ssf2.GlyphCount )
+ return TTO_Err_Invalid_GSUB_SubTable;
+ value[0] = ss->ssf.ssf2.Substitute[index];
+ if ( ADD_String( in, 1, out, 1, value, 0xFFFF, 0xFFFF ) )
+ return error;
+ break;
+
+ default:
+ return TTO_Err_Invalid_GSUB_SubTable;
+ }
+
+ if ( gdef && gdef->NewGlyphClasses )
+ {
+ /* we inherit the old glyph class to the substituted glyph */
+
+ error = Add_Glyph_Property( gdef, value[0], property );
+ if ( error && error != TTO_Err_Not_Covered )
+ return error;
+ }
+
+ return TT_Err_Ok;
+ }
+
+
+ /* LookupType 2 */
+
+ /* Sequence */
+
+ static FT_Error Load_Sequence( TTO_Sequence* s,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, count;
+ FT_UShort* sub;
+
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ count = s->GlyphCount = GET_UShort();
+
+ FORGET_Frame();
+
+ s->Substitute = NULL;
+
+ if ( count )
+ {
+ if ( ALLOC_ARRAY( s->Substitute, count, FT_UShort ) )
+ return error;
+
+ sub = s->Substitute;
+
+ if ( ACCESS_Frame( count * 2L ) )
+ {
+ FREE( sub );
+ return error;
+ }
+
+ for ( n = 0; n < count; n++ )
+ sub[n] = GET_UShort();
+
+ FORGET_Frame();
+ }
+
+ return TT_Err_Ok;
+ }
+
+
+ static void Free_Sequence( TTO_Sequence* s,
+ FT_Memory memory )
+ {
+ FREE( s->Substitute );
+ }
+
+
+ /* MultipleSubstFormat1 */
+
+ FT_Error Load_MultipleSubst( TTO_MultipleSubst* ms,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n = 0, m, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_Sequence* s;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 4L ) )
+ return error;
+
+ ms->SubstFormat = GET_UShort(); /* should be 1 */
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Coverage( &ms->Coverage, stream ) ) != TT_Err_Ok )
+ return error;
+ (void)FILE_Seek( cur_offset );
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail2;
+
+ count = ms->SequenceCount = GET_UShort();
+
+ FORGET_Frame();
+
+ ms->Sequence = NULL;
+
+ if ( ALLOC_ARRAY( ms->Sequence, count, TTO_Sequence ) )
+ goto Fail2;
+
+ s = ms->Sequence;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail1;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Sequence( &s[n], stream ) ) != TT_Err_Ok )
+ goto Fail1;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ return TT_Err_Ok;
+
+ Fail1:
+ for ( m = 0; m < n; m++ )
+ Free_Sequence( &s[m], memory );
+
+ FREE( s );
+
+ Fail2:
+ Free_Coverage( &ms->Coverage, memory );
+ return error;
+ }
+
+
+ void Free_MultipleSubst( TTO_MultipleSubst* ms,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_Sequence* s;
+
+
+ if ( ms->Sequence )
+ {
+ count = ms->SequenceCount;
+ s = ms->Sequence;
+
+ for ( n = 0; n < count; n++ )
+ Free_Sequence( &s[n], memory );
+
+ FREE( s );
+ }
+
+ Free_Coverage( &ms->Coverage, memory );
+ }
+
+
+ static FT_Error Lookup_MultipleSubst( TTO_MultipleSubst* ms,
+ TTO_GSUB_String* in,
+ TTO_GSUB_String* out,
+ FT_UShort flags,
+ FT_UShort context_length,
+ TTO_GDEFHeader* gdef )
+ {
+ FT_Error error;
+ FT_UShort index, property, n, count;
+ FT_UShort*s;
+
+
+ if ( context_length != 0xFFFF && context_length < 1 )
+ return TTO_Err_Not_Covered;
+
+ if ( CHECK_Property( gdef, in->string[in->pos], flags, &property ) )
+ return error;
+
+ error = Coverage_Index( &ms->Coverage, in->string[in->pos], &index );
+ if ( error )
+ return error;
+
+ if ( index >= ms->SequenceCount )
+ return TTO_Err_Invalid_GSUB_SubTable;
+
+ count = ms->Sequence[index].GlyphCount;
+ s = ms->Sequence[index].Substitute;
+
+ if ( ADD_String( in, 1, out, count, s, 0xFFFF, 0xFFFF ) )
+ return error;
+
+ if ( gdef && gdef->NewGlyphClasses )
+ {
+ /* this is a guess only ... */
+
+ if ( property == TTO_LIGATURE )
+ property = TTO_BASE_GLYPH;
+
+ for ( n = 0; n < count; n++ )
+ {
+ error = Add_Glyph_Property( gdef, s[n], property );
+ if ( error && error != TTO_Err_Not_Covered )
+ return error;
+ }
+ }
+
+ return TT_Err_Ok;
+ }
+
+
+ /* LookupType 3 */
+
+ /* AlternateSet */
+
+ static FT_Error Load_AlternateSet( TTO_AlternateSet* as,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, count;
+ FT_UShort* a;
+
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ count = as->GlyphCount = GET_UShort();
+
+ FORGET_Frame();
+
+ as->Alternate = NULL;
+
+ if ( ALLOC_ARRAY( as->Alternate, count, FT_UShort ) )
+ return error;
+
+ a = as->Alternate;
+
+ if ( ACCESS_Frame( count * 2L ) )
+ {
+ FREE( a );
+ return error;
+ }
+
+ for ( n = 0; n < count; n++ )
+ a[n] = GET_UShort();
+
+ FORGET_Frame();
+
+ return TT_Err_Ok;
+ }
+
+
+ static void Free_AlternateSet( TTO_AlternateSet* as,
+ FT_Memory memory )
+ {
+ FREE( as->Alternate );
+ }
+
+
+ /* AlternateSubstFormat1 */
+
+ FT_Error Load_AlternateSubst( TTO_AlternateSubst* as,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n = 0, m, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_AlternateSet* aset;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 4L ) )
+ return error;
+
+ as->SubstFormat = GET_UShort(); /* should be 1 */
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Coverage( &as->Coverage, stream ) ) != TT_Err_Ok )
+ return error;
+ (void)FILE_Seek( cur_offset );
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail2;
+
+ count = as->AlternateSetCount = GET_UShort();
+
+ FORGET_Frame();
+
+ as->AlternateSet = NULL;
+
+ if ( ALLOC_ARRAY( as->AlternateSet, count, TTO_AlternateSet ) )
+ goto Fail2;
+
+ aset = as->AlternateSet;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail1;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_AlternateSet( &aset[n], stream ) ) != TT_Err_Ok )
+ goto Fail1;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ return TT_Err_Ok;
+
+ Fail1:
+ for ( m = 0; m < n; m++ )
+ Free_AlternateSet( &aset[m], memory );
+
+ FREE( aset );
+
+ Fail2:
+ Free_Coverage( &as->Coverage, memory );
+ return error;
+ }
+
+
+ void Free_AlternateSubst( TTO_AlternateSubst* as,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_AlternateSet* aset;
+
+
+ if ( as->AlternateSet )
+ {
+ count = as->AlternateSetCount;
+ aset = as->AlternateSet;
+
+ for ( n = 0; n < count; n++ )
+ Free_AlternateSet( &aset[n], memory );
+
+ FREE( aset );
+ }
+
+ Free_Coverage( &as->Coverage, memory );
+ }
+
+
+ static FT_Error Lookup_AlternateSubst( TTO_GSUBHeader* gsub,
+ TTO_AlternateSubst* as,
+ TTO_GSUB_String* in,
+ TTO_GSUB_String* out,
+ FT_UShort flags,
+ FT_UShort context_length,
+ TTO_GDEFHeader* gdef )
+ {
+ FT_Error error;
+ FT_UShort index, alt_index, property;
+
+ TTO_AlternateSet aset;
+
+
+ if ( context_length != 0xFFFF && context_length < 1 )
+ return TTO_Err_Not_Covered;
+
+ if ( CHECK_Property( gdef, in->string[in->pos], flags, &property ) )
+ return error;
+
+ error = Coverage_Index( &as->Coverage, in->string[in->pos], &index );
+ if ( error )
+ return error;
+
+ aset = as->AlternateSet[index];
+
+ /* we use a user-defined callback function to get the alternate index */
+
+ if ( gsub->altfunc )
+ alt_index = (gsub->altfunc)( out->pos, in->string[in->pos],
+ aset.GlyphCount, aset.Alternate,
+ gsub->data );
+ else
+ alt_index = 0;
+
+ if ( ADD_String( in, 1, out, 1, &aset.Alternate[alt_index],
+ 0xFFFF, 0xFFFF ) )
+ return error;
+
+ if ( gdef && gdef->NewGlyphClasses )
+ {
+ /* we inherit the old glyph class to the substituted glyph */
+
+ error = Add_Glyph_Property( gdef, aset.Alternate[alt_index],
+ property );
+ if ( error && error != TTO_Err_Not_Covered )
+ return error;
+ }
+
+ return TT_Err_Ok;
+ }
+
+
+ /* LookupType 4 */
+
+ /* Ligature */
+
+ static FT_Error Load_Ligature( TTO_Ligature* l,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, count;
+ FT_UShort* c;
+
+
+ if ( ACCESS_Frame( 4L ) )
+ return error;
+
+ l->LigGlyph = GET_UShort();
+ l->ComponentCount = GET_UShort();
+
+ FORGET_Frame();
+
+ l->Component = NULL;
+
+ count = l->ComponentCount - 1; /* only ComponentCount - 1 elements */
+
+ if ( ALLOC_ARRAY( l->Component, count, FT_UShort ) )
+ return error;
+
+ c = l->Component;
+
+ if ( ACCESS_Frame( count * 2L ) )
+ {
+ FREE( c );
+ return error;
+ }
+
+ for ( n = 0; n < count; n++ )
+ c[n] = GET_UShort();
+
+ FORGET_Frame();
+
+ return TT_Err_Ok;
+ }
+
+
+ static void Free_Ligature( TTO_Ligature* l,
+ FT_Memory memory )
+ {
+ FREE( l->Component );
+ }
+
+
+ /* LigatureSet */
+
+ static FT_Error Load_LigatureSet( TTO_LigatureSet* ls,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n = 0, m, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_Ligature* l;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ count = ls->LigatureCount = GET_UShort();
+
+ FORGET_Frame();
+
+ ls->Ligature = NULL;
+
+ if ( ALLOC_ARRAY( ls->Ligature, count, TTO_Ligature ) )
+ return error;
+
+ l = ls->Ligature;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Ligature( &l[n], stream ) ) != TT_Err_Ok )
+ goto Fail;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ return TT_Err_Ok;
+
+ Fail:
+ for ( m = 0; m < n; m++ )
+ Free_Ligature( &l[m], memory );
+
+ FREE( l );
+ return error;
+ }
+
+
+ static void Free_LigatureSet( TTO_LigatureSet* ls,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_Ligature* l;
+
+
+ if ( ls->Ligature )
+ {
+ count = ls->LigatureCount;
+ l = ls->Ligature;
+
+ for ( n = 0; n < count; n++ )
+ Free_Ligature( &l[n], memory );
+
+ FREE( l );
+ }
+ }
+
+
+ /* LigatureSubstFormat1 */
+
+ FT_Error Load_LigatureSubst( TTO_LigatureSubst* ls,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n = 0, m, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_LigatureSet* lset;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 4L ) )
+ return error;
+
+ ls->SubstFormat = GET_UShort(); /* should be 1 */
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Coverage( &ls->Coverage, stream ) ) != TT_Err_Ok )
+ return error;
+ (void)FILE_Seek( cur_offset );
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail2;
+
+ count = ls->LigatureSetCount = GET_UShort();
+
+ FORGET_Frame();
+
+ ls->LigatureSet = NULL;
+
+ if ( ALLOC_ARRAY( ls->LigatureSet, count, TTO_LigatureSet ) )
+ goto Fail2;
+
+ lset = ls->LigatureSet;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail1;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_LigatureSet( &lset[n], stream ) ) != TT_Err_Ok )
+ goto Fail1;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ return TT_Err_Ok;
+
+ Fail1:
+ for ( m = 0; m < n; m++ )
+ Free_LigatureSet( &lset[m], memory );
+
+ FREE( lset );
+
+ Fail2:
+ Free_Coverage( &ls->Coverage, memory );
+ return error;
+ }
+
+
+ void Free_LigatureSubst( TTO_LigatureSubst* ls,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_LigatureSet* lset;
+
+
+ if ( ls->LigatureSet )
+ {
+ count = ls->LigatureSetCount;
+ lset = ls->LigatureSet;
+
+ for ( n = 0; n < count; n++ )
+ Free_LigatureSet( &lset[n], memory );
+
+ FREE( lset );
+ }
+
+ Free_Coverage( &ls->Coverage, memory );
+ }
+
+
+ static FT_Error Lookup_LigatureSubst( TTO_LigatureSubst* ls,
+ TTO_GSUB_String* in,
+ TTO_GSUB_String* out,
+ FT_UShort flags,
+ FT_UShort context_length,
+ TTO_GDEFHeader* gdef )
+ {
+ FT_UShort index, property;
+ FT_Error error;
+ FT_UShort numlig, i, j, is_mark, first_is_mark = FALSE;
+ FT_UShort* s_in;
+ FT_UShort* c;
+
+ TTO_Ligature* lig;
+
+
+ if ( CHECK_Property( gdef, in->string[in->pos], flags, &property ) )
+ return error;
+
+ if ( property == TTO_MARK || property & IGNORE_SPECIAL_MARKS )
+ first_is_mark = TRUE;
+
+ error = Coverage_Index( &ls->Coverage, in->string[in->pos], &index );
+ if ( error )
+ return error;
+
+ if ( index >= ls->LigatureSetCount )
+ return TTO_Err_Invalid_GSUB_SubTable;
+
+ lig = ls->LigatureSet[index].Ligature;
+
+ for ( numlig = ls->LigatureSet[index].LigatureCount;
+ numlig;
+ numlig--, lig++ )
+ {
+ if ( in->pos + lig->ComponentCount > in->length )
+ continue; /* Not enough glyphs in input */
+
+ s_in = &in->string[in->pos];
+ c = lig->Component;
+
+ is_mark = first_is_mark;
+
+ if ( context_length != 0xFFFF && context_length < lig->ComponentCount )
+ break;
+
+ for ( i = 1, j = 1; i < lig->ComponentCount; i++, j++ )
+ {
+ while ( CHECK_Property( gdef, s_in[j], flags, &property ) )
+ {
+ if ( error && error != TTO_Err_Not_Covered )
+ return error;
+
+ if ( in->pos + j < in->length )
+ j++;
+ else
+ break;
+ }
+
+ if ( !( property == TTO_MARK || property & IGNORE_SPECIAL_MARKS ) )
+ is_mark = FALSE;
+
+ if ( s_in[j] != c[i - 1] )
+ break;
+ }
+
+ if ( i == lig->ComponentCount )
+ {
+ if ( gdef && gdef->NewGlyphClasses )
+ {
+ /* this is just a guess ... */
+
+ error = Add_Glyph_Property( gdef, lig->LigGlyph,
+ is_mark ? TTO_MARK : TTO_LIGATURE );
+ if ( error && error != TTO_Err_Not_Covered )
+ return error;
+ }
+
+ if ( i == j )
+ {
+ /* We don't use a new ligature ID if there are no skipped
+ glyphs and the ligature already has an ID. */
+
+ if ( in->ligIDs[in->pos] )
+ {
+ if ( ADD_String( in, i, out, 1, &lig->LigGlyph,
+ 0xFFFF, 0xFFFF ) )
+ return error;
+ }
+ else
+ {
+ if ( ADD_String( in, i, out, 1, &lig->LigGlyph,
+ 0xFFFF, in->max_ligID ) )
+ return error;
+
+ (in->max_ligID)++;
+ }
+ }
+ else
+ {
+ if ( ADD_String( in, 1, out, 1, &lig->LigGlyph,
+ 0xFFFF, in->max_ligID ) )
+ return error;
+
+ /* Now we must do a second loop to copy the skipped glyphs to
+ `out' and assign component values to it. We start with the
+ glyph after the first component. Glyphs between component
+ i and i+1 belong to component i. Together with the ligID
+ value it is later possible to check whether a specific
+ component value really belongs to a given ligature. */
+
+ for ( i = 0; i < lig->ComponentCount - 1; i++ )
+ {
+ while ( CHECK_Property( gdef, in->string[in->pos],
+ flags, &property ) )
+ if ( ADD_String( in, 1, out, 1, &in->string[in->pos],
+ i, in->max_ligID ) )
+ return error;
+
+ (in->pos)++;
+ }
+
+ (in->max_ligID)++;
+ }
+
+ return TT_Err_Ok;
+ }
+ }
+
+ return TTO_Err_Not_Covered;
+ }
+
+
+ /* Do the actual substitution for a context substitution (either format
+ 5 or 6). This is only called after we've determined that the input
+ matches the subrule. */
+
+ static FT_Error Do_ContextSubst( TTO_GSUBHeader* gsub,
+ FT_UShort GlyphCount,
+ FT_UShort SubstCount,
+ TTO_SubstLookupRecord* subst,
+ TTO_GSUB_String* in,
+ TTO_GSUB_String* out,
+ int nesting_level )
+ {
+ FT_Error error;
+ FT_UShort i, old_pos;
+
+
+ i = 0;
+
+ while ( i < GlyphCount )
+ {
+ if ( SubstCount && i == subst->SequenceIndex )
+ {
+ old_pos = in->pos;
+
+ /* Do a substitution */
+
+ error = gsub_Do_Glyph_Lookup( gsub, subst->LookupListIndex, in, out,
+ GlyphCount, nesting_level );
+
+ subst++;
+ SubstCount--;
+ i += in->pos - old_pos;
+
+ if ( error == TTO_Err_Not_Covered )
+ {
+ /* XXX "can't happen" -- but don't count on it */
+
+ if ( ADD_String( in, 1, out, 1, &in->string[in->pos],
+ 0xFFFF, 0xFFFF ) )
+ return error;
+ i++;
+ }
+ else if ( error )
+ return error;
+ }
+ else
+ {
+ /* No substitution for this index */
+
+ if ( ADD_String( in, 1, out, 1, &in->string[in->pos],
+ 0xFFFF, 0xFFFF ) )
+ return error;
+ i++;
+ }
+ }
+
+ return TT_Err_Ok;
+ }
+
+
+ /* LookupType 5 */
+
+ /* SubRule */
+
+ static FT_Error Load_SubRule( TTO_SubRule* sr,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, count;
+ FT_UShort* i;
+
+ TTO_SubstLookupRecord* slr;
+
+
+ if ( ACCESS_Frame( 4L ) )
+ return error;
+
+ sr->GlyphCount = GET_UShort();
+ sr->SubstCount = GET_UShort();
+
+ FORGET_Frame();
+
+ sr->Input = NULL;
+
+ count = sr->GlyphCount - 1; /* only GlyphCount - 1 elements */
+
+ if ( ALLOC_ARRAY( sr->Input, count, FT_UShort ) )
+ return error;
+
+ i = sr->Input;
+
+ if ( ACCESS_Frame( count * 2L ) )
+ goto Fail2;
+
+ for ( n = 0; n < count; n++ )
+ i[n] = GET_UShort();
+
+ FORGET_Frame();
+
+ sr->SubstLookupRecord = NULL;
+
+ count = sr->SubstCount;
+
+ if ( ALLOC_ARRAY( sr->SubstLookupRecord, count, TTO_SubstLookupRecord ) )
+ goto Fail2;
+
+ slr = sr->SubstLookupRecord;
+
+ if ( ACCESS_Frame( count * 4L ) )
+ goto Fail1;
+
+ for ( n = 0; n < count; n++ )
+ {
+ slr[n].SequenceIndex = GET_UShort();
+ slr[n].LookupListIndex = GET_UShort();
+ }
+
+ FORGET_Frame();
+
+ return TT_Err_Ok;
+
+ Fail1:
+ FREE( slr );
+
+ Fail2:
+ FREE( i );
+ return error;
+ }
+
+
+ static void Free_SubRule( TTO_SubRule* sr,
+ FT_Memory memory )
+ {
+ FREE( sr->SubstLookupRecord );
+ FREE( sr->Input );
+ }
+
+
+ /* SubRuleSet */
+
+ static FT_Error Load_SubRuleSet( TTO_SubRuleSet* srs,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n = 0, m, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_SubRule* sr;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ count = srs->SubRuleCount = GET_UShort();
+
+ FORGET_Frame();
+
+ srs->SubRule = NULL;
+
+ if ( ALLOC_ARRAY( srs->SubRule, count, TTO_SubRule ) )
+ return error;
+
+ sr = srs->SubRule;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_SubRule( &sr[n], stream ) ) != TT_Err_Ok )
+ goto Fail;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ return TT_Err_Ok;
+
+ Fail:
+ for ( m = 0; m < n; m++ )
+ Free_SubRule( &sr[m], memory );
+
+ FREE( sr );
+ return error;
+ }
+
+
+ static void Free_SubRuleSet( TTO_SubRuleSet* srs,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_SubRule* sr;
+
+
+ if ( srs->SubRule )
+ {
+ count = srs->SubRuleCount;
+ sr = srs->SubRule;
+
+ for ( n = 0; n < count; n++ )
+ Free_SubRule( &sr[n], memory );
+
+ FREE( sr );
+ }
+ }
+
+
+ /* ContextSubstFormat1 */
+
+ static FT_Error Load_ContextSubst1( TTO_ContextSubstFormat1* csf1,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n = 0, m, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_SubRuleSet* srs;
+
+
+ base_offset = FILE_Pos() - 2L;
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Coverage( &csf1->Coverage, stream ) ) != TT_Err_Ok )
+ return error;
+ (void)FILE_Seek( cur_offset );
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail2;
+
+ count = csf1->SubRuleSetCount = GET_UShort();
+
+ FORGET_Frame();
+
+ csf1->SubRuleSet = NULL;
+
+ if ( ALLOC_ARRAY( csf1->SubRuleSet, count, TTO_SubRuleSet ) )
+ goto Fail2;
+
+ srs = csf1->SubRuleSet;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail1;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_SubRuleSet( &srs[n], stream ) ) != TT_Err_Ok )
+ goto Fail1;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ return TT_Err_Ok;
+
+ Fail1:
+ for ( m = 0; m < n; m++ )
+ Free_SubRuleSet( &srs[m], memory );
+
+ FREE( srs );
+
+ Fail2:
+ Free_Coverage( &csf1->Coverage, memory );
+ return error;
+ }
+
+
+ static void gsub_Free_Context1( TTO_ContextSubstFormat1* csf1,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_SubRuleSet* srs;
+
+
+ if ( csf1->SubRuleSet )
+ {
+ count = csf1->SubRuleSetCount;
+ srs = csf1->SubRuleSet;
+
+ for ( n = 0; n < count; n++ )
+ Free_SubRuleSet( &srs[n], memory );
+
+ FREE( srs );
+ }
+
+ Free_Coverage( &csf1->Coverage, memory );
+ }
+
+
+ /* SubClassRule */
+
+ static FT_Error Load_SubClassRule( TTO_ContextSubstFormat2* csf2,
+ TTO_SubClassRule* scr,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, count;
+
+ FT_UShort* c;
+ TTO_SubstLookupRecord* slr;
+ FT_Bool* d;
+
+
+ if ( ACCESS_Frame( 4L ) )
+ return error;
+
+ scr->GlyphCount = GET_UShort();
+ scr->SubstCount = GET_UShort();
+
+ if ( scr->GlyphCount > csf2->MaxContextLength )
+ csf2->MaxContextLength = scr->GlyphCount;
+
+ FORGET_Frame();
+
+ scr->Class = NULL;
+
+ count = scr->GlyphCount - 1; /* only GlyphCount - 1 elements */
+
+ if ( ALLOC_ARRAY( scr->Class, count, FT_UShort ) )
+ return error;
+
+ c = scr->Class;
+ d = csf2->ClassDef.Defined;
+
+ if ( ACCESS_Frame( count * 2L ) )
+ goto Fail2;
+
+ for ( n = 0; n < count; n++ )
+ {
+ c[n] = GET_UShort();
+
+ /* We check whether the specific class is used at all. If not,
+ class 0 is used instead. */
+ if ( !d[c[n]] )
+ c[n] = 0;
+ }
+
+ FORGET_Frame();
+
+ scr->SubstLookupRecord = NULL;
+
+ count = scr->SubstCount;
+
+ if ( ALLOC_ARRAY( scr->SubstLookupRecord, count, TTO_SubstLookupRecord ) )
+ goto Fail2;
+
+ slr = scr->SubstLookupRecord;
+
+ if ( ACCESS_Frame( count * 4L ) )
+ goto Fail1;
+
+ for ( n = 0; n < count; n++ )
+ {
+ slr[n].SequenceIndex = GET_UShort();
+ slr[n].LookupListIndex = GET_UShort();
+ }
+
+ FORGET_Frame();
+
+ return TT_Err_Ok;
+
+ Fail1:
+ FREE( slr );
+
+ Fail2:
+ FREE( c );
+ return error;
+ }
+
+
+ static void Free_SubClassRule( TTO_SubClassRule* scr,
+ FT_Memory memory )
+ {
+ FREE( scr->SubstLookupRecord );
+ FREE( scr->Class );
+ }
+
+
+ /* SubClassSet */
+
+ static FT_Error Load_SubClassSet( TTO_ContextSubstFormat2* csf2,
+ TTO_SubClassSet* scs,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n = 0, m, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_SubClassRule* scr;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ count = scs->SubClassRuleCount = GET_UShort();
+
+ FORGET_Frame();
+
+ scs->SubClassRule = NULL;
+
+ if ( ALLOC_ARRAY( scs->SubClassRule, count, TTO_SubClassRule ) )
+ return error;
+
+ scr = scs->SubClassRule;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_SubClassRule( csf2, &scr[n],
+ stream ) ) != TT_Err_Ok )
+ goto Fail;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ return TT_Err_Ok;
+
+ Fail:
+ for ( m = 0; m < n; m++ )
+ Free_SubClassRule( &scr[m], memory );
+
+ FREE( scr );
+ return error;
+ }
+
+
+ static void Free_SubClassSet( TTO_SubClassSet* scs,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_SubClassRule* scr;
+
+
+ if ( scs->SubClassRule )
+ {
+ count = scs->SubClassRuleCount;
+ scr = scs->SubClassRule;
+
+ for ( n = 0; n < count; n++ )
+ Free_SubClassRule( &scr[n], memory );
+
+ FREE( scr );
+ }
+ }
+
+
+ /* ContextSubstFormat2 */
+
+ static FT_Error Load_ContextSubst2( TTO_ContextSubstFormat2* csf2,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n = 0, m, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_SubClassSet* scs;
+
+
+ base_offset = FILE_Pos() - 2;
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Coverage( &csf2->Coverage, stream ) ) != TT_Err_Ok )
+ return error;
+ (void)FILE_Seek( cur_offset );
+
+ if ( ACCESS_Frame( 4L ) )
+ goto Fail3;
+
+ new_offset = GET_UShort() + base_offset;
+
+ /* `SubClassSetCount' is the upper limit for class values, thus we
+ read it now to make an additional safety check. */
+
+ count = csf2->SubClassSetCount = GET_UShort();
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_ClassDefinition( &csf2->ClassDef, count,
+ stream ) ) != TT_Err_Ok )
+ goto Fail3;
+ (void)FILE_Seek( cur_offset );
+
+ csf2->SubClassSet = NULL;
+ csf2->MaxContextLength = 0;
+
+ if ( ALLOC_ARRAY( csf2->SubClassSet, count, TTO_SubClassSet ) )
+ goto Fail2;
+
+ scs = csf2->SubClassSet;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail1;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ if ( new_offset != base_offset ) /* not a NULL offset */
+ {
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_SubClassSet( csf2, &scs[n],
+ stream ) ) != TT_Err_Ok )
+ goto Fail1;
+ (void)FILE_Seek( cur_offset );
+ }
+ else
+ {
+ /* we create a SubClassSet table with no entries */
+
+ csf2->SubClassSet[n].SubClassRuleCount = 0;
+ csf2->SubClassSet[n].SubClassRule = NULL;
+ }
+ }
+
+ return TT_Err_Ok;
+
+ Fail1:
+ for ( m = 0; m < n; m++ )
+ Free_SubClassSet( &scs[m], memory );
+
+ FREE( scs );
+
+ Fail2:
+ Free_ClassDefinition( &csf2->ClassDef, memory );
+
+ Fail3:
+ Free_Coverage( &csf2->Coverage, memory );
+ return error;
+ }
+
+
+ static void gsub_Free_Context2( TTO_ContextSubstFormat2* csf2,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_SubClassSet* scs;
+
+
+ if ( csf2->SubClassSet )
+ {
+ count = csf2->SubClassSetCount;
+ scs = csf2->SubClassSet;
+
+ for ( n = 0; n < count; n++ )
+ Free_SubClassSet( &scs[n], memory );
+
+ FREE( scs );
+ }
+
+ Free_ClassDefinition( &csf2->ClassDef, memory );
+ Free_Coverage( &csf2->Coverage, memory );
+ }
+
+
+ /* ContextSubstFormat3 */
+
+ static FT_Error Load_ContextSubst3( TTO_ContextSubstFormat3* csf3,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n = 0, m, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_Coverage* c;
+ TTO_SubstLookupRecord* slr;
+
+
+ base_offset = FILE_Pos() - 2L;
+
+ if ( ACCESS_Frame( 4L ) )
+ return error;
+
+ csf3->GlyphCount = GET_UShort();
+ csf3->SubstCount = GET_UShort();
+
+ FORGET_Frame();
+
+ csf3->Coverage = NULL;
+
+ count = csf3->GlyphCount;
+
+ if ( ALLOC_ARRAY( csf3->Coverage, count, TTO_Coverage ) )
+ return error;
+
+ c = csf3->Coverage;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail2;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Coverage( &c[n], stream ) ) != TT_Err_Ok )
+ goto Fail2;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ csf3->SubstLookupRecord = NULL;
+
+ count = csf3->SubstCount;
+
+ if ( ALLOC_ARRAY( csf3->SubstLookupRecord, count,
+ TTO_SubstLookupRecord ) )
+ goto Fail2;
+
+ slr = csf3->SubstLookupRecord;
+
+ if ( ACCESS_Frame( count * 4L ) )
+ goto Fail1;
+
+ for ( n = 0; n < count; n++ )
+ {
+ slr[n].SequenceIndex = GET_UShort();
+ slr[n].LookupListIndex = GET_UShort();
+ }
+
+ FORGET_Frame();
+
+ return TT_Err_Ok;
+
+ Fail1:
+ FREE( slr );
+
+ Fail2:
+ for ( m = 0; m < n; m++ )
+ Free_Coverage( &c[m], memory );
+
+ FREE( c );
+ return error;
+ }
+
+
+ static void gsub_Free_Context3( TTO_ContextSubstFormat3* csf3,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_Coverage* c;
+
+
+ FREE( csf3->SubstLookupRecord );
+
+ if ( csf3->Coverage )
+ {
+ count = csf3->GlyphCount;
+ c = csf3->Coverage;
+
+ for ( n = 0; n < count; n++ )
+ Free_Coverage( &c[n], memory );
+
+ FREE( c );
+ }
+ }
+
+
+ /* ContextSubst */
+
+ FT_Error Load_ContextSubst( TTO_ContextSubst* cs,
+ FT_Stream stream )
+ {
+ FT_Error error;
+
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ cs->SubstFormat = GET_UShort();
+
+ FORGET_Frame();
+
+ switch ( cs->SubstFormat )
+ {
+ case 1:
+ return Load_ContextSubst1( &cs->csf.csf1, stream );
+
+ case 2:
+ return Load_ContextSubst2( &cs->csf.csf2, stream );
+
+ case 3:
+ return Load_ContextSubst3( &cs->csf.csf3, stream );
+
+ default:
+ return TTO_Err_Invalid_GSUB_SubTable_Format;
+ }
+
+ return TT_Err_Ok; /* never reached */
+ }
+
+
+ void Free_ContextSubst( TTO_ContextSubst* cs,
+ FT_Memory memory )
+ {
+ switch ( cs->SubstFormat )
+ {
+ case 1:
+ gsub_Free_Context1( &cs->csf.csf1, memory );
+ break;
+
+ case 2:
+ gsub_Free_Context2( &cs->csf.csf2, memory );
+ break;
+
+ case 3:
+ gsub_Free_Context3( &cs->csf.csf3, memory );
+ break;
+ }
+ }
+
+
+ static FT_Error Lookup_ContextSubst1(
+ TTO_GSUBHeader* gsub,
+ TTO_ContextSubstFormat1* csf1,
+ TTO_GSUB_String* in,
+ TTO_GSUB_String* out,
+ FT_UShort flags,
+ FT_UShort context_length,
+ int nesting_level )
+ {
+ FT_UShort index, property;
+ FT_UShort i, j, k, numsr;
+ FT_Error error;
+ FT_UShort* s_in;
+
+ TTO_SubRule* sr;
+ TTO_GDEFHeader* gdef;
+
+
+ gdef = gsub->gdef;
+
+ if ( CHECK_Property( gdef, in->string[in->pos], flags, &property ) )
+ return error;
+
+ error = Coverage_Index( &csf1->Coverage, in->string[in->pos], &index );
+ if ( error )
+ return error;
+
+ sr = csf1->SubRuleSet[index].SubRule;
+ numsr = csf1->SubRuleSet[index].SubRuleCount;
+
+ for ( k = 0; k < numsr; k++ )
+ {
+ if ( context_length != 0xFFFF && context_length < sr[k].GlyphCount )
+ continue;
+
+ if ( in->pos + sr[k].GlyphCount > in->length )
+ continue; /* context is too long */
+
+ s_in = &in->string[in->pos];
+
+ for ( i = 1, j = 1; i < sr[k].GlyphCount; i++, j++ )
+ {
+ while ( CHECK_Property( gdef, s_in[j], flags, &property ) )
+ {
+ if ( error && error != TTO_Err_Not_Covered )
+ return error;
+
+ if ( in->pos + j < in->length )
+ j++;
+ else
+ break;
+ }
+
+ if ( s_in[j] != sr[k].Input[i - 1] )
+ break;
+ }
+
+ if ( i == sr[k].GlyphCount )
+ return Do_ContextSubst( gsub, sr[k].GlyphCount,
+ sr[k].SubstCount, sr[k].SubstLookupRecord,
+ in, out,
+ nesting_level );
+ }
+
+ return TTO_Err_Not_Covered;
+ }
+
+
+ static FT_Error Lookup_ContextSubst2(
+ TTO_GSUBHeader* gsub,
+ TTO_ContextSubstFormat2* csf2,
+ TTO_GSUB_String* in,
+ TTO_GSUB_String* out,
+ FT_UShort flags,
+ FT_UShort context_length,
+ int nesting_level )
+ {
+ FT_UShort index, property;
+ FT_Error error;
+ FT_Memory memory = gsub->memory;
+ FT_UShort i, j, k, known_classes;
+
+ FT_UShort* classes;
+ FT_UShort* s_in;
+ FT_UShort* cl;
+
+ TTO_SubClassSet* scs;
+ TTO_SubClassRule* sr;
+ TTO_GDEFHeader* gdef;
+
+
+ gdef = gsub->gdef;
+
+ if ( CHECK_Property( gdef, in->string[in->pos], flags, &property ) )
+ return error;
+
+ /* Note: The coverage table in format 2 doesn't give an index into
+ anything. It just lets us know whether or not we need to
+ do any lookup at all. */
+
+ error = Coverage_Index( &csf2->Coverage, in->string[in->pos], &index );
+ if ( error )
+ return error;
+
+ if ( ALLOC_ARRAY( classes, csf2->MaxContextLength, FT_UShort ) )
+ return error;
+
+ error = Get_Class( &csf2->ClassDef, in->string[in->pos],
+ &classes[0], NULL );
+ if ( error && error != TTO_Err_Not_Covered )
+ goto End;
+ known_classes = 0;
+
+ scs = &csf2->SubClassSet[classes[0]];
+ if ( !scs )
+ {
+ error = TTO_Err_Invalid_GSUB_SubTable;
+ goto End;
+ }
+
+ for ( k = 0; k < scs->SubClassRuleCount; k++ )
+ {
+ sr = &scs->SubClassRule[k];
+
+ if ( context_length != 0xFFFF && context_length < sr->GlyphCount )
+ continue;
+
+ if ( in->pos + sr->GlyphCount > in->length )
+ continue; /* context is too long */
+
+ s_in = &in->string[in->pos];
+ cl = sr->Class;
+
+ /* Start at 1 because [0] is implied */
+
+ for ( i = 1, j = 1; i < sr->GlyphCount; i++, j++ )
+ {
+ while ( CHECK_Property( gdef, s_in[j], flags, &property ) )
+ {
+ if ( error && error != TTO_Err_Not_Covered )
+ goto End;
+
+ if ( in->pos + j < in->length )
+ j++;
+ else
+ break;
+ }
+
+ if ( i > known_classes )
+ {
+ /* Keeps us from having to do this for each rule */
+
+ error = Get_Class( &csf2->ClassDef, s_in[j], &classes[i], NULL );
+ if ( error && error != TTO_Err_Not_Covered )
+ goto End;
+ known_classes = i;
+ }
+
+ if ( cl[i - 1] != classes[i] )
+ break;
+ }
+
+ if ( i == sr->GlyphCount )
+ {
+ error = Do_ContextSubst( gsub, sr->GlyphCount,
+ sr->SubstCount, sr->SubstLookupRecord,
+ in, out,
+ nesting_level );
+ goto End;
+ }
+ }
+
+ error = TTO_Err_Not_Covered;
+
+ End:
+ FREE( classes );
+ return error;
+ }
+
+
+ static FT_Error Lookup_ContextSubst3(
+ TTO_GSUBHeader* gsub,
+ TTO_ContextSubstFormat3* csf3,
+ TTO_GSUB_String* in,
+ TTO_GSUB_String* out,
+ FT_UShort flags,
+ FT_UShort context_length,
+ int nesting_level )
+ {
+ FT_Error error;
+ FT_UShort index, i, j, property;
+ FT_UShort* s_in;
+
+ TTO_Coverage* c;
+ TTO_GDEFHeader* gdef;
+
+
+ gdef = gsub->gdef;
+
+ if ( CHECK_Property( gdef, in->string[in->pos], flags, &property ) )
+ return error;
+
+ if ( context_length != 0xFFFF && context_length < csf3->GlyphCount )
+ return TTO_Err_Not_Covered;
+
+ if ( in->pos + csf3->GlyphCount > in->length )
+ return TTO_Err_Not_Covered; /* context is too long */
+
+ s_in = &in->string[in->pos];
+ c = csf3->Coverage;
+
+ for ( i = 1, j = 1; i < csf3->GlyphCount; i++, j++ )
+ {
+ while ( CHECK_Property( gdef, s_in[j], flags, &property ) )
+ {
+ if ( error && error != TTO_Err_Not_Covered )
+ return error;
+
+ if ( in->pos + j < in->length )
+ j++;
+ else
+ return TTO_Err_Not_Covered;
+ }
+
+ error = Coverage_Index( &c[i], s_in[j], &index );
+ if ( error )
+ return error;
+ }
+
+ return Do_ContextSubst( gsub, csf3->GlyphCount,
+ csf3->SubstCount, csf3->SubstLookupRecord,
+ in, out,
+ nesting_level );
+ }
+
+
+ static FT_Error Lookup_ContextSubst( TTO_GSUBHeader* gsub,
+ TTO_ContextSubst* cs,
+ TTO_GSUB_String* in,
+ TTO_GSUB_String* out,
+ FT_UShort flags,
+ FT_UShort context_length,
+ int nesting_level )
+ {
+ switch ( cs->SubstFormat )
+ {
+ case 1:
+ return Lookup_ContextSubst1( gsub, &cs->csf.csf1, in, out,
+ flags, context_length, nesting_level );
+
+ case 2:
+ return Lookup_ContextSubst2( gsub, &cs->csf.csf2, in, out,
+ flags, context_length, nesting_level );
+
+ case 3:
+ return Lookup_ContextSubst3( gsub, &cs->csf.csf3, in, out,
+ flags, context_length, nesting_level );
+
+ default:
+ return TTO_Err_Invalid_GSUB_SubTable_Format;
+ }
+
+ return TT_Err_Ok; /* never reached */
+ }
+
+
+ /* LookupType 6 */
+
+ /* ChainSubRule */
+
+ static FT_Error Load_ChainSubRule( TTO_ChainSubRule* csr,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, count;
+ FT_UShort* b;
+ FT_UShort* i;
+ FT_UShort* l;
+
+ TTO_SubstLookupRecord* slr;
+
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ csr->BacktrackGlyphCount = GET_UShort();
+
+ FORGET_Frame();
+
+ csr->Backtrack = NULL;
+
+ count = csr->BacktrackGlyphCount;
+
+ if ( ALLOC_ARRAY( csr->Backtrack, count, FT_UShort ) )
+ return error;
+
+ b = csr->Backtrack;
+
+ if ( ACCESS_Frame( count * 2L ) )
+ goto Fail4;
+
+ for ( n = 0; n < count; n++ )
+ b[n] = GET_UShort();
+
+ FORGET_Frame();
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail4;
+
+ csr->InputGlyphCount = GET_UShort();
+
+ FORGET_Frame();
+
+ csr->Input = NULL;
+
+ count = csr->InputGlyphCount - 1; /* only InputGlyphCount - 1 elements */
+
+ if ( ALLOC_ARRAY( csr->Input, count, FT_UShort ) )
+ goto Fail4;
+
+ i = csr->Input;
+
+ if ( ACCESS_Frame( count * 2L ) )
+ goto Fail3;
+
+ for ( n = 0; n < count; n++ )
+ i[n] = GET_UShort();
+
+ FORGET_Frame();
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail3;
+
+ csr->LookaheadGlyphCount = GET_UShort();
+
+ FORGET_Frame();
+
+ csr->Lookahead = NULL;
+
+ count = csr->LookaheadGlyphCount;
+
+ if ( ALLOC_ARRAY( csr->Lookahead, count, FT_UShort ) )
+ goto Fail3;
+
+ l = csr->Lookahead;
+
+ if ( ACCESS_Frame( count * 2L ) )
+ goto Fail2;
+
+ for ( n = 0; n < count; n++ )
+ l[n] = GET_UShort();
+
+ FORGET_Frame();
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail2;
+
+ csr->SubstCount = GET_UShort();
+
+ FORGET_Frame();
+
+ csr->SubstLookupRecord = NULL;
+
+ count = csr->SubstCount;
+
+ if ( ALLOC_ARRAY( csr->SubstLookupRecord, count, TTO_SubstLookupRecord ) )
+ goto Fail2;
+
+ slr = csr->SubstLookupRecord;
+
+ if ( ACCESS_Frame( count * 4L ) )
+ goto Fail1;
+
+ for ( n = 0; n < count; n++ )
+ {
+ slr[n].SequenceIndex = GET_UShort();
+ slr[n].LookupListIndex = GET_UShort();
+ }
+
+ FORGET_Frame();
+
+ return TT_Err_Ok;
+
+ Fail1:
+ FREE( slr );
+
+ Fail2:
+ FREE( l );
+
+ Fail3:
+ FREE( i );
+
+ Fail4:
+ FREE( b );
+ return error;
+ }
+
+
+ static void Free_ChainSubRule( TTO_ChainSubRule* csr,
+ FT_Memory memory )
+ {
+ FREE( csr->SubstLookupRecord );
+ FREE( csr->Lookahead );
+ FREE( csr->Input );
+ FREE( csr->Backtrack );
+ }
+
+
+ /* ChainSubRuleSet */
+
+ static FT_Error Load_ChainSubRuleSet( TTO_ChainSubRuleSet* csrs,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n = 0, m, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_ChainSubRule* csr;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ count = csrs->ChainSubRuleCount = GET_UShort();
+
+ FORGET_Frame();
+
+ csrs->ChainSubRule = NULL;
+
+ if ( ALLOC_ARRAY( csrs->ChainSubRule, count, TTO_ChainSubRule ) )
+ return error;
+
+ csr = csrs->ChainSubRule;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_ChainSubRule( &csr[n], stream ) ) != TT_Err_Ok )
+ goto Fail;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ return TT_Err_Ok;
+
+ Fail:
+ for ( m = 0; m < n; m++ )
+ Free_ChainSubRule( &csr[m], memory );
+
+ FREE( csr );
+ return error;
+ }
+
+
+ static void Free_ChainSubRuleSet( TTO_ChainSubRuleSet* csrs,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_ChainSubRule* csr;
+
+
+ if ( csrs->ChainSubRule )
+ {
+ count = csrs->ChainSubRuleCount;
+ csr = csrs->ChainSubRule;
+
+ for ( n = 0; n < count; n++ )
+ Free_ChainSubRule( &csr[n], memory );
+
+ FREE( csr );
+ }
+ }
+
+
+ /* ChainContextSubstFormat1 */
+
+ static FT_Error Load_ChainContextSubst1(
+ TTO_ChainContextSubstFormat1* ccsf1,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n = 0, m, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_ChainSubRuleSet* csrs;
+
+
+ base_offset = FILE_Pos() - 2L;
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Coverage( &ccsf1->Coverage, stream ) ) != TT_Err_Ok )
+ return error;
+ (void)FILE_Seek( cur_offset );
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail2;
+
+ count = ccsf1->ChainSubRuleSetCount = GET_UShort();
+
+ FORGET_Frame();
+
+ ccsf1->ChainSubRuleSet = NULL;
+
+ if ( ALLOC_ARRAY( ccsf1->ChainSubRuleSet, count, TTO_ChainSubRuleSet ) )
+ goto Fail2;
+
+ csrs = ccsf1->ChainSubRuleSet;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail1;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_ChainSubRuleSet( &csrs[n], stream ) ) != TT_Err_Ok )
+ goto Fail1;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ return TT_Err_Ok;
+
+ Fail1:
+ for ( m = 0; m < n; m++ )
+ Free_ChainSubRuleSet( &csrs[m], memory );
+
+ FREE( csrs );
+
+ Fail2:
+ Free_Coverage( &ccsf1->Coverage, memory );
+ return error;
+ }
+
+
+ static void gsub_Free_ChainContext1( TTO_ChainContextSubstFormat1* ccsf1,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_ChainSubRuleSet* csrs;
+
+
+ if ( ccsf1->ChainSubRuleSet )
+ {
+ count = ccsf1->ChainSubRuleSetCount;
+ csrs = ccsf1->ChainSubRuleSet;
+
+ for ( n = 0; n < count; n++ )
+ Free_ChainSubRuleSet( &csrs[n], memory );
+
+ FREE( csrs );
+ }
+
+ Free_Coverage( &ccsf1->Coverage, memory );
+ }
+
+
+ /* ChainSubClassRule */
+
+ static FT_Error Load_ChainSubClassRule(
+ TTO_ChainContextSubstFormat2* ccsf2,
+ TTO_ChainSubClassRule* cscr,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, count;
+
+ FT_UShort* b;
+ FT_UShort* i;
+ FT_UShort* l;
+ TTO_SubstLookupRecord* slr;
+ FT_Bool* d;
+
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ cscr->BacktrackGlyphCount = GET_UShort();
+
+ FORGET_Frame();
+
+ if ( cscr->BacktrackGlyphCount > ccsf2->MaxBacktrackLength )
+ ccsf2->MaxBacktrackLength = cscr->BacktrackGlyphCount;
+
+ cscr->Backtrack = NULL;
+
+ count = cscr->BacktrackGlyphCount;
+
+ if ( ALLOC_ARRAY( cscr->Backtrack, count, FT_UShort ) )
+ return error;
+
+ b = cscr->Backtrack;
+ d = ccsf2->BacktrackClassDef.Defined;
+
+ if ( ACCESS_Frame( count * 2L ) )
+ goto Fail4;
+
+ for ( n = 0; n < count; n++ )
+ {
+ b[n] = GET_UShort();
+
+ /* We check whether the specific class is used at all. If not,
+ class 0 is used instead. */
+
+ if ( !d[b[n]] )
+ b[n] = 0;
+ }
+
+ FORGET_Frame();
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail4;
+
+ cscr->InputGlyphCount = GET_UShort();
+
+ FORGET_Frame();
+
+ if ( cscr->InputGlyphCount > ccsf2->MaxInputLength )
+ ccsf2->MaxInputLength = cscr->InputGlyphCount;
+
+ cscr->Input = NULL;
+
+ count = cscr->InputGlyphCount - 1; /* only InputGlyphCount - 1 elements */
+
+ if ( ALLOC_ARRAY( cscr->Input, count, FT_UShort ) )
+ goto Fail4;
+
+ i = cscr->Input;
+ d = ccsf2->InputClassDef.Defined;
+
+ if ( ACCESS_Frame( count * 2L ) )
+ goto Fail3;
+
+ for ( n = 0; n < count; n++ )
+ {
+ i[n] = GET_UShort();
+
+ if ( !d[i[n]] )
+ i[n] = 0;
+ }
+
+ FORGET_Frame();
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail3;
+
+ cscr->LookaheadGlyphCount = GET_UShort();
+
+ FORGET_Frame();
+
+ if ( cscr->LookaheadGlyphCount > ccsf2->MaxLookaheadLength )
+ ccsf2->MaxLookaheadLength = cscr->LookaheadGlyphCount;
+
+ cscr->Lookahead = NULL;
+
+ count = cscr->LookaheadGlyphCount;
+
+ if ( ALLOC_ARRAY( cscr->Lookahead, count, FT_UShort ) )
+ goto Fail3;
+
+ l = cscr->Lookahead;
+ d = ccsf2->LookaheadClassDef.Defined;
+
+ if ( ACCESS_Frame( count * 2L ) )
+ goto Fail2;
+
+ for ( n = 0; n < count; n++ )
+ {
+ l[n] = GET_UShort();
+
+ if ( !d[l[n]] )
+ l[n] = 0;
+ }
+
+ FORGET_Frame();
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail2;
+
+ cscr->SubstCount = GET_UShort();
+
+ FORGET_Frame();
+
+ cscr->SubstLookupRecord = NULL;
+
+ count = cscr->SubstCount;
+
+ if ( ALLOC_ARRAY( cscr->SubstLookupRecord, count,
+ TTO_SubstLookupRecord ) )
+ goto Fail2;
+
+ slr = cscr->SubstLookupRecord;
+
+ if ( ACCESS_Frame( count * 4L ) )
+ goto Fail1;
+
+ for ( n = 0; n < count; n++ )
+ {
+ slr[n].SequenceIndex = GET_UShort();
+ slr[n].LookupListIndex = GET_UShort();
+ }
+
+ FORGET_Frame();
+
+ return TT_Err_Ok;
+
+ Fail1:
+ FREE( slr );
+
+ Fail2:
+ FREE( l );
+
+ Fail3:
+ FREE( i );
+
+ Fail4:
+ FREE( b );
+ return error;
+ }
+
+
+ static void Free_ChainSubClassRule( TTO_ChainSubClassRule* cscr,
+ FT_Memory memory )
+ {
+ FREE( cscr->SubstLookupRecord );
+ FREE( cscr->Lookahead );
+ FREE( cscr->Input );
+ FREE( cscr->Backtrack );
+ }
+
+
+ /* SubClassSet */
+
+ static FT_Error Load_ChainSubClassSet(
+ TTO_ChainContextSubstFormat2* ccsf2,
+ TTO_ChainSubClassSet* cscs,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n = 0, m, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_ChainSubClassRule* cscr;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ count = cscs->ChainSubClassRuleCount = GET_UShort();
+
+ FORGET_Frame();
+
+ cscs->ChainSubClassRule = NULL;
+
+ if ( ALLOC_ARRAY( cscs->ChainSubClassRule, count,
+ TTO_ChainSubClassRule ) )
+ return error;
+
+ cscr = cscs->ChainSubClassRule;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_ChainSubClassRule( ccsf2, &cscr[n],
+ stream ) ) != TT_Err_Ok )
+ goto Fail;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ return TT_Err_Ok;
+
+ Fail:
+ for ( m = 0; m < n; m++ )
+ Free_ChainSubClassRule( &cscr[m], memory );
+
+ FREE( cscr );
+ return error;
+ }
+
+
+ static void Free_ChainSubClassSet( TTO_ChainSubClassSet* cscs,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_ChainSubClassRule* cscr;
+
+
+ if ( cscs->ChainSubClassRule )
+ {
+ count = cscs->ChainSubClassRuleCount;
+ cscr = cscs->ChainSubClassRule;
+
+ for ( n = 0; n < count; n++ )
+ Free_ChainSubClassRule( &cscr[n], memory );
+
+ FREE( cscr );
+ }
+ }
+
+ static FT_Error gsub_Load_EmptyOrClassDefinition( TTO_ClassDefinition* cd,
+ FT_UShort limit,
+ FT_ULong class_offset,
+ FT_ULong base_offset,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_ULong cur_offset;
+
+ cur_offset = FILE_Pos();
+
+ if ( class_offset )
+ {
+ if ( !FILE_Seek( class_offset + base_offset ) )
+ error = Load_ClassDefinition( cd, limit, stream );
+ }
+ else
+ error = Load_EmptyClassDefinition ( cd, stream );
+
+ if (error == TT_Err_Ok)
+ (void)FILE_Seek( cur_offset ); /* Changes error as a side-effect */
+
+ return error;
+ }
+
+
+ /* ChainContextSubstFormat2 */
+
+ static FT_Error Load_ChainContextSubst2(
+ TTO_ChainContextSubstFormat2* ccsf2,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n = 0, m, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+ FT_ULong backtrack_offset, input_offset, lookahead_offset;
+
+ TTO_ChainSubClassSet* cscs;
+
+
+ base_offset = FILE_Pos() - 2;
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Coverage( &ccsf2->Coverage, stream ) ) != TT_Err_Ok )
+ return error;
+ (void)FILE_Seek( cur_offset );
+
+ if ( ACCESS_Frame( 8L ) )
+ goto Fail5;
+
+ backtrack_offset = GET_UShort();
+ input_offset = GET_UShort();
+ lookahead_offset = GET_UShort();
+
+ /* `ChainSubClassSetCount' is the upper limit for input class values,
+ thus we read it now to make an additional safety check. No limit
+ is known or needed for the other two class definitions */
+
+ count = ccsf2->ChainSubClassSetCount = GET_UShort();
+
+ FORGET_Frame();
+
+ if ( ( error = gsub_Load_EmptyOrClassDefinition( &ccsf2->BacktrackClassDef, 65535,
+ backtrack_offset, base_offset,
+ stream ) ) != TT_Err_Ok )
+ goto Fail5;
+
+ if ( ( error = gsub_Load_EmptyOrClassDefinition( &ccsf2->InputClassDef, count,
+ input_offset, base_offset,
+ stream ) ) != TT_Err_Ok )
+ goto Fail4;
+ if ( ( error = gsub_Load_EmptyOrClassDefinition( &ccsf2->LookaheadClassDef, 65535,
+ lookahead_offset, base_offset,
+ stream ) ) != TT_Err_Ok )
+ goto Fail3;
+
+ ccsf2->ChainSubClassSet = NULL;
+ ccsf2->MaxBacktrackLength = 0;
+ ccsf2->MaxInputLength = 0;
+ ccsf2->MaxLookaheadLength = 0;
+
+ if ( ALLOC_ARRAY( ccsf2->ChainSubClassSet, count, TTO_ChainSubClassSet ) )
+ goto Fail2;
+
+ cscs = ccsf2->ChainSubClassSet;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail1;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ if ( new_offset != base_offset ) /* not a NULL offset */
+ {
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_ChainSubClassSet( ccsf2, &cscs[n],
+ stream ) ) != TT_Err_Ok )
+ goto Fail1;
+ (void)FILE_Seek( cur_offset );
+ }
+ else
+ {
+ /* we create a ChainSubClassSet table with no entries */
+
+ ccsf2->ChainSubClassSet[n].ChainSubClassRuleCount = 0;
+ ccsf2->ChainSubClassSet[n].ChainSubClassRule = NULL;
+ }
+ }
+
+ return TT_Err_Ok;
+
+ Fail1:
+ for ( m = 0; m < n; m++ )
+ Free_ChainSubClassSet( &cscs[m], memory );
+
+ FREE( cscs );
+
+ Fail2:
+ Free_ClassDefinition( &ccsf2->LookaheadClassDef, memory );
+
+ Fail3:
+ Free_ClassDefinition( &ccsf2->InputClassDef, memory );
+
+ Fail4:
+ Free_ClassDefinition( &ccsf2->BacktrackClassDef, memory );
+
+ Fail5:
+ Free_Coverage( &ccsf2->Coverage, memory );
+ return error;
+ }
+
+
+ static void gsub_Free_ChainContext2( TTO_ChainContextSubstFormat2* ccsf2,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_ChainSubClassSet* cscs;
+
+
+ if ( ccsf2->ChainSubClassSet )
+ {
+ count = ccsf2->ChainSubClassSetCount;
+ cscs = ccsf2->ChainSubClassSet;
+
+ for ( n = 0; n < count; n++ )
+ Free_ChainSubClassSet( &cscs[n], memory );
+
+ FREE( cscs );
+ }
+
+ Free_ClassDefinition( &ccsf2->LookaheadClassDef, memory );
+ Free_ClassDefinition( &ccsf2->InputClassDef, memory );
+ Free_ClassDefinition( &ccsf2->BacktrackClassDef, memory );
+
+ Free_Coverage( &ccsf2->Coverage, memory );
+ }
+
+
+ /* ChainContextSubstFormat3 */
+
+ static FT_Error Load_ChainContextSubst3(
+ TTO_ChainContextSubstFormat3* ccsf3,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, nb = 0, ni =0, nl = 0, m, count;
+ FT_UShort backtrack_count, input_count, lookahead_count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_Coverage* b;
+ TTO_Coverage* i;
+ TTO_Coverage* l;
+ TTO_SubstLookupRecord* slr;
+
+
+ base_offset = FILE_Pos() - 2L;
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ ccsf3->BacktrackGlyphCount = GET_UShort();
+
+ FORGET_Frame();
+
+ ccsf3->BacktrackCoverage = NULL;
+
+ backtrack_count = ccsf3->BacktrackGlyphCount;
+
+ if ( ALLOC_ARRAY( ccsf3->BacktrackCoverage, backtrack_count,
+ TTO_Coverage ) )
+ return error;
+
+ b = ccsf3->BacktrackCoverage;
+
+ for ( nb = 0; nb < backtrack_count; nb++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail4;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Coverage( &b[nb], stream ) ) != TT_Err_Ok )
+ goto Fail4;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail4;
+
+ ccsf3->InputGlyphCount = GET_UShort();
+
+ FORGET_Frame();
+
+ ccsf3->InputCoverage = NULL;
+
+ input_count = ccsf3->InputGlyphCount;
+
+ if ( ALLOC_ARRAY( ccsf3->InputCoverage, input_count, TTO_Coverage ) )
+ goto Fail4;
+
+ i = ccsf3->InputCoverage;
+
+ for ( ni = 0; ni < input_count; ni++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail3;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Coverage( &i[ni], stream ) ) != TT_Err_Ok )
+ goto Fail3;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail3;
+
+ ccsf3->LookaheadGlyphCount = GET_UShort();
+
+ FORGET_Frame();
+
+ ccsf3->LookaheadCoverage = NULL;
+
+ lookahead_count = ccsf3->LookaheadGlyphCount;
+
+ if ( ALLOC_ARRAY( ccsf3->LookaheadCoverage, lookahead_count,
+ TTO_Coverage ) )
+ goto Fail3;
+
+ l = ccsf3->LookaheadCoverage;
+
+ for ( nl = 0; nl < lookahead_count; nl++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail2;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Coverage( &l[nl], stream ) ) != TT_Err_Ok )
+ goto Fail2;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail2;
+
+ ccsf3->SubstCount = GET_UShort();
+
+ FORGET_Frame();
+
+ ccsf3->SubstLookupRecord = NULL;
+
+ count = ccsf3->SubstCount;
+
+ if ( ALLOC_ARRAY( ccsf3->SubstLookupRecord, count,
+ TTO_SubstLookupRecord ) )
+ goto Fail2;
+
+ slr = ccsf3->SubstLookupRecord;
+
+ if ( ACCESS_Frame( count * 4L ) )
+ goto Fail1;
+
+ for ( n = 0; n < count; n++ )
+ {
+ slr[n].SequenceIndex = GET_UShort();
+ slr[n].LookupListIndex = GET_UShort();
+ }
+
+ FORGET_Frame();
+
+ return TT_Err_Ok;
+
+ Fail1:
+ FREE( slr );
+
+ Fail2:
+ for ( m = 0; m < nl; m++ )
+ Free_Coverage( &l[m], memory );
+
+ FREE( l );
+
+ Fail3:
+ for ( m = 0; m < ni; m++ )
+ Free_Coverage( &i[m], memory );
+
+ FREE( i );
+
+ Fail4:
+ for ( m = 0; m < nb; m++ )
+ Free_Coverage( &b[m], memory );
+
+ FREE( b );
+ return error;
+ }
+
+
+ static void gsub_Free_ChainContext3( TTO_ChainContextSubstFormat3* ccsf3,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_Coverage* c;
+
+
+ FREE( ccsf3->SubstLookupRecord );
+
+ if ( ccsf3->LookaheadCoverage )
+ {
+ count = ccsf3->LookaheadGlyphCount;
+ c = ccsf3->LookaheadCoverage;
+
+ for ( n = 0; n < count; n++ )
+ Free_Coverage( &c[n], memory );
+
+ FREE( c );
+ }
+
+ if ( ccsf3->InputCoverage )
+ {
+ count = ccsf3->InputGlyphCount;
+ c = ccsf3->InputCoverage;
+
+ for ( n = 0; n < count; n++ )
+ Free_Coverage( &c[n], memory );
+
+ FREE( c );
+ }
+
+ if ( ccsf3->BacktrackCoverage )
+ {
+ count = ccsf3->BacktrackGlyphCount;
+ c = ccsf3->BacktrackCoverage;
+
+ for ( n = 0; n < count; n++ )
+ Free_Coverage( &c[n], memory );
+
+ FREE( c );
+ }
+ }
+
+
+ /* ChainContextSubst */
+
+ FT_Error Load_ChainContextSubst( TTO_ChainContextSubst* ccs,
+ FT_Stream stream )
+ {
+ FT_Error error;
+
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ ccs->SubstFormat = GET_UShort();
+
+ FORGET_Frame();
+
+ switch ( ccs->SubstFormat )
+ {
+ case 1:
+ return Load_ChainContextSubst1( &ccs->ccsf.ccsf1, stream );
+
+ case 2:
+ return Load_ChainContextSubst2( &ccs->ccsf.ccsf2, stream );
+
+ case 3:
+ return Load_ChainContextSubst3( &ccs->ccsf.ccsf3, stream );
+
+ default:
+ return TTO_Err_Invalid_GSUB_SubTable_Format;
+ }
+
+ return TT_Err_Ok; /* never reached */
+ }
+
+
+ void Free_ChainContextSubst( TTO_ChainContextSubst* ccs,
+ FT_Memory memory )
+ {
+ switch ( ccs->SubstFormat )
+ {
+ case 1:
+ gsub_Free_ChainContext1( &ccs->ccsf.ccsf1, memory );
+ break;
+
+ case 2:
+ gsub_Free_ChainContext2( &ccs->ccsf.ccsf2, memory );
+ break;
+
+ case 3:
+ gsub_Free_ChainContext3( &ccs->ccsf.ccsf3, memory );
+ break;
+ }
+ }
+
+
+ static FT_Error Lookup_ChainContextSubst1(
+ TTO_GSUBHeader* gsub,
+ TTO_ChainContextSubstFormat1* ccsf1,
+ TTO_GSUB_String* in,
+ TTO_GSUB_String* out,
+ FT_UShort flags,
+ FT_UShort context_length,
+ int nesting_level )
+ {
+ FT_UShort index, property;
+ FT_UShort i, j, k, num_csr, curr_pos;
+ FT_UShort bgc, igc, lgc;
+ FT_Error error;
+ FT_UShort* s_in;
+
+ TTO_ChainSubRule* csr;
+ TTO_ChainSubRule curr_csr;
+ TTO_GDEFHeader* gdef;
+
+
+ gdef = gsub->gdef;
+
+ if ( CHECK_Property( gdef, in->string[in->pos], flags, &property ) )
+ return error;
+
+ error = Coverage_Index( &ccsf1->Coverage, in->string[in->pos], &index );
+ if ( error )
+ return error;
+
+ csr = ccsf1->ChainSubRuleSet[index].ChainSubRule;
+ num_csr = ccsf1->ChainSubRuleSet[index].ChainSubRuleCount;
+
+ for ( k = 0; k < num_csr; k++ )
+ {
+ curr_csr = csr[k];
+ bgc = curr_csr.BacktrackGlyphCount;
+ igc = curr_csr.InputGlyphCount;
+ lgc = curr_csr.LookaheadGlyphCount;
+
+ if ( context_length != 0xFFFF && context_length < igc )
+ continue;
+
+ /* check whether context is too long; it is a first guess only */
+
+ if ( bgc > in->pos || in->pos + igc + lgc > in->length )
+ continue;
+
+ if ( bgc )
+ {
+ /* since we don't know in advance the number of glyphs to inspect,
+ we search backwards for matches in the backtrack glyph array */
+
+ curr_pos = 0;
+ s_in = &in->string[curr_pos];
+
+ for ( i = 0, j = in->pos - 1; i < bgc; i++, j-- )
+ {
+ while ( CHECK_Property( gdef, s_in[j], flags, &property ) )
+ {
+ if ( error && error != TTO_Err_Not_Covered )
+ return error;
+
+ if ( j > curr_pos )
+ j--;
+ else
+ break;
+ }
+
+ /* In OpenType 1.3, it is undefined whether the offsets of
+ backtrack glyphs is in logical order or not. Version 1.4
+ will clarify this:
+
+ Logical order - a b c d e f g h i j
+ i
+ Input offsets - 0 1
+ Backtrack offsets - 3 2 1 0
+ Lookahead offsets - 0 1 2 3 */
+
+ if ( s_in[j] != curr_csr.Backtrack[i] )
+ break;
+ }
+
+ if ( i != bgc )
+ continue;
+ }
+
+ curr_pos = in->pos;
+ s_in = &in->string[curr_pos];
+
+ /* Start at 1 because [0] is implied */
+
+ for ( i = 1, j = 1; i < igc; i++, j++ )
+ {
+ while ( CHECK_Property( gdef, s_in[j], flags, &property ) )
+ {
+ if ( error && error != TTO_Err_Not_Covered )
+ return error;
+
+ if ( curr_pos + j < in->length )
+ j++;
+ else
+ break;
+ }
+
+ if ( s_in[j] != curr_csr.Input[i - 1] )
+ break;
+ }
+
+ if ( i != igc )
+ continue;
+
+ /* we are starting to check for lookahead glyphs right after the
+ last context glyph */
+
+ curr_pos += j;
+ s_in = &in->string[curr_pos];
+
+ for ( i = 0, j = 0; i < lgc; i++, j++ )
+ {
+ while ( CHECK_Property( gdef, s_in[j], flags, &property ) )
+ {
+ if ( error && error != TTO_Err_Not_Covered )
+ return error;
+
+ if ( curr_pos + j < in->length )
+ j++;
+ else
+ break;
+ }
+
+ if ( s_in[j] != curr_csr.Lookahead[i] )
+ break;
+ }
+
+ if ( i == lgc )
+ return Do_ContextSubst( gsub, igc,
+ curr_csr.SubstCount,
+ curr_csr.SubstLookupRecord,
+ in, out,
+ nesting_level );
+ }
+
+ return TTO_Err_Not_Covered;
+ }
+
+
+ static FT_Error Lookup_ChainContextSubst2(
+ TTO_GSUBHeader* gsub,
+ TTO_ChainContextSubstFormat2* ccsf2,
+ TTO_GSUB_String* in,
+ TTO_GSUB_String* out,
+ FT_UShort flags,
+ FT_UShort context_length,
+ int nesting_level )
+ {
+ FT_UShort index, property;
+ FT_Memory memory;
+ FT_Error error;
+ FT_UShort i, j, k, curr_pos;
+ FT_UShort bgc, igc, lgc;
+ FT_UShort known_backtrack_classes,
+ known_input_classes,
+ known_lookahead_classes;
+
+ FT_UShort* backtrack_classes;
+ FT_UShort* input_classes;
+ FT_UShort* lookahead_classes;
+
+ FT_UShort* s_in;
+
+ FT_UShort* bc;
+ FT_UShort* ic;
+ FT_UShort* lc;
+
+ TTO_ChainSubClassSet* cscs;
+ TTO_ChainSubClassRule ccsr;
+ TTO_GDEFHeader* gdef;
+
+
+ gdef = gsub->gdef;
+ memory = gsub->memory;
+
+ if ( CHECK_Property( gdef, in->string[in->pos], flags, &property ) )
+ return error;
+
+ /* Note: The coverage table in format 2 doesn't give an index into
+ anything. It just lets us know whether or not we need to
+ do any lookup at all. */
+
+ error = Coverage_Index( &ccsf2->Coverage, in->string[in->pos], &index );
+ if ( error )
+ return error;
+
+ if ( ALLOC_ARRAY( backtrack_classes, ccsf2->MaxBacktrackLength, FT_UShort ) )
+ return error;
+ known_backtrack_classes = 0;
+
+ if ( ALLOC_ARRAY( input_classes, ccsf2->MaxInputLength, FT_UShort ) )
+ goto End3;
+ known_input_classes = 1;
+
+ if ( ALLOC_ARRAY( lookahead_classes, ccsf2->MaxLookaheadLength, FT_UShort ) )
+ goto End2;
+ known_lookahead_classes = 0;
+
+ error = Get_Class( &ccsf2->InputClassDef, in->string[in->pos],
+ &input_classes[0], NULL );
+ if ( error && error != TTO_Err_Not_Covered )
+ goto End1;
+
+ cscs = &ccsf2->ChainSubClassSet[input_classes[0]];
+ if ( !cscs )
+ {
+ error = TTO_Err_Invalid_GSUB_SubTable;
+ goto End1;
+ }
+
+ for ( k = 0; k < cscs->ChainSubClassRuleCount; k++ )
+ {
+ ccsr = cscs->ChainSubClassRule[k];
+ bgc = ccsr.BacktrackGlyphCount;
+ igc = ccsr.InputGlyphCount;
+ lgc = ccsr.LookaheadGlyphCount;
+
+ if ( context_length != 0xFFFF && context_length < igc )
+ continue;
+
+ /* check whether context is too long; it is a first guess only */
+
+ if ( bgc > in->pos || in->pos + igc + lgc > in->length )
+ continue;
+
+ if ( bgc )
+ {
+ /* Since we don't know in advance the number of glyphs to inspect,
+ we search backwards for matches in the backtrack glyph array.
+ Note that `known_backtrack_classes' starts at index 0. */
+
+ curr_pos = 0;
+ s_in = &in->string[curr_pos];
+ bc = ccsr.Backtrack;
+
+ for ( i = 0, j = in->pos - 1; i < bgc; i++, j-- )
+ {
+ while ( CHECK_Property( gdef, s_in[j], flags, &property ) )
+ {
+ if ( error && error != TTO_Err_Not_Covered )
+ goto End1;
+
+ if ( j > curr_pos )
+ j--;
+ else
+ break;
+ }
+
+ if ( i >= known_backtrack_classes )
+ {
+ /* Keeps us from having to do this for each rule */
+
+ error = Get_Class( &ccsf2->BacktrackClassDef, s_in[j],
+ &backtrack_classes[i], NULL );
+ if ( error && error != TTO_Err_Not_Covered )
+ goto End1;
+ known_backtrack_classes = i;
+ }
+
+ if ( bc[i] != backtrack_classes[i] )
+ break;
+ }
+
+ if ( i != bgc )
+ continue;
+ }
+
+ curr_pos = in->pos;
+ s_in = &in->string[curr_pos];
+ ic = ccsr.Input;
+
+ /* Start at 1 because [0] is implied */
+
+ for ( i = 1, j = 1; i < igc; i++, j++ )
+ {
+ while ( CHECK_Property( gdef, s_in[j], flags, &property ) )
+ {
+ if ( error && error != TTO_Err_Not_Covered )
+ goto End1;
+
+ if ( curr_pos + j < in->length )
+ j++;
+ else
+ break;
+ }
+
+ if ( i >= known_input_classes )
+ {
+ error = Get_Class( &ccsf2->InputClassDef, s_in[j],
+ &input_classes[i], NULL );
+ if ( error && error != TTO_Err_Not_Covered )
+ goto End1;
+ known_input_classes = i;
+ }
+
+ if ( ic[i - 1] != input_classes[i] )
+ break;
+ }
+
+ if ( i != igc )
+ continue;
+
+ /* we are starting to check for lookahead glyphs right after the
+ last context glyph */
+
+ curr_pos += j;
+ s_in = &in->string[curr_pos];
+ lc = ccsr.Lookahead;
+
+ for ( i = 0, j = 0; i < lgc; i++, j++ )
+ {
+ while ( CHECK_Property( gdef, s_in[j], flags, &property ) )
+ {
+ if ( error && error != TTO_Err_Not_Covered )
+ goto End1;
+
+ if ( curr_pos + j < in->length )
+ j++;
+ else
+ break;
+ }
+
+ if ( i >= known_lookahead_classes )
+ {
+ error = Get_Class( &ccsf2->LookaheadClassDef, s_in[j],
+ &lookahead_classes[i], NULL );
+ if ( error && error != TTO_Err_Not_Covered )
+ goto End1;
+ known_lookahead_classes = i;
+ }
+
+ if ( lc[i] != lookahead_classes[i] )
+ break;
+ }
+
+ if ( i == lgc )
+ {
+ error = Do_ContextSubst( gsub, igc,
+ ccsr.SubstCount,
+ ccsr.SubstLookupRecord,
+ in, out,
+ nesting_level );
+ goto End1;
+ }
+ }
+
+ error = TTO_Err_Not_Covered;
+
+ End1:
+ FREE( lookahead_classes );
+
+ End2:
+ FREE( input_classes );
+
+ End3:
+ FREE( backtrack_classes );
+ return error;
+ }
+
+
+ static FT_Error Lookup_ChainContextSubst3(
+ TTO_GSUBHeader* gsub,
+ TTO_ChainContextSubstFormat3* ccsf3,
+ TTO_GSUB_String* in,
+ TTO_GSUB_String* out,
+ FT_UShort flags,
+ FT_UShort context_length,
+ int nesting_level )
+ {
+ FT_UShort index, i, j, curr_pos, property;
+ FT_UShort bgc, igc, lgc;
+ FT_Error error;
+ FT_UShort* s_in;
+
+ TTO_Coverage* bc;
+ TTO_Coverage* ic;
+ TTO_Coverage* lc;
+ TTO_GDEFHeader* gdef;
+
+
+ gdef = gsub->gdef;
+
+ if ( CHECK_Property( gdef, in->string[in->pos], flags, &property ) )
+ return error;
+
+ bgc = ccsf3->BacktrackGlyphCount;
+ igc = ccsf3->InputGlyphCount;
+ lgc = ccsf3->LookaheadGlyphCount;
+
+ if ( context_length != 0xFFFF && context_length < igc )
+ return TTO_Err_Not_Covered;
+
+ /* check whether context is too long; it is a first guess only */
+
+ if ( bgc > in->pos || in->pos + igc + lgc > in->length )
+ return TTO_Err_Not_Covered;
+
+ if ( bgc )
+ {
+ /* Since we don't know in advance the number of glyphs to inspect,
+ we search backwards for matches in the backtrack glyph array */
+
+ curr_pos = 0;
+ s_in = &in->string[curr_pos];
+ bc = ccsf3->BacktrackCoverage;
+
+ for ( i = 0, j = in->pos - 1; i < bgc; i++, j-- )
+ {
+ while ( CHECK_Property( gdef, s_in[j], flags, &property ) )
+ {
+ if ( error && error != TTO_Err_Not_Covered )
+ return error;
+
+ if ( j > curr_pos )
+ j--;
+ else
+ return TTO_Err_Not_Covered;
+ }
+
+ error = Coverage_Index( &bc[i], s_in[j], &index );
+ if ( error )
+ return error;
+ }
+ }
+
+ curr_pos = in->pos;
+ s_in = &in->string[curr_pos];
+ ic = ccsf3->InputCoverage;
+
+ for ( i = 0, j = 0; i < igc; i++, j++ )
+ {
+ /* We already called CHECK_Property for s_in[0] */
+ while ( j > 0 && CHECK_Property( gdef, s_in[j], flags, &property ) )
+ {
+ if ( error && error != TTO_Err_Not_Covered )
+ return error;
+
+ if ( curr_pos + j < in->length )
+ j++;
+ else
+ return TTO_Err_Not_Covered;
+ }
+
+ error = Coverage_Index( &ic[i], s_in[j], &index );
+ if ( error )
+ return error;
+ }
+
+ /* we are starting for lookahead glyphs right after the last context
+ glyph */
+
+ curr_pos += j;
+ s_in = &in->string[curr_pos];
+ lc = ccsf3->LookaheadCoverage;
+
+ for ( i = 0, j = 0; i < lgc; i++, j++ )
+ {
+ while ( CHECK_Property( gdef, s_in[j], flags, &property ) )
+ {
+ if ( error && error != TTO_Err_Not_Covered )
+ return error;
+
+ if ( curr_pos + j < in->length )
+ j++;
+ else
+ return TTO_Err_Not_Covered;
+ }
+
+ error = Coverage_Index( &lc[i], s_in[j], &index );
+ if ( error )
+ return error;
+ }
+
+ return Do_ContextSubst( gsub, igc,
+ ccsf3->SubstCount,
+ ccsf3->SubstLookupRecord,
+ in, out,
+ nesting_level );
+ }
+
+
+ static FT_Error Lookup_ChainContextSubst(
+ TTO_GSUBHeader* gsub,
+ TTO_ChainContextSubst* ccs,
+ TTO_GSUB_String* in,
+ TTO_GSUB_String* out,
+ FT_UShort flags,
+ FT_UShort context_length,
+ int nesting_level )
+ {
+ switch ( ccs->SubstFormat )
+ {
+ case 1:
+ return Lookup_ChainContextSubst1( gsub, &ccs->ccsf.ccsf1, in, out,
+ flags, context_length,
+ nesting_level );
+
+ case 2:
+ return Lookup_ChainContextSubst2( gsub, &ccs->ccsf.ccsf2, in, out,
+ flags, context_length,
+ nesting_level );
+
+ case 3:
+ return Lookup_ChainContextSubst3( gsub, &ccs->ccsf.ccsf3, in, out,
+ flags, context_length,
+ nesting_level );
+
+ default:
+ return TTO_Err_Invalid_GSUB_SubTable_Format;
+ }
+
+ return TT_Err_Ok; /* never reached */
+ }
+
+
+
+ /***********
+ * GSUB API
+ ***********/
+
+
+ EXPORT_FUNC
+ FT_Error TT_GSUB_Select_Script( TTO_GSUBHeader* gsub,
+ FT_ULong script_tag,
+ FT_UShort* script_index )
+ {
+ FT_UShort n;
+
+ TTO_ScriptList* sl;
+ TTO_ScriptRecord* sr;
+
+
+ if ( !gsub || !script_index )
+ return TT_Err_Invalid_Argument;
+
+ sl = &gsub->ScriptList;
+ sr = sl->ScriptRecord;
+
+ for ( n = 0; n < sl->ScriptCount; n++ )
+ if ( script_tag == sr[n].ScriptTag )
+ {
+ *script_index = n;
+
+ return TT_Err_Ok;
+ }
+
+ return TTO_Err_Not_Covered;
+ }
+
+
+ EXPORT_FUNC
+ FT_Error TT_GSUB_Select_Language( TTO_GSUBHeader* gsub,
+ FT_ULong language_tag,
+ FT_UShort script_index,
+ FT_UShort* language_index,
+ FT_UShort* req_feature_index )
+ {
+ FT_UShort n;
+
+ TTO_ScriptList* sl;
+ TTO_ScriptRecord* sr;
+ TTO_Script* s;
+ TTO_LangSysRecord* lsr;
+
+
+ if ( !gsub || !language_index || !req_feature_index )
+ return TT_Err_Invalid_Argument;
+
+ sl = &gsub->ScriptList;
+ sr = sl->ScriptRecord;
+
+ if ( script_index >= sl->ScriptCount )
+ return TT_Err_Invalid_Argument;
+
+ s = &sr[script_index].Script;
+ lsr = s->LangSysRecord;
+
+ for ( n = 0; n < s->LangSysCount; n++ )
+ if ( language_tag == lsr[n].LangSysTag )
+ {
+ *language_index = n;
+ *req_feature_index = lsr[n].LangSys.ReqFeatureIndex;
+
+ return TT_Err_Ok;
+ }
+
+ return TTO_Err_Not_Covered;
+ }
+
+
+ /* selecting 0xFFFF for language_index asks for the values of the
+ default language (DefaultLangSys) */
+
+ EXPORT_FUNC
+ FT_Error TT_GSUB_Select_Feature( TTO_GSUBHeader* gsub,
+ FT_ULong feature_tag,
+ FT_UShort script_index,
+ FT_UShort language_index,
+ FT_UShort* feature_index )
+ {
+ FT_UShort n;
+
+ TTO_ScriptList* sl;
+ TTO_ScriptRecord* sr;
+ TTO_Script* s;
+ TTO_LangSysRecord* lsr;
+ TTO_LangSys* ls;
+ FT_UShort* fi;
+
+ TTO_FeatureList* fl;
+ TTO_FeatureRecord* fr;
+
+
+ if ( !gsub || !feature_index )
+ return TT_Err_Invalid_Argument;
+
+ sl = &gsub->ScriptList;
+ sr = sl->ScriptRecord;
+
+ fl = &gsub->FeatureList;
+ fr = fl->FeatureRecord;
+
+ if ( script_index >= sl->ScriptCount )
+ return TT_Err_Invalid_Argument;
+
+ s = &sr[script_index].Script;
+ lsr = s->LangSysRecord;
+
+ if ( language_index == 0xFFFF )
+ ls = &s->DefaultLangSys;
+ else
+ {
+ if ( language_index >= s->LangSysCount )
+ return TT_Err_Invalid_Argument;
+
+ ls = &lsr[language_index].LangSys;
+ }
+
+ fi = ls->FeatureIndex;
+
+ for ( n = 0; n < ls->FeatureCount; n++ )
+ {
+ if ( fi[n] >= fl->FeatureCount )
+ return TTO_Err_Invalid_GSUB_SubTable_Format;
+
+ if ( feature_tag == fr[fi[n]].FeatureTag )
+ {
+ *feature_index = fi[n];
+
+ return TT_Err_Ok;
+ }
+ }
+
+ return TTO_Err_Not_Covered;
+ }
+
+
+ /* The next three functions return a null-terminated list */
+
+ EXPORT_FUNC
+ FT_Error TT_GSUB_Query_Scripts( TTO_GSUBHeader* gsub,
+ FT_ULong** script_tag_list )
+ {
+ FT_UShort n;
+ FT_Error error;
+ FT_Memory memory;
+ FT_ULong* stl;
+
+ TTO_ScriptList* sl;
+ TTO_ScriptRecord* sr;
+
+
+ if ( !gsub || !script_tag_list )
+ return TT_Err_Invalid_Argument;
+
+ memory = gsub->memory;
+
+ sl = &gsub->ScriptList;
+ sr = sl->ScriptRecord;
+
+ if ( ALLOC_ARRAY( stl, sl->ScriptCount + 1, FT_ULong ) )
+ return error;
+
+ for ( n = 0; n < sl->ScriptCount; n++ )
+ stl[n] = sr[n].ScriptTag;
+ stl[n] = 0;
+
+ *script_tag_list = stl;
+
+ return TT_Err_Ok;
+ }
+
+
+ EXPORT_FUNC
+ FT_Error TT_GSUB_Query_Languages( TTO_GSUBHeader* gsub,
+ FT_UShort script_index,
+ FT_ULong** language_tag_list )
+ {
+ FT_UShort n;
+ FT_Error error;
+ FT_Memory memory;
+ FT_ULong* ltl;
+
+ TTO_ScriptList* sl;
+ TTO_ScriptRecord* sr;
+ TTO_Script* s;
+ TTO_LangSysRecord* lsr;
+
+
+ if ( !gsub || !language_tag_list )
+ return TT_Err_Invalid_Argument;
+
+ memory = gsub->memory;
+
+ sl = &gsub->ScriptList;
+ sr = sl->ScriptRecord;
+
+ if ( script_index >= sl->ScriptCount )
+ return TT_Err_Invalid_Argument;
+
+ s = &sr[script_index].Script;
+ lsr = s->LangSysRecord;
+
+ if ( ALLOC_ARRAY( ltl, s->LangSysCount + 1, FT_ULong ) )
+ return error;
+
+ for ( n = 0; n < s->LangSysCount; n++ )
+ ltl[n] = lsr[n].LangSysTag;
+ ltl[n] = 0;
+
+ *language_tag_list = ltl;
+
+ return TT_Err_Ok;
+ }
+
+
+ /* selecting 0xFFFF for language_index asks for the values of the
+ default language (DefaultLangSys) */
+
+ EXPORT_FUNC
+ FT_Error TT_GSUB_Query_Features( TTO_GSUBHeader* gsub,
+ FT_UShort script_index,
+ FT_UShort language_index,
+ FT_ULong** feature_tag_list )
+ {
+ FT_UShort n;
+ FT_Error error;
+ FT_Memory memory;
+ FT_ULong* ftl;
+
+ TTO_ScriptList* sl;
+ TTO_ScriptRecord* sr;
+ TTO_Script* s;
+ TTO_LangSysRecord* lsr;
+ TTO_LangSys* ls;
+ FT_UShort* fi;
+
+ TTO_FeatureList* fl;
+ TTO_FeatureRecord* fr;
+
+
+ if ( !gsub || !feature_tag_list )
+ return TT_Err_Invalid_Argument;
+
+ memory = gsub->memory;
+
+ sl = &gsub->ScriptList;
+ sr = sl->ScriptRecord;
+
+ fl = &gsub->FeatureList;
+ fr = fl->FeatureRecord;
+
+ if ( script_index >= sl->ScriptCount )
+ return TT_Err_Invalid_Argument;
+
+ s = &sr[script_index].Script;
+ lsr = s->LangSysRecord;
+
+ if ( language_index == 0xFFFF )
+ ls = &s->DefaultLangSys;
+ else
+ {
+ if ( language_index >= s->LangSysCount )
+ return TT_Err_Invalid_Argument;
+
+ ls = &lsr[language_index].LangSys;
+ }
+
+ fi = ls->FeatureIndex;
+
+ if ( ALLOC_ARRAY( ftl, ls->FeatureCount + 1, FT_ULong ) )
+ return error;
+
+ for ( n = 0; n < ls->FeatureCount; n++ )
+ {
+ if ( fi[n] >= fl->FeatureCount )
+ {
+ FREE( ftl );
+ return TTO_Err_Invalid_GSUB_SubTable_Format;
+ }
+ ftl[n] = fr[fi[n]].FeatureTag;
+ }
+ ftl[n] = 0;
+
+ *feature_tag_list = ftl;
+
+ return TT_Err_Ok;
+ }
+
+
+ /* Do an individual subtable lookup. Returns TT_Err_Ok if substitution
+ has been done, or TTO_Err_Not_Covered if not. */
+
+ static FT_Error gsub_Do_Glyph_Lookup( TTO_GSUBHeader* gsub,
+ FT_UShort lookup_index,
+ TTO_GSUB_String* in,
+ TTO_GSUB_String* out,
+ FT_UShort context_length,
+ int nesting_level )
+ {
+ FT_Error error = TT_Err_Ok;
+ FT_UShort i, flags;
+ TTO_Lookup* lo;
+
+
+ nesting_level++;
+
+ if ( nesting_level > TTO_MAX_NESTING_LEVEL )
+ return TTO_Err_Too_Many_Nested_Contexts;
+
+ lo = &gsub->LookupList.Lookup[lookup_index];
+ flags = lo->LookupFlag;
+
+ for ( i = 0; i < lo->SubTableCount; i++ )
+ {
+ switch ( lo->LookupType )
+ {
+ case GSUB_LOOKUP_SINGLE:
+ error = Lookup_SingleSubst( &lo->SubTable[i].st.gsub.single,
+ in, out,
+ flags, context_length, gsub->gdef );
+ break;
+
+ case GSUB_LOOKUP_MULTIPLE:
+ error = Lookup_MultipleSubst( &lo->SubTable[i].st.gsub.multiple,
+ in, out,
+ flags, context_length, gsub->gdef );
+ break;
+
+ case GSUB_LOOKUP_ALTERNATE:
+ error = Lookup_AlternateSubst( gsub,
+ &lo->SubTable[i].st.gsub.alternate,
+ in, out,
+ flags, context_length, gsub->gdef );
+ break;
+
+ case GSUB_LOOKUP_LIGATURE:
+ error = Lookup_LigatureSubst( &lo->SubTable[i].st.gsub.ligature,
+ in, out,
+ flags, context_length, gsub->gdef );
+ break;
+
+ case GSUB_LOOKUP_CONTEXT:
+ error = Lookup_ContextSubst( gsub, &lo->SubTable[i].st.gsub.context,
+ in, out,
+ flags, context_length, nesting_level );
+ break;
+
+ case GSUB_LOOKUP_CHAIN:
+ error = Lookup_ChainContextSubst( gsub,
+ &lo->SubTable[i].st.gsub.chain,
+ in, out,
+ flags, context_length,
+ nesting_level );
+ break;
+ }
+
+ /* Check whether we have a successful substitution or an error other
+ than TTO_Err_Not_Covered */
+
+ if ( error != TTO_Err_Not_Covered )
+ return error;
+ }
+
+ return TTO_Err_Not_Covered;
+ }
+
+
+ /* apply one lookup to the input string object */
+
+ static FT_Error gsub_Do_String_Lookup( TTO_GSUBHeader* gsub,
+ FT_UShort lookup_index,
+ TTO_GSUB_String* in,
+ TTO_GSUB_String* out )
+ {
+ FT_Error error, retError = TTO_Err_Not_Covered;
+
+ FT_UShort* properties = gsub->LookupList.Properties;
+ FT_UShort* p_in = in->properties;
+ FT_UShort* s_in = in->string;
+
+ int nesting_level = 0;
+
+
+ while ( in->pos < in->length )
+ {
+ if ( ~p_in[in->pos] & properties[lookup_index] )
+ {
+ /* 0xFFFF indicates that we don't have a context length yet */
+ error = gsub_Do_Glyph_Lookup( gsub, lookup_index, in, out,
+ 0xFFFF, nesting_level );
+ if ( error )
+ {
+ if ( error != TTO_Err_Not_Covered )
+ return error;
+ }
+ else
+ retError = error;
+ }
+ else
+ error = TTO_Err_Not_Covered;
+
+ if ( error == TTO_Err_Not_Covered )
+ if ( ADD_String( in, 1, out, 1, &s_in[in->pos], 0xFFFF, 0xFFFF ) )
+ return error;
+ }
+
+ return retError;
+ }
+
+
+ EXPORT_FUNC
+ FT_Error TT_GSUB_Add_Feature( TTO_GSUBHeader* gsub,
+ FT_UShort feature_index,
+ FT_UShort property )
+ {
+ FT_UShort i;
+
+ TTO_Feature feature;
+ FT_UShort* properties;
+ FT_UShort* index;
+
+
+ if ( !gsub ||
+ feature_index >= gsub->FeatureList.FeatureCount )
+ return TT_Err_Invalid_Argument;
+
+ properties = gsub->LookupList.Properties;
+
+ feature = gsub->FeatureList.FeatureRecord[feature_index].Feature;
+ index = feature.LookupListIndex;
+
+ for ( i = 0; i < feature.LookupListCount; i++ )
+ properties[index[i]] |= property;
+
+ return TT_Err_Ok;
+ }
+
+
+ EXPORT_FUNC
+ FT_Error TT_GSUB_Clear_Features( TTO_GSUBHeader* gsub )
+ {
+ FT_UShort i;
+
+ FT_UShort* properties;
+
+
+ if ( !gsub )
+ return TT_Err_Invalid_Argument;
+
+ properties = gsub->LookupList.Properties;
+
+ for ( i = 0; i < gsub->LookupList.LookupCount; i++ )
+ properties[i] = 0;
+
+ return TT_Err_Ok;
+ }
+
+
+ EXPORT_FUNC
+ FT_Error TT_GSUB_Register_Alternate_Function( TTO_GSUBHeader* gsub,
+ TTO_AltFunction altfunc,
+ void* data )
+ {
+ if ( !gsub )
+ return TT_Err_Invalid_Argument;
+
+ gsub->altfunc = altfunc;
+ gsub->data = data;
+
+ return TT_Err_Ok;
+ }
+
+
+ EXPORT_FUNC
+ FT_Error TT_GSUB_String_New( FT_Memory memory,
+ TTO_GSUB_String **result )
+ {
+ FT_Error error;
+
+ TTO_GSUB_String *str;
+
+ if ( ALLOC( str, sizeof( *str ) ) )
+ return error;
+
+ str->memory = memory;
+
+ str->length = 0;
+ str->allocated = 0;
+ str->pos = 0;
+ str->string = NULL;
+ str->properties = NULL;
+ str->components = NULL;
+ str->max_ligID = 0;
+ str->ligIDs = 0;
+ str->logClusters = 0;
+
+ *result = str;
+
+ return TT_Err_Ok;
+ }
+
+ EXPORT_DEF
+ FT_Error TT_GSUB_String_Set_Length( TTO_GSUB_String *str,
+ FT_ULong new_length)
+ {
+ FT_Memory memory = str->memory;
+ FT_Error error;
+
+ if ( new_length > str->allocated )
+ {
+ if ( REALLOC_ARRAY( str->string, str->allocated, new_length, FT_UShort ) )
+ return error;
+ if ( REALLOC_ARRAY( str->properties, str->allocated, new_length, FT_UShort ) )
+ return error;
+ if ( REALLOC_ARRAY( str->components, str->allocated, new_length, FT_UShort ) )
+ return error;
+ if ( REALLOC_ARRAY( str->ligIDs, str->allocated, new_length, FT_UShort ) )
+ return error;
+ if ( REALLOC_ARRAY( str->logClusters, str->allocated, new_length, FT_Int ) )
+ return error;
+
+ str->allocated = new_length;
+ str->length = new_length;
+ }
+
+ return TT_Err_Ok;
+ }
+
+ EXPORT_FUNC
+ FT_Error TT_GSUB_String_Done( TTO_GSUB_String *str )
+ {
+ FT_Memory memory = str->memory;
+
+ FREE( str->string );
+ FREE( str->properties );
+ FREE( str->components );
+ FREE( str->ligIDs );
+ FREE( str->logClusters );
+
+ FREE( str );
+
+ return TT_Err_Ok;
+ }
+
+ EXPORT_FUNC
+ FT_Error TT_GSUB_Apply_String( TTO_GSUBHeader* gsub,
+ TTO_GSUB_String* in,
+ TTO_GSUB_String* out )
+ {
+ FT_Error error, retError = TTO_Err_Not_Covered;
+ FT_Memory memory = in->memory;
+ FT_UShort j;
+
+ TTO_GSUB_String tmp1;
+ TTO_GSUB_String* ptmp1;
+ TTO_GSUB_String tmp2;
+ TTO_GSUB_String* ptmp2;
+ TTO_GSUB_String* t;
+
+ FT_UShort* properties;
+
+
+ if ( !gsub ||
+ !in || !out || in->length == 0 || in->pos >= in->length )
+ return TT_Err_Invalid_Argument;
+
+ properties = gsub->LookupList.Properties;
+
+ tmp1.memory = memory;
+ tmp1.length = in->length;
+ tmp1.allocated = in->length;
+ tmp1.pos = in->pos;
+ tmp1.max_ligID = 1;
+ tmp1.string = NULL;
+ tmp1.properties = NULL;
+ tmp1.components = NULL;
+ tmp1.ligIDs = NULL;
+ tmp1.logClusters = NULL;
+
+ tmp2.memory = memory;
+ tmp2.allocated = 0;
+ tmp2.pos = 0;
+ tmp2.string = NULL;
+ tmp2.properties = NULL;
+ tmp2.components = NULL;
+ tmp2.ligIDs = NULL;
+ tmp2.logClusters = NULL;
+
+ ptmp1 = &tmp1;
+ ptmp2 = &tmp2;
+
+ if ( ALLOC_ARRAY( tmp1.string, tmp1.length, FT_UShort ) )
+ return error;
+ MEM_Copy( tmp1.string, in->string, in->length * sizeof ( FT_UShort ) );
+
+ /* make sure that we always have a `properties', `components', and
+ `ligIDs' array in the string object */
+
+ if ( ALLOC_ARRAY( tmp1.components, tmp1.length, FT_UShort ) )
+ goto End;
+ if ( ALLOC_ARRAY( tmp1.ligIDs, tmp1.length, FT_UShort ) )
+ goto End;
+ if ( ALLOC_ARRAY( tmp1.properties, tmp1.length, FT_UShort ) )
+ goto End;
+ if ( in->properties )
+ MEM_Copy( tmp1.properties, in->properties,
+ in->length * sizeof( FT_UShort ) );
+ if ( ALLOC_ARRAY( tmp1.logClusters, tmp1.length, FT_Int ) )
+ goto End;
+ MEM_Copy( tmp1.logClusters, in->logClusters,
+ in->length * sizeof( FT_Int ) );
+
+ for ( j = 0; j < gsub->LookupList.LookupCount; j++ )
+ if ( properties[j] )
+ {
+ error = gsub_Do_String_Lookup( gsub, j, ptmp1, ptmp2 );
+ if ( error )
+ {
+ if ( error != TTO_Err_Not_Covered )
+ goto End;
+ }
+ else
+ retError = error;
+
+
+ /* flipping `in' and `out', preparing the next loop */
+
+ ptmp1->pos = in->pos;
+ ptmp2->length = ptmp2->pos;
+ ptmp2->pos = in->pos;
+ ptmp2->max_ligID = ptmp1->max_ligID;
+
+ t = ptmp2;
+ ptmp2 = ptmp1;
+ ptmp1 = t;
+ }
+
+ End:
+ FREE( ptmp2->string );
+ FREE( ptmp2->properties );
+ FREE( ptmp2->components );
+ FREE( ptmp2->ligIDs );
+ FREE( ptmp2->logClusters );
+
+ if ( error && error != TTO_Err_Not_Covered )
+ {
+ FREE( ptmp1->string );
+ FREE( ptmp1->components );
+ FREE( ptmp1->ligIDs );
+ FREE( ptmp1->properties );
+ FREE( ptmp1->logClusters );
+
+ return error;
+ }
+ else
+ {
+ out->length = ptmp1->length;
+ out->pos = 0;
+ out->allocated = ptmp1->allocated;
+ out->string = ptmp1->string;
+ out->components = ptmp1->components;
+ out->ligIDs = ptmp1->ligIDs;
+ out->logClusters = ptmp1->logClusters;
+
+ if ( in->properties )
+ out->properties = ptmp1->properties;
+ else
+ {
+ FREE( ptmp1->properties );
+ out->properties = NULL;
+ }
+
+ return retError;
+ }
+ }
+
+
+/* END */
diff --git a/src/otlayout/ftxgsub.h b/src/otlayout/ftxgsub.h
new file mode 100644
index 000000000..8951e4413
--- /dev/null
+++ b/src/otlayout/ftxgsub.h
@@ -0,0 +1,613 @@
+/*******************************************************************
+ *
+ * ftxgsub.h
+ *
+ * TrueType Open GSUB table support
+ *
+ * Copyright 1996-2000 by
+ * David Turner, Robert Wilhelm, and Werner Lemberg.
+ *
+ * This file is part of the FreeType project, and may only be used
+ * modified and distributed under the terms of the FreeType project
+ * license, LICENSE.TXT. By continuing to use, modify, or distribute
+ * this file you indicate that you have read the license and
+ * understand and accept it fully.
+ *
+ ******************************************************************/
+
+#ifndef FTXOPEN_H
+#error "Don't include this file! Use ftxopen.h instead."
+#endif
+
+#ifndef FTXGSUB_H
+#define FTXGSUB_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define TTO_Err_Invalid_GSUB_SubTable_Format 0x1010
+#define TTO_Err_Invalid_GSUB_SubTable 0x1011
+
+
+/* Lookup types for glyph substitution */
+
+#define GSUB_LOOKUP_SINGLE 1
+#define GSUB_LOOKUP_MULTIPLE 2
+#define GSUB_LOOKUP_ALTERNATE 3
+#define GSUB_LOOKUP_LIGATURE 4
+#define GSUB_LOOKUP_CONTEXT 5
+#define GSUB_LOOKUP_CHAIN 6
+#define GSUB_LOOKUP_EXTENSION 7
+
+
+/* Use this if a feature applies to all glyphs */
+
+#define ALL_GLYPHS 0xFFFF
+
+
+ /* A pointer to a function which selects the alternate glyph. `pos' is
+ the position of the glyph with index `glyphID', `num_alternates'
+ gives the number of alternates in the `alternates' array. `data'
+ points to the user-defined structure specified during a call to
+ TT_GSUB_Register_Alternate_Function(). The function must return an
+ index into the `alternates' array. */
+
+ typedef FT_UShort (*TTO_AltFunction)(FT_ULong pos,
+ FT_UShort glyphID,
+ FT_UShort num_alternates,
+ FT_UShort* alternates,
+ void* data );
+
+
+ struct TTO_GSUBHeader_
+ {
+ FT_Memory memory;
+
+ FT_ULong offset;
+
+ FT_Fixed Version;
+
+ TTO_ScriptList ScriptList;
+ TTO_FeatureList FeatureList;
+ TTO_LookupList LookupList;
+
+ TTO_GDEFHeader* gdef;
+
+ /* the next two fields are used for an alternate substitution callback
+ function to select the proper alternate glyph. */
+
+ TTO_AltFunction altfunc;
+ void* data;
+ };
+
+ typedef struct TTO_GSUBHeader_ TTO_GSUBHeader;
+ typedef struct TTO_GSUBHeader_* TTO_GSUB;
+
+
+ /* LookupType 1 */
+
+ struct TTO_SingleSubstFormat1_
+ {
+ FT_Short DeltaGlyphID; /* constant added to get
+ substitution glyph index */
+ };
+
+ typedef struct TTO_SingleSubstFormat1_ TTO_SingleSubstFormat1;
+
+
+ struct TTO_SingleSubstFormat2_
+ {
+ FT_UShort GlyphCount; /* number of glyph IDs in
+ Substitute array */
+ FT_UShort* Substitute; /* array of substitute glyph IDs */
+ };
+
+ typedef struct TTO_SingleSubstFormat2_ TTO_SingleSubstFormat2;
+
+
+ struct TTO_SingleSubst_
+ {
+ FT_UShort SubstFormat; /* 1 or 2 */
+ TTO_Coverage Coverage; /* Coverage table */
+
+ union
+ {
+ TTO_SingleSubstFormat1 ssf1;
+ TTO_SingleSubstFormat2 ssf2;
+ } ssf;
+ };
+
+ typedef struct TTO_SingleSubst_ TTO_SingleSubst;
+
+
+ /* LookupType 2 */
+
+ struct TTO_Sequence_
+ {
+ FT_UShort GlyphCount; /* number of glyph IDs in the
+ Substitute array */
+ FT_UShort* Substitute; /* string of glyph IDs to
+ substitute */
+ };
+
+ typedef struct TTO_Sequence_ TTO_Sequence;
+
+
+ struct TTO_MultipleSubst_
+ {
+ FT_UShort SubstFormat; /* always 1 */
+ TTO_Coverage Coverage; /* Coverage table */
+ FT_UShort SequenceCount; /* number of Sequence tables */
+ TTO_Sequence* Sequence; /* array of Sequence tables */
+ };
+
+ typedef struct TTO_MultipleSubst_ TTO_MultipleSubst;
+
+
+ /* LookupType 3 */
+
+ struct TTO_AlternateSet_
+ {
+ FT_UShort GlyphCount; /* number of glyph IDs in the
+ Alternate array */
+ FT_UShort* Alternate; /* array of alternate glyph IDs */
+ };
+
+ typedef struct TTO_AlternateSet_ TTO_AlternateSet;
+
+
+ struct TTO_AlternateSubst_
+ {
+ FT_UShort SubstFormat; /* always 1 */
+ TTO_Coverage Coverage; /* Coverage table */
+ FT_UShort AlternateSetCount;
+ /* number of AlternateSet tables */
+ TTO_AlternateSet* AlternateSet; /* array of AlternateSet tables */
+ };
+
+ typedef struct TTO_AlternateSubst_ TTO_AlternateSubst;
+
+
+ /* LookupType 4 */
+
+ struct TTO_Ligature_
+ {
+ FT_UShort LigGlyph; /* glyphID of ligature
+ to substitute */
+ FT_UShort ComponentCount; /* number of components in ligature */
+ FT_UShort* Component; /* array of component glyph IDs */
+ };
+
+ typedef struct TTO_Ligature_ TTO_Ligature;
+
+
+ struct TTO_LigatureSet_
+ {
+ FT_UShort LigatureCount; /* number of Ligature tables */
+ TTO_Ligature* Ligature; /* array of Ligature tables */
+ };
+
+ typedef struct TTO_LigatureSet_ TTO_LigatureSet;
+
+
+ struct TTO_LigatureSubst_
+ {
+ FT_UShort SubstFormat; /* always 1 */
+ TTO_Coverage Coverage; /* Coverage table */
+ FT_UShort LigatureSetCount; /* number of LigatureSet tables */
+ TTO_LigatureSet* LigatureSet; /* array of LigatureSet tables */
+ };
+
+ typedef struct TTO_LigatureSubst_ TTO_LigatureSubst;
+
+
+ /* needed by both lookup type 5 and 6 */
+
+ struct TTO_SubstLookupRecord_
+ {
+ FT_UShort SequenceIndex; /* index into current
+ glyph sequence */
+ FT_UShort LookupListIndex; /* Lookup to apply to that pos. */
+ };
+
+ typedef struct TTO_SubstLookupRecord_ TTO_SubstLookupRecord;
+
+
+ /* LookupType 5 */
+
+ struct TTO_SubRule_
+ {
+ FT_UShort GlyphCount; /* total number of input glyphs */
+ FT_UShort SubstCount; /* number of SubstLookupRecord
+ tables */
+ FT_UShort* Input; /* array of input glyph IDs */
+ TTO_SubstLookupRecord* SubstLookupRecord;
+ /* array of SubstLookupRecord
+ tables */
+ };
+
+ typedef struct TTO_SubRule_ TTO_SubRule;
+
+
+ struct TTO_SubRuleSet_
+ {
+ FT_UShort SubRuleCount; /* number of SubRule tables */
+ TTO_SubRule* SubRule; /* array of SubRule tables */
+ };
+
+ typedef struct TTO_SubRuleSet_ TTO_SubRuleSet;
+
+
+ struct TTO_ContextSubstFormat1_
+ {
+ TTO_Coverage Coverage; /* Coverage table */
+ FT_UShort SubRuleSetCount; /* number of SubRuleSet tables */
+ TTO_SubRuleSet* SubRuleSet; /* array of SubRuleSet tables */
+ };
+
+ typedef struct TTO_ContextSubstFormat1_ TTO_ContextSubstFormat1;
+
+
+ struct TTO_SubClassRule_
+ {
+ FT_UShort GlyphCount; /* total number of context classes */
+ FT_UShort SubstCount; /* number of SubstLookupRecord
+ tables */
+ FT_UShort* Class; /* array of classes */
+ TTO_SubstLookupRecord* SubstLookupRecord;
+ /* array of SubstLookupRecord
+ tables */
+ };
+
+ typedef struct TTO_SubClassRule_ TTO_SubClassRule;
+
+
+ struct TTO_SubClassSet_
+ {
+ FT_UShort SubClassRuleCount;
+ /* number of SubClassRule tables */
+ TTO_SubClassRule* SubClassRule; /* array of SubClassRule tables */
+ };
+
+ typedef struct TTO_SubClassSet_ TTO_SubClassSet;
+
+
+ /* The `MaxContextLength' field is not defined in the TTO specification
+ but simplifies the implementation of this format. It holds the
+ maximal context length used in the context rules. */
+
+ struct TTO_ContextSubstFormat2_
+ {
+ FT_UShort MaxContextLength;
+ /* maximal context length */
+ TTO_Coverage Coverage; /* Coverage table */
+ TTO_ClassDefinition ClassDef; /* ClassDef table */
+ FT_UShort SubClassSetCount;
+ /* number of SubClassSet tables */
+ TTO_SubClassSet* SubClassSet; /* array of SubClassSet tables */
+ };
+
+ typedef struct TTO_ContextSubstFormat2_ TTO_ContextSubstFormat2;
+
+
+ struct TTO_ContextSubstFormat3_
+ {
+ FT_UShort GlyphCount; /* number of input glyphs */
+ FT_UShort SubstCount; /* number of SubstLookupRecords */
+ TTO_Coverage* Coverage; /* array of Coverage tables */
+ TTO_SubstLookupRecord* SubstLookupRecord;
+ /* array of substitution lookups */
+ };
+
+ typedef struct TTO_ContextSubstFormat3_ TTO_ContextSubstFormat3;
+
+
+ struct TTO_ContextSubst_
+ {
+ FT_UShort SubstFormat; /* 1, 2, or 3 */
+
+ union
+ {
+ TTO_ContextSubstFormat1 csf1;
+ TTO_ContextSubstFormat2 csf2;
+ TTO_ContextSubstFormat3 csf3;
+ } csf;
+ };
+
+ typedef struct TTO_ContextSubst_ TTO_ContextSubst;
+
+
+ /* LookupType 6 */
+
+ struct TTO_ChainSubRule_
+ {
+ FT_UShort BacktrackGlyphCount;
+ /* total number of backtrack glyphs */
+ FT_UShort* Backtrack; /* array of backtrack glyph IDs */
+ FT_UShort InputGlyphCount;
+ /* total number of input glyphs */
+ FT_UShort* Input; /* array of input glyph IDs */
+ FT_UShort LookaheadGlyphCount;
+ /* total number of lookahead glyphs */
+ FT_UShort* Lookahead; /* array of lookahead glyph IDs */
+ FT_UShort SubstCount; /* number of SubstLookupRecords */
+ TTO_SubstLookupRecord* SubstLookupRecord;
+ /* array of SubstLookupRecords */
+ };
+
+ typedef struct TTO_ChainSubRule_ TTO_ChainSubRule;
+
+
+ struct TTO_ChainSubRuleSet_
+ {
+ FT_UShort ChainSubRuleCount;
+ /* number of ChainSubRule tables */
+ TTO_ChainSubRule* ChainSubRule; /* array of ChainSubRule tables */
+ };
+
+ typedef struct TTO_ChainSubRuleSet_ TTO_ChainSubRuleSet;
+
+
+ struct TTO_ChainContextSubstFormat1_
+ {
+ TTO_Coverage Coverage; /* Coverage table */
+ FT_UShort ChainSubRuleSetCount;
+ /* number of ChainSubRuleSet tables */
+ TTO_ChainSubRuleSet* ChainSubRuleSet;
+ /* array of ChainSubRuleSet tables */
+ };
+
+ typedef struct TTO_ChainContextSubstFormat1_ TTO_ChainContextSubstFormat1;
+
+
+ struct TTO_ChainSubClassRule_
+ {
+ FT_UShort BacktrackGlyphCount;
+ /* total number of backtrack
+ classes */
+ FT_UShort* Backtrack; /* array of backtrack classes */
+ FT_UShort InputGlyphCount;
+ /* total number of context classes */
+ FT_UShort* Input; /* array of context classes */
+ FT_UShort LookaheadGlyphCount;
+ /* total number of lookahead
+ classes */
+ FT_UShort* Lookahead; /* array of lookahead classes */
+ FT_UShort SubstCount; /* number of SubstLookupRecords */
+ TTO_SubstLookupRecord* SubstLookupRecord;
+ /* array of substitution lookups */
+ };
+
+ typedef struct TTO_ChainSubClassRule_ TTO_ChainSubClassRule;
+
+
+ struct TTO_ChainSubClassSet_
+ {
+ FT_UShort ChainSubClassRuleCount;
+ /* number of ChainSubClassRule
+ tables */
+ TTO_ChainSubClassRule* ChainSubClassRule;
+ /* array of ChainSubClassRule
+ tables */
+ };
+
+ typedef struct TTO_ChainSubClassSet_ TTO_ChainSubClassSet;
+
+
+ /* The `MaxXXXLength' fields are not defined in the TTO specification
+ but simplifies the implementation of this format. It holds the
+ maximal context length used in the specific context rules. */
+
+ struct TTO_ChainContextSubstFormat2_
+ {
+ TTO_Coverage Coverage; /* Coverage table */
+
+ FT_UShort MaxBacktrackLength;
+ /* maximal backtrack length */
+ TTO_ClassDefinition BacktrackClassDef;
+ /* BacktrackClassDef table */
+ FT_UShort MaxInputLength;
+ /* maximal input length */
+ TTO_ClassDefinition InputClassDef;
+ /* InputClassDef table */
+ FT_UShort MaxLookaheadLength;
+ /* maximal lookahead length */
+ TTO_ClassDefinition LookaheadClassDef;
+ /* LookaheadClassDef table */
+
+ FT_UShort ChainSubClassSetCount;
+ /* number of ChainSubClassSet
+ tables */
+ TTO_ChainSubClassSet* ChainSubClassSet;
+ /* array of ChainSubClassSet
+ tables */
+ };
+
+ typedef struct TTO_ChainContextSubstFormat2_ TTO_ChainContextSubstFormat2;
+
+
+ struct TTO_ChainContextSubstFormat3_
+ {
+ FT_UShort BacktrackGlyphCount;
+ /* number of backtrack glyphs */
+ TTO_Coverage* BacktrackCoverage;
+ /* array of backtrack Coverage
+ tables */
+ FT_UShort InputGlyphCount;
+ /* number of input glyphs */
+ TTO_Coverage* InputCoverage;
+ /* array of input coverage
+ tables */
+ FT_UShort LookaheadGlyphCount;
+ /* number of lookahead glyphs */
+ TTO_Coverage* LookaheadCoverage;
+ /* array of lookahead coverage
+ tables */
+ FT_UShort SubstCount; /* number of SubstLookupRecords */
+ TTO_SubstLookupRecord* SubstLookupRecord;
+ /* array of substitution lookups */
+ };
+
+ typedef struct TTO_ChainContextSubstFormat3_ TTO_ChainContextSubstFormat3;
+
+
+ struct TTO_ChainContextSubst_
+ {
+ FT_UShort SubstFormat; /* 1, 2, or 3 */
+
+ union
+ {
+ TTO_ChainContextSubstFormat1 ccsf1;
+ TTO_ChainContextSubstFormat2 ccsf2;
+ TTO_ChainContextSubstFormat3 ccsf3;
+ } ccsf;
+ };
+
+ typedef struct TTO_ChainContextSubst_ TTO_ChainContextSubst;
+
+
+ union TTO_GSUB_SubTable_
+ {
+ TTO_SingleSubst single;
+ TTO_MultipleSubst multiple;
+ TTO_AlternateSubst alternate;
+ TTO_LigatureSubst ligature;
+ TTO_ContextSubst context;
+ TTO_ChainContextSubst chain;
+ };
+
+ typedef union TTO_GSUB_SubTable_ TTO_GSUB_SubTable;
+
+
+ /* A simple string object. It can both `send' and `receive' data.
+ In case of sending, `length' and `pos' will be used. In case of
+ receiving, `pos' points to the first free slot, and `allocated'
+ specifies the amount of allocated memory (and the `length' field
+ will be ignored). The routine TT_Add_String() will increase the
+ amount of memory if necessary. After end of receive, `length'
+ should be set to the value of `pos', and `pos' will be set to zero.
+
+ `properties' (which is treated as a bit field) gives the glyph's
+ properties: If a certain bit is set for a glyph, the feature which
+ has the same bit set in its property value is applied.
+
+ `components' is an internal array which tracks components of
+ ligatures. We need this for MarkToLigature Attachment Positioning
+ Subtables (in GPOS) together with `ligIDs' (which is used to mark
+ ligatures and the skipped glyphs during a ligature lookup).
+ `max_ligID' is increased after a successful ligature lookup.
+
+ NEVER modify any elements of the structure! You should rather copy
+ its contents if necessary.
+
+ TT_Add_String() will also handle allocation; you should use
+ free() in case you want to destroy the arrays in the object. */
+
+ struct TTO_GSUB_String_
+ {
+ FT_Memory memory;
+
+ FT_ULong length;
+ FT_ULong pos;
+ FT_ULong allocated;
+ FT_UShort* string;
+ FT_UShort* properties;
+ FT_UShort* components;
+ FT_UShort max_ligID;
+ FT_UShort* ligIDs;
+ FT_Int* logClusters;
+ };
+
+ typedef struct TTO_GSUB_String_ TTO_GSUB_String;
+
+
+ /* finally, the GSUB API */
+
+ /* EXPORT_DEF
+ TT_Error TT_Init_GSUB_Extension( TT_Engine engine ); */
+
+ EXPORT_DEF
+ FT_Error TT_Load_GSUB_Table( FT_Face face,
+ TTO_GSUBHeader** gsub,
+ TTO_GDEFHeader* gdef );
+
+ EXPORT_DEF
+ FT_Error TT_Done_GSUB_Table( TTO_GSUBHeader* gsub );
+
+ EXPORT_DEF
+ FT_Error TT_GSUB_Select_Script( TTO_GSUBHeader* gsub,
+ FT_ULong script_tag,
+ FT_UShort* script_index );
+ EXPORT_DEF
+ FT_Error TT_GSUB_Select_Language( TTO_GSUBHeader* gsub,
+ FT_ULong language_tag,
+ FT_UShort script_index,
+ FT_UShort* language_index,
+ FT_UShort* req_feature_index );
+ EXPORT_DEF
+ FT_Error TT_GSUB_Select_Feature( TTO_GSUBHeader* gsub,
+ FT_ULong feature_tag,
+ FT_UShort script_index,
+ FT_UShort language_index,
+ FT_UShort* feature_index );
+
+ EXPORT_DEF
+ FT_Error TT_GSUB_Query_Scripts( TTO_GSUBHeader* gsub,
+ FT_ULong** script_tag_list );
+ EXPORT_DEF
+ FT_Error TT_GSUB_Query_Languages( TTO_GSUBHeader* gsub,
+ FT_UShort script_index,
+ FT_ULong** language_tag_list );
+ EXPORT_DEF
+ FT_Error TT_GSUB_Query_Features( TTO_GSUBHeader* gsub,
+ FT_UShort script_index,
+ FT_UShort language_index,
+ FT_ULong** feature_tag_list );
+
+ EXPORT_DEF
+ FT_Error TT_GSUB_Add_Feature( TTO_GSUBHeader* gsub,
+ FT_UShort feature_index,
+ FT_UShort property );
+ EXPORT_DEF
+ FT_Error TT_GSUB_Clear_Features( TTO_GSUBHeader* gsub );
+
+ EXPORT_DEF
+ FT_Error TT_GSUB_Register_Alternate_Function( TTO_GSUBHeader* gsub,
+ TTO_AltFunction altfunc,
+ void* data );
+
+ EXPORT_DEF
+ FT_Error TT_GSUB_String_New( FT_Memory memory,
+ TTO_GSUB_String **result );
+
+ EXPORT_DEF
+ FT_Error TT_GSUB_String_Set_Length( TTO_GSUB_String *str,
+ FT_ULong new_length);
+
+ EXPORT_DEF
+ FT_Error TT_GSUB_String_Done( TTO_GSUB_String *str );
+
+
+ EXPORT_DEF
+ FT_Error TT_GSUB_Apply_String( TTO_GSUBHeader* gsub,
+ TTO_GSUB_String* in,
+ TTO_GSUB_String* out );
+
+ EXPORT_DEF
+ FT_Error TT_GSUB_Add_String( TTO_GSUB_String* in,
+ FT_UShort num_in,
+ TTO_GSUB_String* out,
+ FT_UShort num_out,
+ FT_UShort* glyph_data,
+ FT_UShort component,
+ FT_UShort ligID );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* FTXGSUB_H */
+
+
+/* END */
diff --git a/src/otlayout/ftxopen.c b/src/otlayout/ftxopen.c
new file mode 100644
index 000000000..2325f6a2c
--- /dev/null
+++ b/src/otlayout/ftxopen.c
@@ -0,0 +1,1520 @@
+/*******************************************************************
+ *
+ * ftxopen.c
+ *
+ * TrueType Open common table support.
+ *
+ * Copyright 1996-2000 by
+ * David Turner, Robert Wilhelm, and Werner Lemberg.
+ *
+ * This file is part of the FreeType project, and may only be used
+ * modified and distributed under the terms of the FreeType project
+ * license, LICENSE.TXT. By continuing to use, modify, or distribute
+ * this file you indicate that you have read the license and
+ * understand and accept it fully.
+ *
+ ******************************************************************/
+
+#include "ftxopen.h"
+#include "ftxopenf.h"
+
+#include "fterrcompat.h"
+
+#include FT_INTERNAL_STREAM_H
+#include FT_INTERNAL_MEMORY_H
+#include FT_INTERNAL_TRUETYPE_TYPES_H
+
+
+ /***************************
+ * Script related functions
+ ***************************/
+
+
+ /* LangSys */
+
+ static FT_Error Load_LangSys( TTO_LangSys* ls,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+ FT_UShort n, count;
+ FT_UShort* fi;
+
+
+ if ( ACCESS_Frame( 6L ) )
+ return error;
+
+ ls->LookupOrderOffset = GET_UShort(); /* should be 0 */
+ ls->ReqFeatureIndex = GET_UShort();
+ count = ls->FeatureCount = GET_UShort();
+
+ FORGET_Frame();
+
+ ls->FeatureIndex = NULL;
+
+ if ( ALLOC_ARRAY( ls->FeatureIndex, count, FT_UShort ) )
+ return error;
+
+ if ( ACCESS_Frame( count * 2L ) )
+ {
+ FREE( ls->FeatureIndex );
+ return error;
+ }
+
+ fi = ls->FeatureIndex;
+
+ for ( n = 0; n < count; n++ )
+ fi[n] = GET_UShort();
+
+ FORGET_Frame();
+
+ return TT_Err_Ok;
+ }
+
+
+ static void Free_LangSys( TTO_LangSys* ls,
+ FT_Memory memory )
+ {
+ FREE( ls->FeatureIndex );
+ }
+
+
+ /* Script */
+
+ static FT_Error Load_Script( TTO_Script* s,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+ FT_UShort n, m, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_LangSysRecord* lsr;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ if ( new_offset != base_offset ) /* not a NULL offset */
+ {
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_LangSys( &s->DefaultLangSys,
+ stream ) ) != TT_Err_Ok )
+ return error;
+ (void)FILE_Seek( cur_offset );
+ }
+ else
+ {
+ /* we create a DefaultLangSys table with no entries */
+
+ s->DefaultLangSys.LookupOrderOffset = 0;
+ s->DefaultLangSys.ReqFeatureIndex = 0xFFFF;
+ s->DefaultLangSys.FeatureCount = 0;
+ s->DefaultLangSys.FeatureIndex = NULL;
+ }
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail2;
+
+ count = s->LangSysCount = GET_UShort();
+
+ /* safety check; otherwise the official handling of TrueType Open
+ fonts won't work */
+
+ if ( s->LangSysCount == 0 && s->DefaultLangSys.FeatureCount == 0 )
+ {
+ error = TTO_Err_Empty_Script;
+ goto Fail2;
+ }
+
+ FORGET_Frame();
+
+ s->LangSysRecord = NULL;
+
+ if ( ALLOC_ARRAY( s->LangSysRecord, count, TTO_LangSysRecord ) )
+ goto Fail2;
+
+ lsr = s->LangSysRecord;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 6L ) )
+ goto Fail1;
+
+ lsr[n].LangSysTag = GET_ULong();
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_LangSys( &lsr[n].LangSys, stream ) ) != TT_Err_Ok )
+ goto Fail1;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ return TT_Err_Ok;
+
+ Fail1:
+ for ( m = 0; m < n; m++ )
+ Free_LangSys( &lsr[m].LangSys, memory );
+
+ FREE( s->LangSysRecord );
+
+ Fail2:
+ Free_LangSys( &s->DefaultLangSys, memory );
+ return error;
+ }
+
+
+ static void Free_Script( TTO_Script* s,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_LangSysRecord* lsr;
+
+
+ Free_LangSys( &s->DefaultLangSys, memory );
+
+ if ( s->LangSysRecord )
+ {
+ count = s->LangSysCount;
+ lsr = s->LangSysRecord;
+
+ for ( n = 0; n < count; n++ )
+ Free_LangSys( &lsr[n].LangSys, memory );
+
+ FREE( lsr );
+ }
+ }
+
+
+ /* ScriptList */
+
+ FT_Error Load_ScriptList( TTO_ScriptList* sl,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, script_count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_ScriptRecord* sr;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ script_count = GET_UShort();
+
+ FORGET_Frame();
+
+ sl->ScriptRecord = NULL;
+
+ if ( ALLOC_ARRAY( sl->ScriptRecord, script_count, TTO_ScriptRecord ) )
+ return error;
+
+ sr = sl->ScriptRecord;
+
+ sl->ScriptCount= 0;
+ for ( n = 0; n < script_count; n++ )
+ {
+ if ( ACCESS_Frame( 6L ) )
+ goto Fail;
+
+ sr[sl->ScriptCount].ScriptTag = GET_ULong();
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+
+ if ( FILE_Seek( new_offset ) )
+ goto Fail;
+
+ error = Load_Script( &sr[sl->ScriptCount].Script, stream );
+ if ( error == TT_Err_Ok )
+ sl->ScriptCount += 1;
+ else if ( error != TTO_Err_Empty_Script )
+ goto Fail;
+
+ (void)FILE_Seek( cur_offset );
+ }
+
+ if ( sl->ScriptCount == 0 )
+ {
+ error = TTO_Err_Invalid_SubTable;
+ goto Fail;
+ }
+
+ return TT_Err_Ok;
+
+ Fail:
+ for ( n = 0; n < sl->ScriptCount; n++ )
+ Free_Script( &sr[n].Script, memory );
+
+ FREE( sl->ScriptRecord );
+ return error;
+ }
+
+
+ void Free_ScriptList( TTO_ScriptList* sl,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_ScriptRecord* sr;
+
+
+ if ( sl->ScriptRecord )
+ {
+ count = sl->ScriptCount;
+ sr = sl->ScriptRecord;
+
+ for ( n = 0; n < count; n++ )
+ Free_Script( &sr[n].Script, memory );
+
+ FREE( sr );
+ }
+ }
+
+
+
+ /*********************************
+ * Feature List related functions
+ *********************************/
+
+
+ /* Feature */
+
+ static FT_Error Load_Feature( TTO_Feature* f,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, count;
+
+ FT_UShort* lli;
+
+
+ if ( ACCESS_Frame( 4L ) )
+ return error;
+
+ f->FeatureParams = GET_UShort(); /* should be 0 */
+ count = f->LookupListCount = GET_UShort();
+
+ FORGET_Frame();
+
+ f->LookupListIndex = NULL;
+
+ if ( ALLOC_ARRAY( f->LookupListIndex, count, FT_UShort ) )
+ return error;
+
+ lli = f->LookupListIndex;
+
+ if ( ACCESS_Frame( count * 2L ) )
+ {
+ FREE( f->LookupListIndex );
+ return error;
+ }
+
+ for ( n = 0; n < count; n++ )
+ lli[n] = GET_UShort();
+
+ FORGET_Frame();
+
+ return TT_Err_Ok;
+ }
+
+
+ static void Free_Feature( TTO_Feature* f,
+ FT_Memory memory )
+ {
+ FREE( f->LookupListIndex );
+ }
+
+
+ /* FeatureList */
+
+ FT_Error Load_FeatureList( TTO_FeatureList* fl,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, m, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_FeatureRecord* fr;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ count = fl->FeatureCount = GET_UShort();
+
+ FORGET_Frame();
+
+ fl->FeatureRecord = NULL;
+
+ if ( ALLOC_ARRAY( fl->FeatureRecord, count, TTO_FeatureRecord ) )
+ return error;
+
+ fr = fl->FeatureRecord;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 6L ) )
+ goto Fail;
+
+ fr[n].FeatureTag = GET_ULong();
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Feature( &fr[n].Feature, stream ) ) != TT_Err_Ok )
+ goto Fail;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ return TT_Err_Ok;
+
+ Fail:
+ for ( m = 0; m < n; m++ )
+ Free_Feature( &fr[m].Feature, memory );
+
+ FREE( fl->FeatureRecord );
+ return error;
+ }
+
+
+ void Free_FeatureList( TTO_FeatureList* fl,
+ FT_Memory memory)
+ {
+ FT_UShort n, count;
+
+ TTO_FeatureRecord* fr;
+
+
+ if ( fl->FeatureRecord )
+ {
+ count = fl->FeatureCount;
+ fr = fl->FeatureRecord;
+
+ for ( n = 0; n < count; n++ )
+ Free_Feature( &fr[n].Feature, memory );
+
+ FREE( fr );
+ }
+ }
+
+
+
+ /********************************
+ * Lookup List related functions
+ ********************************/
+
+ /* the subroutines of the following two functions are defined in
+ ftxgsub.c and ftxgpos.c respectively */
+
+
+ /* SubTable */
+
+ static FT_Error Load_SubTable( TTO_SubTable* st,
+ FT_Stream stream,
+ TTO_Type table_type,
+ FT_UShort lookup_type )
+ {
+ if ( table_type == GSUB )
+ switch ( lookup_type )
+ {
+ case GSUB_LOOKUP_SINGLE:
+ return Load_SingleSubst( &st->st.gsub.single, stream );
+
+ case GSUB_LOOKUP_MULTIPLE:
+ return Load_MultipleSubst( &st->st.gsub.multiple, stream );
+
+ case GSUB_LOOKUP_ALTERNATE:
+ return Load_AlternateSubst( &st->st.gsub.alternate, stream );
+
+ case GSUB_LOOKUP_LIGATURE:
+ return Load_LigatureSubst( &st->st.gsub.ligature, stream );
+
+ case GSUB_LOOKUP_CONTEXT:
+ return Load_ContextSubst( &st->st.gsub.context, stream );
+
+ case GSUB_LOOKUP_CHAIN:
+ return Load_ChainContextSubst( &st->st.gsub.chain, stream );
+
+ default:
+ return TTO_Err_Invalid_GSUB_SubTable_Format;
+ }
+ else
+ switch ( lookup_type )
+ {
+ case GPOS_LOOKUP_SINGLE:
+ return Load_SinglePos( &st->st.gpos.single, stream );
+
+ case GPOS_LOOKUP_PAIR:
+ return Load_PairPos( &st->st.gpos.pair, stream );
+
+ case GPOS_LOOKUP_CURSIVE:
+ return Load_CursivePos( &st->st.gpos.cursive, stream );
+
+ case GPOS_LOOKUP_MARKBASE:
+ return Load_MarkBasePos( &st->st.gpos.markbase, stream );
+
+ case GPOS_LOOKUP_MARKLIG:
+ return Load_MarkLigPos( &st->st.gpos.marklig, stream );
+
+ case GPOS_LOOKUP_MARKMARK:
+ return Load_MarkMarkPos( &st->st.gpos.markmark, stream );
+
+ case GPOS_LOOKUP_CONTEXT:
+ return Load_ContextPos( &st->st.gpos.context, stream );
+
+ case GPOS_LOOKUP_CHAIN:
+ return Load_ChainContextPos( &st->st.gpos.chain, stream );
+
+ default:
+ return TTO_Err_Invalid_GPOS_SubTable_Format;
+ }
+
+ return TT_Err_Ok; /* never reached */
+ }
+
+
+ static void Free_SubTable( TTO_SubTable* st,
+ TTO_Type table_type,
+ FT_UShort lookup_type,
+ FT_Memory memory )
+ {
+ if ( table_type == GSUB )
+ switch ( lookup_type )
+ {
+ case GSUB_LOOKUP_SINGLE:
+ Free_SingleSubst( &st->st.gsub.single, memory );
+ break;
+
+ case GSUB_LOOKUP_MULTIPLE:
+ Free_MultipleSubst( &st->st.gsub.multiple, memory );
+ break;
+
+ case GSUB_LOOKUP_ALTERNATE:
+ Free_AlternateSubst( &st->st.gsub.alternate, memory );
+ break;
+
+ case GSUB_LOOKUP_LIGATURE:
+ Free_LigatureSubst( &st->st.gsub.ligature, memory );
+ break;
+
+ case GSUB_LOOKUP_CONTEXT:
+ Free_ContextSubst( &st->st.gsub.context, memory );
+ break;
+
+ case GSUB_LOOKUP_CHAIN:
+ Free_ChainContextSubst( &st->st.gsub.chain, memory );
+ break;
+ }
+ else
+ switch ( lookup_type )
+ {
+ case GPOS_LOOKUP_SINGLE:
+ Free_SinglePos( &st->st.gpos.single, memory );
+ break;
+
+ case GPOS_LOOKUP_PAIR:
+ Free_PairPos( &st->st.gpos.pair, memory );
+ break;
+
+ case GPOS_LOOKUP_CURSIVE:
+ Free_CursivePos( &st->st.gpos.cursive, memory );
+ break;
+
+ case GPOS_LOOKUP_MARKBASE:
+ Free_MarkBasePos( &st->st.gpos.markbase, memory );
+ break;
+
+ case GPOS_LOOKUP_MARKLIG:
+ Free_MarkLigPos( &st->st.gpos.marklig, memory );
+ break;
+
+ case GPOS_LOOKUP_MARKMARK:
+ Free_MarkMarkPos( &st->st.gpos.markmark, memory );
+ break;
+
+ case GPOS_LOOKUP_CONTEXT:
+ Free_ContextPos( &st->st.gpos.context, memory );
+ break;
+
+ case GPOS_LOOKUP_CHAIN:
+ Free_ChainContextPos ( &st->st.gpos.chain, memory );
+ break;
+ }
+ }
+
+
+ /* Lookup */
+
+ static FT_Error Load_Lookup( TTO_Lookup* l,
+ FT_Stream stream,
+ TTO_Type type )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, m, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_SubTable* st;
+
+ FT_Bool is_extension = FALSE;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 6L ) )
+ return error;
+
+ l->LookupType = GET_UShort();
+ l->LookupFlag = GET_UShort();
+ count = l->SubTableCount = GET_UShort();
+
+ FORGET_Frame();
+
+ l->SubTable = NULL;
+
+ if ( ALLOC_ARRAY( l->SubTable, count, TTO_SubTable ) )
+ return error;
+
+ st = l->SubTable;
+
+ if ( ( type == GSUB && l->LookupType == GSUB_LOOKUP_EXTENSION ) ||
+ ( type == GPOS && l->LookupType == GPOS_LOOKUP_EXTENSION ) )
+ is_extension = TRUE;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+
+ if ( is_extension )
+ {
+ if ( FILE_Seek( new_offset ) || ACCESS_Frame( 8L ) )
+ goto Fail;
+
+ (void)GET_UShort(); /* format should be 1 */
+ l->LookupType = GET_UShort();
+ new_offset = GET_ULong() + base_offset;
+
+ FORGET_Frame();
+ }
+
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_SubTable( &st[n], stream,
+ type, l->LookupType ) ) != TT_Err_Ok )
+ goto Fail;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ return TT_Err_Ok;
+
+ Fail:
+ for ( m = 0; m < n; m++ )
+ Free_SubTable( &st[m], type, l->LookupType, memory );
+
+ FREE( l->SubTable );
+ return error;
+ }
+
+
+ static void Free_Lookup( TTO_Lookup* l,
+ TTO_Type type,
+ FT_Memory memory)
+ {
+ FT_UShort n, count;
+
+ TTO_SubTable* st;
+
+
+ if ( l->SubTable )
+ {
+ count = l->SubTableCount;
+ st = l->SubTable;
+
+ for ( n = 0; n < count; n++ )
+ Free_SubTable( &st[n], type, l->LookupType, memory );
+
+ FREE( st );
+ }
+ }
+
+
+ /* LookupList */
+
+ FT_Error Load_LookupList( TTO_LookupList* ll,
+ FT_Stream stream,
+ TTO_Type type )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, m, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_Lookup* l;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ count = ll->LookupCount = GET_UShort();
+
+ FORGET_Frame();
+
+ ll->Lookup = NULL;
+
+ if ( ALLOC_ARRAY( ll->Lookup, count, TTO_Lookup ) )
+ return error;
+ if ( ALLOC_ARRAY( ll->Properties, count, FT_UShort ) )
+ goto Fail2;
+
+ l = ll->Lookup;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail1;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Lookup( &l[n], stream, type ) ) != TT_Err_Ok )
+ goto Fail1;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ return TT_Err_Ok;
+
+ Fail1:
+ FREE( ll->Properties );
+
+ for ( m = 0; m < n; m++ )
+ Free_Lookup( &l[m], type, memory );
+
+ Fail2:
+ FREE( ll->Lookup );
+ return error;
+ }
+
+
+ void Free_LookupList( TTO_LookupList* ll,
+ TTO_Type type,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_Lookup* l;
+
+
+ FREE( ll->Properties );
+
+ if ( ll->Lookup )
+ {
+ count = ll->LookupCount;
+ l = ll->Lookup;
+
+ for ( n = 0; n < count; n++ )
+ Free_Lookup( &l[n], type, memory );
+
+ FREE( l );
+ }
+ }
+
+
+
+ /*****************************
+ * Coverage related functions
+ *****************************/
+
+
+ /* CoverageFormat1 */
+
+ static FT_Error Load_Coverage1( TTO_CoverageFormat1* cf1,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, count;
+
+ FT_UShort* ga;
+
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ count = cf1->GlyphCount = GET_UShort();
+
+ FORGET_Frame();
+
+ cf1->GlyphArray = NULL;
+
+ if ( ALLOC_ARRAY( cf1->GlyphArray, count, FT_UShort ) )
+ return error;
+
+ ga = cf1->GlyphArray;
+
+ if ( ACCESS_Frame( count * 2L ) )
+ {
+ FREE( cf1->GlyphArray );
+ return error;
+ }
+
+ for ( n = 0; n < count; n++ )
+ ga[n] = GET_UShort();
+
+ FORGET_Frame();
+
+ return TT_Err_Ok;
+ }
+
+
+ static void Free_Coverage1( TTO_CoverageFormat1* cf1,
+ FT_Memory memory)
+ {
+ FREE( cf1->GlyphArray );
+ }
+
+
+ /* CoverageFormat2 */
+
+ static FT_Error Load_Coverage2( TTO_CoverageFormat2* cf2,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, count;
+
+ TTO_RangeRecord* rr;
+
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ count = cf2->RangeCount = GET_UShort();
+
+ FORGET_Frame();
+
+ cf2->RangeRecord = NULL;
+
+ if ( ALLOC_ARRAY( cf2->RangeRecord, count, TTO_RangeRecord ) )
+ return error;
+
+ rr = cf2->RangeRecord;
+
+ if ( ACCESS_Frame( count * 6L ) )
+ goto Fail;
+
+ for ( n = 0; n < count; n++ )
+ {
+ rr[n].Start = GET_UShort();
+ rr[n].End = GET_UShort();
+ rr[n].StartCoverageIndex = GET_UShort();
+
+ /* sanity check; we are limited to 16bit integers */
+ if ( rr[n].Start > rr[n].End ||
+ ( rr[n].End - rr[n].Start + (long)rr[n].StartCoverageIndex ) >=
+ 0x10000L )
+ {
+ error = TTO_Err_Invalid_SubTable;
+ goto Fail;
+ }
+ }
+
+ FORGET_Frame();
+
+ return TT_Err_Ok;
+
+ Fail:
+ FREE( cf2->RangeRecord );
+ return error;
+ }
+
+
+ static void Free_Coverage2( TTO_CoverageFormat2* cf2,
+ FT_Memory memory )
+ {
+ FREE( cf2->RangeRecord );
+ }
+
+
+ FT_Error Load_Coverage( TTO_Coverage* c,
+ FT_Stream stream )
+ {
+ FT_Error error;
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ c->CoverageFormat = GET_UShort();
+
+ FORGET_Frame();
+
+ switch ( c->CoverageFormat )
+ {
+ case 1:
+ return Load_Coverage1( &c->cf.cf1, stream );
+
+ case 2:
+ return Load_Coverage2( &c->cf.cf2, stream );
+
+ default:
+ return TTO_Err_Invalid_SubTable_Format;
+ }
+
+ return TT_Err_Ok; /* never reached */
+ }
+
+
+ void Free_Coverage( TTO_Coverage* c,
+ FT_Memory memory )
+ {
+ switch ( c->CoverageFormat )
+ {
+ case 1:
+ Free_Coverage1( &c->cf.cf1, memory );
+ break;
+
+ case 2:
+ Free_Coverage2( &c->cf.cf2, memory );
+ break;
+ }
+ }
+
+
+ static FT_Error Coverage_Index1( TTO_CoverageFormat1* cf1,
+ FT_UShort glyphID,
+ FT_UShort* index )
+ {
+ FT_UShort min, max, new_min, new_max, middle;
+
+ FT_UShort* array = cf1->GlyphArray;
+
+
+ /* binary search */
+
+ new_min = 0;
+ new_max = cf1->GlyphCount - 1;
+
+ do
+ {
+ min = new_min;
+ max = new_max;
+
+ /* we use (min + max) / 2 = max - (max - min) / 2 to avoid
+ overflow and rounding errors */
+
+ middle = max - ( ( max - min ) >> 1 );
+
+ if ( glyphID == array[middle] )
+ {
+ *index = middle;
+ return TT_Err_Ok;
+ }
+ else if ( glyphID < array[middle] )
+ {
+ if ( middle == min )
+ break;
+ new_max = middle - 1;
+ }
+ else
+ {
+ if ( middle == max )
+ break;
+ new_min = middle + 1;
+ }
+ } while ( min < max );
+
+ return TTO_Err_Not_Covered;
+ }
+
+
+ static FT_Error Coverage_Index2( TTO_CoverageFormat2* cf2,
+ FT_UShort glyphID,
+ FT_UShort* index )
+ {
+ FT_UShort min, max, new_min, new_max, middle;
+
+ TTO_RangeRecord* rr = cf2->RangeRecord;
+
+
+ /* binary search */
+
+ new_min = 0;
+ new_max = cf2->RangeCount - 1;
+
+ do
+ {
+ min = new_min;
+ max = new_max;
+
+ /* we use (min + max) / 2 = max - (max - min) / 2 to avoid
+ overflow and rounding errors */
+
+ middle = max - ( ( max - min ) >> 1 );
+
+ if ( glyphID >= rr[middle].Start && glyphID <= rr[middle].End )
+ {
+ *index = rr[middle].StartCoverageIndex + glyphID - rr[middle].Start;
+ return TT_Err_Ok;
+ }
+ else if ( glyphID < rr[middle].Start )
+ {
+ if ( middle == min )
+ break;
+ new_max = middle - 1;
+ }
+ else
+ {
+ if ( middle == max )
+ break;
+ new_min = middle + 1;
+ }
+ } while ( min < max );
+
+ return TTO_Err_Not_Covered;
+ }
+
+
+ FT_Error Coverage_Index( TTO_Coverage* c,
+ FT_UShort glyphID,
+ FT_UShort* index )
+ {
+ switch ( c->CoverageFormat )
+ {
+ case 1:
+ return Coverage_Index1( &c->cf.cf1, glyphID, index );
+
+ case 2:
+ return Coverage_Index2( &c->cf.cf2, glyphID, index );
+
+ default:
+ return TTO_Err_Invalid_SubTable_Format;
+ }
+
+ return TT_Err_Ok; /* never reached */
+ }
+
+
+
+ /*************************************
+ * Class Definition related functions
+ *************************************/
+
+
+ /* ClassDefFormat1 */
+
+ static FT_Error Load_ClassDef1( TTO_ClassDefinition* cd,
+ FT_UShort limit,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, count;
+
+ FT_UShort* cva;
+ FT_Bool* d;
+
+ TTO_ClassDefFormat1* cdf1;
+
+
+ cdf1 = &cd->cd.cd1;
+
+ if ( ACCESS_Frame( 4L ) )
+ return error;
+
+ cdf1->StartGlyph = GET_UShort();
+ count = cdf1->GlyphCount = GET_UShort();
+
+ FORGET_Frame();
+
+ /* sanity check; we are limited to 16bit integers */
+
+ if ( cdf1->StartGlyph + (long)count >= 0x10000L )
+ return TTO_Err_Invalid_SubTable;
+
+ cdf1->ClassValueArray = NULL;
+
+ if ( ALLOC_ARRAY( cdf1->ClassValueArray, count, FT_UShort ) )
+ return error;
+
+ d = cd->Defined;
+ cva = cdf1->ClassValueArray;
+
+ if ( ACCESS_Frame( count * 2L ) )
+ goto Fail;
+
+ for ( n = 0; n < count; n++ )
+ {
+ cva[n] = GET_UShort();
+ if ( cva[n] >= limit )
+ {
+ error = TTO_Err_Invalid_SubTable;
+ goto Fail;
+ }
+ d[cva[n]] = TRUE;
+ }
+
+ FORGET_Frame();
+
+ return TT_Err_Ok;
+
+ Fail:
+ FREE( cva );
+
+ return error;
+ }
+
+
+ static void Free_ClassDef1( TTO_ClassDefFormat1* cdf1,
+ FT_Memory memory )
+ {
+ FREE( cdf1->ClassValueArray );
+ }
+
+
+ /* ClassDefFormat2 */
+
+ static FT_Error Load_ClassDef2( TTO_ClassDefinition* cd,
+ FT_UShort limit,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, count;
+
+ TTO_ClassRangeRecord* crr;
+ FT_Bool* d;
+
+ TTO_ClassDefFormat2* cdf2;
+
+
+ cdf2 = &cd->cd.cd2;
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ count = cdf2->ClassRangeCount = GET_UShort();
+
+ FORGET_Frame();
+
+ cdf2->ClassRangeRecord = NULL;
+
+ if ( ALLOC_ARRAY( cdf2->ClassRangeRecord, count, TTO_ClassRangeRecord ) )
+ return error;
+
+ d = cd->Defined;
+ crr = cdf2->ClassRangeRecord;
+
+ if ( ACCESS_Frame( count * 6L ) )
+ goto Fail;
+
+ for ( n = 0; n < count; n++ )
+ {
+ crr[n].Start = GET_UShort();
+ crr[n].End = GET_UShort();
+ crr[n].Class = GET_UShort();
+
+ /* sanity check */
+
+ if ( crr[n].Start > crr[n].End ||
+ crr[n].Class >= limit )
+ {
+ error = TTO_Err_Invalid_SubTable;
+ goto Fail;
+ }
+ d[crr[n].Class] = TRUE;
+ }
+
+ FORGET_Frame();
+
+ return TT_Err_Ok;
+
+ Fail:
+ FREE( crr );
+
+ return error;
+ }
+
+
+ static void Free_ClassDef2( TTO_ClassDefFormat2* cdf2,
+ FT_Memory memory )
+ {
+ FREE( cdf2->ClassRangeRecord );
+ }
+
+
+ /* ClassDefinition */
+
+ FT_Error Load_ClassDefinition( TTO_ClassDefinition* cd,
+ FT_UShort limit,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+
+ if ( ALLOC_ARRAY( cd->Defined, limit, FT_Bool ) )
+ return error;
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail;
+
+ cd->ClassFormat = GET_UShort();
+
+ FORGET_Frame();
+
+ switch ( cd->ClassFormat )
+ {
+ case 1:
+ error = Load_ClassDef1( cd, limit, stream );
+ break;
+
+ case 2:
+ error = Load_ClassDef2( cd, limit, stream );
+ break;
+
+ default:
+ error = TTO_Err_Invalid_SubTable_Format;
+ break;
+ }
+
+ if ( error )
+ goto Fail;
+
+ cd->loaded = TRUE;
+
+ return TT_Err_Ok;
+
+ Fail:
+ FREE( cd->Defined );
+ return error;
+ }
+
+
+ FT_Error Load_EmptyClassDefinition( TTO_ClassDefinition* cd,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+
+ if ( ALLOC_ARRAY( cd->Defined, 1, FT_Bool ) )
+ return error;
+
+ cd->ClassFormat = 1; /* Meaningless */
+ cd->Defined[0] = FALSE;
+
+ if ( ALLOC_ARRAY( cd->cd.cd1.ClassValueArray, 1, FT_UShort ) )
+ goto Fail;
+
+ return TT_Err_Ok;
+
+ Fail:
+ FREE( cd->Defined );
+ return error;
+ }
+
+ void Free_ClassDefinition( TTO_ClassDefinition* cd,
+ FT_Memory memory )
+ {
+ if ( !cd->loaded )
+ return;
+
+ FREE( cd->Defined );
+
+ switch ( cd->ClassFormat )
+ {
+ case 1:
+ Free_ClassDef1( &cd->cd.cd1, memory );
+ break;
+
+ case 2:
+ Free_ClassDef2( &cd->cd.cd2, memory );
+ break;
+ }
+ }
+
+
+ static FT_Error Get_Class1( TTO_ClassDefFormat1* cdf1,
+ FT_UShort glyphID,
+ FT_UShort* class,
+ FT_UShort* index )
+ {
+ FT_UShort* cva = cdf1->ClassValueArray;
+
+
+ if ( index )
+ *index = 0;
+
+ if ( glyphID >= cdf1->StartGlyph &&
+ glyphID <= cdf1->StartGlyph + cdf1->GlyphCount )
+ {
+ *class = cva[glyphID - cdf1->StartGlyph];
+ return TT_Err_Ok;
+ }
+ else
+ {
+ *class = 0;
+ return TTO_Err_Not_Covered;
+ }
+ }
+
+
+ /* we need the index value of the last searched class range record
+ in case of failure for constructed GDEF tables */
+
+ static FT_Error Get_Class2( TTO_ClassDefFormat2* cdf2,
+ FT_UShort glyphID,
+ FT_UShort* class,
+ FT_UShort* index )
+ {
+ FT_Error error = TT_Err_Ok;
+ FT_UShort min, max, new_min, new_max, middle;
+
+ TTO_ClassRangeRecord* crr = cdf2->ClassRangeRecord;
+
+
+ /* binary search */
+
+ new_min = 0;
+ new_max = cdf2->ClassRangeCount - 1;
+
+ do
+ {
+ min = new_min;
+ max = new_max;
+
+ /* we use (min + max) / 2 = max - (max - min) / 2 to avoid
+ overflow and rounding errors */
+
+ middle = max - ( ( max - min ) >> 1 );
+
+ if ( glyphID >= crr[middle].Start && glyphID <= crr[middle].End )
+ {
+ *class = crr[middle].Class;
+ error = TT_Err_Ok;
+ break;
+ }
+ else if ( glyphID < crr[middle].Start )
+ {
+ if ( middle == min )
+ {
+ *class = 0;
+ error = TTO_Err_Not_Covered;
+ break;
+ }
+ new_max = middle - 1;
+ }
+ else
+ {
+ if ( middle == max )
+ {
+ *class = 0;
+ error = TTO_Err_Not_Covered;
+ break;
+ }
+ new_min = middle + 1;
+ }
+ } while ( min < max );
+
+ if ( index )
+ *index = middle;
+
+ return error;
+ }
+
+
+ FT_Error Get_Class( TTO_ClassDefinition* cd,
+ FT_UShort glyphID,
+ FT_UShort* class,
+ FT_UShort* index )
+ {
+ switch ( cd->ClassFormat )
+ {
+ case 1:
+ return Get_Class1( &cd->cd.cd1, glyphID, class, index );
+
+ case 2:
+ return Get_Class2( &cd->cd.cd2, glyphID, class, index );
+
+ default:
+ return TTO_Err_Invalid_SubTable_Format;
+ }
+
+ return TT_Err_Ok; /* never reached */
+ }
+
+
+
+ /***************************
+ * Device related functions
+ ***************************/
+
+
+ FT_Error Load_Device( TTO_Device* d,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, count;
+
+ FT_UShort* dv;
+
+
+ if ( ACCESS_Frame( 6L ) )
+ return error;
+
+ d->StartSize = GET_UShort();
+ d->EndSize = GET_UShort();
+ d->DeltaFormat = GET_UShort();
+
+ FORGET_Frame();
+
+ if ( d->StartSize > d->EndSize ||
+ d->DeltaFormat == 0 || d->DeltaFormat > 3 )
+ return TTO_Err_Invalid_SubTable;
+
+ d->DeltaValue = NULL;
+
+ count = ( ( d->EndSize - d->StartSize + 1 ) >>
+ ( 4 - d->DeltaFormat ) ) + 1;
+
+ if ( ALLOC_ARRAY( d->DeltaValue, count, FT_UShort ) )
+ return error;
+
+ if ( ACCESS_Frame( count * 2L ) )
+ {
+ FREE( d->DeltaValue );
+ return error;
+ }
+
+ dv = d->DeltaValue;
+
+ for ( n = 0; n < count; n++ )
+ dv[n] = GET_UShort();
+
+ FORGET_Frame();
+
+ return TT_Err_Ok;
+ }
+
+
+ void Free_Device( TTO_Device* d,
+ FT_Memory memory )
+ {
+ FREE( d->DeltaValue );
+ }
+
+
+ /* Since we have the delta values stored in compressed form, we must
+ uncompress it now. To simplify the interface, the function always
+ returns a meaningful value in `value'; the error is just for
+ information.
+ | |
+ format = 1: 0011223344556677|8899101112131415|...
+ | |
+ byte 1 byte 2
+
+ 00: (byte >> 14) & mask
+ 11: (byte >> 12) & mask
+ ...
+
+ mask = 0x0003
+ | |
+ format = 2: 0000111122223333|4444555566667777|...
+ | |
+ byte 1 byte 2
+
+ 0000: (byte >> 12) & mask
+ 1111: (byte >> 8) & mask
+ ...
+
+ mask = 0x000F
+ | |
+ format = 3: 0000000011111111|2222222233333333|...
+ | |
+ byte 1 byte 2
+
+ 00000000: (byte >> 8) & mask
+ 11111111: (byte >> 0) & mask
+ ....
+
+ mask = 0x00FF */
+
+ FT_Error Get_Device( TTO_Device* d,
+ FT_UShort size,
+ FT_Short* value )
+ {
+ FT_UShort byte, bits, mask, f, s;
+
+
+ f = d->DeltaFormat;
+
+ if ( d->DeltaValue && size >= d->StartSize && size <= d->EndSize )
+ {
+ s = size - d->StartSize;
+ byte = d->DeltaValue[s >> ( 4 - f )];
+ bits = byte >> ( 16 - ( ( s % ( 1 << ( 4 - f ) ) + 1 ) << f ) );
+ mask = 0xFFFF >> ( 16 - ( 1 << f ) );
+
+ *value = (FT_Short)( bits & mask );
+
+ /* conversion to a signed value */
+
+ if ( *value >= ( ( mask + 1 ) >> 1 ) )
+ *value -= mask + 1;
+
+ return TT_Err_Ok;
+ }
+ else
+ {
+ *value = 0;
+ return TTO_Err_Not_Covered;
+ }
+ }
+
+
+/* END */
diff --git a/src/otlayout/ftxopen.h b/src/otlayout/ftxopen.h
new file mode 100644
index 000000000..168c85848
--- /dev/null
+++ b/src/otlayout/ftxopen.h
@@ -0,0 +1,314 @@
+/*******************************************************************
+ *
+ * ftxopen.h
+ *
+ * TrueType Open support.
+ *
+ * Copyright 1996-2000 by
+ * David Turner, Robert Wilhelm, and Werner Lemberg.
+ *
+ * This file is part of the FreeType project, and may only be used
+ * modified and distributed under the terms of the FreeType project
+ * license, LICENSE.TXT. By continuing to use, modify, or distribute
+ * this file you indicate that you have read the license and
+ * understand and accept it fully.
+ *
+ * This file should be included by the application. Nevertheless,
+ * the table specific APIs (and structures) are located in files like
+ * ftxgsub.h or ftxgpos.h; these header files are read by ftxopen.h .
+ *
+ ******************************************************************/
+
+#ifndef FTXOPEN_H
+#define FTXOPEN_H
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define EXPORT_DEF static
+#define EXPORT_FUNC static
+
+#define TTO_MAX_NESTING_LEVEL 100
+
+#define TTO_Err_Invalid_SubTable_Format 0x1000
+#define TTO_Err_Invalid_SubTable 0x1001
+#define TTO_Err_Not_Covered 0x1002
+#define TTO_Err_Too_Many_Nested_Contexts 0x1003
+#define TTO_Err_No_MM_Interpreter 0x1004
+#define TTO_Err_Empty_Script 0x1005
+
+
+ /* Script list related structures */
+
+ struct TTO_LangSys_
+ {
+ FT_UShort LookupOrderOffset; /* always 0 for TT Open 1.0 */
+ FT_UShort ReqFeatureIndex; /* required FeatureIndex */
+ FT_UShort FeatureCount; /* number of Feature indices */
+ FT_UShort* FeatureIndex; /* array of Feature indices */
+ };
+
+ typedef struct TTO_LangSys_ TTO_LangSys;
+
+
+ struct TTO_LangSysRecord_
+ {
+ FT_ULong LangSysTag; /* LangSysTag identifier */
+ TTO_LangSys LangSys; /* LangSys table */
+ };
+
+ typedef struct TTO_LangSysRecord_ TTO_LangSysRecord;
+
+
+ struct TTO_Script_
+ {
+ TTO_LangSys DefaultLangSys; /* DefaultLangSys table */
+ FT_UShort LangSysCount; /* number of LangSysRecords */
+ TTO_LangSysRecord* LangSysRecord; /* array of LangSysRecords */
+ };
+
+ typedef struct TTO_Script_ TTO_Script;
+
+
+ struct TTO_ScriptRecord_
+ {
+ FT_ULong ScriptTag; /* ScriptTag identifier */
+ TTO_Script Script; /* Script table */
+ };
+
+ typedef struct TTO_ScriptRecord_ TTO_ScriptRecord;
+
+
+ struct TTO_ScriptList_
+ {
+ FT_UShort ScriptCount; /* number of ScriptRecords */
+ TTO_ScriptRecord* ScriptRecord; /* array of ScriptRecords */
+ };
+
+ typedef struct TTO_ScriptList_ TTO_ScriptList;
+
+
+ /* Feature list related structures */
+
+ struct TTO_Feature_
+ {
+ FT_UShort FeatureParams; /* always 0 for TT Open 1.0 */
+ FT_UShort LookupListCount; /* number of LookupList indices */
+ FT_UShort* LookupListIndex; /* array of LookupList indices */
+ };
+
+ typedef struct TTO_Feature_ TTO_Feature;
+
+
+ struct TTO_FeatureRecord_
+ {
+ FT_ULong FeatureTag; /* FeatureTag identifier */
+ TTO_Feature Feature; /* Feature table */
+ };
+
+ typedef struct TTO_FeatureRecord_ TTO_FeatureRecord;
+
+
+ struct TTO_FeatureList_
+ {
+ FT_UShort FeatureCount; /* number of FeatureRecords */
+ TTO_FeatureRecord* FeatureRecord; /* array of FeatureRecords */
+ };
+
+ typedef struct TTO_FeatureList_ TTO_FeatureList;
+
+
+ /* Lookup list related structures */
+
+ struct TTO_SubTable_; /* defined below after inclusion
+ of ftxgsub.h and ftxgpos.h */
+ typedef struct TTO_SubTable_ TTO_SubTable;
+
+
+ struct TTO_Lookup_
+ {
+ FT_UShort LookupType; /* Lookup type */
+ FT_UShort LookupFlag; /* Lookup qualifiers */
+ FT_UShort SubTableCount; /* number of SubTables */
+ TTO_SubTable* SubTable; /* array of SubTables */
+ };
+
+ typedef struct TTO_Lookup_ TTO_Lookup;
+
+
+ /* The `Properties' field is not defined in the TTO specification but
+ is needed for processing lookups. If properties[n] is > 0, the
+ functions TT_GSUB_Apply_String() resp. TT_GPOS_Apply_String() will
+ process Lookup[n] for glyphs which have the specific bit not set in
+ the `properties' field of the input string object. */
+
+ struct TTO_LookupList_
+ {
+ FT_UShort LookupCount; /* number of Lookups */
+ TTO_Lookup* Lookup; /* array of Lookup records */
+ FT_UShort* Properties; /* array of flags */
+ };
+
+ typedef struct TTO_LookupList_ TTO_LookupList;
+
+
+ /* Possible LookupFlag bit masks. `IGNORE_SPECIAL_MARKS' comes from the
+ OpenType 1.2 specification; RIGHT_TO_LEFT has been (re)introduced in
+ OpenType 1.3 -- if set, the last glyph in a cursive attachment
+ sequence has to be positioned on the baseline -- regardless of the
+ writing direction. */
+
+#define RIGHT_TO_LEFT 0x0001
+#define IGNORE_BASE_GLYPHS 0x0002
+#define IGNORE_LIGATURES 0x0004
+#define IGNORE_MARKS 0x0008
+#define IGNORE_SPECIAL_MARKS 0xFF00
+
+
+ struct TTO_CoverageFormat1_
+ {
+ FT_UShort GlyphCount; /* number of glyphs in GlyphArray */
+ FT_UShort* GlyphArray; /* array of glyph IDs */
+ };
+
+ typedef struct TTO_CoverageFormat1_ TTO_CoverageFormat1;
+
+
+ struct TTO_RangeRecord_
+ {
+ FT_UShort Start; /* first glyph ID in the range */
+ FT_UShort End; /* last glyph ID in the range */
+ FT_UShort StartCoverageIndex; /* coverage index of first
+ glyph ID in the range */
+ };
+
+ typedef struct TTO_RangeRecord_ TTO_RangeRecord;
+
+
+ struct TTO_CoverageFormat2_
+ {
+ FT_UShort RangeCount; /* number of RangeRecords */
+ TTO_RangeRecord* RangeRecord; /* array of RangeRecords */
+ };
+
+ typedef struct TTO_CoverageFormat2_ TTO_CoverageFormat2;
+
+
+ struct TTO_Coverage_
+ {
+ FT_UShort CoverageFormat; /* 1 or 2 */
+
+ union
+ {
+ TTO_CoverageFormat1 cf1;
+ TTO_CoverageFormat2 cf2;
+ } cf;
+ };
+
+ typedef struct TTO_Coverage_ TTO_Coverage;
+
+
+ struct TTO_ClassDefFormat1_
+ {
+ FT_UShort StartGlyph; /* first glyph ID of the
+ ClassValueArray */
+ FT_UShort GlyphCount; /* size of the ClassValueArray */
+ FT_UShort* ClassValueArray; /* array of class values */
+ };
+
+ typedef struct TTO_ClassDefFormat1_ TTO_ClassDefFormat1;
+
+
+ struct TTO_ClassRangeRecord_
+ {
+ FT_UShort Start; /* first glyph ID in the range */
+ FT_UShort End; /* last glyph ID in the range */
+ FT_UShort Class; /* applied to all glyphs in range */
+ };
+
+ typedef struct TTO_ClassRangeRecord_ TTO_ClassRangeRecord;
+
+
+ struct TTO_ClassDefFormat2_
+ {
+ FT_UShort ClassRangeCount;
+ /* number of ClassRangeRecords */
+ TTO_ClassRangeRecord* ClassRangeRecord;
+ /* array of ClassRangeRecords */
+ };
+
+ typedef struct TTO_ClassDefFormat2_ TTO_ClassDefFormat2;
+
+
+ /* The `Defined' field is not defined in the TTO specification but
+ apparently needed for processing fonts like trado.ttf: This font
+ refers to a class which contains not a single element. We map such
+ classes to class 0. */
+
+ struct TTO_ClassDefinition_
+ {
+ FT_Bool loaded;
+
+ FT_Bool* Defined; /* array of Booleans.
+ If Defined[n] is FALSE,
+ class n contains no glyphs. */
+ FT_UShort ClassFormat; /* 1 or 2 */
+
+ union
+ {
+ TTO_ClassDefFormat1 cd1;
+ TTO_ClassDefFormat2 cd2;
+ } cd;
+ };
+
+ typedef struct TTO_ClassDefinition_ TTO_ClassDefinition;
+
+
+ struct TTO_Device_
+ {
+ FT_UShort StartSize; /* smallest size to correct */
+ FT_UShort EndSize; /* largest size to correct */
+ FT_UShort DeltaFormat; /* DeltaValue array data format:
+ 1, 2, or 3 */
+ FT_UShort* DeltaValue; /* array of compressed data */
+ };
+
+ typedef struct TTO_Device_ TTO_Device;
+
+
+#include "ftxgdef.h"
+#include "ftxgsub.h"
+#include "ftxgpos.h"
+
+
+ struct TTO_SubTable_
+ {
+ union
+ {
+ TTO_GSUB_SubTable gsub;
+ TTO_GPOS_SubTable gpos;
+ } st;
+ };
+
+
+ enum TTO_Type_
+ {
+ GSUB,
+ GPOS
+ };
+
+ typedef enum TTO_Type_ TTO_Type;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* FTXOPEN_H */
+
+
+/* END */
diff --git a/src/otlayout/ftxopenf.h b/src/otlayout/ftxopenf.h
new file mode 100644
index 000000000..0c4db8b83
--- /dev/null
+++ b/src/otlayout/ftxopenf.h
@@ -0,0 +1,163 @@
+/*******************************************************************
+ *
+ * ftxopenf.h
+ *
+ * internal TrueType Open functions
+ *
+ * Copyright 1996-2000 by
+ * David Turner, Robert Wilhelm, and Werner Lemberg.
+ *
+ * This file is part of the FreeType project, and may only be used
+ * modified and distributed under the terms of the FreeType project
+ * license, LICENSE.TXT. By continuing to use, modify, or distribute
+ * this file you indicate that you have read the license and
+ * understand and accept it fully.
+ *
+ ******************************************************************/
+
+#ifndef FTXOPENF_H
+#define FTXOPENF_H
+
+#include "ftxopen.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /* functions from ftxopen.c */
+
+ FT_Error Load_ScriptList( TTO_ScriptList* sl,
+ FT_Stream stream );
+ FT_Error Load_FeatureList( TTO_FeatureList* fl,
+ FT_Stream input );
+ FT_Error Load_LookupList( TTO_LookupList* ll,
+ FT_Stream input,
+ TTO_Type type );
+
+ FT_Error Load_Coverage( TTO_Coverage* c,
+ FT_Stream input );
+ FT_Error Load_ClassDefinition( TTO_ClassDefinition* cd,
+ FT_UShort limit,
+ FT_Stream input );
+ FT_Error Load_EmptyClassDefinition( TTO_ClassDefinition* cd,
+ FT_Stream input );
+ FT_Error Load_Device( TTO_Device* d,
+ FT_Stream input );
+
+ void Free_ScriptList( TTO_ScriptList* sl,
+ FT_Memory memory );
+ void Free_FeatureList( TTO_FeatureList* fl,
+ FT_Memory memory );
+ void Free_LookupList( TTO_LookupList* ll,
+ TTO_Type type,
+ FT_Memory memory );
+
+ void Free_Coverage( TTO_Coverage* c,
+ FT_Memory memory );
+ void Free_ClassDefinition( TTO_ClassDefinition* cd,
+ FT_Memory memory );
+ void Free_Device( TTO_Device* d,
+ FT_Memory memory );
+
+
+ /* functions from ftxgsub.c */
+
+ FT_Error Load_SingleSubst( TTO_SingleSubst* ss,
+ FT_Stream input );
+ FT_Error Load_MultipleSubst( TTO_MultipleSubst* ms,
+ FT_Stream input );
+ FT_Error Load_AlternateSubst( TTO_AlternateSubst* as,
+ FT_Stream input );
+ FT_Error Load_LigatureSubst( TTO_LigatureSubst* ls,
+ FT_Stream input );
+ FT_Error Load_ContextSubst( TTO_ContextSubst* cs,
+ FT_Stream input );
+ FT_Error Load_ChainContextSubst( TTO_ChainContextSubst* ccs,
+ FT_Stream input );
+
+ void Free_SingleSubst( TTO_SingleSubst* ss,
+ FT_Memory memory );
+ void Free_MultipleSubst( TTO_MultipleSubst* ms,
+ FT_Memory memory );
+ void Free_AlternateSubst( TTO_AlternateSubst* as,
+ FT_Memory memory );
+ void Free_LigatureSubst( TTO_LigatureSubst* ls,
+ FT_Memory memory );
+ void Free_ContextSubst( TTO_ContextSubst* cs,
+ FT_Memory memory );
+ void Free_ChainContextSubst( TTO_ChainContextSubst* ccs,
+ FT_Memory memory );
+
+
+ /* functions from ftxgpos.c */
+
+ FT_Error Load_SinglePos( TTO_SinglePos* sp,
+ FT_Stream input );
+ FT_Error Load_PairPos( TTO_PairPos* pp,
+ FT_Stream input );
+ FT_Error Load_CursivePos( TTO_CursivePos* cp,
+ FT_Stream input );
+ FT_Error Load_MarkBasePos( TTO_MarkBasePos* mbp,
+ FT_Stream input );
+ FT_Error Load_MarkLigPos( TTO_MarkLigPos* mlp,
+ FT_Stream input );
+ FT_Error Load_MarkMarkPos( TTO_MarkMarkPos* mmp,
+ FT_Stream input );
+ FT_Error Load_ContextPos( TTO_ContextPos* cp,
+ FT_Stream input );
+ FT_Error Load_ChainContextPos( TTO_ChainContextPos* ccp,
+ FT_Stream input );
+
+ void Free_SinglePos( TTO_SinglePos* sp,
+ FT_Memory memory );
+ void Free_PairPos( TTO_PairPos* pp,
+ FT_Memory memory );
+ void Free_CursivePos( TTO_CursivePos* cp,
+ FT_Memory memory );
+ void Free_MarkBasePos( TTO_MarkBasePos* mbp,
+ FT_Memory memory );
+ void Free_MarkLigPos( TTO_MarkLigPos* mlp,
+ FT_Memory memory );
+ void Free_MarkMarkPos( TTO_MarkMarkPos* mmp,
+ FT_Memory memory );
+ void Free_ContextPos( TTO_ContextPos* cp,
+ FT_Memory memory );
+ void Free_ChainContextPos( TTO_ChainContextPos* ccp,
+ FT_Memory memory );
+ /* query functions */
+
+ FT_Error Coverage_Index( TTO_Coverage* c,
+ FT_UShort glyphID,
+ FT_UShort* index );
+ FT_Error Get_Class( TTO_ClassDefinition* cd,
+ FT_UShort glyphID,
+ FT_UShort* class,
+ FT_UShort* index );
+ FT_Error Get_Device( TTO_Device* d,
+ FT_UShort size,
+ FT_Short* value );
+
+
+ /* functions from ftxgdef.c */
+
+ FT_Error Add_Glyph_Property( TTO_GDEFHeader* gdef,
+ FT_UShort glyphID,
+ FT_UShort property );
+
+ FT_Error Check_Property( TTO_GDEFHeader* gdef,
+ FT_UShort index,
+ FT_UShort flags,
+ FT_UShort* property );
+
+#define CHECK_Property( gdef, index, flags, property ) \
+ ( ( error = Check_Property( (gdef), (index), (flags), \
+ (property) ) ) != TT_Err_Ok )
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* FTXOPENF_H */
+
+
+/* END */
diff --git a/src/otlayout/module.mk b/src/otlayout/module.mk
new file mode 100644
index 000000000..6dcf761ca
--- /dev/null
+++ b/src/otlayout/module.mk
@@ -0,0 +1,22 @@
+#
+# FreeType 2 GX module definition
+#
+
+
+# Copyright 1996-2000 by
+# David Turner, Robert Wilhelm, and Werner Lemberg.
+#
+# This file is part of the FreeType project, and may only be used, modified,
+# and distributed under the terms of the FreeType project license,
+# LICENSE.TXT. By continuing to use, modify, or distribute this file you
+# indicate that you have read the license and understand and accept it
+# fully.
+
+
+make_module_list: add_ot_driver
+
+add_ot_driver:
+ $(OPEN_DRIVER)ot_driver_class$(CLOSE_DRIVER)
+ $(ECHO_DRIVER)ot $(ECHO_DRIVER_DESC)OpenType fonts$(ECHO_DRIVER_DONE)
+
+# EOF
diff --git a/src/otlayout/ot-array.c b/src/otlayout/ot-array.c
new file mode 100644
index 000000000..aaa286e26
--- /dev/null
+++ b/src/otlayout/ot-array.c
@@ -0,0 +1,93 @@
+/* OTArray
+ *
+ * Copyright (C) 2003 Red Hat.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "ot-array.h"
+#include FT_INTERNAL_MEMORY_H
+#include FT_CONFIG_STANDARD_LIBRARY_H
+
+#define OT_REALLOC_ARRAY( _pointer_, _old_, _new_, eltsize ) \
+ FT_SET_ERROR( FT_MEM_REALLOC( _pointer_, \
+ (_old_) * eltsize, \
+ (_new_) * eltsize ) )
+
+ FT_LOCAL_DEF( OTArray * )
+ OT_Array_New ( FT_UInt element_size, FT_Memory memory )
+ {
+ FT_Error error;
+ OTArray * array;
+
+ if ( FT_NEW ( array ) )
+ return NULL;
+
+ array->data = NULL;
+ array->length = 0;
+ array->allocated = 0;
+ array->element_size = element_size;
+ array->memory = memory;
+ return OT_Array_Set_Size ( array, 4 );
+ }
+
+ FT_LOCAL_DEF( void )
+ OT_Array_Free ( OTArray * array )
+ {
+ FT_Memory memory = array->memory;
+ FT_FREE( array->data );
+ FT_FREE( array );
+ }
+
+ FT_LOCAL_DEF( OTArray * )
+ OT_Array_Set_Size ( OTArray * array, FT_UInt length )
+ {
+ FT_Error error;
+ FT_Memory memory = array->memory;
+
+ if ( length > array->allocated )
+ {
+ if ( OT_REALLOC_ARRAY(array->data,
+ array->allocated,
+ length,
+ array->element_size) )
+ return NULL;
+ array->allocated = length;
+ }
+ array->length = length;
+ return array;
+ }
+
+ FT_LOCAL_DEF( void )
+ OT_Array_Sort ( OTArray * array, OT_Array_Comapre_Func func )
+ {
+ ft_qsort ( array->data, array->length, array->element_size, func );
+ }
+
+ FT_LOCAL_DEF( OTArray * )
+ OT_Array_Append_Val ( OTArray * array, FT_Pointer newval )
+ {
+ FT_UInt index;
+ FT_Pointer dest;
+
+ if ( !OT_Array_Set_Size( array, array->length + 1 ) )
+ return NULL;
+
+ index = array->length - 1;
+ dest = array->data + ( index * array->element_size );
+ FT_MEM_COPY ( dest, newval, array->element_size );
+ return array;
+ }
diff --git a/src/otlayout/ot-array.h b/src/otlayout/ot-array.h
new file mode 100644
index 000000000..89ea4a097
--- /dev/null
+++ b/src/otlayout/ot-array.h
@@ -0,0 +1,50 @@
+/* OTArray
+ *
+ * Copyright (C) 2003 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __OT_ARRAY_H__
+#define __OT_ARRAY_H__
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+
+FT_BEGIN_HEADER
+
+ typedef struct _OTArray OTArray;
+ typedef FT_Int (*OT_Array_Comapre_Func) (const void * a, const void * b );
+
+ struct _OTArray
+ {
+ FT_Char * data;
+ FT_UInt length;
+ FT_UInt element_size;
+ FT_UInt allocated;
+ FT_Memory memory;
+ };
+
+ FT_LOCAL( OTArray * ) OT_Array_New ( FT_UInt element_size, FT_Memory memory );
+ FT_LOCAL( void ) OT_Array_Free ( OTArray * array );
+ FT_LOCAL( OTArray * ) OT_Array_Set_Size ( OTArray * array, FT_UInt length );
+ FT_LOCAL( void ) OT_Array_Sort ( OTArray * array, OT_Array_Comapre_Func func );
+ FT_LOCAL( OTArray * ) OT_Array_Append_Val ( OTArray * array, FT_Pointer newval );
+#define OT_Array_Index(array, type, index) (((type*)((array)->data))[(index)])
+
+FT_END_HEADER
+
+#endif /* Not def: __OT_ARRAY_H__ */
diff --git a/src/otlayout/ot-info.c b/src/otlayout/ot-info.c
new file mode 100644
index 000000000..1cf107aea
--- /dev/null
+++ b/src/otlayout/ot-info.c
@@ -0,0 +1,762 @@
+/*
+ * ot-info.c: Store tables for OpenType
+ *
+ * Copyright (C) 2003 Red Hat K.K.
+ * Copyright (C) 2000 Red Hat Software
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "ot-info.h"
+#include "ot-ruleset.h"
+#include "ot-unicode.h"
+#include "fterrcompat.h"
+#include FT_INTERNAL_OBJECTS_H
+#include FT_MODULE_H
+
+
+#define noINFO_DEBUG_MEMORY
+
+enum
+{
+ INFO_LOADED_GDEF = 1 << 0,
+ INFO_LOADED_GSUB = 1 << 1,
+ INFO_LOADED_GPOS = 1 << 2
+};
+
+
+static FT_Error ot_table_check( FT_Face face );
+OTInfo *
+ot_info_new ( FT_Face face )
+{
+ FT_Error error;
+ OTInfo *info;
+ FT_Memory memory;
+
+ if ( ot_table_check( face ) )
+ return NULL;
+
+ memory = FT_FACE_MEMORY( face );
+ if ( FT_NEW ( info ) )
+ return NULL;
+
+ ot_info_setup (info);
+
+ return info;
+}
+
+static FT_Error
+ot_table_check( FT_Face face )
+{
+ FT_Stream stream = face->stream;
+ TT_Face tt_face = (TT_Face)face;
+
+ FT_Error error_gdef, error_gpos, error_gsub;
+
+ error_gdef = tt_face->goto_table( tt_face, TTAG_GDEF, stream, 0 );
+ error_gsub = tt_face->goto_table( tt_face, TTAG_GSUB, stream, 0 );
+ error_gpos = tt_face->goto_table( tt_face, TTAG_GPOS, stream, 0 );
+
+ if ( (!error_gdef) || (!error_gsub) || (!error_gpos) )
+ return FT_Err_Ok;
+ else
+ return OT_Err_Unknown_File_Format;
+}
+
+OTInfo *
+ot_info_delete (OTInfo *info)
+{
+ FT_Memory memory = FT_FACE_MEMORY( info->face );
+ if (info) {
+ ot_info_release (info);
+ FT_FREE( info );
+ }
+
+ return NULL;
+}
+
+OTInfo *
+ot_info_ref (OTInfo *info)
+{
+ FT_ASSERT (info != NULL );
+ FT_ASSERT (info->refcount > 0);
+
+ info->refcount += 1;
+
+ return info;
+}
+
+OTInfo *
+ot_info_unref (OTInfo *info)
+{
+ FT_ASSERT (info != NULL);
+ FT_ASSERT (info->refcount > 0);
+
+ info->refcount -= 1;
+
+ if (info->refcount == 0) {
+ ot_info_delete (info);
+ return NULL;
+ }
+
+ return info;
+}
+
+#ifdef INFO_DEBUG_MEMORY
+static int ot_info_count = 0;
+#endif
+
+OTInfo *
+ot_info_setup (OTInfo *info)
+{
+
+#ifdef INFO_DEBUG_MEMORY
+ ot_info_count++;
+ FT_Message ("ot_info_setup: %d\n", ot_info_count);
+#endif
+ info->refcount = 1;
+
+ info->gsub = NULL;
+ info->gdef = NULL;
+ info->gpos = NULL;
+ info->ruleset = NULL;
+
+ return info;
+}
+
+OTInfo *
+ot_info_release (OTInfo *info)
+{
+ FT_ASSERT (info != NULL);
+
+#ifdef INFO_DEBUG_MEMORY
+ ot_info_count--;
+ FT_Message ("ot_info_release: %d\n", ot_info_count);
+#endif
+ if (info->gdef)
+ {
+ TT_Done_GDEF_Table (info->gdef);
+ info->gdef = NULL;
+ }
+ if (info->gsub)
+ {
+ TT_Done_GSUB_Table (info->gsub);
+ info->gsub = NULL;
+ }
+ if (info->gpos)
+ {
+ TT_Done_GPOS_Table (info->gpos);
+ info->gpos = NULL;
+ }
+
+ if (info->ruleset)
+ {
+ ot_ruleset_delete (info->ruleset);
+ info->ruleset = NULL;
+ }
+ return info;
+}
+
+/* static int info_count = 0; */
+void
+ot_info_finalizer (void *object)
+{
+ FT_Face face = object;
+ OTInfo *info = face->generic.data;
+
+ ot_info_unref (info);
+ info->face = NULL;
+}
+
+/**
+ * ot_info_get_ruleset
+ *
+ * @returns: the #OTRulset for @info. This object will
+ * have the same lifetime as OTInfo.
+ *
+ * Returns the #OTRuleset structure for the info.
+ */
+OTRuleset *
+ot_info_get_ruleset (OTInfo *info)
+{
+ if (! info->ruleset) {
+ info->ruleset = ot_ruleset_new (info);
+ }
+
+ return info->ruleset;
+}
+
+/**
+ * ot_info_get:
+ * @face: a #FT_Face.
+ * @returns: the #OTInfo for @face. This object will
+ * have the same lifetime as FT_Face.
+ *
+ * Returns the #OTInfo structure for the given FreeType font.
+ *
+ * Since: 1.2
+ **/
+OTInfo *
+ot_info_get (FT_Face face)
+{
+ OTInfo *info;
+
+ if (face->generic.data)
+ return face->generic.data;
+ else
+ {
+ info = ot_info_new ( face );
+ if ( info ) {
+ face->generic.data = info;
+ face->generic.finalizer = ot_info_finalizer;
+ info->face = face;
+ }
+ }
+
+ return info;
+}
+
+/* There must be be a better way to do this
+ */
+static FT_Bool
+is_truetype (FT_Face face)
+{
+ return (
+ (strcmp (FT_MODULE_CLASS (face->driver)->module_name, "truetype") == 0)
+ || (strcmp (FT_MODULE_CLASS (face->driver)->module_name, "ot") == 0)
+ );
+}
+
+typedef struct _GlyphInfo GlyphInfo;
+
+struct _GlyphInfo {
+ FT_UShort glyph;
+ FT_UShort class;
+};
+
+static int
+compare_glyph_info (const void * a,
+ const void * b)
+{
+ const GlyphInfo *info_a = a;
+ const GlyphInfo *info_b = b;
+
+ return (info_a->glyph < info_b->glyph) ? -1 :
+ (info_a->glyph == info_b->glyph) ? 0 : 1;
+}
+
+/* Make a guess at the appropriate class for a glyph given
+ * a character code that maps to the glyph
+ */
+
+static FT_Bool
+set_unicode_charmap (FT_Face face)
+{
+ int charmap;
+
+ for (charmap = 0; charmap < face->num_charmaps; charmap++)
+ if (face->charmaps[charmap]->encoding == ft_encoding_unicode)
+ {
+ FT_Error error = FT_Set_Charmap(face, face->charmaps[charmap]);
+ return error == FT_Err_Ok;
+ }
+
+ return FALSE;
+}
+
+/* Synthesize a GDEF table using the font's charmap and the
+ * unicode property database. We'll fill in class definitions
+ * for glyphs not in the charmap as we walk through the tables.
+ */
+static void
+synthesize_class_def (OTInfo *info)
+{
+ OTArray *glyph_infos;
+ FT_UShort *glyph_indices;
+ FT_UShort *classes;
+ FT_ULong charcode;
+ FT_UInt glyph;
+ int i, j;
+ FT_CharMap old_charmap;
+ FT_Error error;
+ FT_Memory memory = FT_FACE_MEMORY( info->face );
+
+ old_charmap = info->face->charmap;
+
+ if (!old_charmap || !old_charmap->encoding != ft_encoding_unicode)
+ if (!set_unicode_charmap (info->face))
+ return;
+
+ glyph_infos = OT_Array_New ( sizeof (GlyphInfo), memory );
+
+ /* Collect all the glyphs in the charmap, and guess
+ * the appropriate classes for them
+ */
+ charcode = FT_Get_First_Char (info->face, &glyph);
+ while (glyph != 0)
+ {
+ GlyphInfo glyph_info;
+
+ if (glyph <= 65535)
+ {
+ glyph_info.glyph = glyph;
+ glyph_info.class = ot_get_glyph_class (charcode);
+
+ OT_Array_Append_Val ( glyph_infos, &glyph_info );
+ }
+
+ charcode = FT_Get_Next_Char (info->face, charcode, &glyph);
+ }
+
+ /* Sort and remove duplicates
+ */
+ OT_Array_Sort ( glyph_infos, compare_glyph_info );
+ FT_ALLOC_ARRAY( glyph_indices, glyph_infos->length, FT_UShort );
+ FT_ALLOC_ARRAY( classes, glyph_infos->length, FT_UShort );
+
+ for (i = 0, j = 0; i < glyph_infos->length; i++)
+ {
+ GlyphInfo *info = &OT_Array_Index (glyph_infos, GlyphInfo, i);
+
+ if (j == 0 || info->glyph != glyph_indices[j - 1])
+ {
+ glyph_indices[j] = info->glyph;
+ classes[j] = info->class;
+
+ j++;
+ }
+ }
+
+ OT_Array_Free ( glyph_infos );
+
+ TT_GDEF_Build_ClassDefinition (info->gdef, info->face->num_glyphs, j,
+ glyph_indices, classes);
+ FT_FREE( glyph_indices );
+ FT_FREE( classes );
+
+ if (old_charmap && info->face->charmap != old_charmap)
+ FT_Set_Charmap (info->face, old_charmap);
+}
+
+TTO_GDEF
+ot_info_get_gdef (OTInfo *info)
+{
+ FT_ASSERT (info != NULL);
+
+ if (!(info->loaded & INFO_LOADED_GDEF))
+ {
+ FT_Error error;
+
+ info->loaded |= INFO_LOADED_GDEF;
+
+ if (is_truetype (info->face))
+ {
+ error = TT_Load_GDEF_Table (info->face, &info->gdef);
+
+ if (error && error != TT_Err_Table_Missing)
+ FT_ERROR (("Error loading GDEF table %d", error));
+
+ if (!info->gdef)
+ error = TT_New_GDEF_Table (info->face, &info->gdef);
+
+ if (info->gdef && !info->gdef->GlyphClassDef.loaded)
+ synthesize_class_def (info);
+ }
+ }
+
+ return info->gdef;
+}
+
+TTO_GSUB
+ot_info_get_gsub (OTInfo *info)
+{
+ FT_ASSERT (info != NULL);
+
+ if (!(info->loaded & INFO_LOADED_GSUB))
+ {
+ FT_Error error;
+ TTO_GDEF gdef = ot_info_get_gdef (info);
+
+ info->loaded |= INFO_LOADED_GSUB;
+
+ if (is_truetype (info->face))
+ {
+ error = TT_Load_GSUB_Table (info->face, &info->gsub, gdef);
+
+ if (error && error != TT_Err_Table_Missing)
+ FT_ERROR (("Error loading GSUB table %d", error));
+ }
+ }
+
+ return info->gsub;
+}
+
+TTO_GPOS
+ot_info_get_gpos (OTInfo *info)
+{
+ FT_ASSERT (info != NULL);
+
+ if (!(info->loaded & INFO_LOADED_GPOS))
+ {
+ FT_Error error;
+ TTO_GDEF gdef = ot_info_get_gdef (info);
+
+ info->loaded |= INFO_LOADED_GPOS;
+
+ if (is_truetype (info->face))
+ {
+ error = TT_Load_GPOS_Table (info->face, &info->gpos, gdef);
+
+ if (error && error != TT_Err_Table_Missing)
+ FT_ERROR (("Error loading GPOS table %d", error));
+ }
+ }
+
+ return info->gpos;
+}
+
+static FT_Bool
+get_tables (OTInfo *info,
+ OTTableType table_type,
+ TTO_ScriptList **script_list,
+ TTO_FeatureList **feature_list)
+{
+ if (table_type == OT_TABLE_GSUB)
+ {
+ TTO_GSUB gsub = ot_info_get_gsub (info);
+
+ if (!gsub)
+ return FALSE;
+ else
+ {
+ if (script_list)
+ *script_list = &gsub->ScriptList;
+ if (feature_list)
+ *feature_list = &gsub->FeatureList;
+ return TRUE;
+ }
+ }
+ else
+ {
+ TTO_GPOS gpos = ot_info_get_gpos (info);
+
+ if (!gpos)
+ return FALSE;
+ else
+ {
+ if (script_list)
+ *script_list = &gpos->ScriptList;
+ if (feature_list)
+ *feature_list = &gpos->FeatureList;
+ return TRUE;
+ }
+ }
+}
+
+/**
+ * ot_info_find_script:
+ * @info: a #OTInfo.
+ * @table_type: the table type to obtain information about.
+ * @script_tag: the tag of the script to find.
+ * @script_index: location to store the index of the script, or %NULL.
+ * @returns: %TRUE if the script was found.
+ *
+ * Finds the index of a script.
+ **/
+FT_Bool
+ot_info_find_script (OTInfo *info,
+ OTTableType table_type,
+ OTTag script_tag,
+ FT_UInt *script_index)
+{
+ TTO_ScriptList *script_list;
+ int i;
+
+ FT_ASSERT (info != NULL);
+
+ if (!get_tables (info, table_type, &script_list, NULL))
+ return FALSE;
+
+ for (i=0; i < script_list->ScriptCount; i++)
+ {
+ if (script_list->ScriptRecord[i].ScriptTag == script_tag)
+ {
+ if (script_index)
+ *script_index = i;
+
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+/**
+ * ot_info_find_language:
+ * @info: a #OTInfo.
+ * @table_type: the table type to obtain information about.
+ * @script_index: the index of the script whose languages are searched.
+ * @language_tag: the tag of the language to find.
+ * @language_index: location to store the index of the language, or %NULL.
+ * @required_feature_index: location to store the required feature index of
+ * the language, or %NULL.
+ * @returns: %TRUE if the language was found.
+ *
+ * Finds the index of a language and its required feature index.
+ **/
+FT_Bool
+ot_info_find_language (OTInfo *info,
+ OTTableType table_type,
+ FT_UInt script_index,
+ OTTag language_tag,
+ FT_UInt *language_index,
+ FT_UInt *required_feature_index)
+{
+ TTO_ScriptList *script_list;
+ TTO_Script *script;
+ int i;
+
+ FT_ASSERT (info != NULL);
+
+ if (!get_tables (info, table_type, &script_list, NULL))
+ return FALSE;
+
+ FT_ASSERT (script_index < script_list->ScriptCount);
+
+ script = &script_list->ScriptRecord[script_index].Script;
+
+ for (i = 0; i < script->LangSysCount; i++)
+ {
+ if (script->LangSysRecord[i].LangSysTag == language_tag)
+ {
+ if (language_index)
+ *language_index = i;
+ if (required_feature_index)
+ *required_feature_index = script->LangSysRecord[i].LangSys.ReqFeatureIndex;
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+/**
+ * ot_info_find_feature:
+ * @info: a #OTInfo.
+ * @table_type: the table type to obtain information about.
+ * @feature_tag: the tag of the feature to find.
+ * @script_index: the index of the script.
+ * @language_index: the index of the language whose features are searched,
+ * or 0xffff to use the default language of the script.
+ * @feature_index: location to store the index of the feature, or %NULL.
+ * @returns: %TRUE if the feature was found.
+ *
+ * Finds the index of a feature.
+ **/
+FT_Bool
+ot_info_find_feature (OTInfo *info,
+ OTTableType table_type,
+ OTTag feature_tag,
+ FT_UInt script_index,
+ FT_UInt language_index,
+ FT_UInt *feature_index)
+{
+ TTO_ScriptList *script_list;
+ TTO_FeatureList *feature_list;
+ TTO_Script *script;
+ TTO_LangSys *lang_sys;
+
+ int i;
+
+ FT_ASSERT (info != NULL);
+
+ if (!get_tables (info, table_type, &script_list, &feature_list))
+ return FALSE;
+
+ FT_ASSERT (script_index < script_list->ScriptCount);
+
+ script = &script_list->ScriptRecord[script_index].Script;
+
+ if (language_index == 0xffff)
+ lang_sys = &script->DefaultLangSys;
+ else
+ {
+ FT_ASSERT (language_index < script->LangSysCount);
+ lang_sys = &script->LangSysRecord[language_index].LangSys;
+ }
+
+ for (i = 0; i < lang_sys->FeatureCount; i++)
+ {
+ FT_UShort index = lang_sys->FeatureIndex[i];
+
+ if (feature_list->FeatureRecord[index].FeatureTag == feature_tag)
+ {
+ if (feature_index)
+ *feature_index = index;
+
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+/**
+ * ot_info_list_scripts:
+ * @info: a #OTInfo.
+ * @table_type: the table type to obtain information about.
+ * @returns: a newly-allocated array containing the tags of the
+ * available scripts.
+ *
+ * Obtains the list of available scripts.
+ **/
+OTTag *
+ot_info_list_scripts (OTInfo *info,
+ OTTableType table_type)
+{
+ FT_Error error;
+ FT_Memory memory = FT_FACE_MEMORY( info->face );
+ OTTag *result;
+ TTO_ScriptList *script_list;
+ int i;
+
+ FT_ASSERT (info != NULL);
+
+ if (!get_tables (info, table_type, &script_list, NULL))
+ return NULL;
+ if ( FT_ALLOC_ARRAY ( result,
+ script_list->ScriptCount + 1,
+ OTTag ) )
+ return NULL;
+
+ for (i=0; i < script_list->ScriptCount; i++)
+ result[i] = script_list->ScriptRecord[i].ScriptTag;
+
+ result[i] = 0;
+
+ return result;
+}
+
+/**
+ * ot_info_list_languages:
+ * @info: a #OTInfo.
+ * @table_type: the table type to obtain information about.
+ * @script_index: the index of the script to list languages for.
+ * @language_tag: unused parameter.
+ * @returns: a newly-allocated array containing the tags of the
+ * available languages.
+ *
+ * Obtains the list of available languages for a given script.
+ **/
+OTTag *
+ot_info_list_languages (OTInfo *info,
+ OTTableType table_type,
+ FT_UInt script_index,
+ OTTag language_tag)
+{
+ FT_Error error;
+ FT_Memory memory = FT_FACE_MEMORY( info->face );
+ OTTag *result;
+ TTO_ScriptList *script_list;
+ TTO_Script *script;
+ int i;
+
+ FT_ASSERT (info != NULL);
+
+ if (!get_tables (info, table_type, &script_list, NULL))
+ return NULL;
+
+ FT_ASSERT (script_index < script_list->ScriptCount);
+
+ script = &script_list->ScriptRecord[script_index].Script;
+
+ if ( FT_ALLOC_ARRAY ( result,
+ script->LangSysCount + 1,
+ OTTag ) )
+ return NULL;
+
+ for (i = 0; i < script->LangSysCount; i++)
+ result[i] = script->LangSysRecord[i].LangSysTag;
+
+ result[i] = 0;
+
+ return result;
+}
+
+/**
+ * ot_info_list_features:
+ * @info: a #OTInfo.
+ * @table_type: the table type to obtain information about.
+ * @tag: unused parameter.
+ * @script_index: the index of the script to obtain information about.
+ * @language_index: the indes of the language to list features for, or
+ * 0xffff, to list features for the default language of the script.
+ * @returns: a newly-allocated array containing the tags of the available
+ * features.
+ *
+ * Obtains the list of features for the given language of the given script.
+ **/
+OTTag *
+ot_info_list_features (OTInfo *info,
+ OTTableType table_type,
+ OTTag tag,
+ FT_UInt script_index,
+ FT_UInt language_index)
+{
+ FT_Error error;
+ FT_Memory memory = FT_FACE_MEMORY( info->face );
+ OTTag *result;
+
+ TTO_ScriptList *script_list;
+ TTO_FeatureList *feature_list;
+ TTO_Script *script;
+ TTO_LangSys *lang_sys;
+
+ int i;
+
+ FT_ASSERT (info != NULL);
+
+ if (!get_tables (info, table_type, &script_list, &feature_list))
+ return NULL;
+
+ FT_ASSERT (script_index < script_list->ScriptCount);
+
+ script = &script_list->ScriptRecord[script_index].Script;
+
+ if (language_index == 0xffff)
+ lang_sys = &script->DefaultLangSys;
+ else
+ {
+ FT_ASSERT (language_index < script->LangSysCount);
+ lang_sys = &script->LangSysRecord[language_index].LangSys;
+ }
+
+ if ( FT_ALLOC_ARRAY ( result,
+ lang_sys->FeatureCount + 1,
+ OTTag ) )
+ return NULL;
+
+ for (i = 0; i < lang_sys->FeatureCount; i++)
+ {
+ FT_UShort index = lang_sys->FeatureIndex[i];
+
+ result[i] = feature_list->FeatureRecord[index].FeatureTag;
+ }
+
+ result[i] = 0;
+
+ return result;
+}
diff --git a/src/otlayout/ot-info.h b/src/otlayout/ot-info.h
new file mode 100644
index 000000000..cf8d5ccf1
--- /dev/null
+++ b/src/otlayout/ot-info.h
@@ -0,0 +1,103 @@
+/* OTInfo
+ *
+ * Copyright (C) 2000 Red Hat Software
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __OT_INFO_H__
+#define __OT_INFO_H__
+
+#include "ftxopen.h"
+#include "ot-types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+struct _OTInfo
+{
+ FT_Int refcount;
+
+ FT_UInt loaded;
+
+ FT_Face face;
+
+ TTO_GSUB gsub;
+ TTO_GDEF gdef;
+ TTO_GPOS gpos;
+
+ OTRuleset *ruleset;
+};
+
+/* Don't use these directly */
+
+OTInfo *ot_info_new ( FT_Face face );
+OTInfo *ot_info_delete (OTInfo *info);
+
+OTInfo *ot_info_ref (OTInfo *info);
+OTInfo *ot_info_unref (OTInfo *info);
+
+OTInfo *ot_info_setup (OTInfo *info);
+OTInfo *ot_info_release (OTInfo *info);
+
+/* Member access */
+
+TTO_GDEF ot_info_get_gdef (OTInfo *info);
+TTO_GSUB ot_info_get_gsub (OTInfo *info);
+TTO_GPOS ot_info_get_gpos (OTInfo *info);
+
+OTRuleset *ot_info_get_ruleset (OTInfo *info);
+
+OTInfo *ot_info_get (FT_Face face);
+
+FT_Bool ot_info_find_script (OTInfo *info,
+ OTTableType table_type,
+ OTTag script_tag,
+ FT_UInt *script_index);
+FT_Bool ot_info_find_language (OTInfo *info,
+ OTTableType table_type,
+ FT_UInt script_index,
+ OTTag language_tag,
+ FT_UInt *language_index,
+ FT_UInt *required_feature_index);
+FT_Bool ot_info_find_feature (OTInfo *info,
+ OTTableType table_type,
+ OTTag feature_tag,
+ FT_UInt script_index,
+ FT_UInt language_index,
+ FT_UInt *feature_index);
+
+OTTag *ot_info_list_scripts (OTInfo *info,
+ OTTableType table_type);
+OTTag *ot_info_list_languages (OTInfo *info,
+ OTTableType table_type,
+ FT_UInt script_index,
+ OTTag language_tag);
+OTTag *ot_info_list_features (OTInfo *info,
+ OTTableType table_type,
+ OTTag tag,
+ FT_UInt script_index,
+ FT_UInt language_index);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __OT_INFO_H__ */
diff --git a/src/otlayout/ot-ruleset.c b/src/otlayout/ot-ruleset.c
new file mode 100644
index 000000000..97dd8b75d
--- /dev/null
+++ b/src/otlayout/ot-ruleset.c
@@ -0,0 +1,312 @@
+/*
+ * ot-ruleset.c: Shaping using OpenType features
+ *
+ * Copyright (C) 2000 Red Hat Software
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "ot-ruleset.h"
+#include "ot-info.h"
+
+#define noRULESET_DEBUG_MEMORY
+
+#include FT_INTERNAL_MEMORY_H /* For FT_Free() */
+
+#define OT_SCALE_26_6 (OT_SCALE / (1<<6))
+#define OT_UNITS_26_6(d) (OT_SCALE_26_6 * (d))
+
+typedef struct _OTRule OTRule;
+
+struct _OTRule {
+ FT_ULong property_bit;
+ FT_UShort feature_index;
+ FT_UInt table_type : 1;
+};
+
+OTRuleset *
+ot_ruleset_new (OTInfo *info)
+{
+ OTRuleset *ruleset;
+
+ ruleset = malloc (sizeof (OTRuleset));
+
+ ot_ruleset_setup (ruleset, info);
+
+ return ruleset;
+}
+
+OTRuleset *
+ot_ruleset_delete (OTRuleset *ruleset)
+{
+ if (ruleset) {
+ ot_ruleset_release (ruleset);
+ free (ruleset);
+ }
+
+ return NULL;
+}
+
+#ifdef RULESET_DEBUG_MEMORY
+static ot_ruleset_count = 0;
+#endif
+
+OTRuleset *
+ot_ruleset_setup (OTRuleset *ruleset, OTInfo *info)
+{
+ FT_Memory memory = FT_FACE_MEMORY( info->face );
+ FT_ASSERT (ruleset != NULL);
+
+#ifdef RULESET_DEBUG_MEMORY
+ ot_ruleset_count++;
+ FT_Message("ot_ruleset_setup: %d\n", ot_ruleset_count);
+#endif
+ ruleset->info = info;
+
+ ruleset->rules = OT_Array_New ( sizeof (OTRule), memory );
+
+ return ruleset;
+}
+
+OTRuleset *
+ot_ruleset_release (OTRuleset *ruleset)
+{
+#ifdef RULESET_DEBUG_MEMORY
+ ot_ruleset_count--;
+ FT_Message("ot_ruleset_release: %d\n", ot_ruleset_count);
+#endif
+ if (ruleset->rules) {
+ OT_Array_Free ( ruleset->rules );
+ ruleset->rules = NULL;
+ }
+
+ if (ruleset->info) {
+ ruleset->info = NULL;
+ }
+
+ return NULL;
+}
+
+void
+ot_ruleset_copy ( OTRuleset * from, OTRuleset * to )
+{
+ OTArray *from_array;
+ OTArray *to_array;
+ FT_UInt from_length;
+ FT_UInt i;
+
+ to->info = from->info;
+ from_array = from->rules;
+ from_length = from_array->length;
+ to_array = to->rules;
+ OT_Array_Set_Size( to_array, from_length );
+ for ( i = 0; i < from_length; i++ )
+ OT_Array_Index(to_array, OTRule, i) = OT_Array_Index(from_array, OTRule, i);
+}
+
+/**
+ * ot_ruleset_add_feature:
+ * @ruleset: a #OTRuleset.
+ * @table_type: the table type to add a feature to.
+ * @feature_index: the index of the feature to add.
+ * @property_bit: the property bit to use for this feature.
+ *
+ * Adds a feature to the ruleset. See ot_ruleset_shape()
+ * for an explanation of @property_bit.
+ **/
+void
+ot_ruleset_add_feature (OTRuleset *ruleset, OTTableType table_type, FT_UInt feature_index, FT_ULong property_bit)
+{
+ OTRule tmp_rule;
+
+ FT_ASSERT (ruleset != NULL);
+
+ tmp_rule.table_type = table_type;
+ tmp_rule.feature_index = feature_index;
+ tmp_rule.property_bit = property_bit;
+
+ OT_Array_Append_Val (ruleset->rules, &tmp_rule);
+}
+
+/**
+ * ot_ruleset_shape:
+ * @ruleset: a #OTRuleset.
+ * @glyphs: a pointer to a #OTGlyphString.
+ *
+ * Shapes a string of glyphs with the given properties according to @ruleset.
+ **/
+OTGlyphString *
+ot_ruleset_shape ( OTRuleset *ruleset, OTGlyphString *glyphs )
+{
+ FT_Error error;
+ int i;
+ int last_cluster;
+ int result;
+
+ TTO_GSUB gsub = NULL;
+ TTO_GPOS gpos = NULL;
+
+ TTO_GSUB_String *in_string = NULL;
+ TTO_GSUB_String *out_string = NULL;
+ TTO_GSUB_String *result_string = NULL;
+
+ FT_Bool need_gsub = 0;
+ FT_Bool need_gpos = 0;
+
+ FT_ASSERT (ruleset != NULL);
+
+ for (i = 0; i < ruleset->rules->length; i++)
+ {
+ OTRule *rule = &OT_Array_Index (ruleset->rules, OTRule, i);
+
+ if (rule->table_type == OT_TABLE_GSUB)
+ need_gsub = 1;
+ else
+ need_gpos = 1;
+ }
+
+ if (need_gsub)
+ {
+ gsub = ot_info_get_gsub (ruleset->info);
+
+ if (gsub)
+ TT_GSUB_Clear_Features (gsub);
+ }
+
+ if (need_gpos)
+ {
+ gpos = ot_info_get_gpos (ruleset->info);
+
+ if (gpos)
+ TT_GPOS_Clear_Features (gpos);
+ }
+
+ for (i = 0; i < ruleset->rules->length; i++)
+ {
+ OTRule *rule = &OT_Array_Index (ruleset->rules, OTRule, i);
+
+ if (rule->table_type == OT_TABLE_GSUB)
+ {
+ if (gsub)
+ TT_GSUB_Add_Feature (gsub, rule->feature_index, rule->property_bit);
+ }
+ else
+ {
+ if (gpos)
+ TT_GPOS_Add_Feature (gpos, rule->feature_index, rule->property_bit);
+ }
+ }
+
+ if (!gsub && !gpos)
+ return glyphs;
+
+ result = TT_GSUB_String_New (ruleset->info->face->memory, &in_string);
+ FT_ASSERT (result == FT_Err_Ok);
+
+ result = TT_GSUB_String_Set_Length (in_string, glyphs->length);
+ FT_ASSERT (result == FT_Err_Ok);
+
+ for (i = 0; i < glyphs->length; i++)
+ {
+ in_string->string[i] = glyphs->glyphs[i].gid;
+ in_string->properties[i] = glyphs->glyphs[i].ot_prop;
+#if 0
+ in_string->logClusters[i] = glyphs->log_clusters[i];
+#endif
+ }
+ in_string->max_ligID = i;
+
+ if (gsub)
+ {
+ result = TT_GSUB_String_New (ruleset->info->face->memory,
+ &out_string);
+ FT_ASSERT (result == FT_Err_Ok);
+ result_string = out_string;
+
+ TT_GSUB_Apply_String (gsub, in_string, out_string);
+ }
+ else
+ result_string = in_string;
+
+#if 0 /* TODO: implement this using nr-glyphs */
+ if (gpos)
+ {
+ TTO_GPOS_Data *outgpos = NULL;
+
+ if (!TT_GPOS_Apply_String (ruleset->info->face, gpos, 0, result_string, &outgpos,
+ FALSE /* enable device-dependant values */,
+ FALSE /* Even though this might be r2l text, RTL is handled elsewhere */))
+ {
+ for (i = 0; i < result_string->length; i++)
+ {
+ FT_Pos x_pos = outgpos[i].x_pos;
+ FT_Pos y_pos = outgpos[i].y_pos;
+ int back = i;
+ int j;
+
+ while (outgpos[back].back != 0)
+ {
+ back -= outgpos[back].back;
+ x_pos += outgpos[back].x_pos;
+ y_pos += outgpos[back].y_pos;
+ }
+
+ for (j = back; j < i; j++)
+ glyphs->glyphs[i].geometry.x_offset -= glyphs->glyphs[j].geometry.width;
+
+ glyphs->glyphs[i].geometry.x_offset += OT_UNITS_26_6(x_pos);
+ glyphs->glyphs[i].geometry.y_offset += OT_UNITS_26_6(y_pos);
+
+ if (outgpos[i].new_advance)
+ glyphs->glyphs[i].geometry.width = OT_UNITS_26_6(outgpos[i].x_advance);
+ else
+ glyphs->glyphs[i].geometry.width += OT_UNITS_26_6(outgpos[i].x_advance);
+ }
+
+ FT_Free(gpos->memory, (void *)outgpos);
+ }
+ }
+#endif
+
+ if (glyphs->length != result_string->length)
+ {
+ if (( error = FTL_Set_Glyphs_Array_Length( glyphs, result_string->length ) ))
+ return glyphs;
+ }
+
+ last_cluster = -1;
+ for (i = 0; i < result_string->length; i++)
+ {
+ glyphs->glyphs[i].gid = result_string->string[i];
+ /* TODO: Other fields */
+#if 0 /* TODO: */
+ glyphs->log_clusters[i] = result_string->logClusters[i];
+ if (glyphs->log_clusters[i] != last_cluster)
+ glyphs->glyphs[i].attr.is_cluster_start = 1;
+ else
+ glyphs->glyphs[i].attr.is_cluster_start = 0;
+
+ last_cluster = glyphs->log_clusters[i];
+#endif
+ }
+
+ if (in_string)
+ TT_GSUB_String_Done (in_string);
+ if (out_string)
+ TT_GSUB_String_Done (out_string);
+
+ return glyphs;
+}
diff --git a/src/otlayout/ot-ruleset.h b/src/otlayout/ot-ruleset.h
new file mode 100644
index 000000000..bd2acb89f
--- /dev/null
+++ b/src/otlayout/ot-ruleset.h
@@ -0,0 +1,64 @@
+/*
+ * ot-ruleset.h: Shaping using OpenType features
+ *
+ * Copyright (C) 2000 Red Hat Software
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __OT_RULESET_H__
+#define __OT_RULESET_H__
+
+#include "ftxopen.h"
+#include "ot-types.h"
+#include "ot-array.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+struct _OTRuleset
+{
+ OTArray *rules;
+ OTInfo *info;
+};
+
+/* Dynamic lifecycle */
+
+OTRuleset *ot_ruleset_new (OTInfo *info);
+OTRuleset *ot_ruleset_delete (OTRuleset *ruleset);
+
+/* Automatic lifecycle */
+
+OTRuleset *ot_ruleset_setup (OTRuleset *ruleset, OTInfo *info);
+OTRuleset *ot_ruleset_release (OTRuleset *ruleset);
+
+void ot_ruleset_copy ( OTRuleset * from, OTRuleset * to );
+
+void ot_ruleset_add_feature (OTRuleset *ruleset,
+ OTTableType table_type,
+ FT_UInt feature_index,
+ FT_ULong property_bit);
+OTGlyphString *ot_ruleset_shape ( OTRuleset *ruleset,
+ OTGlyphString *glyphs );
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __OT_RULESET_H__ */
diff --git a/src/otlayout/ot-types.h b/src/otlayout/ot-types.h
new file mode 100644
index 000000000..45d316e91
--- /dev/null
+++ b/src/otlayout/ot-types.h
@@ -0,0 +1,39 @@
+/* ot-types.h
+ *
+ * Copyright (C) 2000 Red Hat Software
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __OT_TYPES_H__
+#define __OT_TYPES_H__
+
+#include <ft2build.h>
+#include FT_LAYOUT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+typedef struct _OTInfo OTInfo;
+typedef struct _OTRuleset OTRuleset;
+typedef FTL_Glyphs_ArrayRec OTGlyphString;
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __OT_TYPES_H__ */
diff --git a/src/otlayout/ot-unicode.c b/src/otlayout/ot-unicode.c
new file mode 100644
index 000000000..adf34e082
--- /dev/null
+++ b/src/otlayout/ot-unicode.c
@@ -0,0 +1,8359 @@
+/* ot-unicode.[ch] are copied from gunicode.[ch] */
+
+/* gunicode.h - Unicode manipulation functions
+ *
+ * Copyright (C) 1999, 2000 Tom Tromey
+ * Copyright 2000 Red Hat, Inc.
+ *
+ * The Gnome Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * The Gnome Library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the Gnome Library; see the file COPYING.LIB. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "ot-unicode.h"
+
+#define G_UNICODE_DATA_VERSION "4.0"
+
+#define G_UNICODE_LAST_CHAR 0x10ffff
+
+#define G_UNICODE_MAX_TABLE_INDEX 10000
+
+#define G_UNICODE_LAST_CHAR_PART1 0x2FAFF
+
+#define G_UNICODE_LAST_PAGE_PART1 762
+
+typedef enum
+{
+ G_UNICODE_CONTROL,
+ G_UNICODE_FORMAT,
+ G_UNICODE_UNASSIGNED,
+ G_UNICODE_PRIVATE_USE,
+ G_UNICODE_SURROGATE,
+ G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_OTHER_LETTER,
+ G_UNICODE_TITLECASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_COMBINING_MARK,
+ G_UNICODE_ENCLOSING_MARK,
+ G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_LETTER_NUMBER,
+ G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_CONNECT_PUNCTUATION,
+ G_UNICODE_DASH_PUNCTUATION,
+ G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_FINAL_PUNCTUATION,
+ G_UNICODE_INITIAL_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OPEN_PUNCTUATION,
+ G_UNICODE_CURRENCY_SYMBOL,
+ G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_LINE_SEPARATOR,
+ G_UNICODE_PARAGRAPH_SEPARATOR,
+ G_UNICODE_SPACE_SEPARATOR
+} OT_UnicodeType;
+
+static const char type_data[][256] = {
+ { /* page 0, index 0 */
+ G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL,
+ G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL,
+ G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL,
+ G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL,
+ G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL,
+ G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL,
+ G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL,
+ G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL,
+ G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL,
+ G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL,
+ G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_SPACE_SEPARATOR,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_CURRENCY_SYMBOL,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION,
+ G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_DASH_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_CONNECT_PUNCTUATION, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_MATH_SYMBOL, G_UNICODE_CONTROL,
+ G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL,
+ G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL,
+ G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL,
+ G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL,
+ G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL,
+ G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL,
+ G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL,
+ G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL,
+ G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL,
+ G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL,
+ G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_SPACE_SEPARATOR,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_CURRENCY_SYMBOL,
+ G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL,
+ G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_INITIAL_PUNCTUATION, G_UNICODE_MATH_SYMBOL, G_UNICODE_FORMAT,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_FINAL_PUNCTUATION, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER
+ },
+ { /* page 1, index 1 */
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_TITLECASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_TITLECASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_TITLECASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_TITLECASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER
+ },
+ { /* page 2, index 2 */
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_MODIFIER_SYMBOL
+ },
+ { /* page 3, index 3 */
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED
+ },
+ { /* page 4, index 4 */
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED,
+ G_UNICODE_ENCLOSING_MARK, G_UNICODE_ENCLOSING_MARK,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED
+ },
+ { /* page 5, index 5 */
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_UNASSIGNED, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_DASH_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED
+ },
+ { /* page 6, index 6 */
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_MODIFIER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_FORMAT, G_UNICODE_ENCLOSING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_LETTER
+ },
+ { /* page 7, index 7 */
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_UNASSIGNED, G_UNICODE_FORMAT, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED
+ },
+ { /* page 9, index 8 */
+ G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED
+ },
+ { /* page 10, index 9 */
+ G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED
+ },
+ { /* page 11, index 10 */
+ G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED
+ },
+ { /* page 12, index 11 */
+ G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED
+ },
+ { /* page 13, index 12 */
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED
+ },
+ { /* page 14, index 13 */
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_CURRENCY_SYMBOL,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_MODIFIER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED
+ },
+ { /* page 15, index 14 */
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_OPEN_PUNCTUATION,
+ G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION,
+ G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED
+ },
+ { /* page 16, index 15 */
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED
+ },
+ { /* page 17, index 16 */
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED
+ },
+ { /* page 18, index 17 */
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER
+ },
+ { /* page 19, index 18 */
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED
+ },
+ { /* page 20, index 19 */
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER
+ },
+ { /* page 22, index 20 */
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_SPACE_SEPARATOR, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OPEN_PUNCTUATION,
+ G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER,
+ G_UNICODE_LETTER_NUMBER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED
+ },
+ { /* page 23, index 21 */
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_FORMAT,
+ G_UNICODE_FORMAT, G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_CURRENCY_SYMBOL,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED
+ },
+ { /* page 24, index 22 */
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_DASH_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_SPACE_SEPARATOR, G_UNICODE_UNASSIGNED,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED
+ },
+ { /* page 25, index 23 */
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL
+ },
+ { /* page 29, index 24 */
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED
+ },
+ { /* page 30, index 25 */
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED
+ },
+ { /* page 31, index 26 */
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER,
+ G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER,
+ G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER,
+ G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER,
+ G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER,
+ G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER,
+ G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER,
+ G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER,
+ G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER,
+ G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_TITLECASE_LETTER, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_TITLECASE_LETTER, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_TITLECASE_LETTER, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_UNASSIGNED
+ },
+ { /* page 32, index 27 */
+ G_UNICODE_SPACE_SEPARATOR, G_UNICODE_SPACE_SEPARATOR,
+ G_UNICODE_SPACE_SEPARATOR, G_UNICODE_SPACE_SEPARATOR,
+ G_UNICODE_SPACE_SEPARATOR, G_UNICODE_SPACE_SEPARATOR,
+ G_UNICODE_SPACE_SEPARATOR, G_UNICODE_SPACE_SEPARATOR,
+ G_UNICODE_SPACE_SEPARATOR, G_UNICODE_SPACE_SEPARATOR,
+ G_UNICODE_SPACE_SEPARATOR, G_UNICODE_SPACE_SEPARATOR, G_UNICODE_FORMAT,
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT,
+ G_UNICODE_DASH_PUNCTUATION, G_UNICODE_DASH_PUNCTUATION,
+ G_UNICODE_DASH_PUNCTUATION, G_UNICODE_DASH_PUNCTUATION,
+ G_UNICODE_DASH_PUNCTUATION, G_UNICODE_DASH_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_INITIAL_PUNCTUATION, G_UNICODE_FINAL_PUNCTUATION,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_INITIAL_PUNCTUATION,
+ G_UNICODE_INITIAL_PUNCTUATION, G_UNICODE_FINAL_PUNCTUATION,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_INITIAL_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_LINE_SEPARATOR, G_UNICODE_PARAGRAPH_SEPARATOR,
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT,
+ G_UNICODE_FORMAT, G_UNICODE_SPACE_SEPARATOR, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_INITIAL_PUNCTUATION, G_UNICODE_FINAL_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_CONNECT_PUNCTUATION, G_UNICODE_CONNECT_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_CONNECT_PUNCTUATION,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_SPACE_SEPARATOR, G_UNICODE_FORMAT,
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT,
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_CURRENCY_SYMBOL,
+ G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL,
+ G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL,
+ G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL,
+ G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL,
+ G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL,
+ G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL,
+ G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL,
+ G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL,
+ G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_ENCLOSING_MARK, G_UNICODE_ENCLOSING_MARK,
+ G_UNICODE_ENCLOSING_MARK, G_UNICODE_ENCLOSING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_ENCLOSING_MARK,
+ G_UNICODE_ENCLOSING_MARK, G_UNICODE_ENCLOSING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED
+ },
+ { /* page 33, index 28 */
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER,
+ G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER,
+ G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER,
+ G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER,
+ G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER,
+ G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER,
+ G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER,
+ G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER,
+ G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER,
+ G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER,
+ G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER,
+ G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER,
+ G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER,
+ G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER,
+ G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER,
+ G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER,
+ G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER,
+ G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL
+ },
+ { /* page 35, index 29 */
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_OPEN_PUNCTUATION,
+ G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED
+ },
+ { /* page 36, index 30 */
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER
+ },
+ { /* page 37, index 31 */
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL
+ },
+ { /* page 38, index 32 */
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED
+ },
+ { /* page 39, index 33 */
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_OPEN_PUNCTUATION,
+ G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION,
+ G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION,
+ G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL
+ },
+ { /* page 41, index 34 */
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_OPEN_PUNCTUATION,
+ G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION,
+ G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION,
+ G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION,
+ G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION,
+ G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION,
+ G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION,
+ G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION,
+ G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION,
+ G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION,
+ G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION,
+ G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_OPEN_PUNCTUATION,
+ G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION,
+ G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_OPEN_PUNCTUATION,
+ G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL
+ },
+ { /* page 43, index 35 */
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED
+ },
+ { /* page 46, index 36 */
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED
+ },
+ { /* page 47, index 37 */
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED
+ },
+ { /* page 48, index 38 */
+ G_UNICODE_SPACE_SEPARATOR, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_LETTER_NUMBER,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_DASH_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION,
+ G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER,
+ G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER,
+ G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER,
+ G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER,
+ G_UNICODE_LETTER_NUMBER, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_DASH_PUNCTUATION,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER,
+ G_UNICODE_LETTER_NUMBER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_DASH_PUNCTUATION, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_CONNECT_PUNCTUATION, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_OTHER_LETTER
+ },
+ { /* page 49, index 39 */
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER
+ },
+ { /* page 50, index 40 */
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_UNASSIGNED
+ },
+ { /* page 77, index 41 */
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL
+ },
+ { /* page 159, index 42 */
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED
+ },
+ { /* page 164, index 43 */
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED
+ },
+ { /* page 215, index 44 */
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED
+ },
+ { /* page 250, index 45 */
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED
+ },
+ { /* page 251, index 46 */
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER
+ },
+ { /* page 253, index 47 */
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED
+ },
+ { /* page 254, index 48 */
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_DASH_PUNCTUATION, G_UNICODE_DASH_PUNCTUATION,
+ G_UNICODE_CONNECT_PUNCTUATION, G_UNICODE_CONNECT_PUNCTUATION,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_CONNECT_PUNCTUATION, G_UNICODE_CONNECT_PUNCTUATION,
+ G_UNICODE_CONNECT_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_DASH_PUNCTUATION,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_DASH_PUNCTUATION, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_FORMAT
+ },
+ { /* page 255, index 49 */
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_DASH_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_CONNECT_PUNCTUATION, G_UNICODE_MODIFIER_SYMBOL,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION,
+ G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_CONNECT_PUNCTUATION, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_CURRENCY_SYMBOL,
+ G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED
+ },
+ { /* page 256, index 50 */
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED
+ },
+ { /* page 257, index 51 */
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED
+ },
+ { /* page 259, index 52 */
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_LETTER_NUMBER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED
+ },
+ { /* page 260, index 53 */
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED
+ },
+ { /* page 264, index 54 */
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED
+ },
+ { /* page 464, index 55 */
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED
+ },
+ { /* page 465, index 56 */
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK,
+ G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, G_UNICODE_FORMAT,
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT,
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED
+ },
+ { /* page 467, index 57 */
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED
+ },
+ { /* page 468, index 58 */
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER
+ },
+ { /* page 469, index 59 */
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER
+ },
+ { /* page 470, index 60 */
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_MATH_SYMBOL, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER
+ },
+ { /* page 471, index 61 */
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER,
+ G_UNICODE_UPPERCASE_LETTER, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_MATH_SYMBOL,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER,
+ G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER
+ },
+ { /* page 678, index 62 */
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED
+ },
+ { /* page 762, index 63 */
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED
+ },
+ { /* page 3584, index 64 */
+ G_UNICODE_UNASSIGNED, G_UNICODE_FORMAT, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_FORMAT,
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT,
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT,
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT,
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT,
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT,
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT,
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT,
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT,
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT,
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT,
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT,
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT,
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT,
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT,
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT,
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT,
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT,
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT,
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT,
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT,
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT,
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT,
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT,
+ G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED
+ },
+ { /* page 3585, index 65 */
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED
+ },
+ { /* page 4095, index 66 */
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED
+ },
+ { /* page 4351, index 67 */
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE,
+ G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_UNASSIGNED,
+ G_UNICODE_UNASSIGNED
+ }
+};
+
+/* U+0000 through U+2FAFF */
+static const FT_UShort type_table_part1[763] = {
+ 0 /* page 0 */,
+ 1 /* page 1 */,
+ 2 /* page 2 */,
+ 3 /* page 3 */,
+ 4 /* page 4 */,
+ 5 /* page 5 */,
+ 6 /* page 6 */,
+ 7 /* page 7 */,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ 8 /* page 9 */,
+ 9 /* page 10 */,
+ 10 /* page 11 */,
+ 11 /* page 12 */,
+ 12 /* page 13 */,
+ 13 /* page 14 */,
+ 14 /* page 15 */,
+ 15 /* page 16 */,
+ 16 /* page 17 */,
+ 17 /* page 18 */,
+ 18 /* page 19 */,
+ 19 /* page 20 */,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ 20 /* page 22 */,
+ 21 /* page 23 */,
+ 22 /* page 24 */,
+ 23 /* page 25 */,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ 24 /* page 29 */,
+ 25 /* page 30 */,
+ 26 /* page 31 */,
+ 27 /* page 32 */,
+ 28 /* page 33 */,
+ G_UNICODE_MATH_SYMBOL + G_UNICODE_MAX_TABLE_INDEX,
+ 29 /* page 35 */,
+ 30 /* page 36 */,
+ 31 /* page 37 */,
+ 32 /* page 38 */,
+ 33 /* page 39 */,
+ G_UNICODE_OTHER_SYMBOL + G_UNICODE_MAX_TABLE_INDEX,
+ 34 /* page 41 */,
+ G_UNICODE_MATH_SYMBOL + G_UNICODE_MAX_TABLE_INDEX,
+ 35 /* page 43 */,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ 36 /* page 46 */,
+ 37 /* page 47 */,
+ 38 /* page 48 */,
+ 39 /* page 49 */,
+ 40 /* page 50 */,
+ G_UNICODE_OTHER_SYMBOL + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ 41 /* page 77 */,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ 42 /* page 159 */,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ 43 /* page 164 */,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ 44 /* page 215 */,
+ G_UNICODE_SURROGATE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_SURROGATE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_SURROGATE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_SURROGATE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_SURROGATE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_SURROGATE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_SURROGATE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_SURROGATE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ 45 /* page 250 */,
+ 46 /* page 251 */,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ 47 /* page 253 */,
+ 48 /* page 254 */,
+ 49 /* page 255 */,
+ 50 /* page 256 */,
+ 51 /* page 257 */,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ 52 /* page 259 */,
+ 53 /* page 260 */,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ 54 /* page 264 */,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ 55 /* page 464 */,
+ 56 /* page 465 */,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ 57 /* page 467 */,
+ 58 /* page 468 */,
+ 59 /* page 469 */,
+ 60 /* page 470 */,
+ 61 /* page 471 */,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ 62 /* page 678 */,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+ 63 /* page 762 */
+};
+
+/* U+E0000 through U+10FFFF */
+static const FT_UShort type_table_part2[768] = {
+ 64 /* page 3584 */,
+ 65 /* page 3585 */,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ 66 /* page 4095 */,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+ 67 /* page 4351 */
+};
+
+
+#define TTYPE_PART1(Page, Char) \
+ ((type_table_part1[Page] >= G_UNICODE_MAX_TABLE_INDEX) \
+ ? (type_table_part1[Page] - G_UNICODE_MAX_TABLE_INDEX) \
+ : (type_data[type_table_part1[Page]][Char]))
+
+#define TTYPE_PART2(Page, Char) \
+ ((type_table_part2[Page] >= G_UNICODE_MAX_TABLE_INDEX) \
+ ? (type_table_part2[Page] - G_UNICODE_MAX_TABLE_INDEX) \
+ : (type_data[type_table_part2[Page]][Char]))
+
+#define TYPE(Char) \
+ (((Char) <= G_UNICODE_LAST_CHAR_PART1) \
+ ? TTYPE_PART1 ((Char) >> 8, (Char) & 0xff) \
+ : (((Char) >= 0xe0000 && (Char) <= G_UNICODE_LAST_CHAR) \
+ ? TTYPE_PART2 (((Char) - 0xe0000) >> 8, (Char) & 0xff) \
+ : G_UNICODE_UNASSIGNED))
+
+static OT_UnicodeType
+ot_unichar_type (FT_ULong c)
+{
+ return TYPE(c);
+}
+
+FT_LOCAL_DEF(FT_UShort)
+ot_get_glyph_class(FT_ULong charcode)
+{
+ switch (ot_unichar_type (charcode)) {
+ case G_UNICODE_COMBINING_MARK:
+ case G_UNICODE_ENCLOSING_MARK:
+ case G_UNICODE_NON_SPACING_MARK:
+ return 3; /* Mark glyph (non-spacing combining glyph) */
+ default:
+ return 1; /* Base glyph (single character, spacing glyph) */
+ }
+}
diff --git a/src/otlayout/ot-unicode.h b/src/otlayout/ot-unicode.h
new file mode 100644
index 000000000..ef8ad004b
--- /dev/null
+++ b/src/otlayout/ot-unicode.h
@@ -0,0 +1,39 @@
+/* ot-unicode.[ch] are copied from gunicode.[ch] */
+
+/* gunicode.h - Unicode manipulation functions
+ *
+ * Copyright (C) 1999, 2000 Tom Tromey
+ * Copyright 2000 Red Hat, Inc.
+ *
+ * The Gnome Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * The Gnome Library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the Gnome Library; see the file COPYING.LIB. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __OT_UNICODE_H__
+#define __OT_UNICODE_H__
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+
+FT_BEGIN_HEADER
+
+/* 3: Mark glyph (non-spacing combining glyph),
+ 1: Base glyph (single character, spacing glyph) */
+
+FT_LOCAL(FT_UShort) ot_get_glyph_class(FT_ULong charcode);
+
+FT_END_HEADER
+#endif /* Not def: __OT_UNICODE_H__ */
+
diff --git a/src/otlayout/ot.c b/src/otlayout/ot.c
new file mode 100644
index 000000000..bb320bbe5
--- /dev/null
+++ b/src/otlayout/ot.c
@@ -0,0 +1,42 @@
+/***************************************************************************/
+/* */
+/* ot.c */
+/* */
+/* FreeType OpenType driver component (body only). */
+/* */
+/* Copyright 2003 by */
+/* Masatake YAMATO and Redhat K.K. */
+/* */
+/* This file may only be used, */
+/* modified, and distributed under the terms of the FreeType project */
+/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
+/* this file you indicate that you have read the license and */
+/* understand and accept it fully. */
+/* */
+/***************************************************************************/
+
+/***************************************************************************/
+/* Development of the code in this file is support of */
+/* Information-technology Promotion Agency, Japan. */
+/***************************************************************************/
+
+#define FT_MAKE_OPTION_SINGLE_OBJECT
+
+#include <ft2build.h>
+
+#include "otdriver.c"
+#include "otobjs.c"
+#include "otlayout.c"
+
+#include "ftxgsub.c"
+#include "ftxgdef.c"
+#include "ftxgpos.c"
+#include "ftxopen.c"
+
+#include "ot-info.c"
+#include "ot-ruleset.c"
+
+#include "ot-array.c"
+#include "ot-unicode.c"
+
+/* END */
diff --git a/src/otlayout/otdemo.c b/src/otlayout/otdemo.c
new file mode 100644
index 000000000..ffe1ae196
--- /dev/null
+++ b/src/otlayout/otdemo.c
@@ -0,0 +1,211 @@
+/***************************************************************************/
+/* */
+/* otdemo.c */
+/* */
+/* Demo program for FreeType/OpenType font driver implementation (body).*/
+/* */
+/* Copyright 2003 by */
+/* Masatake YAMATO and Redhat K.K. */
+/* */
+/* This file may only be used, */
+/* modified, and distributed under the terms of the FreeType project */
+/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
+/* this file you indicate that you have read the license and */
+/* understand and accept it fully. */
+/* */
+/***************************************************************************/
+
+/***************************************************************************/
+/* Development of the code in this file is support of */
+/* Information-technology Promotion Agency, Japan. */
+/***************************************************************************/
+
+#include <ft2build.h>
+#include FT_LAYOUT_H
+#include FT_OTLAYOUT_H
+#include <stdio.h>
+#include <stdlib.h>
+#include <popt.h>
+
+/* KANA specific implementation */
+
+/* Script */
+#define OT_SCRIPT_KANA FT_MAKE_TAG('k', 'a', 'n', 'a')
+
+/* Language */
+#define OT_LANGUAGE_JAPANESE FT_MAKE_TAG('J', 'A', 'N', ' ')
+
+/* Feature */
+#define OT_FEATURE_VERT FT_MAKE_TAG('v', 'e', 'r', 't')
+#define OT_FEATURE_VRT2 FT_MAKE_TAG('v', 'r', 't', '2')
+
+/* Property bit */
+enum {
+ OT_VERT = 1 << 0,
+ OT_VRT2 = 1 << 1
+};
+
+/* Property */
+enum {
+ OT_VERT_P = (~OT_VERT) & (~OT_VRT2)
+};
+
+void doit(FT_Face face);
+
+int
+main(int argc, char ** argv)
+{
+ FT_Library library;
+ FT_Face face;
+ poptContext optCon;
+ int rc;
+ const char * file;
+ static int arg_memprof = 0;
+
+ struct poptOption optTable [] = {
+ { "memprof", 'm', POPT_ARG_NONE, &arg_memprof, 0, "Enter to infinite loop to run under memprof", ""},
+ POPT_AUTOHELP
+ POPT_TABLEEND
+ };
+
+ FTL_EngineType engine_type;
+
+ optCon = poptGetContext(argv[0], argc, (const char **)argv, optTable, 0);
+ poptSetOtherOptionHelp(optCon, "[options] otfont\n");
+ rc = poptReadDefaultConfig (optCon, 0);
+ if (rc < 0)
+ {
+ fprintf(stderr, "Fail to read .popt config file: %s\n",
+ poptStrerror(rc));
+ exit (1);
+ }
+ while ((rc = poptGetNextOpt(optCon)) > 0)
+ if (rc != -1)
+ {
+ fprintf(stderr, "bad argument %s: %s\n",
+ poptBadOption(optCon, POPT_BADOPTION_NOALIAS),
+ poptStrerror(rc));
+ exit (1);
+ }
+
+ if (FT_Init_FreeType (&library))
+ {
+ fprintf(stderr, "Error in %s\n", "FT_Init_FreeType");
+ exit (1);
+ }
+
+ file = poptGetArg(optCon);
+ if (!file)
+ {
+ poptPrintHelp(optCon, stderr, 0);
+ exit(1);
+ }
+
+ if ( FT_New_Face (library, file, 0, &face) )
+ {
+ fprintf(stderr, "Error in %s: %s\n", "FT_New_Face", file);
+ exit (1);
+ }
+
+
+ if ( !( face->face_flags & FT_FACE_FLAG_GLYPH_SUBSTITUTION) )
+ {
+ fprintf(stderr, "Abort: No substitution table for the face\n");
+ exit(1);
+ }
+
+ if ( FTL_Query_EngineType( face, &engine_type )
+ || ( engine_type != FTL_OPENTYPE_ENGINE ) )
+ {
+ fprintf(stderr, "No OT table is existed: %s\n", file);
+ exit ( 1 );
+ }
+
+ doit( face );
+
+ if ( FT_Done_Face ( face ) )
+ fprintf(stderr, "Error in %s: %s\n", "FT_Done_Face", file);
+ if ( FT_Done_FreeType (library) )
+ {
+ fprintf(stderr, "Error in %s\n", "FT_Done_FreeType");
+ exit(1);
+ }
+ if ( arg_memprof || getenv("_MEMPROF_SOCKET") )
+ {
+ fprintf(stderr, "Enter infinite loop for memprof\n");
+ while (1);
+ }
+ return 0;
+}
+
+void
+doit(FT_Face face)
+{
+ FTL_FeaturesRequest request;
+ FT_UInt script_index, feature_index;
+ FT_Memory memory = face->stream->memory;
+ FTL_Glyphs_Array in, out;
+ FT_Int i;
+ if ( FTL_New_FeaturesRequest( face, &request ) )
+ {
+ fprintf(stderr, "error: %s\n", "FTL_New_FeaturesRequest");
+ return ;
+ }
+ if ( !OTL_FeaturesRequest_Find_Script ( (OTL_FeaturesRequest)request,
+ OT_TABLE_GSUB,
+ OT_SCRIPT_KANA,
+ &script_index ) )
+ {
+ fprintf(stderr, "cannot find script: %s\n",
+ "OTL_FeaturesRequest_Find_Script");
+ return ;
+ }
+
+ if ( !OTL_FeaturesRequest_Find_Feature( (OTL_FeaturesRequest)request,
+ OT_TABLE_GSUB,
+ OT_FEATURE_VERT,
+ script_index,
+ 0xffff, /* default language system */
+ &feature_index ) )
+ {
+ fprintf(stderr, "cannot find feature: %s\n",
+ "OTL_FeaturesRequest_Find_Feature");
+ return ;
+ }
+ OTL_FeaturesRequest_Add_Feature ( (OTL_FeaturesRequest)request,
+ OT_TABLE_GSUB,
+ feature_index,
+ OT_VERT );
+
+ if ( FTL_New_Glyphs_Array ( memory, &in )
+ || FTL_New_Glyphs_Array ( memory, &out ) )
+ {
+ fprintf(stderr, "mem error: %s\n", "FTL_New_Glyphs_Array");
+ return ;
+ }
+ if ( FTL_Set_Glyphs_Array_Length ( in, 14751 ) )
+ {
+ fprintf(stderr, "mem error: %s\n",
+ "FTL_Set_Glyphs_Array_Length");
+ return ;
+ }
+
+ for ( i = 0; i < 14751; i++ )
+ {
+ in->glyphs[i].gid = i;
+ in->glyphs[i].ot_prop = OT_VERT_P;
+ }
+ FTL_Activate_FeaturesRequest( request );
+ FTL_Substitute_Glyphs ( face, in, out );
+
+ for ( i = 0; i < 14751; i++ )
+ {
+ if ( out->glyphs[i].gid != i )
+ fprintf( stdout, "%d => %u\n", i, out->glyphs[i].gid );
+ }
+ FTL_Done_Glyphs_Array ( out );
+ FTL_Done_Glyphs_Array ( in );
+ FTL_Done_FeaturesRequest ( request );
+}
+
+/* END */
diff --git a/src/otlayout/otdriver.c b/src/otlayout/otdriver.c
new file mode 100644
index 000000000..128c7274b
--- /dev/null
+++ b/src/otlayout/otdriver.c
@@ -0,0 +1,100 @@
+/***************************************************************************/
+/* */
+/* otdriver.c */
+/* */
+/* High-level OpenType driver interface (body). */
+/* */
+/* Copyright 2003 by */
+/* Masatake YAMATO and Redhat K.K. */
+/* */
+/* This file may only be used, */
+/* modified, and distributed under the terms of the FreeType project */
+/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
+/* this file you indicate that you have read the license and */
+/* understand and accept it fully. */
+/* */
+/***************************************************************************/
+
+/***************************************************************************/
+/* Development of the code in this file is support of */
+/* Information-technology Promotion Agency, Japan. */
+/***************************************************************************/
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include FT_INTERNAL_DEBUG_H
+#include "otdriver.h"
+#include "otobjs.h"
+
+ /*************************************************************************/
+ /* */
+ /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
+ /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
+ /* messages during execution. */
+ /* */
+#undef FT_COMPONENT
+#define FT_COMPONENT trace_otdriver
+
+ /* The FT_DriverInterface structure is defined in ftdriver.h.
+ * -----------------------------------------------------------------------
+ * Almost all fields should be initialized in ot_driver_init.
+ */
+
+ FT_CALLBACK_TABLE_DEF
+ const FT_Driver_ClassRec ot_driver_class =
+ {
+ /* FT_Module_Class */
+ {
+ /* module_flags, copyied from ttdriver.c */
+ FT_MODULE_FONT_DRIVER |
+ FT_MODULE_DRIVER_SCALABLE |
+#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
+ FT_MODULE_DRIVER_HAS_HINTER,
+#else
+ 0,
+#endif
+ /* module_size, copyied from ttdriver.c */
+ sizeof (OT_DriverRec),
+ /* module_name */
+ "ot",
+ /* module_version */
+ 0x10000L,
+ /* module_requires */
+ 0x20000L,
+
+ /* module_interface */
+ NULL,
+
+ /* module_init */
+ (FT_Module_Constructor) ot_driver_init,
+
+ /* module_done */
+ (FT_Module_Destructor) NULL,
+
+ /* get_interface */
+ (FT_Module_Requester) NULL,
+ },
+
+ /* now the specific driver fields */
+ 0,
+ 0,
+ 0,
+
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+
+ NULL,
+ NULL,
+
+ NULL,
+
+ NULL,
+ NULL,
+ NULL,
+ };
+
+/* END */
diff --git a/src/otlayout/otdriver.h b/src/otlayout/otdriver.h
new file mode 100644
index 000000000..c6d9cf1e3
--- /dev/null
+++ b/src/otlayout/otdriver.h
@@ -0,0 +1,41 @@
+/***************************************************************************/
+/* */
+/* otdriver.h */
+/* */
+/* High-level OpenType driver interface (specification). */
+/* */
+/* Copyright 2003 by */
+/* Masatake YAMATO and Redhat K.K. */
+/* */
+/* This file may only be used, */
+/* modified, and distributed under the terms of the FreeType project */
+/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
+/* this file you indicate that you have read the license and */
+/* understand and accept it fully. */
+/* */
+/***************************************************************************/
+
+/***************************************************************************/
+/* Development of the code in this file is support of */
+/* Information-technology Promotion Agency, Japan. */
+/***************************************************************************/
+
+#ifndef __OTDRIVER_H__
+#define __OTDRIVER_H__
+
+#include <ft2build.h>
+#include FT_INTERNAL_DRIVER_H
+
+
+FT_BEGIN_HEADER
+
+
+ FT_CALLBACK_TABLE
+ const FT_Driver_ClassRec ot_driver_class;
+
+FT_END_HEADER
+
+#endif /* __OTDRIVER_H__ */
+
+
+/* END */
diff --git a/src/otlayout/oterrors.h b/src/otlayout/oterrors.h
new file mode 100644
index 000000000..d60ccaf53
--- /dev/null
+++ b/src/otlayout/oterrors.h
@@ -0,0 +1,45 @@
+/***************************************************************************/
+/* */
+/* gxerrors.h */
+/* */
+/* OT error codes (specification only). */
+/* */
+/* Copyright 2003 by */
+/* Masatake YAMATO and Redhat K.K. */
+/* */
+/* This file may only be used, */
+/* modified, and distributed under the terms of the FreeType project */
+/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
+/* this file you indicate that you have read the license and */
+/* understand and accept it fully. */
+/* */
+/***************************************************************************/
+
+/***************************************************************************/
+/* Development of the code in this file is support of */
+/* Information-technology Promotion Agency, Japan. */
+/***************************************************************************/
+
+ /*************************************************************************/
+ /* */
+ /* This file is used to define the OT error enumeration constants. */
+ /* */
+ /*************************************************************************/
+
+#ifndef __OTERRORS_H__
+#define __OTERRORS_H__
+
+#include FT_MODULE_ERRORS_H
+
+#undef __FTERRORS_H__
+
+#define FT_ERR_PREFIX OT_Err_
+#define FT_ERR_BASE FT_Mod_Err_OT
+
+
+#include FT_ERRORS_H
+
+#endif /* __OTERRORS_H__ */
+
+
+/* END */
diff --git a/src/otlayout/otlayout.c b/src/otlayout/otlayout.c
new file mode 100644
index 000000000..18bb55aa4
--- /dev/null
+++ b/src/otlayout/otlayout.c
@@ -0,0 +1,269 @@
+/***************************************************************************/
+/* */
+/* otlayout.c */
+/* */
+/* OpenType based layout engine(body). */
+/* */
+/* Copyright 2003 by */
+/* Masatake YAMATO and Redhat K.K. */
+/* */
+/* This file may only be used, */
+/* modified, and distributed under the terms of the FreeType project */
+/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
+/* this file you indicate that you have read the license and */
+/* understand and accept it fully. */
+/* */
+/***************************************************************************/
+
+/***************************************************************************/
+/* Development of the code in this file is support of */
+/* Information-technology Promotion Agency, Japan. */
+/***************************************************************************/
+
+/*
+ * Experimental: No support for gpos now.
+ */
+
+#include <ft2build.h>
+#include FT_LIST_H
+#include FT_OTLAYOUT_H
+
+#include "otltypes.h"
+#include "ot-types.h"
+#include "ot-ruleset.h"
+#include "ot-info.h"
+#include "oterrors.h"
+
+ FT_LOCAL_DEF ( FT_Error )
+ otl_get_font ( FT_Face face, FTL_Font * font)
+ {
+ *font = ((OT_Face)face)->extra.data;
+
+ if ( *font )
+ return FT_Err_Ok;
+ else
+ return OT_Err_Invalid_Face_Handle;
+ }
+
+ FT_LOCAL_DEF ( FTL_EngineType )
+ otl_get_engine_type ( FT_Face face )
+ {
+ return FTL_OPENTYPE_ENGINE;
+ }
+
+ FT_LOCAL ( FT_Error )
+ otl_new_features_request( FT_Face face, FTL_FeaturesRequest * ftl_request)
+ {
+ FT_Error error;
+ FT_Memory memory = FT_FACE_MEMORY(face);
+ OTL_Font font;
+ OTL_FeaturesRequest request;
+
+ if (( error = otl_get_font ( face, (FTL_Font*)&font ) ))
+ goto Exit;
+
+ if ( FT_NEW(request) )
+ goto Exit;
+
+ request->ruleset = ot_ruleset_new ( font->info );
+ if ( !request->ruleset )
+ {
+ error = OT_Err_Invalid_Argument; /* ??? */
+ goto Failure;
+ }
+
+ if (( error = FTL_FeaturesRequest_Init ( face, (FTL_FeaturesRequest)request ) ))
+ goto Failure;
+ *ftl_request = (FTL_FeaturesRequest)request;
+ Exit:
+ return error;
+ Failure:
+ if ( request->ruleset )
+ ot_ruleset_delete( request->ruleset );
+ FT_FREE( request );
+ return error;
+ }
+
+ FT_LOCAL ( FT_Error )
+ otl_done_features_request( FTL_FeaturesRequest request)
+ {
+ FT_Error error;
+ FTL_Font font;
+ FT_Face face;
+ FT_Memory memory;
+
+ FT_ASSERT( request );
+ font = FTL_FEATURES_REQUEST_FONT ( request );
+
+ FT_ASSERT( font );
+ face = FTL_FONT_FACE(font);
+
+ if ( !face )
+ return OT_Err_Invalid_Argument;
+ memory = FT_FACE_MEMORY( face );
+ ot_ruleset_delete ( ((OTL_FeaturesRequest)request)->ruleset );
+ error = FTL_FeaturesRequest_Finalize ( request );
+ FT_FREE( request ); /* broken */
+ return error;
+ }
+
+ FT_LOCAL ( FT_Error )
+ otl_copy_features_request( FTL_FeaturesRequest from,
+ FTL_FeaturesRequest to)
+ {
+ FT_Error error;
+ ot_ruleset_copy(((OTL_FeaturesRequest)from)->ruleset, ((OTL_FeaturesRequest)to)->ruleset);
+ error = FTL_FeaturesRequest_Copy( from, to );
+ return error;
+ }
+
+ FT_LOCAL ( FT_Error )
+ otl_substitute_glyphs ( FT_Face face,
+ FTL_FeaturesRequest request,
+ FTL_Glyphs_Array in,
+ FTL_Glyphs_Array out )
+ {
+ FT_Error error = FT_Err_Ok;
+ if (( error = FTL_Copy_Glyphs_Array ( in, out ) ))
+ return error;
+ ot_ruleset_shape ( ((OTL_FeaturesRequest)request)->ruleset, out );
+ return FT_Err_Ok;
+ }
+
+ FT_EXPORT( FT_Bool )
+ OTL_FeaturesRequest_Find_Script ( OTL_FeaturesRequest request,
+ OTTableType table_type,
+ OTTag script_tag,
+ FT_UInt *script_index)
+ {
+ OTL_Font font = (OTL_Font)FTL_FEATURES_REQUEST_FONT( request );
+ return ot_info_find_script ( font->info,
+ table_type,
+ script_tag,
+ script_index )
+ ? 1: 0;
+
+ }
+
+ FT_EXPORT( FT_Bool )
+ OTL_FeaturesRequest_Find_Language ( OTL_FeaturesRequest request,
+ OTTableType table_type,
+ FT_UInt script_index,
+ OTTag language_tag,
+ FT_UInt *language_index,
+ FT_UInt *required_feature_index )
+ {
+ OTL_Font font = (OTL_Font)FTL_FEATURES_REQUEST_FONT( request );
+ return ot_info_find_language ( font->info,
+ table_type,
+ script_index,
+ language_tag,
+ language_index,
+ required_feature_index )
+ ? 1: 0;
+ }
+
+ FT_EXPORT ( FT_Bool )
+ OTL_FeaturesRequest_Find_Feature ( OTL_FeaturesRequest request,
+ OTTableType table_type,
+ OTTag feature_tag,
+ FT_UInt script_index,
+ FT_UInt language_index,
+ FT_UInt *feature_index )
+ {
+ OTL_Font font = (OTL_Font)FTL_FEATURES_REQUEST_FONT( request );
+ return ot_info_find_feature ( font->info,
+ table_type,
+ feature_tag,
+ script_index,
+ language_index,
+ feature_index )
+ ? 1: 0;
+ }
+
+ FT_EXPORT ( OTL_Tag_List )
+ OTL_FeaturesRequest_List_Scripts ( OTL_FeaturesRequest request,
+ OTTableType table_type )
+ {
+ FT_Error error;
+ OTL_Font font = (OTL_Font)FTL_FEATURES_REQUEST_FONT( request );
+ FT_Face face = FTL_FONT_FACE(font);
+ FT_Memory memory = FT_FACE_MEMORY(face);
+ OTL_Tag_List tag_list;
+ if ( FT_NEW(tag_list) )
+ return NULL;
+
+ tag_list->request = request;
+ tag_list->tags = ot_info_list_scripts( font->info, table_type );
+ return tag_list;
+ }
+
+ FT_EXPORT ( OTL_Tag_List )
+ OTL_FeaturesRequest_List_Languages ( OTL_FeaturesRequest request,
+ OTTableType table_type,
+ FT_UInt script_index )
+ {
+ FT_Error error;
+ OTL_Font font = (OTL_Font)FTL_FEATURES_REQUEST_FONT( request );
+ FT_Face face = FTL_FONT_FACE( font );
+ FT_Memory memory = FT_FACE_MEMORY( face );
+ OTL_Tag_List tag_list;
+ if ( FT_NEW(tag_list) )
+ return NULL;
+
+ tag_list->request = request;
+ tag_list->tags = ot_info_list_languages( font->info,
+ table_type,
+ script_index,
+ 0 );
+ return tag_list;
+ }
+
+ FT_EXPORT ( OTL_Tag_List )
+ OTL_FeaturesRequest_List_Features ( OTL_FeaturesRequest request,
+ OTTableType table_type,
+ FT_UInt script_index,
+ FT_UInt language_index )
+ {
+ FT_Error error;
+ OTL_Font font = (OTL_Font)FTL_FEATURES_REQUEST_FONT( request );
+ FT_Face face = FTL_FONT_FACE(font);
+ FT_Memory memory = FT_FACE_MEMORY( face );
+ OTL_Tag_List tag_list;
+ if ( FT_NEW(tag_list) )
+ return NULL;
+
+ tag_list->request = request;
+ tag_list->tags = ot_info_list_features( font->info,
+ table_type,
+ 0,
+ script_index,
+ language_index );
+ return tag_list;
+ }
+
+ FT_EXPORT ( FT_Error )
+ OTL_Tag_List_Done ( OTL_Tag_List taglist )
+ {
+ FTL_FeaturesRequest request = (FTL_FeaturesRequest)taglist->request;
+ FTL_Font font = FTL_FEATURES_REQUEST_FONT( request );
+ FT_Face face = FTL_FONT_FACE(font);
+ FT_Memory memory = FT_FACE_MEMORY( face );
+ FT_FREE ( taglist );
+ return FT_Err_Ok;
+ }
+
+ FT_EXPORT ( FT_Error )
+ OTL_FeaturesRequest_Add_Feature ( OTL_FeaturesRequest request,
+ OTTableType table_type,
+ FT_UInt feature_index,
+ FT_ULong property_bit)
+ {
+ ot_ruleset_add_feature( request->ruleset,
+ table_type,
+ feature_index,
+ property_bit );
+ return FT_Err_Ok;
+ }
+
+/* END */
diff --git a/src/otlayout/otltypes.h b/src/otlayout/otltypes.h
new file mode 100644
index 000000000..6b60f48a4
--- /dev/null
+++ b/src/otlayout/otltypes.h
@@ -0,0 +1,77 @@
+/***************************************************************************/
+/* */
+/* otltypes.h */
+/* */
+/* Implicit data types of OpenType based layout engine */
+/* (For application developers but using implicitly, */
+/* specification only). */
+/* */
+/* Copyright 2003 by */
+/* Masatake YAMATO and Redhat K.K. */
+/* */
+/* This file may only be used, */
+/* modified, and distributed under the terms of the FreeType project */
+/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
+/* this file you indicate that you have read the license and */
+/* understand and accept it fully. */
+/* */
+/***************************************************************************/
+
+/***************************************************************************/
+/* Development of the code in this file is support of */
+/* Information-technology Promotion Agency, Japan. */
+/***************************************************************************/
+
+#ifndef __OTLTYPES_H__
+#define __OTLTYPES_H__
+
+#include <ft2build.h>
+#include FT_INTERNAL_TRUETYPE_TYPES_H
+#include FT_INTERNAL_FTL_TYPES_H
+#include FT_OTLAYOUT_H
+#include "ot-ruleset.h"
+#include "ot-info.h"
+
+FT_BEGIN_HEADER
+
+ typedef TT_Face OT_Face;
+
+ typedef struct OTL_FontRec_
+ {
+ FTL_FontRec root;
+ OTInfo * info;
+ } OTL_FontRec, *OTL_Font;
+
+ typedef struct OTL_FeaturesRequestRec_
+ {
+ FTL_FeaturesRequestRec root;
+ OTRuleset *ruleset;
+ } OTL_FeaturesRequestRec;
+
+ FT_LOCAL ( FT_Error )
+ otl_get_font ( FT_Face face, FTL_Font * font);
+
+ FT_LOCAL_DEF ( FTL_EngineType )
+ otl_get_engine_type ( FT_Face face );
+
+ FT_LOCAL ( FT_Error )
+ otl_new_features_request( FT_Face face, FTL_FeaturesRequest * request);
+
+ FT_LOCAL ( FT_Error )
+ otl_done_features_request( FTL_FeaturesRequest request);
+
+ FT_LOCAL ( FT_Error )
+ otl_copy_features_request( FTL_FeaturesRequest from,
+ FTL_FeaturesRequest to);
+
+ FT_LOCAL ( FT_Error )
+ otl_substitute_glyphs ( FT_Face face,
+ FTL_FeaturesRequest request,
+ FTL_Glyphs_Array in,
+ FTL_Glyphs_Array out );
+FT_END_HEADER
+
+#endif /* Not def: __OTLTYPES_H__ */
+
+
+/* END */
diff --git a/src/otlayout/otobjs.c b/src/otlayout/otobjs.c
new file mode 100644
index 000000000..199cddb3d
--- /dev/null
+++ b/src/otlayout/otobjs.c
@@ -0,0 +1,189 @@
+/***************************************************************************/
+/* */
+/* otobjs.c */
+/* */
+/* OpenType objects manager (body). */
+/* */
+/***************************************************************************/
+
+#include <ft2build.h>
+#include FT_INTERNAL_DEBUG_H
+#include FT_INTERNAL_STREAM_H
+#include FT_TRUETYPE_TAGS_H
+#include FT_LIST_H
+#include FT_ERRORS_H
+#include FT_LAYOUT_H
+#include FT_INTERNAL_OBJECTS_H
+#include FT_SERVICE_LAYOUT_H
+#include FT_OTLAYOUT_H
+#include "otobjs.h"
+#include "ot-types.h"
+#include "ot-info.h"
+#include "oterrors.h"
+#include "otdriver.h"
+#include "otltypes.h"
+
+
+ extern const FT_Driver_ClassRec tt_driver_class;
+
+ /*************************************************************************/
+ /* */
+ /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
+ /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
+ /* messages during execution. */
+ /* */
+#undef FT_COMPONENT
+#define FT_COMPONENT trace_otobjs
+
+ static FT_Error
+ ot_face_init( FT_Stream stream,
+ OT_Face face,
+ FT_Int face_index,
+ FT_Int num_params,
+ FT_Parameter* params );
+
+ static FT_Error
+ ot_font_load ( OT_Face face );
+
+ static void
+ ot_font_done( void * object );
+
+ static FT_Module_Interface
+ ot_module_get_interface ( FT_Module module,
+ const char* ot_interface );
+
+ static const FT_Service_LayoutRec ot_service_layout =
+ {
+ (FTL_Get_Font_Func) otl_get_font,
+ (FTL_Get_EngineType_Func) otl_get_engine_type,
+ (FTL_New_FeaturesRequest_Func) otl_new_features_request,
+ (FTL_Done_FeaturesRequest_Func) otl_done_features_request,
+ (FTL_Copy_FeaturesRequest_Func) otl_copy_features_request,
+ (FTL_Get_LigatureCaret_Count_Func) NULL, /* TODO */
+ (FTL_Get_LigatureCaret_Division_Func) NULL, /* TODO */
+ (FTL_Substitute_Glyphs_Func) otl_substitute_glyphs
+ };
+
+ static const FT_ServiceDescRec ot_services[] =
+ {
+ { FT_SERVICE_ID_LAYOUT, &ot_service_layout },
+ { NULL, NULL }
+ };
+
+ FT_LOCAL_DEF( FT_Error )
+ ot_driver_init( OT_Driver driver )
+ {
+ FT_Error error;
+
+ const void * module_name;
+ FT_Driver ot_driver_root = &driver->root;
+ FT_Driver_Class ot_driver_class = ot_driver_root->clazz;
+
+ module_name = ot_driver_class->root.module_name;
+
+ *ot_driver_class = tt_driver_class;
+ driver->root.clazz->root.module_name = module_name;
+
+ if (( error = ((FT_Module_Class*)ot_driver_class)->module_init( (FT_Module)driver ) ))
+ return error;
+
+ ot_driver_class->init_face = (FT_Face_InitFunc)ot_face_init;
+ ((FT_Module_Class*)ot_driver_class)->get_interface = ot_module_get_interface;
+
+ return OT_Err_Ok;
+ }
+
+ static FT_Error
+ ot_face_init( FT_Stream stream,
+ OT_Face face,
+ FT_Int face_index,
+ FT_Int num_params,
+ FT_Parameter* params )
+ {
+ FT_Error error;
+
+ /* TODO */
+ error = tt_driver_class.init_face ( stream, (FT_Face)face, face_index, num_params, params );
+ if ( error )
+ goto Exit;
+
+ error = ot_font_load ( face );
+ if ( error )
+ goto Exit;
+ Exit:
+ return error;
+ }
+
+ static FT_Error
+ ot_font_load( OT_Face face )
+ {
+ FT_Error error;
+ FT_Memory memory = FT_FACE_MEMORY( face );
+
+ OTL_Font font = NULL;
+ OTL_FeaturesRequest features_request;
+ OTInfo * ot_info;
+
+ if ( face->extra.data )
+ {
+ error = OT_Err_Busy_Extra_Data;
+ goto Exit;
+ }
+
+ ot_info = ot_info_get ( (FT_Face) face );
+ if ( !ot_info )
+ {
+ error = OT_Err_Unknown_File_Format;
+ goto Exit;
+ }
+
+ if ( FT_NEW ( font ) )
+ goto Exit;
+
+ font->info = ot_info;
+ if (( error = FTL_Font_Init ( (FTL_Font)font, (FT_Face)face ) ))
+ goto Failure;
+
+ face->extra.finalizer = ot_font_done;
+ face->extra.data = font;
+ if (( error = FTL_New_FeaturesRequest ( (FT_Face)face,
+ (FTL_FeaturesRequest*)(&features_request) ) ))
+ goto Failure;
+ face->root.face_flags |= FT_FACE_FLAG_GLYPH_SUBSTITUTION; /* ??? */
+ error = OT_Err_Ok;
+ Exit:
+ return error;
+ Failure:
+ if ( font )
+ FT_FREE( font );
+ face->extra.finalizer = NULL;
+ face->extra.data = NULL;
+ return error;
+ }
+
+ static void
+ ot_font_done( void * object )
+ {
+ OTL_Font font = object;
+ FT_Face face = FTL_FONT_FACE( font );
+ FT_Memory memory = FT_FACE_MEMORY( face );
+
+ FTL_Font_Finalize((FTL_Font)font);
+ FT_FREE( object );
+ }
+
+ static FT_Module_Interface
+ ot_module_get_interface( FT_Module module,
+ const char* ot_interface )
+ {
+ FT_Module_Interface ot;
+
+ ot = ft_service_list_lookup( ot_services, ot_interface );
+ if ( ot )
+ return ot;
+
+ /* TODO */
+ if ( tt_driver_class.root.get_interface )
+ return tt_driver_class.root.get_interface( module, ot_interface );
+ return NULL;
+ }
diff --git a/src/otlayout/otobjs.h b/src/otlayout/otobjs.h
new file mode 100644
index 000000000..e52dff0f2
--- /dev/null
+++ b/src/otlayout/otobjs.h
@@ -0,0 +1,52 @@
+/***************************************************************************/
+/* */
+/* otdriver.h */
+/* */
+/* OpenType objects manager (specification). */
+/* */
+/* Copyright 2003 by */
+/* Masatake YAMATO and Redhat K.K. */
+/* */
+/* This file may only be used, */
+/* modified, and distributed under the terms of the FreeType project */
+/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
+/* this file you indicate that you have read the license and */
+/* understand and accept it fully. */
+/* */
+/***************************************************************************/
+
+/***************************************************************************/
+/* Development of the code in this file is support of */
+/* Information-technology Promotion Agency, Japan. */
+/***************************************************************************/
+
+#ifndef __OTOBJS_H__
+#define __OTOBJS_H__
+
+#include <ft2build.h>
+#include FT_INTERNAL_OBJECTS_H
+#include FT_INTERNAL_TRUETYPE_TYPES_H
+
+FT_BEGIN_HEADER
+
+ typedef struct OT_DriverRec_
+ {
+ FT_DriverRec root;
+ TT_ExecContext context;
+ TT_GlyphZoneRec zone;
+ void* extension_component;
+ } OT_DriverRec, *OT_Driver;
+
+ /*************************************************************************/
+ /* */
+ /* Driver functions */
+ /* */
+ FT_LOCAL( FT_Error )
+ ot_driver_init( OT_Driver driver );
+
+FT_END_HEADER
+
+#endif /* __OTOBJS_H__ */
+
+
+/* END */
diff --git a/src/otlayout/rules.mk b/src/otlayout/rules.mk
new file mode 100644
index 000000000..ef223f85c
--- /dev/null
+++ b/src/otlayout/rules.mk
@@ -0,0 +1,98 @@
+#
+# FreeType 2 OpneType driver configuration rules
+#
+
+# Copyright 2004 by RedHat K.K.
+# This file is derived from cff/rules.mk.
+
+# ----------------------------------------------------------------------
+#
+# FreeType 2 OpenType/CFF driver configuration rules
+#
+
+# Copyright 1996-2000, 2001, 2003 by
+# David Turner, Robert Wilhelm, and Werner Lemberg.
+#
+# This file is part of the FreeType project, and may only be used, modified,
+# and distributed under the terms of the FreeType project license,
+# LICENSE.TXT. By continuing to use, modify, or distribute this file you
+# indicate that you have read the license and understand and accept it
+# fully.
+# ----------------------------------------------------------------------
+
+# Development of the code in rules.mk is support of
+# Information-technology Promotion Agency, Japan.
+
+# OpenType driver directory
+#
+OT_DIR := $(SRC_DIR)/otlayout
+
+
+OT_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(OT_DIR))
+
+
+# OT driver sources (i.e., C files)
+#
+OT_DRV_SRC := $(OT_DIR)/otobjs.c \
+ $(OT_DIR)/otlayout.c \
+ $(OT_DIR)/otdriver.c \
+ $(OT_DIR)/ftxgdef.c \
+ $(OT_DIR)/ftxgpos.c \
+ $(OT_DIR)/ftxopen.c \
+ $(OT_DIR)/ftxgsub.c \
+ $(OT_DIR)/ot-info.c \
+ $(OT_DIR)/ot-ruleset.c \
+ $(OT_DIR)/ot-array.c \
+ $(OT_DIR)/ot-unicode.c
+
+
+# OT driver headers
+#
+OT_DRV_H := $(OT_DIR)/otdriver.h \
+ $(OT_DIR)/fterrcompat.h \
+ $(OT_DIR)/ftxgdef.h \
+ $(OT_DIR)/ftxgpos.h \
+ $(OT_DIR)/ftxgsub.h \
+ $(OT_DIR)/ftxopen.h \
+ $(OT_DIR)/ftxopenf.h \
+ $(OT_DIR)/ot-info.h \
+ $(OT_DIR)/ot-ruleset.h \
+ $(OT_DIR)/ot-types.h \
+ $(OT_DIR)/ot-array.h \
+ $(OT_DIR)/otltypes.h \
+ $(OT_DIR)/oterrors.h \
+ $(OT_DIR)/otobjs.h \
+ $(OT_DIR)/ot-unicode.h
+
+# OT driver object(s)
+#
+# OT_DRV_OBJ_M is used during `multi' builds
+# OT_DRV_OBJ_S is used during `single' builds
+#
+OT_DRV_OBJ_M := $(OT_DRV_SRC:$(OT_DIR)/%.c=$(OBJ_DIR)/%.$O)
+OT_DRV_OBJ_S := $(OBJ_DIR)/ot.$O
+
+# OT driver source file for single build
+#
+OT_DRV_SRC_S := $(OT_DIR)/ot.c
+
+
+# OT driver - single object
+#
+$(OT_DRV_OBJ_S): $(OT_DRV_SRC_S) $(OT_DRV_SRC) $(FREETYPE_H) $(OT_DRV_H)
+ $(OT_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(OT_DRV_SRC_S))
+
+
+# OT driver - multiple objects
+#
+$(OBJ_DIR)/%.$O: $(OT_DIR)/%.c $(FREETYPE_H) $(OT_DRV_H)
+ $(OT_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<)
+
+
+# update main driver object lists
+#
+DRV_OBJS_S += $(OT_DRV_OBJ_S)
+DRV_OBJS_M += $(OT_DRV_OBJ_M)
+
+
+# EOF