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