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