blob: d4c5b606a130449e3515ba1962620059a7bb4a9d [file] [log] [blame]
/***************************************************************************/
/* */
/* 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);
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);
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);
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);
}
/****************************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 */