Coverage Report

Created: 2025-08-28 07:06

/src/ghostpdl/devices/vector/gdevpdtf.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2001-2025 Artifex Software, Inc.
2
   All Rights Reserved.
3
4
   This software is provided AS-IS with no warranty, either express or
5
   implied.
6
7
   This software is distributed under license and may not be copied,
8
   modified or distributed except as expressly authorized under the terms
9
   of the license contained in the file LICENSE in this distribution.
10
11
   Refer to licensing information at http://www.artifex.com or contact
12
   Artifex Software, Inc.,  39 Mesa Street, Suite 108A, San Francisco,
13
   CA 94129, USA, for further information.
14
*/
15
16
17
/* Font and CMap resource implementation for pdfwrite text */
18
#include "memory_.h"
19
#include "gx.h"
20
#include "gserrors.h"
21
#include "gsutil.h"   /* for bytes_compare */
22
#include "gxfcache.h"   /* for orig_fonts list */
23
#include "gxfcid.h"
24
#include "gxfcmap.h"
25
#include "gxfcopy.h"
26
#include "gxfont.h"
27
#include "gxfont1.h"
28
#include "gdevpsf.h"
29
#include "gdevpdfx.h"
30
#include "gdevpdtb.h"
31
#include "gdevpdtd.h"
32
#include "gdevpdtf.h"
33
#include "gdevpdtw.h"
34
#include "gdevpdti.h"
35
#include "gdevpdfo.h"       /* for cos_free() */
36
#include "whitelst.h"   /* Checks whether protected fonta cna be embedded */
37
38
#include "gscencs.h"
39
40
/* GC descriptors */
41
public_st_pdf_font_resource();
42
private_st_pdf_standard_font();
43
private_st_pdf_standard_font_element();
44
private_st_pdf_outline_fonts();
45
46
static
47
872k
ENUM_PTRS_WITH(pdf_font_resource_enum_ptrs, pdf_font_resource_t *pdfont)
48
218k
ENUM_PREFIX(st_pdf_resource, 12);
49
54.5k
case 0: return ENUM_STRING(&pdfont->BaseFont);
50
54.5k
case 1: ENUM_RETURN(pdfont->FontDescriptor);
51
54.5k
case 2: ENUM_RETURN(pdfont->base_font);
52
54.5k
case 3: ENUM_RETURN(pdfont->Widths);
53
54.5k
case 4: ENUM_RETURN(pdfont->used);
54
54.5k
case 5: ENUM_RETURN(pdfont->res_ToUnicode);
55
54.5k
case 6: ENUM_RETURN(pdfont->cmap_ToUnicode);
56
54.5k
case 7: switch (pdfont->FontType) {
57
2.04k
 case ft_composite:
58
2.04k
     ENUM_RETURN(pdfont->u.type0.DescendantFont);
59
236
 case ft_CID_encrypted:
60
2.04k
 case ft_CID_TrueType:
61
2.04k
     ENUM_RETURN(pdfont->u.cidfont.Widths2);
62
50.4k
 default:
63
50.4k
     pdf_mark_glyph_names(pdfont, mem);
64
50.4k
     ENUM_RETURN(pdfont->u.simple.Encoding);
65
54.5k
}
66
54.5k
case 8: switch (pdfont->FontType) {
67
35.3k
 case ft_encrypted:
68
36.4k
 case ft_encrypted2:
69
46.6k
 case ft_TrueType:
70
46.6k
 case ft_PCL_user_defined:
71
46.6k
 case ft_MicroType:
72
46.6k
 case ft_GL2_stick_user_defined:
73
50.4k
 case ft_user_defined:
74
50.4k
 case ft_PDF_user_defined:
75
50.4k
 case ft_GL2_531:
76
50.4k
     ENUM_RETURN(pdfont->u.simple.v);
77
236
 case ft_CID_encrypted:
78
2.04k
 case ft_CID_TrueType:
79
2.04k
     ENUM_RETURN(pdfont->u.cidfont.v);
80
2.04k
 case ft_composite:
81
2.04k
 default:
82
2.04k
     ENUM_RETURN(0);
83
54.5k
}
84
54.5k
case 9: switch (pdfont->FontType) {
85
0
 case ft_PCL_user_defined:
86
0
 case ft_MicroType:
87
0
 case ft_GL2_stick_user_defined:
88
3.79k
 case ft_user_defined:
89
3.79k
 case ft_PDF_user_defined:
90
3.79k
 case ft_GL2_531:
91
3.79k
     ENUM_RETURN(pdfont->u.simple.s.type3.char_procs);
92
236
 case ft_CID_encrypted:
93
2.04k
 case ft_CID_TrueType:
94
2.04k
     ENUM_RETURN(pdfont->u.cidfont.CIDToGIDMap);
95
48.6k
 default:
96
48.6k
     ENUM_RETURN(0);
97
54.5k
}
98
54.5k
case 10: switch (pdfont->FontType) {
99
0
 case ft_PCL_user_defined:
100
0
 case ft_MicroType:
101
0
 case ft_GL2_stick_user_defined:
102
3.79k
 case ft_user_defined:
103
3.79k
 case ft_PDF_user_defined:
104
3.79k
 case ft_GL2_531:
105
3.79k
     ENUM_RETURN(pdfont->u.simple.s.type3.cached);
106
236
 case ft_CID_encrypted:
107
2.04k
 case ft_CID_TrueType:
108
2.04k
     ENUM_RETURN(pdfont->u.cidfont.parent);
109
48.6k
 default:
110
48.6k
     ENUM_RETURN(0);
111
54.5k
}
112
54.5k
case 11: switch (pdfont->FontType) {
113
0
 case ft_PCL_user_defined:
114
0
 case ft_MicroType:
115
0
 case ft_GL2_stick_user_defined:
116
3.79k
 case ft_user_defined:
117
3.79k
 case ft_PDF_user_defined:
118
3.79k
 case ft_GL2_531:
119
3.79k
     ENUM_RETURN(pdfont->u.simple.s.type3.Resources);
120
236
 case ft_CID_encrypted:
121
2.04k
 case ft_CID_TrueType:
122
2.04k
     ENUM_RETURN(pdfont->u.cidfont.used2);
123
48.6k
 default:
124
48.6k
     ENUM_RETURN(0);
125
54.5k
}
126
872k
ENUM_PTRS_END
127
static
128
54.5k
RELOC_PTRS_WITH(pdf_font_resource_reloc_ptrs, pdf_font_resource_t *pdfont)
129
54.5k
{
130
54.5k
    RELOC_PREFIX(st_pdf_resource);
131
54.5k
    RELOC_STRING_VAR(pdfont->BaseFont);
132
54.5k
    RELOC_VAR(pdfont->FontDescriptor);
133
54.5k
    RELOC_VAR(pdfont->base_font);
134
54.5k
    RELOC_VAR(pdfont->Widths);
135
54.5k
    RELOC_VAR(pdfont->used);
136
54.5k
    RELOC_VAR(pdfont->res_ToUnicode);
137
54.5k
    RELOC_VAR(pdfont->cmap_ToUnicode);
138
54.5k
    switch (pdfont->FontType) {
139
2.04k
    case ft_composite:
140
2.04k
        RELOC_VAR(pdfont->u.type0.DescendantFont);
141
2.04k
        break;
142
0
    case ft_PCL_user_defined:
143
0
    case ft_MicroType:
144
0
    case ft_GL2_stick_user_defined:
145
3.79k
    case ft_user_defined:
146
3.79k
    case ft_PDF_user_defined:
147
3.79k
    case ft_GL2_531:
148
3.79k
        RELOC_VAR(pdfont->u.simple.Encoding);
149
3.79k
        RELOC_VAR(pdfont->u.simple.v);
150
3.79k
        RELOC_VAR(pdfont->u.simple.s.type3.char_procs);
151
3.79k
        RELOC_VAR(pdfont->u.simple.s.type3.cached);
152
3.79k
        RELOC_VAR(pdfont->u.simple.s.type3.Resources);
153
3.79k
        break;
154
236
    case ft_CID_encrypted:
155
2.04k
    case ft_CID_TrueType:
156
2.04k
        RELOC_VAR(pdfont->u.cidfont.Widths2);
157
2.04k
        RELOC_VAR(pdfont->u.cidfont.v);
158
2.04k
        RELOC_VAR(pdfont->u.cidfont.CIDToGIDMap);
159
2.04k
        RELOC_VAR(pdfont->u.cidfont.parent);
160
2.04k
        RELOC_VAR(pdfont->u.cidfont.used2);
161
2.04k
        break;
162
46.6k
    default:
163
46.6k
        RELOC_VAR(pdfont->u.simple.Encoding);
164
46.6k
        RELOC_VAR(pdfont->u.simple.v);
165
46.6k
        break;
166
54.5k
    }
167
54.5k
}
168
54.5k
RELOC_PTRS_END
169
170
/* ---------------- Standard fonts ---------------- */
171
172
/* ------ Private ------ */
173
174
/* Define the 14 standard built-in fonts. */
175
102k
#define PDF_NUM_STANDARD_FONTS 14
176
typedef struct pdf_standard_font_info_s {
177
    const char *fname;
178
    int size;
179
    gs_encoding_index_t base_encoding;
180
} pdf_standard_font_info_t;
181
static const pdf_standard_font_info_t standard_font_info[] = {
182
    {"Courier",                7, ENCODING_INDEX_STANDARD},
183
    {"Courier-Bold",          12, ENCODING_INDEX_STANDARD},
184
    {"Courier-Oblique",       15, ENCODING_INDEX_STANDARD},
185
    {"Courier-BoldOblique",   19, ENCODING_INDEX_STANDARD},
186
    {"Helvetica",              9, ENCODING_INDEX_STANDARD},
187
    {"Helvetica-Bold",        14, ENCODING_INDEX_STANDARD},
188
    {"Helvetica-Oblique",     17, ENCODING_INDEX_STANDARD},
189
    {"Helvetica-BoldOblique", 21, ENCODING_INDEX_STANDARD},
190
    {"Symbol",                 6, ENCODING_INDEX_SYMBOL},
191
    {"Times-Roman",           11, ENCODING_INDEX_STANDARD},
192
    {"Times-Bold",            10, ENCODING_INDEX_STANDARD},
193
    {"Times-Italic",          12, ENCODING_INDEX_STANDARD},
194
    {"Times-BoldItalic",      16, ENCODING_INDEX_STANDARD},
195
    {"ZapfDingbats",          12, ENCODING_INDEX_DINGBATS},
196
    {0}
197
};
198
199
/* Return the index of a standard font name, or -1 if missing. */
200
static int
201
pdf_find_standard_font_name(const byte *str, uint size)
202
77.9k
{
203
77.9k
    const pdf_standard_font_info_t *ppsf;
204
205
1.13M
    for (ppsf = standard_font_info; ppsf->fname; ++ppsf)
206
1.05M
        if (ppsf->size == size &&
207
1.05M
            !memcmp(ppsf->fname, (const char *)str, size)
208
1.05M
            )
209
5.48k
            return ppsf - standard_font_info;
210
72.4k
    return -1;
211
77.9k
}
212
213
/*
214
 * If there is a standard font with the same appearance (CharStrings,
215
 * Private, WeightVector) as the given font, set *psame to the mask of
216
 * identical properties, and return the standard-font index; otherwise,
217
 * set *psame to 0 and return -1.
218
 */
219
static int
220
find_std_appearance(const gx_device_pdf *pdev, gs_font_base *bfont,
221
                    int mask, pdf_char_glyph_pair_t *pairs, int num_glyphs)
222
170
{
223
170
    bool has_uid = uid_is_UniqueID(&bfont->UID) && bfont->UID.id != 0;
224
170
    const pdf_standard_font_t *psf = pdf_standard_fonts(pdev);
225
170
    int i;
226
227
170
    switch (bfont->FontType) {
228
158
    case ft_encrypted:
229
162
    case ft_encrypted2:
230
162
    case ft_TrueType:
231
162
        break;
232
8
    default:
233
8
        return -1;
234
170
    }
235
236
2.43k
    for (i = 0; i < PDF_NUM_STANDARD_FONTS; ++psf, ++i) {
237
2.26k
        gs_font_base *cfont;
238
2.26k
        int code;
239
240
2.26k
        if (!psf->pdfont)
241
2.22k
            continue;
242
47
        cfont = pdf_font_resource_font(psf->pdfont, false);
243
47
        if (has_uid) {
244
            /*
245
             * Require the UIDs to match.  The PostScript spec says this
246
             * is the case iff the outlines are the same.
247
             */
248
0
            if (!uid_equal(&bfont->UID, &cfont->UID))
249
0
                continue;
250
0
        }
251
        /*
252
         * Require the actual outlines to match (within the given subset).
253
         */
254
47
        code = gs_copied_can_copy_glyphs((const gs_font *)cfont,
255
47
                                         (const gs_font *)bfont,
256
47
                                         &pairs[0].glyph, num_glyphs,
257
47
                                         sizeof(pdf_char_glyph_pair_t), true);
258
47
        if (code == gs_error_unregistered) /* Debug purpose only. */
259
0
            return code;
260
        /* Note: code < 0 means an error. Skip it here. */
261
47
        if (code > 0)
262
0
            return i;
263
47
    }
264
162
    return -1;
265
162
}
266
267
/*
268
 * Scan a font directory for standard fonts.  Return true if any new ones
269
 * were found.  A font is recognized as standard if it was loaded as a
270
 * resource, it has a UniqueId, and it has a standard name.
271
 */
272
static bool
273
scan_for_standard_fonts(gx_device_pdf *pdev, const gs_font_dir *dir)
274
170
{
275
170
    bool found = false;
276
170
    gs_font *orig = dir->orig_fonts;
277
278
681
    for (; orig; orig = orig->next) {
279
511
        gs_font_base *obfont;
280
281
511
        if (orig->FontType == ft_composite || !orig->is_resource)
282
264
            continue;
283
247
        obfont = (gs_font_base *)orig;
284
247
        if (uid_is_UniqueID(&obfont->UID)) {
285
            /* Is it one of the standard fonts? */
286
0
            int i = pdf_find_standard_font_name(orig->key_name.chars,
287
0
                                                orig->key_name.size);
288
289
0
            if (i >= 0 && pdf_standard_fonts(pdev)[i].pdfont == 0) {
290
0
                pdf_font_resource_t *pdfont;
291
0
                int code = pdf_font_std_alloc(pdev, &pdfont, true, orig->id, obfont,
292
0
                                              i);
293
294
0
                if (code < 0)
295
0
                    continue;
296
0
                found = true;
297
0
            }
298
0
        }
299
247
    }
300
170
    return found;
301
170
}
302
303
/* ---------------- Initialization ---------------- */
304
305
/*
306
 * Allocate and initialize bookkeeping for outline fonts.
307
 */
308
pdf_outline_fonts_t *
309
pdf_outline_fonts_alloc(gs_memory_t *mem)
310
50.0k
{
311
50.0k
    pdf_outline_fonts_t *pofs =
312
50.0k
        gs_alloc_struct(mem, pdf_outline_fonts_t, &st_pdf_outline_fonts,
313
50.0k
                        "pdf_outline_fonts_alloc(outline_fonts)");
314
50.0k
    pdf_standard_font_t *ppsf =
315
50.0k
        gs_alloc_struct_array(mem, PDF_NUM_STANDARD_FONTS,
316
50.0k
                              pdf_standard_font_t,
317
50.0k
                              &st_pdf_standard_font_element,
318
50.0k
                              "pdf_outline_fonts_alloc(standard_fonts)");
319
320
50.0k
    if (pofs == 0 || ppsf == 0)
321
0
        return 0;
322
50.0k
    memset(ppsf, 0, PDF_NUM_STANDARD_FONTS * sizeof(*ppsf));
323
50.0k
    memset(pofs, 0, sizeof(*pofs));
324
50.0k
    pofs->standard_fonts = ppsf;
325
50.0k
    return pofs;
326
50.0k
}
327
328
/*
329
 * Return the standard fonts array.
330
 */
331
pdf_standard_font_t *
332
pdf_standard_fonts(const gx_device_pdf *pdev)
333
55.5k
{
334
55.5k
    if (pdev->text != NULL && pdev->text->outline_fonts != NULL)
335
55.5k
        return pdev->text->outline_fonts->standard_fonts;
336
0
    return NULL;
337
55.5k
}
338
339
/*
340
 * Clean the standard fonts array.
341
 */
342
void
343
pdf_clean_standard_fonts(const gx_device_pdf *pdev)
344
50.0k
{
345
50.0k
    pdf_standard_font_t *ppsf = pdf_standard_fonts(pdev);
346
347
50.0k
    if (ppsf != NULL)
348
50.0k
        memset(ppsf, 0, PDF_NUM_STANDARD_FONTS * sizeof(*ppsf));
349
50.0k
}
350
351
/* ---------------- Font resources ---------------- */
352
353
/* ------ Private ------ */
354
355
static int
356
pdf_resize_array(gs_memory_t *mem, void **p, int elem_size, uint old_size, uint new_size)
357
4.13k
{
358
4.13k
    void *q = gs_alloc_byte_array(mem, new_size, elem_size, "pdf_resize_array");
359
360
4.13k
    if (q == NULL)
361
0
        return_error(gs_error_VMerror);
362
4.13k
    memset((char *)q + elem_size * old_size, 0, elem_size * (new_size - old_size));
363
4.13k
    memcpy(q, *p, elem_size * old_size);
364
4.13k
    gs_free_object(mem, *p, "pdf_resize_array");
365
4.13k
    *p = q;
366
4.13k
    return 0;
367
4.13k
}
368
369
/*
370
 * Allocate and (minimally) initialize a font resource.
371
 */
372
static int
373
font_resource_alloc(gx_device_pdf *pdev, pdf_font_resource_t **ppfres,
374
                    pdf_resource_type_t rtype, gs_id rid, font_type ftype,
375
                    int chars_count,
376
                    pdf_font_write_contents_proc_t write_contents)
377
50.0k
{
378
50.0k
    gs_memory_t *mem = pdev->pdf_memory;
379
50.0k
    pdf_font_resource_t *pfres;
380
50.0k
    double *widths = 0;
381
50.0k
    byte *used = 0;
382
50.0k
    int code;
383
50.0k
    bool is_CID_font = (ftype == ft_CID_encrypted || ftype == ft_CID_TrueType);
384
385
50.0k
    if (chars_count != 0) {
386
48.4k
        uint size = (chars_count + 7) / 8;
387
388
48.4k
        if (!is_CID_font) {
389
46.8k
            widths = (void *)gs_alloc_byte_array(mem, chars_count, sizeof(*widths),
390
46.8k
                                                "font_resource_alloc(Widths)");
391
46.8k
        } else {
392
            /*  Delay allocation because we don't know which WMode will be used. */
393
1.60k
        }
394
48.4k
        used = gs_alloc_bytes(mem, size, "font_resource_alloc(used)");
395
48.4k
        if ((!is_CID_font && widths == 0) || used == 0) {
396
0
            code = gs_note_error(gs_error_VMerror);
397
0
            goto fail;
398
0
        }
399
48.4k
        if (!is_CID_font)
400
46.8k
            memset(widths, 0, chars_count * sizeof(*widths));
401
48.4k
        memset(used, 0, size);
402
48.4k
    }
403
50.0k
    code = pdf_alloc_resource(pdev, rtype, rid, (pdf_resource_t **)&pfres, -1L);
404
50.0k
    if (code < 0)
405
0
        goto fail;
406
50.0k
    pfres->FontType = ftype;
407
50.0k
    pfres->count = chars_count;
408
50.0k
    pfres->Widths = widths;
409
50.0k
    pfres->used = used;
410
50.0k
    pfres->write_contents = write_contents;
411
50.0k
    pfres->res_ToUnicode = NULL;
412
50.0k
    pfres->cmap_ToUnicode = NULL;
413
50.0k
    pfres->mark_glyph = 0;
414
50.0k
    pfres->mark_glyph_data = 0;
415
50.0k
    pfres->u.simple.standard_glyph_code_for_notdef = gs_c_name_glyph((const byte *)".notdef", 7) - gs_c_min_std_encoding_glyph;
416
50.0k
    *ppfres = pfres;
417
50.0k
    return 0;
418
0
 fail:
419
0
    gs_free_object(mem, used, "font_resource_alloc(used)");
420
0
    gs_free_object(mem, widths, "font_resource_alloc(Widths)");
421
0
    return code;
422
50.0k
}
423
424
int font_resource_free(gx_device_pdf *pdev, pdf_font_resource_t *pdfont)
425
50.0k
{
426
50.0k
    if(pdfont->BaseFont.size
427
50.0k
       && (pdfont->base_font == NULL || !pdfont->base_font->is_standard)) {
428
429
40.9k
        gs_free_string(pdev->pdf_memory, pdfont->BaseFont.data, pdfont->BaseFont.size, "Free BaseFont string");
430
40.9k
        pdfont->BaseFont.data = (byte *)0L;
431
40.9k
        pdfont->BaseFont.size = 0;
432
40.9k
    }
433
50.0k
    if(pdfont->Widths) {
434
48.4k
        gs_free_object(pdev->pdf_memory, pdfont->Widths, "Free Widths array");
435
48.4k
        pdfont->Widths = 0;
436
48.4k
    }
437
50.0k
    if(pdfont->used) {
438
48.4k
        gs_free_object(pdev->pdf_memory, pdfont->used, "Free used array");
439
48.4k
        pdfont->used = 0;
440
48.4k
    }
441
50.0k
    if(pdfont->res_ToUnicode) {
442
        /* ToUnicode resources are tracked amd released separately */
443
5.01k
        pdfont->res_ToUnicode = 0;
444
5.01k
    }
445
50.0k
    if(pdfont->cmap_ToUnicode) {
446
5.36k
        gs_cmap_ToUnicode_free(pdev->pdf_memory, pdfont->cmap_ToUnicode);
447
5.36k
        pdfont->cmap_ToUnicode = 0;
448
5.36k
    }
449
50.0k
    switch(pdfont->FontType) {
450
1.60k
        case ft_composite:
451
1.60k
            if (pdfont->u.type0.CMapName_data != NULL) {
452
1.60k
                gs_free_object(pdev->memory->non_gc_memory, (byte *)pdfont->u.type0.CMapName_data, "font_resource_free(CMapName)");
453
1.60k
                pdfont->u.type0.CMapName_data = NULL;
454
1.60k
                pdfont->u.type0.CMapName_size = 0;
455
1.60k
            }
456
1.60k
            break;
457
0
        case ft_PCL_user_defined:
458
0
        case ft_MicroType:
459
0
        case ft_GL2_stick_user_defined:
460
3.76k
        case ft_user_defined:
461
3.76k
        case ft_PDF_user_defined:
462
3.76k
        case ft_GL2_531:
463
3.76k
            if(pdfont->u.simple.Encoding) {
464
1.46k
                int ix;
465
377k
                for (ix = 0; ix <= 255;ix++)
466
375k
                    gs_free_object(pdev->pdf_memory->non_gc_memory, pdfont->u.simple.Encoding[ix].data, "Free copied glyph name string");
467
1.46k
                gs_free_object(pdev->pdf_memory, pdfont->u.simple.Encoding, "Free simple Encoding");
468
1.46k
                pdfont->u.simple.Encoding = 0;
469
1.46k
            }
470
3.76k
            if(pdfont->u.simple.v) {
471
1.46k
                gs_free_object(pdev->pdf_memory, pdfont->u.simple.v, "Free simple v");
472
1.46k
                pdfont->u.simple.v = 0;
473
1.46k
            }
474
3.76k
            if (pdfont->u.simple.s.type3.char_procs) {
475
3.72k
                pdf_free_charproc_ownership(pdev, (pdf_resource_t *)pdfont->u.simple.s.type3.char_procs);
476
3.72k
                pdfont->u.simple.s.type3.char_procs = 0;
477
3.72k
            }
478
3.76k
            if (pdfont->u.simple.s.type3.cached) {
479
1.46k
                gs_free_object(pdev->pdf_memory, pdfont->u.simple.s.type3.cached, "Free type 3 cached array");
480
1.46k
                pdfont->u.simple.s.type3.cached = NULL;
481
1.46k
            }
482
3.76k
            if (pdfont->u.simple.s.type3.Resources != NULL) {
483
1.46k
                cos_free((cos_object_t *)pdfont->u.simple.s.type3.Resources, "Free type 3 Resources dictionary");
484
1.46k
                pdfont->u.simple.s.type3.Resources = NULL;
485
1.46k
            }
486
3.76k
            break;
487
236
        case ft_CID_encrypted:
488
1.60k
        case ft_CID_TrueType:
489
1.60k
            if(pdfont->u.cidfont.Widths2) {
490
30
                gs_free_object(pdev->pdf_memory, pdfont->u.cidfont.Widths2, "Free CIDFont Widths2 array");
491
30
                pdfont->u.cidfont.Widths2 = NULL;
492
30
            }
493
1.60k
            if(pdfont->u.cidfont.v) {
494
30
                gs_free_object(pdev->pdf_memory, pdfont->u.cidfont.v, "Free CIDFont v array");
495
30
                pdfont->u.cidfont.v = NULL;
496
30
            }
497
1.60k
            if(pdfont->u.cidfont.used2) {
498
1.60k
                gs_free_object(pdev->pdf_memory, pdfont->u.cidfont.used2, "Free CIDFont used2");
499
1.60k
                pdfont->u.cidfont.used2 = 0;
500
1.60k
            }
501
1.60k
            if(pdfont->u.cidfont.CIDToGIDMap) {
502
1.37k
                gs_free_object(pdev->pdf_memory, pdfont->u.cidfont.CIDToGIDMap, "Free CIDToGID map");
503
1.37k
                pdfont->u.cidfont.CIDToGIDMap = 0;
504
1.37k
            }
505
1.60k
            break;
506
43.0k
        default:
507
43.0k
            if(pdfont->u.simple.Encoding) {
508
43.0k
                int ix;
509
11.0M
                for (ix = 0; ix <= 255;ix++)
510
11.0M
                    gs_free_object(pdev->pdf_memory->non_gc_memory, pdfont->u.simple.Encoding[ix].data, "Free copied glyph name string");
511
43.0k
                gs_free_object(pdev->pdf_memory, pdfont->u.simple.Encoding, "Free simple Encoding");
512
43.0k
                pdfont->u.simple.Encoding = 0;
513
43.0k
            }
514
43.0k
            if(pdfont->u.simple.v) {
515
43.0k
                gs_free_object(pdev->pdf_memory, pdfont->u.simple.v, "Free simple v");
516
43.0k
                pdfont->u.simple.v = 0;
517
43.0k
            }
518
43.0k
            break;
519
50.0k
    }
520
50.0k
    if (pdfont->object) {
521
50.0k
        gs_free_object(pdev->pdf_memory, pdfont->object, "Free font resource object");
522
50.0k
        pdfont->object = 0;
523
50.0k
    }
524
    /* We free FontDescriptor resources separately */
525
50.0k
    if(pdfont->FontDescriptor)
526
39.3k
        pdfont->FontDescriptor = NULL;
527
10.6k
    else {
528
10.6k
        if (pdfont->base_font) {
529
            /* Normally we free the 'base font' when we free the Font Descriptor,
530
             * but if we have no font descriptor (we are not embedding the font),
531
             * we won't free the copies of the font, or any other associated memory,
532
             * so do it now.
533
             */
534
5.31k
            pdf_base_font_t *pbfont = pdfont->base_font;
535
5.31k
            gs_font *copied = (gs_font *)pbfont->copied, *complete = (gs_font *)pbfont->complete;
536
537
5.31k
            if (copied)
538
5.31k
                gs_free_copied_font(copied);
539
5.31k
            if (complete && copied != complete) {
540
0
                gs_free_copied_font(complete);
541
0
                pbfont->complete = 0;
542
0
            }
543
5.31k
            pbfont->copied = 0;
544
5.31k
            if (pbfont && pbfont->font_name.size) {
545
5.31k
                gs_free_string(pdev->pdf_memory, pbfont->font_name.data, pbfont->font_name.size, "Free BaseFont FontName string");
546
5.31k
                pbfont->font_name.data = (byte *)0L;
547
5.31k
                pbfont->font_name.size = 0;
548
5.31k
            }
549
5.31k
            if (pbfont) {
550
5.31k
                gs_free_object(pdev->pdf_memory, pbfont, "Free base font from FontDescriptor)");
551
5.31k
                pdfont->base_font = 0;
552
5.31k
            }
553
5.31k
        }
554
10.6k
    }
555
50.0k
    return 0;
556
50.0k
}
557
558
int
559
pdf_assign_font_object_id(gx_device_pdf *pdev, pdf_font_resource_t *pdfont)
560
2.29M
{
561
2.29M
    if (pdf_resource_id((pdf_resource_t *)pdfont) == -1) {
562
41.9k
        int code;
563
564
41.9k
        pdf_reserve_object_id(pdev, (pdf_resource_t *)pdfont, 0);
565
41.9k
        code = pdf_mark_font_descriptor_used(pdev, pdfont->FontDescriptor);
566
41.9k
        if (code < 0)
567
0
            return code;
568
41.9k
        if (pdfont->FontType == 0) {
569
1.55k
            pdf_font_resource_t *pdfont1 = pdfont->u.type0.DescendantFont;
570
571
1.55k
            if (pdf_font_id(pdfont1) == -1) {
572
1.55k
                pdf_reserve_object_id(pdev, (pdf_resource_t *)pdfont1, 0);
573
1.55k
                code = pdf_mark_font_descriptor_used(pdev, pdfont1->FontDescriptor);
574
1.55k
                if (code < 0)
575
0
                    return code;
576
1.55k
            }
577
1.55k
        }
578
41.9k
    }
579
2.29M
    return 0;
580
2.29M
}
581
582
static int
583
font_resource_simple_alloc(gx_device_pdf *pdev, pdf_font_resource_t **ppfres,
584
                           gs_id rid, font_type ftype, int chars_count,
585
                           pdf_font_write_contents_proc_t write_contents)
586
46.8k
{
587
46.8k
    pdf_font_resource_t *pfres;
588
46.8k
    int code = font_resource_alloc(pdev, &pfres, resourceFont, rid, ftype,
589
46.8k
                                   chars_count, write_contents);
590
591
46.8k
    if (code < 0)
592
0
        return code;
593
46.8k
    pfres->u.simple.FirstChar = 256;
594
46.8k
    pfres->u.simple.LastChar = -1;
595
46.8k
    pfres->u.simple.BaseEncoding = -1;
596
46.8k
    pfres->u.simple.preferred_encoding_index = -1;
597
46.8k
    pfres->u.simple.last_reserved_char = -1;
598
46.8k
    *ppfres = pfres;
599
46.8k
    return 0;
600
46.8k
}
601
int
602
font_resource_encoded_alloc(gx_device_pdf *pdev, pdf_font_resource_t **ppfres,
603
                            gs_id rid, font_type ftype,
604
                            pdf_font_write_contents_proc_t write_contents)
605
44.5k
{
606
44.5k
    pdf_encoding_element_t *Encoding = (pdf_encoding_element_t *)gs_alloc_bytes(pdev->pdf_memory, (size_t)256 * sizeof(pdf_encoding_element_t), "font_resource_encoded_alloc");
607
44.5k
    gs_point *v = (gs_point *)gs_alloc_byte_array(pdev->pdf_memory,
608
44.5k
                    256, sizeof(gs_point), "pdf_font_simple_alloc");
609
44.5k
    pdf_font_resource_t *pdfont;
610
44.5k
    int code, i;
611
612
44.5k
    if (v == 0 || Encoding == 0) {
613
0
        gs_free_object(pdev->pdf_memory, Encoding,
614
0
                       "font_resource_encoded_alloc");
615
0
        gs_free_object(pdev->pdf_memory, v,
616
0
                       "font_resource_encoded_alloc");
617
0
        return_error(gs_error_VMerror);
618
0
    }
619
44.5k
    code = font_resource_simple_alloc(pdev, &pdfont, rid, ftype,
620
44.5k
                                      256, write_contents);
621
44.5k
    if (code < 0) {
622
0
        gs_free_object(pdev->pdf_memory, Encoding,
623
0
                       "font_resource_encoded_alloc");
624
0
        gs_free_object(pdev->pdf_memory, v,
625
0
                       "font_resource_encoded_alloc");
626
0
        return_error(gs_error_VMerror);
627
0
    }
628
44.5k
    memset(v, 0, 256 * sizeof(*v));
629
44.5k
    memset(Encoding, 0, 256 * sizeof(*Encoding));
630
11.4M
    for (i = 0; i < 256; ++i)
631
11.3M
        Encoding[i].glyph = GS_NO_GLYPH;
632
44.5k
    pdfont->u.simple.Encoding = Encoding;
633
44.5k
    pdfont->u.simple.v = v;
634
44.5k
    *ppfres = pdfont;
635
44.5k
    return 0;
636
44.5k
}
637
638
/*
639
 * Record whether a Type 1 or Type 2 font is a Multiple Master instance.
640
 */
641
static void
642
set_is_MM_instance(pdf_font_resource_t *pdfont, const gs_font_base *pfont)
643
43.0k
{
644
43.0k
    switch (pfont->FontType) {
645
33.8k
    case ft_encrypted:
646
34.9k
    case ft_encrypted2:
647
34.9k
        pdfont->u.simple.s.type1.is_MM_instance =
648
34.9k
            ((const gs_font_type1 *)pfont)->data.WeightVector.count > 0;
649
43.0k
    default:
650
43.0k
        break;
651
43.0k
    }
652
43.0k
}
653
654
/* ------ Generic public ------ */
655
656
/* Resize font resource arrays. */
657
int
658
pdf_resize_resource_arrays(gx_device_pdf *pdev, pdf_font_resource_t *pfres, uint chars_count)
659
367k
{
660
    /* This function fixes CID fonts that provide a lesser CIDCount than
661
       CIDs used in a document. Rather PS requires to print CID=0,
662
       we need to provide a bigger CIDCount since we don't
663
       re-encode the text. The text should look fine if the
664
       viewer application substitutes the font. */
665
367k
    gs_memory_t *mem = pdev->pdf_memory;
666
367k
    int code;
667
668
    /* Ensure the 'round up' code below doesn't overflow an unsigned int when adding 7 */
669
367k
    if (pfres->count >= max_uint - 7 || chars_count > max_uint - 7)
670
2
        return_error(gs_error_rangecheck);
671
672
367k
    if (chars_count < pfres->count)
673
366k
        return 0;
674
1.03k
    if (pfres->Widths != NULL) {
675
760
        code = pdf_resize_array(mem, (void **)&pfres->Widths, sizeof(*pfres->Widths),
676
760
                    pfres->count, chars_count);
677
760
        if (code < 0)
678
0
            return code;
679
760
    }
680
1.03k
    code = pdf_resize_array(mem, (void **)&pfres->used, sizeof(*pfres->used),
681
1.03k
                    (pfres->count + 7) / 8, (chars_count + 7) / 8);
682
1.03k
    if (code < 0)
683
0
        return code;
684
1.03k
    if (pfres->FontType == ft_CID_encrypted || pfres->FontType == ft_CID_TrueType) {
685
1.03k
        if (pfres->u.cidfont.v != NULL) {
686
320
            code = pdf_resize_array(mem, (void **)&pfres->u.cidfont.v,
687
320
                    sizeof(*pfres->u.cidfont.v), pfres->count * 2, chars_count * 2);
688
320
            if (code < 0)
689
0
                return code;
690
320
        }
691
1.03k
        if (pfres->u.cidfont.Widths2 != NULL) {
692
320
            code = pdf_resize_array(mem, (void **)&pfres->u.cidfont.Widths2,
693
320
                    sizeof(*pfres->u.cidfont.Widths2), pfres->count, chars_count);
694
320
            if (code < 0)
695
0
                return code;
696
320
        }
697
1.03k
    }
698
1.03k
    if (pfres->FontType == ft_CID_TrueType) {
699
654
        if (pfres->u.cidfont.CIDToGIDMap != NULL) {
700
654
            code = pdf_resize_array(mem, (void **)&pfres->u.cidfont.CIDToGIDMap,
701
654
                    sizeof(*pfres->u.cidfont.CIDToGIDMap), pfres->count, chars_count);
702
654
            if (code < 0)
703
0
                return code;
704
654
            pfres->u.cidfont.CIDToGIDMapLength = chars_count;
705
654
        }
706
654
    }
707
1.03k
    if (pfres->FontType == ft_CID_encrypted || pfres->FontType == ft_CID_TrueType) {
708
1.03k
        if (pfres->u.cidfont.used2 != NULL) {
709
1.03k
            code = pdf_resize_array(mem, (void **)&pfres->u.cidfont.used2,
710
1.03k
                    sizeof(*pfres->u.cidfont.used2),
711
1.03k
                    (pfres->count + 7) / 8, (chars_count + 7) / 8);
712
1.03k
            if (code < 0)
713
0
                return code;
714
1.03k
        }
715
1.03k
    }
716
1.03k
    pfres->count = chars_count;
717
1.03k
    return 0;
718
1.03k
}
719
720
/* Get the object ID of a font resource. */
721
int64_t
722
pdf_font_id(const pdf_font_resource_t *pdfont)
723
46.6k
{
724
46.6k
    return pdf_resource_id((const pdf_resource_t *)pdfont);
725
46.6k
}
726
727
/*
728
 * Return the (copied, subset) font associated with a font resource.
729
 * If this font resource doesn't have one (Type 0 or Type 3), return 0.
730
 */
731
gs_font_base *
732
pdf_font_resource_font(const pdf_font_resource_t *pdfont, bool complete)
733
60.1M
{
734
60.1M
    if (pdfont->base_font != NULL)
735
5.35M
        return pdf_base_font_font(pdfont->base_font, complete);
736
54.7M
    if (pdfont->FontDescriptor == 0)
737
3.07M
        return 0;
738
51.7M
    return pdf_font_descriptor_font(pdfont->FontDescriptor, complete);
739
54.7M
}
740
741
/*
742
 * Determine the embedding status of a font.  If the font is in the base
743
 * 14, store its index (0..13) in *pindex and its similarity to the base
744
 * font (as determined by the font's same_font procedure) in *psame.
745
 */
746
static bool
747
font_is_symbolic(const gs_font *font)
748
0
{
749
0
    if (font->FontType == ft_composite || font->FontType == ft_CID_encrypted ||
750
0
        font->FontType == ft_CID_user_defined || font->FontType == ft_CID_TrueType ||
751
0
        font->FontType == ft_CID_bitmap)
752
0
        return false;   /* arbitrary */
753
0
    switch (((const gs_font_base *)font)->nearest_encoding_index) {
754
0
    case ENCODING_INDEX_STANDARD:
755
0
    case ENCODING_INDEX_ISOLATIN1:
756
0
    case ENCODING_INDEX_WINANSI:
757
0
    case ENCODING_INDEX_MACROMAN:
758
0
        return false;
759
0
    default:
760
0
        return true;
761
0
    }
762
0
}
763
static bool
764
embed_list_includes(const gs_param_string_array *psa, const byte *chars,
765
                    uint size)
766
77.5k
{
767
77.5k
    uint i;
768
769
613k
    for (i = 0; i < psa->size; ++i)
770
537k
        if (!bytes_compare(psa->data[i].data, psa->data[i].size, chars, size))
771
2.16k
            return true;
772
75.4k
    return false;
773
77.5k
}
774
static bool
775
embed_as_standard(gx_device_pdf *pdev, gs_font *font, int index,
776
                  pdf_char_glyph_pair_t *pairs, int num_glyphs)
777
5.48k
{
778
5.48k
    if (font->is_resource) {
779
5.31k
        return true;
780
5.31k
    }
781
170
    if (find_std_appearance(pdev, (gs_font_base *)font, -1,
782
170
                            pairs, num_glyphs) == index)
783
0
        return true;
784
170
    if (!scan_for_standard_fonts(pdev, font->dir))
785
170
        return false;
786
0
    return (find_std_appearance(pdev, (gs_font_base *)font, -1,
787
0
                                pairs, num_glyphs) == index);
788
170
}
789
static bool
790
has_extension_glyphs(gs_font *pfont)
791
3.20k
{
792
3.20k
    psf_glyph_enum_t genum;
793
3.20k
    gs_glyph glyph;
794
3.20k
    gs_const_string str;
795
3.20k
    int code, j = 0, l;
796
3.20k
    const int sl = strlen(gx_extendeg_glyph_name_separator);
797
798
3.20k
    psf_enumerate_glyphs_begin(&genum, (gs_font *)pfont, NULL, 0, GLYPH_SPACE_NAME);
799
2.51M
    for (glyph = GS_NO_GLYPH; (psf_enumerate_glyphs_next(&genum, &glyph)) != 1; ) {
800
2.51M
        code = pfont->procs.glyph_name(pfont, glyph, &str);
801
2.51M
        if (code < 0)
802
0
            return code;
803
2.51M
        l = str.size - sl;
804
11.5M
        for (j = 0; j < l; j ++)
805
9.02M
            if (!memcmp(gx_extendeg_glyph_name_separator, str.data + j, sl))
806
0
                return true;
807
2.51M
    }
808
3.20k
    psf_enumerate_glyphs_reset(&genum);
809
3.20k
    return false;
810
3.20k
}
811
812
pdf_font_embed_t
813
pdf_font_embed_status(gx_device_pdf *pdev, gs_font *font, int *pindex,
814
                      pdf_char_glyph_pair_t *pairs, int num_glyphs, font_type *orig_type)
815
77.9k
{
816
77.9k
    const gs_font_name *fn = &font->font_name;
817
77.9k
    const byte *chars = fn->chars;
818
77.9k
    uint size = fn->size;
819
77.9k
    int index = pdf_find_standard_font_name(chars, size);
820
77.9k
    bool embed_as_standard_called = false;
821
77.9k
    bool do_embed_as_standard = false; /* Quiet compiler. */
822
77.9k
    int code;
823
77.9k
    gs_font_info_t info;
824
825
77.9k
    memset(&info, 0x00, sizeof(gs_font_info_t));
826
77.9k
    code = font->procs.font_info(font, NULL, FONT_INFO_EMBEDDING_RIGHTS | FONT_INFO_EMBEDDED, &info);
827
77.9k
    if (code == 0 && (info.members & FONT_INFO_EMBEDDING_RIGHTS)) {
828
34.6k
        if (((info.EmbeddingRights == 0x0002) || (info.EmbeddingRights & 0x0200))
829
34.6k
            && !IsInWhiteList ((const char *)chars, size)) {
830
            /* See the OpenType specification, "The 'OS/2' and Windows Metrics Table" for details
831
               of the fstype parameter. This is a bitfield, currently we forbid embedding of fonts
832
               with these bits set:
833
               bit 1  0x0002  Fonts that have only this bit set must not be modified, embedded or
834
                                exchanged in any manner.
835
               bit 9  0x0200  Bitmap embedding only.
836
837
               Note for Restricted License embedding (bit 1), this must be the only level of embedding
838
               selected (see the OpenType spec).
839
             */
840
373
            char name[gs_font_name_max + 1];
841
373
            int len;
842
843
373
            len = min(gs_font_name_max, font->font_name.size);
844
373
            memcpy(name, font->font_name.chars, len);
845
373
            name[len] = 0;
846
373
            emprintf1(pdev->pdf_memory,
847
373
                      "\nWarning: Font %s cannot be embedded because of licensing restrictions\n",
848
373
                      name);
849
373
            return FONT_EMBED_NO;
850
373
        }
851
34.6k
    }
852
    /*
853
     * The behavior of Acrobat Distiller changed between 3.0 (PDF 1.2),
854
     * which will never embed the base 14 fonts, and 4.0 (PDF 1.3), which
855
     * doesn't treat them any differently from any other fonts.  However,
856
     * if any of the base 14 fonts is not embedded, it still requires
857
     * special treatment.
858
     */
859
77.5k
    if (pindex)
860
77.5k
        *pindex = index;
861
77.5k
    if (pdev->PDFX != 0 || pdev->PDFA != 0)
862
0
        return FONT_EMBED_YES;
863
77.5k
    if (pdev->CompatibilityLevel < 1.3) {
864
38.1k
        if (index >= 0 &&
865
38.1k
            (embed_as_standard_called = true,
866
3.31k
                do_embed_as_standard = embed_as_standard(pdev, font, index, pairs, num_glyphs))) {
867
3.20k
            if (pdev->ForOPDFRead && has_extension_glyphs(font))
868
0
                return FONT_EMBED_YES;
869
870
3.20k
            if (pdev->ForOPDFRead && embed_list_includes(&pdev->params.AlwaysEmbed, chars, size))
871
0
                    return FONT_EMBED_YES;
872
873
3.20k
            return FONT_EMBED_STANDARD;
874
3.20k
        }
875
38.1k
    }
876
    /* Check the Embed lists. */
877
74.3k
    if (!embed_list_includes(&pdev->params.NeverEmbed, chars, size) ||
878
74.3k
        (index >= 0 &&
879
2.16k
            !(embed_as_standard_called ? do_embed_as_standard :
880
2.16k
             (embed_as_standard_called = true,
881
2.16k
              (do_embed_as_standard = embed_as_standard(pdev, font, index, pairs, num_glyphs)))))
882
        /* Ignore NeverEmbed for a non-standard font with a standard name */
883
74.3k
        )
884
72.2k
    {
885
        /* We always mebed fonts that were embedded in the input, so if we embed substitutes as well then we are embedding everything
886
         * which isn't explicitly *not* embedded, via the NeverEmbed test above
887
         */
888
72.2k
        if (pdev->EmbedSubstituteFonts)
889
72.2k
            return FONT_EMBED_YES;
890
        /* We aren't embedding subsitutes, check the AlwaysEmbed list, which overrides that */
891
0
        if (embed_list_includes(&pdev->params.AlwaysEmbed, chars, size))
892
0
                return FONT_EMBED_YES;
893
0
        if (pdev->params.EmbedAllFonts) {
894
0
            if (!(info.members & FONT_INFO_EMBEDDED) || info.FontEmbedded)
895
0
                return FONT_EMBED_YES;
896
0
        } else {
897
            /* Always embed symbolic fonts (we have to ) */
898
0
            if (font_is_symbolic(font))
899
0
                return FONT_EMBED_YES;
900
0
        }
901
0
    }
902
2.10k
    if (index >= 0 &&
903
2.10k
        (embed_as_standard_called ? do_embed_as_standard :
904
2.10k
         embed_as_standard(pdev, font, index, pairs, num_glyphs)))
905
2.10k
        return FONT_EMBED_STANDARD;
906
907
0
    if (info.members & FONT_INFO_EMBEDDED)
908
0
        *orig_type = info.orig_FontType;
909
0
    return FONT_EMBED_NO;
910
2.10k
}
911
912
/*
913
 * Compute the BaseFont of a font according to the algorithm described
914
 * in gdevpdtf.h.
915
 */
916
int
917
pdf_compute_BaseFont(gx_device_pdf *pdev, pdf_font_resource_t *pdfont, bool finish)
918
87.6k
{
919
87.6k
    pdf_font_resource_t *pdsubf = pdfont;
920
87.6k
    gs_string fname;
921
87.6k
    uint size;
922
87.6k
    byte *data;
923
924
87.6k
    if (pdfont->FontType == ft_composite) {
925
3.15k
        int code;
926
927
3.15k
        pdsubf = pdfont->u.type0.DescendantFont;
928
3.15k
        code = pdf_compute_BaseFont(pdev, pdsubf, finish);
929
3.15k
        if (code < 0)
930
0
            return code;
931
3.15k
        fname = pdsubf->BaseFont;
932
3.15k
    }
933
84.4k
    else if (pdfont->FontDescriptor == 0) {
934
        /* Type 3 font, or has its BaseFont computed in some other way. */
935
8.85k
        return 0;
936
8.85k
    } else
937
75.6k
        fname = *pdf_font_descriptor_base_name(pdsubf->FontDescriptor);
938
78.7k
    size = fname.size;
939
78.7k
    data = gs_alloc_string(pdev->pdf_memory, size,
940
78.7k
                           "pdf_compute_BaseFont");
941
78.7k
    if (data == 0)
942
0
        return_error(gs_error_VMerror);
943
78.7k
    memcpy(data, fname.data, size);
944
78.7k
    switch (pdfont->FontType) {
945
3.15k
    case ft_composite:
946
        /* Previously we copied the name of the original CMap onto the font name
947
         * but this doesn't make any sense.
948
         */
949
3.15k
        break;
950
54.9k
    case ft_encrypted:
951
57.0k
    case ft_encrypted2:
952
57.0k
        if (pdfont->u.simple.s.type1.is_MM_instance &&
953
57.0k
            !pdf_font_descriptor_embedding(pdfont->FontDescriptor)
954
57.0k
            ) {
955
            /* Replace spaces by underscores in the base name. */
956
0
            uint i;
957
958
0
            for (i = 0; i < size; ++i)
959
0
                if (data[i] == ' ')
960
0
                    data[i] = '_';
961
0
        }
962
57.0k
        break;
963
12.2k
    case ft_TrueType:
964
17.7k
    case ft_CID_TrueType: {
965
        /* Remove spaces from the base name. */
966
17.7k
        uint i, j;
967
968
193k
        for (i = j = 0; i < size; ++i)
969
175k
            if (data[i] != ' ')
970
175k
                data[j++] = data[i];
971
17.7k
        data = gs_resize_string(pdev->pdf_memory, data, i, j,
972
17.7k
                                "pdf_compute_BaseFont");
973
17.7k
        size = j;
974
17.7k
        break;
975
12.2k
    }
976
844
    default:
977
844
        break;
978
78.7k
    }
979
78.7k
    if (pdfont->BaseFont.size)
980
37.8k
        gs_free_string(pdev->pdf_memory, pdfont->BaseFont.data, pdfont->BaseFont.size, "Replacing BaseFont string");
981
78.7k
    pdfont->BaseFont.data = fname.data = data;
982
78.7k
    pdfont->BaseFont.size = fname.size = size;
983
    /* Compute names for subset fonts. */
984
78.7k
    if (finish && pdfont->FontDescriptor != NULL &&
985
78.7k
        pdf_font_descriptor_is_subset(pdfont->FontDescriptor) &&
986
78.7k
        !pdf_has_subset_prefix(fname.data, fname.size) &&
987
78.7k
        pdf_font_descriptor_embedding(pdfont->FontDescriptor)
988
78.7k
        ) {
989
34.6k
        int code;
990
34.6k
        gs_font_base *pbfont = pdf_font_resource_font(pdfont, false);
991
992
34.6k
        if (pdfont->FontDescriptor)
993
34.6k
            code = pdf_add_subset_prefix(pdev, &fname, pdfont->used, pdfont->count, pdf_fontfile_hash(pdfont->FontDescriptor));
994
0
        else
995
0
            code = pdf_add_subset_prefix(pdev, &fname, pdfont->used, pdfont->count, 0);
996
997
34.6k
        if (code < 0)
998
0
            return code;
999
34.6k
        pdfont->BaseFont = fname;
1000
1001
        /* Don't write a UID for subset fonts. */
1002
34.6k
        if (uid_is_XUID(&pbfont->UID)) {
1003
9.11k
            uid_free(&pbfont->UID, pbfont->memory, "gs_font_finalize");
1004
9.11k
        }
1005
34.6k
        uid_set_invalid(&pbfont->UID);
1006
34.6k
    }
1007
78.7k
    if (pdfont->FontType != ft_composite && pdsubf->FontDescriptor)
1008
75.6k
        *pdf_font_descriptor_name(pdsubf->FontDescriptor) = fname;
1009
78.7k
    return 0;
1010
78.7k
}
1011
1012
/* ------ Type 0 ------ */
1013
1014
/* Allocate a Type 0 font resource. */
1015
int
1016
pdf_font_type0_alloc(gx_device_pdf *pdev, pdf_font_resource_t **ppfres,
1017
                     gs_id rid, pdf_font_resource_t *DescendantFont,
1018
                     const gs_const_string *CMapName)
1019
1.60k
{
1020
1.60k
    int code = font_resource_alloc(pdev, ppfres, resourceFont, rid,
1021
1.60k
                                   ft_composite, 0, pdf_write_contents_type0);
1022
1023
1.60k
    if (code >= 0) {
1024
1.60k
        byte *chars = NULL;
1025
1026
1.60k
        (*ppfres)->u.type0.DescendantFont = DescendantFont;
1027
1028
1.60k
        chars = gs_alloc_bytes(pdev->pdf_memory->non_gc_memory, CMapName->size, "pdf_font_resource_t(CMapName)");
1029
1.60k
        if (chars == 0)
1030
0
            return_error(gs_error_VMerror);
1031
1.60k
        memcpy(chars, CMapName->data, CMapName->size);
1032
1.60k
        (*ppfres)->u.type0.CMapName_data = chars;
1033
1.60k
        (*ppfres)->u.type0.CMapName_size = CMapName->size;
1034
1035
1.60k
        (*ppfres)->u.type0.font_index = 0;
1036
1.60k
        code = pdf_compute_BaseFont(pdev, *ppfres, false);
1037
1.60k
    }
1038
1.60k
    return code;
1039
1.60k
}
1040
1041
/* ------ Type 3 ------ */
1042
1043
/* Allocate a Type 3 font resource for sinthesyzed bitmap fonts. */
1044
int
1045
pdf_font_type3_alloc(gx_device_pdf *pdev, pdf_font_resource_t **ppfres,
1046
                     pdf_font_write_contents_proc_t write_contents)
1047
2.29k
{
1048
2.29k
    return font_resource_simple_alloc(pdev, ppfres, gs_no_id, ft_user_defined,
1049
2.29k
                                      256, write_contents);
1050
2.29k
}
1051
1052
/* ------ Standard (base 14) Type 1 or TrueType ------ */
1053
1054
/* Allocate a standard (base 14) font resource. */
1055
int
1056
pdf_font_std_alloc(gx_device_pdf *pdev, pdf_font_resource_t **ppfres,
1057
                   bool is_original, gs_id rid, gs_font_base *pfont, int index)
1058
5.31k
{
1059
5.31k
    pdf_font_resource_t *pdfont;
1060
5.31k
    int code = font_resource_encoded_alloc(pdev, &pdfont, rid, pfont->FontType,
1061
5.31k
                                           pdf_write_contents_std);
1062
5.31k
    const pdf_standard_font_info_t *psfi = &standard_font_info[index];
1063
5.31k
    pdf_standard_font_t *psf = &pdf_standard_fonts(pdev)[index];
1064
5.31k
    gs_matrix *orig_matrix = (is_original ? &pfont->FontMatrix : &psf->orig_matrix);
1065
1066
5.31k
    if (code < 0 ||
1067
5.31k
        (code = pdf_base_font_alloc(pdev, &pdfont->base_font, pfont, orig_matrix, true)) < 0
1068
5.31k
        )
1069
0
        return code;
1070
5.31k
    pdfont->BaseFont.data = (byte *)psfi->fname; /* break const */
1071
5.31k
    pdfont->BaseFont.size = strlen(psfi->fname);
1072
5.31k
    pdfont->mark_glyph = pfont->dir->ccache.mark_glyph;
1073
5.31k
    set_is_MM_instance(pdfont, pfont);
1074
5.31k
    if (is_original) {
1075
5.29k
        psf->pdfont = pdfont;
1076
5.29k
        psf->orig_matrix = pfont->FontMatrix;
1077
5.29k
    }
1078
5.31k
    *ppfres = pdfont;
1079
5.31k
    return 0;
1080
5.31k
}
1081
1082
/* ------ Other Type 1 or TrueType ------ */
1083
1084
/* Allocate a Type 1 or TrueType font resource. */
1085
int
1086
pdf_font_simple_alloc(gx_device_pdf *pdev, pdf_font_resource_t **ppfres,
1087
                      gs_id rid, pdf_font_descriptor_t *pfd)
1088
37.7k
{
1089
37.7k
    pdf_font_resource_t *pdfont;
1090
37.7k
    int code;
1091
1092
37.7k
    code = font_resource_encoded_alloc(pdev, &pdfont, rid,
1093
37.7k
                                           pdf_font_descriptor_FontType(pfd),
1094
37.7k
                                           pdf_write_contents_simple);
1095
1096
37.7k
    if (code < 0)
1097
0
        return(gs_note_error(code));
1098
37.7k
    pdfont->FontDescriptor = pfd;
1099
37.7k
    set_is_MM_instance(pdfont, pdf_font_descriptor_font(pfd, false));
1100
37.7k
    *ppfres = pdfont;
1101
37.7k
    return pdf_compute_BaseFont(pdev, pdfont, false);
1102
37.7k
}
1103
1104
/* ------ CID-keyed ------ */
1105
1106
/* Allocate a CIDFont resource. */
1107
int
1108
pdf_font_cidfont_alloc(gx_device_pdf *pdev, pdf_font_resource_t **ppfres,
1109
                       gs_id rid, pdf_font_descriptor_t *pfd)
1110
1.60k
{
1111
1.60k
    font_type FontType = pdf_font_descriptor_FontType(pfd);
1112
1.60k
    gs_font_base *font = pdf_font_descriptor_font(pfd, false);
1113
1.60k
    int chars_count;
1114
1.60k
    int code;
1115
1.60k
    pdf_font_write_contents_proc_t write_contents;
1116
1.60k
    const gs_cid_system_info_t *pcidsi;
1117
1.60k
    ushort *map = 0;
1118
1.60k
    pdf_font_resource_t *pdfont;
1119
1120
1.60k
    switch (FontType) {
1121
236
    case ft_CID_encrypted:
1122
236
        chars_count = ((const gs_font_cid0 *)font)->cidata.common.CIDCount;
1123
236
        pcidsi = &((const gs_font_cid0 *)font)->cidata.common.CIDSystemInfo;
1124
236
        write_contents = pdf_write_contents_cid0;
1125
236
        break;
1126
1.37k
    case ft_CID_TrueType:
1127
1.37k
        chars_count = ((const gs_font_cid2 *)font)->cidata.common.CIDCount;
1128
1.37k
        pcidsi = &((const gs_font_cid2 *)font)->cidata.common.CIDSystemInfo;
1129
1.37k
        map = (void *)gs_alloc_byte_array(pdev->pdf_memory, chars_count,
1130
1.37k
                                          sizeof(*map), "CIDToGIDMap");
1131
1.37k
        if (map == 0)
1132
0
            return_error(gs_error_VMerror);
1133
1.37k
        memset(map, 0, chars_count * sizeof(*map));
1134
1.37k
        write_contents = pdf_write_contents_cid2;
1135
1.37k
        break;
1136
0
    default:
1137
0
        return_error(gs_error_rangecheck);
1138
1.60k
    }
1139
1.60k
    code = font_resource_alloc(pdev, &pdfont, resourceCIDFont, rid, FontType,
1140
1.60k
                               chars_count, write_contents);
1141
1.60k
    if (code < 0)
1142
0
        return code;
1143
1.60k
    pdfont->FontDescriptor = pfd;
1144
1.60k
    pdfont->u.cidfont.CIDToGIDMap = map;
1145
1.60k
    pdfont->u.cidfont.CIDToGIDMapLength = chars_count;
1146
    /* fixme : Likely pdfont->u.cidfont.CIDToGIDMap duplicates
1147
       pdfont->FontDescriptor->base_font->copied->client_data->CIDMap.
1148
       Only difference is 0xFFFF designates unmapped CIDs.
1149
     */
1150
1.60k
    pdfont->u.cidfont.Widths2 = NULL;
1151
1.60k
    pdfont->u.cidfont.v = NULL;
1152
1.60k
    pdfont->u.cidfont.parent = NULL;
1153
    /* Don' know whether the font will use WMode 1,
1154
       so reserve it now. */
1155
1.60k
    pdfont->u.cidfont.used2 = gs_alloc_bytes(pdev->pdf_memory,
1156
1.60k
                (chars_count + 7) / 8, "pdf_font_cidfont_alloc");
1157
1.60k
    if (pdfont->u.cidfont.used2 == NULL)
1158
0
        return_error(gs_error_VMerror);
1159
1.60k
    memset(pdfont->u.cidfont.used2, 0, (chars_count + 7) / 8);
1160
    /*
1161
     * Write the CIDSystemInfo now, so we don't try to access it after
1162
     * the font may no longer be available.
1163
     */
1164
1.60k
    code = pdf_write_cid_systemInfo_separate(pdev, pcidsi, &pdfont->u.cidfont.CIDSystemInfo_id);
1165
1.60k
    if (code < 0)
1166
0
        return code;
1167
1.60k
    *ppfres = pdfont;
1168
1.60k
    return pdf_compute_BaseFont(pdev, pdfont, false);
1169
1.60k
}
1170
1171
int
1172
pdf_obtain_cidfont_widths_arrays(gx_device_pdf *pdev, pdf_font_resource_t *pdfont,
1173
                                 int wmode, double **w, double **w0, double **v)
1174
367k
{
1175
367k
    gs_memory_t *mem = pdev->pdf_memory;
1176
367k
    double *ww, *vv = 0, *ww0 = 0;
1177
367k
    int chars_count = pdfont->count;
1178
1179
367k
    *w0 = (wmode ? pdfont->Widths : NULL);
1180
367k
    *v = (wmode ? pdfont->u.cidfont.v : NULL);
1181
367k
    *w = (wmode ? pdfont->u.cidfont.Widths2 : pdfont->Widths);
1182
367k
    if (*w == NULL) {
1183
1.60k
        ww = (double *)gs_alloc_byte_array(mem, chars_count, sizeof(*ww),
1184
1.60k
                                                    "pdf_obtain_cidfont_widths_arrays");
1185
1.60k
        if (wmode) {
1186
30
            vv = (double *)gs_alloc_byte_array(mem, chars_count, sizeof(*vv) * 2,
1187
30
                                                    "pdf_obtain_cidfont_widths_arrays");
1188
30
            if (pdfont->Widths == 0) {
1189
30
                ww0 = (double *)gs_alloc_byte_array(mem, chars_count, sizeof(*ww0),
1190
30
                                                    "pdf_obtain_cidfont_widths_arrays");
1191
30
                pdfont->Widths = *w0 = ww0;
1192
30
                if (ww0 != 0)
1193
30
                    memset(ww0, 0, chars_count * sizeof(*ww));
1194
30
            } else
1195
0
                *w0 = ww0 = pdfont->Widths;
1196
30
        }
1197
1.60k
        if (ww == 0 || (wmode && vv == 0) || (wmode && ww0 == 0)) {
1198
0
            gs_free_object(mem, ww, "pdf_obtain_cidfont_widths_arrays");
1199
0
            gs_free_object(mem, vv, "pdf_obtain_cidfont_widths_arrays");
1200
0
            gs_free_object(mem, ww0, "pdf_obtain_cidfont_widths_arrays");
1201
0
            return_error(gs_error_VMerror);
1202
0
        }
1203
1.60k
        if (wmode)
1204
30
            memset(vv, 0, chars_count * 2 * sizeof(*vv));
1205
1.60k
        memset(ww, 0, chars_count * sizeof(*ww));
1206
1.60k
        if (wmode) {
1207
30
            pdfont->u.cidfont.Widths2 = *w = ww;
1208
30
            pdfont->u.cidfont.v = *v = vv;
1209
1.57k
        } else {
1210
1.57k
            pdfont->Widths = *w = ww;
1211
1.57k
            *v = NULL;
1212
1.57k
        }
1213
1.60k
    }
1214
367k
    return 0;
1215
367k
}
1216
1217
/*
1218
 * Convert True Type fonts into CID fonts for PDF/A.
1219
 */
1220
int
1221
pdf_convert_truetype_font(gx_device_pdf *pdev, pdf_resource_t *pres)
1222
48.4k
{
1223
48.4k
    if (pdev->PDFA == 0)
1224
48.4k
        return 0;
1225
0
    else {
1226
0
        pdf_font_resource_t *pdfont = (pdf_font_resource_t *)pres;
1227
1228
0
        if (pdfont->FontType != ft_TrueType)
1229
0
            return 0;
1230
0
        else if (pdf_resource_id(pres) == -1)
1231
0
            return 0; /* An unused font. */
1232
0
        else {
1233
0
            int code = pdf_different_encoding_index(pdfont, 0);
1234
1235
0
            if (code < 0)
1236
0
                return code;
1237
0
            if (code == 256 && pdfont->u.simple.BaseEncoding != ENCODING_INDEX_UNKNOWN)
1238
0
                return 0;
1239
0
            { /* The encoding have a difference - do convert. */
1240
0
                pdf_font_resource_t *pdfont0;
1241
0
                gs_const_string CMapName = {(const byte *)"OneByteIdentityH", 16};
1242
1243
0
                code = pdf_convert_truetype_font_descriptor(pdev, pdfont);
1244
0
                if (code < 0)
1245
0
                    return code;
1246
0
                code = pdf_font_type0_alloc(pdev, &pdfont0, pres->rid + 1, pdfont, &CMapName);
1247
0
                if (code < 0)
1248
0
                    return code;
1249
                /* Pass the font object ID to the type 0 font resource. */
1250
0
                pdf_reserve_object_id(pdev, (pdf_resource_t *)pdfont0, pdf_resource_id(pres));
1251
0
                pdf_reserve_object_id(pdev, (pdf_resource_t *)pdfont, gs_no_id);
1252
                /* Set Encoding_name because we won't call attach_cmap_resource for it : */
1253
0
                code = pdf_write_OneByteIdentityH(pdev);
1254
0
                if (code < 0)
1255
0
                    return 0;
1256
0
                pdfont->u.cidfont.CIDSystemInfo_id = pdev->IdentityCIDSystemInfo_id;
1257
0
                gs_snprintf(pdfont0->u.type0.Encoding_name, sizeof(pdfont0->u.type0.Encoding_name),
1258
0
                            "%"PRId64" 0 R", pdf_resource_id(pdev->OneByteIdentityH));
1259
                /* Move ToUnicode : */
1260
0
                pdfont0->res_ToUnicode = pdfont->res_ToUnicode; pdfont->res_ToUnicode = 0;
1261
0
                pdfont0->cmap_ToUnicode = pdfont->cmap_ToUnicode; pdfont->cmap_ToUnicode = 0;
1262
                /* Change the font type to CID font : */
1263
0
                pdfont->FontType = ft_CID_TrueType;
1264
0
                pdfont->write_contents = pdf_write_contents_cid2;
1265
0
                return 0;
1266
0
            }
1267
0
        }
1268
0
    }
1269
48.4k
}
1270
1271
/* ---------------- CMap resources ---------------- */
1272
1273
/*
1274
 * Allocate a CMap resource.
1275
 */
1276
int
1277
pdf_cmap_alloc(gx_device_pdf *pdev, const gs_cmap_t *pcmap,
1278
               pdf_resource_t **ppres, int font_index_only)
1279
5.08k
{
1280
5.08k
    return pdf_write_cmap(pdev, pcmap, ppres, font_index_only);
1281
5.08k
}