Coverage Report

Created: 2022-10-31 07:00

/src/ghostpdl/devices/vector/gdevpdtt.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2001-2022 Artifex Software, Inc.
2
   All Rights Reserved.
3
4
   This software is provided AS-IS with no warranty, either express or
5
   implied.
6
7
   This software is distributed under license and may not be copied,
8
   modified or distributed except as expressly authorized under the terms
9
   of the license contained in the file LICENSE in this distribution.
10
11
   Refer to licensing information at http://www.artifex.com or contact
12
   Artifex Software, Inc.,  1305 Grant Avenue - Suite 200, Novato,
13
   CA 94945, U.S.A., +1(415)492-9861, for further information.
14
*/
15
16
17
/* Text processing for pdfwrite. */
18
#include "math_.h"
19
#include "string_.h"
20
#include <stdlib.h> /* abs() */
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 "gdevpdfo.h"
39
#include "gdevpdtx.h"
40
#include "gdevpdtd.h"
41
#include "gdevpdtf.h"
42
#include "gdevpdts.h"
43
#include "gdevpdtt.h"
44
#include "gdevpdti.h"
45
#include "gxhldevc.h"
46
#include "gzpath.h"
47
48
/* ================ Text enumerator ================ */
49
50
/* GC descriptor */
51
private_st_pdf_text_enum();
52
53
/* Define the auxiliary procedures for text processing. */
54
static int
55
pdf_text_resync(gs_text_enum_t *pte, const gs_text_enum_t *pfrom)
56
0
{
57
0
    pdf_text_enum_t *const penum = (pdf_text_enum_t *)pte;
58
59
0
    if ((pte->text.operation ^ pfrom->text.operation) & ~TEXT_FROM_ANY)
60
0
        return_error(gs_error_rangecheck);
61
0
    if (penum->pte_default) {
62
0
        int code = gs_text_resync(penum->pte_default, pfrom);
63
64
0
        if (code < 0)
65
0
            return code;
66
0
    }
67
0
    pte->text = pfrom->text;
68
0
    gs_text_enum_copy_dynamic(pte, pfrom, false);
69
0
    return 0;
70
0
}
71
static bool
72
pdf_text_is_width_only(const gs_text_enum_t *pte)
73
21.7k
{
74
21.7k
    const pdf_text_enum_t *const penum = (const pdf_text_enum_t *)pte;
75
76
21.7k
    if (penum->pte_default)
77
21.7k
        return gs_text_is_width_only(penum->pte_default);
78
0
    return false;
79
21.7k
}
80
static int
81
pdf_text_current_width(const gs_text_enum_t *pte, gs_point *pwidth)
82
0
{
83
0
    const pdf_text_enum_t *const penum = (const pdf_text_enum_t *)pte;
84
85
0
    if (penum->pte_default)
86
0
        return gs_text_current_width(penum->pte_default, pwidth);
87
0
    return_error(gs_error_rangecheck); /* can't happen */
88
0
}
89
90
static void
91
pdf_show_text_release(gs_text_enum_t *pte, client_name_t cname)
92
1.34k
{
93
1.34k
     gs_show_enum *const penum = (gs_show_enum *)pte;
94
1.34k
     gs_text_enum_procs_t *procs = (gs_text_enum_procs_t *)penum->procs;
95
96
1.34k
     penum->cc = 0;
97
1.34k
     if (penum->dev_cache2) {
98
0
         gx_device_retain((gx_device *)penum->dev_cache2, false);
99
0
         penum->dev_cache2 = 0;
100
0
     }
101
1.34k
     if (penum->dev_cache) {
102
0
         gx_device_retain((gx_device *)penum->dev_cache, false);
103
0
         penum->dev_cache = 0;
104
0
     }
105
1.34k
     if (penum->dev_null) {
106
11
         gx_device_retain((gx_device *)penum->dev_null, false);
107
11
         penum->dev_null = 0;
108
11
     }
109
1.34k
     gx_default_text_release(pte, cname);
110
1.34k
     gs_free_object(penum->memory->non_gc_memory, procs, "pdf_show_text_release");
111
1.34k
}
112
113
static int
114
pdf_text_set_cache(gs_text_enum_t *pte, const double *pw,
115
                   gs_text_cache_control_t control)
116
22.5k
{
117
22.5k
    pdf_text_enum_t *penum;
118
22.5k
    gs_text_enum_t *pgste;
119
22.5k
    gx_device_pdf *pdev = (gx_device_pdf *)pte->dev;
120
22.5k
    gs_matrix m;
121
122
22.5k
    if (pdev->pte != NULL)
123
756
        penum = (pdf_text_enum_t *)pdev->pte;
124
21.7k
    else {
125
21.7k
        if (gs_object_type(pte->memory, pte) == &st_pdf_text_enum)
126
21.7k
            penum = (pdf_text_enum_t *)pte;
127
0
        else
128
0
            return_error(gs_error_typecheck);
129
21.7k
    }
130
131
22.5k
    if (pdev->type3charpath)
132
18.6k
        return gs_text_set_cache(penum->pte_default, pw, control);
133
134
3.87k
    switch (control) {
135
3.11k
    case TEXT_SET_CHAR_WIDTH:
136
3.87k
    case TEXT_SET_CACHE_DEVICE:
137
        /* See comments in pdf_text_process. We are using a 100x100 matrix
138
         * NOT the identity, but we want the cache device values to be in
139
         * font co-ordinate space, so we need to undo that scale here.
140
         */
141
3.87k
        if (pdev->PS_accumulator || pdev->Scaled_accumulator){
142
3.87k
            gs_matrix_scale(&ctm_only(pte->pgs), .01, .01, &m);
143
3.87k
            gs_distance_transform(pw[0], pw[1], &m, &pdev->char_width);
144
3.87k
        } else {
145
0
            pdev->char_width.x = pw[0];
146
0
            pdev->char_width.y = pw[1];
147
0
        }
148
3.87k
        break;
149
0
    case TEXT_SET_CACHE_DEVICE2:
150
        /*
151
         * pdev->char_width is used with synthesized Type 3 fonts only.
152
         * Since they are simple fonts, we only need the horisontal
153
         * width for Widths array. Therefore we don't check
154
         * gs_rootfont(pgs)->WMode and don't use pw[6:7].
155
         */
156
        /* See comments in pdf_text_process. We are using a 100x100 matrix
157
         * NOT the identity, but we want the cache device values to be in
158
         * font co-ordinate space, so we need to undo that scale here.
159
         */
160
0
        if (pdev->PS_accumulator || pdev->Scaled_accumulator){
161
0
            gs_matrix_scale(&ctm_only(pte->pgs), .01, .01, &m);
162
0
            gs_distance_transform(pw[0], pw[1], &m, &pdev->char_width);
163
0
        } else {
164
0
            pdev->char_width.x = pw[0];
165
0
            pdev->char_width.y = pw[1];
166
0
        }
167
0
        if (penum->cdevproc_callout) {
168
0
            memcpy(penum->cdevproc_result, pw, sizeof(penum->cdevproc_result));
169
0
            return 0;
170
0
        }
171
0
        break;
172
0
    default:
173
0
        return_error(gs_error_rangecheck);
174
3.87k
    }
175
3.87k
    if (!pdev->PS_accumulator)
176
756
        pgste = (gs_text_enum_t *)penum;
177
3.12k
    else
178
3.12k
        pgste = penum->pte_default;
179
180
3.87k
    if ((penum->current_font->FontType == ft_user_defined ||
181
3.87k
        penum->current_font->FontType == ft_PDF_user_defined ||
182
3.87k
        penum->current_font->FontType == ft_PCL_user_defined ||
183
3.87k
        penum->current_font->FontType == ft_MicroType ||
184
3.87k
        penum->current_font->FontType == ft_GL2_stick_user_defined ||
185
3.87k
        penum->current_font->FontType == ft_GL2_531) &&
186
3.87k
            penum->outer_CID == GS_NO_GLYPH &&
187
3.87k
            !(pgste->text.operation & TEXT_DO_CHARWIDTH)) {
188
3.87k
        int code;
189
3.87k
        gs_glyph glyph;
190
191
3.87k
        glyph = pte->returned.current_glyph;
192
3.87k
        if ((glyph != GS_NO_GLYPH && penum->output_char_code != GS_NO_CHAR) || !pdev->PS_accumulator) {
193
3.87k
            gs_show_enum *penum_s;
194
3.87k
            gs_fixed_rect clip_box;
195
3.87k
            double pw1[10];
196
3.87k
            int narg = (control == TEXT_SET_CHAR_WIDTH ? 2 :
197
3.87k
                        control == TEXT_SET_CACHE_DEVICE ? 6 : 10), i;
198
199
3.87k
            penum_s = (gs_show_enum *)pgste;
200
            /* BuildChar could change the scale before calling setcachedevice (Bug 687290).
201
               We must scale the setcachedevice arguments because we assumed
202
               identity scale before entering the charproc.
203
               For now we only handle scaling matrices.
204
            */
205
9.29k
            for (i = 0; i < narg; i += 2) {
206
5.41k
                gs_point p;
207
208
5.41k
                gs_point_transform(pw[i], pw[i + 1], &ctm_only(penum_s->pgs), &p);
209
5.41k
                pw1[i] = p.x;
210
5.41k
                pw1[i + 1] = p.y;
211
5.41k
            }
212
3.87k
            if (control != TEXT_SET_CHAR_WIDTH) {
213
766
                clip_box.p.x = float2fixed(pw1[2]);
214
766
                clip_box.p.y = float2fixed(pw1[3]);
215
766
                clip_box.q.x = float2fixed(pw1[4]);
216
766
                clip_box.q.y = float2fixed(pw1[5]);
217
3.11k
            } else {
218
                /*
219
                 * We have no character bbox, but we need one to install the clipping
220
                 * to the graphic state of the PS interpreter. Since some fonts don't
221
                 * provide a proper FontBBox (Bug 687239 supplies a zero one),
222
                 * we set an "infinite" clipping here.
223
                 * We also detected that min_int, max_int don't work here with
224
                 * comparefiles/Bug687044.ps, therefore we divide them by 2.
225
                 */
226
3.11k
                clip_box.p.x = clip_box.p.y = min_int / 2;
227
3.11k
                clip_box.q.x = clip_box.q.y = max_int / 2;
228
3.11k
            }
229
3.87k
            code = gx_clip_to_rectangle(penum_s->pgs, &clip_box);
230
3.87k
            if (code < 0)
231
0
                return code;
232
233
            /* See comments in pdf_text_process. We are using a 100x100 matrix
234
             * NOT the identity, but we want the cache device values to be in
235
             * font co-ordinate space, so we need to undo that scale here. We
236
             * can't do it above, where we take any scaling from the BuildChar
237
             * into account, because that would get the clip path wrong, that
238
             * needs to be in the 100x100 space so that it doesn't clip
239
             * out marking operations.
240
             */
241
3.87k
            if (pdev->PS_accumulator || pdev->Scaled_accumulator)
242
3.87k
                gs_matrix_scale(&ctm_only(penum_s->pgs), .01, .01, &m);
243
0
            else
244
0
                m = ctm_only(penum_s->pgs);
245
9.29k
            for (i = 0; i < narg; i += 2) {
246
5.41k
                gs_point p;
247
248
5.41k
                gs_point_transform(pw[i], pw[i + 1], &m, &p);
249
5.41k
                pw1[i] = p.x;
250
5.41k
                pw1[i + 1] = p.y;
251
5.41k
            }
252
3.87k
            if (!pdev->PS_accumulator && !pdev->Scaled_accumulator)
253
0
                code = pdf_set_charproc_attrs(pdev, pte->current_font,
254
0
                        pw1, narg, control, penum->returned.current_char, false);
255
3.87k
            else
256
3.87k
                code = pdf_set_charproc_attrs(pdev, pte->current_font,
257
3.87k
                        pw1, narg, control, penum->output_char_code, true);
258
3.87k
            if (code < 0)
259
0
                return code;
260
            /* Prevent writing the clipping path to charproc.
261
               See the comment above and bugs 687678, 688327.
262
               Note that the clipping in the graphic state will be used while
263
               fallbacks to default implementations of graphic objects.
264
               Hopely such fallbacks are rare. */
265
3.87k
            pdev->clip_path_id = gx_get_clip_path_id(penum_s->pgs);
266
3.87k
            return code;
267
3.87k
        } else {
268
0
            gs_matrix m;
269
0
            pdf_resource_t *pres = pdev->accumulating_substream_resource;
270
271
            /* pdf_text_process started a charproc stream accumulation,
272
               but now we re-decided to go with the default implementation.
273
               Cancel the stream now.
274
             */
275
0
            code = pdf_exit_substream(pdev);
276
0
            if (code < 0)
277
0
                return code;
278
0
            code = pdf_cancel_resource(pdev, pres, resourceCharProc);
279
0
            if (code < 0)
280
0
                return code;
281
0
            pdf_forget_resource(pdev, pres, resourceCharProc);
282
            /* pdf_text_process had set an identity CTM for the
283
               charproc stream accumulation, but now we re-decided
284
               to go with the default implementation.
285
               Need to restore the correct CTM and add
286
               changes, which the charproc possibly did. */
287
            /* See comments in pdf_text_process. We are using a 100x100 matrix
288
             * NOT the identity,  so we need to undo that scale here.
289
             */
290
0
            gs_matrix_scale(&ctm_only(penum->pgs), .01, .01, (gs_matrix *)&ctm_only(penum->pgs));
291
            /* We also scaled the page height and width. Because we
292
             * don't go through the accumulator 'close' in pdf_text_process
293
             * we must also undo that scale.
294
             */
295
0
            pdev->width /= 100;
296
0
            pdev->height /= 100;
297
298
0
            gs_matrix_multiply((gs_matrix *)&pdev->charproc_ctm, (gs_matrix *)&penum->pgs->ctm, &m);
299
0
            gs_matrix_fixed_from_matrix(&penum->pgs->ctm, &m);
300
0
            penum->charproc_accum = false;
301
0
            pdev->accumulating_charproc = false;
302
0
        }
303
3.87k
    }
304
0
    if (pdev->PS_accumulator && penum->pte_default) {
305
0
        if (penum->pte_default->text.operation & TEXT_DO_CHARWIDTH /* See process_cmap_text.*/)
306
0
            return gs_text_set_cache(penum->pte_default, pw, TEXT_SET_CHAR_WIDTH);
307
0
        else
308
0
            return gs_text_set_cache(penum->pte_default, pw, control);
309
0
    }
310
0
    return_error(gs_error_unregistered); /* can't happen */
311
0
}
312
313
static int
314
pdf_text_retry(gs_text_enum_t *pte)
315
0
{
316
0
    pdf_text_enum_t *const penum = (pdf_text_enum_t *)pte;
317
318
0
    if (penum->pte_default)
319
0
        return gs_text_retry(penum->pte_default);
320
0
    return_error(gs_error_rangecheck); /* can't happen */
321
0
}
322
static void
323
pdf_text_release(gs_text_enum_t *pte, client_name_t cname)
324
1.55M
{
325
1.55M
    pdf_text_enum_t *const penum = (pdf_text_enum_t *)pte;
326
1.55M
    gx_device_pdf *pdev = (gx_device_pdf *)penum->dev;
327
1.55M
    ocr_glyph_t *next;
328
329
1.55M
    if (penum->pte_default) {
330
260
        gs_text_release(NULL, penum->pte_default, cname);
331
260
        penum->pte_default = 0;
332
260
    }
333
1.55M
    pdf_text_release_cgp(penum);
334
335
1.55M
    while (pdev->ocr_glyphs != NULL)
336
0
    {
337
0
        next = pdev->ocr_glyphs->next;
338
339
0
        gs_free_object(pdev->memory, pdev->ocr_glyphs->data, "free bitmap");
340
0
        gs_free_object(pdev->memory, pdev->ocr_glyphs, "free bitmap");
341
0
        pdev->ocr_glyphs = next;
342
0
    }
343
1.55M
    if (pdev->OCRUnicode != NULL)
344
0
        gs_free_object(pdev->memory, pdev->OCRUnicode, "free returned unicodes");
345
1.55M
    pdev->OCRUnicode = NULL;
346
347
1.55M
    gx_default_text_release(pte, cname);
348
1.55M
    pdev->OCRStage = 0;
349
1.55M
}
350
void
351
pdf_text_release_cgp(pdf_text_enum_t *penum)
352
1.57M
{
353
1.57M
    if (penum->cgp) {
354
1.49M
        gs_free_object(penum->memory, penum->cgp, "pdf_text_release");
355
1.49M
        penum->cgp = 0;
356
1.49M
    }
357
1.57M
}
358
359
/* Begin processing text. */
360
static text_enum_proc_process(pdf_text_process);
361
static const gs_text_enum_procs_t pdf_text_procs = {
362
    pdf_text_resync, pdf_text_process,
363
    pdf_text_is_width_only, pdf_text_current_width,
364
    pdf_text_set_cache, pdf_text_retry,
365
    pdf_text_release
366
};
367
368
/* Ideally we would set the stroke and fill colours in pdf_prepare_text_drawing
369
 * but this is called from pdf_process_text, not pdf_begin_text. The problem is
370
 * that if we get a pattern colour we need to exit to the interpreter and run
371
 * the PaintProc, we do this by retunring e_ReampColor. But the 'process' routines
372
 * aren't set up to accept this, and just throw an error. Trying to rework the
373
 * interpreter routines began turning into a gigantic task, so I chose instead
374
 * to 'set' the colours here, which is called from text_begin, where the code
375
 * allows us to return_error(gs_error_RemapColor. Attempting to write the colour to the PDF file
376
 * in this routine as well caused trouble keeping the graphics states synchronised,
377
 * so this functionality was left in pdf_prepare_text_drawing.
378
 */
379
static int
380
pdf_prepare_text_color(gx_device_pdf *const pdev, gs_gstate *pgs, const gs_text_params_t *text, gs_font *font)
381
486k
{
382
486k
    int code=0;
383
486k
    if (text->operation & TEXT_DO_DRAW) {
384
481k
        if (!pdev->ForOPDFRead) {
385
481k
            if (pgs->text_rendering_mode != 3 && pgs->text_rendering_mode != 7) {
386
481k
                if (font->PaintType == 2) {
387
                    /* Bit awkward, if the PaintType is 2 then we want to set the
388
                     * current ie 'fill' colour, but as a stroke colour because we
389
                     * will later change the text rendering mode to 1 (stroke).
390
                     */
391
0
                    code = gx_set_dev_color(pgs);
392
0
                    if (code != 0)
393
0
                        return code;
394
0
                    code = pdf_set_drawing_color(pdev, pgs, pgs->color[0].dev_color, &pdev->saved_stroke_color,
395
0
                                 &pdev->stroke_used_process_color,
396
0
                                 &psdf_set_stroke_color_commands);
397
0
                    if (code < 0)
398
0
                        return code;
399
481k
                } else {
400
481k
                    if ((pgs->text_rendering_mode == 0 || pgs->text_rendering_mode == 2 ||
401
481k
                        pgs->text_rendering_mode == 4 || pgs->text_rendering_mode == 6) &&
402
481k
                        !pdev->remap_stroke_color) {
403
481k
                        code = gx_set_dev_color(pgs);
404
481k
                        if (code != 0)
405
0
                            return code;
406
481k
                    }
407
481k
                    if (pgs->text_rendering_mode == 1 || pgs->text_rendering_mode == 2 ||
408
481k
                        pgs->text_rendering_mode == 5 || pgs->text_rendering_mode == 6) {
409
102
                        if (!pdev->remap_fill_color) {
410
102
                            if (pdev->remap_stroke_color) {
411
0
                                pdev->remap_stroke_color = false;
412
102
                            } else {
413
102
                                gs_swapcolors_quick(pgs);
414
102
                                code = gx_set_dev_color(pgs);
415
102
                                if (code == gs_error_Remap_Color)
416
0
                                    pdev->remap_stroke_color = true;
417
102
                                if (code != 0)
418
0
                                    return code;
419
102
                            }
420
102
                        } else
421
0
                            pdev->remap_fill_color = false;
422
102
                        gs_swapcolors_quick(pgs);
423
102
                        code = gx_set_dev_color(pgs);
424
102
                        if (code == gs_error_Remap_Color)
425
0
                            pdev->remap_fill_color = true;
426
102
                        if (code != 0)
427
0
                            return code;
428
102
                    }
429
481k
                }
430
481k
            }
431
481k
        }
432
481k
    }
433
486k
    return code;
434
486k
}
435
436
static int
437
pdf_prepare_text_drawing(gx_device_pdf *const pdev, gs_text_enum_t *pte)
438
1.55M
{
439
1.55M
    gs_gstate * pgs = pte->pgs;
440
1.55M
    const gx_clip_path * pcpath = pte->pcpath;
441
1.55M
    const gs_text_params_t *text = &pte->text;
442
1.55M
    bool new_clip = false; /* Quiet compiler. */
443
1.55M
    int code;
444
1.55M
    gs_font *font = pte->current_font;
445
446
1.55M
    if (!(text->operation & TEXT_DO_NONE) || pgs->text_rendering_mode == 3) {
447
1.55M
        code = pdf_check_soft_mask(pdev, pte->pgs);
448
1.55M
        if (code < 0)
449
0
            return code;
450
1.55M
        new_clip = pdf_must_put_clip_path(pdev, pcpath);
451
1.55M
        if (new_clip)
452
7.15k
            code = pdf_unclip(pdev);
453
1.55M
        else if (pdev->context == PDF_IN_NONE)
454
6.65k
            code = pdf_open_page(pdev, PDF_IN_STREAM);
455
1.54M
        else
456
1.54M
            code = 0;
457
1.55M
        if (code < 0)
458
832
            return code;
459
1.55M
        code = pdf_prepare_fill(pdev, pgs, true);
460
1.55M
        if (code < 0)
461
0
            return code;
462
1.55M
    }
463
1.55M
    if (text->operation & TEXT_DO_DRAW) {
464
        /*
465
         * Set the clipping path and drawing color.  We set both the fill
466
         * and stroke color, because we don't know whether the fonts will be
467
         * filled or stroked, and we can't set a color while we are in text
468
         * mode.  (This is a consequence of the implementation, not a
469
         * limitation of PDF.)
470
         */
471
472
1.55M
        if (new_clip) {
473
7.15k
            code = pdf_put_clip_path(pdev, pcpath);
474
7.15k
            if (code < 0)
475
0
                return code;
476
7.15k
        }
477
478
1.55M
        if (!pdev->ForOPDFRead) {
479
481k
            if (pgs->text_rendering_mode != 3 && pgs->text_rendering_mode != 7) {
480
481k
                if (font->PaintType == 2) {
481
                    /* Bit awkward, if the PaintType is 2 then we want to set the
482
                     * current ie 'fill' colour, but as a stroke colour because we
483
                     * will later change the text rendering mode to 1 (stroke).
484
                     */
485
0
                    code = gx_set_dev_color(pgs);
486
0
                    if (code != 0)
487
0
                        return code;
488
0
                    code = pdf_set_drawing_color(pdev, pgs, pgs->color[0].dev_color, &pdev->saved_stroke_color,
489
0
                                 &pdev->stroke_used_process_color,
490
0
                                 &psdf_set_stroke_color_commands);
491
0
                    if (code < 0)
492
0
                        return code;
493
481k
                } else {
494
481k
                    if (pgs->text_rendering_mode == 0 || pgs->text_rendering_mode == 2 ||
495
481k
                        pgs->text_rendering_mode == 4 || pgs->text_rendering_mode == 6) {
496
481k
                        code = gx_set_dev_color(pgs);
497
481k
                        if (code != 0)
498
0
                            return code;
499
481k
                        code = pdf_set_drawing_color(pdev, pgs, pgs->color[0].dev_color, &pdev->saved_fill_color,
500
481k
                                     &pdev->fill_used_process_color,
501
481k
                                     &psdf_set_fill_color_commands);
502
481k
                        if (code < 0)
503
20
                            return code;
504
481k
                    }
505
481k
                    if (pgs->text_rendering_mode == 1 || pgs->text_rendering_mode == 2 ||
506
481k
                        pgs->text_rendering_mode == 5 || pgs->text_rendering_mode == 6) {
507
102
                        gs_swapcolors_quick(pgs);
508
102
                        code = gx_set_dev_color(pgs);
509
102
                        if (code != 0)
510
0
                            return code;
511
102
                        code = pdf_set_drawing_color(pdev, pgs, pgs->color[0].dev_color, &pdev->saved_stroke_color,
512
102
                                     &pdev->stroke_used_process_color,
513
102
                                     &psdf_set_stroke_color_commands);
514
102
                        if (code < 0)
515
0
                            return code;
516
517
102
                        gs_swapcolors_quick(pgs);
518
102
                    }
519
481k
                }
520
481k
            }
521
1.07M
        } else {
522
1.07M
            code = gx_set_dev_color(pgs);
523
1.07M
            if (code != 0)
524
0
                return code;
525
526
1.07M
            if ((code =
527
1.07M
                 pdf_set_drawing_color(pdev, pgs, pgs->color[0].dev_color, &pdev->saved_stroke_color,
528
1.07M
                                       &pdev->stroke_used_process_color,
529
1.07M
                                       &psdf_set_stroke_color_commands)) < 0 ||
530
1.07M
                (code =
531
1.07M
                 pdf_set_drawing_color(pdev, pgs, pgs->color[0].dev_color, &pdev->saved_fill_color,
532
1.07M
                                       &pdev->fill_used_process_color,
533
1.07M
                                       &psdf_set_fill_color_commands)) < 0
534
1.07M
                )
535
0
                return code;
536
1.07M
        }
537
1.55M
    }
538
1.55M
    return 0;
539
1.55M
}
540
541
int
542
gdev_pdf_text_begin(gx_device * dev, gs_gstate * pgs,
543
                    const gs_text_params_t *text, gs_font * font,
544
                    const gx_clip_path * pcpath,
545
                    gs_text_enum_t ** ppte)
546
1.56M
{
547
1.56M
    gx_device_pdf *const pdev = (gx_device_pdf *)dev;
548
1.56M
    gx_path *path0 = pgs->path;
549
1.56M
    gx_path *path = ((text->operation & TEXT_DO_NONE) &&
550
1.56M
                    !(text->operation & TEXT_RETURN_WIDTH) ? NULL : path0);
551
1.56M
    pdf_text_enum_t *penum;
552
1.56M
    int code, user_defined = 0;
553
1.56M
    gs_memory_t * mem = pgs->memory;
554
555
    /* should we "flatten" the font to "normal" marking operations */
556
1.56M
    if (pdev->FlattenFonts) {
557
0
        font->dir->ccache.upper = 0;
558
0
        return gx_default_text_begin(dev, pgs, text, font,
559
0
                                     pcpath, ppte);
560
0
    }
561
562
    /* Track the dominant text rotation. */
563
1.56M
    {
564
1.56M
        gs_matrix tmat;
565
1.56M
        gs_point p;
566
1.56M
        int i;
567
568
1.56M
        gs_matrix_multiply(&font->FontMatrix, &ctm_only(pgs), &tmat);
569
1.56M
        gs_distance_transform(1, 0, &tmat, &p);
570
1.56M
        if (p.x > fabs(p.y))
571
1.55M
            i = 0;
572
5.82k
        else if (p.x < -fabs(p.y))
573
193
            i = 2;
574
5.63k
        else if (p.y > fabs(p.x))
575
5.44k
            i = 1;
576
190
        else if (p.y < -fabs(p.x))
577
97
            i = 3;
578
93
        else
579
93
            i = 4;
580
1.56M
        pdf_current_page(pdev)->text_rotation.counts[i] += text->size;
581
1.56M
    }
582
583
1.56M
    pdev->last_charpath_op = 0;
584
1.56M
    if ((text->operation & TEXT_DO_ANY_CHARPATH) && !path0->first_subpath) {
585
979
        if (pdf_compare_text_state_for_charpath(pdev->text->text_state, pdev, pgs, font, text))
586
3
            pdev->last_charpath_op = text->operation & TEXT_DO_ANY_CHARPATH;
587
979
    }
588
589
1.56M
    if(font->FontType == ft_user_defined ||
590
1.56M
       font->FontType == ft_PDF_user_defined ||
591
1.56M
       font->FontType == ft_PCL_user_defined ||
592
1.56M
       font->FontType == ft_MicroType ||
593
1.56M
       font->FontType == ft_GL2_stick_user_defined ||
594
1.56M
       font->FontType == ft_GL2_531)
595
1.74k
        user_defined = 1;
596
597
    /* We need to know whether any of the glyphs in a string using a composite font
598
     * use a descendant font which is a type 3 (user-defined) so that we can properly
599
     * skip the caching below.
600
     */
601
1.56M
    if(font->FontType == ft_composite && ((gs_font_type0 *)font)->data.FMapType != fmap_CMap) {
602
0
        int font_code;
603
0
        gs_char chr;
604
0
        gs_glyph glyph;
605
606
0
        rc_alloc_struct_1(penum, pdf_text_enum_t, &st_pdf_text_enum, mem,
607
0
                      return_error(gs_error_VMerror), "gdev_pdf_text_begin");
608
0
        penum->rc.free = rc_free_text_enum;
609
0
        penum->pte_default = 0;
610
0
        penum->charproc_accum = false;
611
0
        pdev->accumulating_charproc = false;
612
0
        penum->cdevproc_callout = false;
613
0
        penum->returned.total_width.x = penum->returned.total_width.y = 0;
614
0
        penum->cgp = NULL;
615
0
        penum->output_char_code = GS_NO_CHAR;
616
0
        code = gs_text_enum_init((gs_text_enum_t *)penum, &pdf_text_procs,
617
0
                             dev, pgs, text, font, pcpath, mem);
618
0
        if (code < 0) {
619
0
            gs_free_object(mem, penum, "gdev_pdf_text_begin");
620
0
            return code;
621
0
        }
622
0
        do {
623
0
            font_code = penum->orig_font->procs.next_char_glyph
624
0
                ((gs_text_enum_t *)penum, &chr, &glyph);
625
0
            if (font_code == 1){
626
0
                if (penum->fstack.items[penum->fstack.depth].font->FontType == 3) {
627
0
                    user_defined = 1;
628
0
                    break;
629
0
                }
630
0
            }
631
0
        } while(font_code != 2 && font_code >= 0);
632
0
        if (!user_defined) {
633
0
            if (penum->fstack.items[penum->fstack.depth].font->FontType == 3)
634
0
                user_defined = 1;
635
0
        }
636
0
        gs_text_release(NULL, (gs_text_enum_t *)penum, "pdf_text_process");
637
0
    }
638
639
1.56M
    if (!user_defined || !(text->operation & TEXT_DO_ANY_CHARPATH)) {
640
1.55M
        if (user_defined &&
641
1.55M
            (text->operation & TEXT_DO_NONE) && (text->operation & TEXT_RETURN_WIDTH)
642
1.55M
            && pgs->text_rendering_mode != 3) {
643
            /* This is stringwidth, see gx_default_text_begin.
644
             * We need to prevent writing characters to PS cache,
645
             * otherwise the font converts to bitmaps.
646
             * So pass through even with stringwidth.
647
             */
648
1
            code = gx_hld_stringwidth_begin(pgs, &path);
649
1
            if (code < 0)
650
0
                return code;
651
1.55M
        } else if ((!(text->operation & TEXT_DO_DRAW) && pgs->text_rendering_mode != 3)
652
1.55M
                    || path == 0 || !path_position_valid(path)
653
1.55M
                    || pdev->type3charpath)
654
845
            return gx_default_text_begin(dev, pgs, text, font,
655
845
                                         pcpath, ppte);
656
1.55M
        else if (text->operation & TEXT_DO_ANY_CHARPATH)
657
0
            return gx_default_text_begin(dev, pgs, text, font,
658
0
                                         pcpath, ppte);
659
1.55M
    }
660
661
1.55M
    if (!pdev->ForOPDFRead) {
662
486k
    code = pdf_prepare_text_color(pdev, pgs, text, font);
663
486k
    if (code != 0)
664
0
        return code;
665
486k
    }
666
667
    /* Allocate and initialize the enumerator. */
668
669
1.55M
    rc_alloc_struct_1(penum, pdf_text_enum_t, &st_pdf_text_enum, mem,
670
1.55M
                      return_error(gs_error_VMerror), "gdev_pdf_text_begin");
671
1.55M
    penum->rc.free = rc_free_text_enum;
672
1.55M
    penum->pte_default = 0;
673
1.55M
    penum->charproc_accum = false;
674
1.55M
    pdev->accumulating_charproc = false;
675
1.55M
    penum->cdevproc_callout = false;
676
1.55M
    penum->returned.total_width.x = penum->returned.total_width.y = 0;
677
1.55M
    penum->cgp = NULL;
678
1.55M
    penum->returned.current_glyph = GS_NO_GLYPH;
679
1.55M
    penum->output_char_code = GS_NO_CHAR;
680
1.55M
    code = gs_text_enum_init((gs_text_enum_t *)penum, &pdf_text_procs,
681
1.55M
                             dev, pgs, text, font, pcpath, mem);
682
1.55M
    penum->k_text_release = 1; /* early release of black_textvec_state */
683
684
1.55M
    if (code < 0) {
685
0
        gs_free_object(mem, penum, "gdev_pdf_text_begin");
686
0
        return code;
687
0
    }
688
1.55M
    if (pdev->font3 != 0) {
689
        /* A text operation happens while accumulating a charproc.
690
           This is a case when source document uses a Type 3 font,
691
           which's charproc uses another font.
692
           Since the text operation is handled by the device,
693
           the font isn't converting to a raster (i.e. to a bitmap font).
694
           Disable the grid fitting for the convertion to get a proper outlines,
695
           because the viewer resolution is not known during the accumulation.
696
           Note we set identity CTM in pdf_text_set_cache for the accumilation,
697
           and therefore the font may look too small while the source charproc
698
           interpretation. The document tpc2.ps of the bug 687087 is an example.
699
        */
700
1.05k
        penum->device_disabled_grid_fitting = true;
701
1.05k
    }
702
703
1.55M
    *ppte = (gs_text_enum_t *)penum;
704
705
1.55M
    return 0;
706
1.55M
}
707
708
/* ================ Font cache element ================ */
709
710
/* GC descriptor */
711
private_st_pdf_font_cache_elem();
712
713
/*
714
 * Compute id for a font cache element.
715
 */
716
static ulong
717
pdf_font_cache_elem_id(gs_font *font)
718
9.43M
{
719
9.43M
    return font->id;
720
9.43M
}
721
722
pdf_font_cache_elem_t **
723
pdf_locate_font_cache_elem(gx_device_pdf *pdev, gs_font *font)
724
9.40M
{
725
9.40M
    pdf_font_cache_elem_t **e = &pdev->font_cache;
726
9.40M
    pdf_font_cache_elem_t *prev = NULL;
727
9.40M
    long id = pdf_font_cache_elem_id(font);
728
729
13.3M
    for (; *e != 0; e = &(*e)->next) {
730
12.8M
        if ((*e)->font_id == id) {
731
8.94M
            if (prev != NULL) {
732
19.3k
                pdf_font_cache_elem_t *curr = *e;
733
734
                /* move the curr font to head of list (Most Recently Used) */
735
19.3k
                prev->next = curr->next;
736
19.3k
                curr->next = pdev->font_cache;
737
19.3k
                pdev->font_cache = curr;
738
19.3k
            }
739
8.94M
            return &(pdev->font_cache);
740
8.94M
        }
741
3.94M
        prev = *e;
742
3.94M
    }
743
465k
    return 0;
744
9.40M
}
745
746
static void
747
pdf_remove_font_cache_elem(gx_device_pdf *pdev, pdf_font_cache_elem_t *e0)
748
27.8k
{
749
27.8k
    pdf_font_cache_elem_t **e = &pdev->font_cache;
750
751
27.8k
    for (; *e != 0; e = &(*e)->next)
752
27.8k
        if (*e == e0) {
753
27.8k
            *e = e0->next;
754
27.8k
            gs_free_object(pdev->pdf_memory, e0->glyph_usage,
755
27.8k
                                "pdf_remove_font_cache_elem");
756
27.8k
            gs_free_object(pdev->pdf_memory, e0->real_widths,
757
27.8k
                                "pdf_remove_font_cache_elem");
758
            /* Clean pointers, because gs_free_object below may work idle
759
               when this function is called by a garbager notification.
760
               Leaving unclean pointers may cause
761
               a further heap validation to fail
762
               since the unfreed structure points to freed areas.
763
               For instance, e0->next may point to an element,
764
               which is really freed with a subsequent 'restore'.
765
               Bug 688837. */
766
27.8k
            e0->next = 0;
767
27.8k
            e0->glyph_usage = 0;
768
27.8k
            e0->real_widths = 0;
769
27.8k
            gs_free_object(pdev->pdf_memory, e0,
770
27.8k
                                "pdf_remove_font_cache_elem");
771
27.8k
            return;
772
27.8k
        }
773
27.8k
}
774
775
static void
776
font_cache_elem_array_sizes(gx_device_pdf *pdev, gs_font *font,
777
                            int *num_widths, int *num_chars)
778
57.4k
{
779
57.4k
    switch (font->FontType) {
780
0
    case ft_composite:
781
0
        *num_widths = 0; /* Unused for Type 0 */
782
0
        *num_chars = 65536; /* No chance to determine, use max. */
783
0
        break;
784
48.7k
    case ft_encrypted:
785
49.0k
    case ft_encrypted2:
786
49.3k
    case ft_user_defined:
787
49.4k
    case ft_PDF_user_defined:
788
49.4k
    case ft_GL2_stick_user_defined:
789
49.4k
    case ft_PCL_user_defined:
790
49.4k
    case ft_MicroType:
791
49.4k
    case ft_GL2_531:
792
49.4k
    case ft_disk_based:
793
49.4k
    case ft_Chameleon:
794
57.0k
    case ft_TrueType:
795
57.0k
        *num_widths = *num_chars = 256; /* Assuming access to glyph_usage by character codes */
796
57.0k
        break;
797
72
    case ft_CID_encrypted:
798
72
        *num_widths = *num_chars = ((gs_font_cid0 *)font)->cidata.common.MaxCID + 1;
799
72
        break;
800
348
    case ft_CID_TrueType:
801
348
        *num_widths = *num_chars = ((gs_font_cid2 *)font)->cidata.common.CIDCount;
802
348
        break;
803
0
    default:
804
0
        *num_widths = *num_chars = 65536; /* No chance to determine, use max. */
805
57.4k
    }
806
57.4k
}
807
808
static int
809
alloc_font_cache_elem_arrays(gx_device_pdf *pdev, pdf_font_cache_elem_t *e,
810
                             gs_font *font)
811
27.8k
{
812
27.8k
    int num_widths, num_chars, len;
813
814
27.8k
    font_cache_elem_array_sizes(pdev, font, &num_widths, &num_chars);
815
27.8k
    len = (num_chars + 7) / 8;
816
27.8k
    if (e->glyph_usage != NULL)
817
0
        gs_free_object(pdev->pdf_memory, e->glyph_usage,
818
27.8k
                            "pdf_attach_font_resource, reallocating");
819
27.8k
    if (e->real_widths != NULL)
820
0
        gs_free_object(pdev->pdf_memory, e->real_widths,
821
27.8k
                            "alloc_font_cache_elem_arrays, reallocating");
822
823
27.8k
    e->glyph_usage = gs_alloc_bytes(pdev->pdf_memory,
824
27.8k
                        len, "alloc_font_cache_elem_arrays");
825
826
27.8k
    e->real_widths = (num_widths > 0 ? (double *)gs_alloc_bytes(pdev->pdf_memory,
827
27.8k
                        num_widths * sizeof(*e->real_widths) *
828
27.8k
                            ((font->FontType == ft_user_defined ||
829
27.8k
                            font->FontType == ft_PDF_user_defined ||
830
27.8k
                            font->FontType == ft_GL2_stick_user_defined ||
831
27.8k
                            font->FontType == ft_PCL_user_defined ||
832
27.8k
                            font->FontType == ft_MicroType ||
833
27.8k
                            font->FontType == ft_GL2_531) ? 2 : 1),
834
27.8k
                        "alloc_font_cache_elem_arrays") : NULL);
835
27.8k
    if (e->glyph_usage == NULL || (num_widths !=0 && e->real_widths == NULL)) {
836
0
        gs_free_object(pdev->pdf_memory, e->glyph_usage,
837
0
                            "pdf_attach_font_resource");
838
0
        gs_free_object(pdev->pdf_memory, e->real_widths,
839
0
                            "alloc_font_cache_elem_arrays");
840
0
        return_error(gs_error_VMerror);
841
0
    }
842
27.8k
    e->num_chars = num_chars;
843
27.8k
    e->num_widths = num_widths;
844
27.8k
    memset(e->glyph_usage, 0, len);
845
27.8k
    if (e->real_widths != NULL)
846
27.8k
        memset(e->real_widths, 0, num_widths * sizeof(*e->real_widths));
847
27.8k
    return 0;
848
27.8k
}
849
850
int
851
pdf_free_font_cache(gx_device_pdf *pdev)
852
16.0k
{
853
16.0k
    pdf_font_cache_elem_t *e = pdev->font_cache, *next;
854
855
    /* fixed! fixme : release elements.
856
     * We no longer track font_cache elements in the original font, which is where
857
     * the memory used to be released. So now we must release it ourselves.
858
     */
859
860
43.9k
    while (e != NULL) {
861
27.8k
        next = e->next;
862
27.8k
        pdf_remove_font_cache_elem(pdev, e);
863
27.8k
        e = next;
864
27.8k
    }
865
16.0k
    pdev->font_cache = NULL;
866
16.0k
    return 0;
867
16.0k
}
868
869
/*
870
 * Retrive font resource attached to a font,
871
 * allocating glyph_usage and real_widths on request.
872
 */
873
int
874
pdf_attached_font_resource(gx_device_pdf *pdev, gs_font *font,
875
                            pdf_font_resource_t **pdfont, byte **glyph_usage,
876
                            double **real_widths, int *num_chars, int *num_widths)
877
9.37M
{
878
9.37M
    pdf_font_cache_elem_t **e = pdf_locate_font_cache_elem(pdev, font);
879
880
9.37M
    if (e != NULL && (((*e)->glyph_usage == NULL && glyph_usage !=NULL) ||
881
8.93M
                      ((*e)->real_widths == NULL && real_widths !=NULL))) {
882
27.8k
        int code = alloc_font_cache_elem_arrays(pdev, *e, font);
883
884
27.8k
        if (code < 0)
885
0
            return code;
886
27.8k
    }
887
9.37M
    *pdfont = (e == NULL ? NULL : (*e)->pdfont);
888
9.37M
    if (glyph_usage != NULL)
889
8.83M
        *glyph_usage = (e == NULL ? NULL : (*e)->glyph_usage);
890
9.37M
    if (real_widths != NULL)
891
8.83M
        *real_widths = (e == NULL ? NULL : (*e)->real_widths);
892
9.37M
    if (num_chars != NULL)
893
8.83M
        *num_chars = (e == NULL ? 0 : (*e)->num_chars);
894
9.37M
    if (num_widths != NULL)
895
8.83M
        *num_widths = (e == NULL ? 0 : (*e)->num_widths);
896
9.37M
    return 0;
897
9.37M
}
898
899
/*
900
 * Attach font resource to a font.
901
 */
902
int
903
pdf_attach_font_resource(gx_device_pdf *pdev, gs_font *font,
904
                         pdf_font_resource_t *pdfont)
905
29.5k
{
906
29.5k
    int num_chars, num_widths, len;
907
29.5k
    pdf_font_cache_elem_t *e, **pe = pdf_locate_font_cache_elem(pdev, font);
908
909
    /* Allow the HPGL2 stick font to be attached to a type 3 font, it *is* a
910
     * type 3 font, its just identified differently so that we can choose not
911
     * to capture it elsewhere. Same for PCL bitmap fonts.
912
     */
913
29.5k
    if (pdfont->FontType != font->FontType &&
914
29.5k
        (pdfont->FontType != ft_user_defined ||
915
65
        (font->FontType != ft_PCL_user_defined &&
916
65
        font->FontType != ft_PDF_user_defined &&
917
65
        font->FontType != ft_MicroType &&
918
65
        font->FontType != ft_GL2_stick_user_defined &&
919
65
        font->FontType != ft_GL2_531)))
920
0
        return_error(gs_error_unregistered); /* Must not happen. */
921
29.5k
    font_cache_elem_array_sizes(pdev, font, &num_widths, &num_chars);
922
29.5k
    len = (num_chars + 7) / 8;
923
29.5k
    if (pe != NULL) {
924
1.72k
        e = *pe;
925
1.72k
        if (e->pdfont == pdfont)
926
552
            return 0;
927
1.17k
        e->pdfont = pdfont;
928
        /* Reset glyph cache because e->pdfont had changed. */
929
1.17k
        memset(e->glyph_usage, 0, len);
930
1.17k
        memset(e->real_widths, 0, num_widths * sizeof(*e->real_widths));
931
27.8k
    } else {
932
27.8k
        e = (pdf_font_cache_elem_t *)gs_alloc_struct(pdev->pdf_memory,
933
27.8k
                pdf_font_cache_elem_t, &st_pdf_font_cache_elem,
934
27.8k
                            "pdf_attach_font_resource");
935
27.8k
        if (e == NULL)
936
0
            return_error(gs_error_VMerror);
937
27.8k
        e->pdfont = pdfont;
938
27.8k
        e->font_id = pdf_font_cache_elem_id(font);
939
27.8k
        e->num_chars = 0;
940
27.8k
        e->glyph_usage = NULL;
941
27.8k
        e->real_widths = NULL;
942
27.8k
        e->next = pdev->font_cache;
943
27.8k
        pdev->font_cache = e;
944
27.8k
        return 0;
945
27.8k
    }
946
1.17k
    return 0;
947
29.5k
}
948
949
/* ================ Process text ================ */
950
951
/* ---------------- Internal utilities ---------------- */
952
953
/*
954
 * Compute and return the orig_matrix of a font.
955
 */
956
int
957
pdf_font_orig_matrix(const gs_font *font, gs_matrix *pmat)
958
942k
{
959
942k
    switch (font->FontType) {
960
0
    case ft_composite:                /* subfonts have their own FontMatrix */
961
183k
    case ft_TrueType:
962
292k
    case ft_CID_TrueType:
963
        /* The TrueType FontMatrix is 1 unit per em, which is what we want. */
964
292k
        gs_make_identity(pmat);
965
292k
        return 0;
966
638k
    case ft_encrypted:
967
644k
    case ft_encrypted2:
968
649k
    case ft_CID_encrypted:
969
649k
    case ft_user_defined:
970
649k
    case ft_PCL_user_defined:
971
649k
    case ft_PDF_user_defined:
972
649k
    case ft_MicroType:
973
649k
    case ft_GL2_stick_user_defined:
974
649k
    case ft_GL2_531:
975
        /*
976
         * Type 1 fonts are supposed to use a standard FontMatrix of
977
         * [0.001 0 0 0.001 0 0], with a 1000-unit cell.  However,
978
         * Windows NT 4.0 creates Type 1 fonts, apparently derived from
979
         * TrueType fonts, that use a 2048-unit cell and corresponding
980
         * FontMatrix.  Also, some PS programs perform font scaling by
981
         * replacing FontMatrix like this :
982
         *
983
         *   /f12 /Times-Roman findfont
984
         *   copyfont          % (remove FID)
985
         *   dup /FontMatrix [0.012 0 0 0.012 0 0] put
986
         *   definefont
987
         *   /f12 1 selectfont
988
         *
989
         * Such fonts are their own "base font", but the orig_matrix
990
         * must still be set to 0.001, not 0.012 .
991
         *
992
         * The old code used a heuristic to detect and correct for this here.
993
         * Unfortunately it doesn't work properly when it meets a font
994
         * with FontMatrix like this :
995
         *
996
         *   /FontMatrix [1 2288 div 0 0 1 2288 div 0 0 ] def
997
         *
998
         * (the bug 686970). Also comparefiles\455690.pdf appears to
999
         * have similar problem. Therefore we added a support to lib/gs_fonts.ps,
1000
         * src/zbfont.c, src/gsfont.c that provides an acces to the original
1001
         * font via a special key OrigFont added to the font dictionary while definefont.
1002
         * Now we work through this access with PS interpreter,
1003
         * but keep the old heuristic for other clients.
1004
         */
1005
649k
        {
1006
649k
            const gs_font *base_font = font;
1007
1008
667k
            while (base_font->base != base_font)
1009
17.8k
                base_font = base_font->base;
1010
649k
            if (font->FontType == ft_user_defined ||
1011
649k
                font->FontType == ft_PDF_user_defined ||
1012
649k
                font->FontType == ft_PCL_user_defined ||
1013
649k
                font->FontType == ft_MicroType ||
1014
649k
                font->FontType == ft_GL2_stick_user_defined ||
1015
649k
                font->FontType == ft_GL2_531)
1016
0
                *pmat = base_font->FontMatrix;
1017
649k
            else if (base_font->orig_FontMatrix.xx != 0 || base_font->orig_FontMatrix.xy != 0 ||
1018
649k
                base_font->orig_FontMatrix.yx != 0 || base_font->orig_FontMatrix.yy != 0)
1019
649k
                *pmat = base_font->orig_FontMatrix;
1020
0
            else {
1021
                /*  Must not happen with PS interpreter.
1022
                    Provide a hewuristic for other clients.
1023
                */
1024
0
                if (base_font->FontMatrix.xx == 1.0/2048 &&
1025
0
                    base_font->FontMatrix.xy == 0 &&
1026
0
                    base_font->FontMatrix.yx == 0 &&
1027
0
                    any_abs(base_font->FontMatrix.yy) == 1.0/2048
1028
0
                    )
1029
0
                    *pmat = base_font->FontMatrix;
1030
0
                else
1031
0
                    gs_make_scaling(0.001, 0.001, pmat);
1032
0
            }
1033
649k
        }
1034
649k
        return 0;
1035
0
    default:
1036
0
        return_error(gs_error_rangecheck);
1037
942k
    }
1038
942k
}
1039
1040
/*
1041
 * Special version of pdf_font_orig_matrix(), that cares FDArray font's FontMatrix too.
1042
 * Called only by pdf_glyph_width().
1043
 * 'cid' is only consulted if 'font' is a CIDFontType 0 CID font.
1044
 */
1045
static int
1046
glyph_orig_matrix(const gs_font *font, gs_glyph cid, gs_matrix *pmat)
1047
927k
{
1048
927k
    int code = pdf_font_orig_matrix(font, pmat);
1049
927k
    if (code >= 0) {
1050
927k
        if (font->FontType == ft_CID_encrypted) {
1051
4.03k
            int fidx;
1052
1053
4.03k
            if (cid < GS_MIN_CID_GLYPH)
1054
0
                cid = GS_MIN_CID_GLYPH;
1055
4.03k
            code = ((gs_font_cid0 *)font)->cidata.glyph_data((gs_font_base *)font,
1056
4.03k
                                cid, NULL, &fidx);
1057
4.03k
            if (code < 0) {
1058
0
                code = ((gs_font_cid0 *)font)->cidata.glyph_data((gs_font_base *)font,
1059
0
                                (gs_glyph)GS_MIN_CID_GLYPH, NULL, &fidx);
1060
0
            }
1061
4.03k
            if (code >= 0) {
1062
4.03k
                gs_matrix_multiply(&(gs_cid0_indexed_font(font, fidx)->FontMatrix),
1063
4.03k
                                pmat, pmat);
1064
4.03k
            }
1065
4.03k
        }
1066
927k
    }
1067
927k
    return code;
1068
927k
}
1069
1070
/*
1071
 * Check the Encoding compatibility
1072
 */
1073
bool
1074
pdf_check_encoding_compatibility(const pdf_font_resource_t *pdfont,
1075
            const pdf_char_glyph_pair_t *pairs, int num_chars)
1076
1.38M
{
1077
1.38M
    int i;
1078
1079
5.42M
    for (i = 0; i < num_chars; ++i) {
1080
4.04M
        gs_char ch = pairs[i].chr;
1081
4.04M
        pdf_encoding_element_t *pet = &pdfont->u.simple.Encoding[ch];
1082
1083
4.04M
        if (pairs[i].glyph == pet->glyph)
1084
3.67M
            continue;
1085
364k
        if (pet->glyph != GS_NO_GLYPH) /* encoding conflict */
1086
932
            return false;
1087
364k
    }
1088
1.38M
    return true;
1089
1.38M
}
1090
1091
/*
1092
 * Check whether the Encoding has listed glyphs.
1093
 */
1094
static bool
1095
pdf_check_encoding_has_glyphs(const pdf_font_resource_t *pdfont,
1096
            const pdf_char_glyph_pair_t *pairs, int num_chars)
1097
0
{
1098
    /* This function is pretty slow, but we can't find a better algorithm.
1099
       It works for the case of glyphshow with no proper encoding,
1100
       which we believe comes from poorly designed documents.
1101
     */
1102
0
    int i, ch;
1103
1104
0
    for (i = 0; i < num_chars; ++i) {
1105
0
        for (ch = 0; ch < 256; ch++) {
1106
0
            pdf_encoding_element_t *pet = &pdfont->u.simple.Encoding[ch];
1107
1108
0
            if (pairs[i].glyph == pet->glyph)
1109
0
                return true;
1110
0
        }
1111
0
    }
1112
0
    return false;
1113
0
}
1114
1115
/*
1116
 * Check font resource for encoding compatibility.
1117
 */
1118
static bool
1119
pdf_is_compatible_encoding(gx_device_pdf *pdev, pdf_font_resource_t *pdfont,
1120
                           gs_font *font, const pdf_char_glyph_pair_t *pairs, int num_chars)
1121
1.38M
{
1122
    /*
1123
     * This crude version of the code ignores
1124
     * the possibility of re-encoding characters.
1125
     */
1126
1.38M
    switch (pdfont->FontType) {
1127
0
    case ft_composite:
1128
0
        {   /*
1129
             * We assume that source document don't redefine CMap
1130
             * resources and that incremental CMaps do not exist.
1131
             * Therefore we don't maintain stable CMap copies,
1132
             * but just compare CMap names for equality.
1133
             * A better implementation should compare the chars->glyphs
1134
             * translation against the stable copy of CMap,
1135
             * which to be handled with PDF CMap resource.
1136
             */
1137
0
            gs_font_type0 *pfont = (gs_font_type0 *)font;
1138
1139
0
            if (pfont->data.FMapType == fmap_CMap) {
1140
0
                const gs_cmap_t *pcmap = pfont->data.CMap;
1141
0
                const gs_const_string *s1 = &pcmap->CMapName;
1142
1143
0
                return (pdfont->u.type0.CMapName_size == s1->size &&
1144
0
                        !memcmp(pdfont->u.type0.CMapName_data, s1->data, pdfont->u.type0.CMapName_size));
1145
0
            }
1146
0
        }
1147
0
        return false;
1148
5.63k
    case ft_user_defined:
1149
5.63k
    case ft_PDF_user_defined:
1150
5.63k
    case ft_PCL_user_defined:
1151
5.63k
    case ft_MicroType:
1152
5.63k
    case ft_GL2_stick_user_defined:
1153
5.63k
    case ft_GL2_531:
1154
5.63k
        if (pdfont->u.simple.Encoding == NULL)
1155
0
            return false; /* Not sure. Happens with 020-01.ps . */
1156
        /* fall through */
1157
1.06M
    case ft_encrypted:
1158
1.09M
    case ft_encrypted2:
1159
1.38M
    case ft_TrueType:
1160
1.38M
        return pdf_check_encoding_compatibility(pdfont, pairs, num_chars);
1161
0
    case ft_CID_encrypted:
1162
0
    case ft_CID_TrueType:
1163
0
        {
1164
0
            gs_font *font1 = (gs_font *)pdf_font_resource_font(pdfont, false);
1165
1166
0
            return gs_is_CIDSystemInfo_compatible(
1167
0
                                gs_font_cid_system_info(font),
1168
0
                                gs_font_cid_system_info(font1));
1169
0
        }
1170
0
    default:
1171
0
        return false;
1172
1.38M
    }
1173
1.38M
}
1174
1175
/*
1176
 * Check whethet the font resource has glyphs.
1177
 */
1178
static bool
1179
pdf_font_has_glyphs(gx_device_pdf *pdev, pdf_font_resource_t *pdfont,
1180
                           gs_font *font, const pdf_char_glyph_pair_t *pairs, int num_chars)
1181
0
{
1182
    /*
1183
     * This crude version of the code ignores
1184
     * the possibility of re-encoding characters.
1185
     */
1186
0
    switch (pdfont->FontType) {
1187
0
    case ft_composite:
1188
0
    case ft_user_defined:
1189
0
    case ft_PDF_user_defined:
1190
0
    case ft_PCL_user_defined:
1191
0
    case ft_MicroType:
1192
0
    case ft_GL2_stick_user_defined:
1193
0
    case ft_GL2_531:
1194
        /* Unused case. */
1195
0
        return false;
1196
0
    case ft_encrypted:
1197
0
    case ft_encrypted2:
1198
0
    case ft_TrueType:
1199
0
        return pdf_check_encoding_has_glyphs(pdfont, pairs, num_chars);
1200
0
    case ft_CID_encrypted:
1201
0
    case ft_CID_TrueType:
1202
        /* Unused case. */
1203
0
        return false;
1204
0
    default:
1205
0
        return false;
1206
0
    }
1207
0
}
1208
1209
/*
1210
 * Find a font resource compatible with a given font.
1211
 */
1212
static int
1213
pdf_find_font_resource(gx_device_pdf *pdev, gs_font *font,
1214
                       pdf_resource_type_t type,
1215
                       pdf_font_resource_t **ppdfont,
1216
                       pdf_char_glyph_pairs_t *cgp,
1217
                       bool compatible_encoding)
1218
245k
{
1219
245k
    pdf_resource_t **pchain = pdev->resources[type].chains;
1220
245k
    pdf_resource_t *pres;
1221
245k
    int i;
1222
1223
4.06M
    for (i = 0; i < NUM_RESOURCE_CHAINS; i++) {
1224
5.55M
        for (pres = pchain[i]; pres != 0; pres = pres->next) {
1225
1.72M
            pdf_font_resource_t *pdfont = (pdf_font_resource_t *)pres;
1226
1.72M
            const gs_font_base *cfont;
1227
1.72M
            gs_font *ofont = font;
1228
1.72M
            int code;
1229
1230
1.72M
            cfont = (gs_font_base *)font;
1231
1.72M
            if (uid_is_XUID(&cfont->UID)){
1232
0
                int size = uid_XUID_size(&cfont->UID);
1233
0
                long *xvalues = uid_XUID_values(&cfont->UID);
1234
0
                if (xvalues && size >= 2 && xvalues[0] == 1000000) {
1235
0
                    if (xvalues[size - 1] != pdfont->XUID)
1236
0
                        continue;
1237
0
                }
1238
0
            }
1239
1240
1.72M
            if (font->FontType != pdfont->FontType)
1241
1.64M
                continue;
1242
79.2k
            if (pdfont->FontType == ft_composite) {
1243
0
                gs_font_type0 *font0 = (gs_font_type0 *)font;
1244
1245
0
                ofont = font0->data.FDepVector[0]; /* See pdf_make_font_resource. */
1246
0
                cfont = pdf_font_resource_font(pdfont->u.type0.DescendantFont, false);
1247
0
                if (font0->data.CMap->WMode != pdfont->u.type0.WMode)
1248
0
                    continue;
1249
0
            } else
1250
79.2k
                cfont = pdf_font_resource_font(pdfont, false);
1251
79.2k
            if (!pdf_is_CID_font(ofont) &&
1252
79.2k
                (compatible_encoding
1253
78.9k
                    ? !pdf_is_compatible_encoding(pdev, pdfont, font, cgp->s, cgp->num_all_chars)
1254
78.9k
                    : !pdf_font_has_glyphs(pdev, pdfont, font, cgp->s, cgp->num_all_chars)))
1255
931
                continue;
1256
78.3k
            if (cfont == 0)
1257
8
                continue;
1258
78.3k
            code = gs_copied_can_copy_glyphs((const gs_font *)cfont, ofont,
1259
78.3k
                            &cgp->s[cgp->unused_offset].glyph, cgp->num_unused_chars,
1260
78.3k
                            sizeof(pdf_char_glyph_pair_t), true);
1261
78.3k
            if (code == gs_error_unregistered) /* Debug purpose only. */
1262
0
                return code;
1263
78.3k
            if(code > 0) {
1264
15.3k
                *ppdfont = pdfont;
1265
15.3k
                return 1;
1266
15.3k
            }
1267
78.3k
        }
1268
3.83M
    }
1269
229k
    return 0;
1270
245k
}
1271
1272
/*
1273
 * Find a type0 font resource for a gived descendent name and CMap name.
1274
 */
1275
static int
1276
pdf_find_type0_font_resource(gx_device_pdf *pdev, const pdf_font_resource_t *pdsubf,
1277
            const gs_const_string *CMapName, uint font_index, pdf_font_resource_t **ppdfont)
1278
1
{
1279
1
    pdf_resource_t **pchain = pdev->resources[resourceFont].chains;
1280
1
    pdf_resource_t *pres;
1281
1
    int i;
1282
1283
17
    for (i = 0; i < NUM_RESOURCE_CHAINS; i++) {
1284
17
        for (pres = pchain[i]; pres != 0; pres = pres->next) {
1285
1
            pdf_font_resource_t *pdfont = (pdf_font_resource_t *)pres;
1286
1287
1
            if (pdfont->FontType != ft_composite)
1288
0
                continue;
1289
1
            if (pdfont->u.type0.DescendantFont != pdsubf)
1290
0
                continue;
1291
1
            if (pdfont->u.type0.font_index != font_index)
1292
0
                continue;
1293
1294
            /* Check to see if the PDF font name is of the form FontName-CMapName
1295
             * If it is, check the name and cmap against the BaseFont Name and CMap
1296
             * I'm not certain this is *ever* true.
1297
             */
1298
1
            if (pdfont->BaseFont.size == pdsubf->BaseFont.size + CMapName->size + 1) {
1299
0
                if (memcmp(pdfont->BaseFont.data + pdsubf->BaseFont.size + 1,
1300
0
                            CMapName->data, CMapName->size))
1301
0
                    continue;
1302
1
            } else {
1303
                /* Otherwise, check the PDF font name against the subfont name, and the
1304
                 * CMap used with the PDF font against the requested CMap. If either differs
1305
                 * then this PDF font is not usable.
1306
                 */
1307
1
                if (pdfont->BaseFont.size != pdsubf->BaseFont.size)
1308
0
                    continue;
1309
1
                if (pdfont->u.type0.CMapName_size != CMapName->size)
1310
0
                    continue;
1311
1
                if (memcmp(pdfont->u.type0.CMapName_data, CMapName->data, CMapName->size))
1312
1
                    continue;
1313
1
            }
1314
1315
0
            *ppdfont = pdfont;
1316
0
            return 1;
1317
1
        }
1318
16
    }
1319
1
    return 0;
1320
1
}
1321
1322
static int pdf_make_font_resource(gx_device_pdf *pdev, gs_font *font,
1323
                       pdf_font_resource_t **ppdfont,
1324
                       pdf_char_glyph_pairs_t *cgp);
1325
1326
/*
1327
 * Create or find a CID font resource object for a glyph set.
1328
 */
1329
int
1330
pdf_obtain_cidfont_resource(gx_device_pdf *pdev, gs_font *subfont,
1331
                            pdf_font_resource_t **ppdsubf,
1332
                            pdf_char_glyph_pairs_t *cgp)
1333
76.0k
{
1334
76.0k
    int code = 0;
1335
1336
76.0k
    code = pdf_attached_font_resource(pdev, subfont, ppdsubf, NULL, NULL, NULL, NULL);
1337
76.0k
    if (code < 0)
1338
0
        return code;
1339
76.0k
    if (*ppdsubf != NULL) {
1340
25.7k
        const gs_font_base *cfont = pdf_font_resource_font(*ppdsubf, false);
1341
1342
25.7k
        code = gs_copied_can_copy_glyphs((const gs_font *)cfont, subfont,
1343
25.7k
                        &cgp->s[cgp->unused_offset].glyph, cgp->num_unused_chars,
1344
25.7k
                        sizeof(pdf_char_glyph_pair_t), true);
1345
25.7k
        if (code > 0)
1346
25.7k
            return 0;
1347
0
        if (code < 0)
1348
0
            return code;
1349
0
        *ppdsubf = NULL;
1350
0
    }
1351
50.3k
    code = pdf_find_font_resource(pdev, subfont,
1352
50.3k
                                  resourceCIDFont, ppdsubf, cgp, true);
1353
50.3k
    if (code < 0)
1354
0
        return code;
1355
50.3k
    if (*ppdsubf == NULL) {
1356
50.3k
        code = pdf_make_font_resource(pdev, subfont, ppdsubf, cgp);
1357
50.3k
        if (code < 0)
1358
50.1k
            return code;
1359
50.3k
    }
1360
210
    return pdf_attach_font_resource(pdev, subfont, *ppdsubf);
1361
50.3k
}
1362
1363
/*
1364
 * Refine index of BaseEncoding.
1365
 */
1366
static int
1367
pdf_refine_encoding_index(const gx_device_pdf *pdev, int index, bool is_standard)
1368
11.9k
{
1369
11.9k
    if (pdev->ForOPDFRead) {
1370
        /*
1371
        * Allow Postscript encodings only.
1372
        * No, also allow MacRoman because if we have a TT font, and subset it, then opdfread
1373
        * will prefer thte MacRoman CMAP from the subset TT font.
1374
        */
1375
5.53k
        switch (index) {
1376
1377
310
            case ENCODING_INDEX_STANDARD: return index;
1378
982
            case ENCODING_INDEX_MACROMAN: return index;
1379
4.24k
            case ENCODING_INDEX_ISOLATIN1: return index;
1380
0
            default:
1381
0
                return ENCODING_INDEX_STANDARD;
1382
5.53k
        }
1383
5.53k
    }
1384
    /*
1385
     * Per the PDF 1.3 documentation, there are only 3 BaseEncoding
1386
     * values allowed for non-embedded fonts.  Pick one here.
1387
     */
1388
6.37k
    switch (index) {
1389
0
    case ENCODING_INDEX_WINANSI:
1390
0
    case ENCODING_INDEX_MACROMAN:
1391
0
    case ENCODING_INDEX_MACEXPERT:
1392
0
        return index;
1393
324
    case ENCODING_INDEX_STANDARD:
1394
324
        if (is_standard)
1395
285
            return index;
1396
        /* Falls through. */
1397
6.09k
    default:
1398
6.09k
        return ENCODING_INDEX_WINANSI;
1399
6.37k
    }
1400
6.37k
}
1401
1402
/*
1403
 * Create a font resource object for a gs_font of Type 3.
1404
 */
1405
int
1406
pdf_make_font3_resource(gx_device_pdf *pdev, gs_font *font,
1407
                       pdf_font_resource_t **ppdfont)
1408
161
{
1409
161
    const gs_font_base *bfont = (const gs_font_base *)font;
1410
161
    pdf_font_resource_t *pdfont;
1411
161
    byte *cached;
1412
161
    int code;
1413
1414
161
    cached = gs_alloc_bytes(pdev->pdf_memory, 256/8, "pdf_make_font3_resource");
1415
161
    if (cached == NULL)
1416
0
        return_error(gs_error_VMerror);
1417
161
    code = font_resource_encoded_alloc(pdev, &pdfont, bfont->id,
1418
161
                    ft_user_defined, pdf_write_contents_bitmap);
1419
161
    if (code < 0) {
1420
0
        gs_free_object(pdev->pdf_memory, cached, "pdf_make_font3_resource");
1421
0
        return code;
1422
0
    }
1423
161
    memset(cached, 0, 256 / 8);
1424
161
    pdfont->mark_glyph = font->dir->ccache.mark_glyph; /* For pdf_font_resource_enum_ptrs. */
1425
161
    pdfont->u.simple.s.type3.bitmap_font = false;
1426
161
    pdfont->u.simple.BaseEncoding = pdf_refine_encoding_index(pdev,
1427
161
                        bfont->nearest_encoding_index, true);
1428
161
    pdfont->u.simple.s.type3.char_procs = NULL;
1429
161
    pdfont->u.simple.s.type3.cached = cached;
1430
161
    if ((pdfont->FontType == ft_user_defined  || pdfont->FontType == ft_PDF_user_defined) && bfont->FontBBox.p.x == 0.0 &&
1431
161
        bfont->FontBBox.p.y == 0.00 && bfont->FontBBox.q.x == 0.00 &&
1432
161
        bfont->FontBBox.q.y == 0.0) {
1433
        /* I think this can only happen with a type 3 (bitmap) font from PCL.
1434
         * If we leave the BBox as 0 then we end up putting a 0 0 1000 1000 in
1435
         * the PDF. This causes Acrobat to be unable to search or highlight
1436
         * the search results. I think that we will always get a consistent
1437
         * type of font from the PCL interpreter, and if so the correct BBox
1438
         * sould always is 0 0 1 -1.
1439
         */
1440
116
        pdfont->u.simple.s.type3.FontBBox.p.x = 0;
1441
116
        pdfont->u.simple.s.type3.FontBBox.p.y = 0;
1442
116
        pdfont->u.simple.s.type3.FontBBox.q.x = 1;
1443
116
        pdfont->u.simple.s.type3.FontBBox.q.y = -1;
1444
116
    } else {
1445
45
        pdfont->u.simple.s.type3.FontBBox.p.x = bfont->FontBBox.p.x;
1446
45
        pdfont->u.simple.s.type3.FontBBox.p.y = bfont->FontBBox.p.y;
1447
45
        pdfont->u.simple.s.type3.FontBBox.q.x = bfont->FontBBox.q.x;
1448
45
        pdfont->u.simple.s.type3.FontBBox.q.y = bfont->FontBBox.q.y;
1449
45
    }
1450
161
    pdfont->u.simple.s.type3.FontMatrix = bfont->FontMatrix;
1451
161
    pdfont->u.simple.s.type3.Resources = cos_dict_alloc(pdev, "pdf_make_font3_resource");
1452
161
    if (pdfont->u.simple.s.type3.Resources == NULL)
1453
0
        return_error(gs_error_VMerror);
1454
    /* Adobe viewers have a precision problem with small font matrices : */
1455
    /* Don't perform this test if all entries are 0, leads to infinite loop! */
1456
161
    if (pdfont->u.simple.s.type3.FontMatrix.xx != 0.0 ||
1457
161
        pdfont->u.simple.s.type3.FontMatrix.xy != 0.0 ||
1458
161
        pdfont->u.simple.s.type3.FontMatrix.yx != 0.0 ||
1459
161
        pdfont->u.simple.s.type3.FontMatrix.yy != 0.0) {
1460
161
        while (any_abs(pdfont->u.simple.s.type3.FontMatrix.xx) < 0.001 &&
1461
161
               any_abs(pdfont->u.simple.s.type3.FontMatrix.xy) < 0.001 &&
1462
161
               any_abs(pdfont->u.simple.s.type3.FontMatrix.yx) < 0.001 &&
1463
161
               any_abs(pdfont->u.simple.s.type3.FontMatrix.yy) < 0.001) {
1464
0
            pdfont->u.simple.s.type3.FontMatrix.xx *= 10;
1465
0
            pdfont->u.simple.s.type3.FontMatrix.xy *= 10;
1466
0
            pdfont->u.simple.s.type3.FontMatrix.yx *= 10;
1467
0
            pdfont->u.simple.s.type3.FontMatrix.yy *= 10;
1468
0
        }
1469
161
    }
1470
161
    *ppdfont = pdfont;
1471
161
    return 0;
1472
161
}
1473
1474
/*
1475
 * Create a font resource object for a gs_font.  Return 1 iff the
1476
 * font was newly created (it's a roudiment, keeping reverse compatibility).
1477
 * This procedure is only intended to be called
1478
 * from a few places in the text code.
1479
 */
1480
static int
1481
pdf_make_font_resource(gx_device_pdf *pdev, gs_font *font,
1482
                       pdf_font_resource_t **ppdfont,
1483
                       pdf_char_glyph_pairs_t *cgp)
1484
229k
{
1485
229k
    int index = -1;
1486
229k
    int BaseEncoding = ENCODING_INDEX_UNKNOWN;
1487
229k
    pdf_font_embed_t embed;
1488
229k
    pdf_font_descriptor_t *pfd = 0;
1489
229k
    int (*font_alloc)(gx_device_pdf *, pdf_font_resource_t **,
1490
229k
                      gs_id, pdf_font_descriptor_t *);
1491
229k
    gs_font *base_font = font; /* A roudiment from old code. Keep it for a while. */
1492
229k
    pdf_font_resource_t *pdfont;
1493
229k
    pdf_standard_font_t *const psfa =
1494
229k
        pdev->text->outline_fonts->standard_fonts;
1495
229k
    int code = 0;
1496
229k
    long XUID = 0;
1497
229k
    gs_font_base *bfont = (gs_font_base *)font;
1498
1499
229k
    if (pdev->version < psdf_version_level2_with_TT) {
1500
0
        switch(font->FontType) {
1501
0
            case ft_TrueType:
1502
0
            case ft_CID_TrueType:
1503
0
                return_error(gs_error_undefined);
1504
0
            default:
1505
0
                break;
1506
0
        }
1507
0
    }
1508
229k
    if (pdev->ForOPDFRead && !pdev->HaveCIDSystem) {
1509
216k
        switch(font->FontType) {
1510
342
            case ft_CID_encrypted:
1511
49.8k
            case ft_CID_TrueType:
1512
49.8k
                return_error(gs_error_undefined);
1513
166k
            default:
1514
166k
                break;
1515
216k
        }
1516
216k
    }
1517
179k
    if (!pdev->HaveCFF) {
1518
166k
        if (font->FontType == ft_encrypted2)
1519
158k
            return_error(gs_error_undefined);
1520
166k
    }
1521
21.4k
    embed = pdf_font_embed_status(pdev, base_font, &index, cgp->s, cgp->num_all_chars);
1522
21.4k
    if (pdev->CompatibilityLevel < 1.3)
1523
8.30k
        if (embed != FONT_EMBED_NO && font->FontType == ft_CID_TrueType)
1524
0
            return_error(gs_error_rangecheck);
1525
21.4k
    if (embed == FONT_EMBED_STANDARD && pdev->CompatibilityLevel < 2.0) {
1526
2.77k
        pdf_standard_font_t *psf = &psfa[index];
1527
1528
2.77k
        if (psf->pdfont == NULL ||
1529
2.77k
                !pdf_is_compatible_encoding(pdev, psf->pdfont, font,
1530
2.77k
                        cgp->s, cgp->num_all_chars)) {
1531
2.77k
            code = pdf_font_std_alloc(pdev, ppdfont, (psf->pdfont == NULL), base_font->id,
1532
2.77k
                                      (gs_font_base *)base_font, index);
1533
2.77k
            if (code < 0)
1534
4
                return code;
1535
2.77k
            if (psf->pdfont == NULL)
1536
0
                psf->pdfont = *ppdfont;
1537
2.77k
            (*ppdfont)->u.simple.BaseEncoding = pdf_refine_encoding_index(pdev,
1538
2.77k
                ((const gs_font_base *)base_font)->nearest_encoding_index, true);
1539
2.77k
            code = 1;
1540
2.77k
        } else
1541
0
            *ppdfont = psf->pdfont;
1542
2.77k
        return code;
1543
2.77k
    }
1544
1545
18.7k
    if (uid_is_XUID(&bfont->UID)){
1546
0
        int size = uid_XUID_size(&bfont->UID);
1547
0
        long *xvalues = uid_XUID_values(&bfont->UID);
1548
0
        if (xvalues && size >= 2 && xvalues[0] == 1000000) {
1549
0
            XUID = xvalues[size - 1];
1550
0
        }
1551
0
    }
1552
1553
18.7k
    switch (font->FontType) {
1554
34
    case ft_CID_encrypted:
1555
421
    case ft_CID_TrueType:
1556
421
        font_alloc = pdf_font_cidfont_alloc;
1557
421
        break;
1558
7.83k
    case ft_encrypted:
1559
7.99k
    case ft_encrypted2:
1560
18.1k
    case ft_TrueType:
1561
18.1k
        font_alloc = pdf_font_simple_alloc;
1562
18.1k
        break;
1563
96
    case ft_user_defined:
1564
157
    case ft_PDF_user_defined:
1565
157
    case ft_PCL_user_defined:
1566
157
    case ft_MicroType:
1567
157
    case ft_GL2_stick_user_defined:
1568
157
    case ft_GL2_531:
1569
157
        code = pdf_make_font3_resource(pdev, font, ppdfont);
1570
157
        if (code < 0)
1571
0
            return code;
1572
157
        (*ppdfont)->XUID = XUID;
1573
157
        return 1;
1574
0
    default:
1575
0
        return_error(gs_error_invalidfont);
1576
18.7k
    }
1577
1578
    /* Create an appropriate font resource and descriptor. */
1579
18.5k
    if (embed == FONT_EMBED_YES) {
1580
        /*
1581
         * HACK: Acrobat Reader 3 has a bug that makes cmap formats 4
1582
         * and 6 not work in embedded TrueType fonts.  Consequently, it
1583
         * can only handle embedded TrueType fonts if all the glyphs
1584
         * referenced by the Encoding have numbers 0-255.  Check for
1585
         * this now.
1586
         */
1587
18.3k
        if (font->FontType == ft_TrueType &&
1588
18.3k
            pdev->CompatibilityLevel <= 1.2 && !pdev->ForOPDFRead
1589
18.3k
            ) {
1590
0
            int i;
1591
1592
0
            for (i = 0; i <= 0xff; ++i) {
1593
0
                gs_glyph glyph =
1594
0
                    font->procs.encode_char(font, (gs_char)i,
1595
0
                                            GLYPH_SPACE_INDEX);
1596
1597
0
                if (glyph == GS_NO_GLYPH ||
1598
0
                    (glyph >= GS_MIN_GLYPH_INDEX &&
1599
0
                     glyph <= GS_MIN_GLYPH_INDEX + 0xff)
1600
0
                    )
1601
0
                    continue;
1602
                /* Can't embed, punt. */
1603
0
                return_error(gs_error_rangecheck);
1604
0
            }
1605
0
        }
1606
18.3k
    }
1607
18.5k
    if ((code = pdf_font_descriptor_alloc(pdev, &pfd,
1608
18.5k
                                          (gs_font_base *)base_font,
1609
18.5k
                                          embed == FONT_EMBED_YES)) < 0 ||
1610
18.5k
        (code = font_alloc(pdev, &pdfont, base_font->id, pfd)) < 0
1611
18.5k
        )
1612
7.81k
        return code;
1613
1614
10.7k
    pdfont->XUID = XUID;
1615
10.7k
    pdf_do_subset_font(pdev, pfd->base_font, -1);
1616
1617
    /* If we have a TrueType font to embed, and we're producing an (E)PS output
1618
     * file, and we are subsetting the font, then the font we produce will *NOT*
1619
     * have the CMAP from the original TrueType font, we will generate a Windows 3,1
1620
     * and a MacRoman 1,0 CMAP, and the opdfread.ps code will prefer to use the
1621
     * MacRoman one. So, in this case, use MacRoman otherwise we will end up
1622
     * with erroneous encodings. Of course, when we are not subssetting the font
1623
     * we do want ot use the original fonts encoding.
1624
     */
1625
10.7k
    if ((font->FontType == ft_TrueType && pdev->ForOPDFRead)) {
1626
982
        if (pfd->base_font->do_subset == DO_SUBSET_YES)
1627
982
            BaseEncoding = pdf_refine_encoding_index(pdev,
1628
982
                ENCODING_INDEX_MACROMAN, false);
1629
0
        else
1630
0
            BaseEncoding = pdf_refine_encoding_index(pdev,
1631
0
                ((const gs_font_base *)base_font)->nearest_encoding_index, false);
1632
982
    }
1633
10.7k
    if (font->FontType == ft_encrypted || font->FontType == ft_encrypted2
1634
10.7k
        || (font->FontType == ft_TrueType && ((const gs_font_base *)base_font)->nearest_encoding_index != ENCODING_INDEX_UNKNOWN && pfd->base_font->do_subset == DO_SUBSET_NO)) {
1635
        /* Yet more crazy heuristics. If we embed a TrueType font and don't subset it, then
1636
         * we preserve the CMAP subtable(s) rather than generatng new ones. The problem is
1637
         * that if we ake the font symbolic, Acrobat uses the 1,0 CMAP, whereas if we don't
1638
         * It uses the 3,1 CMAP (and the Encoding). If these two are not compatible, then
1639
         * the result will be different. So, if we are not subsetting the font, and the original
1640
         * font wasn't symbolic (it has an Encoding) then we will create a new Encoding, and
1641
         * in pdf_write_font_descriptor we wil take back off the symbolic flag.
1642
         */
1643
        /* Removed the addition of Encodings to TrueType fonts as we always write
1644
         * these with the Symbolic flag set. The comment below explains why we
1645
         * previously wrote these, but as the comment notes this was incorrect.
1646
         * Removed as it is causing preflight problems, and is specifically
1647
         * disallowed with PDF/A output.
1648
         */
1649
        /*
1650
         * We write True Types with Symbolic flag set.
1651
         * PDF spec says that "symbolic font should not specify Encoding entry"
1652
         * (see section 5.5, the article "Encodings for True Type fonts", paragraph 3).
1653
         * However Acrobat Reader 4,5,6 fail when TT font with no Encoding
1654
         * appears in a document together with a CID font with a non-standard CMap
1655
         * (AR 4 and 5 claim "The encoding (CMap) specified by a font is corrupted."
1656
         * (we read it as "The encoding or CMap specified by a font is corrupted.",
1657
         * and apply the 1st alternative)). We believe that AR is buggy,
1658
         * and therefore we write an Encoding with non-CID True Type fonts.
1659
         * Hopely other viewers can ignore Encoding in such case. Actually in this case
1660
         * an Encoding doesn't add an useful information.
1661
         */
1662
7.99k
        BaseEncoding = pdf_refine_encoding_index(pdev,
1663
7.99k
            ((const gs_font_base *)base_font)->nearest_encoding_index, false);
1664
7.99k
    }
1665
10.7k
    if (!pdf_is_CID_font(font)) {
1666
10.5k
        pdfont->u.simple.BaseEncoding = BaseEncoding;
1667
10.5k
        pdfont->mark_glyph = font->dir->ccache.mark_glyph;
1668
10.5k
    }
1669
1670
10.7k
    if (pdev->PDFA != 0 && font->FontType == ft_TrueType) {
1671
        /* The Adobe preflight tool for PDF/A
1672
           checks whether Width or W include elements
1673
           for all characters in the True Type font.
1674
           Due to that we need to provide a width
1675
           for .notdef glyph.
1676
           (It's a part of the bug 688790).
1677
         */
1678
0
        gs_font_base *cfont = pdf_font_descriptor_font(pfd, false/*any*/);
1679
0
        gs_glyph notdef_glyph = copied_get_notdef((const gs_font *)cfont);
1680
0
        pdf_glyph_widths_t widths;
1681
0
        double cdevproc_result[10] = {0,0,0,0,0, 0,0,0,0,0};
1682
0
        double *w, *v, *w0;
1683
1684
0
        if (notdef_glyph != GS_NO_GLYPH) {
1685
0
            code = pdf_obtain_cidfont_widths_arrays(pdev, pdfont, font->WMode, &w, &w0, &v);
1686
0
            if (code < 0)
1687
0
                return code;
1688
0
            widths.Width.w = 0;
1689
0
            code = pdf_glyph_widths(pdfont, font->WMode, notdef_glyph,
1690
0
                 font, &widths, cdevproc_result);
1691
0
            if (code < 0)
1692
0
                return code;
1693
0
            w[0] = widths.Width.w;
1694
0
            pdfont->used[0] |= 0x80;
1695
0
        }
1696
0
    }
1697
10.7k
    *ppdfont = pdfont;
1698
10.7k
    return 1;
1699
10.7k
}
1700
1701
/*
1702
 * Check for simple font.
1703
 */
1704
bool
1705
pdf_is_simple_font(gs_font *font)
1706
2.82M
{
1707
2.82M
    return (font->FontType == ft_encrypted ||
1708
2.82M
            font->FontType == ft_encrypted2 ||
1709
2.82M
            font->FontType == ft_TrueType ||
1710
2.82M
            font->FontType == ft_user_defined ||
1711
2.82M
            font->FontType == ft_PDF_user_defined ||
1712
2.82M
            font->FontType == ft_PCL_user_defined ||
1713
2.82M
            font->FontType == ft_MicroType ||
1714
2.82M
            font->FontType == ft_GL2_stick_user_defined ||
1715
2.82M
            font->FontType == ft_GL2_531);
1716
2.82M
}
1717
1718
/*
1719
 * Check for CID font.
1720
 */
1721
bool
1722
pdf_is_CID_font(gs_font *font)
1723
311k
{
1724
311k
    return (font->FontType == ft_CID_encrypted ||
1725
311k
            font->FontType == ft_CID_TrueType);
1726
311k
}
1727
1728
/*
1729
 * Enumerate glyphs for a text.
1730
 */
1731
static int
1732
pdf_next_char_glyph(gs_text_enum_t *penum, const gs_string *pstr,
1733
               /* const */ gs_font *font, bool font_is_simple,
1734
               gs_char *char_code, gs_char *cid, gs_glyph *glyph)
1735
15.7M
{
1736
15.7M
    int code = font->procs.next_char_glyph(penum, char_code, glyph);
1737
1738
15.7M
    if (code == 2)                /* end of string */
1739
2.82M
        return code;
1740
12.9M
    if (code < 0)
1741
0
        return code;
1742
12.9M
    if (font_is_simple) {
1743
12.9M
        *cid = *char_code;
1744
12.9M
        *glyph = font->procs.encode_char(font, *char_code, GLYPH_SPACE_NAME);
1745
12.9M
        if (*glyph == GS_NO_GLYPH)
1746
62
            return 3;
1747
12.9M
    } else {
1748
0
        if (*glyph < GS_MIN_CID_GLYPH)
1749
0
            return 3; /* Not sure why, copied from scan_cmap_text. */
1750
0
        *cid = *glyph - GS_MIN_CID_GLYPH; /* CID */
1751
0
    }
1752
12.9M
    return 0;
1753
12.9M
}
1754
1755
static void
1756
store_glyphs(pdf_char_glyph_pairs_t *cgp,
1757
             byte *glyph_usage, int char_cache_size,
1758
             gs_char char_code, gs_char cid, gs_glyph glyph)
1759
6.50M
{
1760
6.50M
    int j;
1761
1762
74.6M
    for (j = 0; j < cgp->num_all_chars; j++)
1763
70.4M
        if (cgp->s[j].chr == cid)
1764
2.21M
            break;
1765
6.50M
    if (j < cgp->num_all_chars)
1766
2.21M
        return;
1767
4.28M
    cgp->s[cgp->num_all_chars].glyph = glyph;
1768
4.28M
    cgp->s[cgp->num_all_chars].chr = char_code;
1769
4.28M
    cgp->num_all_chars++;
1770
4.28M
    if (glyph_usage == 0 || !(glyph_usage[cid / 8] & (0x80 >> (cid & 7)))) {
1771
867k
        cgp->s[cgp->unused_offset + cgp->num_unused_chars].glyph = glyph;
1772
867k
        cgp->s[cgp->unused_offset + cgp->num_unused_chars].chr = char_code;
1773
867k
        cgp->num_unused_chars++;
1774
867k
    }
1775
    /* We are disliked that gs_copied_can_copy_glyphs can get redundant
1776
     * glyphs, if Encoding specifies several codes for same glyph.
1777
     * But we need the positional correspondence
1778
     * of glyphs to codes for pdf_is_compatible_encoding.
1779
     * Redundant glyphs isn't a big payment for it
1780
     * because they happen seldom.
1781
     */
1782
4.28M
}
1783
1784
static gs_char
1785
pdf_new_char_code_in_pdfont(pdf_char_glyph_pairs_t *cgp, gs_glyph glyph, int *last_reserved_char)
1786
0
{   /* Returns 256 if encoding overflows. */
1787
0
    int j, ch;
1788
1789
0
    for (j = 0; j < cgp->num_all_chars; j++)
1790
0
        if (cgp->s[j].glyph == glyph)
1791
0
            break;
1792
0
    if (j < cgp->num_all_chars)
1793
0
        return cgp->s[j].chr;
1794
0
    ch = ++*last_reserved_char;
1795
0
    cgp->s[cgp->num_all_chars].glyph = glyph;
1796
0
    cgp->s[cgp->num_all_chars].chr = ch;
1797
0
    cgp->num_all_chars++;
1798
0
    cgp->s[cgp->unused_offset + cgp->num_unused_chars].glyph = glyph;
1799
0
    cgp->s[cgp->unused_offset + cgp->num_unused_chars].chr = ch;
1800
0
    cgp->num_unused_chars++;
1801
0
    return ch;
1802
0
}
1803
1804
static gs_char
1805
pdf_reserve_char_code_in_pdfont(pdf_font_resource_t *pdfont, pdf_char_glyph_pairs_t *cgp, gs_glyph glyph,
1806
                                int *last_reserved_char)
1807
0
{   /* Returns 256 if encoding overflows. */
1808
    /* This function is pretty slow, but we can't find a better algorithm.
1809
       It works for the case of glyphshow with no proper encoding,
1810
       which we believe comes from poorly designed documents.
1811
     */
1812
0
    int j, ch;
1813
1814
0
    for (j = 0; j < cgp->num_all_chars; j++)
1815
0
        if (cgp->s[j].glyph == glyph)
1816
0
            break;
1817
0
    if (j < cgp->num_all_chars)
1818
0
        return cgp->s[j].chr;
1819
1820
0
    for (ch = 0; ch < 256; ch++) {
1821
0
        pdf_encoding_element_t *pet = &pdfont->u.simple.Encoding[ch];
1822
1823
0
        if (glyph == pet->glyph)
1824
0
            return ch;
1825
0
    }
1826
    /* If the font has a known encoding, prefer .notdef codes. */
1827
0
    if (pdfont->u.simple.preferred_encoding_index != -1) {
1828
0
        const ushort *enc = gs_c_known_encodings[pdfont->u.simple.preferred_encoding_index];
1829
1830
0
        for (ch = *last_reserved_char + 1; ch < 256; ch++) {
1831
0
            pdf_encoding_element_t *pet = &pdfont->u.simple.Encoding[ch];
1832
1833
0
            if (pet->glyph == GS_NO_GLYPH && enc[ch] == pdfont->u.simple.standard_glyph_code_for_notdef) {
1834
0
                *last_reserved_char = ch;
1835
0
                break;
1836
0
            }
1837
0
        }
1838
0
    }
1839
    /* Otherwise use any code unused in the font. */
1840
0
    if (ch > 255) {
1841
0
        ch = *last_reserved_char + 1;
1842
0
        for (; ch < 255; ch++) {
1843
0
            pdf_encoding_element_t *pet = &pdfont->u.simple.Encoding[ch];
1844
1845
0
            if (pet->glyph == GS_NO_GLYPH)
1846
0
                break;
1847
0
        }
1848
0
        *last_reserved_char = ch;
1849
0
    }
1850
0
    cgp->s[cgp->num_all_chars].glyph = glyph;
1851
0
    cgp->s[cgp->num_all_chars].chr = ch;
1852
0
    cgp->num_all_chars++;
1853
0
    cgp->s[cgp->unused_offset + cgp->num_unused_chars].glyph = glyph;
1854
0
    cgp->s[cgp->unused_offset + cgp->num_unused_chars].chr = ch;
1855
0
    cgp->num_unused_chars++;
1856
0
    return ch;
1857
0
}
1858
1859
/* Allocate storage for the glyph set of the text. */
1860
static int
1861
pdf_alloc_text_glyphs_table(gx_device_pdf *pdev, pdf_text_enum_t *penum, const gs_string *pstr)
1862
1.49M
{
1863
1.49M
    const int go = (pstr != NULL ? pstr->size : penum->text.size);
1864
1.49M
    const int struct_size = sizeof(pdf_char_glyph_pairs_t) +
1865
1.49M
                            sizeof(pdf_char_glyph_pair_t) * (2 * go - 1);
1866
1.49M
    pdf_char_glyph_pairs_t *cgp = (pdf_char_glyph_pairs_t *)gs_alloc_bytes(penum->memory,
1867
1.49M
                struct_size, "pdf_alloc_text_glyphs_table");
1868
1.49M
    if (cgp == NULL)
1869
0
        return_error(gs_error_VMerror);
1870
1.49M
    penum->cgp = cgp;
1871
1.49M
    cgp->unused_offset = go;
1872
1.49M
    cgp->num_all_chars = 0;
1873
1.49M
    cgp->num_unused_chars = 0;
1874
1.49M
    return 0;
1875
1.49M
}
1876
1877
/* Build the glyph set of the text. */
1878
static int
1879
pdf_make_text_glyphs_table(pdf_text_enum_t *penum, const gs_string *pstr,
1880
                byte *glyph_usage, int char_cache_size)
1881
1.49M
{
1882
1.49M
    gs_text_enum_t scan = *(gs_text_enum_t *)penum;
1883
1.49M
    gs_font *font = (gs_font *)penum->current_font;
1884
1.49M
    bool font_is_simple = pdf_is_simple_font(font);
1885
1.49M
    pdf_char_glyph_pairs_t *cgp = penum->cgp;
1886
1.49M
    gs_char char_code, cid;
1887
1.49M
    gs_glyph glyph;
1888
1.49M
    int code;
1889
1890
1.49M
    cgp->num_unused_chars = 0;
1891
1.49M
    cgp->num_all_chars = 0;
1892
1.49M
    if (pstr != NULL) {
1893
1.49M
        scan.text.data.bytes = pstr->data;
1894
1.49M
        scan.text.size = pstr->size;
1895
1.49M
        scan.index = 0;
1896
        /* if TEXT_FROM_CHARS the data was converted to bytes earlier */
1897
1.49M
        if ( scan.text.operation & TEXT_FROM_CHARS )
1898
985
            scan.text.operation = ((scan.text.operation & ~TEXT_FROM_CHARS) | TEXT_FROM_STRING);
1899
1.49M
    }
1900
7.99M
    for (;;) {
1901
7.99M
        code = pdf_next_char_glyph(&scan, pstr, font, font_is_simple,
1902
7.99M
                                   &char_code, &cid, &glyph);
1903
7.99M
        if (code == 2)                /* end of string */
1904
1.49M
            break;
1905
6.50M
        if (code == 3)                /* no glyph */
1906
31
            continue;
1907
6.50M
        if (code < 0)
1908
0
            return code;
1909
6.50M
        if (cgp->num_all_chars > cgp->unused_offset)
1910
0
            return_error(gs_error_unregistered); /* Must not happen. */
1911
6.50M
        if (glyph_usage != 0 && cid > char_cache_size)
1912
0
            continue;
1913
6.50M
        store_glyphs(cgp, glyph_usage, char_cache_size,
1914
6.50M
                     char_code, cid, glyph);
1915
6.50M
    }
1916
1.49M
    return 0;
1917
1.49M
}
1918
1919
/* Build the glyph set of the glyphshow text, and re_encode the text. */
1920
static int
1921
pdf_make_text_glyphs_table_unencoded(gx_device_pdf *pdev, pdf_char_glyph_pairs_t *cgp,
1922
                gs_font *font, const gs_string *pstr, const gs_glyph *gdata,
1923
                int *ps_encoding_index)
1924
0
{
1925
0
    int i, j, code;
1926
0
    gs_char ch;
1927
0
    gs_const_string gname;
1928
0
    gs_glyph *gid = (gs_glyph *)pstr->data; /* pdf_text_process allocs enough space. */
1929
0
    gs_font_base *bfont;
1930
0
    bool unknown = false;
1931
0
    pdf_font_resource_t *pdfont;
1932
0
    int ei, start_ei = -1;
1933
1934
0
    code = pdf_attached_font_resource(pdev, font, &pdfont, NULL, NULL, NULL, NULL);
1935
0
    if (code < 0)
1936
0
        return code;
1937
    /* Translate glyph name indices into gscencs.c indices. */
1938
0
    for (i = 0; i < pstr->size; i++) {
1939
0
        int code = font->procs.glyph_name(font, gdata[i], &gname);
1940
1941
0
        if (code < 0)
1942
0
            return code;
1943
0
        gid[i] = gs_c_name_glyph(gname.data, gname.size);
1944
0
        if (gid[i] == GS_NO_GLYPH) {
1945
            /* Use global glyph name. */
1946
            /* Assuming this can't fail in a middle of a text,
1947
               because TEXT_FROM_GLYPHS never works for Postscript. */
1948
0
            gid[i] = gdata[i];
1949
0
            unknown = true;
1950
0
        }
1951
0
    }
1952
0
do_unknown:
1953
0
    if (unknown) {
1954
0
        int last_reserved_char = -1;
1955
         /* Using global glyph names. */
1956
1957
        /* Try to find an existing font resource, which has necessary glyphs.
1958
           Doing so to prevent creating multiple font copies.
1959
         */
1960
0
        cgp->num_unused_chars = 0;
1961
0
        cgp->num_all_chars = 0;
1962
0
        for (i = 0; i < pstr->size; i++) {
1963
            /* Temporary stub gid instead cid and char_code : */
1964
0
            store_glyphs(cgp, NULL, 0, gdata[i], gdata[i], gdata[i]);
1965
0
        }
1966
0
        code = pdf_find_font_resource(pdev, font, resourceFont, &pdfont, cgp, false);
1967
0
        if (code < 0)
1968
0
            return code;
1969
0
        if (code) {
1970
            /* Found one - make it be current. */
1971
0
            code = pdf_attach_font_resource(pdev, font, pdfont);
1972
0
            if (code < 0)
1973
0
                return code;
1974
0
        }
1975
        /* Try to add glyphs to the current font resource. . */
1976
0
        cgp->num_unused_chars = 0;
1977
0
        cgp->num_all_chars = 0;
1978
1979
0
        if(pdfont != NULL)
1980
0
                last_reserved_char = pdfont->u.simple.last_reserved_char;
1981
1982
0
        for (i = 0; i < pstr->size; i++) {
1983
1984
0
            if (pdfont == NULL)
1985
0
                ch = 256; /* Force new encoding. */
1986
0
            else
1987
0
                ch = pdf_reserve_char_code_in_pdfont(pdfont, cgp, gdata[i], &last_reserved_char);
1988
0
            if (ch > 255) {
1989
0
                if(pdfont != NULL)
1990
0
                        last_reserved_char = pdfont->u.simple.last_reserved_char;
1991
                /* Start a new font/encoding. */
1992
0
                last_reserved_char = -1;
1993
1994
0
                cgp->num_unused_chars = 0;
1995
0
                cgp->num_all_chars = 0;
1996
0
                for (i = 0; i < pstr->size; i++) {
1997
0
                    ch = pdf_new_char_code_in_pdfont(cgp, gdata[i], &last_reserved_char);
1998
0
                    if (ch > 255) {
1999
                        /* More than 255 unknown characters in a text.
2000
                           It must not happen because TEXT_FROM_GLYPHS
2001
                           never works for Postscript. */
2002
0
                        return_error(gs_error_unregistered);
2003
0
                    }
2004
0
                }
2005
0
            }
2006
0
        }
2007
0
        if (pdfont != NULL)
2008
0
            pdfont->u.simple.last_reserved_char = last_reserved_char;
2009
        /* Change glyphs to char codes in the text : */
2010
0
        for (i = 0; i < pstr->size; i++) {
2011
            /* Picked up by Coverity, if pdfont is NULL then the call might dereference it */
2012
0
            if (pdfont != NULL) {
2013
                /* A trick : pdf_reserve_char_code_in_pdfont here simply encodes with cgp. */
2014
0
                ch = pdf_reserve_char_code_in_pdfont(pdfont, cgp, gdata[i], &pdfont->u.simple.last_reserved_char);
2015
0
                pstr->data[i] = ch;
2016
0
            } else {
2017
                /* So if pdffont is NULL, do the 'trick' code mentioned above.
2018
                 * If that fails (I believe it shouod not), then return an error.
2019
                 */
2020
0
                int j;
2021
2022
0
                for (j = 0; j < cgp->num_all_chars; j++)
2023
0
                    if (cgp->s[j].glyph == gdata[i])
2024
0
                        break;
2025
0
                if (j < cgp->num_all_chars)
2026
0
                    pstr->data[i] = cgp->s[j].chr;
2027
0
                else
2028
0
                    return_error(gs_error_unregistered);
2029
0
            }
2030
0
        }
2031
0
        return 0;
2032
0
    }
2033
    /* Now we know it's a base font, bcause it has glyph names. */
2034
0
    bfont = (gs_font_base *)font;
2035
0
    if (start_ei < 0)
2036
0
        start_ei = bfont->nearest_encoding_index;
2037
0
    if (start_ei < 0)
2038
0
        start_ei = 0;
2039
    /* Find an acceptable encodng, starting from start_ei.
2040
       We need a conservative search to minimize the probability
2041
       of encoding conflicts.
2042
     */
2043
0
    for (j = 0, ei = start_ei; gs_c_known_encodings[j]; j++, ei++) {
2044
0
        if (!gs_c_known_encodings[ei])
2045
0
            ei = 0;
2046
        /* Restrict with PDF encodings, because others give frequent conflicts. */
2047
0
        if (ei > 5) /* Hack : gscedata.c must provide a constant. */
2048
0
            continue;
2049
0
        cgp->num_unused_chars = 0;
2050
0
        cgp->num_all_chars = 0;
2051
0
        for (i = 0; i < pstr->size; i++) {
2052
0
            ch = gs_c_decode(gid[i], ei);
2053
0
            if (ch == GS_NO_CHAR)
2054
0
                break;
2055
0
            if (ch > 255)
2056
0
                break; /* MacGlyphEncoding defines extra glyphs. */
2057
            /* pstr->data[i] = (byte)ch; Can't do because pstr->data and gid
2058
               are same pointer. Will do in a separate pass below. */
2059
0
            store_glyphs(cgp, NULL, 0, ch, ch, gdata[i]);
2060
0
        }
2061
0
        *ps_encoding_index = ei;
2062
0
        if (i == pstr->size) {
2063
            /* Change glyphs to char codes in the text : */
2064
0
            for (i = 0; i < pstr->size; i++)
2065
0
                pstr->data[i] = (byte)gs_c_decode(gid[i], ei);
2066
0
            return 0;
2067
0
        }
2068
0
    }
2069
0
    unknown = true;
2070
0
    goto do_unknown;
2071
0
}
2072
2073
/* Get/make font resource for the font with a known encoding. */
2074
static int
2075
pdf_obtain_font_resource_encoded(gx_device_pdf *pdev, gs_font *font,
2076
        pdf_font_resource_t **ppdfont, pdf_char_glyph_pairs_t *cgp)
2077
1.49M
{
2078
1.49M
    int code;
2079
1.49M
    pdf_font_resource_t *pdfont_not_allowed = NULL;
2080
2081
1.49M
    if (*ppdfont != 0) {
2082
1.30M
        gs_font_base *cfont = pdf_font_resource_font(*ppdfont, false);
2083
2084
1.30M
        if (font->FontType != ft_user_defined &&
2085
1.30M
            font->FontType != ft_PDF_user_defined &&
2086
1.30M
            font->FontType != ft_PCL_user_defined &&
2087
1.30M
            font->FontType != ft_MicroType &&
2088
1.30M
            font->FontType != ft_GL2_stick_user_defined &&
2089
1.30M
            font->FontType != ft_GL2_531) {
2090
1.29M
            code = gs_copied_can_copy_glyphs((gs_font *)cfont, font,
2091
1.29M
                        &cgp->s[cgp->unused_offset].glyph, cgp->num_unused_chars,
2092
1.29M
                        sizeof(pdf_char_glyph_pair_t), true);
2093
1.29M
            if (code < 0)
2094
0
                code = 1;
2095
1.29M
        } else
2096
5.63k
            code = 1;
2097
1.30M
        if (code == 0) {
2098
1.17k
            pdfont_not_allowed = *ppdfont;
2099
1.17k
            *ppdfont = 0;
2100
1.30M
        } else if(!pdf_is_compatible_encoding(pdev, *ppdfont, font,
2101
1.30M
                        cgp->s, cgp->num_all_chars)) {
2102
0
            pdfont_not_allowed = *ppdfont;
2103
0
            *ppdfont = 0;
2104
0
        }
2105
1.30M
    }
2106
1.49M
    if (*ppdfont == 0) {
2107
194k
        gs_font *base_font = font;
2108
194k
        gs_font *below;
2109
194k
        bool same_encoding = true;
2110
2111
        /*
2112
         * Find the "lowest" base font that has the same outlines.
2113
         * We use its FontName for font resource.
2114
         */
2115
195k
        while ((below = base_font->base) != base_font &&
2116
195k
               base_font->procs.same_font(base_font, below, FONT_SAME_OUTLINES))
2117
552
            base_font = below;
2118
194k
        if (base_font != font)
2119
552
            same_encoding = ((base_font->procs.same_font(base_font, font,
2120
552
                              FONT_SAME_ENCODING) & FONT_SAME_ENCODING) != 0);
2121
        /* Find or make font resource. */
2122
194k
        code = pdf_attached_font_resource(pdev, base_font, ppdfont, NULL, NULL, NULL, NULL);
2123
194k
        if (code < 0)
2124
0
            return code;
2125
194k
        if (base_font != font) {
2126
552
            if (pdfont_not_allowed == *ppdfont)
2127
552
                *ppdfont = NULL;
2128
552
        }
2129
194k
        if(*ppdfont != NULL && !pdf_is_compatible_encoding(pdev, *ppdfont,
2130
1.17k
                                    base_font, cgp->s, cgp->num_all_chars))
2131
0
                *ppdfont = NULL;
2132
194k
        if (*ppdfont == NULL || *ppdfont == pdfont_not_allowed) {
2133
194k
            pdf_resource_type_t type =
2134
194k
                (pdf_is_CID_font(base_font) ? resourceCIDFont
2135
194k
                                            : resourceFont);
2136
194k
            *ppdfont = NULL;
2137
194k
            code = pdf_find_font_resource(pdev, base_font, type, ppdfont, cgp, true);
2138
194k
            if (code < 0)
2139
0
                return code;
2140
194k
            if (*ppdfont == NULL) {
2141
179k
                code = pdf_make_font_resource(pdev, base_font, ppdfont, cgp);
2142
179k
                if (code < 0)
2143
165k
                    return code;
2144
179k
            }
2145
28.8k
            if (base_font != font && same_encoding) {
2146
552
                code = pdf_attach_font_resource(pdev, base_font, *ppdfont);
2147
552
                if (code < 0)
2148
0
                    return code;
2149
552
            }
2150
28.8k
        }
2151
28.8k
        code = pdf_attach_font_resource(pdev, font, *ppdfont);
2152
28.8k
        if (code < 0)
2153
0
            return code;
2154
28.8k
    }
2155
1.33M
    return 0;
2156
1.49M
}
2157
2158
/* Mark glyphs used in the text with the font resource. */
2159
static int
2160
pdf_mark_text_glyphs(const gs_text_enum_t *penum, const gs_string *pstr,
2161
            byte *glyph_usage, int char_cache_size)
2162
1.33M
{
2163
1.33M
    gs_text_enum_t scan = *penum;
2164
1.33M
    gs_font *font = (gs_font *)penum->current_font;
2165
1.33M
    bool font_is_simple = pdf_is_simple_font(font);
2166
1.33M
    gs_char char_code, cid;
2167
1.33M
    gs_glyph glyph;
2168
2169
1.33M
    if (glyph_usage == NULL)
2170
0
        return 0;
2171
2172
1.33M
    if (pstr != NULL) {
2173
1.33M
        scan.text.data.bytes = pstr->data;
2174
1.33M
        scan.text.size = pstr->size;
2175
1.33M
        scan.index = 0;
2176
        /* if TEXT_FROM_CHARS the data was converted to bytes earlier */
2177
1.33M
        if ( scan.text.operation & TEXT_FROM_CHARS )
2178
2.32k
            scan.text.operation =
2179
2.32k
                ((scan.text.operation & ~TEXT_FROM_CHARS) | TEXT_FROM_STRING);
2180
1.33M
    }
2181
7.75M
    for (;;) {
2182
7.75M
        int code = pdf_next_char_glyph(&scan, pstr, font, font_is_simple,
2183
7.75M
                                       &char_code, &cid, &glyph);
2184
2185
7.75M
        if (code == 2)                /* end of string */
2186
1.33M
            break;
2187
6.42M
        if (code == 3)                /* no glyph */
2188
31
            continue;
2189
6.42M
        if (code < 0)
2190
0
            return code;
2191
6.42M
        if (cid >= char_cache_size)
2192
0
            continue;
2193
6.42M
        glyph_usage[cid / 8] |= 0x80 >> (cid & 7);
2194
6.42M
    }
2195
1.33M
    return 0;
2196
1.33M
}
2197
2198
/* Mark glyphs used in the glyphshow text with the font resource. */
2199
static int
2200
pdf_mark_text_glyphs_unencoded(const gs_text_enum_t *penum, const gs_string *pstr,
2201
            byte *glyph_usage, int char_cache_size)
2202
0
{
2203
0
    int i;
2204
2205
0
    for(i = 0; i < pstr->size; i++) {
2206
0
        byte ch = pstr->data[i];
2207
2208
0
        if (ch >= char_cache_size)
2209
0
            return_error(gs_error_rangecheck);
2210
0
        glyph_usage[ch / 8] |= 0x80 >> (ch & 7);
2211
0
    }
2212
0
    return 0;
2213
0
}
2214
2215
/*
2216
 * Create or find a font resource object for a text.
2217
 */
2218
int
2219
pdf_obtain_font_resource(pdf_text_enum_t *penum,
2220
            const gs_string *pstr, pdf_font_resource_t **ppdfont)
2221
1.49M
{
2222
1.49M
    gx_device_pdf *pdev = (gx_device_pdf *)penum->dev;
2223
1.49M
    gs_font *font = (gs_font *)penum->current_font;
2224
1.49M
    byte *glyph_usage = 0;
2225
1.49M
    double *real_widths;
2226
1.49M
    int char_cache_size, width_cache_size;
2227
1.49M
    int code;
2228
2229
1.49M
    if (font->FontType == ft_composite) {
2230
        /* Must not happen, because we always split composite fonts into descendents. */
2231
0
        return_error(gs_error_unregistered);
2232
0
    }
2233
1.49M
    code = pdf_attached_font_resource(pdev, font, ppdfont,
2234
1.49M
                               &glyph_usage, &real_widths, &char_cache_size, &width_cache_size);
2235
    /* *ppdfont is NULL if no resource attached. */
2236
1.49M
    if (code < 0)
2237
0
        return code;
2238
1.49M
    if (penum->cgp == NULL) {
2239
1.49M
        code = pdf_alloc_text_glyphs_table(pdev, penum, pstr);
2240
1.49M
        if (code < 0)
2241
0
            return code;
2242
1.49M
        code = pdf_make_text_glyphs_table(penum, pstr,
2243
1.49M
                            glyph_usage, char_cache_size);
2244
1.49M
        if (code < 0)
2245
0
            return code;
2246
1.49M
    }
2247
1.49M
    code = pdf_obtain_font_resource_encoded(pdev, font, ppdfont, penum->cgp);
2248
1.49M
    if (code < 0)
2249
165k
        return code;
2250
1.33M
    code = pdf_attached_font_resource(pdev, font, ppdfont,
2251
1.33M
                               &glyph_usage, &real_widths, &char_cache_size, &width_cache_size);
2252
1.33M
    if (code < 0)
2253
0
        return code;
2254
1.33M
    return pdf_mark_text_glyphs((const gs_text_enum_t *)penum, pstr, glyph_usage, char_cache_size);
2255
1.33M
}
2256
2257
/*
2258
 * Create or find a font resource object for a glyphshow text.
2259
 */
2260
int
2261
pdf_obtain_font_resource_unencoded(pdf_text_enum_t *penum,
2262
            const gs_string *pstr, pdf_font_resource_t **ppdfont, const gs_glyph *gdata)
2263
0
{
2264
0
    gx_device_pdf *pdev = (gx_device_pdf *)penum->dev;
2265
0
    gs_font *font = (gs_font *)penum->current_font;
2266
0
    byte *glyph_usage = 0;
2267
0
    double *real_widths = 0;
2268
0
    int char_cache_size = 0, width_cache_size = 0;
2269
0
    int code, ps_encoding_index = -1;
2270
2271
0
    if (font->FontType == ft_composite) {
2272
        /* Must not happen, because we always split composite fonts into descendents. */
2273
0
        return_error(gs_error_unregistered);
2274
0
    }
2275
0
    code = pdf_attached_font_resource(pdev, font, ppdfont,
2276
0
                               &glyph_usage, &real_widths, &char_cache_size, &width_cache_size);
2277
0
    if (code < 0)
2278
0
        return code;
2279
    /* *ppdfont is NULL if no resource attached. */
2280
0
    if (*ppdfont != NULL)
2281
0
        ps_encoding_index = (*ppdfont)->u.simple.preferred_encoding_index;
2282
0
    if (penum->cgp == NULL) {
2283
0
        code = pdf_alloc_text_glyphs_table(pdev, penum, pstr);
2284
0
        if (code < 0)
2285
0
            return code;
2286
0
        code = pdf_make_text_glyphs_table_unencoded(pdev, penum->cgp, font, pstr, gdata, &ps_encoding_index);
2287
0
        if (code < 0)
2288
0
            return code;
2289
0
    }
2290
0
    code = pdf_obtain_font_resource_encoded(pdev, font, ppdfont, penum->cgp);
2291
0
    if (code < 0)
2292
0
        return code;
2293
0
    code = pdf_attached_font_resource(pdev, font, ppdfont,
2294
0
                               &glyph_usage, &real_widths, &char_cache_size, &width_cache_size);
2295
0
    if (code < 0)
2296
0
        return code;
2297
0
    (*ppdfont)->u.simple.preferred_encoding_index = ps_encoding_index;
2298
0
    return pdf_mark_text_glyphs_unencoded((const gs_text_enum_t *)penum,
2299
0
                    pstr, glyph_usage, char_cache_size);
2300
0
}
2301
2302
static inline bool
2303
strings_equal(const gs_const_string *s1, const gs_const_string *s2)
2304
39.9k
{
2305
39.9k
    return s1->size == s2->size &&
2306
39.9k
            !memcmp(s1->data, s2->data, s1->size);
2307
39.9k
}
2308
2309
/*
2310
 * Create or find a parent Type 0 font resource object for a CID font resource.
2311
 */
2312
int
2313
pdf_obtain_parent_type0_font_resource(gx_device_pdf *pdev, pdf_font_resource_t *pdsubf,
2314
                uint font_index, const gs_const_string *CMapName, pdf_font_resource_t **pdfont)
2315
40.1k
{
2316
40.1k
    gs_const_string s1;
2317
2318
40.1k
    if (pdsubf->u.cidfont.parent != 0) {
2319
39.9k
        s1.data = pdsubf->u.cidfont.parent->u.type0.CMapName_data;
2320
39.9k
        s1.size = pdsubf->u.cidfont.parent->u.type0.CMapName_size;
2321
39.9k
    }
2322
2323
40.1k
    if (pdsubf->u.cidfont.parent != 0 &&
2324
40.1k
            font_index == pdsubf->u.cidfont.parent->u.type0.font_index &&
2325
40.1k
            strings_equal(CMapName, &s1))
2326
39.9k
        *pdfont = pdsubf->u.cidfont.parent;
2327
206
    else {
2328
        /*
2329
         * PDF spec 1.4 section 5.6 "Composite Fonts" says :
2330
         *
2331
         * PDF 1.2 introduces a general architecture for composite fonts that theoretically
2332
         * allows a Type 0 font to have multiple descendants,which might themselves be
2333
         * Type 0 fonts.However,in versions up to and including PDF 1.4,only a single
2334
         * descendant is allowed,which must be a CIDFont (not a font).This restriction
2335
         * may be relaxed in a future PDF version.
2336
         */
2337
2338
206
        if (pdsubf->u.cidfont.parent == NULL ||
2339
206
                pdf_find_type0_font_resource(pdev, pdsubf, CMapName, font_index, pdfont) <= 0) {
2340
206
            int code = pdf_font_type0_alloc(pdev, pdfont, gs_no_id, pdsubf, CMapName);
2341
2342
206
            if (code < 0)
2343
0
                return code;
2344
206
            (*pdfont)->u.type0.font_index = font_index;
2345
206
        }
2346
206
        pdsubf->u.cidfont.parent = *pdfont;
2347
206
    }
2348
40.1k
    return 0;
2349
40.1k
}
2350
2351
gs_char
2352
pdf_find_glyph(pdf_font_resource_t *pdfont, gs_glyph glyph)
2353
0
{
2354
0
    if (pdfont->FontType != ft_user_defined &&
2355
0
        pdfont->FontType != ft_PDF_user_defined &&
2356
0
        pdfont->FontType != ft_PCL_user_defined &&
2357
0
        pdfont->FontType != ft_MicroType &&
2358
0
        pdfont->FontType != ft_GL2_stick_user_defined &&
2359
0
        pdfont->FontType != ft_GL2_531)
2360
0
        return GS_NO_CHAR;
2361
0
    else {
2362
0
        pdf_encoding_element_t *pet = pdfont->u.simple.Encoding;
2363
0
        int i, i0 = -1;
2364
2365
0
        if (pdfont->u.simple.FirstChar > pdfont->u.simple.LastChar)
2366
0
            return (gs_char)0;
2367
0
        for (i = pdfont->u.simple.FirstChar; i <= pdfont->u.simple.LastChar; i++, pet++) {
2368
0
            if (pet->glyph == glyph)
2369
0
                return (gs_char)i;
2370
0
            if (i0 == -1 && pet->glyph == GS_NO_GLYPH)
2371
0
                i0 = i;
2372
0
        }
2373
0
        if (i0 != -1)
2374
0
            return (gs_char)i0;
2375
0
        if (i < 256)
2376
0
            return (gs_char)i;
2377
0
        return GS_NO_CHAR;
2378
0
    }
2379
0
}
2380
2381
/*
2382
 * Compute the cached values in the text processing state from the text
2383
 * parameters, current_font, and pgs->ctm.  Return either an error code (<
2384
 * 0) or a mask of operation attributes that the caller must emulate.
2385
 * Currently the only such attributes are TEXT_ADD_TO_ALL_WIDTHS and
2386
 * TEXT_ADD_TO_SPACE_WIDTH.  Note that this procedure fills in all the
2387
 * values in ppts->values, not just the ones that need to be set now.
2388
 */
2389
static int
2390
transform_delta_inverse(const gs_point *pdelta, const gs_matrix *pmat,
2391
                        gs_point *ppt)
2392
444k
{
2393
444k
    int code = gs_distance_transform_inverse(pdelta->x, pdelta->y, pmat, ppt);
2394
444k
    gs_point delta;
2395
2396
444k
    if (code < 0)
2397
0
        return code;
2398
444k
    if (ppt->y == 0)
2399
444k
        return 0;
2400
    /* Check for numerical fuzz. */
2401
0
    code = gs_distance_transform(ppt->x, 0.0, pmat, &delta);
2402
0
    if (code < 0)
2403
0
        return 0;                /* punt */
2404
0
    if (fabs(delta.x - pdelta->x) < 0.01 && fabs(delta.y - pdelta->y) < 0.01) {
2405
        /* Close enough to y == 0: device space error < 0.01 pixel. */
2406
0
        ppt->y = 0;
2407
0
    }
2408
0
    return 0;
2409
0
}
2410
2411
float pdf_calculate_text_size(gs_gstate *pgs, pdf_font_resource_t *pdfont,
2412
                              const gs_matrix *pfmat, gs_matrix *smat, gs_matrix *tmat,
2413
                              gs_font *font, gx_device_pdf *pdev)
2414
1.34M
{
2415
1.34M
    gs_matrix orig_matrix;
2416
1.34M
    double
2417
1.34M
        sx = pdev->HWResolution[0] / 72.0,
2418
1.34M
        sy = pdev->HWResolution[1] / 72.0;
2419
1.34M
    float size;
2420
2421
    /* Get the original matrix of the base font. */
2422
2423
1.34M
    {
2424
1.34M
        gs_font_base *cfont = pdf_font_resource_font(pdfont, false);
2425
2426
1.34M
        if (pdfont->FontType == ft_user_defined ||
2427
1.34M
            pdfont->FontType == ft_PDF_user_defined ||
2428
1.34M
            pdfont->FontType == ft_PCL_user_defined ||
2429
1.34M
            pdfont->FontType == ft_MicroType ||
2430
1.34M
            pdfont->FontType == ft_GL2_stick_user_defined ||
2431
1.34M
            pdfont->FontType == ft_GL2_531)
2432
5.78k
            orig_matrix = pdfont->u.simple.s.type3.FontMatrix;
2433
1.33M
        else if (cfont != 0) {
2434
            /*
2435
             * The text matrix to be computed relatively to the
2436
             * embedded font matrix.
2437
             */
2438
1.32M
            orig_matrix = cfont->FontMatrix;
2439
1.32M
        } else {
2440
            /*
2441
             * We don't embed the font.
2442
             * The text matrix to be computed relatively to
2443
             * standard font matrix.
2444
             */
2445
14.2k
            pdf_font_orig_matrix(font, &orig_matrix);
2446
14.2k
        }
2447
1.34M
    }
2448
2449
    /* Compute the scaling matrix and combined matrix. */
2450
2451
1.34M
    if (gs_matrix_invert(&orig_matrix, smat) < 0) {
2452
0
        gs_make_identity(smat);
2453
0
        gs_make_identity(tmat);
2454
0
        return 1; /* Arbitrary */
2455
0
    }
2456
1.34M
    gs_matrix_multiply(smat, pfmat, smat);
2457
1.34M
    *tmat = ctm_only(pgs);
2458
1.34M
    tmat->tx = tmat->ty = 0;
2459
1.34M
    gs_matrix_multiply(smat, tmat, tmat);
2460
2461
    /* Try to find a reasonable size value.  This isn't necessary, */
2462
    /* but it's worth a little effort. */
2463
2464
1.34M
    size = hypot(tmat->yx, tmat->yy) / sy;
2465
1.34M
    if (size < 0.01)
2466
71
        size = hypot(tmat->xx, tmat->xy) / sx;
2467
1.34M
    if (size < 0.01)
2468
12
        size = 1;
2469
2470
1.34M
    return(size);
2471
1.34M
}
2472
2473
int
2474
pdf_update_text_state(pdf_text_process_state_t *ppts,
2475
                      const pdf_text_enum_t *penum,
2476
                      pdf_font_resource_t *pdfont, const gs_matrix *pfmat)
2477
1.34M
{
2478
1.34M
    gx_device_pdf *const pdev = (gx_device_pdf *)penum->dev;
2479
1.34M
    gs_font *font = penum->current_font;
2480
1.34M
    gs_fixed_point cpt;
2481
1.34M
    gs_matrix smat, tmat;
2482
1.34M
    float size;
2483
1.34M
    float c_s = 0, w_s = 0;
2484
1.34M
    int mask = 0;
2485
1.34M
    int code = gx_path_current_point(gs_text_enum_path(penum), &cpt);
2486
2487
1.34M
    if (code < 0)
2488
0
        return code;
2489
2490
1.34M
    size = pdf_calculate_text_size(penum->pgs, pdfont, pfmat, &smat, &tmat, penum->current_font, pdev);
2491
    /* Check for spacing parameters we can handle, and transform them. */
2492
2493
1.34M
    if (penum->text.operation & TEXT_ADD_TO_ALL_WIDTHS) {
2494
139k
        if (penum->current_font->WMode == 0) {
2495
139k
            gs_point pt;
2496
2497
139k
            code = transform_delta_inverse(&penum->text.delta_all, &smat, &pt);
2498
139k
            if (code >= 0 && pt.y == 0)
2499
139k
                c_s = pt.x * size;
2500
0
            else
2501
0
                mask |= TEXT_ADD_TO_ALL_WIDTHS;
2502
139k
        }
2503
0
        else
2504
0
            mask |= TEXT_ADD_TO_ALL_WIDTHS;
2505
139k
    }
2506
2507
1.34M
    if (penum->text.operation & TEXT_ADD_TO_SPACE_WIDTH) {
2508
304k
        gs_point pt;
2509
2510
304k
        code = transform_delta_inverse(&penum->text.delta_space, &smat, &pt);
2511
304k
        if (code >= 0 && pt.y == 0 && penum->text.space.s_char == 32)
2512
304k
            w_s = pt.x * size;
2513
0
        else
2514
0
            mask |= TEXT_ADD_TO_SPACE_WIDTH;
2515
304k
    }
2516
    /* Store the updated values. */
2517
2518
1.34M
    tmat.xx /= size;
2519
1.34M
    tmat.xy /= size;
2520
1.34M
    tmat.yx /= size;
2521
1.34M
    tmat.yy /= size;
2522
1.34M
    tmat.tx += fixed2float(cpt.x);
2523
1.34M
    tmat.ty += fixed2float(cpt.y);
2524
2525
1.34M
    ppts->values.character_spacing = c_s;
2526
1.34M
    ppts->values.pdfont = pdfont;
2527
1.34M
    ppts->values.size = size;
2528
1.34M
    ppts->values.matrix = tmat;
2529
1.34M
    ppts->values.render_mode = penum->pgs->text_rendering_mode;
2530
1.34M
    ppts->values.word_spacing = w_s;
2531
1.34M
    ppts->font = font;
2532
2533
1.34M
    if (font->PaintType == 2 && penum->pgs->text_rendering_mode == 0)
2534
0
    {
2535
0
        gs_gstate *pgs = penum->pgs;
2536
0
        gs_font *font = penum->current_font;
2537
0
        double scaled_width = font->StrokeWidth != 0 ? font->StrokeWidth : 0.001;
2538
0
        double saved_width = pgs->line_params.half_width;
2539
        /*
2540
         * See stream_to_text in gdevpdfu.c re the computation of
2541
         * the scaling value.
2542
         */
2543
0
        double scale = 72.0 / pdev->HWResolution[1];
2544
2545
0
        if (font->FontMatrix.yy != 0)
2546
0
            scaled_width *= fabs(font->orig_FontMatrix.yy) * size * scale;
2547
0
        else
2548
0
            scaled_width *= fabs(font->orig_FontMatrix.xy) * size * scale;
2549
2550
0
        if (tmat.yy != 0)
2551
0
            scaled_width *= tmat.yy;
2552
0
        else
2553
0
            scaled_width *= tmat.xy;
2554
2555
0
        ppts->values.render_mode = 1;
2556
2557
        /* Sort out any pending glyphs */
2558
0
        code = pdf_set_PaintType0_params(pdev, pgs, size, scaled_width, &ppts->values);
2559
0
        if (code < 0)
2560
0
            return code;
2561
2562
0
        pgs->line_params.half_width = scaled_width / 2;
2563
0
        code = pdf_set_text_process_state(pdev, (const gs_text_enum_t *)penum,
2564
0
                                      ppts);
2565
0
        if (code < 0)
2566
0
            return code;
2567
2568
0
        pgs->line_params.half_width = saved_width;
2569
1.34M
    } else {
2570
1.34M
        code = pdf_set_text_process_state(pdev, (const gs_text_enum_t *)penum,
2571
1.34M
                                      ppts);
2572
1.34M
    }
2573
1.34M
    return (code < 0 ? code : mask);
2574
1.34M
}
2575
2576
/*
2577
 * Set up commands to make the output state match the processing state.
2578
 * General graphics state commands are written now; text state commands
2579
 * are written later.
2580
 */
2581
int
2582
pdf_set_text_process_state(gx_device_pdf *pdev,
2583
                           const gs_text_enum_t *pte,        /* for pdcolor, pgs */
2584
                           pdf_text_process_state_t *ppts)
2585
1.34M
{
2586
    /*
2587
     * Setting the stroke parameters may exit text mode, causing the
2588
     * settings of the text parameters to be lost.  Therefore, we set the
2589
     * stroke parameters first.
2590
     */
2591
1.34M
    if (pdf_render_mode_uses_stroke(pdev, &ppts->values)) {
2592
        /* Write all the parameters for stroking. */
2593
102
        gs_gstate *pgs = pte->pgs;
2594
102
        float save_width = pgs->line_params.half_width;
2595
102
        int code;
2596
2597
102
        if (pdev->context == PDF_IN_STRING) {
2598
40
            code = sync_text_state(pdev);
2599
40
            if (code < 0)
2600
0
                return code;
2601
40
        }
2602
2603
102
        code = pdf_open_contents(pdev, PDF_IN_STREAM);
2604
102
        if (code < 0)
2605
0
            return code;
2606
2607
102
        code = pdf_prepare_stroke(pdev, pgs, true);
2608
102
        if (code >= 0) {
2609
102
            code = gdev_vector_prepare_stroke((gx_device_vector *)pdev,
2610
102
                                              pgs, NULL, NULL, 1);
2611
102
            if (code < 0)
2612
0
                return code;
2613
102
        }
2614
2615
102
        code = pdf_open_contents(pdev, PDF_IN_STRING);
2616
102
        if (code < 0)
2617
0
            return code;
2618
2619
102
        pgs->line_params.half_width = save_width;
2620
102
    }
2621
2622
    /* Now set all the other parameters. */
2623
2624
1.34M
    return pdf_set_text_state_values(pdev, &ppts->values);
2625
1.34M
}
2626
2627
static int
2628
store_glyph_width(pdf_glyph_width_t *pwidth, int wmode, const gs_matrix *scale,
2629
                  const gs_glyph_info_t *pinfo)
2630
923k
{
2631
923k
    double w, v;
2632
2633
923k
    gs_distance_transform(pinfo->width[wmode].x, pinfo->width[wmode].y, scale, &pwidth->xy);
2634
923k
    if (wmode)
2635
676
        w = pwidth->xy.y, v = pwidth->xy.x;
2636
923k
    else
2637
923k
        w = pwidth->xy.x, v = pwidth->xy.y;
2638
923k
    pwidth->w = w;
2639
923k
    if (v != 0)
2640
0
        return 1;
2641
923k
    gs_distance_transform(pinfo->v.x, pinfo->v.y, scale, &pwidth->v);
2642
923k
    return 0;
2643
923k
}
2644
2645
static int
2646
get_missing_width(gs_font_base *cfont, int wmode, const gs_matrix *scale_c,
2647
                    pdf_glyph_widths_t *pwidths)
2648
966
{
2649
966
    gs_font_info_t finfo;
2650
966
    int code;
2651
2652
966
    code = cfont->procs.font_info((gs_font *)cfont, NULL,
2653
966
                                  FONT_INFO_MISSING_WIDTH, &finfo);
2654
966
    if (code < 0)
2655
0
        return code;
2656
966
    if (wmode) {
2657
76
        gs_distance_transform(0.0, -finfo.MissingWidth, scale_c, &pwidths->real_width.xy);
2658
76
        pwidths->Width.xy.x = 0;
2659
76
        pwidths->Width.xy.y = pwidths->real_width.xy.y;
2660
76
        pwidths->Width.w = pwidths->real_width.w =
2661
76
                pwidths->Width.xy.y;
2662
76
        pwidths->Width.v.x = - pwidths->Width.xy.y / 2;
2663
76
        pwidths->Width.v.y = - pwidths->Width.xy.y;
2664
890
    } else {
2665
890
        gs_distance_transform(finfo.MissingWidth, 0.0, scale_c, &pwidths->real_width.xy);
2666
890
        pwidths->Width.xy.x = pwidths->real_width.xy.x;
2667
890
        pwidths->Width.xy.y = 0;
2668
890
        pwidths->Width.w = pwidths->real_width.w =
2669
890
                pwidths->Width.xy.x;
2670
890
        pwidths->Width.v.x = pwidths->Width.v.y = 0;
2671
890
    }
2672
    /*
2673
     * Don't mark the width as known, just in case this is an
2674
     * incrementally defined font.
2675
     */
2676
966
    return 1;
2677
966
}
2678
2679
/*
2680
 * Get the widths (unmodified from the copied font,
2681
 * and possibly modified from the original font) of a given glyph.
2682
 * Return 1 if the width was defaulted to MissingWidth.
2683
 * Return TEXT_PROCESS_CDEVPROC if a CDevProc callout is needed.
2684
 * cdevproc_result != NULL if we restart after a CDevProc callout.
2685
 */
2686
int
2687
pdf_glyph_widths(pdf_font_resource_t *pdfont, int wmode, gs_glyph glyph,
2688
                 gs_font *orig_font, pdf_glyph_widths_t *pwidths,
2689
                 const double cdevproc_result[10])
2690
463k
{
2691
463k
    gs_font_base *cfont = pdf_font_resource_font(pdfont, false);
2692
463k
    gs_font *ofont = orig_font;
2693
463k
    gs_glyph_info_t info;
2694
463k
    gs_matrix scale_c, scale_o;
2695
463k
    int code, rcode = 0;
2696
463k
    gs_point v;
2697
463k
    int allow_cdevproc_callout = (orig_font->FontType == ft_CID_TrueType
2698
463k
                || orig_font->FontType == ft_CID_encrypted
2699
463k
                ? GLYPH_INFO_CDEVPROC : 0); /* fixme : allow more font types. */
2700
2701
463k
    if (ofont->FontType == ft_composite)
2702
0
        return_error(gs_error_unregistered); /* Must not happen. */
2703
463k
    code = glyph_orig_matrix((const gs_font *)cfont, glyph, &scale_c);
2704
463k
    if (code < 0)
2705
0
        return code;
2706
463k
    code = glyph_orig_matrix(ofont, glyph, &scale_o);
2707
463k
    if (code < 0)
2708
0
        return code;
2709
463k
    gs_matrix_scale(&scale_c, 1000.0, 1000.0, &scale_c);
2710
463k
    gs_matrix_scale(&scale_o, 1000.0, 1000.0, &scale_o);
2711
463k
    pwidths->Width.v.x = pwidths->Width.v.y = 0;
2712
463k
    pwidths->real_width.v.x = pwidths->real_width.v.y = 0;
2713
463k
    pwidths->real_width.w = pwidths->real_width.xy.x = pwidths->real_width.xy.y = 0;
2714
463k
    pwidths->replaced_v = false;
2715
463k
    pwidths->ignore_wmode = false;
2716
463k
    if (glyph == GS_NO_GLYPH)
2717
31
        return get_missing_width(cfont, wmode, &scale_c, pwidths);
2718
463k
    code = cfont->procs.glyph_info((gs_font *)cfont, glyph, NULL,
2719
463k
                                    GLYPH_INFO_WIDTH0 |
2720
463k
                                    (GLYPH_INFO_WIDTH0 << wmode) |
2721
463k
                                    GLYPH_INFO_OUTLINE_WIDTHS |
2722
463k
                                    (GLYPH_INFO_VVECTOR0 << wmode),
2723
463k
                                    &info);
2724
    /* For CID fonts the PDF spec requires the x-component of v-vector
2725
       to be equal to half glyph width, and AR5 takes it from W, DW.
2726
       So make a compatibe data here.
2727
     */
2728
463k
    if ((code == gs_error_undefined || !(info.members & (GLYPH_INFO_WIDTH0 << wmode)))) {
2729
        /* If we got an undefined error, and its a type 1/CFF font, try to
2730
         * find the /.notdef glyph and use its width instead (as this is the
2731
         * glyph which will be rendered). We don't do this for other font types
2732
         * as it seems Acrobat/Distiller may not do so either.
2733
         */
2734
2.94k
        if (code == gs_error_undefined && (ofont->FontType == ft_encrypted || ofont->FontType == ft_encrypted2)) {
2735
2.08k
            int index;
2736
2.08k
            gs_glyph notdef_glyph;
2737
2738
2.08k
            v.x = v.y = 0;
2739
2740
2.08k
            for (index = 0;
2741
290k
                (ofont->procs.enumerate_glyph((gs_font *)ofont, &index,
2742
290k
                (GLYPH_SPACE_NAME), &notdef_glyph)) >= 0 &&
2743
290k
                index != 0;) {
2744
290k
                    if (gs_font_glyph_is_notdef((gs_font_base *)ofont, notdef_glyph)) {
2745
2.08k
                        code = ofont->procs.glyph_info((gs_font *)ofont, notdef_glyph, NULL,
2746
2.08k
                                            GLYPH_INFO_WIDTH0 << wmode,
2747
2.08k
                                            &info);
2748
2749
2.08k
                    if (code < 0)
2750
0
                        return code;
2751
2.08k
                    code = store_glyph_width(&pwidths->Width, wmode, &scale_c, &info);
2752
2.08k
                    if (code < 0)
2753
0
                        return code;
2754
2.08k
                    rcode |= code;
2755
2.08k
                    if (info.members  & (GLYPH_INFO_VVECTOR0 << wmode))
2756
0
                        gs_distance_transform(info.v.x, info.v.y, &scale_c, &v);
2757
2.08k
                    else
2758
2.08k
                        v.x = v.y = 0;
2759
2.08k
                    break;
2760
2.08k
                }
2761
290k
            }
2762
2.08k
        } else {
2763
859
        code = get_missing_width(cfont, wmode, &scale_c, pwidths);
2764
859
            if (code < 0)
2765
0
                v.y = 0;
2766
859
            else
2767
859
                v.y = pwidths->Width.v.y;
2768
859
            if (wmode) {
2769
76
                pdf_glyph_widths_t widths1;
2770
2771
76
                if (get_missing_width(cfont, 0, &scale_c, &widths1) < 0)
2772
0
                    v.x = 0;
2773
76
                else
2774
76
                    v.x = widths1.Width.w / 2;
2775
76
            } else
2776
783
                v.x = pwidths->Width.v.x;
2777
859
        }
2778
460k
    } else if (code < 0)
2779
0
        return code;
2780
460k
    else {
2781
460k
        code = store_glyph_width(&pwidths->Width, wmode, &scale_c, &info);
2782
460k
        if (code < 0)
2783
0
            return code;
2784
460k
        rcode |= code;
2785
460k
        if (info.members  & (GLYPH_INFO_VVECTOR0 << wmode))
2786
460k
            gs_distance_transform(info.v.x, info.v.y, &scale_c, &v);
2787
306
        else
2788
306
            v.x = v.y = 0;
2789
460k
        if (wmode && pdf_is_CID_font(ofont)) {
2790
306
            if (info.members & (GLYPH_INFO_WIDTH0 << wmode)) {
2791
306
                gs_point xy;
2792
2793
306
                gs_distance_transform(info.width[0].x, info.width[0].y, &scale_c, &xy);
2794
306
                v.x = xy.x / 2;
2795
306
            } else {
2796
0
                pdf_glyph_widths_t widths1;
2797
2798
0
                if (get_missing_width(cfont, 0, &scale_c, &widths1) < 0)
2799
0
                    v.x = 0;
2800
0
                else
2801
0
                    v.x = widths1.Width.w / 2;
2802
0
            }
2803
306
        }
2804
460k
    }
2805
463k
    pwidths->Width.v = v;
2806
463k
    if (code > 0 && !pdf_is_CID_font(ofont))
2807
483
        pwidths->Width.xy.x = pwidths->Width.xy.y = pwidths->Width.w = 0;
2808
463k
    if (cdevproc_result == NULL) {
2809
463k
        info.members = 0;
2810
463k
        code = ofont->procs.glyph_info(ofont, glyph, NULL,
2811
463k
                                            (GLYPH_INFO_WIDTH0 << wmode) |
2812
463k
                                            (GLYPH_INFO_VVECTOR0 << wmode) |
2813
463k
                                            allow_cdevproc_callout,
2814
463k
                                            &info);
2815
        /* fixme : Move this call before cfont->procs.glyph_info. */
2816
463k
        if (info.members & GLYPH_INFO_CDEVPROC) {
2817
0
            if (allow_cdevproc_callout)
2818
0
                return TEXT_PROCESS_CDEVPROC;
2819
0
        else
2820
0
            return_error(gs_error_rangecheck);
2821
0
        }
2822
463k
    } else {
2823
0
        info.width[0].x = cdevproc_result[0];
2824
0
        info.width[0].y = cdevproc_result[1];
2825
0
        info.width[1].x = cdevproc_result[6];
2826
0
        info.width[1].y = cdevproc_result[7];
2827
0
        info.v.x = (wmode ? cdevproc_result[8] : 0);
2828
0
        info.v.y = (wmode ? cdevproc_result[9] : 0);
2829
0
        info.members = (GLYPH_INFO_WIDTH0 << wmode) |
2830
0
                       (wmode ? GLYPH_INFO_VVECTOR1 : 0);
2831
0
        code = 0;
2832
0
    }
2833
463k
    if (code == gs_error_undefined || !(info.members & (GLYPH_INFO_WIDTH0 << wmode)))
2834
2.94k
        pwidths->real_width = pwidths->Width;
2835
460k
    else if (code < 0)
2836
0
        return code;
2837
460k
    else {
2838
460k
        if ((info.members & (GLYPH_INFO_VVECTOR0 | GLYPH_INFO_VVECTOR1)) != 0) {
2839
443k
            pwidths->replaced_v = true;
2840
443k
            if ((info.members & GLYPH_INFO_VVECTOR1) == 0 && wmode == 1)
2841
0
                pwidths->ignore_wmode = true;
2842
443k
        }
2843
17.8k
        else
2844
17.8k
            info.v.x = info.v.y = 0;
2845
460k
        code = store_glyph_width(&pwidths->real_width, wmode, &scale_o, &info);
2846
460k
        if (code < 0)
2847
0
            return code;
2848
460k
        rcode |= code;
2849
460k
        gs_distance_transform(info.v.x, info.v.y, &scale_o, &pwidths->real_width.v);
2850
460k
    }
2851
463k
    return rcode;
2852
463k
}
2853
2854
static int
2855
pdf_choose_output_char_code(gx_device_pdf *pdev, pdf_text_enum_t *penum, gs_char *pch)
2856
5.80k
{
2857
5.80k
    gs_char ch;
2858
5.80k
    gs_font *font = penum->current_font;
2859
2860
5.80k
    if (penum->text.operation & TEXT_FROM_SINGLE_GLYPH) {
2861
0
        byte buf[1];
2862
0
        int char_code_length;
2863
0
        gs_glyph glyph = penum->text.data.d_glyph;
2864
0
        int code = pdf_encode_glyph((gs_font_base *)font, glyph,
2865
0
                    buf, sizeof(buf), &char_code_length);
2866
2867
0
        if (code < 0) {
2868
            /* Must not happen, becuse pdf_encode_glyph was passed in process_plain_text.*/
2869
0
            ch = GS_NO_CHAR;
2870
0
        } else if (char_code_length != 1) {
2871
            /* Must not happen with type 3 fonts.*/
2872
0
            ch = GS_NO_CHAR;
2873
0
        } else
2874
0
            ch = buf[0];
2875
5.80k
    } else if (penum->orig_font->FontType == ft_composite) {
2876
0
        gs_font_type0 *font0 = (gs_font_type0 *)penum->orig_font;
2877
0
        gs_glyph glyph = penum->returned.current_glyph;
2878
2879
0
        if (font0->data.FMapType == fmap_CMap) {
2880
0
            pdf_font_resource_t *pdfont;
2881
0
            int code = pdf_attached_font_resource(pdev, font, &pdfont, NULL, NULL, NULL, NULL);
2882
2883
0
            if (code < 0)
2884
0
                return code;
2885
0
            ch = pdf_find_glyph(pdfont, glyph);
2886
0
        } else
2887
0
            ch = penum->returned.current_char;
2888
5.80k
    } else {
2889
5.80k
        ch = penum->returned.current_char;
2890
        /* Keep for records : glyph = font->procs.encode_char(font, ch, GLYPH_SPACE_NAME); */
2891
        /*
2892
         * If glyph == GS_NO_GLYPH, we should replace it with
2893
         * a notdef glyph, but we don't know how to do with Type 3 fonts.
2894
         */
2895
5.80k
    }
2896
5.80k
    *pch = ch;
2897
5.80k
    return 0;
2898
5.80k
}
2899
2900
static int
2901
pdf_choose_output_glyph_name(gx_device_pdf *pdev, pdf_text_enum_t *penum, gs_const_string *gnstr, gs_glyph glyph, bool *cleanup)
2902
4.46k
{
2903
4.46k
    if (penum->orig_font->FontType == ft_composite || penum->orig_font->procs.glyph_name(penum->orig_font, glyph, gnstr) < 0
2904
4.46k
        || (penum->orig_font->FontType > 42 && gnstr->size == 7 && strcmp((const char *)gnstr->data, ".notdef")== 0)) {
2905
        /* If we're capturing a PCL bitmap, and the glyph comes back with a name of '/.notdef' then
2906
         * generate a name instead. There's nothing wrong technically with using /.notdef, but Acrobat does
2907
         * 'special stuff' with that name, and messes up the display. See bug #699102.
2908
         */
2909
        /* couldn't find a glyph name, so make one up! This can happen if we are handling PCL and the glyph
2910
         * (character code) is less than 29, the PCL glyph names start with /.notdef at 29. We also need to
2911
         * do this for composite fonts.
2912
         */
2913
0
        char buf[6];
2914
0
        byte *p;
2915
2916
0
        gnstr->size = 5;
2917
0
        p = (byte *)gs_alloc_string(pdev->pdf_memory, gnstr->size, "pdf_text_set_cache");
2918
0
        if (p == NULL)
2919
0
            return_error(gs_error_VMerror);
2920
0
        gs_snprintf(buf, sizeof(buf), "g%04x", (unsigned int)(glyph & 0xFFFF));
2921
0
        memcpy(p, buf, 5);
2922
0
        gnstr->data = p;
2923
0
        *cleanup = true;
2924
0
    }
2925
4.46k
    return 0;
2926
4.46k
}
2927
2928
/* ---------------- Main entry ---------------- */
2929
2930
/*
2931
 * Fall back to the default text processing code when needed.
2932
 */
2933
int
2934
pdf_default_text_begin(gs_text_enum_t *pte, const gs_text_params_t *text,
2935
                       gs_text_enum_t **ppte)
2936
217k
{
2937
217k
    gs_text_params_t text1 = *text;
2938
2939
217k
    if(pte->current_font->FontType == 3 && (text1.operation & TEXT_DO_NONE)) {
2940
        /* We need a real drawing to accumulate charproc. */
2941
3
        text1.operation &= ~TEXT_DO_NONE;
2942
3
        text1.operation |= TEXT_DO_DRAW;
2943
3
    }
2944
217k
    return gx_default_text_begin(pte->dev, pte->pgs, &text1, pte->current_font,
2945
217k
                                 pte->pcpath, ppte);
2946
217k
}
2947
2948
static int install_PS_charproc_accumulator(gx_device_pdf *pdev, gs_text_enum_t *pte,
2949
                             gs_text_enum_t *pte_default, pdf_text_enum_t *const penum)
2950
3.12k
{
2951
3.12k
    int code;
2952
3.12k
    const gx_device_color * pdcolor = gs_currentdevicecolor_inline(pte->pgs);
2953
2954
3.12k
    penum->returned.current_char = pte_default->returned.current_char;
2955
3.12k
    penum->returned.current_glyph = pte_default->returned.current_glyph;
2956
3.12k
    pdev->charproc_ctm = penum->pgs->ctm;
2957
3.12k
    if ((penum->current_font->FontType == ft_user_defined || penum->current_font->FontType == ft_PDF_user_defined)&&
2958
3.12k
        penum->outer_CID == GS_NO_GLYPH &&
2959
3.12k
            !(penum->pte_default->text.operation & TEXT_DO_CHARWIDTH)) {
2960
        /* The condition above must be consistent with one in pdf_text_set_cache,
2961
           which decides to apply pdf_set_charproc_attrs. */
2962
3.12k
        gs_matrix m;
2963
3.12k
        pdf_font_resource_t *pdfont;
2964
2965
3.12k
        code = pdf_start_charproc_accum(pdev);
2966
3.12k
        if (code < 0)
2967
0
            return code;
2968
2969
        /* We need to give FreeType some room for accuracy when
2970
         * retrieving the outline. We will use a scale factor of 100
2971
         * (see below). Because this appears to the regular path
2972
         * handling code as if it were at the page level, the co-ords
2973
         * would be clipped frequently, so we temporarily hack the
2974
         * width and height of the device here to ensure it doesn't.
2975
         * Note that this requires some careful manipulation of the
2976
         * CTM in various places, which want numbers in the font
2977
         * co-ordinate space, not the scaled user space.
2978
         */
2979
3.12k
        pdev->width *= 100;
2980
3.12k
        pdev->height *= 100;
2981
2982
3.12k
        pdf_viewer_state_from_gs_gstate(pdev, pte->pgs, pdcolor);
2983
        /* Set line params to unallowed values so that
2984
           they'll synchronize with writing them out on the first use.
2985
           Doing so because PDF viewer inherits them from the
2986
           contents stream when executing the charproc,
2987
           but at this moment we don't know in what contexts
2988
           it will be used. */
2989
3.12k
        pdev->state.line_params.half_width = -1;
2990
3.12k
        pdev->state.line_params.start_cap = gs_cap_unknown;
2991
3.12k
        pdev->state.line_params.end_cap = gs_cap_unknown;
2992
3.12k
        pdev->state.line_params.dash_cap = gs_cap_unknown;
2993
3.12k
        pdev->state.line_params.join = gs_join_unknown;
2994
3.12k
        pdev->state.line_params.miter_limit = -1;
2995
3.12k
        pdev->state.line_params.dash.pattern_size = -1;
2996
        /* Must set an identity CTM for the charproc accumulation.
2997
           The function show_proceed (called from gs_text_process above)
2998
           executed gsave, so we are safe to change CTM now.
2999
           Note that BuildChar may change CTM before calling setcachedevice. */
3000
3.12k
        gs_make_identity(&m);
3001
        /* See comment above, we actually want to use a scale factor
3002
         * of 100 in order to give FreeType some room in the fixed
3003
         * precision calculations when retrieing the outline. So in
3004
         * fact we don't use the identity CTM, but a 100x100 matrix
3005
         * Originally tried 1000, but that was too likely to cause
3006
         * clipping or arithmetic overflow.
3007
         */
3008
3.12k
        gs_matrix_scale(&m, 100, 100, &m);
3009
3.12k
        gs_matrix_fixed_from_matrix(&penum->pgs->ctm, &m);
3010
3011
        /* Choose a character code to use with the charproc. */
3012
3.12k
        code = pdf_choose_output_char_code(pdev, penum, &penum->output_char_code);
3013
3.12k
        if (code < 0)
3014
0
            return code;
3015
3.12k
        code = pdf_attached_font_resource(pdev, penum->current_font, &pdfont, NULL, NULL, NULL, NULL);
3016
3.12k
        if (code < 0)
3017
0
            return code;
3018
3.12k
        pdev->font3 = (pdf_resource_t *)pdfont;
3019
3.12k
        pdev->substream_Resources = pdfont->u.simple.s.type3.Resources;
3020
3.12k
        penum->charproc_accum = true;
3021
3.12k
        pdev->accumulating_charproc = true;
3022
3.12k
        pdev->charproc_BBox.p.x = 10000;
3023
3.12k
        pdev->charproc_BBox.p.y = 10000;
3024
3.12k
        pdev->charproc_BBox.q.x = 0;
3025
3.12k
        pdev->charproc_BBox.q.y = 0;
3026
3.12k
        return TEXT_PROCESS_RENDER;
3027
3.12k
    }
3028
0
    return 0;
3029
3.12k
}
3030
3031
static int install_charproc_accumulator(gx_device_pdf *pdev, gs_text_enum_t *pte,
3032
                             gs_text_enum_t *pte_default, pdf_text_enum_t *const penum)
3033
1.34k
{
3034
1.34k
    int code;
3035
1.34k
    const gx_device_color * pdcolor = gs_currentdevicecolor_inline(pte->pgs);
3036
3037
1.34k
    pdev->charproc_ctm = penum->pgs->ctm;
3038
1.34k
    if ((penum->current_font->FontType == ft_user_defined ||
3039
1.34k
        penum->current_font->FontType == ft_PDF_user_defined ||
3040
1.34k
        penum->current_font->FontType == ft_PCL_user_defined ||
3041
1.34k
        penum->current_font->FontType == ft_MicroType ||
3042
1.34k
        penum->current_font->FontType == ft_GL2_stick_user_defined ||
3043
1.34k
        penum->current_font->FontType == ft_GL2_531) &&
3044
1.34k
            penum->outer_CID == GS_NO_GLYPH &&
3045
1.34k
            !(penum->pte_default->text.operation & TEXT_DO_CHARWIDTH)) {
3046
        /* The condition above must be consistent with one in pdf_text_set_cache,
3047
           which decides to apply pdf_set_charproc_attrs. */
3048
1.34k
        gs_matrix m;
3049
1.34k
        pdf_font_resource_t *pdfont;
3050
3051
1.34k
        pdev->PS_accumulator = false;
3052
1.34k
        code = pdf_start_charproc_accum(pdev);
3053
1.34k
        if (code < 0)
3054
0
            return code;
3055
3056
1.34k
        pdf_viewer_state_from_gs_gstate(pdev, pte->pgs, pdcolor);
3057
        /* Set line params to unallowed values so that
3058
           they'll synchronize with writing them out on the first use.
3059
           Doing so because PDF viewer inherits them from the
3060
           contents stream when executing the charproc,
3061
           but at this moment we don't know in what contexts
3062
           it will be used. */
3063
1.34k
        pdev->state.line_params.half_width = -1;
3064
1.34k
        pdev->state.line_params.start_cap = gs_cap_unknown;
3065
1.34k
        pdev->state.line_params.end_cap = gs_cap_unknown;
3066
1.34k
        pdev->state.line_params.dash_cap = gs_cap_unknown;
3067
1.34k
        pdev->state.line_params.join = gs_join_unknown;
3068
1.34k
        pdev->state.line_params.miter_limit = -1;
3069
1.34k
        pdev->state.line_params.dash.pattern_size = -1;
3070
        /* Must set an identity CTM for the charproc accumulation.
3071
           The function show_proceed (called from gs_text_process above)
3072
           executed gsave, so we are safe to change CTM now.
3073
           Note that BuildChar may change CTM before calling setcachedevice. */
3074
1.34k
        gs_make_identity(&m);
3075
1.34k
        if (penum->current_font->FontType == ft_PDF_user_defined) {
3076
1.34k
            pdev->width *= 100;
3077
1.34k
            pdev->height *= 100;
3078
1.34k
            gs_matrix_scale(&m, 100, 100, &m);
3079
1.34k
            pdev->Scaled_accumulator = 1;
3080
1.34k
        }
3081
1.34k
        gs_matrix_fixed_from_matrix(&penum->pgs->ctm, &m);
3082
3083
        /* Choose a character code to use with the charproc. */
3084
1.34k
        code = pdf_choose_output_char_code(pdev, penum, &penum->output_char_code);
3085
1.34k
        if (code < 0) {
3086
0
            (void)pdf_exit_substream(pdev);
3087
0
            return code;
3088
0
        }
3089
1.34k
        code = pdf_attached_font_resource(pdev, penum->current_font, &pdfont, NULL, NULL, NULL, NULL);
3090
1.34k
        if (code < 0) {
3091
0
            (void)pdf_exit_substream(pdev);
3092
0
            return code;
3093
0
        }
3094
1.34k
        pdev->font3 = (pdf_resource_t *)pdfont;
3095
1.34k
        if (pdfont == 0L) {
3096
0
            (void)pdf_exit_substream(pdev);
3097
0
            return gs_note_error(gs_error_invalidfont);
3098
0
        }
3099
3100
1.34k
        pdev->substream_Resources = pdfont->u.simple.s.type3.Resources;
3101
1.34k
        penum->charproc_accum = true;
3102
1.34k
        pdev->accumulating_charproc = true;
3103
1.34k
        return TEXT_PROCESS_RENDER;
3104
1.34k
    }
3105
0
    return 0;
3106
1.34k
}
3107
3108
static int complete_charproc(gx_device_pdf *pdev, gs_text_enum_t *pte,
3109
                             gs_text_enum_t *pte_default, pdf_text_enum_t *const penum,
3110
                             bool was_PS_type3)
3111
4.46k
{
3112
4.46k
    gs_const_string gnstr;
3113
4.46k
    int code;
3114
4.46k
    bool cleanup = false;
3115
3116
4.46k
    if (pte_default->returned.current_glyph == GS_NO_GLYPH)
3117
0
      return_error(gs_error_undefined);
3118
4.46k
    code = pdf_choose_output_glyph_name(pdev, penum, &gnstr, pte_default->returned.current_glyph, &cleanup);
3119
4.46k
    if (code < 0) {
3120
0
        return code;
3121
0
    }
3122
3123
4.46k
    if ((penum->current_font->FontType == ft_user_defined ||
3124
4.46k
       penum->current_font->FontType == ft_PDF_user_defined ||
3125
4.46k
       penum->current_font->FontType == ft_PCL_user_defined ||
3126
4.46k
       penum->current_font->FontType == ft_MicroType ||
3127
4.46k
       penum->current_font->FontType == ft_GL2_stick_user_defined ||
3128
4.46k
       penum->current_font->FontType == ft_GL2_531) &&
3129
4.46k
       stell(pdev->strm) == 0)
3130
577
    {
3131
577
        char glyph[256], FontName[gs_font_name_max + 1], KeyName[256];
3132
577
        int len;
3133
3134
577
        len = min(gs_font_name_max, gnstr.size);
3135
577
        memcpy(glyph, gnstr.data, len);
3136
577
        glyph[len] = 0x00;
3137
577
        len = min(gs_font_name_max, penum->current_font->font_name.size);
3138
577
        memcpy(FontName, penum->current_font->font_name.chars, len);
3139
577
        FontName[len] = 0x00;
3140
577
        len = min(gs_font_name_max, penum->current_font->key_name.size);
3141
577
        memcpy(KeyName, penum->current_font->key_name.chars, len);
3142
577
        KeyName[len] = 0x00;
3143
3144
577
        emprintf4(pdev->memory,
3145
577
            "ERROR: Page %d used undefined glyph '%s' from type 3 font '%s', key '%s'\n",
3146
577
            pdev->next_page, glyph, FontName, KeyName);
3147
577
            stream_puts(pdev->strm, "0 0 0 0 0 0 d1\n");
3148
577
    }
3149
3150
4.46k
    if (was_PS_type3 || pdev->Scaled_accumulator) {
3151
        /* See below, we scaled the device height and width to prevent
3152
         * clipping of the CharProc operations, now we need to undo that.
3153
         */
3154
4.46k
        pdev->width /= 100;
3155
4.46k
        pdev->height /= 100;
3156
4.46k
        pdev->Scaled_accumulator = 0;
3157
4.46k
    }
3158
4.46k
    code = pdf_end_charproc_accum(pdev, penum->current_font, penum->cgp,
3159
4.46k
                pte_default->returned.current_glyph, penum->output_char_code, &gnstr);
3160
4.46k
    if (code < 0)
3161
2
        goto exit;
3162
4.46k
    pdev->accumulating_charproc = false;
3163
4.46k
    penum->charproc_accum = false;
3164
4.46k
    code = gx_default_text_restore_state(pte_default);
3165
4.46k
    if (code < 0)
3166
0
        goto exit;
3167
4.46k
    gs_text_release(NULL, pte_default, "pdf_text_process");
3168
4.46k
    penum->pte_default = 0;
3169
3170
4.46k
exit:
3171
4.46k
    if (cleanup)
3172
0
        gs_free_string(pdev->pdf_memory, (byte *)gnstr.data, gnstr.size, "pdf_text_set_cache free working name");
3173
4.46k
    return code;
3174
4.46k
}
3175
3176
/* Nasty hackery. The PCL 'stick font' is drawn by constructing a path, and then stroking it.
3177
 * The stroke width is calculated under the influence of the device default matrix, which
3178
 * ensures it is the same, no matter what size the font is drawn at. Of course we are
3179
 * capturing the glyph under an identity matrix, so using the device matrix blows it up.
3180
 * What we do is replace the get_initial_matrix method for the course of the charproc
3181
 * accumulation *only*, and return a more sensible 'device' matrix.
3182
 * We know that the Charproc CTM is a combination of the font point size, and the default device
3183
 * matrix, so we just take off the default matrix, and invert the font scaling.
3184
 * This will scale the linewidth nicely for us. It does mean that if we use the
3185
 * same font at a different size, then the width will not be 'correct', but I
3186
 * think this is good enough.
3187
 */
3188
static void pdf_type3_get_initial_matrix(gx_device * dev, gs_matrix * pmat)
3189
0
{
3190
0
    gx_device_pdf *pdev = (gx_device_pdf *)dev;
3191
3192
0
    pmat->xx = pdev->charproc_ctm.xx;
3193
0
    pmat->xy = pdev->charproc_ctm.xy;
3194
0
    pmat->yx = pdev->charproc_ctm.yx;
3195
0
    pmat->yy = pdev->charproc_ctm.yy;
3196
0
    pmat->tx = 0;
3197
0
    pmat->ty = 0;
3198
    /* FIXME: Handle error here? Or is the charproc_ctm guaranteed to be invertible? */
3199
0
    (void)gs_matrix_invert(pmat, pmat);
3200
0
    gs_matrix_scale(pmat, pdev->HWResolution[0] / 72.0, pdev->HWResolution[0] / 72.0, pmat);
3201
0
}
3202
3203
static int pdf_query_purge_cached_char(const gs_memory_t *mem, cached_char *cc, void *data)
3204
0
{
3205
0
    cached_char *to_purge = (cached_char *)data;
3206
3207
3208
0
    if (cc->code == to_purge->code && cc_pair(cc) == cc_pair(to_purge) &&
3209
0
        cc->subpix_origin.x == to_purge->subpix_origin.x &&
3210
0
        cc->subpix_origin.y == to_purge->subpix_origin.y &&
3211
0
        cc->wmode == to_purge->wmode && cc_depth(cc) == cc_depth(to_purge)
3212
0
        )
3213
0
        return 1;
3214
0
    return 0;
3215
0
}
3216
3217
static int ProcessTextForOCR(gs_text_enum_t *pte)
3218
0
{
3219
0
    pdf_text_enum_t *const penum = (pdf_text_enum_t *)pte;
3220
0
    gx_device_pdf *pdev = (gx_device_pdf *)penum->dev;
3221
0
    gs_text_enum_t *pte_default;
3222
0
    int code;
3223
3224
0
    if (pdev->OCRStage == OCR_UnInit) {
3225
0
        gs_gsave(pte->pgs);
3226
0
        pdev->OCRSaved = (gs_text_enum_t*)gs_alloc_bytes(pdev->memory,sizeof(gs_text_enum_t),"saved enumerator for OCR");
3227
0
        if(pdev->OCRSaved == NULL)
3228
0
            return_error(gs_error_VMerror);
3229
0
        *(pdev->OCRSaved) = *pte;
3230
0
        gs_text_enum_copy_dynamic(pdev->OCRSaved,pte,true);
3231
3232
0
        code = pdf_default_text_begin(pte, &pte->text, &pte_default);
3233
0
        if (code < 0)
3234
0
            return code;
3235
0
        penum->pte_default = pte_default;
3236
0
        gs_text_enum_copy_dynamic(pte_default, pte, false);
3237
0
        pdev->OCRStage = OCR_Rendering;
3238
0
    }
3239
3240
0
    if (pdev->OCRStage == OCR_Rendering) {
3241
0
        penum->pte_default->can_cache = 0;
3242
0
        code = gs_text_process(penum->pte_default);
3243
0
        pdev->OCR_char_code = penum->pte_default->returned.current_char;
3244
0
        pdev->OCR_glyph = penum->pte_default->returned.current_glyph;
3245
0
        gs_text_enum_copy_dynamic(pte, penum->pte_default, true);
3246
0
        if (code == TEXT_PROCESS_RENDER)
3247
0
            return code;
3248
0
        if (code != 0) {
3249
0
            gs_free_object(pdev->memory, pdev->OCRSaved,"saved enumerator for OCR");
3250
0
            pdev->OCRSaved = NULL;
3251
0
            gs_grestore(pte->pgs);
3252
0
            gs_text_release(pte->pgs, penum->pte_default, "pdf_text_process");
3253
0
            penum->pte_default = NULL;
3254
0
            return code;
3255
0
        }
3256
0
        gs_grestore(pte->pgs);
3257
0
        *pte = *(pdev->OCRSaved);
3258
0
        gs_text_enum_copy_dynamic(pte, pdev->OCRSaved, true);
3259
0
        gs_free_object(pdev->memory, pdev->OCRSaved,"saved enumerator for OCR");
3260
0
        pdev->OCRSaved = NULL;
3261
0
        gs_text_release(pte->pgs, penum->pte_default, "pdf_text_process");
3262
0
        penum->pte_default = NULL;
3263
0
        pdev->OCRStage = OCR_Rendered;
3264
0
    }
3265
0
    return 0;
3266
0
}
3267
3268
/*
3269
 * Continue processing text.  This is the 'process' procedure in the text
3270
 * enumerator.  Per the check in pdf_text_begin, we know the operation is
3271
 * not a charpath, but it could be anything else.
3272
 */
3273
int
3274
pdf_text_process(gs_text_enum_t *pte)
3275
1.58M
{
3276
1.58M
    pdf_text_enum_t *const penum = (pdf_text_enum_t *)pte;
3277
1.58M
    uint operation = pte->text.operation;
3278
1.58M
    uint size = 0;
3279
1.58M
    gs_text_enum_t *pte_default;
3280
1.58M
    PROCESS_TEXT_PROC((*process));
3281
1.58M
    int code = 0, early_accumulator = 0;
3282
1.58M
    gx_device_pdf *pdev = (gx_device_pdf *)penum->dev;
3283
1.58M
    uint captured_pte_index = 0xFFFFFFFF;
3284
1.58M
#define BUF_SIZE 100                /* arbitrary > 0 */
3285
    /* Use a union to ensure alignment. */
3286
1.58M
    union bu_ {
3287
1.58M
        byte bytes[BUF_SIZE];
3288
1.58M
        gs_char chars[BUF_SIZE / sizeof(gs_char)];
3289
1.58M
        gs_glyph glyphs[BUF_SIZE / sizeof(gs_glyph)];
3290
1.58M
    } buf;
3291
3292
1.58M
     if (!penum->pte_default) {
3293
        /* Don't need to sync before exiting charproc. */
3294
1.55M
        code = pdf_prepare_text_drawing(pdev, pte);
3295
1.55M
        if (code == gs_error_rangecheck) {
3296
            /* Fallback to the default implermentation for handling
3297
               a transparency with CompatibilityLevel<=1.3 . */
3298
20
            goto default_impl;
3299
20
        }
3300
1.55M
        if (code < 0)
3301
832
            return code;
3302
1.55M
    }
3303
1.58M
    if (!penum->pte_default) {
3304
1.55M
        pdev->charproc_just_accumulated = false;
3305
1.55M
        if (penum->cdevproc_callout) {
3306
            /* Restore after TEXT_PROCESS_CDEVPROC in scan_cmap_text. */
3307
0
            penum->current_font = penum->orig_font;
3308
0
        }
3309
1.55M
    }
3310
1.58M
    if ((penum->current_font->FontType == ft_user_defined ||
3311
1.58M
        penum->current_font->FontType == ft_PCL_user_defined ||
3312
1.58M
        penum->current_font->FontType == ft_PDF_user_defined ||
3313
1.58M
        penum->current_font->FontType == ft_MicroType ||
3314
1.58M
        penum->current_font->FontType == ft_GL2_stick_user_defined ||
3315
1.58M
        penum->current_font->FontType == ft_GL2_531) &&
3316
1.58M
        (penum->text.operation & TEXT_DO_ANY_CHARPATH)
3317
1.58M
        && !pdev->type3charpath) {
3318
410
        pdev->type3charpath = true;
3319
410
        if (!penum->charproc_accum)
3320
410
            goto default_impl;
3321
410
    }
3322
3323
1.57M
    if (pdev->UseOCR != UseOCRNever) {
3324
0
        code = ProcessTextForOCR(pte);
3325
0
        if (code != 0)
3326
0
            return code;
3327
0
    }
3328
3329
1.57M
    operation = pte->text.operation;
3330
1.57M
    size = pte->text.size - pte->index;
3331
3332
1.57M
    code = -1;                /* to force default implementation */
3333
3334
    /*
3335
     * If we fell back to the default implementation, continue using it.
3336
     */
3337
1.80M
 top:
3338
1.80M
    pte_default = penum->pte_default;
3339
    /* pte_default is a signal that we can't handle the glyph in the current
3340
     * font 'natively'. This means either a type 3 font (for PostScript we
3341
     * need to return to the PS interpreter to run the BuildChar), or a font
3342
     * type we can't or don't support in PDF. In the latter case we have the
3343
     * BuildChar render the glyph and store it in the cache, spot the usage
3344
     * in the pdfwrite image routine and we store the resluting bitmap in a
3345
     * Type 3 font. NB if the glyph is uncached then it just ends up in the
3346
     * output as a bitmap image.
3347
     */
3348
1.80M
    if (pte_default) {
3349
239k
        gs_char *cdata;
3350
3351
239k
        cdata = (gs_char *)pte->text.data.chars;
3352
239k
        if (penum->charproc_accum) {
3353
            /* We've been accumulating a Type 3 CharProc, so now we need to
3354
             * finish off and store it in the font.
3355
             */
3356
3.12k
            code = complete_charproc(pdev, pte, pte_default, penum, true);
3357
3.12k
            if (code < 0)
3358
0
                return code;
3359
            /* Record the current index of the text, this is the index for which we captured
3360
             * this charproc. We use this below to determine whether an error return is an
3361
             * error after we've already captured a CharProc. If it is, then we must not
3362
             * attempt to capture it again, this wil lead to an infinite loop.
3363
             */
3364
3.12k
            captured_pte_index = pte->index;
3365
3.12k
            if (!pdev->type3charpath)
3366
3.12k
                goto top;
3367
0
            else
3368
0
                goto default_impl;
3369
3.12k
        }
3370
3371
235k
        if ((penum->current_font->FontType == ft_GL2_stick_user_defined ||
3372
235k
            penum->current_font->FontType == ft_GL2_531 || penum->current_font->FontType == ft_MicroType)
3373
235k
            && operation & TEXT_FROM_CHARS && !pdev->type3charpath) {
3374
            /* Check for anamorphic sacling, we msut not cache stick font
3375
             * in this case, as the stroke width will vary with the scaling.
3376
             */
3377
3378
            /* To test the scaling we'll map two unit vectors, calculate the
3379
             * length of the transformed vectors and see if they are the same
3380
             * x' = ax + cy + Tx
3381
             * y' = bx + dy + Ty
3382
             * We set Tx and Ty to zero (we only care about scale not translation)
3383
             * We then test 0,0->0,1 and 0,0 -> 1,0. Because one term is always 0
3384
             * this means we can simplify the math.
3385
             */
3386
            /* Vector 0,0 -> 0,1 x is always 0, Tx and Ty are 0 =>
3387
             * x' = cy = c
3388
             * y' = dy = d
3389
             */
3390
            /* Vector 0,0 -> 1,0 y is always 0, Tx and Ty are 0 =>
3391
             * x' = ax = a
3392
             * y' = bx = b
3393
             */
3394
            /* Length of hypotenuse squared = sum of squares We don't care
3395
             * about the length's actual magnitude, so we can compare the
3396
             * squared length
3397
             */
3398
0
            float x0y1, x1y0;
3399
3400
0
            x0y1 = (penum->pgs->ctm.yx * penum->pgs->ctm.yx) +
3401
0
                (penum->pgs->ctm.yy * penum->pgs->ctm.yy);
3402
0
            x1y0 = (penum->pgs->ctm.xx * penum->pgs->ctm.xx) +
3403
0
                (penum->pgs->ctm.xy * penum->pgs->ctm.xy);
3404
3405
0
            if (x0y1 == x1y0)
3406
0
                early_accumulator = 1;
3407
0
        }
3408
235k
        if (penum->current_font->FontType == ft_PDF_user_defined) {
3409
1.34k
            early_accumulator = 1;
3410
1.34k
        }
3411
235k
        if (early_accumulator) {
3412
1.34k
            if (pte->text.operation & TEXT_FROM_BYTES || pte->text.operation & TEXT_FROM_STRING || (pte->text.operation & TEXT_FROM_CHARS && cdata[pte->index] <= 255)) {
3413
                /* The enumerator is created in pdf_default_text_begin and *is*
3414
                 * a show enumerator, so this is safe. We need to update the
3415
                 * graphics state pointer below which is why we need this.
3416
                 */
3417
1.34k
                gs_show_enum psenum = *(gs_show_enum *)pte_default;
3418
1.34k
                gs_gstate *pgs = (gs_gstate *)penum->pgs;
3419
1.34k
                gs_text_enum_procs_t *special_procs;
3420
1.34k
                void (*save_proc)(gx_device *, gs_matrix *) = pdev->procs.get_initial_matrix;
3421
1.34k
                gs_matrix m, savem;
3422
3423
1.34k
                special_procs = (gs_text_enum_procs_t *)gs_alloc_bytes(pte_default->memory->non_gc_memory, sizeof(gs_text_enum_procs_t), "pdf_text_process");
3424
1.34k
                if (special_procs == NULL)
3425
0
                    return_error(gs_error_VMerror);
3426
3427
1.34k
                *special_procs = *pte_default->procs;
3428
1.34k
                special_procs->set_cache = pdf_text_set_cache;
3429
1.34k
                special_procs->release = pdf_show_text_release;
3430
1.34k
                pte_default->procs = special_procs;
3431
3432
1.34k
                {
3433
                    /* We should not come here if we already have a cached character (except for the special case
3434
                     * of redefined characters in PCL downloaded fonts). If we do, it means that we are doing
3435
                     * 'page bursting', ie each page is going to a separate file, and the cache has an entry
3436
                     * from previous pages, but the PDF font resource doesn't. So empty the cached character
3437
                     * from the cache, to ensure the character description gets executed.
3438
                     */
3439
1.34k
                    gs_font *rfont = (pte->fstack.depth < 0 ? pte->current_font : pte->fstack.items[0].font);
3440
1.34k
                    gs_font *pfont = (pte->fstack.depth < 0 ? pte->current_font :
3441
1.34k
                        pte->fstack.items[pte->fstack.depth].font);
3442
1.34k
                    int wmode = rfont->WMode;
3443
1.34k
                    gs_log2_scale_point log2_scale = {0,0};
3444
1.34k
                    gs_fixed_point subpix_origin = {0,0};
3445
1.34k
                    cached_fm_pair *pair;
3446
1.34k
                    cached_char *cc;
3447
3448
1.34k
                    code = gx_lookup_fm_pair(pfont, &ctm_only(pte->pgs), &log2_scale, false, &pair);
3449
1.34k
                    if (code < 0)
3450
0
                        return code;
3451
1.34k
                    cc = gx_lookup_cached_char(pfont, pair, pte_default->text.data.chars[pte_default->index], wmode, 1, &subpix_origin);
3452
1.34k
                    if (cc != 0) {
3453
0
                        gx_purge_selected_cached_chars(pfont->dir, pdf_query_purge_cached_char, (void *)cc);
3454
0
                    }
3455
1.34k
                }
3456
                /* charproc completion will restore a gstate */
3457
0
                gs_gsave(pgs);
3458
                /* Assigning the gs_gstate pointer to the graphics state pointer
3459
                 * makes sure that when we make the CTM into the identity it
3460
                 * affects both.
3461
                 */
3462
1.34k
                psenum.pgs = (gs_gstate *)psenum.pgs;
3463
                /* Save the current FontMatrix */
3464
1.34k
                savem = pgs->font->FontMatrix;
3465
                /* Make the FontMatrix the identity otherwise we will apply
3466
                 * it twice, once in the glyph description and again in the
3467
                 * text matrix.
3468
                 */
3469
1.34k
                gs_make_identity(&m);
3470
1.34k
                pgs->font->FontMatrix = m;
3471
3472
1.34k
                pgs->char_tm_valid = 0;
3473
1.34k
                pgs->char_tm.txy_fixed_valid = 0;
3474
1.34k
                pgs->current_point.x = pgs->current_point.y = 0;
3475
1.34k
                pgs->char_tm.txy_fixed_valid = 0;
3476
3477
1.34k
                if (pte->text.operation & TEXT_FROM_CHARS)
3478
1.34k
                    pte_default->returned.current_char = penum->returned.current_char =
3479
1.34k
                        pte->text.data.chars[pte->index];
3480
0
                else
3481
0
                    pte_default->returned.current_char = penum->returned.current_char =
3482
0
                        pte->text.data.bytes[pte->index];
3483
3484
1.34k
                code = install_charproc_accumulator(pdev, pte, pte_default, penum);
3485
1.34k
                if (code < 0) {
3486
0
                    gs_grestore(pgs);
3487
0
                    pgs->font->FontMatrix = savem;
3488
0
                    return code;
3489
0
                }
3490
3491
                /* We can't capture more than one glyph at a time, so amek this one
3492
                 * otherwise the gs_text_process would try to render all the glyphs
3493
                 * in the string.
3494
                 */
3495
1.34k
                if (pte->text.size != 1)
3496
1.24k
                    pte_default->text.size = pte->index + 1;
3497
                /* We need a special 'initial matrix' method for stick fonts,
3498
                 * See pdf_type3_get_initial_matrix above.
3499
                 */
3500
1.34k
                if (penum->current_font->FontType != ft_PDF_user_defined)
3501
0
                    pdev->procs.get_initial_matrix = pdf_type3_get_initial_matrix;
3502
3503
1.34k
                pdev->pte = (gs_text_enum_t *)penum; /* CAUTION: See comment in gdevpdfx.h . */
3504
                /* In case of error, text_process will restore back to the enumerator 'level'
3505
                 * we must make certain we do not restore back too far!
3506
                 */
3507
1.34k
                pte_default->level = penum->pgs->level;
3508
1.34k
                code = gs_text_process(pte_default);
3509
1.34k
                if (code < 0) {
3510
4
                    (void)complete_charproc(pdev, pte, pte_default, penum, false);
3511
4
                    return code;
3512
4
                }
3513
1.33k
                pdev->pte = NULL;         /* CAUTION: See comment in gdevpdfx.h . */
3514
1.33k
                pdev->charproc_just_accumulated = false;
3515
3516
                /* Restore the saved FontMatrix, so that it gets applied
3517
                 * as part of the text matrix
3518
                 */
3519
1.33k
                pgs->font->FontMatrix = savem;
3520
                /* Restore the default 'initial matrix' mathod. */
3521
1.33k
                pdev->procs.get_initial_matrix = save_proc;
3522
1.33k
                penum->returned.current_char = pte_default->returned.current_char;
3523
1.33k
                penum->returned.current_glyph = pte_default->returned.current_glyph;
3524
1.33k
                code = pdf_choose_output_char_code(pdev, penum, &penum->output_char_code);
3525
1.33k
                if (code < 0) {
3526
0
                    (void)complete_charproc(pdev, pte, pte_default, penum, false);
3527
0
                    gs_grestore(pgs);
3528
0
                    return code;
3529
0
                }
3530
3531
                /* complete_charproc will release the text enumerator 'pte_default', we assume
3532
                 * that we are holding the only reference to it. Note that complete_charproc
3533
                 * also sets penum->pte_default to 0, so that we don't re-entre this  section of
3534
                 * code but process the text normally, now that we have captured the glyph description.
3535
                 */
3536
1.33k
                code = complete_charproc(pdev, pte, pte_default, penum, false);
3537
1.33k
                if (penum->current_font->FontType == ft_PCL_user_defined)
3538
0
                {
3539
                    /* PCL bitmap fonts can have glyphs 'reused'. We can't handle
3540
                     * handle this in a single PDF font, so we need to know when
3541
                     * it has happened and fall back to the 'default' implementation.
3542
                     * In order to do this, we create a cached character representation
3543
                     * and add it to the cache. If the glyph is reused then the
3544
                     * act of redefining it will remove this entry from the cache.
3545
                     * We check if the glyph is in the cache in process_text_return_width
3546
                     * and come back into this code. In the test above for PCL bitmap
3547
                     * fonts we also check to see if the PDF font already has a
3548
                     *'used' entry. If it does we know that its a redefinition, and
3549
                     * we don't try to capture the glyph.
3550
                     */
3551
0
                    cached_char *cc;
3552
0
                    cached_fm_pair *pair;
3553
0
                    gs_log2_scale_point log2_scale = {0,0};
3554
0
                    gs_font *rfont = (pte->fstack.depth < 0 ? pte->current_font : pte->fstack.items[0].font);
3555
0
                    int wmode = rfont->WMode;
3556
0
                    pdf_font_resource_t *pdfont;
3557
3558
                    /* This code copied from show_cache_setup */
3559
0
                    gs_memory_t *mem = penum->memory;
3560
0
                    gx_device_memory *dev =
3561
0
                        gs_alloc_struct(mem, gx_device_memory, &st_device_memory,
3562
0
                        "show_cache_setup(dev_cache)");
3563
3564
0
                    if (dev == 0) {
3565
0
                        gs_free_object(mem, dev, "show_cache_setup(dev_cache)");
3566
0
                        return_error(gs_error_VMerror);
3567
0
                    }
3568
0
                    gs_make_mem_mono_device(dev, mem, penum->dev);
3569
0
                    dev->HWResolution[0] = pgs->device->HWResolution[0];
3570
0
                    dev->HWResolution[1] = pgs->device->HWResolution[1];
3571
                    /* Retain these devices. */
3572
0
                    gx_device_retain((gx_device *)dev, true);
3573
                    /* end of code copied from show_cache_setup */
3574
3575
                    /* This copied from set_cache */
3576
0
                    code = gx_alloc_char_bits(pte->current_font->dir, dev,
3577
0
                                0, 0, &log2_scale, 1, &cc);
3578
0
                    if (code < 0)
3579
0
                        return code;
3580
3581
                    /* The following code is copied from show_update, case sws_cache */
3582
0
                    code = gx_lookup_fm_pair(pte->current_font, &ctm_only(pte->pgs),
3583
0
                            &log2_scale, false, &pair);
3584
0
                    if (code < 0)
3585
0
                        return code;
3586
3587
                    /* These members of the cached character are required
3588
                     * in order to find the cache entry later
3589
                     */
3590
0
                    cc->code = penum->returned.current_char;
3591
0
                    cc->wmode = wmode;
3592
0
                    cc->subpix_origin.x = cc->subpix_origin.y = 0;
3593
0
                    log2_scale.x = log2_scale.y = 0;
3594
0
                    code = gx_add_cached_char(pte->current_font->dir, dev,
3595
0
                               cc, pair, &log2_scale);
3596
0
                    if (code < 0)
3597
0
                        return code;
3598
                    /* End of code from show_update */
3599
3600
                    /* Finally, dispose of the device, which we don't actually need */
3601
0
                    gx_device_retain((gx_device *)dev, false);
3602
3603
                    /* Its possible for a bitmapped PCL font to not execute setcachedevice (invalid empty glyph)
3604
                     * which means that the pdfwrite override doesn't see it, and we don't note that the
3605
                     * glyph is 'cached' in the PDF font resource, but the 'used' flag does get set.
3606
                     * This causes our detection some problems, so mark it 'cached' here to make sure.
3607
                     */
3608
0
                    code = pdf_attached_font_resource(pdev, (gs_font *)penum->current_font, &pdfont, NULL, NULL, NULL, NULL);
3609
0
                    if (code < 0)
3610
0
                        return code;
3611
3612
0
                    pdfont->u.simple.s.type3.cached[cdata[pte->index] >> 3] |= 0x80 >> (cdata[pte->index] & 7);
3613
0
                }
3614
1.33k
                size = pte->text.size - pte->index;
3615
1.33k
                if (code < 0)
3616
2
                    return code;
3617
1.33k
                if (!pdev->type3charpath)
3618
1.33k
                    goto top;
3619
0
                else
3620
0
                    goto default_impl;
3621
1.33k
            }
3622
1.34k
        }
3623
3624
        /* Now we run the default text procedure to see what happens.
3625
         * PCL bitmap fonts and the HP/GL-2 stick font are handled above.
3626
         * If its a PostScript type 3 font (and some other kinds)
3627
         * then it will return TEXT_PROCESS_RENDER and we need to exit
3628
         * to the interpreter to run the glyph description. Otherwise we just
3629
         * run the BuildChar, and later capture the cached bitmap for incorporation
3630
         * into a type 3 font. Note that sometimes we will handle PCL or HP/GL-2
3631
         * fonts by not capturing them above, and they will come through here.
3632
         * The stick font will not be captured as a font at all, just vectors
3633
         * stored into the content stream (for osme kinds of scale/shear),
3634
         * bitmap fonts will be captured in the pdfwrite image routine. These
3635
         * are added to a type 3 font in the same way as glyphs which need to
3636
         * be rendered.
3637
         */
3638
234k
        {
3639
234k
            gs_show_enum *penum = (gs_show_enum *)pte_default;
3640
234k
            int save_can_cache = penum->can_cache;
3641
234k
            const gs_color_space *pcs;
3642
234k
            const gs_client_color *pcc;
3643
234k
            gs_gstate * pgs = pte->pgs;
3644
3645
            /* If we are using a high level pattern, we must not use the cached character, as the
3646
             * cache hasn't seen the pattern. So set can_cache to < 0, which prevents us consulting
3647
             * the cache, or storing the result in it.
3648
             * We actually don't want to use the cache for any Type 3 font where we're trying to
3649
             * capture the charproc - if we want to have a chance of capturing the charproc, we
3650
             * need it to execute, and not use a cache entry.
3651
             */
3652
234k
            if (gx_hld_get_color_space_and_ccolor(pgs, (const gx_drawing_color *)pgs->color[0].dev_color, &pcs, &pcc) == pattern_color_space)
3653
0
                penum->can_cache = -1;
3654
234k
            pdev->pte = pte_default; /* CAUTION: See comment in gdevpdfx.h . */
3655
234k
            code = gs_text_process(pte_default);
3656
234k
            if (code < 0)
3657
253
                return code;
3658
3659
234k
            penum->can_cache = save_can_cache;
3660
3661
234k
            pdev->pte = NULL;         /* CAUTION: See comment in gdevpdfx.h . */
3662
234k
            pdev->charproc_just_accumulated = false;
3663
234k
        }
3664
3665
        /* If the BuildChar returned TEXT_PROCESS_RENDER then we want to try and
3666
         * capture this as a type 3 font, so start the accumulator now. Note
3667
         * that the setcachedevice handling can still abort this later. In which
3668
         * case we get the rendered bitmap, just as for non type 3 fonts.
3669
         */
3670
234k
        if (code == TEXT_PROCESS_RENDER && !pdev->type3charpath) {
3671
3.12k
            int code1;
3672
3673
3.12k
            code1 = install_PS_charproc_accumulator(pdev, pte, pte_default, penum);
3674
3.12k
            if (code1 != 0)
3675
3.12k
                return code1;
3676
3.12k
        }
3677
3678
231k
        gs_text_enum_copy_dynamic(pte, pte_default, true);
3679
3680
231k
        if (code)
3681
18.6k
            return code;
3682
212k
        gs_text_release(NULL, pte_default, "pdf_text_process");
3683
212k
        penum->pte_default = 0;
3684
212k
        if (pdev->type3charpath)
3685
410
            pdev->type3charpath = false;
3686
212k
        return 0;
3687
231k
    }
3688
1.56M
    {
3689
1.56M
        gs_font *font = pte->orig_font; /* Not sure. Changed for CDevProc callout. Was pte->current_font */
3690
3691
1.56M
        switch (font->FontType) {
3692
0
        case ft_CID_encrypted:
3693
0
        case ft_CID_TrueType:
3694
0
            process = process_cid_text;
3695
0
            break;
3696
1.03M
        case ft_encrypted:
3697
1.22M
        case ft_encrypted2:
3698
1.49M
        case ft_TrueType:
3699
1.49M
        case ft_user_defined:
3700
1.49M
        case ft_PDF_user_defined:
3701
1.49M
        case ft_PCL_user_defined:
3702
1.49M
        case ft_MicroType:
3703
1.49M
        case ft_GL2_stick_user_defined:
3704
1.49M
        case ft_GL2_531:
3705
            /* The data may be either glyphs or characters. */
3706
1.49M
            process = process_plain_text;
3707
1.49M
            break;
3708
64.6k
        case ft_composite:
3709
64.6k
            process =
3710
64.6k
                (((gs_font_type0 *)font)->data.FMapType == fmap_CMap ?
3711
64.6k
                 process_cmap_text :
3712
64.6k
                 process_composite_text);
3713
64.6k
            break;
3714
0
        default:
3715
0
            goto skip;
3716
1.56M
        }
3717
1.56M
    }
3718
3719
    /*
3720
     * We want to process the entire string in a single call, but we may
3721
     * need to modify it.  Copy it to a buffer.  Note that it may consist
3722
     * of bytes, gs_chars, or gs_glyphs.
3723
     */
3724
3725
1.56M
    if (operation & (TEXT_FROM_STRING | TEXT_FROM_BYTES)) {
3726
1.56M
        if (size < sizeof(gs_glyph))
3727
1.42M
            size = sizeof(gs_glyph); /* for process_cid_text */
3728
1.56M
    } else if (operation & TEXT_FROM_CHARS)
3729
2.32k
        size *= sizeof(gs_char);
3730
0
    else if (operation & TEXT_FROM_SINGLE_CHAR)
3731
0
        size = sizeof(gs_char);
3732
0
    else if (operation & TEXT_FROM_GLYPHS)
3733
0
        size *= sizeof(gs_glyph);
3734
0
    else if (operation & TEXT_FROM_SINGLE_GLYPH)
3735
0
        size = sizeof(gs_glyph);
3736
0
    else
3737
0
        goto skip;
3738
3739
    /* Now that we are using the working buffer for text in composite fonts, we must make sure
3740
     * it is large enough. Each input character code may be promoted to a gs_glyph, in scan_cmap_text
3741
     * when processing a Type 0 font with a type 1 descendant font. This routine uses
3742
     * pdf_make_text_glyphs_table_unencoded (called from pdf_obtain_font_resource_unencoded) which
3743
     * also may require an identically sized buffer, so we need:
3744
     * num__input_characters * sizeof(gs_glyph) * 2.
3745
     */
3746
1.56M
    if (pte->orig_font->FontType == ft_composite) {
3747
64.6k
        if (size < (pte->text.size - pte->index) * sizeof(gs_glyph) * 2)
3748
64.6k
            size = (pte->text.size - pte->index) * sizeof(gs_glyph) * 2;
3749
64.6k
    }
3750
3751
1.56M
    if (size <= sizeof(buf)) {
3752
1.55M
        code = process(pte, buf.bytes, size);
3753
1.55M
    } else {
3754
4.85k
        byte *buf = gs_alloc_string(pte->memory, size, "pdf_text_process");
3755
3756
4.85k
        if (buf == 0)
3757
0
            return_error(gs_error_VMerror);
3758
4.85k
        code = process(pte, buf, size);
3759
4.85k
        gs_free_string(pte->memory, buf, size, "pdf_text_process");
3760
4.85k
    }
3761
1.56M
 skip:
3762
1.56M
    if (code < 0 ||
3763
1.56M
            ((pte->current_font->FontType == ft_user_defined ||
3764
1.34M
            pte->current_font->FontType == ft_PCL_user_defined ||
3765
1.34M
            pte->current_font->FontType == ft_PDF_user_defined ||
3766
1.34M
            pte->current_font->FontType == ft_MicroType ||
3767
1.34M
            pte->current_font->FontType == ft_GL2_stick_user_defined ||
3768
1.34M
            pte->current_font->FontType == ft_GL2_531 ||
3769
1.34M
            pte->current_font->FontType == ft_TrueType) &&
3770
1.34M
             code != TEXT_PROCESS_INTERVENE &&
3771
1.34M
            penum->index < penum->text.size)) {
3772
221k
        if (code == gs_error_unregistered) /* Debug purpose only. */
3773
1.25k
            return code;
3774
219k
        if (code == gs_error_VMerror)
3775
6
            return code;
3776
219k
        if (code == gs_error_invalidfont) /* Bug 688370. */
3777
3.02k
            return code;
3778
217k
 default_impl:
3779
        /* If we have captured a CharProc, and the current index into the
3780
         * text is unchanged, then the capturing a CharProc for this text still
3781
         * resulted in a text error. So don't try to fix it by capturing the
3782
         * CharProc again, this causes an endless loop.
3783
         */
3784
217k
        if (captured_pte_index == pte->index)
3785
0
            return code;
3786
        /* Fall back to the default implementation. */
3787
217k
        code = pdf_default_text_begin(pte, &pte->text, &pte_default);
3788
217k
        if (code < 0)
3789
0
            return code;
3790
217k
        penum->pte_default = pte_default;
3791
217k
        gs_text_enum_copy_dynamic(pte_default, pte, false);
3792
217k
    }
3793
    /* The 'process' procedure might also have set pte_default itself. */
3794
1.55M
    if (penum->pte_default && !code)
3795
217k
        goto top;
3796
1.34M
    return code;
3797
    /*
3798
     * This function uses an unobvious algorithm while handling type 3 fonts.
3799
     * It runs 'process' to copy text until a glyph, which was not copied to
3800
     * output font. Then it installs pte_default and falls back to default
3801
     * implementation with PS interpreter callout. The callout executes
3802
     * BuildChar/BuildGlyph with setcachedevice. The latter calls
3803
     * pdf_set_charproc_attrs, which sets up an accumulator
3804
     * of graphic objects to a pdf_begin_resource stream.
3805
     * When the callout completes, pdf_text_process calls pdf_end_charproc_accum
3806
     * and later resumes the normal (non-default) text enumeration, repeating the
3807
     * the "callouted" glyph AT SECOND TIME. We can't do without the second pass
3808
     * becauase in the first pass the glyph widths is unknown.
3809
     */
3810
     /*
3811
      * Another unobvious thing is a CDevProc callout.
3812
      * If 'process' returns with TEXT_PROCESS_CDEVPROC,
3813
      * an interpreter callout will happen, and the function will be called again
3814
      * with pte->cdevproc_result_valid = true. Then it restatrs with taking
3815
      * glyph metrics from pte->cdevproc_result instead obtaining them with
3816
      * font->procs.glyph_info .
3817
      */
3818
1.55M
}