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 + + 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 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 + ... + #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 + or 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 + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_LAYOUT_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* FreeType Layout API. */ + /* */ +#define FT_LAYOUT_H + /* */ #define FT_TRIGONOMETRY_H @@ -550,6 +561,9 @@ #define FT_INCREMENTAL_H +#define FT_GXLAYOUT_H +#define FT_OTLAYOUT_H + #define FT_TRUETYPE_UNPATENTED_H /* now include internal headers definitions from */ 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 #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 +#include FT_FREETYPE_H + +FT_BEGIN_HEADER + + /*************************************************************************/ + /* */ + /*
*/ + /* text_layout */ + /* */ + /* */ + /* 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, ¤t_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