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