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,
870 + subtable->u.extension1.ExtensionOffset));
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 printf (" not-yet-supported");
1002 printf (" invalid");
1006 if (subtable->Format == 1)
1008 free (dump_coverage (indent, "Mark1", &subtable->Coverage));
1009 free (dump_coverage (indent, "Mark2",
1010 &subtable->u.mark_mark1.Mark2Coverage));
1011 IPRINT ("(ClassCount %d)",
1012 subtable->u.mark_mark1.ClassCount);
1013 dump_mark_array (indent, &subtable->u.mark_mark1.Mark1Array);
1014 dump_anchor_array (indent, subtable->u.mark_mark1.ClassCount,
1015 &subtable->u.mark_mark1.Mark2Array);
1018 printf (" invalid");
1022 if (subtable->Format == 1)
1024 free (dump_coverage (indent, NULL, &subtable->Coverage));
1025 dump_rule_set_list (indent, subtable->u.context1.RuleSet,
1026 subtable->u.context1.RuleSetCount);
1028 else if (subtable->Format == 2)
1030 free (dump_coverage (indent, NULL, &subtable->Coverage));
1031 dump_class_def (indent, NULL, &subtable->u.context2.ClassDef);
1032 dump_class_set_list (indent, subtable->u.context2.ClassSet,
1033 subtable->u.context2.ClassSetCnt);
1035 else if (subtable->Format == 3)
1037 dump_coverage_list (indent, "Coverage",
1038 subtable->u.context3.Coverage,
1039 subtable->u.context3.GlyphCount);
1040 dump_lookup_record_list (indent,
1041 subtable->u.context3.LookupRecord,
1042 subtable->u.context3.LookupCount);
1045 printf (" invalid");
1049 if (subtable->Format == 1)
1051 free (dump_coverage (indent, NULL, &subtable->Coverage));
1052 dump_chain_rule_set_list
1054 subtable->u.chain_context1.ChainRuleSet,
1055 subtable->u.chain_context1.ChainRuleSetCount);
1057 else if (subtable->Format == 2)
1059 free (dump_coverage (indent, NULL, &subtable->Coverage));
1060 dump_class_def (indent, "BacktrackClassDef",
1061 &subtable->u.chain_context2.BacktrackClassDef);
1062 dump_class_def (indent, "InputClassDef",
1063 &subtable->u.chain_context2.InputClassDef);
1064 dump_class_def (indent, "LookaheadClassDef",
1065 &subtable->u.chain_context2.LookaheadClassDef);
1066 dump_chain_class_set_list
1068 subtable->u.chain_context2.ChainClassSet,
1069 subtable->u.chain_context2.ChainClassSetCnt);
1071 else if (subtable->Format == 3)
1074 (indent, "BackTrackGlyphCount",
1075 subtable->u.chain_context3.Backtrack,
1076 subtable->u.chain_context3.BacktrackGlyphCount);
1078 (indent, "InputGlyphCount",
1079 subtable->u.chain_context3.Input,
1080 subtable->u.chain_context3.InputGlyphCount);
1082 (indent, "LookaheaGlyphCount",
1083 subtable->u.chain_context3.LookAhead,
1084 subtable->u.chain_context3.LookaheadGlyphCount);
1085 dump_lookup_record_list
1087 subtable->u.chain_context3.LookupRecord,
1088 subtable->u.chain_context3.LookupCount);
1091 printf (" invalid");
1099 dump_gpos_table (int indent, OTF_GPOS *gpos)
1107 IPRINT ("(Version %d.%d)", gpos->Version.high, gpos->Version.low);
1108 IPRINT ("(ScriptList #x%04X)", gpos->ScriptList.offset);
1109 IPRINT ("(FeatureList #x%04X)", gpos->FeatureList.offset);
1110 IPRINT ("(LookupList #x%04X))", gpos->LookupList.offset);
1112 dump_script_list (indent, &gpos->ScriptList);
1113 dump_feature_list (indent, &gpos->FeatureList);
1114 dump_lookup_list (indent, &gpos->LookupList, 0);
1120 dump_base_table (OTF_BASE *base)
1125 dump_jstf_table (OTF_JSTF *jstf)
1133 dump_gdef_header (int indent, OTF_GDEFHeader *header)
1137 IPRINT ("(Version %d.%d)",
1138 header->Version.high, header->Version.low);
1139 IPRINT ("(GlyphClassDef #x%04X)", header->GlyphClassDef);
1140 IPRINT ("(AttachList #x%04X)", header->AttachList);
1141 IPRINT ("(LigCaretList #x%04X)", header->LigCaretList);
1142 IPRINT ("(MarkAttachClassDef #x%04X))",
1143 header->MarkAttachClassDef);
1147 dump_attach_list (int indent, OTF_AttachList *list)
1152 dump_lig_caret_list (int indent, OTF_LigCaretList *list)
1156 IPRINT ("(LigCaretList");
1158 free (dump_coverage (indent, NULL, &list->Coverage));
1159 IPRINT ("(LigGlyphCount %d)", list->LigGlyphCount);
1160 for (i = 0; i < list->LigGlyphCount; i++)
1162 IPRINT ("(LigGlyph (%d) (offset #x%04X)",
1163 i, list->LigGlyph[i].offset);
1165 IPRINT ("(CaretCount %d)", list->LigGlyph[i].CaretCount);
1166 for (j = 0; j < list->LigGlyph[i].CaretCount; j++)
1168 unsigned format = list->LigGlyph[i].CaretValue[j].CaretValueFormat;
1170 IPRINT ("(Caret (%d) (CaretValueFormat %d)", j, format);
1173 printf ("(Coordinate %d)",
1174 list->LigGlyph[i].CaretValue[j].f.f1.Coordinate);
1176 else if (format == 2)
1178 printf ("(CaretValuePoint %d)",
1179 list->LigGlyph[i].CaretValue[j].f.f2.CaretValuePoint);
1181 else if (format == 3)
1183 printf ("(Coodinate %d)",
1184 list->LigGlyph[i].CaretValue[j].f.f3.Coordinate);
1187 (indent, "DeviceTable",
1188 &list->LigGlyph[i].CaretValue[j].f.f3.DeviceTable);
1200 dump_gdef_table (int indent, OTF_GDEF *gdef)
1206 dump_gdef_header (indent, &gdef->header);
1207 if (gdef->header.GlyphClassDef)
1208 dump_class_def (indent, "GlyphClassDef", &gdef->glyph_class_def);
1209 if (gdef->header.AttachList)
1210 dump_attach_list (indent, &gdef->attach_list);
1211 if (gdef->header.LigCaretList)
1212 dump_lig_caret_list (indent, &gdef->lig_caret_list);
1213 if (gdef->header.MarkAttachClassDef)
1214 dump_class_def (indent, "MarkAttachClassDef",
1215 &gdef->mark_attach_class_def);
1222 dump_cmap_table (int indent, OTF_cmap *cmap)
1228 IPRINT ("(version %d)", cmap->version);
1229 IPRINT ("(numTables %d)", cmap->numTables);
1230 for (i = 0; i < cmap->numTables; i++)
1232 IPRINT ("(EncodingRecord (%d) (platformID %d) (encodingID %d)",
1234 cmap->EncodingRecord[i].platformID,
1235 cmap->EncodingRecord[i].encodingID);
1237 IPRINT ("(Subtable (offset #x%04X) (format %d) (length #x%04X) (language %d)",
1238 cmap->EncodingRecord[i].offset,
1239 cmap->EncodingRecord[i].subtable.format,
1240 cmap->EncodingRecord[i].subtable.length,
1241 cmap->EncodingRecord[i].subtable.language);
1243 switch (cmap->EncodingRecord[i].subtable.format)
1248 unsigned char *array
1249 = cmap->EncodingRecord[i].subtable.f.f0->glyphIdArray;
1251 IPRINT ("(glyphIdArray");
1252 for (j = 0; j < 16; j++)
1255 for (k = 0; k < 16; k++)
1256 printf (" %3d", array[j * 16 + k]);
1264 OTF_EncodingSubtable4 *sub4
1265 = cmap->EncodingRecord[i].subtable.f.f4;
1268 IPRINT ("(segCountX2 %d) (searchRange %d)",
1269 sub4->segCountX2, sub4->searchRange);
1270 IPRINT ("(entrySelector %d) (rangeShift %d)",
1271 sub4->entrySelector, sub4->rangeShift);
1272 for (j = 0; j < sub4->segCountX2 / 2; j++)
1274 IPRINT ("(Segment (%d)", j);
1276 IPRINT ("(startCount #x%04X) (endCount #x%04X)",
1277 sub4->segments[j].startCount,
1278 sub4->segments[j].endCount);
1279 IPRINT ("(idDelta %d) (idRangeOffset #x%04X))",
1280 sub4->segments[j].idDelta,
1281 sub4->segments[j].idRangeOffset);
1284 IPRINT ("(glyphIdArray");
1285 for (j = 0; j < sub4->GlyphCount; j++)
1289 printf (" %3d", sub4->glyphIdArray[j]);
1297 OTF_EncodingSubtable6 *sub6
1298 = cmap->EncodingRecord[i].subtable.f.f6;
1301 IPRINT ("(firstCode %d) (entryCount %d)",
1302 sub6->firstCode, sub6->entryCount);
1303 IPRINT ("(glyphIdArray");
1304 for (j = 0; j < sub6->entryCount; j++)
1308 printf (" %3d", sub6->glyphIdArray[j]);
1324 dump_name_table (int indent, OTF_name *name)
1330 IPRINT ("(format %d)", name->format);
1331 IPRINT ("(count %d)", name->count);
1332 IPRINT ("(stringOffset %d)", name->stringOffset);
1333 for (i = 0; i < name->count; i++)
1335 OTF_NameRecord *rec = name->nameRecord + i;
1337 IPRINT ("(nameRecord (%d)", i);
1339 IPRINT ("(platformID %d) (encodingID %d) (languageID %d) (nameID %d)",
1340 rec->platformID, rec->encodingID, rec->languageID, rec->nameID);
1341 IPRINT ("(length %d) (offset #x%04X))", rec->length, rec->offset);
1344 for (i = 0; i <= OTF_max_nameID; i++)
1346 IPRINT ("(nameID %d \"%s\")", i, name->name[i]);
1360 dump_offset_table (1, &otf->offset_table);
1361 for (i = 0; i < otf->offset_table.numTables; i++)
1362 dump_table_directory (1, otf->table_dirs + i, i);
1365 dump_head_table (1, otf->head);
1367 dump_name_table (1, otf->name);
1369 dump_cmap_table (1, otf->cmap);
1371 dump_gdef_table (1, otf->gdef);
1373 dump_gsub_table (1, otf->gsub);
1375 dump_gpos_table (1, otf->gpos);
1378 dump_base_table (1, otf->base);
1380 dump_jstf_table (1, otf->jstf);
1387 main (int argc, char **argv)
1391 if (argc != 2 || !strcmp (argv[1], "-h") || !strcmp (argv[1], "--help"))
1393 fprintf (stderr, "Usage: %s OTF-FILE\n", basename (argv[0]));
1397 otf = OTF_open (argv[1]);
1400 OTF_perror ("otfdump");
1403 OTF_get_table (otf, "head");
1404 OTF_get_table (otf, "name");
1405 OTF_get_table (otf, "cmap");
1406 OTF_get_table (otf, "GDEF");
1407 OTF_get_table (otf, "GSUB");
1408 OTF_get_table (otf, "GPOS");
1410 OTF_get_table (otf, "BASE");
1411 OTF_get_table (otf, "JSTF");