Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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
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
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
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
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
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
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
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
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
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 
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 **
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
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
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 
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
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
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 
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
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
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
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
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
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
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
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
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 
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
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
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 
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 
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 
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
}