1 /* otfdump.c -- Dump OpenType Layout Tables.
3 Copyright (C) 2003, 2004
4 National Institute of Advanced Industrial Science and Technology (AIST)
5 Registration Number H15PRO167
7 This file is part of libotf.
9 Libotf is free software; you can redistribute it and/or modify it
10 under the terms of the GNU Lesser General Public License as published
11 by the Free Software Foundation; either version 2.1 of the License, or
12 (at your option) any later version.
14 Libotf is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17 License for more details.
19 You should have received a copy of the GNU Lesser General Public
20 License along with this library, in a file named COPYING; if not,
21 write to the Free Software Foundation, Inc., 59 Temple Place, Suite
22 330, Boston, MA 02111-1307, USA. */
28 #include <sys/types.h>
35 char *indent_spaces[] =
36 { "", " ", " ", " ", " ", " ", " ",
40 #define IPRINT printf("\n%s", indent_spaces[indent]), printf
43 dump_tag (OTF_Tag tag)
47 putchar ((tag >> 16) & 0xFF);
48 putchar ((tag >> 8) & 0xFF);
50 printf ("\" #x%04X)", tag);
56 dump_offset_table (int indent, OTF_OffsetTable *table)
58 IPRINT ("(OffsetTable");
60 IPRINT ("(sfnt-version %d.%d)",
61 table->sfnt_version.high, table->sfnt_version.low);
62 IPRINT ("(numTables %d)", table->numTables);
63 IPRINT ("(searchRange %d)", table->searchRange);
64 IPRINT ("(enterSelector %d)", table->enterSelector);
65 IPRINT ("(rangeShift %d))", table->rangeShift);
69 dump_table_directory (int indent, OTF_TableDirectory *table, int idx)
71 IPRINT ("(Table %d ", idx);
72 dump_tag (table->tag);
74 IPRINT ("(checkSum %08X) (offset #x%08X) (length: #x%08X))",
75 table->checkSum, table->offset, table->length);
82 dump_head_table (int indent, OTF_head *head)
86 IPRINT ("(TableVersionNumber %d.%d)",
87 head->TableVersionNumber.high, head->TableVersionNumber.low);
88 IPRINT ("(fontRevision %d.%d)",
89 head->fontRevision.high, head->fontRevision.low);
90 IPRINT ("(checkSumAdjustment #x%04X)", head->checkSumAdjustment);
91 IPRINT ("(magicNumber #x%04X)", head->magicNumber);
92 IPRINT ("(flags #x%04X)", head->flags);
93 IPRINT ("(unitsPerEm %d)", head->unitsPerEm);
101 dump_glyph_ids (int indent, char *title, OTF_GlyphID *ids, unsigned count)
103 IPRINT ("(%s (count %d)", title, count);
106 printf (" #x%04X", *ids);
113 dump_coverage (int indent, char *title, OTF_Coverage *coverage)
118 IPRINT ("(%sCoverage (CoverageFormat %d)",
119 (title ? title : ""), coverage->CoverageFormat);
121 if (coverage->CoverageFormat == 1)
123 dump_glyph_ids (indent, "GlyphArray", coverage->table.GlyphArray,
125 char_list = malloc (sizeof (int) * (coverage->Count + 1));
126 for (i = 0; i < coverage->Count; i++)
127 char_list[i] = coverage->table.GlyphArray[i];
134 IPRINT ("(RangeCount %d)", coverage->Count);
136 for (i = n = 0; i < coverage->Count; i++)
138 IPRINT ("(Range (%d) (Start #x%04X) (End #x%04X)", i,
139 coverage->table.RangeRecord[i].Start,
140 coverage->table.RangeRecord[i].End);
142 IPRINT ("(StartCoverageIndex %d))",
143 coverage->table.RangeRecord[i].StartCoverageIndex);
145 n += (coverage->table.RangeRecord[i].End
146 - coverage->table.RangeRecord[i].Start + 1);
148 char_list = malloc (sizeof (int) * (n + 1));
149 for (i = n = 0; i < coverage->Count; i++)
150 for (c = coverage->table.RangeRecord[i].Start;
151 c <= coverage->table.RangeRecord[i].End;
161 dump_coverage_list (int indent, char *title,
162 OTF_Coverage *coverage, unsigned num)
166 IPRINT ("(%s %d)", title, num);
167 for (i = 0; i < num; i++)
168 free (dump_coverage (indent, NULL, coverage + i));
173 dump_language_system (int indent, int index, OTF_Tag tag, OTF_Offset offset,
174 OTF_LangSys *langsys)
178 IPRINT ("(LangSys ");
180 printf ("(%d) ", index);
184 printf ("DefaultLangSys");
185 printf (" (Offset #x%04X)", offset);
187 IPRINT ("(LookupOrder #x%04X)", langsys->LookupOrder);
188 IPRINT ("(ReqFeatureIndex %d)", langsys->ReqFeatureIndex);
189 IPRINT ("(FeatureCount %d)", langsys->FeatureCount);
190 if (langsys->FeatureCount)
192 IPRINT ("(FeatureIndex");
193 for (i = 0; i < langsys->FeatureCount; i++)
194 printf (" %d", langsys->FeatureIndex[i]);
201 dump_script_list (int indent, OTF_ScriptList *list)
205 IPRINT ("(ScriptList (count %d)", list->ScriptCount);
207 for (i = 0; i < list->ScriptCount; i++)
209 OTF_Script *script = list->Script + i;
211 IPRINT ("(Script (%d) ", i);
212 dump_tag (list->Script[i].ScriptTag);
213 printf (" (Offset #x%04X)", list->Script[i].offset);
215 IPRINT ("(DefaultLangSysOffset #x%04X)",
216 script->DefaultLangSysOffset);
217 if (script->DefaultLangSysOffset)
218 dump_language_system (indent, -1, 0,
219 script->DefaultLangSysOffset,
220 &script->DefaultLangSys);
221 IPRINT ("(LangSysCount %d)", script->LangSysCount);
222 for (j = 0; j < script->LangSysCount; j++)
223 dump_language_system (indent, j,
224 script->LangSysRecord[j].LangSysTag,
225 script->LangSysRecord[j].LangSys,
226 script->LangSys + j);
234 dump_feature_list (int indent, OTF_FeatureList *list)
238 IPRINT ("(FeatureList (count %d)", list->FeatureCount);
240 for (i = 0; i < list->FeatureCount; i++)
242 OTF_Feature *feature = list->Feature + i;
244 IPRINT ("(Feature (%d) ", i);
245 dump_tag (list->Feature[i].FeatureTag);
246 printf (" (Offset #x%04X)", list->Feature[i].offset);
247 printf (" (LookupCount %d)", feature->LookupCount);
248 if (feature->LookupCount)
251 IPRINT ("(LookupListIndex");
252 for (j = 0; j < feature->LookupCount; j++)
253 printf (" %d", feature->LookupListIndex[j]);
263 dump_class_def (int indent, char *title, OTF_ClassDef *class)
265 IPRINT ("(%s (offset #x%04X) (ClassFormat %d)",
266 (title ? title : "ClassDef"),
267 class->offset, class->ClassFormat);
271 if (class->ClassFormat == 1)
273 IPRINT ("(StartGlyph #x%04X)", class->f.f1.StartGlyph);
274 dump_glyph_ids (indent, "ClassValueArray",
275 (OTF_GlyphID *) class->f.f1.ClassValueArray,
276 class->f.f1.GlyphCount);
278 else if (class->ClassFormat == 2)
282 IPRINT ("(ClassRangeCount %d)", class->f.f2.ClassRangeCount);
283 IPRINT ("(ClassRangeRecord");
285 for (i = 0; i < class->f.f2.ClassRangeCount; i++)
286 IPRINT ("((Start #x%04X) (End #x%04X) (class %d))",
287 class->f.f2.ClassRangeRecord[i].Start,
288 class->f.f2.ClassRangeRecord[i].End,
289 class->f.f2.ClassRangeRecord[i].Class);
293 printf (" UnknownClassFormat");
299 dump_device_table (int indent, char *title, OTF_DeviceTable *table)
305 IPRINT ("(%s (offset #x%04X)", title, table->offset);
307 IPRINT ("(StartSize %d) (EndSize %d) (DeltaFormat %d)",
308 table->StartSize, table->EndSize, table->DeltaFormat);
309 IPRINT ("(DeltaValue");
310 for (i = 0; i < table->EndSize - table->StartSize + 1; i++)
311 printf (" %d", table->DeltaValue[i]);
318 dump_value_record (int indent, char *title, OTF_ValueRecord *rec)
320 IPRINT ("(%s %d %d %d %d", title,
321 rec->XPlacement, rec->YPlacement, rec->XAdvance, rec->YAdvance);
323 if (rec->XPlaDevice.offset)
324 dump_device_table (indent, "XPlaDevice", &rec->XPlaDevice);
325 if (rec->YPlaDevice.offset)
326 dump_device_table (indent, "YPlaDevice", &rec->YPlaDevice);
327 if (rec->XAdvDevice.offset)
328 dump_device_table (indent, "XAdvDevice", &rec->XAdvDevice);
329 if (rec->YAdvDevice.offset)
330 dump_device_table (indent, "YAdvDevice", &rec->YAdvDevice);
336 dump_sequence_list (int indent, OTF_Sequence *sequence, unsigned num)
339 IPRINT ("(SequenceCount %d)", num);
341 for (i = 0; i < num; i++)
343 IPRINT ("(Sequence (%d) (offset #x%04X)",
344 i, sequence[i].offset);
345 dump_glyph_ids (indent + 1, "Substitute", sequence[i].Substitute,
346 sequence[i].GlyphCount);
352 dump_alternate_set_list (int indent, OTF_AlternateSet *altset, unsigned num)
356 IPRINT ("(AlternateSetCount %d)", num);
357 for (i = 0; i < num; i++)
359 IPRINT ("(AlternateSet (%d) (offset #x%04X)",
360 i, altset[i].offset);
361 dump_glyph_ids (indent + 1, "Alternate", altset[i].Alternate,
362 altset[i].GlyphCount);
369 dump_ligature_set_list (int indent, int *char_list,
370 OTF_LigatureSet *ligset, unsigned num)
374 IPRINT ("(LigSetCount %d)", num);
375 for (i = 0; i < num; i++)
377 IPRINT ("(LigatureSet (%d) (offset #x%04X) (count %d)",
378 i, ligset[i].offset, ligset[i].LigatureCount);
380 for (j = 0; j < ligset[i].LigatureCount; j++)
382 IPRINT ("(Ligature (%d) (offset #x%04X)",
383 j, ligset[i].Ligature[j].offset);
385 IPRINT ("(LigGlyph #x%04X)",
386 ligset[i].Ligature[j].LigGlyph);
387 dump_glyph_ids (indent, "Component", ligset[i].Ligature[j].Component,
388 ligset[i].Ligature[j].CompCount - 1);
389 IPRINT ("(i.e. #x%04X", char_list[i]);
390 for (k = 0; k < ligset[i].Ligature[j].CompCount - 1; k++)
391 printf (" #x%04X", ligset[i].Ligature[j].Component[k]);
392 printf (" = #x%04X)", ligset[i].Ligature[j].LigGlyph);
402 dump_pair_set_list (int indent, unsigned count, OTF_PairSet *set)
406 for (i = 0; i < count; i++)
408 IPRINT ("(PairSet (%d)", i);
410 for (j = 0; j < set[i].PairValueCount; j++)
412 IPRINT ("(PairValueRecord (%d)", j);
414 IPRINT ("(SecondGlyph #x%04X)",
415 set[i].PairValueRecord[j].SecondGlyph);
416 dump_value_record (indent, "Value1",
417 &set[i].PairValueRecord[j].Value1);
418 dump_value_record (indent, "Value2",
419 &set[i].PairValueRecord[j].Value2);
429 dump_class1_record_list (int indent,
430 unsigned Class1Count, unsigned Class2Count,
431 OTF_Class1Record *rec)
435 for (i = 0; i < Class1Count; i++)
437 IPRINT ("(Class1Record (%d)", i);
439 for (j = 0; j < Class2Count; j++)
441 IPRINT ("(Class2Record (%d)", j);
443 dump_value_record (indent, "Value1", &rec[i].Class2Record[j].Value1);
444 dump_value_record (indent, "Value2", &rec[i].Class2Record[j].Value2);
454 dump_anchor (int indent, OTF_Anchor *anchor)
456 IPRINT ("(Anchor (offset #x%04X) (AnchorFormat %d)",
457 anchor->offset, anchor->AnchorFormat);
459 IPRINT ("(XCoordinate %d) (YCoordinate %d)",
460 anchor->XCoordinate, anchor->YCoordinate);
461 if (anchor->AnchorFormat == 1)
463 else if (anchor->AnchorFormat == 2)
464 IPRINT ("(AnchorPoint %d)", anchor->f.f1.AnchorPoint);
467 dump_device_table (indent, "XDeviceTable", &anchor->f.f2.XDeviceTable);
468 dump_device_table (indent, "YDeviceTable", &anchor->f.f2.YDeviceTable);
474 dump_entry_exit_list (int indent, unsigned count, OTF_EntryExitRecord *rec)
478 for (i = 0; i < count; i++)
480 IPRINT ("(EntryExitRecord (%d)", i);
482 dump_anchor (indent, &rec[i].EntryAnchor);
483 dump_anchor (indent, &rec[i].EntryAnchor);
490 dump_mark_array (int indent, OTF_MarkArray *array)
494 IPRINT ("(MarkArray (MarkCount %d)", array->MarkCount);
496 for (i = 0; i < array->MarkCount; i++)
498 IPRINT ("(MarkRecord (%d) (Class %d)", i, array->MarkRecord[i].Class);
499 dump_anchor (indent + 1, &array->MarkRecord[i].MarkAnchor);
506 dump_anchor_array (int indent, unsigned ClassCount, OTF_AnchorArray *array)
510 IPRINT ("(AnchorArray (Count %d)", array->Count);
512 for (i = 0; i < array->Count; i++)
514 IPRINT ("(AnchorRecord (%d) ", i);
515 for (j = 0; j < ClassCount; j++)
516 dump_anchor (indent + 1, array->AnchorRecord[i].Anchor + j);
524 dump_lookup_record_list (int indent, OTF_LookupRecord *rec, unsigned num)
528 IPRINT ("(LookupCount %d)", num);
529 for (i = 0; i < num; i++)
531 IPRINT ("(LookupRecord (%d)", i);
533 IPRINT ("(SequenceIndex %d)", rec[i].SequenceIndex);
534 IPRINT ("(LookupListIndex %d))", rec[i].LookupListIndex);
540 static void dump_lookup_subtable_gsub (int indent, int index, unsigned type,
541 OTF_LookupSubTableGSUB *subtable);
542 static void dump_lookup_subtable_gpos (int indent, int index, unsigned type,
543 OTF_LookupSubTableGPOS *subtable);
547 dump_lookup_list (int indent, OTF_LookupList *list, int gsub)
551 IPRINT ("(LookupList (count %d)", list->LookupCount);
553 for (i = 0; i < list->LookupCount; i++)
555 OTF_Lookup *lookup = list->Lookup + i;
557 IPRINT ("(Lookup (%d) (Offset #x%04X)",
559 printf (" (Type %d) (Flag #x%04X) (SubTableCount %d)",
560 lookup->LookupType, lookup->LookupFlag, lookup->SubTableCount);
562 for (j = 0; j < lookup->SubTableCount; j++)
563 dump_lookup_subtable_gsub (indent + 1, j,
565 lookup->SubTable.gsub + j);
567 for (j = 0; j < lookup->SubTableCount; j++)
568 dump_lookup_subtable_gpos (indent + 1, j,
570 lookup->SubTable.gpos + j);
578 dump_rule_list (int indent, OTF_Rule *rule, int count)
582 IPRINT ("(RuleCount %d)", count);
583 for (i = 0; i < count; i++)
585 IPRINT ("(Rule (%d)", i);
587 IPRINT ("(GlyphCount %d)", rule[i].GlyphCount);
588 IPRINT ("(LookupCount %d)", rule[i].LookupCount);
589 dump_glyph_ids (indent, "Input", rule[i].Input, rule[i].GlyphCount - 1);
590 dump_lookup_record_list (indent, rule[i].LookupRecord,
591 rule[i].LookupCount);
598 dump_rule_set_list (int indent, OTF_RuleSet *set, int count)
602 IPRINT ("(RuleSetCount %d)", count);
603 for (i = 0; i < count; i++)
605 IPRINT ("(RuleSet (%d)", i);
606 dump_rule_list (indent + 1, set[i].Rule, set[i].RuleCount);
612 dump_class_rule_list (int indent, OTF_ClassRule *rule, int count)
616 IPRINT ("(ClassRuleCnt %d)", count);
617 for (i = 0; i < count; i++)
619 IPRINT ("(ClassRule (%d)", i);
621 IPRINT ("(GlyphCount %d)", rule[i].GlyphCount);
622 IPRINT ("(LookupCount %d)", rule[i].LookupCount);
624 for (j = 0; j < rule[i].GlyphCount - 1; j++)
625 printf (" %d", rule[i].Class[j]);
627 dump_lookup_record_list (indent, rule[i].LookupRecord,
628 rule[i].LookupCount);
635 dump_class_set_list (int indent, OTF_ClassSet *set, int count)
639 IPRINT ("(ClassSetCount %d)", count);
640 for (i = 0; i < count; i++)
643 IPRINT ("(ClassSet (%d)", i);
644 dump_class_rule_list (indent + 1, set[i].ClassRule,
645 set[i].ClassRuleCnt);
651 dump_chain_rule_list (int indent, OTF_ChainRule *rule, int count)
655 IPRINT ("(ChainRuleCount %d)", count);
656 for (i = 0; i < count; i++)
658 IPRINT ("(ChainRule (%d)", i);
659 dump_glyph_ids (indent + 1, "Backtrack",
660 rule[i].Backtrack, rule[i].BacktrackGlyphCount);
661 dump_glyph_ids (indent + 1, "Input",
662 rule[i].Input, rule[i].InputGlyphCount - 1);
663 dump_glyph_ids (indent + 1, "LookAhead",
664 rule[i].LookAhead, rule[i].LookaheadGlyphCount);
665 dump_lookup_record_list (indent + 1, rule[i].LookupRecord,
666 rule[i].LookupCount);
672 dump_chain_rule_set_list (int indent, OTF_ChainRuleSet *set, int count)
676 IPRINT ("(ChainRuleSetCount %d)", count);
677 for (i = 0; i < count; i++)
679 IPRINT ("(ChainRuleSet (%d)", i);
680 dump_chain_rule_list (indent + 1,
681 set[i].ChainRule, set[i].ChainRuleCount);
687 dump_chain_class_rule_list (int indent, OTF_ChainClassRule *rule, int count)
691 IPRINT ("(ChainClassRuleCount %d)", count);
692 for (i = 0; i < count; i++)
694 IPRINT ("(ChainClassRule (%d)", i);
695 dump_glyph_ids (indent + 1, "Backtrack",
696 rule[i].Backtrack, rule[i].BacktrackGlyphCount);
697 dump_glyph_ids (indent + 1, "Input",
698 rule[i].Input, rule[i].InputGlyphCount - 1);
699 dump_glyph_ids (indent + 1, "LookAhead",
700 rule[i].LookAhead, rule[i].LookaheadGlyphCount);
701 dump_lookup_record_list (indent + 1, rule[i].LookupRecord,
702 rule[i].LookupCount);
708 dump_chain_class_set_list (int indent, OTF_ChainClassSet *set, int count)
712 IPRINT ("(ChainClassSetCount %d)", count);
713 for (i = 0; i < count; i++)
716 IPRINT ("(ChainClassSet (%d)", i);
717 dump_chain_class_rule_list (indent + 1,
718 set[i].ChainClassRule,
719 set[i].ChainClassRuleCnt);
731 dump_lookup_subtable_gsub (int indent, int index, unsigned type,
732 OTF_LookupSubTableGSUB *subtable)
734 IPRINT ("(SubTable (%d) (Format %d)", index, subtable->Format);
739 if (subtable->Format == 1)
741 free (dump_coverage (indent, NULL, &subtable->Coverage));
742 IPRINT ("(DeltaGlyhpID #x%04X)",
743 subtable->u.single1.DeltaGlyphID);
745 else if (subtable->Format == 2)
747 free (dump_coverage (indent, NULL, &subtable->Coverage));
748 dump_glyph_ids (indent, "Substitute", subtable->u.single2.Substitute,
749 subtable->u.single2.GlyphCount);
756 if (subtable->Format == 1)
758 free (dump_coverage (indent, NULL, &subtable->Coverage));
759 dump_sequence_list (indent,
760 subtable->u.multiple1.Sequence,
761 subtable->u.multiple1.SequenceCount);
768 if (subtable->Format == 1)
770 free (dump_coverage (indent, NULL, &subtable->Coverage));
771 dump_alternate_set_list (indent, subtable->u.alternate1.AlternateSet,
772 subtable->u.alternate1.AlternateSetCount);
779 if (subtable->Format == 1)
781 int *char_list = dump_coverage (indent, NULL, &subtable->Coverage);
782 dump_ligature_set_list (indent, char_list,
783 subtable->u.ligature1.LigatureSet,
784 subtable->u.ligature1.LigSetCount);
792 if (subtable->Format == 1)
794 free (dump_coverage (indent, NULL, &subtable->Coverage));
795 dump_rule_set_list (indent, subtable->u.context1.RuleSet,
796 subtable->u.context1.RuleSetCount);
798 else if (subtable->Format == 2)
800 free (dump_coverage (indent, NULL, &subtable->Coverage));
801 dump_class_def (indent, NULL, &subtable->u.context2.ClassDef);
802 dump_class_set_list (indent, subtable->u.context2.ClassSet,
803 subtable->u.context2.ClassSetCnt);
805 else if (subtable->Format == 3)
807 dump_coverage_list (indent, "Coverage",
808 subtable->u.context3.Coverage,
809 subtable->u.context3.GlyphCount);
810 dump_lookup_record_list (indent,
811 subtable->u.context3.LookupRecord,
812 subtable->u.context3.LookupCount);
819 if (subtable->Format == 1)
821 free (dump_coverage (indent, NULL, &subtable->Coverage));
822 dump_chain_rule_set_list
824 subtable->u.chain_context1.ChainRuleSet,
825 subtable->u.chain_context1.ChainRuleSetCount);
827 else if (subtable->Format == 2)
829 free (dump_coverage (indent, NULL, &subtable->Coverage));
830 dump_class_def (indent, "BacktrackClassDef",
831 &subtable->u.chain_context2.BacktrackClassDef);
832 dump_class_def (indent, "InputClassDef",
833 &subtable->u.chain_context2.InputClassDef);
834 dump_class_def (indent, "LookaheadClassDef",
835 &subtable->u.chain_context2.LookaheadClassDef);
836 dump_chain_class_set_list
838 subtable->u.chain_context2.ChainClassSet,
839 subtable->u.chain_context2.ChainClassSetCnt);
841 else if (subtable->Format == 3)
844 (indent, "BackTrackGlyphCount",
845 subtable->u.chain_context3.Backtrack,
846 subtable->u.chain_context3.BacktrackGlyphCount);
848 (indent, "InputGlyphCount",
849 subtable->u.chain_context3.Input,
850 subtable->u.chain_context3.InputGlyphCount);
852 (indent, "LookaheadGlyphCount",
853 subtable->u.chain_context3.LookAhead,
854 subtable->u.chain_context3.LookaheadGlyphCount);
855 dump_lookup_record_list
857 subtable->u.chain_context3.LookupRecord,
858 subtable->u.chain_context3.LookupCount);
865 IPRINT ("(ExtensionLookupType %d)",
866 subtable->u.extension1.ExtensionLookupType);
867 IPRINT ("(ExtensionOffset %d)",
868 subtable->u.extension1.ExtensionOffset);
869 dump_lookup_subtable_gsub (indent, index,
870 subtable->u.extension1.ExtensionLookupType,
871 subtable->u.extension1.ExtensionSubtable);
875 printf (" not-yet-supported");
885 dump_gsub_table (int indent, OTF_GSUB *gsub)
891 IPRINT ("(Version %d.%d)", gsub->Version.high, gsub->Version.low);
892 IPRINT ("(ScriptList #x%04X)", gsub->ScriptList.offset);
893 IPRINT ("(FeatureList #x%04X)", gsub->FeatureList.offset);
894 IPRINT ("(LookupList #x%04X))", gsub->LookupList.offset);
896 dump_script_list (indent, &gsub->ScriptList);
897 dump_feature_list (indent, &gsub->FeatureList);
898 dump_lookup_list (indent, &gsub->LookupList, 1);
906 dump_lookup_subtable_gpos (int indent, int index, unsigned type,
907 OTF_LookupSubTableGPOS *subtable)
909 IPRINT ("(SubTable (%d) (Format %d)", index, subtable->Format);
914 if (subtable->Format == 1)
916 free (dump_coverage (indent, NULL, &subtable->Coverage));
917 IPRINT ("(ValueFormat #x%04X)",
918 subtable->u.single1.ValueFormat);
919 dump_value_record (indent, "Value", &subtable->u.single1.Value);
921 else if (subtable->Format == 2)
925 free (dump_coverage (indent, NULL, &subtable->Coverage));
926 IPRINT ("(ValueFormat #x%04X)",
927 subtable->u.single2.ValueFormat);
928 IPRINT ("(ValueCount %d)",
929 subtable->u.single2.ValueCount);
930 for (i = 0; i < subtable->u.single2.ValueCount; i++)
931 dump_value_record (indent, "Value", &subtable->u.single2.Value[i]);
938 if (subtable->Format == 1)
940 free (dump_coverage (indent, NULL, &subtable->Coverage));
941 IPRINT ("(ValueFormat1 #x%04X)",
942 subtable->u.pair1.ValueFormat1);
943 IPRINT ("(ValueFormat2 #x%04X)",
944 subtable->u.pair1.ValueFormat2);
945 dump_pair_set_list (indent, subtable->u.pair1.PairSetCount,
946 subtable->u.pair1.PairSet);
948 else if (subtable->Format == 2)
950 free (dump_coverage (indent, NULL, &subtable->Coverage));
951 IPRINT ("(ValueFormat1 #x%04X)",
952 subtable->u.pair2.ValueFormat1);
953 IPRINT ("(ValueFormat2 #x%04X)",
954 subtable->u.pair2.ValueFormat2);
955 dump_class_def (indent, "ClassDef1",
956 &subtable->u.pair2.ClassDef1);
957 dump_class_def (indent, "ClassDef2",
958 &subtable->u.pair2.ClassDef2);
959 IPRINT ("(Class1Count %d)",
960 subtable->u.pair2.Class1Count);
961 IPRINT ("(Class2Count %d)",
962 subtable->u.pair2.Class2Count);
963 dump_class1_record_list (indent,
964 subtable->u.pair2.Class1Count,
965 subtable->u.pair2.Class2Count,
966 subtable->u.pair2.Class1Record);
973 if (subtable->Format == 1)
975 free (dump_coverage (indent, NULL, &subtable->Coverage));
976 dump_entry_exit_list (indent, subtable->u.cursive1.EntryExitCount,
977 subtable->u.cursive1.EntryExitRecord);
984 if (subtable->Format == 1)
986 free (dump_coverage (indent, "Mark", &subtable->Coverage));
987 free (dump_coverage (indent, "Base",
988 &subtable->u.mark_base1.BaseCoverage));
989 IPRINT ("(ClassCount %d)",
990 subtable->u.mark_base1.ClassCount);
991 dump_mark_array (indent, &subtable->u.mark_base1.MarkArray);
992 dump_anchor_array (indent, subtable->u.mark_base1.ClassCount,
993 &subtable->u.mark_base1.BaseArray);
998 if (subtable->Format == 1)
1000 OTF_GPOS_MarkLig1 *mark_lig1 = &subtable->u.mark_lig1;
1003 free (dump_coverage (indent, "Mark", &subtable->Coverage));
1004 free (dump_coverage (indent, "Ligature",
1005 &mark_lig1->LigatureCoverage));
1006 IPRINT ("(ClassCount %d)", mark_lig1->ClassCount);
1007 dump_mark_array (indent, &mark_lig1->MarkArray);
1008 IPRINT ("(LigatureArray (%d)",
1009 mark_lig1->LigatureArray.LigatureCount);
1011 for (i = 0; i < mark_lig1->LigatureArray.LigatureCount; i++)
1013 OTF_LigatureAttach *attach
1014 = mark_lig1->LigatureArray.LigatureAttach + i;
1016 IPRINT ("(LigatureAttach (%d)", attach->ComponentCount);
1018 for (j = 0; j < attach->ComponentCount; j++)
1020 OTF_ComponentRecord *rec = attach->ComponentRecord + j;
1022 IPRINT ("(LigatureAnchor (%d)", mark_lig1->ClassCount);
1023 for (k = 0; k < mark_lig1->ClassCount; k++)
1024 if (rec->LigatureAnchor[k].AnchorFormat)
1025 dump_anchor (indent + 1, rec->LigatureAnchor + k);
1034 printf (" invalid");
1038 if (subtable->Format == 1)
1040 free (dump_coverage (indent, "Mark1", &subtable->Coverage));
1041 free (dump_coverage (indent, "Mark2",
1042 &subtable->u.mark_mark1.Mark2Coverage));
1043 IPRINT ("(ClassCount %d)",
1044 subtable->u.mark_mark1.ClassCount);
1045 dump_mark_array (indent, &subtable->u.mark_mark1.Mark1Array);
1046 dump_anchor_array (indent, subtable->u.mark_mark1.ClassCount,
1047 &subtable->u.mark_mark1.Mark2Array);
1050 printf (" invalid");
1054 if (subtable->Format == 1)
1056 free (dump_coverage (indent, NULL, &subtable->Coverage));
1057 dump_rule_set_list (indent, subtable->u.context1.RuleSet,
1058 subtable->u.context1.RuleSetCount);
1060 else if (subtable->Format == 2)
1062 free (dump_coverage (indent, NULL, &subtable->Coverage));
1063 dump_class_def (indent, NULL, &subtable->u.context2.ClassDef);
1064 dump_class_set_list (indent, subtable->u.context2.ClassSet,
1065 subtable->u.context2.ClassSetCnt);
1067 else if (subtable->Format == 3)
1069 dump_coverage_list (indent, "Coverage",
1070 subtable->u.context3.Coverage,
1071 subtable->u.context3.GlyphCount);
1072 dump_lookup_record_list (indent,
1073 subtable->u.context3.LookupRecord,
1074 subtable->u.context3.LookupCount);
1077 printf (" invalid");
1081 if (subtable->Format == 1)
1083 free (dump_coverage (indent, NULL, &subtable->Coverage));
1084 dump_chain_rule_set_list
1086 subtable->u.chain_context1.ChainRuleSet,
1087 subtable->u.chain_context1.ChainRuleSetCount);
1089 else if (subtable->Format == 2)
1091 free (dump_coverage (indent, NULL, &subtable->Coverage));
1092 dump_class_def (indent, "BacktrackClassDef",
1093 &subtable->u.chain_context2.BacktrackClassDef);
1094 dump_class_def (indent, "InputClassDef",
1095 &subtable->u.chain_context2.InputClassDef);
1096 dump_class_def (indent, "LookaheadClassDef",
1097 &subtable->u.chain_context2.LookaheadClassDef);
1098 dump_chain_class_set_list
1100 subtable->u.chain_context2.ChainClassSet,
1101 subtable->u.chain_context2.ChainClassSetCnt);
1103 else if (subtable->Format == 3)
1106 (indent, "BackTrackGlyphCount",
1107 subtable->u.chain_context3.Backtrack,
1108 subtable->u.chain_context3.BacktrackGlyphCount);
1110 (indent, "InputGlyphCount",
1111 subtable->u.chain_context3.Input,
1112 subtable->u.chain_context3.InputGlyphCount);
1114 (indent, "LookaheaGlyphCount",
1115 subtable->u.chain_context3.LookAhead,
1116 subtable->u.chain_context3.LookaheadGlyphCount);
1117 dump_lookup_record_list
1119 subtable->u.chain_context3.LookupRecord,
1120 subtable->u.chain_context3.LookupCount);
1123 printf (" invalid");
1127 if (subtable->Format == 1)
1129 IPRINT ("(ExtensionLookupType %d)",
1130 subtable->u.extension1.ExtensionLookupType);
1131 IPRINT ("(ExtensionOffset %d)",
1132 subtable->u.extension1.ExtensionOffset);
1133 dump_lookup_subtable_gpos
1135 subtable->u.extension1.ExtensionLookupType,
1136 subtable->u.extension1.ExtensionSubtable);
1139 printf (" invalid");
1146 dump_gpos_table (int indent, OTF_GPOS *gpos)
1154 IPRINT ("(Version %d.%d)", gpos->Version.high, gpos->Version.low);
1155 IPRINT ("(ScriptList #x%04X)", gpos->ScriptList.offset);
1156 IPRINT ("(FeatureList #x%04X)", gpos->FeatureList.offset);
1157 IPRINT ("(LookupList #x%04X))", gpos->LookupList.offset);
1159 dump_script_list (indent, &gpos->ScriptList);
1160 dump_feature_list (indent, &gpos->FeatureList);
1161 dump_lookup_list (indent, &gpos->LookupList, 0);
1167 dump_base_table (OTF_BASE *base)
1172 dump_jstf_table (OTF_JSTF *jstf)
1180 dump_gdef_header (int indent, OTF_GDEFHeader *header)
1184 IPRINT ("(Version %d.%d)",
1185 header->Version.high, header->Version.low);
1186 IPRINT ("(GlyphClassDef #x%04X)", header->GlyphClassDef);
1187 IPRINT ("(AttachList #x%04X)", header->AttachList);
1188 IPRINT ("(LigCaretList #x%04X)", header->LigCaretList);
1189 IPRINT ("(MarkAttachClassDef #x%04X))",
1190 header->MarkAttachClassDef);
1194 dump_attach_list (int indent, OTF_AttachList *list)
1199 dump_lig_caret_list (int indent, OTF_LigCaretList *list)
1203 IPRINT ("(LigCaretList");
1205 free (dump_coverage (indent, NULL, &list->Coverage));
1206 IPRINT ("(LigGlyphCount %d)", list->LigGlyphCount);
1207 for (i = 0; i < list->LigGlyphCount; i++)
1209 IPRINT ("(LigGlyph (%d) (offset #x%04X)",
1210 i, list->LigGlyph[i].offset);
1212 IPRINT ("(CaretCount %d)", list->LigGlyph[i].CaretCount);
1213 for (j = 0; j < list->LigGlyph[i].CaretCount; j++)
1215 unsigned format = list->LigGlyph[i].CaretValue[j].CaretValueFormat;
1217 IPRINT ("(Caret (%d) (CaretValueFormat %d)", j, format);
1220 printf ("(Coordinate %d)",
1221 list->LigGlyph[i].CaretValue[j].f.f1.Coordinate);
1223 else if (format == 2)
1225 printf ("(CaretValuePoint %d)",
1226 list->LigGlyph[i].CaretValue[j].f.f2.CaretValuePoint);
1228 else if (format == 3)
1230 printf ("(Coodinate %d)",
1231 list->LigGlyph[i].CaretValue[j].f.f3.Coordinate);
1234 (indent, "DeviceTable",
1235 &list->LigGlyph[i].CaretValue[j].f.f3.DeviceTable);
1247 dump_gdef_table (int indent, OTF_GDEF *gdef)
1253 dump_gdef_header (indent, &gdef->header);
1254 if (gdef->header.GlyphClassDef)
1255 dump_class_def (indent, "GlyphClassDef", &gdef->glyph_class_def);
1256 if (gdef->header.AttachList)
1257 dump_attach_list (indent, &gdef->attach_list);
1258 if (gdef->header.LigCaretList)
1259 dump_lig_caret_list (indent, &gdef->lig_caret_list);
1260 if (gdef->header.MarkAttachClassDef)
1261 dump_class_def (indent, "MarkAttachClassDef",
1262 &gdef->mark_attach_class_def);
1269 dump_cmap_table (int indent, OTF_cmap *cmap)
1275 IPRINT ("(version %d)", cmap->version);
1276 IPRINT ("(numTables %d)", cmap->numTables);
1277 for (i = 0; i < cmap->numTables; i++)
1279 IPRINT ("(EncodingRecord (%d) (platformID %d) (encodingID %d)",
1281 cmap->EncodingRecord[i].platformID,
1282 cmap->EncodingRecord[i].encodingID);
1284 IPRINT ("(Subtable (offset #x%04X) (format %d) (length #x%04X) (language %d)",
1285 cmap->EncodingRecord[i].offset,
1286 cmap->EncodingRecord[i].subtable.format,
1287 cmap->EncodingRecord[i].subtable.length,
1288 cmap->EncodingRecord[i].subtable.language);
1290 switch (cmap->EncodingRecord[i].subtable.format)
1295 unsigned char *array
1296 = cmap->EncodingRecord[i].subtable.f.f0->glyphIdArray;
1298 IPRINT ("(glyphIdArray");
1299 for (j = 0; j < 16; j++)
1302 for (k = 0; k < 16; k++)
1303 printf (" %3d", array[j * 16 + k]);
1311 OTF_EncodingSubtable4 *sub4
1312 = cmap->EncodingRecord[i].subtable.f.f4;
1315 IPRINT ("(segCountX2 %d) (searchRange %d)",
1316 sub4->segCountX2, sub4->searchRange);
1317 IPRINT ("(entrySelector %d) (rangeShift %d)",
1318 sub4->entrySelector, sub4->rangeShift);
1319 for (j = 0; j < sub4->segCountX2 / 2; j++)
1321 IPRINT ("(Segment (%d)", j);
1323 IPRINT ("(startCount #x%04X) (endCount #x%04X)",
1324 sub4->segments[j].startCount,
1325 sub4->segments[j].endCount);
1326 IPRINT ("(idDelta %d) (idRangeOffset #x%04X))",
1327 sub4->segments[j].idDelta,
1328 sub4->segments[j].idRangeOffset);
1331 IPRINT ("(glyphIdArray");
1332 for (j = 0; j < sub4->GlyphCount; j++)
1336 printf (" %3d", sub4->glyphIdArray[j]);
1344 OTF_EncodingSubtable6 *sub6
1345 = cmap->EncodingRecord[i].subtable.f.f6;
1348 IPRINT ("(firstCode %d) (entryCount %d)",
1349 sub6->firstCode, sub6->entryCount);
1350 IPRINT ("(glyphIdArray");
1351 for (j = 0; j < sub6->entryCount; j++)
1355 printf (" %3d", sub6->glyphIdArray[j]);
1363 OTF_EncodingSubtable12 *sub12
1364 = cmap->EncodingRecord[i].subtable.f.f12;
1367 for (j = 0; j < sub12->nGroups; j++)
1369 IPRINT ("(Group (#x%X) (startChar #x%04X) (endChar #x%04X) (startGlyphID #x%X))",
1371 sub12->Groups[j].startCharCode,
1372 sub12->Groups[j].endCharCode,
1373 sub12->Groups[j].startGlyphID);
1387 dump_name_table (int indent, OTF_name *name)
1393 IPRINT ("(format %d)", name->format);
1394 IPRINT ("(count %d)", name->count);
1395 IPRINT ("(stringOffset %d)", name->stringOffset);
1396 for (i = 0; i < name->count; i++)
1398 OTF_NameRecord *rec = name->nameRecord + i;
1400 IPRINT ("(nameRecord (%d)", i);
1402 IPRINT ("(platformID %d) (encodingID %d) (languageID %d) (nameID %d)",
1403 rec->platformID, rec->encodingID, rec->languageID, rec->nameID);
1404 IPRINT ("(length %d) (offset #x%04X))", rec->length, rec->offset);
1407 for (i = 0; i <= OTF_max_nameID; i++)
1409 IPRINT ("(nameID %d \"%s\")", i, name->name[i]);
1423 dump_offset_table (1, &otf->offset_table);
1424 for (i = 0; i < otf->offset_table.numTables; i++)
1425 dump_table_directory (1, otf->table_dirs + i, i);
1428 dump_head_table (1, otf->head);
1430 dump_name_table (1, otf->name);
1432 dump_cmap_table (1, otf->cmap);
1434 dump_gdef_table (1, otf->gdef);
1436 dump_gsub_table (1, otf->gsub);
1438 dump_gpos_table (1, otf->gpos);
1441 dump_base_table (1, otf->base);
1443 dump_jstf_table (1, otf->jstf);
1450 main (int argc, char **argv)
1454 if (argc != 2 || !strcmp (argv[1], "-h") || !strcmp (argv[1], "--help"))
1456 fprintf (stderr, "Usage: %s OTF-FILE\n", basename (argv[0]));
1460 otf = OTF_open (argv[1]);
1463 OTF_perror ("otfdump");
1466 OTF_get_table (otf, "head");
1467 OTF_get_table (otf, "name");
1468 OTF_get_table (otf, "cmap");
1469 OTF_get_table (otf, "GDEF");
1470 OTF_get_table (otf, "GSUB");
1471 OTF_get_table (otf, "GPOS");
1473 OTF_get_table (otf, "BASE");
1474 OTF_get_table (otf, "JSTF");