]> git.donarmstrong.com Git - lilypond.git/blob - ttftool/parse.c
*** empty log message ***
[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 root_nglyphs, struct PostTable *pt,
153                struct GlyphName **gt)
154 {
155   USHORT nglyphs;
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, &nglyphs, sizeof (USHORT));
176
177       /*from freetype2:
178        */
179       /*
180         UNDOCUMENTED!  The number of glyphs in this table can be smaller
181         than the value in the maxp table (cf. cyberbit.ttf).             
182        */
183       FIX_UH (nglyphs);
184       if (nglyphs > root_nglyphs)
185         {
186           fprintf (stderr, "More glyphs in 'post' table than in 'maxp' table");
187         }
188       
189       if (ttf_verbosity >= 2)
190         fprintf (stderr, "  %d glyphs\n", nglyphs);
191       glyphNameIndex = mymalloc (sizeof (USHORT) * nglyphs);
192       surely_read (fd, glyphNameIndex, sizeof (USHORT) * nglyphs);
193       glyphNames = mymalloc (sizeof (struct GlyphName) * nglyphs);
194       for (i = 0, maxIndex = -1; i < nglyphs; i++)
195         {
196           FIX_UH (glyphNameIndex[i]);
197           if (glyphNameIndex[i] < 258)
198             {
199               glyphNames[i].type = 0;
200               glyphNames[i].name.index = glyphNameIndex[i];
201             }
202           else
203             {
204               int index;
205               glyphNames[i].type = 1;
206               index = glyphNameIndex[i] - 258;
207               glyphNames[i].name.index = index;
208               maxIndex = maxIndex > index ? maxIndex : index;
209             }
210         }
211       free (glyphNameIndex);
212
213       i = 0;
214       glyphNamesTemp = mymalloc (sizeof (char *) * (maxIndex + 1));
215       while (i <= maxIndex)
216         {
217           surely_read (fd, &c, 1);
218           glyphNamesTemp[i] = mymalloc (c + 1);
219           surely_read (fd, glyphNamesTemp[i], c);
220           glyphNamesTemp[i][c] = '\0';
221           if (ttf_verbosity >= 3)
222             fprintf (stderr, "    %d: %s\n", i, glyphNamesTemp[i]);
223           i++;
224         }
225       for (i = 0; i < nglyphs; i++)
226         if (glyphNames[i].type == 1)
227           glyphNames[i].name.name = glyphNamesTemp[glyphNames[i].name.index];
228       free (glyphNamesTemp);
229       *gt = glyphNames;
230       return 2;
231     case 3:
232       return 3;                 /* no name table */
233     default:
234       return 0;
235     }
236  /*NOTREACHED*/}
237
238 void *
239 readLocaTable (FILE *fd, int nglyphs, int format)
240 {
241   int i;
242   switch (format)
243     {
244     case 0:
245       {
246         USHORT *offsets;
247         offsets = mymalloc ((nglyphs + 1) * sizeof (USHORT));
248         surely_read (fd, offsets, (nglyphs + 1) * sizeof (USHORT));
249         for (i = 0; i <= nglyphs; i++)
250           FIX_UH (offsets[i]);
251         return offsets;
252       }
253      /*NOTREACHED*/ case 1:
254       {
255         ULONG *offsets;
256         offsets = mymalloc ((nglyphs + 1) * sizeof (ULONG));
257         surely_read (fd, offsets, (nglyphs + 1) * sizeof (ULONG));
258         for (i = 0; i <= nglyphs; i++)
259           FIX_UL (offsets[i]);
260         return offsets;
261       }
262      /*NOTREACHED*/ default:
263       ttf_error ("Unknown `loca' table format");
264      /*NOTREACHED*/}
265  /*NOTREACHED*/}
266
267 struct Box *
268 readGlyfTable (FILE *fd, int nglyphs, int format, void *loca)
269 {
270   int i;
271   struct Box *bbox;
272   off_t base, offset;
273
274   base = ftell (fd);
275
276   bbox = mymalloc (nglyphs * sizeof (struct Box));
277   for (i = 0; i < nglyphs; i++)
278     {
279       if (format == 0)
280         offset = 2 * ((USHORT *) loca)[i];
281       else
282         offset = ((ULONG *) loca)[i];
283       surely_lseek (fd, base + offset + sizeof (SHORT), SEEK_SET);
284       surely_read (fd, bbox + i, sizeof (struct Box));
285       FIX_Box (bbox[i]);
286     }
287   return bbox;
288 }
289
290 longHorMetric *
291 readHmtxTable (FILE *fd, int nummetrics)
292 {
293   longHorMetric *metrics;
294   int i;
295
296   metrics = mymalloc (nummetrics * sizeof (longHorMetric));
297   surely_read (fd, metrics, nummetrics * sizeof (longHorMetric));
298   for (i = 0; i < nummetrics; i++)
299     {
300       FIX_longHorMetric (metrics[i]);
301     }
302   return metrics;
303 }
304
305 struct HheaTable *
306 readHheaTable (FILE *fd)
307 {
308   struct HheaTable *hhea;
309   hhea = mymalloc (sizeof (struct HheaTable));
310   surely_read (fd, hhea, sizeof (struct HheaTable));
311   FIX_HheaTable (*hhea);
312   if (ttf_verbosity >= 2)
313     fprintf (stderr, "  version %d.%u\n",
314              hhea->version.mantissa, hhea->version.fraction);
315   if (hhea->metricDataFormat != 0)
316     ttf_error ("Unknown metric data format");
317   return hhea;
318 }
319
320 int
321 readKernTable (FILE *fd, int **nkep, struct KernEntry0 ***kep)
322 {
323   struct KernTable kt;
324   struct KernSubTableHeader ksth;
325   struct KernSubTable0 kst;
326   int i, j;
327   int *nke;
328   struct KernEntry0 **ke;
329
330   surely_read (fd, &kt, sizeof (struct KernTable));
331   FIX_KernTable (kt);
332   if (ttf_verbosity >= 2)
333     {
334       fprintf (stderr, "  version %d\n", kt.version);
335       fprintf (stderr, "  %d subtables\n", kt.nTables);
336     }
337   nke = mymalloc (kt.nTables * sizeof (int));
338   ke = mymalloc (kt.nTables * sizeof (struct KernEntry0 *));
339
340   for (i = 0; i < kt.nTables; i++)
341     {
342       surely_read (fd, &ksth, sizeof (struct KernSubTableHeader));
343       FIX_KernSubTableHeader (ksth);
344       if (ttf_verbosity >= 2)
345         fprintf (stderr, "  analyzing subtable %d, version %d... ",
346                  i, ksth.version);
347       if ((ksth.coverage & kernHorizontal) &&
348           !(ksth.coverage & kernMinimum) &&
349           !(ksth.coverage & kernCrossStream) &&
350           (kernFormat (ksth.coverage) == 0))
351         {
352           surely_read (fd, &kst, sizeof (struct KernSubTable0));
353           FIX_KernSubTable0 (kst);
354           if (ttf_verbosity >= 2)
355             fprintf (stderr, "reading %d entries.\n", kst.nPairs);
356           nke[i] = kst.nPairs;
357           ke[i] = mymalloc (kst.nPairs * sizeof (struct KernEntry0));
358           surely_read (fd, ke[i], kst.nPairs * sizeof (struct KernEntry0));
359           for (j = 0; j < kst.nPairs; j++)
360             FIX_KernEntry0 (ke[i][j]);
361         }
362       else
363         {
364           if (ttf_verbosity >= 2)
365             fprintf (stderr, "skipping.\n");
366           surely_lseek (fd, ksth.length - sizeof (struct KernSubTableHeader),
367                         SEEK_CUR);
368         }
369     }
370   *nkep = nke;
371   *kep = ke;
372   return kt.nTables;
373 }