Coverage Report

Created: 2025-08-28 07:06

/src/ghostpdl/pdf/pdf_font11.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2020-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 CIDFontType2/Type 9 font handling */
17
/* CIDFonts with Truetype outlines */
18
19
#include "pdf_int.h"
20
#include "pdf_font.h"
21
#include "pdf_font0.h"
22
#include "pdf_fontTT.h"
23
#include "pdf_font_types.h"
24
#include "pdf_stack.h"
25
#include "pdf_file.h"
26
#include "pdf_dict.h"
27
#include "pdf_array.h"
28
#include "pdf_deref.h"
29
#include "gxfont42.h"
30
#include "gxfcid.h"
31
#include "gsutil.h"        /* For gs_next_ids() */
32
33
static int pdfi_cidtype2_string_proc(gs_font_type42 * pfont, ulong offset, uint length,
34
                  const byte ** pdata)
35
458M
{
36
458M
    pdf_cidfont_type2 *ttfont = (pdf_cidfont_type2 *)pfont->client_data;
37
458M
    int code = 0;
38
39
458M
    if (offset + length > ttfont->sfnt->length) {
40
5.02M
        *pdata = NULL;
41
5.02M
        code = gs_note_error(gs_error_invalidfont);
42
5.02M
    }
43
452M
    else {
44
452M
        *pdata = ttfont->sfnt->data + offset;
45
452M
    }
46
458M
    return code;
47
458M
}
48
49
static int pdfi_cidtype2_CIDMap_proc(gs_font_cid2 *pfont, gs_glyph glyph)
50
1.06M
{
51
1.06M
    pdf_cidfont_type2 *pdffont11 = (pdf_cidfont_type2 *)pfont->client_data;
52
1.06M
    uint gid = glyph - GS_MIN_CID_GLYPH;
53
1.06M
    int code = 0;
54
55
1.06M
    if (pdffont11->substitute == true) {
56
519k
        unsigned int ucc = 0;
57
519k
        int code = pfont->procs.decode_glyph((gs_font *)pfont, glyph, -1, NULL, 0);
58
519k
        if (code == 2) {
59
2.76k
            uchar sccode[2] = {0};
60
2.76k
            (void)pfont->procs.decode_glyph((gs_font *)pfont, glyph, -1, (ushort *)&sccode, 2);
61
2.76k
            ucc = (sccode[0] << 8) + sccode[1];
62
2.76k
        }
63
516k
        else if (code == 4) {
64
0
            uchar iccode[4] = {0};
65
0
            (void)pfont->procs.decode_glyph((gs_font *)pfont, glyph, -1, (ushort *)&iccode, 2);
66
0
            ucc = (iccode[0] << 24) + (iccode[1] << 16) + (iccode[2] << 8) + iccode[3];
67
68
0
        }
69
519k
        if (code == 2 || code == 4) {
70
2.76k
            code = pdfi_fapi_check_cmap_for_GID((gs_font *)pfont, (unsigned int)ucc, &gid);
71
2.76k
            if (code < 0 || gid == 0)
72
3
                gid = glyph - GS_MIN_CID_GLYPH;
73
2.76k
        }
74
519k
    }
75
76
1.06M
    if (code == 0 && pdffont11->cidtogidmap != NULL && pdffont11->cidtogidmap->length > (gid << 1) + 1) {
77
532k
       gid = pdffont11->cidtogidmap->data[gid << 1] << 8 | pdffont11->cidtogidmap->data[(gid << 1) + 1];
78
532k
    }
79
80
1.06M
    return (int)gid;
81
1.06M
}
82
83
static uint pdfi_cidtype2_get_glyph_index(gs_font_type42 *pfont, gs_glyph glyph)
84
1.93M
{
85
1.93M
    pdf_cidfont_type2 *pdffont11 = (pdf_cidfont_type2 *)pfont->client_data;
86
1.93M
    uint gid = glyph - GS_MIN_CID_GLYPH;
87
1.93M
    int code = 0;
88
89
1.93M
    if (glyph < GS_MIN_CID_GLYPH) {
90
0
        gid = 0;
91
0
    }
92
1.93M
    else {
93
1.93M
        if (glyph < GS_MIN_GLYPH_INDEX) {
94
1.92M
            if (pdffont11->substitute == true) {
95
934k
                unsigned int ucc = 0;
96
934k
                code = pfont->procs.decode_glyph((gs_font *)pfont, glyph, -1, NULL, 0);
97
934k
                if (code == 2) {
98
6.46k
                    uchar sccode[2] = {0};
99
6.46k
                    (void)pfont->procs.decode_glyph((gs_font *)pfont, glyph, -1, (ushort *)&sccode, 2);
100
6.46k
                    ucc = (sccode[0] << 8) + sccode[1];
101
6.46k
                }
102
927k
                else if (code == 4) {
103
0
                    uchar iccode[4] = {0};
104
0
                    (void)pfont->procs.decode_glyph((gs_font *)pfont, glyph, -1, (ushort *)&iccode, 2);
105
0
                    ucc = (iccode[0] << 24) + (iccode[1] << 16) + (iccode[2] << 8) + iccode[3];
106
107
0
                }
108
934k
                if (code == 2 || code == 4) {
109
6.46k
                    code = pdfi_fapi_check_cmap_for_GID((gs_font *)pfont, (unsigned int)ucc, &gid);
110
6.46k
                    if (code < 0 || gid == 0)
111
8
                        gid = glyph - GS_MIN_CID_GLYPH;
112
6.46k
                }
113
934k
            }
114
115
1.92M
            if (code == 0 && pdffont11->cidtogidmap != NULL && pdffont11->cidtogidmap->length > (gid << 1) + 1) {
116
944k
               gid = pdffont11->cidtogidmap->data[gid << 1] << 8 | pdffont11->cidtogidmap->data[(gid << 1) + 1];
117
944k
            }
118
1.92M
        }
119
1.93M
    }
120
121
1.93M
    return gid;
122
1.93M
}
123
124
static int
125
pdfi_cidtype2_glyph_info(gs_font *font, gs_glyph glyph, const gs_matrix *pmat,
126
                     int members, gs_glyph_info_t *info)
127
1.23M
{
128
1.23M
    int code;
129
1.23M
    pdf_cidfont_type2 *pdffont11 = (pdf_cidfont_type2 *)font->client_data;
130
1.23M
    int submembers = members & ~(GLYPH_INFO_WIDTHS | GLYPH_INFO_VVECTOR0 | GLYPH_INFO_VVECTOR1 | GLYPH_INFO_CDEVPROC);
131
132
    /* Call with the values we should get below removed from the "members" request */
133
1.23M
    code = (*pdffont11->orig_glyph_info)(font, glyph, pmat, submembers, info);
134
135
1.23M
    if (code >= 0 && (members & GLYPH_INFO_WIDTHS) != 0
136
1.23M
      && glyph > GS_MIN_CID_GLYPH
137
1.23M
      && glyph < GS_MIN_GLYPH_INDEX) {
138
1.06M
        double widths[6] = {0};
139
1.06M
        code = pdfi_get_cidfont_glyph_metrics(font, (glyph - GS_MIN_CID_GLYPH), widths, true);
140
1.06M
        if (code < 0) {
141
             /* If we couldn't get values back from W/W2, give up, and fill everything in from glyph_info */
142
1.03k
             code = (*pdffont11->orig_glyph_info)(font, glyph, pmat, members, info);
143
1.03k
        }
144
1.06M
        else {
145
1.06M
            if (pmat == NULL) {
146
719k
                info->width[0].x = widths[GLYPH_W0_WIDTH_INDEX] / 1000.0;
147
719k
                info->width[0].y = widths[GLYPH_W0_HEIGHT_INDEX] / 1000.0;
148
719k
            }
149
340k
            else {
150
340k
                code = gs_point_transform(widths[GLYPH_W0_WIDTH_INDEX] / 1000.0, widths[GLYPH_W0_HEIGHT_INDEX] / 1000.0, pmat, &info->width[0]);
151
340k
                if (code < 0)
152
0
                    return code;
153
340k
            }
154
1.06M
            info->members |= GLYPH_INFO_WIDTH0;
155
156
1.06M
            if ((members & GLYPH_INFO_WIDTH1) != 0
157
1.06M
                && (widths[GLYPH_W1_WIDTH_INDEX] != 0
158
288
                || widths[GLYPH_W1_HEIGHT_INDEX] != 0)) {
159
288
                if (pmat == NULL) {
160
288
                    info->width[1].x = widths[GLYPH_W1_WIDTH_INDEX] / 1000.0;
161
288
                    info->width[1].y = widths[GLYPH_W1_HEIGHT_INDEX] / 1000.0;
162
288
                }
163
0
                else {
164
0
                    code = gs_point_transform(widths[GLYPH_W1_WIDTH_INDEX] / 1000.0, widths[GLYPH_W1_HEIGHT_INDEX] / 1000.0, pmat, &info->width[1]);
165
0
                    if (code < 0)
166
0
                        return code;
167
0
                }
168
288
                info->members |= GLYPH_INFO_WIDTH1;
169
288
            }
170
1.06M
            if ((members & GLYPH_INFO_VVECTOR1) != 0) {
171
288
                if (pmat == NULL) {
172
288
                    info->v.x = widths[GLYPH_W1_V_X_INDEX] / 1000.0;
173
288
                    info->v.y = widths[GLYPH_W1_V_Y_INDEX] / 1000.0;
174
288
                }
175
0
                else {
176
0
                    code = gs_point_transform(widths[GLYPH_W1_V_X_INDEX] / 1000.0, widths[GLYPH_W1_V_Y_INDEX] / 1000.0, pmat, &info->v);
177
0
                    if (code < 0)
178
0
                        return code;
179
0
                }
180
288
                info->members |= GLYPH_INFO_VVECTOR1;
181
288
            }
182
1.06M
        }
183
1.06M
    }
184
185
1.23M
    return code;
186
1.23M
}
187
188
static int
189
pdfi_cidtype2_enumerate_glyph(gs_font *font, int *pindex,
190
                         gs_glyph_space_t glyph_space, gs_glyph *pglyph)
191
19.8M
{
192
19.8M
    int code = 0;
193
19.8M
    gs_font_cid2 *cid2 = (gs_font_cid2 *)font;
194
19.8M
    pdf_cidfont_type2 *pdffont11 = (pdf_cidfont_type2 *)font->client_data;
195
19.8M
    *pglyph = 0;
196
197
19.8M
    if (*pindex <= 0)
198
5.92k
        *pindex = 0;
199
200
19.8M
    if (pdffont11->cidtogidmap != NULL && pdffont11->cidtogidmap->length > 0) {
201
64.6M
        do {
202
64.6M
            *pglyph = pdffont11->cidtogidmap->data[(*pindex) << 1] << 8 | pdffont11->cidtogidmap->data[((*pindex) << 1) + 1];
203
64.6M
            (*pindex)++;
204
64.6M
            if (*pglyph == 0 && *pindex == 1) /* notdef - special case */
205
1.97k
                break;
206
64.6M
        } while (*pglyph == 0 && ((*pindex) << 1) < pdffont11->cidtogidmap->length);
207
208
19.8M
        if (((*pindex) << 1) >= pdffont11->cidtogidmap->length) {
209
1.11k
            *pindex = 0;
210
1.11k
        }
211
19.8M
        else {
212
19.8M
            if (*pglyph != 0 || (*pglyph == 0 && *pindex == 1)) {
213
19.8M
                if (glyph_space == GLYPH_SPACE_INDEX) {
214
0
                    *pglyph += GS_MIN_GLYPH_INDEX;
215
0
                }
216
19.8M
                else {
217
19.8M
                    *pglyph = (*pindex) + GS_MIN_CID_GLYPH;
218
19.8M
                }
219
19.8M
            }
220
19.8M
        }
221
19.8M
    }
222
3.94k
    else {
223
3.94k
        if (*pindex < cid2->cidata.common.CIDCount) {
224
3.94k
           if (glyph_space == GLYPH_SPACE_INDEX) {
225
0
               *pglyph = *pindex + GS_MIN_GLYPH_INDEX;
226
0
           }
227
3.94k
           else {
228
3.94k
               *pglyph = (*pindex) + GS_MIN_CID_GLYPH;
229
3.94k
           }
230
3.94k
        }
231
0
        else {
232
0
            *pindex = 0;
233
0
        }
234
3.94k
    }
235
236
0
    return code;
237
19.8M
}
238
239
static void pdfi_set_cidtype2_custom_procs(pdf_cidfont_type2 *pdfttfont)
240
15.4k
{
241
15.4k
    gs_font_type42 *pfont = (gs_font_type42 *)pdfttfont->pfont;
242
15.4k
    pdfttfont->default_font_info = pfont->procs.font_info;
243
15.4k
    pfont->procs.font_info = pdfi_default_font_info;
244
15.4k
}
245
246
static int
247
pdfi_alloc_cidtype2_font(pdf_context *ctx, pdf_cidfont_type2 **font, bool is_cid)
248
17.8k
{
249
17.8k
    pdf_cidfont_type2 *ttfont = NULL;
250
17.8k
    gs_font_cid2 *pfont = NULL;
251
252
17.8k
    ttfont = (pdf_cidfont_type2 *)gs_alloc_bytes(ctx->memory, sizeof(pdf_cidfont_type2), "pdfi (cidtype2 pdf_font)");
253
17.8k
    if (ttfont == NULL)
254
0
        return_error(gs_error_VMerror);
255
256
17.8k
    memset(ttfont, 0x00, sizeof(pdf_cidfont_type2));
257
17.8k
    ttfont->type = PDF_FONT;
258
17.8k
    ttfont->ctx = ctx;
259
17.8k
    ttfont->pdfi_font_type = e_pdf_cidfont_type2;
260
261
#if REFCNT_DEBUG
262
    ttfont->UID = ctx->UID++;
263
    outprintf(ctx->memory, "Allocated object of type %c with UID %"PRIi64"\n", ttfont->type, ttfont->UID);
264
#endif
265
266
17.8k
    pdfi_countup(ttfont);
267
268
17.8k
    pfont = (gs_font_cid2 *)gs_alloc_struct(ctx->memory, gs_font_cid2, &st_gs_font_cid2,
269
17.8k
                            "pdfi (cidtype2 pfont)");
270
17.8k
    if (pfont == NULL) {
271
0
        pdfi_countdown(ttfont);
272
0
        return_error(gs_error_VMerror);
273
0
    }
274
17.8k
    memset(pfont, 0x00, sizeof(gs_font_cid2));
275
276
17.8k
    ttfont->pfont = (gs_font_base *)pfont;
277
278
17.8k
    gs_make_identity(&pfont->orig_FontMatrix);
279
17.8k
    gs_make_identity(&pfont->FontMatrix);
280
17.8k
    pfont->next = pfont->prev = 0;
281
17.8k
    pfont->memory = ctx->memory;
282
17.8k
    pfont->dir = ctx->font_dir;
283
17.8k
    pfont->is_resource = false;
284
17.8k
    gs_notify_init(&pfont->notify_list, ctx->memory);
285
17.8k
    pfont->base = (gs_font *) ttfont->pfont;
286
17.8k
    pfont->client_data = ttfont;
287
17.8k
    pfont->WMode = 0;
288
17.8k
    pfont->PaintType = 0;
289
17.8k
    pfont->StrokeWidth = 0;
290
17.8k
    pfont->is_cached = 0;
291
17.8k
    pfont->FAPI = NULL;
292
17.8k
    pfont->FAPI_font_data = NULL;
293
17.8k
    pfont->procs.init_fstack = gs_default_init_fstack;
294
17.8k
    pfont->procs.next_char_glyph = gs_default_next_char_glyph;
295
17.8k
    pfont->FontType = ft_CID_TrueType;
296
17.8k
    pfont->ExactSize = fbit_use_outlines;
297
17.8k
    pfont->InBetweenSize = fbit_use_outlines;
298
17.8k
    pfont->TransformedChar = fbit_use_outlines;
299
    /* We may want to do something clever with an XUID here */
300
17.8k
    pfont->id = gs_next_ids(ctx->memory, 1);
301
17.8k
    uid_set_UniqueID(&pfont->UID, pfont->id);
302
    /* The buildchar proc will be filled in by FAPI -
303
       we won't worry about working without FAPI */
304
17.8k
    pfont->procs.encode_char = pdfi_encode_char;
305
17.8k
    pfont->data.string_proc = pdfi_cidtype2_string_proc;
306
17.8k
    pfont->procs.glyph_name = ctx->get_glyph_name;
307
17.8k
    pfont->procs.decode_glyph = pdfi_cidfont_decode_glyph;
308
17.8k
    pfont->procs.define_font = gs_no_define_font;
309
17.8k
    pfont->procs.make_font = gs_no_make_font;
310
311
17.8k
    ttfont->default_font_info = gs_default_font_info;
312
17.8k
    pfont->procs.font_info = pdfi_default_font_info;
313
314
17.8k
    pfont->procs.glyph_info = gs_default_glyph_info;
315
17.8k
    pfont->procs.glyph_outline = gs_no_glyph_outline;
316
17.8k
    pfont->procs.build_char = NULL;
317
17.8k
    pfont->procs.same_font = gs_default_same_font;
318
17.8k
    pfont->procs.enumerate_glyph = gs_no_enumerate_glyph;
319
320
17.8k
    pfont->encoding_index = ENCODING_INDEX_UNKNOWN;
321
17.8k
    pfont->nearest_encoding_index = ENCODING_INDEX_UNKNOWN;
322
323
17.8k
    cid_system_info_set_null(&pfont->cidata.common.CIDSystemInfo);
324
17.8k
    pfont->cidata.common.CIDCount = 0; /* set later */
325
17.8k
    pfont->cidata.common.GDBytes = 2; /* not used */
326
17.8k
    pfont->cidata.MetricsCount = 0;
327
17.8k
    pfont->cidata.CIDMap_proc = pdfi_cidtype2_CIDMap_proc;
328
329
17.8k
    pfont->client_data = (void *)ttfont;
330
331
17.8k
    *font = ttfont;
332
17.8k
    return 0;
333
17.8k
}
334
335
int pdfi_read_cidtype2_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 **ppfont)
336
26.2k
{
337
26.2k
    pdf_cidfont_type2 *font;
338
26.2k
    int code = 0;
339
26.2k
    pdf_obj *fontdesc = NULL;
340
26.2k
    pdf_obj *obj = NULL;
341
26.2k
    gs_font_cid2 *cid2;
342
343
26.2k
    if (ppfont == NULL)
344
0
        return_error(gs_error_invalidaccess);
345
346
26.2k
    *ppfont = NULL;
347
348
26.2k
    code = pdfi_dict_knownget_type(ctx, font_dict, "FontDescriptor", PDF_DICT, &fontdesc);
349
26.2k
    if (code <= 0) {
350
        /* We own the buffer now, so we must free it on error */
351
8.44k
        gs_free_object(ctx->memory, buf, "pdfi_read_cidtype2_font");
352
8.44k
        return_error(gs_error_invalidfont);
353
8.44k
    }
354
355
17.8k
    if ((code = pdfi_alloc_cidtype2_font(ctx, &font, false)) < 0) {
356
        /* We own the buffer now, so we must free it on error */
357
0
        gs_free_object(ctx->memory, buf, "pdfi_read_cidtype2_font");
358
0
        pdfi_countdown(fontdesc);
359
0
        return code;
360
0
    }
361
17.8k
    font->PDF_font = font_dict;
362
17.8k
    pdfi_countup(font_dict);
363
17.8k
    font->object_num = font_dict->object_num;
364
17.8k
    font->generation_num = font_dict->generation_num;
365
17.8k
    font->indirect_num = font_dict->indirect_num;
366
17.8k
    font->indirect_gen = font_dict->indirect_gen;
367
368
17.8k
    font->FontDescriptor = (pdf_dict *)fontdesc;
369
17.8k
    fontdesc = NULL;
370
371
17.8k
    code = pdfi_object_alloc(ctx, PDF_BUFFER, 0, (pdf_obj **)&font->sfnt);
372
17.8k
    if (code < 0) {
373
0
        goto error;
374
0
    }
375
17.8k
    pdfi_countup(font->sfnt);
376
17.8k
    code = pdfi_buffer_set_data((pdf_obj *)font->sfnt, buf, buflen);
377
17.8k
    if (code < 0) {
378
0
        goto error;
379
0
    }
380
17.8k
    buf = NULL;
381
382
    /* Strictly speaking BaseFont is required, but we can continue without one */
383
17.8k
    code = pdfi_dict_knownget_type(ctx, font_dict, "BaseFont", PDF_NAME, (pdf_obj **)&obj);
384
17.8k
    if (code > 0) {
385
17.6k
        pdf_name *nobj = (pdf_name *)obj;
386
17.6k
        int nlen = nobj->length > gs_font_name_max ? gs_font_name_max : nobj->length;
387
388
17.6k
        memcpy(font->pfont->key_name.chars, nobj->data, nlen);
389
17.6k
        font->pfont->key_name.chars[nlen] = 0;
390
17.6k
        font->pfont->key_name.size = nlen;
391
17.6k
        memcpy(font->pfont->font_name.chars, nobj->data, nlen);
392
17.6k
        font->pfont->font_name.chars[nlen] = 0;
393
17.6k
        font->pfont->font_name.size = nlen;
394
17.6k
        pdfi_countdown(obj);
395
17.6k
        obj = NULL;
396
17.6k
    }
397
398
17.8k
    code = pdfi_dict_knownget_number(ctx, font_dict, "DW", &font->DW);
399
17.8k
    if (code <= 0) {
400
3.63k
        font->DW = 1000;
401
3.63k
    }
402
403
17.8k
    code = pdfi_dict_knownget_type(ctx, font_dict, "DW2", PDF_ARRAY, (pdf_obj **)&obj);
404
17.8k
    if (code > 0) {
405
130
        font->DW2 = (pdf_array *)obj;
406
130
        obj = NULL;
407
130
    }
408
17.7k
    else {
409
17.7k
        font->DW2 = NULL;
410
17.7k
    }
411
17.8k
    code = pdfi_dict_knownget_type(ctx, font_dict, "W", PDF_ARRAY, (pdf_obj **)&obj);
412
17.8k
    if (code > 0) {
413
14.6k
        font->W = (pdf_array *)obj;
414
14.6k
        obj = NULL;
415
14.6k
    }
416
3.15k
    else {
417
3.15k
        font->W = NULL;
418
3.15k
    }
419
17.8k
    code = pdfi_dict_knownget_type(ctx, font_dict, "W2", PDF_ARRAY, (pdf_obj **)&obj);
420
17.8k
    if (code > 0) {
421
0
        font->W2 = (pdf_array *)obj;
422
0
        obj = NULL;
423
0
    }
424
17.8k
    else {
425
17.8k
        font->W2 = NULL;
426
17.8k
    }
427
428
17.8k
    code = pdfi_dict_knownget(ctx, font_dict, "CIDToGIDMap", (pdf_obj **)&obj);
429
17.8k
    if (code > 0) {
430
        /* CIDToGIDMap can only be a stream or a name, and if it's a name
431
           it's only permitted to be "/Identity", so ignore it
432
         */
433
11.9k
        if (pdfi_type_of(obj) == PDF_STREAM) {
434
2.11k
            byte *d;
435
2.11k
            int64_t sz = 0;
436
437
2.11k
            code = pdfi_object_alloc(ctx, PDF_BUFFER, 0, (pdf_obj **)&font->cidtogidmap);
438
2.11k
            if (code < 0) {
439
0
                goto error;
440
0
            }
441
2.11k
            pdfi_countup(font->cidtogidmap);
442
2.11k
            code = pdfi_stream_to_buffer(ctx, (pdf_stream *)obj, &d, &sz);
443
2.11k
            if (code < 0) {
444
12
                goto error;
445
12
            }
446
2.10k
            code = pdfi_buffer_set_data((pdf_obj *)font->cidtogidmap, d, (int32_t)sz);
447
2.10k
            if (code < 0) {
448
0
                goto error;
449
0
            }
450
2.10k
        }
451
11.9k
        pdfi_countdown(obj);
452
11.9k
        obj = NULL;
453
11.9k
    }
454
455
17.8k
    cid2 = (gs_font_cid2 *)font->pfont;
456
457
17.8k
    code = pdfi_dict_knownget_type(ctx, font_dict, "CIDSystemInfo", PDF_DICT, (pdf_obj **)&obj);
458
17.8k
    if (code <= 0) {
459
1.63k
        cid2->cidata.common.CIDSystemInfo.Registry.data = NULL;
460
1.63k
        cid2->cidata.common.CIDSystemInfo.Registry.size = 0;
461
1.63k
        cid2->cidata.common.CIDSystemInfo.Ordering.data = NULL;
462
1.63k
        cid2->cidata.common.CIDSystemInfo.Ordering.size = 0;
463
1.63k
    }
464
16.1k
    else {
465
16.1k
        pdf_num *suppl = NULL;
466
467
16.1k
        code = pdfi_dict_knownget_type(ctx, (pdf_dict *)obj, "Registry", PDF_STRING, (pdf_obj **)&font->registry);
468
16.1k
        if (code <= 0) {
469
29
            cid2->cidata.common.CIDSystemInfo.Registry.data = NULL;
470
29
            cid2->cidata.common.CIDSystemInfo.Registry.size = 0;
471
29
        }
472
16.1k
        else {
473
16.1k
            cid2->cidata.common.CIDSystemInfo.Registry.data = font->registry->data;
474
16.1k
            cid2->cidata.common.CIDSystemInfo.Registry.size = font->registry->length;
475
16.1k
        }
476
16.1k
        code = pdfi_dict_knownget_type(ctx, (pdf_dict *)obj, "Ordering", PDF_STRING, (pdf_obj **)&font->ordering);
477
16.1k
        if (code <= 0) {
478
26
            cid2->cidata.common.CIDSystemInfo.Ordering.data = NULL;
479
26
            cid2->cidata.common.CIDSystemInfo.Ordering.size = 0;
480
26
        }
481
16.1k
        else {
482
16.1k
            cid2->cidata.common.CIDSystemInfo.Ordering.data = font->ordering->data;
483
16.1k
            cid2->cidata.common.CIDSystemInfo.Ordering.size = font->ordering->length;
484
16.1k
        }
485
16.1k
        code = pdfi_dict_knownget_type(ctx, (pdf_dict *)obj, "Supplement", PDF_INT, (pdf_obj **)&suppl);
486
16.1k
        if (code <= 0) {
487
119
            cid2->cidata.common.CIDSystemInfo.Supplement = font->supplement = 0;
488
119
        }
489
16.0k
        else {
490
16.0k
            cid2->cidata.common.CIDSystemInfo.Supplement = font->supplement = suppl->value.i;
491
16.0k
        }
492
16.1k
        pdfi_countdown(suppl);
493
16.1k
    }
494
17.8k
    pdfi_countdown(obj);
495
17.8k
    obj = NULL;
496
497
498
17.8k
    code = gs_type42_font_init((gs_font_type42 *)font->pfont, findex);
499
17.8k
    if (code < 0) {
500
2.40k
        goto error;
501
2.40k
    }
502
15.4k
    pdfi_set_cidtype2_custom_procs(font);
503
504
15.4k
    if (uid_is_XUID(&font->pfont->UID))
505
15.4k
        uid_free(&font->pfont->UID, font->pfont->memory, "pdfi_read_type1_font");
506
15.4k
    uid_set_invalid(&font->pfont->UID);
507
15.4k
    font->pfont->id = gs_next_ids(ctx->memory, 1);
508
509
15.4k
    code = pdfi_font_generate_pseudo_XUID(ctx, font_dict, font->pfont);
510
15.4k
    if (code < 0)
511
0
        goto error;
512
513
514
15.4k
    font->orig_glyph_info = font->pfont->procs.glyph_info;
515
15.4k
    font->pfont->procs.glyph_info = pdfi_cidtype2_glyph_info;
516
15.4k
    font->pfont->procs.enumerate_glyph = pdfi_cidtype2_enumerate_glyph;
517
518
15.4k
    if (font->cidtogidmap != NULL) {
519
1.86k
        gs_font_cid2 *cid2 = (gs_font_cid2 *)font->pfont;
520
1.86k
        if (cid2->data.numGlyphs > font->cidtogidmap->length >> 1)
521
500
            cid2->cidata.common.CIDCount = cid2->data.numGlyphs;
522
1.36k
        else {
523
1.36k
            cid2->cidata.common.CIDCount = font->cidtogidmap->length >> 1;
524
1.36k
        }
525
1.86k
        cid2->cidata.common.MaxCID = cid2->cidata.common.CIDCount;
526
1.86k
    }
527
13.5k
    else {
528
13.5k
        gs_font_cid2 *cid2 = (gs_font_cid2 *)font->pfont;
529
13.5k
        cid2->cidata.common.CIDCount = cid2->data.numGlyphs;
530
13.5k
        cid2->cidata.common.MaxCID = cid2->cidata.common.CIDCount;
531
13.5k
    }
532
15.4k
    cid2->data.substitute_glyph_index_vertical = gs_type42_substitute_glyph_index_vertical;
533
15.4k
    cid2->cidata.orig_procs.get_outline = cid2->data.get_outline;
534
15.4k
    cid2->data.get_glyph_index = pdfi_cidtype2_get_glyph_index;
535
536
15.4k
    pdfi_font_set_orig_fonttype(ctx, (pdf_font *)font);
537
15.4k
    code = gs_definefont(ctx->font_dir, (gs_font *)font->pfont);
538
15.4k
    if (code < 0) {
539
0
        goto error;
540
0
    }
541
542
15.4k
    code = pdfi_fapi_passfont((pdf_font *)font, findex, NULL, NULL, font->sfnt->data, font->sfnt->length);
543
15.4k
    if (code < 0) {
544
499
        goto error;
545
499
    }
546
547
    /* object_num can be zero if the dictionary was defined inline */
548
14.9k
    if (font->object_num != 0) {
549
14.0k
        (void)replace_cache_entry(ctx, (pdf_obj *)font);
550
14.0k
    }
551
552
14.9k
    *ppfont = (pdf_font *)font;
553
14.9k
    return code;
554
2.92k
error:
555
2.92k
    pdfi_countdown(obj);
556
2.92k
    obj = NULL;
557
2.92k
    if (pdfi_dict_get(ctx, font_dict, ".Path", &obj) >= 0)
558
0
    {
559
0
        char fname[gp_file_name_sizeof + 1];
560
0
        pdf_string *fobj = (pdf_string *)obj;
561
562
0
        memcpy(fname, fobj->data, fobj->length > gp_file_name_sizeof ? gp_file_name_sizeof : fobj->length);
563
0
        fname[fobj->length > gp_file_name_sizeof ? gp_file_name_sizeof : fobj->length] = '\0';
564
565
0
        (void)pdfi_set_error_var(ctx, code, NULL, E_PDF_BADSTREAM, "pdfi_read_cidtype2_font", "Error reading CIDType2/TrueType font file %s\n", fname);
566
0
    }
567
2.92k
    else {
568
2.92k
        (void)pdfi_set_error_var(ctx, code, NULL, E_PDF_BADSTREAM, "pdfi_read_cidtype2_font", "Error reading embedded CIDType2/TrueType font object %u\n", font_dict->object_num);
569
2.92k
    }
570
571
2.92k
    pdfi_countdown(obj);
572
2.92k
    pdfi_countdown(font);
573
2.92k
    return code;
574
15.4k
}
575
576
int pdfi_free_font_cidtype2(pdf_obj *font)
577
17.8k
{
578
17.8k
    pdf_cidfont_type2 *pdfcidf = (pdf_cidfont_type2 *)font;
579
17.8k
    gs_font_cid2 *pfont = (gs_font_cid2 *)pdfcidf->pfont;
580
17.8k
    gs_free_object(OBJ_MEMORY(pdfcidf), pfont, "pdfi_free_font_cidtype2(pfont)");
581
582
17.8k
    pdfi_countdown(pdfcidf->cidtogidmap);
583
584
17.8k
    pdfi_countdown(pdfcidf->sfnt);
585
17.8k
    pdfi_countdown(pdfcidf->PDF_font);
586
17.8k
    pdfi_countdown(pdfcidf->BaseFont);
587
17.8k
    pdfi_countdown(pdfcidf->FontDescriptor);
588
17.8k
    pdfi_countdown(pdfcidf->W);
589
17.8k
    pdfi_countdown(pdfcidf->DW2);
590
17.8k
    pdfi_countdown(pdfcidf->W2);
591
17.8k
    pdfi_countdown(pdfcidf->registry);
592
17.8k
    pdfi_countdown(pdfcidf->ordering);
593
17.8k
    pdfi_countdown(pdfcidf->filename);
594
17.8k
    pdfi_countdown(pdfcidf->copyright);
595
17.8k
    pdfi_countdown(pdfcidf->notice);
596
17.8k
    pdfi_countdown(pdfcidf->fullname);
597
17.8k
    pdfi_countdown(pdfcidf->familyname);
598
599
17.8k
    gs_free_object(OBJ_MEMORY(pdfcidf), pdfcidf, "pdfi_free_font_cidtype2(pdfcidf)");
600
17.8k
return 0;
601
602
0
    return 0;
603
17.8k
}