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