summaryrefslogtreecommitdiff
path: root/src/gxlayout/gxdump.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gxlayout/gxdump.c')
-rw-r--r--src/gxlayout/gxdump.c2818
1 files changed, 2818 insertions, 0 deletions
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 */