Coverage Report

Created: 2022-10-31 07:00

/src/ghostpdl/pdf/pdf_font0.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2019-2022 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.,  1305 Grant Avenue - Suite 200, Novato,
13
   CA 94945, U.S.A., +1(415)492-9861, for further information.
14
*/
15
16
/* Include this first so that we don't get a macro redefnition of 'offsetof' */
17
#include "pdf_int.h"
18
19
/* code for type 0 (CID) font handling */
20
#include "gxfont.h"
21
#include "gxfont0.h"
22
23
#include "pdf_int.h"
24
#include "pdf_font.h"
25
#include "pdf_font0.h"
26
#include "pdf_font1C.h"
27
#include "pdf_font_types.h"
28
#include "pdf_stack.h"
29
#include "pdf_array.h"
30
#include "pdf_dict.h"
31
#include "pdf_file.h"
32
#include "pdf_cmap.h"
33
#include "pdf_deref.h"
34
35
#include "gsutil.h"        /* For gs_next_ids() */
36
37
extern const pdfi_cid_decoding_t *pdfi_cid_decoding_list[];
38
extern const pdfi_cid_subst_nwp_table_t *pdfi_cid_substnwp_list[];
39
40
static void pdfi_font0_cid_subst_tables(const char *reg, const int reglen, const char *ord,
41
                const int ordlen, pdfi_cid_decoding_t **decoding, pdfi_cid_subst_nwp_table_t **substnwp)
42
1.54k
{
43
1.54k
    int i;
44
1.54k
    *decoding = NULL;
45
1.54k
    *substnwp = NULL;
46
    /* This only makes sense for Adobe orderings */
47
1.54k
    if (reglen == 5 && !memcmp(reg, "Adobe", 5)) {
48
8.21k
        for (i = 0; pdfi_cid_decoding_list[i] != NULL; i++) {
49
6.88k
            if (strlen(pdfi_cid_decoding_list[i]->s_order) == ordlen &&
50
6.88k
                !memcmp(pdfi_cid_decoding_list[i]->s_order, ord, ordlen)) {
51
74
                *decoding = (pdfi_cid_decoding_t *)pdfi_cid_decoding_list[i];
52
74
                break;
53
74
            }
54
6.88k
        }
55
        /* For now, also only for Adobe orderings */
56
8.14k
        for (i = 0; pdfi_cid_substnwp_list[i] != NULL; i++) {
57
6.81k
            if (strlen(pdfi_cid_substnwp_list[i]->ordering) == ordlen &&
58
6.81k
                !memcmp(pdfi_cid_substnwp_list[i]->ordering, ord, ordlen)) {
59
74
                *substnwp = (pdfi_cid_subst_nwp_table_t *)pdfi_cid_substnwp_list[i];
60
74
                break;
61
74
            }
62
6.81k
        }
63
1.41k
    }
64
1.54k
}
65
66
static int
67
pdfi_font0_glyph_name(gs_font *pfont, gs_glyph index, gs_const_string *pstr)
68
0
{
69
0
    int code;
70
0
    pdf_font_type0 *pt0font = (pdf_font_type0 *)pfont->client_data;
71
0
    char gnm[64];
72
0
    pdf_context *ctx = pt0font->ctx;
73
0
    uint gindex = 0;
74
75
0
    gs_snprintf(gnm, 64, "%lu", (long)index);
76
0
    code = (*ctx->get_glyph_index)((gs_font *)pfont, (byte *)gnm, strlen(gnm), &gindex);
77
0
    if (code < 0)
78
0
        return code;
79
0
    code = (*ctx->get_glyph_name)(pfont, (gs_glyph)gindex, (gs_const_string *)pstr);
80
81
0
    return code;
82
0
}
83
84
static int
85
pdfi_font0_map_glyph_to_unicode(gs_font *font, gs_glyph glyph, int ch, ushort *u, unsigned int length)
86
133k
{
87
133k
    gs_glyph cc = glyph < GS_MIN_CID_GLYPH ? glyph : glyph - GS_MIN_CID_GLYPH;
88
133k
    pdf_font_type0 *pt0font = (pdf_font_type0 *)font->client_data;
89
133k
    int code = gs_error_undefined, i;
90
133k
    uchar *unicode_return = (uchar *)u;
91
133k
    pdf_cidfont_type2 *decfont = NULL;
92
133k
    pdfi_cid_subst_nwp_table_t *substnwp = pt0font->substnwp;
93
94
133k
    code = pdfi_array_get(pt0font->ctx, pt0font->DescendantFonts, 0, (pdf_obj **)&decfont);
95
133k
    if (code < 0 || pdfi_type_of(decfont) != PDF_FONT) {
96
0
        pdfi_countdown(decfont);
97
0
        return gs_error_undefined;
98
0
    }
99
100
133k
    code = gs_error_undefined;
101
133k
    while (1) { /* Loop to make retrying with a substitute CID easier */
102
        /* Favour the ToUnicode if one exists */
103
133k
        code = pdfi_tounicode_char_to_unicode(pt0font->ctx, (pdf_cmap *)pt0font->ToUnicode, glyph, ch, u, length);
104
105
133k
        if (code == gs_error_undefined && pt0font->decoding) {
106
1.53k
            const int *n;
107
108
1.53k
            if (cc / 256 < pt0font->decoding->nranges) {
109
1.50k
                n = (const int *)pt0font->decoding->ranges[cc / 256][cc % 256];
110
1.53k
                for (i = 0; i < pt0font->decoding->val_sizes; i++) {
111
1.53k
                    unsigned int cmapcc;
112
1.53k
                    if (n[i] == -1)
113
195
                        break;
114
1.33k
                    cc = n[i];
115
1.33k
                    cmapcc = (unsigned int)cc;
116
1.33k
                    if (decfont->pdfi_font_type == e_pdf_cidfont_type2)
117
1.33k
                        code = pdfi_fapi_check_cmap_for_GID((gs_font *)decfont->pfont, (unsigned int)cc, &cmapcc);
118
0
                    else
119
0
                        code = 0;
120
1.33k
                    if (code >= 0 && cmapcc != 0){
121
1.31k
                        code = 0;
122
1.31k
                        break;
123
1.31k
                    }
124
1.33k
                }
125
                /* If it's a TTF derived CIDFont, we prefer a code point supported by the cmap table
126
                   but if not, use the first available one
127
                 */
128
1.50k
                if (code < 0 && n[0] != -1) {
129
0
                    cc = n[0];
130
0
                    code = 0;
131
0
                }
132
1.50k
            }
133
1.53k
            if (code >= 0) {
134
1.31k
                if (cc > 65535) {
135
0
                    code = 4;
136
0
                    if (unicode_return != NULL && length >= code) {
137
0
                        unicode_return[0] = (cc & 0xFF000000)>> 24;
138
0
                        unicode_return[1] = (cc & 0x00FF0000) >> 16;
139
0
                        unicode_return[2] = (cc & 0x0000FF00) >> 8;
140
0
                        unicode_return[3] = (cc & 0x000000FF);
141
0
                    }
142
0
                }
143
1.31k
                else {
144
1.31k
                    code = 2;
145
1.31k
                    if (unicode_return != NULL && length >= code) {
146
1.26k
                        unicode_return[0] = (cc & 0x0000FF00) >> 8;
147
1.26k
                        unicode_return[1] = (cc & 0x000000FF);
148
1.26k
                    }
149
1.31k
                }
150
1.31k
            }
151
1.53k
        }
152
        /* If we get here, and still don't have a usable code point, check for a
153
           pre-defined CID substitution, and if there's one, jump back to the start
154
           and try again.
155
         */
156
133k
        if (code == gs_error_undefined && substnwp) {
157
1.15k
            for (i = 0; substnwp->subst[i].s_type != 0; i++ ) {
158
1.10k
                if (cc >= substnwp->subst[i].s_scid && cc <= substnwp->subst[i].e_scid) {
159
0
                    cc = substnwp->subst[i].s_dcid + (cc - substnwp->subst[i].s_scid);
160
0
                    substnwp = NULL;
161
0
                    break;
162
0
                }
163
1.10k
                if (cc >= substnwp->subst[i].s_dcid
164
1.10k
                 && cc <= substnwp->subst[i].s_dcid + (substnwp->subst[i].e_scid - substnwp->subst[i].s_scid)) {
165
174
                    cc = substnwp->subst[i].s_scid + (cc - substnwp->subst[i].s_dcid);
166
174
                    substnwp = NULL;
167
174
                    break;
168
174
                }
169
1.10k
            }
170
218
            if (substnwp == NULL)
171
174
                continue;
172
218
        }
173
133k
        break;
174
133k
    }
175
133k
    pdfi_countdown(decfont);
176
133k
    return (code < 0 ? 0 : code);
177
133k
}
178
179
int pdfi_read_type0_font(pdf_context *ctx, pdf_dict *font_dict, pdf_dict *stream_dict, pdf_dict *page_dict, pdf_font **ppdffont)
180
6.85k
{
181
6.85k
    int code, nlen;
182
6.85k
    pdf_obj *cmap = NULL;
183
6.85k
    pdf_cmap *pcmap = NULL;
184
6.85k
    pdf_array *arr = NULL;
185
6.85k
    pdf_dict *decfontdict = NULL; /* there can only be one */
186
6.85k
    pdf_name *n = NULL;
187
6.85k
    pdf_obj *basefont = NULL;
188
6.85k
    pdf_obj *tounicode = NULL;
189
6.85k
    pdf_dict *dfontdesc = NULL;
190
6.85k
    pdf_dict *fontdesc = NULL;
191
6.85k
    pdf_stream *ffile = NULL;
192
6.85k
    pdf_font *descpfont = NULL;
193
6.85k
    pdf_font_type0 *pdft0 = NULL;
194
6.85k
    gs_font_type0 *pfont0 = NULL;
195
6.85k
    pdfi_cid_decoding_t *dec = NULL;
196
6.85k
    pdfi_cid_subst_nwp_table_t *substnwp = NULL;
197
198
    /* We're supposed to have a FontDescriptor, it can be missing, and we have to carry on */
199
6.85k
    (void)pdfi_dict_get(ctx, font_dict, "FontDescriptor", (pdf_obj **)&fontdesc);
200
201
6.85k
    code = pdfi_dict_get(ctx, font_dict, "Encoding", &cmap);
202
6.85k
    if (code < 0) goto error;
203
204
6.80k
    if (pdfi_type_of(cmap) == PDF_CMAP) {
205
0
        pcmap = (pdf_cmap *)cmap;
206
0
        cmap = NULL;
207
0
    }
208
6.80k
    else {
209
6.80k
        code = pdfi_read_cmap(ctx, cmap, &pcmap);
210
6.80k
        pdfi_countdown(cmap);
211
6.80k
        cmap = NULL;
212
6.80k
        if (code < 0) goto error;
213
6.80k
    }
214
215
6.76k
    code = pdfi_dict_get(ctx, font_dict, "DescendantFonts", (pdf_obj **)&arr);
216
6.76k
    if (code < 0) goto error;
217
218
6.64k
    if (pdfi_type_of(arr) != PDF_ARRAY || arr->size != 1) {
219
3
        code = gs_note_error(gs_error_invalidfont);
220
3
        goto error;
221
3
    }
222
6.64k
    code = pdfi_array_get(ctx, arr, 0, (pdf_obj **)&decfontdict);
223
6.64k
    pdfi_countdown(arr);
224
6.64k
    arr = NULL;
225
6.64k
    if (code < 0) goto error;
226
5.71k
    switch (pdfi_type_of(decfontdict)) {
227
577
        case PDF_FONT:
228
577
            descpfont = (pdf_font *)decfontdict;
229
577
            decfontdict = descpfont->PDF_font;
230
577
            pdfi_countup(decfontdict);
231
577
            break;
232
4.70k
        case PDF_DICT:
233
4.70k
            code = pdfi_dict_get(ctx, (pdf_dict *)decfontdict, "Type", (pdf_obj **)&n);
234
4.70k
            if (code < 0) goto error;
235
4.68k
            if (pdfi_type_of(n) != PDF_NAME || n->length != 4 || memcmp(n->data, "Font", 4) != 0) {
236
8
                pdfi_countdown(n);
237
8
                code = gs_note_error(gs_error_invalidfont);
238
8
                goto error;
239
8
            }
240
4.67k
            pdfi_countdown(n);
241
4.67k
            break;
242
438
        default:
243
438
            code = gs_note_error(gs_error_invalidfont);
244
438
            goto error;
245
5.71k
    }
246
#if 0
247
    code = pdfi_dict_get(ctx, (pdf_dict *)decfontdict, "Subtype", (pdf_obj **)&n);
248
    if (code < 0)
249
        goto error;
250
251
    if (pdfi_type_of(n) != PDF_NAME || n->length != 12 || memcmp(n->data, "CIDFontType", 11) != 0) {
252
        pdfi_countdown(n);
253
        code = gs_note_error(gs_error_invalidfont);
254
        goto error;
255
    }
256
    /* cidftype is ignored for now, but we may need to know it when
257
       subsitutions are allowed
258
     */
259
    cidftype = n->data[11] - 48;
260
261
    pdfi_countdown(n);
262
#endif
263
264
5.24k
    code = pdfi_dict_get(ctx, font_dict, "BaseFont", (pdf_obj **)&basefont);
265
5.24k
    if (code < 0) {
266
33
        basefont = NULL;
267
33
    }
268
269
5.24k
    if (ctx->args.ignoretounicode != true) {
270
5.24k
        code = pdfi_dict_get(ctx, font_dict, "ToUnicode", (pdf_obj **)&tounicode);
271
5.24k
        if (code >= 0 && pdfi_type_of(tounicode) == PDF_STREAM) {
272
3.67k
            pdf_cmap *tu = NULL;
273
3.67k
            code = pdfi_read_cmap(ctx, tounicode, &tu);
274
3.67k
            pdfi_countdown(tounicode);
275
3.67k
            tounicode = (pdf_obj *)tu;
276
3.67k
        }
277
5.24k
        if (code < 0 || (tounicode != NULL && pdfi_type_of(tounicode) != PDF_CMAP)) {
278
1.68k
            pdfi_countdown(tounicode);
279
1.68k
            tounicode = NULL;
280
1.68k
            code = 0;
281
1.68k
        }
282
5.24k
    }
283
0
    else {
284
0
        tounicode = NULL;
285
0
    }
286
287
5.24k
    if (descpfont == NULL) {
288
4.67k
        gs_font *pf;
289
290
4.67k
        code = pdfi_load_font(ctx, stream_dict, page_dict, decfontdict, &pf, true);
291
4.67k
        if (code < 0)
292
1.20k
            goto error;
293
3.46k
        descpfont = (pdf_font *)pf->client_data;
294
3.46k
    }
295
296
4.04k
    if (descpfont->pdfi_font_type < e_pdf_cidfont_type0 || descpfont->pdfi_font_type > e_pdf_cidfont_type4) {
297
12
        code = gs_note_error(gs_error_invalidfont);
298
12
        goto error;
299
12
    }
300
301
4.03k
    if (descpfont != NULL && ((pdf_cidfont_t *)descpfont)->substitute) {
302
1.54k
        pdf_obj *csi = NULL;
303
1.54k
        pdf_string *reg = NULL, *ord = NULL;
304
1.54k
        char *r = NULL, *o = NULL;
305
1.54k
        int rlen = 0, olen = 0;
306
307
1.54k
        code = pdfi_dict_get(ctx, decfontdict, "CIDSystemInfo", (pdf_obj **)&csi);
308
1.54k
        if (code >= 0) {
309
1.54k
            (void)pdfi_dict_get(ctx, (pdf_dict *)csi, "Registry", (pdf_obj **)&reg);
310
1.54k
            (void)pdfi_dict_get(ctx, (pdf_dict *)csi, "Ordering", (pdf_obj **)&ord);
311
1.54k
            if (reg != NULL && pdfi_type_of(reg) == PDF_STRING
312
1.54k
             && ord != NULL && pdfi_type_of(ord) == PDF_STRING) {
313
1.53k
                r = (char *)reg->data;
314
1.53k
                rlen = reg->length;
315
1.53k
                o = (char *)ord->data;
316
1.53k
                olen = ord->length;
317
1.53k
            }
318
1.54k
            pdfi_countdown(csi);
319
1.54k
            pdfi_countdown(reg);
320
1.54k
            pdfi_countdown(ord);
321
1.54k
        }
322
1.54k
        if (r == NULL || o == NULL) {
323
8
            r = (char *)pcmap->csi_reg.data;
324
8
            rlen = pcmap->csi_reg.size;
325
8
            o = (char *)pcmap->csi_ord.data;
326
8
            olen = pcmap->csi_ord.size;
327
8
        }
328
1.54k
        if (rlen > 0 && olen > 0)
329
1.54k
            pdfi_font0_cid_subst_tables(r, rlen, o, olen, &dec, &substnwp);
330
0
        else {
331
0
            dec = NULL;
332
0
            substnwp = NULL;
333
0
        }
334
1.54k
    }
335
    /* reference is now owned by the descendent font created above */
336
4.03k
    pdfi_countdown(decfontdict);
337
4.03k
    decfontdict = NULL;
338
4.03k
    if (code < 0) {
339
2
        code = gs_note_error(gs_error_invalidfont);
340
2
        goto error;
341
2
    }
342
    /* If we're got this far, we have a CMap and a descendant font, let's make the Type 0 */
343
4.02k
    pdft0 = (pdf_font_type0 *)gs_alloc_bytes(ctx->memory, sizeof(pdf_font_type0), "pdfi (type0 pdf_font)");
344
4.02k
    if (pdft0 == NULL) {
345
0
        code = gs_note_error(gs_error_VMerror);
346
0
        goto error;
347
0
    }
348
4.02k
    code = pdfi_array_alloc(ctx, 1, &arr);
349
4.02k
    if (code < 0) {
350
0
        gs_free_object(ctx->memory, pdft0, "pdfi_read_type0_font(pdft0)");
351
0
        goto error;
352
0
    }
353
4.02k
    arr->refcnt = 1;
354
4.02k
    code = pdfi_array_put(ctx, arr, 0, (pdf_obj *)descpfont);
355
4.02k
    if (code < 0) {
356
0
        gs_free_object(ctx->memory, pdft0, "pdfi_read_type0_font(pdft0)");
357
0
        goto error;
358
0
    }
359
360
4.02k
    pdft0->type = PDF_FONT;
361
4.02k
    pdft0->pdfi_font_type = e_pdf_font_type0;
362
4.02k
    pdft0->ctx = ctx;
363
#if REFCNT_DEBUG
364
    pdft0->UID = ctx->UID++;
365
    dmprintf2(ctx->memory, "Allocated object of type %c with UID %"PRIi64"\n", pdft0->type, pdft0->UID);
366
#endif
367
4.02k
    pdft0->refcnt = 1;
368
4.02k
    pdft0->filename = NULL;
369
4.02k
    pdft0->object_num = font_dict->object_num;
370
4.02k
    pdft0->generation_num = font_dict->generation_num;
371
4.02k
    pdft0->indirect_num = font_dict->indirect_num;
372
4.02k
    pdft0->indirect_gen = font_dict->indirect_gen;
373
4.02k
    pdft0->Encoding = (pdf_obj *)pcmap;
374
4.02k
    pdft0->ToUnicode = tounicode;
375
4.02k
    tounicode = NULL;
376
4.02k
    pdft0->DescendantFonts = arr;
377
4.02k
    pdft0->PDF_font = font_dict;
378
4.02k
    pdfi_countup(font_dict);
379
4.02k
    pdft0->FontDescriptor = fontdesc;
380
4.02k
    fontdesc = NULL;
381
4.02k
    pdft0->BaseFont = basefont;
382
4.02k
    pdft0->decoding = dec;
383
4.02k
    pdft0->substnwp = substnwp;
384
385
    /* Ownership transferred to pdft0, if we jump to error
386
     * these will now be freed by counting down pdft0.
387
     */
388
4.02k
    tounicode = NULL;
389
4.02k
    arr = NULL;
390
4.02k
    basefont = NULL;
391
392
4.02k
    pdft0->pfont = NULL; /* In case we error out */
393
394
4.02k
    pfont0 = (gs_font_type0 *)gs_alloc_struct(ctx->memory, gs_font, &st_gs_font_type0, "pdfi gs type 0 font");
395
4.02k
    if (pfont0 == NULL) {
396
0
        gs_free_object(ctx->memory, pdft0, "pdfi_read_type0_font(pdft0)");
397
0
        code = gs_note_error(gs_error_VMerror);
398
0
        goto error;
399
0
    }
400
4.02k
    gs_make_identity(&pfont0->orig_FontMatrix);
401
4.02k
    gs_make_identity(&pfont0->FontMatrix);
402
4.02k
    pfont0->next = pfont0->prev = 0;
403
4.02k
    pfont0->memory = ctx->memory;
404
4.02k
    pfont0->dir = ctx->font_dir;
405
4.02k
    pfont0->is_resource = false;
406
4.02k
    gs_notify_init(&pfont0->notify_list, ctx->memory);
407
4.02k
    pfont0->id = gs_next_ids(ctx->memory, 1);
408
4.02k
    pfont0->base = (gs_font *) pfont0;
409
4.02k
    pfont0->client_data = pdft0;
410
4.02k
    pfont0->WMode = pcmap->wmode;
411
4.02k
    pfont0->FontType = ft_composite;
412
4.02k
    pfont0->PaintType = 0;
413
4.02k
    pfont0->StrokeWidth = 0;
414
4.02k
    pfont0->is_cached = 0;
415
4.02k
    if (pdft0->BaseFont != NULL) {
416
4.01k
        pdf_name *nobj = (pdf_name *)pdft0->BaseFont;
417
4.01k
        nlen = nobj->length > gs_font_name_max ? gs_font_name_max : nobj->length;
418
419
4.01k
        memcpy(pfont0->key_name.chars, nobj->data, nlen);
420
4.01k
        pfont0->key_name.size = nlen;
421
4.01k
        memcpy(pfont0->font_name.chars, nobj->data, nlen);
422
4.01k
        pfont0->font_name.size = nlen;
423
4.01k
    }
424
11
    else {
425
11
        nlen = descpfont->pfont->key_name.size > gs_font_name_max ? gs_font_name_max : descpfont->pfont->key_name.size;
426
427
11
        memcpy(pfont0->key_name.chars, descpfont->pfont->key_name.chars, nlen);
428
11
        pfont0->key_name.size = nlen;
429
11
        memcpy(pfont0->font_name.chars, descpfont->pfont->font_name.chars, nlen);
430
11
        pfont0->font_name.size = nlen;
431
11
    }
432
433
4.02k
    if (pcmap->name.size > 0) {
434
4.02k
        if (pfont0->key_name.size + pcmap->name.size + 1 < gs_font_name_max) {
435
3.90k
            memcpy(pfont0->key_name.chars + pfont0->key_name.size, "-", 1);
436
3.90k
            memcpy(pfont0->key_name.chars + pfont0->key_name.size + 1, pcmap->name.data, pcmap->name.size);
437
3.90k
            pfont0->key_name.size += pcmap->name.size + 1;
438
3.90k
        }
439
4.02k
        if (pfont0->font_name.size + pcmap->name.size + 1 < gs_font_name_max) {
440
3.90k
            memcpy(pfont0->font_name.chars + pfont0->font_name.size, "-", 1);
441
3.90k
            memcpy(pfont0->font_name.chars + pfont0->font_name.size + 1, pcmap->name.data, pcmap->name.size);
442
3.90k
            pfont0->font_name.size += pcmap->name.size + 1;
443
3.90k
        }
444
4.02k
    }
445
4.02k
    pfont0->procs.define_font = gs_no_define_font;
446
4.02k
    pfont0->procs.make_font = gs_no_make_font;
447
4.02k
    pfont0->procs.font_info = gs_default_font_info;
448
4.02k
    pfont0->procs.same_font = gs_default_same_font;
449
4.02k
    pfont0->procs.encode_char = pdfi_encode_char;
450
4.02k
    pfont0->procs.decode_glyph = pdfi_font0_map_glyph_to_unicode;
451
4.02k
    pfont0->procs.enumerate_glyph = gs_no_enumerate_glyph;
452
4.02k
    pfont0->procs.glyph_info = gs_default_glyph_info;
453
4.02k
    pfont0->procs.glyph_outline = gs_no_glyph_outline;
454
4.02k
    pfont0->procs.glyph_name = pdfi_font0_glyph_name;
455
4.02k
    pfont0->procs.init_fstack = gs_type0_init_fstack;
456
4.02k
    pfont0->procs.next_char_glyph = gs_type0_next_char_glyph;
457
4.02k
    pfont0->procs.build_char = gs_no_build_char;
458
459
4.02k
    pfont0->data.FMapType = fmap_CMap;
460
4.02k
    pfont0->data.EscChar = 0xff;
461
4.02k
    pfont0->data.ShiftIn = 0x0f;
462
4.02k
    pfont0->data.SubsVector.data = NULL;
463
4.02k
    pfont0->data.SubsVector.size = 0;
464
4.02k
    pfont0->data.subs_size = pfont0->data.subs_width = 0;
465
466
4.02k
    pfont0->data.Encoding = (uint *)gs_alloc_bytes(ctx->memory, sizeof(uint), "pdfi_read_type0_font Encoding");
467
4.02k
    if (pfont0->data.Encoding == NULL) {
468
0
        gs_free_object(ctx->memory, pfont0, "pdfi_read_type0_font(pfont0)");
469
0
        code = gs_note_error(gs_error_VMerror);
470
0
        goto error;
471
0
    }
472
4.02k
    *pfont0->data.Encoding = 0;
473
474
4.02k
    pfont0->data.encoding_size = 1;
475
4.02k
    pfont0->data.FDepVector = (gs_font **)gs_alloc_bytes(ctx->memory, sizeof(gs_font *), "pdfi_read_type0_font FDepVector");
476
4.02k
    if (pfont0->data.FDepVector == NULL) {
477
        /* We transferred ownership of pcmap to pfont0 above, but we didn't null the pointer
478
         * so we could keep using it. We must NULL it out before returning an error to prevent
479
         * reference counting problems.
480
         */
481
0
        pcmap = NULL;
482
0
        gs_free_object(ctx->memory, pfont0, "pdfi_read_type0_font(pfont0)");
483
0
        code = gs_note_error(gs_error_VMerror);
484
0
        goto error;
485
0
    }
486
4.02k
    *pfont0->data.FDepVector = (gs_font *)descpfont->pfont;
487
4.02k
    pdfi_countdown(descpfont);
488
4.02k
    descpfont = NULL;
489
4.02k
    pfont0->data.fdep_size = 1;
490
4.02k
    pfont0->data.CMap = (gs_cmap_t *)pcmap->gscmap;
491
492
    /* NULL he pointer to prevent any reference counting problems, ownership was
493
     * transferred to pfont0, but we maintained the pointer for easy access until this
494
     * point.
495
     */
496
4.02k
    pcmap = NULL;
497
498
4.02k
    pdft0->pfont = (gs_font_base *)pfont0;
499
500
4.02k
    code = gs_definefont(ctx->font_dir, (gs_font *)pdft0->pfont);
501
4.02k
    if (code < 0) {
502
0
        gs_free_object(ctx->memory, pfont0, "pdfi_read_type0_font(pfont0)");
503
0
        code = gs_note_error(gs_error_VMerror);
504
0
        goto error;
505
0
    }
506
507
    /* object_num can be zero if the dictionary was defined inline */
508
4.02k
    if (pdft0->object_num != 0) {
509
4.02k
        (void)replace_cache_entry(ctx, (pdf_obj *)pdft0);
510
4.02k
    }
511
512
4.02k
    *ppdffont = (pdf_font *)pdft0;
513
4.02k
    return 0;
514
515
2.82k
error:
516
2.82k
    pdfi_countdown(arr);
517
2.82k
    pdfi_countdown(pcmap);
518
2.82k
    pdfi_countdown(tounicode);
519
2.82k
    pdfi_countdown(basefont);
520
2.82k
    pdfi_countdown(decfontdict);
521
2.82k
    pdfi_countdown(dfontdesc);
522
2.82k
    pdfi_countdown(fontdesc);
523
2.82k
    pdfi_countdown(ffile);
524
2.82k
    pdfi_countdown(descpfont);
525
2.82k
    pdfi_countdown(pdft0);
526
527
2.82k
    return code;
528
4.02k
}
529
530
int
531
pdfi_free_font_type0(pdf_obj *font)
532
4.02k
{
533
4.02k
    pdf_font_type0 *pdft0 = (pdf_font_type0 *)font;
534
4.02k
    gs_font_type0 *pfont0 = (gs_font_type0 *)pdft0->pfont;
535
4.02k
    pdfi_countdown(pdft0->PDF_font);
536
4.02k
    pdfi_countdown(pdft0->BaseFont);
537
4.02k
    pdfi_countdown(pdft0->FontDescriptor);
538
4.02k
    pdfi_countdown(pdft0->Encoding);
539
4.02k
    pdfi_countdown(pdft0->DescendantFonts);
540
4.02k
    pdfi_countdown(pdft0->ToUnicode);
541
4.02k
    pdfi_countdown(pdft0->filename);
542
543
4.02k
    gs_free_object(OBJ_MEMORY(pdft0), pfont0->data.Encoding, "pdfi_free_font_type0(data.Encoding)");
544
    /* We shouldn't need to free the fonts in the FDepVector, that should happen
545
        with DescendantFonts above.
546
     */
547
4.02k
    gs_free_object(OBJ_MEMORY(pdft0), pfont0->data.FDepVector, "pdfi_free_font_type0(data.FDepVector)");
548
4.02k
    gs_free_object(OBJ_MEMORY(pdft0), pfont0, "pdfi_free_font_type0(pfont0)");
549
4.02k
    gs_free_object(OBJ_MEMORY(pdft0), pdft0, "pdfi_free_font_type0(pdft0)");
550
551
4.02k
    return 0;
552
4.02k
}