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++)
715 IPRINT ("(ChainClassSet (%d)", i);
716 dump_chain_class_rule_list (indent + 1,
717 set[i].ChainClassRule,
718 set[i].ChainClassRuleCnt);
730 dump_lookup_subtable_gsub (int indent, int index, unsigned type,
731 OTF_LookupSubTableGSUB *subtable)
733 IPRINT ("(SubTable (%d) (Format %d)", index, subtable->Format);
738 if (subtable->Format == 1)
740 free (dump_coverage (indent, NULL, &subtable->Coverage));
741 IPRINT ("(DeltaGlyhpID #x%04X)",
742 subtable->u.single1.DeltaGlyphID);
744 else if (subtable->Format == 2)
746 free (dump_coverage (indent, NULL, &subtable->Coverage));
747 dump_glyph_ids (indent, "Substitute", subtable->u.single2.Substitute,
748 subtable->u.single2.GlyphCount);
755 if (subtable->Format == 1)
757 free (dump_coverage (indent, NULL, &subtable->Coverage));
758 dump_sequence_list (indent,
759 subtable->u.multiple1.Sequence,
760 subtable->u.multiple1.SequenceCount);
767 if (subtable->Format == 1)
769 free (dump_coverage (indent, NULL, &subtable->Coverage));
770 dump_alternate_set_list (indent, subtable->u.alternate1.AlternateSet,
771 subtable->u.alternate1.AlternateSetCount);
778 if (subtable->Format == 1)
780 int *char_list = dump_coverage (indent, NULL, &subtable->Coverage);
781 dump_ligature_set_list (indent, char_list,
782 subtable->u.ligature1.LigatureSet,
783 subtable->u.ligature1.LigSetCount);
791 if (subtable->Format == 1)
793 free (dump_coverage (indent, NULL, &subtable->Coverage));
794 dump_rule_set_list (indent, subtable->u.context1.RuleSet,
795 subtable->u.context1.RuleSetCount);
797 else if (subtable->Format == 2)
799 free (dump_coverage (indent, NULL, &subtable->Coverage));
800 dump_class_def (indent, NULL, &subtable->u.context2.ClassDef);
801 dump_class_set_list (indent, subtable->u.context2.ClassSet,
802 subtable->u.context2.ClassSetCnt);
804 else if (subtable->Format == 3)
806 dump_coverage_list (indent, "Coverage",
807 subtable->u.context3.Coverage,
808 subtable->u.context3.GlyphCount);
809 dump_lookup_record_list (indent,
810 subtable->u.context3.LookupRecord,
811 subtable->u.context3.LookupCount);
818 if (subtable->Format == 1)
820 free (dump_coverage (indent, NULL, &subtable->Coverage));
821 dump_chain_rule_set_list
823 subtable->u.chain_context1.ChainRuleSet,
824 subtable->u.chain_context1.ChainRuleSetCount);
826 else if (subtable->Format == 2)
828 free (dump_coverage (indent, NULL, &subtable->Coverage));
829 dump_class_def (indent, "BacktrackClassDef",
830 &subtable->u.chain_context2.BacktrackClassDef);
831 dump_class_def (indent, "InputClassDef",
832 &subtable->u.chain_context2.InputClassDef);
833 dump_class_def (indent, "LookaheadClassDef",
834 &subtable->u.chain_context2.LookaheadClassDef);
835 dump_chain_class_set_list
837 subtable->u.chain_context2.ChainClassSet,
838 subtable->u.chain_context2.ChainClassSetCnt);
840 else if (subtable->Format == 3)
843 (indent, "BackTrackGlyphCount",
844 subtable->u.chain_context3.Backtrack,
845 subtable->u.chain_context3.BacktrackGlyphCount);
847 (indent, "InputGlyphCount",
848 subtable->u.chain_context3.Input,
849 subtable->u.chain_context3.InputGlyphCount);
851 (indent, "LookaheadGlyphCount",
852 subtable->u.chain_context3.LookAhead,
853 subtable->u.chain_context3.LookaheadGlyphCount);
854 dump_lookup_record_list
856 subtable->u.chain_context3.LookupRecord,
857 subtable->u.chain_context3.LookupCount);
864 IPRINT ("(ExtensionLookupType %d)",
865 subtable->u.extension1.ExtensionLookupType);
866 IPRINT ("(ExtensionOffset %d)",
867 subtable->u.extension1.ExtensionOffset);
868 dump_lookup_subtable_gsub (indent, index,
869 subtable->u.extension1.ExtensionLookupType,
870 subtable->u.extension1.ExtensionSubtable);
874 printf (" not-yet-supported");
884 dump_gsub_table (int indent, OTF_GSUB *gsub)
890 IPRINT ("(Version %d.%d)", gsub->Version.high, gsub->Version.low);
891 IPRINT ("(ScriptList #x%04X)", gsub->ScriptList.offset);
892 IPRINT ("(FeatureList #x%04X)", gsub->FeatureList.offset);
893 IPRINT ("(LookupList #x%04X))", gsub->LookupList.offset);
895 dump_script_list (indent, &gsub->ScriptList);
896 dump_feature_list (indent, &gsub->FeatureList);
897 dump_lookup_list (indent, &gsub->LookupList, 1);
905 dump_lookup_subtable_gpos (int indent, int index, unsigned type,
906 OTF_LookupSubTableGPOS *subtable)
908 IPRINT ("(SubTable (%d) (Format %d)", index, subtable->Format);
913 if (subtable->Format == 1)
915 free (dump_coverage (indent, NULL, &subtable->Coverage));
916 IPRINT ("(ValueFormat #x%04X)",
917 subtable->u.single1.ValueFormat);
918 dump_value_record (indent, "Value", &subtable->u.single1.Value);
920 else if (subtable->Format == 2)
924 free (dump_coverage (indent, NULL, &subtable->Coverage));
925 IPRINT ("(ValueFormat #x%04X)",
926 subtable->u.single2.ValueFormat);
927 IPRINT ("(ValueCount %d)",
928 subtable->u.single2.ValueCount);
929 for (i = 0; i < subtable->u.single2.ValueCount; i++)
930 dump_value_record (indent, "Value", &subtable->u.single2.Value[i]);
937 if (subtable->Format == 1)
939 free (dump_coverage (indent, NULL, &subtable->Coverage));
940 IPRINT ("(ValueFormat1 #x%04X)",
941 subtable->u.pair1.ValueFormat1);
942 IPRINT ("(ValueFormat2 #x%04X)",
943 subtable->u.pair1.ValueFormat2);
944 dump_pair_set_list (indent, subtable->u.pair1.PairSetCount,
945 subtable->u.pair1.PairSet);
947 else if (subtable->Format == 2)
949 free (dump_coverage (indent, NULL, &subtable->Coverage));
950 IPRINT ("(ValueFormat1 #x%04X)",
951 subtable->u.pair2.ValueFormat1);
952 IPRINT ("(ValueFormat2 #x%04X)",
953 subtable->u.pair2.ValueFormat2);
954 dump_class_def (indent, "ClassDef1",
955 &subtable->u.pair2.ClassDef1);
956 dump_class_def (indent, "ClassDef2",
957 &subtable->u.pair2.ClassDef2);
958 IPRINT ("(Class1Count %d)",
959 subtable->u.pair2.Class1Count);
960 IPRINT ("(Class2Count %d)",
961 subtable->u.pair2.Class2Count);
962 dump_class1_record_list (indent,
963 subtable->u.pair2.Class1Count,
964 subtable->u.pair2.Class2Count,
965 subtable->u.pair2.Class1Record);
972 if (subtable->Format == 1)
974 free (dump_coverage (indent, NULL, &subtable->Coverage));
975 dump_entry_exit_list (indent, subtable->u.cursive1.EntryExitCount,
976 subtable->u.cursive1.EntryExitRecord);
983 if (subtable->Format == 1)
985 free (dump_coverage (indent, "Mark", &subtable->Coverage));
986 free (dump_coverage (indent, "Base",
987 &subtable->u.mark_base1.BaseCoverage));
988 IPRINT ("(ClassCount %d)",
989 subtable->u.mark_base1.ClassCount);
990 dump_mark_array (indent, &subtable->u.mark_base1.MarkArray);
991 dump_anchor_array (indent, subtable->u.mark_base1.ClassCount,
992 &subtable->u.mark_base1.BaseArray);
997 if (subtable->Format == 1)
999 OTF_GPOS_MarkLig1 *mark_lig1 = &subtable->u.mark_lig1;
1002 free (dump_coverage (indent, "Mark", &subtable->Coverage));
1003 free (dump_coverage (indent, "Ligature",
1004 &mark_lig1->LigatureCoverage));
1005 IPRINT ("(ClassCount %d)", mark_lig1->ClassCount);
1006 dump_mark_array (indent, &mark_lig1->MarkArray);
1007 IPRINT ("(LigatureArray (%d)",
1008 mark_lig1->LigatureArray.LigatureCount);
1010 for (i = 0; i < mark_lig1->LigatureArray.LigatureCount; i++)
1012 OTF_LigatureAttach *attach
1013 = mark_lig1->LigatureArray.LigatureAttach + i;
1015 IPRINT ("(LigatureAttach (%d)", attach->ComponentCount);
1017 for (j = 0; j < attach->ComponentCount; j++)
1019 OTF_ComponentRecord *rec = attach->ComponentRecord + j;
1021 IPRINT ("(LigatureAnchor (%d)", mark_lig1->ClassCount);
1022 for (k = 0; k < mark_lig1->ClassCount; k++)
1023 if (rec->LigatureAnchor[k].AnchorFormat)
1024 dump_anchor (indent + 1, rec->LigatureAnchor + k);
1033 printf (" invalid");
1037 if (subtable->Format == 1)
1039 free (dump_coverage (indent, "Mark1", &subtable->Coverage));
1040 free (dump_coverage (indent, "Mark2",
1041 &subtable->u.mark_mark1.Mark2Coverage));
1042 IPRINT ("(ClassCount %d)",
1043 subtable->u.mark_mark1.ClassCount);
1044 dump_mark_array (indent, &subtable->u.mark_mark1.Mark1Array);
1045 dump_anchor_array (indent, subtable->u.mark_mark1.ClassCount,
1046 &subtable->u.mark_mark1.Mark2Array);
1049 printf (" invalid");
1053 if (subtable->Format == 1)
1055 free (dump_coverage (indent, NULL, &subtable->Coverage));
1056 dump_rule_set_list (indent, subtable->u.context1.RuleSet,
1057 subtable->u.context1.RuleSetCount);
1059 else if (subtable->Format == 2)
1061 free (dump_coverage (indent, NULL, &subtable->Coverage));
1062 dump_class_def (indent, NULL, &subtable->u.context2.ClassDef);
1063 dump_class_set_list (indent, subtable->u.context2.ClassSet,
1064 subtable->u.context2.ClassSetCnt);
1066 else if (subtable->Format == 3)
1068 dump_coverage_list (indent, "Coverage",
1069 subtable->u.context3.Coverage,
1070 subtable->u.context3.GlyphCount);
1071 dump_lookup_record_list (indent,
1072 subtable->u.context3.LookupRecord,
1073 subtable->u.context3.LookupCount);
1076 printf (" invalid");
1080 if (subtable->Format == 1)
1082 free (dump_coverage (indent, NULL, &subtable->Coverage));
1083 dump_chain_rule_set_list
1085 subtable->u.chain_context1.ChainRuleSet,
1086 subtable->u.chain_context1.ChainRuleSetCount);
1088 else if (subtable->Format == 2)
1090 free (dump_coverage (indent, NULL, &subtable->Coverage));
1091 dump_class_def (indent, "BacktrackClassDef",
1092 &subtable->u.chain_context2.BacktrackClassDef);
1093 dump_class_def (indent, "InputClassDef",
1094 &subtable->u.chain_context2.InputClassDef);
1095 dump_class_def (indent, "LookaheadClassDef",
1096 &subtable->u.chain_context2.LookaheadClassDef);
1097 dump_chain_class_set_list
1099 subtable->u.chain_context2.ChainClassSet,
1100 subtable->u.chain_context2.ChainClassSetCnt);
1102 else if (subtable->Format == 3)
1105 (indent, "BackTrackGlyphCount",
1106 subtable->u.chain_context3.Backtrack,
1107 subtable->u.chain_context3.BacktrackGlyphCount);
1109 (indent, "InputGlyphCount",
1110 subtable->u.chain_context3.Input,
1111 subtable->u.chain_context3.InputGlyphCount);
1113 (indent, "LookaheaGlyphCount",
1114 subtable->u.chain_context3.LookAhead,
1115 subtable->u.chain_context3.LookaheadGlyphCount);
1116 dump_lookup_record_list
1118 subtable->u.chain_context3.LookupRecord,
1119 subtable->u.chain_context3.LookupCount);
1122 printf (" invalid");
1126 if (subtable->Format == 1)
1128 IPRINT ("(ExtensionLookupType %d)",
1129 subtable->u.extension1.ExtensionLookupType);
1130 IPRINT ("(ExtensionOffset %d)",
1131 subtable->u.extension1.ExtensionOffset);
1132 dump_lookup_subtable_gpos
1134 subtable->u.extension1.ExtensionLookupType,
1135 subtable->u.extension1.ExtensionSubtable);
1138 printf (" invalid");
1145 dump_gpos_table (int indent, OTF_GPOS *gpos)
1153 IPRINT ("(Version %d.%d)", gpos->Version.high, gpos->Version.low);
1154 IPRINT ("(ScriptList #x%04X)", gpos->ScriptList.offset);
1155 IPRINT ("(FeatureList #x%04X)", gpos->FeatureList.offset);
1156 IPRINT ("(LookupList #x%04X))", gpos->LookupList.offset);
1158 dump_script_list (indent, &gpos->ScriptList);
1159 dump_feature_list (indent, &gpos->FeatureList);
1160 dump_lookup_list (indent, &gpos->LookupList, 0);
1166 dump_base_table (OTF_BASE *base)
1171 dump_jstf_table (OTF_JSTF *jstf)
1179 dump_gdef_header (int indent, OTF_GDEFHeader *header)
1183 IPRINT ("(Version %d.%d)",
1184 header->Version.high, header->Version.low);
1185 IPRINT ("(GlyphClassDef #x%04X)", header->GlyphClassDef);
1186 IPRINT ("(AttachList #x%04X)", header->AttachList);
1187 IPRINT ("(LigCaretList #x%04X)", header->LigCaretList);
1188 IPRINT ("(MarkAttachClassDef #x%04X))",
1189 header->MarkAttachClassDef);
1193 dump_attach_list (int indent, OTF_AttachList *list)
1198 dump_lig_caret_list (int indent, OTF_LigCaretList *list)
1202 IPRINT ("(LigCaretList");
1204 free (dump_coverage (indent, NULL, &list->Coverage));
1205 IPRINT ("(LigGlyphCount %d)", list->LigGlyphCount);
1206 for (i = 0; i < list->LigGlyphCount; i++)
1208 IPRINT ("(LigGlyph (%d) (offset #x%04X)",
1209 i, list->LigGlyph[i].offset);
1211 IPRINT ("(CaretCount %d)", list->LigGlyph[i].CaretCount);
1212 for (j = 0; j < list->LigGlyph[i].CaretCount; j++)
1214 unsigned format = list->LigGlyph[i].CaretValue[j].CaretValueFormat;
1216 IPRINT ("(Caret (%d) (CaretValueFormat %d)", j, format);
1219 printf ("(Coordinate %d)",
1220 list->LigGlyph[i].CaretValue[j].f.f1.Coordinate);
1222 else if (format == 2)
1224 printf ("(CaretValuePoint %d)",
1225 list->LigGlyph[i].CaretValue[j].f.f2.CaretValuePoint);
1227 else if (format == 3)
1229 printf ("(Coodinate %d)",
1230 list->LigGlyph[i].CaretValue[j].f.f3.Coordinate);
1233 (indent, "DeviceTable",
1234 &list->LigGlyph[i].CaretValue[j].f.f3.DeviceTable);
1246 dump_gdef_table (int indent, OTF_GDEF *gdef)
1252 dump_gdef_header (indent, &gdef->header);
1253 if (gdef->header.GlyphClassDef)
1254 dump_class_def (indent, "GlyphClassDef", &gdef->glyph_class_def);
1255 if (gdef->header.AttachList)
1256 dump_attach_list (indent, &gdef->attach_list);
1257 if (gdef->header.LigCaretList)
1258 dump_lig_caret_list (indent, &gdef->lig_caret_list);
1259 if (gdef->header.MarkAttachClassDef)
1260 dump_class_def (indent, "MarkAttachClassDef",
1261 &gdef->mark_attach_class_def);
1268 dump_cmap_table (int indent, OTF_cmap *cmap)
1274 IPRINT ("(version %d)", cmap->version);
1275 IPRINT ("(numTables %d)", cmap->numTables);
1276 for (i = 0; i < cmap->numTables; i++)
1278 IPRINT ("(EncodingRecord (%d) (platformID %d) (encodingID %d)",
1280 cmap->EncodingRecord[i].platformID,
1281 cmap->EncodingRecord[i].encodingID);
1283 IPRINT ("(Subtable (offset #x%04X) (format %d) (length #x%04X) (language %d)",
1284 cmap->EncodingRecord[i].offset,
1285 cmap->EncodingRecord[i].subtable.format,
1286 cmap->EncodingRecord[i].subtable.length,
1287 cmap->EncodingRecord[i].subtable.language);
1289 switch (cmap->EncodingRecord[i].subtable.format)
1294 unsigned char *array
1295 = cmap->EncodingRecord[i].subtable.f.f0->glyphIdArray;
1297 IPRINT ("(glyphIdArray");
1298 for (j = 0; j < 16; j++)
1301 for (k = 0; k < 16; k++)
1302 printf (" %3d", array[j * 16 + k]);
1310 OTF_EncodingSubtable4 *sub4
1311 = cmap->EncodingRecord[i].subtable.f.f4;
1314 IPRINT ("(segCountX2 %d) (searchRange %d)",
1315 sub4->segCountX2, sub4->searchRange);
1316 IPRINT ("(entrySelector %d) (rangeShift %d)",
1317 sub4->entrySelector, sub4->rangeShift);
1318 for (j = 0; j < sub4->segCountX2 / 2; j++)
1320 IPRINT ("(Segment (%d)", j);
1322 IPRINT ("(startCount #x%04X) (endCount #x%04X)",
1323 sub4->segments[j].startCount,
1324 sub4->segments[j].endCount);
1325 IPRINT ("(idDelta %d) (idRangeOffset #x%04X))",
1326 sub4->segments[j].idDelta,
1327 sub4->segments[j].idRangeOffset);
1330 IPRINT ("(glyphIdArray");
1331 for (j = 0; j < sub4->GlyphCount; j++)
1335 printf (" %3d", sub4->glyphIdArray[j]);
1343 OTF_EncodingSubtable6 *sub6
1344 = cmap->EncodingRecord[i].subtable.f.f6;
1347 IPRINT ("(firstCode %d) (entryCount %d)",
1348 sub6->firstCode, sub6->entryCount);
1349 IPRINT ("(glyphIdArray");
1350 for (j = 0; j < sub6->entryCount; j++)
1354 printf (" %3d", sub6->glyphIdArray[j]);
1362 OTF_EncodingSubtable12 *sub12
1363 = cmap->EncodingRecord[i].subtable.f.f12;
1366 for (j = 0; j < sub12->nGroups; j++)
1368 IPRINT ("(Group (#x%X) (startChar #x%04X) (endChar #x%04X) (startGlyphID #x%X))",
1370 sub12->Groups[j].startCharCode,
1371 sub12->Groups[j].endCharCode,
1372 sub12->Groups[j].startGlyphID);
1386 dump_name_table (int indent, OTF_name *name)
1392 IPRINT ("(format %d)", name->format);
1393 IPRINT ("(count %d)", name->count);
1394 IPRINT ("(stringOffset %d)", name->stringOffset);
1395 for (i = 0; i < name->count; i++)
1397 OTF_NameRecord *rec = name->nameRecord + i;
1399 IPRINT ("(nameRecord (%d)", i);
1401 IPRINT ("(platformID %d) (encodingID %d) (languageID %d) (nameID %d)",
1402 rec->platformID, rec->encodingID, rec->languageID, rec->nameID);
1403 IPRINT ("(length %d) (offset #x%04X))", rec->length, rec->offset);
1406 for (i = 0; i <= OTF_max_nameID; i++)
1408 IPRINT ("(nameID %d \"%s\")", i, name->name[i]);
1422 dump_offset_table (1, &otf->offset_table);
1423 for (i = 0; i < otf->offset_table.numTables; i++)
1424 dump_table_directory (1, otf->table_dirs + i, i);
1427 dump_head_table (1, otf->head);
1429 dump_name_table (1, otf->name);
1431 dump_cmap_table (1, otf->cmap);
1433 dump_gdef_table (1, otf->gdef);
1435 dump_gsub_table (1, otf->gsub);
1437 dump_gpos_table (1, otf->gpos);
1440 dump_base_table (1, otf->base);
1442 dump_jstf_table (1, otf->jstf);
1449 main (int argc, char **argv)
1453 if (argc != 2 || !strcmp (argv[1], "-h") || !strcmp (argv[1], "--help"))
1455 fprintf (stderr, "Usage: %s OTF-FILE\n", basename (argv[0]));
1459 otf = OTF_open (argv[1]);
1462 OTF_perror ("otfdump");
1465 OTF_get_table (otf, "head");
1466 OTF_get_table (otf, "name");
1467 OTF_get_table (otf, "cmap");
1468 OTF_get_table (otf, "GDEF");
1469 OTF_get_table (otf, "GSUB");
1470 OTF_get_table (otf, "GPOS");
1472 OTF_get_table (otf, "BASE");
1473 OTF_get_table (otf, "JSTF");