1 /* Copyright (C) 2002 Aladdin Enterprises. All rights reserved.
2
3 This software is provided AS-IS with no warranty, either express or
4 implied.
5
6 This software is distributed under license and may not be copied,
7 modified or distributed except as expressly authorized under the terms
8 of the license contained in the file LICENSE in this distribution.
9
10 For more information about licensing, please refer to
11 http://www.ghostscript.com/licensing/. For information on
12 commercial licensing, go to http://www.artifex.com/licensing/ or
13 contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14 San Rafael, CA 94903, U.S.A., +1(415)492-9861.
15 */
16
17 /* $Id: gdevpdtt.c,v 1.104 2005/10/12 08:16:50 leonardo Exp $ */
18 /* Text processing for pdfwrite. */
19 #include "math_.h"
20 #include "string_.h"
21 #include "gx.h"
22 #include "gserrors.h"
23 #include "gscencs.h"
24 #include "gscedata.h"
25 #include "gsmatrix.h"
26 #include "gzstate.h"
27 #include "gxfcache.h" /* for orig_fonts list */
28 #include "gxfont.h"
29 #include "gxfont0.h"
30 #include "gxfcid.h"
31 #include "gxfcopy.h"
32 #include "gxfcmap.h"
33 #include "gxpath.h" /* for getting current point */
34 #include "gxchar.h"
35 #include "gxstate.h"
36 #include "gdevpdfx.h"
37 #include "gdevpdfg.h"
38 #include "gdevpdtx.h"
39 #include "gdevpdtd.h"
40 #include "gdevpdtf.h"
41 #include "gdevpdts.h"
42 #include "gdevpdtt.h"
43 #include "gdevpdti.h"
44 #include "gxhldevc.h"
45
46 /* ================ Text enumerator ================ */
47
48 /* GC descriptor */
49 private_st_pdf_text_enum();
50
51 /* Define the auxiliary procedures for text processing. */
52 private int
pdf_text_resync(gs_text_enum_t * pte,const gs_text_enum_t * pfrom)53 pdf_text_resync(gs_text_enum_t *pte, const gs_text_enum_t *pfrom)
54 {
55 pdf_text_enum_t *const penum = (pdf_text_enum_t *)pte;
56
57 if ((pte->text.operation ^ pfrom->text.operation) & ~TEXT_FROM_ANY)
58 return_error(gs_error_rangecheck);
59 if (penum->pte_default) {
60 int code = gs_text_resync(penum->pte_default, pfrom);
61
62 if (code < 0)
63 return code;
64 }
65 pte->text = pfrom->text;
66 gs_text_enum_copy_dynamic(pte, pfrom, false);
67 return 0;
68 }
69 private bool
pdf_text_is_width_only(const gs_text_enum_t * pte)70 pdf_text_is_width_only(const gs_text_enum_t *pte)
71 {
72 const pdf_text_enum_t *const penum = (const pdf_text_enum_t *)pte;
73
74 if (penum->pte_default)
75 return gs_text_is_width_only(penum->pte_default);
76 return false;
77 }
78 private int
pdf_text_current_width(const gs_text_enum_t * pte,gs_point * pwidth)79 pdf_text_current_width(const gs_text_enum_t *pte, gs_point *pwidth)
80 {
81 const pdf_text_enum_t *const penum = (const pdf_text_enum_t *)pte;
82
83 if (penum->pte_default)
84 return gs_text_current_width(penum->pte_default, pwidth);
85 return_error(gs_error_rangecheck); /* can't happen */
86 }
87 private int
pdf_text_set_cache(gs_text_enum_t * pte,const double * pw,gs_text_cache_control_t control)88 pdf_text_set_cache(gs_text_enum_t *pte, const double *pw,
89 gs_text_cache_control_t control)
90 {
91 pdf_text_enum_t *const penum = (pdf_text_enum_t *)pte;
92 gx_device_pdf *pdev = (gx_device_pdf *)pte->dev;
93
94 switch (control) {
95 case TEXT_SET_CHAR_WIDTH:
96 case TEXT_SET_CACHE_DEVICE:
97 gs_distance_transform(pw[0], pw[1], &ctm_only(pte->pis), &pdev->char_width);
98 break;
99 case TEXT_SET_CACHE_DEVICE2:
100 /*
101 * pdev->char_width is used with synthesized Type 3 fonts only.
102 * Since they are simple fonts, we only need the horisontal
103 * width for Widths array. Therefore we don't check
104 * gs_rootfont(pgs)->WMode and don't use pw[6:7].
105 */
106 gs_distance_transform(pw[0], pw[1], &ctm_only(pte->pis), &pdev->char_width);
107 if (penum->cdevproc_callout) {
108 memcpy(penum->cdevproc_result, pw, sizeof(penum->cdevproc_result));
109 return 0;
110 }
111 break;
112 default:
113 return_error(gs_error_rangecheck);
114 }
115 if (penum->current_font->FontType == ft_user_defined &&
116 penum->orig_font->FontType != ft_composite &&
117 penum->outer_CID == GS_NO_GLYPH &&
118 !(penum->pte_default->text.operation & TEXT_DO_CHARWIDTH)) {
119 int code;
120 gs_font *font = penum->orig_font;
121 gs_char ch;
122 gs_glyph glyph;
123 gs_const_string gnstr;
124
125 if (penum->text.operation & TEXT_FROM_SINGLE_GLYPH) {
126 byte buf[1];
127 int char_code_length;
128
129 glyph = pte->text.data.d_glyph;
130 code = pdf_encode_glyph((gs_font_base *)font, glyph,
131 buf, sizeof(buf), &char_code_length);
132 if (code < 0) {
133 /* Must not happen, becuse pdf_encode_glyph was passed in process_plain_text.*/
134 ch = GS_NO_CHAR;
135 } else if (char_code_length != 1) {
136 /* Must not happen with type 3 fonts.*/
137 ch = GS_NO_CHAR;
138 } else
139 ch = buf[0];
140 } else {
141 ch = penum->text.data.bytes[penum->index];
142 glyph = font->procs.encode_char(font, ch, GLYPH_SPACE_NAME);
143 /*
144 * If glyph == GS_NO_GLYPH, we should replace it with
145 * a notdef glyph, but we don't know how to do with Type 3 fonts.
146 */
147 }
148 if (glyph != GS_NO_GLYPH && ch != GS_NO_CHAR) {
149 gs_show_enum *penum_s;
150 extern_st(st_gs_show_enum);
151 gs_fixed_rect clip_box;
152 double pw1[10];
153 int narg = (control == TEXT_SET_CHAR_WIDTH ? 2 :
154 control == TEXT_SET_CACHE_DEVICE ? 6 : 10), i;
155
156 if (penum->pte_default == NULL)
157 return_error(gs_error_unregistered); /* Must not happen. */
158 /* Check to verify the structure type is really gs_show_enum */
159 if (gs_object_type(penum->pte_default->memory, penum->pte_default) != &st_gs_show_enum) {
160 /* Must not happen with PS interpreter.
161 Other clients should conform. */
162 return_error(gs_error_unregistered);
163 }
164 penum_s = (gs_show_enum *)penum->pte_default;
165 code = font->procs.glyph_name(font, glyph, &gnstr);
166 if (code < 0)
167 return_error(gs_error_unregistered); /* Must not happen. */
168 /* BuildChar could change the scale before calling setcachedevice (Bug 687290).
169 We must scale the setcachedevice arguments because we assumed
170 identity scale before entering the charproc.
171 For now we only handle scaling matrices.
172 */
173 for (i = 0; i < narg; i += 2) {
174 gs_point p;
175
176 gs_point_transform(pw[i], pw[i + 1], &ctm_only(penum_s->pgs), &p);
177 pw1[i] = p.x;
178 pw1[i + 1] = p.y;
179 }
180 if (control != TEXT_SET_CHAR_WIDTH) {
181 clip_box.p.x = float2fixed(pw1[2]);
182 clip_box.p.y = float2fixed(pw1[3]);
183 clip_box.q.x = float2fixed(pw1[4]);
184 clip_box.q.y = float2fixed(pw1[5]);
185 } else {
186 /*
187 * We have no character bbox, but we need one to install the clipping
188 * to the graphic state of the PS interpreter. Since some fonts don't
189 * provide a proper FontBBox (Bug 687239 supplies a zero one),
190 * we set an "infinite" clipping here.
191 * We also detected that min_int, max_int don't work here with
192 * comparefiles/Bug687044.ps, therefore we divide them by 2.
193 */
194 clip_box.p.x = clip_box.p.y = min_int / 2;
195 clip_box.q.x = clip_box.q.y = max_int / 2;
196 }
197 code = gx_clip_to_rectangle(penum_s->pgs, &clip_box);
198 if (code < 0)
199 return code;
200 code = pdf_set_charproc_attrs(pdev, pte->current_font,
201 pw1, narg, control, ch, &gnstr);
202 if (code < 0)
203 return code;
204 /* Prevent writing the clipping path to charproc.
205 See the comment above and bugs 687678, 688327.
206 Note that the clipping in the graphic state will be used while
207 fallbacks to default implementations of graphic objects.
208 Hopely such fallbacks are rare. */
209 pdev->clip_path_id = gx_get_clip_path_id(penum_s->pgs);
210 penum->charproc_accum = true;
211 return code;
212 } else {
213 gs_matrix m;
214 pdf_resource_t *pres = pdev->accumulating_substream_resource;
215
216 /* pdf_text_process started a charproc stream accumulation,
217 but now we re-decided to go with the default implementation.
218 Cancel the stream now.
219 */
220 code = pdf_exit_substream(pdev);
221 if (code < 0)
222 return code;
223 code = pdf_cancel_resource(pdev, pres, resourceCharProc);
224 if (code < 0)
225 return code;
226 pdf_forget_resource(pdev, pres, resourceCharProc);
227 /* pdf_text_process had set an identity CTM for the
228 charproc stream accumulation, but now we re-decided
229 to go with the default implementation.
230 Need to restore the correct CTM and add
231 changes, which the charproc possibly did. */
232 gs_matrix_multiply((gs_matrix *)&pdev->charproc_ctm, (gs_matrix *)&penum->pis->ctm, &m);
233 gs_matrix_fixed_from_matrix(&penum->pis->ctm, &m);
234 }
235 }
236 if (penum->pte_default) {
237 if (penum->pte_default->text.operation & TEXT_DO_CHARWIDTH /* See process_cmap_text.*/)
238 return gs_text_set_cache(penum->pte_default, pw, TEXT_SET_CHAR_WIDTH);
239 else
240 return gs_text_set_cache(penum->pte_default, pw, control);
241 }
242 return_error(gs_error_unregistered); /* can't happen */
243 }
244 private int
pdf_text_retry(gs_text_enum_t * pte)245 pdf_text_retry(gs_text_enum_t *pte)
246 {
247 pdf_text_enum_t *const penum = (pdf_text_enum_t *)pte;
248
249 if (penum->pte_default)
250 return gs_text_retry(penum->pte_default);
251 return_error(gs_error_rangecheck); /* can't happen */
252 }
253 private void
pdf_text_release(gs_text_enum_t * pte,client_name_t cname)254 pdf_text_release(gs_text_enum_t *pte, client_name_t cname)
255 {
256 pdf_text_enum_t *const penum = (pdf_text_enum_t *)pte;
257
258 if (penum->pte_default) {
259 gs_text_release(penum->pte_default, cname);
260 penum->pte_default = 0;
261 }
262 pdf_text_release_cgp(penum);
263 gx_default_text_release(pte, cname);
264 }
265 void
pdf_text_release_cgp(pdf_text_enum_t * penum)266 pdf_text_release_cgp(pdf_text_enum_t *penum)
267 {
268 if (penum->cgp) {
269 gs_free_object(penum->memory, penum->cgp, "pdf_text_release");
270 penum->cgp = 0;
271 }
272 }
273
274 /* Begin processing text. */
275 private text_enum_proc_process(pdf_text_process);
276 private const gs_text_enum_procs_t pdf_text_procs = {
277 pdf_text_resync, pdf_text_process,
278 pdf_text_is_width_only, pdf_text_current_width,
279 pdf_text_set_cache, pdf_text_retry,
280 pdf_text_release
281 };
282
283 private int
pdf_prepare_text_drawing(gx_device_pdf * const pdev,gs_text_enum_t * pte)284 pdf_prepare_text_drawing(gx_device_pdf *const pdev, gs_text_enum_t *pte)
285 {
286 gs_imager_state * pis = pte->pis;
287 const gx_device_color * pdcolor = pte->pdcolor;
288 const gx_clip_path * pcpath = pte->pcpath;
289 const gs_text_params_t *text = &pte->text;
290 bool new_clip = false; /* Quiet compiler. */
291 int code;
292
293 if (!(text->operation & TEXT_DO_NONE) || pis->text_rendering_mode == 3) {
294 new_clip = pdf_must_put_clip_path(pdev, pcpath);
295 if (new_clip)
296 code = pdf_unclip(pdev);
297 else if (pdev->context == PDF_IN_NONE)
298 code = pdf_open_page(pdev, PDF_IN_STREAM);
299 else
300 code = 0;
301 if (code < 0)
302 return code;
303 code = pdf_prepare_fill(pdev, pis);
304 if (code < 0)
305 return code;
306 }
307 if (text->operation & TEXT_DO_DRAW) {
308 /*
309 * Set the clipping path and drawing color. We set both the fill
310 * and stroke color, because we don't know whether the fonts will be
311 * filled or stroked, and we can't set a color while we are in text
312 * mode. (This is a consequence of the implementation, not a
313 * limitation of PDF.)
314 */
315
316 if (new_clip) {
317 code = pdf_put_clip_path(pdev, pcpath);
318 if (code < 0)
319 return code;
320 }
321
322 if ((code =
323 pdf_set_drawing_color(pdev, pis, pdcolor, &pdev->saved_stroke_color,
324 &pdev->stroke_used_process_color,
325 &psdf_set_stroke_color_commands)) < 0 ||
326 (code =
327 pdf_set_drawing_color(pdev, pis, pdcolor, &pdev->saved_fill_color,
328 &pdev->fill_used_process_color,
329 &psdf_set_fill_color_commands)) < 0
330 )
331 return code;
332 }
333 return 0;
334 }
335
336 int
gdev_pdf_text_begin(gx_device * dev,gs_imager_state * pis,const gs_text_params_t * text,gs_font * font,gx_path * path0,const gx_device_color * pdcolor,const gx_clip_path * pcpath,gs_memory_t * mem,gs_text_enum_t ** ppte)337 gdev_pdf_text_begin(gx_device * dev, gs_imager_state * pis,
338 const gs_text_params_t *text, gs_font * font,
339 gx_path * path0, const gx_device_color * pdcolor,
340 const gx_clip_path * pcpath,
341 gs_memory_t * mem, gs_text_enum_t ** ppte)
342 {
343 gx_device_pdf *const pdev = (gx_device_pdf *)dev;
344 gx_path *path = path0;
345 pdf_text_enum_t *penum;
346 gs_fixed_point cpt;
347 int code;
348
349 /* Track the dominant text rotation. */
350 {
351 gs_matrix tmat;
352 int i;
353
354 gs_matrix_multiply(&font->FontMatrix, &ctm_only(pis), &tmat);
355 if (is_xxyy(&tmat))
356 i = (tmat.xx >= 0 ? 0 : 2);
357 else if (is_xyyx(&tmat))
358 i = (tmat.xy >= 0 ? 1 : 3);
359 else
360 i = 4;
361 pdf_current_page(pdev)->text_rotation.counts[i] += text->size;
362 }
363
364 if (font->FontType == ft_user_defined &&
365 (text->operation & TEXT_DO_NONE) && (text->operation & TEXT_RETURN_WIDTH)) {
366 /* This is stringwidth, see gx_default_text_begin.
367 * We need to prevent writing characters to PS cache,
368 * otherwise the font converts to bitmaps.
369 * So pass through even with stringwidth.
370 */
371 code = gx_hld_stringwidth_begin(pis, &path);
372 if (code < 0)
373 return code;
374 } else if ((!(text->operation & TEXT_DO_DRAW) && pis->text_rendering_mode != 3)
375 || path == 0 || gx_path_current_point(path, &cpt) < 0
376 )
377 return gx_default_text_begin(dev, pis, text, font, path, pdcolor,
378 pcpath, mem, ppte);
379
380 /* Allocate and initialize the enumerator. */
381
382 rc_alloc_struct_1(penum, pdf_text_enum_t, &st_pdf_text_enum, mem,
383 return_error(gs_error_VMerror), "gdev_pdf_text_begin");
384 penum->rc.free = rc_free_text_enum;
385 penum->pte_default = 0;
386 penum->charproc_accum = false;
387 penum->cdevproc_callout = false;
388 penum->returned.total_width.x = penum->returned.total_width.y = 0;
389 penum->cgp = NULL;
390 code = gs_text_enum_init((gs_text_enum_t *)penum, &pdf_text_procs,
391 dev, pis, text, font, path, pdcolor, pcpath, mem);
392 if (code < 0) {
393 gs_free_object(mem, penum, "gdev_pdf_text_begin");
394 return code;
395 }
396 if (pdev->font3 != 0) {
397 /* A text operation happens while accumulating a charproc.
398 This is a case when source document uses a Type 3 font,
399 which's charproc uses another font.
400 Since the text operation is handled by the device,
401 the font isn't converting to a raster (i.e. to a bitmap font).
402 Disable the grid fitting for the convertion to get a proper outlines,
403 because the viewer resolution is not known during the accumulation.
404 Note we set identity CTM in pdf_text_set_cache for the accumilation,
405 and therefore the font may look too small while the source charproc
406 interpretation. The document tpc2.ps of the bug 687087 is an example.
407 */
408 penum->device_disabled_grid_fitting = true;
409 }
410
411 *ppte = (gs_text_enum_t *)penum;
412
413 return 0;
414 }
415
416 /* ================ Font cache element ================ */
417
418 /* GC descriptor */
419 private_st_pdf_font_cache_elem();
420
421 /*
422 * Compute id for a font cache element.
423 */
424 private ulong
pdf_font_cache_elem_id(gs_font * font)425 pdf_font_cache_elem_id(gs_font *font)
426 {
427 #if 0
428 /*
429 * For compatibility with Ghostscript rasterizer's
430 * cache logic we use UniqueID to identify fonts.
431 * Note that with buggy documents, which don't
432 * undefine UniqueID redefining a font,
433 * Ghostscript PS interpreter can occasionaly
434 * replace cache elements on insufficient cache size,
435 * taking glyphs from random fonts with random metrics,
436 * therefore the compatibility isn't complete.
437 */
438 /*
439 * This branch is incompatible with pdf_notify_remove_font.
440 */
441 if (font->FontType == ft_composite || font->PaintType != 0 ||
442 !uid_is_valid(&(((gs_font_base *)font)->UID)))
443 return font->id;
444 else
445 return ((gs_font_base *)font)->UID.id;
446 #else
447 return font->id;
448 #endif
449 }
450
451 private pdf_font_cache_elem_t **
pdf_locate_font_cache_elem(gx_device_pdf * pdev,gs_font * font)452 pdf_locate_font_cache_elem(gx_device_pdf *pdev, gs_font *font)
453 {
454 pdf_font_cache_elem_t **e = &pdev->font_cache;
455 long id = pdf_font_cache_elem_id(font);
456
457 for (; *e != 0; e = &(*e)->next)
458 if ((*e)->font_id == id) {
459 return e;
460 }
461 return 0;
462 }
463
464 private void
pdf_remove_font_cache_elem(pdf_font_cache_elem_t * e0)465 pdf_remove_font_cache_elem(pdf_font_cache_elem_t *e0)
466 {
467 gx_device_pdf *pdev = e0->pdev;
468 pdf_font_cache_elem_t **e = &pdev->font_cache;
469
470 for (; *e != 0; e = &(*e)->next)
471 if (*e == e0) {
472 *e = e0->next;
473 gs_free_object(pdev->pdf_memory, e0->glyph_usage,
474 "pdf_remove_font_cache_elem");
475 gs_free_object(pdev->pdf_memory, e0->real_widths,
476 "pdf_remove_font_cache_elem");
477 e0->glyph_usage = 0;
478 e0->real_widths = 0;
479 gs_free_object(pdev->pdf_memory, e0,
480 "pdf_remove_font_cache_elem");
481 return;
482 }
483 }
484
485 private void
font_cache_elem_array_sizes(gx_device_pdf * pdev,gs_font * font,int * num_widths,int * num_chars)486 font_cache_elem_array_sizes(gx_device_pdf *pdev, gs_font *font,
487 int *num_widths, int *num_chars)
488 {
489 switch (font->FontType) {
490 case ft_composite:
491 *num_widths = 0; /* Unused for Type 0 */
492 *num_chars = 65536; /* No chance to determine, use max. */
493 break;
494 case ft_encrypted:
495 case ft_encrypted2:
496 case ft_user_defined:
497 case ft_disk_based:
498 case ft_Chameleon:
499 case ft_TrueType:
500 *num_widths = *num_chars = 256; /* Assuming access to glyph_usage by character codes */
501 break;
502 case ft_CID_encrypted:
503 *num_widths = *num_chars = ((gs_font_cid0 *)font)->cidata.common.CIDCount;
504 break;
505 case ft_CID_TrueType:
506 *num_widths = *num_chars = ((gs_font_cid2 *)font)->cidata.common.CIDCount;
507 break;
508 default:
509 *num_widths = *num_chars = 65536; /* No chance to determine, use max. */
510 }
511 }
512
513 private int
alloc_font_cache_elem_arrays(gx_device_pdf * pdev,pdf_font_cache_elem_t * e,gs_font * font)514 alloc_font_cache_elem_arrays(gx_device_pdf *pdev, pdf_font_cache_elem_t *e,
515 gs_font *font)
516 {
517 int num_widths, num_chars, len;
518
519 font_cache_elem_array_sizes(pdev, font, &num_widths, &num_chars);
520 len = (num_chars + 7) / 8;
521 e->glyph_usage = gs_alloc_bytes(pdev->pdf_memory,
522 len, "alloc_font_cache_elem_arrays");
523
524 e->real_widths = (num_widths > 0 ? (double *)gs_alloc_bytes(pdev->pdf_memory,
525 num_widths * sizeof(*e->real_widths) *
526 (font->FontType == ft_user_defined ? 2 : 1),
527 "alloc_font_cache_elem_arrays") : NULL);
528 if (e->glyph_usage == NULL || (num_widths !=0 && e->real_widths == NULL)) {
529 gs_free_object(pdev->pdf_memory, e->glyph_usage,
530 "pdf_attach_font_resource");
531 gs_free_object(pdev->pdf_memory, e->real_widths,
532 "alloc_font_cache_elem_arrays");
533 return_error(gs_error_VMerror);
534 }
535 e->num_chars = num_chars;
536 e->num_widths = num_widths;
537 memset(e->glyph_usage, 0, len);
538 memset(e->real_widths, 0, num_widths * sizeof(*e->real_widths));
539 return 0;
540 }
541
542 int
pdf_free_font_cache(gx_device_pdf * pdev)543 pdf_free_font_cache(gx_device_pdf *pdev)
544 {
545 /* fixme : release elements. */
546 pdev->font_cache = NULL;
547 return 0;
548 }
549
550
551 /*
552 * Retrive font resource attached to a font,
553 * allocating glyph_usage and real_widths on request.
554 */
555 int
pdf_attached_font_resource(gx_device_pdf * pdev,gs_font * font,pdf_font_resource_t ** pdfont,byte ** glyph_usage,double ** real_widths,int * num_chars,int * num_widths)556 pdf_attached_font_resource(gx_device_pdf *pdev, gs_font *font,
557 pdf_font_resource_t **pdfont, byte **glyph_usage,
558 double **real_widths, int *num_chars, int *num_widths)
559 {
560 pdf_font_cache_elem_t **e = pdf_locate_font_cache_elem(pdev, font);
561
562 if (e != NULL && (((*e)->glyph_usage == NULL && glyph_usage !=NULL) ||
563 ((*e)->real_widths == NULL && real_widths !=NULL))) {
564 int code = alloc_font_cache_elem_arrays(pdev, *e, font);
565
566 if (code < 0)
567 return code;
568 }
569 *pdfont = (e == NULL ? NULL : (*e)->pdfont);
570 if (glyph_usage != NULL)
571 *glyph_usage = (e == NULL ? NULL : (*e)->glyph_usage);
572 if (real_widths != NULL)
573 *real_widths = (e == NULL ? NULL : (*e)->real_widths);
574 if (num_chars != NULL)
575 *num_chars = (e == NULL ? 0 : (*e)->num_chars);
576 if (num_widths != NULL)
577 *num_widths = (e == NULL ? 0 : (*e)->num_widths);
578 return 0;
579 }
580
581 private int
pdf_notify_remove_font(void * proc_data,void * event_data)582 pdf_notify_remove_font(void *proc_data, void *event_data)
583 { /* gs_font_finalize passes event_data == NULL, so check it here. */
584 if (event_data == NULL)
585 pdf_remove_font_cache_elem((pdf_font_cache_elem_t *)proc_data);
586 return 0;
587 }
588
589 /*
590 * Attach font resource to a font.
591 */
592 int
pdf_attach_font_resource(gx_device_pdf * pdev,gs_font * font,pdf_font_resource_t * pdfont)593 pdf_attach_font_resource(gx_device_pdf *pdev, gs_font *font,
594 pdf_font_resource_t *pdfont)
595 {
596 int num_chars, num_widths, len;
597 pdf_font_cache_elem_t *e, **pe = pdf_locate_font_cache_elem(pdev, font);
598
599 if (pdfont->FontType != font->FontType)
600 return_error(gs_error_unregistered); /* Must not happen. */
601 font_cache_elem_array_sizes(pdev, font, &num_widths, &num_chars);
602 len = (num_chars + 7) / 8;
603 if (pe != NULL) {
604 e = *pe;
605 if (e->pdfont == pdfont)
606 return 0;
607 e->pdfont = pdfont;
608 /* Reset glyph cache because e->pdfont had changed. */
609 memset(e->glyph_usage, 0, len);
610 memset(e->real_widths, 0, num_widths * sizeof(*e->real_widths));
611 } else {
612 int code;
613 e = (pdf_font_cache_elem_t *)gs_alloc_struct(pdev->pdf_memory,
614 pdf_font_cache_elem_t, &st_pdf_font_cache_elem,
615 "pdf_attach_font_resource");
616 if (e == NULL)
617 return_error(gs_error_VMerror);
618 e->pdfont = pdfont;
619 e->font_id = pdf_font_cache_elem_id(font);
620 e->num_chars = 0;
621 e->glyph_usage = NULL;
622 e->real_widths = NULL;
623 e->pdev = pdev;
624 e->next = pdev->font_cache;
625 pdev->font_cache = e;
626 code = gs_notify_register(&font->notify_list, pdf_notify_remove_font, e);
627 if (code < 0)
628 return code;
629 }
630 return 0;
631 }
632
633 /* ================ Process text ================ */
634
635 /* ---------------- Internal utilities ---------------- */
636
637 /*
638 * Compute and return the orig_matrix of a font.
639 */
640 int
pdf_font_orig_matrix(const gs_font * font,gs_matrix * pmat)641 pdf_font_orig_matrix(const gs_font *font, gs_matrix *pmat)
642 {
643 switch (font->FontType) {
644 case ft_composite: /* subfonts have their own FontMatrix */
645 case ft_TrueType:
646 case ft_CID_TrueType:
647 /* The TrueType FontMatrix is 1 unit per em, which is what we want. */
648 gs_make_identity(pmat);
649 return 0;
650 case ft_encrypted:
651 case ft_encrypted2:
652 case ft_CID_encrypted:
653 case ft_user_defined:
654 /*
655 * Type 1 fonts are supposed to use a standard FontMatrix of
656 * [0.001 0 0 0.001 0 0], with a 1000-unit cell. However,
657 * Windows NT 4.0 creates Type 1 fonts, apparently derived from
658 * TrueType fonts, that use a 2048-unit cell and corresponding
659 * FontMatrix. Also, some PS programs perform font scaling by
660 * replacing FontMatrix like this :
661 *
662 * /f12 /Times-Roman findfont
663 * copyfont % (remove FID)
664 * dup /FontMatrix [0.012 0 0 0.012 0 0] put
665 * definefont
666 * /f12 1 selectfont
667 *
668 * Such fonts are their own "base font", but the orig_matrix
669 * must still be set to 0.001, not 0.012 .
670 *
671 * The old code used a heuristic to detect and correct for this here.
672 * Unfortunately it doesn't work properly when it meets a font
673 * with FontMatrix like this :
674 *
675 * /FontMatrix [1 2288 div 0 0 1 2288 div 0 0 ] def
676 *
677 * (the bug 686970). Also comparefiles\455690.pdf appears to
678 * have similar problem. Therefore we added a support to lib/gs_fonts.ps,
679 * src/zbfont.c, src/gsfont.c that provides an acces to the original
680 * font via a special key .OrigFont added to the font dictionary while definefont.
681 * Now we work through this access with PS interpreter,
682 * but keep the old heuristic for other clients.
683 */
684 {
685 const gs_font *base_font = font;
686
687 while (base_font->base != base_font)
688 base_font = base_font->base;
689 if (font->FontType == ft_user_defined)
690 *pmat = base_font->FontMatrix;
691 else if (base_font->orig_FontMatrix.xx != 0 || base_font->orig_FontMatrix.xy != 0 ||
692 base_font->orig_FontMatrix.yx != 0 || base_font->orig_FontMatrix.yy != 0)
693 *pmat = base_font->orig_FontMatrix;
694 else {
695 /* Must not happen with PS interpreter.
696 Provide a hewuristic for other clients.
697 */
698 if (base_font->FontMatrix.xx == 1.0/2048 &&
699 base_font->FontMatrix.xy == 0 &&
700 base_font->FontMatrix.yx == 0 &&
701 any_abs(base_font->FontMatrix.yy) == 1.0/2048
702 )
703 *pmat = base_font->FontMatrix;
704 else
705 gs_make_scaling(0.001, 0.001, pmat);
706 }
707 }
708 return 0;
709 default:
710 return_error(gs_error_rangecheck);
711 }
712 }
713
714 int
font_orig_scale(const gs_font * font,double * sx)715 font_orig_scale(const gs_font *font, double *sx)
716 {
717 gs_matrix mat;
718 int code = pdf_font_orig_matrix(font, &mat);
719
720 if (code < 0)
721 return code;
722 *sx = mat.xx;
723 return 0;
724 }
725
726 /*
727 * Check the Encoding compatibility
728 */
729 bool
pdf_check_encoding_compatibility(const pdf_font_resource_t * pdfont,const pdf_char_glyph_pair_t * pairs,int num_chars)730 pdf_check_encoding_compatibility(const pdf_font_resource_t *pdfont,
731 const pdf_char_glyph_pair_t *pairs, int num_chars)
732 {
733 int i;
734
735 for (i = 0; i < num_chars; ++i) {
736 gs_char ch = pairs[i].chr;
737 pdf_encoding_element_t *pet = &pdfont->u.simple.Encoding[ch];
738
739 if (pairs[i].glyph == pet->glyph)
740 continue;
741 if (pet->glyph != GS_NO_GLYPH) /* encoding conflict */
742 return false;
743 }
744 return true;
745 }
746
747 /*
748 * Check font resource for encoding compatibility.
749 */
750 private bool
pdf_is_compatible_encoding(gx_device_pdf * pdev,pdf_font_resource_t * pdfont,gs_font * font,const pdf_char_glyph_pair_t * pairs,int num_chars)751 pdf_is_compatible_encoding(gx_device_pdf *pdev, pdf_font_resource_t *pdfont,
752 gs_font *font, const pdf_char_glyph_pair_t *pairs, int num_chars)
753 {
754 /*
755 * This crude version of the code ignores
756 * the possibility of re-encoding characters.
757 */
758 switch (pdfont->FontType) {
759 case ft_composite:
760 { /*
761 * We assume that source document don't redefine CMap
762 * resources and that incremental CMaps do not exist.
763 * Therefore we don't maintain stable CMap copies,
764 * but just compare CMap names for equality.
765 * A better implementation should compare the chars->glyphs
766 * translation against the stable copy of CMap,
767 * which to be handled with PDF CMap resource.
768 */
769 gs_font_type0 *pfont = (gs_font_type0 *)font;
770
771 if (pfont->data.FMapType == fmap_CMap) {
772 const gs_cmap_t *pcmap = pfont->data.CMap;
773 const gs_const_string *s0 = &pdfont->u.type0.CMapName;
774 const gs_const_string *s1 = &pcmap->CMapName;
775
776 return (s0->size == s1->size &&
777 !memcmp(s0->data, s1->data, s0->size));
778 }
779 }
780 return false;
781 case ft_user_defined:
782 if (pdfont->u.simple.Encoding == NULL)
783 return false; /* Not sure. Happens with 020-01.ps . */
784 /* fall through */
785 case ft_encrypted:
786 case ft_encrypted2:
787 case ft_TrueType:
788 return pdf_check_encoding_compatibility(pdfont, pairs, num_chars);
789 case ft_CID_encrypted:
790 case ft_CID_TrueType:
791 {
792 gs_font *font1 = (gs_font *)pdf_font_resource_font(pdfont, false);
793
794 return gs_is_CIDSystemInfo_compatible(
795 gs_font_cid_system_info(font),
796 gs_font_cid_system_info(font1));
797 }
798 default:
799 return false;
800 }
801 }
802
803 /*
804 * Find a font resource compatible with a given font.
805 */
806 private int
pdf_find_font_resource(gx_device_pdf * pdev,gs_font * font,pdf_resource_type_t type,pdf_font_resource_t ** ppdfont,pdf_char_glyph_pairs_t * cgp)807 pdf_find_font_resource(gx_device_pdf *pdev, gs_font *font,
808 pdf_resource_type_t type,
809 pdf_font_resource_t **ppdfont,
810 pdf_char_glyph_pairs_t *cgp)
811 {
812 pdf_resource_t **pchain = pdev->resources[type].chains;
813 pdf_resource_t *pres;
814 int i;
815
816 for (i = 0; i < NUM_RESOURCE_CHAINS; i++) {
817 for (pres = pchain[i]; pres != 0; pres = pres->next) {
818 pdf_font_resource_t *pdfont = (pdf_font_resource_t *)pres;
819 const gs_font_base *cfont;
820 gs_font *ofont = font;
821 int code;
822
823 if (font->FontType != pdfont->FontType)
824 continue;
825 if (pdfont->FontType == ft_composite) {
826 gs_font_type0 *font0 = (gs_font_type0 *)font;
827
828 ofont = font0->data.FDepVector[0]; /* See pdf_make_font_resource. */
829 cfont = pdf_font_resource_font(pdfont->u.type0.DescendantFont, false);
830 if (font0->data.CMap->WMode != pdfont->u.type0.WMode)
831 continue;
832 } else
833 cfont = pdf_font_resource_font(pdfont, false);
834 if (!pdf_is_CID_font(ofont) &&
835 !pdf_is_compatible_encoding(pdev, pdfont, font, cgp->s, cgp->num_all_chars))
836 continue;
837 if (cfont == 0)
838 continue;
839 code = gs_copied_can_copy_glyphs((const gs_font *)cfont, ofont,
840 &cgp->s[cgp->unused_offset].glyph, cgp->num_unused_chars,
841 sizeof(pdf_char_glyph_pair_t), true);
842 if (code == gs_error_unregistered) /* Debug purpose only. */
843 return code;
844 if(code > 0) {
845 *ppdfont = pdfont;
846 return 1;
847 }
848 }
849 }
850 return 0;
851 }
852
853 /*
854 * Find a type0 font resource for a gived descendent name and CMap name.
855 */
856 private int
pdf_find_type0_font_resource(gx_device_pdf * pdev,const pdf_font_resource_t * pdsubf,const gs_const_string * CMapName,pdf_font_resource_t ** ppdfont)857 pdf_find_type0_font_resource(gx_device_pdf *pdev, const pdf_font_resource_t *pdsubf,
858 const gs_const_string *CMapName, pdf_font_resource_t **ppdfont)
859 {
860 pdf_resource_t **pchain = pdev->resources[resourceFont].chains;
861 pdf_resource_t *pres;
862 int i;
863
864 for (i = 0; i < NUM_RESOURCE_CHAINS; i++) {
865 for (pres = pchain[i]; pres != 0; pres = pres->next) {
866 pdf_font_resource_t *pdfont = (pdf_font_resource_t *)pres;
867
868 if (pdfont->FontType != ft_composite)
869 continue;
870 if (pdfont->u.type0.DescendantFont != pdsubf)
871 continue;
872 if (pdfont->BaseFont.size != pdsubf->BaseFont.size + CMapName->size + 1)
873 continue;
874 if (memcmp(pdfont->BaseFont.data + pdsubf->BaseFont.size + 1,
875 CMapName->data, CMapName->size))
876 continue;
877 *ppdfont = pdfont;
878 return 1;
879 }
880 }
881 return 0;
882 }
883
884
885 private int pdf_make_font_resource(gx_device_pdf *pdev, gs_font *font,
886 pdf_font_resource_t **ppdfont,
887 pdf_char_glyph_pairs_t *cgp);
888
889 /*
890 * Create or find a CID font resource object for a glyph set.
891 */
892 int
pdf_obtain_cidfont_resource(gx_device_pdf * pdev,gs_font * subfont,pdf_font_resource_t ** ppdsubf,pdf_char_glyph_pairs_t * cgp)893 pdf_obtain_cidfont_resource(gx_device_pdf *pdev, gs_font *subfont,
894 pdf_font_resource_t **ppdsubf,
895 pdf_char_glyph_pairs_t *cgp)
896 {
897 int code = 0;
898
899 pdf_attached_font_resource(pdev, subfont, ppdsubf, NULL, NULL, NULL, NULL);
900 if (*ppdsubf != NULL) {
901 const gs_font_base *cfont = pdf_font_resource_font(*ppdsubf, false);
902
903 code = gs_copied_can_copy_glyphs((const gs_font *)cfont, subfont,
904 &cgp->s[cgp->unused_offset].glyph, cgp->num_unused_chars,
905 sizeof(pdf_char_glyph_pair_t), true);
906 if (code > 0)
907 return 0;
908 if (code < 0)
909 return code;
910 *ppdsubf = NULL;
911 }
912 code = pdf_find_font_resource(pdev, subfont,
913 resourceCIDFont, ppdsubf, cgp);
914 if (code < 0)
915 return code;
916 if (*ppdsubf == NULL) {
917 code = pdf_make_font_resource(pdev, subfont, ppdsubf, cgp);
918 if (code < 0)
919 return code;
920 }
921 return pdf_attach_font_resource(pdev, subfont, *ppdsubf);
922 }
923
924 /*
925 * Refine index of BaseEncoding.
926 */
927 private int
pdf_refine_encoding_index(const gx_device_pdf * pdev,int index,bool is_standard)928 pdf_refine_encoding_index(const gx_device_pdf *pdev, int index, bool is_standard)
929 {
930 if (pdev->ForOPDFRead) {
931 /*
932 * Allow Postscript encodings only.
933 */
934 switch (index) {
935
936 case ENCODING_INDEX_STANDARD: return index;
937 case ENCODING_INDEX_ISOLATIN1: return index;
938 default:
939 return ENCODING_INDEX_STANDARD;
940 }
941 }
942 /*
943 * Per the PDF 1.3 documentation, there are only 3 BaseEncoding
944 * values allowed for non-embedded fonts. Pick one here.
945 */
946 switch (index) {
947 case ENCODING_INDEX_WINANSI:
948 case ENCODING_INDEX_MACROMAN:
949 case ENCODING_INDEX_MACEXPERT:
950 return index;
951 case ENCODING_INDEX_STANDARD:
952 if (is_standard)
953 return index;
954 /* Falls through. */
955 default:
956 return ENCODING_INDEX_WINANSI;
957 }
958 }
959
960 /*
961 * Create a font resource object for a gs_font of Type 3.
962 */
963 int
pdf_make_font3_resource(gx_device_pdf * pdev,gs_font * font,pdf_font_resource_t ** ppdfont)964 pdf_make_font3_resource(gx_device_pdf *pdev, gs_font *font,
965 pdf_font_resource_t **ppdfont)
966 {
967 const gs_font_base *bfont = (const gs_font_base *)font;
968 pdf_font_resource_t *pdfont;
969 byte *cached;
970 int code;
971
972 cached = gs_alloc_bytes(pdev->pdf_memory, 256/8, "pdf_make_font3_resource");
973 if (cached == NULL)
974 return_error(gs_error_VMerror);
975 code = font_resource_encoded_alloc(pdev, &pdfont, bfont->id,
976 ft_user_defined, pdf_write_contents_bitmap);
977 if (code < 0) {
978 gs_free_object(pdev->pdf_memory, cached, "pdf_make_font3_resource");
979 return code;
980 }
981 memset(cached, 0, 256 / 8);
982 pdfont->u.simple.s.type3.bitmap_font = false;
983 pdfont->u.simple.BaseEncoding = pdf_refine_encoding_index(pdev,
984 bfont->nearest_encoding_index, true);
985 pdfont->u.simple.s.type3.char_procs = NULL;
986 pdfont->u.simple.s.type3.cached = cached;
987 pdfont->u.simple.s.type3.FontBBox.p.x = (int)floor(bfont->FontBBox.p.x);
988 pdfont->u.simple.s.type3.FontBBox.p.y = (int)floor(bfont->FontBBox.p.y);
989 pdfont->u.simple.s.type3.FontBBox.q.x = (int)ceil(bfont->FontBBox.q.x);
990 pdfont->u.simple.s.type3.FontBBox.q.y = (int)ceil(bfont->FontBBox.q.y);
991 pdfont->u.simple.s.type3.FontMatrix = bfont->FontMatrix;
992 /* Adobe viewers have a precision problem with small font matrices : */
993 while (any_abs(pdfont->u.simple.s.type3.FontMatrix.xx) < 0.001 &&
994 any_abs(pdfont->u.simple.s.type3.FontMatrix.xy) < 0.001 &&
995 any_abs(pdfont->u.simple.s.type3.FontMatrix.yx) < 0.001 &&
996 any_abs(pdfont->u.simple.s.type3.FontMatrix.yy) < 0.001) {
997 pdfont->u.simple.s.type3.FontMatrix.xx *= 10;
998 pdfont->u.simple.s.type3.FontMatrix.xy *= 10;
999 pdfont->u.simple.s.type3.FontMatrix.yx *= 10;
1000 pdfont->u.simple.s.type3.FontMatrix.yy *= 10;
1001 }
1002 *ppdfont = pdfont;
1003 return 0;
1004 }
1005
1006 /*
1007 * Create a font resource object for a gs_font. Return 1 iff the
1008 * font was newly created (it's a roudiment, keeping reverse compatibility).
1009 * This procedure is only intended to be called
1010 * from a few places in the text code.
1011 */
1012 private int
pdf_make_font_resource(gx_device_pdf * pdev,gs_font * font,pdf_font_resource_t ** ppdfont,pdf_char_glyph_pairs_t * cgp)1013 pdf_make_font_resource(gx_device_pdf *pdev, gs_font *font,
1014 pdf_font_resource_t **ppdfont,
1015 pdf_char_glyph_pairs_t *cgp)
1016 {
1017 int index = -1;
1018 int BaseEncoding = ENCODING_INDEX_UNKNOWN;
1019 pdf_font_embed_t embed;
1020 pdf_font_descriptor_t *pfd = 0;
1021 int (*font_alloc)(gx_device_pdf *, pdf_font_resource_t **,
1022 gs_id, pdf_font_descriptor_t *);
1023 gs_font *base_font = font; /* A roudiment from old code. Keep it for a while. */
1024 pdf_font_resource_t *pdfont;
1025 pdf_standard_font_t *const psfa =
1026 pdev->text->outline_fonts->standard_fonts;
1027 int code = 0;
1028
1029 if (pdev->version < psdf_version_level2_with_TT) {
1030 switch(font->FontType) {
1031 case ft_TrueType:
1032 case ft_CID_TrueType:
1033 return_error(gs_error_undefined);
1034 default:
1035 break;
1036 }
1037 }
1038 if (pdev->ForOPDFRead && !pdev->HaveCIDSystem) {
1039 switch(font->FontType) {
1040 case ft_CID_encrypted:
1041 case ft_CID_TrueType:
1042 return_error(gs_error_undefined);
1043 default:
1044 break;
1045 }
1046 }
1047 if (!pdev->HaveCFF) {
1048 if (font->FontType == ft_encrypted2)
1049 return_error(gs_error_undefined);
1050 }
1051 embed = pdf_font_embed_status(pdev, base_font, &index, cgp->s, cgp->num_all_chars);
1052 if (embed == FONT_EMBED_STANDARD) {
1053 pdf_standard_font_t *psf = &psfa[index];
1054
1055 if (psf->pdfont == NULL ||
1056 !pdf_is_compatible_encoding(pdev, psf->pdfont, font,
1057 cgp->s, cgp->num_all_chars)) {
1058 code = pdf_font_std_alloc(pdev, ppdfont, (psf->pdfont == NULL), base_font->id,
1059 (gs_font_base *)base_font, index);
1060 if (code < 0)
1061 return code;
1062 if (psf->pdfont == NULL)
1063 psf->pdfont = *ppdfont;
1064 (*ppdfont)->u.simple.BaseEncoding = pdf_refine_encoding_index(pdev,
1065 ((const gs_font_base *)base_font)->nearest_encoding_index, true);
1066 code = 1;
1067 } else
1068 *ppdfont = psf->pdfont;
1069 return code;
1070 }
1071
1072 switch (font->FontType) {
1073 case ft_CID_encrypted:
1074 case ft_CID_TrueType:
1075 font_alloc = pdf_font_cidfont_alloc;
1076 break;
1077 case ft_encrypted:
1078 case ft_encrypted2:
1079 case ft_TrueType:
1080 font_alloc = pdf_font_simple_alloc;
1081 break;
1082 case ft_user_defined:
1083 code = pdf_make_font3_resource(pdev, font, ppdfont);
1084 if (code < 0)
1085 return code;
1086 return 1;
1087 default:
1088 return_error(gs_error_invalidfont);
1089 }
1090
1091 /* Create an appropriate font resource and descriptor. */
1092 if (embed == FONT_EMBED_YES) {
1093 /*
1094 * HACK: Acrobat Reader 3 has a bug that makes cmap formats 4
1095 * and 6 not work in embedded TrueType fonts. Consequently, it
1096 * can only handle embedded TrueType fonts if all the glyphs
1097 * referenced by the Encoding have numbers 0-255. Check for
1098 * this now.
1099 */
1100 if (font->FontType == ft_TrueType &&
1101 pdev->CompatibilityLevel <= 1.2
1102 ) {
1103 int i;
1104
1105 for (i = 0; i <= 0xff; ++i) {
1106 gs_glyph glyph =
1107 font->procs.encode_char(font, (gs_char)i,
1108 GLYPH_SPACE_INDEX);
1109
1110 if (glyph == GS_NO_GLYPH ||
1111 (glyph >= GS_MIN_GLYPH_INDEX &&
1112 glyph <= GS_MIN_GLYPH_INDEX + 0xff)
1113 )
1114 continue;
1115 /* Can't embed, punt. */
1116 return_error(gs_error_rangecheck);
1117 }
1118 }
1119 }
1120 if (font->FontType == ft_encrypted || font->FontType == ft_encrypted2 ||
1121 font->FontType == ft_TrueType) {
1122 /*
1123 * We write True Types with Symbolic flag set.
1124 * PDF spec says that "symbolic font should not specify Encoding entry"
1125 * (see section 5.5, the article "Encodings for True Type fonts", paragraph 3).
1126 * However Acrobat Reader 4,5,6 fail when TT font with no Encoding
1127 * appears in a document together with a CID font with a non-standard CMap
1128 * (AR 4 and 5 claim "The encoding (CMap) specified by a font is corrupted."
1129 * (we read it as "The encoding or CMap specified by a font is corrupted.",
1130 * and apply the 1st alternative)). We believe that AR is buggy,
1131 * and therefore we write an Encoding with non-CID True Type fonts.
1132 * Hopely other viewers can ignore Encoding in such case. Actually in this case
1133 * an Encoding doesn't add an useful information.
1134 */
1135 BaseEncoding = pdf_refine_encoding_index(pdev,
1136 ((const gs_font_base *)base_font)->nearest_encoding_index, false);
1137 }
1138 if ((code = pdf_font_descriptor_alloc(pdev, &pfd,
1139 (gs_font_base *)base_font,
1140 embed == FONT_EMBED_YES)) < 0 ||
1141 (code = font_alloc(pdev, &pdfont, base_font->id, pfd)) < 0
1142 )
1143 return code;
1144 code = 1;
1145
1146 if (!pdf_is_CID_font(font))
1147 pdfont->u.simple.BaseEncoding = BaseEncoding;
1148
1149 *ppdfont = pdfont;
1150 return 1;
1151 }
1152
1153 /* Get a synthesized Type 3 font scale. */
1154 void
pdf_font3_scale(gx_device_pdf * pdev,gs_font * font,double * scale)1155 pdf_font3_scale(gx_device_pdf *pdev, gs_font *font, double *scale)
1156 {
1157 pdf_font_resource_t *pdfont;
1158
1159 pdf_attached_font_resource(pdev, font, &pdfont, NULL, NULL, NULL, NULL);
1160 *scale = pdfont->u.simple.s.type3.FontMatrix.xx;
1161 }
1162
1163 /*
1164 * Check for simple font.
1165 */
1166 bool
pdf_is_simple_font(gs_font * font)1167 pdf_is_simple_font(gs_font *font)
1168 {
1169 return (font->FontType == ft_encrypted ||
1170 font->FontType == ft_encrypted2 ||
1171 font->FontType == ft_TrueType ||
1172 font->FontType == ft_user_defined);
1173 }
1174
1175 /*
1176 * Check for CID font.
1177 */
1178 bool
pdf_is_CID_font(gs_font * font)1179 pdf_is_CID_font(gs_font *font)
1180 {
1181 return (font->FontType == ft_CID_encrypted ||
1182 font->FontType == ft_CID_TrueType);
1183 }
1184
1185 /*
1186 * Enumerate glyphs for a text.
1187 */
1188 private int
pdf_next_char_glyph(gs_text_enum_t * penum,const gs_string * pstr,gs_font * font,bool font_is_simple,gs_char * char_code,gs_char * cid,gs_glyph * glyph)1189 pdf_next_char_glyph(gs_text_enum_t *penum, const gs_string *pstr,
1190 /* const */ gs_font *font, bool font_is_simple,
1191 gs_char *char_code, gs_char *cid, gs_glyph *glyph)
1192 {
1193 int code = font->procs.next_char_glyph(penum, char_code, glyph);
1194
1195 if (code == 2) /* end of string */
1196 return code;
1197 if (code < 0)
1198 return code;
1199 if (font_is_simple) {
1200 *cid = *char_code;
1201 *glyph = font->procs.encode_char(font, *char_code, GLYPH_SPACE_NAME);
1202 if (*glyph == GS_NO_GLYPH)
1203 return 3;
1204 } else {
1205 if (*glyph < GS_MIN_CID_GLYPH)
1206 return 3; /* Not sure why, copied from scan_cmap_text. */
1207 *cid = *glyph - GS_MIN_CID_GLYPH; /* CID */
1208 }
1209 return 0;
1210 }
1211
1212 private void
store_glyphs(pdf_char_glyph_pairs_t * cgp,byte * glyph_usage,int char_cache_size,gs_char char_code,gs_char cid,gs_glyph glyph)1213 store_glyphs(pdf_char_glyph_pairs_t *cgp,
1214 byte *glyph_usage, int char_cache_size,
1215 gs_char char_code, gs_char cid, gs_glyph glyph)
1216 {
1217 int j;
1218
1219 for (j = 0; j < cgp->num_all_chars; j++)
1220 if (cgp->s[j].chr == cid)
1221 break;
1222 if (j < cgp->num_all_chars)
1223 return;
1224 cgp->s[cgp->num_all_chars].glyph = glyph;
1225 cgp->s[cgp->num_all_chars].chr = char_code;
1226 cgp->num_all_chars++;
1227 if (glyph_usage == 0 || !(glyph_usage[cid / 8] & (0x80 >> (cid & 7)))) {
1228 cgp->s[cgp->unused_offset + cgp->num_unused_chars].glyph = glyph;
1229 cgp->s[cgp->unused_offset + cgp->num_unused_chars].chr = char_code;
1230 cgp->num_unused_chars++;
1231 }
1232 /* We are disliked that gs_copied_can_copy_glyphs can get redundant
1233 * glyphs, if Encoding specifies several codes for same glyph.
1234 * But we need the positional correspondence
1235 * of glyphs to codes for pdf_is_compatible_encoding.
1236 * Redundant glyphs isn't a big payment for it
1237 * because they happen seldom.
1238 */
1239 }
1240
1241 /* Allocate storage for the glyph set of the text. */
1242 private int
pdf_alloc_text_glyphs_table(gx_device_pdf * pdev,pdf_text_enum_t * penum,const gs_string * pstr)1243 pdf_alloc_text_glyphs_table(gx_device_pdf *pdev, pdf_text_enum_t *penum, const gs_string *pstr)
1244 {
1245 const int go = (pstr != NULL ? pstr->size : penum->text.size);
1246 const int struct_size = sizeof(pdf_char_glyph_pairs_t) +
1247 sizeof(pdf_char_glyph_pair_t) * (2 * go - 1);
1248 pdf_char_glyph_pairs_t *cgp = (pdf_char_glyph_pairs_t *)gs_alloc_bytes(penum->memory,
1249 struct_size, "pdf_alloc_text_glyphs_table");
1250 if (cgp == NULL)
1251 return_error(gs_error_VMerror);
1252 penum->cgp = cgp;
1253 cgp->unused_offset = go;
1254 cgp->num_all_chars = 0;
1255 cgp->num_unused_chars = 0;
1256 return 0;
1257 }
1258
1259 /* Build the glyph set of the text. */
1260 private int
pdf_make_text_glyphs_table(pdf_text_enum_t * penum,const gs_string * pstr,byte * glyph_usage,int char_cache_size)1261 pdf_make_text_glyphs_table(pdf_text_enum_t *penum, const gs_string *pstr,
1262 byte *glyph_usage, int char_cache_size)
1263 {
1264 gs_text_enum_t scan = *(gs_text_enum_t *)penum;
1265 gs_font *font = (gs_font *)penum->current_font;
1266 bool font_is_simple = pdf_is_simple_font(font);
1267 pdf_char_glyph_pairs_t *cgp = penum->cgp;
1268 gs_char char_code, cid;
1269 gs_glyph glyph;
1270 int code;
1271
1272 cgp->num_unused_chars = 0;
1273 cgp->num_all_chars = 0;
1274 if (pstr != NULL) {
1275 scan.text.data.bytes = pstr->data;
1276 scan.text.size = pstr->size;
1277 scan.index = 0;
1278 /* if TEXT_FROM_CHARS the data was converted to bytes earlier */
1279 if ( scan.text.operation & TEXT_FROM_CHARS )
1280 scan.text.operation = ((scan.text.operation & ~TEXT_FROM_CHARS) | TEXT_FROM_STRING);
1281 }
1282 for (;;) {
1283 code = pdf_next_char_glyph(&scan, pstr, font, font_is_simple,
1284 &char_code, &cid, &glyph);
1285 if (code == 2) /* end of string */
1286 break;
1287 if (code == 3) /* no glyph */
1288 continue;
1289 if (code < 0)
1290 return code;
1291 if (cgp->num_all_chars > cgp->unused_offset)
1292 return_error(gs_error_unregistered); /* Must not happen. */
1293 if (glyph_usage != 0 && cid > char_cache_size)
1294 continue;
1295 store_glyphs(cgp, glyph_usage, char_cache_size,
1296 char_code, cid, glyph);
1297 }
1298 return 0;
1299 }
1300
1301 /* Build the glyph set of the glyphshow text, and re_encode the text. */
1302 private int
pdf_make_text_glyphs_table_unencoded(pdf_char_glyph_pairs_t * cgp,gs_font * font,const gs_string * pstr,const gs_glyph * gdata,int * ps_encoding_index)1303 pdf_make_text_glyphs_table_unencoded(pdf_char_glyph_pairs_t *cgp,
1304 gs_font *font, const gs_string *pstr, const gs_glyph *gdata,
1305 int *ps_encoding_index)
1306 {
1307 int i, ei;
1308 gs_char ch;
1309 gs_const_string gname;
1310 gs_glyph *gid = (gs_glyph *)pstr->data; /* pdf_text_process allocs enough space. */
1311
1312 /* Translate glyph name indices into gscencs.c indices. */
1313 for (i = 0; i < pstr->size; i++) {
1314 int code = font->procs.glyph_name(font, gdata[i], &gname);
1315
1316 if (code < 0)
1317 return code;
1318 gid[i] = gs_c_name_glyph(gname.data, gname.size);
1319 if (gid[i] == GS_NO_GLYPH)
1320 return_error(gs_error_rangecheck);
1321 }
1322
1323 /* Find an acceptable encodng. */
1324 for (ei = 0; gs_c_known_encodings[ei]; ei++) {
1325 cgp->num_unused_chars = 0;
1326 cgp->num_all_chars = 0;
1327 for (i = 0; i < pstr->size; i++) {
1328 ch = gs_c_decode(gid[i], ei);
1329 if (ch == GS_NO_CHAR)
1330 break;
1331 /* pstr->data[i] = (byte)ch; Can't do because pstr->data and gid
1332 are same pointer. Will do in a separate pass below. */
1333 store_glyphs(cgp, NULL, 0,
1334 ch, ch, gdata[i]);
1335 }
1336 *ps_encoding_index = ei;
1337 if (i == pstr->size) {
1338 for (i = 0; i < pstr->size; i++)
1339 pstr->data[i] = (byte)gs_c_decode(gid[i], ei);
1340 return 0;
1341 }
1342 }
1343 return_error(gs_error_rangecheck);
1344 }
1345
1346
1347 /* Get/make font resource for the font with a known encoding. */
1348 private int
pdf_obtain_font_resource_encoded(gx_device_pdf * pdev,gs_font * font,pdf_font_resource_t ** ppdfont,pdf_char_glyph_pairs_t * cgp)1349 pdf_obtain_font_resource_encoded(gx_device_pdf *pdev, gs_font *font,
1350 pdf_font_resource_t **ppdfont, pdf_char_glyph_pairs_t *cgp)
1351 {
1352 int code;
1353 pdf_font_resource_t *pdfont_not_allowed = NULL;
1354
1355 if (*ppdfont != 0) {
1356 gs_font_base *cfont = pdf_font_resource_font(*ppdfont, false);
1357
1358 if (font->FontType != ft_user_defined) {
1359 code = gs_copied_can_copy_glyphs((gs_font *)cfont, font,
1360 &cgp->s[cgp->unused_offset].glyph, cgp->num_unused_chars,
1361 sizeof(pdf_char_glyph_pair_t), true);
1362 if (code < 0)
1363 return code;
1364 } else
1365 code = 1;
1366 if (code == 0) {
1367 pdfont_not_allowed = *ppdfont;
1368 *ppdfont = 0;
1369 } else if(!pdf_is_compatible_encoding(pdev, *ppdfont, font,
1370 cgp->s, cgp->num_all_chars)) {
1371 pdfont_not_allowed = *ppdfont;
1372 *ppdfont = 0;
1373 }
1374 }
1375 if (*ppdfont == 0) {
1376 gs_font *base_font = font;
1377 gs_font *below;
1378 bool same_encoding = true;
1379
1380 /*
1381 * Find the "lowest" base font that has the same outlines.
1382 * We use its FontName for font resource.
1383 */
1384 while ((below = base_font->base) != base_font &&
1385 base_font->procs.same_font(base_font, below, FONT_SAME_OUTLINES))
1386 base_font = below;
1387 if (base_font != font)
1388 same_encoding = ((base_font->procs.same_font(base_font, font,
1389 FONT_SAME_ENCODING) & FONT_SAME_ENCODING) != 0);
1390 /* Find or make font resource. */
1391 pdf_attached_font_resource(pdev, base_font, ppdfont, NULL, NULL, NULL, NULL);
1392 if (*ppdfont != NULL && base_font != font) {
1393 if (pdfont_not_allowed == *ppdfont)
1394 *ppdfont = NULL;
1395 else if(!pdf_is_compatible_encoding(pdev, *ppdfont,
1396 base_font, cgp->s, cgp->num_all_chars))
1397 *ppdfont = NULL;
1398 }
1399 if (*ppdfont == NULL || *ppdfont == pdfont_not_allowed) {
1400 pdf_resource_type_t type =
1401 (pdf_is_CID_font(base_font) ? resourceCIDFont
1402 : resourceFont);
1403 *ppdfont = NULL;
1404 code = pdf_find_font_resource(pdev, base_font, type, ppdfont, cgp);
1405 if (code < 0)
1406 return code;
1407 if (*ppdfont == NULL) {
1408 code = pdf_make_font_resource(pdev, base_font, ppdfont, cgp);
1409 if (code < 0)
1410 return code;
1411 }
1412 if (base_font != font && same_encoding) {
1413 code = pdf_attach_font_resource(pdev, base_font, *ppdfont);
1414 if (code < 0)
1415 return code;
1416 }
1417 }
1418 code = pdf_attach_font_resource(pdev, font, *ppdfont);
1419 if (code < 0)
1420 return code;
1421 }
1422 return 0;
1423 }
1424
1425 /* Mark glyphs used in the text with the font resource. */
1426 private int
pdf_mark_text_glyphs(const gs_text_enum_t * penum,const gs_string * pstr,byte * glyph_usage,int char_cache_size)1427 pdf_mark_text_glyphs(const gs_text_enum_t *penum, const gs_string *pstr,
1428 byte *glyph_usage, int char_cache_size)
1429 {
1430 gs_text_enum_t scan = *penum;
1431 gs_font *font = (gs_font *)penum->current_font;
1432 bool font_is_simple = pdf_is_simple_font(font);
1433 gs_char char_code, cid;
1434 gs_glyph glyph;
1435
1436 if (pstr != NULL) {
1437 scan.text.data.bytes = pstr->data;
1438 scan.text.size = pstr->size;
1439 scan.index = 0;
1440 /* if TEXT_FROM_CHARS the data was converted to bytes earlier */
1441 if ( scan.text.operation & TEXT_FROM_CHARS )
1442 scan.text.operation =
1443 ((scan.text.operation & ~TEXT_FROM_CHARS) | TEXT_FROM_STRING);
1444 }
1445 for (;;) {
1446 int code = pdf_next_char_glyph(&scan, pstr, font, font_is_simple,
1447 &char_code, &cid, &glyph);
1448
1449 if (code == 2) /* end of string */
1450 break;
1451 if (code == 3) /* no glyph */
1452 continue;
1453 if (code < 0)
1454 return code;
1455 if (glyph_usage != 0 && cid >= char_cache_size)
1456 continue;
1457 glyph_usage[cid / 8] |= 0x80 >> (cid & 7);
1458 }
1459 return 0;
1460 }
1461
1462 /* Mark glyphs used in the glyphshow text with the font resource. */
1463 private int
pdf_mark_text_glyphs_unencoded(const gs_text_enum_t * penum,const gs_string * pstr,byte * glyph_usage,int char_cache_size)1464 pdf_mark_text_glyphs_unencoded(const gs_text_enum_t *penum, const gs_string *pstr,
1465 byte *glyph_usage, int char_cache_size)
1466 {
1467 int i;
1468
1469 for(i = 0; i < pstr->size; i++) {
1470 byte ch = pstr->data[i];
1471
1472 if (ch >= char_cache_size)
1473 return_error(gs_error_rangecheck);
1474 glyph_usage[ch / 8] |= 0x80 >> (ch & 7);
1475 }
1476 return 0;
1477 }
1478
1479 /*
1480 * Create or find a font resource object for a text.
1481 */
1482 int
pdf_obtain_font_resource(pdf_text_enum_t * penum,const gs_string * pstr,pdf_font_resource_t ** ppdfont)1483 pdf_obtain_font_resource(pdf_text_enum_t *penum,
1484 const gs_string *pstr, pdf_font_resource_t **ppdfont)
1485 {
1486 gx_device_pdf *pdev = (gx_device_pdf *)penum->dev;
1487 gs_font *font = (gs_font *)penum->current_font;
1488 byte *glyph_usage = 0;
1489 double *real_widths;
1490 int char_cache_size, width_cache_size;
1491 int code;
1492
1493 if (font->FontType == ft_composite) {
1494 /* Must not happen, because we always split composite fonts into descendents. */
1495 return_error(gs_error_unregistered);
1496 }
1497 code = pdf_attached_font_resource(pdev, font, ppdfont,
1498 &glyph_usage, &real_widths, &char_cache_size, &width_cache_size);
1499 /* *ppdfont is NULL if no resource attached. */
1500 if (code < 0)
1501 return code;
1502 if (penum->cgp == NULL) {
1503 code = pdf_alloc_text_glyphs_table(pdev, penum, pstr);
1504 if (code < 0)
1505 return code;
1506 code = pdf_make_text_glyphs_table(penum, pstr,
1507 glyph_usage, char_cache_size);
1508 if (code < 0)
1509 return code;
1510 }
1511 code = pdf_obtain_font_resource_encoded(pdev, font, ppdfont, penum->cgp);
1512 if (code < 0)
1513 return code;
1514 code = pdf_attached_font_resource(pdev, font, ppdfont,
1515 &glyph_usage, &real_widths, &char_cache_size, &width_cache_size);
1516 if (code < 0)
1517 return code;
1518 return pdf_mark_text_glyphs((const gs_text_enum_t *)penum, pstr, glyph_usage, char_cache_size);
1519 }
1520
1521 /*
1522 * Create or find a font resource object for a glyphshow text.
1523 */
1524 int
pdf_obtain_font_resource_unencoded(pdf_text_enum_t * penum,const gs_string * pstr,pdf_font_resource_t ** ppdfont,const gs_glyph * gdata)1525 pdf_obtain_font_resource_unencoded(pdf_text_enum_t *penum,
1526 const gs_string *pstr, pdf_font_resource_t **ppdfont, const gs_glyph *gdata)
1527 {
1528 gx_device_pdf *pdev = (gx_device_pdf *)penum->dev;
1529 gs_font *font = (gs_font *)penum->current_font;
1530 byte *glyph_usage = 0;
1531 double *real_widths = 0;
1532 int char_cache_size = 0, width_cache_size = 0;
1533 int code, ps_encoding_index;
1534
1535 if (font->FontType == ft_composite) {
1536 /* Must not happen, because we always split composite fonts into descendents. */
1537 return_error(gs_error_unregistered);
1538 }
1539 code = pdf_attached_font_resource(pdev, font, ppdfont,
1540 &glyph_usage, &real_widths, &char_cache_size, &width_cache_size);
1541 if (code < 0)
1542 return code;
1543 /* *ppdfont is NULL if no resource attached. */
1544 if (penum->cgp == NULL) {
1545 code = pdf_alloc_text_glyphs_table(pdev, penum, pstr);
1546 if (code < 0)
1547 return code;
1548 code = pdf_make_text_glyphs_table_unencoded(penum->cgp, font, pstr, gdata,
1549 &ps_encoding_index);
1550 if (code < 0)
1551 return code;
1552 }
1553 code = pdf_obtain_font_resource_encoded(pdev, font, ppdfont, penum->cgp);
1554 if (code < 0)
1555 return code;
1556 code = pdf_attached_font_resource(pdev, font, ppdfont,
1557 &glyph_usage, &real_widths, &char_cache_size, &width_cache_size);
1558 if (code < 0)
1559 return code;
1560 return pdf_mark_text_glyphs_unencoded((const gs_text_enum_t *)penum,
1561 pstr, glyph_usage, char_cache_size);
1562 }
1563
1564 private inline bool
strings_equal(const gs_const_string * s1,const gs_const_string * s2)1565 strings_equal(const gs_const_string *s1, const gs_const_string *s2)
1566 {
1567 return s1->size == s2->size &&
1568 !memcmp(s1->data, s2->data, s1->size);
1569 }
1570
1571 /*
1572 * Create or find a parent Type 0 font resource object for a CID font resource.
1573 */
1574 int
pdf_obtain_parent_type0_font_resource(gx_device_pdf * pdev,pdf_font_resource_t * pdsubf,const gs_const_string * CMapName,pdf_font_resource_t ** pdfont)1575 pdf_obtain_parent_type0_font_resource(gx_device_pdf *pdev, pdf_font_resource_t *pdsubf,
1576 const gs_const_string *CMapName, pdf_font_resource_t **pdfont)
1577 {
1578 if (pdsubf->u.cidfont.parent != 0 &&
1579 strings_equal(CMapName, &pdsubf->u.cidfont.parent->u.type0.CMapName))
1580 *pdfont = pdsubf->u.cidfont.parent;
1581 else {
1582 /*
1583 * PDF spec 1.4 section 5.6 "Composite Fonts" says :
1584 *
1585 * PDF 1.2 introduces a general architecture for composite fonts that theoretically
1586 * allows a Type 0 font to have multiple descendants,which might themselves be
1587 * Type 0 fonts.However,in versions up to and including PDF 1.4,only a single
1588 * descendant is allowed,which must be a CIDFont (not a font).This restriction
1589 * may be relaxed in a future PDF version.
1590 */
1591
1592 if (pdsubf->u.cidfont.parent == NULL ||
1593 pdf_find_type0_font_resource(pdev, pdsubf, CMapName, pdfont) <= 0) {
1594 int code = pdf_font_type0_alloc(pdev, pdfont, gs_no_id, pdsubf, CMapName);
1595
1596 if (code < 0)
1597 return code;
1598 }
1599 pdsubf->u.cidfont.parent = *pdfont;
1600 }
1601 return 0;
1602 }
1603
1604 /*
1605 * Compute the cached values in the text processing state from the text
1606 * parameters, current_font, and pis->ctm. Return either an error code (<
1607 * 0) or a mask of operation attributes that the caller must emulate.
1608 * Currently the only such attributes are TEXT_ADD_TO_ALL_WIDTHS and
1609 * TEXT_ADD_TO_SPACE_WIDTH. Note that this procedure fills in all the
1610 * values in ppts->values, not just the ones that need to be set now.
1611 */
1612 private int
transform_delta_inverse(const gs_point * pdelta,const gs_matrix * pmat,gs_point * ppt)1613 transform_delta_inverse(const gs_point *pdelta, const gs_matrix *pmat,
1614 gs_point *ppt)
1615 {
1616 int code = gs_distance_transform_inverse(pdelta->x, pdelta->y, pmat, ppt);
1617 gs_point delta;
1618
1619 if (code < 0)
1620 return code;
1621 if (ppt->y == 0)
1622 return 0;
1623 /* Check for numerical fuzz. */
1624 code = gs_distance_transform(ppt->x, 0.0, pmat, &delta);
1625 if (code < 0)
1626 return 0; /* punt */
1627 if (fabs(delta.x - pdelta->x) < 0.01 && fabs(delta.y - pdelta->y) < 0.01) {
1628 /* Close enough to y == 0: device space error < 0.01 pixel. */
1629 ppt->y = 0;
1630 }
1631 return 0;
1632 }
1633 int
pdf_update_text_state(pdf_text_process_state_t * ppts,const pdf_text_enum_t * penum,pdf_font_resource_t * pdfont,const gs_matrix * pfmat)1634 pdf_update_text_state(pdf_text_process_state_t *ppts,
1635 const pdf_text_enum_t *penum,
1636 pdf_font_resource_t *pdfont, const gs_matrix *pfmat)
1637 {
1638 gx_device_pdf *const pdev = (gx_device_pdf *)penum->dev;
1639 gs_font *font = penum->current_font;
1640 gs_fixed_point cpt;
1641 gs_matrix orig_matrix, smat, tmat;
1642 double
1643 sx = pdev->HWResolution[0] / 72.0,
1644 sy = pdev->HWResolution[1] / 72.0;
1645 float size;
1646 float c_s = 0, w_s = 0;
1647 int mask = 0;
1648 int code = gx_path_current_point(penum->path, &cpt);
1649
1650 if (code < 0)
1651 return code;
1652
1653 /* Get the original matrix of the base font. */
1654
1655 {
1656 gs_font_base *cfont = pdf_font_resource_font(pdfont, false);
1657
1658 if (pdfont->FontType == ft_user_defined)
1659 orig_matrix = pdfont->u.simple.s.type3.FontMatrix;
1660 else if (cfont != 0) {
1661 /*
1662 * The text matrix to be computed relatively to the
1663 * embedded font matrix.
1664 */
1665 orig_matrix = cfont->FontMatrix;
1666 } else {
1667 /*
1668 * We don't embed the font.
1669 * The text matrix to be computed relatively to
1670 * standard font matrix.
1671 */
1672 pdf_font_orig_matrix(font, &orig_matrix);
1673 }
1674 }
1675
1676 /* Compute the scaling matrix and combined matrix. */
1677
1678 gs_matrix_invert(&orig_matrix, &smat);
1679 gs_matrix_multiply(&smat, pfmat, &smat);
1680 tmat = ctm_only(penum->pis);
1681 tmat.tx = tmat.ty = 0;
1682 gs_matrix_multiply(&smat, &tmat, &tmat);
1683
1684 /* Try to find a reasonable size value. This isn't necessary, */
1685 /* but it's worth a little effort. */
1686
1687 size = hypot(tmat.yx, tmat.yy) / sy;
1688 if (size < 0.01)
1689 size = hypot(tmat.xx, tmat.xy) / sx;
1690 if (size < 0.01)
1691 size = 1;
1692
1693 /* Check for spacing parameters we can handle, and transform them. */
1694
1695 if (penum->text.operation & TEXT_ADD_TO_ALL_WIDTHS) {
1696 if (penum->current_font->WMode == 0) {
1697 gs_point pt;
1698
1699 code = transform_delta_inverse(&penum->text.delta_all, &smat, &pt);
1700 if (code >= 0 && pt.y == 0)
1701 c_s = pt.x * size;
1702 else
1703 mask |= TEXT_ADD_TO_ALL_WIDTHS;
1704 }
1705 else
1706 mask |= TEXT_ADD_TO_ALL_WIDTHS;
1707 }
1708
1709 if (penum->text.operation & TEXT_ADD_TO_SPACE_WIDTH) {
1710 gs_point pt;
1711
1712 code = transform_delta_inverse(&penum->text.delta_space, &smat, &pt);
1713 if (code >= 0 && pt.y == 0 && penum->text.space.s_char == 32)
1714 w_s = pt.x * size;
1715 else
1716 mask |= TEXT_ADD_TO_SPACE_WIDTH;
1717 }
1718 /* Store the updated values. */
1719
1720 tmat.xx /= size;
1721 tmat.xy /= size;
1722 tmat.yx /= size;
1723 tmat.yy /= size;
1724 tmat.tx += fixed2float(cpt.x);
1725 tmat.ty += fixed2float(cpt.y);
1726
1727 ppts->values.character_spacing = c_s;
1728 ppts->values.pdfont = pdfont;
1729 ppts->values.size = size;
1730 ppts->values.matrix = tmat;
1731 ppts->values.render_mode = (penum->pis->text_rendering_mode == 3 ? 3 :
1732 font->PaintType == 0 ? 0 : 1);
1733 ppts->values.word_spacing = w_s;
1734 ppts->font = font;
1735
1736 code = pdf_set_text_process_state(pdev, (const gs_text_enum_t *)penum,
1737 ppts);
1738 return (code < 0 ? code : mask);
1739 }
1740
1741 /*
1742 * Set up commands to make the output state match the processing state.
1743 * General graphics state commands are written now; text state commands
1744 * are written later.
1745 */
1746 private double
font_matrix_scaling(const gs_font * font)1747 font_matrix_scaling(const gs_font *font)
1748 {
1749 return fabs((font->FontMatrix.yy != 0 ? font->FontMatrix.yy :
1750 font->FontMatrix.yx));
1751 }
1752 int
pdf_set_text_process_state(gx_device_pdf * pdev,const gs_text_enum_t * pte,pdf_text_process_state_t * ppts)1753 pdf_set_text_process_state(gx_device_pdf *pdev,
1754 const gs_text_enum_t *pte, /* for pdcolor, pis */
1755 pdf_text_process_state_t *ppts)
1756 {
1757 /*
1758 * Setting the stroke parameters may exit text mode, causing the
1759 * settings of the text parameters to be lost. Therefore, we set the
1760 * stroke parameters first.
1761 */
1762 if (pdf_render_mode_uses_stroke(pdev, &ppts->values)) {
1763 /* Write all the parameters for stroking. */
1764 gs_imager_state *pis = pte->pis;
1765 float save_width = pis->line_params.half_width;
1766 const gs_font *font = ppts->font;
1767 double scaled_width = font->StrokeWidth;
1768 int code;
1769
1770 /* Note that we compute pis->line_params.half_width in device space,
1771 * even though it logically represents a value in user space.
1772 * The 'scale' value compensates for this.
1773 */
1774 scaled_width *= font_matrix_scaling(font);
1775 scaled_width *= min(hypot(pte->pis->ctm.xx, pte->pis->ctm.yx) /
1776 pdev->HWResolution[0] * pdev->HWResolution[1],
1777 hypot(pte->pis->ctm.xy, pte->pis->ctm.yy));
1778 pis->line_params.half_width = scaled_width / 2;
1779 code = pdf_prepare_stroke(pdev, pis);
1780 if (code >= 0) {
1781 /*
1782 * See stream_to_text in gdevpdfu.c re the computation of
1783 * the scaling value.
1784 */
1785 double scale = 72.0 / pdev->HWResolution[1];
1786
1787 code = gdev_vector_prepare_stroke((gx_device_vector *)pdev,
1788 pis, NULL, NULL, scale);
1789 }
1790 pis->line_params.half_width = save_width;
1791 if (code < 0)
1792 return code;
1793 }
1794
1795 /* Now set all the other parameters. */
1796
1797 return pdf_set_text_state_values(pdev, &ppts->values);
1798 }
1799
1800 private int
store_glyph_width(pdf_glyph_width_t * pwidth,int wmode,double scale,const gs_glyph_info_t * pinfo)1801 store_glyph_width(pdf_glyph_width_t *pwidth, int wmode, double scale,
1802 const gs_glyph_info_t *pinfo)
1803 {
1804 double w, v;
1805
1806 pwidth->xy.x = pinfo->width[wmode].x * scale;
1807 pwidth->xy.y = pinfo->width[wmode].y * scale;
1808 if (wmode)
1809 w = pwidth->xy.y, v = pwidth->xy.x;
1810 else
1811 w = pwidth->xy.x, v = pwidth->xy.y;
1812 if (v != 0)
1813 return 1;
1814 pwidth->w = w;
1815 pwidth->v.x = pinfo->v.x * scale;
1816 pwidth->v.y = pinfo->v.y * scale;
1817 return 0;
1818 }
1819
1820 private int
get_missing_width(gs_font_base * cfont,int wmode,double scale_c,pdf_glyph_widths_t * pwidths)1821 get_missing_width(gs_font_base *cfont, int wmode, double scale_c,
1822 pdf_glyph_widths_t *pwidths)
1823 {
1824 gs_font_info_t finfo;
1825 int code;
1826
1827 code = cfont->procs.font_info((gs_font *)cfont, NULL,
1828 FONT_INFO_MISSING_WIDTH, &finfo);
1829 if (code < 0)
1830 return code;
1831 if (wmode) {
1832 pwidths->Width.xy.x = pwidths->real_width.xy.x = 0;
1833 pwidths->Width.xy.y = pwidths->real_width.xy.y =
1834 - finfo.MissingWidth * scale_c;
1835 pwidths->Width.w = pwidths->real_width.w =
1836 pwidths->Width.xy.y;
1837 pwidths->Width.v.x = - pwidths->Width.xy.y / 2;
1838 pwidths->Width.v.y = - pwidths->Width.xy.y;
1839 } else {
1840 pwidths->Width.xy.x = pwidths->real_width.xy.x =
1841 finfo.MissingWidth * scale_c;
1842 pwidths->Width.w = pwidths->real_width.w =
1843 pwidths->Width.xy.x;
1844 pwidths->Width.xy.y = pwidths->real_width.xy.y = 0;
1845 pwidths->Width.v.x = pwidths->Width.v.y = 0;
1846 }
1847 /*
1848 * Don't mark the width as known, just in case this is an
1849 * incrementally defined font.
1850 */
1851 return 1;
1852 }
1853
1854
1855 /*
1856 * Get the widths (unmodified from the copied font,
1857 * and possibly modified from the original font) of a given glyph.
1858 * Return 1 if the width was defaulted to MissingWidth.
1859 * Return TEXT_PROCESS_CDEVPROC if a CDevProc callout is needed.
1860 * cdevproc_result != NULL if we restart after a CDevProc callout.
1861 */
1862 int
pdf_glyph_widths(pdf_font_resource_t * pdfont,int wmode,gs_glyph glyph,gs_font * orig_font,pdf_glyph_widths_t * pwidths,const double cdevproc_result[10])1863 pdf_glyph_widths(pdf_font_resource_t *pdfont, int wmode, gs_glyph glyph,
1864 gs_font *orig_font, pdf_glyph_widths_t *pwidths,
1865 const double cdevproc_result[10])
1866 {
1867 gs_font_base *cfont = pdf_font_resource_font(pdfont, false);
1868 gs_font *ofont = orig_font;
1869 gs_glyph_info_t info;
1870 /*
1871 * orig_scale is 1.0 for TrueType, 0.001 or 1.0/2048 for Type 1.
1872 */
1873 double sxc, sxo;
1874 double scale_c, scale_o;
1875 int code, rcode = 0;
1876 gs_point v;
1877 int allow_cdevproc_callout = (orig_font->FontType == ft_CID_TrueType
1878 || orig_font->FontType == ft_CID_encrypted
1879 ? GLYPH_INFO_CDEVPROC : 0); /* fixme : allow more font types. */
1880
1881 if (ofont->FontType == ft_composite)
1882 return_error(gs_error_unregistered); /* Must not happen. */
1883 code = font_orig_scale((const gs_font *)cfont, &sxc);
1884 if (code < 0)
1885 return code;
1886 code = font_orig_scale(ofont, &sxo);
1887 if (code < 0)
1888 return code;
1889 scale_c = sxc * 1000.0;
1890 scale_o = sxo * 1000.0;
1891 pwidths->Width.v.x = pwidths->Width.v.y = 0;
1892 pwidths->real_width.v.x = pwidths->real_width.v.y = 0;
1893 pwidths->replaced_v = false;
1894 if (glyph == GS_NO_GLYPH)
1895 return get_missing_width(cfont, wmode, scale_c, pwidths);
1896 code = cfont->procs.glyph_info((gs_font *)cfont, glyph, NULL,
1897 GLYPH_INFO_WIDTH0 |
1898 (GLYPH_INFO_WIDTH0 << wmode) |
1899 GLYPH_INFO_OUTLINE_WIDTHS |
1900 (GLYPH_INFO_VVECTOR0 << wmode),
1901 &info);
1902 /* For CID fonts the PDF spec requires the x-component of v-vector
1903 to be equal to half glyph width, and AR5 takes it from W, DW.
1904 So make a compatibe data here.
1905 */
1906 if (code == gs_error_undefined || !(info.members & (GLYPH_INFO_WIDTH0 << wmode))) {
1907 code = get_missing_width(cfont, wmode, scale_c, pwidths);
1908 if (code < 0)
1909 v.y = 0;
1910 else
1911 v.y = pwidths->Width.v.y;
1912 if (wmode && pdf_is_CID_font(ofont)) {
1913 pdf_glyph_widths_t widths1;
1914
1915 if (get_missing_width(cfont, 0, scale_c, &widths1) < 0)
1916 v.x = 0;
1917 else
1918 v.x = widths1.Width.w / 2;
1919 } else
1920 v.x = pwidths->Width.v.x;
1921 } else if (code < 0)
1922 return code;
1923 else {
1924 code = store_glyph_width(&pwidths->Width, wmode, scale_c, &info);
1925 if (code < 0)
1926 return code;
1927 rcode |= code;
1928 if (info.members & (GLYPH_INFO_VVECTOR0 << wmode)) {
1929 v.y = info.v.y * scale_c;
1930 } else
1931 v.y = 0;
1932 if (wmode && pdf_is_CID_font(ofont)) {
1933 if (info.members & (GLYPH_INFO_WIDTH0 << wmode)) {
1934 v.x = info.width[0].x * scale_c / 2;
1935 } else {
1936 pdf_glyph_widths_t widths1;
1937
1938 if (get_missing_width(cfont, 0, scale_c, &widths1) < 0)
1939 v.x = 0;
1940 else
1941 v.x = widths1.Width.w / 2;
1942 }
1943 } else {
1944 if (info.members & (GLYPH_INFO_VVECTOR0 << wmode)) {
1945 v.x = info.v.x * scale_c;
1946 } else
1947 v.x = 0;
1948 }
1949 }
1950 pwidths->Width.v = v;
1951 #if 0
1952 if (code > 0)
1953 pwidths->Width.xy.x = pwidths->Width.xy.y = pwidths->Width.w = 0;
1954 #else /* Skip only if not paralel to the axis. */
1955 if (code > 0 && !pdf_is_CID_font(ofont))
1956 pwidths->Width.xy.x = pwidths->Width.xy.y = pwidths->Width.w = 0;
1957 #endif
1958 if (cdevproc_result == NULL) {
1959 code = ofont->procs.glyph_info(ofont, glyph, NULL,
1960 (GLYPH_INFO_WIDTH0 << wmode) |
1961 (GLYPH_INFO_VVECTOR0 << wmode) |
1962 allow_cdevproc_callout,
1963 &info);
1964 /* fixme : Move this call before cfont->procs.glyph_info. */
1965 if (info.members & GLYPH_INFO_CDEVPROC) {
1966 if (allow_cdevproc_callout)
1967 return TEXT_PROCESS_CDEVPROC;
1968 else
1969 return_error(gs_error_rangecheck);
1970 }
1971 } else {
1972 info.width[0].x = cdevproc_result[0];
1973 info.width[0].y = cdevproc_result[1];
1974 info.width[1].x = cdevproc_result[6];
1975 info.width[1].y = cdevproc_result[7];
1976 info.v.x = (wmode ? cdevproc_result[8] : 0);
1977 info.v.y = (wmode ? cdevproc_result[9] : 0);
1978 info.members = (GLYPH_INFO_WIDTH0 << wmode) |
1979 (wmode ? GLYPH_INFO_VVECTOR1 : 0);
1980 code = 0;
1981 }
1982 if (code == gs_error_undefined || !(info.members & (GLYPH_INFO_WIDTH0 << wmode)))
1983 pwidths->real_width = pwidths->Width;
1984 else if (code < 0)
1985 return code;
1986 else {
1987 if ((info.members & (GLYPH_INFO_VVECTOR0 | GLYPH_INFO_VVECTOR1)) != 0)
1988 pwidths->replaced_v = true;
1989 else
1990 info.v.x = info.v.y = 0;
1991 code = store_glyph_width(&pwidths->real_width, wmode, scale_o, &info);
1992 if (code < 0)
1993 return code;
1994 rcode |= code;
1995 pwidths->real_width.v.x = info.v.x * scale_o;
1996 pwidths->real_width.v.y = info.v.y * scale_o;
1997 }
1998 return rcode;
1999 }
2000 /* ---------------- Main entry ---------------- */
2001
2002 /*
2003 * Fall back to the default text processing code when needed.
2004 */
2005 int
pdf_default_text_begin(gs_text_enum_t * pte,const gs_text_params_t * text,gs_text_enum_t ** ppte)2006 pdf_default_text_begin(gs_text_enum_t *pte, const gs_text_params_t *text,
2007 gs_text_enum_t **ppte)
2008 {
2009 gs_text_params_t text1 = *text;
2010
2011 if(pte->current_font->FontType == 3 && (text1.operation & TEXT_DO_NONE)) {
2012 /* We need a real drawing to accumulate charproc. */
2013 text1.operation &= ~TEXT_DO_NONE;
2014 text1.operation |= TEXT_DO_DRAW;
2015 }
2016 return gx_default_text_begin(pte->dev, pte->pis, &text1, pte->current_font,
2017 pte->path, pte->pdcolor, pte->pcpath,
2018 pte->memory, ppte);
2019 }
2020
2021 /*
2022 * Continue processing text. This is the 'process' procedure in the text
2023 * enumerator. Per the check in pdf_text_begin, we know the operation is
2024 * not a charpath, but it could be anything else.
2025 */
2026 int
pdf_text_process(gs_text_enum_t * pte)2027 pdf_text_process(gs_text_enum_t *pte)
2028 {
2029 pdf_text_enum_t *const penum = (pdf_text_enum_t *)pte;
2030 uint operation = pte->text.operation;
2031 uint size = pte->text.size - pte->index;
2032 gs_text_enum_t *pte_default;
2033 PROCESS_TEXT_PROC((*process));
2034 int code;
2035 gx_device_pdf *pdev = (gx_device_pdf *)penum->dev;
2036 #define BUF_SIZE 100 /* arbitrary > 0 */
2037 /* Use a union to ensure alignment. */
2038 union bu_ {
2039 byte bytes[BUF_SIZE];
2040 gs_char chars[BUF_SIZE / sizeof(gs_char)];
2041 gs_glyph glyphs[BUF_SIZE / sizeof(gs_glyph)];
2042 } buf;
2043
2044 if (!penum->pte_default && !penum->charproc_accum) {
2045 /* Don't need to sync before exiting charproc. */
2046 code = pdf_prepare_text_drawing(pdev, pte);
2047 if (code == gs_error_rangecheck) {
2048 /* Fallback to the default implermentation for handling
2049 a transparency with CompatibilityLevel<=1.3 . */
2050 goto default_impl;
2051 }
2052 if (penum->outer_CID != GS_NO_GLYPH) {
2053 /* Fallback to the default implermentation for handling
2054 Type 3 fonts with CIDs, because currently Type 3
2055 font resource arrays' sizes are hardcoded to 256 glyphs.
2056 A better solution would be to re-encode the CID text with
2057 Type 3 glyph variations. */
2058 goto default_impl;
2059 }
2060 if (code < 0)
2061 return code;
2062 }
2063 if (!penum->pte_default) {
2064 pdev->charproc_just_accumulated = false;
2065 if (penum->cdevproc_callout) {
2066 /* Restore after TEXT_PROCESS_CDEVPROC in scan_cmap_text. */
2067 penum->current_font = penum->orig_font;
2068 }
2069 }
2070 code = -1; /* to force default implementation */
2071
2072 /*
2073 * If we fell back to the default implementation, continue using it.
2074 */
2075 top:
2076 pte_default = penum->pte_default;
2077 if (pte_default) {
2078 if (penum->charproc_accum) {
2079 code = pdf_end_charproc_accum(pdev, penum->current_font, penum->cgp);
2080 if (code < 0)
2081 return code;
2082 penum->charproc_accum = false;
2083 code = gx_default_text_restore_state(pte_default);
2084 if (code < 0)
2085 return code;
2086 gs_text_release(pte_default, "pdf_text_process");
2087 penum->pte_default = 0;
2088 goto top;
2089 }
2090 pdev->pte = pte_default; /* CAUTION: See comment in gdevpdfx.h . */
2091 code = gs_text_process(pte_default);
2092 pdev->pte = NULL; /* CAUTION: See comment in gdevpdfx.h . */
2093 if (pte->orig_font->FontType != ft_user_defined)
2094 gs_text_enum_copy_dynamic(pte, pte_default, true);
2095 else {
2096 penum->returned.current_char = pte_default->returned.current_char;
2097 penum->returned.current_glyph = pte_default->returned.current_glyph;
2098 }
2099 pdev->charproc_just_accumulated = false;
2100 if (code == TEXT_PROCESS_RENDER) {
2101 pdev->charproc_ctm = penum->pis->ctm;
2102 if (penum->current_font->FontType == ft_user_defined &&
2103 penum->orig_font->FontType != ft_composite &&
2104 penum->outer_CID == GS_NO_GLYPH &&
2105 !(penum->pte_default->text.operation & TEXT_DO_CHARWIDTH)) {
2106 /* The condition above must be consistent with one in pdf_text_set_cache,
2107 which decides to apply pdf_set_charproc_attrs. */
2108 gs_matrix m;
2109
2110 code = pdf_start_charproc_accum(pdev);
2111 if (code < 0)
2112 return code;
2113 pdf_viewer_state_from_imager_state(pdev, pte->pis, pte->pdcolor);
2114 /* Set line params to unallowed values so that
2115 they'll synchronize with writing them out on the first use.
2116 Doing so because PDF viewer inherits them from the
2117 contents stream when executing the charproc,
2118 but at this moment we don't know in what contexts
2119 it will be used. */
2120 pdev->state.line_params.half_width = -1;
2121 pdev->state.line_params.cap = gs_cap_unknown;
2122 pdev->state.line_params.join = gs_join_unknown;
2123 pdev->state.line_params.miter_limit = -1;
2124 pdev->state.line_params.dash.pattern_size = -1;
2125 /* Must set an identity CTM for the charproc accumulation.
2126 The function show_proceed (called from gs_text_process above)
2127 executed gsave, so we are safe to change CTM now.
2128 Note that BuildChar may change CTM before calling setcachedevice. */
2129 gs_make_identity(&m);
2130 gs_matrix_fixed_from_matrix(&penum->pis->ctm, &m);
2131 return TEXT_PROCESS_RENDER;
2132 }
2133 }
2134 if (code)
2135 return code;
2136 gs_text_release(pte_default, "pdf_text_process");
2137 penum->pte_default = 0;
2138 return 0;
2139 }
2140 {
2141 gs_font *font = pte->orig_font; /* Not sure. Changed for CDevProc callout. Was pte->current_font */
2142
2143 switch (font->FontType) {
2144 case ft_CID_encrypted:
2145 case ft_CID_TrueType:
2146 process = process_cid_text;
2147 break;
2148 case ft_encrypted:
2149 case ft_encrypted2:
2150 case ft_TrueType:
2151 case ft_user_defined:
2152 /* The data may be either glyphs or characters. */
2153 process = process_plain_text;
2154 break;
2155 case ft_composite:
2156 process =
2157 (((gs_font_type0 *)font)->data.FMapType == fmap_CMap ?
2158 process_cmap_text :
2159 process_composite_text);
2160 break;
2161 default:
2162 goto skip;
2163 }
2164 }
2165
2166 /*
2167 * We want to process the entire string in a single call, but we may
2168 * need to modify it. Copy it to a buffer. Note that it may consist
2169 * of bytes, gs_chars, or gs_glyphs.
2170 */
2171
2172 if (operation & (TEXT_FROM_STRING | TEXT_FROM_BYTES))
2173 DO_NOTHING;
2174 else if (operation & TEXT_FROM_CHARS)
2175 size *= sizeof(gs_char);
2176 else if (operation & TEXT_FROM_SINGLE_CHAR)
2177 size = sizeof(gs_char);
2178 else if (operation & TEXT_FROM_GLYPHS)
2179 size *= sizeof(gs_glyph);
2180 else if (operation & TEXT_FROM_SINGLE_GLYPH)
2181 size = sizeof(gs_glyph);
2182 else
2183 goto skip;
2184
2185 if (size <= sizeof(buf)) {
2186 code = process(pte, buf.bytes, size);
2187 } else {
2188 byte *buf = gs_alloc_string(pte->memory, size, "pdf_text_process");
2189
2190 if (buf == 0)
2191 return_error(gs_error_VMerror);
2192 code = process(pte, buf, size);
2193 gs_free_string(pte->memory, buf, size, "pdf_text_process");
2194 }
2195 skip:
2196 if (code < 0 ||
2197 (pte->current_font->FontType == ft_user_defined &&
2198 code != TEXT_PROCESS_INTERVENE &&
2199 penum->index < penum->text.size)) {
2200 if (code == gs_error_unregistered) /* Debug purpose only. */
2201 return code;
2202 if (code == gs_error_VMerror)
2203 return code;
2204 default_impl:
2205 /* Fall back to the default implementation. */
2206 code = pdf_default_text_begin(pte, &pte->text, &pte_default);
2207 if (code < 0)
2208 return code;
2209 penum->pte_default = pte_default;
2210 gs_text_enum_copy_dynamic(pte_default, pte, false);
2211 }
2212 /* The 'process' procedure might also have set pte_default itself. */
2213 if (penum->pte_default && !code)
2214 goto top;
2215 return code;
2216 /*
2217 * This function uses an unobvious algorithm while handling type 3 fonts.
2218 * It runs 'process' to copy text until a glyph, which was not copied to
2219 * output font. Then it installs pte_default and falls back to default
2220 * implementation with PS interpreter callout. The callout executes
2221 * BuildChar/BuildGlyph with setcachedevice. The latter calls
2222 * pdf_set_charproc_attrs, which sets up an accumulator
2223 * of graphic objects to a pdf_begin_resource stream.
2224 * When the callout completes, pdf_text_process calls pdf_end_charproc_accum
2225 * and later resumes the normal (non-default) text enumeration, repeating the
2226 * the "callouted" glyph AT SECOND TIME. We can't do without the second pass
2227 * becauase in the first pass the glyph widths is unknown.
2228 */
2229 /*
2230 * Another unobvious thing is a CDevProc callout.
2231 * If 'process' returns with TEXT_PROCESS_CDEVPROC,
2232 * an interpreter callout will happen, and the function will be called again
2233 * with pte->cdevproc_result_valid = true. Then it restatrs with taking
2234 * glyph metrics from pte->cdevproc_result instead obtaining them with
2235 * font->procs.glyph_info .
2236 */
2237 }
2238