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. */
27 #include <sys/types.h>
34 char *indent_spaces[] =
35 { "", " ", " ", " ", " ", " ", " ",
39 #define IPRINT printf("\n%s", indent_spaces[indent]), printf
42 dump_tag (OTF_Tag tag)
46 putchar ((tag >> 16) & 0xFF);
47 putchar ((tag >> 8) & 0xFF);
49 printf ("\" #x%04X)", tag);
55 dump_offset_table (int indent, OTF_OffsetTable *table)
57 IPRINT ("(OffsetTable");
59 IPRINT ("(sfnt-version %d.%d)",
60 table->sfnt_version.high, table->sfnt_version.low);
61 IPRINT ("(numTables %d)", table->numTables);
62 IPRINT ("(searchRange %d)", table->searchRange);
63 IPRINT ("(enterSelector %d)", table->enterSelector);
64 IPRINT ("(rangeShift %d))", table->rangeShift);
68 dump_table_directory (int indent, OTF_TableDirectory *table, int idx)
70 IPRINT ("(Table %d ", idx);
71 dump_tag (table->tag);
73 IPRINT ("(checkSum %08X) (offset #x%08X) (length: #x%08X))",
74 table->checkSum, table->offset, table->length);
81 dump_head_table (int indent, OTF_head *head)
85 IPRINT ("(TableVersionNumber %d.%d)",
86 head->TableVersionNumber.high, head->TableVersionNumber.low);
87 IPRINT ("(fontRevision %d.%d)",
88 head->fontRevision.high, head->fontRevision.low);
89 IPRINT ("(checkSumAdjustment #x%04X)", head->checkSumAdjustment);
90 IPRINT ("(magicNumber #x%04X)", head->magicNumber);
91 IPRINT ("(flags #x%04X)", head->flags);
92 IPRINT ("(unitsPerEm %d)", head->unitsPerEm);
100 dump_glyph_ids (int indent, char *title, OTF_GlyphID *ids, unsigned count)
102 IPRINT ("(%s (count %d)", title, count);
105 printf (" #x%04X", *ids);
112 dump_coverage (int indent, char *title, OTF_Coverage *coverage)
117 IPRINT ("(%sCoverage (CoverageFormat %d)",
118 (title ? title : ""), coverage->CoverageFormat);
120 if (coverage->CoverageFormat == 1)
122 dump_glyph_ids (indent, "GlyphArray", coverage->table.GlyphArray,
124 char_list = malloc (sizeof (int) * (coverage->Count + 1));
125 for (i = 0; i < coverage->Count; i++)
126 char_list[i] = coverage->table.GlyphArray[i];
133 IPRINT ("(RangeCount %d)", coverage->Count);
135 for (i = n = 0; i < coverage->Count; i++)
137 IPRINT ("(Range (%d) (Start #x%04X) (End #x%04X)", i,
138 coverage->table.RangeRecord[i].Start,
139 coverage->table.RangeRecord[i].End);
141 IPRINT ("(StartCoverageIndex %d))",
142 coverage->table.RangeRecord[i].StartCoverageIndex);
144 n += (coverage->table.RangeRecord[i].End
145 - coverage->table.RangeRecord[i].Start + 1);
147 char_list = malloc (sizeof (int) * (n + 1));
148 for (i = n = 0; i < coverage->Count; i++)
149 for (c = coverage->table.RangeRecord[i].Start;
150 c <= coverage->table.RangeRecord[i].End;
160 dump_coverage_list (int indent, char *title,
161 OTF_Coverage *coverage, unsigned num)
165 IPRINT ("(%s %d)", title, num);
166 for (i = 0; i < num; i++)
167 free (dump_coverage (indent, NULL, coverage + i));
172 dump_language_system (int indent, int index, OTF_Tag tag, OTF_Offset offset,
173 OTF_LangSys *langsys)
177 IPRINT ("(LangSys ");
179 printf ("(%d) ", index);
183 printf ("DefaultLangSys");
184 printf (" (Offset #x%04X)", offset);
186 IPRINT ("(LookupOrder #x%04X)", langsys->LookupOrder);
187 IPRINT ("(ReqFeatureIndex %d)", langsys->ReqFeatureIndex);
188 IPRINT ("(FeatureCount %d)", langsys->FeatureCount);
189 if (langsys->FeatureCount)
191 IPRINT ("(FeatureIndex");
192 for (i = 0; i < langsys->FeatureCount; i++)
193 printf (" %d", langsys->FeatureIndex[i]);
200 dump_script_list (int indent, OTF_ScriptList *list)
204 IPRINT ("(ScriptList (count %d)", list->ScriptCount);
206 for (i = 0; i < list->ScriptCount; i++)
208 OTF_Script *script = list->Script + i;
210 IPRINT ("(Script (%d) ", i);
211 dump_tag (list->Script[i].ScriptTag);
212 printf (" (Offset #x%04X)", list->Script[i].offset);
214 IPRINT ("(DefaultLangSysOffset #x%04X)",
215 script->DefaultLangSysOffset);
216 if (script->DefaultLangSysOffset)
217 dump_language_system (indent, -1, 0,
218 script->DefaultLangSysOffset,
219 &script->DefaultLangSys);
220 IPRINT ("(LangSysCount %d)", script->LangSysCount);
221 for (j = 0; j < script->LangSysCount; j++)
222 dump_language_system (indent, j,
223 script->LangSysRecord[j].LangSysTag,
224 script->LangSysRecord[j].LangSys,
225 script->LangSys + j);
233 dump_feature_list (int indent, OTF_FeatureList *list)
237 IPRINT ("(FeatureList (count %d)", list->FeatureCount);
239 for (i = 0; i < list->FeatureCount; i++)
241 OTF_Feature *feature = list->Feature + i;
243 IPRINT ("(Feature (%d) ", i);
244 dump_tag (list->Feature[i].FeatureTag);
245 printf (" (Offset #x%04X)", list->Feature[i].offset);
246 printf (" (LookupCount %d)", feature->LookupCount);
247 if (feature->LookupCount)
250 IPRINT ("(LookupListIndex");
251 for (j = 0; j < feature->LookupCount; j++)
252 printf (" %d", feature->LookupListIndex[j]);
262 dump_class_def (int indent, char *title, OTF_ClassDef *class)
264 IPRINT ("(%s (offset #x%04X) (ClassFormat %d)",
265 (title ? title : "ClassDef"),
266 class->offset, class->ClassFormat);
270 if (class->ClassFormat == 1)
272 IPRINT ("(StartGlyph #x%04X)", class->f.f1.StartGlyph);
273 dump_glyph_ids (indent, "ClassValueArray",
274 (OTF_GlyphID *) class->f.f1.ClassValueArray,
275 class->f.f1.GlyphCount);
277 else if (class->ClassFormat == 2)
281 IPRINT ("(ClassRangeCount %d)", class->f.f2.ClassRangeCount);
282 IPRINT ("(ClassRangeRecord");
284 for (i = 0; i < class->f.f2.ClassRangeCount; i++)
285 IPRINT ("((Start #x%04X) (End #x%04X) (class %d))",
286 class->f.f2.ClassRangeRecord[i].Start,
287 class->f.f2.ClassRangeRecord[i].End,
288 class->f.f2.ClassRangeRecord[i].Class);
292 printf (" UnknownClassFormat");
298 dump_device_table (int indent, char *title, OTF_DeviceTable *table)
304 IPRINT ("(%s (offset #x%04X)", title, table->offset);
306 IPRINT ("(StartSize %d) (EndSize %d) (DeltaFormat %d)",
307 table->StartSize, table->EndSize, table->DeltaFormat);
308 IPRINT ("(DeltaValue");
309 for (i = 0; i < table->EndSize - table->StartSize + 1; i++)
310 printf (" %d", table->DeltaValue[i]);
317 dump_value_record (int indent, char *title, OTF_ValueRecord *rec)
319 IPRINT ("(%s %d %d %d %d", title,
320 rec->XPlacement, rec->YPlacement, rec->XAdvance, rec->YAdvance);
322 if (rec->XPlaDevice.offset)
323 dump_device_table (indent, "XPlaDevice", &rec->XPlaDevice);
324 if (rec->YPlaDevice.offset)
325 dump_device_table (indent, "YPlaDevice", &rec->YPlaDevice);
326 if (rec->XAdvDevice.offset)
327 dump_device_table (indent, "XAdvDevice", &rec->XAdvDevice);
328 if (rec->YAdvDevice.offset)
329 dump_device_table (indent, "YAdvDevice", &rec->YAdvDevice);
335 dump_sequence_list (int indent, OTF_Sequence *sequence, unsigned num)
338 IPRINT ("(SequenceCount %d)", num);
340 for (i = 0; i < num; i++)
342 IPRINT ("(Sequence (%d) (offset #x%04X)",
343 i, sequence[i].offset);
344 dump_glyph_ids (indent + 1, "Substitute", sequence[i].Substitute,
345 sequence[i].GlyphCount);
351 dump_alternate_set_list (int indent, OTF_AlternateSet *altset, unsigned num)
355 IPRINT ("(AlternateSetCount %d)", num);
356 for (i = 0; i < num; i++)
358 IPRINT ("(AlternateSet (%d) (offset #x%04X)",
359 i, altset[i].offset);
360 dump_glyph_ids (indent + 1, "Alternate", altset[i].Alternate,
361 altset[i].GlyphCount);
368 dump_ligature_set_list (int indent, int *char_list,
369 OTF_LigatureSet *ligset, unsigned num)
373 IPRINT ("(LigSetCount %d)", num);
374 for (i = 0; i < num; i++)
376 IPRINT ("(LigatureSet (%d) (offset #x%04X) (count %d)",
377 i, ligset[i].offset, ligset[i].LigatureCount);
379 for (j = 0; j < ligset[i].LigatureCount; j++)
381 IPRINT ("(Ligature (%d) (offset #x%04X)",
382 j, ligset[i].Ligature[j].offset);
384 IPRINT ("(LigGlyph #x%04X)",
385 ligset[i].Ligature[j].LigGlyph);
386 dump_glyph_ids (indent, "Component", ligset[i].Ligature[j].Component,
387 ligset[i].Ligature[j].CompCount - 1);
388 IPRINT ("(i.e. #x%04X", char_list[i]);
389 for (k = 0; k < ligset[i].Ligature[j].CompCount - 1; k++)
390 printf (" #x%04X", ligset[i].Ligature[j].Component[k]);
391 printf (" = #x%04X)", ligset[i].Ligature[j].LigGlyph);
401 dump_pair_set_list (int indent, unsigned count, OTF_PairSet *set)
405 for (i = 0; i < count; i++)
407 IPRINT ("(PairSet (%d)", i);
409 for (j = 0; j < set[i].PairValueCount; j++)
411 IPRINT ("(PairValueRecord (%d)", j);
413 IPRINT ("(SecondGlyph #x%04X)",
414 set[i].PairValueRecord[j].SecondGlyph);
415 dump_value_record (indent, "Value1",
416 &set[i].PairValueRecord[j].Value1);
417 dump_value_record (indent, "Value2",
418 &set[i].PairValueRecord[j].Value2);
428 dump_class1_record_list (int indent,
429 unsigned Class1Count, unsigned Class2Count,
430 OTF_Class1Record *rec)
434 for (i = 0; i < Class1Count; i++)
436 IPRINT ("(Class1Record (%d)", i);
438 for (j = 0; j < Class2Count; j++)
440 IPRINT ("(Class2Record (%d)", j);
442 dump_value_record (indent, "Value1", &rec[i].Class2Record[j].Value1);
443 dump_value_record (indent, "Value2", &rec[i].Class2Record[j].Value2);
453 dump_anchor (int indent, OTF_Anchor *anchor)
455 IPRINT ("(Anchor (offset #x%04X) (AnchorFormat %d)",
456 anchor->offset, anchor->AnchorFormat);
458 IPRINT ("(XCoordinate %d) (YCoordinate %d)",
459 anchor->XCoordinate, anchor->YCoordinate);
460 if (anchor->AnchorFormat == 1)
462 else if (anchor->AnchorFormat == 2)
463 IPRINT ("(AnchorPoint %d)", anchor->f.f1.AnchorPoint);
466 dump_device_table (indent, "XDeviceTable", &anchor->f.f2.XDeviceTable);
467 dump_device_table (indent, "YDeviceTable", &anchor->f.f2.YDeviceTable);
473 dump_entry_exit_list (int indent, unsigned count, OTF_EntryExitRecord *rec)
477 for (i = 0; i < count; i++)
479 IPRINT ("(EntryExitRecord (%d)", i);
481 dump_anchor (indent, &rec[i].EntryAnchor);
482 dump_anchor (indent, &rec[i].EntryAnchor);
489 dump_mark_array (int indent, OTF_MarkArray *array)
493 IPRINT ("(MarkArray (MarkCount %d)", array->MarkCount);
495 for (i = 0; i < array->MarkCount; i++)
497 IPRINT ("(MarkRecord (%d) (Class %d)", i, array->MarkRecord[i].Class);
498 dump_anchor (indent + 1, &array->MarkRecord[i].MarkAnchor);
505 dump_anchor_array (int indent, unsigned ClassCount, OTF_AnchorArray *array)
509 IPRINT ("(AnchorArray (Count %d)", array->Count);
511 for (i = 0; i < array->Count; i++)
513 IPRINT ("(AnchorRecord (%d) ", i);
514 for (j = 0; j < ClassCount; j++)
515 dump_anchor (indent + 1, array->AnchorRecord[i].Anchor + j);
523 dump_lookup_record_list (int indent, OTF_LookupRecord *rec, unsigned num)
527 IPRINT ("(LookupCount %d)", num);
528 for (i = 0; i < num; i++)
530 IPRINT ("(LookupRecord (%d)", i);
532 IPRINT ("(SequenceIndex %d)", rec[i].SequenceIndex);
533 IPRINT ("(LookupListIndex %d))", rec[i].LookupListIndex);
539 static void dump_lookup_subtable_gsub (int indent, int index, unsigned type,
540 OTF_LookupSubTableGSUB *subtable);
541 static void dump_lookup_subtable_gpos (int indent, int index, unsigned type,
542 OTF_LookupSubTableGPOS *subtable);
546 dump_lookup_list (int indent, OTF_LookupList *list, int gsub)
550 IPRINT ("(LookupList (count %d)", list->LookupCount);
552 for (i = 0; i < list->LookupCount; i++)
554 OTF_Lookup *lookup = list->Lookup + i;
556 IPRINT ("(Lookup (%d) (Offset #x%04X)",
558 printf (" (Type %d) (Flag #x%04X) (SubTableCount %d)",
559 lookup->LookupType, lookup->LookupFlag, lookup->SubTableCount);
561 for (j = 0; j < lookup->SubTableCount; j++)
562 dump_lookup_subtable_gsub (indent + 1, j,
564 lookup->SubTable.gsub + j);
566 for (j = 0; j < lookup->SubTableCount; j++)
567 dump_lookup_subtable_gpos (indent + 1, j,
569 lookup->SubTable.gpos + j);
577 dump_rule_list (int indent, OTF_Rule *rule, int count)
581 IPRINT ("(RuleCount %d)", count);
582 for (i = 0; i < count; i++)
584 IPRINT ("(Rule (%d)", i);
586 IPRINT ("(GlyphCount %d)", rule[i].GlyphCount);
587 IPRINT ("(LookupCount %d)", rule[i].LookupCount);
588 dump_glyph_ids (indent, "Input", rule[i].Input, rule[i].GlyphCount - 1);
589 dump_lookup_record_list (indent, rule[i].LookupRecord,
590 rule[i].LookupCount);
597 dump_rule_set_list (int indent, OTF_RuleSet *set, int count)
601 IPRINT ("(RuleSetCount %d)", count);
602 for (i = 0; i < count; i++)
604 IPRINT ("(RuleSet (%d)", i);
605 dump_rule_list (indent + 1, set[i].Rule, set[i].RuleCount);
611 dump_class_rule_list (int indent, OTF_ClassRule *rule, int count)
615 IPRINT ("(ClassRuleCnt %d)", count);
616 for (i = 0; i < count; i++)
618 IPRINT ("(ClassRule (%d)", i);
620 IPRINT ("(GlyphCount %d)", rule[i].GlyphCount);
621 IPRINT ("(LookupCount %d)", rule[i].LookupCount);
623 for (j = 0; j < rule[i].GlyphCount - 1; j++)
624 printf (" %d", rule[i].Class[j]);
626 dump_lookup_record_list (indent, rule[i].LookupRecord,
627 rule[i].LookupCount);
634 dump_class_set_list (int indent, OTF_ClassSet *set, int count)
638 IPRINT ("(ClassSetCount %d)", count);
639 for (i = 0; i < count; i++)
642 IPRINT ("(ClassSet (%d)", i);
643 dump_class_rule_list (indent + 1, set[i].ClassRule,
644 set[i].ClassRuleCnt);
650 dump_chain_rule_list (int indent, OTF_ChainRule *rule, int count)
654 IPRINT ("(ChainRuleCount %d)", count);
655 for (i = 0; i < count; i++)
657 IPRINT ("(ChainRule (%d)", i);
658 dump_glyph_ids (indent + 1, "Backtrack",
659 rule[i].Backtrack, rule[i].BacktrackGlyphCount);
660 dump_glyph_ids (indent + 1, "Input",
661 rule[i].Input, rule[i].InputGlyphCount - 1);
662 dump_glyph_ids (indent + 1, "LookAhead",
663 rule[i].LookAhead, rule[i].LookaheadGlyphCount);
664 dump_lookup_record_list (indent + 1, rule[i].LookupRecord,
665 rule[i].LookupCount);
671 dump_chain_rule_set_list (int indent, OTF_ChainRuleSet *set, int count)
675 IPRINT ("(ChainRuleSetCount %d)", count);
676 for (i = 0; i < count; i++)
678 IPRINT ("(ChainRuleSet (%d)", i);
679 dump_chain_rule_list (indent + 1,
680 set[i].ChainRule, set[i].ChainRuleCount);
686 dump_chain_class_rule_list (int indent, OTF_ChainClassRule *rule, int count)
690 IPRINT ("(ChainClassRuleCount %d)", count);
691 for (i = 0; i < count; i++)
693 IPRINT ("(ChainClassRule (%d)", i);
694 dump_glyph_ids (indent + 1, "Backtrack",
695 rule[i].Backtrack, rule[i].BacktrackGlyphCount);
696 dump_glyph_ids (indent + 1, "Input",
697 rule[i].Input, rule[i].InputGlyphCount - 1);
698 dump_glyph_ids (indent + 1, "LookAhead",
699 rule[i].LookAhead, rule[i].LookaheadGlyphCount);
700 dump_lookup_record_list (indent + 1, rule[i].LookupRecord,
701 rule[i].LookupCount);
707 dump_chain_class_set_list (int indent, OTF_ChainClassSet *set, int count)
711 IPRINT ("(ChainClassSetCount %d)", count);
712 for (i = 0; i < count; i++)
714 IPRINT ("(ChainClassSet (%d)", i);
715 dump_chain_class_rule_list (indent + 1,
716 set[i].ChainClassRule,
717 set[i].ChainClassRuleCnt);
729 dump_lookup_subtable_gsub (int indent, int index, unsigned type,
730 OTF_LookupSubTableGSUB *subtable)
732 IPRINT ("(SubTable (%d) (Format %d)", index, subtable->Format);
737 if (subtable->Format == 1)
739 free (dump_coverage (indent, NULL, &subtable->Coverage));
740 IPRINT ("(DeltaGlyhpID #x%04X)",
741 subtable->u.single1.DeltaGlyphID);
743 else if (subtable->Format == 2)
745 free (dump_coverage (indent, NULL, &subtable->Coverage));
746 dump_glyph_ids (indent, "Substitute", subtable->u.single2.Substitute,
747 subtable->u.single2.GlyphCount);
754 if (subtable->Format == 1)
756 free (dump_coverage (indent, NULL, &subtable->Coverage));
757 dump_sequence_list (indent,
758 subtable->u.multiple1.Sequence,
759 subtable->u.multiple1.SequenceCount);
766 if (subtable->Format == 1)
768 free (dump_coverage (indent, NULL, &subtable->Coverage));
769 dump_alternate_set_list (indent, subtable->u.alternate1.AlternateSet,
770 subtable->u.alternate1.AlternateSetCount);
777 if (subtable->Format == 1)
779 int *char_list = dump_coverage (indent, NULL, &subtable->Coverage);
780 dump_ligature_set_list (indent, char_list,
781 subtable->u.ligature1.LigatureSet,
782 subtable->u.ligature1.LigSetCount);
790 if (subtable->Format == 1)
792 free (dump_coverage (indent, NULL, &subtable->Coverage));
793 dump_rule_set_list (indent, subtable->u.context1.RuleSet,
794 subtable->u.context1.RuleSetCount);
796 else if (subtable->Format == 2)
798 free (dump_coverage (indent, NULL, &subtable->Coverage));
799 dump_class_def (indent, NULL, &subtable->u.context2.ClassDef);
800 dump_class_set_list (indent, subtable->u.context2.ClassSet,
801 subtable->u.context2.ClassSetCnt);
803 else if (subtable->Format == 3)
805 dump_coverage_list (indent, "Coverage",
806 subtable->u.context3.Coverage,
807 subtable->u.context3.GlyphCount);
808 dump_lookup_record_list (indent,
809 subtable->u.context3.LookupRecord,
810 subtable->u.context3.LookupCount);
817 if (subtable->Format == 1)
819 free (dump_coverage (indent, NULL, &subtable->Coverage));
820 dump_chain_rule_set_list
822 subtable->u.chain_context1.ChainRuleSet,
823 subtable->u.chain_context1.ChainRuleSetCount);
825 else if (subtable->Format == 2)
827 free (dump_coverage (indent, NULL, &subtable->Coverage));
828 dump_class_def (indent, "BacktrackClassDef",
829 &subtable->u.chain_context2.BacktrackClassDef);
830 dump_class_def (indent, "InputClassDef",
831 &subtable->u.chain_context2.InputClassDef);
832 dump_class_def (indent, "LookaheadClassDef",
833 &subtable->u.chain_context2.LookaheadClassDef);
834 dump_chain_class_set_list
836 subtable->u.chain_context2.ChainClassSet,
837 subtable->u.chain_context2.ChainClassSetCnt);
839 else if (subtable->Format == 3)
842 (indent, "BackTrackGlyphCount",
843 subtable->u.chain_context3.Backtrack,
844 subtable->u.chain_context3.BacktrackGlyphCount);
846 (indent, "InputGlyphCount",
847 subtable->u.chain_context3.Input,
848 subtable->u.chain_context3.InputGlyphCount);
850 (indent, "LookaheadGlyphCount",
851 subtable->u.chain_context3.LookAhead,
852 subtable->u.chain_context3.LookaheadGlyphCount);
853 dump_lookup_record_list
855 subtable->u.chain_context3.LookupRecord,
856 subtable->u.chain_context3.LookupCount);
863 IPRINT ("(ExtensionLookupType %d)",
864 subtable->u.extension1.ExtensionLookupType);
865 IPRINT ("(ExtensionOffset %d)",
866 subtable->u.extension1.ExtensionOffset);
867 dump_lookup_subtable_gsub (indent, index,
868 subtable->u.extension1.ExtensionLookupType,
869 subtable->u.extension1.ExtensionSubtable);
873 printf (" not-yet-supported");
883 dump_gsub_table (int indent, OTF_GSUB *gsub)
889 IPRINT ("(Version %d.%d)", gsub->Version.high, gsub->Version.low);
890 IPRINT ("(ScriptList #x%04X)", gsub->ScriptList.offset);
891 IPRINT ("(FeatureList #x%04X)", gsub->FeatureList.offset);
892 IPRINT ("(LookupList #x%04X))", gsub->LookupList.offset);
894 dump_script_list (indent, &gsub->ScriptList);
895 dump_feature_list (indent, &gsub->FeatureList);
896 dump_lookup_list (indent, &gsub->LookupList, 1);
904 dump_lookup_subtable_gpos (int indent, int index, unsigned type,
905 OTF_LookupSubTableGPOS *subtable)
907 IPRINT ("(SubTable (%d) (Format %d)", index, subtable->Format);
912 if (subtable->Format == 1)
914 free (dump_coverage (indent, NULL, &subtable->Coverage));
915 IPRINT ("(ValueFormat #x%04X)",
916 subtable->u.single1.ValueFormat);
917 dump_value_record (indent, "Value", &subtable->u.single1.Value);
919 else if (subtable->Format == 2)
923 free (dump_coverage (indent, NULL, &subtable->Coverage));
924 IPRINT ("(ValueFormat #x%04X)",
925 subtable->u.single2.ValueFormat);
926 IPRINT ("(ValueCount %d)",
927 subtable->u.single2.ValueCount);
928 for (i = 0; i < subtable->u.single2.ValueCount; i++)
929 dump_value_record (indent, "Value", &subtable->u.single2.Value[i]);
936 if (subtable->Format == 1)
938 free (dump_coverage (indent, NULL, &subtable->Coverage));
939 IPRINT ("(ValueFormat1 #x%04X)",
940 subtable->u.pair1.ValueFormat1);
941 IPRINT ("(ValueFormat2 #x%04X)",
942 subtable->u.pair1.ValueFormat2);
943 dump_pair_set_list (indent, subtable->u.pair1.PairSetCount,
944 subtable->u.pair1.PairSet);
946 else if (subtable->Format == 2)
948 free (dump_coverage (indent, NULL, &subtable->Coverage));
949 IPRINT ("(ValueFormat1 #x%04X)",
950 subtable->u.pair2.ValueFormat1);
951 IPRINT ("(ValueFormat2 #x%04X)",
952 subtable->u.pair2.ValueFormat2);
953 dump_class_def (indent, "ClassDef1",
954 &subtable->u.pair2.ClassDef1);
955 dump_class_def (indent, "ClassDef2",
956 &subtable->u.pair2.ClassDef2);
957 IPRINT ("(Class1Count %d)",
958 subtable->u.pair2.Class1Count);
959 IPRINT ("(Class2Count %d)",
960 subtable->u.pair2.Class2Count);
961 dump_class1_record_list (indent,
962 subtable->u.pair2.Class1Count,
963 subtable->u.pair2.Class2Count,
964 subtable->u.pair2.Class1Record);
971 if (subtable->Format == 1)
973 free (dump_coverage (indent, NULL, &subtable->Coverage));
974 dump_entry_exit_list (indent, subtable->u.cursive1.EntryExitCount,
975 subtable->u.cursive1.EntryExitRecord);
982 if (subtable->Format == 1)
984 free (dump_coverage (indent, "Mark", &subtable->Coverage));
985 free (dump_coverage (indent, "Base",
986 &subtable->u.mark_base1.BaseCoverage));
987 IPRINT ("(ClassCount %d)",
988 subtable->u.mark_base1.ClassCount);
989 dump_mark_array (indent, &subtable->u.mark_base1.MarkArray);
990 dump_anchor_array (indent, subtable->u.mark_base1.ClassCount,
991 &subtable->u.mark_base1.BaseArray);
996 if (subtable->Format == 1)
998 printf (" not-yet-supported");
1001 printf (" invalid");
1005 if (subtable->Format == 1)
1007 free (dump_coverage (indent, "Mark1", &subtable->Coverage));
1008 free (dump_coverage (indent, "Mark2",
1009 &subtable->u.mark_mark1.Mark2Coverage));
1010 IPRINT ("(ClassCount %d)",
1011 subtable->u.mark_mark1.ClassCount);
1012 dump_mark_array (indent, &subtable->u.mark_mark1.Mark1Array);
1013 dump_anchor_array (indent, subtable->u.mark_mark1.ClassCount,
1014 &subtable->u.mark_mark1.Mark2Array);
1017 printf (" invalid");
1021 if (subtable->Format == 1)
1023 free (dump_coverage (indent, NULL, &subtable->Coverage));
1024 dump_rule_set_list (indent, subtable->u.context1.RuleSet,
1025 subtable->u.context1.RuleSetCount);
1027 else if (subtable->Format == 2)
1029 free (dump_coverage (indent, NULL, &subtable->Coverage));
1030 dump_class_def (indent, NULL, &subtable->u.context2.ClassDef);
1031 dump_class_set_list (indent, subtable->u.context2.ClassSet,
1032 subtable->u.context2.ClassSetCnt);
1034 else if (subtable->Format == 3)
1036 dump_coverage_list (indent, "Coverage",
1037 subtable->u.context3.Coverage,
1038 subtable->u.context3.GlyphCount);
1039 dump_lookup_record_list (indent,
1040 subtable->u.context3.LookupRecord,
1041 subtable->u.context3.LookupCount);
1044 printf (" invalid");
1048 if (subtable->Format == 1)
1050 free (dump_coverage (indent, NULL, &subtable->Coverage));
1051 dump_chain_rule_set_list
1053 subtable->u.chain_context1.ChainRuleSet,
1054 subtable->u.chain_context1.ChainRuleSetCount);
1056 else if (subtable->Format == 2)
1058 free (dump_coverage (indent, NULL, &subtable->Coverage));
1059 dump_class_def (indent, "BacktrackClassDef",
1060 &subtable->u.chain_context2.BacktrackClassDef);
1061 dump_class_def (indent, "InputClassDef",
1062 &subtable->u.chain_context2.InputClassDef);
1063 dump_class_def (indent, "LookaheadClassDef",
1064 &subtable->u.chain_context2.LookaheadClassDef);
1065 dump_chain_class_set_list
1067 subtable->u.chain_context2.ChainClassSet,
1068 subtable->u.chain_context2.ChainClassSetCnt);
1070 else if (subtable->Format == 3)
1073 (indent, "BackTrackGlyphCount",
1074 subtable->u.chain_context3.Backtrack,
1075 subtable->u.chain_context3.BacktrackGlyphCount);
1077 (indent, "InputGlyphCount",
1078 subtable->u.chain_context3.Input,
1079 subtable->u.chain_context3.InputGlyphCount);
1081 (indent, "LookaheaGlyphCount",
1082 subtable->u.chain_context3.LookAhead,
1083 subtable->u.chain_context3.LookaheadGlyphCount);
1084 dump_lookup_record_list
1086 subtable->u.chain_context3.LookupRecord,
1087 subtable->u.chain_context3.LookupCount);
1090 printf (" invalid");
1094 if (subtable->Format == 1)
1096 IPRINT ("(ExtensionLookupType %d)",
1097 subtable->u.extension1.ExtensionLookupType);
1098 IPRINT ("(ExtensionOffset %d)",
1099 subtable->u.extension1.ExtensionOffset);
1100 dump_lookup_subtable_gpos
1102 subtable->u.extension1.ExtensionLookupType,
1103 subtable->u.extension1.ExtensionSubtable);
1106 printf (" invalid");
1113 dump_gpos_table (int indent, OTF_GPOS *gpos)
1121 IPRINT ("(Version %d.%d)", gpos->Version.high, gpos->Version.low);
1122 IPRINT ("(ScriptList #x%04X)", gpos->ScriptList.offset);
1123 IPRINT ("(FeatureList #x%04X)", gpos->FeatureList.offset);
1124 IPRINT ("(LookupList #x%04X))", gpos->LookupList.offset);
1126 dump_script_list (indent, &gpos->ScriptList);
1127 dump_feature_list (indent, &gpos->FeatureList);
1128 dump_lookup_list (indent, &gpos->LookupList, 0);
1134 dump_base_table (OTF_BASE *base)
1139 dump_jstf_table (OTF_JSTF *jstf)
1147 dump_gdef_header (int indent, OTF_GDEFHeader *header)
1151 IPRINT ("(Version %d.%d)",
1152 header->Version.high, header->Version.low);
1153 IPRINT ("(GlyphClassDef #x%04X)", header->GlyphClassDef);
1154 IPRINT ("(AttachList #x%04X)", header->AttachList);
1155 IPRINT ("(LigCaretList #x%04X)", header->LigCaretList);
1156 IPRINT ("(MarkAttachClassDef #x%04X))",
1157 header->MarkAttachClassDef);
1161 dump_attach_list (int indent, OTF_AttachList *list)
1166 dump_lig_caret_list (int indent, OTF_LigCaretList *list)
1170 IPRINT ("(LigCaretList");
1172 free (dump_coverage (indent, NULL, &list->Coverage));
1173 IPRINT ("(LigGlyphCount %d)", list->LigGlyphCount);
1174 for (i = 0; i < list->LigGlyphCount; i++)
1176 IPRINT ("(LigGlyph (%d) (offset #x%04X)",
1177 i, list->LigGlyph[i].offset);
1179 IPRINT ("(CaretCount %d)", list->LigGlyph[i].CaretCount);
1180 for (j = 0; j < list->LigGlyph[i].CaretCount; j++)
1182 unsigned format = list->LigGlyph[i].CaretValue[j].CaretValueFormat;
1184 IPRINT ("(Caret (%d) (CaretValueFormat %d)", j, format);
1187 printf ("(Coordinate %d)",
1188 list->LigGlyph[i].CaretValue[j].f.f1.Coordinate);
1190 else if (format == 2)
1192 printf ("(CaretValuePoint %d)",
1193 list->LigGlyph[i].CaretValue[j].f.f2.CaretValuePoint);
1195 else if (format == 3)
1197 printf ("(Coodinate %d)",
1198 list->LigGlyph[i].CaretValue[j].f.f3.Coordinate);
1201 (indent, "DeviceTable",
1202 &list->LigGlyph[i].CaretValue[j].f.f3.DeviceTable);
1214 dump_gdef_table (int indent, OTF_GDEF *gdef)
1220 dump_gdef_header (indent, &gdef->header);
1221 if (gdef->header.GlyphClassDef)
1222 dump_class_def (indent, "GlyphClassDef", &gdef->glyph_class_def);
1223 if (gdef->header.AttachList)
1224 dump_attach_list (indent, &gdef->attach_list);
1225 if (gdef->header.LigCaretList)
1226 dump_lig_caret_list (indent, &gdef->lig_caret_list);
1227 if (gdef->header.MarkAttachClassDef)
1228 dump_class_def (indent, "MarkAttachClassDef",
1229 &gdef->mark_attach_class_def);
1236 dump_cmap_table (int indent, OTF_cmap *cmap)
1242 IPRINT ("(version %d)", cmap->version);
1243 IPRINT ("(numTables %d)", cmap->numTables);
1244 for (i = 0; i < cmap->numTables; i++)
1246 IPRINT ("(EncodingRecord (%d) (platformID %d) (encodingID %d)",
1248 cmap->EncodingRecord[i].platformID,
1249 cmap->EncodingRecord[i].encodingID);
1251 IPRINT ("(Subtable (offset #x%04X) (format %d) (length #x%04X) (language %d)",
1252 cmap->EncodingRecord[i].offset,
1253 cmap->EncodingRecord[i].subtable.format,
1254 cmap->EncodingRecord[i].subtable.length,
1255 cmap->EncodingRecord[i].subtable.language);
1257 switch (cmap->EncodingRecord[i].subtable.format)
1262 unsigned char *array
1263 = cmap->EncodingRecord[i].subtable.f.f0->glyphIdArray;
1265 IPRINT ("(glyphIdArray");
1266 for (j = 0; j < 16; j++)
1269 for (k = 0; k < 16; k++)
1270 printf (" %3d", array[j * 16 + k]);
1278 OTF_EncodingSubtable4 *sub4
1279 = cmap->EncodingRecord[i].subtable.f.f4;
1282 IPRINT ("(segCountX2 %d) (searchRange %d)",
1283 sub4->segCountX2, sub4->searchRange);
1284 IPRINT ("(entrySelector %d) (rangeShift %d)",
1285 sub4->entrySelector, sub4->rangeShift);
1286 for (j = 0; j < sub4->segCountX2 / 2; j++)
1288 IPRINT ("(Segment (%d)", j);
1290 IPRINT ("(startCount #x%04X) (endCount #x%04X)",
1291 sub4->segments[j].startCount,
1292 sub4->segments[j].endCount);
1293 IPRINT ("(idDelta %d) (idRangeOffset #x%04X))",
1294 sub4->segments[j].idDelta,
1295 sub4->segments[j].idRangeOffset);
1298 IPRINT ("(glyphIdArray");
1299 for (j = 0; j < sub4->GlyphCount; j++)
1303 printf (" %3d", sub4->glyphIdArray[j]);
1311 OTF_EncodingSubtable6 *sub6
1312 = cmap->EncodingRecord[i].subtable.f.f6;
1315 IPRINT ("(firstCode %d) (entryCount %d)",
1316 sub6->firstCode, sub6->entryCount);
1317 IPRINT ("(glyphIdArray");
1318 for (j = 0; j < sub6->entryCount; j++)
1322 printf (" %3d", sub6->glyphIdArray[j]);
1338 dump_name_table (int indent, OTF_name *name)
1344 IPRINT ("(format %d)", name->format);
1345 IPRINT ("(count %d)", name->count);
1346 IPRINT ("(stringOffset %d)", name->stringOffset);
1347 for (i = 0; i < name->count; i++)
1349 OTF_NameRecord *rec = name->nameRecord + i;
1351 IPRINT ("(nameRecord (%d)", i);
1353 IPRINT ("(platformID %d) (encodingID %d) (languageID %d) (nameID %d)",
1354 rec->platformID, rec->encodingID, rec->languageID, rec->nameID);
1355 IPRINT ("(length %d) (offset #x%04X))", rec->length, rec->offset);
1358 for (i = 0; i <= OTF_max_nameID; i++)
1360 IPRINT ("(nameID %d \"%s\")", i, name->name[i]);
1374 dump_offset_table (1, &otf->offset_table);
1375 for (i = 0; i < otf->offset_table.numTables; i++)
1376 dump_table_directory (1, otf->table_dirs + i, i);
1379 dump_head_table (1, otf->head);
1381 dump_name_table (1, otf->name);
1383 dump_cmap_table (1, otf->cmap);
1385 dump_gdef_table (1, otf->gdef);
1387 dump_gsub_table (1, otf->gsub);
1389 dump_gpos_table (1, otf->gpos);
1392 dump_base_table (1, otf->base);
1394 dump_jstf_table (1, otf->jstf);
1401 main (int argc, char **argv)
1405 if (argc != 2 || !strcmp (argv[1], "-h") || !strcmp (argv[1], "--help"))
1407 fprintf (stderr, "Usage: %s OTF-FILE\n", basename (argv[0]));
1411 otf = OTF_open (argv[1]);
1414 OTF_perror ("otfdump");
1417 OTF_get_table (otf, "head");
1418 OTF_get_table (otf, "name");
1419 OTF_get_table (otf, "cmap");
1420 OTF_get_table (otf, "GDEF");
1421 OTF_get_table (otf, "GSUB");
1422 OTF_get_table (otf, "GPOS");
1424 OTF_get_table (otf, "BASE");
1425 OTF_get_table (otf, "JSTF");