Coverage Report

Created: 2026-04-01 07:17

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ghostpdl/devices/vector/gdevpdtb.c
Line
Count
Source
1
/* Copyright (C) 2001-2024 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
/* BaseFont implementation for pdfwrite */
18
#include "memory_.h"
19
#include "ctype_.h"
20
#include "gx.h"
21
#include "gserrors.h"
22
#include "gsutil.h"   /* for bytes_compare */
23
#include "gxfcid.h"
24
#include "gxfcopy.h"
25
#include "gxfont.h"   /* for gxfont42.h */
26
#include "gxfont42.h"
27
#include "gdevpsf.h"
28
#include "gdevpdfx.h"
29
#include "gdevpdfo.h"
30
#include "gdevpdtb.h"
31
#include "gdevpdtf.h"
32
#include "gdevpdtd.h"
33
#include "smd5.h"
34
#include "gxfcache.h"   /* for gs_purge_font_from_char_caches_completely */
35
/*
36
 * Adobe's Distiller Parameters documentation for Acrobat Distiller 5
37
 * says that all fonts other than Type 1 are always subsetted; the
38
 * documentation for Distiller 4 says that fonts other than Type 1 and
39
 * TrueType are subsetted.  We do the latter, except that we always
40
 * subset large TrueType fonts.
41
 */
42
28.1k
#define MAX_NO_SUBSET_GLYPHS 4096  /* arbitrary */
43
44
/* ---------------- Private ---------------- */
45
46
private_st_pdf_base_font();
47
gs_private_st_basic(st_pdf_base_font, pdf_base_font_t, "pdf_base_font_t",\
48
                    pdf_base_font_ptrs, pdf_base_font_data);
49
50
typedef struct pdf_base14_font_info_s {
51
    const char *urwname;
52
    const char *stdname;
53
} pdf_base14_font_info_t;
54
55
static const pdf_base14_font_info_t base14_font_info[] = {
56
    /* Standard mapping of URW fonts */
57
    {"NimbusMonL-Regu",       "Courier"              },
58
    {"NimbusMonL-Bold",       "Courier-Bold"         },
59
    {"NimbusMonL-ReguObli",   "Courier-Oblique"      },
60
    {"NimbusMonL-BoldObli",   "Courier-BoldOblique"  },
61
    {"NimbusSanL-Regu",       "Helvetica"            },
62
    {"NimbusSanL-Bold",       "Helvetica-Bold"       },
63
    {"NimbusSanL-ReguItal",   "Helvetica-Oblique"    },
64
    {"NimbusSanL-BoldItal",   "Helvetica-BoldOblique"},
65
    {"StandardSymL",          "Symbol"               },
66
    {"NimbusRomNo9L-Regu",    "Times-Roman"          },
67
    {"NimbusRomNo9L-Medi",    "Times-Bold"           },
68
    {"NimbusRomNo9L-ReguItal","Times-Italic"         },
69
    {"NimbusRomNo9L-MediItal","Times-BoldItalic"     },
70
    {"Dingbats",              "ZapfDingbats"         },
71
    /* A few other mappings of URW fonts */
72
    {"NimbusMono-Reg",        "Courier"              },
73
    {"NimbusMono-Bol",        "Courier-Bold"         },
74
    {"NimbusMono-Ita",        "Courier-Oblique"      },
75
    {"NimbusMono-BolIta",     "Courier-BoldOblique"   },
76
    {"NimbusSan-Reg",         "Helvetica"            },
77
    {"NimbusSan-Bol",         "Helvetica-Bold"       },
78
    {"NimbusSan-Ita",         "Helvetica-Oblique"    },
79
    {"NimbusSan-BolIta",      "Helvetica-BoldOblique"},
80
    {"A030-Reg",              "Helvetica"            },
81
    {"A030-Bol",              "Helvetica-Bold"       },
82
    {"A030-Ita",              "Helvetica-Oblique"    },
83
    {"A030-BolIta",           "Helvetica-BoldOblique"},
84
    {"NimbusSanNo2-Reg",      "Helvetica"            },
85
    {"NimbusSanNo2-Bol",      "Helvetica-Bold"       },
86
    {"NimbusSanNo2-Ita",      "Helvetica-Oblique"    },
87
    {"NimbusSanNo2-BolIta",   "Helvetica-BoldOblique"},
88
    {"NimbusRomanNo4-Lig",    "Times-Roman"          },
89
    {"NimbusRomanNo4-Bol",    "Times-Bold"           },
90
    {"NimbusRomanNo4-LigIta", "Times-Italic"         },
91
    {"NimbusRomanNo4-BolIta", "Times-BoldItalic"     },
92
    {"NimbusRomanNo9-Reg",    "Times-Roman"          },
93
    {"NimbusRomanNo9-Med",    "Times-Bold"           },
94
    {"NimbusRomanNo9-Ita",    "Times-Italic"         },
95
    {"NimbusRomanNo9-MedIta", "Times-BoldItalic"     },
96
    {"NimbusRom-Reg",         "Times-Roman"          },
97
    {"NimbusRom-Med",         "Times-Bold"           },
98
    {"NimbusRom-Ita",         "Times-Italic"         },
99
    {"NimbusRom-MedIta",      "Times-BoldItalic"     },
100
    {"NimbusRomNo9-Reg",      "Times-Roman"          },
101
    {"NimbusRomNo9-Bol",      "Times-Bold"           },
102
    {"NimbusRomNo9-Ita",      "Times-Italic"         },
103
    {"NimbusRomNo9-MedIta",   "Times-BoldItalic"     },
104
    {0}
105
};
106
107
/* Given a pointer to a font name, return a pointer to an
108
 * equivalent base 14 font name, of NULL if there is no
109
 * equivalent.
110
 */
111
const char *pdf_find_base14_name(const byte *str, uint size)
112
48
{
113
48
    const pdf_base14_font_info_t *ppsf;
114
115
2.25k
    for (ppsf = base14_font_info; ppsf->urwname; ++ppsf) {
116
2.20k
        if (strlen(ppsf->urwname) == size) {
117
22
            if (!memcmp(ppsf->urwname, (const char *)str, size))
118
0
                return ppsf->stdname;
119
22
        }
120
2.20k
    }
121
48
    return NULL;
122
48
}
123
124
125
/*
126
 * Determine whether a font is a subset font by examining the name.
127
 */
128
bool
129
pdf_has_subset_prefix(const byte *str, uint size)
130
5.50M
{
131
5.50M
    int i;
132
133
5.50M
    if (size < SUBSET_PREFIX_SIZE || str[SUBSET_PREFIX_SIZE - 1] != '+')
134
3.66M
        return false;
135
12.9M
    for (i = 0; i < SUBSET_PREFIX_SIZE - 1; ++i)
136
11.0M
        if ((uint)(str[i] - 'A') >= 26)
137
344
            return false;
138
1.84M
    return true;
139
1.84M
}
140
141
static inline ulong
142
hash(ulong v, int index, ushort w)
143
4.64M
{
144
4.64M
    return v * 3141592653u + w;
145
4.64M
}
146
147
/*
148
 * Add the XXXXXX+ prefix for a subset font.
149
 */
150
int
151
pdf_add_subset_prefix(const gx_device_pdf *pdev, gs_string *pstr, byte *used, int count, char *md5_hash)
152
26.1k
{
153
26.1k
    uint size = pstr->size;
154
26.1k
    byte *data = gs_resize_string(pdev->pdf_memory, pstr->data, size,
155
26.1k
                                  size + SUBSET_PREFIX_SIZE,
156
26.1k
                                  "pdf_add_subset_prefix");
157
26.1k
    int len = (count + 7) / 8;
158
26.1k
    int len0 = len & ~(sizeof(ushort) - 1);
159
26.1k
    ulong v = 0;
160
26.1k
    int i;
161
162
26.1k
    if (data == 0)
163
0
        return_error(gs_error_VMerror);
164
165
26.1k
    if (md5_hash) {
166
127k
        for (i = 0; i < 8; i += sizeof(ushort)) {
167
101k
      v = hash(v, i, (*(md5_hash + i) | *(md5_hash + i + 1) << 8));
168
101k
        }
169
25.4k
    }
170
171
    /* Hash the 'used' array. */
172
4.56M
    for (i = 0; i < len0; i += sizeof(ushort))
173
4.54M
        v = hash(v, i, *(ushort *)(used + i));
174
27.9k
    for (; i < len; i++)
175
1.79k
        v = hash(v, i, used[i]);
176
177
26.1k
    memmove(data + SUBSET_PREFIX_SIZE, data, size);
178
182k
    for (i = 0; i < SUBSET_PREFIX_SIZE - 1; ++i, v /= 26)
179
156k
        data[i] = 'A' + (v % 26);
180
26.1k
    data[SUBSET_PREFIX_SIZE - 1] = '+';
181
26.1k
    pstr->data = data;
182
26.1k
    pstr->size = size + SUBSET_PREFIX_SIZE;
183
26.1k
    return 0;
184
26.1k
}
185
186
/* Finish writing FontFile* data. */
187
static int
188
pdf_end_fontfile(gx_device_pdf *pdev, pdf_data_writer_t *pdw)
189
24.2k
{
190
    /* We would like to call pdf_end_data,
191
       but we don't want to write the object to the output file now. */
192
24.2k
    return pdf_close_aside(pdw->pdev);
193
24.2k
}
194
195
static int copied_font_notify(void *proc_data, void *event_data)
196
32.9k
{
197
32.9k
    return gs_purge_font_from_char_caches_completely((gs_font *)proc_data);
198
32.9k
}
199
200
/* ---------------- Public ---------------- */
201
/*
202
 * Allocate and initialize a base font structure, making the required
203
 * stable copy/ies of the gs_font.  Note that this removes any XXXXXX+
204
 * font name prefix from the copy.  If is_standard is true, the copy is
205
 * a complete one, and adding glyphs or Encoding entries is not allowed.
206
 */
207
int
208
pdf_base_font_alloc(gx_device_pdf *pdev, pdf_base_font_t **ppbfont,
209
                    gs_font_base *font, const gs_matrix *orig_matrix,
210
                    bool is_standard)
211
57.4k
{
212
57.4k
    gs_memory_t *mem = pdev->pdf_memory;
213
57.4k
    gs_font *copied;
214
57.4k
    gs_font *complete;
215
57.4k
    pdf_base_font_t *pbfont =
216
57.4k
        gs_alloc_struct(mem, pdf_base_font_t,
217
57.4k
                        &st_pdf_base_font, "pdf_base_font_alloc");
218
57.4k
    const gs_font_name *pfname = &font->font_name;
219
57.4k
    gs_const_string font_name;
220
57.4k
    char fnbuf[2*sizeof(long) + 3]; /* .F########\0 */
221
57.4k
    int code, reserve_glyphs = -1;
222
223
57.4k
    if (pbfont == 0)
224
0
        return_error(gs_error_VMerror);
225
57.4k
    memset(pbfont, 0, sizeof(*pbfont));
226
57.4k
    switch (font->FontType) {
227
26.0k
    case ft_encrypted:
228
26.8k
    case ft_encrypted2:
229
26.8k
        {
230
26.8k
            int index, count;
231
26.8k
            gs_glyph glyph;
232
233
26.8k
            for (index = 0, count = 0;
234
21.3M
                (font->procs.enumerate_glyph((gs_font *)font, &index,
235
21.3M
                                              GLYPH_SPACE_NAME, &glyph),
236
21.3M
                  index != 0);
237
26.8k
                 )
238
21.3M
                    ++count;
239
26.8k
            pbfont->num_glyphs = count;
240
26.8k
            pbfont->do_subset = (is_standard ? DO_SUBSET_NO : DO_SUBSET_UNKNOWN);
241
26.8k
        }
242
        /* If we find an excessively large type 1 font we won't be able to emit
243
         * a complete copy. Instead we will emit multiple subsets. Detect that here
244
         * and only reserve enough space in the font copy for the maximum subset
245
         * glyphs, 257.
246
         * This also prevents us making a 'complete' copy of the font below. NB the
247
         * value 2048 is merely a guess, intended to prevent copying very large fonts.
248
         */
249
26.8k
        if(pbfont->num_glyphs > 2048 && !is_standard) {
250
0
            reserve_glyphs = 257;
251
0
            if(pbfont->do_subset != DO_SUBSET_NO){
252
0
                char buf[gs_font_name_max + 1];
253
0
                int l = min(font->font_name.size, sizeof(buf) - 1);
254
255
0
                memcpy(buf, font->font_name.chars, l);
256
0
                buf[l] = 0;
257
0
                emprintf1(pdev->memory,
258
0
                          "Can't embed the complete font %s as it is too large, embedding a subset.\n",
259
0
                          buf);
260
0
            }
261
0
        }
262
26.8k
        break;
263
28.1k
    case ft_TrueType:
264
28.1k
        pbfont->num_glyphs = ((gs_font_type42 *)font)->data.trueNumGlyphs;
265
28.1k
        pbfont->do_subset =
266
28.1k
            (pbfont->num_glyphs <= MAX_NO_SUBSET_GLYPHS ?
267
24.7k
             DO_SUBSET_UNKNOWN : DO_SUBSET_YES);
268
28.1k
        break;
269
139
    case ft_CID_encrypted:
270
139
        pbfont->num_glyphs = ((gs_font_cid0 *)font)->cidata.common.CIDCount;
271
139
        goto cid;
272
2.26k
    case ft_CID_TrueType:
273
2.26k
        pbfont->num_glyphs = ((gs_font_cid2 *)font)->cidata.common.CIDCount;
274
2.40k
    cid:
275
2.40k
        pbfont->do_subset = DO_SUBSET_YES;
276
2.40k
        pbfont->CIDSet =
277
2.40k
            gs_alloc_bytes(mem, (pbfont->num_glyphs + 7) / 8,
278
2.40k
                           "pdf_base_font_alloc(CIDSet)");
279
2.40k
        if (pbfont->CIDSet == 0) {
280
0
            code = gs_note_error(gs_error_VMerror);
281
0
            goto fail;
282
0
        }
283
2.40k
        pbfont->CIDSetLength = (pbfont->num_glyphs + 7) / 8;
284
2.40k
        memset(pbfont->CIDSet, 0, (pbfont->num_glyphs + 7) / 8);
285
2.40k
        break;
286
0
    default:
287
0
        code = gs_note_error(gs_error_rangecheck);
288
0
        goto fail;
289
57.4k
    }
290
291
57.4k
    code = gs_copy_font((gs_font *)font, orig_matrix, mem, &copied, reserve_glyphs);
292
57.4k
    if (code < 0)
293
24.4k
        goto fail;
294
32.9k
    gs_notify_register(&copied->notify_list, copied_font_notify, copied);
295
32.9k
    {
296
        /*
297
         * Adobe Technical Note # 5012 "The Type 42 Font Format Specification" says :
298
         *
299
         * There is a known bug in the TrueType rasterizer included in versions of the
300
         * PostScript interpreter previous to version 2013. The problem is that the
301
         * translation components of the FontMatrix, as used as an argument to the
302
         * definefont or makefont operators, are ignored. Translation of user space is
303
         * not affected by this bug.
304
         *
305
         * Besides that, we found that Adobe Acrobat Reader 4 and 5 ignore
306
         * FontMatrix.ty .
307
         */
308
32.9k
        copied->FontMatrix.tx = copied->FontMatrix.ty = 0;
309
32.9k
    }
310
311
32.9k
    if (pbfont->do_subset != DO_SUBSET_YES && reserve_glyphs == -1) {
312
        /* The only possibly non-subsetted fonts are Type 1/2 and Type 42. */
313
31.4k
        if (is_standard)
314
4.28k
            complete = copied;
315
27.1k
        else {
316
27.1k
            code = gs_copy_font((gs_font *)font, &font->FontMatrix, mem, &complete, -1);
317
27.1k
            if (code < 0) {
318
0
                gs_free_copied_font(copied);
319
0
                goto fail;
320
0
            }
321
27.1k
        }
322
31.4k
        code = gs_copy_font_complete((gs_font *)font, complete);
323
31.4k
        if (code < 0 && pbfont->do_subset == DO_SUBSET_NO) {
324
0
            char buf[gs_font_name_max + 1];
325
0
            int l = min(copied->font_name.size, sizeof(buf) - 1);
326
327
0
            memcpy(buf, copied->font_name.chars, l);
328
0
            buf[l] = 0;
329
0
            emprintf1(pdev->memory,
330
0
                      "Can't embed the complete font %s due to font error.\n",
331
0
                      buf);
332
0
            gs_free_copied_font(copied);
333
0
            copied = NULL;
334
0
            goto fail;
335
0
        }
336
31.4k
        if (code < 0) {
337
            /* A font error happened, but it may be caused by a glyph,
338
               which is not used in the document. Continue with subsetting the font.
339
               If the failed glyph will be used in the document,
340
               another error will hgappen when the glyph is used.
341
             */
342
3.42k
            gs_free_copied_font(complete);
343
3.42k
            complete = copied;
344
3.42k
        }
345
31.4k
    } else
346
1.47k
        complete = copied;
347
32.9k
    pbfont->copied = (gs_font_base *)copied;
348
32.9k
    pbfont->complete = (gs_font_base *)complete;
349
350
    /* replace the font cache of the copied fonts with our own font cache
351
     * this is required for PCL, see 'pdf_free_pdf_font_cache' in gdevpdf.c
352
     * for further details.
353
     */
354
32.9k
    pdev->pdf_font_dir->global_glyph_code = font->dir->global_glyph_code;
355
356
32.9k
    pbfont->copied->dir = pbfont->complete->dir = pdev->pdf_font_dir;
357
358
32.9k
    if (pbfont->copied->FontType == ft_CID_encrypted) {
359
139
        gs_font_cid0 *copied0 = (gs_font_cid0 *)pbfont->copied;
360
139
        int i;
361
422
        for (i = 0; i < copied0->cidata.FDArray_size; ++i) {
362
283
            ((gs_font *)copied0->cidata.FDArray[i])->dir = pdev->pdf_font_dir;
363
283
        }
364
139
    }
365
366
32.9k
    pbfont->is_standard = is_standard;
367
32.9k
    if (pfname->size > 0) {
368
31.8k
        font_name.data = pfname->chars;
369
31.8k
        font_name.size = pfname->size;
370
43.5k
        while (pdf_has_subset_prefix(font_name.data, font_name.size)) {
371
            /* Strip off an existing subset prefix. */
372
11.6k
            font_name.data += SUBSET_PREFIX_SIZE;
373
11.6k
            font_name.size -= SUBSET_PREFIX_SIZE;
374
11.6k
        }
375
31.8k
    } else {
376
1.08k
        gs_snprintf(fnbuf, sizeof(fnbuf), "Anonymous");
377
1.08k
        font_name.data = (byte *)fnbuf;
378
1.08k
        font_name.size = strlen(fnbuf);
379
1.08k
    }
380
32.9k
    pbfont->font_name.data =
381
32.9k
        gs_alloc_string(mem, font_name.size, "pdf_base_font_alloc(font_name)");
382
32.9k
    if (pbfont->font_name.data == 0)
383
0
        goto fail;
384
32.9k
    memcpy(pbfont->font_name.data, font_name.data, font_name.size);
385
32.9k
    pbfont->font_name.size = font_name.size;
386
32.9k
    *ppbfont = pbfont;
387
32.9k
    return 0;
388
24.4k
 fail:
389
24.4k
    pdf_base_font_free(pdev, pbfont);
390
24.4k
    return code;
391
32.9k
}
392
393
/*
394
 * Return a reference to the name of a base font.  This name is guaranteed
395
 * not to have a XXXXXX+ prefix.  The client may change the name at will,
396
 * but must not add a XXXXXX+ prefix.
397
 */
398
gs_string *
399
pdf_base_font_name(pdf_base_font_t *pbfont)
400
56.0k
{
401
56.0k
    return &pbfont->font_name;
402
56.0k
}
403
404
/*
405
 * Return the (copied, subset) font associated with a base font.
406
 * This procedure probably shouldn't exist....
407
 */
408
gs_font_base *
409
pdf_base_font_font(const pdf_base_font_t *pbfont, bool complete)
410
29.7M
{
411
29.7M
    return (complete ? pbfont->complete : pbfont->copied);
412
29.7M
}
413
414
/*
415
 * Check for subset font.
416
 */
417
bool
418
pdf_base_font_is_subset(const pdf_base_font_t *pbfont)
419
26.1k
{
420
26.1k
    return pbfont->do_subset == DO_SUBSET_YES;
421
26.1k
}
422
423
/*
424
 * Drop the copied complete font associated with a base font.
425
 */
426
void
427
pdf_base_font_drop_complete(pdf_base_font_t *pbfont)
428
529
{
429
    /* gs_font is a subset of gs_font_base and we only want to
430
     * free the members which are common to both, so this cast is
431
     * (at the time of writing) safe.
432
     */
433
529
    if (pbfont->complete != pbfont->copied)
434
529
        gs_free_copied_font((gs_font *)pbfont->complete);
435
529
    pbfont->complete = NULL;
436
529
}
437
438
/*
439
 * Copy a glyph (presumably one that was just used) into a saved base
440
 * font.  Note that it is the client's responsibility to determine that
441
 * the source font is compatible with the target font.  (Normally they
442
 * will be the same.)
443
 */
444
int
445
pdf_base_font_copy_glyph(pdf_base_font_t *pbfont, gs_glyph glyph,
446
                         gs_font_base *font)
447
943k
{
448
943k
    int code;
449
450
    /* If we're a TrueType CIDFont, check teh GSUB table for replacement glyphs.
451
     * Bug #691574
452
     */
453
943k
    if (font->FontType == ft_CID_TrueType) {
454
245k
        code =
455
245k
            gs_copy_glyph_options((gs_font *)font, glyph,
456
245k
                              (gs_font *)pbfont->copied,
457
245k
                              (pbfont->is_standard ? COPY_GLYPH_NO_NEW : COPY_GLYPH_USE_GSUB));
458
698k
    } else {
459
698k
        code =
460
698k
            gs_copy_glyph_options((gs_font *)font, glyph,
461
698k
                              (gs_font *)pbfont->copied,
462
698k
                              (pbfont->is_standard ? COPY_GLYPH_NO_NEW : 0));
463
698k
    }
464
943k
    if (code < 0)
465
25.8k
        return code;
466
917k
    if (pbfont->CIDSet != 0 &&
467
245k
        (uint)(glyph - GS_MIN_CID_GLYPH) < pbfont->num_glyphs
468
917k
        ) {
469
245k
        uint cid = glyph - GS_MIN_CID_GLYPH;
470
471
245k
        pbfont->CIDSet[cid >> 3] |= 0x80 >> (cid & 7);
472
245k
    }
473
917k
    return 0;
474
943k
}
475
476
/*
477
 * Determine whether a font should be subsetted.
478
 */
479
bool
480
pdf_do_subset_font(gx_device_pdf *pdev, pdf_base_font_t *pbfont, gs_id rid)
481
77.9k
{
482
77.9k
    gs_font_base *copied = pbfont->copied;
483
484
    /*
485
     * If the decision has not been made already, determine whether or not
486
     * to subset the font.
487
     */
488
77.9k
    if (pbfont->do_subset == DO_SUBSET_UNKNOWN) {
489
27.1k
        int max_pct = pdev->params.MaxSubsetPct;
490
27.1k
        bool do_subset = pdev->params.SubsetFonts && max_pct > 0;
491
492
27.1k
        if (do_subset && max_pct < 100) {
493
            /* We want to subset iff used <= total * MaxSubsetPct / 100. */
494
0
            do_subset = false;
495
0
            if (max_pct > 0) {
496
0
                int max_subset_used = pbfont->num_glyphs * max_pct / 100;
497
0
                int used, index;
498
0
                gs_glyph ignore_glyph;
499
500
0
                do_subset = true;
501
0
                for (index = 0, used = 0;
502
0
                     (copied->procs.enumerate_glyph((gs_font *)copied,
503
0
                                                &index, GLYPH_SPACE_INDEX,
504
0
                                                &ignore_glyph), index != 0);
505
0
                     )
506
0
                    if (++used > max_subset_used) {
507
0
                        do_subset = false;
508
0
                        break;
509
0
                    }
510
0
            }
511
0
        }
512
27.1k
        pbfont->do_subset = (do_subset ? DO_SUBSET_YES : DO_SUBSET_NO);
513
27.1k
    }
514
77.9k
    return (pbfont->do_subset == DO_SUBSET_YES);
515
77.9k
}
516
517
/*
518
 * Write the FontFile entry for an embedded font, /FontFile<n> # # R.
519
 */
520
int
521
pdf_write_FontFile_entry(gx_device_pdf *pdev, pdf_base_font_t *pbfont)
522
24.2k
{
523
24.2k
    stream *s = pdev->strm;
524
24.2k
    const char *FontFile_key;
525
526
24.2k
    switch (pbfont->copied->FontType) {
527
2.71k
    case ft_TrueType:
528
3.78k
    case ft_CID_TrueType:
529
3.78k
        FontFile_key = "/FontFile2";
530
3.78k
        break;
531
20.4k
    default:      /* Type 1/2, CIDFontType 0 */
532
20.4k
        if (!pdev->HaveCFF)
533
8.75k
            FontFile_key = "/FontFile";
534
11.7k
        else
535
11.7k
            FontFile_key = "/FontFile3";
536
24.2k
    }
537
24.2k
    stream_puts(s, FontFile_key);
538
24.2k
    pprinti64d1(s, " %"PRId64" 0 R", pbfont->FontFile->id);
539
24.2k
    return 0;
540
24.2k
}
541
542
/*
543
 * Adjust font name for Acrobat Reader 3.
544
 */
545
static int
546
pdf_adjust_font_name(gx_device_pdf *pdev, int64_t id, pdf_base_font_t *pbfont)
547
0
{
548
    /*
549
     * In contradiction with previous version of pdfwrite,
550
     * this always adds a suffix. We don't check the original name
551
     * for uniquity bacause the layered architecture
552
     * (see gdevpdtx.h) doesn't provide an easy access for
553
     * related information.
554
     */
555
0
    int i;
556
0
    byte *chars = (byte *)pbfont->font_name.data; /* break 'const' */
557
0
    byte *data;
558
0
    uint size = pbfont->font_name.size;
559
0
    char suffix[sizeof(int64_t) * 2 + 2];
560
0
    uint suffix_size;
561
562
0
#define SUFFIX_CHAR '~'
563
    /*
564
     * If the name looks as though it has one of our unique suffixes,
565
     * remove the suffix.
566
     */
567
0
    for (i = size;
568
0
         i > 0 && isxdigit(chars[i - 1]);
569
0
         --i)
570
0
        DO_NOTHING;
571
0
    if (i < size && i > 0 && chars[i - 1] == SUFFIX_CHAR) {
572
0
        do {
573
0
            --i;
574
0
        } while (i > 0 && chars[i - 1] == SUFFIX_CHAR);
575
0
        size = i + 1;
576
0
    }
577
    /* Create a unique name. */
578
0
    gs_snprintf(suffix, sizeof(suffix), "%c%lx", SUFFIX_CHAR, id);
579
0
    suffix_size = strlen(suffix);
580
0
    data = gs_resize_string(pdev->pdf_memory, chars, size,
581
0
                                  size + suffix_size,
582
0
                                  "pdf_adjust_font_name");
583
0
    if (data == 0)
584
0
        return_error(gs_error_VMerror);
585
0
    memcpy(data + size, (const byte *)suffix, suffix_size);
586
0
    pbfont->font_name.data = data;
587
0
    pbfont->font_name.size = size + suffix_size;
588
0
#undef SUFFIX_CHAR
589
0
    return 0;
590
0
}
591
592
/*
593
 * Write an embedded font.
594
 */
595
int
596
pdf_write_embedded_font(gx_device_pdf *pdev, pdf_base_font_t *pbfont, font_type FontType,
597
                        gs_int_rect *FontBBox, gs_id rid, cos_dict_t **ppcd)
598
24.2k
{
599
24.2k
    bool do_subset = pdf_do_subset_font(pdev, pbfont, rid);
600
24.2k
    gs_font_base *out_font =
601
24.2k
        (do_subset || pbfont->complete == NULL ? pbfont->copied : pbfont->complete);
602
24.2k
    gs_const_string fnstr;
603
24.2k
    pdf_data_writer_t writer;
604
24.2k
    byte digest[6] = {0,0,0,0,0,0};
605
24.2k
    int code = 0;
606
24.2k
    int options=0;
607
608
24.2k
    if (pbfont->written)
609
0
        return 0;   /* already written */
610
24.2k
    code = copied_order_font((gs_font *)out_font);
611
24.2k
    if (code < 0)
612
0
        return code;
613
    /* Since we now always ASCIIHex encode the eexec encrypted portion of a
614
     * Type 1 font, such a font cannot contain any binary data, if its not being
615
     * compressed then there is no reason to ASCII encode it (which will happen
616
     * we set DATA_STREAM_BINARY and the device does not permit binary output)
617
     * NB if HaveCFF is true then we convert type 1 to CFF which is a binary
618
     * format, so we still need to set DATA_STREAM_BINARY.
619
     */
620
24.2k
    if (pdev->CompressFonts)
621
24.2k
        options = DATA_STREAM_BINARY | DATA_STREAM_COMPRESS;
622
0
    else
623
0
         if (FontType != ft_encrypted || pdev->HaveCFF)
624
0
            options = DATA_STREAM_BINARY;
625
    /* Don't set DATA_STREAM_ENCRYPT since we write to a temporary file.
626
     * See comment in pdf_begin_encrypt.
627
     */
628
24.2k
    code = pdf_begin_data_stream(pdev, &writer, options, 0);
629
24.2k
    if (code < 0)
630
0
        return code;
631
24.2k
    if (pdev->PDFA != 0) {
632
0
        stream *s = s_MD5C_make_stream(pdev->pdf_memory, writer.binary.strm);
633
634
0
        if (s == NULL)
635
0
            return_error(gs_error_VMerror);
636
0
        writer.binary.strm = s;
637
0
    }
638
24.2k
    if (pdev->CompatibilityLevel == 1.2 &&
639
10.1k
        !do_subset && !pbfont->is_standard ) {
640
        /*
641
         * Due to a bug in Acrobat Reader 3, we need to generate
642
         * unique font names, except base 14 fonts being not embedded.
643
         * To recognize base 14 fonts here we used the knowledge
644
         * that pbfont->is_standard is true for base 14 fonts only.
645
         * Note that subsetted fonts already have an unique name
646
         * due to subset prefix.
647
         */
648
0
         int code = pdf_adjust_font_name(pdev, writer.pres->object->id, pbfont);
649
0
         if (code < 0)
650
0
            return code;
651
0
    }
652
24.2k
    fnstr.data = pbfont->font_name.data;
653
24.2k
    fnstr.size = pbfont->font_name.size;
654
    /* Now write the font (or subset). */
655
24.2k
    switch (FontType) {
656
657
0
    case ft_composite:
658
        /* Nothing to embed -- the descendant fonts do it all. */
659
0
        code = 0;
660
0
        break;
661
662
599
    case ft_encrypted2:
663
599
        if (!pdev->HaveCFF) {
664
            /* Must convert to Type 1 charstrings. */
665
0
            return_error(gs_error_unregistered); /* Not implemented yet. */
666
0
        }
667
20.3k
    case ft_encrypted:
668
20.3k
        if (pdev->HavePDFWidths) {
669
11.6k
            code = copied_drop_extension_glyphs((gs_font *)out_font);
670
11.6k
            if (code < 0)
671
0
                return code;
672
11.6k
        }
673
20.3k
        if (!pdev->HaveCFF) {
674
            /* Write the type 1 font with no converting to CFF. */
675
8.75k
            int lengths[3];
676
677
8.75k
            if (pbfont->do_subset != DO_SUBSET_NO)
678
8.75k
                code = psf_write_type1_font(writer.binary.strm,
679
8.75k
                                (gs_font_type1 *)out_font,
680
8.75k
                                WRITE_TYPE1_WITH_LENIV | WRITE_TYPE1_EEXEC |
681
8.75k
                                WRITE_TYPE1_EEXEC_PAD | WRITE_TYPE1_ASCIIHEX,
682
8.75k
                                NULL, 0, &fnstr, lengths);
683
0
            else
684
0
                code = psf_write_type1_font(writer.binary.strm,
685
0
                                (gs_font_type1 *)out_font,
686
0
                                WRITE_TYPE1_WITH_LENIV | WRITE_TYPE1_EEXEC |
687
0
                                WRITE_TYPE1_EEXEC_PAD | WRITE_TYPE1_ASCIIHEX | WRITE_TYPE1_XUID,
688
0
                                NULL, 0, &fnstr, lengths);
689
8.75k
            if (lengths[0] > 0) {
690
8.75k
                if (code < 0)
691
0
                    goto finish;
692
8.75k
                code = cos_dict_put_c_key_int((cos_dict_t *)writer.pres->object,
693
8.75k
                            "/Length1", lengths[0]);
694
8.75k
            }
695
8.75k
            if (lengths[1] > 0) {
696
8.75k
                if (code < 0)
697
0
                    goto finish;
698
8.75k
                code = cos_dict_put_c_key_int((cos_dict_t *)writer.pres->object,
699
8.75k
                            "/Length2", lengths[1]);
700
8.75k
                if (code < 0)
701
0
                    return code;
702
8.75k
                code = cos_dict_put_c_key_int((cos_dict_t *)writer.pres->object,
703
8.75k
                            "/Length3", lengths[2]);
704
8.75k
            }
705
11.6k
        } else {
706
            /*
707
             * Since we only support PDF 1.2 and later, always write Type 1
708
             * fonts as Type1C (Type 2).  Acrobat Reader apparently doesn't
709
             * accept CFF fonts with Type 1 CharStrings, so we need to convert
710
             * them.  Also remove lenIV, so Type 2 fonts will compress better.
711
             */
712
11.7k
#define TYPE2_OPTIONS (WRITE_TYPE2_NO_LENIV | WRITE_TYPE2_CHARSTRINGS)
713
11.6k
            code = cos_dict_put_string_copy((cos_dict_t *)writer.pres->object, "/Subtype", "/Type1C");
714
11.6k
            if (code < 0)
715
0
                return code;
716
11.6k
            code = psf_write_type2_font(writer.binary.strm,
717
11.6k
                                        (gs_font_type1 *)out_font,
718
11.6k
                                        TYPE2_OPTIONS |
719
11.6k
                            (pdev->CompatibilityLevel < 1.3 ? WRITE_TYPE2_AR3 : 0) |
720
11.6k
                            (pbfont->do_subset == DO_SUBSET_NO ? WRITE_TYPE2_XUID : 0),
721
11.6k
                                        NULL, 0, &fnstr, FontBBox);
722
11.6k
        }
723
20.3k
        goto finish;
724
725
20.3k
    case ft_TrueType: {
726
2.72k
        gs_font_type42 *const pfont = (gs_font_type42 *)out_font;
727
2.72k
#define TRUETYPE_OPTIONS (WRITE_TRUETYPE_NAME | WRITE_TRUETYPE_HVMTX)
728
        /* Acrobat Reader 3 doesn't handle cmap format 6 correctly. */
729
2.72k
        const int options = TRUETYPE_OPTIONS |
730
2.72k
            (pdev->PDFA != 0 ? WRITE_TRUETYPE_UNICODE_CMAP : 0) |
731
2.72k
            (pdev->CompatibilityLevel <= 1.2 ?
732
1.39k
             WRITE_TRUETYPE_NO_TRIMMED_TABLE : 0) |
733
            /* Generate a cmap only for incrementally downloaded fonts
734
               and for subsetted fonts. */
735
2.72k
            (pfont->data.numGlyphs != pfont->data.trueNumGlyphs ||
736
2.47k
             pbfont->do_subset == DO_SUBSET_YES ?
737
2.72k
             WRITE_TRUETYPE_CMAP : 0);
738
2.72k
        stream poss;
739
740
2.72k
        if (pdev->HavePDFWidths) {
741
1.33k
            code = copied_drop_extension_glyphs((gs_font *)out_font);
742
1.33k
            if (code < 0)
743
0
                return code;
744
1.33k
        }
745
2.72k
        s_init(&poss, pdev->memory);
746
2.72k
        swrite_position_only(&poss);
747
2.72k
        code = psf_write_truetype_font(&poss, pfont, options, NULL, 0, &fnstr);
748
2.72k
        if (code < 0)
749
12
            goto finish;
750
2.71k
        code = cos_dict_put_c_key_int((cos_dict_t *)writer.pres->object, "/Length1", stell(&poss));
751
2.71k
        if (code < 0)
752
0
            goto finish;
753
2.71k
        code = psf_write_truetype_font(writer.binary.strm, pfont,
754
2.71k
                                       options, NULL, 0, &fnstr);
755
2.71k
        goto finish;
756
2.71k
    }
757
758
101
    case ft_CID_encrypted:
759
101
        code = cos_dict_put_string_copy((cos_dict_t *)writer.pres->object, "/Subtype", "/CIDFontType0C");
760
101
        if (code < 0)
761
0
            return code;
762
101
        code = psf_write_cid0_font(writer.binary.strm,
763
101
                                   (gs_font_cid0 *)out_font, TYPE2_OPTIONS,
764
101
                                   NULL, 0, &fnstr);
765
101
        goto finish;
766
767
1.07k
    case ft_CID_TrueType:
768
        /* CIDFontType 2 fonts don't use cmap, name, OS/2, or post. */
769
1.07k
#define CID2_OPTIONS WRITE_TRUETYPE_HVMTX
770
1.07k
        code = psf_write_cid2_font(writer.binary.strm,
771
1.07k
                                   (gs_font_cid2 *)out_font,
772
1.07k
                                   CID2_OPTIONS, NULL, 0, &fnstr);
773
24.2k
    finish:
774
24.2k
        if (pdev->PDFA != 0) {
775
0
            sflush(writer.binary.strm);
776
0
            s_MD5C_get_digest(writer.binary.strm, digest, sizeof(digest));
777
0
        }
778
24.2k
        *ppcd = (cos_dict_t *)writer.pres->object;
779
24.2k
        if (code < 0) {
780
19
            pdf_end_fontfile(pdev, &writer);
781
19
            pdf_obj_mark_unused(pdev, writer.pres->object->id);
782
19
            return code;
783
19
        }
784
24.2k
        code = pdf_end_fontfile(pdev, &writer);
785
24.2k
        break;
786
787
0
    default:
788
0
        code = gs_note_error(gs_error_rangecheck);
789
24.2k
    }
790
791
24.2k
    pbfont->written = true;
792
24.2k
    return code;
793
24.2k
}
794
795
/*
796
 * Write the CharSet for a subsetted font, as a PDF string.
797
 */
798
int
799
pdf_write_CharSet(gx_device_pdf *pdev, pdf_base_font_t *pbfont)
800
20.7k
{
801
20.7k
    stream *s = pdev->strm;
802
20.7k
    gs_font_base *font = pbfont->copied;
803
20.7k
    int index;
804
20.7k
    gs_glyph glyph;
805
806
20.7k
    stream_puts(s, "(");
807
20.7k
    for (index = 0;
808
409k
         (font->procs.enumerate_glyph((gs_font *)font, &index,
809
409k
                                      GLYPH_SPACE_NAME, &glyph),
810
409k
          index != 0);
811
389k
         ) {
812
389k
        gs_const_string gstr;
813
389k
        int code = font->procs.glyph_name((gs_font *)font, glyph, &gstr);
814
815
        /* Don't include .notdef. */
816
389k
        if (code >= 0 &&
817
389k
            bytes_compare(gstr.data, gstr.size, (const byte *)".notdef", 7)
818
389k
            )
819
368k
            pdf_put_name(pdev, gstr.data, gstr.size);
820
389k
    }
821
20.7k
    stream_puts(s, ")");
822
20.7k
    return 0;
823
20.7k
}
824
825
/*
826
 * Write the CIDSet object for a subsetted CIDFont.
827
 */
828
int
829
pdf_write_CIDSet(gx_device_pdf *pdev, pdf_base_font_t *pbfont,
830
                 int64_t *pcidset_id)
831
1.18k
{
832
1.18k
    pdf_data_writer_t writer;
833
1.18k
    int code;
834
835
1.18k
    code = pdf_begin_data_stream(pdev, &writer,
836
1.18k
                      DATA_STREAM_BINARY |
837
1.18k
                      (pdev->CompressFonts ? DATA_STREAM_COMPRESS : 0),
838
1.18k
                      gs_no_id);
839
1.18k
    if (code < 0)
840
0
        return code;
841
1.18k
    stream_write(writer.binary.strm, pbfont->CIDSet,
842
1.18k
                 pbfont->CIDSetLength);
843
1.18k
    code = pdf_end_data(&writer);
844
1.18k
    if (code < 0)
845
0
        return code;
846
1.18k
    *pcidset_id = pdf_resource_id(writer.pres);
847
1.18k
    return 0;
848
1.18k
}
849
/*
850
 * Check whether a base font is standard.
851
 */
852
bool
853
pdf_is_standard_font(pdf_base_font_t *bfont)
854
0
{   return bfont->is_standard;
855
0
}
856
857
void
858
pdf_set_FontFile_object(pdf_base_font_t *bfont, cos_dict_t *pcd)
859
24.2k
{
860
24.2k
    bfont->FontFile = pcd;
861
24.2k
}
862
const cos_dict_t *
863
pdf_get_FontFile_object(pdf_base_font_t *bfont)
864
24.9k
{
865
24.9k
    return bfont->FontFile;
866
24.9k
}