Coverage Report

Created: 2025-06-24 07:01

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