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, ¶ms, 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