*** empty log message ***
[m17n/libotf.git] / src / otf-open.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4
5 #include "otf.h"
6 #include "otf-util.h"
7
8 /* OTF_Stream
9
10    Example of typical usage of OTF_Stream.
11
12     {
13       OTF_Stream *stream;
14       OTF_StreamState state;
15       int offset, nbytes;
16
17       OPEN_STREAM (_FILE_NAME_, stream);
18       if (! stream)
19         _ERROR_;
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_);
24       ...;
25       CLOSE_STREAM (stream);
26     }
27
28 */
29
30 typedef struct
31 {
32   FILE *fp;
33   char *name;
34   long pos;
35   long bufsize;
36   long allocated;
37   unsigned char *buf;
38 } OTF_Stream;
39
40 typedef long OTF_StreamState;
41
42 OTF_Stream *
43 stream_open (char *filename)
44 {
45   FILE *fp;
46   OTF_Stream *stream;
47   char *errfmt = "stream open for %s";
48   void *errret = NULL;
49
50   fp = fopen (filename, "r");
51   if (! fp)
52     OTF_ERROR (OTF_ERROR_FILE, filename);
53   OTF_CALLOC (stream, 1, filename);
54   stream->fp = fp;
55   return stream;
56 }
57
58 int
59 stream_setup (OTF_Stream *stream, long offset, int nbytes, char *name)
60 {
61   char *errfmt = "stream setup for %s";
62   int errret = -1;
63
64   stream->name = name;
65   stream->pos = 0;
66   if (stream->allocated < nbytes)
67     {
68       unsigned char *buf = (unsigned char *) malloc (nbytes);
69
70       if (! buf)
71         OTF_ERROR (OTF_ERROR_MEMORY, stream->name);
72       if (stream->buf)
73         free (stream->buf);
74       stream->buf = buf;
75       stream->allocated = nbytes;
76     }
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);
82   return 0;
83 }
84
85
86 void
87 stream_close (OTF_Stream *stream)
88 {
89   fclose (stream->fp);
90   free (stream);
91 }
92
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))
96
97 int
98 stream_overrun (OTF_Stream *stream)
99 {
100   char *errfmt = "buffer overrun in %s";
101   int errret = -1;
102
103   OTF_ERROR (OTF_ERROR_TABLE, (stream)->name);
104 }
105
106 #define STREAM_CHECK_SIZE(stream, size)                 \
107   if ((stream)->pos + (size) > (stream)->bufsize)       \
108     {                                                   \
109       stream_overrun (stream);                          \
110       return errret;                                    \
111     }                                                   \
112   else
113
114
115 #define READ_USHORT(stream, var)                        \
116   do {                                                  \
117     STREAM_CHECK_SIZE ((stream), 2);                    \
118     (var) = (((stream)->buf[(stream)->pos] << 8)        \
119              | (stream)->buf[(stream)->pos + 1]);       \
120     (stream)->pos += 2;                                 \
121   } while (0)
122
123 #define READ_SHORT(stream, var)                                 \
124   do {                                                          \
125     STREAM_CHECK_SIZE ((stream), 2);                            \
126     (var) = (short) (((stream)->buf[(stream)->pos] << 8)        \
127                      | (stream)->buf[(stream)->pos + 1]);       \
128     (stream)->pos += 2;                                         \
129   } while (0)
130
131 #define READ_ULONG(stream, var)                         \
132   do {                                                  \
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;                                 \
139   } while (0)
140
141 #define READ_LONG(stream, var)                                  \
142   do {                                                          \
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;                                         \
149   } while (0)
150
151
152 #define READ_FIXED(stream, fixed)               \
153   do {                                          \
154     READ_USHORT ((stream), (fixed).high);       \
155     READ_USHORT ((stream), (fixed).low);        \
156   } while (0)
157
158
159 #define READ_BYTES(stream, p, nbytes)                           \
160   do {                                                          \
161     STREAM_CHECK_SIZE ((stream), (nbytes));                     \
162     memcpy ((p), (stream)->buf + (stream)->pos, (nbytes));      \
163     (stream)->pos += (nbytes);                                  \
164   } while (0)
165
166
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
172
173 \f
174
175 int
176 read_offset_table (OTF_Stream *stream, OTF_OffsetTable *table)
177 {  
178   int errret = -1;
179
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);
185   return 0;
186 }
187
188 static int
189 read_table_directory (OTF_Stream *stream, OTF_TableDirectory *table)
190 {
191   int errret = -1;
192
193   READ_TAG (stream, table->tag);
194   READ_ULONG (stream, table->checkSum);
195   READ_ULONG (stream, table->offset);
196   READ_ULONG (stream, table->length);
197   return 0;
198 }
199
200 \f
201
202 OTF_head *
203 read_head_table (OTF_Stream *stream)
204 {
205   char *errfmt = "head%s";
206   void *errret = NULL;
207   OTF_head *head;
208
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);
216
217   return head;
218 }
219
220 \f
221
222 static int
223 read_script_list (OTF_Stream *stream, long offset, OTF_ScriptList *list)
224 {
225   char *errfmt = "Script List%s";
226   int errret = -1;
227   int i, j, k;
228
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, "");
233
234   for (i = 0; i < list->ScriptCount; i++)
235     {
236       READ_TAG (stream, list->ScriptRecord[i].ScriptTag);
237       READ_OFFSET (stream, list->ScriptRecord[i].Script);
238     }
239   for (i = 0;  i < list->ScriptCount; i++)
240     {
241       OTF_Script *script = list->Script + i;
242       long script_offset = offset + list->ScriptRecord[i].Script;
243
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++)
250         {
251           READ_TAG (stream, script->LangSysRecord[j].LangSysTag);
252           READ_OFFSET (stream, script->LangSysRecord[j].LangSys);
253         }
254
255       if (script->DefaultLangSysOffset)
256         {
257           OTF_LangSys *langsys = &script->DefaultLangSys;
258
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,
264                       " (FeatureIndex)");
265           for (k = 0; k < langsys->FeatureCount; k++)
266             READ_USHORT (stream, langsys->FeatureIndex[k]);
267         }
268           
269       for (j = 0; j < script->LangSysCount; j++)
270         {
271           OTF_LangSys *langsys = script->LangSys + j;
272
273           STREAM_SEEK (stream,
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,
279                       " (FeatureIndex)");
280           for (k = 0; k < langsys->FeatureCount; k++)
281             READ_USHORT (stream, langsys->FeatureIndex[k]);
282         }
283     }
284
285   return 0;
286 }
287
288 static int
289 read_feature_list (OTF_Stream *stream, long offset, OTF_FeatureList *list)
290 {
291   char *errfmt = "Feature List%s";
292   int errret = -1;
293   int i, j;
294
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++)
299     {
300       READ_TAG (stream, list->FeatureRecord[i].FeatureTag);
301       READ_OFFSET (stream, list->FeatureRecord[i].Feature);
302     }
303   for (i = 0; i < list->FeatureCount; i++)
304     {
305       OTF_Feature *feature = list->Feature + i;
306
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]);
314     }
315
316   return 0;
317 }
318
319 static int read_lookup_subtable_gsub (OTF_Stream *stream, long offset,
320                                       unsigned type,
321                                       OTF_LookupSubTable *subtable);
322 static int read_lookup_subtable_gpos (OTF_Stream *stream, long offset,
323                                       unsigned type,
324                                       OTF_LookupSubTable *subtable);
325
326 static int
327 read_lookup_list (OTF_Stream *stream, long offset,
328                   OTF_LookupList *list, int gsub)
329 {
330   char *errfmt = "Lookup List%s";
331   int errret = -1;
332   int i, j;
333
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, "");
338
339   for (i = 0; i < list->LookupCount; i++)
340     READ_OFFSET (stream, list->LookupOffset[i]);
341   for (i = 0; i < list->LookupCount; i++)
342     {
343       OTF_Lookup *lookup = list->Lookup + i;
344
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,
352                   " (SubTable)");
353       for (j = 0; j < lookup->SubTableCount; j++)
354         READ_OFFSET (stream, lookup->SubTableOffset[j]);
355       if (gsub)
356         for (j = 0; j < lookup->SubTableCount; j++)
357           {
358             long this_offset
359               = offset + list->LookupOffset[i] + lookup->SubTableOffset[j];
360
361             if (read_lookup_subtable_gsub (stream, this_offset,
362                                            lookup->LookupType,
363                                            lookup->SubTable + j) < 0)
364               return errret;
365           }
366       else
367         for (j = 0; j < lookup->SubTableCount; j++)
368           {
369             long this_offset
370               = offset + list->LookupOffset[i] + lookup->SubTableOffset[j];
371
372             if (read_lookup_subtable_gpos (stream, this_offset,
373                                            lookup->LookupType,
374                                            lookup->SubTable + j) < 0)
375               return errret;
376           }
377     }
378
379   return 0;
380 }
381
382
383 static int
384 read_glyph_ids (OTF_Stream *stream, OTF_GlyphID **ids, int minus)
385 {
386   char *errfmt = "GlyphID List%s";
387   int errret = -1;
388   unsigned count;
389   int i;
390
391   READ_UINT16 (stream, count);
392   if (! count)
393     return 0;
394   OTF_MALLOC (*ids, count, "");
395   for (i = 0; i < count + minus; i++)
396     READ_GLYPHID (stream, (*ids)[i]);
397   return (int) count;
398 }
399      
400 static unsigned
401 read_range_record (OTF_Stream *stream, OTF_RangeRecord **record)
402 {
403   char *errfmt = "RangeRecord%s";
404   unsigned errret = 0;
405   unsigned count;
406   int i;
407
408   READ_UINT16 (stream, count);
409   if (! count)
410     return 0;
411   OTF_MALLOC (*record, count, "");
412   for (i = 0; i < count; i++)
413     {
414       READ_GLYPHID (stream, (*record)[i].Start);
415       READ_GLYPHID (stream, (*record)[i].End);
416       READ_UINT16 (stream, (*record)[i].StartCoverageIndex);
417     }
418   return count;
419 }
420
421
422 static int
423 read_coverage (OTF_Stream *stream, long offset, OTF_Coverage *coverage)
424 {
425   char *errfmt = "Coverage%s";
426   int errret = -1;
427   OTF_StreamState state;
428   int count;
429   
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);
438   else
439     OTF_ERROR (OTF_ERROR_TABLE, " (Invalid Format)");
440   if (count < 0)
441     return -1;
442   coverage->Count = (unsigned) count;
443   STREAM_RESTORE_STATE (stream, state);
444   return 0;
445 }
446
447 static int
448 read_coverage_list (OTF_Stream *stream, long offset, OTF_Coverage **coverage)
449 {
450   char *errfmt = "Coverage List%s";
451   int errret = -1;
452   int count;
453   int i;
454
455   READ_UINT16 (stream, count);
456   if (! count)
457     return 0;
458   OTF_MALLOC (*coverage, count, "");
459   for (i = 0; i < count; i++)
460     if (read_coverage (stream, offset, (*coverage) + i) < 0)
461       return -1;
462   return count;
463 }
464
465
466 static int
467 read_class_def_without_offset (OTF_Stream *stream, OTF_ClassDef *class)
468 {
469   char *errfmt = "ClassDef%s";
470   int errret = -1;
471
472   STREAM_SEEK (stream, class->offset);
473   READ_UINT16 (stream, class->ClassFormat);
474   if (class->ClassFormat == 1)
475     {
476       READ_GLYPHID (stream, class->f.f1.StartGlyph);
477       class->f.f1.GlyphCount
478         = (read_glyph_ids
479            (stream, (OTF_GlyphID **) &class->f.f1.ClassValueArray, 0));
480       if (! class->f.f1.GlyphCount)
481         return -1;
482     }
483   else if (class->ClassFormat == 2)
484     {
485       class->f.f2.ClassRangeCount
486         = (read_range_record
487            (stream, (OTF_RangeRecord **) &class->f.f2.ClassRangeRecord));
488       if (! class->f.f2.ClassRangeCount)
489         return -1;
490     }
491   else
492     OTF_ERROR (OTF_ERROR_TABLE, " (Invalid format)");
493   return 0;
494 }
495
496
497 static int
498 read_class_def (OTF_Stream *stream, long offset, OTF_ClassDef *class)
499 {
500   char *errfmt = "ClassDef%s";
501   int errret = -1;
502   OTF_StreamState state;
503   
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)
509     {
510       READ_GLYPHID (stream, class->f.f1.StartGlyph);
511       class->f.f1.GlyphCount
512         = (read_glyph_ids
513            (stream, (OTF_GlyphID **) &class->f.f1.ClassValueArray, 0));
514       if (! class->f.f1.GlyphCount)
515         return -1;
516     }
517   else if (class->ClassFormat == 2)
518     {
519       class->f.f2.ClassRangeCount
520         = (read_range_record
521            (stream, (OTF_RangeRecord **) &class->f.f2.ClassRangeRecord));
522       if (! class->f.f2.ClassRangeCount)
523         return -1;
524     }
525   else
526     OTF_ERROR (OTF_ERROR_TABLE, " (Invalid format)");
527
528   STREAM_RESTORE_STATE (stream, state);
529   return 0;
530 }
531
532 static int
533 read_device_table (OTF_Stream *stream, long offset, OTF_DeviceTable *table)
534 {
535   char *errfmt = "Device Table%s";
536   int errret = -1;
537
538   int num, i;
539   unsigned val;
540   struct {
541     int int2 : 2;
542     int int4 : 4;
543     int int8 : 8;
544   } intval;
545
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, "");
552
553   if (table->DeltaFormat == 1)
554     for (i = 0; i < num; i++)
555       {
556         if ((i % 8) == 0)
557           READ_UINT16 (stream, val);
558         intval.int2 = (val >> (14 - (i % 8) * 2)) & 0x03;
559         table->DeltaValue[i] = intval.int2;
560       }
561   else if (table->DeltaFormat == 2)
562     for (i = 0; i < num; i++)
563       {
564         if ((i % 4) == 0)
565           READ_UINT16 (stream, val);
566         intval.int4 = (val >> (12 - (i % 4) * 4)) & 0x0F;
567         table->DeltaValue[i] = intval.int4;
568       }
569   else if (table->DeltaFormat == 3)
570     for (i = 0; i < num; i++)
571       {
572         if ((i % 2) == 0)
573           {
574             READ_UINT16 (stream, val);
575             intval.int8 = val >> 8;
576             table->DeltaValue[i] = intval.int8;
577           }
578         else
579           {
580             intval.int8 = val >> 8;
581             table->DeltaValue[i] = intval.int8;
582           }
583       }
584   else
585     OTF_ERROR (OTF_ERROR_TABLE, " (Invalid format)");
586   return 0;
587 }
588
589
590 \f
591 /* GSUB */
592
593 static int
594 read_gsub_header (OTF_Stream *stream, OTF_GSUBHeader *header)
595 {
596   int errret = -1;
597
598   READ_FIXED (stream, header->Version);
599   READ_OFFSET (stream, header->ScriptList);
600   READ_OFFSET (stream, header->FeatureList);
601   READ_OFFSET (stream, header->LookupList);
602   return 0;
603 }
604
605 static OTF_GSUB *
606 read_gsub_table (OTF_Stream *stream)
607 {
608   char *errfmt = "GSUB%s";
609   void *errret = NULL;
610   OTF_GSUB *gsub;
611
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)
620     return NULL;
621   return gsub;
622 }
623
624
625 static unsigned
626 read_sequence (OTF_Stream *stream, long offset, OTF_Sequence **seq)
627 {
628   char *errfmt = "Sequence%s";
629   unsigned errret = 0;
630   unsigned count;
631   int i;
632
633   READ_UINT16 (stream, count);
634   OTF_MALLOC (*seq, count, "");
635   if (! 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++)
640     {
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)
644         return 0;
645     }
646   return count;
647 }
648
649 static int
650 read_ligature (OTF_Stream *stream, long offset, OTF_Ligature **ligature)
651 {
652   char *errfmt = "Ligature%s";
653   int errret = -1;
654   int count;
655   int i;
656
657   READ_UINT16 (stream, count);
658   if (! count)
659     return 0;
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++)
664     {
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)
670         return -1;
671     }
672   return count;
673 }
674
675 static int
676 read_ligature_set (OTF_Stream *stream, long offset, OTF_LigatureSet **ligset)
677 {
678   char *errfmt = "LigatureSet%s";
679   int errret = -1;
680   int count;
681   int i;
682
683   READ_UINT16 (stream, count);
684   if (! count)
685     return 0;
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++)
690     {
691       int lig_count;
692
693       STREAM_SEEK (stream, offset + (*ligset)[i].offset);
694       lig_count = read_ligature (stream, offset + (*ligset)[i].offset,
695                                  &(*ligset)[i].Ligature);
696       if (lig_count < 0)
697         return -1;
698       (*ligset)[i].LigatureCount = (unsigned) lig_count;
699     }
700   return count;
701 }
702
703 static unsigned
704 read_subst_lookup_record (OTF_Stream *stream, OTF_SubstLookupRecord **record)
705 {
706   char *errfmt = "SubstLookupRecord%s";
707   unsigned errret = 0;
708   unsigned count;
709   int i;
710
711   READ_UINT16 (stream, count);
712   if (! count)
713     OTF_ERROR (OTF_ERROR_TABLE, " (zero count)");
714   OTF_MALLOC (*record, count, "");
715   for (i = 0; i < count; i++)
716     {
717       READ_UINT16 (stream, (*record)[i].SequenceIndex);
718       READ_UINT16 (stream, (*record)[i].LookupListIndex);
719     }
720   return count;
721 }
722
723 static unsigned
724 read_chain_subrule (OTF_Stream *stream, long offset, OTF_ChainSubRule **rule)
725 {
726   char *errfmt = "ChainSubRule%s";
727   unsigned errret = 0;
728   unsigned count;
729   int i;
730
731   READ_UINT16 (stream, count);
732   if (! 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++)
738     {
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)
743         return 0;
744       (*rule)[i].InputGlyphCount
745         = read_glyph_ids (stream, &(*rule)[i].Input, -1);
746       if (! (*rule)[i].InputGlyphCount)
747         return 0;
748       (*rule)[i].LookaheadGlyphCount
749         = read_glyph_ids (stream, &(*rule)[i].LookAhead, 0);
750       if (! (*rule)[i].LookaheadGlyphCount)
751         return 0;
752       (*rule)[i].SubstCount
753         = read_subst_lookup_record (stream, &(*rule)[i].SubstLookupRecord);
754       if (! (*rule)[i].SubstCount)
755         return 0;
756     }
757   return count;
758 }
759
760
761 static unsigned
762 read_chain_subrule_set (OTF_Stream *stream, long offset,
763                         OTF_ChainSubRuleSet **set)
764 {
765   char *errfmt = "ChainSubRuleSet%s";
766   unsigned errret = 0;
767   unsigned count;
768   int i;
769
770   READ_UINT16 (stream, count);
771   if (! 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++)
777     {
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)
783         return 0;
784     }
785   return count;
786 }
787
788 static unsigned
789 read_chain_subclass_rule (OTF_Stream *stream, long offset,
790                           OTF_ChainSubClassRule **rule)
791 {
792   char *errfmt = "ChainSubClassRule%s";
793   unsigned errret = 0;
794   unsigned count;
795   int i;
796
797   READ_UINT16 (stream, count);
798   if (! 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++)
804     {
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)
809         return 0;
810       (*rule)[i].InputGlyphCount
811         = read_glyph_ids (stream, (OTF_GlyphID **) &(*rule)[i].Input, -1);
812       if (! (*rule)[i].InputGlyphCount)
813         return 0;
814       (*rule)[i].LookaheadGlyphCount
815         = read_glyph_ids (stream, (OTF_GlyphID **) &(*rule)[i].LookAhead, 0);
816       if (! (*rule)[i].LookaheadGlyphCount)
817         return 0;
818       (*rule)[i].SubstCount
819         = read_subst_lookup_record (stream, &(*rule)[i].SubstLookupRecord);
820       if (! (*rule)[i].SubstCount)
821         return 0;
822     }
823   return count;
824 }
825
826 static unsigned
827 read_chain_subclass_set (OTF_Stream *stream, long offset,
828                          OTF_ChainSubClassSet **set)
829 {
830   char *errfmt = "ChainSubClassSet%s";
831   unsigned errret = 0;
832   unsigned count;
833   int i;
834
835   READ_UINT16 (stream, count);
836   if (! 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++)
842     {
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)
848         return 0;
849     }
850   return count;
851 }
852
853
854 static int 
855 read_lookup_subtable_gsub (OTF_Stream *stream, long offset,
856                            unsigned type, OTF_LookupSubTable *subtable)
857 {
858   char *errfmt = "GSUB LookupSubTable%s";
859   int errret = -1;
860   int count;
861
862   STREAM_SEEK (stream, offset);
863   READ_UINT16 (stream, subtable->Format);
864   switch (type)
865     {
866     case 1:
867       if (subtable->Format == 1)
868         {
869           if (read_coverage (stream, offset, &subtable->Coverage) < 0)
870             return -1;
871           READ_INT16 (stream, subtable->sub.gsub.single1.DeltaGlyphID);
872         }
873       else if (subtable->Format == 2)
874         {
875           if (read_coverage (stream, offset, &subtable->Coverage) < 0)
876             return -1;
877           subtable->sub.gsub.single2.GlyphCount
878             = read_glyph_ids (stream, &subtable->sub.gsub.single2.Substitute,
879                               0);
880           if (! subtable->sub.gsub.single2.GlyphCount)
881             return -1;
882         }
883       else
884         OTF_ERROR (OTF_ERROR_TABLE, " (Invalid SubFormat)");
885       break;
886
887     case 2:
888       if (subtable->Format == 1)
889         {
890           read_coverage (stream, offset, &subtable->Coverage);
891           subtable->sub.gsub.multiple1.SequenceCount
892             = read_sequence (stream, offset,
893                              &subtable->sub.gsub.multiple1.Sequence);
894         }
895       else
896         OTF_ERROR (OTF_ERROR_TABLE, " (Invalid SubFormat)");
897       break;
898       
899     case 3:
900       break;
901
902     case 4:
903       if (subtable->Format == 1)
904         {
905           read_coverage (stream, offset, &subtable->Coverage);
906           count = (read_ligature_set
907                    (stream, offset,
908                     &subtable->sub.gsub.ligature1.LigatureSet));
909           if (count < 0)
910             return -1;
911           subtable->sub.gsub.ligature1.LigSetCount = (unsigned) count;
912         }
913       else
914         OTF_ERROR (OTF_ERROR_TABLE, " (Invalid SubFormat)");
915       break;
916
917     case 6:
918       if (subtable->Format == 1)
919         {
920           read_coverage (stream, offset, &subtable->Coverage);
921           subtable->sub.gsub.chain_context1.ChainSubRuleSetCount
922             = (read_chain_subrule_set
923                (stream, offset,
924                 &subtable->sub.gsub.chain_context1.ChainSubRuleSet));
925         }
926       else if (subtable->Format == 2)
927         {
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
937                (stream, offset,
938                 &subtable->sub.gsub.chain_context2.ChainSubClassSet));
939         }
940       else if (subtable->Format == 3)
941         {
942           count = (read_coverage_list
943                    (stream, offset,
944                     &subtable->sub.gsub.chain_context3.Backtrack));
945           if (count < 0)
946             return -1;
947           subtable->sub.gsub.chain_context3.BacktrackGlyphCount
948             = (unsigned) count;
949           count = (read_coverage_list
950                    (stream, offset,
951                     &subtable->sub.gsub.chain_context3.Input));
952           if (count <= 0)
953             return -1;
954           subtable->sub.gsub.chain_context3.InputGlyphCount
955             = (unsigned) count;
956           subtable->Coverage = subtable->sub.gsub.chain_context3.Input[0];
957           count = (read_coverage_list
958                    (stream, offset,
959                     &subtable->sub.gsub.chain_context3.LookAhead));
960           subtable->sub.gsub.chain_context3.LookaheadGlyphCount
961             = (unsigned) count;
962           subtable->sub.gsub.chain_context3.SubstCount
963             = (read_subst_lookup_record
964                (stream, &subtable->sub.gsub.chain_context3.SubstLookupRecord));
965         }
966       else
967         OTF_ERROR (OTF_ERROR_TABLE, " (Invalid SubFormat)");
968       break;
969
970
971     default:
972         OTF_ERROR (OTF_ERROR_TABLE, " (Invalid LookupType)");
973     }
974   return 0;
975 }
976
977 \f
978 /* GPOS */
979
980 static int
981 read_value_record (OTF_Stream *stream, long offset,
982                    enum OTF_ValueFormat bit, OTF_ValueRecord *value_record)
983 {
984   int errret = -1;
985   OTF_StreamState state;
986   int size, i;
987
988   if (! bit)
989     return 0;
990   for (i = 0, size = 0; i < 8; i++)
991     if (bit & (1 << i))
992       size += 2;
993
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)
1012     {
1013       if (read_device_table (stream, offset, &value_record->XPlaDevice) < 0)
1014         return -1;
1015     }
1016   if (value_record->YPlaDevice.offset)
1017     {
1018       if (read_device_table (stream, offset, &value_record->YPlaDevice) < 0)
1019         return -1;
1020     }
1021   if (value_record->XAdvDevice.offset)
1022     {
1023       if (read_device_table (stream, offset, &value_record->XAdvDevice) < 0)
1024         return -1;
1025     }
1026   if (value_record->YAdvDevice.offset)
1027     {
1028       if (read_device_table (stream, offset, &value_record->YAdvDevice) < 0)
1029         return -1;
1030     }
1031   STREAM_RESTORE_STATE (stream, state);
1032   return 0;
1033 }
1034
1035
1036 static int
1037 read_anchor (OTF_Stream *stream, long offset, OTF_Anchor *anchor)
1038 {
1039   char *errfmt = "Anchor%s";
1040   int errret = -1;
1041
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)
1047     ;
1048   else if (anchor->AnchorFormat == 2)
1049     {
1050       READ_UINT16 (stream, anchor->f.f1.AnchorPoint);
1051     }
1052   else if (anchor->AnchorFormat == 3)
1053     {
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)
1057         {
1058           if (read_device_table (stream, offset + anchor->offset,
1059                                  &anchor->f.f2.XDeviceTable) < 0)
1060             return -1;
1061         }
1062       if (anchor->f.f2.YDeviceTable.offset)
1063         {
1064           if (read_device_table (stream, offset + anchor->offset,
1065                                  &anchor->f.f2.YDeviceTable) < 0)
1066             return -1;
1067         }
1068     }
1069   else
1070     OTF_ERROR (OTF_ERROR_TABLE, " (invalid format)");
1071
1072   return 0;
1073 }
1074
1075 static int
1076 read_mark_array (OTF_Stream *stream, long offset, OTF_MarkArray *array)
1077 {
1078   char *errfmt = "MarkArray%s";
1079   int errret = -1;
1080   OTF_StreamState state;
1081   int i;
1082   
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++)
1089     {
1090       READ_UINT16 (stream, array->MarkRecord[i].Class);
1091       READ_OFFSET (stream, array->MarkRecord[i].MarkAnchor.offset);
1092     }
1093   for (i = 0; i < array->MarkCount; i++)
1094     if (read_anchor (stream, offset + array->offset,
1095                      &array->MarkRecord[i].MarkAnchor) < 0)
1096       return -1;;
1097   STREAM_RESTORE_STATE (stream, state);
1098   return 0;
1099 }
1100
1101 static int
1102 read_base_array (OTF_Stream *stream, long offset,
1103                  unsigned ClassCount, OTF_BaseArray *array)
1104 {
1105   char *errfmt = "BaseArray%s";
1106   int errret = -1;
1107   OTF_StreamState state;
1108   int i, j;
1109   
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++)
1116     {
1117       OTF_MALLOC (array->BaseRecord[i].BaseAnchor, ClassCount,
1118                   " (BaseRecord)");
1119       for (j = 0; j < ClassCount; j++)
1120         READ_OFFSET (stream, array->BaseRecord[i].BaseAnchor[j].offset);
1121     }
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)
1126         return -1;
1127   STREAM_RESTORE_STATE (stream, state);
1128   return 0;
1129 }
1130
1131
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)
1136 {
1137   char *errfmt = "Class1Record%s";
1138   void *errret = NULL;
1139   OTF_Class1Record *rec;
1140   int i, j;
1141
1142   OTF_MALLOC (rec, num1, "");
1143   for (i = 0; i < num1; i++)
1144     {
1145       OTF_CALLOC (rec[i].Class2Record, num2, " (Class2Record)");
1146       for (j = 0; j < num2; j++)
1147         {
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)
1152             return NULL;
1153         }
1154     }
1155   return rec;
1156 }
1157
1158
1159 static int 
1160 read_lookup_subtable_gpos (OTF_Stream *stream, long offset, unsigned type,
1161                            OTF_LookupSubTable *subtable)
1162 {
1163   char *errfmt = "GPOS LookupSubTable%s";
1164   int errret = -1;
1165
1166   STREAM_SEEK (stream, offset);
1167   READ_UINT16 (stream, subtable->Format);
1168   switch (type)
1169     {
1170     case 1:
1171 #if 0
1172       if (subtable->Format == 1)
1173         {
1174           read_coverage (stream, offset, &subtable->Coverage);
1175           subtable->sub.gsub.single1.DeltaGlyphID = READ_INT16 (stream);
1176         }
1177       else if (subtable->Format == 2)
1178         {
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);
1183         }
1184       else
1185         OTF_ERROR (OTF_ERROR_TABLE, " (Invalid SubFormat)");
1186 #endif
1187       break;
1188
1189     case 2:
1190       if (subtable->Format == 1)
1191         {
1192           read_coverage (stream, offset, &subtable->Coverage);
1193         }
1194       else if (subtable->Format == 2)
1195         {
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);
1210         }
1211       else
1212         OTF_ERROR (OTF_ERROR_TABLE, " (Invalid SubFormat)");
1213       break;
1214       
1215     case 4:
1216       if (subtable->Format == 1)
1217         {
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);
1227         }
1228       else
1229         OTF_ERROR (OTF_ERROR_TABLE, " (Invalid SubFormat)");
1230       break;
1231
1232     case 6:
1233 #if 0
1234       if (subtable->Format == 1)
1235         {
1236           read_coverage (stream, offset,
1237                          &subtable->sub.gsub.chain_context1.Coverage);
1238           subtable->sub.gsub.chain_context1.ChainSubRuleSetCount
1239             = (read_chain_subrule_set
1240                (stream, offset,
1241                 &subtable->sub.gsub.chain_context1.ChainSubRuleSet));
1242         }
1243       else if (subtable->Format == 2)
1244         {
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
1255                (stream, offset,
1256                 &subtable->sub.gsub.chain_context2.ChainSubClassSet));
1257         }
1258       else if (subtable->Format == 3)
1259         {
1260           subtable->sub.gsub.chain_context3.BacktrackGlyphCount
1261             = (read_coverage_list
1262                (stream, offset,
1263                 &subtable->sub.gsub.chain_context3.Backtrack));
1264           subtable->sub.gsub.chain_context3.InputGlyphCount
1265             = (read_coverage_list
1266                (stream, offset,
1267                 &subtable->sub.gsub.chain_context3.Input));
1268           subtable->sub.gsub.chain_context3.LookaheadGlyphCount
1269             = (read_coverage_list
1270                (stream, offset,
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));
1275         }
1276       else
1277         OTF_ERROR (OTF_ERROR_TABLE, " (Invalid SubFormat)");
1278 #endif
1279
1280     default:
1281         OTF_ERROR (OTF_ERROR_TABLE, " (Invalid LookupType)");
1282     }
1283   return 0;
1284 }
1285
1286
1287 static OTF_GPOS *
1288 read_gpos_table (OTF_Stream *stream)
1289 {
1290   char *errfmt = "GPOS%s";
1291   void *errret = NULL;
1292   OTF_GPOS *gpos;
1293
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)
1302     return NULL;
1303   return gpos;
1304 }
1305
1306 \f
1307 #if 0
1308 /* BASE */
1309
1310 static OTF_BASE *
1311 read_base_table (OTF_Stream *stream, long offset)
1312 {
1313   OTF_BASE *base;
1314
1315   OTF_MALLOC (base, 1);
1316
1317   return base;
1318 }
1319
1320 \f
1321 /* JSTF */
1322
1323 static OTF_JSTF *
1324 read_jstf_table (OTF_Stream *stream, long offset)
1325 {
1326   OTF_JSTF *jstf;
1327
1328   OTF_MALLOC (jstf, 1);
1329
1330   return jstf;
1331 }
1332 #endif
1333 \f
1334 /* GDEF */
1335 static int
1336 read_attach_list (OTF_Stream *stream, long offset, OTF_AttachList *list)
1337 {
1338   char *errfmt = "AttachList%s";
1339   int errret = -1;
1340   int i, j;
1341
1342   if (read_coverage (stream, offset, &list->Coverage) < 0)
1343     return -1;
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++)
1349     {
1350       int count;
1351
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]);
1358     }
1359   return 0;
1360 }
1361
1362 static int
1363 read_caret_value (OTF_Stream *stream, long offset, OTF_CaretValue *caret)
1364 {
1365   char *errfmt = "CaretValue%s";
1366   int errret = -1;
1367
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)
1375     {
1376       READ_INT16 (stream, caret->f.f3.Coordinate);
1377       if (read_device_table (stream, offset + caret->offset,
1378                              &caret->f.f3.DeviceTable) < 0)
1379         return -1;
1380     }
1381   else
1382     OTF_ERROR (OTF_ERROR_TABLE, " (Invalid format)");
1383   return 0;
1384 }
1385
1386 static int
1387 read_lig_caret_list (OTF_Stream *stream, long offset, OTF_LigCaretList *list)
1388 {
1389   char *errfmt = "LigCaretList%s";
1390   int errret = -1;
1391   int i, j;
1392
1393   if (read_coverage (stream, offset, &list->Coverage) < 0)
1394     return -1;
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++)
1400     {
1401       int count;
1402
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)
1412           return -1;
1413     }
1414   return 0;
1415 }
1416
1417
1418 static int
1419 read_gdef_header (OTF_Stream *stream, OTF_GDEFHeader *header)
1420 {
1421   int errret = -1;
1422
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);
1428   return 0;
1429 }
1430
1431 static OTF_GDEF *
1432 read_gdef_table (OTF_Stream *stream)
1433 {
1434   char *errfmt = "GDEF%s";
1435   void *errret = NULL;
1436   OTF_GDEF *gdef;
1437
1438   OTF_CALLOC (gdef, 1, "");
1439   read_gdef_header (stream, (OTF_GDEFHeader *) &gdef->header);
1440   if (gdef->header.GlyphClassDef)
1441     {
1442       gdef->glyph_class_def.offset = gdef->header.GlyphClassDef;
1443       read_class_def_without_offset (stream, &gdef->glyph_class_def);
1444     }
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)
1452     {
1453       gdef->mark_attach_class_def.offset = gdef->header.MarkAttachClassDef;
1454       read_class_def_without_offset (stream, &gdef->mark_attach_class_def);
1455     }
1456
1457   return gdef;
1458 }
1459
1460 \f
1461
1462 /* cmap */
1463
1464 static OTF_cmap *
1465 read_cmap_table (OTF_Stream *stream)
1466 {
1467   char *errfmt = "cmap%s";
1468   void *errret = NULL;
1469   OTF_cmap *cmap;
1470   int i;
1471
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++)
1477     {
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;
1484     }
1485   for (i = 0; i < cmap->numTables; i++)
1486     {
1487       unsigned format;
1488
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)
1494         {
1495           READ_ULONG (stream, cmap->EncodingRecord[i].subtable.length);
1496           READ_ULONG (stream, cmap->EncodingRecord[i].subtable.language);
1497         }
1498       else
1499         {
1500           READ_USHORT (stream, cmap->EncodingRecord[i].subtable.language);
1501         }
1502       switch (format)
1503         {
1504         case 0:
1505           {
1506             OTF_MALLOC (cmap->EncodingRecord[i].subtable.f.f0, 1,
1507                         " (EncodingRecord)");
1508             READ_BYTES (stream,
1509                         cmap->EncodingRecord[i].subtable.f.f0->glyphIdArray,
1510                         256);
1511           }
1512           break;
1513
1514         case 2:
1515           break;
1516
1517         case 4:
1518           {
1519             OTF_EncodingSubtable4 *sub4;
1520             int segCount;
1521             int j;
1522             unsigned dummy;
1523
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++)
1540               {
1541                 unsigned off;
1542                 unsigned rest = 2 * (segCount - j);
1543                 
1544                 READ_USHORT (stream, off);
1545                 if (off == 0)
1546                   sub4->segments[j].idRangeOffset = 0xFFFF;
1547                 else
1548                   sub4->segments[j].idRangeOffset = (off - rest) / 2;
1549               }
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]);
1556           }
1557         }
1558     }
1559   return cmap;
1560 }
1561
1562 \f
1563
1564 /* name */
1565
1566 static char *
1567 read_name (OTF_Stream *stream, OTF_NameRecord *rec, int bytes)
1568 {
1569   char *errfmt = "nameID (%d)";
1570   void *errret = NULL;
1571   OTF_StreamState state;
1572   char *str;
1573   int i;
1574   int c;
1575
1576   STREAM_SAVE_STATE (stream, state);
1577   STREAM_SEEK (stream, stream->pos + rec->offset);
1578
1579   if (bytes == 1)
1580     {
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++)
1584         if (str[i] < 0)
1585           str[i] = '?';
1586     }
1587   else if (bytes == 2)
1588     {
1589       OTF_MALLOC (str, rec->length / 2 + 1, (void *) rec->nameID);
1590       for (i = 0; i < rec->length / 2; i++)
1591         {
1592           READ_USHORT (stream, c);
1593           if (c >= 128)
1594             c = '?';
1595           str[i] = c;
1596         }
1597     }
1598   else if (bytes == 4)
1599     {
1600       OTF_MALLOC (str, rec->length / 4 + 1, (void *) rec->nameID);
1601       for (i = 0; i < rec->length / 4; i++)
1602         {
1603           READ_ULONG (stream, c);
1604           if (c >= 128)
1605             c = '?';
1606           str[i] = c;
1607         }
1608     }
1609   str[i] = '\0';
1610   STREAM_RESTORE_STATE (stream, state);
1611   return str;
1612 }
1613
1614 static OTF_name *
1615 read_name_table (OTF_Stream *stream)
1616 {
1617   char *errfmt = "name%s";
1618   void *errret = NULL;
1619   OTF_name *name;
1620   int i;
1621
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++)
1628     {
1629       OTF_NameRecord *rec = name->nameRecord + i;
1630
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);
1637     }
1638   for (i = 0; i < name->count; i++)
1639     {
1640       OTF_NameRecord *rec = name->nameRecord + i;
1641       int nameID = rec->nameID;
1642
1643       if (nameID <= OTF_max_nameID
1644           && ! name->name[nameID])
1645         {
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);
1656         }
1657     }
1658
1659   return name;
1660 }
1661
1662
1663 \f
1664
1665 OTF *
1666 otf_open (char *otf_name)
1667 {
1668   char *errfmt = "OTF%s";
1669   void *errret = NULL;
1670   OTF_Stream *stream;
1671   OTF *otf;
1672   OTF_Tag head_tag, cmap_tag, name_tag, gdef_tag, gsub_tag, gpos_tag;
1673   int i;
1674
1675   stream = stream_open (otf_name);
1676   if (! stream)
1677     return NULL;
1678
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");
1685
1686   /* Size of Offset Table in OTF is 12 bytes.  */
1687   if (stream_setup (stream, 0, 12, "Offset Table") < 0)
1688     return NULL;
1689   
1690   OTF_CALLOC_GOTO (otf, 1, " (body)", err);
1691   otf->filename = strdup (otf_name);
1692   if (! otf->filename)
1693     {
1694       otf_error = OTF_ERROR_MEMORY;
1695       goto err;
1696     }
1697   if (read_offset_table (stream, &otf->offset_table) < 0)
1698     goto err;
1699
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)
1703     goto err;
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)
1708       goto err;
1709
1710   for (i = 0; i < otf->offset_table.numTables; i++)
1711     {
1712       if (otf->table_dirs[i].tag == head_tag)
1713         {
1714           stream_setup (stream, otf->table_dirs[i].offset,
1715                         otf->table_dirs[i].length, "head");
1716           otf->head = read_head_table (stream);
1717         }
1718       else if (otf->table_dirs[i].tag == cmap_tag)
1719         {
1720           stream_setup (stream, otf->table_dirs[i].offset,
1721                         otf->table_dirs[i].length, "cmap");
1722           otf->cmap = read_cmap_table (stream);
1723         }
1724       else if (otf->table_dirs[i].tag == name_tag)
1725         {
1726           stream_setup (stream, otf->table_dirs[i].offset,
1727                         otf->table_dirs[i].length, "name");
1728           otf->name = read_name_table (stream);
1729         }
1730       else if (otf->table_dirs[i].tag == gdef_tag)
1731         {
1732           stream_setup (stream, otf->table_dirs[i].offset,
1733                         otf->table_dirs[i].length, "GDEF");
1734           otf->gdef = read_gdef_table (stream);
1735         }
1736       else if (otf->table_dirs[i].tag == gsub_tag)
1737         {
1738           stream_setup (stream, otf->table_dirs[i].offset,
1739                         otf->table_dirs[i].length, "GSUB");
1740           otf->gsub = read_gsub_table (stream);
1741         }
1742       else if (otf->table_dirs[i].tag == gpos_tag)
1743         {
1744           stream_setup (stream, otf->table_dirs[i].offset,
1745                         otf->table_dirs[i].length, "GPOS");
1746           otf->gpos = read_gpos_table (stream);
1747         }
1748     }
1749
1750   stream_close (stream);
1751   return otf;
1752
1753  err:
1754   stream_close (stream);
1755   otf_close (otf);
1756   return NULL;
1757 }
1758
1759 void
1760 otf_close (OTF *otf)
1761 {
1762   if (otf->filename)
1763     free (otf->filename);
1764   if (otf->table_dirs)
1765     free (otf->table_dirs);
1766 }