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