Coverage Report

Created: 2022-10-31 07:00

/src/ghostpdl/pdf/pdf_fontTT.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
/* 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
145M
{
44
145M
    pdf_font_truetype *ttfont = (pdf_font_truetype *)pfont->client_data;
45
145M
    int code = 0;
46
47
145M
    if ((uint64_t)offset + length > ttfont->sfnt->length) {
48
4.26M
        *pdata = NULL;
49
4.26M
        code = gs_note_error(gs_error_invalidfont);
50
4.26M
    }
51
141M
    else {
52
141M
        *pdata = ttfont->sfnt->data + offset;
53
141M
    }
54
145M
    return code;
55
145M
}
56
57
static gs_glyph pdfi_ttf_encode_char(gs_font *pfont, gs_char chr, gs_glyph_space_t sp)
58
6.99M
{
59
6.99M
    pdf_font_truetype *ttfont = (pdf_font_truetype *)pfont->client_data;
60
6.99M
    gs_glyph g = GS_NO_GLYPH;
61
6.99M
    uint ID;
62
6.99M
    int code;
63
64
6.99M
    if ((ttfont->descflags & 4) != 0 || sp == GLYPH_SPACE_INDEX) {
65
491k
        int code = pdfi_fapi_check_cmap_for_GID(pfont, (uint)chr, &ID);
66
491k
        if (code < 0 || ID == 0)
67
173k
            code = pdfi_fapi_check_cmap_for_GID(pfont, (uint)(chr | 0xf0 << 8), &ID);
68
491k
        g = (gs_glyph)ID;
69
491k
    }
70
6.50M
    else {
71
6.50M
        pdf_context *ctx = (pdf_context *)ttfont->ctx;
72
73
6.50M
        if (ttfont->Encoding != NULL) { /* safety */
74
6.50M
            pdf_name *GlyphName = NULL;
75
6.50M
            code = pdfi_array_get(ctx, ttfont->Encoding, (uint64_t)chr, (pdf_obj **)&GlyphName);
76
6.50M
            if (code >= 0) {
77
6.49M
                code = (*ctx->get_glyph_index)(pfont, (byte *)GlyphName->data, GlyphName->length, &ID);
78
6.49M
                pdfi_countdown(GlyphName);
79
6.49M
                if (code >= 0)
80
6.49M
                    g = (gs_glyph)ID;
81
6.49M
            }
82
6.50M
        }
83
6.50M
    }
84
85
6.99M
    return g;
86
6.99M
}
87
88
extern single_glyph_list_t SingleGlyphList[];
89
90
static uint pdfi_type42_get_glyph_index(gs_font_type42 *pfont, gs_glyph glyph)
91
4.65M
{
92
4.65M
    pdf_font_truetype *ttfont = (pdf_font_truetype *)pfont->client_data;
93
4.65M
    uint gind = 0;
94
4.65M
    uint cc = 0;
95
4.65M
    int i, code = 0;
96
97
4.65M
    if ((ttfont->descflags & 4) != 0 || glyph >= GS_MIN_GLYPH_INDEX) {
98
152k
        gind = (uint)glyph < GS_MIN_GLYPH_INDEX ? glyph : glyph - GS_MIN_GLYPH_INDEX;
99
152k
    }
100
4.50M
    else {
101
4.50M
        pdf_context *ctx = (pdf_context *)ttfont->ctx;
102
4.50M
        gs_const_string gname;
103
104
4.50M
        code = (*ctx->get_glyph_name)((gs_font *)pfont, glyph, &gname);
105
4.50M
        if (code < 0 || gname.data == NULL) {
106
0
            return (uint)glyph;
107
0
        }
108
4.50M
        if (gname.size == 7 && gname.data[0] == '.' && strncmp((char *)gname.data, ".notdef", 7) == 0) {
109
456k
            return 0; /* .notdef is GID 0, so short cut the rest of the function */
110
456k
        }
111
112
4.05M
        if (ttfont->cmap == pdfi_truetype_cmap_10) {
113
343k
            gs_string postname = {0};
114
343k
            gs_glyph g;
115
116
343k
            g = gs_c_name_glyph((const byte *)gname.data, gname.size);
117
343k
            if (g != GS_NO_GLYPH) {
118
343k
                g = (gs_glyph)gs_c_decode(g, ENCODING_INDEX_MACROMAN);
119
343k
            }
120
0
            else {
121
0
                g = GS_NO_CHAR;
122
0
            }
123
124
343k
            if (g != GS_NO_CHAR) {
125
342k
                code = pdfi_fapi_check_cmap_for_GID((gs_font *)pfont, (uint)g, &cc);
126
342k
            }
127
128
343k
            if (code < 0 || cc == 0) {
129
                /* This is a very slow implementation, we may benefit from creating a
130
                 * a reverse post table upfront */
131
28.7M
                for (i = 0; i < pfont->data.numGlyphs; i++) {
132
28.4M
                    code = gs_type42_find_post_name(pfont, (gs_glyph)i, &postname);
133
28.4M
                    if (code >= 0) {
134
2.23M
                        if (gname.data[0] == postname.data[0]
135
2.23M
                            && gname.size == postname.size
136
2.23M
                            && !strncmp((char *)gname.data, (char *)postname.data, postname.size))
137
4.62k
                        {
138
4.62k
                            cc = i;
139
4.62k
                            break;
140
4.62k
                        }
141
2.23M
                    }
142
28.4M
                }
143
260k
           }
144
343k
        }
145
3.70M
        else {
146
            /* In theory, this should be 3,1 cmap, but we have examples that use 0,1 or other
147
               Unicode "platform" cmap tables, so "hail mary" just try it
148
             */
149
3.70M
            single_glyph_list_t *sgl = (single_glyph_list_t *)&(SingleGlyphList);
150
            /* Not to spec, but... if we get a "uni..." formatted name, use
151
               the hex value from that.
152
             */
153
3.70M
            if (gname.size > 5 && !strncmp((char *)gname.data, "uni", 3)) {
154
8.37k
                char gnbuf[64];
155
8.37k
                int l = (gname.size - 3) > 63 ? 63 : gname.size - 3;
156
157
8.37k
                memcpy(gnbuf, gname.data + 3, l);
158
8.37k
                gnbuf[l] = '\0';
159
8.37k
                l = sscanf(gnbuf, "%x", &gind);
160
8.37k
                if (l > 0)
161
8.37k
                    (void)pdfi_fapi_check_cmap_for_GID((gs_font *)pfont, (uint)gind, &cc);
162
0
                else
163
0
                    cc = 0;
164
8.37k
            }
165
3.69M
            else {
166
                /* Slow linear search */
167
6.83G
                for (i = 0; sgl->Glyph != 0x00; i++) {
168
6.83G
                    if (sgl->Glyph[0] == gname.data[0]
169
6.83G
                        && strlen(sgl->Glyph) == gname.size
170
6.83G
                        && !strncmp((char *)sgl->Glyph, (char *)gname.data, gname.size))
171
3.69M
                        break;
172
6.83G
                    sgl++;
173
6.83G
                }
174
3.69M
                if (sgl->Glyph != NULL) {
175
3.69M
                    code = pdfi_fapi_check_cmap_for_GID((gs_font *)pfont, (uint)sgl->Unicode, &cc);
176
3.69M
                    if (code < 0 || cc == 0)
177
2.19M
                        cc = 0;
178
3.69M
                }
179
12
                else
180
12
                    cc = 0;
181
182
3.69M
                if (cc == 0) {
183
2.19M
                    gs_string postname = {0};
184
185
                    /* This is a very slow implementation, we may benefit from creating a
186
                     * a reverse post table upfront */
187
3.33G
                    for (i = 0; i < pfont->data.numGlyphs; i++) {
188
3.33G
                        code = gs_type42_find_post_name(pfont, (gs_glyph)i, &postname);
189
3.33G
                        if (code >= 0) {
190
185k
                            if (postname.data[0] == gname.data[0]
191
185k
                                && postname.size == gname.size
192
185k
                                && !strncmp((char *)postname.data, (char *)gname.data, gname.size))
193
825
                            {
194
825
                                cc = i;
195
825
                                break;
196
825
                            }
197
185k
                        }
198
3.33G
                    }
199
2.19M
                }
200
3.69M
            }
201
3.70M
        }
202
4.05M
        gind = cc;
203
4.05M
    }
204
4.20M
    return gind;
205
4.65M
}
206
207
static int
208
pdfi_ttf_enumerate_glyph(gs_font *font, int *pindex, gs_glyph_space_t glyph_space, gs_glyph *pglyph)
209
3.17M
{
210
3.17M
    if (glyph_space == GLYPH_SPACE_INDEX) {
211
106k
        return gs_type42_enumerate_glyph(font, pindex, glyph_space, pglyph);
212
106k
    }
213
3.06M
    else if (glyph_space == GLYPH_SPACE_NAME) {
214
3.06M
        pdf_font_truetype *ttfont = (pdf_font_truetype *)font->client_data;
215
216
3.06M
        if ((ttfont->descflags & 4) == 0) {
217
3.06M
            if (*pindex <= 0) {
218
23.7k
                *pindex = 0;
219
23.7k
            }
220
3.06M
            *pglyph = (*font->procs.encode_char)(font, (gs_char)*pindex, glyph_space);
221
3.06M
            if (*pglyph == GS_NO_GLYPH)
222
11.5k
                *pindex = 0;
223
3.05M
            else
224
3.05M
                (*pindex)++;
225
3.06M
        }
226
3.06M
    }
227
0
    else
228
0
        *pindex = 0;
229
3.06M
    return 0;
230
3.17M
}
231
232
static int pdfi_ttf_glyph_name(gs_font *pfont, gs_glyph glyph, gs_const_string * pstr)
233
787k
{
234
787k
    pdf_font_truetype *ttfont = (pdf_font_truetype *)pfont->client_data;
235
787k
    pdf_context *ctx = (pdf_context *)ttfont->ctx;
236
787k
    uint ID = 0;
237
787k
    int code = -1;
238
239
787k
    if (glyph >= GS_MIN_GLYPH_INDEX)
240
320
        glyph -= GS_MIN_GLYPH_INDEX;
241
242
787k
    if ((ttfont->descflags & 4) != 0) {
243
6.01k
        code = gs_type42_find_post_name((gs_font_type42 *)pfont, glyph, (gs_string *)pstr);
244
6.01k
        if (code < 0) {
245
5.87k
            char buf[64];
246
5.87k
            int l;
247
5.87k
            l = gs_snprintf(buf, sizeof(buf), "~gs~gName~%04x", (uint)glyph);
248
5.87k
            code = (*ctx->get_glyph_index)(pfont, (byte *)buf, l, &ID);
249
5.87k
        }
250
139
        else {
251
139
            code = (*ctx->get_glyph_index)(pfont, (byte *)pstr->data, pstr->size, &ID);
252
139
        }
253
6.01k
        if (code < 0)
254
0
            return -1; /* No name, trigger pdfwrite Type 3 fallback */
255
256
6.01k
        code = (*ctx->get_glyph_name)(pfont, (gs_glyph)ID, pstr);
257
6.01k
        if (code < 0)
258
0
            return -1; /* No name, trigger pdfwrite Type 3 fallback */
259
6.01k
    }
260
781k
    else {
261
781k
        code = (*ctx->get_glyph_name)(pfont, glyph, pstr);
262
781k
        if (code < 0)
263
0
            return -1; /* No name, trigger pdfwrite Type 3 fallback */
264
781k
    }
265
787k
    return code;
266
267
787k
}
268
269
static int
270
pdfi_alloc_tt_font(pdf_context *ctx, pdf_font_truetype **font, bool is_cid)
271
16.8k
{
272
16.8k
    pdf_font_truetype *ttfont = NULL;
273
16.8k
    gs_font_type42 *pfont = NULL;
274
275
16.8k
    ttfont = (pdf_font_truetype *)gs_alloc_bytes(ctx->memory, sizeof(pdf_font_truetype), "pdfi (truetype pdf_font)");
276
16.8k
    if (ttfont == NULL)
277
0
        return_error(gs_error_VMerror);
278
279
16.8k
    memset(ttfont, 0x00, sizeof(pdf_font_truetype));
280
16.8k
    ttfont->type = PDF_FONT;
281
16.8k
    ttfont->ctx = ctx;
282
16.8k
    ttfont->pdfi_font_type = e_pdf_font_truetype;
283
284
#if REFCNT_DEBUG
285
    ttfont->UID = ctx->UID++;
286
    dmprintf2(ctx->memory, "Allocated object of type %c with UID %"PRIi64"\n", ttfont->type, ttfont->UID);
287
#endif
288
289
16.8k
    pdfi_countup(ttfont);
290
291
16.8k
    pfont = (gs_font_type42 *)gs_alloc_struct(ctx->memory, gs_font_type42, &st_gs_font_type42,
292
16.8k
                            "pdfi (truetype pfont)");
293
16.8k
    if (pfont == NULL) {
294
0
        pdfi_countdown(ttfont);
295
0
        return_error(gs_error_VMerror);
296
0
    }
297
16.8k
    memset(pfont, 0x00, sizeof(gs_font_type42));
298
299
16.8k
    ttfont->pfont = (gs_font_base *)pfont;
300
301
16.8k
    gs_make_identity(&pfont->orig_FontMatrix);
302
16.8k
    gs_make_identity(&pfont->FontMatrix);
303
16.8k
    pfont->next = pfont->prev = 0;
304
16.8k
    pfont->memory = ctx->memory;
305
16.8k
    pfont->dir = ctx->font_dir;
306
16.8k
    pfont->is_resource = false;
307
16.8k
    gs_notify_init(&pfont->notify_list, ctx->memory);
308
16.8k
    pfont->base = (gs_font *) ttfont->pfont;
309
16.8k
    pfont->client_data = ttfont;
310
16.8k
    pfont->WMode = 0;
311
16.8k
    pfont->PaintType = 0;
312
16.8k
    pfont->StrokeWidth = 0;
313
16.8k
    pfont->is_cached = 0;
314
16.8k
    pfont->FAPI = NULL;
315
16.8k
    pfont->FAPI_font_data = NULL;
316
16.8k
    pfont->procs.init_fstack = gs_default_init_fstack;
317
16.8k
    pfont->procs.next_char_glyph = gs_default_next_char_glyph;
318
16.8k
    pfont->FontType = ft_TrueType;
319
16.8k
    pfont->ExactSize = fbit_use_outlines;
320
16.8k
    pfont->InBetweenSize = fbit_use_outlines;
321
16.8k
    pfont->TransformedChar = fbit_use_outlines;
322
    /* We may want to do something clever with an XUID here */
323
16.8k
    pfont->id = gs_next_ids(ctx->memory, 1);
324
16.8k
    uid_set_UniqueID(&pfont->UID, pfont->id);
325
    /* The buildchar proc will be filled in by FAPI -
326
       we won't worry about working without FAPI */
327
16.8k
    pfont->procs.encode_char = pdfi_ttf_encode_char;
328
16.8k
    pfont->data.string_proc = pdfi_ttf_string_proc;
329
16.8k
    pfont->procs.glyph_name = pdfi_ttf_glyph_name;
330
16.8k
    pfont->procs.decode_glyph = pdfi_decode_glyph;
331
16.8k
    pfont->procs.define_font = gs_no_define_font;
332
16.8k
    pfont->procs.make_font = gs_no_make_font;
333
16.8k
    pfont->procs.font_info = gs_default_font_info;
334
16.8k
    pfont->procs.glyph_info = gs_default_glyph_info;
335
16.8k
    pfont->procs.glyph_outline = gs_no_glyph_outline;
336
16.8k
    pfont->procs.build_char = NULL;
337
16.8k
    pfont->procs.same_font = gs_default_same_font;
338
16.8k
    pfont->procs.enumerate_glyph = gs_no_enumerate_glyph;
339
340
16.8k
    pfont->encoding_index = -1;          /****** WRONG ******/
341
16.8k
    pfont->nearest_encoding_index = -1;          /****** WRONG ******/
342
343
16.8k
    pfont->client_data = (void *)ttfont;
344
345
16.8k
    *font = ttfont;
346
16.8k
    return 0;
347
16.8k
}
348
349
static int pdfi_set_type42_data_procs(gs_font_type42 *pfont)
350
13.5k
{
351
13.5k
    pfont->data.get_glyph_index = pdfi_type42_get_glyph_index;
352
13.5k
    pfont->procs.enumerate_glyph = pdfi_ttf_enumerate_glyph;
353
13.5k
    return 0;
354
13.5k
}
355
356
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)
357
16.8k
{
358
16.8k
    pdf_font_truetype *font = NULL;
359
16.8k
    int code = 0, i;
360
16.8k
    pdf_obj *fontdesc = NULL;
361
16.8k
    pdf_obj *obj = NULL;
362
16.8k
    pdf_obj *basefont = NULL;
363
16.8k
    int64_t descflags;
364
16.8k
    bool encoding_known = false;
365
16.8k
    bool forced_symbolic = false;
366
16.8k
    pdf_obj *tounicode = NULL;
367
368
16.8k
    if (ppdffont == NULL)
369
0
        return_error(gs_error_invalidaccess);
370
371
16.8k
    *ppdffont = NULL;
372
373
16.8k
    if (font_dict != NULL)
374
16.8k
        (void)pdfi_dict_knownget_type(ctx, font_dict, "FontDescriptor", PDF_DICT, &fontdesc);
375
376
16.8k
    if ((code = pdfi_alloc_tt_font(ctx, &font, false)) < 0) {
377
0
        code = gs_note_error(gs_error_invalidfont);
378
0
        goto error;
379
0
    }
380
16.8k
    if (font_dict != NULL) {
381
16.8k
        font->object_num = font_dict->object_num;
382
16.8k
        font->generation_num = font_dict->generation_num;
383
16.8k
        font->indirect_num = font_dict->indirect_num;
384
16.8k
        font->indirect_gen = font_dict->indirect_gen;
385
16.8k
    }
386
387
16.8k
    font->FontDescriptor = (pdf_dict *)fontdesc;
388
16.8k
    fontdesc = NULL;
389
390
16.8k
    pdfi_font_set_first_last_char(ctx, font_dict, (pdf_font *)font);
391
392
16.8k
    code = pdfi_object_alloc(ctx, PDF_BUFFER, 0, (pdf_obj **)&font->sfnt);
393
16.8k
    if (code < 0) {
394
0
        goto error;
395
0
    }
396
16.8k
    pdfi_countup(font->sfnt);
397
16.8k
    code = pdfi_buffer_set_data((pdf_obj *)font->sfnt, buf, buflen);
398
16.8k
    if (code < 0) {
399
0
        goto error;
400
0
    }
401
16.8k
    buf = NULL;
402
403
    /* Strictly speaking BaseFont is required, but we can continue without one */
404
16.8k
    if (font_dict != NULL) {
405
16.8k
        code = pdfi_dict_knownget_type(ctx, font_dict, "BaseFont", PDF_NAME, (pdf_obj **)&basefont);
406
16.8k
        if (code > 0) {
407
16.7k
            pdf_name *nobj = (pdf_name *)basefont;
408
16.7k
            int nlen = nobj->length > gs_font_name_max ? gs_font_name_max : nobj->length;
409
410
16.7k
            memcpy(font->pfont->key_name.chars, nobj->data, nlen);
411
16.7k
            font->pfont->key_name.chars[nlen] = 0;
412
16.7k
            font->pfont->key_name.size = nlen;
413
16.7k
            memcpy(font->pfont->font_name.chars, nobj->data, nlen);
414
16.7k
            font->pfont->font_name.chars[nlen] = 0;
415
16.7k
            font->pfont->font_name.size = nlen;
416
16.7k
            pdfi_countdown(obj);
417
16.7k
            obj = NULL;
418
16.7k
        }
419
16.8k
    }
420
16.8k
    font->BaseFont = basefont;
421
16.8k
    basefont = NULL;
422
16.8k
    font->PDF_font = font_dict;
423
16.8k
    pdfi_countup(font_dict);
424
425
    /* ignore errors with widths... for now */
426
16.8k
    if (font_dict != NULL)
427
16.8k
        (void)pdfi_font_create_widths(ctx, font_dict, (pdf_font*)font, 0.001);
428
429
16.8k
    if (ctx->args.ignoretounicode != true && font_dict != NULL) {
430
16.8k
        code = pdfi_dict_get(ctx, font_dict, "ToUnicode", (pdf_obj **)&tounicode);
431
16.8k
        if (code >= 0 && pdfi_type_of(tounicode) == PDF_STREAM) {
432
3.78k
            pdf_cmap *tu = NULL;
433
3.78k
            code = pdfi_read_cmap(ctx, tounicode, &tu);
434
3.78k
            pdfi_countdown(tounicode);
435
3.78k
            tounicode = (pdf_obj *)tu;
436
3.78k
        }
437
16.8k
        if (code < 0 || (tounicode != NULL && pdfi_type_of(tounicode) != PDF_CMAP)) {
438
13.1k
            pdfi_countdown(tounicode);
439
13.1k
            tounicode = NULL;
440
13.1k
            code = 0;
441
13.1k
        }
442
16.8k
    }
443
0
    else {
444
0
        tounicode = NULL;
445
0
    }
446
16.8k
    font->ToUnicode = tounicode;
447
16.8k
    tounicode = NULL;
448
449
16.8k
    if (font->FontDescriptor != NULL) {
450
16.8k
        code = pdfi_dict_get_int(ctx, font->FontDescriptor, "Flags", &descflags);
451
16.8k
        if (code < 0)
452
4
            descflags = 0;
453
16.8k
    }
454
0
    else {
455
0
        descflags = 0;
456
0
    }
457
458
16.8k
    if (font_dict != NULL)
459
16.8k
        code = pdfi_dict_get(ctx, font_dict, "Encoding", &obj);
460
0
    else
461
0
        code = gs_error_undefined;
462
463
16.8k
    if (code < 0) {
464
1.26k
        static const char encstr[] = "WinAnsiEncoding";
465
1.26k
        code = pdfi_name_alloc(ctx, (byte *)encstr, strlen(encstr), (pdf_obj **)&obj);
466
1.26k
        if (code >= 0)
467
1.26k
            pdfi_countup(obj);
468
0
        else
469
0
            goto error;
470
1.26k
    }
471
15.6k
    else {
472
15.6k
        encoding_known = true;
473
        /* If we have and encoding, and both the symbolic and non-symbolic flag are set,
474
           believe that latter.
475
         */
476
15.6k
        if ((descflags & 32) != 0)
477
15.4k
            descflags = (descflags & ~4);
478
15.6k
    }
479
480
16.8k
    if ((forced_symbolic = pdfi_font_known_symbolic(font->BaseFont)) == true) {
481
0
        descflags |= 4;
482
0
    }
483
484
16.8k
    code = pdfi_create_Encoding(ctx, obj, NULL, (pdf_obj **)&font->Encoding);
485
    /* If we get an error, and the font is non-symbolic, return the error */
486
16.8k
    if (code < 0 && (descflags & 4) == 0)
487
24
        goto error;
488
    /* If we get an error, and the font is symbolic, pretend we never saw an /Encoding */
489
16.8k
    if (code < 0)
490
4
        encoding_known = false;
491
16.8k
    pdfi_countdown(obj);
492
16.8k
    obj = NULL;
493
494
16.8k
    code = gs_type42_font_init((gs_font_type42 *)font->pfont, 0);
495
16.8k
    if (code < 0) {
496
3.34k
        goto error;
497
3.34k
    }
498
499
13.5k
    code = pdfi_set_type42_data_procs((gs_font_type42 *)font->pfont);
500
13.5k
    if (code < 0) {
501
0
        goto error;
502
0
    }
503
504
    /* We're probably dead in the water without cmap tables, but make sure, for safety */
505
    /* This is a horrendous morass of guesses at what Acrobat does with files that contravene
506
       what the spec says about symbolic fonts, cmap tables and encodings.
507
     */
508
13.5k
    if (forced_symbolic != true && (descflags & 4) != 0 && ((gs_font_type42 *)font->pfont)->data.cmap != 0) {
509
1.06k
        gs_font_type42 *t42f = (gs_font_type42 *)font->pfont;
510
1.06k
        int numcmaps;
511
1.06k
        int cmaps_available = CMAP_TABLE_NONE;
512
1.06k
        const byte *d;
513
1.06k
        code = (*t42f->data.string_proc)(t42f, t42f->data.cmap + 2, 2, &d);
514
1.06k
        if (code < 0)
515
1
            goto error;
516
1.06k
        numcmaps = d[1] | d[0] << 8;
517
18.2k
        for (i = 0; i < numcmaps; i++) {
518
17.1k
            code = (*t42f->data.string_proc)(t42f, t42f->data.cmap + 4 + i * 8, 4, &d);
519
17.1k
            if (code < 0)
520
19
                goto error;
521
18.4k
#define CMAP_PLAT_ENC_ID(a,b,c,d) (a << 24 | b << 16 | c << 8 | d)
522
17.1k
            switch(CMAP_PLAT_ENC_ID(d[0], d[1], d[2], d[3])) {
523
1.00k
                case CMAP_PLAT_ENC_ID(0, 1, 0, 0):
524
1.00k
                    cmaps_available |= CMAP_TABLE_10_PRESENT;
525
1.00k
                    break;
526
256
                case CMAP_PLAT_ENC_ID(0, 3, 0, 0):
527
256
                    cmaps_available |= CMAP_TABLE_30_PRESENT;
528
256
                    break;
529
18
                case CMAP_PLAT_ENC_ID(0, 3, 0, 1):
530
18
                    cmaps_available |= CMAP_TABLE_31_PRESENT;
531
18
                    break;
532
0
                case CMAP_PLAT_ENC_ID(0, 3, 1, 0):
533
0
                    cmaps_available |= CMAP_TABLE_310_PRESENT;
534
0
                    break;
535
15.8k
                default: /* Not one we're interested in */
536
15.8k
                    break;
537
17.1k
            }
538
17.1k
        }
539
1.04k
#undef CMAP_PLAT_ENC_ID
540
1.04k
        if ((cmaps_available & CMAP_TABLE_30_PRESENT) == CMAP_TABLE_30_PRESENT) {
541
256
            font->descflags = descflags;
542
256
        }
543
791
        else if (encoding_known == true) {
544
8
            static const char mrencstr[] = "MacRomanEncoding";
545
8
            static const char waencstr[] = "WinAnsiEncoding";
546
8
            const char *encstr = ((cmaps_available & CMAP_TABLE_31_PRESENT) == CMAP_TABLE_31_PRESENT) ? waencstr : mrencstr;
547
8
            font->descflags = descflags & ~4;
548
8
            code = pdfi_name_alloc(ctx, (byte *)encstr, strlen(encstr), (pdf_obj **)&obj);
549
8
            if (code >= 0)
550
8
                pdfi_countup(obj);
551
0
            else
552
0
                goto error;
553
8
            pdfi_countdown(font->Encoding);
554
8
            code = pdfi_create_Encoding(ctx, obj, NULL, (pdf_obj **)&font->Encoding);
555
8
            if (code < 0)
556
0
                goto error;
557
8
            pdfi_countdown(obj);
558
8
            obj = NULL;
559
8
        }
560
783
        else
561
783
            font->descflags = descflags;
562
1.04k
    }
563
12.4k
    else {
564
12.4k
        font->descflags = descflags;
565
12.4k
    }
566
567
13.5k
    if (uid_is_XUID(&font->pfont->UID))
568
13.5k
        uid_free(&font->pfont->UID, font->pfont->memory, "pdfi_read_type1_font");
569
13.5k
    uid_set_invalid(&font->pfont->UID);
570
571
13.5k
    code = pdfi_font_generate_pseudo_XUID(ctx, font_dict, font->pfont);
572
13.5k
    if (code < 0) {
573
0
        goto error;
574
0
    }
575
576
13.5k
    if ((font->descflags & 4) == 0) {
577
        /* Horrid hacky solution */
578
        /* We don't want to draw the TTF notdef */
579
12.4k
        gs_font_type42 *gst42 = ((gs_font_type42 *)font->pfont);
580
12.4k
        if (gst42->data.len_glyphs != NULL && gst42->data.len_glyphs[0] > 10) {
581
10.3k
            gst42->data.len_glyphs[0] = 0;
582
10.3k
        }
583
12.4k
    }
584
585
13.5k
    code = gs_definefont(ctx->font_dir, (gs_font *)font->pfont);
586
13.5k
    if (code < 0) {
587
0
        goto error;
588
0
    }
589
590
13.5k
    code = pdfi_fapi_passfont((pdf_font *)font, 0, NULL, NULL, font->sfnt->data, font->sfnt->length);
591
13.5k
    if (code < 0) {
592
1.16k
        goto error;
593
1.16k
    }
594
595
    /* object_num can be zero if the dictionary was defined inline */
596
12.3k
    if (font->object_num != 0) {
597
11.8k
        (void)replace_cache_entry(ctx, (pdf_obj *)font);
598
11.8k
    }
599
600
12.3k
    *ppdffont = (pdf_font *)font;
601
12.3k
    return code;
602
4.55k
error:
603
4.55k
    if (buf != NULL)
604
0
        gs_free_object(ctx->memory, buf, "pdfi_read_truetype_font(buf)");
605
4.55k
    pdfi_countdown(fontdesc);
606
4.55k
    pdfi_countdown(basefont);
607
4.55k
    pdfi_countdown(obj);
608
4.55k
    pdfi_countdown(font);
609
4.55k
    return code;
610
13.5k
}
611
612
int
613
pdfi_copy_truetype_font(pdf_context *ctx, pdf_font *spdffont, pdf_dict *font_dict, pdf_font **tpdffont)
614
0
{
615
0
    int code = 0;
616
0
    pdf_font_truetype *font = NULL;
617
0
    gs_font_type42 *spfont1 = (gs_font_type42 *) spdffont->pfont;
618
0
    gs_font_type42 *dpfont42;
619
0
    gs_id t_id;
620
0
    pdf_obj *tmp;
621
622
0
    if (font_dict == NULL)
623
0
        return_error(gs_error_invalidfont);
624
625
0
    code = pdfi_alloc_tt_font(ctx, &font, font_dict->object_num);
626
0
    if (code < 0)
627
0
        return code;
628
0
    dpfont42 = (gs_font_type42 *) font->pfont;
629
630
0
    t_id = dpfont42->id;
631
0
    memcpy(dpfont42, spfont1, sizeof(gs_font_type42));
632
0
    dpfont42->id = t_id;
633
0
    dpfont42->FAPI = NULL;
634
0
    dpfont42->FAPI_font_data = NULL;
635
0
    dpfont42->notify_list.memory = NULL;
636
0
    dpfont42->notify_list.first = NULL;
637
0
    gs_notify_init(&dpfont42->notify_list, dpfont42->memory);
638
639
0
    memcpy(font, spdffont, sizeof(pdf_font_truetype));
640
0
    font->refcnt = 1;
641
0
    font->filename = NULL;
642
643
0
    font->pfont = (gs_font_base *)dpfont42;
644
0
    dpfont42->client_data = (void *)font;
645
646
0
    font->PDF_font = font_dict;
647
0
    font->object_num = font_dict->object_num;
648
0
    font->generation_num = font_dict->generation_num;
649
0
    pdfi_countup(font->PDF_font);
650
651
    /* We want basefont and descriptor, but we can live without them */
652
0
    font->BaseFont = NULL;
653
0
    (void)pdfi_dict_knownget_type(ctx, font_dict, "BaseFont", PDF_NAME, &font->BaseFont);
654
0
    font->FontDescriptor = NULL;
655
0
    (void)pdfi_dict_knownget_type(ctx, font_dict, "FontDescriptor", PDF_DICT, (pdf_obj **)&font->FontDescriptor);
656
657
0
    pdfi_countup(font->sfnt);
658
659
0
    if (font->BaseFont != NULL && ((pdf_name *)font->BaseFont)->length <= gs_font_name_max) {
660
0
        memcpy(dpfont42->key_name.chars, ((pdf_name *)font->BaseFont)->data, ((pdf_name *)font->BaseFont)->length);
661
0
        dpfont42->key_name.size = ((pdf_name *)font->BaseFont)->length;
662
0
        memcpy(dpfont42->font_name.chars, ((pdf_name *)font->BaseFont)->data, ((pdf_name *)font->BaseFont)->length);
663
0
        dpfont42->font_name.size = ((pdf_name *)font->BaseFont)->length;
664
0
    }
665
666
0
    font->Encoding = NULL;
667
0
    font->ToUnicode = NULL;
668
0
    font->Widths = NULL;
669
670
0
    pdfi_font_set_first_last_char(ctx, font_dict, (pdf_font *)font);
671
0
    (void)pdfi_font_create_widths(ctx, font_dict, (pdf_font*)font, (double)0.001);
672
673
0
    font->descflags = 0;
674
0
    if (font->FontDescriptor != NULL) {
675
0
        code = pdfi_dict_get_int(ctx, font->FontDescriptor, "Flags", &font->descflags);
676
0
        if (code >= 0) {
677
            /* If both the symbolic and non-symbolic flag are set,
678
               believe that latter.
679
             */
680
0
            if ((font->descflags & 32) != 0)
681
0
                font->descflags = (font->descflags & ~4);
682
0
        }
683
0
    }
684
685
0
    tmp = NULL;
686
0
    code = pdfi_dict_knownget(ctx, font_dict, "Encoding", &tmp);
687
0
    if (code == 1) {
688
0
        if ((pdfi_type_of(tmp) == PDF_NAME || pdfi_type_of(tmp) == PDF_DICT) && (font->descflags & 4) == 0) {
689
0
            code = pdfi_create_Encoding(ctx, tmp, NULL, (pdf_obj **) & font->Encoding);
690
0
        }
691
0
        else if (pdfi_type_of(tmp) == PDF_DICT && (font->descflags & 4) != 0) {
692
0
            code = pdfi_create_Encoding(ctx, tmp, (pdf_obj *)spdffont->Encoding, (pdf_obj **) &font->Encoding);
693
0
        }
694
0
        else {
695
0
            code = gs_error_undefined;
696
0
        }
697
0
        pdfi_countdown(tmp);
698
0
        tmp = NULL;
699
0
    }
700
0
    else {
701
0
        pdfi_countdown(tmp);
702
0
        tmp = NULL;
703
0
        code = gs_error_undefined;
704
0
    }
705
706
0
    if (code < 0) {
707
0
        font->Encoding = spdffont->Encoding;
708
0
        pdfi_countup(font->Encoding);
709
0
    }
710
711
    /* Since various aspects of the font may differ (widths, encoding, etc)
712
       we cannot reliably use the UniqueID/XUID for copied fonts.
713
     */
714
0
    if (uid_is_XUID(&font->pfont->UID))
715
0
        uid_free(&font->pfont->UID, font->pfont->memory, "pdfi_read_type1_font");
716
0
    uid_set_invalid(&font->pfont->UID);
717
718
0
    code = pdfi_font_generate_pseudo_XUID(ctx, font_dict, font->pfont);
719
0
    if (code < 0) {
720
0
        goto error;
721
0
    }
722
723
0
    if (ctx->args.ignoretounicode != true) {
724
0
        code = pdfi_dict_get(ctx, font_dict, "ToUnicode", (pdf_obj **)&tmp);
725
0
        if (code >= 0 && pdfi_type_of(tmp) == PDF_STREAM) {
726
0
            pdf_cmap *tu = NULL;
727
0
            code = pdfi_read_cmap(ctx, tmp, &tu);
728
0
            pdfi_countdown(tmp);
729
0
            tmp = (pdf_obj *)tu;
730
0
        }
731
0
        if (code < 0 || (tmp != NULL && pdfi_type_of(tmp) != PDF_CMAP)) {
732
0
            pdfi_countdown(tmp);
733
0
            tmp = NULL;
734
0
            code = 0;
735
0
        }
736
0
    }
737
0
    else {
738
0
        tmp = NULL;
739
0
    }
740
0
    font->ToUnicode = tmp;
741
0
    code = gs_definefont(ctx->font_dir, (gs_font *) font->pfont);
742
0
    if (code < 0) {
743
0
        goto error;
744
0
    }
745
746
0
    code = pdfi_fapi_passfont((pdf_font *) font, 0, NULL, NULL, NULL, 0);
747
0
    if (code < 0) {
748
0
        goto error;
749
0
    }
750
    /* object_num can be zero if the dictionary was defined inline */
751
0
    if (font->object_num != 0) {
752
0
        (void)replace_cache_entry(ctx, (pdf_obj *) font);
753
0
    }
754
755
0
    *tpdffont = (pdf_font *)font;
756
757
0
error:
758
0
    if (code < 0)
759
0
        pdfi_countdown(font);
760
0
    return code;
761
0
}
762
763
int pdfi_free_font_truetype(pdf_obj *font)
764
16.8k
{
765
16.8k
    pdf_font_truetype *ttfont = (pdf_font_truetype *)font;
766
767
16.8k
    if (ttfont->pfont)
768
16.8k
        gs_free_object(OBJ_MEMORY(ttfont), ttfont->pfont, "Free TrueType gs_font");
769
770
16.8k
    if (ttfont->Widths)
771
16.5k
        gs_free_object(OBJ_MEMORY(ttfont), ttfont->Widths, "Free TrueType font Widths array");
772
773
16.8k
    pdfi_countdown(ttfont->sfnt);
774
16.8k
    pdfi_countdown(ttfont->FontDescriptor);
775
16.8k
    pdfi_countdown(ttfont->Encoding);
776
16.8k
    pdfi_countdown(ttfont->BaseFont);
777
16.8k
    pdfi_countdown(ttfont->PDF_font);
778
16.8k
    pdfi_countdown(ttfont->ToUnicode);
779
16.8k
    pdfi_countdown(ttfont->filename);
780
781
16.8k
    gs_free_object(OBJ_MEMORY(ttfont), ttfont, "Free TrueType font");
782
783
16.8k
    return 0;
784
16.8k
}