Coverage Report

Created: 2025-08-28 07:06

/src/ghostpdl/pdf/pdf_font.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2018-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
/* Font operations for the PDF interpreter */
17
18
#include "pdf_int.h"
19
#include "pdf_font_types.h"
20
#include "pdf_gstate.h"
21
#include "pdf_file.h"
22
#include "pdf_dict.h"
23
#include "pdf_loop_detect.h"
24
#include "pdf_array.h"
25
#include "pdf_font.h"
26
#include "pdf_stack.h"
27
#include "pdf_misc.h"
28
#include "pdf_doc.h"
29
#include "pdf_font0.h"
30
#include "pdf_font1.h"
31
#include "pdf_font1C.h"
32
#include "pdf_font3.h"
33
#include "pdf_fontTT.h"
34
#include "pdf_fontmt.h"
35
#include "pdf_font0.h"
36
#include "pdf_fmap.h"
37
#include "gscencs.h"            /* For gs_c_known_encode and gs_c_glyph_name */
38
#include "gsagl.h"
39
40
#include "strmio.h"
41
#include "stream.h"
42
#include "gsstate.h"            /* For gs_setPDFfontsize() */
43
44
extern single_glyph_list_t SingleGlyphList[];
45
46
static int pdfi_gs_setfont(pdf_context *ctx, gs_font *pfont)
47
1.94M
{
48
1.94M
    int code = 0;
49
1.94M
    pdfi_int_gstate *igs = (pdfi_int_gstate *)ctx->pgs->client_data;
50
1.94M
    pdf_font *old_font = igs->current_font;
51
52
1.94M
    code = gs_setfont(ctx->pgs, pfont);
53
1.94M
    if (code >= 0) {
54
1.94M
        igs->current_font = (pdf_font *)pfont->client_data;
55
1.94M
        pdfi_countup(igs->current_font);
56
1.94M
        pdfi_countdown(old_font);
57
1.94M
    }
58
1.94M
    return code;
59
1.94M
}
60
61
static void pdfi_cache_resource_font(pdf_context *ctx, pdf_obj *fontdesc, pdf_obj *ppdffont)
62
40.8k
{
63
40.8k
    resource_font_cache_t *entry = NULL;
64
40.8k
    int i;
65
66
40.8k
    if (ctx->resource_font_cache == NULL) {
67
23.5k
        ctx->resource_font_cache = (resource_font_cache_t *)gs_alloc_bytes(ctx->memory, RESOURCE_FONT_CACHE_BLOCK_SIZE * sizeof(pdfi_name_entry_t), "pdfi_cache_resource_font");
68
23.5k
        if (ctx->resource_font_cache == NULL)
69
0
            return;
70
23.5k
        ctx->resource_font_cache_size = RESOURCE_FONT_CACHE_BLOCK_SIZE;
71
23.5k
        memset(ctx->resource_font_cache, 0x00, RESOURCE_FONT_CACHE_BLOCK_SIZE * sizeof(pdfi_name_entry_t));
72
23.5k
        entry = &ctx->resource_font_cache[0];
73
23.5k
    }
74
75
113k
    for (i = 0; entry == NULL && i < ctx->resource_font_cache_size; i++) {
76
72.8k
        if (ctx->resource_font_cache[i].pdffont == NULL) {
77
17.2k
            entry = &ctx->resource_font_cache[i];
78
17.2k
        }
79
55.6k
        else if (i == ctx->resource_font_cache_size - 1) {
80
2
            entry = (resource_font_cache_t *)gs_resize_object(ctx->memory, ctx->resource_font_cache, sizeof(pdfi_name_entry_t) * (ctx->resource_font_cache_size + RESOURCE_FONT_CACHE_BLOCK_SIZE), "pdfi_cache_resource_font");
81
2
            if (entry == NULL)
82
0
                break;
83
2
            memset(entry + ctx->resource_font_cache_size, 0x00, RESOURCE_FONT_CACHE_BLOCK_SIZE * sizeof(pdfi_name_entry_t));
84
2
            ctx->resource_font_cache = entry;
85
2
            entry = &ctx->resource_font_cache[ctx->resource_font_cache_size];
86
2
            ctx->resource_font_cache_size += RESOURCE_FONT_CACHE_BLOCK_SIZE;
87
2
        }
88
72.8k
    }
89
40.8k
    if (entry != NULL) {
90
40.8k
        entry->desc_obj_num = fontdesc->object_num;
91
40.8k
        entry->pdffont = ppdffont;
92
40.8k
        pdfi_countup(ppdffont);
93
40.8k
    }
94
40.8k
}
95
96
void pdfi_purge_cache_resource_font(pdf_context *ctx)
97
123k
{
98
123k
    int i;
99
876k
    for (i = 0; i < ctx->resource_font_cache_size; i++) {
100
753k
       pdfi_countdown(ctx->resource_font_cache[i].pdffont);
101
753k
    }
102
123k
    gs_free_object(ctx->memory, ctx->resource_font_cache, "pdfi_purge_cache_resource_font");
103
123k
    ctx->resource_font_cache = NULL;
104
123k
    ctx->resource_font_cache_size = 0;
105
123k
}
106
107
static int pdfi_find_cache_resource_font(pdf_context *ctx, pdf_obj *fontdesc, pdf_obj **ppdffont)
108
80.9k
{
109
80.9k
    int i, code = gs_error_undefined;
110
907k
    for (i = 0; i < ctx->resource_font_cache_size; i++) {
111
830k
        if (ctx->resource_font_cache[i].desc_obj_num == fontdesc->object_num) {
112
4.02k
           *ppdffont = ctx->resource_font_cache[i].pdffont;
113
4.02k
           pdfi_countup(*ppdffont);
114
4.02k
           code = 0;
115
4.02k
           break;
116
4.02k
        }
117
830k
    }
118
80.9k
    return code;
119
80.9k
}
120
121
/* These are fonts for which we have to ignore "named" encodings */
122
typedef struct known_symbolic_font_name_s
123
{
124
    const char *name;
125
    const int namelen;
126
} known_symbolic_font_name_t;
127
128
#define DEFINE_NAME_LEN(s) #s, sizeof(#s) - 1
129
static const known_symbolic_font_name_t known_symbolic_font_names[] =
130
{
131
  {DEFINE_NAME_LEN(Symbol)},
132
  {DEFINE_NAME_LEN(Wingdings2)},
133
  {DEFINE_NAME_LEN(Wingdings)},
134
  {DEFINE_NAME_LEN(ZapfDingbats)},
135
  {NULL , 0}
136
};
137
#undef DEFINE_NAME_LEN
138
139
bool pdfi_font_known_symbolic(pdf_obj *basefont)
140
1.05M
{
141
1.05M
    bool ignore = false;
142
1.05M
    int i;
143
1.05M
    pdf_name *nm = (pdf_name *)basefont;
144
145
1.05M
    if (basefont != NULL && pdfi_type_of(basefont) == PDF_NAME) {
146
4.98M
        for (i = 0; known_symbolic_font_names[i].name != NULL; i++) {
147
3.99M
            if (nm->length == known_symbolic_font_names[i].namelen
148
3.99M
             && !strncmp((char *)nm->data, known_symbolic_font_names[i].name, nm->length)) {
149
2.51k
                ignore = true;
150
2.51k
                break;
151
2.51k
            }
152
3.99M
        }
153
998k
    }
154
1.05M
    return ignore;
155
1.05M
}
156
157
static int
158
pdfi_font_match_glyph_widths(pdf_font *pdfont)
159
928k
{
160
928k
    int code = 0;
161
928k
    int i;
162
928k
    int sindex, lindex;
163
928k
    gs_font_base *pbfont = pdfont->pfont;
164
928k
    double fw = 0.0, ww = 0.0;
165
166
928k
    if (pdfont->LastChar <  pdfont->FirstChar || pdfont->Widths == NULL)
167
896k
        return 0; /* Technically invalid - carry on, hope for the best */
168
169
    /* For "best" results, restrict to what we *hope* are A-Z,a-z */
170
31.5k
    sindex = pdfont->FirstChar < 96 ? 96 : pdfont->FirstChar;
171
31.5k
    lindex = pdfont->LastChar > 122 ? 123 : pdfont->LastChar + 1;
172
173
567k
    for (i = sindex; i < lindex; i++) {
174
535k
        gs_glyph_info_t ginfo = {0};
175
535k
        gs_glyph g;
176
535k
        g = pbfont->procs.encode_char((gs_font *)pbfont, i, GLYPH_SPACE_NAME);
177
178
        /* We're only interested in non-zero Widths entries for glyphs that actually exist in the font */
179
535k
        if (g != GS_NO_GLYPH && pdfont->Widths[i - pdfont->FirstChar] != 0.0
180
535k
          && (*pbfont->procs.glyph_info)((gs_font *)pbfont, g, NULL, GLYPH_INFO_WIDTH0, &ginfo) >= 0) {
181
400k
            fw += hypot(ginfo.width[0].x, ginfo.width[0].y);
182
400k
            ww += pdfont->Widths[i - pdfont->FirstChar];
183
400k
        }
184
535k
    }
185
    /* Only reduce font width, don't expand */
186
31.5k
    if (ww != 0.0 && fw != 0.0 && ww / fw < 1.0) {
187
10.2k
        gs_matrix nmat, smat = {1.0, 0.0, 0.0, 1.0, 0.0, 0.0};
188
10.2k
        double wscale;
189
10.2k
        smat.xx = smat.yy = ww/fw;
190
10.2k
        wscale = 1.0 / smat.xx;
191
192
10.2k
        gs_matrix_multiply(&pbfont->FontMatrix, &smat, &nmat);
193
10.2k
        memcpy(&pbfont->FontMatrix, &nmat, sizeof(pbfont->FontMatrix));
194
195
1.27M
        for (i = pdfont->FirstChar; i <= pdfont->LastChar; i++) {
196
1.26M
            pdfont->Widths[i - pdfont->FirstChar] *= wscale;
197
1.26M
        }
198
199
        /* Purging a font can be expensive, but in this case, we know
200
           we have no scaled instances (pdfi doesn't work that way)
201
           and we know we have no fm pairs, nor glyphs to purge (we
202
           *just* created the font!).
203
           So "purging" the font is really just removing it from the
204
           doubly linked list of font objects in the font directory
205
         */
206
10.2k
        code = gs_purge_font((gs_font *)pbfont);
207
10.2k
        if (code >= 0)
208
10.2k
            code = gs_definefont(pbfont->dir, (gs_font *)pbfont);
209
10.2k
        if (code >= 0)
210
10.2k
            code = pdfi_fapi_passfont((pdf_font *)pdfont, 0, NULL, NULL, NULL, 0);
211
10.2k
    }
212
213
31.5k
    return code;
214
928k
}
215
216
/* Print a name object to stdout */
217
static void pdfi_print_font_name(pdf_context *ctx, pdf_name *n)
218
965k
{
219
965k
    if (ctx->args.QUIET != true)
220
0
        (void)outwrite(ctx->memory, (const char *)n->data, n->length);
221
965k
}
222
223
static void pdfi_print_font_string(pdf_context *ctx, pdf_string *s)
224
949k
{
225
949k
    if (ctx->args.QUIET != true)
226
0
        (void)outwrite(ctx->memory, (const char *)s->data, s->length);
227
949k
}
228
229
/* Print a null terminated string to stdout */
230
static void pdfi_print_cstring(pdf_context *ctx, const char *str)
231
2.91M
{
232
2.91M
    if (ctx->args.QUIET != true)
233
0
        (void)outwrite(ctx->memory, str, strlen(str));
234
2.91M
}
235
236
/* Call with a CIDFont name to try to find the CIDFont on disk
237
   call if with ffname NULL to load the default fallback CIDFont
238
   substitue
239
   Currently only loads substitute - DroidSansFallback
240
 */
241
static int
242
pdfi_open_CIDFont_substitute_file(pdf_context *ctx, pdf_dict *font_dict, pdf_dict *fontdesc, bool fallback, byte ** buf, int64_t * buflen, int *findex)
243
33.0k
{
244
33.0k
    int code = 0;
245
33.0k
    char fontfname[gp_file_name_sizeof];
246
33.0k
    stream *s;
247
33.0k
    pdf_name *cidname = NULL;
248
33.0k
    gs_const_string fname;
249
250
33.0k
    (void)pdfi_dict_get(ctx, font_dict, "BaseFont", (pdf_obj **)&cidname);
251
252
33.0k
    if (fallback == true) {
253
16.5k
        pdf_string *mname = NULL;
254
16.5k
        pdf_dict *csi = NULL;
255
16.5k
        pdf_name *fbname;
256
16.5k
        const char *cidfbstr = "CIDFallBack";
257
258
16.5k
        code = pdfi_fontmap_lookup_cidfont(ctx, font_dict, NULL, (pdf_obj **)&mname, findex);
259
260
16.5k
        if (mname == NULL || pdfi_type_of(mname) != PDF_STRING) {
261
16.5k
            pdfi_countdown(mname);
262
263
16.5k
            code = pdfi_object_alloc(ctx, PDF_NAME, strlen(cidfbstr), (pdf_obj **)&fbname);
264
16.5k
            if (code >= 0) {
265
16.5k
                pdfi_countup(fbname);
266
16.5k
                memcpy(fbname->data, cidfbstr, strlen(cidfbstr));
267
16.5k
                code = pdfi_fontmap_lookup_cidfont(ctx, font_dict, fbname, (pdf_obj **)&mname, findex);
268
16.5k
                pdfi_countdown(fbname);
269
16.5k
            }
270
271
16.5k
            if (code < 0 || pdfi_type_of(mname) != PDF_STRING) {
272
16.5k
                pdfi_countdown(mname);
273
16.5k
                mname = NULL;
274
16.5k
                code = pdfi_dict_get(ctx, font_dict, "CIDSystemInfo", (pdf_obj **)&csi);
275
16.5k
                if (code >= 0 && pdfi_type_of(csi) == PDF_DICT) {
276
13.3k
                    pdf_string *csi_reg = NULL, *csi_ord = NULL;
277
278
13.3k
                    if (pdfi_dict_get(ctx, csi, "Registry", (pdf_obj **)&csi_reg) >= 0
279
13.3k
                     && pdfi_dict_get(ctx, csi, "Ordering", (pdf_obj **)&csi_ord) >= 0
280
13.3k
                     && pdfi_type_of(csi_reg) == PDF_STRING && pdfi_type_of(csi_ord) == PDF_STRING
281
13.3k
                     && csi_reg->length + csi_ord->length + 1 < gp_file_name_sizeof - 1) {
282
13.1k
                        pdf_name *reg_ord;
283
13.1k
                        memcpy(fontfname, csi_reg->data, csi_reg->length);
284
13.1k
                        memcpy(fontfname + csi_reg->length, "-", 1);
285
13.1k
                        memcpy(fontfname + csi_reg->length + 1, csi_ord->data, csi_ord->length);
286
13.1k
                        fontfname[csi_reg->length + csi_ord->length + 1] = '\0';
287
288
13.1k
                        code = pdfi_name_alloc(ctx, (byte *)fontfname, strlen(fontfname), (pdf_obj **) &reg_ord);
289
13.1k
                        if (code >= 0) {
290
13.1k
                            pdfi_countup(reg_ord);
291
13.1k
                            code = pdfi_fontmap_lookup_cidfont(ctx, font_dict, reg_ord, (pdf_obj **)&mname, findex);
292
13.1k
                            pdfi_countdown(reg_ord);
293
13.1k
                        }
294
13.1k
                    }
295
13.3k
                    pdfi_countdown(csi_reg);
296
13.3k
                    pdfi_countdown(csi_ord);
297
13.3k
                }
298
16.5k
                pdfi_countdown(csi);
299
16.5k
            }
300
301
16.5k
            if (mname == NULL || pdfi_type_of(mname) != PDF_STRING) {
302
16.5k
                pdfi_countdown(mname);
303
16.5k
                mname = NULL;
304
16.5k
                code = pdfi_fontmap_lookup_cidfont(ctx, font_dict, NULL, (pdf_obj **)&mname, findex);
305
16.5k
            }
306
16.5k
        }
307
308
16.5k
        do {
309
16.5k
            if (code < 0 || pdfi_type_of(mname) != PDF_STRING) {
310
16.5k
                const char *fsprefix = "CIDFSubst/";
311
16.5k
                int fsprefixlen = strlen(fsprefix);
312
16.5k
                const char *defcidfallack = "DroidSansFallback.ttf";
313
16.5k
                int defcidfallacklen = strlen(defcidfallack);
314
315
16.5k
                pdfi_countdown(mname);
316
317
16.5k
                if (ctx->args.nocidfallback == true) {
318
0
                    code = gs_note_error(gs_error_invalidfont);
319
0
                }
320
16.5k
                else {
321
16.5k
                    if (ctx->args.cidfsubstpath.data == NULL) {
322
16.5k
                        memcpy(fontfname, fsprefix, fsprefixlen);
323
16.5k
                    }
324
0
                    else {
325
0
                        if (ctx->args.cidfsubstpath.size > gp_file_name_sizeof - 1) {
326
0
                            code = gs_note_error(gs_error_rangecheck);
327
0
                            if ((code = pdfi_set_warning_stop(ctx, code, NULL, W_PDF_BAD_CONFIG, "pdfi_open_CIDFont_substitute_file", "CIDFSubstPath parameter too long")) < 0)
328
0
                                goto exit;
329
0
                            memcpy(fontfname, fsprefix, fsprefixlen);
330
0
                        }
331
0
                        else {
332
0
                            memcpy(fontfname, ctx->args.cidfsubstpath.data, ctx->args.cidfsubstpath.size);
333
0
                            fsprefixlen = ctx->args.cidfsubstpath.size;
334
0
                        }
335
0
                    }
336
337
16.5k
                    if (ctx->args.cidfsubstfont.data == NULL) {
338
16.5k
                        int len = 0;
339
16.5k
                        if (gp_getenv("CIDFSUBSTFONT", (char *)0, &len) < 0) {
340
0
                            if (len + fsprefixlen + 1 > gp_file_name_sizeof) {
341
0
                                code = gs_note_error(gs_error_rangecheck);
342
0
                                if ((code = pdfi_set_warning_stop(ctx, code, NULL, W_PDF_BAD_CONFIG, "pdfi_open_CIDFont_substitute_file", "CIDFSUBSTFONT environment variable too long")) < 0)
343
0
                                    goto exit;
344
345
0
                                if (defcidfallacklen + fsprefixlen > gp_file_name_sizeof - 1) {
346
0
                                    pdfi_set_warning(ctx, code, NULL, W_PDF_BAD_CONFIG, "pdfi_open_CIDFont_substitute_file", "CIDFSubstPath parameter too long");
347
0
                                    memcpy(fontfname, defcidfallack, defcidfallacklen);
348
0
                                    fsprefixlen = 0;
349
0
                                } else
350
0
                                    memcpy(fontfname + fsprefixlen, defcidfallack, defcidfallacklen);
351
0
                            }
352
0
                            else {
353
0
                                (void)gp_getenv("CIDFSUBSTFONT", (char *)(fontfname + fsprefixlen), &defcidfallacklen);
354
0
                            }
355
0
                        }
356
16.5k
                        else {
357
16.5k
                            if (fsprefixlen + defcidfallacklen > gp_file_name_sizeof - 1) {
358
0
                                code = gs_note_error(gs_error_rangecheck);
359
0
                                if ((code = pdfi_set_warning_stop(ctx, code, NULL, W_PDF_BAD_CONFIG, "pdfi_open_CIDFont_substitute_file", "CIDFSUBSTFONT environment variable too long")) < 0)
360
0
                                    goto exit;
361
362
0
                                memcpy(fontfname, defcidfallack, defcidfallacklen);
363
                                /* cidfsubstfont should either be a font name we find in the search path(s)
364
                                   or an absolute path.
365
                                 */
366
0
                                fsprefixlen = 0;
367
0
                            }
368
16.5k
                            else {
369
16.5k
                                memcpy(fontfname + fsprefixlen, defcidfallack, defcidfallacklen);
370
16.5k
                            }
371
16.5k
                        }
372
16.5k
                    }
373
0
                    else {
374
0
                        if (ctx->args.cidfsubstfont.size + fsprefixlen > gp_file_name_sizeof - 1) {
375
0
                            code = gs_note_error(gs_error_rangecheck);
376
0
                            if ((code = pdfi_set_warning_stop(ctx, code, NULL, W_PDF_BAD_CONFIG, "pdfi_open_CIDFont_substitute_file", "CIDFSubstFont parameter too long")) < 0)
377
0
                                goto exit;
378
379
0
                            if (fsprefixlen + defcidfallacklen > gp_file_name_sizeof - 1) {
380
0
                                pdfi_set_warning(ctx, code, NULL, W_PDF_BAD_CONFIG, "pdfi_open_CIDFont_substitute_file", "CIDFSubstPath parameter too long");
381
0
                                memcpy(fontfname, defcidfallack, defcidfallacklen);
382
0
                                fsprefixlen = 0;
383
0
                            }
384
0
                            else
385
0
                                memcpy(fontfname + fsprefixlen, defcidfallack, defcidfallacklen);
386
0
                        }
387
0
                        else {
388
0
                            if (ctx->args.cidfsubstfont.size > gp_file_name_sizeof - 1) {
389
0
                                code = gs_note_error(gs_error_rangecheck);
390
0
                                if ((code = pdfi_set_warning_stop(ctx, code, NULL, W_PDF_BAD_CONFIG, "pdfi_open_CIDFont_substitute_file", "CIDFSubstFont parameter too long")) < 0)
391
0
                                    goto exit;
392
393
0
                                memcpy(fontfname, defcidfallack, defcidfallacklen);
394
0
                                defcidfallacklen = ctx->args.cidfsubstfont.size;
395
                                /* cidfsubstfont should either be a font name we find in the search path(s)
396
                                   or an absolute path.
397
                                 */
398
0
                                fsprefixlen = 0;
399
0
                            }
400
0
                            else {
401
0
                                memcpy(fontfname, ctx->args.cidfsubstfont.data, ctx->args.cidfsubstfont.size);
402
0
                                defcidfallacklen = ctx->args.cidfsubstfont.size;
403
                                /* cidfsubstfont should either be a font name we find in the search path(s)
404
                                   or an absolute path.
405
                                 */
406
0
                                fsprefixlen = 0;
407
0
                            }
408
0
                        }
409
0
                    }
410
16.5k
                    fontfname[fsprefixlen + defcidfallacklen] = '\0';
411
412
16.5k
                    code = pdfi_open_resource_file(ctx, fontfname, strlen(fontfname), &s);
413
16.5k
                    if (code < 0) {
414
0
                        pdf_name *fn;
415
0
                        code = pdfi_object_alloc(ctx, PDF_NAME, strlen(fontfname), (pdf_obj **)&fn);
416
0
                        if (code < 0) {
417
0
                            code = gs_note_error(gs_error_invalidfont);
418
0
                        }
419
0
                        else {
420
0
                            pdfi_countup(fn);
421
0
                            memcpy(fn->data, fontfname, strlen(fontfname));
422
0
                            pdfi_countdown(mname);
423
0
                            mname = NULL;
424
0
                            code = pdfi_fontmap_lookup_cidfont(ctx, font_dict, fn, (pdf_obj **)&mname, findex);
425
0
                            pdfi_countdown(fn);
426
0
                            if (code < 0)
427
0
                                code = gs_note_error(gs_error_invalidfont);
428
0
                            else
429
0
                                continue;
430
0
                        }
431
0
                    }
432
16.5k
                    else {
433
16.5k
                        if (cidname) {
434
16.2k
                            pdfi_print_cstring(ctx, "Loading CIDFont ");
435
16.2k
                            pdfi_print_font_name(ctx, (pdf_name *)cidname);
436
16.2k
                            pdfi_print_cstring(ctx, " substitute from ");
437
16.2k
                        }
438
315
                        else {
439
315
                            pdfi_print_cstring(ctx, "Loading nameless CIDFont from ");
440
315
                        }
441
16.5k
                        sfilename(s, &fname);
442
16.5k
                        if (fname.size < gp_file_name_sizeof) {
443
16.5k
                            memcpy(fontfname, fname.data, fname.size);
444
16.5k
                            fontfname[fname.size] = '\0';
445
16.5k
                        }
446
0
                        else {
447
0
                            strcpy(fontfname, "unnamed file");
448
0
                        }
449
16.5k
                        pdfi_print_cstring(ctx, fontfname);
450
16.5k
                        pdfi_print_cstring(ctx, "\n");
451
452
453
16.5k
                        sfseek(s, 0, SEEK_END);
454
16.5k
                        *buflen = sftell(s);
455
16.5k
                        sfseek(s, 0, SEEK_SET);
456
16.5k
                        *buf = gs_alloc_bytes(ctx->memory, *buflen, "pdfi_open_CIDFont_file(buf)");
457
16.5k
                        if (*buf != NULL) {
458
16.5k
                            sfread(*buf, 1, *buflen, s);
459
16.5k
                        }
460
0
                        else {
461
0
                            code = gs_note_error(gs_error_VMerror);
462
0
                        }
463
16.5k
                        sfclose(s);
464
16.5k
                        break;
465
16.5k
                    }
466
16.5k
                }
467
16.5k
            }
468
0
            else {
469
0
                if (mname->length + 1 > gp_file_name_sizeof) {
470
0
                    pdfi_countdown(mname);
471
0
                    return_error(gs_error_invalidfont);
472
0
                }
473
0
                memcpy(fontfname, mname->data, mname->length);
474
0
                fontfname[mname->length] = '\0';
475
0
                code = pdfi_open_resource_file(ctx, (const char *)fontfname, mname->length, &s);
476
0
                pdfi_countdown(mname);
477
0
                if (code < 0) {
478
0
                    code = gs_note_error(gs_error_invalidfont);
479
0
                }
480
0
                else {
481
0
                    if (cidname) {
482
0
                        pdfi_print_cstring(ctx, "Loading CIDFont ");
483
0
                        pdfi_print_font_name(ctx, (pdf_name *)cidname);
484
0
                        pdfi_print_cstring(ctx, " (or substitute) from ");
485
0
                    }
486
0
                    else {
487
0
                        pdfi_print_cstring(ctx, "Loading nameless CIDFont from ");
488
0
                    }
489
0
                    sfilename(s, &fname);
490
0
                    if (fname.size < gp_file_name_sizeof) {
491
0
                        memcpy(fontfname, fname.data, fname.size);
492
0
                        fontfname[fname.size] = '\0';
493
0
                    }
494
0
                    else {
495
0
                        strcpy(fontfname, "unnamed file");
496
0
                    }
497
0
                    pdfi_print_cstring(ctx, fontfname);
498
0
                    pdfi_print_cstring(ctx, "\n");
499
0
                    sfseek(s, 0, SEEK_END);
500
0
                    *buflen = sftell(s);
501
0
                    sfseek(s, 0, SEEK_SET);
502
0
                    *buf = gs_alloc_bytes(ctx->memory, *buflen, "pdfi_open_CIDFont_file(buf)");
503
0
                    if (*buf != NULL) {
504
0
                        sfread(*buf, 1, *buflen, s);
505
0
                    }
506
0
                    else {
507
0
                        code = gs_note_error(gs_error_VMerror);
508
0
                    }
509
0
                    sfclose(s);
510
0
                    break;
511
0
                }
512
0
            }
513
16.5k
        } while (code >= 0);
514
16.5k
    }
515
16.5k
    else {
516
16.5k
        const char *fsprefix = "CIDFont/";
517
16.5k
        const int fsprefixlen = strlen(fsprefix);
518
519
16.5k
        if (cidname == NULL || pdfi_type_of(cidname) != PDF_NAME
520
16.5k
         || fsprefixlen + cidname->length >= gp_file_name_sizeof) {
521
323
            code = gs_note_error(gs_error_invalidfont);
522
323
            goto exit;
523
323
        }
524
525
16.2k
        memcpy(fontfname, fsprefix, fsprefixlen);
526
16.2k
        memcpy(fontfname + fsprefixlen, cidname->data, cidname->length);
527
16.2k
        fontfname[fsprefixlen + cidname->length] = '\0';
528
529
16.2k
        code = pdfi_open_resource_file(ctx, fontfname, strlen(fontfname), &s);
530
16.2k
        if (code < 0) {
531
16.2k
            code = gs_note_error(gs_error_invalidfont);
532
16.2k
        }
533
0
        else {
534
0
            sfseek(s, 0, SEEK_END);
535
0
            *buflen = sftell(s);
536
0
            sfseek(s, 0, SEEK_SET);
537
0
            *buf = gs_alloc_bytes(ctx->memory, *buflen, "pdfi_open_CIDFont_file(buf)");
538
0
            if (*buf != NULL) {
539
0
                sfread(*buf, 1, *buflen, s);
540
0
            }
541
0
            else {
542
0
                code = gs_note_error(gs_error_invalidfont);
543
0
            }
544
0
            sfclose(s);
545
0
        }
546
16.2k
    }
547
548
33.0k
exit:
549
33.0k
    if (cidname != NULL)
550
32.4k
        pdfi_countdown(cidname);
551
552
33.0k
    return code;
553
33.0k
}
554
555
enum
556
{
557
    pdfi_font_flag_none =        0x00000,
558
    pdfi_font_flag_fixed =       0x00001,
559
    pdfi_font_flag_serif =       0x00002,
560
    pdfi_font_flag_symbolic =    0x00004,
561
    pdfi_font_flag_script =      0x00008,
562
    pdfi_font_flag_nonsymbolic = 0x00020,
563
    pdfi_font_flag_italic =      0x00040,
564
    pdfi_font_flag_allcap =      0x10000,
565
    pdfi_font_flag_smallcap =    0x20000,
566
    pdfi_font_flag_forcebold =   0x40000
567
};
568
569
/* Barefaced theft from mupdf! */
570
static const char *pdfi_base_font_names[][10] =
571
{
572
  { "Courier", "CourierNew", "CourierNewPSMT", "CourierStd", NULL },
573
  { "Courier-Bold", "CourierNew,Bold", "Courier,Bold", "CourierNewPS-BoldMT", "CourierNew-Bold", NULL },
574
  { "Courier-Oblique", "CourierNew,Italic", "Courier,Italic", "CourierNewPS-ItalicMT", "CourierNew-Italic", NULL },
575
  { "Courier-BoldOblique", "CourierNew,BoldItalic", "Courier,BoldItalic", "CourierNewPS-BoldItalicMT", "CourierNew-BoldItalic", NULL },
576
  { "Helvetica", "ArialMT", "Arial", NULL },
577
  { "Helvetica-Bold", "Arial-BoldMT", "Arial,Bold", "Arial-Bold", "Helvetica,Bold", NULL },
578
  { "Helvetica-Oblique", "Arial-ItalicMT", "Arial,Italic", "Arial-Italic", "Helvetica,Italic", "Helvetica-Italic", NULL },
579
  { "Helvetica-BoldOblique", "Arial-BoldItalicMT", "Arial,BoldItalic", "Arial-BoldItalic", "Helvetica,BoldItalic", "Helvetica-BoldItalic", NULL },
580
  { "Times-Roman", "TimesNewRomanPSMT", "TimesNewRoman", "TimesNewRomanPS", NULL },
581
  { "Times-Bold", "TimesNewRomanPS-BoldMT", "TimesNewRoman,Bold", "TimesNewRomanPS-Bold", "TimesNewRoman-Bold", NULL },
582
  { "Times-Italic", "TimesNewRomanPS-ItalicMT", "TimesNewRoman,Italic", "TimesNewRomanPS-Italic", "TimesNewRoman-Italic", NULL },
583
  { "Times-BoldItalic", "TimesNewRomanPS-BoldItalicMT", "TimesNewRoman,BoldItalic", "TimesNewRomanPS-BoldItalic", "TimesNewRoman-BoldItalic", NULL },
584
  { "Symbol", "Symbol,Italic", "Symbol,Bold", "Symbol,BoldItalic", "SymbolMT", "SymbolMT,Italic", "SymbolMT,Bold", "SymbolMT,BoldItalic", NULL },
585
  { "ZapfDingbats", NULL }
586
};
587
588
static int strncmp_ignore_space(const char *a, const char *b)
589
119M
{
590
139M
    while (1)
591
139M
    {
592
139M
        while (*a == ' ')
593
0
            a++;
594
139M
        while (*b == ' ')
595
4.90k
            b++;
596
139M
        if (*a != *b)
597
119M
            return 1;
598
20.1M
        if (*a == 0)
599
9.44k
            return *a != *b;
600
20.1M
        if (*b == 0)
601
0
            return *a != *b;
602
20.1M
        a++;
603
20.1M
        b++;
604
20.1M
    }
605
0
    return 0; /* Shouldn't happen */
606
119M
}
607
608
static const char *pdfi_clean_font_name(const char *fontname)
609
1.79M
{
610
1.79M
    int i, k;
611
26.8M
    for (i = 0; i < (sizeof(pdfi_base_font_names)/sizeof(pdfi_base_font_names[0])); i++) {
612
144M
        for (k = 0; pdfi_base_font_names[i][k]; k++) {
613
119M
            if (!strncmp_ignore_space(pdfi_base_font_names[i][k], (const char *)fontname))
614
9.44k
                return pdfi_base_font_names[i][0];
615
119M
        }
616
25.0M
    }
617
1.78M
    return NULL;
618
1.79M
}
619
620
static int pdfi_font_substitute_by_flags(pdf_context *ctx, unsigned int flags, char **name, int *namelen)
621
920k
{
622
920k
    bool fixed = ((flags & pdfi_font_flag_fixed) != 0);
623
920k
    bool serif = ((flags & pdfi_font_flag_serif) != 0);
624
920k
    bool italic = ((flags & pdfi_font_flag_italic) != 0);
625
920k
    bool bold = ((flags & pdfi_font_flag_forcebold) != 0);
626
920k
    int code = 0;
627
628
920k
    if (ctx->args.defaultfont_is_name == true && ctx->args.defaultfont.size == 4
629
920k
        && !memcmp(ctx->args.defaultfont.data, "None", 4)) {
630
0
       *name = NULL;
631
0
       *namelen = 0;
632
0
       code = gs_error_invalidfont;
633
0
    }
634
920k
    else if (ctx->args.defaultfont.data != NULL && ctx->args.defaultfont.size > 0) {
635
0
        *name = (char *)ctx->args.defaultfont.data;
636
0
        *namelen = ctx->args.defaultfont.size;
637
0
    }
638
920k
    else if (fixed) {
639
263
        if (bold) {
640
4
            if (italic) {
641
4
                *name = (char *)pdfi_base_font_names[3][0];
642
4
                *namelen = strlen(*name);
643
4
            }
644
0
            else {
645
0
                *name = (char *)pdfi_base_font_names[1][0];
646
0
                *namelen = strlen(*name);
647
0
            }
648
4
        }
649
259
        else {
650
259
            if (italic) {
651
3
                *name = (char *)pdfi_base_font_names[2][0];
652
3
                *namelen = strlen(*name);
653
3
            }
654
256
            else {
655
256
                *name = (char *)pdfi_base_font_names[0][0];
656
256
                *namelen = strlen(*name);
657
256
            }
658
259
        }
659
263
    }
660
920k
    else if (serif) {
661
2.32k
        if (bold) {
662
9
            if (italic) {
663
0
                *name = (char *)pdfi_base_font_names[11][0];
664
0
                *namelen = strlen(*name);
665
0
            }
666
9
            else {
667
9
                *name = (char *)pdfi_base_font_names[9][0];
668
9
                *namelen = strlen(*name);
669
9
            }
670
9
        }
671
2.31k
        else {
672
2.31k
            if (italic) {
673
231
                *name = (char *)pdfi_base_font_names[10][0];
674
231
                *namelen = strlen(*name);
675
231
            }
676
2.08k
            else {
677
2.08k
                *name = (char *)pdfi_base_font_names[8][0];
678
2.08k
                *namelen = strlen(*name);
679
2.08k
            }
680
2.31k
        }
681
917k
    } else {
682
917k
        if (bold) {
683
164
            if (italic) {
684
0
                *name = (char *)pdfi_base_font_names[7][0];
685
0
                *namelen = strlen(*name);
686
0
            }
687
164
            else {
688
164
                *name = (char *)pdfi_base_font_names[5][0];
689
164
                *namelen = strlen(*name);
690
164
            }
691
164
        }
692
917k
        else {
693
917k
            if (italic) {
694
715
                *name = (char *)pdfi_base_font_names[6][0];
695
715
                *namelen = strlen(*name);
696
715
            }
697
916k
            else {
698
916k
                *name = (char *)pdfi_base_font_names[4][0];
699
916k
                *namelen = strlen(*name);
700
916k
            }
701
917k
        }
702
917k
    }
703
920k
    return code;
704
920k
}
705
706
enum {
707
  no_type_font = -1,
708
  type0_font = 0,
709
  type1_font = 1,
710
  cff_font = 2,
711
  type3_font = 3,
712
  tt_font = 42
713
};
714
715
static int pdfi_fonttype_picker(byte *buf, int64_t buflen)
716
148k
{
717
1.36M
#define MAKEMAGIC(a, b, c, d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
718
719
148k
    if (buflen >= 4) {
720
148k
        if (MAKEMAGIC(buf[0], buf[1], buf[2], buf[3]) == MAKEMAGIC(0, 1, 0, 0)
721
148k
            || MAKEMAGIC(buf[0], buf[1], buf[2], buf[3]) == MAKEMAGIC('t', 'r', 'u', 'e')
722
148k
            || MAKEMAGIC(buf[0], buf[1], buf[2], buf[3]) == MAKEMAGIC('t', 't', 'c', 'f')) {
723
56.7k
            return tt_font;
724
56.7k
        }
725
91.2k
        else if (MAKEMAGIC(buf[0], buf[1], buf[2], buf[3]) == MAKEMAGIC('O', 'T', 'T', 'O')) {
726
649
            return cff_font; /* OTTO will end up as CFF */
727
649
        }
728
90.6k
        else if (MAKEMAGIC(buf[0], buf[1], buf[2], 0) == MAKEMAGIC('%', '!', 'P', 0)) {
729
75.9k
            return type1_font; /* pfa */
730
75.9k
        }
731
14.6k
        else if (MAKEMAGIC(buf[0], buf[1], buf[2], 0) == MAKEMAGIC(1, 0, 4, 0)) {
732
13.8k
            return cff_font; /* 1C/CFF */
733
13.8k
        }
734
841
        else if (MAKEMAGIC(buf[0], buf[1], 0, 0) == MAKEMAGIC(128, 1, 0, 0)) {
735
201
            return type1_font; /* pfb */
736
201
        }
737
148k
    }
738
664
    return no_type_font;
739
148k
#undef MAKEMAGIC
740
148k
}
741
742
static int pdfi_copy_font(pdf_context *ctx, pdf_font *spdffont, pdf_dict *font_dict, pdf_font **tpdffont)
743
953k
{
744
953k
    int code;
745
953k
    if (pdfi_type_of(spdffont) != PDF_FONT)
746
0
        return_error(gs_error_typecheck);
747
748
953k
    switch(spdffont->pdfi_font_type) {
749
950k
        case e_pdf_font_type1:
750
950k
          code = pdfi_copy_type1_font(ctx, spdffont, font_dict, tpdffont);
751
950k
          break;
752
107
        case e_pdf_font_cff:
753
107
          code = pdfi_copy_cff_font(ctx, spdffont, font_dict, tpdffont);
754
107
          break;
755
3.78k
        case e_pdf_font_truetype:
756
3.78k
          code = pdfi_copy_truetype_font(ctx, spdffont, font_dict, tpdffont);
757
3.78k
          break;
758
0
        case e_pdf_font_microtype:
759
0
          code = pdfi_copy_microtype_font(ctx, spdffont, font_dict, tpdffont);
760
0
          break;
761
0
        default:
762
0
            return_error(gs_error_invalidfont);
763
953k
    }
764
953k
    return code;
765
953k
}
766
767
enum {
768
  font_embedded = 0,
769
  font_from_file = 1,
770
  font_substitute = 2
771
};
772
773
static int pdfi_load_font_buffer(pdf_context *ctx, byte *fbuf, int fbuflen, int fftype, pdf_name *Subtype, int findex, pdf_dict *stream_dict, pdf_dict *page_dict, pdf_dict *font_dict, pdf_font **ppdffont, bool cidfont)
774
148k
{
775
148k
    int code = gs_error_invalidfont;
776
148k
    if (fbuf != NULL) {
777
        /* First, see if we can glean the type from the magic number */
778
148k
        int sftype = pdfi_fonttype_picker(fbuf, fbuflen);
779
148k
        if (sftype == no_type_font) {
780
664
            if (fftype != no_type_font)
781
636
                sftype = fftype;
782
28
            else {
783
                /* If we don't have a Subtype, can't work it out, try Type 1 */
784
28
                if (Subtype == NULL || pdfi_name_is(Subtype, "Type1") || pdfi_name_is(Subtype, "MMType1"))
785
25
                    sftype = type1_font;
786
3
                else if (pdfi_name_is(Subtype, "Type1C"))
787
0
                    sftype = cff_font;
788
3
                else if (pdfi_name_is(Subtype, "TrueType"))
789
0
                    sftype = tt_font;
790
28
            }
791
664
        }
792
        /* fbuf ownership passes to the font loader */
793
148k
        switch (sftype) {
794
76.5k
            case type1_font:
795
76.5k
                code = pdfi_read_type1_font(ctx, (pdf_dict *)font_dict, stream_dict, page_dict, fbuf, fbuflen, ppdffont);
796
76.5k
                fbuf = NULL;
797
76.5k
                break;
798
14.5k
            case cff_font:
799
14.5k
                code = pdfi_read_cff_font(ctx, (pdf_dict *)font_dict, stream_dict, page_dict, fbuf, fbuflen, cidfont, ppdffont);
800
14.5k
                fbuf = NULL;
801
14.5k
                break;
802
56.9k
            case tt_font:
803
56.9k
                {
804
56.9k
                    if (cidfont)
805
26.2k
                        code = pdfi_read_cidtype2_font(ctx, font_dict, stream_dict, page_dict, fbuf, fbuflen, findex, ppdffont);
806
30.6k
                    else
807
30.6k
                        code = pdfi_read_truetype_font(ctx, font_dict, stream_dict, page_dict, fbuf, fbuflen, findex, ppdffont);
808
56.9k
                    fbuf = NULL;
809
56.9k
                }
810
56.9k
                break;
811
3
            default:
812
3
                gs_free_object(ctx->memory, fbuf, "pdfi_load_font_buffer(fbuf)");
813
3
                code = gs_note_error(gs_error_invalidfont);
814
148k
        }
815
148k
    }
816
148k
    return code;
817
148k
}
818
819
static int pdfi_load_font_file(pdf_context *ctx, int fftype, pdf_name *Subtype, pdf_dict *stream_dict, pdf_dict *page_dict, pdf_dict *font_dict, pdf_dict *fontdesc, bool substitute, pdf_font **ppdffont)
820
1.87M
{
821
1.87M
    int code;
822
1.87M
    char fontfname[gp_file_name_sizeof];
823
1.87M
    pdf_obj *basefont = NULL, *mapname = NULL;
824
1.87M
    pdf_obj *fontname = NULL;
825
1.87M
    stream *s = NULL;
826
1.87M
    const char *fn;
827
1.87M
    int findex = 0;
828
1.87M
    byte *buf;
829
1.87M
    int buflen;
830
1.87M
    pdf_font *pdffont = NULL;
831
1.87M
    pdf_font *substpdffont = NULL;
832
1.87M
    bool f_retry = true;
833
834
1.87M
    code = pdfi_dict_knownget_type(ctx, font_dict, "BaseFont", PDF_NAME, &basefont);
835
1.87M
    if (substitute == false && (code < 0 || basefont == NULL || ((pdf_name *)basefont)->length == 0)) {
836
28.1k
        pdfi_countdown(basefont);
837
28.1k
        return_error(gs_error_invalidfont);
838
28.1k
    }
839
840
1.84M
    if (substitute == true) {
841
920k
        char *fbname;
842
920k
        int fbnamelen;
843
920k
        int64_t flags = 0;
844
920k
        if (fontdesc != NULL) {
845
29.0k
            (void)pdfi_dict_get_int(ctx, fontdesc, "Flags", &flags);
846
29.0k
        }
847
920k
        code = pdfi_font_substitute_by_flags(ctx, (int)flags, &fbname, &fbnamelen);
848
920k
        if (code < 0)
849
0
            return code;
850
851
920k
        code = pdfi_name_alloc(ctx, (byte *)fbname, strlen(fbname), (pdf_obj **) &fontname);
852
920k
        if (code < 0)
853
0
            return code;
854
920k
        pdfi_countup(fontname);
855
920k
    }
856
921k
    else {
857
921k
        fontname = basefont;
858
921k
        pdfi_countup(fontname);
859
921k
    }
860
861
1.84M
    if (((pdf_name *)fontname)->length < gp_file_name_sizeof) {
862
1.84M
        memcpy(fontfname, ((pdf_name *)fontname)->data, ((pdf_name *)fontname)->length);
863
1.84M
        fontfname[((pdf_name *)fontname)->length] = '\0';
864
1.84M
        pdfi_countdown(fontname);
865
866
1.84M
        code = pdfi_name_alloc(ctx, (byte *)fontfname, strlen(fontfname), (pdf_obj **) &fontname);
867
1.84M
        if (code < 0)
868
0
            return code;
869
1.84M
        pdfi_countup(fontname);
870
1.84M
    }
871
2
    else {
872
        /* Just to ensure that fontfname is a valid, though empty, string */
873
2
        fontfname[0] = '\0';
874
2
    }
875
876
2.73M
    do {
877
2.73M
        if (f_retry == true && pdfi_font_file_exists(ctx, (const char *)((pdf_name *)fontname)->data, ((pdf_name *)fontname)->length) == true) {
878
0
            code = 0;
879
0
        }
880
2.73M
        else {
881
2.73M
            code = pdfi_fontmap_lookup_font(ctx, font_dict, (pdf_name *) fontname, &mapname, &findex);
882
2.73M
            if (code < 0) {
883
1.79M
                if (((pdf_name *)fontname)->length < gp_file_name_sizeof) {
884
1.79M
                    memcpy(fontfname, ((pdf_name *)fontname)->data, ((pdf_name *)fontname)->length);
885
1.79M
                    fontfname[((pdf_name *)fontname)->length] = '\0';
886
1.79M
                    fn = pdfi_clean_font_name(fontfname);
887
1.79M
                    if (fn != NULL) {
888
9.44k
                        pdfi_countdown(fontname);
889
890
9.44k
                        code = pdfi_name_alloc(ctx, (byte *)fn, strlen(fn), (pdf_obj **) &fontname);
891
9.44k
                        if (code < 0)
892
0
                            return code;
893
9.44k
                        pdfi_countup(fontname);
894
9.44k
                    }
895
1.79M
                }
896
1.79M
                code = pdfi_fontmap_lookup_font(ctx, font_dict, (pdf_name *) fontname, &mapname, &findex);
897
1.79M
                if (code < 0) {
898
1.78M
                    mapname = fontname;
899
1.78M
                    pdfi_countup(mapname);
900
1.78M
                    code = 0;
901
1.78M
                }
902
1.79M
            }
903
2.73M
            if (pdfi_type_of(mapname) == PDF_FONT) {
904
0
                pdffont = (pdf_font *)mapname;
905
0
                pdfi_countup(pdffont);
906
0
                break;
907
0
            }
908
2.73M
            if (pdfi_type_of(mapname) == PDF_NAME || pdfi_type_of(mapname) == PDF_STRING) {
909
2.73M
                pdf_name *mname = (pdf_name *) mapname;
910
2.73M
                if (mname->length + 1 < gp_file_name_sizeof) {
911
2.73M
                    memcpy(fontfname, mname->data, mname->length);
912
2.73M
                    fontfname[mname->length] = '\0';
913
2.73M
                }
914
2
                else {
915
2
                    pdfi_countdown(mapname);
916
2
                    pdfi_countdown(fontname);
917
2
                    return_error(gs_error_invalidfileaccess);
918
2
                }
919
2.73M
            }
920
0
            else {
921
0
                pdfi_countdown(mapname);
922
0
                pdfi_countdown(fontname);
923
0
                return_error(gs_error_invalidfileaccess);
924
0
            }
925
926
2.73M
            if (ctx->pdf_substitute_fonts != NULL) {
927
2.61M
                code = pdfi_dict_knownget_type(ctx, ctx->pdf_substitute_fonts, fontfname, PDF_FONT, (pdf_obj **)&pdffont);
928
2.61M
                if (code == 1 && pdffont->filename == NULL) {
929
0
                    pdfi_countdown(pdffont);
930
0
                    pdffont = NULL;
931
0
                    code = 0;
932
0
                }
933
2.61M
            }
934
117k
            else
935
117k
                code = 0;
936
2.73M
        }
937
2.73M
        if (code != 1) {
938
1.84M
            code = pdfi_open_font_file(ctx, fontfname, strlen(fontfname), &s);
939
1.84M
            if (code < 0 && f_retry && pdfi_type_of(mapname) == PDF_NAME) {
940
895k
                pdfi_countdown(fontname);
941
895k
                fontname = mapname;
942
895k
                mapname = NULL;
943
895k
                f_retry = false;
944
895k
                continue;
945
895k
            }
946
951k
            if (code >= 0) {
947
58.8k
                gs_const_string fname;
948
949
58.8k
                sfilename(s, &fname);
950
58.8k
                if (fname.size < gp_file_name_sizeof) {
951
58.8k
                    memcpy(fontfname, fname.data, fname.size);
952
58.8k
                    fontfname[fname.size] = '\0';
953
58.8k
                }
954
0
                else {
955
0
                    strcpy(fontfname, "unnamed file");
956
0
                }
957
58.8k
                sfseek(s, 0, SEEK_END);
958
58.8k
                buflen = sftell(s);
959
58.8k
                sfseek(s, 0, SEEK_SET);
960
58.8k
                buf = gs_alloc_bytes(ctx->memory, buflen, "pdfi_open_t1_font_file(buf)");
961
58.8k
                if (buf != NULL) {
962
58.8k
                    sfread(buf, 1, buflen, s);
963
58.8k
                }
964
0
                else {
965
0
                    code = gs_note_error(gs_error_VMerror);
966
0
                }
967
58.8k
                sfclose(s);
968
                /* Buffer owership moves to the font object */
969
58.8k
                code = pdfi_load_font_buffer(ctx, buf, buflen, no_type_font, NULL, findex, stream_dict, page_dict, NULL, &pdffont, false);
970
58.8k
                if (code >= 0) {
971
58.8k
                    pdffont->filename = NULL;
972
58.8k
                    code = pdfi_object_alloc(ctx, PDF_STRING, strlen(fontfname) , (pdf_obj **)&pdffont->filename);
973
58.8k
                    if (code >= 0) {
974
58.8k
                        pdfi_countup(pdffont->filename);
975
58.8k
                        memcpy(pdffont->filename->data, fontfname, strlen(fontfname));
976
58.8k
                        pdffont->filename->length = strlen(fontfname);
977
58.8k
                    }
978
979
58.8k
                    if (ctx->pdf_substitute_fonts == NULL) {
980
45.8k
                        code = pdfi_dict_alloc(ctx, 16, &ctx->pdf_substitute_fonts);
981
45.8k
                        if (code >= 0)
982
45.8k
                            pdfi_countup(ctx->pdf_substitute_fonts);
983
45.8k
                    }
984
58.8k
                    if (ctx->pdf_substitute_fonts != NULL) {
985
58.8k
                        if (pdfi_type_of(mapname) == PDF_STRING) {
986
0
                            pdf_name *n = NULL;
987
0
                            pdf_string *mn = (pdf_string *)mapname;
988
989
0
                            code = pdfi_name_alloc(ctx, mn->data, mn->length, (pdf_obj **)&n);
990
0
                            if (code >= 0) {
991
0
                                pdfi_countdown(mapname);
992
0
                                mapname = (pdf_obj *)n;
993
0
                                pdfi_countup(mapname);
994
0
                                code = 0;
995
0
                            }
996
0
                        }
997
58.8k
                        else
998
58.8k
                            code = 0;
999
1000
58.8k
                        if (code == 0)
1001
58.8k
                            (void)pdfi_dict_put_obj(ctx, ctx->pdf_substitute_fonts, mapname, (pdf_obj *)pdffont, true);
1002
58.8k
                        code = 0;
1003
58.8k
                    }
1004
58.8k
                }
1005
58.8k
            }
1006
951k
        }
1007
1.84M
        break;
1008
2.73M
    } while (1);
1009
1010
1.84M
    if (code >= 0) {
1011
949k
        if (basefont) {
1012
948k
            pdfi_print_cstring(ctx, "Loading font ");
1013
948k
            pdfi_print_font_name(ctx, (pdf_name *)basefont);
1014
948k
            pdfi_print_cstring(ctx, " (or substitute) from ");
1015
948k
        }
1016
1.07k
        else {
1017
1.07k
            pdfi_print_cstring(ctx, "Loading nameless font from ");
1018
1.07k
        }
1019
949k
        pdfi_print_font_string(ctx, pdffont->filename);
1020
949k
        pdfi_print_cstring(ctx, "\n");
1021
1022
949k
        code = pdfi_copy_font(ctx, pdffont, font_dict, &substpdffont);
1023
949k
        pdfi_countdown(pdffont);
1024
949k
    }
1025
1026
1.84M
    *ppdffont = substpdffont;
1027
1028
1.84M
    pdfi_countdown(basefont);
1029
1.84M
    pdfi_countdown(mapname);
1030
1.84M
    pdfi_countdown(fontname);
1031
1.84M
    return code;
1032
1.84M
}
1033
1034
int pdfi_load_font(pdf_context *ctx, pdf_dict *stream_dict, pdf_dict *page_dict, pdf_dict *font_dict, gs_font **ppfont, bool cidfont)
1035
1.07M
{
1036
1.07M
    int code;
1037
1.07M
    pdf_font *ppdffont = NULL;
1038
1.07M
    pdf_font *ppdfdescfont = NULL;
1039
1.07M
    pdf_name *Type = NULL;
1040
1.07M
    pdf_name *Subtype = NULL;
1041
1.07M
    pdf_dict *fontdesc = NULL;
1042
1.07M
    pdf_stream *fontfile = NULL;
1043
1.07M
    pdf_name *ffsubtype = NULL;
1044
1.07M
    int fftype = no_type_font;
1045
1.07M
    byte *fbuf = NULL;
1046
1.07M
    int64_t fbuflen = 0;
1047
1.07M
    int substitute = font_embedded;
1048
1.07M
    int findex = 0;
1049
1050
1.07M
    code = pdfi_dict_get_type(ctx, font_dict, "Type", PDF_NAME, (pdf_obj **)&Type);
1051
1.07M
    if (code < 0) {
1052
762
        if ((code = pdfi_set_error_stop(ctx, code, NULL, E_PDF_MISSINGTYPE, "pdfi_load_font", NULL)) < 0)
1053
0
            goto exit;
1054
762
    }
1055
1.07M
    else {
1056
1.07M
        if (!pdfi_name_is(Type, "Font")){
1057
7.27k
            code = gs_note_error(gs_error_typecheck);
1058
7.27k
            goto exit;
1059
7.27k
        }
1060
1.07M
    }
1061
1.07M
    code = pdfi_dict_get_type(ctx, font_dict, "Subtype", PDF_NAME, (pdf_obj **)&Subtype);
1062
1.07M
    if (code < 0) {
1063
845
        if ((code = pdfi_set_error_stop(ctx, code, NULL, E_PDF_NO_SUBTYPE, "pdfi_load_font", NULL)) < 0)
1064
0
            goto exit;
1065
845
    }
1066
1067
    /* Beyond Type 0 and Type 3, there is no point trusting the Subtype key */
1068
1.07M
    if (Subtype != NULL && pdfi_name_is(Subtype, "Type0")) {
1069
47.0k
        if (cidfont == true) {
1070
9
            code = gs_note_error(gs_error_invalidfont);
1071
9
        }
1072
47.0k
        else {
1073
47.0k
            code = pdfi_read_type0_font(ctx, (pdf_dict *)font_dict, stream_dict, page_dict, &ppdffont);
1074
47.0k
        }
1075
47.0k
    }
1076
1.02M
    else if (Subtype != NULL && pdfi_name_is(Subtype, "Type3")) {
1077
3.12k
        code = pdfi_read_type3_font(ctx, (pdf_dict *)font_dict, stream_dict, page_dict, &ppdffont);
1078
3.12k
        if (code < 0)
1079
614
            goto exit;
1080
3.12k
    }
1081
1.02M
    else {
1082
1.02M
        if (Subtype != NULL && !pdfi_name_is(Subtype, "Type1") && !pdfi_name_is(Subtype, "TrueType") && !pdfi_name_is(Subtype, "CIDFont")
1083
1.02M
            && !pdfi_name_is(Subtype, "CIDFontType2") && !pdfi_name_is(Subtype, "CIDFontType0") && !pdfi_name_is(Subtype, "MMType1")) {
1084
1085
877
            if ((code = pdfi_set_error_stop(ctx, gs_note_error(gs_error_typecheck), NULL, E_PDF_BAD_SUBTYPE, "pdfi_load_font", NULL)) < 0) {
1086
0
                goto exit;
1087
0
            }
1088
877
        }
1089
        /* We should always have a font descriptor here, but we have to carry on
1090
           even if we don't
1091
         */
1092
1.02M
        code = pdfi_dict_get_type(ctx, font_dict, "FontDescriptor", PDF_DICT, (pdf_obj **)&fontdesc);
1093
1.02M
        if (fontdesc != NULL && pdfi_type_of(fontdesc) == PDF_DICT) {
1094
98.4k
            pdf_obj *Name = NULL;
1095
1096
98.4k
            code = pdfi_dict_get_type(ctx, (pdf_dict *) fontdesc, "FontName", PDF_NAME, (pdf_obj **)&Name);
1097
98.4k
            if (code < 0)
1098
1.28k
                pdfi_set_warning(ctx, 0, NULL, W_PDF_FDESC_BAD_FONTNAME, "pdfi_load_font", "");
1099
98.4k
            pdfi_countdown(Name);
1100
98.4k
            Name = NULL;
1101
1102
98.4k
            if (cidfont == true) {
1103
17.5k
                code = -1;
1104
17.5k
            }
1105
80.9k
            else {
1106
80.9k
                code = pdfi_find_cache_resource_font(ctx, (pdf_obj *)fontdesc, (pdf_obj **)&ppdfdescfont);
1107
80.9k
                if (code >= 0) {
1108
4.02k
                    code = pdfi_copy_font(ctx, ppdfdescfont, font_dict, &ppdffont);
1109
4.02k
                }
1110
80.9k
            }
1111
1112
98.4k
            if (code < 0) {
1113
94.4k
                code = pdfi_dict_get_type(ctx, (pdf_dict *) fontdesc, "FontFile", PDF_STREAM, (pdf_obj **)&fontfile);
1114
94.4k
                if (code >= 0)
1115
17.6k
                    fftype = type1_font;
1116
76.8k
                else {
1117
76.8k
                    code = pdfi_dict_get_type(ctx, (pdf_dict *) fontdesc, "FontFile2", PDF_STREAM, (pdf_obj **)&fontfile);
1118
76.8k
                    fftype = tt_font;
1119
76.8k
                }
1120
94.4k
                if (code < 0) {
1121
35.0k
                    code = pdfi_dict_get_type(ctx, (pdf_dict *) fontdesc, "FontFile3", PDF_STREAM, (pdf_obj **)&fontfile);
1122
35.0k
                    if (code >= 0 && fontfile != NULL) {
1123
15.0k
                        code = pdfi_dict_get_type(ctx, fontfile->stream_dict, "Subtype", PDF_NAME, (pdf_obj **)&ffsubtype);
1124
15.0k
                        if (code >= 0) {
1125
14.9k
                            if (pdfi_name_is(ffsubtype, "Type1"))
1126
0
                                fftype = type1_font;
1127
14.9k
                            else if (pdfi_name_is(ffsubtype, "Type1C"))
1128
11.5k
                                fftype = cff_font;
1129
3.44k
                            else if (pdfi_name_is(ffsubtype, "OpenType"))
1130
429
                                fftype = cff_font;
1131
3.01k
                            else if (pdfi_name_is(ffsubtype, "CIDFontType0C"))
1132
2.53k
                                fftype = cff_font;
1133
480
                            else if (pdfi_name_is(ffsubtype, "TrueType"))
1134
0
                                fftype = tt_font;
1135
480
                            else
1136
480
                                fftype = no_type_font;
1137
14.9k
                        }
1138
15.0k
                    }
1139
35.0k
                }
1140
94.4k
            }
1141
98.4k
        }
1142
1143
1.02M
        if (ppdffont == NULL) {
1144
1.01M
            if (fontfile != NULL) {
1145
74.4k
                code = pdfi_stream_to_buffer(ctx, (pdf_stream *) fontfile, &fbuf, &fbuflen);
1146
74.4k
                pdfi_countdown(fontfile);
1147
74.4k
                if (code < 0 || fbuflen == 0) {
1148
1.72k
                    char obj[129];
1149
1.72k
                    pdfi_print_cstring(ctx, "**** Warning: cannot process embedded stream for font object ");
1150
1.72k
                    gs_snprintf(obj, 128, "%d %d\n", (int)font_dict->object_num, (int)font_dict->generation_num);
1151
1.72k
                    pdfi_print_cstring(ctx, obj);
1152
1.72k
                    pdfi_print_cstring(ctx, "**** Attempting to load a substitute font.\n");
1153
1.72k
                    gs_free_object(ctx->memory, fbuf, "pdfi_load_font(fbuf)");
1154
1.72k
                    fbuf = NULL;
1155
1.72k
                    code = gs_note_error(gs_error_invalidfont);
1156
1.72k
                }
1157
74.4k
            }
1158
1159
1.03M
            while (1) {
1160
1.03M
                if (fbuf != NULL) {
1161
                    /* fbuf overship passes to pdfi_load_font_buffer() */
1162
89.2k
                    code = pdfi_load_font_buffer(ctx, fbuf, fbuflen, fftype, Subtype, findex, stream_dict, page_dict, font_dict, &ppdffont, cidfont);
1163
1164
89.2k
                    if (code < 0 && substitute == font_embedded) {
1165
22.7k
                        char msg[129];
1166
1167
22.7k
                        gs_snprintf(msg, 128, "Cannot process embedded stream for font object %d %d. Attempting to load a substitute font.\n", (int)font_dict->object_num, (int)font_dict->generation_num);
1168
1169
22.7k
                        if ((code = pdfi_set_error_stop(ctx, gs_note_error(gs_error_invalidfont), NULL, E_PDF_BAD_EMBEDDED_FONT, "pdfi_load_font", msg)) < 0) {
1170
0
                            goto exit;
1171
0
                        }
1172
22.7k
                        else {
1173
22.7k
                            code = gs_error_invalidfont;
1174
22.7k
                        }
1175
22.7k
                    }
1176
89.2k
                }
1177
943k
                else {
1178
943k
                    code = gs_error_invalidfont;
1179
943k
                }
1180
1181
1.03M
                if (code < 0 && code != gs_error_VMerror && substitute == font_embedded) {
1182
966k
                    substitute = font_from_file;
1183
1184
966k
                    if (cidfont == true) {
1185
16.5k
                        code =  pdfi_open_CIDFont_substitute_file(ctx, font_dict, fontdesc, false, &fbuf, &fbuflen, &findex);
1186
16.5k
                        if (code < 0) {
1187
16.5k
                            code =  pdfi_open_CIDFont_substitute_file(ctx, font_dict, fontdesc, true, &fbuf, &fbuflen, &findex);
1188
16.5k
                            substitute |= font_substitute;
1189
16.5k
                        }
1190
1191
16.5k
                        if (code < 0)
1192
0
                            goto exit;
1193
16.5k
                    }
1194
949k
                    else {
1195
949k
                        code = pdfi_load_font_file(ctx, no_type_font, Subtype, stream_dict, page_dict, font_dict, fontdesc, false, &ppdffont);
1196
949k
                        if (code < 0) {
1197
920k
                            code = pdfi_load_font_file(ctx, no_type_font, Subtype, stream_dict, page_dict, font_dict, fontdesc, true, &ppdffont);
1198
920k
                            substitute |= font_substitute;
1199
920k
                        }
1200
949k
                        break;
1201
949k
                    }
1202
16.5k
                    continue;
1203
966k
                }
1204
66.4k
                break;
1205
1.03M
            }
1206
1.01M
        }
1207
1.02M
    }
1208
1.06M
    if (ppdffont == NULL || code < 0) {
1209
37.8k
        *ppfont = NULL;
1210
37.8k
        code = gs_note_error(gs_error_invalidfont);
1211
37.8k
    }
1212
1.03M
    else {
1213
1.03M
        ppdffont->substitute = (substitute != font_embedded);
1214
1215
1.03M
        if ((substitute & font_substitute) == font_substitute)
1216
928k
            code = pdfi_font_match_glyph_widths(ppdffont);
1217
103k
        else if (ppdffont->substitute != true && fontdesc != NULL && ppdfdescfont == NULL
1218
103k
            && (ppdffont->pdfi_font_type == e_pdf_font_type1 || ppdffont->pdfi_font_type == e_pdf_font_cff
1219
49.8k
            || ppdffont->pdfi_font_type == e_pdf_font_truetype)) {
1220
40.8k
            pdfi_cache_resource_font(ctx, (pdf_obj *)fontdesc, (pdf_obj *)ppdffont);
1221
40.8k
        }
1222
1.03M
        *ppfont = (gs_font *)ppdffont->pfont;
1223
1.03M
     }
1224
1225
1.07M
exit:
1226
1.07M
    pdfi_countdown(ppdfdescfont);
1227
1.07M
    pdfi_countdown(fontdesc);
1228
1.07M
    pdfi_countdown(Type);
1229
1.07M
    pdfi_countdown(Subtype);
1230
1.07M
    pdfi_countdown(ffsubtype);
1231
1.07M
    return code;
1232
1.06M
}
1233
1234
int pdfi_load_dict_font(pdf_context *ctx, pdf_dict *stream_dict, pdf_dict *page_dict, pdf_dict *font_dict, double point_size)
1235
1.35M
{
1236
1.35M
    int code;
1237
1.35M
    gs_font *pfont;
1238
1.35M
    pdf_font *pdfif;
1239
1240
1.35M
    switch (pdfi_type_of(font_dict)) {
1241
1.17M
        case PDF_FONT:
1242
1.17M
            pdfi_countup(font_dict);
1243
1.17M
            pfont = (gs_font *)((pdf_font *)font_dict)->pfont;
1244
1.17M
            code = 0;
1245
1.17M
            break;
1246
163k
        case PDF_DICT:
1247
163k
            code = pdfi_load_font(ctx, stream_dict, page_dict, font_dict, &pfont, false);
1248
163k
            break;
1249
18.1k
        default:
1250
18.1k
            code = gs_note_error(gs_error_typecheck);
1251
18.1k
            goto exit;
1252
1.35M
    }
1253
1.33M
    if (code < 0)
1254
37.2k
        goto exit;
1255
1256
    /* Everything looks good, set the font, unless it's the current font */
1257
1.29M
    if (pfont != ctx->pgs->font) {
1258
1.05M
        code = pdfi_gs_setfont(ctx, pfont);
1259
1.05M
    }
1260
1.29M
    pdfif = (pdf_font *)pfont->client_data;
1261
1.29M
    pdfi_countdown(pdfif);
1262
1263
1.29M
    if (code < 0)
1264
0
        goto exit;
1265
1266
1.29M
    code = gs_setPDFfontsize(ctx->pgs, point_size);
1267
1.35M
exit:
1268
1.35M
    return code;
1269
1.29M
}
1270
1271
static int pdfi_load_resource_font(pdf_context *ctx, pdf_dict *stream_dict, pdf_dict *page_dict, pdf_name *fontname, double point_size)
1272
2.18M
{
1273
2.18M
    int code;
1274
2.18M
    pdf_dict *font_dict = NULL;
1275
1276
2.18M
    if (pdfi_type_of(fontname) != PDF_NAME) {
1277
        /* Passing empty string here should fall back to a default font */
1278
24.6k
        return pdfi_font_set_internal_string(ctx, "", point_size);
1279
24.6k
    }
1280
1281
    /* Look fontname up in the resources */
1282
2.15M
    code = pdfi_loop_detector_mark(ctx);
1283
2.15M
    if (code < 0)
1284
0
        goto exit;
1285
2.15M
    code = pdfi_find_resource(ctx, (unsigned char *)"Font", fontname, stream_dict, page_dict, (pdf_obj **)&font_dict);
1286
2.15M
    (void)pdfi_loop_detector_cleartomark(ctx);
1287
2.15M
    if (code < 0)
1288
807k
        goto exit;
1289
1.35M
    code = pdfi_load_dict_font(ctx, stream_dict, page_dict, font_dict, point_size);
1290
1291
2.15M
exit:
1292
2.15M
    pdfi_countdown(font_dict);
1293
2.15M
    return code;
1294
1.35M
}
1295
1296
int pdfi_get_cidfont_glyph_metrics(gs_font *pfont, gs_glyph cid, double *widths, bool vertical)
1297
2.61M
{
1298
2.61M
    pdf_font *pdffont = (pdf_font *)pfont->client_data;
1299
2.61M
    int i, code = 0;
1300
2.61M
    pdf_num *c = NULL, *c2 = NULL;
1301
2.61M
    pdf_obj *o = NULL;
1302
2.61M
    pdf_array *W = NULL, *W2 = NULL, *DW2 = NULL;
1303
2.61M
    double DW;
1304
1305
2.61M
    if (pdffont->pdfi_font_type == e_pdf_cidfont_type0) {
1306
143k
        pdf_cidfont_type0 *cidfont = (pdf_cidfont_type0 *)pdffont;
1307
143k
        DW = cidfont->DW;
1308
143k
        DW2 = cidfont->DW2;
1309
143k
        W = cidfont->W;
1310
143k
        W2 = cidfont->W2;
1311
143k
    }
1312
2.46M
    else if (pdffont->pdfi_font_type == e_pdf_cidfont_type2) {
1313
2.46M
        pdf_cidfont_type2 *cidfont = (pdf_cidfont_type2 *)pdffont;
1314
2.46M
        DW = cidfont->DW;
1315
2.46M
        DW2 = cidfont->DW2;
1316
2.46M
        W = cidfont->W;
1317
2.46M
        W2 = cidfont->W2;
1318
2.46M
    }
1319
0
    else {
1320
0
        return_error(gs_error_invalidfont);
1321
0
    }
1322
1323
2.61M
    widths[GLYPH_W0_WIDTH_INDEX] = DW;
1324
2.61M
    widths[GLYPH_W0_HEIGHT_INDEX] = 0;
1325
2.61M
    if (W != NULL) {
1326
2.38M
        i = 0;
1327
1328
37.1M
        while(1) {
1329
37.1M
            pdf_obj_type type;
1330
1331
37.1M
            if (i + 1>= W->size) break;
1332
36.9M
            code = pdfi_array_get_type(pdffont->ctx, W, i, PDF_INT, (pdf_obj **)&c);
1333
36.9M
            if (code < 0) goto cleanup;
1334
1335
36.8M
            code = pdfi_array_get(pdffont->ctx, W, i + 1, &o);
1336
36.8M
            if (code < 0) goto cleanup;
1337
1338
36.8M
            type = pdfi_type_of(o);
1339
36.8M
            if (type == PDF_INT) {
1340
5.68M
                double d;
1341
5.68M
                c2 = (pdf_num *)o;
1342
5.68M
                o = NULL;
1343
5.68M
                if (i + 2 >= W->size){
1344
                    /* We countdown and NULL c, c2 and o after exit from the loop
1345
                     * in order to avoid doing so in the break statements
1346
                     */
1347
166
                    break;
1348
166
                }
1349
1350
5.68M
                code = pdfi_array_get_number(pdffont->ctx, W, i + 2, &d);
1351
5.68M
                if (code < 0) goto cleanup;
1352
5.67M
                if (cid >= c->value.i && cid <= c2->value.i) {
1353
319k
                    widths[GLYPH_W0_WIDTH_INDEX] = d;
1354
319k
                    widths[GLYPH_W0_HEIGHT_INDEX] = 0.0;
1355
                    /* We countdown and NULL c, c2 and o after exit from the loop
1356
                     * in order to avoid doing so in the break statements
1357
                     */
1358
319k
                    break;
1359
319k
                }
1360
5.35M
                else {
1361
5.35M
                    i += 3;
1362
5.35M
                    pdfi_countdown(c2);
1363
5.35M
                    pdfi_countdown(c);
1364
5.35M
                    c = c2 = NULL;
1365
5.35M
                    continue;
1366
5.35M
                }
1367
5.67M
            }
1368
31.2M
            else if (type == PDF_ARRAY) {
1369
31.2M
                pdf_array *a = (pdf_array *)o;
1370
31.2M
                o = NULL;
1371
31.2M
                if (cid >= c->value.i && cid < c->value.i + a->size) {
1372
1.83M
                    code = pdfi_array_get_number(pdffont->ctx, a, cid - c->value.i, &widths[GLYPH_W0_WIDTH_INDEX]);
1373
1.83M
                    if (code >= 0) {
1374
1.83M
                        pdfi_countdown(a);
1375
1.83M
                        widths[GLYPH_W0_HEIGHT_INDEX] = 0.0;
1376
                        /* We countdown and NULL c, c2 and o on exit from the loop
1377
                         * in order to avoid doing so in the break statements
1378
                         */
1379
1.83M
                        break;
1380
1.83M
                    }
1381
1.83M
                }
1382
29.3M
                pdfi_countdown(a);
1383
29.3M
                pdfi_countdown(c);
1384
29.3M
                c = NULL;
1385
29.3M
                i += 2;
1386
29.3M
                continue;
1387
31.2M
            }
1388
1.10k
            else {
1389
1.10k
                code = gs_note_error(gs_error_typecheck);
1390
1.10k
                goto cleanup;
1391
1.10k
            }
1392
36.8M
        }
1393
2.38M
        pdfi_countdown(c2);
1394
2.38M
        pdfi_countdown(c);
1395
2.38M
        pdfi_countdown(o);
1396
2.38M
        c = c2 = NULL;
1397
2.38M
        o = NULL;
1398
2.38M
    }
1399
1400
2.60M
    if (vertical) {
1401
        /* Default default <sigh>! */
1402
2.60M
        widths[GLYPH_W1_WIDTH_INDEX] = 0;
1403
2.60M
        widths[GLYPH_W1_HEIGHT_INDEX] = -1000.0;
1404
2.60M
        widths[GLYPH_W1_V_X_INDEX] = (widths[GLYPH_W0_WIDTH_INDEX] / 2.0);
1405
2.60M
        widths[GLYPH_W1_V_Y_INDEX] = 880.0;
1406
1407
2.60M
        if (DW2 != NULL && pdfi_type_of(DW2) == PDF_ARRAY
1408
2.60M
            && DW2->size >= 2) {
1409
12.9k
            code = pdfi_array_get_number(pdffont->ctx, (pdf_array *)DW2, 0, &widths[GLYPH_W1_V_Y_INDEX]);
1410
12.9k
            if (code >= 0)
1411
12.9k
                code = pdfi_array_get_number(pdffont->ctx, (pdf_array *)DW2, 1, &widths[GLYPH_W1_HEIGHT_INDEX]);
1412
12.9k
            if (code >= 0) {
1413
12.9k
                widths[GLYPH_W1_V_X_INDEX] = widths[GLYPH_W0_WIDTH_INDEX] / 2.0;
1414
12.9k
                widths[GLYPH_W1_WIDTH_INDEX] = 0.0;
1415
12.9k
            }
1416
12.9k
        }
1417
2.60M
        if (W2 != NULL && pdfi_type_of(W2) == PDF_ARRAY) {
1418
0
            i = 0;
1419
0
            while(1) {
1420
0
                pdf_obj_type type;
1421
0
                if (i + 1 >= W2->size) break;
1422
0
                (void)pdfi_array_get(pdffont->ctx, W2, i, (pdf_obj **)&c);
1423
0
                if (pdfi_type_of(c) != PDF_INT) {
1424
0
                    code = gs_note_error(gs_error_typecheck);
1425
0
                    goto cleanup;
1426
0
                }
1427
0
                code = pdfi_array_get(pdffont->ctx, W2, i + 1, (pdf_obj **)&o);
1428
0
                if (code < 0) goto cleanup;
1429
0
                type = pdfi_type_of(o);
1430
0
                if (type == PDF_INT) {
1431
0
                    if (cid >= c->value.i && cid <= ((pdf_num *)o)->value.i) {
1432
0
                        if (i + 4 >= W2->size) {
1433
                            /* We countdown and NULL c, and o on exit from the function
1434
                             * so we don't need to do so in the break statements
1435
                             */
1436
0
                            break;
1437
0
                        }
1438
0
                        code = pdfi_array_get_number(pdffont->ctx, W2, i + 2, &widths[GLYPH_W1_HEIGHT_INDEX]);
1439
0
                        if (code < 0) goto cleanup;
1440
0
                        code = pdfi_array_get_number(pdffont->ctx, W2, i + 3, &widths[GLYPH_W1_V_X_INDEX]);
1441
0
                        if (code < 0) goto cleanup;
1442
0
                        code = pdfi_array_get_number(pdffont->ctx, W2, i + 4, &widths[GLYPH_W1_V_Y_INDEX]);
1443
0
                        if (code < 0) goto cleanup;
1444
                        /* We countdown and NULL c, and o on exit from the function
1445
                         * so we don't need to do so in the break statements
1446
                         */
1447
0
                        break;
1448
0
                    }
1449
0
                    i += 5;
1450
0
                }
1451
0
                else if (type == PDF_ARRAY) {
1452
0
                    pdf_array *a = (pdf_array *)o;
1453
0
                    int l = a->size - (a->size % 3);
1454
0
                    o = NULL;
1455
0
                    if (cid >= c->value.i && cid < c->value.i + (l / 3)) {
1456
0
                        int index = (cid - c->value.i) * 3;
1457
0
                        code = pdfi_array_get_number(pdffont->ctx, a, index, &widths[GLYPH_W1_HEIGHT_INDEX]);
1458
0
                        if (code < 0) {
1459
0
                            pdfi_countdown(a);
1460
0
                            goto cleanup;
1461
0
                        }
1462
0
                        code = pdfi_array_get_number(pdffont->ctx, a, index + 1, &widths[GLYPH_W1_V_X_INDEX]);
1463
0
                        if (code < 0) {
1464
0
                            pdfi_countdown(a);
1465
0
                            goto cleanup;
1466
0
                        }
1467
0
                        code = pdfi_array_get_number(pdffont->ctx, a, index + 2, &widths[GLYPH_W1_V_Y_INDEX]);
1468
0
                        pdfi_countdown(a);
1469
0
                        if (code < 0) goto cleanup;
1470
1471
                        /* We countdown and NULL c, and o on exit from the function
1472
                         * so we don't need to do so in the break statements
1473
                         */
1474
0
                        break;
1475
0
                    } else
1476
0
                        pdfi_countdown(a);
1477
0
                    i += 2;
1478
0
                }
1479
0
                else {
1480
0
                    code = gs_note_error(gs_error_typecheck);
1481
0
                    goto cleanup;
1482
0
                }
1483
0
                pdfi_countdown(o);
1484
0
                pdfi_countdown(c);
1485
0
                o = NULL;
1486
0
                c = NULL;
1487
0
            }
1488
0
        }
1489
2.60M
    }
1490
1491
2.61M
cleanup:
1492
2.61M
    pdfi_countdown(c2);
1493
2.61M
    pdfi_countdown(c);
1494
2.61M
    pdfi_countdown(o);
1495
1496
2.61M
    return code;
1497
2.60M
}
1498
1499
int pdfi_d0(pdf_context *ctx)
1500
3.29k
{
1501
3.29k
    int code = 0, gsave_level = 0;
1502
3.29k
    double width[2];
1503
1504
3.29k
    if (ctx->text.inside_CharProc == false)
1505
2.44k
        pdfi_set_warning(ctx, 0, NULL, W_PDF_NOTINCHARPROC, "pdfi_d0", NULL);
1506
1507
3.29k
    ctx->text.CharProc_d_type = pdf_type3_d0;
1508
1509
3.29k
    if (pdfi_count_stack(ctx) < 2) {
1510
723
        code = gs_note_error(gs_error_stackunderflow);
1511
723
        goto d0_error;
1512
723
    }
1513
1514
2.57k
    if (pdfi_type_of(ctx->stack_top[-1]) != PDF_INT && pdfi_type_of(ctx->stack_top[-1]) != PDF_REAL) {
1515
748
        code = gs_note_error(gs_error_typecheck);
1516
748
        goto d0_error;
1517
748
    }
1518
1.82k
    if (pdfi_type_of(ctx->stack_top[-2]) != PDF_INT && pdfi_type_of(ctx->stack_top[-2]) != PDF_REAL) {
1519
119
        code = gs_note_error(gs_error_typecheck);
1520
119
        goto d0_error;
1521
119
    }
1522
1.70k
    if(ctx->text.current_enum == NULL) {
1523
853
        code = gs_note_error(gs_error_undefined);
1524
853
        goto d0_error;
1525
853
    }
1526
1527
855
    if (pdfi_type_of(ctx->stack_top[-2]) == PDF_INT)
1528
853
        width[0] = (double)((pdf_num *)ctx->stack_top[-2])->value.i;
1529
2
    else
1530
2
        width[0] = ((pdf_num *)ctx->stack_top[-2])->value.d;
1531
855
    if (pdfi_type_of(ctx->stack_top[-1]) == PDF_INT)
1532
853
        width[1] = (double)((pdf_num *)ctx->stack_top[-1])->value.i;
1533
2
    else
1534
2
        width[1] = ((pdf_num *)ctx->stack_top[-1])->value.d;
1535
1536
855
    gsave_level = ctx->pgs->level;
1537
1538
    /*
1539
     * We don't intend to retain this, instead we will use (effectively) xyshow to apply
1540
     * width overrides at the text level.
1541
    if (font && font->Widths && ctx->current_chr >= font->FirstChar && ctx->current_chr <= font->LastChar)
1542
        width[0] = font->Widths[font->ctx->current_chr - font->FirstChar];
1543
     */
1544
1545
855
    if (ctx->text.current_enum == NULL) {
1546
0
        code = gs_note_error(gs_error_unknownerror);
1547
0
        goto d0_error;
1548
0
    }
1549
1550
855
    code = gs_text_setcharwidth(ctx->text.current_enum, width);
1551
1552
    /* Nasty hackery. setcachedevice potentially pushes a new device into the graphics state
1553
     * and there's no way to remove that device again without grestore'ing back to a point
1554
     * before the device was loaded. To facilitate this, setcachedevice will do a gs_gsave()
1555
     * before changing the device. Note, the grestore for this is done back in show_update()
1556
     * which is not reached until after the CharProc has been executed.
1557
     *
1558
     * This is a problem for us when running a PDF content stream, because after running the
1559
     * stream we check the gsave level and, if its not the same as it was when we started
1560
     * the stream, we pdfi_grestore() back until it is. This mismatch of the gsave levels
1561
     * causes all sorts of trouble with the font and we can end up counting the pdf_font
1562
     * object down and discarding the font we're tryign to use.
1563
     *
1564
     * The solution (ugly though it is) is to patch up the saved gsave_level in the
1565
     * context to expect that we have one more gsave level on exit. That wasy we won't
1566
     * try and pdf_grestore() back to an earlier point.
1567
     */
1568
855
    if (ctx->pgs->level > gsave_level)
1569
0
        ctx->current_stream_save.gsave_level += ctx->pgs->level - gsave_level;
1570
1571
855
    if (code < 0)
1572
3
        goto d0_error;
1573
852
    pdfi_pop(ctx, 2);
1574
852
    return 0;
1575
1576
2.44k
d0_error:
1577
2.44k
    pdfi_clearstack(ctx);
1578
2.44k
    return code;
1579
855
}
1580
1581
int pdfi_d1(pdf_context *ctx)
1582
43.3k
{
1583
43.3k
    int code = 0, gsave_level;
1584
43.3k
    double wbox[6];
1585
1586
43.3k
    if (ctx->text.inside_CharProc == false)
1587
671
        pdfi_set_warning(ctx, 0, NULL, W_PDF_NOTINCHARPROC, "pdfi_d1", NULL);
1588
1589
43.3k
    ctx->text.CharProc_d_type = pdf_type3_d1;
1590
1591
43.3k
    code = pdfi_destack_reals(ctx, wbox, 6);
1592
43.3k
    if (code < 0)
1593
793
        goto d1_error;
1594
1595
    /*
1596
     * We don't intend to retain this, instead we will use (effectively) xyshow to apply
1597
     * width overrides at the text level.
1598
    if (font && font->Widths && ctx->current_chr >= font->FirstChar && ctx->current_chr <= font->LastChar)
1599
        wbox[0] = font->Widths[font->ctx->current_chr - font->FirstChar];
1600
     */
1601
1602
42.5k
    gsave_level = ctx->pgs->level;
1603
1604
42.5k
    if (ctx->text.current_enum == NULL) {
1605
208
        code = gs_note_error(gs_error_unknownerror);
1606
208
        goto d1_error;
1607
208
    }
1608
1609
#if 0
1610
    /* This code stops us caching the bitmap and filling it. This is required if the 'pdf-differences'
1611
     * test Type3WordSpacing/Type3Test.pdf is to be rendered with a red stroke. Currently the cache
1612
     * results in a bitmap which is filled with the current fill colour, stroke colours are not
1613
     * implemented. I believe that, since the spec references the PLRM implementation of 'd1' that
1614
     * this is correct. I further suspect that the authors of the test used viewers which do not implement
1615
     * a cache at all, and redraw the glyph every time it is used. This has implications for other parts
1616
     * of the graphics state, such as dash patterns, line joins and caps etc.
1617
     *
1618
     * The change in rendering results in many small differences, particularly at low resolution and PDF generated
1619
     * by pdfwrite from PCL input.
1620
     *
1621
     * We need to clip the glyph description to the bounding box, because that's how the cache works with
1622
     * a bitmap, if we don't do this then some glyphs are fully rendered which should only be partially
1623
     * rendered. However, adding this causes two test files to render incorrectly (PostScript files
1624
     * converted to PDF via pdfwrite). This is what decided me to revert this code.
1625
     */
1626
    code = gs_rectclip(ctx->pgs, (const gs_rect *)&wbox[2], 1);
1627
    if (code < 0)
1628
        goto d1_error;
1629
1630
    code = gs_text_setcharwidth(ctx->text.current_enum, wbox);
1631
#else
1632
42.3k
    code = gs_text_setcachedevice(ctx->text.current_enum, wbox);
1633
42.3k
#endif
1634
1635
    /* See the comment immediately after gs_text_setcachedvice() in pdfi_d0 above */
1636
42.3k
    if (ctx->pgs->level > gsave_level)
1637
13.1k
        ctx->current_stream_save.gsave_level += ctx->pgs->level - gsave_level;
1638
1639
42.3k
    if (code < 0)
1640
24
        goto d1_error;
1641
42.2k
    return 0;
1642
1643
1.02k
d1_error:
1644
1.02k
    pdfi_clearstack(ctx);
1645
1.02k
    return code;
1646
42.3k
}
1647
1648
int pdfi_Tf(pdf_context *ctx, pdf_dict *stream_dict, pdf_dict *page_dict)
1649
2.22M
{
1650
2.22M
    double point_size = 0;
1651
2.22M
    pdf_obj *point_arg = NULL;
1652
2.22M
    int code = 0;
1653
2.22M
    pdf_name *fontname = NULL;
1654
1655
2.22M
    if (pdfi_count_stack(ctx) < 2) {
1656
35.6k
        pdfi_clearstack(ctx);
1657
35.6k
        return_error(gs_error_stackunderflow);
1658
35.6k
    }
1659
1660
    /* Get refs to the args and pop them */
1661
2.18M
    point_arg = ctx->stack_top[-1];
1662
2.18M
    pdfi_countup(point_arg);
1663
2.18M
    fontname = (pdf_name *)ctx->stack_top[-2];
1664
2.18M
    pdfi_countup(fontname);
1665
2.18M
    pdfi_pop(ctx, 2);
1666
1667
    /* Get the point_size */
1668
2.18M
    code = pdfi_obj_to_real(ctx, point_arg, &point_size);
1669
2.18M
    if (code < 0)
1670
3.38k
        goto exit0;
1671
1672
2.18M
    code = pdfi_load_resource_font(ctx, stream_dict, page_dict, fontname, point_size);
1673
1674
    /* If we failed to load font, try to load an internal one */
1675
2.18M
    if (code < 0)
1676
863k
        code = pdfi_font_set_internal_name(ctx, fontname, point_size);
1677
2.18M
 exit0:
1678
2.18M
    pdfi_countdown(fontname);
1679
2.18M
    pdfi_countdown(point_arg);
1680
2.18M
    return code;
1681
2.18M
}
1682
1683
int pdfi_free_font(pdf_obj *font)
1684
1.10M
{
1685
1.10M
    pdf_font *f = (pdf_font *)font;
1686
1687
1.10M
    switch (f->pdfi_font_type) {
1688
17.7k
        case e_pdf_font_type0:
1689
17.7k
            return pdfi_free_font_type0((pdf_obj *)font);
1690
0
            break;
1691
1.01M
        case e_pdf_font_type1:
1692
1.01M
            return pdfi_free_font_type1((pdf_obj *)font);
1693
0
            break;
1694
13.8k
        case e_pdf_font_cff:
1695
13.8k
            return pdfi_free_font_cff((pdf_obj *)font);
1696
3.12k
        case e_pdf_font_type3:
1697
3.12k
            return pdfi_free_font_type3((pdf_obj *)font);
1698
0
            break;
1699
34.4k
        case e_pdf_font_truetype:
1700
34.4k
            return pdfi_free_font_truetype((pdf_obj *)font);
1701
0
            break;
1702
0
        case e_pdf_font_microtype:
1703
0
            return pdfi_free_font_microtype((pdf_obj *)font);
1704
0
            break;
1705
17.8k
        case e_pdf_cidfont_type2:
1706
17.8k
            return pdfi_free_font_cidtype2((pdf_obj *)font);
1707
0
            break;
1708
2.23k
        case e_pdf_cidfont_type0:
1709
2.23k
            return pdfi_free_font_cidtype0((pdf_obj *)font);
1710
0
            break;
1711
0
        case e_pdf_cidfont_type1:
1712
0
        case e_pdf_cidfont_type4:
1713
0
        default:
1714
0
            return gs_note_error(gs_error_typecheck);
1715
0
            break;
1716
1.10M
    }
1717
0
    return 0;
1718
1.10M
}
1719
1720
/* Assumes Encoding is an array, and parameters *ind and *near_ind set to ENCODING_INDEX_UNKNOWN */
1721
static void
1722
pdfi_gs_simple_font_encoding_indices(pdf_context *ctx, pdf_array *Encoding, gs_encoding_index_t *ind, gs_encoding_index_t *near_ind)
1723
26.0k
{
1724
26.0k
    uint esize = Encoding->size;
1725
26.0k
    uint best = esize / 3;  /* must match at least this many */
1726
26.0k
    int i, index, near_index = ENCODING_INDEX_UNKNOWN, code;
1727
1728
204k
    for (index = 0; index < NUM_KNOWN_REAL_ENCODINGS; ++index) {
1729
179k
        uint match = esize;
1730
1731
22.4M
        for (i = esize; --i >= 0;) {
1732
22.4M
            gs_const_string rstr;
1733
22.4M
            pdf_name *ename;
1734
1735
22.4M
            code = pdfi_array_get_type(ctx, Encoding, (uint64_t)i, PDF_NAME, (pdf_obj **)&ename);
1736
22.4M
            if (code < 0) {
1737
20
                return;
1738
20
            }
1739
1740
22.4M
            gs_c_glyph_name(gs_c_known_encode((gs_char)i, index), &rstr);
1741
22.4M
            if (rstr.size == ename->length &&
1742
22.4M
                !memcmp(rstr.data, ename->data, rstr.size)) {
1743
9.46M
                pdfi_countdown(ename);
1744
9.46M
                continue;
1745
9.46M
            }
1746
12.9M
            pdfi_countdown(ename);
1747
12.9M
            if (--match <= best) {
1748
135k
                break;
1749
135k
            }
1750
12.9M
        }
1751
179k
        if (match > best) {
1752
44.3k
            best = match;
1753
44.3k
            near_index = index;
1754
            /* If we have a perfect match, stop now. */
1755
44.3k
            if (best == esize)
1756
853
                break;
1757
44.3k
        }
1758
179k
    }
1759
25.9k
    if (best == esize) *ind = index;
1760
25.9k
    *near_ind = near_index;
1761
25.9k
}
1762
1763
static inline int pdfi_encoding_name_to_index(pdf_name *name)
1764
161k
{
1765
161k
    int ind = gs_error_undefined;
1766
161k
    if (pdfi_type_of(name) == PDF_NAME) {
1767
161k
        if (pdfi_name_is(name, "StandardEncoding")) {
1768
77.4k
            ind = ENCODING_INDEX_STANDARD;
1769
84.2k
        } else if (pdfi_name_is(name, "WinAnsiEncoding")) {
1770
68.0k
            ind = ENCODING_INDEX_WINANSI;
1771
68.0k
        }
1772
16.2k
        else if (pdfi_name_is(name, "MacRomanEncoding")) {
1773
15.7k
            ind = ENCODING_INDEX_MACROMAN;
1774
15.7k
        }
1775
506
        else if (pdfi_name_is(name, "MacExpertEncoding")) {
1776
41
            ind = ENCODING_INDEX_MACEXPERT;
1777
41
        }
1778
465
        else if (pdfi_name_is(name, "SymbolEncoding")) {
1779
0
            ind = ENCODING_INDEX_SYMBOL;
1780
0
        }
1781
465
        else if (pdfi_name_is(name, "DingbatsEncoding")) {
1782
0
            ind = ENCODING_INDEX_DINGBATS;
1783
0
        }
1784
161k
    }
1785
161k
    return ind;
1786
161k
}
1787
1788
/*
1789
 * Routine to fill in an array with each of the glyph names from a given
1790
 * 'standard' Encoding.
1791
 */
1792
static int pdfi_build_Encoding(pdf_context *ctx, pdf_name *name, pdf_array *Encoding, gs_encoding_index_t *ind)
1793
157k
{
1794
157k
    int i, code = 0;
1795
157k
    unsigned char gs_encoding;
1796
157k
    gs_glyph temp;
1797
157k
    gs_const_string str;
1798
157k
    pdf_name *n = NULL;
1799
1800
157k
    if (pdfi_array_size(Encoding) < 256)
1801
0
        return gs_note_error(gs_error_rangecheck);
1802
1803
157k
    code = pdfi_encoding_name_to_index(name);
1804
157k
    if (code < 0)
1805
445
        return code;
1806
157k
    if (ind != NULL) *ind = (gs_encoding_index_t)code;
1807
157k
    gs_encoding = (unsigned char)code;
1808
157k
    code = 0;
1809
1810
40.4M
    for (i = 0;i<256;i++) {
1811
40.2M
        temp = gs_c_known_encode(i, gs_encoding);
1812
40.2M
        gs_c_glyph_name(temp, &str);
1813
40.2M
        code = pdfi_name_alloc(ctx, (byte *)str.data, str.size, (pdf_obj **)&n);
1814
40.2M
        if (code < 0)
1815
0
            return code;
1816
40.2M
        pdfi_countup(n);
1817
40.2M
        code = pdfi_array_put(ctx, Encoding, (uint64_t)i, (pdf_obj *)n);
1818
40.2M
        pdfi_countdown(n);
1819
40.2M
        if (code < 0)
1820
0
            return code;
1821
40.2M
    }
1822
157k
    return 0;
1823
157k
}
1824
1825
/*
1826
 * Create and fill in a pdf_array with an Encoding for a font. pdf_Encoding must be either
1827
 * a name (eg StandardEncoding) or a dictionary. If its a name we use that to create the
1828
 * entries, if its a dictionary we start by getting the BaseEncoding and using that to
1829
 * create an array of glyph names as above, *or* for a symbolic font, we use the "predef_Encoding"
1830
 * which is the encoding from the font description itself (i.e. the /Encoding array
1831
 * from a Type 1 font. We then get the Differences array from the dictionary and use that to
1832
 * refine the Encoding.
1833
 */
1834
int pdfi_create_Encoding(pdf_context *ctx, pdf_font *ppdffont, pdf_obj *pdf_Encoding, pdf_obj *font_Encoding, pdf_obj **Encoding)
1835
171k
{
1836
171k
    int code = 0, i;
1837
171k
    gs_encoding_index_t encoding_index = ENCODING_INDEX_UNKNOWN, nearest_encoding_index = ENCODING_INDEX_UNKNOWN;
1838
1839
171k
    code = pdfi_array_alloc(ctx, 256, (pdf_array **)Encoding);
1840
171k
    if (code < 0)
1841
0
        return code;
1842
171k
    pdfi_countup(*Encoding);
1843
1844
171k
    switch (pdfi_type_of(pdf_Encoding)) {
1845
144k
        case PDF_NAME:
1846
144k
            code = pdfi_build_Encoding(ctx, (pdf_name *)pdf_Encoding, (pdf_array *)*Encoding, &encoding_index);
1847
144k
            if (code < 0) {
1848
445
                pdfi_countdown(*Encoding);
1849
445
                *Encoding = NULL;
1850
445
                return code;
1851
445
            }
1852
143k
            nearest_encoding_index = encoding_index;
1853
143k
            break;
1854
26.6k
        case PDF_DICT:
1855
26.6k
        {
1856
26.6k
            pdf_name *n = NULL;
1857
26.6k
            pdf_array *a = NULL;
1858
26.6k
            pdf_obj *o = NULL;
1859
26.6k
            int offset = 0;
1860
26.6k
            bool b_e_known;
1861
1862
26.6k
            if (pdfi_type_of(pdf_Encoding) == PDF_DICT) {
1863
26.6k
                code = pdfi_dict_known(ctx, (pdf_dict *)pdf_Encoding, "BaseEncoding", &b_e_known);
1864
26.6k
                if (code < 0)
1865
0
                    b_e_known = false;
1866
26.6k
            }
1867
0
            else {
1868
0
                b_e_known = false;
1869
0
            }
1870
1871
26.6k
            if (b_e_known == false && font_Encoding != NULL && pdfi_type_of(font_Encoding) == PDF_ARRAY) {
1872
13.2k
                pdf_array *fenc = (pdf_array *)font_Encoding;
1873
3.38M
                for (i = 0; i < pdfi_array_size(fenc) && code >= 0; i++) {
1874
3.37M
                    code = pdfi_array_get(ctx, fenc, (uint64_t)i, &o);
1875
3.37M
                    if (code >= 0)
1876
3.37M
                        code = pdfi_array_put(ctx, (pdf_array *)*Encoding, (uint64_t)i, o);
1877
3.37M
                    pdfi_countdown(o);
1878
3.37M
                }
1879
13.2k
                if (code < 0) {
1880
0
                    pdfi_countdown(*Encoding);
1881
0
                    *Encoding = NULL;
1882
0
                    return code;
1883
0
                }
1884
13.2k
            }
1885
13.4k
            else {
1886
13.4k
                code = pdfi_dict_get(ctx, (pdf_dict *)pdf_Encoding, "BaseEncoding", (pdf_obj **)&n);
1887
13.4k
                if (code >= 0) {
1888
3.93k
                    if (pdfi_encoding_name_to_index(n) < 0) {
1889
20
                        pdfi_set_warning(ctx, 0, NULL, W_PDF_INVALID_FONT_BASEENC, "pdfi_create_Encoding", NULL);
1890
20
                        pdfi_countdown(n);
1891
20
                        n = NULL;
1892
20
                        code = gs_error_undefined;
1893
20
                    }
1894
3.91k
                    else if (pdfi_name_is(n, "StandardEncoding") == true) {
1895
0
                        pdfi_set_warning(ctx, 0, NULL, W_PDF_INVALID_FONT_BASEENC, "pdfi_create_Encoding", NULL);
1896
0
                    }
1897
3.93k
                }
1898
1899
13.4k
                if (code < 0) {
1900
9.52k
                    code = pdfi_name_alloc(ctx, (byte *)"StandardEncoding", 16, (pdf_obj **)&n);
1901
9.52k
                    if (code < 0) {
1902
0
                        pdfi_countdown(*Encoding);
1903
0
                        *Encoding = NULL;
1904
0
                        return code;
1905
0
                    }
1906
9.52k
                    pdfi_countup(n);
1907
9.52k
                }
1908
1909
13.4k
                code = pdfi_build_Encoding(ctx, n, (pdf_array *)*Encoding, NULL);
1910
13.4k
                if (code < 0) {
1911
0
                    pdfi_countdown(*Encoding);
1912
0
                    *Encoding = NULL;
1913
0
                    pdfi_countdown(n);
1914
0
                    return code;
1915
0
                }
1916
13.4k
                pdfi_countdown(n);
1917
13.4k
            }
1918
26.6k
            code = pdfi_dict_knownget_type(ctx, (pdf_dict *)pdf_Encoding, "Differences", PDF_ARRAY, (pdf_obj **)&a);
1919
26.6k
            if (code <= 0) {
1920
534
                if (code < 0) {
1921
0
                    pdfi_countdown(*Encoding);
1922
0
                    *Encoding = NULL;
1923
0
                }
1924
534
                return code;
1925
534
            }
1926
1927
2.45M
            for (i=0;i < pdfi_array_size(a);i++) {
1928
2.42M
                pdf_obj_type type;
1929
2.42M
                code = pdfi_array_get(ctx, a, (uint64_t)i, &o);
1930
2.42M
                if (code < 0)
1931
11
                    break;
1932
2.42M
                type = pdfi_type_of(o);
1933
2.42M
                if (type == PDF_NAME) {
1934
2.19M
                    if (offset < pdfi_array_size((pdf_array *)*Encoding))
1935
2.19M
                        code = pdfi_array_put(ctx, (pdf_array *)*Encoding, (uint64_t)offset, o);
1936
2.19M
                    pdfi_countdown(o);
1937
2.19M
                    offset++;
1938
2.19M
                    if (code < 0)
1939
0
                        break;
1940
2.19M
                } else if (type == PDF_INT) {
1941
231k
                    offset = ((pdf_num *)o)->value.i;
1942
231k
                    pdfi_countdown(o);
1943
231k
                } else {
1944
80
                    code = gs_note_error(gs_error_typecheck);
1945
80
                    pdfi_countdown(o);
1946
80
                    break;
1947
80
                }
1948
2.42M
            }
1949
26.1k
            pdfi_countdown(a);
1950
26.1k
            if (code < 0) {
1951
91
                pdfi_countdown(*Encoding);
1952
91
                *Encoding = NULL;
1953
91
                return code;
1954
91
            }
1955
26.0k
            if (ppdffont != NULL) /* No sense doing this if we can't record the result */
1956
26.0k
                pdfi_gs_simple_font_encoding_indices(ctx, (pdf_array *)(*Encoding), &encoding_index, &nearest_encoding_index);
1957
26.0k
            break;
1958
26.1k
        }
1959
509
        default:
1960
509
            pdfi_countdown(*Encoding);
1961
509
            *Encoding = NULL;
1962
509
            return gs_note_error(gs_error_typecheck);
1963
171k
    }
1964
169k
    if (ppdffont != NULL) {
1965
105k
        ppdffont->pfont->encoding_index = encoding_index;
1966
105k
        ppdffont->pfont->nearest_encoding_index = nearest_encoding_index;
1967
105k
    }
1968
169k
    return 0;
1969
171k
}
1970
1971
gs_glyph pdfi_encode_char(gs_font * pfont, gs_char chr, gs_glyph_space_t not_used)
1972
137M
{
1973
137M
    int code;
1974
137M
    unsigned int nindex = 0;
1975
137M
    gs_glyph g = GS_NO_GLYPH;
1976
1977
137M
    if (pfont->FontType == ft_encrypted || pfont->FontType == ft_encrypted2
1978
137M
     || pfont->FontType == ft_user_defined || pfont->FontType == ft_TrueType
1979
137M
     || pfont->FontType == ft_MicroType
1980
137M
     || pfont->FontType == ft_PDF_user_defined) {
1981
137M
        pdf_font *font = (pdf_font *)pfont->client_data;
1982
137M
        pdf_context *ctx = (pdf_context *)font->ctx;
1983
1984
137M
        if (font->Encoding != NULL) { /* safety */
1985
137M
            pdf_name *GlyphName = NULL;
1986
137M
            code = pdfi_array_get(ctx, font->Encoding, (uint64_t)chr, (pdf_obj **)&GlyphName);
1987
137M
            if (code >= 0) {
1988
137M
                if (pdfi_type_of(GlyphName) != PDF_NAME)
1989
                    /* Can't signal an error, just return the 'not found' case */
1990
1.12k
                    return g;
1991
1992
137M
                code = (*ctx->get_glyph_index)(pfont, (byte *)GlyphName->data, GlyphName->length, &nindex);
1993
137M
                pdfi_countdown(GlyphName);
1994
137M
                if (code >= 0)
1995
137M
                    g = (gs_glyph)nindex;
1996
137M
            }
1997
137M
        }
1998
137M
    }
1999
2000
137M
    return g;
2001
137M
}
2002
2003
extern const pdfi_cid_decoding_t *pdfi_cid_decoding_list[];
2004
extern const pdfi_cid_subst_nwp_table_t *pdfi_cid_substnwp_list[];
2005
2006
void pdfi_cidfont_cid_subst_tables(const char *reg, const int reglen, const char *ord,
2007
                const int ordlen, pdfi_cid_decoding_t **decoding, pdfi_cid_subst_nwp_table_t **substnwp)
2008
8.82k
{
2009
8.82k
    int i;
2010
8.82k
    *decoding = NULL;
2011
8.82k
    *substnwp = NULL;
2012
    /* This only makes sense for Adobe orderings */
2013
8.82k
    if (reglen == 5 && !memcmp(reg, "Adobe", 5)) {
2014
47.8k
        for (i = 0; pdfi_cid_decoding_list[i] != NULL; i++) {
2015
39.9k
            if (strlen(pdfi_cid_decoding_list[i]->s_order) == ordlen &&
2016
39.9k
                !memcmp(pdfi_cid_decoding_list[i]->s_order, ord, ordlen)) {
2017
325
                *decoding = (pdfi_cid_decoding_t *)pdfi_cid_decoding_list[i];
2018
325
                break;
2019
325
            }
2020
39.9k
        }
2021
        /* For now, also only for Adobe orderings */
2022
47.9k
        for (i = 0; pdfi_cid_substnwp_list[i] != NULL; i++) {
2023
40.1k
            if (strlen(pdfi_cid_substnwp_list[i]->ordering) == ordlen &&
2024
40.1k
                !memcmp(pdfi_cid_substnwp_list[i]->ordering, ord, ordlen)) {
2025
325
                *substnwp = (pdfi_cid_subst_nwp_table_t *)pdfi_cid_substnwp_list[i];
2026
325
                break;
2027
325
            }
2028
40.1k
        }
2029
8.16k
    }
2030
8.82k
}
2031
2032
int pdfi_tounicode_char_to_unicode(pdf_context *ctx, pdf_cmap *tounicode, gs_glyph glyph, int ch, ushort *unicode_return, unsigned int length)
2033
3.99M
{
2034
3.99M
    int i, l = 0;
2035
3.99M
    int code = gs_error_undefined;
2036
3.99M
    unsigned char *ucode = (unsigned char *)unicode_return;
2037
2038
3.99M
    if (tounicode != NULL) {
2039
1.03M
        gs_cmap_lookups_enum_t lenum;
2040
1.03M
        gs_cmap_lookups_enum_init((const gs_cmap_t *)tounicode->gscmap, 0, &lenum);
2041
15.3M
        while (l == 0 && gs_cmap_enum_next_lookup(ctx->memory, &lenum) == 0) {
2042
14.3M
            gs_cmap_lookups_enum_t counter = lenum;
2043
28.6M
            while (l == 0 && gs_cmap_enum_next_entry(&counter) == 0) {
2044
14.3M
                if (counter.entry.value_type == CODE_VALUE_CID) {
2045
14.3M
                    if (counter.entry.key_is_range) {
2046
3.36M
                        unsigned int v0 = 0, v1 = 0;
2047
7.79M
                        for (i = 0; i < counter.entry.key_size; i++) {
2048
4.43M
                            v0 |= (counter.entry.key[0][counter.entry.key_size - i - 1]) << (i * 8);
2049
4.43M
                        }
2050
7.79M
                        for (i = 0; i < counter.entry.key_size; i++) {
2051
4.43M
                            v1 |= (counter.entry.key[1][counter.entry.key_size - i - 1]) << (i * 8);
2052
4.43M
                        }
2053
2054
3.36M
                        if (ch >= v0 && ch <= v1) {
2055
615k
                            unsigned int offs = ch - v0;
2056
2057
615k
                            if (counter.entry.value.size == 1) {
2058
0
                                l = 2;
2059
0
                                if (ucode != NULL && length >= l) {
2060
0
                                    ucode[0] = 0x00;
2061
0
                                    ucode[1] = counter.entry.value.data[0] + offs;
2062
0
                                }
2063
0
                            }
2064
615k
                            else if (counter.entry.value.size == 2) {
2065
613k
                                l = 2;
2066
613k
                                if (ucode != NULL && length >= l) {
2067
398k
                                    ucode[0] = counter.entry.value.data[0] + ((offs >> 8) & 0xff);
2068
398k
                                    ucode[1] = counter.entry.value.data[1] + (offs & 0xff);
2069
398k
                                }
2070
613k
                            }
2071
1.70k
                            else if (counter.entry.value.size == 3) {
2072
24
                                l = 4;
2073
24
                                if (ucode != NULL && length >= l) {
2074
12
                                    ucode[0] = 0;
2075
12
                                    ucode[1] = counter.entry.value.data[0] + ((offs >> 16) & 0xff);
2076
12
                                    ucode[2] = counter.entry.value.data[1] + ((offs >> 8) & 0xff);
2077
12
                                    ucode[3] = counter.entry.value.data[2] + (offs & 0xff);
2078
12
                                }
2079
24
                            }
2080
1.67k
                            else {
2081
1.67k
                                l = 4;
2082
1.67k
                                if (ucode != NULL && length >= l) {
2083
1.56k
                                    ucode[0] = counter.entry.value.data[0] + ((offs >> 24) & 0xff);
2084
1.56k
                                    ucode[1] = counter.entry.value.data[1] + ((offs >> 16) & 0xff);
2085
1.56k
                                    ucode[2] = counter.entry.value.data[2] + ((offs >> 8) & 0xff);
2086
1.56k
                                    ucode[3] = counter.entry.value.data[3] + (offs & 0xff);
2087
1.56k
                                }
2088
1.67k
                            }
2089
615k
                        }
2090
3.36M
                    }
2091
10.9M
                    else {
2092
10.9M
                        unsigned int v = 0;
2093
31.6M
                        for (i = 0; i < counter.entry.key_size; i++) {
2094
20.6M
                            v |= (counter.entry.key[0][counter.entry.key_size - i - 1]) << (i * 8);
2095
20.6M
                        }
2096
10.9M
                        if (ch == v) {
2097
334k
                            if (counter.entry.value.size == 1) {
2098
0
                                l = 2;
2099
0
                                if (ucode != NULL && length >= l) {
2100
0
                                    ucode[0] = 0x00;
2101
0
                                    ucode[1] = counter.entry.value.data[0];
2102
0
                                }
2103
0
                            }
2104
334k
                            else if (counter.entry.value.size == 2) {
2105
333k
                                l = 2;
2106
333k
                                if (ucode != NULL && length >= l) {
2107
213k
                                    ucode[0] = counter.entry.value.data[0];
2108
213k
                                    ucode[1] = counter.entry.value.data[1];
2109
213k
                                }
2110
333k
                            }
2111
838
                            else if (counter.entry.value.size == 3) {
2112
56
                                l = 4;
2113
56
                                if (ucode != NULL && length >= l) {
2114
33
                                    ucode[0] = 0;
2115
33
                                    ucode[1] = counter.entry.value.data[0];
2116
33
                                    ucode[2] = counter.entry.value.data[1];
2117
33
                                    ucode[3] = counter.entry.value.data[2];
2118
33
                                }
2119
56
                            }
2120
782
                            else {
2121
782
                                l = 4;
2122
782
                                if (ucode != NULL && length >= l) {
2123
536
                                    ucode[0] = counter.entry.value.data[0];
2124
536
                                    ucode[1] = counter.entry.value.data[1];
2125
536
                                    ucode[2] = counter.entry.value.data[2];
2126
536
                                    ucode[3] = counter.entry.value.data[3];
2127
536
                                }
2128
782
                            }
2129
334k
                        }
2130
10.9M
                    }
2131
14.3M
                }
2132
14.3M
            }
2133
14.3M
        }
2134
1.03M
        if (l > 0)
2135
950k
            code = l;
2136
1.03M
    }
2137
2138
3.99M
    return code;
2139
3.99M
}
2140
2141
int
2142
pdfi_cidfont_decode_glyph(gs_font *font, gs_glyph glyph, int ch, ushort *u, unsigned int length)
2143
1.82M
{
2144
1.82M
    gs_glyph cc = glyph < GS_MIN_CID_GLYPH ? glyph : glyph - GS_MIN_CID_GLYPH;
2145
1.82M
    pdf_cidfont_t *pcidfont = (pdf_cidfont_t *)font->client_data;
2146
1.82M
    int code = gs_error_undefined, i;
2147
1.82M
    uchar *unicode_return = (uchar *)u;
2148
1.82M
    pdfi_cid_subst_nwp_table_t *substnwp = pcidfont->substnwp;
2149
2150
1.82M
    code = gs_error_undefined;
2151
1.82M
    while (1) { /* Loop to make retrying with a substitute CID easier */
2152
        /* Favour the ToUnicode if one exists */
2153
1.82M
        code = pdfi_tounicode_char_to_unicode(pcidfont->ctx, (pdf_cmap *)pcidfont->ToUnicode, glyph, ch, u, length);
2154
2155
1.82M
        if (code == gs_error_undefined && pcidfont->decoding) {
2156
24.7k
            const int *n;
2157
2158
24.7k
            if (cc / 256 < pcidfont->decoding->nranges) {
2159
24.4k
                n = (const int *)pcidfont->decoding->ranges[cc / 256][cc % 256];
2160
25.3k
                for (i = 0; i < pcidfont->decoding->val_sizes; i++) {
2161
25.3k
                    unsigned int cmapcc;
2162
25.3k
                    if (n[i] == -1)
2163
3.86k
                        break;
2164
21.4k
                    cc = n[i];
2165
21.4k
                    cmapcc = (unsigned int)cc;
2166
21.4k
                    if (pcidfont->pdfi_font_type == e_pdf_cidfont_type2)
2167
21.4k
                        code = pdfi_fapi_check_cmap_for_GID((gs_font *)pcidfont->pfont, (unsigned int)cc, &cmapcc);
2168
0
                    else
2169
0
                        code = 0;
2170
21.4k
                    if (code >= 0 && cmapcc != 0){
2171
20.6k
                        code = 0;
2172
20.6k
                        break;
2173
20.6k
                    }
2174
21.4k
                }
2175
                /* If it's a TTF derived CIDFont, we prefer a code point supported by the cmap table
2176
                   but if not, use the first available one
2177
                 */
2178
24.4k
                if (code < 0 && n[0] != -1) {
2179
0
                    cc = n[0];
2180
0
                    code = 0;
2181
0
                }
2182
24.4k
            }
2183
24.7k
            if (code >= 0) {
2184
20.6k
                if (cc > 65535) {
2185
0
                    code = 4;
2186
0
                    if (unicode_return != NULL && length >= code) {
2187
0
                        unicode_return[0] = (cc & 0xFF000000)>> 24;
2188
0
                        unicode_return[1] = (cc & 0x00FF0000) >> 16;
2189
0
                        unicode_return[2] = (cc & 0x0000FF00) >> 8;
2190
0
                        unicode_return[3] = (cc & 0x000000FF);
2191
0
                    }
2192
0
                }
2193
20.6k
                else {
2194
20.6k
                    code = 2;
2195
20.6k
                    if (unicode_return != NULL && length >= code) {
2196
9.86k
                        unicode_return[0] = (cc & 0x0000FF00) >> 8;
2197
9.86k
                        unicode_return[1] = (cc & 0x000000FF);
2198
9.86k
                    }
2199
20.6k
                }
2200
20.6k
            }
2201
24.7k
        }
2202
        /* If we get here, and still don't have a usable code point, check for a
2203
           pre-defined CID substitution, and if there's one, jump back to the start
2204
           and try again.
2205
         */
2206
1.82M
        if (code == gs_error_undefined && substnwp) {
2207
11.4k
            for (i = 0; substnwp->subst[i].s_type != 0; i++ ) {
2208
10.8k
                if (cc >= substnwp->subst[i].s_scid && cc <= substnwp->subst[i].e_scid) {
2209
0
                    cc = substnwp->subst[i].s_dcid + (cc - substnwp->subst[i].s_scid);
2210
0
                    substnwp = NULL;
2211
0
                    break;
2212
0
                }
2213
10.8k
                if (cc >= substnwp->subst[i].s_dcid
2214
10.8k
                 && cc <= substnwp->subst[i].s_dcid + (substnwp->subst[i].e_scid - substnwp->subst[i].s_scid)) {
2215
3.53k
                    cc = substnwp->subst[i].s_scid + (cc - substnwp->subst[i].s_dcid);
2216
3.53k
                    substnwp = NULL;
2217
3.53k
                    break;
2218
3.53k
                }
2219
10.8k
            }
2220
4.08k
            if (substnwp == NULL)
2221
3.53k
                continue;
2222
4.08k
        }
2223
1.82M
        break;
2224
1.82M
    }
2225
1.82M
    return (code < 0 ? 0 : code);
2226
1.82M
}
2227
2228
/* Get the unicode valude for a glyph FIXME - not written yet
2229
 */
2230
int pdfi_decode_glyph(gs_font * font, gs_glyph glyph, int ch, ushort *unicode_return, unsigned int length)
2231
912k
{
2232
912k
    pdf_font *pdffont = (pdf_font *)font->client_data;
2233
912k
    int code = 0;
2234
2235
912k
    if (pdffont->pdfi_font_type != e_pdf_cidfont_type0 && pdffont->pdfi_font_type != e_pdf_cidfont_type1
2236
912k
     && pdffont->pdfi_font_type != e_pdf_cidfont_type2 && pdffont->pdfi_font_type != e_pdf_cidfont_type4) {
2237
906k
        code = pdfi_tounicode_char_to_unicode(pdffont->ctx, (pdf_cmap *)pdffont->ToUnicode, glyph, ch, unicode_return, length);
2238
906k
    }
2239
912k
    if (code < 0) code = 0;
2240
2241
912k
    return code;
2242
912k
}
2243
2244
int pdfi_glyph_index(gs_font *pfont, byte *str, uint size, uint *glyph)
2245
0
{
2246
0
    int code = 0;
2247
0
    pdf_font *font = (pdf_font *)pfont->client_data;
2248
2249
0
    code = pdfi_get_name_index(font->ctx, (char *)str, size, glyph);
2250
2251
0
    return code;
2252
0
}
2253
2254
int pdfi_glyph_name(gs_font * pfont, gs_glyph glyph, gs_const_string * pstr)
2255
0
{
2256
0
    int code = gs_error_invalidfont;
2257
2258
0
    if (pfont->FontType == ft_encrypted || pfont->FontType == ft_encrypted2
2259
0
     || pfont->FontType == ft_user_defined || pfont->FontType == ft_TrueType
2260
0
     || pfont->FontType == ft_PDF_user_defined || pfont->FontType == ft_MicroType) {
2261
0
        pdf_font *font = (pdf_font *)pfont->client_data;
2262
2263
0
        code = pdfi_name_from_index(font->ctx, glyph, (unsigned char **)&pstr->data, &pstr->size);
2264
0
    }
2265
2266
0
    return code;
2267
0
}
2268
2269
2270
static int pdfi_global_glyph_code(const gs_font *pfont, gs_const_string *gstr, gs_glyph *pglyph)
2271
57
{
2272
57
    int code = 0;
2273
57
    if (pfont->FontType == ft_encrypted) {
2274
1
        code = pdfi_t1_global_glyph_code(pfont, gstr, pglyph);
2275
1
    }
2276
56
    else if (pfont->FontType == ft_encrypted2) {
2277
56
        code = pdfi_cff_global_glyph_code(pfont, gstr, pglyph);
2278
56
    }
2279
0
    else {
2280
0
        code = gs_note_error(gs_error_invalidaccess);
2281
0
    }
2282
57
    return code;
2283
57
}
2284
2285
int pdfi_map_glyph_name_via_agl(pdf_dict *cstrings, pdf_name *gname, pdf_string **cstring)
2286
896k
{
2287
896k
    single_glyph_list_t *sgl = (single_glyph_list_t *)&(SingleGlyphList);
2288
896k
    int i, code, ucode = gs_error_undefined;
2289
896k
    *cstring = NULL;
2290
2291
896k
    if (gname->length == 7 && strncmp((char *)gname->data, "uni", 3) == 0) {
2292
3.98k
        char u[5] = {0};
2293
3.98k
        memcpy(u, gname->data + 3, 4);
2294
3.98k
        code = sscanf(u, "%x", &ucode);
2295
3.98k
        if (code <= 0)
2296
0
            ucode = gs_error_undefined;
2297
3.98k
    }
2298
2299
896k
    if (ucode == gs_error_undefined) {
2300
3.34G
        for (i = 0; sgl[i].Glyph != 0x00; i++) {
2301
3.34G
            if (sgl[i].Glyph[0] == gname->data[0]
2302
3.34G
                && strlen(sgl[i].Glyph) == gname->length
2303
3.34G
                && !strncmp((char *)sgl[i].Glyph, (char *)gname->data, gname->length)) {
2304
273k
                ucode = (int)sgl[i].Unicode;
2305
273k
                break;
2306
273k
            }
2307
3.34G
        }
2308
892k
    }
2309
896k
    if (ucode > 0) {
2310
1.16G
        for (i = 0; sgl[i].Glyph != 0x00; i++) {
2311
1.16G
            if (sgl[i].Unicode == (unsigned short)ucode) {
2312
280k
                pdf_string *s;
2313
280k
                code = pdfi_dict_get((pdf_context *)cstrings->ctx, cstrings, (char *)sgl[i].Glyph, (pdf_obj **)&s);
2314
280k
                if (code >= 0) {
2315
2.97k
                    *cstring = s;
2316
2.97k
                    break;
2317
2.97k
                }
2318
280k
            }
2319
1.16G
        }
2320
277k
        if (*cstring == NULL) {
2321
274k
            char u[16] = {0};
2322
274k
            code = gs_snprintf(u, 16, "uni%04x", ucode);
2323
274k
            if (code > 0) {
2324
274k
                pdf_string *s;
2325
274k
                code = pdfi_dict_get((pdf_context *)cstrings->ctx, cstrings, u, (pdf_obj **)&s);
2326
274k
                if (code >= 0) {
2327
2
                    *cstring = s;
2328
2
                }
2329
274k
            }
2330
274k
        }
2331
277k
    }
2332
2333
896k
    if (*cstring == NULL)
2334
893k
        code = gs_note_error(gs_error_undefined);
2335
2.98k
    else
2336
2.98k
        code = 0;
2337
2338
896k
    return code;
2339
896k
}
2340
2341
2342
int pdfi_init_font_directory(pdf_context *ctx)
2343
109k
{
2344
109k
    gs_font_dir *pfdir = ctx->memory->gs_lib_ctx->font_dir;
2345
109k
    if (pfdir) {
2346
109k
        ctx->font_dir = gs_font_dir_alloc2_limits(ctx->memory, ctx->memory,
2347
109k
                   pfdir->smax, pfdir->ccache.bmax, pfdir->fmcache.mmax,
2348
109k
                   pfdir->ccache.cmax, pfdir->ccache.upper);
2349
109k
        if (ctx->font_dir == NULL) {
2350
0
            return_error(gs_error_VMerror);
2351
0
        }
2352
109k
        ctx->font_dir->align_to_pixels = pfdir->align_to_pixels;
2353
109k
        ctx->font_dir->grid_fit_tt = pfdir->grid_fit_tt;
2354
109k
    }
2355
0
    else {
2356
0
        ctx->font_dir = gs_font_dir_alloc2(ctx->memory, ctx->memory);
2357
0
        if (ctx->font_dir == NULL) {
2358
0
            return_error(gs_error_VMerror);
2359
0
        }
2360
0
    }
2361
109k
    ctx->font_dir->global_glyph_code = pdfi_global_glyph_code;
2362
109k
    return 0;
2363
109k
}
2364
2365
/* Loads a (should be!) non-embedded font by name
2366
   Only currently works for Type 1 fonts set.
2367
 */
2368
int pdfi_load_font_by_name_string(pdf_context *ctx, const byte *fontname, size_t length,
2369
                                  pdf_obj **ppdffont)
2370
888k
{
2371
888k
    pdf_obj *fname = NULL;
2372
888k
    pdf_obj *fontobjtype = NULL;
2373
888k
    pdf_dict *fdict = NULL;
2374
888k
    int code;
2375
888k
    gs_font *pgsfont = NULL;
2376
888k
    const char *fs = "Font";
2377
888k
    pdf_name *Type1Name = NULL;
2378
2379
888k
    code = pdfi_name_alloc(ctx, (byte *)fontname, length, &fname);
2380
888k
    if (code < 0)
2381
0
        return code;
2382
888k
    pdfi_countup(fname);
2383
2384
888k
    code = pdfi_name_alloc(ctx, (byte *)fs, strlen(fs), &fontobjtype);
2385
888k
    if (code < 0)
2386
0
        goto exit;
2387
888k
    pdfi_countup(fontobjtype);
2388
2389
888k
    code = pdfi_dict_alloc(ctx, 1, &fdict);
2390
888k
    if (code < 0)
2391
0
        goto exit;
2392
888k
    pdfi_countup(fdict);
2393
2394
888k
    code = pdfi_dict_put(ctx, fdict, "BaseFont", fname);
2395
888k
    if (code < 0)
2396
0
        goto exit;
2397
2398
888k
    code = pdfi_dict_put(ctx, fdict, "Type", fontobjtype);
2399
888k
    if (code < 0)
2400
0
        goto exit;
2401
2402
888k
    code = pdfi_obj_charstr_to_name(ctx, "Type1", &Type1Name);
2403
888k
    if (code < 0)
2404
0
        goto exit;
2405
2406
888k
    code = pdfi_dict_put(ctx, fdict, "Subtype", (pdf_obj *)Type1Name);
2407
888k
    if (code < 0)
2408
0
        goto exit;
2409
2410
888k
    code = pdfi_load_font(ctx, NULL, NULL, fdict, &pgsfont, false);
2411
888k
    if (code < 0)
2412
0
        goto exit;
2413
2414
888k
    *ppdffont = (pdf_obj *)pgsfont->client_data;
2415
2416
888k
 exit:
2417
888k
    pdfi_countdown(Type1Name);
2418
888k
    pdfi_countdown(fontobjtype);
2419
888k
    pdfi_countdown(fname);
2420
888k
    pdfi_countdown(fdict);
2421
888k
    return code;
2422
888k
}
2423
2424
2425
int pdfi_font_create_widths(pdf_context *ctx, pdf_dict *fontdict, pdf_font *font, double scale)
2426
1.00M
{
2427
1.00M
    int code = 0;
2428
1.00M
    pdf_obj *obj = NULL;
2429
1.00M
    int i;
2430
2431
1.00M
    font->Widths = NULL;
2432
2433
1.00M
    if (font->FontDescriptor != NULL) {
2434
91.0k
        code = pdfi_dict_knownget(ctx, font->FontDescriptor, "MissingWidth", &obj);
2435
91.0k
        if (code > 0) {
2436
7.14k
            if (pdfi_type_of(obj) == PDF_INT) {
2437
7.14k
                font->MissingWidth = ((pdf_num *) obj)->value.i * scale;
2438
7.14k
            }
2439
0
            else if (pdfi_type_of(obj) == PDF_REAL) {
2440
0
                font->MissingWidth = ((pdf_num *) obj)->value.d  * scale;
2441
0
            }
2442
0
            else {
2443
0
                font->MissingWidth = 0;
2444
0
            }
2445
7.14k
            pdfi_countdown(obj);
2446
7.14k
            obj = NULL;
2447
7.14k
        }
2448
83.9k
        else {
2449
83.9k
            font->MissingWidth = 0;
2450
83.9k
        }
2451
91.0k
    }
2452
916k
    else {
2453
916k
        font->MissingWidth = 0;
2454
916k
    }
2455
2456
1.00M
    code = pdfi_dict_knownget_type(ctx, fontdict, "Widths", PDF_ARRAY, (pdf_obj **)&obj);
2457
1.00M
    if (code > 0) {
2458
96.3k
        if (pdfi_array_size((pdf_array *)obj) < font->LastChar - font->FirstChar + 1) {
2459
2.38k
            code = gs_note_error(gs_error_rangecheck);
2460
2.38k
            goto error;
2461
2.38k
        }
2462
2463
94.0k
        font->Widths = (double *)gs_alloc_bytes(OBJ_MEMORY(font), (size_t)sizeof(double) * (font->LastChar - font->FirstChar + 1), "pdfi_font_create_widths(Widths)");
2464
94.0k
        if (font->Widths == NULL) {
2465
0
            code = gs_note_error(gs_error_VMerror);
2466
0
            goto error;
2467
0
        }
2468
94.0k
        memset(font->Widths, 0x00, sizeof(double) * (font->LastChar - font->FirstChar + 1));
2469
9.65M
        for (i = 0; i < (font->LastChar - font->FirstChar + 1); i++) {
2470
9.55M
            code = pdfi_array_get_number(ctx, (pdf_array *)obj, (uint64_t)i, &font->Widths[i]);
2471
9.55M
            if (code < 0)
2472
299
                goto error;
2473
9.55M
            font->Widths[i] *= scale;
2474
9.55M
        }
2475
94.0k
    }
2476
1.00M
error:
2477
1.00M
    pdfi_countdown(obj);
2478
1.00M
    if (code < 0) {
2479
6.52k
        gs_free_object(OBJ_MEMORY(font), font->Widths, "pdfi_font_create_widths(Widths)");
2480
6.52k
        font->Widths = NULL;
2481
6.52k
    }
2482
1.00M
    return code;
2483
1.00M
}
2484
2485
void pdfi_font_set_first_last_char(pdf_context *ctx, pdf_dict *fontdict, pdf_font *font)
2486
1.06M
{
2487
1.06M
    double f, l;
2488
1.06M
    int code;
2489
2490
1.06M
    if (fontdict == NULL) {
2491
58.8k
        f = (double)0;
2492
58.8k
        l = (double)255;
2493
58.8k
    }
2494
1.00M
    else {
2495
1.00M
        code = pdfi_dict_get_number(ctx, fontdict, "FirstChar", &f);
2496
1.00M
        if (code < 0 || f < 0 || f > 255)
2497
906k
            f = (double)0;
2498
2499
1.00M
        code = pdfi_dict_get_number(ctx, fontdict, "LastChar", &l);
2500
1.00M
        if (code < 0 || l < 0 || l > 255)
2501
907k
            l = (double)255;
2502
1.00M
    }
2503
1.06M
    if (f <= l) {
2504
1.06M
        font->FirstChar = (int)f;
2505
1.06M
        font->LastChar = (int)l;
2506
1.06M
    }
2507
64
    else {
2508
64
        font->FirstChar = 0;
2509
64
        font->LastChar = 255;
2510
64
    }
2511
1.06M
}
2512
2513
void pdfi_font_set_orig_fonttype(pdf_context *ctx, pdf_font *font)
2514
1.07M
{
2515
1.07M
    pdf_name *ftype;
2516
1.07M
    pdf_dict *fontdict = font->PDF_font;
2517
1.07M
    int code;
2518
2519
1.07M
    code = pdfi_dict_get_type(ctx, fontdict, "Subtype", PDF_NAME, (pdf_obj**)&ftype);
2520
1.07M
    if (code < 0) {
2521
59.6k
        font->orig_FontType = ft_undefined;
2522
59.6k
    }
2523
1.01M
    else {
2524
1.01M
        if (pdfi_name_is(ftype, "Type1") || pdfi_name_is(ftype, "MMType1"))
2525
941k
            font->orig_FontType = ft_encrypted;
2526
74.3k
        else if (pdfi_name_is(ftype, "Type1C"))
2527
0
            font->orig_FontType = ft_encrypted2;
2528
74.3k
        else if (pdfi_name_is(ftype, "TrueType"))
2529
53.3k
            font->orig_FontType = ft_TrueType;
2530
20.9k
        else if (pdfi_name_is(ftype, "Type3"))
2531
2.50k
            font->orig_FontType = ft_user_defined;
2532
18.4k
        else if (pdfi_name_is(ftype, "CIDFontType0"))
2533
3.52k
            font->orig_FontType = ft_CID_encrypted;
2534
14.9k
        else if (pdfi_name_is(ftype, "CIDFontType2"))
2535
14.2k
            font->orig_FontType = ft_CID_TrueType;
2536
744
        else
2537
744
            font->orig_FontType = ft_undefined;
2538
1.01M
    }
2539
1.07M
    pdfi_countdown(ftype);
2540
1.07M
}
2541
2542
/* Patch or create a new XUID based on the existing UID/XUID, a simple hash
2543
   of the input file name and the font dictionary object number.
2544
   This allows improved glyph cache efficiency, also ensures pdfwrite understands
2545
   which fonts are repetitions, and which are different.
2546
   Currently cannot return an error - if we can't allocate the new XUID values array,
2547
   we just skip it, and assume the font is compliant.
2548
 */
2549
int pdfi_font_generate_pseudo_XUID(pdf_context *ctx, pdf_dict *fontdict, gs_font_base *pfont)
2550
122k
{
2551
122k
    gs_const_string fn;
2552
122k
    int i;
2553
122k
    uint32_t hash = 0;
2554
122k
    long *xvalues;
2555
122k
    int xuidlen = 3;
2556
2557
122k
    sfilename(ctx->main_stream->s, &fn);
2558
122k
    if (fontdict!= NULL && fontdict->object_num != 0) {
2559
57.9k
        const byte *sb;
2560
57.9k
        size_t l;
2561
57.9k
        if (fn.size > 0) {
2562
0
            sb = fn.data;
2563
0
            l = fn.size;
2564
0
        }
2565
57.9k
        else {
2566
57.9k
            s_process_read_buf(ctx->main_stream->s);
2567
57.9k
            sb = sbufptr(ctx->main_stream->s);
2568
57.9k
            l = sbufavailable(ctx->main_stream->s) > 128 ? 128: sbufavailable(ctx->main_stream->s);
2569
57.9k
        }
2570
2571
7.47M
        for (i = 0; i < l; i++) {
2572
7.41M
            hash = ((((hash & 0xf8000000) >> 27) ^ (hash << 5)) & 0x7ffffffff) ^ sb[i];
2573
7.41M
        }
2574
57.9k
        hash = ((((hash & 0xf8000000) >> 27) ^ (hash << 5)) & 0x7ffffffff) ^ fontdict->object_num;
2575
2576
57.9k
        if (uid_is_XUID(&pfont->UID) && uid_XUID_size(&pfont->UID) > 2 && uid_XUID_values(&pfont->UID)[0] == 1000000) {
2577
            /* This is already a pseudo XUID, probably because we are copying an existing font object
2578
             * So just update the hash and the object number
2579
             */
2580
597
             uid_XUID_values(&pfont->UID)[1] = hash;
2581
597
             uid_XUID_values(&pfont->UID)[2] = ctx->device_state.HighLevelDevice ? fontdict->object_num : 0;
2582
597
        }
2583
57.3k
        else {
2584
57.3k
            if (uid_is_XUID(&pfont->UID))
2585
2.12k
                xuidlen += uid_XUID_size(&pfont->UID);
2586
55.2k
            else if (uid_is_valid(&pfont->UID))
2587
671
                xuidlen++;
2588
2589
57.3k
            xvalues = (long *)gs_alloc_bytes(pfont->memory, (size_t)xuidlen * sizeof(long), "pdfi_font_generate_pseudo_XUID");
2590
57.3k
            if (xvalues == NULL) {
2591
0
                return 0;
2592
0
            }
2593
57.3k
            xvalues[0] = 1000000; /* "Private" value */
2594
57.3k
            xvalues[1] = hash;
2595
2596
57.3k
            xvalues[2] = ctx->device_state.HighLevelDevice ? fontdict->object_num : 0;
2597
2598
57.3k
            if (uid_is_XUID(&pfont->UID)) {
2599
12.8k
                for (i = 0; i < uid_XUID_size(&pfont->UID); i++) {
2600
10.6k
                    xvalues[i + 3] = uid_XUID_values(&pfont->UID)[i];
2601
10.6k
                }
2602
2.12k
                uid_free(&pfont->UID, pfont->memory, "pdfi_font_generate_pseudo_XUID");
2603
2.12k
            }
2604
55.2k
            else if (uid_is_valid(&pfont->UID))
2605
671
                xvalues[3] = pfont->UID.id;
2606
2607
57.3k
            uid_set_XUID(&pfont->UID, xvalues, xuidlen);
2608
57.3k
        }
2609
57.9k
    }
2610
122k
    return 0;
2611
122k
}
2612
2613
int pdfi_default_font_info(gs_font *font, const gs_point *pscale, int members, gs_font_info_t *info)
2614
186k
{
2615
186k
    pdf_font *pdff = (pdf_font *)font->client_data;
2616
186k
    int code;
2617
2618
    /* We *must* call this first as it sets info->members = 0; */
2619
186k
    code = pdff->default_font_info(font, pscale, members, info);
2620
186k
    if (code < 0)
2621
8.58k
        return code;
2622
178k
    if ((members & FONT_INFO_EMBEDDED) != 0) {
2623
178k
        info->orig_FontType = pdff->orig_FontType;
2624
178k
        if (pdff->pdfi_font_type == e_pdf_font_type3) {
2625
864
            info->FontEmbedded = (int)(true);
2626
864
            info->members |= FONT_INFO_EMBEDDED;
2627
864
        }
2628
177k
        else {
2629
177k
            info->FontEmbedded = (int)(pdff->substitute == font_embedded);
2630
177k
            info->members |= FONT_INFO_EMBEDDED;
2631
177k
        }
2632
178k
    }
2633
178k
    if (pdff->pdfi_font_type != e_pdf_font_truetype && pdff->pdfi_font_type != e_pdf_cidfont_type2) {
2634
96.4k
        if (((members & FONT_INFO_COPYRIGHT) != 0) && pdff->copyright != NULL) {
2635
55.9k
            info->Copyright.data = pdff->copyright->data;
2636
55.9k
            info->Copyright.size = pdff->copyright->length;
2637
55.9k
            info->members |= FONT_INFO_COPYRIGHT;
2638
55.9k
        }
2639
96.4k
        if (((members & FONT_INFO_NOTICE) != 0) && pdff->notice != NULL) {
2640
61.1k
            info->Notice.data = pdff->notice->data;
2641
61.1k
            info->Notice.size = pdff->notice->length;
2642
61.1k
            info->members |= FONT_INFO_NOTICE;
2643
61.1k
        }
2644
96.4k
        if (((members & FONT_INFO_FAMILY_NAME) != 0) && pdff->familyname != NULL) {
2645
60.4k
            info->FamilyName.data = pdff->familyname->data;
2646
60.4k
            info->FamilyName.size = pdff->familyname->length;
2647
60.4k
            info->members |= FONT_INFO_FAMILY_NAME;
2648
60.4k
        }
2649
96.4k
        if (((members & FONT_INFO_FULL_NAME) != 0) && pdff->fullname != NULL) {
2650
60.4k
            info->FullName.data = pdff->fullname->data;
2651
60.4k
            info->FullName.size = pdff->fullname->length;
2652
60.4k
            info->members |= FONT_INFO_FULL_NAME;
2653
60.4k
        }
2654
96.4k
    }
2655
178k
    return 0;
2656
186k
}
2657
2658
/* Convenience function for using fonts created by
2659
   pdfi_load_font_by_name_string
2660
 */
2661
int pdfi_set_font_internal(pdf_context *ctx, pdf_obj *fontobj, double point_size)
2662
888k
{
2663
888k
    int code;
2664
888k
    pdf_font *pdffont = (pdf_font *)fontobj;
2665
2666
888k
    if (pdfi_type_of(pdffont) != PDF_FONT || pdffont->pfont == NULL)
2667
0
        return_error(gs_error_invalidfont);
2668
2669
888k
    code = gs_setPDFfontsize(ctx->pgs, point_size);
2670
888k
    if (code < 0)
2671
0
        return code;
2672
2673
888k
    return pdfi_gs_setfont(ctx, (gs_font *)pdffont->pfont);
2674
888k
}
2675
2676
/* Convenience function for setting font by name
2677
 * Keeps one ref to the font, which will be in the graphics state font ->client_data
2678
 */
2679
static int pdfi_font_set_internal_inner(pdf_context *ctx, const byte *fontname, size_t length,
2680
                                        double point_size)
2681
888k
{
2682
888k
    int code = 0;
2683
888k
    pdf_obj *font = NULL;
2684
2685
2686
888k
    code = pdfi_load_font_by_name_string(ctx, fontname, length, &font);
2687
888k
    if (code < 0) goto exit;
2688
2689
888k
    code = pdfi_set_font_internal(ctx, font, point_size);
2690
2691
888k
 exit:
2692
888k
    pdfi_countdown(font);
2693
888k
    return code;
2694
888k
}
2695
2696
int pdfi_font_set_internal_string(pdf_context *ctx, const char *fontname, double point_size)
2697
25.1k
{
2698
25.1k
    return pdfi_font_set_internal_inner(ctx, (const byte *)fontname, strlen(fontname), point_size);
2699
25.1k
}
2700
2701
int pdfi_font_set_internal_name(pdf_context *ctx, pdf_name *fontname, double point_size)
2702
863k
{
2703
863k
    if (pdfi_type_of(fontname) != PDF_NAME)
2704
0
        return_error(gs_error_typecheck);
2705
863k
    else
2706
863k
        return pdfi_font_set_internal_inner(ctx, fontname->data, fontname->length, point_size);
2707
863k
}