Coverage Report

Created: 2022-10-31 07:00

/src/ghostpdl/devices/vector/gdevpdtf.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2001-2022 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.,  1305 Grant Avenue - Suite 200, Novato,
13
   CA 94945, U.S.A., +1(415)492-9861, 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
232k
ENUM_PTRS_WITH(pdf_font_resource_enum_ptrs, pdf_font_resource_t *pdfont)
48
58.0k
ENUM_PREFIX(st_pdf_resource, 12);
49
14.5k
case 0: return ENUM_STRING(&pdfont->BaseFont);
50
14.5k
case 1: ENUM_RETURN(pdfont->FontDescriptor);
51
14.5k
case 2: ENUM_RETURN(pdfont->base_font);
52
14.5k
case 3: ENUM_RETURN(pdfont->Widths);
53
14.5k
case 4: ENUM_RETURN(pdfont->used);
54
14.5k
case 5: ENUM_RETURN(pdfont->res_ToUnicode);
55
14.5k
case 6: ENUM_RETURN(pdfont->cmap_ToUnicode);
56
14.5k
case 7: switch (pdfont->FontType) {
57
221
 case ft_composite:
58
221
     ENUM_RETURN(pdfont->u.type0.DescendantFont);
59
34
 case ft_CID_encrypted:
60
220
 case ft_CID_TrueType:
61
220
     ENUM_RETURN(pdfont->u.cidfont.Widths2);
62
14.0k
 default:
63
14.0k
     pdf_mark_glyph_names(pdfont, mem);
64
14.0k
     ENUM_RETURN(pdfont->u.simple.Encoding);
65
14.5k
}
66
14.5k
case 8: switch (pdfont->FontType) {
67
10.6k
 case ft_encrypted:
68
10.8k
 case ft_encrypted2:
69
13.5k
 case ft_TrueType:
70
13.5k
 case ft_PCL_user_defined:
71
13.5k
 case ft_MicroType:
72
13.5k
 case ft_GL2_stick_user_defined:
73
14.0k
 case ft_user_defined:
74
14.0k
 case ft_PDF_user_defined:
75
14.0k
 case ft_GL2_531:
76
14.0k
     ENUM_RETURN(pdfont->u.simple.v);
77
34
 case ft_CID_encrypted:
78
220
 case ft_CID_TrueType:
79
220
     ENUM_RETURN(pdfont->u.cidfont.v);
80
221
 case ft_composite:
81
221
 default:
82
221
     ENUM_RETURN(0);
83
14.5k
}
84
14.5k
case 9: switch (pdfont->FontType) {
85
0
 case ft_PCL_user_defined:
86
0
 case ft_MicroType:
87
0
 case ft_GL2_stick_user_defined:
88
525
 case ft_user_defined:
89
525
 case ft_PDF_user_defined:
90
525
 case ft_GL2_531:
91
525
     ENUM_RETURN(pdfont->u.simple.s.type3.char_procs);
92
34
 case ft_CID_encrypted:
93
220
 case ft_CID_TrueType:
94
220
     ENUM_RETURN(pdfont->u.cidfont.CIDToGIDMap);
95
13.7k
 default:
96
13.7k
     ENUM_RETURN(0);
97
14.5k
}
98
14.5k
case 10: switch (pdfont->FontType) {
99
0
 case ft_PCL_user_defined:
100
0
 case ft_MicroType:
101
0
 case ft_GL2_stick_user_defined:
102
525
 case ft_user_defined:
103
525
 case ft_PDF_user_defined:
104
525
 case ft_GL2_531:
105
525
     ENUM_RETURN(pdfont->u.simple.s.type3.cached);
106
34
 case ft_CID_encrypted:
107
220
 case ft_CID_TrueType:
108
220
     ENUM_RETURN(pdfont->u.cidfont.parent);
109
13.7k
 default:
110
13.7k
     ENUM_RETURN(0);
111
14.5k
}
112
14.5k
case 11: switch (pdfont->FontType) {
113
0
 case ft_PCL_user_defined:
114
0
 case ft_MicroType:
115
0
 case ft_GL2_stick_user_defined:
116
525
 case ft_user_defined:
117
525
 case ft_PDF_user_defined:
118
525
 case ft_GL2_531:
119
525
     ENUM_RETURN(pdfont->u.simple.s.type3.Resources);
120
34
 case ft_CID_encrypted:
121
220
 case ft_CID_TrueType:
122
220
     ENUM_RETURN(pdfont->u.cidfont.used2);
123
13.7k
 default:
124
13.7k
     ENUM_RETURN(0);
125
14.5k
}
126
232k
ENUM_PTRS_END
127
static
128
14.5k
RELOC_PTRS_WITH(pdf_font_resource_reloc_ptrs, pdf_font_resource_t *pdfont)
129
14.5k
{
130
14.5k
    RELOC_PREFIX(st_pdf_resource);
131
14.5k
    RELOC_STRING_VAR(pdfont->BaseFont);
132
14.5k
    RELOC_VAR(pdfont->FontDescriptor);
133
14.5k
    RELOC_VAR(pdfont->base_font);
134
14.5k
    RELOC_VAR(pdfont->Widths);
135
14.5k
    RELOC_VAR(pdfont->used);
136
14.5k
    RELOC_VAR(pdfont->res_ToUnicode);
137
14.5k
    RELOC_VAR(pdfont->cmap_ToUnicode);
138
14.5k
    switch (pdfont->FontType) {
139
221
    case ft_composite:
140
221
        RELOC_VAR(pdfont->u.type0.DescendantFont);
141
221
        break;
142
0
    case ft_PCL_user_defined:
143
0
    case ft_MicroType:
144
0
    case ft_GL2_stick_user_defined:
145
525
    case ft_user_defined:
146
525
    case ft_PDF_user_defined:
147
525
    case ft_GL2_531:
148
525
        RELOC_VAR(pdfont->u.simple.Encoding);
149
525
        RELOC_VAR(pdfont->u.simple.v);
150
525
        RELOC_VAR(pdfont->u.simple.s.type3.char_procs);
151
525
        RELOC_VAR(pdfont->u.simple.s.type3.cached);
152
525
        RELOC_VAR(pdfont->u.simple.s.type3.Resources);
153
525
        break;
154
34
    case ft_CID_encrypted:
155
220
    case ft_CID_TrueType:
156
220
        RELOC_VAR(pdfont->u.cidfont.Widths2);
157
220
        RELOC_VAR(pdfont->u.cidfont.v);
158
220
        RELOC_VAR(pdfont->u.cidfont.CIDToGIDMap);
159
220
        RELOC_VAR(pdfont->u.cidfont.parent);
160
220
        RELOC_VAR(pdfont->u.cidfont.used2);
161
220
        break;
162
13.5k
    default:
163
13.5k
        RELOC_VAR(pdfont->u.simple.Encoding);
164
13.5k
        RELOC_VAR(pdfont->u.simple.v);
165
13.5k
        break;
166
14.5k
    }
167
14.5k
}
168
14.5k
RELOC_PTRS_END
169
170
/* ---------------- Standard fonts ---------------- */
171
172
/* ------ Private ------ */
173
174
/* Define the 14 standard built-in fonts. */
175
32.7k
#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
21.4k
{
203
21.4k
    const pdf_standard_font_info_t *ppsf;
204
205
304k
    for (ppsf = standard_font_info; ppsf->fname; ++ppsf)
206
286k
        if (ppsf->size == size &&
207
286k
            !memcmp(ppsf->fname, (const char *)str, size)
208
286k
            )
209
2.82k
            return ppsf - standard_font_info;
210
18.6k
    return -1;
211
21.4k
}
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
48
{
223
48
    bool has_uid = uid_is_UniqueID(&bfont->UID) && bfont->UID.id != 0;
224
48
    const pdf_standard_font_t *psf = pdf_standard_fonts(pdev);
225
48
    int i;
226
227
48
    switch (bfont->FontType) {
228
42
    case ft_encrypted:
229
43
    case ft_encrypted2:
230
43
    case ft_TrueType:
231
43
        break;
232
5
    default:
233
5
        return -1;
234
48
    }
235
236
645
    for (i = 0; i < PDF_NUM_STANDARD_FONTS; ++psf, ++i) {
237
602
        gs_font_base *cfont;
238
602
        int code;
239
240
602
        if (!psf->pdfont)
241
592
            continue;
242
10
        cfont = pdf_font_resource_font(psf->pdfont, false);
243
10
        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
10
        code = gs_copied_can_copy_glyphs((const gs_font *)cfont,
255
10
                                         (const gs_font *)bfont,
256
10
                                         &pairs[0].glyph, num_glyphs,
257
10
                                         sizeof(pdf_char_glyph_pair_t), true);
258
10
        if (code == gs_error_unregistered) /* Debug purpose only. */
259
0
            return code;
260
        /* Note: code < 0 means an error. Skip it here. */
261
10
        if (code > 0)
262
0
            return i;
263
10
    }
264
43
    return -1;
265
43
}
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
48
{
275
48
    bool found = false;
276
48
    gs_font *orig = dir->orig_fonts;
277
278
152
    for (; orig; orig = orig->next) {
279
104
        gs_font_base *obfont;
280
281
104
        if (orig->FontType == ft_composite || !orig->is_resource)
282
84
            continue;
283
20
        obfont = (gs_font_base *)orig;
284
20
        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
20
    }
300
48
    return found;
301
48
}
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
16.0k
{
311
16.0k
    pdf_outline_fonts_t *pofs =
312
16.0k
        gs_alloc_struct(mem, pdf_outline_fonts_t, &st_pdf_outline_fonts,
313
16.0k
                        "pdf_outline_fonts_alloc(outline_fonts)");
314
16.0k
    pdf_standard_font_t *ppsf =
315
16.0k
        gs_alloc_struct_array(mem, PDF_NUM_STANDARD_FONTS,
316
16.0k
                              pdf_standard_font_t,
317
16.0k
                              &st_pdf_standard_font_element,
318
16.0k
                              "pdf_outline_fonts_alloc(standard_fonts)");
319
320
16.0k
    if (pofs == 0 || ppsf == 0)
321
0
        return 0;
322
16.0k
    memset(ppsf, 0, PDF_NUM_STANDARD_FONTS * sizeof(*ppsf));
323
16.0k
    memset(pofs, 0, sizeof(*pofs));
324
16.0k
    pofs->standard_fonts = ppsf;
325
16.0k
    return pofs;
326
16.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
18.8k
{
334
18.8k
    if (pdev->text != NULL && pdev->text->outline_fonts != NULL)
335
18.8k
        return pdev->text->outline_fonts->standard_fonts;
336
0
    return NULL;
337
18.8k
}
338
339
/*
340
 * Clean the standard fonts array.
341
 */
342
void
343
pdf_clean_standard_fonts(const gx_device_pdf *pdev)
344
16.0k
{
345
16.0k
    pdf_standard_font_t *ppsf = pdf_standard_fonts(pdev);
346
347
16.0k
    if (ppsf != NULL)
348
16.0k
        memset(ppsf, 0, PDF_NUM_STANDARD_FONTS * sizeof(*ppsf));
349
16.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, int old_size, int new_size)
357
626
{
358
626
    void *q = gs_alloc_byte_array(mem, new_size, elem_size, "pdf_resize_array");
359
360
626
    if (q == NULL)
361
0
        return_error(gs_error_VMerror);
362
626
    memset((char *)q + elem_size * old_size, 0, elem_size * (new_size - old_size));
363
626
    memcpy(q, *p, elem_size * old_size);
364
626
    gs_free_object(mem, *p, "pdf_resize_array");
365
626
    *p = q;
366
626
    return 0;
367
626
}
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
14.2k
{
378
14.2k
    gs_memory_t *mem = pdev->pdf_memory;
379
14.2k
    pdf_font_resource_t *pfres;
380
14.2k
    double *widths = 0;
381
14.2k
    byte *used = 0;
382
14.2k
    int code;
383
14.2k
    bool is_CID_font = (ftype == ft_CID_encrypted || ftype == ft_CID_TrueType);
384
385
14.2k
    if (chars_count != 0) {
386
14.0k
        uint size = (chars_count + 7) / 8;
387
388
14.0k
        if (!is_CID_font) {
389
13.8k
            widths = (void *)gs_alloc_byte_array(mem, chars_count, sizeof(*widths),
390
13.8k
                                                "font_resource_alloc(Widths)");
391
13.8k
        } else {
392
            /*  Delay allocation because we don't know which WMode will be used. */
393
205
        }
394
14.0k
        used = gs_alloc_bytes(mem, size, "font_resource_alloc(used)");
395
14.0k
        if ((!is_CID_font && widths == 0) || used == 0) {
396
0
            code = gs_note_error(gs_error_VMerror);
397
0
            goto fail;
398
0
        }
399
14.0k
        if (!is_CID_font)
400
13.8k
            memset(widths, 0, chars_count * sizeof(*widths));
401
14.0k
        memset(used, 0, size);
402
14.0k
    }
403
14.2k
    code = pdf_alloc_resource(pdev, rtype, rid, (pdf_resource_t **)&pfres, -1L);
404
14.2k
    if (code < 0)
405
0
        goto fail;
406
14.2k
    memset((byte *)pfres + sizeof(pdf_resource_t), 0,
407
14.2k
           sizeof(*pfres) - sizeof(pdf_resource_t));
408
14.2k
    pfres->FontType = ftype;
409
14.2k
    pfres->count = chars_count;
410
14.2k
    pfres->Widths = widths;
411
14.2k
    pfres->used = used;
412
14.2k
    pfres->write_contents = write_contents;
413
14.2k
    pfres->res_ToUnicode = NULL;
414
14.2k
    pfres->cmap_ToUnicode = NULL;
415
14.2k
    pfres->mark_glyph = 0;
416
14.2k
    pfres->mark_glyph_data = 0;
417
14.2k
    pfres->u.simple.standard_glyph_code_for_notdef = gs_c_name_glyph((const byte *)".notdef", 7) - gs_c_min_std_encoding_glyph;
418
14.2k
    *ppfres = pfres;
419
14.2k
    return 0;
420
0
 fail:
421
0
    gs_free_object(mem, used, "font_resource_alloc(used)");
422
0
    gs_free_object(mem, widths, "font_resource_alloc(Widths)");
423
0
    return code;
424
14.2k
}
425
426
int font_resource_free(gx_device_pdf *pdev, pdf_font_resource_t *pdfont)
427
14.2k
{
428
14.2k
    if(pdfont->BaseFont.size
429
14.2k
       && (pdfont->base_font == NULL || !pdfont->base_font->is_standard)) {
430
431
10.9k
        gs_free_string(pdev->pdf_memory, pdfont->BaseFont.data, pdfont->BaseFont.size, "Free BaseFont string");
432
10.9k
        pdfont->BaseFont.data = (byte *)0L;
433
10.9k
        pdfont->BaseFont.size = 0;
434
10.9k
    }
435
14.2k
    if(pdfont->Widths) {
436
14.0k
        gs_free_object(pdev->pdf_memory, pdfont->Widths, "Free Widths array");
437
14.0k
        pdfont->Widths = 0;
438
14.0k
    }
439
14.2k
    if(pdfont->used) {
440
14.0k
        gs_free_object(pdev->pdf_memory, pdfont->used, "Free used array");
441
14.0k
        pdfont->used = 0;
442
14.0k
    }
443
14.2k
    if(pdfont->res_ToUnicode) {
444
        /* ToUnicode resources are tracked amd released separately */
445
444
        pdfont->res_ToUnicode = 0;
446
444
    }
447
14.2k
    if(pdfont->cmap_ToUnicode) {
448
964
        gs_cmap_ToUnicode_free(pdev->pdf_memory, pdfont->cmap_ToUnicode);
449
964
        pdfont->cmap_ToUnicode = 0;
450
964
    }
451
14.2k
    switch(pdfont->FontType) {
452
206
        case ft_composite:
453
206
            if (pdfont->u.type0.CMapName_data != NULL) {
454
206
                gs_free_object(pdev->memory->non_gc_memory, (byte *)pdfont->u.type0.CMapName_data, "font_resource_free(CMapName)");
455
206
                pdfont->u.type0.CMapName_data = NULL;
456
206
                pdfont->u.type0.CMapName_size = 0;
457
206
            }
458
206
            break;
459
0
        case ft_PCL_user_defined:
460
0
        case ft_MicroType:
461
0
        case ft_GL2_stick_user_defined:
462
525
        case ft_user_defined:
463
525
        case ft_PDF_user_defined:
464
525
        case ft_GL2_531:
465
525
            if(pdfont->u.simple.Encoding) {
466
161
                int ix;
467
41.3k
                for (ix = 0; ix <= 255;ix++)
468
41.2k
                    gs_free_object(pdev->pdf_memory->non_gc_memory, pdfont->u.simple.Encoding[ix].data, "Free copied glyph name string");
469
161
                gs_free_object(pdev->pdf_memory, pdfont->u.simple.Encoding, "Free simple Encoding");
470
161
                pdfont->u.simple.Encoding = 0;
471
161
            }
472
525
            if(pdfont->u.simple.v) {
473
161
                gs_free_object(pdev->pdf_memory, pdfont->u.simple.v, "Free simple v");
474
161
                pdfont->u.simple.v = 0;
475
161
            }
476
525
            if (pdfont->u.simple.s.type3.char_procs) {
477
520
                pdf_free_charproc_ownership(pdev, (pdf_resource_t *)pdfont->u.simple.s.type3.char_procs);
478
520
                pdfont->u.simple.s.type3.char_procs = 0;
479
520
            }
480
525
            if (pdfont->u.simple.s.type3.cached) {
481
161
                gs_free_object(pdev->pdf_memory, pdfont->u.simple.s.type3.cached, "Free type 3 cached array");
482
161
                pdfont->u.simple.s.type3.cached = NULL;
483
161
            }
484
525
            if (pdfont->u.simple.s.type3.Resources != NULL) {
485
161
                cos_free((cos_object_t *)pdfont->u.simple.s.type3.Resources, "Free type 3 Resources dictionary");
486
161
                pdfont->u.simple.s.type3.Resources = NULL;
487
161
            }
488
525
            break;
489
34
        case ft_CID_encrypted:
490
205
        case ft_CID_TrueType:
491
205
            if(pdfont->u.cidfont.Widths2) {
492
5
                gs_free_object(pdev->pdf_memory, pdfont->u.cidfont.Widths2, "Free CIDFont Widths2 array");
493
5
                pdfont->u.cidfont.Widths2 = NULL;
494
5
            }
495
205
            if(pdfont->u.cidfont.v) {
496
5
                gs_free_object(pdev->pdf_memory, pdfont->u.cidfont.v, "Free CIDFont v array");
497
5
                pdfont->u.cidfont.v = NULL;
498
5
            }
499
205
            if(pdfont->u.cidfont.used2) {
500
205
                gs_free_object(pdev->pdf_memory, pdfont->u.cidfont.used2, "Free CIDFont used2");
501
205
                pdfont->u.cidfont.used2 = 0;
502
205
            }
503
205
            if(pdfont->u.cidfont.CIDToGIDMap) {
504
171
                gs_free_object(pdev->pdf_memory, pdfont->u.cidfont.CIDToGIDMap, "Free CIDToGID map");
505
171
                pdfont->u.cidfont.CIDToGIDMap = 0;
506
171
            }
507
205
            break;
508
13.3k
        default:
509
13.3k
            if(pdfont->u.simple.Encoding) {
510
13.3k
                int ix;
511
3.42M
                for (ix = 0; ix <= 255;ix++)
512
3.40M
                    gs_free_object(pdev->pdf_memory->non_gc_memory, pdfont->u.simple.Encoding[ix].data, "Free copied glyph name string");
513
13.3k
                gs_free_object(pdev->pdf_memory, pdfont->u.simple.Encoding, "Free simple Encoding");
514
13.3k
                pdfont->u.simple.Encoding = 0;
515
13.3k
            }
516
13.3k
            if(pdfont->u.simple.v) {
517
13.3k
                gs_free_object(pdev->pdf_memory, pdfont->u.simple.v, "Free simple v");
518
13.3k
                pdfont->u.simple.v = 0;
519
13.3k
            }
520
13.3k
            break;
521
14.2k
    }
522
14.2k
    if (pdfont->object) {
523
14.2k
        gs_free_object(pdev->pdf_memory, pdfont->object, "Free font resource object");
524
14.2k
        pdfont->object = 0;
525
14.2k
    }
526
    /* We free FontDescriptor resources separately */
527
14.2k
    if(pdfont->FontDescriptor)
528
10.7k
        pdfont->FontDescriptor = NULL;
529
3.50k
    else {
530
3.50k
        if (pdfont->base_font) {
531
            /* Normally we free the 'base font' when we free the Font Descriptor,
532
             * but if we have no font descriptor (we are not embedding the font),
533
             * we won't free the copies of the font, or any other associated memory,
534
             * so do it now.
535
             */
536
2.77k
            pdf_base_font_t *pbfont = pdfont->base_font;
537
2.77k
            gs_font *copied = (gs_font *)pbfont->copied, *complete = (gs_font *)pbfont->complete;
538
539
2.77k
            if (copied)
540
2.77k
                gs_free_copied_font(copied);
541
2.77k
            if (complete && copied != complete) {
542
0
                gs_free_copied_font(complete);
543
0
                pbfont->complete = 0;
544
0
            }
545
2.77k
            pbfont->copied = 0;
546
2.77k
            if (pbfont && pbfont->font_name.size) {
547
2.77k
                gs_free_string(pdev->pdf_memory, pbfont->font_name.data, pbfont->font_name.size, "Free BaseFont FontName string");
548
2.77k
                pbfont->font_name.data = (byte *)0L;
549
2.77k
                pbfont->font_name.size = 0;
550
2.77k
            }
551
2.77k
            if (pbfont) {
552
2.77k
                gs_free_object(pdev->pdf_memory, pbfont, "Free base font from FontDescriptor)");
553
2.77k
                pdfont->base_font = 0;
554
2.77k
            }
555
2.77k
        }
556
3.50k
    }
557
14.2k
    return 0;
558
14.2k
}
559
560
int
561
pdf_assign_font_object_id(gx_device_pdf *pdev, pdf_font_resource_t *pdfont)
562
589k
{
563
589k
    if (pdf_resource_id((pdf_resource_t *)pdfont) == -1) {
564
13.6k
        int code;
565
566
13.6k
        pdf_reserve_object_id(pdev, (pdf_resource_t *)pdfont, 0);
567
13.6k
        code = pdf_mark_font_descriptor_used(pdev, pdfont->FontDescriptor);
568
13.6k
        if (code < 0)
569
0
            return code;
570
13.6k
        if (pdfont->FontType == 0) {
571
202
            pdf_font_resource_t *pdfont1 = pdfont->u.type0.DescendantFont;
572
573
202
            if (pdf_font_id(pdfont1) == -1) {
574
201
                pdf_reserve_object_id(pdev, (pdf_resource_t *)pdfont1, 0);
575
201
                code = pdf_mark_font_descriptor_used(pdev, pdfont1->FontDescriptor);
576
201
                if (code < 0)
577
0
                    return code;
578
201
            }
579
202
        }
580
13.6k
    }
581
589k
    return 0;
582
589k
}
583
584
static int
585
font_resource_simple_alloc(gx_device_pdf *pdev, pdf_font_resource_t **ppfres,
586
                           gs_id rid, font_type ftype, int chars_count,
587
                           pdf_font_write_contents_proc_t write_contents)
588
13.8k
{
589
13.8k
    pdf_font_resource_t *pfres;
590
13.8k
    int code = font_resource_alloc(pdev, &pfres, resourceFont, rid, ftype,
591
13.8k
                                   chars_count, write_contents);
592
593
13.8k
    if (code < 0)
594
0
        return code;
595
13.8k
    pfres->u.simple.FirstChar = 256;
596
13.8k
    pfres->u.simple.LastChar = -1;
597
13.8k
    pfres->u.simple.BaseEncoding = -1;
598
13.8k
    pfres->u.simple.preferred_encoding_index = -1;
599
13.8k
    pfres->u.simple.last_reserved_char = -1;
600
13.8k
    pfres->TwoByteToUnicode = 1;
601
13.8k
    *ppfres = pfres;
602
13.8k
    return 0;
603
13.8k
}
604
int
605
font_resource_encoded_alloc(gx_device_pdf *pdev, pdf_font_resource_t **ppfres,
606
                            gs_id rid, font_type ftype,
607
                            pdf_font_write_contents_proc_t write_contents)
608
13.4k
{
609
13.4k
    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");
610
13.4k
    gs_point *v = (gs_point *)gs_alloc_byte_array(pdev->pdf_memory,
611
13.4k
                    256, sizeof(gs_point), "pdf_font_simple_alloc");
612
13.4k
    pdf_font_resource_t *pdfont;
613
13.4k
    int code, i;
614
615
13.4k
    if (v == 0 || Encoding == 0) {
616
0
        gs_free_object(pdev->pdf_memory, Encoding,
617
0
                       "font_resource_encoded_alloc");
618
0
        gs_free_object(pdev->pdf_memory, v,
619
0
                       "font_resource_encoded_alloc");
620
0
        return_error(gs_error_VMerror);
621
0
    }
622
13.4k
    code = font_resource_simple_alloc(pdev, &pdfont, rid, ftype,
623
13.4k
                                      256, write_contents);
624
13.4k
    if (code < 0) {
625
0
        gs_free_object(pdev->pdf_memory, Encoding,
626
0
                       "font_resource_encoded_alloc");
627
0
        gs_free_object(pdev->pdf_memory, v,
628
0
                       "font_resource_encoded_alloc");
629
0
        return_error(gs_error_VMerror);
630
0
    }
631
13.4k
    memset(v, 0, 256 * sizeof(*v));
632
13.4k
    memset(Encoding, 0, 256 * sizeof(*Encoding));
633
3.46M
    for (i = 0; i < 256; ++i)
634
3.44M
        Encoding[i].glyph = GS_NO_GLYPH;
635
13.4k
    pdfont->u.simple.Encoding = Encoding;
636
13.4k
    pdfont->u.simple.v = v;
637
13.4k
    *ppfres = pdfont;
638
13.4k
    return 0;
639
13.4k
}
640
641
/*
642
 * Record whether a Type 1 or Type 2 font is a Multiple Master instance.
643
 */
644
static void
645
set_is_MM_instance(pdf_font_resource_t *pdfont, const gs_font_base *pfont)
646
13.3k
{
647
13.3k
    switch (pfont->FontType) {
648
10.6k
    case ft_encrypted:
649
10.7k
    case ft_encrypted2:
650
10.7k
        pdfont->u.simple.s.type1.is_MM_instance =
651
10.7k
            ((const gs_font_type1 *)pfont)->data.WeightVector.count > 0;
652
13.3k
    default:
653
13.3k
        break;
654
13.3k
    }
655
13.3k
}
656
657
/* ------ Generic public ------ */
658
659
/* Resize font resource arrays. */
660
int
661
pdf_resize_resource_arrays(gx_device_pdf *pdev, pdf_font_resource_t *pfres, int chars_count)
662
25.9k
{
663
    /* This function fixes CID fonts that provide a lesser CIDCount than
664
       CIDs used in a document. Rather PS requires to print CID=0,
665
       we need to provide a bigger CIDCount since we don't
666
       re-encode the text. The text should look fine if the
667
       viewer application substitutes the font. */
668
25.9k
    gs_memory_t *mem = pdev->pdf_memory;
669
25.9k
    int code;
670
671
25.9k
    if (chars_count < pfres->count)
672
25.7k
        return 0;
673
170
    if (pfres->Widths != NULL) {
674
154
        code = pdf_resize_array(mem, (void **)&pfres->Widths, sizeof(*pfres->Widths),
675
154
                    pfres->count, chars_count);
676
154
        if (code < 0)
677
0
            return code;
678
154
    }
679
170
    code = pdf_resize_array(mem, (void **)&pfres->used, sizeof(*pfres->used),
680
170
                    (pfres->count + 7) / 8, (chars_count + 7) / 8);
681
170
    if (code < 0)
682
0
        return code;
683
170
    if (pfres->FontType == ft_CID_encrypted || pfres->FontType == ft_CID_TrueType) {
684
170
        if (pfres->u.cidfont.v != NULL) {
685
23
            code = pdf_resize_array(mem, (void **)&pfres->u.cidfont.v,
686
23
                    sizeof(*pfres->u.cidfont.v), pfres->count * 2, chars_count * 2);
687
23
            if (code < 0)
688
0
                return code;
689
23
        }
690
170
        if (pfres->u.cidfont.Widths2 != NULL) {
691
23
            code = pdf_resize_array(mem, (void **)&pfres->u.cidfont.Widths2,
692
23
                    sizeof(*pfres->u.cidfont.Widths2), pfres->count, chars_count);
693
23
            if (code < 0)
694
0
                return code;
695
23
        }
696
170
    }
697
170
    if (pfres->FontType == ft_CID_TrueType) {
698
86
        if (pfres->u.cidfont.CIDToGIDMap != NULL) {
699
86
            code = pdf_resize_array(mem, (void **)&pfres->u.cidfont.CIDToGIDMap,
700
86
                    sizeof(*pfres->u.cidfont.CIDToGIDMap), pfres->count, chars_count);
701
86
            if (code < 0)
702
0
                return code;
703
86
            pfres->u.cidfont.CIDToGIDMapLength = chars_count;
704
86
        }
705
86
    }
706
170
    if (pfres->FontType == ft_CID_encrypted || pfres->FontType == ft_CID_TrueType) {
707
170
        if (pfres->u.cidfont.used2 != NULL) {
708
170
            code = pdf_resize_array(mem, (void **)&pfres->u.cidfont.used2,
709
170
                    sizeof(*pfres->u.cidfont.used2),
710
170
                    (pfres->count + 7) / 8, (chars_count + 7) / 8);
711
170
            if (code < 0)
712
0
                return code;
713
170
        }
714
170
    }
715
170
    pfres->count = chars_count;
716
170
    return 0;
717
170
}
718
719
/* Get the object ID of a font resource. */
720
long
721
pdf_font_id(const pdf_font_resource_t *pdfont)
722
14.2k
{
723
14.2k
    return pdf_resource_id((const pdf_resource_t *)pdfont);
724
14.2k
}
725
726
/*
727
 * Return the (copied, subset) font associated with a font resource.
728
 * If this font resource doesn't have one (Type 0 or Type 3), return 0.
729
 */
730
gs_font_base *
731
pdf_font_resource_font(const pdf_font_resource_t *pdfont, bool complete)
732
15.1M
{
733
15.1M
    if (pdfont->base_font != NULL)
734
3.20M
        return pdf_base_font_font(pdfont->base_font, complete);
735
11.9M
    if (pdfont->FontDescriptor == 0)
736
48.6k
        return 0;
737
11.9M
    return pdf_font_descriptor_font(pdfont->FontDescriptor, complete);
738
11.9M
}
739
740
/*
741
 * Determine the embedding status of a font.  If the font is in the base
742
 * 14, store its index (0..13) in *pindex and its similarity to the base
743
 * font (as determined by the font's same_font procedure) in *psame.
744
 */
745
static bool
746
font_is_symbolic(const gs_font *font)
747
0
{
748
0
    if (font->FontType == ft_composite)
749
0
        return true;   /* arbitrary */
750
0
    switch (((const gs_font_base *)font)->nearest_encoding_index) {
751
0
    case ENCODING_INDEX_STANDARD:
752
0
    case ENCODING_INDEX_ISOLATIN1:
753
0
    case ENCODING_INDEX_WINANSI:
754
0
    case ENCODING_INDEX_MACROMAN:
755
0
        return false;
756
0
    default:
757
0
        return true;
758
0
    }
759
0
}
760
static bool
761
embed_list_includes(const gs_param_string_array *psa, const byte *chars,
762
                    uint size)
763
19.8k
{
764
19.8k
    uint i;
765
766
194k
    for (i = 0; i < psa->size; ++i)
767
175k
        if (!bytes_compare(psa->data[i].data, psa->data[i].size, chars, size))
768
1.36k
            return true;
769
18.4k
    return false;
770
19.8k
}
771
static bool
772
embed_as_standard(gx_device_pdf *pdev, gs_font *font, int index,
773
                  pdf_char_glyph_pair_t *pairs, int num_glyphs)
774
2.82k
{
775
2.82k
    if (font->is_resource) {
776
2.77k
        return true;
777
2.77k
    }
778
48
    if (find_std_appearance(pdev, (gs_font_base *)font, -1,
779
48
                            pairs, num_glyphs) == index)
780
0
        return true;
781
48
    if (!scan_for_standard_fonts(pdev, font->dir))
782
48
        return false;
783
0
    return (find_std_appearance(pdev, (gs_font_base *)font, -1,
784
0
                                pairs, num_glyphs) == index);
785
48
}
786
static bool
787
has_extension_glyphs(gs_font *pfont)
788
1.43k
{
789
1.43k
    psf_glyph_enum_t genum;
790
1.43k
    gs_glyph glyph;
791
1.43k
    gs_const_string str;
792
1.43k
    int code, j = 0, l;
793
1.43k
    const int sl = strlen(gx_extendeg_glyph_name_separator);
794
795
1.43k
    psf_enumerate_glyphs_begin(&genum, (gs_font *)pfont, NULL, 0, GLYPH_SPACE_NAME);
796
886k
    for (glyph = GS_NO_GLYPH; (psf_enumerate_glyphs_next(&genum, &glyph)) != 1; ) {
797
884k
        code = pfont->procs.glyph_name(pfont, glyph, &str);
798
884k
        if (code < 0)
799
0
            return code;
800
884k
        l = str.size - sl;
801
3.75M
        for (j = 0; j < l; j ++)
802
2.87M
            if (!memcmp(gx_extendeg_glyph_name_separator, str.data + j, sl))
803
0
                return true;
804
884k
    }
805
1.43k
    psf_enumerate_glyphs_reset(&genum);
806
1.43k
    return false;
807
1.43k
}
808
809
pdf_font_embed_t
810
pdf_font_embed_status(gx_device_pdf *pdev, gs_font *font, int *pindex,
811
                      pdf_char_glyph_pair_t *pairs, int num_glyphs)
812
21.4k
{
813
21.4k
    const gs_font_name *fn = &font->font_name;
814
21.4k
    const byte *chars = fn->chars;
815
21.4k
    uint size = fn->size;
816
21.4k
    int index = pdf_find_standard_font_name(chars, size);
817
21.4k
    bool embed_as_standard_called = false;
818
21.4k
    bool do_embed_as_standard = false; /* Quiet compiler. */
819
21.4k
    int code;
820
21.4k
    gs_font_info_t info;
821
822
21.4k
    memset(&info, 0x00, sizeof(gs_font_info_t));
823
21.4k
    code = font->procs.font_info(font, NULL, FONT_INFO_EMBEDDING_RIGHTS, &info);
824
21.4k
    if (code == 0 && (info.members & FONT_INFO_EMBEDDING_RIGHTS)) {
825
8.35k
        if (((info.EmbeddingRights == 0x0002) || (info.EmbeddingRights & 0x0200))
826
8.35k
            && !IsInWhiteList ((const char *)chars, size)) {
827
            /* See the OpenType specification, "The 'OS/2' and Windows Metrics Table" for details
828
               of the fstype parameter. This is a bitfield, currently we forbid embedding of fonts
829
               with these bits set:
830
               bit 1  0x0002  Fonts that have only this bit set must not be modified, embedded or
831
                                exchanged in any manner.
832
               bit 9  0x0200  Bitmap embedding only.
833
834
               Note for Restricted License embedding (bit 1), this must be the only level of embedding
835
               selected (see the OpenType spec).
836
             */
837
227
            char name[gs_font_name_max + 1];
838
227
            int len;
839
840
227
            len = min(gs_font_name_max, font->font_name.size);
841
227
            memcpy(name, font->font_name.chars, len);
842
227
            name[len] = 0;
843
227
            emprintf1(pdev->pdf_memory,
844
227
                      "\nWarning: %s cannot be embedded because of licensing restrictions\n",
845
227
                      name);
846
227
            return FONT_EMBED_NO;
847
227
        }
848
8.35k
    }
849
    /*
850
     * The behavior of Acrobat Distiller changed between 3.0 (PDF 1.2),
851
     * which will never embed the base 14 fonts, and 4.0 (PDF 1.3), which
852
     * doesn't treat them any differently from any other fonts.  However,
853
     * if any of the base 14 fonts is not embedded, it still requires
854
     * special treatment.
855
     */
856
21.2k
    if (pindex)
857
21.2k
        *pindex = index;
858
21.2k
    if (pdev->PDFX || pdev->PDFA != 0)
859
0
        return FONT_EMBED_YES;
860
21.2k
    if (pdev->CompatibilityLevel < 1.3) {
861
8.11k
        if (index >= 0 &&
862
8.11k
            (embed_as_standard_called = true,
863
1.46k
                do_embed_as_standard = embed_as_standard(pdev, font, index, pairs, num_glyphs))) {
864
1.43k
            if (pdev->ForOPDFRead && has_extension_glyphs(font))
865
0
                return FONT_EMBED_YES;
866
1.43k
            return FONT_EMBED_STANDARD;
867
1.43k
        }
868
8.11k
    }
869
    /* Check the Embed lists. */
870
19.8k
    if (!embed_list_includes(&pdev->params.NeverEmbed, chars, size) ||
871
19.8k
        (index >= 0 &&
872
1.36k
            !(embed_as_standard_called ? do_embed_as_standard :
873
1.36k
             (embed_as_standard_called = true,
874
1.36k
              (do_embed_as_standard = embed_as_standard(pdev, font, index, pairs, num_glyphs)))))
875
        /* Ignore NeverEmbed for a non-standard font with a standard name */
876
19.8k
        ) {
877
18.4k
        if (pdev->params.EmbedAllFonts || font_is_symbolic(font) ||
878
18.4k
            embed_list_includes(&pdev->params.AlwaysEmbed, chars, size))
879
18.4k
            return FONT_EMBED_YES;
880
18.4k
    }
881
1.34k
    if (index >= 0 &&
882
1.34k
        (embed_as_standard_called ? do_embed_as_standard :
883
1.34k
         embed_as_standard(pdev, font, index, pairs, num_glyphs)))
884
1.34k
        return FONT_EMBED_STANDARD;
885
0
    return FONT_EMBED_NO;
886
1.34k
}
887
888
/*
889
 * Compute the BaseFont of a font according to the algorithm described
890
 * in gdevpdtf.h.
891
 */
892
int
893
pdf_compute_BaseFont(gx_device_pdf *pdev, pdf_font_resource_t *pdfont, bool finish)
894
25.1k
{
895
25.1k
    pdf_font_resource_t *pdsubf = pdfont;
896
25.1k
    gs_string fname;
897
25.1k
    uint size;
898
25.1k
    byte *data;
899
900
25.1k
    if (pdfont->FontType == ft_composite) {
901
408
        int code;
902
903
408
        pdsubf = pdfont->u.type0.DescendantFont;
904
408
        code = pdf_compute_BaseFont(pdev, pdsubf, finish);
905
408
        if (code < 0)
906
0
            return code;
907
408
        fname = pdsubf->BaseFont;
908
408
    }
909
24.7k
    else if (pdfont->FontDescriptor == 0) {
910
        /* Type 3 font, or has its BaseFont computed in some other way. */
911
3.28k
        return 0;
912
3.28k
    } else
913
21.4k
        fname = *pdf_font_descriptor_base_name(pdsubf->FontDescriptor);
914
21.8k
    size = fname.size;
915
21.8k
    data = gs_alloc_string(pdev->pdf_memory, size,
916
21.8k
                           "pdf_compute_BaseFont");
917
21.8k
    if (data == 0)
918
0
        return_error(gs_error_VMerror);
919
21.8k
    memcpy(data, fname.data, size);
920
21.8k
    switch (pdfont->FontType) {
921
408
    case ft_composite:
922
        /* Previously we copied the name of the original CMap onto the font name
923
         * but this doesn't make any sense.
924
         */
925
408
        break;
926
15.3k
    case ft_encrypted:
927
15.6k
    case ft_encrypted2:
928
15.6k
        if (pdfont->u.simple.s.type1.is_MM_instance &&
929
15.6k
            !pdf_font_descriptor_embedding(pdfont->FontDescriptor)
930
15.6k
            ) {
931
            /* Replace spaces by underscores in the base name. */
932
0
            uint i;
933
934
0
            for (i = 0; i < size; ++i)
935
0
                if (data[i] == ' ')
936
0
                    data[i] = '_';
937
0
        }
938
15.6k
        break;
939
5.02k
    case ft_TrueType:
940
5.70k
    case ft_CID_TrueType: {
941
        /* Remove spaces from the base name. */
942
5.70k
        uint i, j;
943
944
57.7k
        for (i = j = 0; i < size; ++i)
945
52.0k
            if (data[i] != ' ')
946
51.9k
                data[j++] = data[i];
947
5.70k
        data = gs_resize_string(pdev->pdf_memory, data, i, j,
948
5.70k
                                "pdf_compute_BaseFont");
949
5.70k
        size = j;
950
5.70k
        break;
951
5.02k
    }
952
132
    default:
953
132
        break;
954
21.8k
    }
955
21.8k
    if (pdfont->BaseFont.size)
956
10.9k
        gs_free_string(pdev->pdf_memory, pdfont->BaseFont.data, pdfont->BaseFont.size, "Replacing BaseFont string");
957
21.8k
    pdfont->BaseFont.data = fname.data = data;
958
21.8k
    pdfont->BaseFont.size = fname.size = size;
959
    /* Compute names for subset fonts. */
960
21.8k
    if (finish && pdfont->FontDescriptor != NULL &&
961
21.8k
        pdf_font_descriptor_is_subset(pdfont->FontDescriptor) &&
962
21.8k
        !pdf_has_subset_prefix(fname.data, fname.size) &&
963
21.8k
        pdf_font_descriptor_embedding(pdfont->FontDescriptor)
964
21.8k
        ) {
965
10.5k
        int code;
966
10.5k
        gs_font_base *pbfont = pdf_font_resource_font(pdfont, false);
967
968
10.5k
        if (pdfont->FontDescriptor)
969
10.5k
            code = pdf_add_subset_prefix(pdev, &fname, pdfont->used, pdfont->count, pdf_fontfile_hash(pdfont->FontDescriptor));
970
0
        else
971
0
            code = pdf_add_subset_prefix(pdev, &fname, pdfont->used, pdfont->count, 0);
972
973
10.5k
        if (code < 0)
974
0
            return code;
975
10.5k
        pdfont->BaseFont = fname;
976
977
        /* Don't write a UID for subset fonts. */
978
10.5k
        if (uid_is_XUID(&pbfont->UID)) {
979
0
            uid_free(&pbfont->UID, pbfont->memory, "gs_font_finalize");
980
0
        }
981
10.5k
        uid_set_invalid(&pbfont->UID);
982
10.5k
    }
983
21.8k
    if (pdfont->FontType != ft_composite && pdsubf->FontDescriptor)
984
21.4k
        *pdf_font_descriptor_name(pdsubf->FontDescriptor) = fname;
985
21.8k
    return 0;
986
21.8k
}
987
988
/* ------ Type 0 ------ */
989
990
/* Allocate a Type 0 font resource. */
991
int
992
pdf_font_type0_alloc(gx_device_pdf *pdev, pdf_font_resource_t **ppfres,
993
                     gs_id rid, pdf_font_resource_t *DescendantFont,
994
                     const gs_const_string *CMapName)
995
206
{
996
206
    int code = font_resource_alloc(pdev, ppfres, resourceFont, rid,
997
206
                                   ft_composite, 0, pdf_write_contents_type0);
998
999
206
    if (code >= 0) {
1000
206
        byte *chars = NULL;
1001
1002
206
        (*ppfres)->u.type0.DescendantFont = DescendantFont;
1003
1004
206
        chars = gs_alloc_bytes(pdev->pdf_memory->non_gc_memory, CMapName->size, "pdf_font_resource_t(CMapName)");
1005
206
        if (chars == 0)
1006
0
            return_error(gs_error_VMerror);
1007
206
        memcpy(chars, CMapName->data, CMapName->size);
1008
206
        (*ppfres)->u.type0.CMapName_data = chars;
1009
206
        (*ppfres)->u.type0.CMapName_size = CMapName->size;
1010
1011
206
        (*ppfres)->u.type0.font_index = 0;
1012
206
        code = pdf_compute_BaseFont(pdev, *ppfres, false);
1013
206
    }
1014
206
    return code;
1015
206
}
1016
1017
/* ------ Type 3 ------ */
1018
1019
/* Allocate a Type 3 font resource for sinthesyzed bitmap fonts. */
1020
int
1021
pdf_font_type3_alloc(gx_device_pdf *pdev, pdf_font_resource_t **ppfres,
1022
                     pdf_font_write_contents_proc_t write_contents)
1023
364
{
1024
364
    return font_resource_simple_alloc(pdev, ppfres, gs_no_id, ft_user_defined,
1025
364
                                      256, write_contents);
1026
364
}
1027
1028
/* ------ Standard (base 14) Type 1 or TrueType ------ */
1029
1030
/* Allocate a standard (base 14) font resource. */
1031
int
1032
pdf_font_std_alloc(gx_device_pdf *pdev, pdf_font_resource_t **ppfres,
1033
                   bool is_original, gs_id rid, gs_font_base *pfont, int index)
1034
2.77k
{
1035
2.77k
    pdf_font_resource_t *pdfont;
1036
2.77k
    int code = font_resource_encoded_alloc(pdev, &pdfont, rid, pfont->FontType,
1037
2.77k
                                           pdf_write_contents_std);
1038
2.77k
    const pdf_standard_font_info_t *psfi = &standard_font_info[index];
1039
2.77k
    pdf_standard_font_t *psf = &pdf_standard_fonts(pdev)[index];
1040
2.77k
    gs_matrix *orig_matrix = (is_original ? &pfont->FontMatrix : &psf->orig_matrix);
1041
1042
2.77k
    if (code < 0 ||
1043
2.77k
        (code = pdf_base_font_alloc(pdev, &pdfont->base_font, pfont, orig_matrix, true)) < 0
1044
2.77k
        )
1045
4
        return code;
1046
2.77k
    pdfont->BaseFont.data = (byte *)psfi->fname; /* break const */
1047
2.77k
    pdfont->BaseFont.size = strlen(psfi->fname);
1048
2.77k
    pdfont->mark_glyph = pfont->dir->ccache.mark_glyph;
1049
2.77k
    set_is_MM_instance(pdfont, pfont);
1050
2.77k
    if (is_original) {
1051
2.77k
        psf->pdfont = pdfont;
1052
2.77k
        psf->orig_matrix = pfont->FontMatrix;
1053
2.77k
    }
1054
2.77k
    *ppfres = pdfont;
1055
2.77k
    return 0;
1056
2.77k
}
1057
1058
/* ------ Other Type 1 or TrueType ------ */
1059
1060
/* Allocate a Type 1 or TrueType font resource. */
1061
int
1062
pdf_font_simple_alloc(gx_device_pdf *pdev, pdf_font_resource_t **ppfres,
1063
                      gs_id rid, pdf_font_descriptor_t *pfd)
1064
10.5k
{
1065
10.5k
    pdf_font_resource_t *pdfont;
1066
10.5k
    int code;
1067
1068
10.5k
    code = font_resource_encoded_alloc(pdev, &pdfont, rid,
1069
10.5k
                                           pdf_font_descriptor_FontType(pfd),
1070
10.5k
                                           pdf_write_contents_simple);
1071
1072
10.5k
    if (code < 0)
1073
0
        return(gs_note_error(code));
1074
10.5k
    pdfont->FontDescriptor = pfd;
1075
10.5k
    set_is_MM_instance(pdfont, pdf_font_descriptor_font(pfd, false));
1076
10.5k
    *ppfres = pdfont;
1077
10.5k
    return pdf_compute_BaseFont(pdev, pdfont, false);
1078
10.5k
}
1079
1080
/* ------ CID-keyed ------ */
1081
1082
/* Allocate a CIDFont resource. */
1083
int
1084
pdf_font_cidfont_alloc(gx_device_pdf *pdev, pdf_font_resource_t **ppfres,
1085
                       gs_id rid, pdf_font_descriptor_t *pfd)
1086
205
{
1087
205
    font_type FontType = pdf_font_descriptor_FontType(pfd);
1088
205
    gs_font_base *font = pdf_font_descriptor_font(pfd, false);
1089
205
    int chars_count;
1090
205
    int code;
1091
205
    pdf_font_write_contents_proc_t write_contents;
1092
205
    const gs_cid_system_info_t *pcidsi;
1093
205
    ushort *map = 0;
1094
205
    pdf_font_resource_t *pdfont;
1095
1096
205
    switch (FontType) {
1097
34
    case ft_CID_encrypted:
1098
34
        chars_count = ((const gs_font_cid0 *)font)->cidata.common.CIDCount;
1099
34
        pcidsi = &((const gs_font_cid0 *)font)->cidata.common.CIDSystemInfo;
1100
34
        write_contents = pdf_write_contents_cid0;
1101
34
        break;
1102
171
    case ft_CID_TrueType:
1103
171
        chars_count = ((const gs_font_cid2 *)font)->cidata.common.CIDCount;
1104
171
        pcidsi = &((const gs_font_cid2 *)font)->cidata.common.CIDSystemInfo;
1105
171
        map = (void *)gs_alloc_byte_array(pdev->pdf_memory, chars_count,
1106
171
                                          sizeof(*map), "CIDToGIDMap");
1107
171
        if (map == 0)
1108
0
            return_error(gs_error_VMerror);
1109
171
        memset(map, 0, chars_count * sizeof(*map));
1110
171
        write_contents = pdf_write_contents_cid2;
1111
171
        break;
1112
0
    default:
1113
0
        return_error(gs_error_rangecheck);
1114
205
    }
1115
205
    code = font_resource_alloc(pdev, &pdfont, resourceCIDFont, rid, FontType,
1116
205
                               chars_count, write_contents);
1117
205
    if (code < 0)
1118
0
        return code;
1119
205
    pdfont->FontDescriptor = pfd;
1120
205
    pdfont->u.cidfont.CIDToGIDMap = map;
1121
205
    pdfont->u.cidfont.CIDToGIDMapLength = chars_count;
1122
    /* fixme : Likely pdfont->u.cidfont.CIDToGIDMap duplicates
1123
       pdfont->FontDescriptor->base_font->copied->client_data->CIDMap.
1124
       Only difference is 0xFFFF designates unmapped CIDs.
1125
     */
1126
205
    pdfont->u.cidfont.Widths2 = NULL;
1127
205
    pdfont->u.cidfont.v = NULL;
1128
205
    pdfont->u.cidfont.parent = NULL;
1129
    /* Don' know whether the font will use WMode 1,
1130
       so reserve it now. */
1131
205
    pdfont->u.cidfont.used2 = gs_alloc_bytes(pdev->pdf_memory,
1132
205
                (chars_count + 7) / 8, "pdf_font_cidfont_alloc");
1133
205
    if (pdfont->u.cidfont.used2 == NULL)
1134
0
        return_error(gs_error_VMerror);
1135
205
    memset(pdfont->u.cidfont.used2, 0, (chars_count + 7) / 8);
1136
    /*
1137
     * Write the CIDSystemInfo now, so we don't try to access it after
1138
     * the font may no longer be available.
1139
     */
1140
205
    code = pdf_write_cid_systemInfo_separate(pdev, pcidsi, &pdfont->u.cidfont.CIDSystemInfo_id);
1141
205
    if (code < 0)
1142
0
        return code;
1143
205
    *ppfres = pdfont;
1144
205
    return pdf_compute_BaseFont(pdev, pdfont, false);
1145
205
}
1146
1147
int
1148
pdf_obtain_cidfont_widths_arrays(gx_device_pdf *pdev, pdf_font_resource_t *pdfont,
1149
                                 int wmode, double **w, double **w0, double **v)
1150
25.9k
{
1151
25.9k
    gs_memory_t *mem = pdev->pdf_memory;
1152
25.9k
    double *ww, *vv = 0, *ww0 = 0;
1153
25.9k
    int chars_count = pdfont->count;
1154
1155
25.9k
    *w0 = (wmode ? pdfont->Widths : NULL);
1156
25.9k
    *v = (wmode ? pdfont->u.cidfont.v : NULL);
1157
25.9k
    *w = (wmode ? pdfont->u.cidfont.Widths2 : pdfont->Widths);
1158
25.9k
    if (*w == NULL) {
1159
205
        ww = (double *)gs_alloc_byte_array(mem, chars_count, sizeof(*ww),
1160
205
                                                    "pdf_obtain_cidfont_widths_arrays");
1161
205
        if (wmode) {
1162
5
            vv = (double *)gs_alloc_byte_array(mem, chars_count, sizeof(*vv) * 2,
1163
5
                                                    "pdf_obtain_cidfont_widths_arrays");
1164
5
            if (pdfont->Widths == 0) {
1165
5
                ww0 = (double *)gs_alloc_byte_array(mem, chars_count, sizeof(*ww0),
1166
5
                                                    "pdf_obtain_cidfont_widths_arrays");
1167
5
                pdfont->Widths = *w0 = ww0;
1168
5
                if (ww0 != 0)
1169
5
                    memset(ww0, 0, chars_count * sizeof(*ww));
1170
5
            } else
1171
0
                *w0 = ww0 = pdfont->Widths;
1172
5
        }
1173
205
        if (ww == 0 || (wmode && vv == 0) || (wmode && ww0 == 0)) {
1174
0
            gs_free_object(mem, ww, "pdf_obtain_cidfont_widths_arrays");
1175
0
            gs_free_object(mem, vv, "pdf_obtain_cidfont_widths_arrays");
1176
0
            gs_free_object(mem, ww0, "pdf_obtain_cidfont_widths_arrays");
1177
0
            return_error(gs_error_VMerror);
1178
0
        }
1179
205
        if (wmode)
1180
5
            memset(vv, 0, chars_count * 2 * sizeof(*vv));
1181
205
        memset(ww, 0, chars_count * sizeof(*ww));
1182
205
        if (wmode) {
1183
5
            pdfont->u.cidfont.Widths2 = *w = ww;
1184
5
            pdfont->u.cidfont.v = *v = vv;
1185
200
        } else {
1186
200
            pdfont->Widths = *w = ww;
1187
200
            *v = NULL;
1188
200
        }
1189
205
    }
1190
25.9k
    return 0;
1191
25.9k
}
1192
1193
/*
1194
 * Convert True Type fonts into CID fonts for PDF/A.
1195
 */
1196
int
1197
pdf_convert_truetype_font(gx_device_pdf *pdev, pdf_resource_t *pres)
1198
14.0k
{
1199
14.0k
    if (pdev->PDFA == 0)
1200
14.0k
        return 0;
1201
0
    else {
1202
0
        pdf_font_resource_t *pdfont = (pdf_font_resource_t *)pres;
1203
1204
0
        if (pdfont->FontType != ft_TrueType)
1205
0
            return 0;
1206
0
        else if (pdf_resource_id(pres) == -1)
1207
0
            return 0; /* An unused font. */
1208
0
        else {
1209
0
            int code = pdf_different_encoding_index(pdfont, 0);
1210
1211
0
            if (code < 0)
1212
0
                return code;
1213
0
            if (code == 256 && pdfont->u.simple.BaseEncoding != ENCODING_INDEX_UNKNOWN)
1214
0
                return 0;
1215
0
            { /* The encoding have a difference - do convert. */
1216
0
                pdf_font_resource_t *pdfont0;
1217
0
                gs_const_string CMapName = {(const byte *)"OneByteIdentityH", 16};
1218
1219
0
                code = pdf_convert_truetype_font_descriptor(pdev, pdfont);
1220
0
                if (code < 0)
1221
0
                    return code;
1222
0
                code = pdf_font_type0_alloc(pdev, &pdfont0, pres->rid + 1, pdfont, &CMapName);
1223
0
                if (code < 0)
1224
0
                    return code;
1225
                /* Pass the font object ID to the type 0 font resource. */
1226
0
                pdf_reserve_object_id(pdev, (pdf_resource_t *)pdfont0, pdf_resource_id(pres));
1227
0
                pdf_reserve_object_id(pdev, (pdf_resource_t *)pdfont, gs_no_id);
1228
                /* Set Encoding_name because we won't call attach_cmap_resource for it : */
1229
0
                code = pdf_write_OneByteIdentityH(pdev);
1230
0
                if (code < 0)
1231
0
                    return 0;
1232
0
                pdfont->u.cidfont.CIDSystemInfo_id = pdev->IdentityCIDSystemInfo_id;
1233
0
                gs_snprintf(pdfont0->u.type0.Encoding_name, sizeof(pdfont0->u.type0.Encoding_name),
1234
0
                            "%ld 0 R", pdf_resource_id(pdev->OneByteIdentityH));
1235
                /* Move ToUnicode : */
1236
0
                pdfont0->res_ToUnicode = pdfont->res_ToUnicode; pdfont->res_ToUnicode = 0;
1237
0
                pdfont0->cmap_ToUnicode = pdfont->cmap_ToUnicode; pdfont->cmap_ToUnicode = 0;
1238
                /* Change the font type to CID font : */
1239
0
                pdfont->FontType = ft_CID_TrueType;
1240
0
                pdfont->write_contents = pdf_write_contents_cid2;
1241
0
                return 0;
1242
0
            }
1243
0
        }
1244
0
    }
1245
14.0k
}
1246
1247
/* ---------------- CMap resources ---------------- */
1248
1249
/*
1250
 * Allocate a CMap resource.
1251
 */
1252
int
1253
pdf_cmap_alloc(gx_device_pdf *pdev, const gs_cmap_t *pcmap,
1254
               pdf_resource_t **ppres, int font_index_only)
1255
451
{
1256
451
    return pdf_write_cmap(pdev, pcmap, ppres, font_index_only);
1257
451
}