1 /* otfdump.c -- Dump OpenType Layout Tables.
3 Copyright (C) 2003, 2004, 2008, 2009, 2010
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>
36 #define IPRINT printf("\n%*s", indent * 2, ""), printf
39 dump_tag (OTF_Tag tag)
43 putchar ((tag >> 16) & 0xFF);
44 putchar ((tag >> 8) & 0xFF);
46 printf ("\" #x%04X)", tag);
52 dump_offset_table (int indent, OTF_OffsetTable *table)
54 IPRINT ("(OffsetTable");
56 IPRINT ("(sfnt-version %d.%d)",
57 table->sfnt_version.high, table->sfnt_version.low);
58 IPRINT ("(numTables %d)", table->numTables);
59 IPRINT ("(searchRange %d)", table->searchRange);
60 IPRINT ("(enterSelector %d)", table->enterSelector);
61 IPRINT ("(rangeShift %d))", table->rangeShift);
65 dump_table_directory (int indent, OTF_TableDirectory *table, int idx)
67 IPRINT ("(Table %d ", idx);
68 dump_tag (table->tag);
70 IPRINT ("(checkSum %08X) (offset #x%08X) (length: #x%08X))",
71 table->checkSum, table->offset, table->length);
78 dump_head_table (int indent, OTF_head *head)
82 IPRINT ("(TableVersionNumber %d.%d)",
83 head->TableVersionNumber.high, head->TableVersionNumber.low);
84 IPRINT ("(fontRevision %d.%d)",
85 head->fontRevision.high, head->fontRevision.low);
86 IPRINT ("(checkSumAdjustment #x%04X)", head->checkSumAdjustment);
87 IPRINT ("(magicNumber #x%04X)", head->magicNumber);
88 IPRINT ("(flags #x%04X)", head->flags);
89 IPRINT ("(unitsPerEm %d)", head->unitsPerEm);
97 dump_glyph_ids (int indent, char *title, OTF_GlyphID *ids, unsigned count)
99 IPRINT ("(%s (count %d)", title, count);
102 printf (" #x%04X", *ids);
109 dump_coverage (int indent, char *title, OTF_Coverage *coverage)
114 IPRINT ("(%sCoverage (CoverageFormat %d)",
115 (title ? title : ""), coverage->CoverageFormat);
117 if (coverage->CoverageFormat == 1)
119 dump_glyph_ids (indent, "GlyphArray", coverage->table.GlyphArray,
121 char_list = malloc (sizeof (int) * (coverage->Count + 1));
122 for (i = 0; i < coverage->Count; i++)
123 char_list[i] = coverage->table.GlyphArray[i];
130 IPRINT ("(RangeCount %d)", coverage->Count);
132 for (i = n = 0; i < coverage->Count; i++)
134 IPRINT ("(Range (%d) (Start #x%04X) (End #x%04X)", i,
135 coverage->table.RangeRecord[i].Start,
136 coverage->table.RangeRecord[i].End);
138 IPRINT ("(StartCoverageIndex %d))",
139 coverage->table.RangeRecord[i].StartCoverageIndex);
141 n += (coverage->table.RangeRecord[i].End
142 - coverage->table.RangeRecord[i].Start + 1);
144 char_list = malloc (sizeof (int) * (n + 1));
145 for (i = n = 0; i < coverage->Count; i++)
146 for (c = coverage->table.RangeRecord[i].Start;
147 c <= coverage->table.RangeRecord[i].End;
157 dump_coverage_list (int indent, char *title,
158 OTF_Coverage *coverage, unsigned num)
162 IPRINT ("(%s %d)", title, num);
163 for (i = 0; i < num; i++)
164 free (dump_coverage (indent, NULL, coverage + i));
169 dump_language_system (int indent, int index, OTF_Tag tag, OTF_Offset offset,
170 OTF_LangSys *langsys)
174 IPRINT ("(LangSys ");
176 printf ("(%d) ", index);
180 printf ("DefaultLangSys");
181 printf (" (Offset #x%04X)", offset);
183 IPRINT ("(LookupOrder #x%04X)", langsys->LookupOrder);
184 IPRINT ("(ReqFeatureIndex %d)", langsys->ReqFeatureIndex);
185 IPRINT ("(FeatureCount %d)", langsys->FeatureCount);
186 if (langsys->FeatureCount)
188 IPRINT ("(FeatureIndex");
189 for (i = 0; i < langsys->FeatureCount; i++)
190 printf (" %d", langsys->FeatureIndex[i]);
197 dump_script_list (int indent, OTF_ScriptList *list)
201 IPRINT ("(ScriptList (count %d)", list->ScriptCount);
203 for (i = 0; i < list->ScriptCount; i++)
205 OTF_Script *script = list->Script + i;
207 IPRINT ("(Script (%d) ", i);
208 dump_tag (list->Script[i].ScriptTag);
209 printf (" (Offset #x%04X)", list->Script[i].offset);
211 IPRINT ("(DefaultLangSysOffset #x%04X)",
212 script->DefaultLangSysOffset);
213 if (script->DefaultLangSysOffset)
214 dump_language_system (indent, -1, 0,
215 script->DefaultLangSysOffset,
216 &script->DefaultLangSys);
217 IPRINT ("(LangSysCount %d)", script->LangSysCount);
218 for (j = 0; j < script->LangSysCount; j++)
219 dump_language_system (indent, j,
220 script->LangSysRecord[j].LangSysTag,
221 script->LangSysRecord[j].LangSys,
222 script->LangSys + j);
230 dump_feature_list (int indent, OTF_FeatureList *list)
234 IPRINT ("(FeatureList (count %d)", list->FeatureCount);
236 for (i = 0; i < list->FeatureCount; i++)
238 OTF_Feature *feature = list->Feature + i;
240 IPRINT ("(Feature (%d) ", i);
241 dump_tag (list->Feature[i].FeatureTag);
242 printf (" (Offset #x%04X)", list->Feature[i].offset);
243 printf (" (LookupCount %d)", feature->LookupCount);
244 if (feature->LookupCount)
247 IPRINT ("(LookupListIndex");
248 for (j = 0; j < feature->LookupCount; j++)
249 printf (" %d", feature->LookupListIndex[j]);
259 dump_class_def (int indent, char *title, OTF_ClassDef *class)
261 IPRINT ("(%s (offset #x%04X) (ClassFormat %d)",
262 (title ? title : "ClassDef"),
263 class->offset, class->ClassFormat);
267 if (class->ClassFormat == 1)
269 IPRINT ("(StartGlyph #x%04X)", class->f.f1.StartGlyph);
270 dump_glyph_ids (indent, "ClassValueArray",
271 (OTF_GlyphID *) class->f.f1.ClassValueArray,
272 class->f.f1.GlyphCount);
274 else if (class->ClassFormat == 2)
278 IPRINT ("(ClassRangeCount %d)", class->f.f2.ClassRangeCount);
279 IPRINT ("(ClassRangeRecord");
281 for (i = 0; i < class->f.f2.ClassRangeCount; i++)
282 IPRINT ("((Start #x%04X) (End #x%04X) (class %d))",
283 class->f.f2.ClassRangeRecord[i].Start,
284 class->f.f2.ClassRangeRecord[i].End,
285 class->f.f2.ClassRangeRecord[i].Class);
289 printf (" UnknownClassFormat");
295 dump_device_table (int indent, char *title, OTF_DeviceTable *table)
301 IPRINT ("(%s (offset #x%04X)", title, table->offset);
303 IPRINT ("(StartSize %d) (EndSize %d) (DeltaFormat %d)",
304 table->StartSize, table->EndSize, table->DeltaFormat);
305 if (table->DeltaValue)
307 IPRINT ("(DeltaValue");
308 for (i = 0; i < table->EndSize - table->StartSize + 1; i++)
309 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 if (anchor->offset == 0)
458 IPRINT ("(Anchor (offset #x%04X) (AnchorFormat %d)",
459 anchor->offset, anchor->AnchorFormat);
461 IPRINT ("(XCoordinate %d) (YCoordinate %d)",
462 anchor->XCoordinate, anchor->YCoordinate);
463 if (anchor->AnchorFormat == 1)
465 else if (anchor->AnchorFormat == 2)
466 IPRINT ("(AnchorPoint %d)", anchor->f.f1.AnchorPoint);
469 dump_device_table (indent, "XDeviceTable", &anchor->f.f2.XDeviceTable);
470 dump_device_table (indent, "YDeviceTable", &anchor->f.f2.YDeviceTable);
476 dump_entry_exit_list (int indent, unsigned count, OTF_EntryExitRecord *rec)
480 for (i = 0; i < count; i++)
482 IPRINT ("(EntryExitRecord (%d)", i);
484 dump_anchor (indent, &rec[i].EntryAnchor);
485 dump_anchor (indent, &rec[i].EntryAnchor);
492 dump_mark_array (int indent, OTF_MarkArray *array)
496 IPRINT ("(MarkArray (MarkCount %d)", array->MarkCount);
498 for (i = 0; i < array->MarkCount; i++)
500 IPRINT ("(MarkRecord (%d) (Class %d)", i, array->MarkRecord[i].Class);
501 dump_anchor (indent + 1, &array->MarkRecord[i].MarkAnchor);
508 dump_anchor_array (int indent, unsigned ClassCount, OTF_AnchorArray *array)
512 IPRINT ("(AnchorArray (Count %d)", array->Count);
514 for (i = 0; i < array->Count; i++)
516 IPRINT ("(AnchorRecord (%d) ", i);
517 for (j = 0; j < ClassCount; j++)
518 dump_anchor (indent + 1, array->AnchorRecord[i].Anchor + j);
526 dump_lookup_record_list (int indent, OTF_LookupRecord *rec, unsigned num)
530 IPRINT ("(LookupCount %d)", num);
531 for (i = 0; i < num; i++)
533 IPRINT ("(LookupRecord (%d)", i);
535 IPRINT ("(SequenceIndex %d)", rec[i].SequenceIndex);
536 IPRINT ("(LookupListIndex %d))", rec[i].LookupListIndex);
542 static void dump_lookup_subtable_gsub (int indent, int index, unsigned type,
543 OTF_LookupSubTableGSUB *subtable);
544 static void dump_lookup_subtable_gpos (int indent, int index, unsigned type,
545 OTF_LookupSubTableGPOS *subtable);
549 dump_lookup_list (int indent, OTF_LookupList *list, int gsub)
553 IPRINT ("(LookupList (count %d)", list->LookupCount);
555 for (i = 0; i < list->LookupCount; i++)
557 OTF_Lookup *lookup = list->Lookup + i;
559 IPRINT ("(Lookup (%d) (Offset #x%04X)",
561 printf (" (Type %d) (Flag #x%04X) (SubTableCount %d)",
562 lookup->LookupType, lookup->LookupFlag, lookup->SubTableCount);
564 for (j = 0; j < lookup->SubTableCount; j++)
565 dump_lookup_subtable_gsub (indent + 1, j,
567 lookup->SubTable.gsub + j);
569 for (j = 0; j < lookup->SubTableCount; j++)
570 dump_lookup_subtable_gpos (indent + 1, j,
572 lookup->SubTable.gpos + j);
580 dump_rule_list (int indent, OTF_Rule *rule, int count)
584 IPRINT ("(RuleCount %d)", count);
585 for (i = 0; i < count; i++)
587 IPRINT ("(Rule (%d)", i);
589 IPRINT ("(GlyphCount %d)", rule[i].GlyphCount);
590 IPRINT ("(LookupCount %d)", rule[i].LookupCount);
591 dump_glyph_ids (indent, "Input", rule[i].Input, rule[i].GlyphCount - 1);
592 dump_lookup_record_list (indent, rule[i].LookupRecord,
593 rule[i].LookupCount);
600 dump_rule_set_list (int indent, OTF_RuleSet *set, int count)
604 IPRINT ("(RuleSetCount %d)", count);
605 for (i = 0; i < count; i++)
607 IPRINT ("(RuleSet (%d)", i);
608 dump_rule_list (indent + 1, set[i].Rule, set[i].RuleCount);
614 dump_class_rule_list (int indent, OTF_ClassRule *rule, int count)
618 IPRINT ("(ClassRuleCnt %d)", count);
619 for (i = 0; i < count; i++)
621 IPRINT ("(ClassRule (%d)", i);
623 IPRINT ("(GlyphCount %d)", rule[i].GlyphCount);
624 IPRINT ("(LookupCount %d)", rule[i].LookupCount);
626 for (j = 0; j < rule[i].GlyphCount - 1; j++)
627 printf (" %d", rule[i].Class[j]);
629 dump_lookup_record_list (indent, rule[i].LookupRecord,
630 rule[i].LookupCount);
637 dump_class_set_list (int indent, OTF_ClassSet *set, int count)
641 IPRINT ("(ClassSetCount %d)", count);
642 for (i = 0; i < count; i++)
645 IPRINT ("(ClassSet (%d)", i);
646 dump_class_rule_list (indent + 1, set[i].ClassRule,
647 set[i].ClassRuleCnt);
653 dump_chain_rule_list (int indent, OTF_ChainRule *rule, int count)
657 IPRINT ("(ChainRuleCount %d)", count);
658 for (i = 0; i < count; i++)
660 IPRINT ("(ChainRule (%d)", i);
661 dump_glyph_ids (indent + 1, "Backtrack",
662 rule[i].Backtrack, rule[i].BacktrackGlyphCount);
663 dump_glyph_ids (indent + 1, "Input",
664 rule[i].Input, rule[i].InputGlyphCount - 1);
665 dump_glyph_ids (indent + 1, "LookAhead",
666 rule[i].LookAhead, rule[i].LookaheadGlyphCount);
667 dump_lookup_record_list (indent + 1, rule[i].LookupRecord,
668 rule[i].LookupCount);
674 dump_chain_rule_set_list (int indent, OTF_ChainRuleSet *set, int count)
678 IPRINT ("(ChainRuleSetCount %d)", count);
679 for (i = 0; i < count; i++)
681 IPRINT ("(ChainRuleSet (%d)", i);
682 dump_chain_rule_list (indent + 1,
683 set[i].ChainRule, set[i].ChainRuleCount);
689 dump_chain_class_rule_list (int indent, OTF_ChainClassRule *rule, int count)
693 IPRINT ("(ChainClassRuleCount %d)", count);
694 for (i = 0; i < count; i++)
696 IPRINT ("(ChainClassRule (%d)", i);
697 dump_glyph_ids (indent + 1, "Backtrack",
698 rule[i].Backtrack, rule[i].BacktrackGlyphCount);
699 dump_glyph_ids (indent + 1, "Input",
700 rule[i].Input, rule[i].InputGlyphCount - 1);
701 dump_glyph_ids (indent + 1, "LookAhead",
702 rule[i].LookAhead, rule[i].LookaheadGlyphCount);
703 dump_lookup_record_list (indent + 1, rule[i].LookupRecord,
704 rule[i].LookupCount);
710 dump_chain_class_set_list (int indent, OTF_ChainClassSet *set, int count)
714 IPRINT ("(ChainClassSetCount %d)", count);
715 for (i = 0; i < count; i++)
718 IPRINT ("(ChainClassSet (%d)", i);
719 dump_chain_class_rule_list (indent + 1,
720 set[i].ChainClassRule,
721 set[i].ChainClassRuleCnt);
733 dump_lookup_subtable_gsub (int indent, int index, unsigned type,
734 OTF_LookupSubTableGSUB *subtable)
736 IPRINT ("(SubTable (%d) (Format %d)", index, subtable->Format);
741 if (subtable->Format == 1)
743 free (dump_coverage (indent, NULL, &subtable->Coverage));
744 IPRINT ("(DeltaGlyhpID #x%04X)",
745 subtable->u.single1.DeltaGlyphID);
747 else if (subtable->Format == 2)
749 free (dump_coverage (indent, NULL, &subtable->Coverage));
750 dump_glyph_ids (indent, "Substitute", subtable->u.single2.Substitute,
751 subtable->u.single2.GlyphCount);
758 if (subtable->Format == 1)
760 free (dump_coverage (indent, NULL, &subtable->Coverage));
761 dump_sequence_list (indent,
762 subtable->u.multiple1.Sequence,
763 subtable->u.multiple1.SequenceCount);
770 if (subtable->Format == 1)
772 free (dump_coverage (indent, NULL, &subtable->Coverage));
773 dump_alternate_set_list (indent, subtable->u.alternate1.AlternateSet,
774 subtable->u.alternate1.AlternateSetCount);
781 if (subtable->Format == 1)
783 int *char_list = dump_coverage (indent, NULL, &subtable->Coverage);
784 dump_ligature_set_list (indent, char_list,
785 subtable->u.ligature1.LigatureSet,
786 subtable->u.ligature1.LigSetCount);
794 if (subtable->Format == 1)
796 free (dump_coverage (indent, NULL, &subtable->Coverage));
797 dump_rule_set_list (indent, subtable->u.context1.RuleSet,
798 subtable->u.context1.RuleSetCount);
800 else if (subtable->Format == 2)
802 free (dump_coverage (indent, NULL, &subtable->Coverage));
803 dump_class_def (indent, NULL, &subtable->u.context2.ClassDef);
804 dump_class_set_list (indent, subtable->u.context2.ClassSet,
805 subtable->u.context2.ClassSetCnt);
807 else if (subtable->Format == 3)
809 dump_coverage_list (indent, "Coverage",
810 subtable->u.context3.Coverage,
811 subtable->u.context3.GlyphCount);
812 dump_lookup_record_list (indent,
813 subtable->u.context3.LookupRecord,
814 subtable->u.context3.LookupCount);
821 if (subtable->Format == 1)
823 free (dump_coverage (indent, NULL, &subtable->Coverage));
824 dump_chain_rule_set_list
826 subtable->u.chain_context1.ChainRuleSet,
827 subtable->u.chain_context1.ChainRuleSetCount);
829 else if (subtable->Format == 2)
831 free (dump_coverage (indent, NULL, &subtable->Coverage));
832 dump_class_def (indent, "BacktrackClassDef",
833 &subtable->u.chain_context2.BacktrackClassDef);
834 dump_class_def (indent, "InputClassDef",
835 &subtable->u.chain_context2.InputClassDef);
836 dump_class_def (indent, "LookaheadClassDef",
837 &subtable->u.chain_context2.LookaheadClassDef);
838 dump_chain_class_set_list
840 subtable->u.chain_context2.ChainClassSet,
841 subtable->u.chain_context2.ChainClassSetCnt);
843 else if (subtable->Format == 3)
846 (indent, "BackTrackGlyphCount",
847 subtable->u.chain_context3.Backtrack,
848 subtable->u.chain_context3.BacktrackGlyphCount);
850 (indent, "InputGlyphCount",
851 subtable->u.chain_context3.Input,
852 subtable->u.chain_context3.InputGlyphCount);
854 (indent, "LookaheadGlyphCount",
855 subtable->u.chain_context3.LookAhead,
856 subtable->u.chain_context3.LookaheadGlyphCount);
857 dump_lookup_record_list
859 subtable->u.chain_context3.LookupRecord,
860 subtable->u.chain_context3.LookupCount);
867 IPRINT ("(ExtensionLookupType %d)",
868 subtable->u.extension1.ExtensionLookupType);
869 IPRINT ("(ExtensionOffset %d)",
870 subtable->u.extension1.ExtensionOffset);
871 dump_lookup_subtable_gsub (indent, index,
872 subtable->u.extension1.ExtensionLookupType,
873 subtable->u.extension1.ExtensionSubtable);
877 printf (" not-yet-supported");
887 dump_gsub_table (int indent, OTF_GSUB *gsub)
893 IPRINT ("(Version %d.%d)", gsub->Version.high, gsub->Version.low);
894 IPRINT ("(ScriptList #x%04X)", gsub->ScriptList.offset);
895 IPRINT ("(FeatureList #x%04X)", gsub->FeatureList.offset);
896 IPRINT ("(LookupList #x%04X))", gsub->LookupList.offset);
898 dump_script_list (indent, &gsub->ScriptList);
899 dump_feature_list (indent, &gsub->FeatureList);
900 dump_lookup_list (indent, &gsub->LookupList, 1);
908 dump_lookup_subtable_gpos (int indent, int index, unsigned type,
909 OTF_LookupSubTableGPOS *subtable)
911 IPRINT ("(SubTable (%d) (Format %d)", index, subtable->Format);
916 if (subtable->Format == 1)
918 free (dump_coverage (indent, NULL, &subtable->Coverage));
919 IPRINT ("(ValueFormat #x%04X)",
920 subtable->u.single1.ValueFormat);
921 dump_value_record (indent, "Value", &subtable->u.single1.Value);
923 else if (subtable->Format == 2)
927 free (dump_coverage (indent, NULL, &subtable->Coverage));
928 IPRINT ("(ValueFormat #x%04X)",
929 subtable->u.single2.ValueFormat);
930 IPRINT ("(ValueCount %d)",
931 subtable->u.single2.ValueCount);
932 for (i = 0; i < subtable->u.single2.ValueCount; i++)
933 dump_value_record (indent, "Value", &subtable->u.single2.Value[i]);
940 if (subtable->Format == 1)
942 free (dump_coverage (indent, NULL, &subtable->Coverage));
943 IPRINT ("(ValueFormat1 #x%04X)",
944 subtable->u.pair1.ValueFormat1);
945 IPRINT ("(ValueFormat2 #x%04X)",
946 subtable->u.pair1.ValueFormat2);
947 dump_pair_set_list (indent, subtable->u.pair1.PairSetCount,
948 subtable->u.pair1.PairSet);
950 else if (subtable->Format == 2)
952 free (dump_coverage (indent, NULL, &subtable->Coverage));
953 IPRINT ("(ValueFormat1 #x%04X)",
954 subtable->u.pair2.ValueFormat1);
955 IPRINT ("(ValueFormat2 #x%04X)",
956 subtable->u.pair2.ValueFormat2);
957 dump_class_def (indent, "ClassDef1",
958 &subtable->u.pair2.ClassDef1);
959 dump_class_def (indent, "ClassDef2",
960 &subtable->u.pair2.ClassDef2);
961 IPRINT ("(Class1Count %d)",
962 subtable->u.pair2.Class1Count);
963 IPRINT ("(Class2Count %d)",
964 subtable->u.pair2.Class2Count);
965 dump_class1_record_list (indent,
966 subtable->u.pair2.Class1Count,
967 subtable->u.pair2.Class2Count,
968 subtable->u.pair2.Class1Record);
975 if (subtable->Format == 1)
977 free (dump_coverage (indent, NULL, &subtable->Coverage));
978 dump_entry_exit_list (indent, subtable->u.cursive1.EntryExitCount,
979 subtable->u.cursive1.EntryExitRecord);
986 if (subtable->Format == 1)
988 free (dump_coverage (indent, "Mark", &subtable->Coverage));
989 free (dump_coverage (indent, "Base",
990 &subtable->u.mark_base1.BaseCoverage));
991 IPRINT ("(ClassCount %d)",
992 subtable->u.mark_base1.ClassCount);
993 dump_mark_array (indent, &subtable->u.mark_base1.MarkArray);
994 dump_anchor_array (indent, subtable->u.mark_base1.ClassCount,
995 &subtable->u.mark_base1.BaseArray);
1000 if (subtable->Format == 1)
1002 OTF_GPOS_MarkLig1 *mark_lig1 = &subtable->u.mark_lig1;
1005 free (dump_coverage (indent, "Mark", &subtable->Coverage));
1006 free (dump_coverage (indent, "Ligature",
1007 &mark_lig1->LigatureCoverage));
1008 IPRINT ("(ClassCount %d)", mark_lig1->ClassCount);
1009 dump_mark_array (indent, &mark_lig1->MarkArray);
1010 IPRINT ("(LigatureArray (%d)",
1011 mark_lig1->LigatureArray.LigatureCount);
1013 for (i = 0; i < mark_lig1->LigatureArray.LigatureCount; i++)
1015 OTF_LigatureAttach *attach
1016 = mark_lig1->LigatureArray.LigatureAttach + i;
1018 IPRINT ("(LigatureAttach (%d)", attach->ComponentCount);
1020 for (j = 0; j < attach->ComponentCount; j++)
1022 OTF_ComponentRecord *rec = attach->ComponentRecord + j;
1024 IPRINT ("(LigatureAnchor (%d)", mark_lig1->ClassCount);
1025 for (k = 0; k < mark_lig1->ClassCount; k++)
1026 if (rec->LigatureAnchor[k].AnchorFormat)
1027 dump_anchor (indent + 1, rec->LigatureAnchor + k);
1036 printf (" invalid");
1040 if (subtable->Format == 1)
1042 free (dump_coverage (indent, "Mark1", &subtable->Coverage));
1043 free (dump_coverage (indent, "Mark2",
1044 &subtable->u.mark_mark1.Mark2Coverage));
1045 IPRINT ("(ClassCount %d)",
1046 subtable->u.mark_mark1.ClassCount);
1047 dump_mark_array (indent, &subtable->u.mark_mark1.Mark1Array);
1048 dump_anchor_array (indent, subtable->u.mark_mark1.ClassCount,
1049 &subtable->u.mark_mark1.Mark2Array);
1052 printf (" invalid");
1056 if (subtable->Format == 1)
1058 free (dump_coverage (indent, NULL, &subtable->Coverage));
1059 dump_rule_set_list (indent, subtable->u.context1.RuleSet,
1060 subtable->u.context1.RuleSetCount);
1062 else if (subtable->Format == 2)
1064 free (dump_coverage (indent, NULL, &subtable->Coverage));
1065 dump_class_def (indent, NULL, &subtable->u.context2.ClassDef);
1066 dump_class_set_list (indent, subtable->u.context2.ClassSet,
1067 subtable->u.context2.ClassSetCnt);
1069 else if (subtable->Format == 3)
1071 dump_coverage_list (indent, "Coverage",
1072 subtable->u.context3.Coverage,
1073 subtable->u.context3.GlyphCount);
1074 dump_lookup_record_list (indent,
1075 subtable->u.context3.LookupRecord,
1076 subtable->u.context3.LookupCount);
1079 printf (" invalid");
1083 if (subtable->Format == 1)
1085 free (dump_coverage (indent, NULL, &subtable->Coverage));
1086 dump_chain_rule_set_list
1088 subtable->u.chain_context1.ChainRuleSet,
1089 subtable->u.chain_context1.ChainRuleSetCount);
1091 else if (subtable->Format == 2)
1093 free (dump_coverage (indent, NULL, &subtable->Coverage));
1094 dump_class_def (indent, "BacktrackClassDef",
1095 &subtable->u.chain_context2.BacktrackClassDef);
1096 dump_class_def (indent, "InputClassDef",
1097 &subtable->u.chain_context2.InputClassDef);
1098 dump_class_def (indent, "LookaheadClassDef",
1099 &subtable->u.chain_context2.LookaheadClassDef);
1100 dump_chain_class_set_list
1102 subtable->u.chain_context2.ChainClassSet,
1103 subtable->u.chain_context2.ChainClassSetCnt);
1105 else if (subtable->Format == 3)
1108 (indent, "BackTrackGlyphCount",
1109 subtable->u.chain_context3.Backtrack,
1110 subtable->u.chain_context3.BacktrackGlyphCount);
1112 (indent, "InputGlyphCount",
1113 subtable->u.chain_context3.Input,
1114 subtable->u.chain_context3.InputGlyphCount);
1116 (indent, "LookaheaGlyphCount",
1117 subtable->u.chain_context3.LookAhead,
1118 subtable->u.chain_context3.LookaheadGlyphCount);
1119 dump_lookup_record_list
1121 subtable->u.chain_context3.LookupRecord,
1122 subtable->u.chain_context3.LookupCount);
1125 printf (" invalid");
1129 if (subtable->Format == 1)
1131 IPRINT ("(ExtensionLookupType %d)",
1132 subtable->u.extension1.ExtensionLookupType);
1133 IPRINT ("(ExtensionOffset %d)",
1134 subtable->u.extension1.ExtensionOffset);
1135 dump_lookup_subtable_gpos
1137 subtable->u.extension1.ExtensionLookupType,
1138 subtable->u.extension1.ExtensionSubtable);
1141 printf (" invalid");
1148 dump_gpos_table (int indent, OTF_GPOS *gpos)
1156 IPRINT ("(Version %d.%d)", gpos->Version.high, gpos->Version.low);
1157 IPRINT ("(ScriptList #x%04X)", gpos->ScriptList.offset);
1158 IPRINT ("(FeatureList #x%04X)", gpos->FeatureList.offset);
1159 IPRINT ("(LookupList #x%04X))", gpos->LookupList.offset);
1161 dump_script_list (indent, &gpos->ScriptList);
1162 dump_feature_list (indent, &gpos->FeatureList);
1163 dump_lookup_list (indent, &gpos->LookupList, 0);
1169 dump_base_table (OTF_BASE *base)
1174 dump_jstf_table (OTF_JSTF *jstf)
1182 dump_gdef_header (int indent, OTF_GDEFHeader *header)
1186 IPRINT ("(Version %d.%d)",
1187 header->Version.high, header->Version.low);
1188 IPRINT ("(GlyphClassDef #x%04X)", header->GlyphClassDef);
1189 IPRINT ("(AttachList #x%04X)", header->AttachList);
1190 IPRINT ("(LigCaretList #x%04X)", header->LigCaretList);
1191 IPRINT ("(MarkAttachClassDef #x%04X))",
1192 header->MarkAttachClassDef);
1196 dump_attach_list (int indent, OTF_AttachList *list)
1201 dump_lig_caret_list (int indent, OTF_LigCaretList *list)
1205 IPRINT ("(LigCaretList");
1207 free (dump_coverage (indent, NULL, &list->Coverage));
1208 IPRINT ("(LigGlyphCount %d)", list->LigGlyphCount);
1209 for (i = 0; i < list->LigGlyphCount; i++)
1211 IPRINT ("(LigGlyph (%d) (offset #x%04X)",
1212 i, list->LigGlyph[i].offset);
1214 IPRINT ("(CaretCount %d)", list->LigGlyph[i].CaretCount);
1215 for (j = 0; j < list->LigGlyph[i].CaretCount; j++)
1217 unsigned format = list->LigGlyph[i].CaretValue[j].CaretValueFormat;
1219 IPRINT ("(Caret (%d) (CaretValueFormat %d)", j, format);
1222 printf ("(Coordinate %d)",
1223 list->LigGlyph[i].CaretValue[j].f.f1.Coordinate);
1225 else if (format == 2)
1227 printf ("(CaretValuePoint %d)",
1228 list->LigGlyph[i].CaretValue[j].f.f2.CaretValuePoint);
1230 else if (format == 3)
1232 printf ("(Coodinate %d)",
1233 list->LigGlyph[i].CaretValue[j].f.f3.Coordinate);
1236 (indent, "DeviceTable",
1237 &list->LigGlyph[i].CaretValue[j].f.f3.DeviceTable);
1249 dump_gdef_table (int indent, OTF_GDEF *gdef)
1255 dump_gdef_header (indent, &gdef->header);
1256 if (gdef->header.GlyphClassDef)
1257 dump_class_def (indent, "GlyphClassDef", &gdef->glyph_class_def);
1258 if (gdef->header.AttachList)
1259 dump_attach_list (indent, &gdef->attach_list);
1260 if (gdef->header.LigCaretList)
1261 dump_lig_caret_list (indent, &gdef->lig_caret_list);
1262 if (gdef->header.MarkAttachClassDef)
1263 dump_class_def (indent, "MarkAttachClassDef",
1264 &gdef->mark_attach_class_def);
1271 dump_cmap_table (int indent, OTF_cmap *cmap)
1277 IPRINT ("(version %d)", cmap->version);
1278 IPRINT ("(numTables %d)", cmap->numTables);
1279 for (i = 0; i < cmap->numTables; i++)
1281 IPRINT ("(EncodingRecord (%d) (platformID %d) (encodingID %d)",
1283 cmap->EncodingRecord[i].platformID,
1284 cmap->EncodingRecord[i].encodingID);
1286 IPRINT ("(Subtable (offset #x%04X) (format %d) (length #x%04X) (language %d)",
1287 cmap->EncodingRecord[i].offset,
1288 cmap->EncodingRecord[i].subtable.format,
1289 cmap->EncodingRecord[i].subtable.length,
1290 cmap->EncodingRecord[i].subtable.language);
1292 switch (cmap->EncodingRecord[i].subtable.format)
1297 unsigned char *array
1298 = cmap->EncodingRecord[i].subtable.f.f0->glyphIdArray;
1300 IPRINT ("(glyphIdArray");
1301 for (j = 0; j < 16; j++)
1304 for (k = 0; k < 16; k++)
1305 printf (" %3d", array[j * 16 + k]);
1313 OTF_EncodingSubtable4 *sub4
1314 = cmap->EncodingRecord[i].subtable.f.f4;
1317 IPRINT ("(segCountX2 %d) (searchRange %d)",
1318 sub4->segCountX2, sub4->searchRange);
1319 IPRINT ("(entrySelector %d) (rangeShift %d)",
1320 sub4->entrySelector, sub4->rangeShift);
1321 for (j = 0; j < sub4->segCountX2 / 2; j++)
1323 IPRINT ("(Segment (%d)", j);
1325 IPRINT ("(startCount #x%04X) (endCount #x%04X)",
1326 sub4->segments[j].startCount,
1327 sub4->segments[j].endCount);
1328 IPRINT ("(idDelta %d) (idRangeOffset #x%04X))",
1329 sub4->segments[j].idDelta,
1330 sub4->segments[j].idRangeOffset);
1333 IPRINT ("(glyphIdArray");
1334 for (j = 0; j < sub4->GlyphCount; j++)
1338 printf (" %3d", sub4->glyphIdArray[j]);
1346 OTF_EncodingSubtable6 *sub6
1347 = cmap->EncodingRecord[i].subtable.f.f6;
1350 IPRINT ("(firstCode %d) (entryCount %d)",
1351 sub6->firstCode, sub6->entryCount);
1352 IPRINT ("(glyphIdArray");
1353 for (j = 0; j < sub6->entryCount; j++)
1357 printf (" %3d", sub6->glyphIdArray[j]);
1365 OTF_EncodingSubtable12 *sub12
1366 = cmap->EncodingRecord[i].subtable.f.f12;
1369 for (j = 0; j < sub12->nGroups; j++)
1371 IPRINT ("(Group (#x%X) (startChar #x%04X) (endChar #x%04X) (startGlyphID #x%X))",
1373 sub12->Groups[j].startCharCode,
1374 sub12->Groups[j].endCharCode,
1375 sub12->Groups[j].startGlyphID);
1382 OTF_EncodingSubtable14 *sub14
1383 = cmap->EncodingRecord[i].subtable.f.f14;
1386 IPRINT ("(VariationSelectorRecords %d)",sub14->nRecords);
1387 for (j = 0; j < sub14->nRecords; j++)
1389 OTF_VariationSelectorRecord *record = sub14->Records + j;
1390 IPRINT ("(VariationSelectorRecord (varSelector #x%x)",
1391 record->varSelector);
1393 IPRINT ("(defaultUVSOffset #x%x)",
1394 record->defaultUVSOffset);
1395 if (record->defaultUVSOffset)
1397 IPRINT ("(defaultUVS");
1399 for (k = 0 ; k < record->numUnicodeValueRanges; k++)
1401 OTF_UnicodeValueRange *unicodeValueRange
1402 = &record->unicodeValueRanges[k];
1403 IPRINT("(startUnicodeValue #x%x) (additionalCount %d)",
1404 unicodeValueRange->startUnicodeValue,
1405 unicodeValueRange->additionalCount);
1410 IPRINT ("(nonDefaultUVSOffset #x%x)",
1411 record->nonDefaultUVSOffset);
1412 if (record->nonDefaultUVSOffset)
1414 IPRINT ("(NonDefaultUVS");
1416 for (k=0; k < record->numUVSMappings; k++)
1418 OTF_UVSMapping *uvsMapping
1419 = &record->uvsMappings[k];
1420 IPRINT("(unicodeValue #x%x) (glyphID %d)",
1421 uvsMapping->unicodeValue,
1422 uvsMapping->glyphID);
1442 dump_name_table (int indent, OTF_name *name)
1448 IPRINT ("(format %d)", name->format);
1449 IPRINT ("(count %d)", name->count);
1450 IPRINT ("(stringOffset %d)", name->stringOffset);
1451 for (i = 0; i < name->count; i++)
1453 OTF_NameRecord *rec = name->nameRecord + i;
1455 IPRINT ("(nameRecord (%d)", i);
1457 IPRINT ("(platformID %d) (encodingID %d) (languageID %d) (nameID %d)",
1458 rec->platformID, rec->encodingID, rec->languageID, rec->nameID);
1459 IPRINT ("(length %d) (offset #x%04X))", rec->length, rec->offset);
1462 for (i = 0; i <= OTF_max_nameID; i++)
1464 IPRINT ("(nameID %d \"%s\")", i, name->name[i]);
1478 dump_offset_table (1, &otf->offset_table);
1479 for (i = 0; i < otf->offset_table.numTables; i++)
1480 dump_table_directory (1, otf->table_dirs + i, i);
1483 dump_head_table (1, otf->head);
1485 dump_name_table (1, otf->name);
1487 dump_cmap_table (1, otf->cmap);
1489 dump_gdef_table (1, otf->gdef);
1491 dump_gsub_table (1, otf->gsub);
1493 dump_gpos_table (1, otf->gpos);
1496 dump_base_table (1, otf->base);
1498 dump_jstf_table (1, otf->jstf);
1505 main (int argc, char **argv)
1509 if (argc != 2 || !strcmp (argv[1], "-h") || !strcmp (argv[1], "--help"))
1511 fprintf (stderr, "Usage: %s OTF-FILE\n", basename (argv[0]));
1515 otf = OTF_open (argv[1]);
1518 OTF_perror ("otfdump");
1521 OTF_get_table (otf, "head");
1522 OTF_get_table (otf, "name");
1523 OTF_get_table (otf, "cmap");
1524 OTF_get_table (otf, "GDEF");
1525 OTF_get_table (otf, "GSUB");
1526 OTF_get_table (otf, "GPOS");
1528 OTF_get_table (otf, "BASE");
1529 OTF_get_table (otf, "JSTF");