/src/ghostpdl/devices/vector/gdevpdtb.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* Copyright (C) 2001-2022 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., 1305 Grant Avenue - Suite 200, Novato, |
13 | | CA 94945, U.S.A., +1(415)492-9861, for further information. |
14 | | */ |
15 | | |
16 | | |
17 | | /* BaseFont implementation for pdfwrite */ |
18 | | #include "memory_.h" |
19 | | #include "ctype_.h" |
20 | | #include "gx.h" |
21 | | #include "gserrors.h" |
22 | | #include "gsutil.h" /* for bytes_compare */ |
23 | | #include "gxfcid.h" |
24 | | #include "gxfcopy.h" |
25 | | #include "gxfont.h" /* for gxfont42.h */ |
26 | | #include "gxfont42.h" |
27 | | #include "gdevpsf.h" |
28 | | #include "gdevpdfx.h" |
29 | | #include "gdevpdfo.h" |
30 | | #include "gdevpdtb.h" |
31 | | #include "gdevpdtf.h" |
32 | | #include "gdevpdtd.h" |
33 | | #include "smd5.h" |
34 | | #include "gxfcache.h" /* for gs_purge_font_from_char_caches_completely */ |
35 | | /* |
36 | | * Adobe's Distiller Parameters documentation for Acrobat Distiller 5 |
37 | | * says that all fonts other than Type 1 are always subsetted; the |
38 | | * documentation for Distiller 4 says that fonts other than Type 1 and |
39 | | * TrueType are subsetted. We do the latter, except that we always |
40 | | * subset large TrueType fonts. |
41 | | */ |
42 | 10.1k | #define MAX_NO_SUBSET_GLYPHS 4096 /* arbitrary */ |
43 | | |
44 | | /* ---------------- Private ---------------- */ |
45 | | |
46 | | private_st_pdf_base_font(); |
47 | | gs_private_st_basic(st_pdf_base_font, pdf_base_font_t, "pdf_base_font_t",\ |
48 | | pdf_base_font_ptrs, pdf_base_font_data); |
49 | | |
50 | 226k | #define SUBSET_PREFIX_SIZE 7 /* XXXXXX+ */ |
51 | | |
52 | | typedef struct pdf_base14_font_info_s { |
53 | | const char *urwname; |
54 | | const char *stdname; |
55 | | } pdf_base14_font_info_t; |
56 | | |
57 | | static const pdf_base14_font_info_t base14_font_info[] = { |
58 | | /* Standard mapping of URW fonts */ |
59 | | {"NimbusMonL-Regu", "Courier" }, |
60 | | {"NimbusMonL-Bold", "Courier-Bold" }, |
61 | | {"NimbusMonL-ReguObli", "Courier-Oblique" }, |
62 | | {"NimbusMonL-BoldObli", "Courier-BoldOblique" }, |
63 | | {"NimbusSanL-Regu", "Helvetica" }, |
64 | | {"NimbusSanL-Bold", "Helvetica-Bold" }, |
65 | | {"NimbusSanL-ReguItal", "Helvetica-Oblique" }, |
66 | | {"NimbusSanL-BoldItal", "Helvetica-BoldOblique"}, |
67 | | {"StandardSymL", "Symbol" }, |
68 | | {"NimbusRomNo9L-Regu", "Times-Roman" }, |
69 | | {"NimbusRomNo9L-Medi", "Times-Bold" }, |
70 | | {"NimbusRomNo9L-ReguItal","Times-Italic" }, |
71 | | {"NimbusRomNo9L-MediItal","Times-BoldItalic" }, |
72 | | {"Dingbats", "ZapfDingbats" }, |
73 | | /* A few other mappings of URW fonts */ |
74 | | {"NimbusMono-Reg", "Courier" }, |
75 | | {"NimbusMono-Bol", "Courier-Bold" }, |
76 | | {"NimbusMono-Ita", "Courier-Oblique" }, |
77 | | {"NimbusMono-BolIta", "Courier-BoldOblique" }, |
78 | | {"NimbusSan-Reg", "Helvetica" }, |
79 | | {"NimbusSan-Bol", "Helvetica-Bold" }, |
80 | | {"NimbusSan-Ita", "Helvetica-Oblique" }, |
81 | | {"NimbusSan-BolIta", "Helvetica-BoldOblique"}, |
82 | | {"A030-Reg", "Helvetica" }, |
83 | | {"A030-Bol", "Helvetica-Bold" }, |
84 | | {"A030-Ita", "Helvetica-Oblique" }, |
85 | | {"A030-BolIta", "Helvetica-BoldOblique"}, |
86 | | {"NimbusSanNo2-Reg", "Helvetica" }, |
87 | | {"NimbusSanNo2-Bol", "Helvetica-Bold" }, |
88 | | {"NimbusSanNo2-Ita", "Helvetica-Oblique" }, |
89 | | {"NimbusSanNo2-BolIta", "Helvetica-BoldOblique"}, |
90 | | {"NimbusRomanNo4-Lig", "Times-Roman" }, |
91 | | {"NimbusRomanNo4-Bol", "Times-Bold" }, |
92 | | {"NimbusRomanNo4-LigIta", "Times-Italic" }, |
93 | | {"NimbusRomanNo4-BolIta", "Times-BoldItalic" }, |
94 | | {"NimbusRomanNo9-Reg", "Times-Roman" }, |
95 | | {"NimbusRomanNo9-Med", "Times-Bold" }, |
96 | | {"NimbusRomanNo9-Ita", "Times-Italic" }, |
97 | | {"NimbusRomanNo9-MedIta", "Times-BoldItalic" }, |
98 | | {"NimbusRom-Reg", "Times-Roman" }, |
99 | | {"NimbusRom-Med", "Times-Bold" }, |
100 | | {"NimbusRom-Ita", "Times-Italic" }, |
101 | | {"NimbusRom-MedIta", "Times-BoldItalic" }, |
102 | | {"NimbusRomNo9-Reg", "Times-Roman" }, |
103 | | {"NimbusRomNo9-Bol", "Times-Bold" }, |
104 | | {"NimbusRomNo9-Ita", "Times-Italic" }, |
105 | | {"NimbusRomNo9-MedIta", "Times-BoldItalic" }, |
106 | | {0} |
107 | | }; |
108 | | |
109 | | /* Given a pointer to a font name, return a pointer to an |
110 | | * equivalent base 14 font name, of NULL if there is no |
111 | | * equivalent. |
112 | | */ |
113 | | const char *pdf_find_base14_name(const byte *str, uint size) |
114 | 30 | { |
115 | 30 | const pdf_base14_font_info_t *ppsf; |
116 | | |
117 | 1.41k | for (ppsf = base14_font_info; ppsf->urwname; ++ppsf) { |
118 | 1.38k | if (strlen(ppsf->urwname) == size) { |
119 | 8 | if (!memcmp(ppsf->urwname, (const char *)str, size)) |
120 | 0 | return ppsf->stdname; |
121 | 8 | } |
122 | 1.38k | } |
123 | 30 | return NULL; |
124 | 30 | } |
125 | | |
126 | | |
127 | | /* |
128 | | * Determine whether a font is a subset font by examining the name. |
129 | | */ |
130 | | bool |
131 | | pdf_has_subset_prefix(const byte *str, uint size) |
132 | 28.8k | { |
133 | 28.8k | int i; |
134 | | |
135 | 28.8k | if (size < SUBSET_PREFIX_SIZE || str[SUBSET_PREFIX_SIZE - 1] != '+') |
136 | 23.9k | return false; |
137 | 34.2k | for (i = 0; i < SUBSET_PREFIX_SIZE - 1; ++i) |
138 | 29.3k | if ((uint)(str[i] - 'A') >= 26) |
139 | 6 | return false; |
140 | 4.88k | return true; |
141 | 4.89k | } |
142 | | |
143 | | static inline ulong |
144 | | hash(ulong v, int index, ushort w) |
145 | 830k | { |
146 | 830k | return v * 3141592653u + w; |
147 | 830k | } |
148 | | |
149 | | /* |
150 | | * Add the XXXXXX+ prefix for a subset font. |
151 | | */ |
152 | | int |
153 | | pdf_add_subset_prefix(const gx_device_pdf *pdev, gs_string *pstr, byte *used, int count, char *md5_hash) |
154 | 10.5k | { |
155 | 10.5k | uint size = pstr->size; |
156 | 10.5k | byte *data = gs_resize_string(pdev->pdf_memory, pstr->data, size, |
157 | 10.5k | size + SUBSET_PREFIX_SIZE, |
158 | 10.5k | "pdf_add_subset_prefix"); |
159 | 10.5k | int len = (count + 7) / 8; |
160 | 10.5k | int len0 = len & ~(sizeof(ushort) - 1); |
161 | 10.5k | ulong v = 0; |
162 | 10.5k | int i; |
163 | | |
164 | 10.5k | if (data == 0) |
165 | 0 | return_error(gs_error_VMerror); |
166 | | |
167 | 10.5k | if (md5_hash) { |
168 | 51.8k | for (i = 0; i < 8; i += sizeof(ushort)) { |
169 | 41.5k | v = hash(v, i, (*(md5_hash + i) | *(md5_hash + i + 1) << 8)); |
170 | 41.5k | } |
171 | 10.3k | } |
172 | | |
173 | | /* Hash the 'used' array. */ |
174 | 799k | for (i = 0; i < len0; i += sizeof(ushort)) |
175 | 789k | v = hash(v, i, *(ushort *)(used + i)); |
176 | 10.8k | for (; i < len; i++) |
177 | 281 | v = hash(v, i, used[i]); |
178 | | |
179 | 10.5k | memmove(data + SUBSET_PREFIX_SIZE, data, size); |
180 | 73.6k | for (i = 0; i < SUBSET_PREFIX_SIZE - 1; ++i, v /= 26) |
181 | 63.1k | data[i] = 'A' + (v % 26); |
182 | 10.5k | data[SUBSET_PREFIX_SIZE - 1] = '+'; |
183 | 10.5k | pstr->data = data; |
184 | 10.5k | pstr->size = size + SUBSET_PREFIX_SIZE; |
185 | 10.5k | return 0; |
186 | 10.5k | } |
187 | | |
188 | | /* Finish writing FontFile* data. */ |
189 | | static int |
190 | | pdf_end_fontfile(gx_device_pdf *pdev, pdf_data_writer_t *pdw) |
191 | 10.3k | { |
192 | | /* We would like to call pdf_end_data, |
193 | | but we don't want to write the object to the output file now. */ |
194 | 10.3k | return pdf_close_aside(pdw->pdev); |
195 | 10.3k | } |
196 | | |
197 | | static int copied_font_notify(void *proc_data, void *event_data) |
198 | 13.5k | { |
199 | 13.5k | return gs_purge_font_from_char_caches_completely((gs_font *)proc_data); |
200 | 13.5k | } |
201 | | |
202 | | /* ---------------- Public ---------------- */ |
203 | | /* |
204 | | * Allocate and initialize a base font structure, making the required |
205 | | * stable copy/ies of the gs_font. Note that this removes any XXXXXX+ |
206 | | * font name prefix from the copy. If is_standard is true, the copy is |
207 | | * a complete one, and adding glyphs or Encoding entries is not allowed. |
208 | | */ |
209 | | int |
210 | | pdf_base_font_alloc(gx_device_pdf *pdev, pdf_base_font_t **ppbfont, |
211 | | gs_font_base *font, const gs_matrix *orig_matrix, |
212 | | bool is_standard) |
213 | 21.3k | { |
214 | 21.3k | gs_memory_t *mem = pdev->pdf_memory; |
215 | 21.3k | gs_font *copied; |
216 | 21.3k | gs_font *complete; |
217 | 21.3k | pdf_base_font_t *pbfont = |
218 | 21.3k | gs_alloc_struct(mem, pdf_base_font_t, |
219 | 21.3k | &st_pdf_base_font, "pdf_base_font_alloc"); |
220 | 21.3k | const gs_font_name *pfname = &font->font_name; |
221 | 21.3k | gs_const_string font_name; |
222 | 21.3k | char fnbuf[2*sizeof(long) + 3]; /* .F########\0 */ |
223 | 21.3k | int code, reserve_glyphs = -1; |
224 | | |
225 | 21.3k | if (pbfont == 0) |
226 | 0 | return_error(gs_error_VMerror); |
227 | 21.3k | memset(pbfont, 0, sizeof(*pbfont)); |
228 | 21.3k | switch (font->FontType) { |
229 | 10.6k | case ft_encrypted: |
230 | 10.7k | case ft_encrypted2: |
231 | 10.7k | { |
232 | 10.7k | int index, count; |
233 | 10.7k | gs_glyph glyph; |
234 | | |
235 | 10.7k | for (index = 0, count = 0; |
236 | 8.25M | (font->procs.enumerate_glyph((gs_font *)font, &index, |
237 | 8.25M | GLYPH_SPACE_NAME, &glyph), |
238 | 8.25M | index != 0); |
239 | 10.7k | ) |
240 | 8.24M | ++count; |
241 | 10.7k | pbfont->num_glyphs = count; |
242 | 10.7k | pbfont->do_subset = (is_standard ? DO_SUBSET_NO : DO_SUBSET_UNKNOWN); |
243 | 10.7k | } |
244 | | /* If we find an excessively large type 1 font we won't be able to emit |
245 | | * a complete copy. Instead we will emit multiple subsets. Detect that here |
246 | | * and only reserve enough space in the font copy for the maximum subset |
247 | | * glyphs, 257. |
248 | | * This also prevents us making a 'complete' copy of the font below. NB the |
249 | | * value 2048 is merely a guess, intended to prevent copying very large fonts. |
250 | | */ |
251 | 10.7k | if(pbfont->num_glyphs > 2048 && !is_standard) { |
252 | 0 | reserve_glyphs = 257; |
253 | 0 | if(pbfont->do_subset != DO_SUBSET_NO){ |
254 | 0 | char buf[gs_font_name_max + 1]; |
255 | 0 | int l = min(font->font_name.size, sizeof(buf) - 1); |
256 | |
|
257 | 0 | memcpy(buf, font->font_name.chars, l); |
258 | 0 | buf[l] = 0; |
259 | 0 | emprintf1(pdev->memory, |
260 | 0 | "Can't embed the complete font %s as it is too large, embedding a subset.\n", |
261 | 0 | buf); |
262 | 0 | } |
263 | 0 | } |
264 | 10.7k | break; |
265 | 10.1k | case ft_TrueType: |
266 | 10.1k | pbfont->num_glyphs = ((gs_font_type42 *)font)->data.trueNumGlyphs; |
267 | 10.1k | pbfont->do_subset = |
268 | 10.1k | (pbfont->num_glyphs <= MAX_NO_SUBSET_GLYPHS ? |
269 | 8.95k | DO_SUBSET_UNKNOWN : DO_SUBSET_YES); |
270 | 10.1k | break; |
271 | 34 | case ft_CID_encrypted: |
272 | 34 | pbfont->num_glyphs = ((gs_font_cid0 *)font)->cidata.common.CIDCount; |
273 | 34 | goto cid; |
274 | 387 | case ft_CID_TrueType: |
275 | 387 | pbfont->num_glyphs = ((gs_font_cid2 *)font)->cidata.common.CIDCount; |
276 | 421 | cid: |
277 | 421 | pbfont->do_subset = DO_SUBSET_YES; |
278 | 421 | pbfont->CIDSet = |
279 | 421 | gs_alloc_bytes(mem, (pbfont->num_glyphs + 7) / 8, |
280 | 421 | "pdf_base_font_alloc(CIDSet)"); |
281 | 421 | if (pbfont->CIDSet == 0) { |
282 | 0 | code = gs_note_error(gs_error_VMerror); |
283 | 0 | goto fail; |
284 | 0 | } |
285 | 421 | pbfont->CIDSetLength = (pbfont->num_glyphs + 7) / 8; |
286 | 421 | memset(pbfont->CIDSet, 0, (pbfont->num_glyphs + 7) / 8); |
287 | 421 | break; |
288 | 0 | default: |
289 | 0 | code = gs_note_error(gs_error_rangecheck); |
290 | 0 | goto fail; |
291 | 21.3k | } |
292 | | |
293 | 21.3k | code = gs_copy_font((gs_font *)font, orig_matrix, mem, &copied, reserve_glyphs); |
294 | 21.3k | if (code < 0) |
295 | 7.82k | goto fail; |
296 | 13.5k | gs_notify_register(&copied->notify_list, copied_font_notify, copied); |
297 | 13.5k | { |
298 | | /* |
299 | | * Adobe Technical Note # 5012 "The Type 42 Font Format Specification" says : |
300 | | * |
301 | | * There is a known bug in the TrueType rasterizer included in versions of the |
302 | | * PostScript interpreter previous to version 2013. The problem is that the |
303 | | * translation components of the FontMatrix, as used as an argument to the |
304 | | * definefont or makefont operators, are ignored. Translation of user space is |
305 | | * not affected by this bug. |
306 | | * |
307 | | * Besides that, we found that Adobe Acrobat Reader 4 and 5 ignore |
308 | | * FontMatrix.ty . |
309 | | */ |
310 | 13.5k | copied->FontMatrix.tx = copied->FontMatrix.ty = 0; |
311 | 13.5k | } |
312 | | |
313 | 13.5k | if (pbfont->do_subset != DO_SUBSET_YES && reserve_glyphs == -1) { |
314 | | /* The only possibly non-subsetted fonts are Type 1/2 and Type 42. */ |
315 | 13.2k | if (is_standard) |
316 | 2.77k | complete = copied; |
317 | 10.4k | else { |
318 | 10.4k | code = gs_copy_font((gs_font *)font, &font->FontMatrix, mem, &complete, -1); |
319 | 10.4k | if (code < 0) |
320 | 0 | goto fail; |
321 | 10.4k | } |
322 | 13.2k | code = gs_copy_font_complete((gs_font *)font, complete); |
323 | 13.2k | if (code < 0 && pbfont->do_subset == DO_SUBSET_NO) { |
324 | 0 | char buf[gs_font_name_max + 1]; |
325 | 0 | int l = min(copied->font_name.size, sizeof(buf) - 1); |
326 | |
|
327 | 0 | memcpy(buf, copied->font_name.chars, l); |
328 | 0 | buf[l] = 0; |
329 | 0 | emprintf1(pdev->memory, |
330 | 0 | "Can't embed the complete font %s due to font error.\n", |
331 | 0 | buf); |
332 | 0 | goto fail; |
333 | 0 | } |
334 | 13.2k | if (code < 0) { |
335 | | /* A font error happened, but it may be caused by a glyph, |
336 | | which is not used in the document. Continue with subsetting the font. |
337 | | If the failed glyph will be used in the document, |
338 | | another error will hgappen when the glyph is used. |
339 | | */ |
340 | 457 | gs_free_copied_font(complete); |
341 | 457 | complete = copied; |
342 | 457 | } |
343 | 13.2k | } else |
344 | 296 | complete = copied; |
345 | 13.5k | pbfont->copied = (gs_font_base *)copied; |
346 | 13.5k | pbfont->complete = (gs_font_base *)complete; |
347 | | |
348 | | /* replace the font cache of the copied fonts with our own font cache |
349 | | * this is required for PCL, see 'pdf_free_pdf_font_cache' in gdevpdf.c |
350 | | * for further details. |
351 | | */ |
352 | 13.5k | pdev->pdf_font_dir->global_glyph_code = font->dir->global_glyph_code; |
353 | | |
354 | 13.5k | pbfont->copied->dir = pbfont->complete->dir = pdev->pdf_font_dir; |
355 | | |
356 | 13.5k | if (pbfont->copied->FontType == ft_CID_encrypted) { |
357 | 34 | gs_font_cid0 *copied0 = (gs_font_cid0 *)pbfont->copied; |
358 | 34 | int i; |
359 | 75 | for (i = 0; i < copied0->cidata.FDArray_size; ++i) { |
360 | 41 | ((gs_font *)copied0->cidata.FDArray[i])->dir = pdev->pdf_font_dir; |
361 | 41 | } |
362 | 34 | } |
363 | | |
364 | 13.5k | pbfont->is_standard = is_standard; |
365 | 13.5k | if (pfname->size > 0) { |
366 | 13.3k | font_name.data = pfname->chars; |
367 | 13.3k | font_name.size = pfname->size; |
368 | 18.2k | while (pdf_has_subset_prefix(font_name.data, font_name.size)) { |
369 | | /* Strip off an existing subset prefix. */ |
370 | 4.88k | font_name.data += SUBSET_PREFIX_SIZE; |
371 | 4.88k | font_name.size -= SUBSET_PREFIX_SIZE; |
372 | 4.88k | } |
373 | 13.3k | } else { |
374 | 122 | gs_snprintf(fnbuf, sizeof(fnbuf), ".F" PRI_INTPTR, (intptr_t)copied); |
375 | 122 | font_name.data = (byte *)fnbuf; |
376 | 122 | font_name.size = strlen(fnbuf); |
377 | 122 | } |
378 | 13.5k | pbfont->font_name.data = |
379 | 13.5k | gs_alloc_string(mem, font_name.size, "pdf_base_font_alloc(font_name)"); |
380 | 13.5k | if (pbfont->font_name.data == 0) |
381 | 0 | goto fail; |
382 | 13.5k | memcpy(pbfont->font_name.data, font_name.data, font_name.size); |
383 | 13.5k | pbfont->font_name.size = font_name.size; |
384 | 13.5k | *ppbfont = pbfont; |
385 | 13.5k | return 0; |
386 | 7.82k | fail: |
387 | 7.82k | pdf_base_font_free(pdev, pbfont); |
388 | 7.82k | return code; |
389 | 13.5k | } |
390 | | |
391 | | /* |
392 | | * Return a reference to the name of a base font. This name is guaranteed |
393 | | * not to have a XXXXXX+ prefix. The client may change the name at will, |
394 | | * but must not add a XXXXXX+ prefix. |
395 | | */ |
396 | | gs_string * |
397 | | pdf_base_font_name(pdf_base_font_t *pbfont) |
398 | 21.4k | { |
399 | 21.4k | return &pbfont->font_name; |
400 | 21.4k | } |
401 | | |
402 | | /* |
403 | | * Return the (copied, subset) font associated with a base font. |
404 | | * This procedure probably shouldn't exist.... |
405 | | */ |
406 | | gs_font_base * |
407 | | pdf_base_font_font(const pdf_base_font_t *pbfont, bool complete) |
408 | 15.1M | { |
409 | 15.1M | return (complete ? pbfont->complete : pbfont->copied); |
410 | 15.1M | } |
411 | | |
412 | | /* |
413 | | * Check for subset font. |
414 | | */ |
415 | | bool |
416 | | pdf_base_font_is_subset(const pdf_base_font_t *pbfont) |
417 | 10.5k | { |
418 | 10.5k | return pbfont->do_subset == DO_SUBSET_YES; |
419 | 10.5k | } |
420 | | |
421 | | /* |
422 | | * Drop the copied complete font associated with a base font. |
423 | | */ |
424 | | void |
425 | | pdf_base_font_drop_complete(pdf_base_font_t *pbfont) |
426 | 116 | { |
427 | | /* gs_font is a subset of gs_font_base and we only want to |
428 | | * free the members which are common to both, so this cast is |
429 | | * (at the time of writing) safe. |
430 | | */ |
431 | 116 | gs_free_copied_font((gs_font *)pbfont->complete); |
432 | 116 | pbfont->complete = NULL; |
433 | 116 | } |
434 | | |
435 | | /* |
436 | | * Copy a glyph (presumably one that was just used) into a saved base |
437 | | * font. Note that it is the client's responsibility to determine that |
438 | | * the source font is compatible with the target font. (Normally they |
439 | | * will be the same.) |
440 | | */ |
441 | | int |
442 | | pdf_base_font_copy_glyph(pdf_base_font_t *pbfont, gs_glyph glyph, |
443 | | gs_font_base *font) |
444 | 318k | { |
445 | 318k | int code; |
446 | | |
447 | | /* If we're a TrueType CIDFont, check teh GSUB table for replacement glyphs. |
448 | | * Bug #691574 |
449 | | */ |
450 | 318k | if (font->FontType == ft_CID_TrueType) { |
451 | 24.9k | code = |
452 | 24.9k | gs_copy_glyph_options((gs_font *)font, glyph, |
453 | 24.9k | (gs_font *)pbfont->copied, |
454 | 24.9k | (pbfont->is_standard ? COPY_GLYPH_NO_NEW : COPY_GLYPH_USE_GSUB)); |
455 | 293k | } else { |
456 | 293k | code = |
457 | 293k | gs_copy_glyph_options((gs_font *)font, glyph, |
458 | 293k | (gs_font *)pbfont->copied, |
459 | 293k | (pbfont->is_standard ? COPY_GLYPH_NO_NEW : 0)); |
460 | 293k | } |
461 | 318k | if (code < 0) |
462 | 2.80k | return code; |
463 | 315k | if (pbfont->CIDSet != 0 && |
464 | 315k | (uint)(glyph - GS_MIN_CID_GLYPH) < pbfont->num_glyphs |
465 | 315k | ) { |
466 | 25.4k | uint cid = glyph - GS_MIN_CID_GLYPH; |
467 | | |
468 | 25.4k | pbfont->CIDSet[cid >> 3] |= 0x80 >> (cid & 7); |
469 | 25.4k | } |
470 | 315k | return 0; |
471 | 318k | } |
472 | | |
473 | | /* |
474 | | * Determine whether a font should be subsetted. |
475 | | */ |
476 | | bool |
477 | | pdf_do_subset_font(gx_device_pdf *pdev, pdf_base_font_t *pbfont, gs_id rid) |
478 | 31.4k | { |
479 | 31.4k | gs_font_base *copied = pbfont->copied; |
480 | | |
481 | | /* |
482 | | * If the decision has not been made already, determine whether or not |
483 | | * to subset the font. |
484 | | */ |
485 | 31.4k | if (pbfont->do_subset == DO_SUBSET_UNKNOWN) { |
486 | 10.4k | int max_pct = pdev->params.MaxSubsetPct; |
487 | 10.4k | bool do_subset = pdev->params.SubsetFonts && max_pct > 0; |
488 | | |
489 | 10.4k | if (do_subset && max_pct < 100) { |
490 | | /* We want to subset iff used <= total * MaxSubsetPct / 100. */ |
491 | 0 | do_subset = false; |
492 | 0 | if (max_pct > 0) { |
493 | 0 | int max_subset_used = pbfont->num_glyphs * max_pct / 100; |
494 | 0 | int used, index; |
495 | 0 | gs_glyph ignore_glyph; |
496 | |
|
497 | 0 | do_subset = true; |
498 | 0 | for (index = 0, used = 0; |
499 | 0 | (copied->procs.enumerate_glyph((gs_font *)copied, |
500 | 0 | &index, GLYPH_SPACE_INDEX, |
501 | 0 | &ignore_glyph), index != 0); |
502 | 0 | ) |
503 | 0 | if (++used > max_subset_used) { |
504 | 0 | do_subset = false; |
505 | 0 | break; |
506 | 0 | } |
507 | 0 | } |
508 | 0 | } |
509 | 10.4k | pbfont->do_subset = (do_subset ? DO_SUBSET_YES : DO_SUBSET_NO); |
510 | 10.4k | } |
511 | 31.4k | return (pbfont->do_subset == DO_SUBSET_YES); |
512 | 31.4k | } |
513 | | |
514 | | /* |
515 | | * Write the FontFile entry for an embedded font, /FontFile<n> # # R. |
516 | | */ |
517 | | int |
518 | | pdf_write_FontFile_entry(gx_device_pdf *pdev, pdf_base_font_t *pbfont) |
519 | 10.1k | { |
520 | 10.1k | stream *s = pdev->strm; |
521 | 10.1k | const char *FontFile_key; |
522 | | |
523 | 10.1k | switch (pbfont->copied->FontType) { |
524 | 2.31k | case ft_TrueType: |
525 | 2.48k | case ft_CID_TrueType: |
526 | 2.48k | FontFile_key = "/FontFile2"; |
527 | 2.48k | break; |
528 | 7.68k | default: /* Type 1/2, CIDFontType 0 */ |
529 | 7.68k | if (!pdev->HaveCFF) |
530 | 3.02k | FontFile_key = "/FontFile"; |
531 | 4.65k | else |
532 | 4.65k | FontFile_key = "/FontFile3"; |
533 | 10.1k | } |
534 | 10.1k | stream_puts(s, FontFile_key); |
535 | 10.1k | pprintld1(s, " %ld 0 R", pbfont->FontFile->id); |
536 | 10.1k | return 0; |
537 | 10.1k | } |
538 | | |
539 | | /* |
540 | | * Adjust font name for Acrobat Reader 3. |
541 | | */ |
542 | | static int |
543 | | pdf_adjust_font_name(gx_device_pdf *pdev, long id, pdf_base_font_t *pbfont) |
544 | 0 | { |
545 | | /* |
546 | | * In contradiction with previous version of pdfwrite, |
547 | | * this always adds a suffix. We don't check the original name |
548 | | * for uniquity bacause the layered architecture |
549 | | * (see gdevpdtx.h) doesn't provide an easy access for |
550 | | * related information. |
551 | | */ |
552 | 0 | int i; |
553 | 0 | byte *chars = (byte *)pbfont->font_name.data; /* break 'const' */ |
554 | 0 | byte *data; |
555 | 0 | uint size = pbfont->font_name.size; |
556 | 0 | char suffix[sizeof(long) * 2 + 2]; |
557 | 0 | uint suffix_size; |
558 | |
|
559 | 0 | #define SUFFIX_CHAR '~' |
560 | | /* |
561 | | * If the name looks as though it has one of our unique suffixes, |
562 | | * remove the suffix. |
563 | | */ |
564 | 0 | for (i = size; |
565 | 0 | i > 0 && isxdigit(chars[i - 1]); |
566 | 0 | --i) |
567 | 0 | DO_NOTHING; |
568 | 0 | if (i < size && i > 0 && chars[i - 1] == SUFFIX_CHAR) { |
569 | 0 | do { |
570 | 0 | --i; |
571 | 0 | } while (i > 0 && chars[i - 1] == SUFFIX_CHAR); |
572 | 0 | size = i + 1; |
573 | 0 | } |
574 | | /* Create a unique name. */ |
575 | 0 | gs_snprintf(suffix, sizeof(suffix), "%c%lx", SUFFIX_CHAR, id); |
576 | 0 | suffix_size = strlen(suffix); |
577 | 0 | data = gs_resize_string(pdev->pdf_memory, chars, size, |
578 | 0 | size + suffix_size, |
579 | 0 | "pdf_adjust_font_name"); |
580 | 0 | if (data == 0) |
581 | 0 | return_error(gs_error_VMerror); |
582 | 0 | memcpy(data + size, (const byte *)suffix, suffix_size); |
583 | 0 | pbfont->font_name.data = data; |
584 | 0 | pbfont->font_name.size = size + suffix_size; |
585 | 0 | #undef SUFFIX_CHAR |
586 | 0 | return 0; |
587 | 0 | } |
588 | | |
589 | | /* |
590 | | * Write an embedded font. |
591 | | */ |
592 | | int |
593 | | pdf_write_embedded_font(gx_device_pdf *pdev, pdf_base_font_t *pbfont, font_type FontType, |
594 | | gs_int_rect *FontBBox, gs_id rid, cos_dict_t **ppcd) |
595 | 10.3k | { |
596 | 10.3k | bool do_subset = pdf_do_subset_font(pdev, pbfont, rid); |
597 | 10.3k | gs_font_base *out_font = |
598 | 10.3k | (do_subset || pbfont->complete == NULL ? pbfont->copied : pbfont->complete); |
599 | 10.3k | gs_const_string fnstr; |
600 | 10.3k | pdf_data_writer_t writer; |
601 | 10.3k | byte digest[6] = {0,0,0,0,0,0}; |
602 | 10.3k | int code = 0; |
603 | 10.3k | int options=0; |
604 | | |
605 | 10.3k | if (pbfont->written) |
606 | 0 | return 0; /* already written */ |
607 | 10.3k | code = copied_order_font((gs_font *)out_font); |
608 | 10.3k | if (code < 0) |
609 | 0 | return code; |
610 | | /* Since we now always ASCIIHex encode the eexec encrypted portion of a |
611 | | * Type 1 font, such a font cannot contain any binary data, if its not being |
612 | | * compressed then there is no reason to ASCII encode it (which will happen |
613 | | * we set DATA_STREAM_BINARY and the device does not permit binary output) |
614 | | * NB if HaveCFF is true then we convert type 1 to CFF which is a binary |
615 | | * format, so we still need to set DATA_STREAM_BINARY. |
616 | | */ |
617 | 10.3k | if (pdev->CompressFonts) |
618 | 10.3k | options = DATA_STREAM_BINARY | DATA_STREAM_COMPRESS; |
619 | 0 | else |
620 | 0 | if (FontType != ft_encrypted || pdev->HaveCFF) |
621 | 0 | options = DATA_STREAM_BINARY; |
622 | | /* Don't set DATA_STREAM_ENCRYPT since we write to a temporary file. |
623 | | * See comment in pdf_begin_encrypt. |
624 | | */ |
625 | 10.3k | code = pdf_begin_data_stream(pdev, &writer, options, 0); |
626 | 10.3k | if (code < 0) |
627 | 0 | return code; |
628 | 10.3k | if (pdev->PDFA != 0) { |
629 | 0 | stream *s = s_MD5C_make_stream(pdev->pdf_memory, writer.binary.strm); |
630 | |
|
631 | 0 | if (s == NULL) |
632 | 0 | return_error(gs_error_VMerror); |
633 | 0 | writer.binary.strm = s; |
634 | 0 | } |
635 | 10.3k | if (pdev->CompatibilityLevel == 1.2 && |
636 | 10.3k | !do_subset && !pbfont->is_standard ) { |
637 | | /* |
638 | | * Due to a bug in Acrobat Reader 3, we need to generate |
639 | | * unique font names, except base 14 fonts being not embedded. |
640 | | * To recognize base 14 fonts here we used the knowledge |
641 | | * that pbfont->is_standard is true for base 14 fonts only. |
642 | | * Note that subsetted fonts already have an unique name |
643 | | * due to subset prefix. |
644 | | */ |
645 | 0 | int code = pdf_adjust_font_name(pdev, writer.pres->object->id, pbfont); |
646 | 0 | if (code < 0) |
647 | 0 | return code; |
648 | 0 | } |
649 | 10.3k | fnstr.data = pbfont->font_name.data; |
650 | 10.3k | fnstr.size = pbfont->font_name.size; |
651 | | /* Now write the font (or subset). */ |
652 | 10.3k | switch (FontType) { |
653 | | |
654 | 0 | case ft_composite: |
655 | | /* Nothing to embed -- the descendant fonts do it all. */ |
656 | 0 | code = 0; |
657 | 0 | break; |
658 | | |
659 | 163 | case ft_encrypted2: |
660 | 163 | if (!pdev->HaveCFF) { |
661 | | /* Must convert to Type 1 charstrings. */ |
662 | 0 | return_error(gs_error_unregistered); /* Not implemented yet. */ |
663 | 0 | } |
664 | 7.65k | case ft_encrypted: |
665 | 7.65k | if (pdev->HavePDFWidths) { |
666 | 4.62k | code = copied_drop_extension_glyphs((gs_font *)out_font); |
667 | 4.62k | if (code < 0) |
668 | 0 | return code; |
669 | 4.62k | } |
670 | 7.65k | if (!pdev->HaveCFF) { |
671 | | /* Write the type 1 font with no converting to CFF. */ |
672 | 3.02k | int lengths[3]; |
673 | | |
674 | 3.02k | if (pbfont->do_subset != DO_SUBSET_NO) |
675 | 3.02k | code = psf_write_type1_font(writer.binary.strm, |
676 | 3.02k | (gs_font_type1 *)out_font, |
677 | 3.02k | WRITE_TYPE1_WITH_LENIV | WRITE_TYPE1_EEXEC | |
678 | 3.02k | WRITE_TYPE1_EEXEC_PAD | WRITE_TYPE1_ASCIIHEX, |
679 | 3.02k | NULL, 0, &fnstr, lengths); |
680 | 0 | else |
681 | 0 | code = psf_write_type1_font(writer.binary.strm, |
682 | 0 | (gs_font_type1 *)out_font, |
683 | 0 | WRITE_TYPE1_WITH_LENIV | WRITE_TYPE1_EEXEC | |
684 | 0 | WRITE_TYPE1_EEXEC_PAD | WRITE_TYPE1_ASCIIHEX | WRITE_TYPE1_XUID, |
685 | 0 | NULL, 0, &fnstr, lengths); |
686 | 3.02k | if (lengths[0] > 0) { |
687 | 3.02k | if (code < 0) |
688 | 0 | goto finish; |
689 | 3.02k | code = cos_dict_put_c_key_int((cos_dict_t *)writer.pres->object, |
690 | 3.02k | "/Length1", lengths[0]); |
691 | 3.02k | } |
692 | 3.02k | if (lengths[1] > 0) { |
693 | 3.02k | if (code < 0) |
694 | 0 | goto finish; |
695 | 3.02k | code = cos_dict_put_c_key_int((cos_dict_t *)writer.pres->object, |
696 | 3.02k | "/Length2", lengths[1]); |
697 | 3.02k | if (code < 0) |
698 | 0 | return code; |
699 | 3.02k | code = cos_dict_put_c_key_int((cos_dict_t *)writer.pres->object, |
700 | 3.02k | "/Length3", lengths[2]); |
701 | 3.02k | } |
702 | 4.62k | } else { |
703 | | /* |
704 | | * Since we only support PDF 1.2 and later, always write Type 1 |
705 | | * fonts as Type1C (Type 2). Acrobat Reader apparently doesn't |
706 | | * accept CFF fonts with Type 1 CharStrings, so we need to convert |
707 | | * them. Also remove lenIV, so Type 2 fonts will compress better. |
708 | | */ |
709 | 4.65k | #define TYPE2_OPTIONS (WRITE_TYPE2_NO_LENIV | WRITE_TYPE2_CHARSTRINGS) |
710 | 4.62k | code = cos_dict_put_string_copy((cos_dict_t *)writer.pres->object, "/Subtype", "/Type1C"); |
711 | 4.62k | if (code < 0) |
712 | 0 | return code; |
713 | 4.62k | code = psf_write_type2_font(writer.binary.strm, |
714 | 4.62k | (gs_font_type1 *)out_font, |
715 | 4.62k | TYPE2_OPTIONS | |
716 | 4.62k | (pdev->CompatibilityLevel < 1.3 ? WRITE_TYPE2_AR3 : 0) | |
717 | 4.62k | (pbfont->do_subset == DO_SUBSET_NO ? WRITE_TYPE2_XUID : 0), |
718 | 4.62k | NULL, 0, &fnstr, FontBBox); |
719 | 4.62k | } |
720 | 7.65k | goto finish; |
721 | | |
722 | 7.65k | case ft_TrueType: { |
723 | 2.46k | gs_font_type42 *const pfont = (gs_font_type42 *)out_font; |
724 | 2.46k | #define TRUETYPE_OPTIONS (WRITE_TRUETYPE_NAME | WRITE_TRUETYPE_HVMTX) |
725 | | /* Acrobat Reader 3 doesn't handle cmap format 6 correctly. */ |
726 | 2.46k | const int options = TRUETYPE_OPTIONS | |
727 | 2.46k | (pdev->PDFA != 0 ? WRITE_TRUETYPE_UNICODE_CMAP : 0) | |
728 | 2.46k | (pdev->CompatibilityLevel <= 1.2 ? |
729 | 1.49k | WRITE_TRUETYPE_NO_TRIMMED_TABLE : 0) | |
730 | | /* Generate a cmap only for incrementally downloaded fonts |
731 | | and for subsetted fonts. */ |
732 | 2.46k | (pfont->data.numGlyphs != pfont->data.trueNumGlyphs || |
733 | 2.46k | pbfont->do_subset == DO_SUBSET_YES ? |
734 | 2.46k | WRITE_TRUETYPE_CMAP : 0); |
735 | 2.46k | stream poss; |
736 | | |
737 | 2.46k | if (pdev->HavePDFWidths) { |
738 | 1.49k | code = copied_drop_extension_glyphs((gs_font *)out_font); |
739 | 1.49k | if (code < 0) |
740 | 0 | return code; |
741 | 1.49k | } |
742 | 2.46k | s_init(&poss, pdev->memory); |
743 | 2.46k | swrite_position_only(&poss); |
744 | 2.46k | code = psf_write_truetype_font(&poss, pfont, options, NULL, 0, &fnstr); |
745 | 2.46k | if (code < 0) |
746 | 149 | goto finish; |
747 | 2.31k | code = cos_dict_put_c_key_int((cos_dict_t *)writer.pres->object, "/Length1", stell(&poss)); |
748 | 2.31k | if (code < 0) |
749 | 0 | goto finish; |
750 | 2.31k | code = psf_write_truetype_font(writer.binary.strm, pfont, |
751 | 2.31k | options, NULL, 0, &fnstr); |
752 | 2.31k | goto finish; |
753 | 2.31k | } |
754 | | |
755 | 31 | case ft_CID_encrypted: |
756 | 31 | code = cos_dict_put_string_copy((cos_dict_t *)writer.pres->object, "/Subtype", "/CIDFontType0C"); |
757 | 31 | if (code < 0) |
758 | 0 | return code; |
759 | 31 | code = psf_write_cid0_font(writer.binary.strm, |
760 | 31 | (gs_font_cid0 *)out_font, TYPE2_OPTIONS, |
761 | 31 | NULL, 0, &fnstr); |
762 | 31 | goto finish; |
763 | | |
764 | 170 | case ft_CID_TrueType: |
765 | | /* CIDFontType 2 fonts don't use cmap, name, OS/2, or post. */ |
766 | 170 | #define CID2_OPTIONS WRITE_TRUETYPE_HVMTX |
767 | 170 | code = psf_write_cid2_font(writer.binary.strm, |
768 | 170 | (gs_font_cid2 *)out_font, |
769 | 170 | CID2_OPTIONS, NULL, 0, &fnstr); |
770 | 10.3k | finish: |
771 | 10.3k | if (pdev->PDFA != 0) { |
772 | 0 | sflush(writer.binary.strm); |
773 | 0 | s_MD5C_get_digest(writer.binary.strm, digest, sizeof(digest)); |
774 | 0 | } |
775 | 10.3k | *ppcd = (cos_dict_t *)writer.pres->object; |
776 | 10.3k | if (code < 0) { |
777 | 150 | pdf_end_fontfile(pdev, &writer); |
778 | 150 | pdf_obj_mark_unused(pdev, writer.pres->object->id); |
779 | 150 | return code; |
780 | 150 | } |
781 | 10.1k | code = pdf_end_fontfile(pdev, &writer); |
782 | 10.1k | break; |
783 | | |
784 | 0 | default: |
785 | 0 | code = gs_note_error(gs_error_rangecheck); |
786 | 10.3k | } |
787 | | |
788 | 10.1k | pbfont->written = true; |
789 | 10.1k | return code; |
790 | 10.3k | } |
791 | | |
792 | | /* |
793 | | * Write the CharSet for a subsetted font, as a PDF string. |
794 | | */ |
795 | | int |
796 | | pdf_write_CharSet(gx_device_pdf *pdev, pdf_base_font_t *pbfont) |
797 | 7.65k | { |
798 | 7.65k | stream *s = pdev->strm; |
799 | 7.65k | gs_font_base *font = pbfont->copied; |
800 | 7.65k | int index; |
801 | 7.65k | gs_glyph glyph; |
802 | | |
803 | 7.65k | stream_puts(s, "("); |
804 | 7.65k | for (index = 0; |
805 | 203k | (font->procs.enumerate_glyph((gs_font *)font, &index, |
806 | 203k | GLYPH_SPACE_NAME, &glyph), |
807 | 203k | index != 0); |
808 | 195k | ) { |
809 | 195k | gs_const_string gstr; |
810 | 195k | int code = font->procs.glyph_name((gs_font *)font, glyph, &gstr); |
811 | | |
812 | | /* Don't include .notdef. */ |
813 | 195k | if (code >= 0 && |
814 | 195k | bytes_compare(gstr.data, gstr.size, (const byte *)".notdef", 7) |
815 | 195k | ) |
816 | 187k | pdf_put_name(pdev, gstr.data, gstr.size); |
817 | 195k | } |
818 | 7.65k | stream_puts(s, ")"); |
819 | 7.65k | return 0; |
820 | 7.65k | } |
821 | | |
822 | | /* |
823 | | * Write the CIDSet object for a subsetted CIDFont. |
824 | | */ |
825 | | int |
826 | | pdf_write_CIDSet(gx_device_pdf *pdev, pdf_base_font_t *pbfont, |
827 | | long *pcidset_id) |
828 | 201 | { |
829 | 201 | pdf_data_writer_t writer; |
830 | 201 | int code; |
831 | | |
832 | 201 | code = pdf_begin_data_stream(pdev, &writer, |
833 | 201 | DATA_STREAM_BINARY | |
834 | 201 | (pdev->CompressFonts ? DATA_STREAM_COMPRESS : 0), |
835 | 201 | gs_no_id); |
836 | 201 | if (code < 0) |
837 | 0 | return code; |
838 | 201 | stream_write(writer.binary.strm, pbfont->CIDSet, |
839 | 201 | pbfont->CIDSetLength); |
840 | 201 | code = pdf_end_data(&writer); |
841 | 201 | if (code < 0) |
842 | 0 | return code; |
843 | 201 | *pcidset_id = pdf_resource_id(writer.pres); |
844 | 201 | return 0; |
845 | 201 | } |
846 | | /* |
847 | | * Check whether a base font is standard. |
848 | | */ |
849 | | bool |
850 | | pdf_is_standard_font(pdf_base_font_t *bfont) |
851 | 0 | { return bfont->is_standard; |
852 | 0 | } |
853 | | |
854 | | void |
855 | | pdf_set_FontFile_object(pdf_base_font_t *bfont, cos_dict_t *pcd) |
856 | 10.1k | { |
857 | 10.1k | bfont->FontFile = pcd; |
858 | 10.1k | } |
859 | | const cos_dict_t * |
860 | | pdf_get_FontFile_object(pdf_base_font_t *bfont) |
861 | 10.3k | { |
862 | 10.3k | return bfont->FontFile; |
863 | 10.3k | } |