]> git.donarmstrong.com Git - lilypond.git/blob - ttftool/parse.c
* ttftool/util.c (syserror): use errno for better error reporting.
[lilypond.git] / ttftool / parse.c
1 /* Copyright (c) 1997-1998 by Juliusz Chroboczek */
2
3 #include <sys/types.h>
4 #include <unistd.h>
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include "types.h"
8 #include "proto.h"
9
10 struct TableDirectoryEntry *
11 readDirectory (int fd, struct OffsetTable *ot)
12 {
13   unsigned n;
14   int i;
15
16   struct TableDirectoryEntry *td;
17   surely_read (fd, ot, sizeof (struct OffsetTable));
18   FIX_OffsetTable (*ot);
19   if (verbosity >= 2)
20     fprintf (stderr, "%d tables\n", ot->numTables);
21   n = sizeof (struct TableDirectoryEntry) * ot->numTables;
22   td = mymalloc (n);
23   surely_read (fd, td, n);
24   for (i = 0; i < ot->numTables; i++)
25     FIX_TableDirectoryEntry (td[i]);
26   return td;
27 }
28
29 char **
30 readNamingTable (int fd)
31 {
32   USHORT format;
33   USHORT nrecords;
34   off_t position;
35   USHORT offset;
36   int i, index, maxIndex;
37   struct NameRecord *records;
38   char *data;
39   char **strings;
40
41   position = surely_lseek (fd, 0, SEEK_CUR);
42
43   surely_read (fd, &format, sizeof (USHORT));
44   FIX_UH (format);
45   if (format != 0)
46     ttf_error ("Format should be 0\n");
47
48   surely_read (fd, &nrecords, sizeof (USHORT));
49   FIX_UH (nrecords);
50   surely_read (fd, &offset, sizeof (USHORT));
51   FIX_UH (offset);
52   records = mymalloc (nrecords * sizeof (struct NameRecord));
53   surely_read (fd, records, nrecords * sizeof (struct NameRecord));
54
55   for (i = 0, maxIndex = -1; i < nrecords; i++)
56     {
57       FIX_NameRecord (records[i]);
58       index = records[i].offset + records[i].length;
59       maxIndex = maxIndex > index ? maxIndex : index;
60     }
61   data = mymalloc (maxIndex);
62   surely_lseek (fd, position + offset, SEEK_SET);
63   surely_read (fd, data, maxIndex);
64
65   strings = mymalloc (8 * sizeof (char *));
66   for (i = 0; i < 8; i++)
67     strings[i] = NULL;
68
69   for (i = 0; i < nrecords; i++)
70     {
71       if
72         ((records[i].platformID == 3 && /* Microsoft */
73           records[i].encodingID == 1 && /* UGL */
74           records[i].languageID == 0x0409 &&    /* US English */
75           records[i].nameID <= 7))
76         {
77           strings[records[i].nameID] = mymalloc (records[i].length / 2 + 1);
78           unistrncpy (strings[records[i].nameID],
79                       data + records[i].offset, records[i].length);
80           if (verbosity >= 2)
81             fprintf (stderr, "%d: %s\n", records[i].nameID,
82                      strings[records[i].nameID]);
83         }
84     }
85
86
87   for (i = 0; i < nrecords; i++)
88     {
89       int id = records[i].nameID;
90       if (records[i].platformID == 1 && /* Apple */
91           records[i].encodingID == 0 && /* 8bit */
92           id <= 7 &&
93           !strings[id]
94          )
95         {
96           strings[id] = mymalloc (records[i].length + 1);
97           strncpy (strings[id],
98                    data + records[i].offset, records[i].length);
99           strings[id][records[i].length] = 0;
100           if (verbosity >= 2)
101             fprintf (stderr, "%d: %s\n", records[i].nameID,
102                      strings[records[i].nameID]);
103         }
104     }
105
106   free (records);
107   free (data);
108   return strings;
109 }
110
111 int
112 readMaxpTable (int fd)
113 {
114   struct
115   {
116     Fixed version;
117     USHORT nglyphs;
118   } data;
119   surely_read (fd, &data, sizeof (data));
120   FIX_Fixed (data.version);
121   FIX_UH (data.nglyphs);
122   if (verbosity >= 2)
123     fprintf (stderr, "  version %d.%u\n",
124              data.version.mantissa, data.version.fraction);
125   return data.nglyphs;
126 }
127
128 void
129 readHeadTable (int fd, struct HeadTable *ht)
130 {
131   surely_read (fd, ht, sizeof (struct HeadTable));
132   FIX_HeadTable (*ht);
133   if (verbosity >= 2)
134     {
135       fprintf (stderr, "  version %d.%d\n",
136                ht->version.mantissa, ht->version.fraction);
137       fprintf (stderr, "  font revision %d.%d\n",
138                ht->fontRevision.mantissa, ht->fontRevision.fraction);
139     }
140   if (ht->magicNumber != 0x5F0F3CF5)
141     ttf_error ("Bad magic number");
142   if (verbosity >= 2)
143     fprintf (stderr, "  %d units per Em\n", ht->unitsPerEm);
144 }
145
146 int
147 readPostTable (int fd, int nglyphs, struct PostTable *pt,
148                struct GlyphName **gt)
149 {
150   USHORT nglyphspost;
151   USHORT *glyphNameIndex;
152   struct GlyphName *glyphNames;
153   char **glyphNamesTemp;
154   int i, maxIndex;
155   CHAR c;
156
157   surely_read (fd, pt, sizeof (struct PostTable));
158   FIX_PostTable (*pt);
159   if (verbosity >= 2)
160     fprintf (stderr, "  format type %d.%u\n",
161              pt->formatType.mantissa, pt->formatType.fraction);
162
163   switch (pt->formatType.mantissa)
164     {
165     case 1:
166       return 1;                 /* MacGlyphEncoding */
167     case 2:
168       if (pt->formatType.fraction != 0)
169         ttf_error ("Unsupported `post' table format");
170       surely_read (fd, &nglyphspost, sizeof (USHORT));
171       FIX_UH (nglyphspost);
172       if (nglyphspost != nglyphs)
173         ttf_error ("Inconsistency between `maxp' and `nglyphs' tables!");
174       if (verbosity >= 2)
175         fprintf (stderr, "  %d glyphs\n", nglyphs);
176       glyphNameIndex = mymalloc (sizeof (USHORT) * nglyphs);
177       surely_read (fd, glyphNameIndex, sizeof (USHORT) * nglyphs);
178       glyphNames = mymalloc (sizeof (struct GlyphName) * nglyphs);
179       for (i = 0, maxIndex = -1; i < nglyphs; i++)
180         {
181           FIX_UH (glyphNameIndex[i]);
182           if (glyphNameIndex[i] < 258)
183             {
184               glyphNames[i].type = 0;
185               glyphNames[i].name.index = glyphNameIndex[i];
186             }
187           else
188             {
189               int index;
190               glyphNames[i].type = 1;
191               index = glyphNameIndex[i] - 258;
192               glyphNames[i].name.index = index;
193               maxIndex = maxIndex > index ? maxIndex : index;
194             }
195         }
196       free (glyphNameIndex);
197
198       i = 0;
199       glyphNamesTemp = mymalloc (sizeof (char *) * (maxIndex + 1));
200       while (i <= maxIndex)
201         {
202           surely_read (fd, &c, 1);
203           glyphNamesTemp[i] = mymalloc (c + 1);
204           surely_read (fd, glyphNamesTemp[i], c);
205           glyphNamesTemp[i][c] = '\0';
206           if (verbosity >= 3)
207             fprintf (stderr, "    %d: %s\n", i, glyphNamesTemp[i]);
208           i++;
209         }
210       for (i = 0; i < nglyphs; i++)
211         if (glyphNames[i].type == 1)
212           glyphNames[i].name.name = glyphNamesTemp[glyphNames[i].name.index];
213       free (glyphNamesTemp);
214       *gt = glyphNames;
215       return 2;
216     case 3:
217       return 3;                 /* no name table */
218     default:
219       return 0;
220     }
221  /*NOTREACHED*/}
222
223 void *
224 readLocaTable (int fd, int nglyphs, int format)
225 {
226   int i;
227   switch (format)
228     {
229     case 0:
230       {
231         USHORT *offsets;
232         offsets = mymalloc ((nglyphs + 1) * sizeof (USHORT));
233         surely_read (fd, offsets, (nglyphs + 1) * sizeof (USHORT));
234         for (i = 0; i <= nglyphs; i++)
235           FIX_UH (offsets[i]);
236         return offsets;
237       }
238      /*NOTREACHED*/ case 1:
239       {
240         ULONG *offsets;
241         offsets = mymalloc ((nglyphs + 1) * sizeof (ULONG));
242         surely_read (fd, offsets, (nglyphs + 1) * sizeof (ULONG));
243         for (i = 0; i <= nglyphs; i++)
244           FIX_UL (offsets[i]);
245         return offsets;
246       }
247      /*NOTREACHED*/ default:
248       ttf_error ("Unknown `loca' table format");
249      /*NOTREACHED*/}
250  /*NOTREACHED*/}
251
252 struct Box *
253 readGlyfTable (int fd, int nglyphs, int format, void *loca)
254 {
255   int i;
256   struct Box *bbox;
257   off_t base, offset;
258
259   base = surely_lseek (fd, 0, SEEK_CUR);
260
261   bbox = mymalloc (nglyphs * sizeof (struct Box));
262   for (i = 0; i < nglyphs; i++)
263     {
264       if (format == 0)
265         offset = 2 * ((USHORT *) loca)[i];
266       else
267         offset = ((ULONG *) loca)[i];
268       surely_lseek (fd, base + offset + sizeof (SHORT), SEEK_SET);
269       surely_read (fd, bbox + i, sizeof (struct Box));
270       FIX_Box (bbox[i]);
271     }
272   return bbox;
273 }
274
275 longHorMetric *
276 readHmtxTable (int fd, int nummetrics)
277 {
278   longHorMetric *metrics;
279   int i;
280
281   metrics = mymalloc (nummetrics * sizeof (longHorMetric));
282   surely_read (fd, metrics, nummetrics * sizeof (longHorMetric));
283   for (i = 0; i < nummetrics; i++)
284     {
285       FIX_longHorMetric (metrics[i]);
286     }
287   return metrics;
288 }
289
290 struct HheaTable *
291 readHheaTable (int fd)
292 {
293   struct HheaTable *hhea;
294   hhea = mymalloc (sizeof (struct HheaTable));
295   surely_read (fd, hhea, sizeof (struct HheaTable));
296   FIX_HheaTable (*hhea);
297   if (verbosity >= 2)
298     fprintf (stderr, "  version %d.%u\n",
299              hhea->version.mantissa, hhea->version.fraction);
300   if (hhea->metricDataFormat != 0)
301     ttf_error ("Unknown metric data format");
302   return hhea;
303 }
304
305 int
306 readKernTable (int fd, int **nkep, struct KernEntry0 ***kep)
307 {
308   struct KernTable kt;
309   struct KernSubTableHeader ksth;
310   struct KernSubTable0 kst;
311   int i, j;
312   int *nke;
313   struct KernEntry0 **ke;
314
315   surely_read (fd, &kt, sizeof (struct KernTable));
316   FIX_KernTable (kt);
317   if (verbosity >= 2)
318     {
319       fprintf (stderr, "  version %d\n", kt.version);
320       fprintf (stderr, "  %d subtables\n", kt.nTables);
321     }
322   nke = mymalloc (kt.nTables * sizeof (int));
323   ke = mymalloc (kt.nTables * sizeof (struct KernEntry0 *));
324
325   for (i = 0; i < kt.nTables; i++)
326     {
327       surely_read (fd, &ksth, sizeof (struct KernSubTableHeader));
328       FIX_KernSubTableHeader (ksth);
329       if (verbosity >= 2)
330         fprintf (stderr, "  analyzing subtable %d, version %d... ",
331                  i, ksth.version);
332       if ((ksth.coverage & kernHorizontal) &&
333           !(ksth.coverage & kernMinimum) &&
334           !(ksth.coverage & kernCrossStream) &&
335           (kernFormat (ksth.coverage) == 0))
336         {
337           surely_read (fd, &kst, sizeof (struct KernSubTable0));
338           FIX_KernSubTable0 (kst);
339           if (verbosity >= 2)
340             fprintf (stderr, "reading %d entries.\n", kst.nPairs);
341           nke[i] = kst.nPairs;
342           ke[i] = mymalloc (kst.nPairs * sizeof (struct KernEntry0));
343           surely_read (fd, ke[i], kst.nPairs * sizeof (struct KernEntry0));
344           for (j = 0; j < kst.nPairs; j++)
345             FIX_KernEntry0 (ke[i][j]);
346         }
347       else
348         {
349           if (verbosity >= 2)
350             fprintf (stderr, "skipping.\n");
351           surely_lseek (fd, ksth.length - sizeof (struct KernSubTableHeader),
352                         SEEK_CUR);
353         }
354     }
355   *nkep = nke;
356   *kep = ke;
357   return kt.nTables;
358 }