Coverage Report

Created: 2025-11-16 07:40

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