1 /* otfdump.c -- Dump OpenType Layout Tables.
3 Copyright (C) 2003, 2004
4 National Institute of Advanced Industrial Science and Technology (AIST)
5 Registration Number H15PRO167
7 This file is part of libotf.
9 Libotf is free software; you can redistribute it and/or modify it
10 under the terms of the GNU Lesser General Public License as published
11 by the Free Software Foundation; either version 2.1 of the License, or
12 (at your option) any later version.
14 Libotf is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17 License for more details.
19 You should have received a copy of the GNU Lesser General Public
20 License along with this library, in a file named COPYING; if not,
21 write to the Free Software Foundation, Inc., 59 Temple Place, Suite
22 330, Boston, MA 02111-1307, USA. */
28 #include <sys/types.h>
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 OTF_GPOS_MarkLig1 *mark_lig1 = &subtable->u.mark_lig1;
1001 free (dump_coverage (indent, "Mark", &subtable->Coverage));
1002 free (dump_coverage (indent, "Ligature",
1003 &mark_lig1->LigatureCoverage));
1004 IPRINT ("(ClassCount %d)", mark_lig1->ClassCount);
1005 dump_mark_array (indent, &mark_lig1->MarkArray);
1006 IPRINT ("(LigatureArray (%d)",
1007 mark_lig1->LigatureArray.LigatureCount);
1009 for (i = 0; i < mark_lig1->LigatureArray.LigatureCount; i++)
1011 OTF_LigatureAttach *attach
1012 = mark_lig1->LigatureArray.LigatureAttach + i;
1014 IPRINT ("(LigatureAttach (%d)", attach->ComponentCount);
1016 for (j = 0; j < attach->ComponentCount; j++)
1018 OTF_ComponentRecord *rec = attach->ComponentRecord + j;
1020 IPRINT ("(LigatureAnchor (%d)", mark_lig1->ClassCount);
1021 for (k = 0; k < mark_lig1->ClassCount; k++)
1022 if (rec->LigatureAnchor[k].AnchorFormat)
1023 dump_anchor (indent + 1, rec->LigatureAnchor + k);
1032 printf (" invalid");
1036 if (subtable->Format == 1)
1038 free (dump_coverage (indent, "Mark1", &subtable->Coverage));
1039 free (dump_coverage (indent, "Mark2",
1040 &subtable->u.mark_mark1.Mark2Coverage));
1041 IPRINT ("(ClassCount %d)",
1042 subtable->u.mark_mark1.ClassCount);
1043 dump_mark_array (indent, &subtable->u.mark_mark1.Mark1Array);
1044 dump_anchor_array (indent, subtable->u.mark_mark1.ClassCount,
1045 &subtable->u.mark_mark1.Mark2Array);
1048 printf (" invalid");
1052 if (subtable->Format == 1)
1054 free (dump_coverage (indent, NULL, &subtable->Coverage));
1055 dump_rule_set_list (indent, subtable->u.context1.RuleSet,
1056 subtable->u.context1.RuleSetCount);
1058 else if (subtable->Format == 2)
1060 free (dump_coverage (indent, NULL, &subtable->Coverage));
1061 dump_class_def (indent, NULL, &subtable->u.context2.ClassDef);
1062 dump_class_set_list (indent, subtable->u.context2.ClassSet,
1063 subtable->u.context2.ClassSetCnt);
1065 else if (subtable->Format == 3)
1067 dump_coverage_list (indent, "Coverage",
1068 subtable->u.context3.Coverage,
1069 subtable->u.context3.GlyphCount);
1070 dump_lookup_record_list (indent,
1071 subtable->u.context3.LookupRecord,
1072 subtable->u.context3.LookupCount);
1075 printf (" invalid");
1079 if (subtable->Format == 1)
1081 free (dump_coverage (indent, NULL, &subtable->Coverage));
1082 dump_chain_rule_set_list
1084 subtable->u.chain_context1.ChainRuleSet,
1085 subtable->u.chain_context1.ChainRuleSetCount);
1087 else if (subtable->Format == 2)
1089 free (dump_coverage (indent, NULL, &subtable->Coverage));
1090 dump_class_def (indent, "BacktrackClassDef",
1091 &subtable->u.chain_context2.BacktrackClassDef);
1092 dump_class_def (indent, "InputClassDef",
1093 &subtable->u.chain_context2.InputClassDef);
1094 dump_class_def (indent, "LookaheadClassDef",
1095 &subtable->u.chain_context2.LookaheadClassDef);
1096 dump_chain_class_set_list
1098 subtable->u.chain_context2.ChainClassSet,
1099 subtable->u.chain_context2.ChainClassSetCnt);
1101 else if (subtable->Format == 3)
1104 (indent, "BackTrackGlyphCount",
1105 subtable->u.chain_context3.Backtrack,
1106 subtable->u.chain_context3.BacktrackGlyphCount);
1108 (indent, "InputGlyphCount",
1109 subtable->u.chain_context3.Input,
1110 subtable->u.chain_context3.InputGlyphCount);
1112 (indent, "LookaheaGlyphCount",
1113 subtable->u.chain_context3.LookAhead,
1114 subtable->u.chain_context3.LookaheadGlyphCount);
1115 dump_lookup_record_list
1117 subtable->u.chain_context3.LookupRecord,
1118 subtable->u.chain_context3.LookupCount);
1121 printf (" invalid");
1125 if (subtable->Format == 1)
1127 IPRINT ("(ExtensionLookupType %d)",
1128 subtable->u.extension1.ExtensionLookupType);
1129 IPRINT ("(ExtensionOffset %d)",
1130 subtable->u.extension1.ExtensionOffset);
1131 dump_lookup_subtable_gpos
1133 subtable->u.extension1.ExtensionLookupType,
1134 subtable->u.extension1.ExtensionSubtable);
1137 printf (" invalid");
1144 dump_gpos_table (int indent, OTF_GPOS *gpos)
1152 IPRINT ("(Version %d.%d)", gpos->Version.high, gpos->Version.low);
1153 IPRINT ("(ScriptList #x%04X)", gpos->ScriptList.offset);
1154 IPRINT ("(FeatureList #x%04X)", gpos->FeatureList.offset);
1155 IPRINT ("(LookupList #x%04X))", gpos->LookupList.offset);
1157 dump_script_list (indent, &gpos->ScriptList);
1158 dump_feature_list (indent, &gpos->FeatureList);
1159 dump_lookup_list (indent, &gpos->LookupList, 0);
1165 dump_base_table (OTF_BASE *base)
1170 dump_jstf_table (OTF_JSTF *jstf)
1178 dump_gdef_header (int indent, OTF_GDEFHeader *header)
1182 IPRINT ("(Version %d.%d)",
1183 header->Version.high, header->Version.low);
1184 IPRINT ("(GlyphClassDef #x%04X)", header->GlyphClassDef);
1185 IPRINT ("(AttachList #x%04X)", header->AttachList);
1186 IPRINT ("(LigCaretList #x%04X)", header->LigCaretList);
1187 IPRINT ("(MarkAttachClassDef #x%04X))",
1188 header->MarkAttachClassDef);
1192 dump_attach_list (int indent, OTF_AttachList *list)
1197 dump_lig_caret_list (int indent, OTF_LigCaretList *list)
1201 IPRINT ("(LigCaretList");
1203 free (dump_coverage (indent, NULL, &list->Coverage));
1204 IPRINT ("(LigGlyphCount %d)", list->LigGlyphCount);
1205 for (i = 0; i < list->LigGlyphCount; i++)
1207 IPRINT ("(LigGlyph (%d) (offset #x%04X)",
1208 i, list->LigGlyph[i].offset);
1210 IPRINT ("(CaretCount %d)", list->LigGlyph[i].CaretCount);
1211 for (j = 0; j < list->LigGlyph[i].CaretCount; j++)
1213 unsigned format = list->LigGlyph[i].CaretValue[j].CaretValueFormat;
1215 IPRINT ("(Caret (%d) (CaretValueFormat %d)", j, format);
1218 printf ("(Coordinate %d)",
1219 list->LigGlyph[i].CaretValue[j].f.f1.Coordinate);
1221 else if (format == 2)
1223 printf ("(CaretValuePoint %d)",
1224 list->LigGlyph[i].CaretValue[j].f.f2.CaretValuePoint);
1226 else if (format == 3)
1228 printf ("(Coodinate %d)",
1229 list->LigGlyph[i].CaretValue[j].f.f3.Coordinate);
1232 (indent, "DeviceTable",
1233 &list->LigGlyph[i].CaretValue[j].f.f3.DeviceTable);
1245 dump_gdef_table (int indent, OTF_GDEF *gdef)
1251 dump_gdef_header (indent, &gdef->header);
1252 if (gdef->header.GlyphClassDef)
1253 dump_class_def (indent, "GlyphClassDef", &gdef->glyph_class_def);
1254 if (gdef->header.AttachList)
1255 dump_attach_list (indent, &gdef->attach_list);
1256 if (gdef->header.LigCaretList)
1257 dump_lig_caret_list (indent, &gdef->lig_caret_list);
1258 if (gdef->header.MarkAttachClassDef)
1259 dump_class_def (indent, "MarkAttachClassDef",
1260 &gdef->mark_attach_class_def);
1267 dump_cmap_table (int indent, OTF_cmap *cmap)
1273 IPRINT ("(version %d)", cmap->version);
1274 IPRINT ("(numTables %d)", cmap->numTables);
1275 for (i = 0; i < cmap->numTables; i++)
1277 IPRINT ("(EncodingRecord (%d) (platformID %d) (encodingID %d)",
1279 cmap->EncodingRecord[i].platformID,
1280 cmap->EncodingRecord[i].encodingID);
1282 IPRINT ("(Subtable (offset #x%04X) (format %d) (length #x%04X) (language %d)",
1283 cmap->EncodingRecord[i].offset,
1284 cmap->EncodingRecord[i].subtable.format,
1285 cmap->EncodingRecord[i].subtable.length,
1286 cmap->EncodingRecord[i].subtable.language);
1288 switch (cmap->EncodingRecord[i].subtable.format)
1293 unsigned char *array
1294 = cmap->EncodingRecord[i].subtable.f.f0->glyphIdArray;
1296 IPRINT ("(glyphIdArray");
1297 for (j = 0; j < 16; j++)
1300 for (k = 0; k < 16; k++)
1301 printf (" %3d", array[j * 16 + k]);
1309 OTF_EncodingSubtable4 *sub4
1310 = cmap->EncodingRecord[i].subtable.f.f4;
1313 IPRINT ("(segCountX2 %d) (searchRange %d)",
1314 sub4->segCountX2, sub4->searchRange);
1315 IPRINT ("(entrySelector %d) (rangeShift %d)",
1316 sub4->entrySelector, sub4->rangeShift);
1317 for (j = 0; j < sub4->segCountX2 / 2; j++)
1319 IPRINT ("(Segment (%d)", j);
1321 IPRINT ("(startCount #x%04X) (endCount #x%04X)",
1322 sub4->segments[j].startCount,
1323 sub4->segments[j].endCount);
1324 IPRINT ("(idDelta %d) (idRangeOffset #x%04X))",
1325 sub4->segments[j].idDelta,
1326 sub4->segments[j].idRangeOffset);
1329 IPRINT ("(glyphIdArray");
1330 for (j = 0; j < sub4->GlyphCount; j++)
1334 printf (" %3d", sub4->glyphIdArray[j]);
1342 OTF_EncodingSubtable6 *sub6
1343 = cmap->EncodingRecord[i].subtable.f.f6;
1346 IPRINT ("(firstCode %d) (entryCount %d)",
1347 sub6->firstCode, sub6->entryCount);
1348 IPRINT ("(glyphIdArray");
1349 for (j = 0; j < sub6->entryCount; j++)
1353 printf (" %3d", sub6->glyphIdArray[j]);
1369 dump_name_table (int indent, OTF_name *name)
1375 IPRINT ("(format %d)", name->format);
1376 IPRINT ("(count %d)", name->count);
1377 IPRINT ("(stringOffset %d)", name->stringOffset);
1378 for (i = 0; i < name->count; i++)
1380 OTF_NameRecord *rec = name->nameRecord + i;
1382 IPRINT ("(nameRecord (%d)", i);
1384 IPRINT ("(platformID %d) (encodingID %d) (languageID %d) (nameID %d)",
1385 rec->platformID, rec->encodingID, rec->languageID, rec->nameID);
1386 IPRINT ("(length %d) (offset #x%04X))", rec->length, rec->offset);
1389 for (i = 0; i <= OTF_max_nameID; i++)
1391 IPRINT ("(nameID %d \"%s\")", i, name->name[i]);
1405 dump_offset_table (1, &otf->offset_table);
1406 for (i = 0; i < otf->offset_table.numTables; i++)
1407 dump_table_directory (1, otf->table_dirs + i, i);
1410 dump_head_table (1, otf->head);
1412 dump_name_table (1, otf->name);
1414 dump_cmap_table (1, otf->cmap);
1416 dump_gdef_table (1, otf->gdef);
1418 dump_gsub_table (1, otf->gsub);
1420 dump_gpos_table (1, otf->gpos);
1423 dump_base_table (1, otf->base);
1425 dump_jstf_table (1, otf->jstf);
1432 main (int argc, char **argv)
1436 if (argc != 2 || !strcmp (argv[1], "-h") || !strcmp (argv[1], "--help"))
1438 fprintf (stderr, "Usage: %s OTF-FILE\n", basename (argv[0]));
1442 otf = OTF_open (argv[1]);
1445 OTF_perror ("otfdump");
1448 OTF_get_table (otf, "head");
1449 OTF_get_table (otf, "name");
1450 OTF_get_table (otf, "cmap");
1451 OTF_get_table (otf, "GDEF");
1452 OTF_get_table (otf, "GSUB");
1453 OTF_get_table (otf, "GPOS");
1455 OTF_get_table (otf, "BASE");
1456 OTF_get_table (otf, "JSTF");