Coverage Report

Created: 2025-06-10 07:27

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