* ttftool/parse.c (readNamingTable): handle Apple/8bit encoding too.
[lilypond.git] / ttftool / parse.c
blobb233910b58918237db2c98df4778e42fd8feab05
1 /* Copyright (c) 1997-1998 by Juliusz Chroboczek */
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"
10 struct TableDirectoryEntry *
11 readDirectory (int fd, struct OffsetTable *ot)
13 unsigned n;
14 int i;
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;
29 char **
30 readNamingTable (int fd)
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;
41 position = surely_lseek (fd, 0, SEEK_CUR);
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));
54 for (i = 0, maxIndex = -1; i < nrecords; i++)
56 FIX_NameRecord (records[i]);
57 index = records[i].offset + records[i].length;
58 maxIndex = maxIndex > index ? maxIndex : index;
60 data = mymalloc (maxIndex);
61 surely_lseek (fd, position + offset, SEEK_SET);
62 surely_read (fd, data, maxIndex);
64 strings = mymalloc (8 * sizeof (char *));
65 for (i = 0; i < 8; i++)
66 strings[i] = NULL;
68 for (i = 0; i < nrecords; i++)
71 ((records[i].platformID == 3 && /* Microsoft */
72 records[i].encodingID == 1 && /* UGL */
73 records[i].languageID == 0x0409 && /* US English */
74 records[i].nameID <= 7))
76 strings[records[i].nameID] = mymalloc (records[i].length / 2 + 1);
77 unistrncpy (strings[records[i].nameID],
78 data + records[i].offset, records[i].length);
79 if (verbosity >= 2)
80 fprintf (stderr, "%d: %s\n", records[i].nameID,
81 strings[records[i].nameID]);
86 for (i = 0; i < nrecords; i++)
88 int id = records[i].nameID;
89 if (records[i].platformID == 1 && /* Apple */
90 records[i].encodingID == 0 && /* 8bit */
91 id <= 7 &&
92 !strings[id]
95 strings[id] = mymalloc (records[i].length + 1);
96 strncpy (strings[id],
97 data + records[i].offset, records[i].length);
98 strings[id][records[i].length] = 0;
99 if (verbosity >= 2)
100 fprintf (stderr, "%d: %s\n", records[i].nameID,
101 strings[records[i].nameID]);
105 free (records);
106 free (data);
107 return strings;
111 readMaxpTable (int fd)
113 struct
115 Fixed version;
116 USHORT nglyphs;
117 } data;
118 surely_read (fd, &data, sizeof (data));
119 FIX_Fixed (data.version);
120 FIX_UH (data.nglyphs);
121 if (verbosity >= 2)
122 fprintf (stderr, " version %d.%u\n",
123 data.version.mantissa, data.version.fraction);
124 return data.nglyphs;
127 void
128 readHeadTable (int fd, struct HeadTable *ht)
130 surely_read (fd, ht, sizeof (struct HeadTable));
131 FIX_HeadTable (*ht);
132 if (verbosity >= 2)
134 fprintf (stderr, " version %d.%d\n",
135 ht->version.mantissa, ht->version.fraction);
136 fprintf (stderr, " font revision %d.%d\n",
137 ht->fontRevision.mantissa, ht->fontRevision.fraction);
139 if (ht->magicNumber != 0x5F0F3CF5)
140 error ("Bad magic number in TTF file");
141 if (verbosity >= 2)
142 fprintf (stderr, " %d units per Em\n", ht->unitsPerEm);
146 readPostTable (int fd, int nglyphs, struct PostTable *pt,
147 struct GlyphName **gt)
149 USHORT nglyphspost;
150 USHORT *glyphNameIndex;
151 struct GlyphName *glyphNames;
152 char **glyphNamesTemp;
153 int i, maxIndex;
154 CHAR c;
156 surely_read (fd, pt, sizeof (struct PostTable));
157 FIX_PostTable (*pt);
158 if (verbosity >= 2)
159 fprintf (stderr, " format type %d.%u\n",
160 pt->formatType.mantissa, pt->formatType.fraction);
162 switch (pt->formatType.mantissa)
164 case 1:
165 return 1; /* MacGlyphEncoding */
166 case 2:
167 if (pt->formatType.fraction != 0)
168 error ("Unsupported `post' table format");
169 surely_read (fd, &nglyphspost, sizeof (USHORT));
170 FIX_UH (nglyphspost);
171 if (nglyphspost != nglyphs)
172 error ("Inconsistency between `maxp' and `nglyphs' tables!");
173 if (verbosity >= 2)
174 fprintf (stderr, " %d glyphs\n", nglyphs);
175 glyphNameIndex = mymalloc (sizeof (USHORT) * nglyphs);
176 surely_read (fd, glyphNameIndex, sizeof (USHORT) * nglyphs);
177 glyphNames = mymalloc (sizeof (struct GlyphName) * nglyphs);
178 for (i = 0, maxIndex = -1; i < nglyphs; i++)
180 FIX_UH (glyphNameIndex[i]);
181 if (glyphNameIndex[i] < 258)
183 glyphNames[i].type = 0;
184 glyphNames[i].name.index = glyphNameIndex[i];
186 else
188 int index;
189 glyphNames[i].type = 1;
190 index = glyphNameIndex[i] - 258;
191 glyphNames[i].name.index = index;
192 maxIndex = maxIndex > index ? maxIndex : index;
195 free (glyphNameIndex);
197 i = 0;
198 glyphNamesTemp = mymalloc (sizeof (char *) * (maxIndex + 1));
199 while (i <= maxIndex)
201 surely_read (fd, &c, 1);
202 glyphNamesTemp[i] = mymalloc (c + 1);
203 surely_read (fd, glyphNamesTemp[i], c);
204 glyphNamesTemp[i][c] = '\0';
205 if (verbosity >= 3)
206 fprintf (stderr, " %d: %s\n", i, glyphNamesTemp[i]);
207 i++;
209 for (i = 0; i < nglyphs; i++)
210 if (glyphNames[i].type == 1)
211 glyphNames[i].name.name = glyphNamesTemp[glyphNames[i].name.index];
212 free (glyphNamesTemp);
213 *gt = glyphNames;
214 return 2;
215 case 3:
216 return 3; /* no name table */
217 default:
218 return 0;
220 /*NOTREACHED*/}
222 void *
223 readLocaTable (int fd, int nglyphs, int format)
225 int i;
226 switch (format)
228 case 0:
230 USHORT *offsets;
231 offsets = mymalloc ((nglyphs + 1) * sizeof (USHORT));
232 surely_read (fd, offsets, (nglyphs + 1) * sizeof (USHORT));
233 for (i = 0; i <= nglyphs; i++)
234 FIX_UH (offsets[i]);
235 return offsets;
237 /*NOTREACHED*/ case 1:
239 ULONG *offsets;
240 offsets = mymalloc ((nglyphs + 1) * sizeof (ULONG));
241 surely_read (fd, offsets, (nglyphs + 1) * sizeof (ULONG));
242 for (i = 0; i <= nglyphs; i++)
243 FIX_UL (offsets[i]);
244 return offsets;
246 /*NOTREACHED*/ default:
247 error ("Unknown `loca' table format");
248 /*NOTREACHED*/}
249 /*NOTREACHED*/}
251 struct Box *
252 readGlyfTable (int fd, int nglyphs, int format, void *loca)
254 int i;
255 struct Box *bbox;
256 off_t base, offset;
258 base = surely_lseek (fd, 0, SEEK_CUR);
260 bbox = mymalloc (nglyphs * sizeof (struct Box));
261 for (i = 0; i < nglyphs; i++)
263 if (format == 0)
264 offset = 2 * ((USHORT *) loca)[i];
265 else
266 offset = ((ULONG *) loca)[i];
267 surely_lseek (fd, base + offset + sizeof (SHORT), SEEK_SET);
268 surely_read (fd, bbox + i, sizeof (struct Box));
269 FIX_Box (bbox[i]);
271 return bbox;
274 longHorMetric *
275 readHmtxTable (int fd, int nummetrics)
277 longHorMetric *metrics;
278 int i;
280 metrics = mymalloc (nummetrics * sizeof (longHorMetric));
281 surely_read (fd, metrics, nummetrics * sizeof (longHorMetric));
282 for (i = 0; i < nummetrics; i++)
284 FIX_longHorMetric (metrics[i]);
286 return metrics;
289 struct HheaTable *
290 readHheaTable (int fd)
292 struct HheaTable *hhea;
293 hhea = mymalloc (sizeof (struct HheaTable));
294 surely_read (fd, hhea, sizeof (struct HheaTable));
295 FIX_HheaTable (*hhea);
296 if (verbosity >= 2)
297 fprintf (stderr, " version %d.%u\n",
298 hhea->version.mantissa, hhea->version.fraction);
299 if (hhea->metricDataFormat != 0)
300 error ("Unknown metric data format");
301 return hhea;
305 readKernTable (int fd, int **nkep, struct KernEntry0 ***kep)
307 struct KernTable kt;
308 struct KernSubTableHeader ksth;
309 struct KernSubTable0 kst;
310 int i, j;
311 int *nke;
312 struct KernEntry0 **ke;
314 surely_read (fd, &kt, sizeof (struct KernTable));
315 FIX_KernTable (kt);
316 if (verbosity >= 2)
318 fprintf (stderr, " version %d\n", kt.version);
319 fprintf (stderr, " %d subtables\n", kt.nTables);
321 nke = mymalloc (kt.nTables * sizeof (int));
322 ke = mymalloc (kt.nTables * sizeof (struct KernEntry0 *));
324 for (i = 0; i < kt.nTables; i++)
326 surely_read (fd, &ksth, sizeof (struct KernSubTableHeader));
327 FIX_KernSubTableHeader (ksth);
328 if (verbosity >= 2)
329 fprintf (stderr, " analyzing subtable %d, version %d... ",
330 i, ksth.version);
331 if ((ksth.coverage & kernHorizontal) &&
332 !(ksth.coverage & kernMinimum) &&
333 !(ksth.coverage & kernCrossStream) &&
334 (kernFormat (ksth.coverage) == 0))
336 surely_read (fd, &kst, sizeof (struct KernSubTable0));
337 FIX_KernSubTable0 (kst);
338 if (verbosity >= 2)
339 fprintf (stderr, "reading %d entries.\n", kst.nPairs);
340 nke[i] = kst.nPairs;
341 ke[i] = mymalloc (kst.nPairs * sizeof (struct KernEntry0));
342 surely_read (fd, ke[i], kst.nPairs * sizeof (struct KernEntry0));
343 for (j = 0; j < kst.nPairs; j++)
344 FIX_KernEntry0 (ke[i][j]);
346 else
348 if (verbosity >= 2)
349 fprintf (stderr, "skipping.\n");
350 surely_lseek (fd, ksth.length - sizeof (struct KernSubTableHeader),
351 SEEK_CUR);
354 *nkep = nke;
355 *kep = ke;
356 return kt.nTables;