Coverage Report

Created: 2025-06-24 07:01

/src/ghostpdl/devices/vector/gdevpdtf.h
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2001-2025 Artifex Software, Inc.
2
   All Rights Reserved.
3
4
   This software is provided AS-IS with no warranty, either express or
5
   implied.
6
7
   This software is distributed under license and may not be copied,
8
   modified or distributed except as expressly authorized under the terms
9
   of the license contained in the file LICENSE in this distribution.
10
11
   Refer to licensing information at http://www.artifex.com or contact
12
   Artifex Software, Inc.,  39 Mesa Street, Suite 108A, San Francisco,
13
   CA 94129, USA, for further information.
14
*/
15
16
17
/* Font and CMap resource structure and API for pdfwrite */
18
19
#ifndef gdevpdtf_INCLUDED
20
#  define gdevpdtf_INCLUDED
21
22
#include "gdevpdtx.h"
23
#include "gsfcmap.h"
24
25
/* ================ Types and structures ================ */
26
27
/* ---------------- Font resources ---------------- */
28
29
/*
30
 * pdfwrite manages several different flavors of font resources:
31
 *
32
 *  Those that have neither a FontDescriptor nor a base_font:
33
 *  Type 0 (composite) fonts
34
 *  Those that have no FontDescriptor, but do have a base_font:
35
 *  Standard 14 fonts
36
 *  Those that have a FontDescriptor but no base_font:
37
 *  Type 3 bitmap fonts
38
 *  Those that have a FontDescriptor with a base_font:
39
 *  Type 1 / Type 2 fonts
40
 *  Type 42 (TrueType) fonts
41
 *  CIDFontType 0 (Type 1/2) CIDFonts
42
 *  CIDFontType 2 (TrueType) CIDFonts
43
 */
44
/*
45
 * Font names in PDF files have caused an enormous amount of trouble, so we
46
 * document specifically how they are handled in each structure.
47
 *
48
 * The PDF Reference specifies the BaseFont of a font resource as follows,
49
 * depending on the font type:
50
 *
51
 *   Type 0 - if the descendant font is CIDFontType 0, the descendant font
52
 *     name followed by a hyphen and the CMap name (the value of Encoding,
53
 *     if a name, otherwise the CMapName from the CMap); if the descendant
54
 *     font is CIDFontType 2, the descendant font name.
55
 *
56
 *   Type 1 - "usually" the same as the FontName in the base font.
57
 *
58
 *   MM Type 1 - if embedded, the same as Type 1; if not embedded, spaces
59
 *     in the font name are replaced with underscores.
60
 *
61
 *   Type 3 - not used.
62
 *
63
 *   TrueType - initially, the PostScript name from the 'name' table in
64
 *     the font; if none, the "name by which the font is known in the host
65
 *     operating system".  Spaces are removed.  Then, under circumstances
66
 *     not defined, the string ",Bold", ",Italic", or ",BoldItalic" is
67
 *     appended if the font has the corresponding style properties.
68
 *     [We do not do this: we simply use the key_name or font_name.]
69
 *
70
 *   CIDFontType 0 - "usually" the same as the CIDFontName in the base font.
71
 *
72
 *   CIDFontType 2 - the same as TrueType.
73
 *
74
 * In addition, the BaseFont has a XXXXXX+ prefix if the font is a subset
75
 * (whether embedded or not).
76
 *
77
 * We would like to compute the BaseFont at the time that we create the font
78
 * resource object.  The font descriptor (which is needed to provide
79
 * information about embedding) and the base font are both available at that
80
 * time.  Unfortunately, the information as to whether the font will be
81
 * subsetted is not available.  Therefore, we do compute the BaseFont from
82
 * the base font name when the font resource is created, to allow checking
83
 * for duplicate names and for standard font names, but we compute it again
84
 * after writing out the base font.
85
 */
86
87
#ifndef pdf_font_descriptor_DEFINED
88
#  define pdf_font_descriptor_DEFINED
89
typedef struct pdf_font_descriptor_s pdf_font_descriptor_t;
90
#endif
91
92
typedef struct pdf_char_glyph_pair_s pdf_char_glyph_pair_t;
93
94
struct pdf_char_glyph_pair_s {
95
    gs_char chr;
96
    gs_glyph glyph;
97
};
98
99
/*
100
 * The write_contents procedure is set by the implementation when the
101
 * font resource is created.  It is called after generic code has opened
102
 * the resource object and written the Type, BaseFont (if any),
103
 * FontDescriptor reference (if any), ToUnicode CMap reference (if any),
104
 * and additional dictionary entries (if any).
105
 * The write_contents procedure must write any remaining entries specific
106
 * to the FontType, followed by the closing ">>", and then call
107
 * pdf_end_separate.  The reason for this division of function is to allow
108
 * the write_contents procedure to write additional objects that the
109
 * resource object references, after closing the resource object.
110
 */
111
typedef int (*pdf_font_write_contents_proc_t)
112
     (gx_device_pdf *, pdf_font_resource_t *);
113
114
/*
115
 * Define an element of an Encoding.  The element is unused if glyph ==
116
 * GS_NO_GLYPH.
117
 */
118
typedef struct pdf_encoding_element_s {
119
    gs_glyph glyph;
120
    byte *data;
121
    uint size;
122
    bool is_difference;   /* true if must be written in Differences */
123
} pdf_encoding_element_t;
124
125
static inline int pdf_copy_string_to_encoding(gx_device_pdf *pdev, gs_const_string *gnstr, pdf_encoding_element_t *pet)
126
749k
{
127
749k
    byte *p = NULL;
128
129
749k
    p = gs_alloc_bytes(pdev->pdf_memory->non_gc_memory, gnstr->size, "pdf_copy_string_to_encoding");
130
749k
    if (p == NULL)
131
0
        return_error(gs_error_VMerror);
132
749k
    memcpy(p, gnstr->data, gnstr->size);
133
749k
    if (pet->data != NULL)
134
108k
        gs_free_object(pdev->pdf_memory->non_gc_memory, pet->data, "pdf_copy_string_to_encoding free existing glyph name");
135
749k
    pet->data = p;
136
749k
    pet->size = gnstr->size;
137
749k
    return 0;
138
749k
}
Unexecuted instantiation: gdevpdf.c:pdf_copy_string_to_encoding
Unexecuted instantiation: gdevpdfb.c:pdf_copy_string_to_encoding
Unexecuted instantiation: gdevpdfd.c:pdf_copy_string_to_encoding
Unexecuted instantiation: gdevpdt.c:pdf_copy_string_to_encoding
Unexecuted instantiation: gdevpdtd.c:pdf_copy_string_to_encoding
Unexecuted instantiation: gdevpdtf.c:pdf_copy_string_to_encoding
gdevpdti.c:pdf_copy_string_to_encoding
Line
Count
Source
126
98.6k
{
127
98.6k
    byte *p = NULL;
128
129
98.6k
    p = gs_alloc_bytes(pdev->pdf_memory->non_gc_memory, gnstr->size, "pdf_copy_string_to_encoding");
130
98.6k
    if (p == NULL)
131
0
        return_error(gs_error_VMerror);
132
98.6k
    memcpy(p, gnstr->data, gnstr->size);
133
98.6k
    if (pet->data != NULL)
134
98.5k
        gs_free_object(pdev->pdf_memory->non_gc_memory, pet->data, "pdf_copy_string_to_encoding free existing glyph name");
135
98.6k
    pet->data = p;
136
98.6k
    pet->size = gnstr->size;
137
98.6k
    return 0;
138
98.6k
}
Unexecuted instantiation: gdevpdts.c:pdf_copy_string_to_encoding
Unexecuted instantiation: gdevpdtt.c:pdf_copy_string_to_encoding
Unexecuted instantiation: gdevpdtw.c:pdf_copy_string_to_encoding
Unexecuted instantiation: gdevpdtb.c:pdf_copy_string_to_encoding
Unexecuted instantiation: gdevpdtc.c:pdf_copy_string_to_encoding
gdevpdte.c:pdf_copy_string_to_encoding
Line
Count
Source
126
650k
{
127
650k
    byte *p = NULL;
128
129
650k
    p = gs_alloc_bytes(pdev->pdf_memory->non_gc_memory, gnstr->size, "pdf_copy_string_to_encoding");
130
650k
    if (p == NULL)
131
0
        return_error(gs_error_VMerror);
132
650k
    memcpy(p, gnstr->data, gnstr->size);
133
650k
    if (pet->data != NULL)
134
9.44k
        gs_free_object(pdev->pdf_memory->non_gc_memory, pet->data, "pdf_copy_string_to_encoding free existing glyph name");
135
650k
    pet->data = p;
136
650k
    pet->size = gnstr->size;
137
650k
    return 0;
138
650k
}
139
140
#define private_st_pdf_encoding1() /* gdevpdtf.c */\
141
  gs_private_st_const_strings1(st_pdf_encoding1,\
142
    pdf_encoding_element_t, "pdf_encoding_element_t",\
143
    pdf_encoding1_enum_ptrs, pdf_encoding1_reloc_ptrs, bah)
144
#define private_st_pdf_encoding_element() /* gdevpdtf.c */\
145
  gs_private_st_element(st_pdf_encoding_element, pdf_encoding_element_t,\
146
    "pdf_encoding_element_t[]", pdf_encoding_elt_enum_ptrs,\
147
    pdf_encoding_elt_reloc_ptrs, st_pdf_encoding1)
148
149
struct pdf_base_font_s {
150
    /*
151
     * For the standard 14 fonts, copied == complete is a complete copy
152
     * of the font, and DO_SUBSET = NO.
153
     *
154
     * For fonts that MAY be subsetted, copied is a partial copy,
155
     * complete is a complete copy, and DO_SUBSET = UNKNOWN until
156
     * pdf_font_do_subset is called.
157
     *
158
     * For fonts that MUST be subsetted, copied == complete is a partial
159
     * copy, and DO_SUBSET = YES.
160
     */
161
    gs_font_base *copied;
162
    gs_font_base *complete;
163
    enum {
164
        DO_SUBSET_UNKNOWN = 0,
165
        DO_SUBSET_NO,
166
        DO_SUBSET_YES
167
    } do_subset;
168
    bool is_standard;
169
    /*
170
     * For CIDFonts, which are always subsetted, num_glyphs is CIDCount.
171
     * For optionally subsetted fonts, num_glyphs is the count of glyphs
172
     * in the font when originally copied.  Note that if the font is
173
     * downloaded incrementally, num_glyphs may be 0.
174
     */
175
    int num_glyphs;
176
    byte *CIDSet;   /* for CIDFonts */
177
    int CIDSetLength;
178
    gs_string font_name;
179
    bool written;
180
    cos_dict_t *FontFile;
181
};
182
#define private_st_pdf_base_font()\
183
BASIC_PTRS(pdf_base_font_ptrs) {\
184
    GC_OBJ_ELT(pdf_base_font_t, copied),\
185
    GC_OBJ_ELT(pdf_base_font_t, complete),\
186
    GC_OBJ_ELT(pdf_base_font_t, CIDSet),\
187
    GC_OBJ_ELT(pdf_base_font_t, FontFile),\
188
    GC_STRING_ELT(pdf_base_font_t, font_name)\
189
}
190
191
typedef struct {
192
    gs_id id;
193
    pdf_resource_type_t type;
194
} pdf_resource_ref_t;
195
196
/*
197
 * Widths are the widths in the outlines: this is what PDF interpreters
198
 * use, and what will be written in the PDF file.  real_widths are the
199
 * widths possibly modified by Metrics[2] and CDevProc: these define the
200
 * actual advance widths of the characters in the PostScript text.
201
 */
202
struct pdf_font_resource_s {
203
    pdf_resource_common(pdf_font_resource_t);
204
    font_type FontType;   /* copied from font, if any */
205
    int64_t XUID;
206
    pdf_font_write_contents_proc_t write_contents;
207
    gs_string BaseFont;   /* (not used for Type 3) */
208
    pdf_font_descriptor_t *FontDescriptor; /* (not used for Type 0, Type 3, */
209
                                /* or standard 14 fonts) */
210
    /*
211
     * The base_font member is only used for
212
     * the standard 14 fonts, which do not have a FontDescriptor.
213
     */
214
    pdf_base_font_t *base_font; /* == FontDescriptor->base_font */
215
    uint count;     /* # of chars/CIDs */
216
    double *Widths;   /* [count] (not used for Type 0) */
217
    byte *used;     /* [ceil(count/8)] bitmap of chars/CIDs used */
218
                                /* (not used for Type 0 or Type 3) */
219
    pdf_resource_t *res_ToUnicode; /* CMap (not used for CIDFonts) */
220
    gs_cmap_t *cmap_ToUnicode;     /* CMap (not used for CIDFonts) */
221
    gs_glyph_mark_proc_t mark_glyph;
222
    void *mark_glyph_data;  /* closure data */
223
224
    union {
225
226
        struct /*type0*/ {
227
228
            pdf_font_resource_t *DescendantFont; /* CIDFont */
229
            /*
230
             * The Encoding_name must be long enough to hold either the
231
             * longest standard CMap name defined in the PDF Reference,
232
             * or the longest reference to an embedded CMap (# 0 R).
233
             */
234
            char Encoding_name[max( /* standard name or <id> 0 R */
235
                      17, /* /UniJIS-UCS2-HW-H */
236
                      sizeof(int64_t) * 8 / 3 + 1 + 4 /* <id> 0 R */
237
                      ) + 1 /* \0 terminator */
238
            ];
239
            byte *CMapName_data;
240
            uint CMapName_size;
241
            uint font_index;  /* The index of the descendent font in the source CMap. */
242
            bool cmap_is_standard;
243
            int WMode;    /* of CMap */
244
245
        } type0;
246
247
        struct /*cidfont*/ {
248
249
            /* [D]W[2] is Widths. */
250
            int64_t CIDSystemInfo_id; /* (written when font is allocated) */
251
            ushort *CIDToGIDMap; /* (CIDFontType 2 only) [count] */
252
            unsigned int CIDToGIDMapLength;
253
            gs_id glyphshow_font_id;
254
            double *Widths2;  /* [count * 2] (x, y) */
255
            double *v;    /* [count] */
256
            byte *used2;  /* [(count + 7) / 8] */
257
            pdf_font_resource_t *parent;
258
259
        } cidfont;
260
261
        struct /*simple*/ {
262
263
            int FirstChar, LastChar; /* 0 <= FirstChar <= LastChar <= 255 */
264
            /*
265
             * The BaseEncoding can only be ENCODING_INDEX_WINANSI,
266
             * ENCODING_INDEX_MACROMAN, ENCODING_INDEX_MACEXPERT, or -1.
267
             */
268
            gs_encoding_index_t BaseEncoding;
269
            gs_encoding_index_t preferred_encoding_index;
270
            pdf_encoding_element_t *Encoding; /* [256], not for Type 3 */
271
            gs_point *v; /* [256], glyph origin for WMode 1 */
272
            int last_reserved_char; /* Except for synthesised Type 3,
273
                                           which stores such data in LastChar */
274
            gs_glyph standard_glyph_code_for_notdef;
275
            union {
276
277
                struct /*type1*/ {
278
                    bool is_MM_instance;
279
                } type1;
280
281
                struct /*truetype*/ {
282
                    /*
283
                     * No extra info needed, but the ANSI standard doesn't
284
                     * allow empty structs.
285
                     */
286
                    int _dummy;
287
                } truetype;
288
289
                struct /*type3*/ {
290
                    gs_rect FontBBox;
291
                    gs_matrix FontMatrix;
292
                    pdf_char_proc_ownership_t *char_procs;
293
                    int max_y_offset;
294
                    bool bitmap_font;
295
                    cos_dict_t *Resources;
296
                    byte *cached;
297
                } type3;
298
299
            } s;
300
301
        } simple;
302
303
    } u;
304
};
305
/* The GC descriptor for resource types must be public. */
306
#define public_st_pdf_font_resource() /* gdevpdtf.c */\
307
  gs_public_st_composite(st_pdf_font_resource, pdf_font_resource_t,\
308
    "pdf_font_resource_t", pdf_font_resource_enum_ptrs,\
309
    pdf_font_resource_reloc_ptrs)
310
311
/*
312
 * Define the possible embedding statuses of a font.
313
 */
314
typedef enum {
315
    FONT_EMBED_STANDARD,  /* 14 standard fonts */
316
    FONT_EMBED_NO,
317
    FONT_EMBED_YES
318
} pdf_font_embed_t;
319
320
/* ---------------- Global structures ---------------- */
321
322
/*
323
 * Define a structure for keeping track of the (unique) resource for
324
 * each standard font.  Note that standard fonts do not have descriptors:
325
 * the base_font and copied_font members of the font resource provide the
326
 * necessary information.
327
 */
328
typedef struct pdf_standard_font_s {
329
    pdf_font_resource_t *pdfont;
330
    gs_matrix orig_matrix;  /* ****** do we need this? */
331
} pdf_standard_font_t;
332
#define private_st_pdf_standard_font() /* gdevpdtf.c */\
333
  gs_private_st_ptrs1(st_pdf_standard_font, pdf_standard_font_t,\
334
    "pdf_standard_font_t", pdf_std_font_enum_ptrs, pdf_std_font_reloc_ptrs,\
335
    pdfont)
336
#define private_st_pdf_standard_font_element() /* gdevpdtf.c */\
337
  gs_private_st_element(st_pdf_standard_font_element, pdf_standard_font_t,\
338
    "pdf_standard_font_t[]", pdf_std_font_elt_enum_ptrs,\
339
    pdf_std_font_elt_reloc_ptrs, st_pdf_standard_font)
340
341
/*
342
 * There is a single instance (per device) of a structure that tracks global
343
 * information about outline fonts.  It is defined here, rather than
344
 * opaquely in the implementation file, because the text processing code
345
 * needs access to it.
346
 */
347
348
/*typedef struct pdf_outline_fonts_s pdf_outline_fonts_t;*/  /* gdevpdtx.h */
349
struct pdf_outline_fonts_s {
350
    pdf_standard_font_t *standard_fonts; /* [PDF_NUM_STANDARD_FONTS] */
351
};
352
#define private_st_pdf_outline_fonts() /* gdevpdtf.c */\
353
  gs_private_st_ptrs1(st_pdf_outline_fonts, pdf_outline_fonts_t,\
354
    "pdf_outline_fonts_t", pdf_outline_fonts_enum_ptrs,\
355
    pdf_outline_fonts_reloc_ptrs, standard_fonts)
356
357
/* ================ Procedures ================ */
358
359
/* ---------------- Font resources ---------------- */
360
361
/*
362
 * Allocate and initialize bookkeeping for outline fonts.
363
 */
364
pdf_outline_fonts_t *pdf_outline_fonts_alloc(gs_memory_t *mem);
365
366
/*
367
 * Return the standard fonts array.
368
 */
369
pdf_standard_font_t *pdf_standard_fonts(const gx_device_pdf *pdev);
370
371
/*
372
 * Clean the standard fonts array.
373
 */
374
void pdf_clean_standard_fonts(const gx_device_pdf *pdev);
375
376
/* Free font cache. */
377
int pdf_free_font_cache(gx_device_pdf *pdev);
378
379
/*
380
 * Allocate specific types of font resource.
381
 */
382
int pdf_font_type0_alloc(gx_device_pdf *pdev, pdf_font_resource_t **ppfres,
383
                         gs_id rid, pdf_font_resource_t *DescendantFont,
384
                         const gs_const_string *CMapName);
385
int pdf_font_type3_alloc(gx_device_pdf *pdev, pdf_font_resource_t **ppfres,
386
                         pdf_font_write_contents_proc_t write_contents);
387
int pdf_font_std_alloc(gx_device_pdf *pdev, pdf_font_resource_t **ppfres,
388
                   bool is_original, gs_id rid, gs_font_base *pfont, int index);
389
int pdf_font_simple_alloc(gx_device_pdf *pdev, pdf_font_resource_t **ppfres,
390
                          gs_id rid, pdf_font_descriptor_t *pfd);
391
int pdf_font_cidfont_alloc(gx_device_pdf *pdev, pdf_font_resource_t **ppfres,
392
                           gs_id rid, pdf_font_descriptor_t *pfd);
393
int pdf_obtain_cidfont_widths_arrays(gx_device_pdf *pdev, pdf_font_resource_t *pdfont,
394
                    int wmode, double **w, double **w0, double **v);
395
int font_resource_encoded_alloc(gx_device_pdf *pdev, pdf_font_resource_t **ppfres,
396
                            gs_id rid, font_type ftype,
397
                            pdf_font_write_contents_proc_t write_contents);
398
int pdf_assign_font_object_id(gx_device_pdf *pdev, pdf_font_resource_t *pdfont);
399
400
int font_resource_free(gx_device_pdf *pdev, pdf_font_resource_t *pdfont);
401
402
/* Resize font resource arrays. */
403
int pdf_resize_resource_arrays(gx_device_pdf *pdev, pdf_font_resource_t *pfres,
404
        uint chars_count);
405
406
/*
407
 * Return the (copied, subset or complete) font associated with a font resource.
408
 * If this font resource doesn't have a descriptor (Type 0, Type 3, or
409
 * standard 14), return 0.
410
 */
411
gs_font_base *pdf_font_resource_font(const pdf_font_resource_t *pdfont, bool complete);
412
413
/*
414
 * Determine the embedding status of a font.  If the font is in the base
415
 * 14, store its index (0..13) in *pindex and its similarity to the base
416
 * font (as determined by the font's same_font procedure) in *psame.
417
 * (pindex and/or psame may be NULL.)
418
 */
419
pdf_font_embed_t pdf_font_embed_status(gx_device_pdf *pdev, gs_font *font,
420
                                       int *pindex,
421
                                       pdf_char_glyph_pair_t *pairs, int num_glyphs, font_type *orig_type);
422
423
/*
424
 * Compute the BaseFont of a font according to the algorithm described
425
 * above.
426
 */
427
int pdf_compute_BaseFont(gx_device_pdf *pdev, pdf_font_resource_t *pdfont, bool finish);
428
429
/*
430
 * Convert True Type fonts into CID fonts for PDF/A.
431
 */
432
int pdf_convert_truetype_font(gx_device_pdf *pdev,  pdf_resource_t *pres);
433
434
/*
435
 * Convert True Type font descriptor into CID font descriptor for PDF/A.
436
 */
437
int pdf_convert_truetype_font_descriptor(gx_device_pdf *pdev, pdf_font_resource_t *pdfont);
438
439
/* ---------------- CMap resources ---------------- */
440
441
/*
442
 * Allocate a CMap resource.
443
 */
444
int pdf_cmap_alloc(gx_device_pdf *pdev, const gs_cmap_t *pcmap,
445
                   pdf_resource_t **ppres /* CMap */, int font_index_only);
446
447
/*
448
 * Add a CID-to-GID mapping to a CIDFontType 2 font resource.
449
 */
450
int pdf_font_add_cid_to_gid(pdf_font_resource_t *pdfont, uint cid, uint gid);
451
452
#endif /* gdevpdtf_INCLUDED */