318 lines
7.7 KiB
C
318 lines
7.7 KiB
C
/* Pango
|
|
* disasm.c: Dump OpenType layout tables
|
|
*
|
|
* Copyright (C) 2000 Red Hat Software
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Library General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Library General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Library General Public
|
|
* License along with this library; if not, write to the
|
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
* Boston, MA 02111-1307, USA.
|
|
*/
|
|
|
|
#include <stdarg.h>
|
|
|
|
#include "disasm.h"
|
|
|
|
#define DUMP(args...) dump (stream, indent, args)
|
|
#define DUMP_FINT(strct,fld) dump (stream, indent, "<" #fld ">%d</" #fld ">\n", (strct)->fld)
|
|
#define DUMP_FUINT(strct,fld) dump (stream, indent, "<" #fld ">%u</" #fld ">\n", (strct)->fld)
|
|
#define DUMP_FGLYPH(strct,fld) dump (stream, indent, "<" #fld ">%#4x</" #fld ">\n", (strct)->fld)
|
|
|
|
#define DEF_DUMP(type) static void Dump_ ## type (TTO_ ## type *type, FILE *stream, int indent, FT_Bool is_gsub)
|
|
#define RECURSE(name, type, val) do { DUMP ("<" #name ">\n"); Dump_ ## type (val, stream, indent + 1, is_gsub); DUMP ("</" #name ">\n"); } while (0)
|
|
|
|
static void
|
|
do_indent (FILE *stream, int indent)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < indent * 3; i++)
|
|
fputc (' ', stream);
|
|
}
|
|
|
|
static void
|
|
dump (FILE *stream, int indent, const char *format, ...)
|
|
{
|
|
va_list list;
|
|
|
|
do_indent (stream, indent);
|
|
|
|
va_start (list, format);
|
|
vfprintf (stream, format, list);
|
|
va_end (list);
|
|
}
|
|
|
|
static void
|
|
Print_Tag (FT_ULong tag, FILE *stream)
|
|
{
|
|
fprintf (stream, "%c%c%c%c",
|
|
(unsigned char)(tag >> 24),
|
|
(unsigned char)((tag & 0xff0000) >> 16),
|
|
(unsigned char)((tag & 0xff00) >> 8),
|
|
(unsigned char)(tag & 0xff));
|
|
}
|
|
|
|
DEF_DUMP (LangSys)
|
|
{
|
|
int i;
|
|
|
|
DUMP_FUINT (LangSys, LookupOrderOffset);
|
|
DUMP_FUINT (LangSys, ReqFeatureIndex);
|
|
DUMP_FUINT (LangSys, FeatureCount);
|
|
|
|
for (i=0; i < LangSys->FeatureCount; i++)
|
|
DUMP("<FeatureIndex>%d</FeatureIndex>\n", LangSys->FeatureIndex[i]);
|
|
}
|
|
|
|
DEF_DUMP (Script)
|
|
{
|
|
int i;
|
|
|
|
RECURSE (DefaultLangSys, LangSys, &Script->DefaultLangSys);
|
|
|
|
DUMP_FUINT (Script, LangSysCount);
|
|
|
|
for (i=0; i < Script->LangSysCount; i++)
|
|
{
|
|
do_indent (stream, indent);
|
|
fprintf (stream, "<LangSysTag>");
|
|
Print_Tag (Script->LangSysRecord[i].LangSysTag, stream);
|
|
fprintf (stream, "</LangSysTag>\n");
|
|
RECURSE (LangSys, LangSys, &Script->LangSysRecord[i].LangSys);
|
|
}
|
|
}
|
|
|
|
DEF_DUMP (ScriptList)
|
|
{
|
|
int i;
|
|
|
|
DUMP_FUINT (ScriptList, ScriptCount);
|
|
|
|
for (i=0; i < ScriptList->ScriptCount; i++)
|
|
{
|
|
do_indent (stream, indent);
|
|
fprintf (stream, "<ScriptTag>");
|
|
Print_Tag (ScriptList->ScriptRecord[i].ScriptTag, stream);
|
|
fprintf (stream, "</ScriptTag>\n");
|
|
RECURSE (Script, Script, &ScriptList->ScriptRecord[i].Script);
|
|
}
|
|
}
|
|
|
|
DEF_DUMP (Feature)
|
|
{
|
|
int i;
|
|
|
|
DUMP_FUINT (Feature, FeatureParams);
|
|
DUMP_FUINT (Feature, LookupListCount);
|
|
|
|
for (i=0; i < Feature->LookupListCount; i++)
|
|
DUMP("<LookupIndex>%d</LookupIndex>\n", Feature->LookupListIndex[i]);
|
|
}
|
|
|
|
DEF_DUMP (FeatureList)
|
|
{
|
|
int i;
|
|
|
|
DUMP_FUINT (FeatureList, FeatureCount);
|
|
|
|
for (i=0; i < FeatureList->FeatureCount; i++)
|
|
{
|
|
do_indent (stream, indent);
|
|
fprintf (stream, "<FeatureTag>");
|
|
Print_Tag (FeatureList->FeatureRecord[i].FeatureTag, stream);
|
|
fprintf (stream, "</FeatureTag>\n");
|
|
RECURSE (Feature, Feature, &FeatureList->FeatureRecord[i].Feature);
|
|
}
|
|
}
|
|
|
|
DEF_DUMP (Coverage)
|
|
{
|
|
DUMP_FUINT (Coverage, CoverageFormat);
|
|
|
|
if (Coverage->CoverageFormat == 1)
|
|
{
|
|
int i;
|
|
DUMP_FUINT (&Coverage->cf.cf1, GlyphCount);
|
|
|
|
for (i = 0; i < Coverage->cf.cf1.GlyphCount; i++)
|
|
DUMP("<Glyph>%#4x</Glyph> <!-- %d -->\n", Coverage->cf.cf1.GlyphArray[i], i);
|
|
}
|
|
else
|
|
{
|
|
}
|
|
}
|
|
|
|
static void
|
|
Dump_GSUB_Lookup_Single (TTO_SubTable *subtable, FILE *stream, int indent, FT_Bool is_gsub)
|
|
{
|
|
TTO_SingleSubst *SingleSubst = &subtable->st.gsub.single;
|
|
|
|
DUMP_FUINT (SingleSubst, SubstFormat);
|
|
RECURSE (Coverage, Coverage, &SingleSubst->Coverage);
|
|
|
|
if (SingleSubst->SubstFormat == 1)
|
|
{
|
|
DUMP_FINT (&SingleSubst->ssf.ssf1, DeltaGlyphID);
|
|
}
|
|
else
|
|
{
|
|
int i;
|
|
|
|
DUMP_FINT (&SingleSubst->ssf.ssf2, GlyphCount);
|
|
for (i=0; i < SingleSubst->ssf.ssf2.GlyphCount; i++)
|
|
DUMP("<Substitute>%#4x</Substitute> <!-- %d -->\n", SingleSubst->ssf.ssf2.Substitute[i], i);
|
|
}
|
|
}
|
|
|
|
DEF_DUMP (Ligature)
|
|
{
|
|
int i;
|
|
|
|
DUMP_FGLYPH (Ligature, LigGlyph);
|
|
DUMP_FUINT (Ligature, ComponentCount);
|
|
|
|
for (i=0; i < Ligature->ComponentCount - 1; i++)
|
|
DUMP("<Component>%#4x</Component>\n", Ligature->Component[i]);
|
|
}
|
|
|
|
DEF_DUMP (LigatureSet)
|
|
{
|
|
int i;
|
|
|
|
DUMP_FUINT (LigatureSet, LigatureCount);
|
|
|
|
for (i=0; i < LigatureSet->LigatureCount; i++)
|
|
RECURSE (Ligature, Ligature, &LigatureSet->Ligature[i]);
|
|
}
|
|
|
|
static void
|
|
Dump_GSUB_Lookup_Ligature (TTO_SubTable *subtable, FILE *stream, int indent, FT_Bool is_gsub)
|
|
{
|
|
int i;
|
|
TTO_LigatureSubst *LigatureSubst = &subtable->st.gsub.ligature;
|
|
|
|
DUMP_FUINT (LigatureSubst, SubstFormat);
|
|
RECURSE (Coverage, Coverage, &LigatureSubst->Coverage);
|
|
|
|
DUMP_FUINT (LigatureSubst, LigatureSetCount);
|
|
|
|
for (i=0; i < LigatureSubst->LigatureSetCount; i++)
|
|
RECURSE (LigatureSet, LigatureSet, &LigatureSubst->LigatureSet[i]);
|
|
}
|
|
|
|
DEF_DUMP (Lookup)
|
|
{
|
|
int i;
|
|
const char *lookup_name = NULL;
|
|
void (*lookup_func) (TTO_SubTable *subtable, FILE *stream, int indent, FT_Bool is_gsub) = NULL;
|
|
|
|
if (is_gsub)
|
|
{
|
|
switch (Lookup->LookupType)
|
|
{
|
|
case GSUB_LOOKUP_SINGLE:
|
|
lookup_name = "SINGLE";
|
|
lookup_func = Dump_GSUB_Lookup_Single;
|
|
break;
|
|
case GSUB_LOOKUP_MULTIPLE:
|
|
lookup_name = "MULTIPLE";
|
|
break;
|
|
case GSUB_LOOKUP_ALTERNATE:
|
|
lookup_name = "ALTERNATE";
|
|
break;
|
|
case GSUB_LOOKUP_LIGATURE:
|
|
lookup_name = "LIGATURE";
|
|
lookup_func = Dump_GSUB_Lookup_Ligature;
|
|
break;
|
|
case GSUB_LOOKUP_CONTEXT:
|
|
lookup_name = "CONTEXT";
|
|
break;
|
|
case GSUB_LOOKUP_CHAIN:
|
|
lookup_name = "CHAIN";
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
switch (Lookup->LookupType)
|
|
{
|
|
case GPOS_LOOKUP_SINGLE:
|
|
lookup_name = "SINGLE";
|
|
break;
|
|
case GPOS_LOOKUP_PAIR:
|
|
lookup_name = "PAIR";
|
|
break;
|
|
case GPOS_LOOKUP_CURSIVE:
|
|
lookup_name = "CURSIVE";
|
|
break;
|
|
case GPOS_LOOKUP_MARKBASE:
|
|
lookup_name = "MARKBASE";
|
|
break;
|
|
case GPOS_LOOKUP_MARKLIG:
|
|
lookup_name = "MARKLIG";
|
|
break;
|
|
case GPOS_LOOKUP_MARKMARK:
|
|
lookup_name = "MARKMARK";
|
|
break;
|
|
case GPOS_LOOKUP_CONTEXT:
|
|
lookup_name = "CONTEXT";
|
|
break;
|
|
case GPOS_LOOKUP_CHAIN:
|
|
lookup_name = "CHAIN";
|
|
break;
|
|
}
|
|
}
|
|
|
|
DUMP("<LookupType>%s</LookupType>\n", lookup_name);
|
|
|
|
for (i=0; i < Lookup->SubTableCount; i++)
|
|
{
|
|
DUMP ("<Subtable>\n");
|
|
if (lookup_func)
|
|
(*lookup_func) (&Lookup->SubTable[i], stream, indent + 1, is_gsub);
|
|
DUMP ("</Subtable>\n");
|
|
}
|
|
}
|
|
|
|
DEF_DUMP (LookupList)
|
|
{
|
|
int i;
|
|
|
|
DUMP_FUINT (LookupList, LookupCount);
|
|
|
|
for (i=0; i < LookupList->LookupCount; i++)
|
|
RECURSE (Lookup, Lookup, &LookupList->Lookup[i]);
|
|
}
|
|
|
|
void
|
|
TT_Dump_GSUB_Table (TTO_GSUB gsub, FILE *stream)
|
|
{
|
|
int indent = 0;
|
|
FT_Bool is_gsub = 1;
|
|
|
|
RECURSE (ScriptList, ScriptList, &gsub->ScriptList);
|
|
RECURSE (FeatureList, FeatureList, &gsub->FeatureList);
|
|
RECURSE (LookupList, LookupList, &gsub->LookupList);
|
|
}
|
|
|
|
void
|
|
TT_Dump_GPOS_Table (TTO_GPOS gpos, FILE *stream)
|
|
{
|
|
int indent = 0;
|
|
FT_Bool is_gsub = 0;
|
|
|
|
RECURSE (ScriptList, ScriptList, &gpos->ScriptList);
|
|
RECURSE (FeatureList, FeatureList, &gpos->FeatureList);
|
|
RECURSE (LookupList, LookupList, &gpos->LookupList);
|
|
}
|