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