1 /* otfdump.c -- Dump OpenType Layout Tables.
3 Copyright (C) 2003, 2004, 2008
4 National Institute of Advanced Industrial Science and Technology (AIST)
5 Registration Number H15PRO167
7 This file is part of libotf.
9 Libotf is free software; you can redistribute it and/or modify it
10 under the terms of the GNU Lesser General Public License as published
11 by the Free Software Foundation; either version 2.1 of the License, or
12 (at your option) any later version.
14 Libotf is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17 License for more details.
19 You should have received a copy of the GNU Lesser General Public
20 License along with this library, in a file named COPYING; if not,
21 write to the Free Software Foundation, Inc., 59 Temple Place, Suite
22 330, Boston, MA 02111-1307, USA. */
28 #include <sys/types.h>
35 char *indent_spaces[] =
36 { "", " ", " ", " ", " ", " ", " ",
40 #define IPRINT printf("\n%s", indent_spaces[indent]), printf
43 dump_tag (OTF_Tag tag)
47 putchar ((tag >> 16) & 0xFF);
48 putchar ((tag >> 8) & 0xFF);
50 printf ("\" #x%04X)", tag);
56 dump_offset_table (int indent, OTF_OffsetTable *table)
58 IPRINT ("(OffsetTable");
60 IPRINT ("(sfnt-version %d.%d)",
61 table->sfnt_version.high, table->sfnt_version.low);
62 IPRINT ("(numTables %d)", table->numTables);
63 IPRINT ("(searchRange %d)", table->searchRange);
64 IPRINT ("(enterSelector %d)", table->enterSelector);
65 IPRINT ("(rangeShift %d))", table->rangeShift);
69 dump_table_directory (int indent, OTF_TableDirectory *table, int idx)
71 IPRINT ("(Table %d ", idx);
72 dump_tag (table->tag);
74 IPRINT ("(checkSum %08X) (offset #x%08X) (length: #x%08X))",
75 table->checkSum, table->offset, table->length);
82 dump_head_table (int indent, OTF_head *head)
86 IPRINT ("(TableVersionNumber %d.%d)",
87 head->TableVersionNumber.high, head->TableVersionNumber.low);
88 IPRINT ("(fontRevision %d.%d)",
89 head->fontRevision.high, head->fontRevision.low);
90 IPRINT ("(checkSumAdjustment #x%04X)", head->checkSumAdjustment);
91 IPRINT ("(magicNumber #x%04X)", head->magicNumber);
92 IPRINT ("(flags #x%04X)", head->flags);
93 IPRINT ("(unitsPerEm %d)", head->unitsPerEm);
101 dump_glyph_ids (int indent, char *title, OTF_GlyphID *ids, unsigned count)
103 IPRINT ("(%s (count %d)", title, count);
106 printf (" #x%04X", *ids);
113 dump_coverage (int indent, char *title, OTF_Coverage *coverage)
118 IPRINT ("(%sCoverage (CoverageFormat %d)",
119 (title ? title : ""), coverage->CoverageFormat);
121 if (coverage->CoverageFormat == 1)
123 dump_glyph_ids (indent, "GlyphArray", coverage->table.GlyphArray,
125 char_list = malloc (sizeof (int) * (coverage->Count + 1));
126 for (i = 0; i < coverage->Count; i++)
127 char_list[i] = coverage->table.GlyphArray[i];
134 IPRINT ("(RangeCount %d)", coverage->Count);
136 for (i = n = 0; i < coverage->Count; i++)
138 IPRINT ("(Range (%d) (Start #x%04X) (End #x%04X)", i,
139 coverage->table.RangeRecord[i].Start,
140 coverage->table.RangeRecord[i].End);
142 IPRINT ("(StartCoverageIndex %d))",
143 coverage->table.RangeRecord[i].StartCoverageIndex);
145 n += (coverage->table.RangeRecord[i].End
146 - coverage->table.RangeRecord[i].Start + 1);
148 char_list = malloc (sizeof (int) * (n + 1));
149 for (i = n = 0; i < coverage->Count; i++)
150 for (c = coverage->table.RangeRecord[i].Start;
151 c <= coverage->table.RangeRecord[i].End;
161 dump_coverage_list (int indent, char *title,
162 OTF_Coverage *coverage, unsigned num)
166 IPRINT ("(%s %d)", title, num);
167 for (i = 0; i < num; i++)
168 free (dump_coverage (indent, NULL, coverage + i));
173 dump_language_system (int indent, int index, OTF_Tag tag, OTF_Offset offset,
174 OTF_LangSys *langsys)
178 IPRINT ("(LangSys ");
180 printf ("(%d) ", index);
184 printf ("DefaultLangSys");
185 printf (" (Offset #x%04X)", offset);
187 IPRINT ("(LookupOrder #x%04X)", langsys->LookupOrder);
188 IPRINT ("(ReqFeatureIndex %d)", langsys->ReqFeatureIndex);
189 IPRINT ("(FeatureCount %d)", langsys->FeatureCount);
190 if (langsys->FeatureCount)
192 IPRINT ("(FeatureIndex");
193 for (i = 0; i < langsys->FeatureCount; i++)
194 printf (" %d", langsys->FeatureIndex[i]);
201 dump_script_list (int indent, OTF_ScriptList *list)
205 IPRINT ("(ScriptList (count %d)", list->ScriptCount);
207 for (i = 0; i < list->ScriptCount; i++)
209 OTF_Script *script = list->Script + i;
211 IPRINT ("(Script (%d) ", i);
212 dump_tag (list->Script[i].ScriptTag);
213 printf (" (Offset #x%04X)", list->Script[i].offset);
215 IPRINT ("(DefaultLangSysOffset #x%04X)",
216 script->DefaultLangSysOffset);
217 if (script->DefaultLangSysOffset)
218 dump_language_system (indent, -1, 0,
219 script->DefaultLangSysOffset,
220 &script->DefaultLangSys);
221 IPRINT ("(LangSysCount %d)", script->LangSysCount);
222 for (j = 0; j < script->LangSysCount; j++)
223 dump_language_system (indent, j,
224 script->LangSysRecord[j].LangSysTag,
225 script->LangSysRecord[j].LangSys,
226 script->LangSys + j);
234 dump_feature_list (int indent, OTF_FeatureList *list)
238 IPRINT ("(FeatureList (count %d)", list->FeatureCount);
240 for (i = 0; i < list->FeatureCount; i++)
242 OTF_Feature *feature = list->Feature + i;
244 IPRINT ("(Feature (%d) ", i);
245 dump_tag (list->Feature[i].FeatureTag);
246 printf (" (Offset #x%04X)", list->Feature[i].offset);
247 printf (" (LookupCount %d)", feature->LookupCount);
248 if (feature->LookupCount)
251 IPRINT ("(LookupListIndex");
252 for (j = 0; j < feature->LookupCount; j++)
253 printf (" %d", feature->LookupListIndex[j]);
263 dump_class_def (int indent, char *title, OTF_ClassDef *class)
265 IPRINT ("(%s (offset #x%04X) (ClassFormat %d)",
266 (title ? title : "ClassDef"),
267 class->offset, class->ClassFormat);
271 if (class->ClassFormat == 1)
273 IPRINT ("(StartGlyph #x%04X)", class->f.f1.StartGlyph);
274 dump_glyph_ids (indent, "ClassValueArray",
275 (OTF_GlyphID *) class->f.f1.ClassValueArray,
276 class->f.f1.GlyphCount);
278 else if (class->ClassFormat == 2)
282 IPRINT ("(ClassRangeCount %d)", class->f.f2.ClassRangeCount);
283 IPRINT ("(ClassRangeRecord");
285 for (i = 0; i < class->f.f2.ClassRangeCount; i++)
286 IPRINT ("((Start #x%04X) (End #x%04X) (class %d))",
287 class->f.f2.ClassRangeRecord[i].Start,
288 class->f.f2.ClassRangeRecord[i].End,
289 class->f.f2.ClassRangeRecord[i].Class);
293 printf (" UnknownClassFormat");
299 dump_device_table (int indent, char *title, OTF_DeviceTable *table)
305 IPRINT ("(%s (offset #x%04X)", title, table->offset);
307 IPRINT ("(StartSize %d) (EndSize %d) (DeltaFormat %d)",
308 table->StartSize, table->EndSize, table->DeltaFormat);
309 if (table->DeltaValue)
311 IPRINT ("(DeltaValue");
312 for (i = 0; i < table->EndSize - table->StartSize + 1; i++)
313 printf (" %d", table->DeltaValue[i]);
322 dump_value_record (int indent, char *title, OTF_ValueRecord *rec)
324 IPRINT ("(%s %d %d %d %d", title,
325 rec->XPlacement, rec->YPlacement, rec->XAdvance, rec->YAdvance);
327 if (rec->XPlaDevice.offset)
328 dump_device_table (indent, "XPlaDevice", &rec->XPlaDevice);
329 if (rec->YPlaDevice.offset)
330 dump_device_table (indent, "YPlaDevice", &rec->YPlaDevice);
331 if (rec->XAdvDevice.offset)
332 dump_device_table (indent, "XAdvDevice", &rec->XAdvDevice);
333 if (rec->YAdvDevice.offset)
334 dump_device_table (indent, "YAdvDevice", &rec->YAdvDevice);
340 dump_sequence_list (int indent, OTF_Sequence *sequence, unsigned num)
343 IPRINT ("(SequenceCount %d)", num);
345 for (i = 0; i < num; i++)
347 IPRINT ("(Sequence (%d) (offset #x%04X)",
348 i, sequence[i].offset);
349 dump_glyph_ids (indent + 1, "Substitute", sequence[i].Substitute,
350 sequence[i].GlyphCount);
356 dump_alternate_set_list (int indent, OTF_AlternateSet *altset, unsigned num)
360 IPRINT ("(AlternateSetCount %d)", num);
361 for (i = 0; i < num; i++)
363 IPRINT ("(AlternateSet (%d) (offset #x%04X)",
364 i, altset[i].offset);
365 dump_glyph_ids (indent + 1, "Alternate", altset[i].Alternate,
366 altset[i].GlyphCount);
373 dump_ligature_set_list (int indent, int *char_list,
374 OTF_LigatureSet *ligset, unsigned num)
378 IPRINT ("(LigSetCount %d)", num);
379 for (i = 0; i < num; i++)
381 IPRINT ("(LigatureSet (%d) (offset #x%04X) (count %d)",
382 i, ligset[i].offset, ligset[i].LigatureCount);
384 for (j = 0; j < ligset[i].LigatureCount; j++)
386 IPRINT ("(Ligature (%d) (offset #x%04X)",
387 j, ligset[i].Ligature[j].offset);
389 IPRINT ("(LigGlyph #x%04X)",
390 ligset[i].Ligature[j].LigGlyph);
391 dump_glyph_ids (indent, "Component", ligset[i].Ligature[j].Component,
392 ligset[i].Ligature[j].CompCount - 1);
393 IPRINT ("(i.e. #x%04X", char_list[i]);
394 for (k = 0; k < ligset[i].Ligature[j].CompCount - 1; k++)
395 printf (" #x%04X", ligset[i].Ligature[j].Component[k]);
396 printf (" = #x%04X)", ligset[i].Ligature[j].LigGlyph);
406 dump_pair_set_list (int indent, unsigned count, OTF_PairSet *set)
410 for (i = 0; i < count; i++)
412 IPRINT ("(PairSet (%d)", i);
414 for (j = 0; j < set[i].PairValueCount; j++)
416 IPRINT ("(PairValueRecord (%d)", j);
418 IPRINT ("(SecondGlyph #x%04X)",
419 set[i].PairValueRecord[j].SecondGlyph);
420 dump_value_record (indent, "Value1",
421 &set[i].PairValueRecord[j].Value1);
422 dump_value_record (indent, "Value2",
423 &set[i].PairValueRecord[j].Value2);
433 dump_class1_record_list (int indent,
434 unsigned Class1Count, unsigned Class2Count,
435 OTF_Class1Record *rec)
439 for (i = 0; i < Class1Count; i++)
441 IPRINT ("(Class1Record (%d)", i);
443 for (j = 0; j < Class2Count; j++)
445 IPRINT ("(Class2Record (%d)", j);
447 dump_value_record (indent, "Value1", &rec[i].Class2Record[j].Value1);
448 dump_value_record (indent, "Value2", &rec[i].Class2Record[j].Value2);
458 dump_anchor (int indent, OTF_Anchor *anchor)
460 IPRINT ("(Anchor (offset #x%04X) (AnchorFormat %d)",
461 anchor->offset, anchor->AnchorFormat);
463 IPRINT ("(XCoordinate %d) (YCoordinate %d)",
464 anchor->XCoordinate, anchor->YCoordinate);
465 if (anchor->AnchorFormat == 1)
467 else if (anchor->AnchorFormat == 2)
468 IPRINT ("(AnchorPoint %d)", anchor->f.f1.AnchorPoint);
471 dump_device_table (indent, "XDeviceTable", &anchor->f.f2.XDeviceTable);
472 dump_device_table (indent, "YDeviceTable", &anchor->f.f2.YDeviceTable);
478 dump_entry_exit_list (int indent, unsigned count, OTF_EntryExitRecord *rec)
482 for (i = 0; i < count; i++)
484 IPRINT ("(EntryExitRecord (%d)", i);
486 dump_anchor (indent, &rec[i].EntryAnchor);
487 dump_anchor (indent, &rec[i].EntryAnchor);
494 dump_mark_array (int indent, OTF_MarkArray *array)
498 IPRINT ("(MarkArray (MarkCount %d)", array->MarkCount);
500 for (i = 0; i < array->MarkCount; i++)
502 IPRINT ("(MarkRecord (%d) (Class %d)", i, array->MarkRecord[i].Class);
503 dump_anchor (indent + 1, &array->MarkRecord[i].MarkAnchor);
510 dump_anchor_array (int indent, unsigned ClassCount, OTF_AnchorArray *array)
514 IPRINT ("(AnchorArray (Count %d)", array->Count);
516 for (i = 0; i < array->Count; i++)
518 IPRINT ("(AnchorRecord (%d) ", i);
519 for (j = 0; j < ClassCount; j++)
520 dump_anchor (indent + 1, array->AnchorRecord[i].Anchor + j);
528 dump_lookup_record_list (int indent, OTF_LookupRecord *rec, unsigned num)
532 IPRINT ("(LookupCount %d)", num);
533 for (i = 0; i < num; i++)
535 IPRINT ("(LookupRecord (%d)", i);
537 IPRINT ("(SequenceIndex %d)", rec[i].SequenceIndex);
538 IPRINT ("(LookupListIndex %d))", rec[i].LookupListIndex);
544 static void dump_lookup_subtable_gsub (int indent, int index, unsigned type,
545 OTF_LookupSubTableGSUB *subtable);
546 static void dump_lookup_subtable_gpos (int indent, int index, unsigned type,
547 OTF_LookupSubTableGPOS *subtable);
551 dump_lookup_list (int indent, OTF_LookupList *list, int gsub)
555 IPRINT ("(LookupList (count %d)", list->LookupCount);
557 for (i = 0; i < list->LookupCount; i++)
559 OTF_Lookup *lookup = list->Lookup + i;
561 IPRINT ("(Lookup (%d) (Offset #x%04X)",
563 printf (" (Type %d) (Flag #x%04X) (SubTableCount %d)",
564 lookup->LookupType, lookup->LookupFlag, lookup->SubTableCount);
566 for (j = 0; j < lookup->SubTableCount; j++)
567 dump_lookup_subtable_gsub (indent + 1, j,
569 lookup->SubTable.gsub + j);
571 for (j = 0; j < lookup->SubTableCount; j++)
572 dump_lookup_subtable_gpos (indent + 1, j,
574 lookup->SubTable.gpos + j);
582 dump_rule_list (int indent, OTF_Rule *rule, int count)
586 IPRINT ("(RuleCount %d)", count);
587 for (i = 0; i < count; i++)
589 IPRINT ("(Rule (%d)", i);
591 IPRINT ("(GlyphCount %d)", rule[i].GlyphCount);
592 IPRINT ("(LookupCount %d)", rule[i].LookupCount);
593 dump_glyph_ids (indent, "Input", rule[i].Input, rule[i].GlyphCount - 1);
594 dump_lookup_record_list (indent, rule[i].LookupRecord,
595 rule[i].LookupCount);
602 dump_rule_set_list (int indent, OTF_RuleSet *set, int count)
606 IPRINT ("(RuleSetCount %d)", count);
607 for (i = 0; i < count; i++)
609 IPRINT ("(RuleSet (%d)", i);
610 dump_rule_list (indent + 1, set[i].Rule, set[i].RuleCount);
616 dump_class_rule_list (int indent, OTF_ClassRule *rule, int count)
620 IPRINT ("(ClassRuleCnt %d)", count);
621 for (i = 0; i < count; i++)
623 IPRINT ("(ClassRule (%d)", i);
625 IPRINT ("(GlyphCount %d)", rule[i].GlyphCount);
626 IPRINT ("(LookupCount %d)", rule[i].LookupCount);
628 for (j = 0; j < rule[i].GlyphCount - 1; j++)
629 printf (" %d", rule[i].Class[j]);
631 dump_lookup_record_list (indent, rule[i].LookupRecord,
632 rule[i].LookupCount);
639 dump_class_set_list (int indent, OTF_ClassSet *set, int count)
643 IPRINT ("(ClassSetCount %d)", count);
644 for (i = 0; i < count; i++)
647 IPRINT ("(ClassSet (%d)", i);
648 dump_class_rule_list (indent + 1, set[i].ClassRule,
649 set[i].ClassRuleCnt);
655 dump_chain_rule_list (int indent, OTF_ChainRule *rule, int count)
659 IPRINT ("(ChainRuleCount %d)", count);
660 for (i = 0; i < count; i++)
662 IPRINT ("(ChainRule (%d)", i);
663 dump_glyph_ids (indent + 1, "Backtrack",
664 rule[i].Backtrack, rule[i].BacktrackGlyphCount);
665 dump_glyph_ids (indent + 1, "Input",
666 rule[i].Input, rule[i].InputGlyphCount - 1);
667 dump_glyph_ids (indent + 1, "LookAhead",
668 rule[i].LookAhead, rule[i].LookaheadGlyphCount);
669 dump_lookup_record_list (indent + 1, rule[i].LookupRecord,
670 rule[i].LookupCount);
676 dump_chain_rule_set_list (int indent, OTF_ChainRuleSet *set, int count)
680 IPRINT ("(ChainRuleSetCount %d)", count);
681 for (i = 0; i < count; i++)
683 IPRINT ("(ChainRuleSet (%d)", i);
684 dump_chain_rule_list (indent + 1,
685 set[i].ChainRule, set[i].ChainRuleCount);
691 dump_chain_class_rule_list (int indent, OTF_ChainClassRule *rule, int count)
695 IPRINT ("(ChainClassRuleCount %d)", count);
696 for (i = 0; i < count; i++)
698 IPRINT ("(ChainClassRule (%d)", i);
699 dump_glyph_ids (indent + 1, "Backtrack",
700 rule[i].Backtrack, rule[i].BacktrackGlyphCount);
701 dump_glyph_ids (indent + 1, "Input",
702 rule[i].Input, rule[i].InputGlyphCount - 1);
703 dump_glyph_ids (indent + 1, "LookAhead",
704 rule[i].LookAhead, rule[i].LookaheadGlyphCount);
705 dump_lookup_record_list (indent + 1, rule[i].LookupRecord,
706 rule[i].LookupCount);
712 dump_chain_class_set_list (int indent, OTF_ChainClassSet *set, int count)
716 IPRINT ("(ChainClassSetCount %d)", count);
717 for (i = 0; i < count; i++)
720 IPRINT ("(ChainClassSet (%d)", i);
721 dump_chain_class_rule_list (indent + 1,
722 set[i].ChainClassRule,
723 set[i].ChainClassRuleCnt);
735 dump_lookup_subtable_gsub (int indent, int index, unsigned type,
736 OTF_LookupSubTableGSUB *subtable)
738 IPRINT ("(SubTable (%d) (Format %d)", index, subtable->Format);
743 if (subtable->Format == 1)
745 free (dump_coverage (indent, NULL, &subtable->Coverage));
746 IPRINT ("(DeltaGlyhpID #x%04X)",
747 subtable->u.single1.DeltaGlyphID);
749 else if (subtable->Format == 2)
751 free (dump_coverage (indent, NULL, &subtable->Coverage));
752 dump_glyph_ids (indent, "Substitute", subtable->u.single2.Substitute,
753 subtable->u.single2.GlyphCount);
760 if (subtable->Format == 1)
762 free (dump_coverage (indent, NULL, &subtable->Coverage));
763 dump_sequence_list (indent,
764 subtable->u.multiple1.Sequence,
765 subtable->u.multiple1.SequenceCount);
772 if (subtable->Format == 1)
774 free (dump_coverage (indent, NULL, &subtable->Coverage));
775 dump_alternate_set_list (indent, subtable->u.alternate1.AlternateSet,
776 subtable->u.alternate1.AlternateSetCount);
783 if (subtable->Format == 1)
785 int *char_list = dump_coverage (indent, NULL, &subtable->Coverage);
786 dump_ligature_set_list (indent, char_list,
787 subtable->u.ligature1.LigatureSet,
788 subtable->u.ligature1.LigSetCount);
796 if (subtable->Format == 1)
798 free (dump_coverage (indent, NULL, &subtable->Coverage));
799 dump_rule_set_list (indent, subtable->u.context1.RuleSet,
800 subtable->u.context1.RuleSetCount);
802 else if (subtable->Format == 2)
804 free (dump_coverage (indent, NULL, &subtable->Coverage));
805 dump_class_def (indent, NULL, &subtable->u.context2.ClassDef);
806 dump_class_set_list (indent, subtable->u.context2.ClassSet,
807 subtable->u.context2.ClassSetCnt);
809 else if (subtable->Format == 3)
811 dump_coverage_list (indent, "Coverage",
812 subtable->u.context3.Coverage,
813 subtable->u.context3.GlyphCount);
814 dump_lookup_record_list (indent,
815 subtable->u.context3.LookupRecord,
816 subtable->u.context3.LookupCount);
823 if (subtable->Format == 1)
825 free (dump_coverage (indent, NULL, &subtable->Coverage));
826 dump_chain_rule_set_list
828 subtable->u.chain_context1.ChainRuleSet,
829 subtable->u.chain_context1.ChainRuleSetCount);
831 else if (subtable->Format == 2)
833 free (dump_coverage (indent, NULL, &subtable->Coverage));
834 dump_class_def (indent, "BacktrackClassDef",
835 &subtable->u.chain_context2.BacktrackClassDef);
836 dump_class_def (indent, "InputClassDef",
837 &subtable->u.chain_context2.InputClassDef);
838 dump_class_def (indent, "LookaheadClassDef",
839 &subtable->u.chain_context2.LookaheadClassDef);
840 dump_chain_class_set_list
842 subtable->u.chain_context2.ChainClassSet,
843 subtable->u.chain_context2.ChainClassSetCnt);
845 else if (subtable->Format == 3)
848 (indent, "BackTrackGlyphCount",
849 subtable->u.chain_context3.Backtrack,
850 subtable->u.chain_context3.BacktrackGlyphCount);
852 (indent, "InputGlyphCount",
853 subtable->u.chain_context3.Input,
854 subtable->u.chain_context3.InputGlyphCount);
856 (indent, "LookaheadGlyphCount",
857 subtable->u.chain_context3.LookAhead,
858 subtable->u.chain_context3.LookaheadGlyphCount);
859 dump_lookup_record_list
861 subtable->u.chain_context3.LookupRecord,
862 subtable->u.chain_context3.LookupCount);
869 IPRINT ("(ExtensionLookupType %d)",
870 subtable->u.extension1.ExtensionLookupType);
871 IPRINT ("(ExtensionOffset %d)",
872 subtable->u.extension1.ExtensionOffset);
873 dump_lookup_subtable_gsub (indent, index,
874 subtable->u.extension1.ExtensionLookupType,
875 subtable->u.extension1.ExtensionSubtable);
879 printf (" not-yet-supported");
889 dump_gsub_table (int indent, OTF_GSUB *gsub)
895 IPRINT ("(Version %d.%d)", gsub->Version.high, gsub->Version.low);
896 IPRINT ("(ScriptList #x%04X)", gsub->ScriptList.offset);
897 IPRINT ("(FeatureList #x%04X)", gsub->FeatureList.offset);
898 IPRINT ("(LookupList #x%04X))", gsub->LookupList.offset);
900 dump_script_list (indent, &gsub->ScriptList);
901 dump_feature_list (indent, &gsub->FeatureList);
902 dump_lookup_list (indent, &gsub->LookupList, 1);
910 dump_lookup_subtable_gpos (int indent, int index, unsigned type,
911 OTF_LookupSubTableGPOS *subtable)
913 IPRINT ("(SubTable (%d) (Format %d)", index, subtable->Format);
918 if (subtable->Format == 1)
920 free (dump_coverage (indent, NULL, &subtable->Coverage));
921 IPRINT ("(ValueFormat #x%04X)",
922 subtable->u.single1.ValueFormat);
923 dump_value_record (indent, "Value", &subtable->u.single1.Value);
925 else if (subtable->Format == 2)
929 free (dump_coverage (indent, NULL, &subtable->Coverage));
930 IPRINT ("(ValueFormat #x%04X)",
931 subtable->u.single2.ValueFormat);
932 IPRINT ("(ValueCount %d)",
933 subtable->u.single2.ValueCount);
934 for (i = 0; i < subtable->u.single2.ValueCount; i++)
935 dump_value_record (indent, "Value", &subtable->u.single2.Value[i]);
942 if (subtable->Format == 1)
944 free (dump_coverage (indent, NULL, &subtable->Coverage));
945 IPRINT ("(ValueFormat1 #x%04X)",
946 subtable->u.pair1.ValueFormat1);
947 IPRINT ("(ValueFormat2 #x%04X)",
948 subtable->u.pair1.ValueFormat2);
949 dump_pair_set_list (indent, subtable->u.pair1.PairSetCount,
950 subtable->u.pair1.PairSet);
952 else if (subtable->Format == 2)
954 free (dump_coverage (indent, NULL, &subtable->Coverage));
955 IPRINT ("(ValueFormat1 #x%04X)",
956 subtable->u.pair2.ValueFormat1);
957 IPRINT ("(ValueFormat2 #x%04X)",
958 subtable->u.pair2.ValueFormat2);
959 dump_class_def (indent, "ClassDef1",
960 &subtable->u.pair2.ClassDef1);
961 dump_class_def (indent, "ClassDef2",
962 &subtable->u.pair2.ClassDef2);
963 IPRINT ("(Class1Count %d)",
964 subtable->u.pair2.Class1Count);
965 IPRINT ("(Class2Count %d)",
966 subtable->u.pair2.Class2Count);
967 dump_class1_record_list (indent,
968 subtable->u.pair2.Class1Count,
969 subtable->u.pair2.Class2Count,
970 subtable->u.pair2.Class1Record);
977 if (subtable->Format == 1)
979 free (dump_coverage (indent, NULL, &subtable->Coverage));
980 dump_entry_exit_list (indent, subtable->u.cursive1.EntryExitCount,
981 subtable->u.cursive1.EntryExitRecord);
988 if (subtable->Format == 1)
990 free (dump_coverage (indent, "Mark", &subtable->Coverage));
991 free (dump_coverage (indent, "Base",
992 &subtable->u.mark_base1.BaseCoverage));
993 IPRINT ("(ClassCount %d)",
994 subtable->u.mark_base1.ClassCount);
995 dump_mark_array (indent, &subtable->u.mark_base1.MarkArray);
996 dump_anchor_array (indent, subtable->u.mark_base1.ClassCount,
997 &subtable->u.mark_base1.BaseArray);
1002 if (subtable->Format == 1)
1004 OTF_GPOS_MarkLig1 *mark_lig1 = &subtable->u.mark_lig1;
1007 free (dump_coverage (indent, "Mark", &subtable->Coverage));
1008 free (dump_coverage (indent, "Ligature",
1009 &mark_lig1->LigatureCoverage));
1010 IPRINT ("(ClassCount %d)", mark_lig1->ClassCount);
1011 dump_mark_array (indent, &mark_lig1->MarkArray);
1012 IPRINT ("(LigatureArray (%d)",
1013 mark_lig1->LigatureArray.LigatureCount);
1015 for (i = 0; i < mark_lig1->LigatureArray.LigatureCount; i++)
1017 OTF_LigatureAttach *attach
1018 = mark_lig1->LigatureArray.LigatureAttach + i;
1020 IPRINT ("(LigatureAttach (%d)", attach->ComponentCount);
1022 for (j = 0; j < attach->ComponentCount; j++)
1024 OTF_ComponentRecord *rec = attach->ComponentRecord + j;
1026 IPRINT ("(LigatureAnchor (%d)", mark_lig1->ClassCount);
1027 for (k = 0; k < mark_lig1->ClassCount; k++)
1028 if (rec->LigatureAnchor[k].AnchorFormat)
1029 dump_anchor (indent + 1, rec->LigatureAnchor + k);
1038 printf (" invalid");
1042 if (subtable->Format == 1)
1044 free (dump_coverage (indent, "Mark1", &subtable->Coverage));
1045 free (dump_coverage (indent, "Mark2",
1046 &subtable->u.mark_mark1.Mark2Coverage));
1047 IPRINT ("(ClassCount %d)",
1048 subtable->u.mark_mark1.ClassCount);
1049 dump_mark_array (indent, &subtable->u.mark_mark1.Mark1Array);
1050 dump_anchor_array (indent, subtable->u.mark_mark1.ClassCount,
1051 &subtable->u.mark_mark1.Mark2Array);
1054 printf (" invalid");
1058 if (subtable->Format == 1)
1060 free (dump_coverage (indent, NULL, &subtable->Coverage));
1061 dump_rule_set_list (indent, subtable->u.context1.RuleSet,
1062 subtable->u.context1.RuleSetCount);
1064 else if (subtable->Format == 2)
1066 free (dump_coverage (indent, NULL, &subtable->Coverage));
1067 dump_class_def (indent, NULL, &subtable->u.context2.ClassDef);
1068 dump_class_set_list (indent, subtable->u.context2.ClassSet,
1069 subtable->u.context2.ClassSetCnt);
1071 else if (subtable->Format == 3)
1073 dump_coverage_list (indent, "Coverage",
1074 subtable->u.context3.Coverage,
1075 subtable->u.context3.GlyphCount);
1076 dump_lookup_record_list (indent,
1077 subtable->u.context3.LookupRecord,
1078 subtable->u.context3.LookupCount);
1081 printf (" invalid");
1085 if (subtable->Format == 1)
1087 free (dump_coverage (indent, NULL, &subtable->Coverage));
1088 dump_chain_rule_set_list
1090 subtable->u.chain_context1.ChainRuleSet,
1091 subtable->u.chain_context1.ChainRuleSetCount);
1093 else if (subtable->Format == 2)
1095 free (dump_coverage (indent, NULL, &subtable->Coverage));
1096 dump_class_def (indent, "BacktrackClassDef",
1097 &subtable->u.chain_context2.BacktrackClassDef);
1098 dump_class_def (indent, "InputClassDef",
1099 &subtable->u.chain_context2.InputClassDef);
1100 dump_class_def (indent, "LookaheadClassDef",
1101 &subtable->u.chain_context2.LookaheadClassDef);
1102 dump_chain_class_set_list
1104 subtable->u.chain_context2.ChainClassSet,
1105 subtable->u.chain_context2.ChainClassSetCnt);
1107 else if (subtable->Format == 3)
1110 (indent, "BackTrackGlyphCount",
1111 subtable->u.chain_context3.Backtrack,
1112 subtable->u.chain_context3.BacktrackGlyphCount);
1114 (indent, "InputGlyphCount",
1115 subtable->u.chain_context3.Input,
1116 subtable->u.chain_context3.InputGlyphCount);
1118 (indent, "LookaheaGlyphCount",
1119 subtable->u.chain_context3.LookAhead,
1120 subtable->u.chain_context3.LookaheadGlyphCount);
1121 dump_lookup_record_list
1123 subtable->u.chain_context3.LookupRecord,
1124 subtable->u.chain_context3.LookupCount);
1127 printf (" invalid");
1131 if (subtable->Format == 1)
1133 IPRINT ("(ExtensionLookupType %d)",
1134 subtable->u.extension1.ExtensionLookupType);
1135 IPRINT ("(ExtensionOffset %d)",
1136 subtable->u.extension1.ExtensionOffset);
1137 dump_lookup_subtable_gpos
1139 subtable->u.extension1.ExtensionLookupType,
1140 subtable->u.extension1.ExtensionSubtable);
1143 printf (" invalid");
1150 dump_gpos_table (int indent, OTF_GPOS *gpos)
1158 IPRINT ("(Version %d.%d)", gpos->Version.high, gpos->Version.low);
1159 IPRINT ("(ScriptList #x%04X)", gpos->ScriptList.offset);
1160 IPRINT ("(FeatureList #x%04X)", gpos->FeatureList.offset);
1161 IPRINT ("(LookupList #x%04X))", gpos->LookupList.offset);
1163 dump_script_list (indent, &gpos->ScriptList);
1164 dump_feature_list (indent, &gpos->FeatureList);
1165 dump_lookup_list (indent, &gpos->LookupList, 0);
1171 dump_base_table (OTF_BASE *base)
1176 dump_jstf_table (OTF_JSTF *jstf)
1184 dump_gdef_header (int indent, OTF_GDEFHeader *header)
1188 IPRINT ("(Version %d.%d)",
1189 header->Version.high, header->Version.low);
1190 IPRINT ("(GlyphClassDef #x%04X)", header->GlyphClassDef);
1191 IPRINT ("(AttachList #x%04X)", header->AttachList);
1192 IPRINT ("(LigCaretList #x%04X)", header->LigCaretList);
1193 IPRINT ("(MarkAttachClassDef #x%04X))",
1194 header->MarkAttachClassDef);
1198 dump_attach_list (int indent, OTF_AttachList *list)
1203 dump_lig_caret_list (int indent, OTF_LigCaretList *list)
1207 IPRINT ("(LigCaretList");
1209 free (dump_coverage (indent, NULL, &list->Coverage));
1210 IPRINT ("(LigGlyphCount %d)", list->LigGlyphCount);
1211 for (i = 0; i < list->LigGlyphCount; i++)
1213 IPRINT ("(LigGlyph (%d) (offset #x%04X)",
1214 i, list->LigGlyph[i].offset);
1216 IPRINT ("(CaretCount %d)", list->LigGlyph[i].CaretCount);
1217 for (j = 0; j < list->LigGlyph[i].CaretCount; j++)
1219 unsigned format = list->LigGlyph[i].CaretValue[j].CaretValueFormat;
1221 IPRINT ("(Caret (%d) (CaretValueFormat %d)", j, format);
1224 printf ("(Coordinate %d)",
1225 list->LigGlyph[i].CaretValue[j].f.f1.Coordinate);
1227 else if (format == 2)
1229 printf ("(CaretValuePoint %d)",
1230 list->LigGlyph[i].CaretValue[j].f.f2.CaretValuePoint);
1232 else if (format == 3)
1234 printf ("(Coodinate %d)",
1235 list->LigGlyph[i].CaretValue[j].f.f3.Coordinate);
1238 (indent, "DeviceTable",
1239 &list->LigGlyph[i].CaretValue[j].f.f3.DeviceTable);
1251 dump_gdef_table (int indent, OTF_GDEF *gdef)
1257 dump_gdef_header (indent, &gdef->header);
1258 if (gdef->header.GlyphClassDef)
1259 dump_class_def (indent, "GlyphClassDef", &gdef->glyph_class_def);
1260 if (gdef->header.AttachList)
1261 dump_attach_list (indent, &gdef->attach_list);
1262 if (gdef->header.LigCaretList)
1263 dump_lig_caret_list (indent, &gdef->lig_caret_list);
1264 if (gdef->header.MarkAttachClassDef)
1265 dump_class_def (indent, "MarkAttachClassDef",
1266 &gdef->mark_attach_class_def);
1273 dump_cmap_table (int indent, OTF_cmap *cmap)
1279 IPRINT ("(version %d)", cmap->version);
1280 IPRINT ("(numTables %d)", cmap->numTables);
1281 for (i = 0; i < cmap->numTables; i++)
1283 IPRINT ("(EncodingRecord (%d) (platformID %d) (encodingID %d)",
1285 cmap->EncodingRecord[i].platformID,
1286 cmap->EncodingRecord[i].encodingID);
1288 IPRINT ("(Subtable (offset #x%04X) (format %d) (length #x%04X) (language %d)",
1289 cmap->EncodingRecord[i].offset,
1290 cmap->EncodingRecord[i].subtable.format,
1291 cmap->EncodingRecord[i].subtable.length,
1292 cmap->EncodingRecord[i].subtable.language);
1294 switch (cmap->EncodingRecord[i].subtable.format)
1299 unsigned char *array
1300 = cmap->EncodingRecord[i].subtable.f.f0->glyphIdArray;
1302 IPRINT ("(glyphIdArray");
1303 for (j = 0; j < 16; j++)
1306 for (k = 0; k < 16; k++)
1307 printf (" %3d", array[j * 16 + k]);
1315 OTF_EncodingSubtable4 *sub4
1316 = cmap->EncodingRecord[i].subtable.f.f4;
1319 IPRINT ("(segCountX2 %d) (searchRange %d)",
1320 sub4->segCountX2, sub4->searchRange);
1321 IPRINT ("(entrySelector %d) (rangeShift %d)",
1322 sub4->entrySelector, sub4->rangeShift);
1323 for (j = 0; j < sub4->segCountX2 / 2; j++)
1325 IPRINT ("(Segment (%d)", j);
1327 IPRINT ("(startCount #x%04X) (endCount #x%04X)",
1328 sub4->segments[j].startCount,
1329 sub4->segments[j].endCount);
1330 IPRINT ("(idDelta %d) (idRangeOffset #x%04X))",
1331 sub4->segments[j].idDelta,
1332 sub4->segments[j].idRangeOffset);
1335 IPRINT ("(glyphIdArray");
1336 for (j = 0; j < sub4->GlyphCount; j++)
1340 printf (" %3d", sub4->glyphIdArray[j]);
1348 OTF_EncodingSubtable6 *sub6
1349 = cmap->EncodingRecord[i].subtable.f.f6;
1352 IPRINT ("(firstCode %d) (entryCount %d)",
1353 sub6->firstCode, sub6->entryCount);
1354 IPRINT ("(glyphIdArray");
1355 for (j = 0; j < sub6->entryCount; j++)
1359 printf (" %3d", sub6->glyphIdArray[j]);
1367 OTF_EncodingSubtable12 *sub12
1368 = cmap->EncodingRecord[i].subtable.f.f12;
1371 for (j = 0; j < sub12->nGroups; j++)
1373 IPRINT ("(Group (#x%X) (startChar #x%04X) (endChar #x%04X) (startGlyphID #x%X))",
1375 sub12->Groups[j].startCharCode,
1376 sub12->Groups[j].endCharCode,
1377 sub12->Groups[j].startGlyphID);
1384 OTF_EncodingSubtable14 *sub14
1385 = cmap->EncodingRecord[i].subtable.f.f14;
1388 IPRINT ("(VariationSelectorRecords %d)",sub14->nRecords);
1389 for (j = 0; j < sub14->nRecords; j++)
1391 OTF_VariationSelectorRecord *record = sub14->Records + j;
1392 IPRINT ("(VariationSelectorRecord (varSelector #x%x)",
1393 record->varSelector);
1395 IPRINT ("(defaultUVSOffset #x%x)",
1396 record->defaultUVSOffset);
1397 if (record->defaultUVSOffset)
1399 IPRINT ("(defaultUVS");
1401 for (k = 0 ; k < record->numUnicodeValueRanges; k++)
1403 OTF_UnicodeValueRange *unicodeValueRange
1404 = &record->unicodeValueRanges[k];
1405 IPRINT("(startUnicodeValue #x%x) (additionalCount %d)",
1406 unicodeValueRange->startUnicodeValue,
1407 unicodeValueRange->additionalCount);
1412 IPRINT ("(nonDefaultUVSOffset #x%x)",
1413 record->nonDefaultUVSOffset);
1414 if (record->nonDefaultUVSOffset)
1416 IPRINT ("(NonDefaultUVS");
1418 for (k=0; k < record->numUVSMappings; k++)
1420 OTF_UVSMapping *uvsMapping
1421 = &record->uvsMappings[k];
1422 IPRINT("(unicodeValue #x%x) (glyphID %d)",
1423 uvsMapping->unicodeValue,
1424 uvsMapping->glyphID);
1444 dump_name_table (int indent, OTF_name *name)
1450 IPRINT ("(format %d)", name->format);
1451 IPRINT ("(count %d)", name->count);
1452 IPRINT ("(stringOffset %d)", name->stringOffset);
1453 for (i = 0; i < name->count; i++)
1455 OTF_NameRecord *rec = name->nameRecord + i;
1457 IPRINT ("(nameRecord (%d)", i);
1459 IPRINT ("(platformID %d) (encodingID %d) (languageID %d) (nameID %d)",
1460 rec->platformID, rec->encodingID, rec->languageID, rec->nameID);
1461 IPRINT ("(length %d) (offset #x%04X))", rec->length, rec->offset);
1464 for (i = 0; i <= OTF_max_nameID; i++)
1466 IPRINT ("(nameID %d \"%s\")", i, name->name[i]);
1480 dump_offset_table (1, &otf->offset_table);
1481 for (i = 0; i < otf->offset_table.numTables; i++)
1482 dump_table_directory (1, otf->table_dirs + i, i);
1485 dump_head_table (1, otf->head);
1487 dump_name_table (1, otf->name);
1489 dump_cmap_table (1, otf->cmap);
1491 dump_gdef_table (1, otf->gdef);
1493 dump_gsub_table (1, otf->gsub);
1495 dump_gpos_table (1, otf->gpos);
1498 dump_base_table (1, otf->base);
1500 dump_jstf_table (1, otf->jstf);
1507 main (int argc, char **argv)
1511 if (argc != 2 || !strcmp (argv[1], "-h") || !strcmp (argv[1], "--help"))
1513 fprintf (stderr, "Usage: %s OTF-FILE\n", basename (argv[0]));
1517 otf = OTF_open (argv[1]);
1520 OTF_perror ("otfdump");
1523 OTF_get_table (otf, "head");
1524 OTF_get_table (otf, "name");
1525 OTF_get_table (otf, "cmap");
1526 OTF_get_table (otf, "GDEF");
1527 OTF_get_table (otf, "GSUB");
1528 OTF_get_table (otf, "GPOS");
1530 OTF_get_table (otf, "BASE");
1531 OTF_get_table (otf, "JSTF");