Coverage Report

Created: 2022-10-31 07:00

/src/ghostpdl/pdf/pdf_font11.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2020-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
/* 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
93.8M
{
36
93.8M
    pdf_cidfont_type2 *ttfont = (pdf_cidfont_type2 *)pfont->client_data;
37
93.8M
    int code = 0;
38
39
93.8M
    if (offset + length > ttfont->sfnt->length) {
40
730k
        *pdata = NULL;
41
730k
        code = gs_note_error(gs_error_invalidfont);
42
730k
    }
43
93.0M
    else {
44
93.0M
        *pdata = ttfont->sfnt->data + offset;
45
93.0M
    }
46
93.8M
    return code;
47
93.8M
}
48
49
static int pdfi_cidtype2_CIDMap_proc(gs_font_cid2 *pfont, gs_glyph glyph)
50
74.8k
{
51
74.8k
    pdf_cidfont_type2 *pdffont11 = (pdf_cidfont_type2 *)pfont->client_data;
52
74.8k
    uint gid = glyph - GS_MIN_CID_GLYPH;
53
54
74.8k
    if (pdffont11->cidtogidmap != NULL && pdffont11->cidtogidmap->length > (gid << 1) + 1) {
55
25.7k
        gid = pdffont11->cidtogidmap->data[gid << 1] << 8 | pdffont11->cidtogidmap->data[(gid << 1) + 1];
56
25.7k
    }
57
58
74.8k
    return (int)gid;
59
74.8k
}
60
61
static uint pdfi_cidtype2_get_glyph_index(gs_font_type42 *pfont, gs_glyph glyph)
62
238k
{
63
238k
    pdf_cidfont_type2 *pdffont11 = (pdf_cidfont_type2 *)pfont->client_data;
64
238k
    uint gid = 0;
65
66
238k
    if (glyph < GS_MIN_CID_GLYPH) {
67
0
        gid = 0;
68
0
    }
69
238k
    else {
70
238k
        if (glyph < GS_MIN_GLYPH_INDEX) {
71
237k
            gid = glyph - GS_MIN_CID_GLYPH;
72
237k
            if (pdffont11->cidtogidmap != NULL && pdffont11->cidtogidmap->length > (gid << 1) + 1) {
73
83.5k
                gid = pdffont11->cidtogidmap->data[gid << 1] << 8 | pdffont11->cidtogidmap->data[(gid << 1) + 1];
74
83.5k
            }
75
237k
        }
76
238k
    }
77
78
238k
    return gid;
79
238k
}
80
81
static int
82
pdfi_cidtype2_glyph_info(gs_font *font, gs_glyph glyph, const gs_matrix *pmat,
83
                     int members, gs_glyph_info_t *info)
84
141k
{
85
141k
    int code;
86
141k
    pdf_cidfont_type2 *pdffont11 = (pdf_cidfont_type2 *)font->client_data;
87
141k
    code = (*pdffont11->orig_glyph_info)(font, glyph, pmat, members, info);
88
141k
    if (code < 0)
89
767
        return code;
90
91
140k
    if ((members & GLYPH_INFO_WIDTHS) != 0
92
140k
      && glyph > GS_MIN_CID_GLYPH
93
140k
      && glyph < GS_MIN_GLYPH_INDEX) {
94
131k
        double widths[6] = {0};
95
131k
        code = pdfi_get_cidfont_glyph_metrics(font, (glyph - GS_MIN_CID_GLYPH), widths, true);
96
131k
        if (code >= 0) {
97
130k
            if (pmat == NULL) {
98
59.3k
                info->width[0].x = widths[GLYPH_W0_WIDTH_INDEX] / 1000.0;
99
59.3k
                info->width[0].y = widths[GLYPH_W0_HEIGHT_INDEX] / 1000.0;
100
59.3k
            }
101
71.6k
            else {
102
71.6k
                code = gs_point_transform(widths[GLYPH_W0_WIDTH_INDEX] / 1000.0, widths[GLYPH_W0_HEIGHT_INDEX] / 1000.0, pmat, &info->width[0]);
103
71.6k
                if (code < 0)
104
0
                    return code;
105
71.6k
            }
106
130k
            info->members |= GLYPH_INFO_WIDTH0;
107
108
130k
            if ((members & GLYPH_INFO_WIDTH1) != 0
109
130k
                && (widths[GLYPH_W1_WIDTH_INDEX] != 0
110
64
                || widths[GLYPH_W1_HEIGHT_INDEX] != 0)) {
111
64
                if (pmat == NULL) {
112
64
                    info->width[1].x = widths[GLYPH_W1_WIDTH_INDEX] / 1000.0;
113
64
                    info->width[1].y = widths[GLYPH_W1_HEIGHT_INDEX] / 1000.0;
114
64
                }
115
0
                else {
116
0
                    code = gs_point_transform(widths[GLYPH_W1_WIDTH_INDEX] / 1000.0, widths[GLYPH_W1_HEIGHT_INDEX] / 1000.0, pmat, &info->width[1]);
117
0
                    if (code < 0)
118
0
                        return code;
119
0
                }
120
64
                info->members |= GLYPH_INFO_WIDTH1;
121
64
            }
122
130k
            if ((members & GLYPH_INFO_VVECTOR1) != 0) {
123
64
                if (pmat == NULL) {
124
64
                    info->v.x = widths[GLYPH_W1_V_X_INDEX] / 1000.0;
125
64
                    info->v.y = widths[GLYPH_W1_V_Y_INDEX] / 1000.0;
126
64
                }
127
0
                else {
128
0
                    code = gs_point_transform(widths[GLYPH_W1_V_X_INDEX] / 1000.0, widths[GLYPH_W1_V_Y_INDEX] / 1000.0, pmat, &info->v);
129
0
                    if (code < 0)
130
0
                        return code;
131
0
                }
132
64
                info->members |= GLYPH_INFO_VVECTOR1;
133
64
            }
134
130k
        }
135
131k
    }
136
140k
    return code;
137
140k
}
138
139
static int
140
pdfi_cidtype2_enumerate_glyph(gs_font *font, int *pindex,
141
                         gs_glyph_space_t glyph_space, gs_glyph *pglyph)
142
55.6k
{
143
55.6k
    int code = 0;
144
55.6k
    gs_font_cid2 *cid2 = (gs_font_cid2 *)font;
145
55.6k
    pdf_cidfont_type2 *pdffont11 = (pdf_cidfont_type2 *)font->client_data;
146
55.6k
    *pglyph = 0;
147
148
55.6k
    if (*pindex <= 0)
149
774
        *pindex = 0;
150
151
55.6k
    if (pdffont11->cidtogidmap != NULL && pdffont11->cidtogidmap->length > 0) {
152
14.9M
        do {
153
14.9M
            *pglyph = pdffont11->cidtogidmap->data[(*pindex) << 1] << 8 | pdffont11->cidtogidmap->data[((*pindex) << 1) + 1];
154
14.9M
            (*pindex)++;
155
14.9M
            if (*pglyph == 0 && *pindex == 1) /* notdef - special case */
156
500
                break;
157
14.9M
        } while (*pglyph == 0 && ((*pindex) << 1) < pdffont11->cidtogidmap->length);
158
159
55.3k
        if (((*pindex) << 1) >= pdffont11->cidtogidmap->length) {
160
278
            *pindex = 0;
161
278
        }
162
55.1k
        else {
163
55.1k
            if (*pglyph != 0 || (*pglyph == 0 && *pindex == 1)) {
164
55.1k
                if (glyph_space == GLYPH_SPACE_INDEX) {
165
0
                    *pglyph += GS_MIN_GLYPH_INDEX;
166
0
                }
167
55.1k
                else {
168
55.1k
                    *pglyph = (*pindex) + GS_MIN_CID_GLYPH;
169
55.1k
                }
170
55.1k
            }
171
55.1k
        }
172
55.3k
    }
173
270
    else {
174
270
        if (*pindex < cid2->cidata.common.CIDCount) {
175
270
           if (glyph_space == GLYPH_SPACE_INDEX) {
176
0
               *pglyph = *pindex + GS_MIN_GLYPH_INDEX;
177
0
           }
178
270
           else {
179
270
               *pglyph = (*pindex) + GS_MIN_CID_GLYPH;
180
270
           }
181
270
        }
182
0
        else {
183
0
            *pindex = 0;
184
0
        }
185
270
    }
186
187
0
    return code;
188
55.6k
}
189
190
static int
191
pdfi_alloc_cidtype2_font(pdf_context *ctx, pdf_cidfont_type2 **font, bool is_cid)
192
3.43k
{
193
3.43k
    pdf_cidfont_type2 *ttfont = NULL;
194
3.43k
    gs_font_cid2 *pfont = NULL;
195
196
3.43k
    ttfont = (pdf_cidfont_type2 *)gs_alloc_bytes(ctx->memory, sizeof(pdf_cidfont_type2), "pdfi (cidtype2 pdf_font)");
197
3.43k
    if (ttfont == NULL)
198
0
        return_error(gs_error_VMerror);
199
200
3.43k
    memset(ttfont, 0x00, sizeof(pdf_cidfont_type2));
201
3.43k
    ttfont->type = PDF_FONT;
202
3.43k
    ttfont->ctx = ctx;
203
3.43k
    ttfont->pdfi_font_type = e_pdf_cidfont_type2;
204
205
#if REFCNT_DEBUG
206
    ttfont->UID = ctx->UID++;
207
    dmprintf2(ctx->memory, "Allocated object of type %c with UID %"PRIi64"\n", ttfont->type, ttfont->UID);
208
#endif
209
210
3.43k
    pdfi_countup(ttfont);
211
212
3.43k
    pfont = (gs_font_cid2 *)gs_alloc_struct(ctx->memory, gs_font_cid2, &st_gs_font_cid2,
213
3.43k
                            "pdfi (cidtype2 pfont)");
214
3.43k
    if (pfont == NULL) {
215
0
        pdfi_countdown(ttfont);
216
0
        return_error(gs_error_VMerror);
217
0
    }
218
3.43k
    memset(pfont, 0x00, sizeof(gs_font_cid2));
219
220
3.43k
    ttfont->pfont = (gs_font_base *)pfont;
221
222
3.43k
    gs_make_identity(&pfont->orig_FontMatrix);
223
3.43k
    gs_make_identity(&pfont->FontMatrix);
224
3.43k
    pfont->next = pfont->prev = 0;
225
3.43k
    pfont->memory = ctx->memory;
226
3.43k
    pfont->dir = ctx->font_dir;
227
3.43k
    pfont->is_resource = false;
228
3.43k
    gs_notify_init(&pfont->notify_list, ctx->memory);
229
3.43k
    pfont->base = (gs_font *) ttfont->pfont;
230
3.43k
    pfont->client_data = ttfont;
231
3.43k
    pfont->WMode = 0;
232
3.43k
    pfont->PaintType = 0;
233
3.43k
    pfont->StrokeWidth = 0;
234
3.43k
    pfont->is_cached = 0;
235
3.43k
    pfont->FAPI = NULL;
236
3.43k
    pfont->FAPI_font_data = NULL;
237
3.43k
    pfont->procs.init_fstack = gs_default_init_fstack;
238
3.43k
    pfont->procs.next_char_glyph = gs_default_next_char_glyph;
239
3.43k
    pfont->FontType = ft_CID_TrueType;
240
3.43k
    pfont->ExactSize = fbit_use_outlines;
241
3.43k
    pfont->InBetweenSize = fbit_use_outlines;
242
3.43k
    pfont->TransformedChar = fbit_use_outlines;
243
    /* We may want to do something clever with an XUID here */
244
3.43k
    pfont->id = gs_next_ids(ctx->memory, 1);
245
3.43k
    uid_set_UniqueID(&pfont->UID, pfont->id);
246
    /* The buildchar proc will be filled in by FAPI -
247
       we won't worry about working without FAPI */
248
3.43k
    pfont->procs.encode_char = pdfi_encode_char;
249
3.43k
    pfont->data.string_proc = pdfi_cidtype2_string_proc;
250
3.43k
    pfont->procs.glyph_name = ctx->get_glyph_name;
251
3.43k
    pfont->procs.decode_glyph = pdfi_decode_glyph;
252
3.43k
    pfont->procs.define_font = gs_no_define_font;
253
3.43k
    pfont->procs.make_font = gs_no_make_font;
254
3.43k
    pfont->procs.font_info = gs_default_font_info;
255
3.43k
    pfont->procs.glyph_info = gs_default_glyph_info;
256
3.43k
    pfont->procs.glyph_outline = gs_no_glyph_outline;
257
3.43k
    pfont->procs.build_char = NULL;
258
3.43k
    pfont->procs.same_font = gs_default_same_font;
259
3.43k
    pfont->procs.enumerate_glyph = gs_no_enumerate_glyph;
260
261
3.43k
    pfont->encoding_index = 1;          /****** WRONG ******/
262
3.43k
    pfont->nearest_encoding_index = 1;          /****** WRONG ******/
263
264
3.43k
    cid_system_info_set_null(&pfont->cidata.common.CIDSystemInfo);
265
3.43k
    pfont->cidata.common.CIDCount = 0; /* set later */
266
3.43k
    pfont->cidata.common.GDBytes = 2; /* not used */
267
3.43k
    pfont->cidata.MetricsCount = 0;
268
3.43k
    pfont->cidata.CIDMap_proc = pdfi_cidtype2_CIDMap_proc;
269
270
3.43k
    pfont->client_data = (void *)ttfont;
271
272
3.43k
    *font = ttfont;
273
3.43k
    return 0;
274
3.43k
}
275
276
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)
277
4.61k
{
278
4.61k
    pdf_cidfont_type2 *font;
279
4.61k
    int code = 0;
280
4.61k
    pdf_obj *fontdesc = NULL;
281
4.61k
    pdf_obj *obj = NULL;
282
4.61k
    gs_font_cid2 *cid2;
283
284
4.61k
    if (ppfont == NULL)
285
0
        return_error(gs_error_invalidaccess);
286
287
4.61k
    *ppfont = NULL;
288
289
4.61k
    code = pdfi_dict_knownget_type(ctx, font_dict, "FontDescriptor", PDF_DICT, &fontdesc);
290
4.61k
    if (code <= 0) {
291
        /* We own the buffer now, so we must free it on error */
292
1.18k
        gs_free_object(ctx->memory, buf, "pdfi_read_cidtype2_font");
293
1.18k
        return_error(gs_error_invalidfont);
294
1.18k
    }
295
296
3.43k
    if ((code = pdfi_alloc_cidtype2_font(ctx, &font, false)) < 0) {
297
        /* We own the buffer now, so we must free it on error */
298
0
        gs_free_object(ctx->memory, buf, "pdfi_read_cidtype2_font");
299
0
        pdfi_countdown(fontdesc);
300
0
        return code;
301
0
    }
302
3.43k
    font->PDF_font = font_dict;
303
3.43k
    pdfi_countup(font_dict);
304
3.43k
    font->object_num = font_dict->object_num;
305
3.43k
    font->generation_num = font_dict->generation_num;
306
3.43k
    font->indirect_num = font_dict->indirect_num;
307
3.43k
    font->indirect_gen = font_dict->indirect_gen;
308
309
3.43k
    font->FontDescriptor = (pdf_dict *)fontdesc;
310
3.43k
    fontdesc = NULL;
311
312
3.43k
    code = pdfi_object_alloc(ctx, PDF_BUFFER, 0, (pdf_obj **)&font->sfnt);
313
3.43k
    if (code < 0) {
314
0
        goto error;
315
0
    }
316
3.43k
    pdfi_countup(font->sfnt);
317
3.43k
    code = pdfi_buffer_set_data((pdf_obj *)font->sfnt, buf, buflen);
318
3.43k
    if (code < 0) {
319
0
        goto error;
320
0
    }
321
3.43k
    buf = NULL;
322
323
    /* Strictly speaking BaseFont is required, but we can continue without one */
324
3.43k
    code = pdfi_dict_knownget_type(ctx, font_dict, "BaseFont", PDF_NAME, (pdf_obj **)&obj);
325
3.43k
    if (code > 0) {
326
3.42k
        pdf_name *nobj = (pdf_name *)obj;
327
3.42k
        int nlen = nobj->length > gs_font_name_max ? gs_font_name_max : nobj->length;
328
329
3.42k
        memcpy(font->pfont->key_name.chars, nobj->data, nlen);
330
3.42k
        font->pfont->key_name.chars[nlen] = 0;
331
3.42k
        font->pfont->key_name.size = nlen;
332
3.42k
        memcpy(font->pfont->font_name.chars, nobj->data, nlen);
333
3.42k
        font->pfont->font_name.chars[nlen] = 0;
334
3.42k
        font->pfont->font_name.size = nlen;
335
3.42k
        pdfi_countdown(obj);
336
3.42k
        obj = NULL;
337
3.42k
    }
338
339
3.43k
    code = pdfi_dict_knownget_type(ctx, font_dict, "DW", PDF_INT, (pdf_obj **)&obj);
340
3.43k
    if (code > 0) {
341
2.73k
        font->DW = ((pdf_num *)obj)->value.i;
342
2.73k
        pdfi_countdown(obj);
343
2.73k
        obj = NULL;
344
2.73k
    }
345
704
    else {
346
704
        font->DW = 1000;
347
704
    }
348
3.43k
    code = pdfi_dict_knownget_type(ctx, font_dict, "DW2", PDF_ARRAY, (pdf_obj **)&obj);
349
3.43k
    if (code > 0) {
350
7
        font->DW2 = (pdf_array *)obj;
351
7
        obj = NULL;
352
7
    }
353
3.42k
    else {
354
3.42k
        font->DW2 = NULL;
355
3.42k
    }
356
3.43k
    code = pdfi_dict_knownget_type(ctx, font_dict, "W", PDF_ARRAY, (pdf_obj **)&obj);
357
3.43k
    if (code > 0) {
358
3.07k
        font->W = (pdf_array *)obj;
359
3.07k
        obj = NULL;
360
3.07k
    }
361
357
    else {
362
357
        font->W = NULL;
363
357
    }
364
3.43k
    code = pdfi_dict_knownget_type(ctx, font_dict, "W2", PDF_ARRAY, (pdf_obj **)&obj);
365
3.43k
    if (code > 0) {
366
0
        font->W2 = (pdf_array *)obj;
367
0
        obj = NULL;
368
0
    }
369
3.43k
    else {
370
3.43k
        font->W2 = NULL;
371
3.43k
    }
372
373
3.43k
    code = pdfi_dict_knownget(ctx, font_dict, "CIDToGIDMap", (pdf_obj **)&obj);
374
3.43k
    if (code > 0) {
375
        /* CIDToGIDMap can only be a stream or a name, and if it's a name
376
           it's only permitted to be "/Identity", so ignore it
377
         */
378
2.09k
        if (pdfi_type_of(obj) == PDF_STREAM) {
379
509
            byte *d;
380
509
            int64_t sz = 0;
381
382
509
            code = pdfi_object_alloc(ctx, PDF_BUFFER, 0, (pdf_obj **)&font->cidtogidmap);
383
509
            if (code < 0) {
384
0
                goto error;
385
0
            }
386
509
            pdfi_countup(font->cidtogidmap);
387
509
            code = pdfi_stream_to_buffer(ctx, (pdf_stream *)obj, &d, &sz);
388
509
            if (code < 0) {
389
0
                goto error;
390
0
            }
391
509
            code = pdfi_buffer_set_data((pdf_obj *)font->cidtogidmap, d, (int32_t)sz);
392
509
            if (code < 0) {
393
0
                goto error;
394
0
            }
395
509
        }
396
2.09k
        pdfi_countdown(obj);
397
2.09k
        obj = NULL;
398
2.09k
    }
399
400
3.43k
    cid2 = (gs_font_cid2 *)font->pfont;
401
402
3.43k
    code = pdfi_dict_knownget_type(ctx, font_dict, "CIDSystemInfo", PDF_DICT, (pdf_obj **)&obj);
403
3.43k
    if (code <= 0) {
404
9
        cid2->cidata.common.CIDSystemInfo.Registry.data = NULL;
405
9
        cid2->cidata.common.CIDSystemInfo.Registry.size = 0;
406
9
        cid2->cidata.common.CIDSystemInfo.Ordering.data = NULL;
407
9
        cid2->cidata.common.CIDSystemInfo.Ordering.size = 0;
408
9
    }
409
3.42k
    else {
410
3.42k
        pdf_num *suppl = NULL;
411
412
3.42k
        code = pdfi_dict_knownget_type(ctx, (pdf_dict *)obj, "Registry", PDF_STRING, (pdf_obj **)&font->registry);
413
3.42k
        if (code <= 0) {
414
0
            cid2->cidata.common.CIDSystemInfo.Registry.data = NULL;
415
0
            cid2->cidata.common.CIDSystemInfo.Registry.size = 0;
416
0
        }
417
3.42k
        else {
418
3.42k
            cid2->cidata.common.CIDSystemInfo.Registry.data = font->registry->data;
419
3.42k
            cid2->cidata.common.CIDSystemInfo.Registry.size = font->registry->length;
420
3.42k
        }
421
3.42k
        code = pdfi_dict_knownget_type(ctx, (pdf_dict *)obj, "Ordering", PDF_STRING, (pdf_obj **)&font->ordering);
422
3.42k
        if (code <= 0) {
423
1
            cid2->cidata.common.CIDSystemInfo.Ordering.data = NULL;
424
1
            cid2->cidata.common.CIDSystemInfo.Ordering.size = 0;
425
1
        }
426
3.42k
        else {
427
3.42k
            cid2->cidata.common.CIDSystemInfo.Ordering.data = font->ordering->data;
428
3.42k
            cid2->cidata.common.CIDSystemInfo.Ordering.size = font->ordering->length;
429
3.42k
        }
430
3.42k
        code = pdfi_dict_knownget_type(ctx, (pdf_dict *)obj, "Supplement", PDF_INT, (pdf_obj **)&suppl);
431
3.42k
        if (code <= 0) {
432
2
            cid2->cidata.common.CIDSystemInfo.Supplement = font->supplement = 0;
433
2
        }
434
3.42k
        else {
435
3.42k
            cid2->cidata.common.CIDSystemInfo.Supplement = font->supplement = suppl->value.i;
436
3.42k
        }
437
3.42k
        pdfi_countdown(suppl);
438
3.42k
    }
439
3.43k
    pdfi_countdown(obj);
440
3.43k
    obj = NULL;
441
442
443
3.43k
    code = gs_type42_font_init((gs_font_type42 *)font->pfont, 0);
444
3.43k
    if (code < 0) {
445
406
        goto error;
446
406
    }
447
3.02k
    if (uid_is_XUID(&font->pfont->UID))
448
3.02k
        uid_free(&font->pfont->UID, font->pfont->memory, "pdfi_read_type1_font");
449
3.02k
    uid_set_invalid(&font->pfont->UID);
450
3.02k
    font->pfont->id = gs_next_ids(ctx->memory, 1);
451
452
3.02k
    code = pdfi_font_generate_pseudo_XUID(ctx, font_dict, font->pfont);
453
3.02k
    if (code < 0)
454
0
        goto error;
455
456
457
3.02k
    font->orig_glyph_info = font->pfont->procs.glyph_info;
458
3.02k
    font->pfont->procs.glyph_info = pdfi_cidtype2_glyph_info;
459
3.02k
    font->pfont->procs.enumerate_glyph = pdfi_cidtype2_enumerate_glyph;
460
461
3.02k
    if (font->cidtogidmap != NULL) {
462
460
        gs_font_cid2 *cid2 = (gs_font_cid2 *)font->pfont;
463
460
        if (cid2->data.numGlyphs > font->cidtogidmap->length >> 1)
464
88
            cid2->cidata.common.CIDCount = cid2->data.numGlyphs;
465
372
        else {
466
372
            cid2->cidata.common.CIDCount = font->cidtogidmap->length >> 1;
467
372
        }
468
460
        cid2->cidata.common.MaxCID = cid2->cidata.common.CIDCount;
469
460
    }
470
2.56k
    else {
471
2.56k
        gs_font_cid2 *cid2 = (gs_font_cid2 *)font->pfont;
472
2.56k
        cid2->cidata.common.CIDCount = cid2->data.numGlyphs;
473
2.56k
        cid2->cidata.common.MaxCID = cid2->cidata.common.CIDCount;
474
2.56k
    }
475
3.02k
    cid2->data.substitute_glyph_index_vertical = gs_type42_substitute_glyph_index_vertical;
476
3.02k
    cid2->cidata.orig_procs.get_outline = cid2->data.get_outline;
477
3.02k
    cid2->data.get_glyph_index = pdfi_cidtype2_get_glyph_index;
478
479
3.02k
    code = gs_definefont(ctx->font_dir, (gs_font *)font->pfont);
480
3.02k
    if (code < 0) {
481
0
        goto error;
482
0
    }
483
484
3.02k
    code = pdfi_fapi_passfont((pdf_font *)font, 0, NULL, NULL, font->sfnt->data, font->sfnt->length);
485
3.02k
    if (code < 0) {
486
63
        goto error;
487
63
    }
488
489
    /* object_num can be zero if the dictionary was defined inline */
490
2.96k
    if (font->object_num != 0) {
491
2.82k
        (void)replace_cache_entry(ctx, (pdf_obj *)font);
492
2.82k
    }
493
494
2.96k
    *ppfont = (pdf_font *)font;
495
2.96k
    return code;
496
469
error:
497
498
469
    pdfi_countdown(obj);
499
469
    pdfi_countdown(font);
500
469
    return code;
501
3.02k
}
502
503
int pdfi_free_font_cidtype2(pdf_obj *font)
504
3.43k
{
505
3.43k
    pdf_cidfont_type2 *pdfcidf = (pdf_cidfont_type2 *)font;
506
3.43k
    gs_font_cid2 *pfont = (gs_font_cid2 *)pdfcidf->pfont;
507
3.43k
    gs_free_object(OBJ_MEMORY(pdfcidf), pfont, "pdfi_free_font_cidtype2(pfont)");
508
509
3.43k
    pdfi_countdown(pdfcidf->cidtogidmap);
510
511
3.43k
    pdfi_countdown(pdfcidf->sfnt);
512
3.43k
    pdfi_countdown(pdfcidf->PDF_font);
513
3.43k
    pdfi_countdown(pdfcidf->BaseFont);
514
3.43k
    pdfi_countdown(pdfcidf->FontDescriptor);
515
3.43k
    pdfi_countdown(pdfcidf->W);
516
3.43k
    pdfi_countdown(pdfcidf->DW2);
517
3.43k
    pdfi_countdown(pdfcidf->W2);
518
3.43k
    pdfi_countdown(pdfcidf->registry);
519
3.43k
    pdfi_countdown(pdfcidf->ordering);
520
3.43k
    pdfi_countdown(pdfcidf->filename);
521
522
3.43k
    gs_free_object(OBJ_MEMORY(pdfcidf), pdfcidf, "pdfi_free_font_cidtype2(pdfcidf)");
523
3.43k
return 0;
524
525
0
    return 0;
526
3.43k
}