10 Example of typical usage of OTF_Stream.
14 OTF_StreamState state;
17 OPEN_STREAM (_FILE_NAME_, stream);
20 SETUP_STREAM (stream, fp, 0, 256, _NAME_);
21 offset = READ_OFFSET (stream);
22 nbytes = READ_ULONG (stream);
23 SETUP_STREAM (stream, fp, offset, nbytes, _NAME2_);
25 CLOSE_STREAM (stream);
40 typedef long OTF_StreamState;
43 stream_open (char *filename)
47 char *errfmt = "stream open for %s";
50 fp = fopen (filename, "r");
52 OTF_ERROR (OTF_ERROR_FILE, filename);
53 OTF_CALLOC (stream, 1, filename);
59 stream_setup (OTF_Stream *stream, long offset, int nbytes, char *name)
61 char *errfmt = "stream setup for %s";
66 if (stream->allocated < nbytes)
68 unsigned char *buf = (unsigned char *) malloc (nbytes);
71 OTF_ERROR (OTF_ERROR_MEMORY, stream->name);
75 stream->allocated = nbytes;
77 stream->bufsize = nbytes;
78 if (fseek (stream->fp, offset, SEEK_SET) < 0)
79 OTF_ERROR (OTF_ERROR_FILE, stream->name);
80 if (fread (stream->buf, 1, nbytes, stream->fp) != nbytes)
81 OTF_ERROR (OTF_ERROR_FILE, stream->name);
87 stream_close (OTF_Stream *stream)
93 #define STREAM_SAVE_STATE(stream, state) ((state) = (stream)->pos)
94 #define STREAM_RESTORE_STATE(stream, state) ((stream)->pos = (state))
95 #define STREAM_SEEK(stream, offset) ((stream)->pos = (offset))
98 stream_overrun (OTF_Stream *stream)
100 char *errfmt = "buffer overrun in %s";
103 OTF_ERROR (OTF_ERROR_TABLE, (stream)->name);
106 #define STREAM_CHECK_SIZE(stream, size) \
107 if ((stream)->pos + (size) > (stream)->bufsize) \
109 stream_overrun (stream); \
115 #define READ_USHORT(stream, var) \
117 STREAM_CHECK_SIZE ((stream), 2); \
118 (var) = (((stream)->buf[(stream)->pos] << 8) \
119 | (stream)->buf[(stream)->pos + 1]); \
120 (stream)->pos += 2; \
123 #define READ_SHORT(stream, var) \
125 STREAM_CHECK_SIZE ((stream), 2); \
126 (var) = (short) (((stream)->buf[(stream)->pos] << 8) \
127 | (stream)->buf[(stream)->pos + 1]); \
128 (stream)->pos += 2; \
131 #define READ_ULONG(stream, var) \
133 STREAM_CHECK_SIZE ((stream), 4); \
134 (var) = (((stream)->buf[(stream)->pos] << 24) \
135 | ((stream)->buf[(stream)->pos + 1] << 16) \
136 | ((stream)->buf[(stream)->pos + 2] << 8) \
137 | (stream)->buf[(stream)->pos + 3]); \
138 (stream)->pos += 4; \
141 #define READ_LONG(stream, var) \
143 STREAM_CHECK_SIZE ((stream), 4); \
144 (var) = (int) (((stream)->buf[(stream)->pos] << 24) \
145 | ((stream)->buf[(stream)->pos + 1] << 16) \
146 | ((stream)->buf[(stream)->pos + 2] << 8) \
147 | (stream)->buf[(stream)->pos + 3]); \
148 (stream)->pos += 4; \
152 #define READ_FIXED(stream, fixed) \
154 READ_USHORT ((stream), (fixed).high); \
155 READ_USHORT ((stream), (fixed).low); \
159 #define READ_BYTES(stream, p, nbytes) \
161 STREAM_CHECK_SIZE ((stream), (nbytes)); \
162 memcpy ((p), (stream)->buf + (stream)->pos, (nbytes)); \
163 (stream)->pos += (nbytes); \
167 #define READ_TAG READ_ULONG
168 #define READ_OFFSET READ_USHORT
169 #define READ_UINT16 READ_USHORT
170 #define READ_INT16 READ_SHORT
171 #define READ_GLYPHID READ_USHORT
176 read_offset_table (OTF_Stream *stream, OTF_OffsetTable *table)
180 READ_FIXED (stream, table->sfnt_version);
181 READ_USHORT (stream, table->numTables);
182 READ_USHORT (stream, table->searchRange);
183 READ_USHORT (stream, table->enterSelector);
184 READ_USHORT (stream, table->rangeShift);
189 read_table_directory (OTF_Stream *stream, OTF_TableDirectory *table)
193 READ_TAG (stream, table->tag);
194 READ_ULONG (stream, table->checkSum);
195 READ_ULONG (stream, table->offset);
196 READ_ULONG (stream, table->length);
203 read_head_table (OTF_Stream *stream)
205 char *errfmt = "head%s";
209 OTF_CALLOC (head, 1, "");
210 READ_FIXED (stream, head->TableVersionNumber);
211 READ_FIXED (stream, head->fontRevision);
212 READ_ULONG (stream, head->checkSumAdjustment);
213 READ_ULONG (stream, head->magicNumber);
214 READ_USHORT (stream, head->flags);
215 READ_USHORT (stream, head->unitsPerEm);
223 read_script_list (OTF_Stream *stream, long offset, OTF_ScriptList *list)
225 char *errfmt = "Script List%s";
229 STREAM_SEEK (stream, offset);
230 READ_USHORT (stream, list->ScriptCount);
231 OTF_MALLOC (list->ScriptRecord, list->ScriptCount, "");
232 OTF_CALLOC (list->Script, list->ScriptCount, "");
234 for (i = 0; i < list->ScriptCount; i++)
236 READ_TAG (stream, list->ScriptRecord[i].ScriptTag);
237 READ_OFFSET (stream, list->ScriptRecord[i].Script);
239 for (i = 0; i < list->ScriptCount; i++)
241 OTF_Script *script = list->Script + i;
242 long script_offset = offset + list->ScriptRecord[i].Script;
244 STREAM_SEEK (stream, script_offset);
245 READ_OFFSET (stream, script->DefaultLangSysOffset);
246 READ_USHORT (stream, script->LangSysCount);
247 OTF_MALLOC (script->LangSysRecord, script->LangSysCount, " (LangSys)");
248 OTF_CALLOC (script->LangSys, script->LangSysCount, " (LangSys)");
249 for (j = 0; j < script->LangSysCount; j++)
251 READ_TAG (stream, script->LangSysRecord[j].LangSysTag);
252 READ_OFFSET (stream, script->LangSysRecord[j].LangSys);
255 if (script->DefaultLangSysOffset)
257 OTF_LangSys *langsys = &script->DefaultLangSys;
259 STREAM_SEEK (stream, script_offset + script->DefaultLangSysOffset);
260 READ_OFFSET (stream, langsys->LookupOrder);
261 READ_USHORT (stream, langsys->ReqFeatureIndex);
262 READ_USHORT (stream, langsys->FeatureCount);
263 OTF_MALLOC (langsys->FeatureIndex, langsys->FeatureCount,
265 for (k = 0; k < langsys->FeatureCount; k++)
266 READ_USHORT (stream, langsys->FeatureIndex[k]);
269 for (j = 0; j < script->LangSysCount; j++)
271 OTF_LangSys *langsys = script->LangSys + j;
274 script_offset + script->LangSysRecord[j].LangSys);
275 READ_OFFSET (stream, langsys->LookupOrder);
276 READ_USHORT (stream, langsys->ReqFeatureIndex);
277 READ_USHORT (stream, langsys->FeatureCount);
278 OTF_MALLOC (langsys->FeatureIndex, langsys->FeatureCount,
280 for (k = 0; k < langsys->FeatureCount; k++)
281 READ_USHORT (stream, langsys->FeatureIndex[k]);
289 read_feature_list (OTF_Stream *stream, long offset, OTF_FeatureList *list)
291 char *errfmt = "Feature List%s";
295 READ_UINT16 (stream, list->FeatureCount);
296 OTF_MALLOC (list->FeatureRecord, list->FeatureCount, "");
297 OTF_CALLOC (list->Feature, list->FeatureCount, "");
298 for (i = 0; i < list->FeatureCount; i++)
300 READ_TAG (stream, list->FeatureRecord[i].FeatureTag);
301 READ_OFFSET (stream, list->FeatureRecord[i].Feature);
303 for (i = 0; i < list->FeatureCount; i++)
305 OTF_Feature *feature = list->Feature + i;
307 STREAM_SEEK (stream, offset + list->FeatureRecord[i].Feature);
308 READ_OFFSET (stream, feature->FeatureParams);
309 READ_UINT16 (stream, feature->LookupCount);
310 OTF_MALLOC (feature->LookupListIndex, feature->LookupCount,
311 " (LookupListIndex)");
312 for (j = 0; j < feature->LookupCount; j++)
313 READ_UINT16 (stream, feature->LookupListIndex[j]);
319 static int read_lookup_subtable_gsub (OTF_Stream *stream, long offset,
321 OTF_LookupSubTable *subtable);
322 static int read_lookup_subtable_gpos (OTF_Stream *stream, long offset,
324 OTF_LookupSubTable *subtable);
327 read_lookup_list (OTF_Stream *stream, long offset,
328 OTF_LookupList *list, int gsub)
330 char *errfmt = "Lookup List%s";
334 STREAM_SEEK (stream, offset);
335 READ_UINT16 (stream, list->LookupCount);
336 OTF_MALLOC (list->LookupOffset, list->LookupCount, "");
337 OTF_CALLOC (list->Lookup, list->LookupCount, "");
339 for (i = 0; i < list->LookupCount; i++)
340 READ_OFFSET (stream, list->LookupOffset[i]);
341 for (i = 0; i < list->LookupCount; i++)
343 OTF_Lookup *lookup = list->Lookup + i;
345 STREAM_SEEK (stream, offset + list->LookupOffset[i]);
346 READ_UINT16 (stream, lookup->LookupType);
347 READ_UINT16 (stream, lookup->LookupFlag);
348 READ_UINT16 (stream, lookup->SubTableCount);
349 OTF_MALLOC (lookup->SubTableOffset, lookup->SubTableCount,
350 " (SubTableOffset)");
351 OTF_CALLOC (lookup->SubTable, lookup->SubTableCount,
353 for (j = 0; j < lookup->SubTableCount; j++)
354 READ_OFFSET (stream, lookup->SubTableOffset[j]);
356 for (j = 0; j < lookup->SubTableCount; j++)
359 = offset + list->LookupOffset[i] + lookup->SubTableOffset[j];
361 if (read_lookup_subtable_gsub (stream, this_offset,
363 lookup->SubTable + j) < 0)
367 for (j = 0; j < lookup->SubTableCount; j++)
370 = offset + list->LookupOffset[i] + lookup->SubTableOffset[j];
372 if (read_lookup_subtable_gpos (stream, this_offset,
374 lookup->SubTable + j) < 0)
384 read_glyph_ids (OTF_Stream *stream, OTF_GlyphID **ids, int minus)
386 char *errfmt = "GlyphID List%s";
391 READ_UINT16 (stream, count);
394 OTF_MALLOC (*ids, count, "");
395 for (i = 0; i < count + minus; i++)
396 READ_GLYPHID (stream, (*ids)[i]);
401 read_range_record (OTF_Stream *stream, OTF_RangeRecord **record)
403 char *errfmt = "RangeRecord%s";
408 READ_UINT16 (stream, count);
411 OTF_MALLOC (*record, count, "");
412 for (i = 0; i < count; i++)
414 READ_GLYPHID (stream, (*record)[i].Start);
415 READ_GLYPHID (stream, (*record)[i].End);
416 READ_UINT16 (stream, (*record)[i].StartCoverageIndex);
423 read_coverage (OTF_Stream *stream, long offset, OTF_Coverage *coverage)
425 char *errfmt = "Coverage%s";
427 OTF_StreamState state;
430 READ_OFFSET (stream, coverage->offset);
431 STREAM_SAVE_STATE (stream, state);
432 STREAM_SEEK (stream, offset + coverage->offset);
433 READ_UINT16 (stream, coverage->CoverageFormat);
434 if (coverage->CoverageFormat == 1)
435 count = read_glyph_ids (stream, &coverage->table.GlyphArray, 0);
436 else if (coverage->CoverageFormat == 2)
437 count = read_range_record (stream, &coverage->table.RangeRecord);
439 OTF_ERROR (OTF_ERROR_TABLE, " (Invalid Format)");
442 coverage->Count = (unsigned) count;
443 STREAM_RESTORE_STATE (stream, state);
448 read_coverage_list (OTF_Stream *stream, long offset, OTF_Coverage **coverage)
450 char *errfmt = "Coverage List%s";
455 READ_UINT16 (stream, count);
458 OTF_MALLOC (*coverage, count, "");
459 for (i = 0; i < count; i++)
460 if (read_coverage (stream, offset, (*coverage) + i) < 0)
467 read_class_def_without_offset (OTF_Stream *stream, OTF_ClassDef *class)
469 char *errfmt = "ClassDef%s";
472 STREAM_SEEK (stream, class->offset);
473 READ_UINT16 (stream, class->ClassFormat);
474 if (class->ClassFormat == 1)
476 READ_GLYPHID (stream, class->f.f1.StartGlyph);
477 class->f.f1.GlyphCount
479 (stream, (OTF_GlyphID **) &class->f.f1.ClassValueArray, 0));
480 if (! class->f.f1.GlyphCount)
483 else if (class->ClassFormat == 2)
485 class->f.f2.ClassRangeCount
487 (stream, (OTF_RangeRecord **) &class->f.f2.ClassRangeRecord));
488 if (! class->f.f2.ClassRangeCount)
492 OTF_ERROR (OTF_ERROR_TABLE, " (Invalid format)");
498 read_class_def (OTF_Stream *stream, long offset, OTF_ClassDef *class)
500 char *errfmt = "ClassDef%s";
502 OTF_StreamState state;
504 READ_OFFSET (stream, class->offset);
505 STREAM_SAVE_STATE (stream, state);
506 STREAM_SEEK (stream, offset + class->offset);
507 READ_UINT16 (stream, class->ClassFormat);
508 if (class->ClassFormat == 1)
510 READ_GLYPHID (stream, class->f.f1.StartGlyph);
511 class->f.f1.GlyphCount
513 (stream, (OTF_GlyphID **) &class->f.f1.ClassValueArray, 0));
514 if (! class->f.f1.GlyphCount)
517 else if (class->ClassFormat == 2)
519 class->f.f2.ClassRangeCount
521 (stream, (OTF_RangeRecord **) &class->f.f2.ClassRangeRecord));
522 if (! class->f.f2.ClassRangeCount)
526 OTF_ERROR (OTF_ERROR_TABLE, " (Invalid format)");
528 STREAM_RESTORE_STATE (stream, state);
533 read_device_table (OTF_Stream *stream, long offset, OTF_DeviceTable *table)
535 char *errfmt = "Device Table%s";
546 STREAM_SEEK (stream, offset + table->offset);
547 READ_UINT16 (stream, table->StartSize);
548 READ_UINT16 (stream, table->EndSize);
549 READ_UINT16 (stream, table->DeltaFormat);
550 num = table->EndSize - table->StartSize + 1;
551 OTF_MALLOC (table->DeltaValue, num, "");
553 if (table->DeltaFormat == 1)
554 for (i = 0; i < num; i++)
557 READ_UINT16 (stream, val);
558 intval.int2 = (val >> (14 - (i % 8) * 2)) & 0x03;
559 table->DeltaValue[i] = intval.int2;
561 else if (table->DeltaFormat == 2)
562 for (i = 0; i < num; i++)
565 READ_UINT16 (stream, val);
566 intval.int4 = (val >> (12 - (i % 4) * 4)) & 0x0F;
567 table->DeltaValue[i] = intval.int4;
569 else if (table->DeltaFormat == 3)
570 for (i = 0; i < num; i++)
574 READ_UINT16 (stream, val);
575 intval.int8 = val >> 8;
576 table->DeltaValue[i] = intval.int8;
580 intval.int8 = val >> 8;
581 table->DeltaValue[i] = intval.int8;
585 OTF_ERROR (OTF_ERROR_TABLE, " (Invalid format)");
594 read_gsub_header (OTF_Stream *stream, OTF_GSUBHeader *header)
598 READ_FIXED (stream, header->Version);
599 READ_OFFSET (stream, header->ScriptList);
600 READ_OFFSET (stream, header->FeatureList);
601 READ_OFFSET (stream, header->LookupList);
606 read_gsub_table (OTF_Stream *stream)
608 char *errfmt = "GSUB%s";
612 OTF_CALLOC (gsub, 1, "");
613 if (read_gsub_header (stream, &gsub->header) < 0
614 || read_script_list (stream, gsub->header.ScriptList,
615 &gsub->script_list) < 0
616 || read_feature_list (stream, gsub->header.FeatureList,
617 &gsub->feature_list) < 0
618 || read_lookup_list (stream, gsub->header.LookupList,
619 &gsub->lookup_list, 1) < 0)
626 read_sequence (OTF_Stream *stream, long offset, OTF_Sequence **seq)
628 char *errfmt = "Sequence%s";
633 READ_UINT16 (stream, count);
634 OTF_MALLOC (*seq, count, "");
636 OTF_ERROR (OTF_ERROR_TABLE, " (zero count)");
637 for (i = 0; i < count; i++)
638 READ_OFFSET (stream, (*seq)[i].offset);
639 for (i = 0; i < count; i++)
641 STREAM_SEEK (stream, offset + (*seq)[i].offset);
642 (*seq)[i].GlyphCount = read_glyph_ids (stream, &(*seq)[i].Substitute, 0);
643 if (! (*seq)[i].GlyphCount)
650 read_ligature (OTF_Stream *stream, long offset, OTF_Ligature **ligature)
652 char *errfmt = "Ligature%s";
657 READ_UINT16 (stream, count);
660 OTF_MALLOC (*ligature, count, "");
661 for (i = 0; i < count; i++)
662 READ_OFFSET (stream, (*ligature)[i].offset);
663 for (i = 0; i < count; i++)
665 STREAM_SEEK (stream, offset + (*ligature)[i].offset);
666 READ_GLYPHID (stream, (*ligature)[i].LigGlyph);
667 (*ligature)[i].CompCount
668 = read_glyph_ids (stream, &(*ligature)[i].Component, -1);
669 if (! (*ligature)[i].CompCount)
676 read_ligature_set (OTF_Stream *stream, long offset, OTF_LigatureSet **ligset)
678 char *errfmt = "LigatureSet%s";
683 READ_UINT16 (stream, count);
686 OTF_MALLOC (*ligset, count, "");
687 for (i = 0; i < count; i++)
688 READ_OFFSET (stream, (*ligset)[i].offset);
689 for (i = 0; i < count; i++)
693 STREAM_SEEK (stream, offset + (*ligset)[i].offset);
694 lig_count = read_ligature (stream, offset + (*ligset)[i].offset,
695 &(*ligset)[i].Ligature);
698 (*ligset)[i].LigatureCount = (unsigned) lig_count;
704 read_subst_lookup_record (OTF_Stream *stream, OTF_SubstLookupRecord **record)
706 char *errfmt = "SubstLookupRecord%s";
711 READ_UINT16 (stream, count);
713 OTF_ERROR (OTF_ERROR_TABLE, " (zero count)");
714 OTF_MALLOC (*record, count, "");
715 for (i = 0; i < count; i++)
717 READ_UINT16 (stream, (*record)[i].SequenceIndex);
718 READ_UINT16 (stream, (*record)[i].LookupListIndex);
724 read_chain_subrule (OTF_Stream *stream, long offset, OTF_ChainSubRule **rule)
726 char *errfmt = "ChainSubRule%s";
731 READ_UINT16 (stream, count);
733 OTF_ERROR (OTF_ERROR_TABLE, " (zero count)");
734 OTF_MALLOC (*rule, count, "");
735 for (i = 0; i < count; i++)
736 READ_OFFSET (stream, (*rule)[i].offset);
737 for (i = 0; i < count; i++)
739 STREAM_SEEK (stream, offset + (*rule)[i].offset);
740 (*rule)[i].BacktrackGlyphCount
741 = read_glyph_ids (stream, &(*rule)[i].Backtrack, 0);
742 if (! (*rule)[i].BacktrackGlyphCount)
744 (*rule)[i].InputGlyphCount
745 = read_glyph_ids (stream, &(*rule)[i].Input, -1);
746 if (! (*rule)[i].InputGlyphCount)
748 (*rule)[i].LookaheadGlyphCount
749 = read_glyph_ids (stream, &(*rule)[i].LookAhead, 0);
750 if (! (*rule)[i].LookaheadGlyphCount)
752 (*rule)[i].SubstCount
753 = read_subst_lookup_record (stream, &(*rule)[i].SubstLookupRecord);
754 if (! (*rule)[i].SubstCount)
762 read_chain_subrule_set (OTF_Stream *stream, long offset,
763 OTF_ChainSubRuleSet **set)
765 char *errfmt = "ChainSubRuleSet%s";
770 READ_UINT16 (stream, count);
772 OTF_ERROR (OTF_ERROR_TABLE, " (zero count)");
773 OTF_MALLOC (*set, count, "");
774 for (i = 0; i < count; i++)
775 READ_OFFSET (stream, (*set)[i].offset);
776 for (i = 0; i < count; i++)
778 STREAM_SEEK (stream, offset + (*set)[i].offset);
779 (*set)[i].ChainSubRuleCount
780 = read_chain_subrule (stream, offset + (*set)[i].offset,
781 &(*set)[i].ChainSubRule);
782 if (! (*set)[i].ChainSubRuleCount)
789 read_chain_subclass_rule (OTF_Stream *stream, long offset,
790 OTF_ChainSubClassRule **rule)
792 char *errfmt = "ChainSubClassRule%s";
797 READ_UINT16 (stream, count);
799 OTF_ERROR (OTF_ERROR_TABLE, " (zero count)");
800 OTF_MALLOC (*rule, count, "");
801 for (i = 0; i < count; i++)
802 READ_OFFSET (stream, (*rule)[i].offset);
803 for (i = 0; i < count; i++)
805 STREAM_SEEK (stream, offset + (*rule)[i].offset);
806 (*rule)[i].BacktrackGlyphCount
807 = read_glyph_ids (stream, (OTF_GlyphID **) &(*rule)[i].Backtrack, 0);
808 if (! (*rule)[i].BacktrackGlyphCount)
810 (*rule)[i].InputGlyphCount
811 = read_glyph_ids (stream, (OTF_GlyphID **) &(*rule)[i].Input, -1);
812 if (! (*rule)[i].InputGlyphCount)
814 (*rule)[i].LookaheadGlyphCount
815 = read_glyph_ids (stream, (OTF_GlyphID **) &(*rule)[i].LookAhead, 0);
816 if (! (*rule)[i].LookaheadGlyphCount)
818 (*rule)[i].SubstCount
819 = read_subst_lookup_record (stream, &(*rule)[i].SubstLookupRecord);
820 if (! (*rule)[i].SubstCount)
827 read_chain_subclass_set (OTF_Stream *stream, long offset,
828 OTF_ChainSubClassSet **set)
830 char *errfmt = "ChainSubClassSet%s";
835 READ_UINT16 (stream, count);
837 OTF_ERROR (OTF_ERROR_TABLE, " (zero count)");
838 OTF_MALLOC (*set, count, "");
839 for (i = 0; i < count; i++)
840 READ_OFFSET (stream, (*set)[i].offset);
841 for (i = 0; i < count; i++)
843 STREAM_SEEK (stream, offset + (*set)[i].offset);
844 (*set)[i].ChainSubClassRuleCnt
845 = read_chain_subclass_rule (stream, offset + (*set)[i].offset,
846 &(*set)[i].ChainSubClassRule);
847 if (! (*set)[i].ChainSubClassRuleCnt)
855 read_lookup_subtable_gsub (OTF_Stream *stream, long offset,
856 unsigned type, OTF_LookupSubTable *subtable)
858 char *errfmt = "GSUB LookupSubTable%s";
862 STREAM_SEEK (stream, offset);
863 READ_UINT16 (stream, subtable->Format);
867 if (subtable->Format == 1)
869 if (read_coverage (stream, offset, &subtable->Coverage) < 0)
871 READ_INT16 (stream, subtable->sub.gsub.single1.DeltaGlyphID);
873 else if (subtable->Format == 2)
875 if (read_coverage (stream, offset, &subtable->Coverage) < 0)
877 subtable->sub.gsub.single2.GlyphCount
878 = read_glyph_ids (stream, &subtable->sub.gsub.single2.Substitute,
880 if (! subtable->sub.gsub.single2.GlyphCount)
884 OTF_ERROR (OTF_ERROR_TABLE, " (Invalid SubFormat)");
888 if (subtable->Format == 1)
890 read_coverage (stream, offset, &subtable->Coverage);
891 subtable->sub.gsub.multiple1.SequenceCount
892 = read_sequence (stream, offset,
893 &subtable->sub.gsub.multiple1.Sequence);
896 OTF_ERROR (OTF_ERROR_TABLE, " (Invalid SubFormat)");
903 if (subtable->Format == 1)
905 read_coverage (stream, offset, &subtable->Coverage);
906 count = (read_ligature_set
908 &subtable->sub.gsub.ligature1.LigatureSet));
911 subtable->sub.gsub.ligature1.LigSetCount = (unsigned) count;
914 OTF_ERROR (OTF_ERROR_TABLE, " (Invalid SubFormat)");
918 if (subtable->Format == 1)
920 read_coverage (stream, offset, &subtable->Coverage);
921 subtable->sub.gsub.chain_context1.ChainSubRuleSetCount
922 = (read_chain_subrule_set
924 &subtable->sub.gsub.chain_context1.ChainSubRuleSet));
926 else if (subtable->Format == 2)
928 read_coverage (stream, offset, &subtable->Coverage);
929 read_class_def (stream, offset,
930 &subtable->sub.gsub.chain_context2.Backtrack);
931 read_class_def (stream, offset,
932 &subtable->sub.gsub.chain_context2.Input);
933 read_class_def (stream, offset,
934 &subtable->sub.gsub.chain_context2.LookAhead);
935 subtable->sub.gsub.chain_context2.ChainSubClassSetCnt
936 = (read_chain_subclass_set
938 &subtable->sub.gsub.chain_context2.ChainSubClassSet));
940 else if (subtable->Format == 3)
942 count = (read_coverage_list
944 &subtable->sub.gsub.chain_context3.Backtrack));
947 subtable->sub.gsub.chain_context3.BacktrackGlyphCount
949 count = (read_coverage_list
951 &subtable->sub.gsub.chain_context3.Input));
954 subtable->sub.gsub.chain_context3.InputGlyphCount
956 subtable->Coverage = subtable->sub.gsub.chain_context3.Input[0];
957 count = (read_coverage_list
959 &subtable->sub.gsub.chain_context3.LookAhead));
960 subtable->sub.gsub.chain_context3.LookaheadGlyphCount
962 subtable->sub.gsub.chain_context3.SubstCount
963 = (read_subst_lookup_record
964 (stream, &subtable->sub.gsub.chain_context3.SubstLookupRecord));
967 OTF_ERROR (OTF_ERROR_TABLE, " (Invalid SubFormat)");
972 OTF_ERROR (OTF_ERROR_TABLE, " (Invalid LookupType)");
981 read_value_record (OTF_Stream *stream, long offset,
982 enum OTF_ValueFormat bit, OTF_ValueRecord *value_record)
985 OTF_StreamState state;
990 for (i = 0, size = 0; i < 8; i++)
994 if (bit & OTF_XPlacement)
995 READ_INT16 (stream, value_record->XPlacement);
996 if (bit & OTF_XPlacement)
997 READ_INT16 (stream, value_record->YPlacement);
998 if (bit & OTF_XAdvance)
999 READ_INT16 (stream, value_record->XAdvance);
1000 if (bit & OTF_YAdvance)
1001 READ_INT16 (stream, value_record->YAdvance);
1002 if (bit & OTF_XPlaDevice)
1003 READ_OFFSET (stream, value_record->XPlaDevice.offset);
1004 if (bit & OTF_YPlaDevice)
1005 READ_OFFSET (stream, value_record->YPlaDevice.offset);
1006 if (bit & OTF_XAdvDevice)
1007 READ_OFFSET (stream, value_record->XAdvDevice.offset);
1008 if (bit & OTF_YAdvDevice)
1009 READ_OFFSET (stream, value_record->YAdvDevice.offset);
1010 STREAM_SAVE_STATE (stream, state);
1011 if (value_record->XPlaDevice.offset)
1013 if (read_device_table (stream, offset, &value_record->XPlaDevice) < 0)
1016 if (value_record->YPlaDevice.offset)
1018 if (read_device_table (stream, offset, &value_record->YPlaDevice) < 0)
1021 if (value_record->XAdvDevice.offset)
1023 if (read_device_table (stream, offset, &value_record->XAdvDevice) < 0)
1026 if (value_record->YAdvDevice.offset)
1028 if (read_device_table (stream, offset, &value_record->YAdvDevice) < 0)
1031 STREAM_RESTORE_STATE (stream, state);
1037 read_anchor (OTF_Stream *stream, long offset, OTF_Anchor *anchor)
1039 char *errfmt = "Anchor%s";
1042 STREAM_SEEK (stream, offset + anchor->offset);
1043 READ_UINT16 (stream, anchor->AnchorFormat);
1044 READ_INT16 (stream, anchor->XCoordinate);
1045 READ_INT16 (stream, anchor->YCoordinate);
1046 if (anchor->AnchorFormat == 1)
1048 else if (anchor->AnchorFormat == 2)
1050 READ_UINT16 (stream, anchor->f.f1.AnchorPoint);
1052 else if (anchor->AnchorFormat == 3)
1054 READ_OFFSET (stream, anchor->f.f2.XDeviceTable.offset);
1055 READ_OFFSET (stream, anchor->f.f2.YDeviceTable.offset);
1056 if (anchor->f.f2.XDeviceTable.offset)
1058 if (read_device_table (stream, offset + anchor->offset,
1059 &anchor->f.f2.XDeviceTable) < 0)
1062 if (anchor->f.f2.YDeviceTable.offset)
1064 if (read_device_table (stream, offset + anchor->offset,
1065 &anchor->f.f2.YDeviceTable) < 0)
1070 OTF_ERROR (OTF_ERROR_TABLE, " (invalid format)");
1076 read_mark_array (OTF_Stream *stream, long offset, OTF_MarkArray *array)
1078 char *errfmt = "MarkArray%s";
1080 OTF_StreamState state;
1083 READ_OFFSET (stream, array->offset);
1084 STREAM_SAVE_STATE (stream, state);
1085 STREAM_SEEK (stream, offset + array->offset);
1086 READ_UINT16 (stream, array->MarkCount);
1087 OTF_MALLOC (array->MarkRecord, array->MarkCount, "");
1088 for (i = 0; i < array->MarkCount; i++)
1090 READ_UINT16 (stream, array->MarkRecord[i].Class);
1091 READ_OFFSET (stream, array->MarkRecord[i].MarkAnchor.offset);
1093 for (i = 0; i < array->MarkCount; i++)
1094 if (read_anchor (stream, offset + array->offset,
1095 &array->MarkRecord[i].MarkAnchor) < 0)
1097 STREAM_RESTORE_STATE (stream, state);
1102 read_base_array (OTF_Stream *stream, long offset,
1103 unsigned ClassCount, OTF_BaseArray *array)
1105 char *errfmt = "BaseArray%s";
1107 OTF_StreamState state;
1110 READ_OFFSET (stream, array->offset);
1111 STREAM_SAVE_STATE (stream, state);
1112 STREAM_SEEK (stream, offset + array->offset);
1113 READ_UINT16 (stream, array->BaseCount);
1114 OTF_MALLOC (array->BaseRecord, array->BaseCount, "");
1115 for (i = 0; i < array->BaseCount; i++)
1117 OTF_MALLOC (array->BaseRecord[i].BaseAnchor, ClassCount,
1119 for (j = 0; j < ClassCount; j++)
1120 READ_OFFSET (stream, array->BaseRecord[i].BaseAnchor[j].offset);
1122 for (i = 0; i < array->BaseCount; i++)
1123 for (j = 0; j < ClassCount; j++)
1124 if (read_anchor (stream, offset + array->offset,
1125 &array->BaseRecord[i].BaseAnchor[j]) < 0)
1127 STREAM_RESTORE_STATE (stream, state);
1132 static OTF_Class1Record *
1133 read_class1_record_list (OTF_Stream *stream, long offset,
1134 unsigned num1, enum OTF_ValueFormat bit1,
1135 unsigned num2, enum OTF_ValueFormat bit2)
1137 char *errfmt = "Class1Record%s";
1138 void *errret = NULL;
1139 OTF_Class1Record *rec;
1142 OTF_MALLOC (rec, num1, "");
1143 for (i = 0; i < num1; i++)
1145 OTF_CALLOC (rec[i].Class2Record, num2, " (Class2Record)");
1146 for (j = 0; j < num2; j++)
1148 if (read_value_record (stream, offset,
1149 bit1, &rec[i].Class2Record[j].Value1) < 0
1150 || read_value_record (stream, offset,
1151 bit2, &rec[i].Class2Record[j].Value2) < 0)
1160 read_lookup_subtable_gpos (OTF_Stream *stream, long offset, unsigned type,
1161 OTF_LookupSubTable *subtable)
1163 char *errfmt = "GPOS LookupSubTable%s";
1166 STREAM_SEEK (stream, offset);
1167 READ_UINT16 (stream, subtable->Format);
1172 if (subtable->Format == 1)
1174 read_coverage (stream, offset, &subtable->Coverage);
1175 subtable->sub.gsub.single1.DeltaGlyphID = READ_INT16 (stream);
1177 else if (subtable->Format == 2)
1179 read_coverage (stream, offset, &subtable->Coverage);
1180 subtable->sub.gsub.single2.GlyphCount
1181 = read_glyph_ids (stream,
1182 &subtable->sub.gsub.single2.Substitute, 0);
1185 OTF_ERROR (OTF_ERROR_TABLE, " (Invalid SubFormat)");
1190 if (subtable->Format == 1)
1192 read_coverage (stream, offset, &subtable->Coverage);
1194 else if (subtable->Format == 2)
1196 STREAM_SEEK (stream, offset + 2);
1197 read_coverage (stream, offset, &subtable->Coverage);
1198 READ_UINT16 (stream, subtable->sub.gpos.pair2.ValueFormat1);
1199 READ_UINT16 (stream, subtable->sub.gpos.pair2.ValueFormat2);
1200 read_class_def (stream, offset, &subtable->sub.gpos.pair2.ClassDef1);
1201 read_class_def (stream, offset, &subtable->sub.gpos.pair2.ClassDef2);
1202 READ_UINT16 (stream, subtable->sub.gpos.pair2.Class1Count);
1203 READ_UINT16 (stream, subtable->sub.gpos.pair2.Class2Count);
1204 subtable->sub.gpos.pair2.Class1Record
1205 = read_class1_record_list (stream, offset,
1206 subtable->sub.gpos.pair2.Class1Count,
1207 subtable->sub.gpos.pair2.ValueFormat1,
1208 subtable->sub.gpos.pair2.Class2Count,
1209 subtable->sub.gpos.pair2.ValueFormat2);
1212 OTF_ERROR (OTF_ERROR_TABLE, " (Invalid SubFormat)");
1216 if (subtable->Format == 1)
1218 read_coverage (stream, offset, &subtable->Coverage);
1219 read_coverage (stream, offset,
1220 &subtable->sub.gpos.mark_base1.BaseCoverage);
1221 READ_UINT16 (stream, subtable->sub.gpos.mark_base1.ClassCount);
1222 read_mark_array (stream, offset,
1223 &subtable->sub.gpos.mark_base1.MarkArray);
1224 read_base_array (stream, offset,
1225 subtable->sub.gpos.mark_base1.ClassCount,
1226 &subtable->sub.gpos.mark_base1.BaseArray);
1229 OTF_ERROR (OTF_ERROR_TABLE, " (Invalid SubFormat)");
1234 if (subtable->Format == 1)
1236 read_coverage (stream, offset,
1237 &subtable->sub.gsub.chain_context1.Coverage);
1238 subtable->sub.gsub.chain_context1.ChainSubRuleSetCount
1239 = (read_chain_subrule_set
1241 &subtable->sub.gsub.chain_context1.ChainSubRuleSet));
1243 else if (subtable->Format == 2)
1245 read_coverage (stream, offset,
1246 &subtable->sub.gsub.chain_context2.Coverage);
1247 read_class_def (stream, offset,
1248 &subtable->sub.gsub.chain_context2.Backtrack);
1249 read_class_def (stream, offset,
1250 &subtable->sub.gsub.chain_context2.Input);
1251 read_class_def (stream, offset,
1252 &subtable->sub.gsub.chain_context2.LookAhead);
1253 subtable->sub.gsub.chain_context2.ChainSubClassSetCnt
1254 = (read_chain_subclass_set
1256 &subtable->sub.gsub.chain_context2.ChainSubClassSet));
1258 else if (subtable->Format == 3)
1260 subtable->sub.gsub.chain_context3.BacktrackGlyphCount
1261 = (read_coverage_list
1263 &subtable->sub.gsub.chain_context3.Backtrack));
1264 subtable->sub.gsub.chain_context3.InputGlyphCount
1265 = (read_coverage_list
1267 &subtable->sub.gsub.chain_context3.Input));
1268 subtable->sub.gsub.chain_context3.LookaheadGlyphCount
1269 = (read_coverage_list
1271 &subtable->sub.gsub.chain_context3.LookAhead));
1272 subtable->sub.gsub.chain_context3.SubstCount
1273 = (read_subst_lookup_record
1274 (stream, &subtable->sub.gsub.chain_context3.SubstLookupRecord));
1277 OTF_ERROR (OTF_ERROR_TABLE, " (Invalid SubFormat)");
1281 OTF_ERROR (OTF_ERROR_TABLE, " (Invalid LookupType)");
1288 read_gpos_table (OTF_Stream *stream)
1290 char *errfmt = "GPOS%s";
1291 void *errret = NULL;
1294 OTF_MALLOC (gpos, 1, "");
1295 if (read_gsub_header (stream, (OTF_GPOSHeader *) &gpos->header) < 0
1296 || read_script_list (stream, gpos->header.ScriptList,
1297 &gpos->script_list) < 0
1298 || read_feature_list (stream, gpos->header.FeatureList,
1299 &gpos->feature_list) < 0
1300 || read_lookup_list (stream, gpos->header.LookupList,
1301 &gpos->lookup_list, 0) < 0)
1311 read_base_table (OTF_Stream *stream, long offset)
1315 OTF_MALLOC (base, 1);
1324 read_jstf_table (OTF_Stream *stream, long offset)
1328 OTF_MALLOC (jstf, 1);
1336 read_attach_list (OTF_Stream *stream, long offset, OTF_AttachList *list)
1338 char *errfmt = "AttachList%s";
1342 if (read_coverage (stream, offset, &list->Coverage) < 0)
1344 READ_UINT16 (stream, list->GlyphCount);
1345 OTF_MALLOC (list->AttachPoint, list->GlyphCount, "");
1346 for (i = 0; i < list->GlyphCount; i++)
1347 READ_OFFSET (stream, list->AttachPoint[i].offset);
1348 for (i = 0; i < list->GlyphCount; i++)
1352 STREAM_SEEK (stream, offset + list->AttachPoint[i].offset);
1353 READ_UINT16 (stream, count);
1354 list->AttachPoint[i].PointCount = count;
1355 OTF_MALLOC (list->AttachPoint[i].PointIndex, count, " (PointIndex)");
1356 for (j = 0; j < count; j++)
1357 READ_UINT16 (stream, list->AttachPoint[i].PointIndex[j]);
1363 read_caret_value (OTF_Stream *stream, long offset, OTF_CaretValue *caret)
1365 char *errfmt = "CaretValue%s";
1368 STREAM_SEEK (stream, offset + caret->offset);
1369 READ_UINT16 (stream, caret->CaretValueFormat);
1370 if (caret->CaretValueFormat == 1)
1371 READ_INT16 (stream, caret->f.f1.Coordinate);
1372 else if (caret->CaretValueFormat == 2)
1373 READ_UINT16 (stream, caret->f.f2.CaretValuePoint);
1374 else if (caret->CaretValueFormat == 3)
1376 READ_INT16 (stream, caret->f.f3.Coordinate);
1377 if (read_device_table (stream, offset + caret->offset,
1378 &caret->f.f3.DeviceTable) < 0)
1382 OTF_ERROR (OTF_ERROR_TABLE, " (Invalid format)");
1387 read_lig_caret_list (OTF_Stream *stream, long offset, OTF_LigCaretList *list)
1389 char *errfmt = "LigCaretList%s";
1393 if (read_coverage (stream, offset, &list->Coverage) < 0)
1395 READ_UINT16 (stream, list->LigGlyphCount);
1396 OTF_MALLOC (list->LigGlyph, list->LigGlyphCount, "");
1397 for (i = 0; i < list->LigGlyphCount; i++)
1398 READ_OFFSET (stream, list->LigGlyph[i].offset);
1399 for (i = 0; i < list->LigGlyphCount; i++)
1403 STREAM_SEEK (stream, offset + list->LigGlyph[i].offset);
1404 READ_UINT16 (stream, count);
1405 list->LigGlyph[i].CaretCount = count;
1406 OTF_MALLOC (list->LigGlyph[i].CaretValue, count, " (CaretValue)");
1407 for (j = 0; j < count; j++)
1408 READ_OFFSET (stream, list->LigGlyph[i].CaretValue[j].offset);
1409 for (j = 0; j < count; j++)
1410 if (read_caret_value (stream, offset + list->LigGlyph[i].offset,
1411 &list->LigGlyph[i].CaretValue[j]) < 0)
1419 read_gdef_header (OTF_Stream *stream, OTF_GDEFHeader *header)
1423 READ_FIXED (stream, header->Version);
1424 READ_OFFSET (stream, header->GlyphClassDef);
1425 READ_OFFSET (stream, header->AttachList);
1426 READ_OFFSET (stream, header->LigCaretList);
1427 READ_OFFSET (stream, header->MarkAttachClassDef);
1432 read_gdef_table (OTF_Stream *stream)
1434 char *errfmt = "GDEF%s";
1435 void *errret = NULL;
1438 OTF_CALLOC (gdef, 1, "");
1439 read_gdef_header (stream, (OTF_GDEFHeader *) &gdef->header);
1440 if (gdef->header.GlyphClassDef)
1442 gdef->glyph_class_def.offset = gdef->header.GlyphClassDef;
1443 read_class_def_without_offset (stream, &gdef->glyph_class_def);
1445 if (gdef->header.AttachList)
1446 read_attach_list (stream, gdef->header.AttachList,
1447 &gdef->attach_list);
1448 if (gdef->header.LigCaretList)
1449 read_lig_caret_list (stream, gdef->header.LigCaretList,
1450 &gdef->lig_caret_list);
1451 if (gdef->header.MarkAttachClassDef)
1453 gdef->mark_attach_class_def.offset = gdef->header.MarkAttachClassDef;
1454 read_class_def_without_offset (stream, &gdef->mark_attach_class_def);
1465 read_cmap_table (OTF_Stream *stream)
1467 char *errfmt = "cmap%s";
1468 void *errret = NULL;
1472 OTF_CALLOC (cmap, 1, "");
1473 READ_USHORT (stream, cmap->version);
1474 READ_USHORT (stream, cmap->numTables);
1475 OTF_MALLOC (cmap->EncodingRecord, cmap->numTables, "");
1476 for (i = 0; i < cmap->numTables; i++)
1478 READ_USHORT (stream, cmap->EncodingRecord[i].platformID);
1479 READ_USHORT (stream, cmap->EncodingRecord[i].encodingID);
1480 READ_ULONG (stream, cmap->EncodingRecord[i].offset);
1481 if (cmap->EncodingRecord[i].platformID == 3
1482 && cmap->EncodingRecord[i].encodingID == 1)
1483 cmap->Unicode = cmap->EncodingRecord + i;
1485 for (i = 0; i < cmap->numTables; i++)
1489 STREAM_SEEK (stream, cmap->EncodingRecord[i].offset);
1490 READ_USHORT (stream, format);
1491 cmap->EncodingRecord[i].subtable.format = format;
1492 READ_USHORT (stream, cmap->EncodingRecord[i].subtable.length);
1493 if (format == 8 || format == 10 || format == 12)
1495 READ_ULONG (stream, cmap->EncodingRecord[i].subtable.length);
1496 READ_ULONG (stream, cmap->EncodingRecord[i].subtable.language);
1500 READ_USHORT (stream, cmap->EncodingRecord[i].subtable.language);
1506 OTF_MALLOC (cmap->EncodingRecord[i].subtable.f.f0, 1,
1507 " (EncodingRecord)");
1509 cmap->EncodingRecord[i].subtable.f.f0->glyphIdArray,
1519 OTF_EncodingSubtable4 *sub4;
1524 OTF_MALLOC (sub4, 1, " (EncodingSubtable4)");
1525 cmap->EncodingRecord[i].subtable.f.f4 = sub4;
1526 READ_USHORT (stream, sub4->segCountX2);
1527 segCount = sub4->segCountX2 / 2;
1528 READ_USHORT (stream, sub4->searchRange);
1529 READ_USHORT (stream, sub4->entrySelector);
1530 READ_USHORT (stream, sub4->rangeShift);
1531 OTF_MALLOC (sub4->segments, segCount, " (segCount)");
1532 for (j = 0; j < segCount; j++)
1533 READ_USHORT (stream, sub4->segments[j].endCount);
1534 READ_USHORT (stream, dummy);
1535 for (j = 0; j < segCount; j++)
1536 READ_USHORT (stream, sub4->segments[j].startCount);
1537 for (j = 0; j < segCount; j++)
1538 READ_SHORT (stream, sub4->segments[j].idDelta);
1539 for (j = 0; j < segCount; j++)
1542 unsigned rest = 2 * (segCount - j);
1544 READ_USHORT (stream, off);
1546 sub4->segments[j].idRangeOffset = 0xFFFF;
1548 sub4->segments[j].idRangeOffset = (off - rest) / 2;
1550 j = (cmap->EncodingRecord[i].subtable.length
1551 - (14 + 2 * (segCount * 4 + 1)));
1552 sub4->GlyphCount = j / 2;
1553 OTF_MALLOC (sub4->glyphIdArray, sub4->GlyphCount, " (GlyphCount)");
1554 for (j = 0; j < sub4->GlyphCount; j++)
1555 READ_USHORT (stream, sub4->glyphIdArray[j]);
1567 read_name (OTF_Stream *stream, OTF_NameRecord *rec, int bytes)
1569 char *errfmt = "nameID (%d)";
1570 void *errret = NULL;
1571 OTF_StreamState state;
1576 STREAM_SAVE_STATE (stream, state);
1577 STREAM_SEEK (stream, stream->pos + rec->offset);
1581 OTF_MALLOC (str, rec->length + 1, (void *) rec->nameID);
1582 READ_BYTES (stream, str, rec->length);
1583 for (i = 0; i < rec->length; i++)
1587 else if (bytes == 2)
1589 OTF_MALLOC (str, rec->length / 2 + 1, (void *) rec->nameID);
1590 for (i = 0; i < rec->length / 2; i++)
1592 READ_USHORT (stream, c);
1598 else if (bytes == 4)
1600 OTF_MALLOC (str, rec->length / 4 + 1, (void *) rec->nameID);
1601 for (i = 0; i < rec->length / 4; i++)
1603 READ_ULONG (stream, c);
1610 STREAM_RESTORE_STATE (stream, state);
1615 read_name_table (OTF_Stream *stream)
1617 char *errfmt = "name%s";
1618 void *errret = NULL;
1622 OTF_CALLOC (name, 1, "");
1623 READ_USHORT (stream, name->format);
1624 READ_USHORT (stream, name->count);
1625 READ_USHORT (stream, name->stringOffset);
1626 OTF_MALLOC (name->nameRecord, name->count, "");
1627 for (i = 0; i < name->count; i++)
1629 OTF_NameRecord *rec = name->nameRecord + i;
1631 READ_USHORT (stream, rec->platformID);
1632 READ_USHORT (stream, rec->encodingID);
1633 READ_USHORT (stream, rec->languageID);
1634 READ_USHORT (stream, rec->nameID);
1635 READ_USHORT (stream, rec->length);
1636 READ_USHORT (stream, rec->offset);
1638 for (i = 0; i < name->count; i++)
1640 OTF_NameRecord *rec = name->nameRecord + i;
1641 int nameID = rec->nameID;
1643 if (nameID <= OTF_max_nameID
1644 && ! name->name[nameID])
1646 if (rec->platformID == 0)
1647 name->name[nameID] = read_name (stream, rec,
1648 rec->encodingID <= 3 ? 2 : 4);
1649 else if (rec->platformID == 1
1650 && rec->encodingID == 0)
1651 name->name[nameID] = read_name (stream, rec, 1);
1652 else if (rec->platformID == 3
1653 && (rec->encodingID == 1 || rec->encodingID == 10))
1654 name->name[nameID] = read_name (stream,
1655 rec, rec->encodingID == 1 ? 2 : 4);
1666 otf_open (char *otf_name)
1668 char *errfmt = "OTF%s";
1669 void *errret = NULL;
1672 OTF_Tag head_tag, cmap_tag, name_tag, gdef_tag, gsub_tag, gpos_tag;
1675 stream = stream_open (otf_name);
1679 head_tag = otf_tag ("head");
1680 cmap_tag = otf_tag ("cmap");
1681 name_tag = otf_tag ("name");
1682 gdef_tag = otf_tag ("GDEF");
1683 gsub_tag = otf_tag ("GSUB");
1684 gpos_tag = otf_tag ("GPOS");
1686 /* Size of Offset Table in OTF is 12 bytes. */
1687 if (stream_setup (stream, 0, 12, "Offset Table") < 0)
1690 OTF_CALLOC_GOTO (otf, 1, " (body)", err);
1691 otf->filename = strdup (otf_name);
1692 if (! otf->filename)
1694 otf_error = OTF_ERROR_MEMORY;
1697 if (read_offset_table (stream, &otf->offset_table) < 0)
1700 /* Size of each Table Directory in OTF is 16 bytes. */
1701 if (stream_setup (stream, 12, 16 * otf->offset_table.numTables,
1702 "Table Directory") < 0)
1704 OTF_CALLOC_GOTO (otf->table_dirs, otf->offset_table.numTables,
1705 " (OffsetTable)", err);
1706 for (i = 0; i < otf->offset_table.numTables; i++)
1707 if (read_table_directory (stream, otf->table_dirs + i) < 0)
1710 for (i = 0; i < otf->offset_table.numTables; i++)
1712 if (otf->table_dirs[i].tag == head_tag)
1714 stream_setup (stream, otf->table_dirs[i].offset,
1715 otf->table_dirs[i].length, "head");
1716 otf->head = read_head_table (stream);
1718 else if (otf->table_dirs[i].tag == cmap_tag)
1720 stream_setup (stream, otf->table_dirs[i].offset,
1721 otf->table_dirs[i].length, "cmap");
1722 otf->cmap = read_cmap_table (stream);
1724 else if (otf->table_dirs[i].tag == name_tag)
1726 stream_setup (stream, otf->table_dirs[i].offset,
1727 otf->table_dirs[i].length, "name");
1728 otf->name = read_name_table (stream);
1730 else if (otf->table_dirs[i].tag == gdef_tag)
1732 stream_setup (stream, otf->table_dirs[i].offset,
1733 otf->table_dirs[i].length, "GDEF");
1734 otf->gdef = read_gdef_table (stream);
1736 else if (otf->table_dirs[i].tag == gsub_tag)
1738 stream_setup (stream, otf->table_dirs[i].offset,
1739 otf->table_dirs[i].length, "GSUB");
1740 otf->gsub = read_gsub_table (stream);
1742 else if (otf->table_dirs[i].tag == gpos_tag)
1744 stream_setup (stream, otf->table_dirs[i].offset,
1745 otf->table_dirs[i].length, "GPOS");
1746 otf->gpos = read_gpos_table (stream);
1750 stream_close (stream);
1754 stream_close (stream);
1760 otf_close (OTF *otf)
1763 free (otf->filename);
1764 if (otf->table_dirs)
1765 free (otf->table_dirs);