1 /* Copyright (C) 1999, 2000 artofcode LLC.  All rights reserved.
2 
3   This program is free software; you can redistribute it and/or modify it
4   under the terms of the GNU General Public License as published by the
5   Free Software Foundation; either version 2 of the License, or (at your
6   option) any later version.
7 
8   This program is distributed in the hope that it will be useful, but
9   WITHOUT ANY WARRANTY; without even the implied warranty of
10   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11   General Public License for more details.
12 
13   You should have received a copy of the GNU General Public License along
14   with this program; if not, write to the Free Software Foundation, Inc.,
15   59 Temple Place, Suite 330, Boston, MA, 02111-1307.
16 
17 */
18 
19 /*$Id: gdevpdfw.c,v 1.12.2.1.2.1 2003/01/17 00:49:01 giles Exp $ */
20 /* Font writing for pdfwrite driver. */
21 #include "memory_.h"
22 #include "string_.h"
23 #include "gx.h"
24 #include "gsalloc.h"		/* for patching font memory */
25 #include "gsbittab.h"
26 #include "gserrors.h"
27 #include "gsmatrix.h"
28 #include "gsutil.h"		/* for bytes_compare */
29 #include "gxfcid.h"
30 #include "gxfcmap.h"
31 #include "gxfont.h"
32 #include "gxfont0.h"
33 #include "gdevpdfx.h"
34 #include "gdevpdff.h"
35 #include "gdevpsf.h"
36 #include "scommon.h"
37 
38 /* Get the ID of various kinds of resources, with type checking. */
39 inline private long
pdf_font_id(const pdf_font_t * pdfont)40 pdf_font_id(const pdf_font_t *pdfont)
41 {
42     return pdf_resource_id((const pdf_resource_t *)pdfont);
43 }
44 inline private long
pdf_font_descriptor_id(const pdf_font_descriptor_t * pfd)45 pdf_font_descriptor_id(const pdf_font_descriptor_t *pfd)
46 {
47     return pdf_resource_id((const pdf_resource_t *)pfd);
48 }
49 inline private long
pdf_char_proc_id(const pdf_char_proc_t * pcp)50 pdf_char_proc_id(const pdf_char_proc_t *pcp)
51 {
52     return pdf_resource_id((const pdf_resource_t *)pcp);
53 }
54 
55 /* Write the Widths for a font. */
56 private int
pdf_write_Widths(gx_device_pdf * pdev,int first,int last,const int widths[256])57 pdf_write_Widths(gx_device_pdf *pdev, int first, int last,
58 		 const int widths[256])
59 {
60     stream *s = pdev->strm;
61     int i;
62 
63     pprintd2(s, "/FirstChar %d/LastChar %d/Widths[", first, last);
64     for (i = first; i <= last; ++i)
65 	pprintd1(s, (i & 15 ? " %d" : "\n%d"), widths[i]);
66     stream_puts(s, "]\n");
67     return 0;
68 }
69 
70 /* Write a FontBBox dictionary element. */
71 private int
pdf_write_font_bbox(gx_device_pdf * pdev,const gs_int_rect * pbox)72 pdf_write_font_bbox(gx_device_pdf *pdev, const gs_int_rect *pbox)
73 {
74     stream *s = pdev->strm;
75     /* AR 4 doesn't like fonts with empty FontBBox which
76      * happens when the font contains only space characters.
77      * Small bbox causes AR 4 to display a hairline. So we use
78      * the full BBox.
79      */
80     int x= pbox->q.x + ((pbox->p.x == pbox->q.x) ? 1000 : 0);
81     int y= pbox->q.y + ((pbox->p.y == pbox->q.y) ? 1000 : 0);
82 
83     pprintd4(s, "/FontBBox[%d %d %d %d]",
84 	     pbox->p.x, pbox->p.y, x, y);
85     return 0;
86 }
87 
88 /* Write a synthesized bitmap font resource. */
89 private int
pdf_write_synthesized_type3(gx_device_pdf * pdev,const pdf_font_t * pef)90 pdf_write_synthesized_type3(gx_device_pdf *pdev, const pdf_font_t *pef)
91 {
92     stream *s;
93     gs_int_rect bbox;
94     int widths[256];
95 
96     memset(&bbox, 0, sizeof(bbox));
97     memset(widths, 0, sizeof(widths));
98     pdf_open_separate(pdev, pdf_font_id(pef));
99     s = pdev->strm;
100     pprints1(s, "<</Type/Font/Name/%s/Subtype/Type3", pef->rname);
101     pprintld1(s, "/Encoding %ld 0 R/CharProcs", pdev->embedded_encoding_id);
102 
103     /* Write the CharProcs. */
104     {
105 	const pdf_char_proc_t *pcp;
106 	int w;
107 
108 	stream_puts(s, "<<");
109 	/* Write real characters. */
110 	for (pcp = pef->char_procs; pcp; pcp = pcp->char_next) {
111 	    bbox.p.y = min(bbox.p.y, pcp->y_offset);
112 	    bbox.q.x = max(bbox.q.x, pcp->width);
113 	    bbox.q.y = max(bbox.q.y, pcp->height + pcp->y_offset);
114 	    widths[pcp->char_code] = pcp->x_width;
115 	    pprintld2(s, "/a%ld\n%ld 0 R", (long)pcp->char_code,
116 		      pdf_char_proc_id(pcp));
117 	}
118 	/* Write space characters. */
119 	for (w = 0; w < countof(pef->spaces); ++w) {
120 	    byte ch = pef->spaces[w];
121 
122 	    if (ch) {
123 		pprintld2(s, "/a%ld\n%ld 0 R", (long)ch,
124 			  pdev->space_char_ids[w]);
125 		widths[ch] = w + X_SPACE_MIN;
126 	    }
127 	}
128 	stream_puts(s, ">>");
129     }
130 
131     pdf_write_font_bbox(pdev, &bbox);
132     stream_puts(s, "/FontMatrix[1 0 0 1 0 0]");
133     pdf_write_Widths(pdev, 0, pef->num_chars - 1, widths);
134     stream_puts(s, ">>\n");
135     pdf_end_separate(pdev);
136     return 0;
137 }
138 
139 /* Write a font descriptor. */
140 int
pdf_write_FontDescriptor(gx_device_pdf * pdev,const pdf_font_descriptor_t * pfd)141 pdf_write_FontDescriptor(gx_device_pdf *pdev, const pdf_font_descriptor_t *pfd)
142 {
143     gs_font *font = pfd->base_font;
144     bool is_subset =
145 	pdf_has_subset_prefix(pfd->FontName.chars, pfd->FontName.size);
146     long cidset_id = 0;		/* pro forma initialization */
147     stream *s;
148     int code = 0;
149 
150     /* If this is a CIDFont subset, write the CIDSet now. */
151     if (font && is_subset) {
152 	switch (pfd->values.FontType) {
153 	case ft_CID_encrypted:
154 	case ft_CID_TrueType: {
155 	    pdf_data_writer_t writer;
156 
157 	    cidset_id = pdf_begin_separate(pdev);
158 	    s = pdev->strm;
159 	    stream_puts(s, "<<");
160 	    code = pdf_begin_data(pdev, &writer);
161 	    if (code >= 0) {
162 		stream_write(writer.binary.strm, pfd->chars_used.data,
163 		       pfd->chars_used.size);
164 		code = pdf_end_data(&writer);
165 	    } else		/* code < 0 */
166 		pdf_end_separate(pdev);
167 	}
168 	default:
169 	    break;
170 	}
171     }
172     pdf_open_separate(pdev, pdf_font_descriptor_id(pfd));
173     s = pdev->strm;
174     stream_puts(s, "<</Type/FontDescriptor/FontName");
175     pdf_put_name(pdev, pfd->FontName.chars, pfd->FontName.size);
176     if (font) {		/* not a built-in font */
177 	param_printer_params_t params;
178 	printer_param_list_t rlist;
179 	gs_param_list *const plist = (gs_param_list *)&rlist;
180 
181 	pdf_write_font_bbox(pdev, &pfd->values.FontBBox);
182 	params = param_printer_params_default;
183 	code = s_init_param_printer(&rlist, &params, s);
184 	if (code >= 0) {
185 #define DESC_INT(str, memb)\
186  {str, gs_param_type_int, offset_of(pdf_font_descriptor_t, values.memb)}
187 	    static const gs_param_item_t required_items[] = {
188 		DESC_INT("Ascent", Ascent),
189 		DESC_INT("CapHeight", CapHeight),
190 		DESC_INT("Descent", Descent),
191 		DESC_INT("ItalicAngle", ItalicAngle),
192 		DESC_INT("StemV", StemV),
193 		gs_param_item_end
194 	    };
195 	    static const gs_param_item_t optional_items[] = {
196 		DESC_INT("AvgWidth", AvgWidth),
197 		DESC_INT("Leading", Leading),
198 		DESC_INT("MaxWidth", MaxWidth),
199 		DESC_INT("MissingWidth", MissingWidth),
200 		DESC_INT("StemH", StemH),
201 		DESC_INT("XHeight", XHeight),
202 		gs_param_item_end
203 	    };
204 #undef DESC_INT
205 	    int Flags = pfd->values.Flags;
206 	    pdf_font_descriptor_t defaults;
207 
208 	    /*
209 	     * Hack: make all embedded subset TrueType fonts "symbolic" to
210 	     * work around undocumented assumptions in Acrobat Reader.
211 	     */
212 	    if (pfd->values.FontType == ft_TrueType &&
213 		pdf_has_subset_prefix(pfd->FontName.chars, pfd->FontName.size))
214 		Flags = (Flags & ~(FONT_IS_ADOBE_ROMAN)) | FONT_IS_SYMBOLIC;
215 	    param_write_int(plist, "Flags", &Flags);
216 	    gs_param_write_items(plist, pfd, NULL, required_items);
217 	    memset(&defaults, 0, sizeof(defaults));
218 	    gs_param_write_items(plist, pfd, &defaults, optional_items);
219 	    s_release_param_printer(&rlist);
220 	}
221 	if (is_subset) {
222 	    switch (pfd->values.FontType) {
223 	    case ft_CID_encrypted:
224 	    case ft_CID_TrueType:
225 		pprintld1(s, "/CIDSet %ld 0 R\n", cidset_id);
226 		break;
227 	    case ft_composite:
228 		return_error(gs_error_rangecheck);
229 	    case ft_encrypted: {
230 		gs_glyph subset_glyphs[256];
231 		uint subset_size = psf_subset_glyphs(subset_glyphs, font,
232 						     pfd->chars_used.data);
233 		int i;
234 
235 		stream_puts(s, "/CharSet(");
236 		for (i = 0; i < subset_size; ++i) {
237 		    uint len;
238 		    const char *str = font->procs.callbacks.glyph_name
239 			(subset_glyphs[i], &len);
240 
241 		    /* Don't include .notdef. */
242 		    if (bytes_compare((const byte *)str, len,
243 				      (const byte *)".notdef", 7))
244 			pdf_put_name(pdev, (const byte *)str, len);
245 		}
246 		stream_puts(s, ")\n");
247 	    }
248 	    default:
249 		break;
250 	    }
251 	}
252 	if (pfd->FontFile_id) {
253 	    const char *FontFile_key;
254 
255 	    switch (pfd->values.FontType) {
256 	    case ft_TrueType:
257 	    case ft_CID_TrueType:
258 		FontFile_key = "/FontFile2";
259 		break;
260 	    default:
261 		code = gs_note_error(gs_error_rangecheck);
262 		/* falls through */
263 	    case ft_encrypted:
264 		if (pdev->CompatibilityLevel < 1.2) {
265 		    FontFile_key = "/FontFile";
266 		    break;
267 		}
268 		/* For PDF 1.2 and later, write Type 1 fonts as Type1C. */
269 	    case ft_encrypted2:
270 	    case ft_CID_encrypted:
271 		FontFile_key = "/FontFile3";
272 		break;
273 	    }
274 	    stream_puts(s, FontFile_key);
275 	    pprintld1(s, " %ld 0 R", pfd->FontFile_id);
276 	}
277     }
278     stream_puts(s, ">>\n");
279     pdf_end_separate(pdev);
280     return code;
281 }
282 
283 /* Write CIDSystemInfo for a CIDFont or CMap. */
284 private int
pdf_write_cid_system_info(gx_device_pdf * pdev,const gs_cid_system_info_t * pcidsi)285 pdf_write_cid_system_info(gx_device_pdf *pdev,
286 			  const gs_cid_system_info_t *pcidsi)
287 {
288     stream *s = pdev->strm;
289 
290     stream_puts(s, "<<\n/Registry");
291     s_write_ps_string(s, pcidsi->Registry.data, pcidsi->Registry.size,
292 		      PRINT_HEX_NOT_OK);
293     stream_puts(s, "\n/Ordering");
294     s_write_ps_string(s, pcidsi->Ordering.data, pcidsi->Ordering.size,
295 		      PRINT_HEX_NOT_OK);
296     pprintd1(s, "\n/Supplement %d\n>>\n", pcidsi->Supplement);
297     return 0;
298 }
299 int
pdf_write_CIDFont_system_info(gx_device_pdf * pdev,const gs_font * pcidfont)300 pdf_write_CIDFont_system_info(gx_device_pdf *pdev, const gs_font *pcidfont)
301 {
302     const gs_cid_system_info_t *pcidsi;
303 
304     switch (pcidfont->FontType) {
305     case ft_CID_encrypted:
306 	pcidsi = &((const gs_font_cid0 *)pcidfont)->
307 	    cidata.common.CIDSystemInfo;
308 	break;
309     case ft_CID_TrueType:
310 	pcidsi = &((const gs_font_cid2 *)pcidfont)->
311 	    cidata.common.CIDSystemInfo;
312 	break;
313     default:
314 	return_error(gs_error_rangecheck);
315     }
316     return pdf_write_cid_system_info(pdev, pcidsi);
317 }
318 int
pdf_write_CMap_system_info(gx_device_pdf * pdev,const gs_cmap_t * pcmap)319 pdf_write_CMap_system_info(gx_device_pdf *pdev, const gs_cmap_t *pcmap)
320 {
321     return pdf_write_cid_system_info(pdev, pcmap->CIDSystemInfo);
322 }
323 
324 /*
325  * Write the [D]W[2] entries for a CIDFont.  *pfont is known to be a
326  * CIDFont (type 0 or 2).
327  */
328 private int
pdf_write_CIDFont_widths(gx_device_pdf * pdev,const pdf_font_t * ppf)329 pdf_write_CIDFont_widths(gx_device_pdf *pdev, const pdf_font_t *ppf)
330 {
331     /*
332      * The values of the CIDFont width keys are as follows:
333      *   DW = w (default 0)
334      *   W = [{c [w ...] | cfirst clast w}*]
335      *   DW2 = [vy w1y] (default [880 -1000])
336      *   W2 = [{c [w1y vx vy ...] | cfirst clast w1y vx vy}*]
337      * Currently we only write DW and W.
338      */
339     stream *s = pdev->strm;
340     psf_glyph_enum_t genum;
341     gs_glyph glyph;
342     int dw = 0;
343 
344     psf_enumerate_bits_begin(&genum, NULL, ppf->widths_known,
345 			     ppf->FontDescriptor->chars_count,
346 			     GLYPH_SPACE_INDEX);
347 
348     /* Use the most common width as DW. */
349 
350     {
351         ushort counts[1500*2]; /* histogram of (-1500..1500) */
352 	int dw_count = 0, i;
353 
354 	memset(counts, 0, sizeof(counts));
355 	while (!psf_enumerate_glyphs_next(&genum, &glyph)) {
356 	    int cid = glyph - gs_min_cid_glyph;
357 	    int width = ppf->Widths[cid];
358 
359 	    counts[max(0,min(width+countof(counts)/2,countof(counts)-1))]++;
360 	}
361 	for (i = 0; i < countof(counts); i++)
362 	    if (counts[i] > dw_count)
363 		dw = i - countof(counts)/2, dw_count = counts[i];
364 	if (dw != 0)
365 	    pprintd1(s, "/DW %d\n", dw);
366     }
367 
368     /*
369      * Now write all widths different from DW.  Currently we make no
370      * attempt to optimize this: we write every width individually.
371      */
372 
373     psf_enumerate_glyphs_reset(&genum);
374     {
375 	int prev = -2;
376 
377 	while (!psf_enumerate_glyphs_next(&genum, &glyph)) {
378 	    int cid = glyph - gs_min_cid_glyph;
379 	    int width = ppf->Widths[cid];
380 
381 	    if (cid == prev + 1)
382 		pprintd1(s, "\n%d", width);
383 	    else if (width == dw)
384 		continue;
385 	    else {
386 		if (prev >= 0)
387 		    stream_puts(s, "]\n");
388 		else
389 		    stream_puts(s, "/W[");
390 		pprintd2(s, "%d[%d", cid, width);
391 	    }
392 	    prev = cid;
393 	}
394 	if (prev >= 0)
395 	    stream_puts(s, "]]");
396     }
397 
398     return 0;
399 }
400 
401 /*
402  * Write the CIDToGIDMap for a CIDFontType 2 font.  We only need to worry
403  * about mapping CIDs that have actually been used.
404  */
405 private int
pdf_write_CIDToGIDMap(gx_device_pdf * pdev,pdf_font_t * ppf,long * pcidmap_id)406 pdf_write_CIDToGIDMap(gx_device_pdf *pdev, pdf_font_t *ppf,
407 		      long *pcidmap_id)
408 {
409     stream *s = pdev->strm;
410     psf_glyph_enum_t genum;
411     gs_glyph glyph;
412 
413     psf_enumerate_bits_begin(&genum, NULL, ppf->widths_known,
414 			     ppf->FontDescriptor->chars_count,
415 			     GLYPH_SPACE_INDEX);
416 
417     /* Check for the identity map. */
418     while (!psf_enumerate_glyphs_next(&genum, &glyph)) {
419 	int cid = glyph - gs_min_cid_glyph;
420 	int gid = ppf->CIDToGIDMap[cid];
421 
422 	if (gid != cid) {
423 	    /*
424 	     * The map isn't Identity.  Assign an object ID for writing the
425 	     * map later.
426 	     */
427 	    *pcidmap_id = pdf_obj_ref(pdev);
428 	    pprintld1(s, "/CIDToGIDMap %ld 0 R\n", *pcidmap_id);
429 	    return 1;
430 	}
431     }
432     /* All CIDs and GIDs match. */
433     stream_puts(s, "/CIDToGIDMap/Identity\n");
434     *pcidmap_id = 0;
435     return 0;
436 }
437 private int
pdf_write_CIDMap(stream * s,pdf_font_t * ppf)438 pdf_write_CIDMap(stream *s, pdf_font_t *ppf)
439 {
440     psf_glyph_enum_t genum;
441     int next = 0, count = ppf->FontDescriptor->chars_count;
442     gs_glyph glyph;
443 
444     psf_enumerate_bits_begin(&genum, NULL, ppf->widths_known, count,
445 			     GLYPH_SPACE_INDEX);
446     while (!psf_enumerate_glyphs_next(&genum, &glyph)) {
447 	int cid = glyph - gs_min_cid_glyph;
448 	int gid = ppf->CIDToGIDMap[cid];
449 
450 	for (; next < cid; ++next) {
451 	    stream_putc(s, 0); stream_putc(s, 0);
452 	}
453 	stream_putc(s, (byte)(gid >> 8));
454 	stream_putc(s, (byte)gid);
455 	next = cid + 1;
456     }
457     for (; next < count; ++next) {
458 	stream_putc(s, 0); stream_putc(s, 0);
459     }
460     return 0;
461 }
462 
463 /*
464  * Write a font resource, including Widths and/or Encoding if relevant,
465  * but not the FontDescriptor or embedded font data.  Note that the
466  * font itself may not be available.
467  *
468  * If the font is a subset, we must write the Widths even if it is a
469  * built-in font.
470  */
471 private int
pdf_write_font_resource(gx_device_pdf * pdev,pdf_font_t * pef,const gs_const_string * pfname)472 pdf_write_font_resource(gx_device_pdf *pdev, pdf_font_t *pef,
473 			const gs_const_string *pfname)
474 {
475     stream *s;
476     const pdf_font_descriptor_t *pfd = pef->FontDescriptor;
477     static const char *const encoding_names[] = {
478 	KNOWN_REAL_ENCODING_NAMES
479     };
480     /* write_Widths = 0 if not writing, 1 if Widths, -1 if [D]W[2]. */
481     int write_Widths =
482 	(pef->write_Widths ||
483 	 pdf_has_subset_prefix(pfname->data, pfname->size) ? 1 : 0);
484     long cidmap_id = 0;
485     gs_const_string fname;
486     byte fnchars[MAX_PDF_FONT_NAME];
487 
488     fname = *pfname;
489     pdf_open_separate(pdev, pdf_font_id(pef));
490     s = pdev->strm;
491     switch (pef->FontType) {
492     case ft_composite: {
493 	byte *chars = pef->fname.chars;
494 	uint size = pef->fname.size;
495 
496 	stream_puts(s, "<</Type/Font/Subtype/Type0/BaseFont");
497 	if (pdf_has_subset_prefix(chars, size))
498 	    chars += SUBSET_PREFIX_SIZE, size -= SUBSET_PREFIX_SIZE;
499 	pdf_put_name(pdev, chars, size);
500 	if ((pef->sub_font_type == ft_CID_encrypted ||
501 	     pef->sub_font_type == ft_CID_TrueType) &&
502 	    pef->cmapname[0] == '/'
503 	    ) {
504 	    stream_putc(s, '-');
505 	    pdf_put_name_chars(pdev, (const byte*) (pef->cmapname + 1),
506 			       strlen(pef->cmapname + 1));
507 	}
508 	pprints1(s, (pef->cmapname[0] == '/') ? "/Encoding%s" : "/Encoding %s",
509 		 pef->cmapname);
510 	pprintld1(s, "/DescendantFonts[%ld 0 R]",
511 		pdf_resource_id((const pdf_resource_t *)pef->DescendantFont));
512 	write_Widths = 0;
513 	goto out;
514     }
515     case ft_encrypted:
516     case ft_encrypted2:
517 	/*
518 	 * Multiple Master instances must be identified as such iff they
519 	 * are not embedded.
520 	 */
521 	if (pef->is_MM_instance && !pfd->FontFile_id) {
522 	    /* Replace spaces in the name by underscores. */
523 	    uint i;
524 
525 	    stream_puts(s, "<</Subtype/MMType1");
526 	    if (fname.size > sizeof(fnchars))
527 		return_error(gs_error_rangecheck);
528 	    for (i = 0; i < fname.size; ++i)
529 		fnchars[i] = (fname.data[i] == ' ' ? '_' : fname.data[i]);
530 	    fname.data = fnchars;
531 	} else {
532 	    stream_puts(s, "<</Subtype/Type1");
533 	}
534     bfname:
535 	stream_puts(s, "/BaseFont");
536 	pdf_put_name(pdev, fname.data, fname.size);
537 	break;
538     case ft_CID_encrypted:
539 	pprintld1(s, "<</Subtype/CIDFontType0/CIDSystemInfo %ld 0 R",
540 		  pef->CIDSystemInfo_id);
541 	write_Widths = -write_Widths;
542 	goto bfname;
543     case ft_CID_TrueType:
544 	pprintld1(s, "<</Subtype/CIDFontType2/CIDSystemInfo %ld 0 R",
545 		  pef->CIDSystemInfo_id);
546 	write_Widths = -write_Widths;
547 	goto ttname;
548     case ft_TrueType:
549 	stream_puts(s, "<</Subtype/TrueType");
550     ttname:
551 	stream_puts(s, "/BaseFont");
552 	pdf_put_name(pdev, fname.data, fname.size);
553 	/****** WHAT ABOUT STYLE INFO? ******/
554 	break;
555     default:
556 	return_error(gs_error_rangecheck);
557     }
558     pprintld1(s, "/Type/Font/Name/R%ld", pdf_font_id(pef));
559     if (pef->index < 0 || pfd->base_font || pfd->FontFile_id)
560 	pprintld1(s, "/FontDescriptor %ld 0 R", pdf_font_descriptor_id(pfd));
561     switch (write_Widths) {
562     case 0:
563 	break;
564     case 1:
565 	pdf_write_Widths(pdev, pef->FirstChar, pef->LastChar, pef->Widths);
566 	break;
567     case -1:
568 	pdf_write_CIDFont_widths(pdev, pef);
569 	if (pef->FontType == ft_CID_TrueType) {
570 	    if (pef->embed != FONT_EMBED_NO)
571 	        pdf_write_CIDToGIDMap(pdev, pef, &cidmap_id);
572 	}
573 	break;
574     }
575     if (pef->Differences) {
576 	long diff_id = pdf_obj_ref(pdev);
577 	int prev = 256;
578 	int i;
579 
580 	pprintld1(s, "/Encoding %ld 0 R>>\n", diff_id);
581 	pdf_end_separate(pdev);
582 	pdf_open_separate(pdev, diff_id);
583 	s = pdev->strm;
584 	stream_puts(s, "<</Type/Encoding");
585 	if (pef->BaseEncoding != ENCODING_INDEX_UNKNOWN)
586 	    pprints1(s, "/BaseEncoding/%s", encoding_names[pef->BaseEncoding]);
587 	stream_puts(s, "/Differences[");
588 	for (i = 0; i < 256; ++i)
589 	    if (pef->Differences[i].str.data != 0) {
590 		if (i != prev + 1)
591 		    pprintd1(s, "\n%d", i);
592 		pdf_put_name(pdev, pef->Differences[i].str.data,
593 			     pef->Differences[i].str.size);
594 		prev = i;
595 	    }
596 	stream_puts(s, "]");
597     } else if (pef->BaseEncoding != ENCODING_INDEX_UNKNOWN) {
598 	pprints1(s, "/Encoding/%s", encoding_names[pef->BaseEncoding]);
599     }
600     if (cidmap_id) {
601 	pdf_data_writer_t writer;
602 
603 	stream_puts(pdev->strm, ">>\n");
604 	pdf_end_separate(pdev);
605 	pdf_open_separate(pdev, cidmap_id);
606 	stream_puts(pdev->strm, "<<");
607 	pdf_begin_data(pdev, &writer);
608 	pdf_write_CIDMap(writer.binary.strm, pef);
609 	return pdf_end_data(&writer);
610     }
611  out:
612     stream_puts(s, ">>\n");
613     return pdf_end_separate(pdev);
614 }
615 
616 /* Register a font for eventual writing (embedded or not). */
617 private GS_NOTIFY_PROC(pdf_font_notify_proc);
618 typedef struct pdf_font_notify_s {
619     gs_memory_t *memory;	/* used to allocate this object */
620     gx_device_pdf *pdev;
621     pdf_font_t *pdfont;		/* 0 if only for base_font */
622     pdf_font_descriptor_t *pfd;	/* 0 if not for base_font */
623 } pdf_font_notify_t;
624 gs_private_st_ptrs3(st_pdf_font_notify, pdf_font_notify_t, "pdf_font_notify_t",
625 		    pdf_font_notify_enum_ptrs, pdf_font_notify_reloc_ptrs,
626 		    pdev, pdfont, pfd);
627 int
pdf_register_font(gx_device_pdf * pdev,gs_font * font,pdf_font_t * ppf)628 pdf_register_font(gx_device_pdf *pdev, gs_font *font, pdf_font_t *ppf)
629 {
630     /*
631      * Note that we do this allocation in stable font->memory, not
632      * pdev->pdf_memory.
633      */
634     pdf_font_descriptor_t *pfd = ppf->FontDescriptor;
635     gs_font *base_font = (pfd ? pfd->base_font : NULL);
636     gs_memory_t *fn_memory = gs_memory_stable(font->memory);
637     pdf_font_notify_t *pfn =
638 	gs_alloc_struct(fn_memory, pdf_font_notify_t,
639 			&st_pdf_font_notify, "pdf_register_font");
640     int code;
641 
642     if (pfn == 0)
643 	return_error(gs_error_VMerror);
644     pfn->memory = fn_memory;
645     pfn->pdev = pdev;
646     pfn->pfd = pfd;
647     if (base_font == 0 || pfd->notified)
648 	pfn->pfd = 0;
649     else if (base_font != font) {
650 	/*
651 	 * We need two notifications: one for ppf->font, one for
652 	 * base_font.  Create the latter first.
653 	 */
654 	pfn->pdfont = 0;
655 	if_debug4('_', "[_]register 0x%lx: pdf_font_descriptor_t 0x%lx => 0x%lx, id %ld\n",
656 		  (ulong)pfn, (ulong)pfd, (ulong)base_font, base_font->id);
657 	code = gs_font_notify_register(base_font, pdf_font_notify_proc, pfn);
658 	if (code < 0)
659 	    return 0;
660 	pfn = gs_alloc_struct(fn_memory, pdf_font_notify_t,
661 			      &st_pdf_font_notify, "pdf_register_font");
662 	if (pfn == 0)
663 	    return_error(gs_error_VMerror);
664 	pfn->memory = fn_memory;
665 	pfn->pdev = pdev;
666 	pfn->pfd = 0;
667     }
668     if (pfd)
669 	pfd->notified = true;
670     pfn->pdfont = ppf;
671 #ifdef DEBUG
672     if_debug4('_', "[_]register 0x%lx: pdf_font_t 0x%lx => 0x%lx, id %ld\n",
673 	      (ulong)pfn, (ulong)ppf, (ulong)font, font->id);
674     if (pfn->pfd)
675 	if_debug3('_',
676 		  "                pdf_font_descriptor_t 0x%lx => 0x%lx, id %ld\n",
677 		  (ulong)pfd, (ulong)pfd->base_font, pfd->base_font->id);
678 #endif
679     ppf->font = font;
680     return gs_font_notify_register(font, pdf_font_notify_proc, pfn);
681 }
682 private int
pdf_finalize_font_descriptor(gx_device_pdf * pdev,pdf_font_descriptor_t * pfd)683 pdf_finalize_font_descriptor(gx_device_pdf *pdev, pdf_font_descriptor_t *pfd)
684 {
685     gs_font *font = pfd->base_font;
686     int code =
687 	(font ? pdf_compute_font_descriptor(pdev, pfd, font, NULL) : 0);
688 
689     if (code >= 0) {
690 	if (pfd->FontFile_id)
691 	    code = pdf_write_embedded_font(pdev, pfd);
692 	else
693 	    code = pdf_write_FontDescriptor(pdev, pfd);
694 	pfd->written = true;
695     }
696     pfd->base_font = 0;		/* clean up for GC */
697     return code;
698 }
699 private int
pdf_font_notify_proc(void * vpfn,void * event_data)700 pdf_font_notify_proc(void *vpfn /*proc_data*/, void *event_data)
701 {
702     pdf_font_notify_t *const pfn = vpfn;
703     gx_device_pdf *const pdev = pfn->pdev;
704     pdf_font_t *const ppf = pfn->pdfont;	/* may be 0 */
705     pdf_font_descriptor_t *pfd = pfn->pfd;	/* may be 0 */
706     int code = 0;
707 
708     if (event_data)
709 	return 0;		/* unknown event */
710 
711     if (ppf) {
712 	/*
713 	 * The font of this pdf_font is about to be freed.  Just clear the
714 	 * pointer.
715 	 */
716 	gs_font *const font = ppf->font;
717 
718 	if_debug4('_',
719 		  "[_]  notify 0x%lx: pdf_font_t 0x%lx => 0x%lx, id %ld\n",
720 		  (ulong)pfn, (ulong)ppf, (ulong)font, font->id);
721 	gs_font_notify_unregister(font, pdf_font_notify_proc, vpfn);
722 	ppf->font = 0;
723     }
724 
725     if (pfd) {
726 	/*
727 	 * The base_font of this FontDescriptor is about to be freed.
728 	 * Write the FontDescriptor and, if relevant, the FontFile.
729 	 */
730 	gs_font *const font = pfd->base_font;
731 
732 	if_debug4('_',
733 		  "[_]  notify 0x%lx: pdf_font_descriptor_t 0x%lx => 0x%lx, id %ld\n",
734 		  (ulong)pfn, (ulong)pfd, (ulong)font, font->id);
735 	gs_font_notify_unregister(font, pdf_font_notify_proc, vpfn);
736 	/*
737 	 * HACK: temporarily patch the font's memory to one that we know is
738 	 * available even during GC or restore.  (Eventually we need to fix
739 	 * this by prohibiting implementations of font_info and glyph_info
740 	 * from doing any allocations.)  However, don't use gs_memory_default
741 	 * directly, because some malloc/free implementations (such as the
742 	 * default one in some versions of Linux) don't recognize LIFO
743 	 * behavior and can wind up allocation huge amounts of address space.
744 	 */
745 	{
746 	    gs_memory_t *save_memory = font->memory;
747 	    gs_ref_memory_t *fmem =
748 		ialloc_alloc_state((gs_raw_memory_t *)&gs_memory_default,
749 				   5000);
750 
751 	    if (fmem == 0)
752 		return_error(gs_error_VMerror);
753 	    font->memory = (gs_memory_t *)fmem;
754 	    code = pdf_finalize_font_descriptor(pdev, pfd);
755 	    gs_memory_free_all((gs_memory_t *)fmem, FREE_ALL_EVERYTHING,
756 			       "pdf_font_notify_proc");
757 	    font->memory = save_memory;
758 	}
759     }
760     gs_free_object(pfn->memory, vpfn, "pdf_font_notify_proc");
761     return code;
762 }
763 
764 /* Write out the font resources when wrapping up the output. */
765 private void
pdf_font_unreg_proc(void * vpfn)766 pdf_font_unreg_proc(void *vpfn /*proc_data*/)
767 {
768     pdf_font_notify_t *const pfn = vpfn;
769 
770     gs_free_object(pfn->memory, vpfn, "pdf_font_unreg_proc");
771 }
772 /* Write out the font resources when wrapping up the output. */
773 int
pdf_write_font_resources(gx_device_pdf * pdev)774 pdf_write_font_resources(gx_device_pdf *pdev)
775 {
776     int j;
777 
778     /* Write the fonts and descriptors. */
779 
780     for (j = 0; j < NUM_RESOURCE_CHAINS; ++j) {
781 	pdf_font_t *ppf;
782 	pdf_font_descriptor_t *pfd;
783 
784 	for (ppf = (pdf_font_t *)pdev->resources[resourceFont].chains[j];
785 	     ppf != 0; ppf = ppf->next
786 	     ) {
787 	    if (PDF_FONT_IS_SYNTHESIZED(ppf))
788 		pdf_write_synthesized_type3(pdev, ppf);
789 	    else {
790 		gs_const_string font_name;
791 
792 		pfd = ppf->FontDescriptor;
793 		if (pfd) {
794 		    font_name.data = pfd->FontName.chars;
795 		    font_name.size = pfd->FontName.size;
796 		} else {	/* must be composite */
797 		    font_name.data = 0;
798 		    font_name.size = 0;
799 		}
800 		pdf_write_font_resource(pdev, ppf, &font_name);
801 		if (ppf->font)
802 		    gs_notify_unregister_calling(&ppf->font->notify_list,
803 						 pdf_font_notify_proc, NULL,
804 						 pdf_font_unreg_proc);
805 	    }
806 	}
807 
808 	for (ppf = (pdf_font_t *)pdev->resources[resourceCIDFont].chains[j];
809 	     ppf != 0; ppf = ppf->next
810 	     ) {
811 	    gs_const_string font_name;
812 
813 	    pfd = ppf->FontDescriptor;
814 	    font_name.data = pfd->FontName.chars;
815 	    font_name.size = pfd->FontName.size;
816 	    pdf_write_font_resource(pdev, ppf, &font_name);
817 	    if (ppf->font)
818 		gs_notify_unregister_calling(&ppf->font->notify_list,
819 					     pdf_font_notify_proc, NULL,
820 					     pdf_font_unreg_proc);
821 	}
822 
823 	for (pfd = (pdf_font_descriptor_t *)pdev->resources[resourceFontDescriptor].chains[j];
824 	     pfd != 0; pfd = pfd->next
825 	     ) {
826 	    if (!pfd->written) {
827 		pdf_finalize_font_descriptor(pdev, pfd);
828 		if (pfd->base_font)
829 		    gs_notify_unregister_calling(&pfd->base_font->notify_list,
830 						 pdf_font_notify_proc, NULL,
831 						 pdf_font_unreg_proc);
832 	    }
833 	}
834 
835     }
836 
837     /* If required, write the Encoding for Type 3 bitmap fonts. */
838 
839     if (pdev->embedded_encoding_id) {
840 	stream *s;
841 	int i;
842 
843 	pdf_open_separate(pdev, pdev->embedded_encoding_id);
844 	s = pdev->strm;
845 	/*
846 	 * Even though the PDF reference documentation says that a
847 	 * BaseEncoding key is required unless the encoding is
848 	 * "based on the base font's encoding" (and there is no base
849 	 * font in this case), Acrobat 2.1 gives an error if the
850 	 * BaseEncoding key is present.
851 	 */
852 	stream_puts(s, "<</Type/Encoding/Differences[0");
853 	for (i = 0; i <= pdev->max_embedded_code; ++i) {
854 	    if (!(i & 15))
855 		stream_puts(s, "\n");
856 	    pprintd1(s, "/a%d", i);
857 	}
858 	stream_puts(s, "\n] >>\n");
859 	pdf_end_separate(pdev);
860     }
861 
862     return 0;
863 }
864