Coverage Report

Created: 2025-06-10 07:27

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