Coverage Report

Created: 2025-08-28 07:06

/src/ghostpdl/pdf/pdf_fontTT.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2019-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
/* code for TrueType font handling */
17
18
#include "pdf_int.h"
19
#include "pdf_font.h"
20
#include "pdf_fontTT.h"
21
#include "pdf_font1C.h" /* OTTO support */
22
#include "pdf_font_types.h"
23
#include "pdf_stack.h"
24
#include "pdf_file.h"
25
#include "pdf_dict.h"
26
#include "pdf_array.h"
27
#include "pdf_deref.h"
28
#include "gxfont42.h"
29
#include "gscencs.h"
30
#include "gsagl.h"
31
#include "gsutil.h"        /* For gs_next_ids() */
32
33
enum {
34
    CMAP_TABLE_NONE = 0,
35
    CMAP_TABLE_10_PRESENT = 1,
36
    CMAP_TABLE_30_PRESENT = 2,
37
    CMAP_TABLE_31_PRESENT = 4,
38
    CMAP_TABLE_310_PRESENT = 8
39
};
40
41
static int
42
pdfi_ttf_string_proc(gs_font_type42 * pfont, ulong offset, uint length, const byte ** pdata)
43
3.51G
{
44
3.51G
    pdf_font_truetype *ttfont = (pdf_font_truetype *)pfont->client_data;
45
3.51G
    int code = 0;
46
47
3.51G
    if ((uint64_t)offset + length > ttfont->sfnt->length) {
48
15.0M
        *pdata = NULL;
49
15.0M
        code = gs_note_error(gs_error_invalidfont);
50
15.0M
    }
51
3.49G
    else {
52
3.49G
        *pdata = ttfont->sfnt->data + offset;
53
3.49G
    }
54
3.51G
    return code;
55
3.51G
}
56
57
static gs_glyph pdfi_ttf_encode_char(gs_font *pfont, gs_char chr, gs_glyph_space_t sp)
58
14.3M
{
59
14.3M
    pdf_font_truetype *ttfont = (pdf_font_truetype *)pfont->client_data;
60
14.3M
    gs_glyph g = GS_NO_GLYPH;
61
14.3M
    uint ID;
62
14.3M
    int code;
63
64
14.3M
    if ((ttfont->descflags & 4) != 0 || sp == GLYPH_SPACE_INDEX) {
65
4.08M
        int code = pdfi_fapi_check_cmap_for_GID(pfont, (uint)chr, &ID);
66
4.08M
        if (code < 0 || ID == 0)
67
1.34M
            code = pdfi_fapi_check_cmap_for_GID(pfont, (uint)(chr | 0xf0 << 8), &ID);
68
4.08M
        g = (gs_glyph)ID;
69
4.08M
    }
70
10.2M
    else {
71
10.2M
        pdf_context *ctx = (pdf_context *)ttfont->ctx;
72
73
10.2M
        if (ttfont->Encoding != NULL) { /* safety */
74
10.2M
            pdf_name *GlyphName = NULL;
75
10.2M
            code = pdfi_array_get(ctx, ttfont->Encoding, (uint64_t)chr, (pdf_obj **)&GlyphName);
76
10.2M
            if (code >= 0) {
77
10.2M
                code = (*ctx->get_glyph_index)(pfont, (byte *)GlyphName->data, GlyphName->length, &ID);
78
10.2M
                pdfi_countdown(GlyphName);
79
10.2M
                if (code >= 0)
80
10.2M
                    g = (gs_glyph)ID;
81
10.2M
            }
82
10.2M
        }
83
10.2M
    }
84
85
14.3M
    return g;
86
14.3M
}
87
88
int pdfi_find_post_entry(gs_font_type42 *pfont, gs_const_string *gname, uint *cc)
89
3.98M
{
90
3.98M
    pdf_font_truetype *ttfont = (pdf_font_truetype *)pfont->client_data;
91
3.98M
    pdf_context *ctx = (pdf_context *)ttfont->ctx;
92
3.98M
    int code = 0;
93
3.98M
    if (ttfont->post != NULL) {
94
3.91M
        pdf_name *name = NULL;
95
3.91M
        pdf_num *n = NULL;
96
97
3.91M
        code = pdfi_name_alloc(ctx, (byte *)gname->data, gname->size, (pdf_obj **)&name);
98
3.91M
        if (code >= 0) {
99
3.91M
            pdfi_countup(name);
100
3.91M
            code = pdfi_dict_get_by_key(ctx, ttfont->post, name, (pdf_obj **)&n);
101
3.91M
            if (code >= 0 && pdfi_type_of(n) == PDF_INT) {
102
68.9k
                *cc = (uint)n->value.i;
103
68.9k
            }
104
3.84M
            else
105
3.84M
              *cc = 0;
106
3.91M
            pdfi_countdown(name);
107
3.91M
            pdfi_countdown(n);
108
3.91M
        }
109
3.91M
    }
110
69.6k
    else
111
69.6k
        code = gs_error_VMerror;
112
113
3.98M
    if (code == gs_error_VMerror){
114
69.6k
        uint i;
115
69.6k
        gs_string postname = {0};
116
117
69.6k
        code = gs_error_undefined;
118
69.6k
        if (pfont->data.numGlyphs > 0) { /* protect from corrupt font */
119
0
            for (i = 0; i < pfont->data.numGlyphs; i++) {
120
0
                code = gs_type42_find_post_name(pfont, (gs_glyph)i, &postname);
121
0
                if (code >= 0) {
122
0
                    if (gname->data[0] == postname.data[0]
123
0
                        && gname->size == postname.size
124
0
                        && !strncmp((char *)gname->data, (char *)postname.data, postname.size))
125
0
                    {
126
0
                        *cc = i;
127
0
                        code = 0;
128
0
                        break;
129
0
                    }
130
0
                }
131
0
            }
132
0
        }
133
69.6k
    }
134
3.98M
    return code;
135
3.98M
}
136
137
extern single_glyph_list_t SingleGlyphList[];
138
139
static uint pdfi_type42_get_glyph_index(gs_font_type42 *pfont, gs_glyph glyph)
140
9.44M
{
141
9.44M
    pdf_font_truetype *ttfont = (pdf_font_truetype *)pfont->client_data;
142
9.44M
    uint gind = 0;
143
9.44M
    uint cc = 0;
144
9.44M
    int i, code = 0;
145
146
9.44M
    if ((ttfont->descflags & 4) != 0 || glyph >= GS_MIN_GLYPH_INDEX) {
147
1.86M
        gind = (uint)glyph < GS_MIN_GLYPH_INDEX ? glyph : glyph - GS_MIN_GLYPH_INDEX;
148
1.86M
    }
149
7.58M
    else {
150
7.58M
        pdf_context *ctx = (pdf_context *)ttfont->ctx;
151
7.58M
        gs_const_string gname;
152
153
7.58M
        code = (*ctx->get_glyph_name)((gs_font *)pfont, glyph, &gname);
154
7.58M
        if (code < 0 || gname.data == NULL) {
155
0
            return (uint)glyph;
156
0
        }
157
7.58M
        if (gname.size == 7 && gname.data[0] == '.' && strncmp((char *)gname.data, ".notdef", 7) == 0) {
158
1.39M
            return 0; /* .notdef is GID 0, so short cut the rest of the function */
159
1.39M
        }
160
161
6.18M
        if (ttfont->cmap == pdfi_truetype_cmap_10) {
162
795k
            gs_glyph g;
163
164
795k
            g = gs_c_name_glyph((const byte *)gname.data, gname.size);
165
795k
            if (g != GS_NO_GLYPH) {
166
795k
                g = (gs_glyph)gs_c_decode(g, ENCODING_INDEX_MACROMAN);
167
795k
            }
168
0
            else {
169
0
                g = GS_NO_CHAR;
170
0
            }
171
172
795k
            if (g != GS_NO_CHAR) {
173
785k
                code = pdfi_fapi_check_cmap_for_GID((gs_font *)pfont, (uint)g, &cc);
174
785k
            }
175
176
795k
            if (code < 0 || cc == 0) {
177
508k
                code = pdfi_find_post_entry(pfont, &gname, &cc);
178
508k
                if (code < 0) {
179
504k
                    cc = 0;
180
504k
                    code = 0;
181
504k
                }
182
508k
            }
183
795k
        }
184
5.39M
        else {
185
            /* In theory, this should be 3,1 cmap, but we have examples that use 0,1 or other
186
               Unicode "platform" cmap tables, so "hail mary" just try it
187
             */
188
5.39M
            single_glyph_list_t *sgl = (single_glyph_list_t *)&(SingleGlyphList);
189
            /* Not to spec, but... if we get a "uni..." formatted name, use
190
               the hex value from that.
191
             */
192
5.39M
            if (gname.size == 7 && !strncmp((char *)gname.data, "uni", 3)) {
193
33.5k
                char gnbuf[64];
194
33.5k
                int l = (gname.size - 3) > 63 ? 63 : gname.size - 3;
195
196
33.5k
                memcpy(gnbuf, gname.data + 3, l);
197
33.5k
                gnbuf[l] = '\0';
198
33.5k
                l = sscanf(gnbuf, "%x", &gind);
199
33.5k
                if (l > 0)
200
33.5k
                    (void)pdfi_fapi_check_cmap_for_GID((gs_font *)pfont, (uint)gind, &cc);
201
0
                else
202
0
                    cc = 0;
203
33.5k
            }
204
5.36M
            else {
205
                /* Slow linear search */
206
10.2G
                for (i = 0; sgl->Glyph != 0x00; i++) {
207
10.2G
                    if (sgl->Glyph[0] == gname.data[0]
208
10.2G
                        && strlen(sgl->Glyph) == gname.size
209
10.2G
                        && !strncmp((char *)sgl->Glyph, (char *)gname.data, gname.size))
210
5.35M
                        break;
211
10.2G
                    sgl++;
212
10.2G
                }
213
5.36M
                if (sgl->Glyph != NULL) {
214
5.35M
                    code = pdfi_fapi_check_cmap_for_GID((gs_font *)pfont, (uint)sgl->Unicode, &cc);
215
5.35M
                    if (code < 0 || cc == 0)
216
3.44M
                        cc = 0;
217
5.35M
                }
218
159
                else
219
159
                    cc = 0;
220
221
5.36M
                if (cc == 0) {
222
3.44M
                    code = pdfi_find_post_entry(pfont, &gname, &cc);
223
3.44M
                    if (code < 0) {
224
3.37M
                        cc = (uint)glyph;
225
3.37M
                        code = 0;
226
3.37M
                    }
227
3.44M
                }
228
5.36M
            }
229
5.39M
        }
230
6.18M
        gind = cc;
231
6.18M
    }
232
8.05M
    return gind;
233
9.44M
}
234
235
static int
236
pdfi_ttf_enumerate_glyph(gs_font *font, int *pindex, gs_glyph_space_t glyph_space, gs_glyph *pglyph)
237
5.98M
{
238
5.98M
    if (glyph_space == GLYPH_SPACE_INDEX) {
239
146k
        return gs_type42_enumerate_glyph(font, pindex, glyph_space, pglyph);
240
146k
    }
241
5.83M
    else if (glyph_space == GLYPH_SPACE_NAME) {
242
5.83M
        pdf_font_truetype *ttfont = (pdf_font_truetype *)font->client_data;
243
244
5.83M
        if ((ttfont->descflags & 4) == 0) {
245
5.81M
            if (*pindex <= 0) {
246
73.6k
                *pindex = 0;
247
73.6k
            }
248
5.81M
            *pglyph = (*font->procs.encode_char)(font, (gs_char)*pindex, glyph_space);
249
5.81M
            if (*pglyph == GS_NO_GLYPH)
250
15.0k
                *pindex = 0;
251
5.80M
            else
252
5.80M
                (*pindex)++;
253
5.81M
        }
254
5.83M
    }
255
0
    else
256
0
        *pindex = 0;
257
5.83M
    return 0;
258
5.98M
}
259
260
static int pdfi_ttf_glyph_name(gs_font *pfont, gs_glyph glyph, gs_const_string * pstr)
261
757k
{
262
757k
    pdf_font_truetype *ttfont = (pdf_font_truetype *)pfont->client_data;
263
757k
    pdf_context *ctx = (pdf_context *)ttfont->ctx;
264
757k
    uint ID = 0;
265
757k
    int l, code = -1;
266
267
757k
    if (glyph >= GS_MIN_CID_GLYPH) { /* Fabricate a numeric name. */
268
1.42k
        char cid_name[sizeof(gs_glyph) * 3 + 1];
269
270
1.42k
        l = gs_snprintf(cid_name, sizeof(cid_name), "%lu", (ulong) glyph);
271
        /* We need to create the entry in the name table... */
272
1.42k
        code = (*ctx->get_glyph_index)(pfont, (byte *)cid_name, l, &ID);
273
1.42k
        if (code < 0)
274
0
            return -1;
275
276
1.42k
        code = (*ctx->get_glyph_name)(pfont, (gs_glyph)ID, pstr);
277
1.42k
        if (code < 0)
278
0
            return -1; /* No name, trigger pdfwrite Type 3 fallback */
279
756k
    } else {
280
756k
        if ((ttfont->descflags & 4) != 0) {
281
56.3k
            code = gs_type42_find_post_name((gs_font_type42 *)pfont, glyph, (gs_string *)pstr);
282
56.3k
            if (code < 0) {
283
50.2k
                char buf[64];
284
50.2k
                l = gs_snprintf(buf, sizeof(buf), "~gs~gName~%04x", (uint)glyph);
285
50.2k
                code = (*ctx->get_glyph_index)(pfont, (byte *)buf, l, &ID);
286
50.2k
            }
287
6.04k
            else {
288
6.04k
                code = (*ctx->get_glyph_index)(pfont, (byte *)pstr->data, pstr->size, &ID);
289
6.04k
            }
290
56.3k
            if (code < 0)
291
0
                return -1; /* No name, trigger pdfwrite Type 3 fallback */
292
293
56.3k
            code = (*ctx->get_glyph_name)(pfont, (gs_glyph)ID, pstr);
294
56.3k
            if (code < 0)
295
0
                return -1; /* No name, trigger pdfwrite Type 3 fallback */
296
56.3k
        }
297
699k
        else {
298
699k
            code = (*ctx->get_glyph_name)(pfont, glyph, pstr);
299
699k
            if (code < 0)
300
0
                return -1; /* No name, trigger pdfwrite Type 3 fallback */
301
699k
        }
302
756k
    }
303
757k
    return code;
304
305
757k
}
306
307
static void pdfi_make_post_dict(gs_font_type42 *pfont)
308
22.5k
{
309
22.5k
    pdf_font_truetype *ttfont = (pdf_font_truetype *)pfont->client_data;
310
22.5k
    pdf_context *ctx = (pdf_context *)ttfont->ctx;
311
22.5k
    int i, code = 0;
312
22.5k
    if (ttfont->post == NULL && pfont->data.numGlyphs > 0) {
313
22.3k
        code = pdfi_dict_alloc(ctx, pfont->data.numGlyphs, &ttfont->post);
314
22.3k
        if (code < 0)
315
0
            return;
316
317
22.3k
        pdfi_countup(ttfont->post);
318
319
27.0M
        for (i = 0; i < pfont->data.numGlyphs; i++) {
320
27.0M
            gs_string postname = {0};
321
27.0M
            pdf_name *key;
322
27.0M
            pdf_num *ind;
323
324
27.0M
            code = gs_type42_find_post_name(pfont, (gs_glyph)i, &postname);
325
27.0M
            if (code < 0) {
326
24.3M
                continue;
327
24.3M
            }
328
2.70M
            code = pdfi_name_alloc(ctx, postname.data, postname.size, (pdf_obj **)&key);
329
2.70M
            if (code < 0) {
330
0
               continue;
331
0
            }
332
2.70M
            pdfi_countup(key);
333
2.70M
            code = pdfi_object_alloc(ctx, PDF_INT, 0, (pdf_obj **)&ind);
334
2.70M
            if (code < 0) {
335
0
               pdfi_countdown(key);
336
0
               continue;
337
0
            }
338
2.70M
            pdfi_countup(ind);
339
2.70M
            ind->value.i = i;
340
2.70M
            (void)pdfi_dict_put_obj(ctx, ttfont->post, (pdf_obj *)key, (pdf_obj *)ind, false);
341
2.70M
            pdfi_countdown(key);
342
2.70M
            pdfi_countdown(ind);
343
2.70M
        }
344
22.3k
    }
345
22.5k
}
346
347
348
static int
349
pdfi_alloc_tt_font(pdf_context *ctx, pdf_font_truetype **font, bool is_cid)
350
34.4k
{
351
34.4k
    pdf_font_truetype *ttfont = NULL;
352
34.4k
    gs_font_type42 *pfont = NULL;
353
354
34.4k
    ttfont = (pdf_font_truetype *)gs_alloc_bytes(ctx->memory, sizeof(pdf_font_truetype), "pdfi (truetype pdf_font)");
355
34.4k
    if (ttfont == NULL)
356
0
        return_error(gs_error_VMerror);
357
358
34.4k
    memset(ttfont, 0x00, sizeof(pdf_font_truetype));
359
34.4k
    ttfont->type = PDF_FONT;
360
34.4k
    ttfont->ctx = ctx;
361
34.4k
    ttfont->pdfi_font_type = e_pdf_font_truetype;
362
363
#if REFCNT_DEBUG
364
    ttfont->UID = ctx->UID++;
365
    outprintf(ctx->memory, "Allocated object of type %c with UID %"PRIi64"\n", ttfont->type, ttfont->UID);
366
#endif
367
368
34.4k
    pdfi_countup(ttfont);
369
370
34.4k
    pfont = (gs_font_type42 *)gs_alloc_struct(ctx->memory, gs_font_type42, &st_gs_font_type42,
371
34.4k
                            "pdfi (truetype pfont)");
372
34.4k
    if (pfont == NULL) {
373
0
        pdfi_countdown(ttfont);
374
0
        return_error(gs_error_VMerror);
375
0
    }
376
34.4k
    memset(pfont, 0x00, sizeof(gs_font_type42));
377
378
34.4k
    ttfont->pfont = (gs_font_base *)pfont;
379
380
34.4k
    gs_make_identity(&pfont->orig_FontMatrix);
381
34.4k
    gs_make_identity(&pfont->FontMatrix);
382
34.4k
    pfont->next = pfont->prev = 0;
383
34.4k
    pfont->memory = ctx->memory;
384
34.4k
    pfont->dir = ctx->font_dir;
385
34.4k
    pfont->is_resource = false;
386
34.4k
    gs_notify_init(&pfont->notify_list, ctx->memory);
387
34.4k
    pfont->base = (gs_font *) ttfont->pfont;
388
34.4k
    pfont->client_data = ttfont;
389
34.4k
    pfont->WMode = 0;
390
34.4k
    pfont->PaintType = 0;
391
34.4k
    pfont->StrokeWidth = 0;
392
34.4k
    pfont->is_cached = 0;
393
34.4k
    pfont->FAPI = NULL;
394
34.4k
    pfont->FAPI_font_data = NULL;
395
34.4k
    pfont->procs.init_fstack = gs_default_init_fstack;
396
34.4k
    pfont->procs.next_char_glyph = gs_default_next_char_glyph;
397
34.4k
    pfont->FontType = ft_TrueType;
398
34.4k
    pfont->ExactSize = fbit_use_outlines;
399
34.4k
    pfont->InBetweenSize = fbit_use_outlines;
400
34.4k
    pfont->TransformedChar = fbit_use_outlines;
401
    /* We may want to do something clever with an XUID here */
402
34.4k
    pfont->id = gs_next_ids(ctx->memory, 1);
403
34.4k
    uid_set_UniqueID(&pfont->UID, pfont->id);
404
    /* The buildchar proc will be filled in by FAPI -
405
       we won't worry about working without FAPI */
406
34.4k
    pfont->procs.encode_char = pdfi_ttf_encode_char;
407
34.4k
    pfont->data.string_proc = pdfi_ttf_string_proc;
408
34.4k
    pfont->procs.glyph_name = pdfi_ttf_glyph_name;
409
34.4k
    pfont->procs.decode_glyph = pdfi_decode_glyph;
410
34.4k
    pfont->procs.define_font = gs_no_define_font;
411
34.4k
    pfont->procs.make_font = gs_no_make_font;
412
413
34.4k
    ttfont->default_font_info = gs_default_font_info;
414
34.4k
    pfont->procs.font_info = pdfi_default_font_info;
415
416
34.4k
    pfont->procs.glyph_info = gs_default_glyph_info;
417
34.4k
    pfont->procs.glyph_outline = gs_no_glyph_outline;
418
34.4k
    pfont->procs.build_char = NULL;
419
34.4k
    pfont->procs.same_font = gs_default_same_font;
420
34.4k
    pfont->procs.enumerate_glyph = gs_no_enumerate_glyph;
421
422
34.4k
    pfont->encoding_index = ENCODING_INDEX_UNKNOWN;
423
34.4k
    pfont->nearest_encoding_index = ENCODING_INDEX_UNKNOWN;
424
425
34.4k
    pfont->client_data = (void *)ttfont;
426
427
34.4k
    *font = ttfont;
428
34.4k
    return 0;
429
34.4k
}
430
431
static void pdfi_set_type42_custom_procs(pdf_font_truetype *pdfttfont)
432
22.7k
{
433
22.7k
    gs_font_type42 *pfont = (gs_font_type42 *)pdfttfont->pfont;
434
435
22.7k
    pdfttfont->default_font_info = pfont->procs.font_info;
436
22.7k
    pfont->procs.font_info = pdfi_default_font_info;
437
22.7k
    pfont->data.get_glyph_index = pdfi_type42_get_glyph_index;
438
22.7k
    pfont->procs.enumerate_glyph = pdfi_ttf_enumerate_glyph;
439
22.7k
}
440
441
int pdfi_read_truetype_font(pdf_context *ctx, pdf_dict *font_dict, pdf_dict *stream_dict, pdf_dict *page_dict, byte *buf, int64_t buflen, int findex, pdf_font **ppdffont)
442
30.6k
{
443
30.6k
    pdf_font_truetype *font = NULL;
444
30.6k
    int code = 0, i;
445
30.6k
    pdf_obj *fontdesc = NULL;
446
30.6k
    pdf_obj *obj = NULL;
447
30.6k
    pdf_obj *basefont = NULL;
448
30.6k
    int64_t descflags;
449
30.6k
    bool encoding_known = false;
450
30.6k
    bool forced_symbolic = false;
451
30.6k
    pdf_obj *tounicode = NULL;
452
453
30.6k
    if (ppdffont == NULL)
454
0
        return_error(gs_error_invalidaccess);
455
456
30.6k
    *ppdffont = NULL;
457
458
30.6k
    if (font_dict != NULL)
459
30.6k
        (void)pdfi_dict_knownget_type(ctx, font_dict, "FontDescriptor", PDF_DICT, &fontdesc);
460
461
30.6k
    if ((code = pdfi_alloc_tt_font(ctx, &font, false)) < 0) {
462
0
        code = gs_note_error(gs_error_invalidfont);
463
0
        goto error;
464
0
    }
465
30.6k
    if (font_dict != NULL) {
466
30.6k
        font->object_num = font_dict->object_num;
467
30.6k
        font->generation_num = font_dict->generation_num;
468
30.6k
        font->indirect_num = font_dict->indirect_num;
469
30.6k
        font->indirect_gen = font_dict->indirect_gen;
470
30.6k
    }
471
472
30.6k
    font->FontDescriptor = (pdf_dict *)fontdesc;
473
30.6k
    fontdesc = NULL;
474
475
30.6k
    pdfi_font_set_first_last_char(ctx, font_dict, (pdf_font *)font);
476
477
30.6k
    code = pdfi_object_alloc(ctx, PDF_BUFFER, 0, (pdf_obj **)&font->sfnt);
478
30.6k
    if (code < 0) {
479
0
        goto error;
480
0
    }
481
30.6k
    pdfi_countup(font->sfnt);
482
30.6k
    code = pdfi_buffer_set_data((pdf_obj *)font->sfnt, buf, buflen);
483
30.6k
    if (code < 0) {
484
0
        goto error;
485
0
    }
486
30.6k
    buf = NULL;
487
488
    /* Strictly speaking BaseFont is required, but we can continue without one */
489
30.6k
    if (font_dict != NULL) {
490
30.6k
        code = pdfi_dict_knownget_type(ctx, font_dict, "BaseFont", PDF_NAME, (pdf_obj **)&basefont);
491
30.6k
        if (code > 0) {
492
29.9k
            pdf_name *nobj = (pdf_name *)basefont;
493
29.9k
            int nlen = nobj->length > gs_font_name_max ? gs_font_name_max : nobj->length;
494
495
29.9k
            memcpy(font->pfont->key_name.chars, nobj->data, nlen);
496
29.9k
            font->pfont->key_name.chars[nlen] = 0;
497
29.9k
            font->pfont->key_name.size = nlen;
498
29.9k
            memcpy(font->pfont->font_name.chars, nobj->data, nlen);
499
29.9k
            font->pfont->font_name.chars[nlen] = 0;
500
29.9k
            font->pfont->font_name.size = nlen;
501
29.9k
            pdfi_countdown(obj);
502
29.9k
            obj = NULL;
503
29.9k
        }
504
30.6k
    }
505
30.6k
    font->BaseFont = basefont;
506
30.6k
    basefont = NULL;
507
30.6k
    font->PDF_font = font_dict;
508
30.6k
    pdfi_countup(font_dict);
509
510
    /* ignore errors with widths... for now */
511
30.6k
    if (font_dict != NULL)
512
30.6k
        (void)pdfi_font_create_widths(ctx, font_dict, (pdf_font*)font, 0.001);
513
514
30.6k
    if (ctx->args.ignoretounicode != true && font_dict != NULL) {
515
30.6k
        code = pdfi_dict_get(ctx, font_dict, "ToUnicode", (pdf_obj **)&tounicode);
516
30.6k
        if (code >= 0 && pdfi_type_of(tounicode) == PDF_STREAM) {
517
11.4k
            pdf_cmap *tu = NULL;
518
11.4k
            code = pdfi_read_cmap(ctx, tounicode, &tu);
519
11.4k
            pdfi_countdown(tounicode);
520
11.4k
            tounicode = (pdf_obj *)tu;
521
11.4k
        }
522
30.6k
        if (code < 0 || (tounicode != NULL && pdfi_type_of(tounicode) != PDF_CMAP)) {
523
19.0k
            pdfi_countdown(tounicode);
524
19.0k
            tounicode = NULL;
525
19.0k
            code = 0;
526
19.0k
        }
527
30.6k
    }
528
0
    else {
529
0
        tounicode = NULL;
530
0
    }
531
30.6k
    font->ToUnicode = tounicode;
532
30.6k
    tounicode = NULL;
533
534
30.6k
    if (font->FontDescriptor != NULL) {
535
30.6k
        code = pdfi_dict_get_int(ctx, font->FontDescriptor, "Flags", &descflags);
536
30.6k
        if (code < 0)
537
18
            descflags = 0;
538
30.6k
    }
539
0
    else {
540
0
        descflags = 0;
541
0
    }
542
543
30.6k
    if (font_dict != NULL)
544
30.6k
        code = pdfi_dict_get(ctx, font_dict, "Encoding", &obj);
545
0
    else
546
0
        code = gs_error_undefined;
547
548
30.6k
    if (code < 0) {
549
6.44k
        static const char encstr[] = "WinAnsiEncoding";
550
6.44k
        code = pdfi_name_alloc(ctx, (byte *)encstr, strlen(encstr), (pdf_obj **)&obj);
551
6.44k
        if (code >= 0)
552
6.44k
            pdfi_countup(obj);
553
0
        else
554
0
            goto error;
555
6.44k
    }
556
24.2k
    else {
557
24.2k
        encoding_known = true;
558
        /* If we have and encoding, and both the symbolic and non-symbolic flag are set,
559
           believe that latter.
560
         */
561
24.2k
        if ((descflags & 32) != 0)
562
23.8k
            descflags = (descflags & ~4);
563
24.2k
    }
564
565
30.6k
    if ((forced_symbolic = pdfi_font_known_symbolic(font->BaseFont)) == true) {
566
0
        descflags |= 4;
567
0
    }
568
569
30.6k
    code = pdfi_create_Encoding(ctx, (pdf_font *)font, obj, NULL, (pdf_obj **)&font->Encoding);
570
    /* If we get an error, and the font is non-symbolic, return the error */
571
30.6k
    if (code < 0 && (descflags & 4) == 0)
572
64
        goto error;
573
    /* If we get an error, and the font is symbolic, pretend we never saw an /Encoding */
574
30.6k
    if (code < 0)
575
5
        encoding_known = false;
576
30.6k
    pdfi_countdown(obj);
577
30.6k
    obj = NULL;
578
579
30.6k
    code = gs_type42_font_init((gs_font_type42 *)font->pfont, 0);
580
30.6k
    if (code < 0) {
581
7.85k
        goto error;
582
7.85k
    }
583
584
22.7k
    pdfi_set_type42_custom_procs(font);
585
586
    /* We're probably dead in the water without cmap tables, but make sure, for safety */
587
    /* This is a horrendous morass of guesses at what Acrobat does with files that contravene
588
       what the spec says about symbolic fonts, cmap tables and encodings.
589
     */
590
22.7k
    if (forced_symbolic != true && (descflags & 4) != 0 && ((gs_font_type42 *)font->pfont)->data.cmap != 0) {
591
4.77k
        gs_font_type42 *t42f = (gs_font_type42 *)font->pfont;
592
4.77k
        int numcmaps;
593
4.77k
        int cmaps_available = CMAP_TABLE_NONE;
594
4.77k
        const byte *d;
595
4.77k
        code = (*t42f->data.string_proc)(t42f, t42f->data.cmap + 2, 2, &d);
596
4.77k
        if (code < 0)
597
9
            goto error;
598
4.76k
        numcmaps = d[1] | d[0] << 8;
599
97.3k
        for (i = 0; i < numcmaps; i++) {
600
92.7k
            code = (*t42f->data.string_proc)(t42f, t42f->data.cmap + 4 + i * 8, 4, &d);
601
92.7k
            if (code < 0)
602
161
                goto error;
603
98.4k
#define CMAP_PLAT_ENC_ID(a,b,c,d) (a << 24 | b << 16 | c << 8 | d)
604
92.5k
            switch(CMAP_PLAT_ENC_ID(d[0], d[1], d[2], d[3])) {
605
4.35k
                case CMAP_PLAT_ENC_ID(0, 1, 0, 0):
606
4.35k
                    cmaps_available |= CMAP_TABLE_10_PRESENT;
607
4.35k
                    break;
608
1.47k
                case CMAP_PLAT_ENC_ID(0, 3, 0, 0):
609
1.47k
                    cmaps_available |= CMAP_TABLE_30_PRESENT;
610
1.47k
                    break;
611
80
                case CMAP_PLAT_ENC_ID(0, 3, 0, 1):
612
80
                    cmaps_available |= CMAP_TABLE_31_PRESENT;
613
80
                    break;
614
0
                case CMAP_PLAT_ENC_ID(0, 3, 1, 0):
615
0
                    cmaps_available |= CMAP_TABLE_310_PRESENT;
616
0
                    break;
617
86.6k
                default: /* Not one we're interested in */
618
86.6k
                    break;
619
92.5k
            }
620
92.5k
        }
621
4.60k
#undef CMAP_PLAT_ENC_ID
622
4.60k
        if ((cmaps_available & CMAP_TABLE_30_PRESENT) == CMAP_TABLE_30_PRESENT) {
623
1.43k
            font->descflags = descflags;
624
1.43k
        }
625
3.17k
        else if (encoding_known == true) {
626
35
            static const char mrencstr[] = "MacRomanEncoding";
627
35
            static const char waencstr[] = "WinAnsiEncoding";
628
35
            const char *encstr = ((cmaps_available & CMAP_TABLE_31_PRESENT) == CMAP_TABLE_31_PRESENT) ? waencstr : mrencstr;
629
35
            font->descflags = descflags & ~4;
630
35
            code = pdfi_name_alloc(ctx, (byte *)encstr, strlen(encstr), (pdf_obj **)&obj);
631
35
            if (code >= 0)
632
35
                pdfi_countup(obj);
633
0
            else
634
0
                goto error;
635
35
            pdfi_countdown(font->Encoding);
636
35
            code = pdfi_create_Encoding(ctx, (pdf_font *)font, obj, NULL, (pdf_obj **)&font->Encoding);
637
35
            if (code < 0)
638
0
                goto error;
639
35
            pdfi_countdown(obj);
640
35
            obj = NULL;
641
35
        }
642
3.13k
        else
643
3.13k
            font->descflags = descflags;
644
4.60k
    }
645
17.9k
    else {
646
17.9k
        font->descflags = descflags;
647
17.9k
    }
648
649
22.5k
    if (uid_is_XUID(&font->pfont->UID))
650
22.5k
        uid_free(&font->pfont->UID, font->pfont->memory, "pdfi_read_type1_font");
651
22.5k
    uid_set_invalid(&font->pfont->UID);
652
653
22.5k
    code = pdfi_font_generate_pseudo_XUID(ctx, font_dict, font->pfont);
654
22.5k
    if (code < 0) {
655
0
        goto error;
656
0
    }
657
658
22.5k
    if ((font->descflags & 4) == 0) {
659
        /* Horrid hacky solution */
660
        /* We don't want to draw the TTF notdef */
661
18.0k
        gs_font_type42 *gst42 = ((gs_font_type42 *)font->pfont);
662
18.0k
        if (gst42->data.len_glyphs != NULL && gst42->data.len_glyphs[0] > 10) {
663
14.0k
            gst42->data.len_glyphs[0] = 0;
664
14.0k
        }
665
18.0k
    }
666
667
22.5k
    pdfi_make_post_dict((gs_font_type42 *)font->pfont);
668
669
22.5k
    pdfi_font_set_orig_fonttype(ctx, (pdf_font *)font);
670
22.5k
    code = gs_definefont(ctx->font_dir, (gs_font *)font->pfont);
671
22.5k
    if (code < 0) {
672
0
        goto error;
673
0
    }
674
675
22.5k
    code = pdfi_fapi_passfont((pdf_font *)font, 0, NULL, NULL, font->sfnt->data, font->sfnt->length);
676
22.5k
    if (code < 0) {
677
1.40k
        goto error;
678
1.40k
    }
679
680
    /* object_num can be zero if the dictionary was defined inline */
681
21.1k
    if (font->object_num != 0) {
682
20.9k
        (void)replace_cache_entry(ctx, (pdf_obj *)font);
683
20.9k
    }
684
685
21.1k
    *ppdffont = (pdf_font *)font;
686
21.1k
    return code;
687
9.49k
error:
688
9.49k
    pdfi_countdown(obj);
689
9.49k
    obj = NULL;
690
9.49k
    if (font_dict != NULL) {
691
9.49k
        if (pdfi_dict_get(ctx, font_dict, ".Path", &obj) >= 0)
692
0
        {
693
0
            char fname[gp_file_name_sizeof + 1];
694
0
            pdf_string *fobj = (pdf_string *)obj;
695
696
0
            memcpy(fname, fobj->data, fobj->length > gp_file_name_sizeof ? gp_file_name_sizeof : fobj->length);
697
0
            fname[fobj->length > gp_file_name_sizeof ? gp_file_name_sizeof : fobj->length] = '\0';
698
699
0
            (void)pdfi_set_error_var(ctx, code, NULL, E_PDF_BADSTREAM, "pdfi_read_truetype_font", "Error reading TrueType font file %s\n", fname);
700
0
        }
701
9.49k
        else {
702
9.49k
            (void)pdfi_set_error_var(ctx, code, NULL, E_PDF_BADSTREAM, "pdfi_read_truetype_font", "Error reading embedded TrueType font object %u\n", font_dict->object_num);
703
9.49k
        }
704
9.49k
    }
705
0
    else {
706
0
        pdfi_set_error(ctx, code, NULL, E_PDF_BADSTREAM, "pdfi_read_truetype_font", "Error reading font\n");
707
0
    }
708
9.49k
    if (buf != NULL)
709
0
        gs_free_object(ctx->memory, buf, "pdfi_read_truetype_font(buf)");
710
9.49k
    pdfi_countdown(fontdesc);
711
9.49k
    pdfi_countdown(basefont);
712
9.49k
    pdfi_countdown(font);
713
9.49k
    return code;
714
22.5k
}
715
716
int
717
pdfi_copy_truetype_font(pdf_context *ctx, pdf_font *spdffont, pdf_dict *font_dict, pdf_font **tpdffont)
718
3.78k
{
719
3.78k
    int code = 0;
720
3.78k
    pdf_font_truetype *font = NULL;
721
3.78k
    gs_font_type42 *spfont1 = (gs_font_type42 *) spdffont->pfont;
722
3.78k
    gs_font_type42 *dpfont42;
723
3.78k
    gs_id t_id;
724
3.78k
    pdf_obj *tmp;
725
726
3.78k
    if (font_dict == NULL)
727
0
        return_error(gs_error_invalidfont);
728
729
3.78k
    code = pdfi_alloc_tt_font(ctx, &font, font_dict->object_num);
730
3.78k
    if (code < 0)
731
0
        return code;
732
3.78k
    dpfont42 = (gs_font_type42 *) font->pfont;
733
734
3.78k
    t_id = dpfont42->id;
735
3.78k
    memcpy(dpfont42, spfont1, sizeof(gs_font_type42));
736
3.78k
    dpfont42->id = t_id;
737
3.78k
    dpfont42->FAPI = NULL;
738
3.78k
    dpfont42->FAPI_font_data = NULL;
739
3.78k
    dpfont42->notify_list.memory = NULL;
740
3.78k
    dpfont42->notify_list.first = NULL;
741
3.78k
    gs_notify_init(&dpfont42->notify_list, dpfont42->memory);
742
743
3.78k
    memcpy(font, spdffont, sizeof(pdf_font_truetype));
744
3.78k
    font->refcnt = 1;
745
3.78k
    font->filename = NULL;
746
3.78k
    pdfi_countup(font->post);
747
748
3.78k
    if (dpfont42->data.len_glyphs != NULL) {
749
3.78k
        dpfont42->data.len_glyphs = (uint *)gs_alloc_byte_array(dpfont42->memory, dpfont42->data.numGlyphs + 1, sizeof(uint), "pdfi_copy_truetype_font");
750
3.78k
        if (dpfont42->data.len_glyphs == NULL) {
751
0
            pdfi_countdown(font);
752
0
            return_error(gs_error_VMerror);
753
0
        }
754
3.78k
        code = gs_font_notify_register((gs_font *)dpfont42, gs_len_glyphs_release, (void *)dpfont42);
755
3.78k
        if (code < 0) {
756
0
            gs_free_object(dpfont42->memory, dpfont42->data.len_glyphs, "gs_len_glyphs_release");
757
0
            dpfont42->data.len_glyphs = NULL;
758
0
            pdfi_countdown(font);
759
0
            return code;
760
0
        }
761
3.78k
        memcpy(dpfont42->data.len_glyphs, spfont1->data.len_glyphs, (dpfont42->data.numGlyphs + 1) * sizeof(uint));
762
3.78k
    }
763
3.78k
    if (dpfont42->data.gsub != NULL) {
764
0
        dpfont42->data.gsub_size = spfont1->data.gsub_size;
765
766
0
        dpfont42->data.gsub = gs_alloc_byte_array(dpfont42->memory, dpfont42->data.gsub_size, 1, "pdfi_copy_truetype_font");
767
0
        if (dpfont42->data.gsub == 0) {
768
0
            pdfi_countdown(font);
769
0
            return_error(gs_error_VMerror);
770
0
        }
771
772
0
        code = gs_font_notify_register((gs_font *)dpfont42, gs_gsub_release, (void *)dpfont42);
773
0
        if (code < 0) {
774
0
            gs_free_object(dpfont42->memory, dpfont42->data.gsub, "gs_len_glyphs_release");
775
0
            dpfont42->data.gsub = NULL;
776
0
            pdfi_countdown(font);
777
0
            return code;
778
0
        }
779
0
        memcpy(dpfont42->data.gsub, spfont1->data.gsub, dpfont42->data.gsub_size);
780
0
    }
781
782
3.78k
    font->pfont = (gs_font_base *)dpfont42;
783
3.78k
    dpfont42->client_data = (void *)font;
784
785
3.78k
    font->PDF_font = font_dict;
786
3.78k
    font->object_num = font_dict->object_num;
787
3.78k
    font->generation_num = font_dict->generation_num;
788
3.78k
    pdfi_countup(font->PDF_font);
789
790
    /* We want basefont and descriptor, but we can live without them */
791
3.78k
    font->BaseFont = NULL;
792
3.78k
    (void)pdfi_dict_knownget_type(ctx, font_dict, "BaseFont", PDF_NAME, &font->BaseFont);
793
3.78k
    font->FontDescriptor = NULL;
794
3.78k
    (void)pdfi_dict_knownget_type(ctx, font_dict, "FontDescriptor", PDF_DICT, (pdf_obj **)&font->FontDescriptor);
795
796
3.78k
    pdfi_countup(font->sfnt);
797
3.78k
    pdfi_countup(font->copyright);
798
3.78k
    pdfi_countup(font->notice);
799
3.78k
    pdfi_countup(font->fullname);
800
3.78k
    pdfi_countup(font->familyname);
801
802
3.78k
    if (font->BaseFont != NULL && ((pdf_name *)font->BaseFont)->length <= gs_font_name_max) {
803
3.73k
        memcpy(dpfont42->key_name.chars, ((pdf_name *)font->BaseFont)->data, ((pdf_name *)font->BaseFont)->length);
804
3.73k
        dpfont42->key_name.size = ((pdf_name *)font->BaseFont)->length;
805
3.73k
        memcpy(dpfont42->font_name.chars, ((pdf_name *)font->BaseFont)->data, ((pdf_name *)font->BaseFont)->length);
806
3.73k
        dpfont42->font_name.size = ((pdf_name *)font->BaseFont)->length;
807
3.73k
    }
808
809
3.78k
    font->Encoding = NULL;
810
3.78k
    font->ToUnicode = NULL;
811
3.78k
    font->Widths = NULL;
812
813
3.78k
    pdfi_font_set_first_last_char(ctx, font_dict, (pdf_font *)font);
814
3.78k
    (void)pdfi_font_create_widths(ctx, font_dict, (pdf_font*)font, (double)0.001);
815
816
3.78k
    font->descflags = 0;
817
3.78k
    if (font->FontDescriptor != NULL) {
818
3.78k
        code = pdfi_dict_get_int(ctx, font->FontDescriptor, "Flags", &font->descflags);
819
3.78k
        if (code >= 0) {
820
            /* If both the symbolic and non-symbolic flag are set,
821
               believe that latter.
822
             */
823
3.78k
            if ((font->descflags & 32) != 0)
824
3.76k
                font->descflags = (font->descflags & ~4);
825
3.78k
        }
826
3.78k
    }
827
828
3.78k
    tmp = NULL;
829
3.78k
    code = pdfi_dict_knownget(ctx, font_dict, "Encoding", &tmp);
830
3.78k
    if (code == 1) {
831
3.76k
        if ((pdfi_type_of(tmp) == PDF_NAME || pdfi_type_of(tmp) == PDF_DICT) && (font->descflags & 4) == 0) {
832
3.76k
            code = pdfi_create_Encoding(ctx, (pdf_font *)font, tmp, NULL, (pdf_obj **) & font->Encoding);
833
3.76k
        }
834
0
        else if (pdfi_type_of(tmp) == PDF_DICT && (font->descflags & 4) != 0) {
835
0
            code = pdfi_create_Encoding(ctx, (pdf_font *)font, tmp, (pdf_obj *)spdffont->Encoding, (pdf_obj **) &font->Encoding);
836
0
        }
837
0
        else {
838
0
            code = gs_error_undefined;
839
0
        }
840
3.76k
        pdfi_countdown(tmp);
841
3.76k
        tmp = NULL;
842
3.76k
    }
843
21
    else {
844
21
        pdfi_countdown(tmp);
845
21
        tmp = NULL;
846
21
        code = gs_error_undefined;
847
21
    }
848
849
3.78k
    if (code < 0) {
850
21
        font->Encoding = spdffont->Encoding;
851
21
        pdfi_countup(font->Encoding);
852
21
    }
853
854
3.78k
    code = uid_copy(&font->pfont->UID, font->pfont->memory, "pdfi_copy_cff_font");
855
3.78k
    if (code < 0) {
856
0
        uid_set_invalid(&font->pfont->UID);
857
0
    }
858
3.78k
    if (spdffont->filename == NULL) {
859
3.78k
        code = pdfi_font_generate_pseudo_XUID(ctx, font_dict, font->pfont);
860
3.78k
        if (code < 0) {
861
0
            goto error;
862
0
        }
863
3.78k
    }
864
3.78k
    if (ctx->args.ignoretounicode != true) {
865
3.78k
        code = pdfi_dict_get(ctx, font_dict, "ToUnicode", (pdf_obj **)&tmp);
866
3.78k
        if (code >= 0 && pdfi_type_of(tmp) == PDF_STREAM) {
867
290
            pdf_cmap *tu = NULL;
868
290
            code = pdfi_read_cmap(ctx, tmp, &tu);
869
290
            pdfi_countdown(tmp);
870
290
            tmp = (pdf_obj *)tu;
871
290
        }
872
3.78k
        if (code < 0 || (tmp != NULL && pdfi_type_of(tmp) != PDF_CMAP)) {
873
3.49k
            pdfi_countdown(tmp);
874
3.49k
            tmp = NULL;
875
3.49k
            code = 0;
876
3.49k
        }
877
3.78k
    }
878
0
    else {
879
0
        tmp = NULL;
880
0
    }
881
3.78k
    font->ToUnicode = tmp;
882
3.78k
    pdfi_font_set_orig_fonttype(ctx, (pdf_font *)font);
883
884
3.78k
    code = gs_definefont(ctx->font_dir, (gs_font *) font->pfont);
885
3.78k
    if (code < 0) {
886
0
        goto error;
887
0
    }
888
889
3.78k
    code = pdfi_fapi_passfont((pdf_font *) font, 0, NULL, NULL, NULL, 0);
890
3.78k
    if (code < 0) {
891
0
        goto error;
892
0
    }
893
    /* object_num can be zero if the dictionary was defined inline */
894
3.78k
    if (font->object_num != 0) {
895
356
        (void)replace_cache_entry(ctx, (pdf_obj *) font);
896
356
    }
897
898
3.78k
    *tpdffont = (pdf_font *)font;
899
900
3.78k
error:
901
3.78k
    if (code < 0)
902
0
        pdfi_countdown(font);
903
3.78k
    return code;
904
3.78k
}
905
906
int pdfi_free_font_truetype(pdf_obj *font)
907
34.4k
{
908
34.4k
    pdf_font_truetype *ttfont = (pdf_font_truetype *)font;
909
910
34.4k
    if (ttfont->pfont)
911
34.4k
        gs_free_object(OBJ_MEMORY(ttfont), ttfont->pfont, "Free TrueType gs_font");
912
913
34.4k
    if (ttfont->Widths)
914
32.7k
        gs_free_object(OBJ_MEMORY(ttfont), ttfont->Widths, "Free TrueType font Widths array");
915
916
34.4k
    pdfi_countdown(ttfont->sfnt);
917
34.4k
    pdfi_countdown(ttfont->FontDescriptor);
918
34.4k
    pdfi_countdown(ttfont->Encoding);
919
34.4k
    pdfi_countdown(ttfont->BaseFont);
920
34.4k
    pdfi_countdown(ttfont->PDF_font);
921
34.4k
    pdfi_countdown(ttfont->ToUnicode);
922
34.4k
    pdfi_countdown(ttfont->filename);
923
34.4k
    pdfi_countdown(ttfont->post);
924
34.4k
    pdfi_countdown(ttfont->copyright);
925
34.4k
    pdfi_countdown(ttfont->notice);
926
34.4k
    pdfi_countdown(ttfont->fullname);
927
34.4k
    pdfi_countdown(ttfont->familyname);
928
929
34.4k
    gs_free_object(OBJ_MEMORY(ttfont), ttfont, "Free TrueType font");
930
931
34.4k
    return 0;
932
34.4k
}