Coverage Report

Created: 2025-06-24 07:01

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