Coverage Report

Created: 2026-04-09 07:06

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