Coverage Report

Created: 2026-10-28 08:05

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