Coverage Report

Created: 2025-11-16 07:40

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ghostpdl/devices/vector/gdevpdtt.c
Line
Count
Source
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
126k
{
75
126k
    const pdf_text_enum_t *const penum = (const pdf_text_enum_t *)pte;
76
77
126k
    if (penum->pte_default)
78
126k
        return gs_text_is_width_only(penum->pte_default);
79
0
    return false;
80
126k
}
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
25.4k
{
94
25.4k
     gs_show_enum *const penum = (gs_show_enum *)pte;
95
25.4k
     gs_text_enum_procs_t *procs = (gs_text_enum_procs_t *)penum->procs;
96
97
25.4k
     penum->cc = 0;
98
25.4k
     if (penum->dev_cache2) {
99
0
         gx_device_retain((gx_device *)penum->dev_cache2, false);
100
0
         penum->dev_cache2 = 0;
101
0
     }
102
25.4k
     if (penum->dev_cache) {
103
0
         gx_device_retain((gx_device *)penum->dev_cache, false);
104
0
         penum->dev_cache = 0;
105
0
     }
106
25.4k
     if (penum->dev_null) {
107
23
         gx_device_retain((gx_device *)penum->dev_null, false);
108
23
         penum->dev_null = 0;
109
23
     }
110
25.4k
     gx_default_text_release(pte, cname);
111
25.4k
     gs_free_object(penum->memory->non_gc_memory, procs, "pdf_show_text_release");
112
25.4k
}
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
135k
{
118
135k
    pdf_text_enum_t *penum;
119
135k
    gs_text_enum_t *pgste;
120
135k
    gx_device_pdf *pdev = (gx_device_pdf *)pte->dev;
121
135k
    gs_matrix m;
122
123
135k
    if (pdev->pte != NULL)
124
9.01k
        penum = (pdf_text_enum_t *)pdev->pte;
125
126k
    else {
126
126k
        if (gs_object_type(pte->memory, pte) == &st_pdf_text_enum)
127
126k
            penum = (pdf_text_enum_t *)pte;
128
0
        else
129
0
            return_error(gs_error_typecheck);
130
126k
    }
131
132
135k
    if (pdev->type3charpath || (penum->current_font->FontType == ft_PDF_user_defined && pdev->OCRStage == OCR_Rendering))
133
8.21k
        return gs_text_set_cache(penum->pte_default, pw, control);
134
135
126k
    switch (control) {
136
117k
    case TEXT_SET_CHAR_WIDTH:
137
126k
    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
126k
        if (pdev->PS_accumulator || pdev->Scaled_accumulator){
143
126k
            gs_matrix_scale(&ctm_only(pte->pgs), .01, .01, &m);
144
126k
            gs_distance_transform(pw[0], pw[1], &m, &pdev->char_width);
145
126k
        } else {
146
0
            pdev->char_width.x = pw[0];
147
0
            pdev->char_width.y = pw[1];
148
0
        }
149
126k
        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
126k
    }
176
126k
    if (!pdev->PS_accumulator)
177
9.01k
        pgste = (gs_text_enum_t *)penum;
178
117k
    else
179
117k
        pgste = penum->pte_default;
180
181
126k
    if ((penum->current_font->FontType == ft_user_defined ||
182
9.01k
        penum->current_font->FontType == ft_PDF_user_defined ||
183
0
        penum->current_font->FontType == ft_PCL_user_defined ||
184
0
        penum->current_font->FontType == ft_MicroType ||
185
0
        penum->current_font->FontType == ft_GL2_stick_user_defined ||
186
0
        penum->current_font->FontType == ft_GL2_531) &&
187
126k
            penum->outer_CID == GS_NO_GLYPH &&
188
126k
            !(pgste->text.operation & TEXT_DO_CHARWIDTH)) {
189
126k
        int code;
190
126k
        gs_glyph glyph;
191
192
126k
        glyph = pte->returned.current_glyph;
193
126k
        if ((glyph != GS_NO_GLYPH && penum->output_char_code != GS_NO_CHAR) || !pdev->PS_accumulator) {
194
126k
            gs_show_enum *penum_s;
195
126k
            gs_fixed_rect clip_box;
196
126k
            double pw1[10];
197
126k
            int narg = (control == TEXT_SET_CHAR_WIDTH ? 2 :
198
126k
                        control == TEXT_SET_CACHE_DEVICE ? 6 : 10), i;
199
200
126k
            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
272k
            for (i = 0; i < narg; i += 2) {
207
145k
                gs_point p;
208
209
145k
                gs_point_transform(pw[i], pw[i + 1], &ctm_only(penum_s->pgs), &p);
210
145k
                pw1[i] = p.x;
211
145k
                pw1[i + 1] = p.y;
212
145k
            }
213
126k
            if (control != TEXT_SET_CHAR_WIDTH) {
214
9.37k
                clip_box.p.x = float2fixed(pw1[2]);
215
9.37k
                clip_box.p.y = float2fixed(pw1[3]);
216
9.37k
                clip_box.q.x = float2fixed(pw1[4]);
217
9.37k
                clip_box.q.y = float2fixed(pw1[5]);
218
117k
            } 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
117k
                clip_box.p.x = clip_box.p.y = min_int / 2;
228
117k
                clip_box.q.x = clip_box.q.y = max_int / 2;
229
117k
            }
230
126k
            code = gx_clip_to_rectangle(penum_s->pgs, &clip_box);
231
126k
            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
126k
            if (pdev->PS_accumulator || pdev->Scaled_accumulator)
243
126k
                gs_matrix_scale(&ctm_only(penum_s->pgs), .01, .01, &m);
244
0
            else
245
0
                m = ctm_only(penum_s->pgs);
246
272k
            for (i = 0; i < narg; i += 2) {
247
145k
                gs_point p;
248
249
145k
                gs_point_transform(pw[i], pw[i + 1], &m, &p);
250
145k
                pw1[i] = p.x;
251
145k
                pw1[i + 1] = p.y;
252
145k
            }
253
126k
            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
126k
            else
257
126k
                code = pdf_set_charproc_attrs(pdev, pte->current_font,
258
126k
                        pw1, narg, control, penum->output_char_code, true);
259
126k
            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
126k
            pdev->clip_path_id = gx_get_clip_path_id(penum_s->pgs);
267
126k
            return code;
268
126k
        } 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
126k
    }
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.75M
{
328
6.75M
    pdf_text_enum_t *const penum = (pdf_text_enum_t *)pte;
329
6.75M
    gx_device_pdf *pdev = (gx_device_pdf *)penum->dev;
330
6.75M
    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.75M
    if (!penum->text_clipped && (penum->text.operation & TEXT_DO_DRAW || penum->pgs->text_rendering_mode == 3))
336
6.67M
    {
337
6.67M
        gs_matrix tmat, fmat;
338
6.67M
        gs_point p;
339
6.67M
        int i;
340
6.67M
        gs_font *font = (gs_font *)penum->current_font;
341
6.67M
        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.67M
        if (font != penum->orig_font) {
348
428k
            gs_matrix_multiply(&font->FontMatrix, &penum->orig_font->FontMatrix, &fmat);
349
428k
            gs_matrix_multiply(&fmat, &ctm_only(penum->pgs), &tmat);
350
6.24M
        } else {
351
6.24M
            gs_matrix_multiply(&font->FontMatrix, &ctm_only(penum->pgs), &tmat);
352
6.24M
        }
353
354
6.67M
        gs_distance_transform(1, 0, &tmat, &p);
355
6.67M
        if (p.x > fabs(p.y))
356
6.64M
            i = 0;
357
29.8k
        else if (p.x < -fabs(p.y))
358
1.78k
            i = 2;
359
28.0k
        else if (p.y > fabs(p.x))
360
25.8k
            i = 1;
361
2.16k
        else if (p.y < -fabs(p.x))
362
1.12k
            i = 3;
363
1.04k
        else
364
1.04k
            i = 4;
365
6.67M
        pdf_current_page(pdev)->text_rotation.counts[i] += text->size;
366
6.67M
    }
367
368
6.75M
    if (penum->pte_default) {
369
2.15k
        gs_text_release(NULL, penum->pte_default, cname);
370
2.15k
        penum->pte_default = 0;
371
2.15k
    }
372
6.75M
    pdf_text_release_cgp(penum);
373
374
6.75M
    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.75M
    if (pdev->OCRUnicode != NULL)
383
0
        gs_free_object(pdev->memory, pdev->OCRUnicode, "free returned unicodes");
384
6.75M
    pdev->OCRUnicode = NULL;
385
386
6.75M
    gx_default_text_release(pte, cname);
387
6.75M
    pdev->OCRStage = 0;
388
6.75M
}
389
void
390
pdf_text_release_cgp(pdf_text_enum_t *penum)
391
6.91M
{
392
6.91M
    if (penum->cgp) {
393
6.31M
        gs_free_object(penum->memory, penum->cgp, "pdf_text_release");
394
6.31M
        penum->cgp = 0;
395
6.31M
    }
396
6.91M
}
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
3.35M
{
421
3.35M
    int code=0;
422
3.35M
    if (text->operation & TEXT_DO_DRAW) {
423
3.34M
        if (!pdev->ForOPDFRead) {
424
3.34M
            if (pgs->text_rendering_mode != 3 && pgs->text_rendering_mode != 7) {
425
3.34M
                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
3.34M
                } else {
439
3.34M
                    if ((pgs->text_rendering_mode == 0 || pgs->text_rendering_mode == 2 ||
440
357
                        pgs->text_rendering_mode == 4 || pgs->text_rendering_mode == 6) &&
441
3.34M
                        !pdev->remap_stroke_color) {
442
3.34M
                        code = gx_set_dev_color(pgs);
443
3.34M
                        if (code != 0)
444
0
                            return code;
445
3.34M
                    }
446
3.34M
                    if (pgs->text_rendering_mode == 1 || pgs->text_rendering_mode == 2 ||
447
3.33M
                        pgs->text_rendering_mode == 5 || pgs->text_rendering_mode == 6) {
448
1.19k
                        if (!pdev->remap_fill_color) {
449
1.19k
                            if (pdev->remap_stroke_color) {
450
0
                                pdev->remap_stroke_color = false;
451
1.19k
                            } else {
452
1.19k
                                gs_swapcolors_quick(pgs);
453
1.19k
                                code = gx_set_dev_color(pgs);
454
1.19k
                                if (code == gs_error_Remap_Color)
455
0
                                    pdev->remap_stroke_color = true;
456
1.19k
                                if (code != 0)
457
0
                                    return code;
458
1.19k
                            }
459
1.19k
                        } else
460
0
                            pdev->remap_fill_color = false;
461
1.19k
                        gs_swapcolors_quick(pgs);
462
1.19k
                        code = gx_set_dev_color(pgs);
463
1.19k
                        if (code == gs_error_Remap_Color)
464
0
                            pdev->remap_fill_color = true;
465
1.19k
                        if (code != 0)
466
0
                            return code;
467
1.19k
                    }
468
3.34M
                }
469
3.34M
            }
470
3.34M
        }
471
3.34M
    }
472
3.35M
    return code;
473
3.35M
}
474
475
static int
476
pdf_prepare_text_drawing(gx_device_pdf *const pdev, gs_text_enum_t *pte)
477
6.75M
{
478
6.75M
    gs_gstate * pgs = pte->pgs;
479
6.75M
    const gx_clip_path * pcpath = pte->pcpath;
480
6.75M
    const gs_text_params_t *text = &pte->text;
481
6.75M
    bool new_clip = false; /* Quiet compiler. */
482
6.75M
    int code;
483
6.75M
    gs_font *font = pte->current_font;
484
485
6.75M
    if (!(text->operation & TEXT_DO_NONE) || pgs->text_rendering_mode == 3) {
486
6.75M
        code = pdf_check_soft_mask(pdev, pte->pgs);
487
6.75M
        if (code < 0)
488
0
            return code;
489
6.75M
        new_clip = pdf_must_put_clip_path(pdev, pcpath);
490
6.75M
        if (new_clip)
491
66.5k
            code = pdf_unclip(pdev);
492
6.68M
        else if (pdev->context == PDF_IN_NONE)
493
13.3k
            code = pdf_open_page(pdev, PDF_IN_STREAM);
494
6.67M
        else
495
6.67M
            code = 0;
496
6.75M
        if (code < 0)
497
0
            return code;
498
6.75M
        code = pdf_prepare_fill(pdev, pgs, true);
499
6.75M
        if (code < 0)
500
3.92k
            return code;
501
6.75M
    }
502
6.74M
    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.70M
        if (new_clip) {
512
18.7k
            code = pdf_put_clip_path(pdev, pcpath);
513
18.7k
            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.7k
            if (pdev->clipped_text_pending)
524
2
                pdev->vgstack_bottom = pdev->vgstack_depth;
525
18.7k
        }
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.70M
        if (!pdev->ForOPDFRead && font->FontType != ft_user_defined && font->FontType != ft_CID_user_defined
532
3.33M
            && font->FontType != ft_PCL_user_defined && font->FontType != ft_GL2_531 && font->FontType != ft_PDF_user_defined
533
3.31M
            && font->FontType != ft_GL2_stick_user_defined) {
534
3.31M
            if (pgs->text_rendering_mode != 3 && pgs->text_rendering_mode != 7) {
535
3.31M
                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
3.31M
                } else {
549
3.31M
                    if (pgs->text_rendering_mode == 0 || pgs->text_rendering_mode == 2 ||
550
3.31M
                        pgs->text_rendering_mode == 4 || pgs->text_rendering_mode == 6) {
551
3.31M
                        code = gx_set_dev_color(pgs);
552
3.31M
                        if (code != 0)
553
0
                            return code;
554
3.31M
                        code = pdf_set_drawing_color(pdev, pgs, pgs->color[0].dev_color, &pdev->saved_fill_color,
555
3.31M
                                     &pdev->fill_used_process_color,
556
3.31M
                                     &psdf_set_fill_color_commands);
557
3.31M
                        if (code < 0)
558
1.24k
                            return code;
559
3.31M
                    }
560
3.31M
                    if (pgs->text_rendering_mode == 1 || pgs->text_rendering_mode == 2 ||
561
3.31M
                        pgs->text_rendering_mode == 5 || pgs->text_rendering_mode == 6) {
562
1.12k
                        gs_swapcolors_quick(pgs);
563
1.12k
                        code = gx_set_dev_color(pgs);
564
1.12k
                        if (code != 0)
565
0
                            return code;
566
1.12k
                        code = pdf_set_drawing_color(pdev, pgs, pgs->color[0].dev_color, &pdev->saved_stroke_color,
567
1.12k
                                     &pdev->stroke_used_process_color,
568
1.12k
                                     &psdf_set_stroke_color_commands);
569
1.12k
                        if (code < 0)
570
0
                            return code;
571
572
1.12k
                        gs_swapcolors_quick(pgs);
573
1.12k
                    }
574
3.31M
                }
575
3.31M
            }
576
3.38M
        } else {
577
3.38M
            code = gx_set_dev_color(pgs);
578
3.38M
            if (code != 0)
579
0
                return code;
580
581
3.38M
            if ((code =
582
3.38M
                 pdf_set_drawing_color(pdev, pgs, pgs->color[0].dev_color, &pdev->saved_stroke_color,
583
3.38M
                                       &pdev->stroke_used_process_color,
584
3.38M
                                       &psdf_set_stroke_color_commands)) < 0 ||
585
3.38M
                (code =
586
3.38M
                 pdf_set_drawing_color(pdev, pgs, pgs->color[0].dev_color, &pdev->saved_fill_color,
587
3.38M
                                       &pdev->fill_used_process_color,
588
3.38M
                                       &psdf_set_fill_color_commands)) < 0
589
3.38M
                )
590
218
                return code;
591
3.38M
        }
592
6.70M
    }
593
6.74M
    return 0;
594
6.74M
}
595
596
static bool
597
outline_list_includes(const gs_param_string_array *psa, const byte *chars,
598
                    uint size)
599
6.75M
{
600
6.75M
    uint i;
601
602
6.75M
    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.75M
    return false;
606
6.75M
}
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.75M
{
614
6.75M
    gx_device_pdf *const pdev = (gx_device_pdf *)dev;
615
6.75M
    gx_path *path0 = pgs->path;
616
6.75M
    gx_path *path = ((text->operation & TEXT_DO_NONE) &&
617
6.75M
                    !(text->operation & TEXT_RETURN_WIDTH) ? NULL : path0);
618
6.75M
    pdf_text_enum_t *penum;
619
6.75M
    int code, user_defined = 0;
620
6.75M
    gs_memory_t * mem = pgs->memory;
621
6.75M
    byte *chars_ptr = font->font_name.chars;
622
6.75M
    uint size = font->font_name.size;
623
624
11.0M
    while (pdf_has_subset_prefix(chars_ptr, size)) {
625
        /* Strip off an existing subset prefix. */
626
4.33M
        chars_ptr += SUBSET_PREFIX_SIZE;
627
4.33M
        size -= SUBSET_PREFIX_SIZE;
628
4.33M
    }
629
630
    /* should we "flatten" the font to "normal" marking operations */
631
6.75M
    if (outline_list_includes(&pdev->params.AlwaysOutline, (const byte *)chars_ptr, size) ||
632
6.75M
        (pdev->FlattenFonts && !outline_list_includes(&pdev->params.NeverOutline, (const byte *)chars_ptr, size))
633
6.75M
        ) {
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.75M
    pdev->last_charpath_op = 0;
640
6.75M
    if ((text->operation & TEXT_DO_ANY_CHARPATH) && !path0->first_subpath) {
641
1.92k
        if (pdf_compare_text_state_for_charpath(pdev->text->text_state, pdev, pgs, font, text))
642
12
            pdev->last_charpath_op = text->operation & TEXT_DO_ANY_CHARPATH;
643
1.92k
    }
644
645
6.75M
    if(font->FontType == ft_user_defined ||
646
6.75M
       font->FontType == ft_PDF_user_defined ||
647
6.72M
       font->FontType == ft_PCL_user_defined ||
648
6.72M
       font->FontType == ft_MicroType ||
649
6.72M
       font->FontType == ft_GL2_stick_user_defined ||
650
6.72M
       font->FontType == ft_GL2_531)
651
28.1k
        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.75M
    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.75M
    if (!user_defined || !(text->operation & TEXT_DO_ANY_CHARPATH)) {
696
6.75M
        if (user_defined &&
697
27.9k
            (text->operation & TEXT_DO_NONE) && (text->operation & TEXT_RETURN_WIDTH)
698
39
            && 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
36
            code = gx_hld_stringwidth_begin(pgs, &path);
705
36
            if (code < 0)
706
0
                return code;
707
6.75M
        } else if ((!(text->operation & TEXT_DO_DRAW) && pgs->text_rendering_mode != 3)
708
6.75M
                    || path == 0 || !path_position_valid(path)
709
6.75M
                    || pdev->type3charpath)
710
2.84k
            return gx_default_text_begin(dev, pgs, text, font,
711
2.84k
                                         pcpath, ppte);
712
6.75M
        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.75M
    }
716
717
6.75M
    if (!pdev->ForOPDFRead) {
718
3.35M
    code = pdf_prepare_text_color(pdev, pgs, text, font);
719
3.35M
    if (code != 0)
720
0
        return code;
721
3.35M
    }
722
723
    /* Allocate and initialize the enumerator. */
724
725
6.75M
    rc_alloc_struct_1(penum, pdf_text_enum_t, &st_pdf_text_enum, mem,
726
6.75M
                      return_error(gs_error_VMerror), "gdev_pdf_text_begin");
727
6.75M
    penum->rc.free = rc_free_text_enum;
728
6.75M
    penum->pte_default = 0;
729
6.75M
    penum->charproc_accum = false;
730
6.75M
    pdev->accumulating_charproc = false;
731
6.75M
    penum->cdevproc_callout = false;
732
6.75M
    penum->text_clipped = false;
733
6.75M
    penum->returned.total_width.x = penum->returned.total_width.y = 0;
734
6.75M
    penum->cgp = NULL;
735
6.75M
    penum->returned.current_glyph = GS_NO_GLYPH;
736
6.75M
    penum->output_char_code = GS_NO_CHAR;
737
6.75M
    code = gs_text_enum_init((gs_text_enum_t *)penum, &pdf_text_procs,
738
6.75M
                             dev, pgs, text, font, pcpath, mem);
739
6.75M
    penum->k_text_release = 1; /* early release of black_textvec_state */
740
741
6.75M
    if (code < 0) {
742
0
        gs_free_object(mem, penum, "gdev_pdf_text_begin");
743
0
        return code;
744
0
    }
745
6.75M
    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.64k
        penum->device_disabled_grid_fitting = true;
758
2.64k
    }
759
760
6.75M
    *ppte = (gs_text_enum_t *)penum;
761
762
6.75M
    return 0;
763
6.75M
}
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.7M
{
776
39.7M
    return font->id;
777
39.7M
}
778
779
pdf_font_cache_elem_t **
780
pdf_locate_font_cache_elem(gx_device_pdf *pdev, gs_font *font)
781
39.6M
{
782
39.6M
    pdf_font_cache_elem_t **e = &pdev->font_cache;
783
39.6M
    pdf_font_cache_elem_t *prev = NULL;
784
39.6M
    int64_t id = pdf_font_cache_elem_id(font);
785
786
102M
    for (; *e != 0; e = &(*e)->next) {
787
100M
        if ((*e)->font_id == id) {
788
37.7M
            if (prev != NULL) {
789
148k
                pdf_font_cache_elem_t *curr = *e;
790
791
                /* move the curr font to head of list (Most Recently Used) */
792
148k
                prev->next = curr->next;
793
148k
                curr->next = pdev->font_cache;
794
148k
                pdev->font_cache = curr;
795
148k
            }
796
37.7M
            return &(pdev->font_cache);
797
37.7M
        }
798
63.1M
        prev = *e;
799
63.1M
    }
800
1.90M
    return 0;
801
39.6M
}
802
803
static void
804
pdf_remove_font_cache_elem(gx_device_pdf *pdev, pdf_font_cache_elem_t *e0)
805
181k
{
806
181k
    pdf_font_cache_elem_t **e = &pdev->font_cache;
807
808
181k
    for (; *e != 0; e = &(*e)->next)
809
181k
        if (*e == e0) {
810
181k
            *e = e0->next;
811
181k
            gs_free_object(pdev->pdf_memory, e0->glyph_usage,
812
181k
                                "pdf_remove_font_cache_elem");
813
181k
            gs_free_object(pdev->pdf_memory, e0->real_widths,
814
181k
                                "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
181k
            e0->next = 0;
824
181k
            e0->glyph_usage = 0;
825
181k
            e0->real_widths = 0;
826
181k
            gs_free_object(pdev->pdf_memory, e0,
827
181k
                                "pdf_remove_font_cache_elem");
828
181k
            return;
829
181k
        }
830
181k
}
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
367k
{
836
367k
    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
346k
    case ft_encrypted:
842
349k
    case ft_encrypted2:
843
350k
    case ft_user_defined:
844
351k
    case ft_PDF_user_defined:
845
351k
    case ft_GL2_stick_user_defined:
846
351k
    case ft_PCL_user_defined:
847
351k
    case ft_MicroType:
848
351k
    case ft_GL2_531:
849
351k
    case ft_disk_based:
850
351k
    case ft_Chameleon:
851
364k
    case ft_TrueType:
852
364k
        *num_widths = *num_chars = 256; /* Assuming access to glyph_usage by character codes */
853
364k
        break;
854
582
    case ft_CID_encrypted:
855
582
        *num_widths = *num_chars = ((gs_font_cid0 *)font)->cidata.common.MaxCID + 1;
856
582
        break;
857
2.91k
    case ft_CID_TrueType:
858
2.91k
        *num_widths = *num_chars = ((gs_font_cid2 *)font)->cidata.common.CIDCount;
859
2.91k
        break;
860
0
    default:
861
0
        *num_widths = *num_chars = 65536; /* No chance to determine, use max. */
862
367k
    }
863
367k
}
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
181k
{
869
181k
    int num_widths, num_chars, len;
870
871
181k
    font_cache_elem_array_sizes(pdev, font, &num_widths, &num_chars);
872
181k
    len = (num_chars + 7) / 8;
873
181k
    if (e->glyph_usage != NULL)
874
0
        gs_free_object(pdev->pdf_memory, e->glyph_usage,
875
181k
                            "pdf_attach_font_resource, reallocating");
876
181k
    if (e->real_widths != NULL)
877
0
        gs_free_object(pdev->pdf_memory, e->real_widths,
878
181k
                            "alloc_font_cache_elem_arrays, reallocating");
879
880
181k
    e->glyph_usage = gs_alloc_bytes(pdev->pdf_memory,
881
181k
                        len, "alloc_font_cache_elem_arrays");
882
883
181k
    e->real_widths = (num_widths > 0 ? (double *)gs_alloc_bytes(pdev->pdf_memory,
884
181k
                        num_widths * sizeof(*e->real_widths) *
885
181k
                            ((font->FontType == ft_user_defined ||
886
181k
                            font->FontType == ft_PDF_user_defined ||
887
181k
                            font->FontType == ft_GL2_stick_user_defined ||
888
181k
                            font->FontType == ft_PCL_user_defined ||
889
181k
                            font->FontType == ft_MicroType ||
890
181k
                            font->FontType == ft_GL2_531) ? 2 : 1),
891
181k
                        "alloc_font_cache_elem_arrays") : NULL);
892
181k
    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
181k
    e->num_chars = num_chars;
903
181k
    e->num_widths = num_widths;
904
181k
    memset(e->glyph_usage, 0, len);
905
181k
    if (e->real_widths != NULL)
906
181k
        memset(e->real_widths, 0, num_widths * sizeof(*e->real_widths));
907
181k
    return 0;
908
181k
}
909
910
int
911
pdf_free_font_cache(gx_device_pdf *pdev)
912
39.3k
{
913
39.3k
    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
220k
    while (e != NULL) {
921
181k
        next = e->next;
922
181k
        pdf_remove_font_cache_elem(pdev, e);
923
181k
        e = next;
924
181k
    }
925
39.3k
    pdev->font_cache = NULL;
926
39.3k
    return 0;
927
39.3k
}
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
39.4M
{
938
39.4M
    pdf_font_cache_elem_t **e = pdf_locate_font_cache_elem(pdev, font);
939
940
39.4M
    if (e != NULL && (((*e)->glyph_usage == NULL && glyph_usage !=NULL) ||
941
37.5M
                      ((*e)->real_widths == NULL && real_widths !=NULL))) {
942
181k
        int code = alloc_font_cache_elem_arrays(pdev, *e, font);
943
944
181k
        if (code < 0)
945
0
            return code;
946
181k
    }
947
39.4M
    *pdfont = (e == NULL ? NULL : (*e)->pdfont);
948
39.4M
    if (glyph_usage != NULL)
949
35.6M
        *glyph_usage = (e == NULL ? NULL : (*e)->glyph_usage);
950
39.4M
    if (real_widths != NULL)
951
35.6M
        *real_widths = (e == NULL ? NULL : (*e)->real_widths);
952
39.4M
    if (num_chars != NULL)
953
35.6M
        *num_chars = (e == NULL ? 0 : (*e)->num_chars);
954
39.4M
    if (num_widths != NULL)
955
35.6M
        *num_widths = (e == NULL ? 0 : (*e)->num_widths);
956
39.4M
    return 0;
957
39.4M
}
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
186k
{
966
186k
    int num_chars, num_widths, len;
967
186k
    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
186k
    if (pdfont->FontType != font->FontType &&
974
765
        (pdfont->FontType != ft_user_defined ||
975
765
        (font->FontType != ft_PCL_user_defined &&
976
765
        font->FontType != ft_PDF_user_defined &&
977
0
        font->FontType != ft_MicroType &&
978
0
        font->FontType != ft_GL2_stick_user_defined &&
979
0
        font->FontType != ft_GL2_531)))
980
0
        return_error(gs_error_unregistered); /* Must not happen. */
981
186k
    font_cache_elem_array_sizes(pdev, font, &num_widths, &num_chars);
982
186k
    len = (num_chars + 7) / 8;
983
186k
    if (pe != NULL) {
984
5.31k
        e = *pe;
985
5.31k
        if (e->pdfont == pdfont)
986
1.26k
            return 0;
987
4.04k
        e->pdfont = pdfont;
988
        /* Reset glyph cache because e->pdfont had changed. */
989
4.04k
        memset(e->glyph_usage, 0, len);
990
4.04k
        memset(e->real_widths, 0, num_widths * sizeof(*e->real_widths));
991
181k
    } else {
992
181k
        e = (pdf_font_cache_elem_t *)gs_alloc_struct(pdev->pdf_memory,
993
181k
                pdf_font_cache_elem_t, &st_pdf_font_cache_elem,
994
181k
                            "pdf_attach_font_resource");
995
181k
        if (e == NULL)
996
0
            return_error(gs_error_VMerror);
997
181k
        e->pdfont = pdfont;
998
181k
        e->font_id = pdf_font_cache_elem_id(font);
999
181k
        e->num_chars = 0;
1000
181k
        e->glyph_usage = NULL;
1001
181k
        e->real_widths = NULL;
1002
181k
        e->next = pdev->font_cache;
1003
181k
        pdev->font_cache = e;
1004
181k
        return 0;
1005
181k
    }
1006
4.04k
    return 0;
1007
186k
}
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.72M
{
1019
5.72M
    switch (font->FontType) {
1020
0
    case ft_composite:                /* subfonts have their own FontMatrix */
1021
270k
    case ft_TrueType:
1022
2.08M
    case ft_CID_TrueType:
1023
        /* The TrueType FontMatrix is 1 unit per em, which is what we want. */
1024
2.08M
        gs_make_identity(pmat);
1025
2.08M
        return 0;
1026
3.49M
    case ft_encrypted:
1027
3.59M
    case ft_encrypted2:
1028
3.63M
    case ft_CID_encrypted:
1029
3.63M
    case ft_user_defined:
1030
3.63M
    case ft_PCL_user_defined:
1031
3.63M
    case ft_PDF_user_defined:
1032
3.63M
    case ft_MicroType:
1033
3.63M
    case ft_GL2_stick_user_defined:
1034
3.63M
    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.63M
        {
1066
3.63M
            const gs_font *base_font = font;
1067
1068
3.67M
            while (base_font->base != base_font)
1069
42.1k
                base_font = base_font->base;
1070
3.63M
            if (font->FontType == ft_user_defined ||
1071
3.63M
                font->FontType == ft_PDF_user_defined ||
1072
3.63M
                font->FontType == ft_PCL_user_defined ||
1073
3.63M
                font->FontType == ft_MicroType ||
1074
3.63M
                font->FontType == ft_GL2_stick_user_defined ||
1075
3.63M
                font->FontType == ft_GL2_531)
1076
0
                *pmat = base_font->FontMatrix;
1077
3.63M
            else if (base_font->orig_FontMatrix.xx != 0 || base_font->orig_FontMatrix.xy != 0 ||
1078
0
                base_font->orig_FontMatrix.yx != 0 || base_font->orig_FontMatrix.yy != 0)
1079
3.63M
                *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.63M
        }
1094
3.63M
        return 0;
1095
0
    default:
1096
0
        return_error(gs_error_rangecheck);
1097
5.72M
    }
1098
5.72M
}
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.55M
{
1108
5.55M
    int code = pdf_font_orig_matrix(font, pmat);
1109
5.55M
    if (code >= 0) {
1110
5.55M
        if (font->FontType == ft_CID_encrypted) {
1111
39.0k
            int fidx;
1112
1113
39.0k
            if (cid < GS_MIN_CID_GLYPH)
1114
0
                cid = GS_MIN_CID_GLYPH;
1115
39.0k
            code = ((gs_font_cid0 *)font)->cidata.glyph_data((gs_font_base *)font,
1116
39.0k
                                cid, NULL, &fidx);
1117
39.0k
            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
39.0k
            if (code >= 0) {
1122
39.0k
                gs_matrix_multiply(&(gs_cid0_indexed_font(font, fidx)->FontMatrix),
1123
39.0k
                                pmat, pmat);
1124
39.0k
            }
1125
39.0k
        }
1126
5.55M
    }
1127
5.55M
    return code;
1128
5.55M
}
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.85M
{
1137
6.85M
    int i;
1138
1139
36.0M
    for (i = 0; i < num_chars; ++i) {
1140
29.2M
        gs_char ch = pairs[i].chr;
1141
29.2M
        pdf_encoding_element_t *pet = &pdfont->u.simple.Encoding[ch];
1142
1143
29.2M
        if (pairs[i].glyph == pet->glyph)
1144
23.5M
            continue;
1145
5.69M
        if (pet->glyph != GS_NO_GLYPH) /* encoding conflict */
1146
4.13k
            return false;
1147
5.69M
    }
1148
6.84M
    return true;
1149
6.85M
}
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.85M
{
1182
    /*
1183
     * This crude version of the code ignores
1184
     * the possibility of re-encoding characters.
1185
     */
1186
6.85M
    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
169k
    case ft_user_defined:
1209
169k
    case ft_PDF_user_defined:
1210
169k
    case ft_PCL_user_defined:
1211
169k
    case ft_MicroType:
1212
169k
    case ft_GL2_stick_user_defined:
1213
169k
    case ft_GL2_531:
1214
169k
        if (pdfont->u.simple.Encoding == NULL)
1215
0
            return false; /* Not sure. Happens with 020-01.ps . */
1216
        /* fall through */
1217
5.13M
    case ft_encrypted:
1218
5.46M
    case ft_encrypted2:
1219
6.85M
    case ft_TrueType:
1220
6.85M
        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.85M
    }
1233
6.85M
}
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
999k
{
1279
999k
    pdf_resource_t **pchain = pdev->resources[type].chains;
1280
999k
    pdf_resource_t *pres;
1281
999k
    int i;
1282
1283
15.9M
    for (i = 0; i < NUM_RESOURCE_CHAINS; i++) {
1284
19.9M
        for (pres = pchain[i]; pres != 0; pres = pres->next) {
1285
5.00M
            pdf_font_resource_t *pdfont = (pdf_font_resource_t *)pres;
1286
5.00M
            const gs_font_base *cfont;
1287
5.00M
            gs_font *ofont = font;
1288
5.00M
            int code;
1289
1290
5.00M
            cfont = (gs_font_base *)font;
1291
5.00M
            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.88M
                        if (pdfont->XUID_Vals[XUIDi] != xvalues[XUIDi])
1300
3.77M
                            break;
1301
4.30M
                    if (XUIDi < size)
1302
3.77M
                        continue;
1303
4.30M
                }
1304
4.30M
            }
1305
1306
1.22M
            if (font->FontType != pdfont->FontType)
1307
90.8k
                continue;
1308
1.13M
            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.13M
                cfont = pdf_font_resource_font(pdfont, false);
1317
1.13M
            if (!pdf_is_CID_font(ofont) &&
1318
1.12M
                (compatible_encoding
1319
1.12M
                    ? !pdf_is_compatible_encoding(pdev, pdfont, font, cgp->s, cgp->num_all_chars)
1320
1.12M
                    : !pdf_font_has_glyphs(pdev, pdfont, font, cgp->s, cgp->num_all_chars)))
1321
4.08k
                continue;
1322
1.13M
            if (cfont == 0)
1323
3
                continue;
1324
1.13M
            code = gs_copied_can_copy_glyphs((const gs_font *)cfont, ofont,
1325
1.13M
                            &cgp->s[cgp->unused_offset].glyph, cgp->num_unused_chars,
1326
1.13M
                            sizeof(pdf_char_glyph_pair_t), true);
1327
1.13M
            if (code == gs_error_unregistered) /* Debug purpose only. */
1328
0
                return code;
1329
1.13M
            if(code > 0) {
1330
141k
                *ppdfont = pdfont;
1331
141k
                return 1;
1332
141k
            }
1333
1.13M
        }
1334
15.1M
    }
1335
858k
    return 0;
1336
999k
}
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
689k
{
1400
689k
    int code = 0;
1401
1402
689k
    code = pdf_attached_font_resource(pdev, subfont, ppdsubf, NULL, NULL, NULL, NULL);
1403
689k
    if (code < 0)
1404
0
        return code;
1405
689k
    if (*ppdsubf != NULL) {
1406
423k
        const gs_font_base *cfont = pdf_font_resource_font(*ppdsubf, false);
1407
1408
423k
        code = gs_copied_can_copy_glyphs((const gs_font *)cfont, subfont,
1409
423k
                        &cgp->s[cgp->unused_offset].glyph, cgp->num_unused_chars,
1410
423k
                        sizeof(pdf_char_glyph_pair_t), true);
1411
423k
        if (code > 0)
1412
423k
            return 0;
1413
338
        if (code < 0)
1414
140
            return code;
1415
198
        *ppdsubf = NULL;
1416
198
    }
1417
265k
    code = pdf_find_font_resource(pdev, subfont,
1418
265k
                                  resourceCIDFont, ppdsubf, cgp, true);
1419
265k
    if (code < 0)
1420
0
        return code;
1421
265k
    if (*ppdsubf == NULL) {
1422
265k
        code = pdf_make_font_resource(pdev, subfont, ppdsubf, cgp);
1423
265k
        if (code < 0)
1424
264k
            return code;
1425
265k
    }
1426
1.84k
    return pdf_attach_font_resource(pdev, subfont, *ppdsubf);
1427
265k
}
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
38.1k
{
1435
38.1k
    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
18.1k
        switch (index) {
1442
1443
2.20k
            case ENCODING_INDEX_STANDARD: return index;
1444
4.79k
            case ENCODING_INDEX_MACROMAN: return index;
1445
245
            case ENCODING_INDEX_ISOLATIN1: return index;
1446
10.9k
            default:
1447
10.9k
                return ENCODING_INDEX_STANDARD;
1448
18.1k
        }
1449
18.1k
    }
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
20.0k
    switch (index) {
1455
4.61k
    case ENCODING_INDEX_WINANSI:
1456
5.68k
    case ENCODING_INDEX_MACROMAN:
1457
5.68k
    case ENCODING_INDEX_MACEXPERT:
1458
5.68k
        return index;
1459
3.02k
    case ENCODING_INDEX_STANDARD:
1460
3.02k
        if (is_standard)
1461
1.08k
            return index;
1462
        /* Falls through. */
1463
13.2k
    default:
1464
13.2k
        return ENCODING_INDEX_WINANSI;
1465
20.0k
    }
1466
20.0k
}
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.15k
{
1475
1.15k
    const gs_font_base *bfont = (const gs_font_base *)font;
1476
1.15k
    pdf_font_resource_t *pdfont;
1477
1.15k
    byte *cached;
1478
1.15k
    int code;
1479
1480
1.15k
    cached = gs_alloc_bytes(pdev->pdf_memory, 256/8, "pdf_make_font3_resource");
1481
1.15k
    if (cached == NULL)
1482
0
        return_error(gs_error_VMerror);
1483
1.15k
    code = font_resource_encoded_alloc(pdev, &pdfont, bfont->id,
1484
1.15k
                    ft_user_defined, pdf_write_contents_bitmap);
1485
1.15k
    if (code < 0) {
1486
0
        gs_free_object(pdev->pdf_memory, cached, "pdf_make_font3_resource");
1487
0
        return code;
1488
0
    }
1489
1.15k
    memset(cached, 0, 256 / 8);
1490
1.15k
    pdfont->mark_glyph = font->dir->ccache.mark_glyph; /* For pdf_font_resource_enum_ptrs. */
1491
1.15k
    pdfont->u.simple.s.type3.bitmap_font = false;
1492
1.15k
    pdfont->u.simple.BaseEncoding = pdf_refine_encoding_index(pdev,
1493
1.15k
                        bfont->nearest_encoding_index, true);
1494
1.15k
    pdfont->u.simple.s.type3.char_procs = NULL;
1495
1.15k
    pdfont->u.simple.s.type3.cached = cached;
1496
1.15k
    if ((pdfont->FontType == ft_user_defined  || pdfont->FontType == ft_PDF_user_defined) && bfont->FontBBox.p.x == 0.0 &&
1497
721
        bfont->FontBBox.p.y == 0.00 && bfont->FontBBox.q.x == 0.00 &&
1498
466
        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
466
        pdfont->u.simple.s.type3.FontBBox.p.x = 0;
1507
466
        pdfont->u.simple.s.type3.FontBBox.p.y = 0;
1508
466
        pdfont->u.simple.s.type3.FontBBox.q.x = 1;
1509
466
        pdfont->u.simple.s.type3.FontBBox.q.y = -1;
1510
691
    } else {
1511
691
        pdfont->u.simple.s.type3.FontBBox.p.x = bfont->FontBBox.p.x;
1512
691
        pdfont->u.simple.s.type3.FontBBox.p.y = bfont->FontBBox.p.y;
1513
691
        pdfont->u.simple.s.type3.FontBBox.q.x = bfont->FontBBox.q.x;
1514
691
        pdfont->u.simple.s.type3.FontBBox.q.y = bfont->FontBBox.q.y;
1515
691
    }
1516
1.15k
    pdfont->u.simple.s.type3.FontMatrix = bfont->FontMatrix;
1517
1.15k
    pdfont->u.simple.s.type3.Resources = cos_dict_alloc(pdev, "pdf_make_font3_resource");
1518
1.15k
    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.15k
    if (pdfont->u.simple.s.type3.FontMatrix.xx != 0.0 ||
1523
0
        pdfont->u.simple.s.type3.FontMatrix.xy != 0.0 ||
1524
0
        pdfont->u.simple.s.type3.FontMatrix.yx != 0.0 ||
1525
1.15k
        pdfont->u.simple.s.type3.FontMatrix.yy != 0.0) {
1526
1.15k
        while (any_abs(pdfont->u.simple.s.type3.FontMatrix.xx) < 0.001 &&
1527
0
               any_abs(pdfont->u.simple.s.type3.FontMatrix.xy) < 0.001 &&
1528
0
               any_abs(pdfont->u.simple.s.type3.FontMatrix.yx) < 0.001 &&
1529
0
               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.15k
    }
1536
1.15k
    *ppdfont = pdfont;
1537
1.15k
    return 0;
1538
1.15k
}
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
858k
{
1551
858k
    int index = -1;
1552
858k
    font_type orig_type = ft_undefined;
1553
858k
    int BaseEncoding = ENCODING_INDEX_UNKNOWN;
1554
858k
    pdf_font_embed_t embed;
1555
858k
    pdf_font_descriptor_t *pfd = 0;
1556
858k
    int (*font_alloc)(gx_device_pdf *, pdf_font_resource_t **,
1557
858k
                      gs_id, pdf_font_descriptor_t *);
1558
858k
    gs_font *base_font = font; /* A roudiment from old code. Keep it for a while. */
1559
858k
    pdf_font_resource_t *pdfont;
1560
858k
    pdf_standard_font_t *const psfa =
1561
858k
        pdev->text->outline_fonts->standard_fonts;
1562
858k
    int code = 0;
1563
858k
    long XUID[3] = {0,0,0};
1564
858k
    int XUIDi = 0;
1565
858k
    gs_font_base *bfont = (gs_font_base *)font;
1566
1567
858k
    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
858k
    if (pdev->ForOPDFRead && !pdev->HaveCIDSystem) {
1577
815k
        switch(font->FontType) {
1578
4.14k
            case ft_CID_encrypted:
1579
261k
            case ft_CID_TrueType:
1580
261k
                return_error(gs_error_undefined);
1581
553k
            default:
1582
553k
                break;
1583
815k
        }
1584
815k
    }
1585
596k
    if (!pdev->HaveCFF) {
1586
553k
        if (font->FontType == ft_encrypted2)
1587
524k
            return_error(gs_error_undefined);
1588
553k
    }
1589
71.8k
    embed = pdf_font_embed_status(pdev, base_font, &index, cgp->s, cgp->num_all_chars, &orig_type);
1590
71.8k
    if (pdev->CompatibilityLevel < 1.3)
1591
29.1k
        if (embed != FONT_EMBED_NO && font->FontType == ft_CID_TrueType)
1592
0
            return_error(gs_error_rangecheck);
1593
71.8k
    if (embed == FONT_EMBED_STANDARD && pdev->CompatibilityLevel < 2.0) {
1594
4.90k
        pdf_standard_font_t *psf = &psfa[index];
1595
1596
4.90k
        if (psf->pdfont == NULL ||
1597
15
                !pdf_is_compatible_encoding(pdev, psf->pdfont, font,
1598
4.90k
                        cgp->s, cgp->num_all_chars)) {
1599
4.90k
            code = pdf_font_std_alloc(pdev, ppdfont, (psf->pdfont == NULL), base_font->id,
1600
4.90k
                                      (gs_font_base *)base_font, index);
1601
4.90k
            if (code < 0)
1602
0
                return code;
1603
4.90k
            if (psf->pdfont == NULL)
1604
0
                psf->pdfont = *ppdfont;
1605
4.90k
            (*ppdfont)->u.simple.BaseEncoding = pdf_refine_encoding_index(pdev,
1606
4.90k
                ((const gs_font_base *)base_font)->nearest_encoding_index, true);
1607
4.90k
            code = 1;
1608
4.90k
        } else
1609
0
            *ppdfont = psf->pdfont;
1610
4.90k
        return code;
1611
4.90k
    }
1612
1613
66.9k
    if (uid_is_XUID(&bfont->UID)){
1614
41.9k
        int size = uid_XUID_size(&bfont->UID);
1615
41.9k
        long *xvalues = uid_XUID_values(&bfont->UID);
1616
41.9k
        if (xvalues && size >= 3 && xvalues[0] == 1000000) {
1617
167k
            for (XUIDi = 0;XUIDi < 3; XUIDi++)
1618
125k
                XUID[XUIDi] = xvalues[XUIDi];
1619
41.9k
        }
1620
41.9k
    }
1621
1622
66.9k
    switch (font->FontType) {
1623
291
    case ft_CID_encrypted:
1624
3.98k
    case ft_CID_TrueType:
1625
3.98k
        font_alloc = pdf_font_cidfont_alloc;
1626
3.98k
        break;
1627
26.2k
    case ft_encrypted:
1628
27.4k
    case ft_encrypted2:
1629
61.8k
    case ft_TrueType:
1630
61.8k
        font_alloc = pdf_font_simple_alloc;
1631
61.8k
        break;
1632
392
    case ft_user_defined:
1633
1.12k
    case ft_PDF_user_defined:
1634
1.12k
    case ft_PCL_user_defined:
1635
1.12k
    case ft_MicroType:
1636
1.12k
    case ft_GL2_stick_user_defined:
1637
1.12k
    case ft_GL2_531:
1638
1.12k
        code = pdf_make_font3_resource(pdev, font, ppdfont);
1639
1.12k
        if (code < 0)
1640
0
            return code;
1641
4.50k
        for (XUIDi = 0;XUIDi < 3; XUIDi++)
1642
3.37k
            (*ppdfont)->XUID_Vals[XUIDi] = XUID[XUIDi];
1643
1.12k
        return 1;
1644
0
    default:
1645
0
        return_error(gs_error_invalidfont);
1646
66.9k
    }
1647
1648
    /* Create an appropriate font resource and descriptor. */
1649
65.8k
    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
65.4k
        if (font->FontType == ft_TrueType &&
1658
34.0k
            pdev->CompatibilityLevel <= 1.2 && !pdev->ForOPDFRead
1659
65.4k
            ) {
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
65.4k
    }
1677
65.8k
    if ((code = pdf_font_descriptor_alloc(pdev, &pfd,
1678
65.8k
                                          (gs_font_base *)base_font,
1679
65.8k
                                          embed == FONT_EMBED_YES)) < 0 ||
1680
37.4k
        (code = font_alloc(pdev, &pdfont, base_font->id, pfd)) < 0
1681
65.8k
        )
1682
28.4k
        return code;
1683
1684
149k
    for (XUIDi = 0;XUIDi < 3; XUIDi++)
1685
112k
        pdfont->XUID_Vals[XUIDi] = XUID[XUIDi];
1686
1687
37.4k
    pdf_do_subset_font(pdev, pfd->base_font, -1);
1688
37.4k
    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
37.4k
    if ((font->FontType == ft_TrueType && pdev->ForOPDFRead)) {
1700
4.65k
        if (pfd->base_font->do_subset == DO_SUBSET_YES)
1701
4.65k
            BaseEncoding = pdf_refine_encoding_index(pdev,
1702
4.65k
                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.65k
    }
1707
37.4k
    if (font->FontType == ft_encrypted || font->FontType == ft_encrypted2
1708
27.4k
        || (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
27.4k
        BaseEncoding = pdf_refine_encoding_index(pdev,
1737
27.4k
            ((const gs_font_base *)base_font)->nearest_encoding_index, false);
1738
27.4k
    }
1739
37.4k
    if (!pdf_is_CID_font(font)) {
1740
35.5k
        pdfont->u.simple.BaseEncoding = BaseEncoding;
1741
35.5k
        pdfont->mark_glyph = font->dir->ccache.mark_glyph;
1742
35.5k
    }
1743
1744
37.4k
    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
37.4k
    if (embed == FONT_EMBED_NO && orig_type != ft_undefined) {
1772
0
        pfd->FontType = orig_type;
1773
0
    }
1774
37.4k
    *ppdfont = pdfont;
1775
37.4k
    return 1;
1776
37.4k
}
1777
1778
/*
1779
 * Check for simple font.
1780
 */
1781
bool
1782
pdf_is_simple_font(gs_font *font)
1783
12.2M
{
1784
12.2M
    return (font->FontType == ft_encrypted ||
1785
3.17M
            font->FontType == ft_encrypted2 ||
1786
1.98M
            font->FontType == ft_TrueType ||
1787
198k
            font->FontType == ft_user_defined ||
1788
74.3k
            font->FontType == ft_PDF_user_defined ||
1789
0
            font->FontType == ft_PCL_user_defined ||
1790
0
            font->FontType == ft_MicroType ||
1791
0
            font->FontType == ft_GL2_stick_user_defined ||
1792
0
            font->FontType == ft_GL2_531);
1793
12.2M
}
1794
1795
/*
1796
 * Check for CID font.
1797
 */
1798
bool
1799
pdf_is_CID_font(gs_font *font)
1800
2.36M
{
1801
2.36M
    return (font->FontType == ft_CID_encrypted ||
1802
2.35M
            font->FontType == ft_CID_TrueType);
1803
2.36M
}
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
160M
{
1813
160M
    int code = font->procs.next_char_glyph(penum, char_code, glyph);
1814
1815
160M
    if (code == 2)                /* end of string */
1816
12.2M
        return code;
1817
148M
    if (code < 0)
1818
0
        return code;
1819
148M
    if (font_is_simple) {
1820
148M
        *cid = *char_code;
1821
148M
        *glyph = font->procs.encode_char(font, *char_code, GLYPH_SPACE_NAME);
1822
148M
        if (*glyph == GS_NO_GLYPH)
1823
2.53k
            return 3;
1824
148M
    } 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
148M
    return 0;
1830
148M
}
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
24.5M
{
1837
24.5M
    int j;
1838
1839
110M
    for (j = 0; j < cgp->num_all_chars; j++)
1840
91.7M
        if (cgp->s[j].chr == cid)
1841
5.49M
            break;
1842
24.5M
    if (j < cgp->num_all_chars)
1843
5.49M
        return;
1844
19.0M
    cgp->s[cgp->num_all_chars].glyph = glyph;
1845
19.0M
    cgp->s[cgp->num_all_chars].chr = char_code;
1846
19.0M
    cgp->num_all_chars++;
1847
19.0M
    if (glyph_usage == 0 || !(glyph_usage[cid / 8] & (0x80 >> (cid & 7)))) {
1848
3.42M
        cgp->s[cgp->unused_offset + cgp->num_unused_chars].glyph = glyph;
1849
3.42M
        cgp->s[cgp->unused_offset + cgp->num_unused_chars].chr = char_code;
1850
3.42M
        cgp->num_unused_chars++;
1851
3.42M
    }
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
19.0M
}
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.31M
{
1940
6.31M
    const int go = (pstr != NULL ? pstr->size : penum->text.size);
1941
6.31M
    const size_t struct_size = sizeof(pdf_char_glyph_pairs_t) +
1942
6.31M
                            sizeof(pdf_char_glyph_pair_t) * (2 * go - 1);
1943
6.31M
    pdf_char_glyph_pairs_t *cgp = (pdf_char_glyph_pairs_t *)gs_alloc_bytes(penum->memory,
1944
6.31M
                struct_size, "pdf_alloc_text_glyphs_table");
1945
6.31M
    if (cgp == NULL)
1946
0
        return_error(gs_error_VMerror);
1947
6.31M
    penum->cgp = cgp;
1948
6.31M
    cgp->unused_offset = go;
1949
6.31M
    cgp->num_all_chars = 0;
1950
6.31M
    cgp->num_unused_chars = 0;
1951
6.31M
    return 0;
1952
6.31M
}
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.31M
{
1959
6.31M
    gs_text_enum_t scan = *(gs_text_enum_t *)penum;
1960
6.31M
    gs_font *font = (gs_font *)penum->current_font;
1961
6.31M
    bool font_is_simple = pdf_is_simple_font(font);
1962
6.31M
    pdf_char_glyph_pairs_t *cgp = penum->cgp;
1963
6.31M
    gs_char char_code, cid;
1964
6.31M
    gs_glyph glyph;
1965
6.31M
    int code;
1966
1967
6.31M
    cgp->num_unused_chars = 0;
1968
6.31M
    cgp->num_all_chars = 0;
1969
6.31M
    if (pstr != NULL) {
1970
6.31M
        scan.text.data.bytes = pstr->data;
1971
6.31M
        scan.text.size = pstr->size;
1972
6.31M
        scan.index = 0;
1973
        /* if TEXT_FROM_CHARS the data was converted to bytes earlier */
1974
6.31M
        if ( scan.text.operation & TEXT_FROM_CHARS )
1975
24.7k
            scan.text.operation = ((scan.text.operation & ~TEXT_FROM_CHARS) | TEXT_FROM_STRING);
1976
6.31M
    }
1977
30.8M
    for (;;) {
1978
30.8M
        code = pdf_next_char_glyph(&scan, pstr, font, font_is_simple,
1979
30.8M
                                   &char_code, &cid, &glyph);
1980
30.8M
        if (code == 2)                /* end of string */
1981
6.31M
            break;
1982
24.5M
        if (code == 3)                /* no glyph */
1983
921
            continue;
1984
24.5M
        if (code < 0)
1985
0
            return code;
1986
24.5M
        if (cgp->num_all_chars > cgp->unused_offset)
1987
0
            return_error(gs_error_unregistered); /* Must not happen. */
1988
24.5M
        if (glyph_usage != 0 && cid > char_cache_size)
1989
0
            continue;
1990
24.5M
        store_glyphs(cgp, glyph_usage, char_cache_size,
1991
24.5M
                     char_code, cid, glyph);
1992
24.5M
    }
1993
6.31M
    return 0;
1994
6.31M
}
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.45M
{
2155
6.45M
    int code;
2156
6.45M
    pdf_font_resource_t *pdfont_not_allowed = NULL;
2157
2158
6.45M
    if (*ppdfont != 0) {
2159
5.72M
        gs_font_base *cfont = pdf_font_resource_font(*ppdfont, false);
2160
2161
5.72M
        if (font->FontType != ft_user_defined &&
2162
5.60M
            font->FontType != ft_PDF_user_defined &&
2163
5.55M
            font->FontType != ft_PCL_user_defined &&
2164
5.55M
            font->FontType != ft_MicroType &&
2165
5.55M
            font->FontType != ft_GL2_stick_user_defined &&
2166
5.55M
            font->FontType != ft_GL2_531) {
2167
5.55M
            code = gs_copied_can_copy_glyphs((gs_font *)cfont, font,
2168
5.55M
                        &cgp->s[cgp->unused_offset].glyph, cgp->num_unused_chars,
2169
5.55M
                        sizeof(pdf_char_glyph_pair_t), true);
2170
5.55M
            if (code < 0)
2171
2
                code = 1;
2172
5.55M
        } else
2173
169k
            code = 1;
2174
5.72M
        if (code == 0) {
2175
3.79k
            pdfont_not_allowed = *ppdfont;
2176
3.79k
            *ppdfont = 0;
2177
5.72M
        } else if(!pdf_is_compatible_encoding(pdev, *ppdfont, font,
2178
5.72M
                        cgp->s, cgp->num_all_chars)) {
2179
21
            pdfont_not_allowed = *ppdfont;
2180
21
            *ppdfont = 0;
2181
21
        }
2182
5.72M
    }
2183
6.45M
    if (*ppdfont == 0) {
2184
733k
        gs_font *base_font = font;
2185
733k
        gs_font *below;
2186
733k
        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
735k
        while ((below = base_font->base) != base_font &&
2193
1.26k
               base_font->procs.same_font(base_font, below, FONT_SAME_OUTLINES))
2194
1.26k
            base_font = below;
2195
733k
        if (base_font != font)
2196
1.26k
            same_encoding = ((base_font->procs.same_font(base_font, font,
2197
1.26k
                              FONT_SAME_ENCODING) & FONT_SAME_ENCODING) != 0);
2198
        /* Find or make font resource. */
2199
733k
        code = pdf_attached_font_resource(pdev, base_font, ppdfont, NULL, NULL, NULL, NULL);
2200
733k
        if (code < 0)
2201
0
            return code;
2202
733k
        if (base_font != font) {
2203
1.26k
            if (pdfont_not_allowed == *ppdfont)
2204
1.26k
                *ppdfont = NULL;
2205
1.26k
        }
2206
733k
        if(*ppdfont != NULL && !pdf_is_compatible_encoding(pdev, *ppdfont,
2207
3.81k
                                    base_font, cgp->s, cgp->num_all_chars))
2208
21
                *ppdfont = NULL;
2209
733k
        if (*ppdfont == NULL || *ppdfont == pdfont_not_allowed) {
2210
733k
            pdf_resource_type_t type =
2211
733k
                (pdf_is_CID_font(base_font) ? resourceCIDFont
2212
733k
                                            : resourceFont);
2213
733k
            *ppdfont = NULL;
2214
733k
            code = pdf_find_font_resource(pdev, base_font, type, ppdfont, cgp, true);
2215
733k
            if (code < 0)
2216
0
                return code;
2217
733k
            if (*ppdfont == NULL) {
2218
592k
                code = pdf_make_font_resource(pdev, base_font, ppdfont, cgp);
2219
592k
                if (code < 0)
2220
550k
                    return code;
2221
592k
            }
2222
183k
            if (base_font != font && same_encoding) {
2223
1.26k
                code = pdf_attach_font_resource(pdev, base_font, *ppdfont);
2224
1.26k
                if (code < 0)
2225
0
                    return code;
2226
1.26k
            }
2227
183k
        }
2228
183k
        code = pdf_attach_font_resource(pdev, font, *ppdfont);
2229
183k
        if (code < 0)
2230
0
            return code;
2231
183k
    }
2232
5.90M
    return 0;
2233
6.45M
}
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.90M
{
2240
5.90M
    gs_text_enum_t scan = *penum;
2241
5.90M
    gs_font *font = (gs_font *)penum->current_font;
2242
5.90M
    bool font_is_simple = pdf_is_simple_font(font);
2243
5.90M
    gs_char char_code, cid;
2244
5.90M
    gs_glyph glyph;
2245
2246
5.90M
    if (glyph_usage == NULL)
2247
0
        return 0;
2248
2249
5.90M
    if (pstr != NULL) {
2250
5.90M
        scan.text.data.bytes = pstr->data;
2251
5.90M
        scan.text.size = pstr->size;
2252
5.90M
        scan.index = 0;
2253
        /* if TEXT_FROM_CHARS the data was converted to bytes earlier */
2254
5.90M
        if ( scan.text.operation & TEXT_FROM_CHARS )
2255
49.5k
            scan.text.operation =
2256
49.5k
                ((scan.text.operation & ~TEXT_FROM_CHARS) | TEXT_FROM_STRING);
2257
5.90M
    }
2258
129M
    for (;;) {
2259
129M
        int code = pdf_next_char_glyph(&scan, pstr, font, font_is_simple,
2260
129M
                                       &char_code, &cid, &glyph);
2261
2262
129M
        if (code == 2)                /* end of string */
2263
5.90M
            break;
2264
123M
        if (code == 3)                /* no glyph */
2265
1.61k
            continue;
2266
123M
        if (code < 0)
2267
0
            return code;
2268
123M
        if (cid >= char_cache_size)
2269
0
            continue;
2270
123M
        glyph_usage[cid / 8] |= 0x80 >> (cid & 7);
2271
123M
    }
2272
5.90M
    return 0;
2273
5.90M
}
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.45M
{
2299
6.45M
    gx_device_pdf *pdev = (gx_device_pdf *)penum->dev;
2300
6.45M
    gs_font *font = (gs_font *)penum->current_font;
2301
6.45M
    byte *glyph_usage = 0;
2302
6.45M
    double *real_widths;
2303
6.45M
    int char_cache_size, width_cache_size;
2304
6.45M
    int code;
2305
2306
6.45M
    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.45M
    code = pdf_attached_font_resource(pdev, font, ppdfont,
2311
6.45M
                               &glyph_usage, &real_widths, &char_cache_size, &width_cache_size);
2312
    /* *ppdfont is NULL if no resource attached. */
2313
6.45M
    if (code < 0)
2314
0
        return code;
2315
6.45M
    if (penum->cgp == NULL) {
2316
6.31M
        code = pdf_alloc_text_glyphs_table(pdev, penum, pstr);
2317
6.31M
        if (code < 0)
2318
0
            return code;
2319
6.31M
        code = pdf_make_text_glyphs_table(penum, pstr,
2320
6.31M
                            glyph_usage, char_cache_size);
2321
6.31M
        if (code < 0)
2322
0
            return code;
2323
6.31M
    }
2324
6.45M
    code = pdf_obtain_font_resource_encoded(pdev, font, ppdfont, penum->cgp);
2325
6.45M
    if (code < 0)
2326
550k
        return code;
2327
5.90M
    code = pdf_attached_font_resource(pdev, font, ppdfont,
2328
5.90M
                               &glyph_usage, &real_widths, &char_cache_size, &width_cache_size);
2329
5.90M
    if (code < 0)
2330
0
        return code;
2331
5.90M
    return pdf_mark_text_glyphs((const gs_text_enum_t *)penum, pstr, glyph_usage, char_cache_size);
2332
5.90M
}
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
590k
{
2382
590k
    return s1->size == s2->size &&
2383
590k
            !memcmp(s1->data, s2->data, s1->size);
2384
590k
}
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
591k
{
2393
591k
    gs_const_string s1;
2394
2395
591k
    if (pdsubf->u.cidfont.parent != 0) {
2396
590k
        s1.data = pdsubf->u.cidfont.parent->u.type0.CMapName_data;
2397
590k
        s1.size = pdsubf->u.cidfont.parent->u.type0.CMapName_size;
2398
590k
    }
2399
2400
591k
    if (pdsubf->u.cidfont.parent != 0 &&
2401
590k
            font_index == pdsubf->u.cidfont.parent->u.type0.font_index &&
2402
590k
            strings_equal(CMapName, &s1))
2403
590k
        *pdfont = pdsubf->u.cidfont.parent;
2404
1.84k
    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.84k
        if (pdsubf->u.cidfont.parent == NULL ||
2416
1.84k
                pdf_find_type0_font_resource(pdev, pdsubf, CMapName, font_index, pdfont) <= 0) {
2417
1.84k
            int code = pdf_font_type0_alloc(pdev, pdfont, gs_no_id, pdsubf, CMapName);
2418
2419
1.84k
            if (code < 0)
2420
0
                return code;
2421
1.84k
            (*pdfont)->u.type0.font_index = font_index;
2422
1.84k
        }
2423
1.84k
        pdsubf->u.cidfont.parent = *pdfont;
2424
1.84k
    }
2425
591k
    return 0;
2426
591k
}
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
725k
{
2470
725k
    int code = gs_distance_transform_inverse(pdelta->x, pdelta->y, pmat, ppt);
2471
725k
    gs_point delta;
2472
2473
725k
    if (code < 0)
2474
0
        return code;
2475
725k
    if (ppt->y == 0)
2476
725k
        return 0;
2477
    /* Check for numerical fuzz. */
2478
469
    code = gs_distance_transform(ppt->x, 0.0, pmat, &delta);
2479
469
    if (code < 0)
2480
0
        return 0;                /* punt */
2481
469
    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
1
        ppt->y = 0;
2484
1
    }
2485
469
    return 0;
2486
469
}
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
6.07M
{
2492
6.07M
    gs_matrix orig_matrix;
2493
6.07M
    double
2494
6.07M
        sx = pdev->HWResolution[0] / 72.0,
2495
6.07M
        sy = pdev->HWResolution[1] / 72.0;
2496
6.07M
    float size;
2497
2498
    /* Get the original matrix of the base font. */
2499
2500
6.07M
    {
2501
6.07M
        gs_font_base *cfont = pdf_font_resource_font(pdfont, false);
2502
2503
6.07M
        if (pdfont->FontType == ft_user_defined ||
2504
5.90M
            pdfont->FontType == ft_PDF_user_defined ||
2505
5.90M
            pdfont->FontType == ft_PCL_user_defined ||
2506
5.90M
            pdfont->FontType == ft_MicroType ||
2507
5.90M
            pdfont->FontType == ft_GL2_stick_user_defined ||
2508
5.90M
            pdfont->FontType == ft_GL2_531)
2509
170k
            orig_matrix = pdfont->u.simple.s.type3.FontMatrix;
2510
5.90M
        else if (cfont != 0) {
2511
            /*
2512
             * The text matrix to be computed relatively to the
2513
             * embedded font matrix.
2514
             */
2515
5.73M
            orig_matrix = cfont->FontMatrix;
2516
5.73M
        } else {
2517
            /*
2518
             * We don't embed the font.
2519
             * The text matrix to be computed relatively to
2520
             * standard font matrix.
2521
             */
2522
166k
            pdf_font_orig_matrix(font, &orig_matrix);
2523
166k
        }
2524
6.07M
    }
2525
2526
    /* Compute the scaling matrix and combined matrix. */
2527
2528
6.07M
    if (gs_matrix_invert(&orig_matrix, smat) < 0) {
2529
0
        gs_make_identity(smat);
2530
0
        gs_make_identity(tmat);
2531
0
        return 1; /* Arbitrary */
2532
0
    }
2533
6.07M
    gs_matrix_multiply(smat, pfmat, smat);
2534
6.07M
    *tmat = ctm_only(pgs);
2535
6.07M
    tmat->tx = tmat->ty = 0;
2536
6.07M
    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
6.07M
    size = hypot(tmat->yx, tmat->yy) / sy;
2542
6.07M
    if (size < 0.01)
2543
3.41k
        size = hypot(tmat->xx, tmat->xy) / sx;
2544
6.07M
    if (size < 0.01)
2545
3.01k
        size = 1;
2546
2547
6.07M
    return(size);
2548
6.07M
}
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
6.07M
{
2555
6.07M
    gx_device_pdf *const pdev = (gx_device_pdf *)penum->dev;
2556
6.07M
    gs_font *font = penum->current_font;
2557
6.07M
    gs_fixed_point cpt;
2558
6.07M
    gs_matrix smat, tmat;
2559
6.07M
    float size;
2560
6.07M
    float c_s = 0, w_s = 0;
2561
6.07M
    int mask = 0;
2562
6.07M
    int code = gx_path_current_point(gs_text_enum_path(penum), &cpt);
2563
2564
6.07M
    if (code < 0)
2565
0
        return code;
2566
2567
6.07M
    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
6.07M
    if (penum->text.operation & TEXT_ADD_TO_ALL_WIDTHS) {
2571
407k
        if (penum->current_font->WMode == 0) {
2572
407k
            gs_point pt;
2573
2574
407k
            code = transform_delta_inverse(&penum->text.delta_all, &smat, &pt);
2575
407k
            if (code >= 0 && pt.y == 0)
2576
406k
                c_s = pt.x * size;
2577
468
            else
2578
468
                mask |= TEXT_ADD_TO_ALL_WIDTHS;
2579
407k
        }
2580
0
        else
2581
0
            mask |= TEXT_ADD_TO_ALL_WIDTHS;
2582
407k
    }
2583
2584
6.07M
    if (penum->text.operation & TEXT_ADD_TO_SPACE_WIDTH) {
2585
318k
        gs_point pt;
2586
2587
318k
        code = transform_delta_inverse(&penum->text.delta_space, &smat, &pt);
2588
318k
        if (code >= 0 && pt.y == 0 && penum->text.space.s_char == 32)
2589
318k
            w_s = pt.x * size;
2590
0
        else
2591
0
            mask |= TEXT_ADD_TO_SPACE_WIDTH;
2592
318k
    }
2593
    /* Store the updated values. */
2594
2595
6.07M
    tmat.xx /= size;
2596
6.07M
    tmat.xy /= size;
2597
6.07M
    tmat.yx /= size;
2598
6.07M
    tmat.yy /= size;
2599
6.07M
    tmat.tx += fixed2float(cpt.x);
2600
6.07M
    tmat.ty += fixed2float(cpt.y);
2601
2602
6.07M
    ppts->values.character_spacing = c_s;
2603
6.07M
    ppts->values.pdfont = pdfont;
2604
6.07M
    ppts->values.size = size;
2605
6.07M
    ppts->values.matrix = tmat;
2606
6.07M
    ppts->values.render_mode = penum->pgs->text_rendering_mode;
2607
6.07M
    ppts->values.word_spacing = w_s;
2608
6.07M
    ppts->font = font;
2609
2610
6.07M
    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
6.07M
    } else {
2647
6.07M
        code = pdf_set_text_process_state(pdev, (const gs_text_enum_t *)penum,
2648
6.07M
                                      ppts);
2649
6.07M
    }
2650
6.07M
    return (code < 0 ? code : mask);
2651
6.07M
}
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
6.07M
{
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
6.07M
    if (pdf_render_mode_uses_stroke(pdev, &ppts->values)) {
2669
        /* Write all the parameters for stroking. */
2670
1.41k
        gs_gstate *pgs = pte->pgs;
2671
1.41k
        float save_width = pgs->line_params.half_width;
2672
1.41k
        int code;
2673
2674
1.41k
        if (pdev->context == PDF_IN_STRING) {
2675
1.09k
            code = sync_text_state(pdev);
2676
1.09k
            if (code < 0)
2677
0
                return code;
2678
1.09k
        }
2679
2680
1.41k
        code = pdf_open_contents(pdev, PDF_IN_STREAM);
2681
1.41k
        if (code < 0)
2682
0
            return code;
2683
2684
1.41k
        code = pdf_prepare_stroke(pdev, pgs, true);
2685
1.41k
        if (code >= 0) {
2686
1.41k
            code = gdev_vector_prepare_stroke((gx_device_vector *)pdev,
2687
1.41k
                                              pgs, NULL, NULL, 1);
2688
1.41k
            if (code < 0)
2689
0
                return code;
2690
1.41k
        }
2691
2692
1.41k
        code = pdf_open_contents(pdev, PDF_IN_STRING);
2693
1.41k
        if (code < 0)
2694
0
            return code;
2695
2696
1.41k
        pgs->line_params.half_width = save_width;
2697
1.41k
    }
2698
2699
    /* Now set all the other parameters. */
2700
2701
6.07M
    return pdf_set_text_state_values(pdev, &ppts->values);
2702
6.07M
}
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.46M
{
2708
5.46M
    double w, v;
2709
2710
5.46M
    gs_distance_transform(pinfo->width[wmode].x, pinfo->width[wmode].y, scale, &pwidth->xy);
2711
5.46M
    if (wmode)
2712
10.3k
        w = pwidth->xy.y, v = pwidth->xy.x;
2713
5.45M
    else
2714
5.45M
        w = pwidth->xy.x, v = pwidth->xy.y;
2715
5.46M
    pwidth->w = w;
2716
5.46M
    if (v != 0)
2717
54
        return 1;
2718
5.46M
    gs_distance_transform(pinfo->v.x, pinfo->v.y, scale, &pwidth->v);
2719
5.46M
    return 0;
2720
5.46M
}
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
32.6k
{
2726
32.6k
    gs_font_info_t finfo;
2727
32.6k
    int code;
2728
2729
32.6k
    code = cfont->procs.font_info((gs_font *)cfont, NULL,
2730
32.6k
                                  FONT_INFO_MISSING_WIDTH, &finfo);
2731
32.6k
    if (code < 0)
2732
0
        return code;
2733
32.6k
    if (wmode) {
2734
4.27k
        gs_distance_transform(0.0, -finfo.MissingWidth, scale_c, &pwidths->real_width.xy);
2735
4.27k
        pwidths->Width.xy.x = 0;
2736
4.27k
        pwidths->Width.xy.y = pwidths->real_width.xy.y;
2737
4.27k
        pwidths->Width.w = pwidths->real_width.w =
2738
4.27k
                pwidths->Width.xy.y;
2739
4.27k
        pwidths->Width.v.x = - pwidths->Width.xy.y / 2;
2740
4.27k
        pwidths->Width.v.y = - pwidths->Width.xy.y;
2741
28.4k
    } else {
2742
28.4k
        gs_distance_transform(finfo.MissingWidth, 0.0, scale_c, &pwidths->real_width.xy);
2743
28.4k
        pwidths->Width.xy.x = pwidths->real_width.xy.x;
2744
28.4k
        pwidths->Width.xy.y = 0;
2745
28.4k
        pwidths->Width.w = pwidths->real_width.w =
2746
28.4k
                pwidths->Width.xy.x;
2747
28.4k
        pwidths->Width.v.x = pwidths->Width.v.y = 0;
2748
28.4k
    }
2749
    /*
2750
     * Don't mark the width as known, just in case this is an
2751
     * incrementally defined font.
2752
     */
2753
32.6k
    return 1;
2754
32.6k
}
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.77M
{
2768
2.77M
    gs_font_base *cfont = pdf_font_resource_font(pdfont, false);
2769
2.77M
    gs_font *ofont = orig_font;
2770
2.77M
    gs_glyph_info_t info;
2771
2.77M
    gs_matrix scale_c, scale_o;
2772
2.77M
    int code, rcode = 0;
2773
2.77M
    gs_point v;
2774
2.77M
    int allow_cdevproc_callout = (orig_font->FontType == ft_CID_TrueType
2775
1.95M
                || orig_font->FontType == ft_CID_encrypted
2776
2.77M
                ? GLYPH_INFO_CDEVPROC : 0); /* fixme : allow more font types. */
2777
2778
2.77M
    if (ofont->FontType == ft_composite)
2779
0
        return_error(gs_error_unregistered); /* Must not happen. */
2780
2.77M
    code = glyph_orig_matrix((const gs_font *)cfont, glyph, &scale_c);
2781
2.77M
    if (code < 0)
2782
0
        return code;
2783
2.77M
    code = glyph_orig_matrix(ofont, glyph, &scale_o);
2784
2.77M
    if (code < 0)
2785
0
        return code;
2786
2.77M
    gs_matrix_scale(&scale_c, 1000.0, 1000.0, &scale_c);
2787
2.77M
    gs_matrix_scale(&scale_o, 1000.0, 1000.0, &scale_o);
2788
2.77M
    pwidths->Width.v.x = pwidths->Width.v.y = 0;
2789
2.77M
    pwidths->real_width.v.x = pwidths->real_width.v.y = 0;
2790
2.77M
    pwidths->real_width.w = pwidths->real_width.xy.x = pwidths->real_width.xy.y = 0;
2791
2.77M
    pwidths->replaced_v = false;
2792
2.77M
    pwidths->ignore_wmode = false;
2793
2.77M
    if (glyph == GS_NO_GLYPH)
2794
225
        return get_missing_width(cfont, wmode, &scale_c, pwidths);
2795
2.77M
    code = cfont->procs.glyph_info((gs_font *)cfont, glyph, NULL,
2796
2.77M
                                    GLYPH_INFO_WIDTH0 |
2797
2.77M
                                    (GLYPH_INFO_WIDTH0 << wmode) |
2798
2.77M
                                    GLYPH_INFO_OUTLINE_WIDTHS |
2799
2.77M
                                    (GLYPH_INFO_VVECTOR0 << wmode),
2800
2.77M
                                    &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.77M
    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
40.8k
        if (code == gs_error_undefined && (ofont->FontType == ft_encrypted || ofont->FontType == ft_encrypted2)) {
2812
12.6k
            int index;
2813
12.6k
            gs_glyph notdef_glyph;
2814
2815
12.6k
            v.x = v.y = 0;
2816
2817
12.6k
            for (index = 0;
2818
1.61M
                (ofont->procs.enumerate_glyph((gs_font *)ofont, &index,
2819
1.61M
                (GLYPH_SPACE_NAME), &notdef_glyph)) >= 0 &&
2820
1.61M
                index != 0;) {
2821
1.61M
                    if (gs_font_glyph_is_notdef((gs_font_base *)ofont, notdef_glyph)) {
2822
12.6k
                        code = ofont->procs.glyph_info((gs_font *)ofont, notdef_glyph, NULL,
2823
12.6k
                                            GLYPH_INFO_WIDTH0 << wmode,
2824
12.6k
                                            &info);
2825
2826
12.6k
                    if (code < 0)
2827
0
                        return code;
2828
12.6k
                    code = store_glyph_width(&pwidths->Width, wmode, &scale_c, &info);
2829
12.6k
                    if (code < 0)
2830
0
                        return code;
2831
12.6k
                    rcode |= code;
2832
12.6k
                    if (info.members  & (GLYPH_INFO_VVECTOR0 << wmode))
2833
0
                        gs_distance_transform(info.v.x, info.v.y, &scale_c, &v);
2834
12.6k
                    else
2835
12.6k
                        v.x = v.y = 0;
2836
12.6k
                    break;
2837
12.6k
                }
2838
1.61M
            }
2839
28.1k
        } else {
2840
28.1k
        code = get_missing_width(cfont, wmode, &scale_c, pwidths);
2841
28.1k
            if (code < 0)
2842
0
                v.y = 0;
2843
28.1k
            else
2844
28.1k
                v.y = pwidths->Width.v.y;
2845
28.1k
            if (wmode) {
2846
4.27k
                pdf_glyph_widths_t widths1;
2847
2848
4.27k
                if (get_missing_width(cfont, 0, &scale_c, &widths1) < 0)
2849
0
                    v.x = 0;
2850
4.27k
                else
2851
4.27k
                    v.x = widths1.Width.w / 2;
2852
4.27k
            } else
2853
23.9k
                v.x = pwidths->Width.v.x;
2854
28.1k
        }
2855
2.73M
    } else if (code < 0)
2856
0
        return code;
2857
2.73M
    else {
2858
2.73M
        code = store_glyph_width(&pwidths->Width, wmode, &scale_c, &info);
2859
2.73M
        if (code < 0)
2860
0
            return code;
2861
2.73M
        rcode |= code;
2862
2.73M
        if (info.members  & (GLYPH_INFO_VVECTOR0 << wmode))
2863
2.73M
            gs_distance_transform(info.v.x, info.v.y, &scale_c, &v);
2864
4.97k
        else
2865
4.97k
            v.x = v.y = 0;
2866
2.73M
        if (wmode && pdf_is_CID_font(ofont)) {
2867
4.97k
            if (info.members & (GLYPH_INFO_WIDTH0 << wmode)) {
2868
4.97k
                gs_point xy;
2869
2870
4.97k
                gs_distance_transform(info.width[0].x, info.width[0].y, &scale_c, &xy);
2871
4.97k
                v.x = xy.x / 2;
2872
4.97k
            } 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
4.97k
        }
2881
2.73M
    }
2882
2.77M
    pwidths->Width.v = v;
2883
2.77M
    if (code > 0 && !pdf_is_CID_font(ofont))
2884
6.17k
        pwidths->Width.xy.x = pwidths->Width.xy.y = pwidths->Width.w = 0;
2885
2.77M
    if (cdevproc_result == NULL) {
2886
2.77M
        info.members = 0;
2887
2.77M
        code = ofont->procs.glyph_info(ofont, glyph, NULL,
2888
2.77M
                                            (GLYPH_INFO_WIDTH0 << wmode) |
2889
2.77M
                                            (GLYPH_INFO_VVECTOR0 << wmode) |
2890
2.77M
                                            allow_cdevproc_callout,
2891
2.77M
                                            &info);
2892
        /* fixme : Move this call before cfont->procs.glyph_info. */
2893
2.77M
        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.77M
    } 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.77M
    if (code == gs_error_undefined || !(info.members & (GLYPH_INFO_WIDTH0 << wmode)))
2911
58.2k
        pwidths->real_width = pwidths->Width;
2912
2.71M
    else if (code < 0)
2913
4
        return code;
2914
2.71M
    else {
2915
2.71M
        if ((info.members & (GLYPH_INFO_VVECTOR0 | GLYPH_INFO_VVECTOR1)) != 0) {
2916
1.88M
            pwidths->replaced_v = true;
2917
1.88M
            if ((info.members & GLYPH_INFO_VVECTOR1) == 0 && wmode == 1)
2918
0
                pwidths->ignore_wmode = true;
2919
1.88M
        }
2920
829k
        else
2921
829k
            info.v.x = info.v.y = 0;
2922
2.71M
        code = store_glyph_width(&pwidths->real_width, wmode, &scale_o, &info);
2923
2.71M
        if (code < 0)
2924
0
            return code;
2925
2.71M
        rcode |= code;
2926
2.71M
        gs_distance_transform(info.v.x, info.v.y, &scale_o, &pwidths->real_width.v);
2927
2.71M
    }
2928
2.77M
    return rcode;
2929
2.77M
}
2930
2931
static int
2932
pdf_choose_output_char_code(gx_device_pdf *pdev, pdf_text_enum_t *penum, gs_char *pch)
2933
168k
{
2934
168k
    gs_char ch;
2935
168k
    gs_font *font = penum->current_font;
2936
2937
168k
    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
168k
    } 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
168k
    } else {
2966
168k
        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
168k
    }
2973
168k
    *pch = ch;
2974
168k
    return 0;
2975
168k
}
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
143k
{
2980
143k
    if (penum->orig_font->FontType == ft_composite || penum->orig_font->procs.glyph_name(penum->orig_font, glyph, gnstr) < 0
2981
143k
        || (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
143k
    return 0;
3003
143k
}
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
959k
{
3014
959k
    gs_text_params_t text1 = *text;
3015
3016
959k
    if(pte->current_font->FontType == 3 && (text1.operation & TEXT_DO_NONE)) {
3017
        /* We need a real drawing to accumulate charproc. */
3018
23.7k
        text1.operation &= ~TEXT_DO_NONE;
3019
23.7k
        text1.operation |= TEXT_DO_DRAW;
3020
23.7k
    }
3021
959k
    return gx_default_text_begin(pte->dev, pte->pgs, &text1, pte->current_font,
3022
959k
                                 pte->pcpath, ppte);
3023
959k
}
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
117k
{
3028
117k
    int code;
3029
117k
    const gx_device_color * pdcolor = gs_currentdevicecolor_inline(pte->pgs);
3030
3031
117k
    penum->returned.current_char = pte_default->returned.current_char;
3032
117k
    penum->returned.current_glyph = pte_default->returned.current_glyph;
3033
117k
    pdev->charproc_ctm = penum->pgs->ctm;
3034
117k
    if ((penum->current_font->FontType == ft_user_defined || penum->current_font->FontType == ft_PDF_user_defined)&&
3035
117k
        penum->outer_CID == GS_NO_GLYPH &&
3036
117k
            !(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
117k
        gs_matrix m;
3040
117k
        pdf_font_resource_t *pdfont;
3041
3042
117k
        code = pdf_start_charproc_accum(pdev);
3043
117k
        if (code < 0)
3044
0
            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
117k
        pdev->width *= 100;
3057
117k
        pdev->height *= 100;
3058
3059
117k
        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
117k
        pdev->state.line_params.half_width = -1;
3067
117k
        pdev->state.line_params.start_cap = gs_cap_unknown;
3068
117k
        pdev->state.line_params.end_cap = gs_cap_unknown;
3069
117k
        pdev->state.line_params.dash_cap = gs_cap_unknown;
3070
117k
        pdev->state.line_params.join = gs_join_unknown;
3071
117k
        pdev->state.line_params.miter_limit = -1;
3072
117k
        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
117k
        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
117k
        gs_matrix_scale(&m, 100, 100, &m);
3086
117k
        gs_matrix_fixed_from_matrix(&penum->pgs->ctm, &m);
3087
3088
        /* Choose a character code to use with the charproc. */
3089
117k
        code = pdf_choose_output_char_code(pdev, penum, &penum->output_char_code);
3090
117k
        if (code < 0)
3091
0
            return code;
3092
117k
        code = pdf_attached_font_resource(pdev, penum->current_font, &pdfont, NULL, NULL, NULL, NULL);
3093
117k
        if (code < 0)
3094
0
            return code;
3095
117k
        pdev->font3 = (pdf_resource_t *)pdfont;
3096
117k
        pdev->substream_Resources = pdfont->u.simple.s.type3.Resources;
3097
117k
        penum->charproc_accum = true;
3098
117k
        pdev->accumulating_charproc = true;
3099
117k
        pdev->charproc_BBox.p.x = 10000;
3100
117k
        pdev->charproc_BBox.p.y = 10000;
3101
117k
        pdev->charproc_BBox.q.x = 0;
3102
117k
        pdev->charproc_BBox.q.y = 0;
3103
117k
        return TEXT_PROCESS_RENDER;
3104
117k
    }
3105
0
    return 0;
3106
117k
}
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
25.4k
{
3111
25.4k
    int code;
3112
25.4k
    const gx_device_color * pdcolor = gs_currentdevicecolor_inline(pte->pgs);
3113
3114
25.4k
    pdev->charproc_ctm = penum->pgs->ctm;
3115
25.4k
    if ((penum->current_font->FontType == ft_user_defined ||
3116
25.4k
        penum->current_font->FontType == ft_PDF_user_defined ||
3117
0
        penum->current_font->FontType == ft_PCL_user_defined ||
3118
0
        penum->current_font->FontType == ft_MicroType ||
3119
0
        penum->current_font->FontType == ft_GL2_stick_user_defined ||
3120
0
        penum->current_font->FontType == ft_GL2_531) &&
3121
25.4k
            penum->outer_CID == GS_NO_GLYPH &&
3122
25.4k
            !(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
25.4k
        gs_matrix m;
3126
25.4k
        pdf_font_resource_t *pdfont;
3127
3128
25.4k
        pdev->PS_accumulator = false;
3129
25.4k
        code = pdf_start_charproc_accum(pdev);
3130
25.4k
        if (code < 0)
3131
0
            return code;
3132
3133
25.4k
        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
25.4k
        pdev->state.line_params.half_width = -1;
3141
25.4k
        pdev->state.line_params.start_cap = gs_cap_unknown;
3142
25.4k
        pdev->state.line_params.end_cap = gs_cap_unknown;
3143
25.4k
        pdev->state.line_params.dash_cap = gs_cap_unknown;
3144
25.4k
        pdev->state.line_params.join = gs_join_unknown;
3145
25.4k
        pdev->state.line_params.miter_limit = -1;
3146
25.4k
        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
25.4k
        gs_make_identity(&m);
3152
25.4k
        if (penum->current_font->FontType == ft_PDF_user_defined) {
3153
25.4k
            if (!pdev->Scaled_accumulator) {
3154
24.5k
                if (pdev->width > max_int / 100 || pdev->height > max_int / 100)
3155
0
                    return_error(gs_error_rangecheck);
3156
24.5k
                pdev->width *= 100;
3157
24.5k
                pdev->height *= 100;
3158
24.5k
                gs_matrix_scale(&m, 100, 100, &m);
3159
24.5k
                gs_matrix_fixed_from_matrix(&penum->pgs->ctm, &m);
3160
24.5k
            }
3161
25.4k
            pdev->Scaled_accumulator++;
3162
25.4k
        } else
3163
0
            gs_matrix_fixed_from_matrix(&penum->pgs->ctm, &m);
3164
3165
        /* Choose a character code to use with the charproc. */
3166
25.4k
        code = pdf_choose_output_char_code(pdev, penum, &penum->output_char_code);
3167
25.4k
        if (code < 0) {
3168
0
            (void)pdf_exit_substream(pdev);
3169
0
            return code;
3170
0
        }
3171
25.4k
        code = pdf_attached_font_resource(pdev, penum->current_font, &pdfont, NULL, NULL, NULL, NULL);
3172
25.4k
        if (code < 0) {
3173
0
            (void)pdf_exit_substream(pdev);
3174
0
            return code;
3175
0
        }
3176
25.4k
        pdev->font3 = (pdf_resource_t *)pdfont;
3177
25.4k
        if (pdfont == 0L) {
3178
0
            (void)pdf_exit_substream(pdev);
3179
0
            return gs_note_error(gs_error_invalidfont);
3180
0
        }
3181
3182
25.4k
        pdev->substream_Resources = pdfont->u.simple.s.type3.Resources;
3183
25.4k
        penum->charproc_accum = true;
3184
25.4k
        pdev->accumulating_charproc = true;
3185
25.4k
        return TEXT_PROCESS_RENDER;
3186
25.4k
    }
3187
0
    return 0;
3188
25.4k
}
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
143k
{
3194
143k
    gs_const_string gnstr;
3195
143k
    int code;
3196
143k
    bool cleanup = false;
3197
3198
143k
    if (pte_default->returned.current_glyph == GS_NO_GLYPH)
3199
0
      return_error(gs_error_undefined);
3200
143k
    code = pdf_choose_output_glyph_name(pdev, penum, &gnstr, pte_default->returned.current_glyph, &cleanup);
3201
143k
    if (code < 0) {
3202
0
        return code;
3203
0
    }
3204
3205
143k
    if ((penum->current_font->FontType == ft_user_defined ||
3206
25.4k
       penum->current_font->FontType == ft_PDF_user_defined ||
3207
0
       penum->current_font->FontType == ft_PCL_user_defined ||
3208
0
       penum->current_font->FontType == ft_MicroType ||
3209
0
       penum->current_font->FontType == ft_GL2_stick_user_defined ||
3210
0
       penum->current_font->FontType == ft_GL2_531) &&
3211
143k
       stell(pdev->strm) == 0)
3212
16.2k
    {
3213
16.2k
        char glyph[256], FontName[gs_font_name_max + 1], KeyName[256];
3214
16.2k
        int len;
3215
3216
16.2k
        len = min(gs_font_name_max, gnstr.size);
3217
16.2k
        memcpy(glyph, gnstr.data, len);
3218
16.2k
        glyph[len] = 0x00;
3219
16.2k
        len = min(gs_font_name_max, penum->current_font->font_name.size);
3220
16.2k
        memcpy(FontName, penum->current_font->font_name.chars, len);
3221
16.2k
        FontName[len] = 0x00;
3222
16.2k
        len = min(gs_font_name_max, penum->current_font->key_name.size);
3223
16.2k
        memcpy(KeyName, penum->current_font->key_name.chars, len);
3224
16.2k
        KeyName[len] = 0x00;
3225
3226
16.2k
        emprintf4(pdev->memory,
3227
16.2k
            "ERROR: Page %d used undefined glyph '%s' from type 3 font '%s', key '%s'\n",
3228
16.2k
            pdev->next_page, glyph, FontName, KeyName);
3229
16.2k
            stream_puts(pdev->strm, "0 0 0 0 0 0 d1\n");
3230
16.2k
    }
3231
3232
143k
    if (was_PS_type3 || pdev->Scaled_accumulator) {
3233
143k
        if (pdev->Scaled_accumulator)
3234
25.4k
            pdev->Scaled_accumulator--;
3235
143k
        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
142k
            pdev->width /= 100;
3240
142k
            pdev->height /= 100;
3241
142k
        }
3242
143k
    }
3243
143k
    code = pdf_end_charproc_accum(pdev, penum->current_font, penum->cgp,
3244
143k
                pte_default->returned.current_glyph, penum->output_char_code, &gnstr);
3245
143k
    if (code < 0)
3246
15
        goto exit;
3247
143k
    pdev->accumulating_charproc = false;
3248
143k
    penum->charproc_accum = false;
3249
143k
    code = gx_default_text_restore_state(pte_default);
3250
143k
    if (code < 0)
3251
0
        goto exit;
3252
143k
    gs_text_release(NULL, pte_default, "pdf_text_process");
3253
143k
    penum->pte_default = 0;
3254
3255
143k
exit:
3256
143k
    if (cleanup)
3257
0
        gs_free_string(pdev->pdf_memory, (byte *)gnstr.data, gnstr.size, "pdf_text_set_cache free working name");
3258
143k
    return code;
3259
143k
}
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.87M
{
3360
6.87M
    pdf_text_enum_t *const penum = (pdf_text_enum_t *)pte;
3361
6.87M
    uint operation = pte->text.operation;
3362
6.87M
    uint size = 0;
3363
6.87M
    gs_text_enum_t *pte_default;
3364
6.87M
    PROCESS_TEXT_PROC((*process));
3365
6.87M
    int code = 0, early_accumulator = 0;
3366
6.87M
    gx_device_pdf *pdev = (gx_device_pdf *)penum->dev;
3367
6.87M
    uint captured_pte_index = 0xFFFFFFFF;
3368
6.87M
#define BUF_SIZE 100                /* arbitrary > 0 */
3369
    /* Use a union to ensure alignment. */
3370
6.87M
    union bu_ {
3371
6.87M
        byte bytes[BUF_SIZE];
3372
6.87M
        gs_char chars[BUF_SIZE / sizeof(gs_char)];
3373
6.87M
        gs_glyph glyphs[BUF_SIZE / sizeof(gs_glyph)];
3374
6.87M
    } buf;
3375
3376
6.87M
     if (!penum->pte_default) {
3377
        /* Don't need to sync before exiting charproc. */
3378
6.75M
        code = pdf_prepare_text_drawing(pdev, pte);
3379
6.75M
        if (code == gs_error_rangecheck) {
3380
            /* Fallback to the default implermentation for handling
3381
               a transparency with CompatibilityLevel<=1.3 . */
3382
5.38k
            goto default_impl;
3383
5.38k
        }
3384
6.74M
        if (code < 0)
3385
0
            return code;
3386
6.74M
    }
3387
6.87M
    if (!penum->pte_default) {
3388
6.74M
        pdev->charproc_just_accumulated = false;
3389
6.74M
        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.74M
    }
3394
6.87M
    if ((penum->current_font->FontType == ft_user_defined ||
3395
6.74M
        penum->current_font->FontType == ft_PCL_user_defined ||
3396
6.74M
        penum->current_font->FontType == ft_PDF_user_defined ||
3397
6.71M
        penum->current_font->FontType == ft_MicroType ||
3398
6.71M
        penum->current_font->FontType == ft_GL2_stick_user_defined ||
3399
6.71M
        penum->current_font->FontType == ft_GL2_531) &&
3400
154k
        (penum->text.operation & TEXT_DO_ANY_CHARPATH)
3401
8.48k
        && !pdev->type3charpath) {
3402
270
        pdev->type3charpath = true;
3403
270
        if (!penum->charproc_accum)
3404
270
            goto default_impl;
3405
270
    }
3406
3407
6.87M
    if (pdev->UseOCR != UseOCRNever) {
3408
0
        code = ProcessTextForOCR(pte);
3409
0
        if (code != 0)
3410
0
            return code;
3411
0
    }
3412
3413
6.87M
    operation = pte->text.operation;
3414
6.87M
    size = pte->text.size - pte->index;
3415
3416
6.87M
    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.08M
        gs_char *cdata;
3434
3435
1.08M
        cdata = (gs_char *)pte->text.data.chars;
3436
1.08M
        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
117k
            code = complete_charproc(pdev, pte, pte_default, penum, true);
3441
117k
            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
117k
            captured_pte_index = pte->index;
3449
117k
            if (!pdev->type3charpath)
3450
117k
                goto top;
3451
0
            else
3452
0
                goto default_impl;
3453
117k
        }
3454
3455
967k
        if ((penum->current_font->FontType == ft_GL2_stick_user_defined ||
3456
967k
            penum->current_font->FontType == ft_GL2_531 || penum->current_font->FontType == ft_MicroType)
3457
0
            && 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
967k
        if (penum->current_font->FontType == ft_PDF_user_defined) {
3493
25.4k
            early_accumulator = 1;
3494
25.4k
        }
3495
967k
        if (early_accumulator) {
3496
25.4k
            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
25.4k
                gs_show_enum psenum = *(gs_show_enum *)pte_default;
3502
25.4k
                gs_gstate *pgs = (gs_gstate *)penum->pgs;
3503
25.4k
                gs_text_enum_procs_t *special_procs;
3504
25.4k
                void (*save_proc)(gx_device *, gs_matrix *) = pdev->procs.get_initial_matrix;
3505
25.4k
                gs_matrix m, savem;
3506
3507
25.4k
                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
25.4k
                if (special_procs == NULL)
3509
0
                    return_error(gs_error_VMerror);
3510
3511
25.4k
                *special_procs = *pte_default->procs;
3512
25.4k
                special_procs->set_cache = pdf_text_set_cache;
3513
25.4k
                special_procs->release = pdf_show_text_release;
3514
25.4k
                pte_default->procs = special_procs;
3515
3516
25.4k
                {
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
25.4k
                    gs_font *rfont = (pte->fstack.depth < 0 ? pte->current_font : pte->fstack.items[0].font);
3524
25.4k
                    gs_font *pfont = (pte->fstack.depth < 0 ? pte->current_font :
3525
25.4k
                        pte->fstack.items[pte->fstack.depth].font);
3526
25.4k
                    int wmode = rfont->WMode;
3527
25.4k
                    gs_log2_scale_point log2_scale = {0,0};
3528
25.4k
                    gs_fixed_point subpix_origin = {0,0};
3529
25.4k
                    cached_fm_pair *pair;
3530
25.4k
                    cached_char *cc;
3531
25.4k
                    gs_glyph glyph;
3532
3533
25.4k
                    code = gx_lookup_fm_pair(pfont, &char_tm_only(pte->pgs), &log2_scale, false, &pair);
3534
25.4k
                    if (code < 0)
3535
0
                        return code;
3536
25.4k
                    glyph = (*pte_default->encode_char)(pfont, pte_default->text.data.chars[pte_default->index],
3537
25.4k
                                                      GLYPH_SPACE_NAME);
3538
25.4k
                    cc = gx_lookup_cached_char(pfont, pair, glyph, wmode, 1, &subpix_origin);
3539
25.4k
                    if (cc != 0) {
3540
0
                        gx_purge_selected_cached_chars(pfont->dir, pdf_query_purge_cached_char, (void *)cc);
3541
0
                    }
3542
25.4k
                }
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
25.4k
                psenum.pgs = (gs_gstate *)psenum.pgs;
3550
                /* Save the current FontMatrix */
3551
25.4k
                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
25.4k
                gs_make_identity(&m);
3557
25.4k
                pgs->font->FontMatrix = m;
3558
3559
25.4k
                pgs->char_tm_valid = 0;
3560
25.4k
                pgs->char_tm.txy_fixed_valid = 0;
3561
25.4k
                pgs->current_point.x = pgs->current_point.y = 0;
3562
25.4k
                pgs->char_tm.txy_fixed_valid = 0;
3563
3564
25.4k
                if (pte->text.operation & TEXT_FROM_CHARS)
3565
25.4k
                    pte_default->returned.current_char = penum->returned.current_char =
3566
25.4k
                        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
25.4k
                code = install_charproc_accumulator(pdev, pte, pte_default, penum);
3572
25.4k
                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
25.4k
                if (pte->text.size != 1)
3583
22.9k
                    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
25.4k
                if (penum->current_font->FontType != ft_PDF_user_defined)
3588
0
                    pdev->procs.get_initial_matrix = pdf_type3_get_initial_matrix;
3589
3590
25.4k
                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
25.4k
                pte_default->level = penum->pgs->level;
3595
25.4k
                code = gs_text_process(pte_default);
3596
25.4k
                if (code < 0) {
3597
650
                    (void)complete_charproc(pdev, pte, pte_default, penum, false);
3598
650
                    return code;
3599
650
                }
3600
24.7k
                pdev->pte = NULL;         /* CAUTION: See comment in gdevpdfx.h . */
3601
24.7k
                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
24.7k
                pgs->font->FontMatrix = savem;
3607
                /* Restore the default 'initial matrix' mathod. */
3608
24.7k
                pdev->procs.get_initial_matrix = save_proc;
3609
24.7k
                penum->returned.current_char = pte_default->returned.current_char;
3610
24.7k
                penum->returned.current_glyph = pte_default->returned.current_glyph;
3611
24.7k
                code = pdf_choose_output_char_code(pdev, penum, &penum->output_char_code);
3612
24.7k
                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
24.7k
                code = complete_charproc(pdev, pte, pte_default, penum, false);
3624
24.7k
                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
24.7k
                size = pte->text.size - pte->index;
3702
24.7k
                if (code < 0)
3703
15
                    return code;
3704
24.7k
                if (!pdev->type3charpath)
3705
24.7k
                    goto top;
3706
0
                else
3707
0
                    goto default_impl;
3708
24.7k
            }
3709
25.4k
        }
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
942k
        {
3726
942k
            gs_show_enum *penum = (gs_show_enum *)pte_default;
3727
942k
            int save_can_cache = penum->can_cache;
3728
942k
            const gs_color_space *pcs;
3729
942k
            const gs_client_color *pcc;
3730
942k
            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
942k
            if (gx_hld_get_color_space_and_ccolor(pgs, (const gx_drawing_color *)pgs->color[0].dev_color, &pcs, &pcc) == pattern_color_space)
3740
48
                penum->can_cache = -1;
3741
942k
            pdev->pte = pte_default; /* CAUTION: See comment in gdevpdfx.h . */
3742
942k
            code = gs_text_process(pte_default);
3743
942k
            if (code < 0)
3744
2.12k
                return code;
3745
3746
940k
            penum->can_cache = save_can_cache;
3747
3748
940k
            pdev->pte = NULL;         /* CAUTION: See comment in gdevpdfx.h . */
3749
940k
            pdev->charproc_just_accumulated = false;
3750
940k
        }
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
940k
        if (code == TEXT_PROCESS_RENDER && !pdev->type3charpath) {
3758
117k
            int code1;
3759
3760
117k
            code1 = install_PS_charproc_accumulator(pdev, pte, pte_default, penum);
3761
117k
            if (code1 != 0)
3762
117k
                return code1;
3763
117k
        }
3764
3765
822k
        gs_text_enum_copy_dynamic(pte, pte_default, true);
3766
3767
822k
        if (code)
3768
8.21k
            return code;
3769
813k
        gs_text_release(NULL, pte_default, "pdf_text_process");
3770
813k
        penum->pte_default = 0;
3771
813k
        if (pdev->type3charpath)
3772
270
            pdev->type3charpath = false;
3773
813k
        return 0;
3774
822k
    }
3775
6.88M
    {
3776
6.88M
        gs_font *font = pte->orig_font; /* Not sure. Changed for CDevProc callout. Was pte->current_font */
3777
3778
6.88M
        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.52M
        case ft_encrypted:
3784
5.38M
        case ft_encrypted2:
3785
6.28M
        case ft_TrueType:
3786
6.40M
        case ft_user_defined:
3787
6.45M
        case ft_PDF_user_defined:
3788
6.45M
        case ft_PCL_user_defined:
3789
6.45M
        case ft_MicroType:
3790
6.45M
        case ft_GL2_stick_user_defined:
3791
6.45M
        case ft_GL2_531:
3792
            /* The data may be either glyphs or characters. */
3793
6.45M
            process = process_plain_text;
3794
6.45M
            break;
3795
432k
        case ft_composite:
3796
432k
            process =
3797
432k
                (((gs_font_type0 *)font)->data.FMapType == fmap_CMap ?
3798
432k
                 process_cmap_text :
3799
432k
                 process_composite_text);
3800
432k
            break;
3801
0
        default:
3802
0
            goto skip;
3803
6.88M
        }
3804
6.88M
    }
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.88M
    if (operation & (TEXT_FROM_STRING | TEXT_FROM_BYTES)) {
3813
6.83M
        if (size < sizeof(gs_glyph))
3814
6.05M
            size = sizeof(gs_glyph); /* for process_cid_text */
3815
6.83M
    } else if (operation & TEXT_FROM_CHARS)
3816
49.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.88M
    if (pte->orig_font->FontType == ft_composite) {
3834
432k
        if (size < (pte->text.size - pte->index) * sizeof(gs_glyph) * 2)
3835
432k
            size = (pte->text.size - pte->index) * sizeof(gs_glyph) * 2;
3836
432k
    }
3837
3838
6.88M
    if (size <= sizeof(buf)) {
3839
6.76M
        code = process(pte, buf.bytes, size);
3840
6.76M
    } else {
3841
120k
        byte *dbuf = gs_alloc_bytes(pte->memory, size, "pdf_text_process");
3842
3843
120k
        if (dbuf == 0)
3844
0
            return_error(gs_error_VMerror);
3845
120k
        code = process(pte, dbuf, size);
3846
120k
        gs_free_object(pte->memory, dbuf, "pdf_text_process");
3847
120k
    }
3848
6.88M
 skip:
3849
6.88M
    if (code < 0 ||
3850
6.04M
            ((pte->current_font->FontType == ft_user_defined ||
3851
5.92M
            pte->current_font->FontType == ft_PCL_user_defined ||
3852
5.92M
            pte->current_font->FontType == ft_PDF_user_defined ||
3853
5.88M
            pte->current_font->FontType == ft_MicroType ||
3854
5.88M
            pte->current_font->FontType == ft_GL2_stick_user_defined ||
3855
5.88M
            pte->current_font->FontType == ft_GL2_531 ||
3856
5.88M
            pte->current_font->FontType == ft_TrueType) &&
3857
1.02M
             code != TEXT_PROCESS_INTERVENE &&
3858
1.02M
            penum->index < penum->text.size)) {
3859
974k
        if (code == gs_error_unregistered) /* Debug purpose only. */
3860
11.8k
            return code;
3861
962k
        if (code == gs_error_VMerror)
3862
0
            return code;
3863
962k
        if (code == gs_error_invalidfont) /* Bug 688370. */
3864
8.53k
            return code;
3865
959k
 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
959k
        if (captured_pte_index == pte->index)
3872
0
            return code;
3873
        /* Fall back to the default implementation. */
3874
959k
        code = pdf_default_text_begin(pte, &pte->text, &pte_default);
3875
959k
        if (code < 0)
3876
46
            return code;
3877
959k
        penum->pte_default = pte_default;
3878
959k
        gs_text_enum_copy_dynamic(pte_default, pte, false);
3879
959k
    }
3880
    /* The 'process' procedure might also have set pte_default itself. */
3881
6.87M
    if (penum->pte_default && !code)
3882
959k
        goto top;
3883
5.91M
    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.87M
}