+/* otfdump.c -- Dump OpenType Layout Tables.
+
+Copyright (C) 2003, 2004
+ National Institute of Advanced Industrial Science and Technology (AIST)
+ Registration Number H15PRO167
+
+This file is part of libotf.
+
+Libotf is free software; you can redistribute it and/or modify it
+under the terms of the GNU Lesser General Public License as published
+by the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+Libotf is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library, in a file named COPYING; if not,
+write to the Free Software Foundation, Inc., 59 Temple Place, Suite
+330, Boston, MA 02111-1307, USA. */
+
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
+#include <libgen.h>
#include <otf.h>
printf (")");
}
-static void
+static int *
dump_coverage (int indent, char *title, OTF_Coverage *coverage)
{
int i;
+ int *char_list;
IPRINT ("(%sCoverage (CoverageFormat %d)",
(title ? title : ""), coverage->CoverageFormat);
{
dump_glyph_ids (indent, "GlyphArray", coverage->table.GlyphArray,
coverage->Count);
+ char_list = malloc (sizeof (int) * (coverage->Count + 1));
+ for (i = 0; i < coverage->Count; i++)
+ char_list[i] = coverage->table.GlyphArray[i];
+ char_list[i] = -1;
}
else
{
+ int n, c;
+
IPRINT ("(RangeCount %d)", coverage->Count);
indent++;
- for (i = 0; i < coverage->Count; i++)
+ for (i = n = 0; i < coverage->Count; i++)
{
IPRINT ("(Range (%d) (Start #x%04X) (End #x%04X)", i,
coverage->table.RangeRecord[i].Start,
IPRINT ("(StartCoverageIndex %d))",
coverage->table.RangeRecord[i].StartCoverageIndex);
indent--;
+ n += (coverage->table.RangeRecord[i].End
+ - coverage->table.RangeRecord[i].Start + 1);
}
+ char_list = malloc (sizeof (int) * (n + 1));
+ for (i = n = 0; i < coverage->Count; i++)
+ for (c = coverage->table.RangeRecord[i].Start;
+ c <= coverage->table.RangeRecord[i].End;
+ c++)
+ char_list[n++] = c;
+ char_list[n] = -1;
}
printf (")");
+ return char_list;
}
static void
IPRINT ("(%s %d)", title, num);
for (i = 0; i < num; i++)
- dump_coverage (indent, NULL, coverage + i);
+ free (dump_coverage (indent, NULL, coverage + i));
}
static void
-dump_ligature_set_list (int indent, OTF_LigatureSet *ligset, unsigned num)
+dump_ligature_set_list (int indent, int *char_list,
+ OTF_LigatureSet *ligset, unsigned num)
{
- int i, j;
+ int i, j, k;
IPRINT ("(LigSetCount %d)", num);
for (i = 0; i < num; i++)
ligset[i].Ligature[j].LigGlyph);
dump_glyph_ids (indent, "Component", ligset[i].Ligature[j].Component,
ligset[i].Ligature[j].CompCount - 1);
+ IPRINT ("(i.e. #x%04X", char_list[i]);
+ for (k = 0; k < ligset[i].Ligature[j].CompCount - 1; k++)
+ printf (" #x%04X", ligset[i].Ligature[j].Component[k]);
+ printf (" = #x%04X)", ligset[i].Ligature[j].LigGlyph);
printf (")");
indent--;
}
}
static void
+dump_pair_set_list (int indent, unsigned count, OTF_PairSet *set)
+{
+ int i, j;
+
+ for (i = 0; i < count; i++)
+ {
+ IPRINT ("(PairSet (%d)", i);
+ indent++;
+ for (j = 0; j < set[i].PairValueCount; j++)
+ {
+ IPRINT ("(PairValueRecord (%d)", j);
+ indent++;
+ IPRINT ("(SecondGlyph #x%04X)",
+ set[i].PairValueRecord[j].SecondGlyph);
+ dump_value_record (indent, "Value1",
+ &set[i].PairValueRecord[j].Value1);
+ dump_value_record (indent, "Value2",
+ &set[i].PairValueRecord[j].Value2);
+ printf (")");
+ indent--;
+ }
+ printf (")");
+ indent--;
+ }
+}
+
+static void
dump_class1_record_list (int indent,
unsigned Class1Count, unsigned Class2Count,
OTF_Class1Record *rec)
}
static void
+dump_entry_exit_list (int indent, unsigned count, OTF_EntryExitRecord *rec)
+{
+ int i;
+
+ for (i = 0; i < count; i++)
+ {
+ IPRINT ("(EntryExitRecord (%d)", i);
+ indent++;
+ dump_anchor (indent, &rec[i].EntryAnchor);
+ dump_anchor (indent, &rec[i].EntryAnchor);
+ printf (")");
+ indent--;
+ }
+}
+
+static void
dump_mark_array (int indent, OTF_MarkArray *array)
{
int i;
case 1:
if (subtable->Format == 1)
{
- dump_coverage (indent, NULL, &subtable->Coverage);
+ free (dump_coverage (indent, NULL, &subtable->Coverage));
IPRINT ("(DeltaGlyhpID #x%04X)",
subtable->u.single1.DeltaGlyphID);
}
else if (subtable->Format == 2)
{
- dump_coverage (indent, NULL, &subtable->Coverage);
+ free (dump_coverage (indent, NULL, &subtable->Coverage));
dump_glyph_ids (indent, "Substitute", subtable->u.single2.Substitute,
subtable->u.single2.GlyphCount);
}
case 2:
if (subtable->Format == 1)
{
- dump_coverage (indent, NULL, &subtable->Coverage);
+ free (dump_coverage (indent, NULL, &subtable->Coverage));
dump_sequence_list (indent,
subtable->u.multiple1.Sequence,
subtable->u.multiple1.SequenceCount);
case 3:
if (subtable->Format == 1)
{
- dump_coverage (indent, NULL, &subtable->Coverage);
+ free (dump_coverage (indent, NULL, &subtable->Coverage));
dump_alternate_set_list (indent, subtable->u.alternate1.AlternateSet,
subtable->u.alternate1.AlternateSetCount);
}
case 4:
if (subtable->Format == 1)
{
- dump_coverage (indent, NULL, &subtable->Coverage);
- dump_ligature_set_list (indent,
+ int *char_list = dump_coverage (indent, NULL, &subtable->Coverage);
+ dump_ligature_set_list (indent, char_list,
subtable->u.ligature1.LigatureSet,
subtable->u.ligature1.LigSetCount);
+ free (char_list);
}
else
printf (" invalid");
case 5:
if (subtable->Format == 1)
{
- dump_coverage (indent, NULL, &subtable->Coverage);
+ free (dump_coverage (indent, NULL, &subtable->Coverage));
dump_rule_set_list (indent, subtable->u.context1.RuleSet,
subtable->u.context1.RuleSetCount);
}
else if (subtable->Format == 2)
{
- dump_coverage (indent, NULL, &subtable->Coverage);
+ free (dump_coverage (indent, NULL, &subtable->Coverage));
dump_class_def (indent, NULL, &subtable->u.context2.ClassDef);
dump_class_set_list (indent, subtable->u.context2.ClassSet,
subtable->u.context2.ClassSetCnt);
case 6:
if (subtable->Format == 1)
{
- dump_coverage (indent, NULL, &subtable->Coverage);
+ free (dump_coverage (indent, NULL, &subtable->Coverage));
dump_chain_rule_set_list
(indent,
subtable->u.chain_context1.ChainRuleSet,
}
else if (subtable->Format == 2)
{
- dump_coverage (indent, NULL, &subtable->Coverage);
+ free (dump_coverage (indent, NULL, &subtable->Coverage));
dump_class_def (indent, "BacktrackClassDef",
&subtable->u.chain_context2.BacktrackClassDef);
dump_class_def (indent, "InputClassDef",
break;
case 7:
+ IPRINT ("(ExtensionLookupType %d)",
+ subtable->u.extension1.ExtensionLookupType);
+ IPRINT ("(ExtensionOffset %d)",
+ subtable->u.extension1.ExtensionOffset);
+ dump_lookup_subtable_gsub (indent, index,
+ subtable->u.extension1.ExtensionLookupType,
+ subtable->u.extension1.ExtensionSubtable);
+ break;
+
case 8:
- printf (" not-yet-substcount");
+ printf (" not-yet-supported");
break;
default:
case 1:
if (subtable->Format == 1)
{
- dump_coverage (indent, NULL, &subtable->Coverage);
+ free (dump_coverage (indent, NULL, &subtable->Coverage));
IPRINT ("(ValueFormat #x%04X)",
subtable->u.single1.ValueFormat);
dump_value_record (indent, "Value", &subtable->u.single1.Value);
{
int i;
- dump_coverage (indent, NULL, &subtable->Coverage);
+ free (dump_coverage (indent, NULL, &subtable->Coverage));
IPRINT ("(ValueFormat #x%04X)",
subtable->u.single2.ValueFormat);
IPRINT ("(ValueCount %d)",
case 2:
if (subtable->Format == 1)
{
- printf (" not-yet-supported");
+ free (dump_coverage (indent, NULL, &subtable->Coverage));
+ IPRINT ("(ValueFormat1 #x%04X)",
+ subtable->u.pair1.ValueFormat1);
+ IPRINT ("(ValueFormat2 #x%04X)",
+ subtable->u.pair1.ValueFormat2);
+ dump_pair_set_list (indent, subtable->u.pair1.PairSetCount,
+ subtable->u.pair1.PairSet);
}
else if (subtable->Format == 2)
{
- dump_coverage (indent, NULL, &subtable->Coverage);
+ free (dump_coverage (indent, NULL, &subtable->Coverage));
IPRINT ("(ValueFormat1 #x%04X)",
subtable->u.pair2.ValueFormat1);
IPRINT ("(ValueFormat2 #x%04X)",
case 3:
if (subtable->Format == 1)
{
- printf (" not-yet-supported");
+ free (dump_coverage (indent, NULL, &subtable->Coverage));
+ dump_entry_exit_list (indent, subtable->u.cursive1.EntryExitCount,
+ subtable->u.cursive1.EntryExitRecord);
}
else
printf (" invalid");
case 4:
if (subtable->Format == 1)
{
- dump_coverage (indent, "Mark", &subtable->Coverage);
- dump_coverage (indent, "Base",
- &subtable->u.mark_base1.BaseCoverage);
+ free (dump_coverage (indent, "Mark", &subtable->Coverage));
+ free (dump_coverage (indent, "Base",
+ &subtable->u.mark_base1.BaseCoverage));
IPRINT ("(ClassCount %d)",
subtable->u.mark_base1.ClassCount);
dump_mark_array (indent, &subtable->u.mark_base1.MarkArray);
case 6:
if (subtable->Format == 1)
{
- dump_coverage (indent, "Mark1", &subtable->Coverage);
- dump_coverage (indent, "Mark2",
- &subtable->u.mark_mark1.Mark2Coverage);
+ free (dump_coverage (indent, "Mark1", &subtable->Coverage));
+ free (dump_coverage (indent, "Mark2",
+ &subtable->u.mark_mark1.Mark2Coverage));
IPRINT ("(ClassCount %d)",
subtable->u.mark_mark1.ClassCount);
dump_mark_array (indent, &subtable->u.mark_mark1.Mark1Array);
case 7:
if (subtable->Format == 1)
{
- dump_coverage (indent, NULL, &subtable->Coverage);
+ free (dump_coverage (indent, NULL, &subtable->Coverage));
dump_rule_set_list (indent, subtable->u.context1.RuleSet,
subtable->u.context1.RuleSetCount);
}
else if (subtable->Format == 2)
{
- dump_coverage (indent, NULL, &subtable->Coverage);
+ free (dump_coverage (indent, NULL, &subtable->Coverage));
dump_class_def (indent, NULL, &subtable->u.context2.ClassDef);
dump_class_set_list (indent, subtable->u.context2.ClassSet,
subtable->u.context2.ClassSetCnt);
case 8:
if (subtable->Format == 1)
{
- dump_coverage (indent, NULL, &subtable->Coverage);
+ free (dump_coverage (indent, NULL, &subtable->Coverage));
dump_chain_rule_set_list
(indent,
subtable->u.chain_context1.ChainRuleSet,
}
else if (subtable->Format == 2)
{
- dump_coverage (indent, NULL, &subtable->Coverage);
+ free (dump_coverage (indent, NULL, &subtable->Coverage));
dump_class_def (indent, "BacktrackClassDef",
&subtable->u.chain_context2.BacktrackClassDef);
dump_class_def (indent, "InputClassDef",
else
printf (" invalid");
break;
+
+ case 9:
+ if (subtable->Format == 1)
+ {
+ IPRINT ("(ExtensionLookupType %d)",
+ subtable->u.extension1.ExtensionLookupType);
+ IPRINT ("(ExtensionOffset %d)",
+ subtable->u.extension1.ExtensionOffset);
+ dump_lookup_subtable_gpos
+ (indent, index,
+ subtable->u.extension1.ExtensionLookupType,
+ subtable->u.extension1.ExtensionSubtable);
+ }
+ else
+ printf (" invalid");
}
printf (")");
}
IPRINT ("(LigCaretList");
indent++;
- dump_coverage (indent, NULL, &list->Coverage);
+ free (dump_coverage (indent, NULL, &list->Coverage));
IPRINT ("(LigGlyphCount %d)", list->LigGlyphCount);
for (i = 0; i < list->LigGlyphCount; i++)
{
printf (")");
}
break;
+
+ case 6:
+ {
+ OTF_EncodingSubtable6 *sub6
+ = cmap->EncodingRecord[i].subtable.f.f6;
+ int j;
+
+ IPRINT ("(firstCode %d) (entryCount %d)",
+ sub6->firstCode, sub6->entryCount);
+ IPRINT ("(glyphIdArray");
+ for (j = 0; j < sub6->entryCount; j++)
+ {
+ if ((j % 16) == 0)
+ IPRINT (" ");
+ printf (" %3d", sub6->glyphIdArray[j]);
+ }
+ printf (")");
+ }
+ break;
}
indent -= 2;
{
OTF *otf;
- if (argc != 2)
+ if (argc != 2 || !strcmp (argv[1], "-h") || !strcmp (argv[1], "--help"))
{
- fprintf (stderr, "Usage, dtfdump OTF-FILE");
- exit (1);
+ fprintf (stderr, "Usage: %s OTF-FILE\n", basename (argv[0]));
+ exit (argc != 2);
}
otf = OTF_open (argv[1]);