Coverage Report

Created: 2025-06-10 07:27

/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
724k
ENUM_PTRS_WITH(pdf_font_resource_enum_ptrs, pdf_font_resource_t *pdfont)
48
181k
ENUM_PREFIX(st_pdf_resource, 12);
49
45.3k
case 0: return ENUM_STRING(&pdfont->BaseFont);
50
45.3k
case 1: ENUM_RETURN(pdfont->FontDescriptor);
51
45.3k
case 2: ENUM_RETURN(pdfont->base_font);
52
45.3k
case 3: ENUM_RETURN(pdfont->Widths);
53
45.3k
case 4: ENUM_RETURN(pdfont->used);
54
45.3k
case 5: ENUM_RETURN(pdfont->res_ToUnicode);
55
45.3k
case 6: ENUM_RETURN(pdfont->cmap_ToUnicode);
56
45.3k
case 7: switch (pdfont->FontType) {
57
1.70k
 case ft_composite:
58
1.70k
     ENUM_RETURN(pdfont->u.type0.DescendantFont);
59
193
 case ft_CID_encrypted:
60
1.70k
 case ft_CID_TrueType:
61
1.70k
     ENUM_RETURN(pdfont->u.cidfont.Widths2);
62
41.8k
 default:
63
41.8k
     pdf_mark_glyph_names(pdfont, mem);
64
41.8k
     ENUM_RETURN(pdfont->u.simple.Encoding);
65
45.3k
}
66
45.3k
case 8: switch (pdfont->FontType) {
67
29.8k
 case ft_encrypted:
68
30.7k
 case ft_encrypted2:
69
38.5k
 case ft_TrueType:
70
38.5k
 case ft_PCL_user_defined:
71
38.5k
 case ft_MicroType:
72
38.5k
 case ft_GL2_stick_user_defined:
73
41.8k
 case ft_user_defined:
74
41.8k
 case ft_PDF_user_defined:
75
41.8k
 case ft_GL2_531:
76
41.8k
     ENUM_RETURN(pdfont->u.simple.v);
77
193
 case ft_CID_encrypted:
78
1.70k
 case ft_CID_TrueType:
79
1.70k
     ENUM_RETURN(pdfont->u.cidfont.v);
80
1.70k
 case ft_composite:
81
1.70k
 default:
82
1.70k
     ENUM_RETURN(0);
83
45.3k
}
84
45.3k
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.38k
 case ft_user_defined:
89
3.38k
 case ft_PDF_user_defined:
90
3.38k
 case ft_GL2_531:
91
3.38k
     ENUM_RETURN(pdfont->u.simple.s.type3.char_procs);
92
193
 case ft_CID_encrypted:
93
1.70k
 case ft_CID_TrueType:
94
1.70k
     ENUM_RETURN(pdfont->u.cidfont.CIDToGIDMap);
95
40.2k
 default:
96
40.2k
     ENUM_RETURN(0);
97
45.3k
}
98
45.3k
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.38k
 case ft_user_defined:
103
3.38k
 case ft_PDF_user_defined:
104
3.38k
 case ft_GL2_531:
105
3.38k
     ENUM_RETURN(pdfont->u.simple.s.type3.cached);
106
193
 case ft_CID_encrypted:
107
1.70k
 case ft_CID_TrueType:
108
1.70k
     ENUM_RETURN(pdfont->u.cidfont.parent);
109
40.2k
 default:
110
40.2k
     ENUM_RETURN(0);
111
45.3k
}
112
45.3k
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.38k
 case ft_user_defined:
117
3.38k
 case ft_PDF_user_defined:
118
3.38k
 case ft_GL2_531:
119
3.38k
     ENUM_RETURN(pdfont->u.simple.s.type3.Resources);
120
193
 case ft_CID_encrypted:
121
1.70k
 case ft_CID_TrueType:
122
1.70k
     ENUM_RETURN(pdfont->u.cidfont.used2);
123
40.2k
 default:
124
40.2k
     ENUM_RETURN(0);
125
45.3k
}
126
724k
ENUM_PTRS_END
127
static
128
45.2k
RELOC_PTRS_WITH(pdf_font_resource_reloc_ptrs, pdf_font_resource_t *pdfont)
129
45.2k
{
130
45.2k
    RELOC_PREFIX(st_pdf_resource);
131
45.2k
    RELOC_STRING_VAR(pdfont->BaseFont);
132
45.2k
    RELOC_VAR(pdfont->FontDescriptor);
133
45.2k
    RELOC_VAR(pdfont->base_font);
134
45.2k
    RELOC_VAR(pdfont->Widths);
135
45.2k
    RELOC_VAR(pdfont->used);
136
45.2k
    RELOC_VAR(pdfont->res_ToUnicode);
137
45.2k
    RELOC_VAR(pdfont->cmap_ToUnicode);
138
45.2k
    switch (pdfont->FontType) {
139
1.70k
    case ft_composite:
140
1.70k
        RELOC_VAR(pdfont->u.type0.DescendantFont);
141
1.70k
        break;
142
0
    case ft_PCL_user_defined:
143
0
    case ft_MicroType:
144
0
    case ft_GL2_stick_user_defined:
145
3.38k
    case ft_user_defined:
146
3.38k
    case ft_PDF_user_defined:
147
3.38k
    case ft_GL2_531:
148
3.38k
        RELOC_VAR(pdfont->u.simple.Encoding);
149
3.38k
        RELOC_VAR(pdfont->u.simple.v);
150
3.38k
        RELOC_VAR(pdfont->u.simple.s.type3.char_procs);
151
3.38k
        RELOC_VAR(pdfont->u.simple.s.type3.cached);
152
3.38k
        RELOC_VAR(pdfont->u.simple.s.type3.Resources);
153
3.38k
        break;
154
193
    case ft_CID_encrypted:
155
1.70k
    case ft_CID_TrueType:
156
1.70k
        RELOC_VAR(pdfont->u.cidfont.Widths2);
157
1.70k
        RELOC_VAR(pdfont->u.cidfont.v);
158
1.70k
        RELOC_VAR(pdfont->u.cidfont.CIDToGIDMap);
159
1.70k
        RELOC_VAR(pdfont->u.cidfont.parent);
160
1.70k
        RELOC_VAR(pdfont->u.cidfont.used2);
161
1.70k
        break;
162
38.4k
    default:
163
38.4k
        RELOC_VAR(pdfont->u.simple.Encoding);
164
38.4k
        RELOC_VAR(pdfont->u.simple.v);
165
38.4k
        break;
166
45.2k
    }
167
45.2k
}
168
45.2k
RELOC_PTRS_END
169
170
/* ---------------- Standard fonts ---------------- */
171
172
/* ------ Private ------ */
173
174
/* Define the 14 standard built-in fonts. */
175
86.2k
#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
64.7k
{
203
64.7k
    const pdf_standard_font_info_t *ppsf;
204
205
943k
    for (ppsf = standard_font_info; ppsf->fname; ++ppsf)
206
882k
        if (ppsf->size == size &&
207
882k
            !memcmp(ppsf->fname, (const char *)str, size)
208
882k
            )
209
4.09k
            return ppsf - standard_font_info;
210
60.6k
    return -1;
211
64.7k
}
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
179
{
223
179
    bool has_uid = uid_is_UniqueID(&bfont->UID) && bfont->UID.id != 0;
224
179
    const pdf_standard_font_t *psf = pdf_standard_fonts(pdev);
225
179
    int i;
226
227
179
    switch (bfont->FontType) {
228
165
    case ft_encrypted:
229
168
    case ft_encrypted2:
230
168
    case ft_TrueType:
231
168
        break;
232
11
    default:
233
11
        return -1;
234
179
    }
235
236
2.52k
    for (i = 0; i < PDF_NUM_STANDARD_FONTS; ++psf, ++i) {
237
2.35k
        gs_font_base *cfont;
238
2.35k
        int code;
239
240
2.35k
        if (!psf->pdfont)
241
2.30k
            continue;
242
46
        cfont = pdf_font_resource_font(psf->pdfont, false);
243
46
        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
46
        code = gs_copied_can_copy_glyphs((const gs_font *)cfont,
255
46
                                         (const gs_font *)bfont,
256
46
                                         &pairs[0].glyph, num_glyphs,
257
46
                                         sizeof(pdf_char_glyph_pair_t), true);
258
46
        if (code == gs_error_unregistered) /* Debug purpose only. */
259
0
            return code;
260
        /* Note: code < 0 means an error. Skip it here. */
261
46
        if (code > 0)
262
0
            return i;
263
46
    }
264
168
    return -1;
265
168
}
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
179
{
275
179
    bool found = false;
276
179
    gs_font *orig = dir->orig_fonts;
277
278
692
    for (; orig; orig = orig->next) {
279
513
        gs_font_base *obfont;
280
281
513
        if (orig->FontType == ft_composite || !orig->is_resource)
282
297
            continue;
283
216
        obfont = (gs_font_base *)orig;
284
216
        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
216
    }
300
179
    return found;
301
179
}
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
41.8k
{
311
41.8k
    pdf_outline_fonts_t *pofs =
312
41.8k
        gs_alloc_struct(mem, pdf_outline_fonts_t, &st_pdf_outline_fonts,
313
41.8k
                        "pdf_outline_fonts_alloc(outline_fonts)");
314
41.8k
    pdf_standard_font_t *ppsf =
315
41.8k
        gs_alloc_struct_array(mem, PDF_NUM_STANDARD_FONTS,
316
41.8k
                              pdf_standard_font_t,
317
41.8k
                              &st_pdf_standard_font_element,
318
41.8k
                              "pdf_outline_fonts_alloc(standard_fonts)");
319
320
41.8k
    if (pofs == 0 || ppsf == 0)
321
0
        return 0;
322
41.8k
    memset(ppsf, 0, PDF_NUM_STANDARD_FONTS * sizeof(*ppsf));
323
41.8k
    memset(pofs, 0, sizeof(*pofs));
324
41.8k
    pofs->standard_fonts = ppsf;
325
41.8k
    return pofs;
326
41.8k
}
327
328
/*
329
 * Return the standard fonts array.
330
 */
331
pdf_standard_font_t *
332
pdf_standard_fonts(const gx_device_pdf *pdev)
333
45.9k
{
334
45.9k
    if (pdev->text != NULL && pdev->text->outline_fonts != NULL)
335
45.9k
        return pdev->text->outline_fonts->standard_fonts;
336
0
    return NULL;
337
45.9k
}
338
339
/*
340
 * Clean the standard fonts array.
341
 */
342
void
343
pdf_clean_standard_fonts(const gx_device_pdf *pdev)
344
41.8k
{
345
41.8k
    pdf_standard_font_t *ppsf = pdf_standard_fonts(pdev);
346
347
41.8k
    if (ppsf != NULL)
348
41.8k
        memset(ppsf, 0, PDF_NUM_STANDARD_FONTS * sizeof(*ppsf));
349
41.8k
}
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
2.97k
{
358
2.97k
    void *q = gs_alloc_byte_array(mem, new_size, elem_size, "pdf_resize_array");
359
360
2.97k
    if (q == NULL)
361
0
        return_error(gs_error_VMerror);
362
2.97k
    memset((char *)q + elem_size * old_size, 0, elem_size * (new_size - old_size));
363
2.97k
    memcpy(q, *p, elem_size * old_size);
364
2.97k
    gs_free_object(mem, *p, "pdf_resize_array");
365
2.97k
    *p = q;
366
2.97k
    return 0;
367
2.97k
}
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
41.9k
{
378
41.9k
    gs_memory_t *mem = pdev->pdf_memory;
379
41.9k
    pdf_font_resource_t *pfres;
380
41.9k
    double *widths = 0;
381
41.9k
    byte *used = 0;
382
41.9k
    int code;
383
41.9k
    bool is_CID_font = (ftype == ft_CID_encrypted || ftype == ft_CID_TrueType);
384
385
41.9k
    if (chars_count != 0) {
386
40.6k
        uint size = (chars_count + 7) / 8;
387
388
40.6k
        if (!is_CID_font) {
389
39.2k
            widths = (void *)gs_alloc_byte_array(mem, chars_count, sizeof(*widths),
390
39.2k
                                                "font_resource_alloc(Widths)");
391
39.2k
        } else {
392
            /*  Delay allocation because we don't know which WMode will be used. */
393
1.35k
        }
394
40.6k
        used = gs_alloc_bytes(mem, size, "font_resource_alloc(used)");
395
40.6k
        if ((!is_CID_font && widths == 0) || used == 0) {
396
0
            code = gs_note_error(gs_error_VMerror);
397
0
            goto fail;
398
0
        }
399
40.6k
        if (!is_CID_font)
400
39.2k
            memset(widths, 0, chars_count * sizeof(*widths));
401
40.6k
        memset(used, 0, size);
402
40.6k
    }
403
41.9k
    code = pdf_alloc_resource(pdev, rtype, rid, (pdf_resource_t **)&pfres, -1L);
404
41.9k
    if (code < 0)
405
0
        goto fail;
406
41.9k
    pfres->FontType = ftype;
407
41.9k
    pfres->count = chars_count;
408
41.9k
    pfres->Widths = widths;
409
41.9k
    pfres->used = used;
410
41.9k
    pfres->write_contents = write_contents;
411
41.9k
    pfres->res_ToUnicode = NULL;
412
41.9k
    pfres->cmap_ToUnicode = NULL;
413
41.9k
    pfres->mark_glyph = 0;
414
41.9k
    pfres->mark_glyph_data = 0;
415
41.9k
    pfres->u.simple.standard_glyph_code_for_notdef = gs_c_name_glyph((const byte *)".notdef", 7) - gs_c_min_std_encoding_glyph;
416
41.9k
    *ppfres = pfres;
417
41.9k
    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
41.9k
}
423
424
int font_resource_free(gx_device_pdf *pdev, pdf_font_resource_t *pdfont)
425
41.9k
{
426
41.9k
    if(pdfont->BaseFont.size
427
41.9k
       && (pdfont->base_font == NULL || !pdfont->base_font->is_standard)) {
428
429
34.7k
        gs_free_string(pdev->pdf_memory, pdfont->BaseFont.data, pdfont->BaseFont.size, "Free BaseFont string");
430
34.7k
        pdfont->BaseFont.data = (byte *)0L;
431
34.7k
        pdfont->BaseFont.size = 0;
432
34.7k
    }
433
41.9k
    if(pdfont->Widths) {
434
40.6k
        gs_free_object(pdev->pdf_memory, pdfont->Widths, "Free Widths array");
435
40.6k
        pdfont->Widths = 0;
436
40.6k
    }
437
41.9k
    if(pdfont->used) {
438
40.6k
        gs_free_object(pdev->pdf_memory, pdfont->used, "Free used array");
439
40.6k
        pdfont->used = 0;
440
40.6k
    }
441
41.9k
    if(pdfont->res_ToUnicode) {
442
        /* ToUnicode resources are tracked amd released separately */
443
4.46k
        pdfont->res_ToUnicode = 0;
444
4.46k
    }
445
41.9k
    if(pdfont->cmap_ToUnicode) {
446
4.79k
        gs_cmap_ToUnicode_free(pdev->pdf_memory, pdfont->cmap_ToUnicode);
447
4.79k
        pdfont->cmap_ToUnicode = 0;
448
4.79k
    }
449
41.9k
    switch(pdfont->FontType) {
450
1.35k
        case ft_composite:
451
1.35k
            if (pdfont->u.type0.CMapName_data != NULL) {
452
1.35k
                gs_free_object(pdev->memory->non_gc_memory, (byte *)pdfont->u.type0.CMapName_data, "font_resource_free(CMapName)");
453
1.35k
                pdfont->u.type0.CMapName_data = NULL;
454
1.35k
                pdfont->u.type0.CMapName_size = 0;
455
1.35k
            }
456
1.35k
            break;
457
0
        case ft_PCL_user_defined:
458
0
        case ft_MicroType:
459
0
        case ft_GL2_stick_user_defined:
460
3.36k
        case ft_user_defined:
461
3.36k
        case ft_PDF_user_defined:
462
3.36k
        case ft_GL2_531:
463
3.36k
            if(pdfont->u.simple.Encoding) {
464
1.21k
                int ix;
465
312k
                for (ix = 0; ix <= 255;ix++)
466
311k
                    gs_free_object(pdev->pdf_memory->non_gc_memory, pdfont->u.simple.Encoding[ix].data, "Free copied glyph name string");
467
1.21k
                gs_free_object(pdev->pdf_memory, pdfont->u.simple.Encoding, "Free simple Encoding");
468
1.21k
                pdfont->u.simple.Encoding = 0;
469
1.21k
            }
470
3.36k
            if(pdfont->u.simple.v) {
471
1.21k
                gs_free_object(pdev->pdf_memory, pdfont->u.simple.v, "Free simple v");
472
1.21k
                pdfont->u.simple.v = 0;
473
1.21k
            }
474
3.36k
            if (pdfont->u.simple.s.type3.char_procs) {
475
3.33k
                pdf_free_charproc_ownership(pdev, (pdf_resource_t *)pdfont->u.simple.s.type3.char_procs);
476
3.33k
                pdfont->u.simple.s.type3.char_procs = 0;
477
3.33k
            }
478
3.36k
            if (pdfont->u.simple.s.type3.cached) {
479
1.21k
                gs_free_object(pdev->pdf_memory, pdfont->u.simple.s.type3.cached, "Free type 3 cached array");
480
1.21k
                pdfont->u.simple.s.type3.cached = NULL;
481
1.21k
            }
482
3.36k
            if (pdfont->u.simple.s.type3.Resources != NULL) {
483
1.21k
                cos_free((cos_object_t *)pdfont->u.simple.s.type3.Resources, "Free type 3 Resources dictionary");
484
1.21k
                pdfont->u.simple.s.type3.Resources = NULL;
485
1.21k
            }
486
3.36k
            break;
487
193
        case ft_CID_encrypted:
488
1.35k
        case ft_CID_TrueType:
489
1.35k
            if(pdfont->u.cidfont.Widths2) {
490
19
                gs_free_object(pdev->pdf_memory, pdfont->u.cidfont.Widths2, "Free CIDFont Widths2 array");
491
19
                pdfont->u.cidfont.Widths2 = NULL;
492
19
            }
493
1.35k
            if(pdfont->u.cidfont.v) {
494
19
                gs_free_object(pdev->pdf_memory, pdfont->u.cidfont.v, "Free CIDFont v array");
495
19
                pdfont->u.cidfont.v = NULL;
496
19
            }
497
1.35k
            if(pdfont->u.cidfont.used2) {
498
1.35k
                gs_free_object(pdev->pdf_memory, pdfont->u.cidfont.used2, "Free CIDFont used2");
499
1.35k
                pdfont->u.cidfont.used2 = 0;
500
1.35k
            }
501
1.35k
            if(pdfont->u.cidfont.CIDToGIDMap) {
502
1.16k
                gs_free_object(pdev->pdf_memory, pdfont->u.cidfont.CIDToGIDMap, "Free CIDToGID map");
503
1.16k
                pdfont->u.cidfont.CIDToGIDMap = 0;
504
1.16k
            }
505
1.35k
            break;
506
35.9k
        default:
507
35.9k
            if(pdfont->u.simple.Encoding) {
508
35.9k
                int ix;
509
9.22M
                for (ix = 0; ix <= 255;ix++)
510
9.19M
                    gs_free_object(pdev->pdf_memory->non_gc_memory, pdfont->u.simple.Encoding[ix].data, "Free copied glyph name string");
511
35.9k
                gs_free_object(pdev->pdf_memory, pdfont->u.simple.Encoding, "Free simple Encoding");
512
35.9k
                pdfont->u.simple.Encoding = 0;
513
35.9k
            }
514
35.9k
            if(pdfont->u.simple.v) {
515
35.9k
                gs_free_object(pdev->pdf_memory, pdfont->u.simple.v, "Free simple v");
516
35.9k
                pdfont->u.simple.v = 0;
517
35.9k
            }
518
35.9k
            break;
519
41.9k
    }
520
41.9k
    if (pdfont->object) {
521
41.9k
        gs_free_object(pdev->pdf_memory, pdfont->object, "Free font resource object");
522
41.9k
        pdfont->object = 0;
523
41.9k
    }
524
    /* We free FontDescriptor resources separately */
525
41.9k
    if(pdfont->FontDescriptor)
526
33.3k
        pdfont->FontDescriptor = NULL;
527
8.63k
    else {
528
8.63k
        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
3.91k
            pdf_base_font_t *pbfont = pdfont->base_font;
535
3.91k
            gs_font *copied = (gs_font *)pbfont->copied, *complete = (gs_font *)pbfont->complete;
536
537
3.91k
            if (copied)
538
3.91k
                gs_free_copied_font(copied);
539
3.91k
            if (complete && copied != complete) {
540
0
                gs_free_copied_font(complete);
541
0
                pbfont->complete = 0;
542
0
            }
543
3.91k
            pbfont->copied = 0;
544
3.91k
            if (pbfont && pbfont->font_name.size) {
545
3.91k
                gs_free_string(pdev->pdf_memory, pbfont->font_name.data, pbfont->font_name.size, "Free BaseFont FontName string");
546
3.91k
                pbfont->font_name.data = (byte *)0L;
547
3.91k
                pbfont->font_name.size = 0;
548
3.91k
            }
549
3.91k
            if (pbfont) {
550
3.91k
                gs_free_object(pdev->pdf_memory, pbfont, "Free base font from FontDescriptor)");
551
3.91k
                pdfont->base_font = 0;
552
3.91k
            }
553
3.91k
        }
554
8.63k
    }
555
41.9k
    return 0;
556
41.9k
}
557
558
int
559
pdf_assign_font_object_id(gx_device_pdf *pdev, pdf_font_resource_t *pdfont)
560
2.16M
{
561
2.16M
    if (pdf_resource_id((pdf_resource_t *)pdfont) == -1) {
562
35.3k
        int code;
563
564
35.3k
        pdf_reserve_object_id(pdev, (pdf_resource_t *)pdfont, 0);
565
35.3k
        code = pdf_mark_font_descriptor_used(pdev, pdfont->FontDescriptor);
566
35.3k
        if (code < 0)
567
0
            return code;
568
35.3k
        if (pdfont->FontType == 0) {
569
1.32k
            pdf_font_resource_t *pdfont1 = pdfont->u.type0.DescendantFont;
570
571
1.32k
            if (pdf_font_id(pdfont1) == -1) {
572
1.32k
                pdf_reserve_object_id(pdev, (pdf_resource_t *)pdfont1, 0);
573
1.32k
                code = pdf_mark_font_descriptor_used(pdev, pdfont1->FontDescriptor);
574
1.32k
                if (code < 0)
575
0
                    return code;
576
1.32k
            }
577
1.32k
        }
578
35.3k
    }
579
2.16M
    return 0;
580
2.16M
}
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
39.2k
{
587
39.2k
    pdf_font_resource_t *pfres;
588
39.2k
    int code = font_resource_alloc(pdev, &pfres, resourceFont, rid, ftype,
589
39.2k
                                   chars_count, write_contents);
590
591
39.2k
    if (code < 0)
592
0
        return code;
593
39.2k
    pfres->u.simple.FirstChar = 256;
594
39.2k
    pfres->u.simple.LastChar = -1;
595
39.2k
    pfres->u.simple.BaseEncoding = -1;
596
39.2k
    pfres->u.simple.preferred_encoding_index = -1;
597
39.2k
    pfres->u.simple.last_reserved_char = -1;
598
39.2k
    *ppfres = pfres;
599
39.2k
    return 0;
600
39.2k
}
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
37.1k
{
606
37.1k
    pdf_encoding_element_t *Encoding = (pdf_encoding_element_t *)gs_alloc_bytes(pdev->pdf_memory, 256 * sizeof(pdf_encoding_element_t), "font_resource_encoded_alloc");
607
37.1k
    gs_point *v = (gs_point *)gs_alloc_byte_array(pdev->pdf_memory,
608
37.1k
                    256, sizeof(gs_point), "pdf_font_simple_alloc");
609
37.1k
    pdf_font_resource_t *pdfont;
610
37.1k
    int code, i;
611
612
37.1k
    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
37.1k
    code = font_resource_simple_alloc(pdev, &pdfont, rid, ftype,
620
37.1k
                                      256, write_contents);
621
37.1k
    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
37.1k
    memset(v, 0, 256 * sizeof(*v));
629
37.1k
    memset(Encoding, 0, 256 * sizeof(*Encoding));
630
9.54M
    for (i = 0; i < 256; ++i)
631
9.50M
        Encoding[i].glyph = GS_NO_GLYPH;
632
37.1k
    pdfont->u.simple.Encoding = Encoding;
633
37.1k
    pdfont->u.simple.v = v;
634
37.1k
    *ppfres = pdfont;
635
37.1k
    return 0;
636
37.1k
}
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
35.9k
{
644
35.9k
    switch (pfont->FontType) {
645
28.5k
    case ft_encrypted:
646
29.4k
    case ft_encrypted2:
647
29.4k
        pdfont->u.simple.s.type1.is_MM_instance =
648
29.4k
            ((const gs_font_type1 *)pfont)->data.WeightVector.count > 0;
649
35.9k
    default:
650
35.9k
        break;
651
35.9k
    }
652
35.9k
}
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
279k
{
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
279k
    gs_memory_t *mem = pdev->pdf_memory;
666
279k
    int code;
667
668
    /* Ensure the 'round up' code below doesn't overflow an unsigned int when adding 7 */
669
279k
    if (pfres->count >= max_uint - 7 || chars_count > max_uint - 7)
670
2
        return_error(gs_error_rangecheck);
671
672
279k
    if (chars_count < pfres->count)
673
278k
        return 0;
674
791
    if (pfres->Widths != NULL) {
675
533
        code = pdf_resize_array(mem, (void **)&pfres->Widths, sizeof(*pfres->Widths),
676
533
                    pfres->count, chars_count);
677
533
        if (code < 0)
678
0
            return code;
679
533
    }
680
791
    code = pdf_resize_array(mem, (void **)&pfres->used, sizeof(*pfres->used),
681
791
                    (pfres->count + 7) / 8, (chars_count + 7) / 8);
682
791
    if (code < 0)
683
0
        return code;
684
791
    if (pfres->FontType == ft_CID_encrypted || pfres->FontType == ft_CID_TrueType) {
685
791
        if (pfres->u.cidfont.v != NULL) {
686
175
            code = pdf_resize_array(mem, (void **)&pfres->u.cidfont.v,
687
175
                    sizeof(*pfres->u.cidfont.v), pfres->count * 2, chars_count * 2);
688
175
            if (code < 0)
689
0
                return code;
690
175
        }
691
791
        if (pfres->u.cidfont.Widths2 != NULL) {
692
175
            code = pdf_resize_array(mem, (void **)&pfres->u.cidfont.Widths2,
693
175
                    sizeof(*pfres->u.cidfont.Widths2), pfres->count, chars_count);
694
175
            if (code < 0)
695
0
                return code;
696
175
        }
697
791
    }
698
791
    if (pfres->FontType == ft_CID_TrueType) {
699
509
        if (pfres->u.cidfont.CIDToGIDMap != NULL) {
700
509
            code = pdf_resize_array(mem, (void **)&pfres->u.cidfont.CIDToGIDMap,
701
509
                    sizeof(*pfres->u.cidfont.CIDToGIDMap), pfres->count, chars_count);
702
509
            if (code < 0)
703
0
                return code;
704
509
            pfres->u.cidfont.CIDToGIDMapLength = chars_count;
705
509
        }
706
509
    }
707
791
    if (pfres->FontType == ft_CID_encrypted || pfres->FontType == ft_CID_TrueType) {
708
791
        if (pfres->u.cidfont.used2 != NULL) {
709
791
            code = pdf_resize_array(mem, (void **)&pfres->u.cidfont.used2,
710
791
                    sizeof(*pfres->u.cidfont.used2),
711
791
                    (pfres->count + 7) / 8, (chars_count + 7) / 8);
712
791
            if (code < 0)
713
0
                return code;
714
791
        }
715
791
    }
716
791
    pfres->count = chars_count;
717
791
    return 0;
718
791
}
719
720
/* Get the object ID of a font resource. */
721
int64_t
722
pdf_font_id(const pdf_font_resource_t *pdfont)
723
39.3k
{
724
39.3k
    return pdf_resource_id((const pdf_resource_t *)pdfont);
725
39.3k
}
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
61.5M
{
734
61.5M
    if (pdfont->base_font != NULL)
735
7.17M
        return pdf_base_font_font(pdfont->base_font, complete);
736
54.3M
    if (pdfont->FontDescriptor == 0)
737
2.15M
        return 0;
738
52.2M
    return pdf_font_descriptor_font(pdfont->FontDescriptor, complete);
739
54.3M
}
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
64.6k
{
767
64.6k
    uint i;
768
769
531k
    for (i = 0; i < psa->size; ++i)
770
468k
        if (!bytes_compare(psa->data[i].data, psa->data[i].size, chars, size))
771
1.59k
            return true;
772
63.0k
    return false;
773
64.6k
}
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
4.09k
{
778
4.09k
    if (font->is_resource) {
779
3.91k
        return true;
780
3.91k
    }
781
179
    if (find_std_appearance(pdev, (gs_font_base *)font, -1,
782
179
                            pairs, num_glyphs) == index)
783
0
        return true;
784
179
    if (!scan_for_standard_fonts(pdev, font->dir))
785
179
        return false;
786
0
    return (find_std_appearance(pdev, (gs_font_base *)font, -1,
787
0
                                pairs, num_glyphs) == index);
788
179
}
789
static bool
790
has_extension_glyphs(gs_font *pfont)
791
2.39k
{
792
2.39k
    psf_glyph_enum_t genum;
793
2.39k
    gs_glyph glyph;
794
2.39k
    gs_const_string str;
795
2.39k
    int code, j = 0, l;
796
2.39k
    const int sl = strlen(gx_extendeg_glyph_name_separator);
797
798
2.39k
    psf_enumerate_glyphs_begin(&genum, (gs_font *)pfont, NULL, 0, GLYPH_SPACE_NAME);
799
1.88M
    for (glyph = GS_NO_GLYPH; (psf_enumerate_glyphs_next(&genum, &glyph)) != 1; ) {
800
1.87M
        code = pfont->procs.glyph_name(pfont, glyph, &str);
801
1.87M
        if (code < 0)
802
0
            return code;
803
1.87M
        l = str.size - sl;
804
8.60M
        for (j = 0; j < l; j ++)
805
6.72M
            if (!memcmp(gx_extendeg_glyph_name_separator, str.data + j, sl))
806
0
                return true;
807
1.87M
    }
808
2.39k
    psf_enumerate_glyphs_reset(&genum);
809
2.39k
    return false;
810
2.39k
}
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
64.7k
{
816
64.7k
    const gs_font_name *fn = &font->font_name;
817
64.7k
    const byte *chars = fn->chars;
818
64.7k
    uint size = fn->size;
819
64.7k
    int index = pdf_find_standard_font_name(chars, size);
820
64.7k
    bool embed_as_standard_called = false;
821
64.7k
    bool do_embed_as_standard = false; /* Quiet compiler. */
822
64.7k
    int code;
823
64.7k
    gs_font_info_t info;
824
825
64.7k
    memset(&info, 0x00, sizeof(gs_font_info_t));
826
64.7k
    code = font->procs.font_info(font, NULL, FONT_INFO_EMBEDDING_RIGHTS | FONT_INFO_EMBEDDED, &info);
827
64.7k
    if (code == 0 && (info.members & FONT_INFO_EMBEDDING_RIGHTS)) {
828
27.8k
        if (((info.EmbeddingRights == 0x0002) || (info.EmbeddingRights & 0x0200))
829
27.8k
            && !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
143
            char name[gs_font_name_max + 1];
841
143
            int len;
842
843
143
            len = min(gs_font_name_max, font->font_name.size);
844
143
            memcpy(name, font->font_name.chars, len);
845
143
            name[len] = 0;
846
143
            emprintf1(pdev->pdf_memory,
847
143
                      "\nWarning: Font %s cannot be embedded because of licensing restrictions\n",
848
143
                      name);
849
143
            return FONT_EMBED_NO;
850
143
        }
851
27.8k
    }
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
64.6k
    if (pindex)
860
64.6k
        *pindex = index;
861
64.6k
    if (pdev->PDFX != 0 || pdev->PDFA != 0)
862
0
        return FONT_EMBED_YES;
863
64.6k
    if (pdev->CompatibilityLevel < 1.3) {
864
30.4k
        if (index >= 0 &&
865
30.4k
            (embed_as_standard_called = true,
866
2.49k
                do_embed_as_standard = embed_as_standard(pdev, font, index, pairs, num_glyphs))) {
867
2.39k
            if (pdev->ForOPDFRead && has_extension_glyphs(font))
868
0
                return FONT_EMBED_YES;
869
870
2.39k
            if (pdev->ForOPDFRead && embed_list_includes(&pdev->params.AlwaysEmbed, chars, size))
871
0
                    return FONT_EMBED_YES;
872
873
2.39k
            return FONT_EMBED_STANDARD;
874
2.39k
        }
875
30.4k
    }
876
    /* Check the Embed lists. */
877
62.2k
    if (!embed_list_includes(&pdev->params.NeverEmbed, chars, size) ||
878
62.2k
        (index >= 0 &&
879
1.59k
            !(embed_as_standard_called ? do_embed_as_standard :
880
1.59k
             (embed_as_standard_called = true,
881
1.59k
              (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
62.2k
        )
884
60.7k
    {
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
60.7k
        if (pdev->EmbedSubstituteFonts)
889
60.7k
            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
1.51k
    if (index >= 0 &&
903
1.51k
        (embed_as_standard_called ? do_embed_as_standard :
904
1.51k
         embed_as_standard(pdev, font, index, pairs, num_glyphs)))
905
1.51k
        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
1.51k
}
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
74.0k
{
919
74.0k
    pdf_font_resource_t *pdsubf = pdfont;
920
74.0k
    gs_string fname;
921
74.0k
    uint size;
922
74.0k
    byte *data;
923
924
74.0k
    if (pdfont->FontType == ft_composite) {
925
2.68k
        int code;
926
927
2.68k
        pdsubf = pdfont->u.type0.DescendantFont;
928
2.68k
        code = pdf_compute_BaseFont(pdev, pdsubf, finish);
929
2.68k
        if (code < 0)
930
0
            return code;
931
2.68k
        fname = pdsubf->BaseFont;
932
2.68k
    }
933
71.3k
    else if (pdfont->FontDescriptor == 0) {
934
        /* Type 3 font, or has its BaseFont computed in some other way. */
935
7.07k
        return 0;
936
7.07k
    } else
937
64.3k
        fname = *pdf_font_descriptor_base_name(pdsubf->FontDescriptor);
938
67.0k
    size = fname.size;
939
67.0k
    data = gs_alloc_string(pdev->pdf_memory, size,
940
67.0k
                           "pdf_compute_BaseFont");
941
67.0k
    if (data == 0)
942
0
        return_error(gs_error_VMerror);
943
67.0k
    memcpy(data, fname.data, size);
944
67.0k
    switch (pdfont->FontType) {
945
2.68k
    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
2.68k
        break;
950
47.4k
    case ft_encrypted:
951
49.1k
    case ft_encrypted2:
952
49.1k
        if (pdfont->u.simple.s.type1.is_MM_instance &&
953
49.1k
            !pdf_font_descriptor_embedding(pdfont->FontDescriptor)
954
49.1k
            ) {
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
49.1k
        break;
963
9.77k
    case ft_TrueType:
964
14.4k
    case ft_CID_TrueType: {
965
        /* Remove spaces from the base name. */
966
14.4k
        uint i, j;
967
968
158k
        for (i = j = 0; i < size; ++i)
969
143k
            if (data[i] != ' ')
970
143k
                data[j++] = data[i];
971
14.4k
        data = gs_resize_string(pdev->pdf_memory, data, i, j,
972
14.4k
                                "pdf_compute_BaseFont");
973
14.4k
        size = j;
974
14.4k
        break;
975
9.77k
    }
976
726
    default:
977
726
        break;
978
67.0k
    }
979
67.0k
    if (pdfont->BaseFont.size)
980
32.2k
        gs_free_string(pdev->pdf_memory, pdfont->BaseFont.data, pdfont->BaseFont.size, "Replacing BaseFont string");
981
67.0k
    pdfont->BaseFont.data = fname.data = data;
982
67.0k
    pdfont->BaseFont.size = fname.size = size;
983
    /* Compute names for subset fonts. */
984
67.0k
    if (finish && pdfont->FontDescriptor != NULL &&
985
67.0k
        pdf_font_descriptor_is_subset(pdfont->FontDescriptor) &&
986
67.0k
        !pdf_has_subset_prefix(fname.data, fname.size) &&
987
67.0k
        pdf_font_descriptor_embedding(pdfont->FontDescriptor)
988
67.0k
        ) {
989
29.5k
        int code;
990
29.5k
        gs_font_base *pbfont = pdf_font_resource_font(pdfont, false);
991
992
29.5k
        if (pdfont->FontDescriptor)
993
29.5k
            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
29.5k
        if (code < 0)
998
0
            return code;
999
29.5k
        pdfont->BaseFont = fname;
1000
1001
        /* Don't write a UID for subset fonts. */
1002
29.5k
        if (uid_is_XUID(&pbfont->UID)) {
1003
7.98k
            uid_free(&pbfont->UID, pbfont->memory, "gs_font_finalize");
1004
7.98k
        }
1005
29.5k
        uid_set_invalid(&pbfont->UID);
1006
29.5k
    }
1007
67.0k
    if (pdfont->FontType != ft_composite && pdsubf->FontDescriptor)
1008
64.3k
        *pdf_font_descriptor_name(pdsubf->FontDescriptor) = fname;
1009
67.0k
    return 0;
1010
67.0k
}
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.35k
{
1020
1.35k
    int code = font_resource_alloc(pdev, ppfres, resourceFont, rid,
1021
1.35k
                                   ft_composite, 0, pdf_write_contents_type0);
1022
1023
1.35k
    if (code >= 0) {
1024
1.35k
        byte *chars = NULL;
1025
1026
1.35k
        (*ppfres)->u.type0.DescendantFont = DescendantFont;
1027
1028
1.35k
        chars = gs_alloc_bytes(pdev->pdf_memory->non_gc_memory, CMapName->size, "pdf_font_resource_t(CMapName)");
1029
1.35k
        if (chars == 0)
1030
0
            return_error(gs_error_VMerror);
1031
1.35k
        memcpy(chars, CMapName->data, CMapName->size);
1032
1.35k
        (*ppfres)->u.type0.CMapName_data = chars;
1033
1.35k
        (*ppfres)->u.type0.CMapName_size = CMapName->size;
1034
1035
1.35k
        (*ppfres)->u.type0.font_index = 0;
1036
1.35k
        code = pdf_compute_BaseFont(pdev, *ppfres, false);
1037
1.35k
    }
1038
1.35k
    return code;
1039
1.35k
}
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.14k
{
1048
2.14k
    return font_resource_simple_alloc(pdev, ppfres, gs_no_id, ft_user_defined,
1049
2.14k
                                      256, write_contents);
1050
2.14k
}
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
3.91k
{
1059
3.91k
    pdf_font_resource_t *pdfont;
1060
3.91k
    int code = font_resource_encoded_alloc(pdev, &pdfont, rid, pfont->FontType,
1061
3.91k
                                           pdf_write_contents_std);
1062
3.91k
    const pdf_standard_font_info_t *psfi = &standard_font_info[index];
1063
3.91k
    pdf_standard_font_t *psf = &pdf_standard_fonts(pdev)[index];
1064
3.91k
    gs_matrix *orig_matrix = (is_original ? &pfont->FontMatrix : &psf->orig_matrix);
1065
1066
3.91k
    if (code < 0 ||
1067
3.91k
        (code = pdf_base_font_alloc(pdev, &pdfont->base_font, pfont, orig_matrix, true)) < 0
1068
3.91k
        )
1069
0
        return code;
1070
3.91k
    pdfont->BaseFont.data = (byte *)psfi->fname; /* break const */
1071
3.91k
    pdfont->BaseFont.size = strlen(psfi->fname);
1072
3.91k
    pdfont->mark_glyph = pfont->dir->ccache.mark_glyph;
1073
3.91k
    set_is_MM_instance(pdfont, pfont);
1074
3.91k
    if (is_original) {
1075
3.90k
        psf->pdfont = pdfont;
1076
3.90k
        psf->orig_matrix = pfont->FontMatrix;
1077
3.90k
    }
1078
3.91k
    *ppfres = pdfont;
1079
3.91k
    return 0;
1080
3.91k
}
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
31.9k
{
1089
31.9k
    pdf_font_resource_t *pdfont;
1090
31.9k
    int code;
1091
1092
31.9k
    code = font_resource_encoded_alloc(pdev, &pdfont, rid,
1093
31.9k
                                           pdf_font_descriptor_FontType(pfd),
1094
31.9k
                                           pdf_write_contents_simple);
1095
1096
31.9k
    if (code < 0)
1097
0
        return(gs_note_error(code));
1098
31.9k
    pdfont->FontDescriptor = pfd;
1099
31.9k
    set_is_MM_instance(pdfont, pdf_font_descriptor_font(pfd, false));
1100
31.9k
    *ppfres = pdfont;
1101
31.9k
    return pdf_compute_BaseFont(pdev, pdfont, false);
1102
31.9k
}
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.35k
{
1111
1.35k
    font_type FontType = pdf_font_descriptor_FontType(pfd);
1112
1.35k
    gs_font_base *font = pdf_font_descriptor_font(pfd, false);
1113
1.35k
    int chars_count;
1114
1.35k
    int code;
1115
1.35k
    pdf_font_write_contents_proc_t write_contents;
1116
1.35k
    const gs_cid_system_info_t *pcidsi;
1117
1.35k
    ushort *map = 0;
1118
1.35k
    pdf_font_resource_t *pdfont;
1119
1120
1.35k
    switch (FontType) {
1121
193
    case ft_CID_encrypted:
1122
193
        chars_count = ((const gs_font_cid0 *)font)->cidata.common.CIDCount;
1123
193
        pcidsi = &((const gs_font_cid0 *)font)->cidata.common.CIDSystemInfo;
1124
193
        write_contents = pdf_write_contents_cid0;
1125
193
        break;
1126
1.16k
    case ft_CID_TrueType:
1127
1.16k
        chars_count = ((const gs_font_cid2 *)font)->cidata.common.CIDCount;
1128
1.16k
        pcidsi = &((const gs_font_cid2 *)font)->cidata.common.CIDSystemInfo;
1129
1.16k
        map = (void *)gs_alloc_byte_array(pdev->pdf_memory, chars_count,
1130
1.16k
                                          sizeof(*map), "CIDToGIDMap");
1131
1.16k
        if (map == 0)
1132
0
            return_error(gs_error_VMerror);
1133
1.16k
        memset(map, 0, chars_count * sizeof(*map));
1134
1.16k
        write_contents = pdf_write_contents_cid2;
1135
1.16k
        break;
1136
0
    default:
1137
0
        return_error(gs_error_rangecheck);
1138
1.35k
    }
1139
1.35k
    code = font_resource_alloc(pdev, &pdfont, resourceCIDFont, rid, FontType,
1140
1.35k
                               chars_count, write_contents);
1141
1.35k
    if (code < 0)
1142
0
        return code;
1143
1.35k
    pdfont->FontDescriptor = pfd;
1144
1.35k
    pdfont->u.cidfont.CIDToGIDMap = map;
1145
1.35k
    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.35k
    pdfont->u.cidfont.Widths2 = NULL;
1151
1.35k
    pdfont->u.cidfont.v = NULL;
1152
1.35k
    pdfont->u.cidfont.parent = NULL;
1153
    /* Don' know whether the font will use WMode 1,
1154
       so reserve it now. */
1155
1.35k
    pdfont->u.cidfont.used2 = gs_alloc_bytes(pdev->pdf_memory,
1156
1.35k
                (chars_count + 7) / 8, "pdf_font_cidfont_alloc");
1157
1.35k
    if (pdfont->u.cidfont.used2 == NULL)
1158
0
        return_error(gs_error_VMerror);
1159
1.35k
    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.35k
    code = pdf_write_cid_systemInfo_separate(pdev, pcidsi, &pdfont->u.cidfont.CIDSystemInfo_id);
1165
1.35k
    if (code < 0)
1166
0
        return code;
1167
1.35k
    *ppfres = pdfont;
1168
1.35k
    return pdf_compute_BaseFont(pdev, pdfont, false);
1169
1.35k
}
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
279k
{
1175
279k
    gs_memory_t *mem = pdev->pdf_memory;
1176
279k
    double *ww, *vv = 0, *ww0 = 0;
1177
279k
    int chars_count = pdfont->count;
1178
1179
279k
    *w0 = (wmode ? pdfont->Widths : NULL);
1180
279k
    *v = (wmode ? pdfont->u.cidfont.v : NULL);
1181
279k
    *w = (wmode ? pdfont->u.cidfont.Widths2 : pdfont->Widths);
1182
279k
    if (*w == NULL) {
1183
1.35k
        ww = (double *)gs_alloc_byte_array(mem, chars_count, sizeof(*ww),
1184
1.35k
                                                    "pdf_obtain_cidfont_widths_arrays");
1185
1.35k
        if (wmode) {
1186
19
            vv = (double *)gs_alloc_byte_array(mem, chars_count, sizeof(*vv) * 2,
1187
19
                                                    "pdf_obtain_cidfont_widths_arrays");
1188
19
            if (pdfont->Widths == 0) {
1189
19
                ww0 = (double *)gs_alloc_byte_array(mem, chars_count, sizeof(*ww0),
1190
19
                                                    "pdf_obtain_cidfont_widths_arrays");
1191
19
                pdfont->Widths = *w0 = ww0;
1192
19
                if (ww0 != 0)
1193
19
                    memset(ww0, 0, chars_count * sizeof(*ww));
1194
19
            } else
1195
0
                *w0 = ww0 = pdfont->Widths;
1196
19
        }
1197
1.35k
        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.35k
        if (wmode)
1204
19
            memset(vv, 0, chars_count * 2 * sizeof(*vv));
1205
1.35k
        memset(ww, 0, chars_count * sizeof(*ww));
1206
1.35k
        if (wmode) {
1207
19
            pdfont->u.cidfont.Widths2 = *w = ww;
1208
19
            pdfont->u.cidfont.v = *v = vv;
1209
1.33k
        } else {
1210
1.33k
            pdfont->Widths = *w = ww;
1211
1.33k
            *v = NULL;
1212
1.33k
        }
1213
1.35k
    }
1214
279k
    return 0;
1215
279k
}
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
40.6k
{
1223
40.6k
    if (pdev->PDFA == 0)
1224
40.6k
        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
40.6k
}
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
4.52k
{
1280
4.52k
    return pdf_write_cmap(pdev, pcmap, ppres, font_index_only);
1281
4.52k
}