Coverage Report

Created: 2025-08-28 07:06

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