1 /* Copyright (C) 2001-2012 Artifex Software, Inc.
2    All Rights Reserved.
3 
4    This software is provided AS-IS with no warranty, either express or
5    implied.
6 
7    This software is distributed under license and may not be copied,
8    modified or distributed except as expressly authorized under the terms
9    of the license contained in the file LICENSE in this distribution.
10 
11    Refer to licensing information at http://www.artifex.com or contact
12    Artifex Software, Inc.,  7 Mt. Lassen Drive - Suite A-134, San Rafael,
13    CA  94903, U.S.A., +1(415)492-9861, for further information.
14 */
15 
16 
17 /* Write an embedded TrueType font */
18 #include "memory_.h"
19 #include <stdlib.h>		/* for qsort */
20 #include <math.h>		/* for floor */
21 #include "gx.h"
22 #include "gscencs.h"
23 #include "gserrors.h"
24 #include "gsmatrix.h"
25 #include "gsutil.h"
26 #include "gxfcid.h"
27 #include "gxfont.h"
28 #include "gxfont42.h"
29 #include "gxttf.h"
30 #include "stream.h"
31 #include "spprint.h"
32 #include "gdevpsf.h"
33 
34 /* Internally used options */
35 #define WRITE_TRUETYPE_STRIPPED 0x1000	/* internal */
36 #define WRITE_TRUETYPE_CID 0x2000 /* internal */
37 
38 #define MAX_COMPOSITE_PIECES 3	/* adhoc */
39 
40 /*
41  * The following are only for debugging.  They force various format choices
42  * in the output.  The normal (non-debugging) values for all of these are
43  * as indicated in the comments.
44  *
45  * Note that these options interact.  Here is the complete list of settings
46  * that make sense.
47         0	-1,0,1	N/A	0,1	0,1
48         0xf000	-1	N/A	1	0,1
49         0xf000	0,1	0,1	1	0,1
50  */
51 /* Define whether to use the 0xf000 character bias for generated tables. */
52 #define TT_BIAS 0xf000		/* 0xf000 */
53 /* Define whether to use cmap format 6 never(-1), sometimes(0), always(1). */
54 #define TT_FORCE_CMAP_6 0	/* 0 */
55 /* Define whether to use the bias for the cmap format 6 "first code". */
56 #define TT_BIAS_CMAP_6 0	/* 0 */
57 /* Define whether to generate an OS/2 table if none is supplied. */
58 #define TT_GENERATE_OS_2 1	/* 1 */
59 /* Define whether to adjust the OS/2 range bits. */
60 #define TT_ADJUST_OS_2 1	/* 1 */
61 /*
62  * End of options.
63  */
64 
65 /* ---------------- Utilities ---------------- */
66 
67 /* Pad to a multiple of 4 bytes. */
68 static void
put_pad(stream * s,uint length)69 put_pad(stream *s, uint length)
70 {
71     static const byte pad_to_4[3] = {0, 0, 0};
72 
73     stream_write(s, pad_to_4, (uint)(-(int)length & 3));
74 }
75 
76 /* Put short and long values on a stream. */
77 static void
put_ushort(stream * s,uint v)78 put_ushort(stream *s, uint v)
79 {
80     stream_putc(s, (byte)(v >> 8));
81     stream_putc(s, (byte)v);
82 }
83 static void
put_short(stream * s,short v)84 put_short(stream *s, short v)
85 {
86     stream_putc(s, (byte)(v >> 8));
87     stream_putc(s, (byte)v);
88 }
89 static void
put_ulong(stream * s,ulong v)90 put_ulong(stream *s, ulong v)
91 {
92     put_ushort(s, (uint)(v >> 16));
93     put_ushort(s, (uint)v);
94 }
95 static void
put_loca(stream * s,ulong offset,int indexToLocFormat)96 put_loca(stream *s, ulong offset, int indexToLocFormat)
97 {
98     if (indexToLocFormat)
99         put_ulong(s, offset);
100     else
101         put_ushort(s, (uint)(offset >> 1));
102 }
103 
104 /* Get or put 2- or 4-byte quantities from/into a table. */
105 #define U8(p) ((uint)((p)[0]))
106 #define S8(p) (int)((U8(p) ^ 0x80) - 0x80)
107 #define U16(p) (((uint)((p)[0]) << 8) + (p)[1])
108 #define S16(p) (int)((U16(p) ^ 0x8000) - 0x8000)
109 #define u32(p) get_u32_msb(p)
110 static void
put_u16(byte * p,uint v)111 put_u16(byte *p, uint v)
112 {
113     p[0] = (byte)(v >> 8);
114     p[1] = (byte)v;
115 }
116 static void
put_u32(byte * p,ulong v)117 put_u32(byte *p, ulong v)
118 {
119     put_u16(p, (ushort)(v >> 16));
120     put_u16(p + 2, (ushort)v);
121 }
122 static ulong
put_table(byte tab[16],const char * tname,ulong checksum,ulong offset,uint length)123 put_table(byte tab[16], const char *tname, ulong checksum, ulong offset,
124           uint length)
125 {
126     memcpy(tab, (const byte *)tname, 4);
127     put_u32(tab + 4, checksum);
128     put_u32(tab + 8, offset + 0x40000000);
129     put_u32(tab + 12, (ulong)length);
130     return offset + round_up(length, 4);
131 }
132 
133 /* Write one range of a TrueType font. */
134 static int
write_range(stream * s,gs_font_type42 * pfont,ulong start,uint length)135 write_range(stream *s, gs_font_type42 *pfont, ulong start, uint length)
136 {
137     ulong base = start, size = length;
138 
139     if_debug3('l', "[l]write_range pos = %ld, start = %lu, length = %u\n",
140               stell(s), start, length);
141     while (size > 0) {
142         const byte *ptr;
143         int code;
144 
145         code = pfont->data.string_proc(pfont, base, size, &ptr);
146         if (code < 0)
147             return code;
148         if (!code)
149             code = size;
150         stream_write(s, ptr, code);
151         base += code;
152         size -= code;
153     }
154     return 0;
155 }
156 
157 /*
158  * Determine the Macintosh glyph number for a given character, if any.
159  * If no glyph can be found, return -1 and store the name in *pstr.
160  */
161 static int
mac_glyph_index(gs_font * font,int ch,gs_const_string * pstr,int * index)162 mac_glyph_index(gs_font *font, int ch, gs_const_string *pstr, int *index)
163 {
164     gs_glyph glyph = font->procs.encode_char(font, (gs_char)ch,
165                                              GLYPH_SPACE_NAME);
166     int code;
167 
168     if (glyph == gs_no_glyph) {
169         *index = 0;
170         return 0;		/* .notdef */
171     }
172     code = font->procs.glyph_name(font, glyph, pstr);
173     if (code < 0)
174         return code;
175     if (glyph < gs_min_cid_glyph) {
176         gs_char mac_char;
177         gs_glyph mac_glyph;
178         gs_const_string mstr;
179 
180         /* Look (not very hard) for a match in the Mac glyph space. */
181         if (ch >= 32 && ch <= 126)
182             mac_char = ch - 29;
183         else if (ch >= 128 && ch <= 255)
184             mac_char = ch - 30;
185         else {
186             *index = -1;
187             return 0;
188         }
189         mac_glyph = gs_c_known_encode(mac_char, ENCODING_INDEX_MACGLYPH);
190         if (mac_glyph == gs_no_glyph) {
191             *index = -1;
192             return 0;
193         }
194         code = gs_c_glyph_name(mac_glyph, &mstr);
195         if (code < 0)
196             return code;
197         if (!bytes_compare(pstr->data, pstr->size, mstr.data, mstr.size)) {
198             *index = (int)mac_char;
199             return 0;
200         }
201     }
202     *index = -1;
203     return 0;
204 }
205 
206 /* ---------------- Individual tables ---------------- */
207 
208 /* ------ cmap ------ */
209 
210 /* Write a generated cmap table. */
211 static const byte cmap_initial_0[] = {
212     0, 0,		/* table version # = 0 */
213     0, 2,		/* # of encoding tables = 2 */
214 
215         /* First table, Macintosh */
216     0, 1,		/* platform ID = Macintosh */
217     0, 0,		/* platform encoding ID = ??? */
218     0, 0, 0, 4+8+8,	/* offset to table start */
219         /* Second table, Windows */
220     0, 3,		/* platform ID = Microsoft */
221     0, 0,		/* platform encoding ID = unknown */
222     0, 0, 1, 4+8+8+6,	/* offset to table start */
223 
224         /* Start of Macintosh format 0 table */
225     0, 0,		/* format = 0, byte encoding table */
226     1, 6,		/* length */
227     0, 0		/* version number */
228 };
229 static const byte cmap_initial_6[] = {
230     0, 0,		/* table version # = 0 */
231     0, 2,		/* # of encoding tables = 2 */
232 
233         /* First table, Macintosh */
234     0, 1,		/* platform ID = Macintosh */
235     0, 0,		/* platform encoding ID = ??? */
236     0, 0, 0, 4+8+8,	/* offset to table start */
237         /* Second table, Windows */
238     0, 3,		/* platform ID = Microsoft */
239     0, 0,		/* platform encoding ID = unknown */
240     0, 0, 0, 4+8+8+10,	/* offset to table start */
241                         /* *VARIABLE*, add 2 x # of entries */
242 
243         /* Start of Macintosh format 6 table */
244     0, 6,		/* format = 6, trimmed table mapping */
245     0, 10,		/* length *VARIABLE*, add 2 x # of entries */
246     0, 0,		/* version number */
247     0, 0,		/* first character code */
248     0, 0		/* # of entries *VARIABLE* */
249 };
250 static const byte cmap_unicode_initial_6[] = {
251     0, 0,		/* table version # = 0 */
252     0, 2,		/* # of encoding tables = 2 */
253 
254         /* First table, Macintosh */
255     0, 1,		/* platform ID = Macintosh */
256     0, 0,		/* platform encoding ID = ??? */
257     0, 0, 0, 4+8+8,	/* offset to table start */
258         /* Second table, Windows */
259     0, 3,		/* platform ID = Microsoft */
260     0, 1,		/* platform encoding ID = Unicode */
261     0, 0, 0, 4+8+8+10,	/* offset to table start */
262                         /* *VARIABLE*, add 2 x # of entries */
263 
264         /* Start of Macintosh format 6 table */
265     0, 6,		/* format = 6, trimmed table mapping */
266     0, 10,		/* length *VARIABLE*, add 2 x # of entries */
267     0, 0,		/* version number */
268     0, 0,		/* first character code */
269     0, 0		/* # of entries *VARIABLE* */
270 };
271 static const byte cmap_initial_4[] = {
272     0, 0,		/* table version # = 0 */
273     0, 1,		/* # of encoding tables = 2 */
274 
275         /* Single table, Windows */
276     0, 3,		/* platform ID = Microsoft */
277     0, 0,		/* platform encoding ID = unknown */
278     0, 0, 0, 4+8	/* offset to table start */
279 };
280 static const byte cmap_sub_initial[] = {
281     0, 4,		/* format = 4, segment mapping */
282     0, 32,		/* length ** VARIABLE, add 2 x # of glyphs ** */
283     0, 0,		/* version # */
284     0, 4,		/* 2 x segCount */
285     0, 4,		/* searchRange = 2 x 2 ^ floor(log2(segCount)) */
286     0, 1,		/* floor(log2(segCount)) */
287     0, 0,		/* 2 x segCount - searchRange */
288 
289     0, 0,		/* endCount[0] **VARIABLE** */
290     255, 255,		/* endCount[1] */
291     0, 0,		/* reservedPad */
292     0, 0,		/* startCount[0] **VARIABLE** */
293     255, 255,		/* startCount[1] */
294     0, 0,		/* idDelta[0] */
295     0, 1,		/* idDelta[1] */
296     0, 4,		/* idRangeOffset[0] */
297     0, 0		/* idRangeOffset[1] */
298 };
299 /*
300  * The following nonsense is required because C defines sizeof()
301  * inconsistently.
302  */
303 #define CMAP_ENTRIES_SIZE (256 * 2)
304 static void
write_cmap_0(stream * s,byte * entries,uint num_glyphs)305 write_cmap_0(stream *s, byte* entries /*[CMAP_ENTRIES_SIZE]*/, uint num_glyphs)
306 {
307     int i;
308 
309     if (CMAP_ENTRIES_SIZE - 2 * num_glyphs>0)
310       memset(entries + 2 * num_glyphs, 0, CMAP_ENTRIES_SIZE - 2 * num_glyphs);
311     stream_write(s, cmap_initial_0, sizeof(cmap_initial_0));
312     for (i = 0; i <= 0xff; ++i)
313         sputc(s, (byte)entries[2 * i + 1]);
314 }
315 static void
write_cmap_6(stream * s,byte * entries,uint first_code,uint first_entry,uint num_entries)316 write_cmap_6(stream *s, byte *entries /*[CMAP_ENTRIES_SIZE]*/, uint first_code,
317              uint first_entry, uint num_entries)
318 {
319     byte cmap_data[sizeof(cmap_initial_6)];
320 
321     memcpy(cmap_data, cmap_initial_6, sizeof(cmap_initial_6));
322     put_u16(cmap_data + 18,
323             U16(cmap_data + 18) + num_entries * 2);  /* offset */
324     put_u16(cmap_data + 22,
325             U16(cmap_data + 22) + num_entries * 2);  /* length */
326     put_u16(cmap_data + 26,
327 #if TT_BIAS_CMAP_6
328             first_code +
329 #endif
330             first_entry);
331     put_u16(cmap_data + 28, num_entries);
332     stream_write(s, cmap_data, sizeof(cmap_data));
333     stream_write(s, entries + first_entry * 2, num_entries * 2);
334 }
write_unicode_cmap_6(stream * s,byte * entries,uint first_code,uint first_entry,uint num_entries)335 static void write_unicode_cmap_6(stream *s, byte *entries, uint first_code,
336              uint first_entry, uint num_entries)
337 {
338     byte cmap_data[sizeof(cmap_unicode_initial_6)];
339 
340     memcpy(cmap_data, cmap_unicode_initial_6, sizeof(cmap_unicode_initial_6));
341     put_u16(cmap_data + 18,
342             U16(cmap_data + 18) + num_entries * 2);  /* offset */
343     put_u16(cmap_data + 22,
344             U16(cmap_data + 22) + num_entries * 2);  /* length */
345     put_u16(cmap_data + 26, first_entry);
346     put_u16(cmap_data + 28, num_entries);
347     stream_write(s, cmap_data, sizeof(cmap_data));
348     stream_write(s, entries + first_entry * 2, num_entries * 2);
349 }
350 static void
write_cmap(stream * s,gs_font * font,uint first_code,int num_glyphs,gs_glyph max_glyph,int options,uint cmap_length)351 write_cmap(stream *s, gs_font *font, uint first_code, int num_glyphs,
352            gs_glyph max_glyph, int options, uint cmap_length)
353 {
354     byte cmap_sub[sizeof(cmap_sub_initial)];
355     byte entries[CMAP_ENTRIES_SIZE];
356     int first_entry = 0, end_entry = num_glyphs;
357     bool can_use_trimmed = !(options & WRITE_TRUETYPE_NO_TRIMMED_TABLE);
358     uint merge = 0;
359     uint num_entries;
360     int i;
361 
362     /* Collect the table entries. */
363 
364     for (i = 0; i < num_glyphs; ++i) {
365         gs_glyph glyph =
366             font->procs.encode_char(font, (gs_char)i, GLYPH_SPACE_INDEX);
367         uint glyph_index;
368 
369         if (glyph == gs_no_glyph || glyph < GS_MIN_GLYPH_INDEX ||
370             glyph > max_glyph
371             )
372             glyph = GS_MIN_GLYPH_INDEX;
373         glyph_index = (uint)(glyph - GS_MIN_GLYPH_INDEX);
374         merge |= glyph_index;
375         put_u16(entries + 2 * i, glyph_index);
376     }
377     while (end_entry > first_entry && !U16(entries + 2 * end_entry - 2))
378         --end_entry;
379     while (first_entry < end_entry && !U16(entries + 2 * first_entry))
380         ++first_entry;
381     num_entries = end_entry - first_entry;
382 
383     /* Write the table header and Macintosh sub-table (if any). */
384 
385     if (options & WRITE_TRUETYPE_UNICODE_CMAP) {
386         write_unicode_cmap_6(s, entries, first_code, first_entry, num_entries);
387 
388         /* Write the Windows sub-table. */
389         memcpy(cmap_sub, cmap_sub_initial, sizeof(cmap_sub_initial));
390         put_u16(cmap_sub + 2, U16(cmap_sub + 2) + num_entries * 2); /* length */
391         put_u16(cmap_sub + 14, end_entry - 1); /* endCount[0] */
392         put_u16(cmap_sub + 20, first_entry); /* startCount[0] */
393         stream_write(s, cmap_sub, sizeof(cmap_sub));
394         stream_write(s, entries + first_entry * 2, num_entries * 2);
395         put_pad(s, cmap_length);
396         return;
397     }
398 #if TT_FORCE_CMAP_6 > 0
399     /* Always use format 6. */
400     write_cmap_6(s, entries, first_code, first_entry, num_entries);
401 #else
402 # if TT_FORCE_CMAP_6 < 0
403     /* Never use format 6.  Use format 0 if possible. */
404     if (merge == (byte)merge)
405         write_cmap_0(s, entries, num_glyphs);
406     else
407 # else /* TT_FORCE_CMAP == 0 */
408     /*
409      * Use format 0 if possible and (economical or format 6 disallowed),
410      * otherwise format 6 if allowed.
411      */
412     if (merge == (byte)merge && (num_entries <= 127 || !can_use_trimmed))
413         write_cmap_0(s, entries, num_glyphs);
414     else if (can_use_trimmed)
415         write_cmap_6(s, entries, first_code, first_entry, num_entries);
416     else
417 # endif
418     {
419         /*
420          * Punt.  Acrobat Reader 3 can't handle any other Mac table format.
421          * (AR3 for Linux doesn't seem to be able to handle Windows format,
422          * either, but maybe AR3 for Windows can.)
423          */
424         stream_write(s, cmap_initial_4, sizeof(cmap_initial_4));
425     }
426 #endif
427 
428     /* Write the Windows sub-table. */
429 
430     memcpy(cmap_sub, cmap_sub_initial, sizeof(cmap_sub_initial));
431     put_u16(cmap_sub + 2, U16(cmap_sub + 2) + num_entries * 2); /* length */
432     put_u16(cmap_sub + 14, first_code + end_entry - 1); /* endCount[0] */
433     put_u16(cmap_sub + 20, first_code + first_entry); /* startCount[0] */
434     stream_write(s, cmap_sub, sizeof(cmap_sub));
435     stream_write(s, entries + first_entry * 2, num_entries * 2);
436     put_pad(s, cmap_length);
437 }
438 static uint
size_cmap(gs_font * font,uint first_code,int num_glyphs,gs_glyph max_glyph,int options)439 size_cmap(gs_font *font, uint first_code, int num_glyphs, gs_glyph max_glyph,
440           int options)
441 {
442     stream poss;
443 
444     s_init(&poss, NULL);
445     swrite_position_only(&poss);
446     write_cmap(&poss, font, first_code, num_glyphs, max_glyph, options, 0);
447     return stell(&poss);
448 }
449 
450 /* ------ hmtx/vmtx ------ */
451 
452 static void
write_mtx(stream * s,gs_font_type42 * pfont,const gs_type42_mtx_t * pmtx,int wmode)453 write_mtx(stream *s, gs_font_type42 *pfont, const gs_type42_mtx_t *pmtx,
454           int wmode)
455 {
456     uint num_metrics = pmtx->numMetrics;
457     uint len = num_metrics * 4;
458     double factor = (double)pfont->data.unitsPerEm * (wmode ? -1 : 1);
459     float sbw[4];
460     uint i;
461 
462     sbw[0] = sbw[1] = sbw[2] = sbw[3] = 0; /* in case of failures */
463     for (i = 0; i < pmtx->numMetrics; ++i) {
464         float f;
465         DISCARD(pfont->data.get_metrics(pfont, i, wmode, sbw));
466         /* the temporary assignment to a float is necessary for AIX else the result is always 0 if sbw[] < 0
467            this happens even with gcc and I'm not sure why it happens at all nor why only on AIX */
468         f = (float) (sbw[wmode + 2] * factor); /* width */
469         put_short(s, (short) floor(f + 0.5));
470         f = (float) (sbw[wmode] * factor); /* lsb, may be <0 */
471         put_short(s, (short) floor(f + 0.5));
472     }
473     for (; len < pmtx->length; ++i, len += 2) {
474         float f;
475         DISCARD(pfont->data.get_metrics(pfont, i, wmode, sbw));
476         f = (float) (sbw[wmode] * factor); /* lsb, may be <0 */
477         put_short(s, (short) floor(f + 0.5));
478     }
479 }
480 
481 /* Compute the metrics from the glyph_info. */
482 static uint
size_mtx(gs_font_type42 * pfont,gs_type42_mtx_t * pmtx,uint max_glyph,int wmode)483 size_mtx(gs_font_type42 *pfont, gs_type42_mtx_t *pmtx, uint max_glyph,
484          int wmode)
485 {
486     int prev_width = min_int;
487     uint last_width = 0; /* pacify compilers */
488     double factor = pfont->data.unitsPerEm * (wmode ? -1 : 1);
489     uint i;
490 
491     for (i = 0; i <= max_glyph; ++i) {
492         float sbw[4];
493         int code = pfont->data.get_metrics(pfont, i, wmode, sbw);
494         int width;
495 
496         if (code < 0)
497             continue;
498         width = (int)(sbw[wmode + 2] * factor + 0.5);
499         if (width != prev_width)
500             prev_width = width, last_width = i;
501     }
502     pmtx->numMetrics = last_width + 1;
503     pmtx->length = pmtx->numMetrics * 4 + (max_glyph - last_width) * 2;
504     return pmtx->length;
505 }
506 
507 /* ------ name ------ */
508 
509 /* Write a generated name table. */
510 static const byte name_initial[] = {
511     0, 0,			/* format */
512     0, 1,			/* # of records = 1 */
513     0, 18,			/* start of string storage */
514 
515     0, 2,			/* platform ID = ISO */
516     0, 2,			/* encoding ID = ISO 8859-1 */
517     0, 0,			/* language ID (none) */
518     0, 6,			/* name ID = PostScript name */
519     0, 0,			/* length *VARIABLE* */
520     0, 0			/* start of string within string storage */
521 };
522 static uint
size_name(const gs_const_string * font_name)523 size_name(const gs_const_string *font_name)
524 {
525     return sizeof(name_initial) + font_name->size;
526 }
527 static void
write_name(stream * s,const gs_const_string * font_name)528 write_name(stream *s, const gs_const_string *font_name)
529 {
530     byte name_bytes[sizeof(name_initial)];
531 
532     memcpy(name_bytes, name_initial, sizeof(name_initial));
533     put_u16(name_bytes + 14, font_name->size);
534     stream_write(s, name_bytes, sizeof(name_bytes));
535     stream_write(s, font_name->data, font_name->size);
536     put_pad(s, size_name(font_name));
537 }
538 
539 /* ------ OS/2 ------ */
540 
541 /* Write a generated OS/2 table. */
542 #define OS_2_LENGTH1 offset_of(ttf_OS_2_t, sxHeight[0]) /* OS/2 version 1. */
543 #define OS_2_LENGTH2 sizeof(ttf_OS_2_t) /* OS/2 version 2. */
544 static void
update_OS_2(ttf_OS_2_t * pos2,uint first_glyph,int num_glyphs)545 update_OS_2(ttf_OS_2_t *pos2, uint first_glyph, int num_glyphs)
546 {
547     put_u16(pos2->usFirstCharIndex, first_glyph);
548     put_u16(pos2->usLastCharIndex, first_glyph + num_glyphs - 1);
549 #if TT_ADJUST_OS_2
550     if (first_glyph >= 0xf000) {
551         /* This font is being treated as a symbolic font. */
552         memset(pos2->ulUnicodeRanges, 0, sizeof(pos2->ulUnicodeRanges));
553         pos2->ulUnicodeRanges[7] = 8; /* bit 60, private use range */
554         memset(pos2->ulCodePageRanges, 0, sizeof(pos2->ulCodePageRanges));
555         pos2->ulCodePageRanges[3] = 1; /* bit 31, symbolic */
556     }
557 #endif
558 }
559 static void
write_OS_2(stream * s,gs_font * font,uint first_glyph,int num_glyphs)560 write_OS_2(stream *s, gs_font *font, uint first_glyph, int num_glyphs)
561 {
562     ttf_OS_2_t os2;
563     gs_font_info_t info;
564     int code;
565 
566     /*
567      * We don't bother to set most of the fields.  The really important
568      * ones, which affect character mapping, are usFirst/LastCharIndex.
569      * We also need to set usWeightClass and usWidthClass to avoid
570      * crashing ttfdump. Version 1 86-byte structure has all the fields
571      * we need.
572      */
573     memset(&os2, 0, sizeof(os2));
574     put_u16(os2.version, 1);
575     put_u16(os2.usWeightClass, 400); /* Normal */
576     put_u16(os2.usWidthClass, 5); /* Normal */
577     update_OS_2(&os2, first_glyph, num_glyphs);
578 
579     /*
580      * We should also preserve the licensed embedding rights, to prevent
581      * 'laundering' a TrueType font. These can be non-zero even when embedding is permitted.
582      */
583     memset(&info, 0x00, sizeof(gs_font_info_t));
584     code = font->procs.font_info(font, NULL, FONT_INFO_EMBEDDING_RIGHTS, &info);
585     if (code == 0 && (info.members & FONT_INFO_EMBEDDING_RIGHTS)) {
586         put_u16(os2.fsType, info.EmbeddingRights);
587     }
588 
589     stream_write(s, &os2, offset_of(ttf_OS_2_t, sxHeight[0]));
590     put_pad(s, offset_of(ttf_OS_2_t, sxHeight[0]));
591 }
592 
593 /* ------ post ------ */
594 
595 /* Construct and then write the post table. */
596 typedef struct post_glyph_s {
597     byte char_index;
598     byte size;
599     ushort glyph_index;
600 } post_glyph_t;
601 static int
compare_post_glyphs(const void * pg1,const void * pg2)602 compare_post_glyphs(const void *pg1, const void *pg2)
603 {
604     gs_glyph g1 = ((const post_glyph_t *)pg1)->glyph_index,
605         g2 = ((const post_glyph_t *)pg2)->glyph_index;
606 
607     return (g1 < g2 ? -1 : g1 > g2 ? 1 : 0);
608 }
609 typedef struct post_s {
610     post_glyph_t glyphs[256 + 1];
611     int count, glyph_count;
612     uint length;
613 } post_t;
614 
615 /*
616  * If necessary, compute the length of the post table.  Note that we
617  * only generate post entries for characters in the Encoding.
618  */
619 static int
compute_post(gs_font * font,post_t * post)620 compute_post(gs_font *font, post_t *post)
621 {
622     int i;
623 
624     for (i = 0, post->length = 32 + 2; i <= 255; ++i) {
625         gs_const_string str;
626         gs_glyph glyph = font->procs.encode_char(font, (gs_char)i,
627                                                  GLYPH_SPACE_INDEX);
628         int mac_index;
629 
630         int code = mac_glyph_index(font, i, &str, &mac_index);
631         if (code < 0)
632             return code;
633         if (mac_index != 0) {
634             post->glyphs[post->count].char_index = i;
635             post->glyphs[post->count].size =
636                 (mac_index < 0 ? str.size + 1 : 0);
637             post->glyphs[post->count].glyph_index = glyph - GS_MIN_GLYPH_INDEX;
638             post->count++;
639         }
640     }
641     if (post->count) {
642         int j;
643 
644         qsort(post->glyphs, post->count, sizeof(post->glyphs[0]),
645               compare_post_glyphs);
646         /* Eliminate duplicate references to the same glyph. */
647         for (i = j = 0; i < post->count; ++i) {
648             if (i == 0 ||
649                 post->glyphs[i].glyph_index !=
650                 post->glyphs[i - 1].glyph_index
651                 ) {
652                 post->length += post->glyphs[i].size;
653                 post->glyphs[j++] = post->glyphs[i];
654             }
655         }
656         post->count = j;
657         post->glyph_count = post->glyphs[post->count - 1].glyph_index + 1;
658     }
659     post->length += post->glyph_count * 2;
660     return 0;
661 }
662 
663 /* Write the post table */
664 static int
write_post(stream * s,gs_font * font,post_t * post)665 write_post(stream *s, gs_font *font, post_t *post)
666 {
667     byte post_initial[32 + 2];
668     uint name_index;
669     uint glyph_index;
670     int i;
671 
672     memset(post_initial, 0, 32);
673     put_u32(post_initial, 0x00020000);
674     put_u16(post_initial + 32, post->glyph_count);
675     stream_write(s, post_initial, sizeof(post_initial));
676 
677     /* Write the name index table. */
678 
679     for (i = 0, name_index = 258, glyph_index = 0; i < post->count; ++i) {
680         gs_const_string str;
681         int ch = post->glyphs[i].char_index;
682         int mac_index;
683         int code = mac_glyph_index(font, ch, &str, &mac_index);
684 
685         if (code < 0)
686             return code;
687         for (; glyph_index < post->glyphs[i].glyph_index; ++glyph_index)
688             put_ushort(s, 0);
689         glyph_index++;
690         if (mac_index >= 0)
691             put_ushort(s, mac_index);
692         else {
693             put_ushort(s, name_index);
694             name_index++;
695         }
696     }
697 
698     /* Write the string names of the glyphs. */
699 
700     for (i = 0; i < post->count; ++i) {
701         gs_const_string str;
702         int ch = post->glyphs[i].char_index;
703         int mac_index;
704         int code = mac_glyph_index(font, ch, &str, &mac_index);
705 
706         if (code < 0)
707             return code;
708         if (mac_index < 0) {
709             spputc(s, (byte)str.size);
710             stream_write(s, str.data, str.size);
711         }
712     }
713     put_pad(s, post->length);
714     return 0;
715 }
716 
check_position(const gs_memory_t * mem,int pos1,int pos2)717 static inline bool check_position(const gs_memory_t *mem, int pos1, int pos2)
718 {
719     if (pos1 == pos2)
720         return false;
721     emprintf2(mem,
722               "Actual TT subtable offset %d differs from one in the TT header %d.\n",
723               pos1,
724               pos2);
725     return true;
726 }
727 
remove_table(byte * tables,char * tag,uint * numTables)728 static void remove_table(byte *tables, char *tag, uint *numTables)
729 {
730     /* Not a high performance implementation because it is called seldom. */
731     int i;
732 
733     for (i = 0; i < *numTables;) {
734         byte *tab = tables + i * 16;
735 
736         if (!memcmp(tab, tag, 4)) {
737             memmove(tab, tab + 16, 16 * (*numTables - i - 1));
738             --*numTables;
739         } else
740             ++i;
741     }
742 }
743 
744 /* ---------------- Main program ---------------- */
745 
746 /* Write the definition of a TrueType font. */
747 static int
compare_table_tags(const void * pt1,const void * pt2)748 compare_table_tags(const void *pt1, const void *pt2)
749 {
750     ulong t1 = u32(pt1), t2 = u32(pt2);
751 
752     return (t1 < t2 ? -1 : t1 > t2 ? 1 : 0);
753 }
754 static int
psf_write_truetype_data(stream * s,gs_font_type42 * pfont,int options,psf_glyph_enum_t * penum,bool is_subset,const gs_const_string * alt_font_name)755 psf_write_truetype_data(stream *s, gs_font_type42 *pfont, int options,
756                         psf_glyph_enum_t *penum, bool is_subset,
757                         const gs_const_string *alt_font_name)
758 {
759     gs_font *const font = (gs_font *)pfont;
760     gs_const_string font_name;
761     byte OffsetTable[12];
762     uint numTables_stored, numTables, numTables_out;
763     byte tables[MAX_NUM_TT_TABLES * 16];
764     uint i;
765     ulong offset;
766     gs_glyph glyph, glyph_prev;
767     ulong max_glyph;
768     uint glyf_length, loca_length;
769     ulong glyf_checksum = 0L; /****** NO CHECKSUM ******/
770     ulong loca_checksum[2] = {0L,0L};
771     ulong glyf_alignment = 0;
772     uint numGlyphs = 0;		/* original value from maxp */
773     byte head[56];		/* 0 mod 4 */
774     gs_type42_mtx_t mtx[2];
775     post_t post;
776     ulong head_checksum, file_checksum = 0;
777     int indexToLocFormat = 0;
778     bool
779         writing_cid = (options & WRITE_TRUETYPE_CID) != 0,
780         writing_stripped = (options & WRITE_TRUETYPE_STRIPPED) != 0,
781         generate_mtx = (options & WRITE_TRUETYPE_HVMTX) != 0,
782         no_generate = writing_cid | writing_stripped,
783         have_cmap = no_generate,
784         have_name = !(options & WRITE_TRUETYPE_NAME),
785         have_OS_2 = no_generate,
786         have_post = no_generate;
787     int have_hvhea[2];
788     uint cmap_length = 0;
789     ulong OS_2_start = 0;
790     uint OS_2_length = OS_2_LENGTH1;
791     ulong maxp_start = 0;
792     uint maxp_length = 0;
793     struct { int glyf, loca, cmap, name, os_2, mtx[2], post, head;
794            } subtable_positions;
795     int start_position = stell(s);
796     int enlarged_numGlyphs = 0;
797     int code;
798     int TTCFontOffset = 0;
799 
800     memset(&subtable_positions, 0, sizeof(subtable_positions));
801     have_hvhea[0] = have_hvhea[1] = 0;
802     if (alt_font_name)
803         font_name = *alt_font_name;
804     else
805         font_name.data = font->font_name.chars,
806             font_name.size = font->font_name.size;
807 
808     /*
809      * Count the number of tables, including the eventual glyf and loca
810      * (which may not actually be present in the font), and copy the
811      * table directory.
812      */
813 
814 #define W(a,b,c,d)\
815   ( ((a) << 24) + ((b) << 16) + ((c) << 8) + (d))
816 
817     READ_SFNTS(pfont, 0, 12, OffsetTable);
818     if (u32(OffsetTable) == W('t','t','c','f')) {
819         READ_SFNTS(pfont, 12, 4, OffsetTable);
820         TTCFontOffset = u32(OffsetTable);
821         READ_SFNTS(pfont, TTCFontOffset, 12, OffsetTable);
822     }
823     numTables_stored = U16(OffsetTable + 4);
824     for (i = numTables = 0; i < numTables_stored; ++i) {
825         byte tab[16];
826         byte data[54];
827         ulong start;
828         uint length;
829 
830         if (numTables == MAX_NUM_TT_TABLES)
831             return_error(gs_error_limitcheck);
832         READ_SFNTS(pfont, TTCFontOffset + 12 + i * 16, 16, tab);
833         start = u32(tab + 8);
834         length = u32(tab + 12);
835         /* Copy the table data now (a rudiment of old code). */
836         memcpy(&tables[numTables * 16], tab, 16);
837 
838         switch (u32(tab)) {
839         case W('h','e','a','d'):
840             if (length < 54)
841                 return_error(gs_error_invalidfont);
842             length = 54; /* bug 688409 fig2.eps has length=56. */
843             READ_SFNTS(pfont, start, length, data);
844             memcpy(head, data, length);
845             continue;
846         case W('g','l','y','f'): /* synthesized */
847         case W('g','l','y','x'): /* Adobe bogus */
848         case W('l','o','c','a'): /* synthesized */
849         case W('l','o','c','x'): /* Adobe bogus */
850         case W('g','d','i','r'): /* Adobe marker */
851             continue;
852         case W('c','m','a','p'):
853             if (options & (WRITE_TRUETYPE_CMAP | WRITE_TRUETYPE_CID))
854                 continue;
855             have_cmap = true;
856             break;
857         case W('m','a','x','p'):
858             READ_SFNTS(pfont, start, length, data);
859             numGlyphs = U16(data + 4);
860             maxp_start = start;
861             maxp_length = length;
862             break;
863         case W('n','a','m','e'):
864             if (writing_cid)
865                 continue;
866             have_name = true;
867             break;
868         case W('O','S','/','2'):
869             if (writing_cid)
870                 continue;
871             have_OS_2 = true;
872             if (length > OS_2_LENGTH2)
873                 return_error(gs_error_invalidfont);
874             OS_2_start = start;
875             OS_2_length = length;
876             continue;
877         case W('p','o','s','t'):
878             have_post = true;
879             break;
880         case W('h','h','e','a'):
881             have_hvhea[0] = 1;
882             break;
883         case W('v','h','e','a'):
884             have_hvhea[1] = 1;
885             break;
886         case W('h','m','t','x'):
887         case W('v','m','t','x'):
888             if (generate_mtx)
889                 continue;
890             /* falls through */
891         case W('c','v','t',' '):
892         case W('f','p','g','m'):
893         case W('g','a','s','p'):
894         case W('k','e','r','n'):
895         case W('p','r','e','p'):
896             break;		/* always copy these if present */
897         case W('E','B','D','T'):
898         case W('E','B','L','C'):
899         case W('E','B','S','C'):
900             continue;
901         default:
902             if (writing_cid)
903                 continue;
904             break;
905         }
906         numTables++;
907     }
908 
909     /*
910      * Enumerate the glyphs to get the size of glyf and loca,
911      * and to compute the checksums for these tables.
912      */
913 
914     /****** NO CHECKSUMS YET ******/
915     for (max_glyph = 0, glyf_length = 0;
916          (code = psf_enumerate_glyphs_next(penum, &glyph)) != 1;
917          ) {
918         uint glyph_index;
919         gs_glyph_data_t glyph_data;
920 
921         if (glyph < gs_min_cid_glyph)
922             return_error(gs_error_invalidfont);
923         glyph_index = glyph  & ~GS_GLYPH_TAG;
924         if_debug1('L', "[L]glyph_index %u\n", glyph_index);
925         glyph_data.memory = pfont->memory;
926         if ((code = pfont->data.get_outline(pfont, glyph_index, &glyph_data)) >= 0) {
927             /* Since indexToLocFormat==0 assumes even glyph lengths,
928                round it up here. If later we choose indexToLocFormat==1,
929                subtract the glyf_alignment to compensate it. */
930             uint l = (glyph_data.bits.size + 1) & ~1;
931 
932             max_glyph = max(max_glyph, glyph_index);
933             glyf_length += l;
934             if (l != glyph_data.bits.size)
935                 glyf_alignment++;
936             if_debug1('L', "[L]  size %u\n", glyph_data.bits.size);
937             gs_glyph_data_free(&glyph_data, "psf_write_truetype_data");
938         }
939     }
940     if (writing_stripped) {
941         glyf_length = 0;
942         loca_length = 0;
943     } else {
944         if (max_glyph + 1 > numGlyphs) {
945             /* Either original font is wrong,
946                or we added glyphs to it due to font merge.
947                Need to adjust maxp, hmtx, vmtx, vdmx, hdmx,
948                assuming that the merge doesn't change hhea
949                and other tables.
950                Since changing hdmx, vdmx is too difficult,
951                and since they're not required for PDF,
952                we'll simply skip them.
953              */
954             enlarged_numGlyphs = max_glyph + 1;
955             if (enlarged_numGlyphs > 0xFFFF) {
956                 emprintf1(pfont->memory,
957                           "The number of glyphs %d exceeds capability of True Type format.\n",
958                           enlarged_numGlyphs);
959                 return_error(gs_error_unregistered);
960             }
961             loca_length = (enlarged_numGlyphs + 1) << 2;
962             remove_table(tables, (char *)"hdmx", &numTables);
963             remove_table(tables, (char *)"vdmx", &numTables);
964         } else
965             loca_length = (numGlyphs + 1) << 2;
966         indexToLocFormat = (glyf_length > 0x1fffc);
967         if (!indexToLocFormat)
968             loca_length >>= 1;
969         else
970             glyf_length -= glyf_alignment;
971         /* Acrobat Reader won't accept fonts with empty glyfs. */
972         if (glyf_length == 0)
973             glyf_length = 1;
974     }
975     if_debug2('l', "[l]max_glyph = %lu, glyf_length = %lu\n",
976               (ulong)max_glyph, (ulong)glyf_length);
977 
978     /*
979      * If necessary, compute the length of the post table.  Note that we
980      * only generate post entries for characters in the Encoding.  */
981 
982     if (!have_post) {
983         memset(&post, 0, sizeof(post));
984         if (options & WRITE_TRUETYPE_POST) {
985             code = compute_post(font, &post);
986             if (code < 0)
987                 return code;
988         } else
989             post.length = 32;	/* dummy table */
990     }
991 
992     /* Fix up the head table. */
993 
994     memset(head + 8, 0, 4);
995     head[51] = (byte)indexToLocFormat;
996     memset(head + 54, 0, 2);
997     for (head_checksum = 0, i = 0; i < 56; i += 4)
998         head_checksum += u32(&head[i]);
999 
1000     /*
1001      * Construct the table directory, except for glyf, loca, head, OS/2,
1002      * and, if necessary, generated cmap, name, and post tables.
1003      * Note that the existing directory is already sorted by tag.
1004      */
1005 
1006     numTables_out = numTables + 1 /* head */
1007         + !writing_stripped * 2	/* glyf, loca */
1008         + generate_mtx * (have_hvhea[0] + have_hvhea[1]) /* hmtx, vmtx */
1009         + !have_OS_2		/* OS/2 */
1010         + !have_cmap + !have_name + !have_post;
1011     if (numTables_out >= MAX_NUM_TT_TABLES)
1012         return_error(gs_error_limitcheck);
1013     offset = 12 + numTables_out * 16;
1014     for (i = 0; i < numTables; ++i) {
1015         byte *tab = &tables[i * 16];
1016         ulong length = u32(tab + 12);
1017 
1018         offset += round_up(length, 4);
1019     }
1020 
1021     /* Make the table directory entries for generated tables. */
1022 
1023     {
1024         byte *tab = &tables[numTables * 16];
1025 
1026         if (!writing_stripped) {
1027             subtable_positions.glyf = offset;
1028             offset = put_table(tab, "glyf", glyf_checksum,
1029                                offset, glyf_length);
1030             tab += 16;
1031             subtable_positions.loca = offset;
1032             offset = put_table(tab, "loca", loca_checksum[indexToLocFormat],
1033                                offset, loca_length);
1034             tab += 16;
1035         }
1036 
1037         if (!have_cmap) {
1038             cmap_length = size_cmap(font, TT_BIAS, 256,
1039                                     GS_MIN_GLYPH_INDEX + max_glyph, options);
1040             subtable_positions.cmap = offset;
1041             offset = put_table(tab, "cmap", 0L /****** NO CHECKSUM ******/,
1042                                offset, cmap_length);
1043             tab += 16;
1044         }
1045 
1046         if (!have_name) {
1047             subtable_positions.name = offset;
1048             offset = put_table(tab, "name", 0L /****** NO CHECKSUM ******/,
1049                                offset, size_name(&font_name));
1050             tab += 16;
1051         }
1052 
1053         if (!no_generate) {
1054             subtable_positions.os_2 = offset;
1055             offset = put_table(tab, "OS/2", 0L /****** NO CHECKSUM ******/,
1056                                offset, OS_2_length);
1057             tab += 16;
1058         }
1059 
1060         if (generate_mtx)
1061             for (i = 0; i < 2; ++i)
1062                 if (have_hvhea[i]) {
1063                     subtable_positions.mtx[i] = offset;
1064                     offset = put_table(tab, (i ? "vmtx" : "hmtx"),
1065                                        0L /****** NO CHECKSUM ******/,
1066                                        offset,
1067                                        size_mtx(pfont, &mtx[i], max_glyph, i));
1068                     tab += 16;
1069                 }
1070 
1071         if (!have_post) {
1072             subtable_positions.post = offset;
1073             offset = put_table(tab, "post", 0L /****** NO CHECKSUM ******/,
1074                                offset, post.length);
1075             tab += 16;
1076         }
1077 
1078         /*
1079          * Note that the 'head' table must have length 54, even though
1080          * it occupies 56 bytes on the file.
1081          */
1082         subtable_positions.head = offset;
1083         offset = put_table(tab, "head", head_checksum, offset, 54);
1084         tab += 16;
1085     }
1086     numTables = numTables_out;
1087 
1088     /* Write the font header. */
1089 
1090     {
1091         static const byte version[4] = {0, 1, 0, 0};
1092 
1093         stream_write(s, version, 4);
1094     }
1095     put_ushort(s, numTables);
1096     for (i = 0; 1 << i <= numTables; ++i)
1097         DO_NOTHING;
1098     --i;
1099     put_ushort(s, 16 << i);	/* searchRange */
1100     put_ushort(s, i);		/* entrySelectors */
1101     put_ushort(s, numTables * 16 - (16 << i)); /* rangeShift */
1102 
1103     /* Write the table directory. */
1104 
1105     qsort(tables, numTables, 16, compare_table_tags);
1106     offset = 12 + numTables * 16;
1107     for (i = 0; i < numTables; ++i) {
1108         const byte *tab = &tables[i * 16];
1109         byte entry[16];
1110 
1111         memcpy(entry, tab, 16);
1112         if (entry[8] < 0x40) {
1113             /* Not a generated table. */
1114             uint length = u32(tab + 12);
1115 
1116             put_u32(entry + 8, offset);
1117             offset += round_up(length, 4);
1118         } else {
1119             entry[8] -= 0x40;
1120         }
1121         stream_write(s, entry, 16);
1122     }
1123 
1124     /* Write tables other than the ones we generate here. */
1125 
1126     for (i = 0; i < numTables; ++i) {
1127         const byte *tab = &tables[i * 16];
1128 
1129         if (tab[8] < 0x40) {
1130             ulong start = u32(tab + 8);
1131             uint length = u32(tab + 12);
1132 
1133             switch (u32(tab)) {
1134             case W('O','S','/','2'):
1135                 if (!have_cmap) {
1136                     /*
1137                      * Adjust the first and last character indices in the OS/2
1138                      * table to reflect the values in the generated cmap.
1139                      */
1140                     byte pos2[OS_2_LENGTH2];
1141                     ttf_OS_2_t os2;
1142 
1143                     READ_SFNTS(pfont, OS_2_start, OS_2_length, pos2);
1144                     memcpy(&os2, pos2, min(OS_2_length, sizeof(os2)));
1145                     update_OS_2(&os2, TT_BIAS, 256);
1146                     stream_write(s, &os2, OS_2_length);
1147                     put_pad(s, OS_2_length);
1148                 } else {
1149                     /* Just copy the existing OS/2 table. */
1150                     write_range(s, pfont, OS_2_start, OS_2_length);
1151                     put_pad(s, OS_2_length);
1152                 }
1153             break;
1154             case W('m','a','x','p'):
1155                 if (enlarged_numGlyphs) {
1156                     /* Must keep the table size. */
1157                     byte buf[6];
1158 
1159                     READ_SFNTS(pfont, maxp_start, sizeof(buf), buf);
1160                     put_u16(buf + 4, enlarged_numGlyphs);
1161                     stream_write(s, buf, min(length, sizeof(buf)));
1162                     if (length > sizeof(buf)) /* Paranoid Safety */
1163                         write_range(s, pfont, start + sizeof(buf), length - sizeof(buf));
1164                 } else
1165                     write_range(s, pfont, start, length);
1166                 break;
1167             case W('h','h','e','a'):
1168             case W('v','h','e','a'):
1169                 if (generate_mtx) {
1170                     write_range(s, pfont, start, length - 2); /* 34 */
1171                     put_ushort(s, mtx[tab[0] == 'v'].numMetrics);
1172                     break;
1173                 }
1174                 /* falls through */
1175             default:
1176                 write_range(s, pfont, start, length);
1177             }
1178             put_pad(s, length);
1179         }
1180     }
1181 
1182     if (!writing_stripped) {
1183         int n = max(numGlyphs, enlarged_numGlyphs) + 1;
1184 
1185         /* Write glyf. */
1186 
1187         if (check_position(pfont->memory,
1188                            subtable_positions.glyf + start_position,
1189                            stell(s)))
1190             return_error(gs_error_unregistered);
1191         psf_enumerate_glyphs_reset(penum);
1192         for (offset = 0; psf_enumerate_glyphs_next(penum, &glyph) != 1; ) {
1193             gs_glyph_data_t glyph_data;
1194 
1195             glyph_data.memory = pfont->memory;
1196             if ((code = pfont->data.get_outline(pfont,
1197                                                 glyph & ~GS_GLYPH_TAG,
1198                                                 &glyph_data)) >= 0
1199                 ) {
1200                 uint l = glyph_data.bits.size, zero = 0;
1201 
1202                 if (!indexToLocFormat)
1203                     l = (l + 1) & ~1;
1204                 stream_write(s, glyph_data.bits.data, glyph_data.bits.size);
1205                 if (glyph_data.bits.size < l)
1206                     stream_write(s, &zero, 1);
1207                 offset += l;
1208                 if_debug2('L', "[L]glyf index = %u, size = %u\n",
1209                           i, glyph_data.bits.size);
1210                 gs_glyph_data_free(&glyph_data, "psf_write_truetype_data");
1211             }
1212         }
1213         if_debug1('l', "[l]glyf final offset = %lu\n", offset);
1214         /* Add a dummy byte if necessary to make glyf non-empty. */
1215         while (offset < glyf_length)
1216             stream_putc(s, 0), ++offset;
1217         put_pad(s, (uint)offset);
1218 
1219         /* Write loca. */
1220 
1221         if (check_position(pfont->memory,
1222                            subtable_positions.loca + start_position,
1223                            stell(s)))
1224             return_error(gs_error_unregistered);
1225         psf_enumerate_glyphs_reset(penum);
1226         glyph_prev = 0;
1227         for (offset = 0; psf_enumerate_glyphs_next(penum, &glyph) != 1; ) {
1228             gs_glyph_data_t glyph_data;
1229             uint glyph_index = glyph & ~GS_GLYPH_TAG;
1230 
1231             for (; glyph_prev <= glyph_index; ++glyph_prev)
1232                 put_loca(s, offset, indexToLocFormat);
1233             glyph_data.memory = pfont->memory;
1234             if ((code = pfont->data.get_outline(pfont, glyph_index,
1235                                                 &glyph_data)) >= 0
1236                 ) {
1237                 uint l = glyph_data.bits.size;
1238 
1239                 if (!indexToLocFormat)
1240                     l = (l + 1) & ~1;
1241                 offset += l;
1242                 gs_glyph_data_free(&glyph_data, "psf_write_truetype_data");
1243             }
1244 
1245         }
1246         /* Pad to numGlyphs + 1 entries (including the trailing entry). */
1247         for (; glyph_prev < n; ++glyph_prev)
1248             put_loca(s, offset, indexToLocFormat);
1249         put_pad(s, loca_length);
1250 
1251         /* If necessary, write cmap, name, and OS/2. */
1252 
1253         if (!have_cmap) {
1254             if (check_position(pfont->memory,
1255                                subtable_positions.cmap + start_position,
1256                                stell(s)))
1257                 return_error(gs_error_unregistered);
1258             write_cmap(s, font, TT_BIAS, 256, GS_MIN_GLYPH_INDEX + max_glyph,
1259                        options, cmap_length);
1260         }
1261         if (!have_name) {
1262             if (check_position(pfont->memory,
1263                                subtable_positions.name + start_position,
1264                                stell(s)))
1265                 return_error(gs_error_unregistered);
1266             write_name(s, &font_name);
1267         }
1268         if (!have_OS_2) {
1269             if (check_position(pfont->memory,
1270                                subtable_positions.os_2 + start_position,
1271                                stell(s)))
1272                 return_error(gs_error_unregistered);
1273             write_OS_2(s, font, TT_BIAS, 256);
1274         }
1275 
1276         /* If necessary, write [hv]mtx. */
1277 
1278         if (generate_mtx)
1279             for (i = 0; i < 2; ++i)
1280                 if (have_hvhea[i]) {
1281                     if (check_position(pfont->memory,
1282                                        subtable_positions.mtx[i] + start_position,
1283                                        stell(s)))
1284                         return_error(gs_error_unregistered);
1285                     write_mtx(s, pfont, &mtx[i], i);
1286                     put_pad(s, mtx[i].length);
1287                 }
1288 
1289         /* If necessary, write post. */
1290 
1291         if (!have_post) {
1292             if (check_position(pfont->memory,
1293                                subtable_positions.post + start_position,
1294                                stell(s)))
1295                 return_error(gs_error_unregistered);
1296             if (options & WRITE_TRUETYPE_POST) {
1297                 code = write_post(s, font, &post);
1298                 if (code < 0)
1299                     return code;
1300             } else {
1301                 byte post_initial[32 + 2];
1302 
1303                 memset(post_initial, 0, 32);
1304                 put_u32(post_initial, 0x00030000);
1305                 stream_write(s, post_initial, 32);
1306             }
1307         }
1308     }
1309 
1310     /* Write head. */
1311 
1312     /****** CHECKSUM WAS NEVER COMPUTED ******/
1313     /*
1314      * The following nonsense is to avoid warnings about the constant
1315      * 0xb1b0afbaL being "unsigned in ANSI C, signed with -traditional".
1316      */
1317 #if ARCH_SIZEOF_LONG > ARCH_SIZEOF_INT
1318 #  define HEAD_MAGIC 0xb1b0afbaL
1319 #else
1320 #  define HEAD_MAGIC ((ulong)~0x4e4f5045)
1321 #endif
1322     put_u32(head + 8, HEAD_MAGIC - file_checksum); /* per spec */
1323 #undef HEAD_MAGIC
1324     if (check_position(pfont->memory,
1325                        subtable_positions.head + start_position,
1326                        stell(s)))
1327         return_error(gs_error_unregistered);
1328     stream_write(s, head, 56);
1329 
1330     return 0;
1331 }
1332 
1333 /* Write a TrueType font. */
1334 int
psf_write_truetype_font(stream * s,gs_font_type42 * pfont,int options,gs_glyph * orig_subset_glyphs,uint orig_subset_size,const gs_const_string * alt_font_name)1335 psf_write_truetype_font(stream *s, gs_font_type42 *pfont, int options,
1336                         gs_glyph *orig_subset_glyphs, uint orig_subset_size,
1337                         const gs_const_string *alt_font_name)
1338 {
1339     gs_font *const font = (gs_font *)pfont;
1340     psf_glyph_enum_t genum;
1341     gs_glyph subset_data[256 * MAX_COMPOSITE_PIECES];
1342     gs_glyph *subset_glyphs = orig_subset_glyphs;
1343     uint subset_size = orig_subset_size;
1344 
1345     /* Sort the subset glyphs, if any. */
1346 
1347     if (subset_glyphs) {
1348         /* Add the component glyphs for composites. */
1349         int code;
1350 
1351         memcpy(subset_data, orig_subset_glyphs,
1352                sizeof(gs_glyph) * subset_size);
1353         subset_glyphs = subset_data;
1354         code = psf_add_subset_pieces(subset_glyphs, &subset_size,
1355                                      countof(subset_data),
1356                                      countof(subset_data),
1357                                      font);
1358         if (code < 0)
1359             return code;
1360         subset_size = psf_sort_glyphs(subset_glyphs, subset_size);
1361     }
1362     psf_enumerate_glyphs_begin(&genum, font, subset_glyphs,
1363                                (subset_glyphs ? subset_size : 0),
1364                                GLYPH_SPACE_INDEX);
1365     return psf_write_truetype_data(s, pfont, options & ~WRITE_TRUETYPE_CID,
1366                                    &genum, subset_glyphs != 0, alt_font_name);
1367 }
1368 /* Write a stripped TrueType font. */
1369 int
psf_write_truetype_stripped(stream * s,gs_font_type42 * pfont)1370 psf_write_truetype_stripped(stream *s, gs_font_type42 *pfont)
1371 {
1372     psf_glyph_enum_t genum;
1373     byte no_subset = 0;
1374 
1375     psf_enumerate_bits_begin(&genum, (gs_font *)pfont, &no_subset, 0,
1376                              GLYPH_SPACE_INDEX);
1377     return psf_write_truetype_data(s, pfont, WRITE_TRUETYPE_STRIPPED,
1378                                    &genum, true, NULL);
1379 }
1380 
1381 /* Write a CIDFontType 2 font. */
1382 int
psf_write_cid2_font(stream * s,gs_font_cid2 * pfont,int options,const byte * subset_bits,uint subset_size,const gs_const_string * alt_font_name)1383 psf_write_cid2_font(stream *s, gs_font_cid2 *pfont, int options,
1384                     const byte *subset_bits, uint subset_size,
1385                     const gs_const_string *alt_font_name)
1386 {
1387     gs_font *const font = (gs_font *)pfont;
1388     psf_glyph_enum_t genum;
1389 
1390     psf_enumerate_bits_begin(&genum, font, subset_bits,
1391                              (subset_bits ? subset_size : 0),
1392                              GLYPH_SPACE_INDEX);
1393     return psf_write_truetype_data(s, (gs_font_type42 *)font,
1394                                    options | WRITE_TRUETYPE_CID, &genum,
1395                                    subset_bits != 0, alt_font_name);
1396 }
1397 
1398 /* Write a stripped CIDFontType 2 font. */
1399 int
psf_write_cid2_stripped(stream * s,gs_font_cid2 * pfont)1400 psf_write_cid2_stripped(stream *s, gs_font_cid2 *pfont)
1401 {
1402     gs_font *const font = (gs_font *)pfont;
1403     psf_glyph_enum_t genum;
1404     byte no_subset = 0;
1405 
1406     psf_enumerate_bits_begin(&genum, font, &no_subset, 0,
1407                              GLYPH_SPACE_INDEX);
1408     return psf_write_truetype_data(s, (gs_font_type42 *)font,
1409                                    WRITE_TRUETYPE_STRIPPED |
1410                                      WRITE_TRUETYPE_CID,
1411                                    &genum, true, NULL);
1412 }
1413