diff options
Diffstat (limited to 'src/gxlayout/gxdump.c')
-rw-r--r-- | src/gxlayout/gxdump.c | 2818 |
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 */ |