Coverage Report

Created: 2025-06-24 07:01

/src/ghostpdl/devices/vector/gdevpdtb.c
Line
Count
Source (jump to first uncovered line)
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
23.2k
#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
26
{
113
26
    const pdf_base14_font_info_t *ppsf;
114
115
1.22k
    for (ppsf = base14_font_info; ppsf->urwname; ++ppsf) {
116
1.19k
        if (strlen(ppsf->urwname) == size) {
117
12
            if (!memcmp(ppsf->urwname, (const char *)str, size))
118
0
                return ppsf->stdname;
119
12
        }
120
1.19k
    }
121
26
    return NULL;
122
26
}
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
8.43M
{
131
8.43M
    int i;
132
133
8.43M
    if (size < SUBSET_PREFIX_SIZE || str[SUBSET_PREFIX_SIZE - 1] != '+')
134
5.28M
        return false;
135
22.0M
    for (i = 0; i < SUBSET_PREFIX_SIZE - 1; ++i)
136
18.9M
        if ((uint)(str[i] - 'A') >= 26)
137
279
            return false;
138
3.15M
    return true;
139
3.15M
}
140
141
static inline ulong
142
hash(ulong v, int index, ushort w)
143
1.89M
{
144
1.89M
    return v * 3141592653u + w;
145
1.89M
}
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
21.5k
{
153
21.5k
    uint size = pstr->size;
154
21.5k
    byte *data = gs_resize_string(pdev->pdf_memory, pstr->data, size,
155
21.5k
                                  size + SUBSET_PREFIX_SIZE,
156
21.5k
                                  "pdf_add_subset_prefix");
157
21.5k
    int len = (count + 7) / 8;
158
21.5k
    int len0 = len & ~(sizeof(ushort) - 1);
159
21.5k
    ulong v = 0;
160
21.5k
    int i;
161
162
21.5k
    if (data == 0)
163
0
        return_error(gs_error_VMerror);
164
165
21.5k
    if (md5_hash) {
166
107k
        for (i = 0; i < 8; i += sizeof(ushort)) {
167
85.8k
      v = hash(v, i, (*(md5_hash + i) | *(md5_hash + i + 1) << 8));
168
85.8k
        }
169
21.4k
    }
170
171
    /* Hash the 'used' array. */
172
1.83M
    for (i = 0; i < len0; i += sizeof(ushort))
173
1.81M
        v = hash(v, i, *(ushort *)(used + i));
174
22.0k
    for (; i < len; i++)
175
547
        v = hash(v, i, used[i]);
176
177
21.5k
    memmove(data + SUBSET_PREFIX_SIZE, data, size);
178
150k
    for (i = 0; i < SUBSET_PREFIX_SIZE - 1; ++i, v /= 26)
179
129k
        data[i] = 'A' + (v % 26);
180
21.5k
    data[SUBSET_PREFIX_SIZE - 1] = '+';
181
21.5k
    pstr->data = data;
182
21.5k
    pstr->size = size + SUBSET_PREFIX_SIZE;
183
21.5k
    return 0;
184
21.5k
}
185
186
/* Finish writing FontFile* data. */
187
static int
188
pdf_end_fontfile(gx_device_pdf *pdev, pdf_data_writer_t *pdw)
189
21.1k
{
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
21.1k
    return pdf_close_aside(pdw->pdev);
193
21.1k
}
194
195
static int copied_font_notify(void *proc_data, void *event_data)
196
29.2k
{
197
29.2k
    return gs_purge_font_from_char_caches_completely((gs_font *)proc_data);
198
29.2k
}
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
47.1k
{
212
47.1k
    gs_memory_t *mem = pdev->pdf_memory;
213
47.1k
    gs_font *copied;
214
47.1k
    gs_font *complete;
215
47.1k
    pdf_base_font_t *pbfont =
216
47.1k
        gs_alloc_struct(mem, pdf_base_font_t,
217
47.1k
                        &st_pdf_base_font, "pdf_base_font_alloc");
218
47.1k
    const gs_font_name *pfname = &font->font_name;
219
47.1k
    gs_const_string font_name;
220
47.1k
    char fnbuf[2*sizeof(long) + 3]; /* .F########\0 */
221
47.1k
    int code, reserve_glyphs = -1;
222
223
47.1k
    if (pbfont == 0)
224
0
        return_error(gs_error_VMerror);
225
47.1k
    memset(pbfont, 0, sizeof(*pbfont));
226
47.1k
    switch (font->FontType) {
227
23.3k
    case ft_encrypted:
228
23.5k
    case ft_encrypted2:
229
23.5k
        {
230
23.5k
            int index, count;
231
23.5k
            gs_glyph glyph;
232
233
23.5k
            for (index = 0, count = 0;
234
18.2M
                (font->procs.enumerate_glyph((gs_font *)font, &index,
235
18.2M
                                              GLYPH_SPACE_NAME, &glyph),
236
18.2M
                  index != 0);
237
23.5k
                 )
238
18.2M
                    ++count;
239
23.5k
            pbfont->num_glyphs = count;
240
23.5k
            pbfont->do_subset = (is_standard ? DO_SUBSET_NO : DO_SUBSET_UNKNOWN);
241
23.5k
        }
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
23.5k
        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
23.5k
        break;
263
23.2k
    case ft_TrueType:
264
23.2k
        pbfont->num_glyphs = ((gs_font_type42 *)font)->data.trueNumGlyphs;
265
23.2k
        pbfont->do_subset =
266
23.2k
            (pbfont->num_glyphs <= MAX_NO_SUBSET_GLYPHS ?
267
20.7k
             DO_SUBSET_UNKNOWN : DO_SUBSET_YES);
268
23.2k
        break;
269
26
    case ft_CID_encrypted:
270
26
        pbfont->num_glyphs = ((gs_font_cid0 *)font)->cidata.common.CIDCount;
271
26
        goto cid;
272
331
    case ft_CID_TrueType:
273
331
        pbfont->num_glyphs = ((gs_font_cid2 *)font)->cidata.common.CIDCount;
274
357
    cid:
275
357
        pbfont->do_subset = DO_SUBSET_YES;
276
357
        pbfont->CIDSet =
277
357
            gs_alloc_bytes(mem, (pbfont->num_glyphs + 7) / 8,
278
357
                           "pdf_base_font_alloc(CIDSet)");
279
357
        if (pbfont->CIDSet == 0) {
280
0
            code = gs_note_error(gs_error_VMerror);
281
0
            goto fail;
282
0
        }
283
357
        pbfont->CIDSetLength = (pbfont->num_glyphs + 7) / 8;
284
357
        memset(pbfont->CIDSet, 0, (pbfont->num_glyphs + 7) / 8);
285
357
        break;
286
0
    default:
287
0
        code = gs_note_error(gs_error_rangecheck);
288
0
        goto fail;
289
47.1k
    }
290
291
47.1k
    code = gs_copy_font((gs_font *)font, orig_matrix, mem, &copied, reserve_glyphs);
292
47.1k
    if (code < 0)
293
17.9k
        goto fail;
294
29.2k
    gs_notify_register(&copied->notify_list, copied_font_notify, copied);
295
29.2k
    {
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
29.2k
        copied->FontMatrix.tx = copied->FontMatrix.ty = 0;
309
29.2k
    }
310
311
29.2k
    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
28.7k
        if (is_standard)
314
3.29k
            complete = copied;
315
25.4k
        else {
316
25.4k
            code = gs_copy_font((gs_font *)font, &font->FontMatrix, mem, &complete, -1);
317
25.4k
            if (code < 0) {
318
0
                gs_free_copied_font(copied);
319
0
                goto fail;
320
0
            }
321
25.4k
        }
322
28.7k
        code = gs_copy_font_complete((gs_font *)font, complete);
323
28.7k
        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
28.7k
        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.86k
            gs_free_copied_font(complete);
343
3.86k
            complete = copied;
344
3.86k
        }
345
28.7k
    } else
346
483
        complete = copied;
347
29.2k
    pbfont->copied = (gs_font_base *)copied;
348
29.2k
    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
29.2k
    pdev->pdf_font_dir->global_glyph_code = font->dir->global_glyph_code;
355
356
29.2k
    pbfont->copied->dir = pbfont->complete->dir = pdev->pdf_font_dir;
357
358
29.2k
    if (pbfont->copied->FontType == ft_CID_encrypted) {
359
26
        gs_font_cid0 *copied0 = (gs_font_cid0 *)pbfont->copied;
360
26
        int i;
361
74
        for (i = 0; i < copied0->cidata.FDArray_size; ++i) {
362
48
            ((gs_font *)copied0->cidata.FDArray[i])->dir = pdev->pdf_font_dir;
363
48
        }
364
26
    }
365
366
29.2k
    pbfont->is_standard = is_standard;
367
29.2k
    if (pfname->size > 0) {
368
28.0k
        font_name.data = pfname->chars;
369
28.0k
        font_name.size = pfname->size;
370
39.4k
        while (pdf_has_subset_prefix(font_name.data, font_name.size)) {
371
            /* Strip off an existing subset prefix. */
372
11.3k
            font_name.data += SUBSET_PREFIX_SIZE;
373
11.3k
            font_name.size -= SUBSET_PREFIX_SIZE;
374
11.3k
        }
375
28.0k
    } else {
376
1.11k
        gs_snprintf(fnbuf, sizeof(fnbuf), "Anonymous");
377
1.11k
        font_name.data = (byte *)fnbuf;
378
1.11k
        font_name.size = strlen(fnbuf);
379
1.11k
    }
380
29.2k
    pbfont->font_name.data =
381
29.2k
        gs_alloc_string(mem, font_name.size, "pdf_base_font_alloc(font_name)");
382
29.2k
    if (pbfont->font_name.data == 0)
383
0
        goto fail;
384
29.2k
    memcpy(pbfont->font_name.data, font_name.data, font_name.size);
385
29.2k
    pbfont->font_name.size = font_name.size;
386
29.2k
    *ppbfont = pbfont;
387
29.2k
    return 0;
388
17.9k
 fail:
389
17.9k
    pdf_base_font_free(pdev, pbfont);
390
17.9k
    return code;
391
29.2k
}
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
47.7k
{
401
47.7k
    return &pbfont->font_name;
402
47.7k
}
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
47.9M
{
411
47.9M
    return (complete ? pbfont->complete : pbfont->copied);
412
47.9M
}
413
414
/*
415
 * Check for subset font.
416
 */
417
bool
418
pdf_base_font_is_subset(const pdf_base_font_t *pbfont)
419
21.5k
{
420
21.5k
    return pbfont->do_subset == DO_SUBSET_YES;
421
21.5k
}
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
788
{
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
788
    if (pbfont->complete != pbfont->copied)
434
788
        gs_free_copied_font((gs_font *)pbfont->complete);
435
788
    pbfont->complete = NULL;
436
788
}
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
718k
{
448
718k
    int code;
449
450
    /* If we're a TrueType CIDFont, check teh GSUB table for replacement glyphs.
451
     * Bug #691574
452
     */
453
718k
    if (font->FontType == ft_CID_TrueType) {
454
86.6k
        code =
455
86.6k
            gs_copy_glyph_options((gs_font *)font, glyph,
456
86.6k
                              (gs_font *)pbfont->copied,
457
86.6k
                              (pbfont->is_standard ? COPY_GLYPH_NO_NEW : COPY_GLYPH_USE_GSUB));
458
632k
    } else {
459
632k
        code =
460
632k
            gs_copy_glyph_options((gs_font *)font, glyph,
461
632k
                              (gs_font *)pbfont->copied,
462
632k
                              (pbfont->is_standard ? COPY_GLYPH_NO_NEW : 0));
463
632k
    }
464
718k
    if (code < 0)
465
18.5k
        return code;
466
700k
    if (pbfont->CIDSet != 0 &&
467
700k
        (uint)(glyph - GS_MIN_CID_GLYPH) < pbfont->num_glyphs
468
700k
        ) {
469
85.6k
        uint cid = glyph - GS_MIN_CID_GLYPH;
470
471
85.6k
        pbfont->CIDSet[cid >> 3] |= 0x80 >> (cid & 7);
472
85.6k
    }
473
700k
    return 0;
474
718k
}
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
68.2k
{
482
68.2k
    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
68.2k
    if (pbfont->do_subset == DO_SUBSET_UNKNOWN) {
489
25.4k
        int max_pct = pdev->params.MaxSubsetPct;
490
25.4k
        bool do_subset = pdev->params.SubsetFonts && max_pct > 0;
491
492
25.4k
        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
25.4k
        pbfont->do_subset = (do_subset ? DO_SUBSET_YES : DO_SUBSET_NO);
513
25.4k
    }
514
68.2k
    return (pbfont->do_subset == DO_SUBSET_YES);
515
68.2k
}
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
21.1k
{
523
21.1k
    stream *s = pdev->strm;
524
21.1k
    const char *FontFile_key;
525
526
21.1k
    switch (pbfont->copied->FontType) {
527
2.39k
    case ft_TrueType:
528
2.69k
    case ft_CID_TrueType:
529
2.69k
        FontFile_key = "/FontFile2";
530
2.69k
        break;
531
18.4k
    default:      /* Type 1/2, CIDFontType 0 */
532
18.4k
        if (!pdev->HaveCFF)
533
13.1k
            FontFile_key = "/FontFile";
534
5.30k
        else
535
5.30k
            FontFile_key = "/FontFile3";
536
21.1k
    }
537
21.1k
    stream_puts(s, FontFile_key);
538
21.1k
    pprinti64d1(s, " %"PRId64" 0 R", pbfont->FontFile->id);
539
21.1k
    return 0;
540
21.1k
}
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
21.1k
{
599
21.1k
    bool do_subset = pdf_do_subset_font(pdev, pbfont, rid);
600
21.1k
    gs_font_base *out_font =
601
21.1k
        (do_subset || pbfont->complete == NULL ? pbfont->copied : pbfont->complete);
602
21.1k
    gs_const_string fnstr;
603
21.1k
    pdf_data_writer_t writer;
604
21.1k
    byte digest[6] = {0,0,0,0,0,0};
605
21.1k
    int code = 0;
606
21.1k
    int options=0;
607
608
21.1k
    if (pbfont->written)
609
0
        return 0;   /* already written */
610
21.1k
    code = copied_order_font((gs_font *)out_font);
611
21.1k
    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
21.1k
    if (pdev->CompressFonts)
621
21.1k
        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
21.1k
    code = pdf_begin_data_stream(pdev, &writer, options, 0);
629
21.1k
    if (code < 0)
630
0
        return code;
631
21.1k
    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
21.1k
    if (pdev->CompatibilityLevel == 1.2 &&
639
21.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
21.1k
    fnstr.data = pbfont->font_name.data;
653
21.1k
    fnstr.size = pbfont->font_name.size;
654
    /* Now write the font (or subset). */
655
21.1k
    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
188
    case ft_encrypted2:
663
188
        if (!pdev->HaveCFF) {
664
            /* Must convert to Type 1 charstrings. */
665
0
            return_error(gs_error_unregistered); /* Not implemented yet. */
666
0
        }
667
18.4k
    case ft_encrypted:
668
18.4k
        if (pdev->HavePDFWidths) {
669
5.31k
            code = copied_drop_extension_glyphs((gs_font *)out_font);
670
5.31k
            if (code < 0)
671
0
                return code;
672
5.31k
        }
673
18.4k
        if (!pdev->HaveCFF) {
674
            /* Write the type 1 font with no converting to CFF. */
675
13.1k
            int lengths[3];
676
677
13.1k
            if (pbfont->do_subset != DO_SUBSET_NO)
678
13.1k
                code = psf_write_type1_font(writer.binary.strm,
679
13.1k
                                (gs_font_type1 *)out_font,
680
13.1k
                                WRITE_TYPE1_WITH_LENIV | WRITE_TYPE1_EEXEC |
681
13.1k
                                WRITE_TYPE1_EEXEC_PAD | WRITE_TYPE1_ASCIIHEX,
682
13.1k
                                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
13.1k
            if (lengths[0] > 0) {
690
13.1k
                if (code < 0)
691
0
                    goto finish;
692
13.1k
                code = cos_dict_put_c_key_int((cos_dict_t *)writer.pres->object,
693
13.1k
                            "/Length1", lengths[0]);
694
13.1k
            }
695
13.1k
            if (lengths[1] > 0) {
696
13.1k
                if (code < 0)
697
0
                    goto finish;
698
13.1k
                code = cos_dict_put_c_key_int((cos_dict_t *)writer.pres->object,
699
13.1k
                            "/Length2", lengths[1]);
700
13.1k
                if (code < 0)
701
0
                    return code;
702
13.1k
                code = cos_dict_put_c_key_int((cos_dict_t *)writer.pres->object,
703
13.1k
                            "/Length3", lengths[2]);
704
13.1k
            }
705
13.1k
        } 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
5.33k
#define TYPE2_OPTIONS (WRITE_TYPE2_NO_LENIV | WRITE_TYPE2_CHARSTRINGS)
713
5.31k
            code = cos_dict_put_string_copy((cos_dict_t *)writer.pres->object, "/Subtype", "/Type1C");
714
5.31k
            if (code < 0)
715
0
                return code;
716
5.31k
            code = psf_write_type2_font(writer.binary.strm,
717
5.31k
                                        (gs_font_type1 *)out_font,
718
5.31k
                                        TYPE2_OPTIONS |
719
5.31k
                            (pdev->CompatibilityLevel < 1.3 ? WRITE_TYPE2_AR3 : 0) |
720
5.31k
                            (pbfont->do_subset == DO_SUBSET_NO ? WRITE_TYPE2_XUID : 0),
721
5.31k
                                        NULL, 0, &fnstr, FontBBox);
722
5.31k
        }
723
18.4k
        goto finish;
724
725
18.4k
    case ft_TrueType: {
726
2.39k
        gs_font_type42 *const pfont = (gs_font_type42 *)out_font;
727
2.39k
#define TRUETYPE_OPTIONS (WRITE_TRUETYPE_NAME | WRITE_TRUETYPE_HVMTX)
728
        /* Acrobat Reader 3 doesn't handle cmap format 6 correctly. */
729
2.39k
        const int options = TRUETYPE_OPTIONS |
730
2.39k
            (pdev->PDFA != 0 ? WRITE_TRUETYPE_UNICODE_CMAP : 0) |
731
2.39k
            (pdev->CompatibilityLevel <= 1.2 ?
732
1.97k
             WRITE_TRUETYPE_NO_TRIMMED_TABLE : 0) |
733
            /* Generate a cmap only for incrementally downloaded fonts
734
               and for subsetted fonts. */
735
2.39k
            (pfont->data.numGlyphs != pfont->data.trueNumGlyphs ||
736
2.39k
             pbfont->do_subset == DO_SUBSET_YES ?
737
2.39k
             WRITE_TRUETYPE_CMAP : 0);
738
2.39k
        stream poss;
739
740
2.39k
        if (pdev->HavePDFWidths) {
741
420
            code = copied_drop_extension_glyphs((gs_font *)out_font);
742
420
            if (code < 0)
743
0
                return code;
744
420
        }
745
2.39k
        s_init(&poss, pdev->memory);
746
2.39k
        swrite_position_only(&poss);
747
2.39k
        code = psf_write_truetype_font(&poss, pfont, options, NULL, 0, &fnstr);
748
2.39k
        if (code < 0)
749
0
            goto finish;
750
2.39k
        code = cos_dict_put_c_key_int((cos_dict_t *)writer.pres->object, "/Length1", stell(&poss));
751
2.39k
        if (code < 0)
752
0
            goto finish;
753
2.39k
        code = psf_write_truetype_font(writer.binary.strm, pfont,
754
2.39k
                                       options, NULL, 0, &fnstr);
755
2.39k
        goto finish;
756
2.39k
    }
757
758
21
    case ft_CID_encrypted:
759
21
        code = cos_dict_put_string_copy((cos_dict_t *)writer.pres->object, "/Subtype", "/CIDFontType0C");
760
21
        if (code < 0)
761
0
            return code;
762
21
        code = psf_write_cid0_font(writer.binary.strm,
763
21
                                   (gs_font_cid0 *)out_font, TYPE2_OPTIONS,
764
21
                                   NULL, 0, &fnstr);
765
21
        goto finish;
766
767
298
    case ft_CID_TrueType:
768
        /* CIDFontType 2 fonts don't use cmap, name, OS/2, or post. */
769
298
#define CID2_OPTIONS WRITE_TRUETYPE_HVMTX
770
298
        code = psf_write_cid2_font(writer.binary.strm,
771
298
                                   (gs_font_cid2 *)out_font,
772
298
                                   CID2_OPTIONS, NULL, 0, &fnstr);
773
21.1k
    finish:
774
21.1k
        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
21.1k
        *ppcd = (cos_dict_t *)writer.pres->object;
779
21.1k
        if (code < 0) {
780
30
            pdf_end_fontfile(pdev, &writer);
781
30
            pdf_obj_mark_unused(pdev, writer.pres->object->id);
782
30
            return code;
783
30
        }
784
21.1k
        code = pdf_end_fontfile(pdev, &writer);
785
21.1k
        break;
786
787
0
    default:
788
0
        code = gs_note_error(gs_error_rangecheck);
789
21.1k
    }
790
791
21.1k
    pbfont->written = true;
792
21.1k
    return code;
793
21.1k
}
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
18.4k
{
801
18.4k
    stream *s = pdev->strm;
802
18.4k
    gs_font_base *font = pbfont->copied;
803
18.4k
    int index;
804
18.4k
    gs_glyph glyph;
805
806
18.4k
    stream_puts(s, "(");
807
18.4k
    for (index = 0;
808
374k
         (font->procs.enumerate_glyph((gs_font *)font, &index,
809
374k
                                      GLYPH_SPACE_NAME, &glyph),
810
374k
          index != 0);
811
356k
         ) {
812
356k
        gs_const_string gstr;
813
356k
        int code = font->procs.glyph_name((gs_font *)font, glyph, &gstr);
814
815
        /* Don't include .notdef. */
816
356k
        if (code >= 0 &&
817
356k
            bytes_compare(gstr.data, gstr.size, (const byte *)".notdef", 7)
818
356k
            )
819
337k
            pdf_put_name(pdev, gstr.data, gstr.size);
820
356k
    }
821
18.4k
    stream_puts(s, ")");
822
18.4k
    return 0;
823
18.4k
}
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
319
{
832
319
    pdf_data_writer_t writer;
833
319
    int code;
834
835
319
    code = pdf_begin_data_stream(pdev, &writer,
836
319
                      DATA_STREAM_BINARY |
837
319
                      (pdev->CompressFonts ? DATA_STREAM_COMPRESS : 0),
838
319
                      gs_no_id);
839
319
    if (code < 0)
840
0
        return code;
841
319
    stream_write(writer.binary.strm, pbfont->CIDSet,
842
319
                 pbfont->CIDSetLength);
843
319
    code = pdf_end_data(&writer);
844
319
    if (code < 0)
845
0
        return code;
846
319
    *pcidset_id = pdf_resource_id(writer.pres);
847
319
    return 0;
848
319
}
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
21.1k
{
860
21.1k
    bfont->FontFile = pcd;
861
21.1k
}
862
const cos_dict_t *
863
pdf_get_FontFile_object(pdf_base_font_t *bfont)
864
21.1k
{
865
21.1k
    return bfont->FontFile;
866
21.1k
}