1 /* Copyright (C) 2001-2012 Artifex Software, Inc.
2 All Rights Reserved.
3
4 This software is provided AS-IS with no warranty, either express or
5 implied.
6
7 This software is distributed under license and may not be copied,
8 modified or distributed except as expressly authorized under the terms
9 of the license contained in the file LICENSE in this distribution.
10
11 Refer to licensing information at http://www.artifex.com or contact
12 Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael,
13 CA 94903, U.S.A., +1(415)492-9861, for further information.
14 */
15
16
17 /* Font resource writing for pdfwrite text */
18 #include "memory_.h"
19 #include "gx.h"
20 #include "gserrors.h"
21 #include "gxfcmap.h"
22 #include "gxfont.h"
23 #include "gxfcopy.h"
24 #include "gscencs.h"
25 #include "gdevpsf.h"
26 #include "gdevpdfx.h"
27 #include "gdevpdfo.h" /* for object->written */
28 #include "gdevpdtd.h" /* for writing FontDescriptor */
29 #include "gdevpdtf.h"
30 #include "gdevpdti.h" /* for writing bitmap fonts Encoding */
31 #include "gdevpdtw.h"
32 #include "gdevpdtv.h"
33 #include "sarc4.h"
34
35 static const char *const encoding_names[] = {
36 KNOWN_REAL_ENCODING_NAMES
37 };
38
39 /* ================ Font resource writing ================ */
40
41 /* ---------------- Private ---------------- */
42
43 /* Write the Widths for a font. */
44 static int
pdf_write_Widths(gx_device_pdf * pdev,int first,int last,const double * widths)45 pdf_write_Widths(gx_device_pdf *pdev, int first, int last, const double *widths)
46 {
47 stream *s = pdev->strm;
48 int i;
49
50 if (first > last)
51 first = last = 0;
52 pprintd2(s, "/FirstChar %d/LastChar %d/Widths[", first, last);
53 for (i = first; i <= last; ++i)
54 pprintg1(s, (i & 15 ? " %g" : "\n%g"), psdf_round(widths[i], 100, 10));
55 stream_puts(s, "]\n");
56 return 0;
57 }
58
59 /* Check strings equality. */
60 static bool
strings_equal(const gs_const_string * str0,const gs_const_string * str1)61 strings_equal(const gs_const_string *str0, const gs_const_string *str1)
62 {
63 return str0->size == str1->size &&
64 !memcmp(str0->data, str1->data, str0->size);
65 }
66
67 /* Check if an encoding element differs from a standard one. */
68 static int
pdf_different_encoding_element(const pdf_font_resource_t * pdfont,int ch,int encoding_index)69 pdf_different_encoding_element(const pdf_font_resource_t *pdfont, int ch, int encoding_index)
70 {
71 if (pdfont->u.simple.Encoding[ch].is_difference)
72 return 1;
73 else if (encoding_index != ENCODING_INDEX_UNKNOWN) {
74 gs_glyph glyph0 = gs_c_known_encode(ch, encoding_index);
75 gs_glyph glyph1 = pdfont->u.simple.Encoding[ch].glyph;
76 gs_const_string str;
77 int code = gs_c_glyph_name(glyph0, &str);
78
79 if (code < 0)
80 return code; /* Must not happen */
81 if (glyph1 != GS_NO_GLYPH)
82 if (!strings_equal(&str, &pdfont->u.simple.Encoding[ch].str))
83 return 1;
84 }
85 return 0;
86 }
87
88 /* Find an index of a different encoding element. */
89 int
pdf_different_encoding_index(const pdf_font_resource_t * pdfont,int ch0)90 pdf_different_encoding_index(const pdf_font_resource_t *pdfont, int ch0)
91 {
92 gs_encoding_index_t base_encoding = pdfont->u.simple.BaseEncoding;
93 int ch, code;
94
95 for (ch = ch0; ch < 256; ++ch) {
96 code = pdf_different_encoding_element(pdfont, ch, base_encoding);
97 if (code < 0)
98 return code; /* Must not happen */
99 if (code)
100 break;
101 }
102 return ch;
103 }
104
105 /* Check for unknown encode (simple fonts only). */
106 static bool
pdf_simple_font_needs_ToUnicode(const pdf_font_resource_t * pdfont)107 pdf_simple_font_needs_ToUnicode(const pdf_font_resource_t *pdfont)
108 {
109 int ch;
110 unsigned char mask = (pdfont->FontType == ft_encrypted || pdfont->FontType == ft_encrypted2
111 ? GS_C_PDF_GOOD_GLYPH_MASK : GS_C_PDF_GOOD_NON_SYMBOL_MASK);
112
113 if (pdfont->u.simple.Encoding == NULL)
114 return true; /* Bitmap Type 3 fonts have no pdfont->u.simple.Encoding . */
115 if (pdfont->FontType == ft_TrueType)
116 /*
117 TrueType fonts are always written as symbolic, and so they do not have
118 an Encoding entry (SVN revision 11735, bugs #690744, #691036, #691319).
119 In this circumstance, write the ToUnicode map to get a searchable PDF.
120 */
121 return true;
122 for (ch = 0; ch < 256; ++ch) {
123 pdf_encoding_element_t *pet = &pdfont->u.simple.Encoding[ch];
124 gs_glyph glyph = pet->glyph;
125
126 if (glyph == GS_NO_GLYPH)
127 continue;
128 if (glyph < gs_c_min_std_encoding_glyph || glyph >= GS_MIN_CID_GLYPH) {
129 if (pet->str.size == 0)
130 return true;
131 glyph = gs_c_name_glyph(pet->str.data, pet->str.size);
132 if (glyph == GS_NO_GLYPH)
133 return true;
134 }
135 glyph -= gs_c_min_std_encoding_glyph;
136 if( glyph > GS_C_PDF_MAX_GOOD_GLYPH ||
137 !(gs_c_pdf_glyph_type[glyph >> 2] & (mask << (( glyph & 3 )<<1) )))
138 return true;
139 }
140 return false;
141 }
142
143 /* Write Encoding differencrs. */
144 int
pdf_write_encoding(gx_device_pdf * pdev,const pdf_font_resource_t * pdfont,long id,int ch)145 pdf_write_encoding(gx_device_pdf *pdev, const pdf_font_resource_t *pdfont, long id, int ch)
146 {
147 /* Note : this truncates extended glyph names to original names. */
148 stream *s;
149 gs_encoding_index_t base_encoding = pdfont->u.simple.BaseEncoding;
150 const int sl = strlen(gx_extendeg_glyph_name_separator);
151 int prev = 256, code, cnt = 0;
152
153 pdf_open_separate(pdev, id, resourceEncoding);
154 s = pdev->strm;
155 stream_puts(s, "<</Type/Encoding");
156 if (base_encoding < 0 && pdev->ForOPDFRead)
157 base_encoding = ENCODING_INDEX_STANDARD;
158 if (base_encoding > 0)
159 pprints1(s, "/BaseEncoding/%s", encoding_names[base_encoding]);
160 stream_puts(s, "/Differences[");
161 for (; ch < 256; ++ch) {
162 code = pdf_different_encoding_element(pdfont, ch, base_encoding);
163 if (code < 0)
164 return code; /* Must not happen */
165 if (code == 0 && (pdfont->FontType == ft_user_defined ||
166 pdfont->FontType == ft_PCL_user_defined ||
167 pdfont->FontType == ft_GL2_stick_user_defined)) {
168 /* PDF 1.4 spec Appendix H Note 42 says that
169 * Acrobat 4 can't properly handle Base Encoding.
170 * Enforce writing differences against that.
171 */
172 if (pdfont->used[ch >> 3] & 0x80 >> (ch & 7))
173 if (pdfont->u.simple.Encoding[ch].str.size)
174 code = 1;
175 }
176 if (code) {
177 const byte *d = pdfont->u.simple.Encoding[ch].str.data;
178 int i, l = pdfont->u.simple.Encoding[ch].str.size;
179
180 if (pdev->HavePDFWidths) {
181 for (i = 0; i + sl < l; i++)
182 if (!memcmp(d + i, gx_extendeg_glyph_name_separator, sl)) {
183 l = i;
184 break;
185 }
186 }
187 if (ch != prev + 1) {
188 pprintd1(s, "\n%d", ch);
189 cnt = 1;
190 } else if (!(cnt++ & 15))
191 stream_puts(s, "\n");
192 pdf_put_name(pdev, d, l);
193 prev = ch;
194 }
195 }
196 stream_puts(s, "]>>\n");
197 pdf_end_separate(pdev, resourceEncoding);
198 return 0;
199 }
200
201 /* Write Encoding reference. */
202 int
pdf_write_encoding_ref(gx_device_pdf * pdev,const pdf_font_resource_t * pdfont,long id)203 pdf_write_encoding_ref(gx_device_pdf *pdev,
204 const pdf_font_resource_t *pdfont, long id)
205 {
206 stream *s = pdev->strm;
207
208 if (id != 0)
209 pprintld1(s, "/Encoding %ld 0 R", id);
210 else if (pdfont->u.simple.BaseEncoding > 0) {
211 gs_encoding_index_t base_encoding = pdfont->u.simple.BaseEncoding;
212 pprints1(s, "/Encoding/%s", encoding_names[base_encoding]);
213 }
214 return 0;
215 }
216
217 /* Write the Subtype and Encoding for a simple font. */
218 static int
pdf_write_simple_contents(gx_device_pdf * pdev,const pdf_font_resource_t * pdfont)219 pdf_write_simple_contents(gx_device_pdf *pdev,
220 const pdf_font_resource_t *pdfont)
221 {
222 stream *s = pdev->strm;
223 long diff_id = 0;
224 int ch = (pdfont->u.simple.Encoding ? 0 : 256);
225 int code = 0;
226
227 ch = pdf_different_encoding_index(pdfont, ch);
228 if (ch < 256)
229 diff_id = pdf_obj_ref(pdev);
230 code = pdf_write_encoding_ref(pdev, pdfont, diff_id);
231 if (code < 0)
232 return code;
233 pprints1(s, "/Subtype/%s>>\n",
234 (pdfont->FontType == ft_TrueType ? "TrueType" :
235 pdfont->u.simple.s.type1.is_MM_instance ? "MMType1" : "Type1"));
236 pdf_end_separate(pdev, resourceFont);
237 if (diff_id) {
238 mark_font_descriptor_symbolic(pdfont);
239 code = pdf_write_encoding(pdev, pdfont, diff_id, ch);
240 if (code < 0)
241 return code;
242 }
243 return 0;
244 }
245
246 /*
247 * Write the W[2] entries for a CIDFont. *pdfont is known to be a
248 * CIDFont (type 0 or 2).
249 */
250 static bool
pdf_compute_CIDFont_default_widths(const pdf_font_resource_t * pdfont,int wmode,int * pdw,int * pdv)251 pdf_compute_CIDFont_default_widths(const pdf_font_resource_t *pdfont, int wmode, int *pdw, int *pdv)
252 {
253 psf_glyph_enum_t genum;
254 gs_glyph glyph;
255 ushort counts[1500]; /* Some CID fonts use vertical widths 1026 .*/
256 int dw_count = 0, i, dwi = 0, neg_count = 0, pos_count = 0;
257 double *w = (wmode ? pdfont->u.cidfont.Widths2 : pdfont->Widths);
258
259 /* We don't wont to scan for both negative and positive widths,
260 * to save the C stack space.
261 * Doubtly they both are used in same font.
262 * So just count positive and negative widths separately
263 * and use the corresponding sign.
264 * fixme : implement 2 hystograms.
265 */
266 psf_enumerate_bits_begin(&genum, NULL,
267 wmode ? pdfont->u.cidfont.used2 : pdfont->used,
268 pdfont->count, GLYPH_SPACE_INDEX);
269 memset(counts, 0, sizeof(counts));
270 while (!psf_enumerate_glyphs_next(&genum, &glyph)) {
271 int i = glyph - GS_MIN_CID_GLYPH;
272
273 if ( i < pdfont->count) { /* safety */
274 int width = (int)(w[i] + 0.5);
275
276 counts[min(any_abs(width), countof(counts) - 1)]++;
277 if (width > 0)
278 pos_count++;
279 else if (width < 0)
280 neg_count++;
281 }
282 }
283 for (i = 1; i < countof(counts); ++i)
284 if (counts[i] > dw_count)
285 dwi = i, dw_count = counts[i];
286 *pdw = (neg_count > pos_count ? -dwi : dwi);
287 *pdv = 0;
288 if (wmode) {
289 psf_enumerate_glyphs_reset(&genum);
290 while (!psf_enumerate_glyphs_next(&genum, &glyph)) {
291 int i = glyph - GS_MIN_CID_GLYPH;
292
293 if ( i < pdfont->count) { /* safety */
294 int width = (int)(w[i] + 0.5);
295
296 if (min(any_abs(width), countof(counts) - 1) == any_abs(dwi)) {
297 *pdv = (int)(pdfont->u.cidfont.v[i * 2 + 1] + 0.5);
298 break;
299 }
300 }
301 }
302 }
303 return (dw_count + counts[0] > 0);
304 }
305
306 /*
307 * Write the [D]W[2] entries for a CIDFont. *pdfont is known to be a
308 * CIDFont (type 0 or 2).
309 */
310 static int
pdf_write_CIDFont_widths(gx_device_pdf * pdev,const pdf_font_resource_t * pdfont,int wmode)311 pdf_write_CIDFont_widths(gx_device_pdf *pdev,
312 const pdf_font_resource_t *pdfont, int wmode)
313 {
314 /*
315 * The values of the CIDFont width keys are as follows:
316 * DW = w (default 0)
317 * W = [{c [w ...] | cfirst clast w}*]
318 * DW2 = [vy w1y] (default [880 -1000])
319 * W2 = [{c [w1y vx vy ...] | cfirst clast w1y vx vy}*]
320 */
321 stream *s = pdev->strm;
322 psf_glyph_enum_t genum;
323 gs_glyph glyph;
324 int dw = 0, dv = 0, prev = -2;
325 const char *Widths_key = (wmode ? "/W2" : "/W");
326 double *w = (wmode ? pdfont->u.cidfont.Widths2 : pdfont->Widths);
327
328 /* Compute and write default width : */
329 if (pdf_compute_CIDFont_default_widths(pdfont, wmode, &dw, &dv)) {
330 if (wmode) {
331 pprintd2(s, "/DW2 [%d %d]\n", dv, dw);
332 } else
333 pprintd1(s, "/DW %d\n", dw);
334 }
335
336 /*
337 * Now write all widths different from the default one. Currently we make no
338 * attempt to optimize this: we write every width individually.
339 */
340 psf_enumerate_bits_begin(&genum, NULL,
341 wmode ? pdfont->u.cidfont.used2 : pdfont->used,
342 pdfont->count, GLYPH_SPACE_INDEX);
343 {
344 while (!psf_enumerate_glyphs_next(&genum, &glyph)) {
345 int cid = glyph - GS_MIN_CID_GLYPH;
346 int width = (int)(w[cid] + 0.5);
347
348 #if 0 /* Must write zero widths - see test file of the bug Bug 687681.
349 We don't enumerate unused glyphs here due to pdfont->used. */
350 if (width == 0)
351 continue; /* Don't write for unused glyphs. */
352 #else
353 { /* Check whether copied font really have this glyph.
354 debugged with 401-01.ps, which uses undefined CIDs. */
355 gs_font_base *pfont = pdf_font_resource_font(pdfont, false);
356 gs_glyph_info_t info;
357
358 if (pfont->FontType == ft_TrueType) {
359 /* We're converting a Type 42 into CIDFontType2. */
360 /* We know that CIDs equal to char codes. */
361 gs_glyph glyph1;
362 int ch = glyph & 0xff;
363
364 glyph1 = pfont->procs.encode_char((gs_font *)pfont, ch, GLYPH_SPACE_NAME);
365 if (cid == 0 && glyph1 == GS_NO_GLYPH)
366 glyph1 = copied_get_notdef((gs_font *)pdf_font_resource_font(pdfont, false));
367 if (glyph1 == GS_NO_GLYPH)
368 continue;
369 if (pfont->procs.glyph_info((gs_font *)pfont, glyph1, NULL, 0, &info) < 0)
370 continue;
371 } else if (pfont->procs.glyph_info((gs_font *)pfont, glyph, NULL, 0, &info) < 0)
372 continue;
373 }
374 #endif
375 if (cid == prev + 1) {
376 if (wmode) {
377 int vx = (int)(pdfont->u.cidfont.v[cid * 2 + 0] + 0.5);
378 int vy = (int)(pdfont->u.cidfont.v[cid * 2 + 1] + 0.5);
379
380 pprintd3(s, "\n%d %d %d", width, vx, vy);
381 } else
382 pprintd1(s, "\n%d", width);
383 } else if (pdev->PDFA == 0 && width == dw &&
384 (!wmode || (int)(pdfont->u.cidfont.v[cid * 2 + 0] + 0.5) ==
385 (int)(pdfont->Widths[cid] / 2 + 0.5)) &&
386 (!wmode || (int)(pdfont->u.cidfont.v[cid * 2 + 1] + 0.5) == dv))
387 continue;
388 else {
389 if (prev >= 0)
390 stream_puts(s, "]\n");
391 else {
392 stream_puts(s, Widths_key);
393 stream_puts(s, "[");
394 }
395 if (wmode) {
396 int vx = (int)(pdfont->u.cidfont.v[cid * 2 + 0] + 0.5);
397 int vy = (int)(pdfont->u.cidfont.v[cid * 2 + 1] + 0.5);
398
399 pprintd4(s, "%d[%d %d %d", cid, width, vx, vy);
400 } else
401 pprintd2(s, "%d[%d", cid, width);
402 }
403 prev = cid;
404 }
405 if (prev >= 0)
406 stream_puts(s, "]]\n");
407 }
408
409 return 0;
410 }
411
412 /* ---------------- Specific FontTypes ---------------- */
413
414 /* Write the contents of a Type 0 font resource. */
415 int
pdf_write_contents_type0(gx_device_pdf * pdev,pdf_font_resource_t * pdfont)416 pdf_write_contents_type0(gx_device_pdf *pdev, pdf_font_resource_t *pdfont)
417 {
418 stream *s = pdev->strm;
419
420 /*
421 * The Encoding name might be missing if an error occurred when
422 * creating the font resource.
423 */
424 if (pdfont->u.type0.Encoding_name[0])
425 pprints1(s, "/Encoding %s", pdfont->u.type0.Encoding_name);
426 pprintld1(s, "/DescendantFonts[%ld 0 R]",
427 pdf_font_id(pdfont->u.type0.DescendantFont));
428 stream_puts(s, "/Subtype/Type0>>\n");
429 pdf_end_separate(pdev, resourceFont);
430 return 0;
431 }
432
433 /*
434 * Finish writing the contents of a Type 3 font resource (FontBBox, Widths,
435 * Subtype).
436 */
437 int
pdf_finish_write_contents_type3(gx_device_pdf * pdev,pdf_font_resource_t * pdfont)438 pdf_finish_write_contents_type3(gx_device_pdf *pdev,
439 pdf_font_resource_t *pdfont)
440 {
441 stream *s = pdev->strm;
442
443 pdf_write_font_bbox_float(pdev, &pdfont->u.simple.s.type3.FontBBox);
444 pdf_write_Widths(pdev, pdfont->u.simple.FirstChar,
445 pdfont->u.simple.LastChar, pdfont->Widths);
446 stream_puts(s, "/Subtype/Type3>>\n");
447 pdf_end_separate(pdev, resourceFont);
448 return 0;
449 }
450
451 /* Write the contents of a standard (base 14) font resource. */
452 int
pdf_write_contents_std(gx_device_pdf * pdev,pdf_font_resource_t * pdfont)453 pdf_write_contents_std(gx_device_pdf *pdev, pdf_font_resource_t *pdfont)
454 {
455 return pdf_write_simple_contents(pdev, pdfont);
456 }
457
458 /* Write the contents of a simple (Type 1 or Type 42) font resource. */
459 int
pdf_write_contents_simple(gx_device_pdf * pdev,pdf_font_resource_t * pdfont)460 pdf_write_contents_simple(gx_device_pdf *pdev, pdf_font_resource_t *pdfont)
461 {
462 pdf_write_Widths(pdev, pdfont->u.simple.FirstChar,
463 pdfont->u.simple.LastChar, pdfont->Widths);
464 return pdf_write_simple_contents(pdev, pdfont);
465 }
466
467 /* Write the contents of a CIDFont resource. */
468 static int
write_contents_cid_common(gx_device_pdf * pdev,pdf_font_resource_t * pdfont,int subtype)469 write_contents_cid_common(gx_device_pdf *pdev, pdf_font_resource_t *pdfont,
470 int subtype)
471 {
472 /* Write [D]W[2], CIDSystemInfo, and Subtype, and close the object. */
473 stream *s = pdev->strm;
474 int code;
475
476 if (pdfont->Widths != 0) {
477 code = pdf_write_CIDFont_widths(pdev, pdfont, 0);
478 if (code < 0)
479 return code;
480 } else {
481 /* With a vertical font, the viewer uses /DW
482 to determine glyph width to compute its v-vector. */
483 stream_puts(s, "/DW 0\n");
484 }
485 if (pdfont->u.cidfont.Widths2 != 0) {
486 code = pdf_write_CIDFont_widths(pdev, pdfont, 1);
487 if (code < 0)
488 return code;
489 }
490 if (pdfont->u.cidfont.CIDSystemInfo_id)
491 pprintld1(s, "/CIDSystemInfo %ld 0 R",
492 pdfont->u.cidfont.CIDSystemInfo_id);
493 pprintd1(s, "/Subtype/CIDFontType%d>>\n", subtype);
494 pdf_end_separate(pdev, resourceFont);
495 return 0;
496 }
497 int
pdf_write_contents_cid0(gx_device_pdf * pdev,pdf_font_resource_t * pdfont)498 pdf_write_contents_cid0(gx_device_pdf *pdev, pdf_font_resource_t *pdfont)
499 {
500 return write_contents_cid_common(pdev, pdfont, 0);
501 }
502 int
pdf_write_contents_cid2(gx_device_pdf * pdev,pdf_font_resource_t * pdfont)503 pdf_write_contents_cid2(gx_device_pdf *pdev, pdf_font_resource_t *pdfont)
504 {
505 int count = pdfont->count;
506 long map_id = 0;
507 psf_glyph_enum_t genum;
508 gs_glyph glyph;
509 int code;
510
511 /* Check for the identity CIDMap. */
512 psf_enumerate_bits_begin(&genum, NULL, pdfont->used, count,
513 GLYPH_SPACE_INDEX);
514 while (!psf_enumerate_glyphs_next(&genum, &glyph)) {
515 int cid = glyph - GS_MIN_CID_GLYPH;
516 int gid = pdfont->u.cidfont.CIDToGIDMap[cid];
517
518 if (gid != cid) { /* non-identity map */
519 map_id = pdf_obj_ref(pdev);
520 pprintld1(pdev->strm, "/CIDToGIDMap %ld 0 R\n", map_id);
521 break;
522 }
523 }
524
525 if (map_id == 0 && pdf_font_descriptor_embedding(pdfont->FontDescriptor)) {
526 code = stream_puts(pdev->strm, "/CIDToGIDMap /Identity\n");
527 if (code < 0)
528 return code;
529 }
530
531 code = write_contents_cid_common(pdev, pdfont, 2);
532 if (code < 0)
533 return code;
534
535 if (map_id && pdf_font_descriptor_embedding(pdfont->FontDescriptor)) {
536 pdf_data_writer_t writer;
537 int i;
538
539 pdf_begin_data_stream(pdev, &writer,
540 DATA_STREAM_BINARY | (pdev->CompressFonts ? DATA_STREAM_COMPRESS : 0),
541 /* Don't set DATA_STREAM_ENCRYPT since we write to a temporary file.
542 See comment in pdf_begin_encrypt. */
543 map_id);
544 for (i = 0; i < pdfont->u.cidfont.CIDToGIDMapLength; ++i) {
545 uint gid = pdfont->u.cidfont.CIDToGIDMap[i];
546
547 stream_putc(writer.binary.strm, (byte)(gid >> 8));
548 stream_putc(writer.binary.strm, (byte)(gid));
549 }
550 code = pdf_end_data(&writer);
551 }
552 return code;
553 }
554
555 /* ---------------- External entries ---------------- */
556
557 /* Write a font resource. */
558 static int
pdf_write_font_resource(gx_device_pdf * pdev,pdf_font_resource_t * pdfont)559 pdf_write_font_resource(gx_device_pdf *pdev, pdf_font_resource_t *pdfont)
560 {
561 stream *s;
562 cos_dict_t *pcd_Resources = NULL;
563 char *base14_name = NULL;
564
565 if (pdfont->cmap_ToUnicode != NULL && pdfont->res_ToUnicode == NULL)
566 if (pdfont->FontType == ft_composite ||
567 ((pdfont->FontType == ft_encrypted || pdfont->FontType == ft_encrypted2 ||
568 pdfont->FontType == ft_TrueType || pdfont->FontType == ft_user_defined ||
569 pdfont->FontType == ft_GL2_stick_user_defined || pdfont->FontType == ft_PCL_user_defined ) &&
570 pdf_simple_font_needs_ToUnicode(pdfont))
571 ) {
572 pdf_resource_t *prcmap;
573 int code = pdf_cmap_alloc(pdev, pdfont->cmap_ToUnicode, &prcmap, -1);
574
575 if (code < 0)
576 return code;
577 pdfont->res_ToUnicode = prcmap;
578 }
579 if (pdev->CompatibilityLevel >= 1.2 &&
580 (pdfont->FontType == ft_user_defined ||
581 pdfont->FontType == ft_PCL_user_defined ||
582 pdfont->FontType == ft_GL2_stick_user_defined) &&
583 pdfont->u.simple.s.type3.Resources != NULL &&
584 pdfont->u.simple.s.type3.Resources->elements != NULL) {
585 int code;
586
587 pcd_Resources = pdfont->u.simple.s.type3.Resources;
588 pcd_Resources->id = pdf_obj_ref(pdev);
589 pdf_open_separate(pdev, pcd_Resources->id, resourceFont);
590 code = COS_WRITE(pcd_Resources, pdev);
591 if (code < 0)
592 return code;
593 pdf_end_separate(pdev, resourceFont);
594 }
595 pdf_open_separate(pdev, pdf_font_id(pdfont), resourceFont);
596 s = pdev->strm;
597 stream_puts(s, "<<");
598 if (pdfont->BaseFont.size > 0) {
599 stream_puts(s, "/BaseFont");
600 if (pdfont->FontDescriptor && !pdf_font_descriptor_embedding(pdfont->FontDescriptor)
601 && (base14_name = (char *)pdf_find_base14_name((byte *)pdfont->BaseFont.data, (unsigned int)pdfont->BaseFont.size)))
602 pdf_put_name(pdev, (byte *)base14_name, (unsigned int)strlen(base14_name));
603 else
604 pdf_put_name(pdev, (byte *)pdfont->BaseFont.data, pdfont->BaseFont.size);
605 }
606 if (pdfont->FontDescriptor)
607 pprintld1(s, "/FontDescriptor %ld 0 R",
608 pdf_font_descriptor_id(pdfont->FontDescriptor));
609 if (pdfont->res_ToUnicode)
610 pprintld1(s, "/ToUnicode %ld 0 R",
611 pdf_resource_id((const pdf_resource_t *)pdfont->res_ToUnicode));
612 if (pdev->CompatibilityLevel > 1.0)
613 stream_puts(s, "/Type/Font\n");
614 else
615 pprintld1(s, "/Type/Font/Name/R%ld\n", pdf_font_id(pdfont));
616 if (pdev->ForOPDFRead && pdfont->global)
617 stream_puts(s, "/.Global true\n");
618 if (pcd_Resources != NULL)
619 pprintld1(s, "/Resources %ld 0 R\n", pcd_Resources->id);
620 return pdfont->write_contents(pdev, pdfont);
621 }
622
623 /*
624 * Close the text-related parts of a document, including writing out font
625 * and related resources.
626 */
627 int
write_font_resources(gx_device_pdf * pdev,pdf_resource_list_t * prlist)628 write_font_resources(gx_device_pdf *pdev, pdf_resource_list_t *prlist)
629 {
630 int j;
631 pdf_resource_t *pres;
632
633 for (j = 0; j < NUM_RESOURCE_CHAINS; ++j)
634 for (pres = prlist->chains[j]; pres != 0; pres = pres->next) {
635 pdf_font_resource_t *const pdfont = (pdf_font_resource_t *)pres;
636
637 if (pdf_resource_id(pres) != -1) {
638 int code = pdf_compute_BaseFont(pdev, pdfont, true);
639
640 if (code < 0)
641 return code;
642 code = pdf_write_font_resource(pdev, pdfont);
643 if (code < 0)
644 return code;
645 pdfont->object->written = true;
646 }
647 }
648 return 0;
649 }
650 int
pdf_finish_resources(gx_device_pdf * pdev,pdf_resource_type_t type,int (* finish_proc)(gx_device_pdf *,pdf_resource_t *))651 pdf_finish_resources(gx_device_pdf *pdev, pdf_resource_type_t type,
652 int (*finish_proc)(gx_device_pdf *,
653 pdf_resource_t *))
654 {
655 int j;
656 pdf_resource_t *pres;
657
658 for (j = 0; j < NUM_RESOURCE_CHAINS; ++j)
659 for (pres = pdev->resources[type].chains[j];
660 pres != 0; pres = pres->next
661 ) {
662 int code = finish_proc(pdev, pres);
663
664 if (code < 0)
665 return code;
666 }
667 return 0;
668 }
669
670 #ifdef DEPRECATED_906
671 int
pdf_close_text_document(gx_device_pdf * pdev)672 pdf_close_text_document(gx_device_pdf *pdev)
673 {
674 int code;
675
676 /*
677 * Finish the descriptors and write any embedded fonts, but don't
678 * write the descriptors yet; then write the fonts; finally write
679 * the descriptors.
680 */
681
682 pdf_clean_standard_fonts(pdev);
683 code = pdf_free_font_cache(pdev);
684 if (code < 0)
685 return code;
686
687 code = pdf_write_resource_objects(pdev, resourceCharProc);
688 if (code < 0)
689 return code;
690
691 code = pdf_finish_resources(pdev, resourceFont, pdf_convert_truetype_font);
692 if (code < 0)
693 return code;
694
695 code = pdf_finish_resources(pdev, resourceFontDescriptor, pdf_finish_FontDescriptor);
696 if (code < 0)
697 return code;
698
699 code = write_font_resources(pdev, &pdev->resources[resourceCIDFont]);
700 if (code < 0)
701 return code;
702
703 code = write_font_resources(pdev, &pdev->resources[resourceFont]);
704 if (code < 0)
705 return code;
706
707 code = pdf_finish_resources(pdev, resourceFontDescriptor, pdf_write_FontDescriptor);
708 if (code < 0)
709 return code;
710
711 /* If required, write the Encoding for Type 3 bitmap fonts. */
712
713 return pdf_write_bitmap_fonts_Encoding(pdev);
714 }
715 #endif
716
717 /* ================ CMap resource writing ================ */
718
719 /*
720 * Write the CIDSystemInfo for a CIDFont or a CMap.
721 */
722 static int
pdf_write_cid_system_info_to_stream(gx_device_pdf * pdev,stream * s,const gs_cid_system_info_t * pcidsi,gs_id object_id)723 pdf_write_cid_system_info_to_stream(gx_device_pdf *pdev, stream *s,
724 const gs_cid_system_info_t *pcidsi, gs_id object_id)
725 {
726 byte Registry[32], Ordering[32];
727
728 if (pcidsi->Registry.size > sizeof(Registry))
729 return_error(gs_error_limitcheck);
730 if (pcidsi->Ordering.size > sizeof(Ordering))
731 return_error(gs_error_limitcheck);
732 memcpy(Registry, pcidsi->Registry.data, pcidsi->Registry.size);
733 memcpy(Ordering, pcidsi->Ordering.data, pcidsi->Ordering.size);
734 if (pdev->KeyLength && object_id != 0) {
735 stream_arcfour_state sarc4;
736 int code;
737
738 code = pdf_encrypt_init(pdev, object_id, &sarc4);
739 if (code < 0)
740 return code;
741 s_arcfour_process_buffer(&sarc4, Registry, pcidsi->Registry.size);
742 code = pdf_encrypt_init(pdev, object_id, &sarc4);
743 if (code < 0)
744 return code;
745 s_arcfour_process_buffer(&sarc4, Ordering, pcidsi->Ordering.size);
746 }
747 stream_puts(s, "<<\n/Registry");
748 s_write_ps_string(s, Registry, pcidsi->Registry.size, PRINT_HEX_NOT_OK);
749 stream_puts(s, "\n/Ordering");
750 s_write_ps_string(s, Ordering, pcidsi->Ordering.size, PRINT_HEX_NOT_OK);
751 pprintd1(s, "\n/Supplement %d\n>>\n", pcidsi->Supplement);
752 return 0;
753 }
754
755 int
pdf_write_cid_system_info(gx_device_pdf * pdev,const gs_cid_system_info_t * pcidsi,gs_id object_id)756 pdf_write_cid_system_info(gx_device_pdf *pdev,
757 const gs_cid_system_info_t *pcidsi, gs_id object_id)
758 {
759 return pdf_write_cid_system_info_to_stream(pdev, pdev->strm, pcidsi, object_id);
760 }
761
762 int
pdf_write_cid_systemInfo_separate(gx_device_pdf * pdev,const gs_cid_system_info_t * pcidsi,long * id)763 pdf_write_cid_systemInfo_separate(gx_device_pdf *pdev, const gs_cid_system_info_t *pcidsi, long *id)
764 {
765 int code;
766
767 *id = pdf_begin_separate(pdev, resourceCIDSystemInfo);
768 code = pdf_write_cid_system_info(pdev, pcidsi, *id);
769 pdf_end_separate(pdev, resourceCIDSystemInfo);
770 return code;
771 }
772
773 /*
774 * Write a CMap resource. We pass the CMap object as well as the resource,
775 * because we write CMaps when they are created.
776 */
777 int
pdf_write_cmap(gx_device_pdf * pdev,const gs_cmap_t * pcmap,pdf_resource_t ** ppres,int font_index_only)778 pdf_write_cmap(gx_device_pdf *pdev, const gs_cmap_t *pcmap,
779 pdf_resource_t **ppres /*CMap*/, int font_index_only)
780 {
781 int code;
782 pdf_data_writer_t writer;
783 gs_const_string alt_cmap_name;
784 const gs_const_string *cmap_name = &pcmap->CMapName;
785
786 code = pdf_begin_data_stream(pdev, &writer,
787 DATA_STREAM_NOT_BINARY |
788 /* Don't set DATA_STREAM_ENCRYPT since we write to a temporary file.
789 See comment in pdf_begin_encrypt. */
790 (pdev->CompressFonts ?
791 DATA_STREAM_COMPRESS : 0), gs_no_id);
792 if (code < 0)
793 return code;
794 *ppres = writer.pres;
795 writer.pres->where_used = 0; /* CMap isn't a PDF resource. */
796 if (!pcmap->ToUnicode) {
797 byte buf[200];
798 cos_dict_t *pcd = (cos_dict_t *)writer.pres->object;
799 stream s;
800
801 code = cos_dict_put_c_key_int(pcd, "/WMode", pcmap->WMode);
802 if (code < 0)
803 return code;
804 buf[0] = '/';
805 memcpy(buf + 1, pcmap->CMapName.data, pcmap->CMapName.size);
806 code = cos_dict_put_c_key_string(pcd, "/CMapName",
807 buf, pcmap->CMapName.size + 1);
808 if (code < 0)
809 return code;
810 s_init(&s, pdev->memory);
811 swrite_string(&s, buf, sizeof(buf));
812 code = pdf_write_cid_system_info_to_stream(pdev, &s, pcmap->CIDSystemInfo, 0);
813 if (code < 0)
814 return code;
815 code = cos_dict_put_c_key_string(pcd, "/CIDSystemInfo",
816 buf, stell(&s));
817 if (code < 0)
818 return code;
819 code = cos_dict_put_string_copy(pcd, "/Type", "/CMap");
820 if (code < 0)
821 return code;
822 }
823 if (pcmap->CMapName.size == 0) {
824 /* Create an arbitrary name (for ToUnicode CMap). */
825 alt_cmap_name.data = (byte *)(*ppres)->rname;
826 alt_cmap_name.size = strlen((*ppres)->rname);
827 cmap_name = &alt_cmap_name;
828 }
829 code = psf_write_cmap(pdev->memory, writer.binary.strm, pcmap,
830 pdf_put_name_chars_proc(pdev),
831 cmap_name, font_index_only);
832 if (code < 0)
833 return code;
834 code = pdf_end_data(&writer);
835 if (code < 0)
836 return code;
837 return code;
838 }
839
840 static const char *OneByteIdentityH[] = {
841 "/CIDInit /ProcSet findresource begin",
842 "12 dict begin",
843 "begincmap",
844 "/CIDSystemInfo 3 dict dup begin",
845 "/Registry (Adobe) def",
846 "/Ordering (Identity) def",
847 "/Supplement 0 def",
848 "end def",
849 "/CMapName /OneByteIdentityH def",
850 "/CMapVersion 1.000 def",
851 "/CMapType 1 def",
852 "/UIDOffset 0 def",
853 "/XUID [1 10 25404 9999] def",
854 "/WMode 0 def",
855 "1 begincodespacerange",
856 "<00> <FF>",
857 "endcodespacerange",
858 "1 begincidrange",
859 "<00> <FF> 0",
860 "endcidrange",
861 "endcmap",
862 "CMapName currentdict /CMap defineresource pop",
863 "end",
864 "end",
865 NULL};
866
867 /*
868 * Write OneByteIdentityH CMap.
869 */
870 int
pdf_write_OneByteIdentityH(gx_device_pdf * pdev)871 pdf_write_OneByteIdentityH(gx_device_pdf *pdev)
872 {
873 int code, i;
874 pdf_data_writer_t writer;
875 cos_dict_t *pcd;
876 char buf[200];
877 static const gs_cid_system_info_t cidsi = {{(const byte *)"Adobe", 5}, {(const byte *)"Identity", 8}, 0};
878 long id;
879
880 if (pdev->IdentityCIDSystemInfo_id == gs_no_id) {
881 code = pdf_write_cid_systemInfo_separate(pdev, &cidsi, &id);
882 if (code < 0)
883 return code;
884 pdev->IdentityCIDSystemInfo_id = id;
885 }
886 if (pdev->OneByteIdentityH != NULL)
887 return 0;
888 code = pdf_begin_data_stream(pdev, &writer,
889 DATA_STREAM_NOT_BINARY |
890 /* Don't set DATA_STREAM_ENCRYPT since we write to a temporary file.
891 See comment in pdf_begin_encrypt. */
892 (pdev->CompressFonts ?
893 DATA_STREAM_COMPRESS : 0), gs_no_id);
894 if (code < 0)
895 return code;
896 pdev->OneByteIdentityH = writer.pres;
897 pcd = (cos_dict_t *)writer.pres->object;
898 code = cos_dict_put_string_copy(pcd, "/CMapName", "/OneByteIdentityH");
899 if (code < 0)
900 return code;
901 sprintf(buf, "%ld 0 R", pdev->IdentityCIDSystemInfo_id);
902 code = cos_dict_put_string_copy(pcd, "/CIDSystemInfo", buf);
903 if (code < 0)
904 return code;
905 code = cos_dict_put_string_copy(pcd, "/Type", "/CMap");
906 if (code < 0)
907 return code;
908 for (i = 0; OneByteIdentityH[i]; i++) {
909 stream_puts(pdev->strm, OneByteIdentityH[i]);
910 stream_putc(pdev->strm, '\n');
911 }
912 return pdf_end_data(&writer);
913 }
914