Coverage Report

Created: 2025-06-24 07:01

/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.76M
{
48
1.76M
    int code = 0;
49
1.76M
    pdfi_int_gstate *igs = (pdfi_int_gstate *)ctx->pgs->client_data;
50
1.76M
    pdf_font *old_font = igs->current_font;
51
52
1.76M
    code = gs_setfont(ctx->pgs, pfont);
53
1.76M
    if (code >= 0) {
54
1.76M
        igs->current_font = (pdf_font *)pfont->client_data;
55
1.76M
        pdfi_countup(igs->current_font);
56
1.76M
        pdfi_countdown(old_font);
57
1.76M
    }
58
1.76M
    return code;
59
1.76M
}
60
61
static void pdfi_cache_resource_font(pdf_context *ctx, pdf_obj *fontdesc, pdf_obj *ppdffont)
62
33.8k
{
63
33.8k
    resource_font_cache_t *entry = NULL;
64
33.8k
    int i;
65
66
33.8k
    if (ctx->resource_font_cache == NULL) {
67
18.0k
        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.0k
        if (ctx->resource_font_cache == NULL)
69
0
            return;
70
18.0k
        ctx->resource_font_cache_size = RESOURCE_FONT_CACHE_BLOCK_SIZE;
71
18.0k
        memset(ctx->resource_font_cache, 0x00, RESOURCE_FONT_CACHE_BLOCK_SIZE * sizeof(pdfi_name_entry_t));
72
18.0k
        entry = &ctx->resource_font_cache[0];
73
18.0k
    }
74
75
100k
    for (i = 0; entry == NULL && i < ctx->resource_font_cache_size; i++) {
76
66.1k
        if (ctx->resource_font_cache[i].pdffont == NULL) {
77
15.7k
            entry = &ctx->resource_font_cache[i];
78
15.7k
        }
79
50.4k
        else if (i == ctx->resource_font_cache_size - 1) {
80
2
            entry = (resource_font_cache_t *)gs_resize_object(ctx->memory, ctx->resource_font_cache, sizeof(pdfi_name_entry_t) * (ctx->resource_font_cache_size + RESOURCE_FONT_CACHE_BLOCK_SIZE), "pdfi_cache_resource_font");
81
2
            if (entry == NULL)
82
0
                break;
83
2
            memset(entry + ctx->resource_font_cache_size, 0x00, RESOURCE_FONT_CACHE_BLOCK_SIZE * sizeof(pdfi_name_entry_t));
84
2
            ctx->resource_font_cache = entry;
85
2
            entry = &ctx->resource_font_cache[ctx->resource_font_cache_size];
86
2
            ctx->resource_font_cache_size += RESOURCE_FONT_CACHE_BLOCK_SIZE;
87
2
        }
88
66.1k
    }
89
33.8k
    if (entry != NULL) {
90
33.8k
        entry->desc_obj_num = fontdesc->object_num;
91
33.8k
        entry->pdffont = ppdffont;
92
33.8k
        pdfi_countup(ppdffont);
93
33.8k
    }
94
33.8k
}
95
96
void pdfi_purge_cache_resource_font(pdf_context *ctx)
97
105k
{
98
105k
    int i;
99
683k
    for (i = 0; i < ctx->resource_font_cache_size; i++) {
100
578k
       pdfi_countdown(ctx->resource_font_cache[i].pdffont);
101
578k
    }
102
105k
    gs_free_object(ctx->memory, ctx->resource_font_cache, "pdfi_purge_cache_resource_font");
103
105k
    ctx->resource_font_cache = NULL;
104
105k
    ctx->resource_font_cache_size = 0;
105
105k
}
106
107
static int pdfi_find_cache_resource_font(pdf_context *ctx, pdf_obj *fontdesc, pdf_obj **ppdffont)
108
66.7k
{
109
66.7k
    int i, code = gs_error_undefined;
110
793k
    for (i = 0; i < ctx->resource_font_cache_size; i++) {
111
730k
        if (ctx->resource_font_cache[i].desc_obj_num == fontdesc->object_num) {
112
3.45k
           *ppdffont = ctx->resource_font_cache[i].pdffont;
113
3.45k
           pdfi_countup(*ppdffont);
114
3.45k
           code = 0;
115
3.45k
           break;
116
3.45k
        }
117
730k
    }
118
66.7k
    return code;
119
66.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
941k
{
141
941k
    bool ignore = false;
142
941k
    int i;
143
941k
    pdf_name *nm = (pdf_name *)basefont;
144
145
941k
    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.56M
            if (nm->length == known_symbolic_font_names[i].namelen
148
3.56M
             && !strncmp((char *)nm->data, known_symbolic_font_names[i].name, nm->length)) {
149
1.53k
                ignore = true;
150
1.53k
                break;
151
1.53k
            }
152
3.56M
        }
153
890k
    }
154
941k
    return ignore;
155
941k
}
156
157
static int
158
pdfi_font_match_glyph_widths(pdf_font *pdfont)
159
834k
{
160
834k
    int code = 0;
161
834k
    int i;
162
834k
    int sindex, lindex;
163
834k
    gs_font_base *pbfont = pdfont->pfont;
164
834k
    double fw = 0.0, ww = 0.0;
165
166
834k
    if (pdfont->LastChar <  pdfont->FirstChar || pdfont->Widths == NULL)
167
807k
        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
26.7k
    sindex = pdfont->FirstChar < 96 ? 96 : pdfont->FirstChar;
171
26.7k
    lindex = pdfont->LastChar > 122 ? 123 : pdfont->LastChar + 1;
172
173
464k
    for (i = sindex; i < lindex; i++) {
174
438k
        gs_glyph_info_t ginfo = {0};
175
438k
        gs_glyph g;
176
438k
        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
438k
        if (g != GS_NO_GLYPH && pdfont->Widths[i - pdfont->FirstChar] != 0.0
180
438k
          && (*pbfont->procs.glyph_info)((gs_font *)pbfont, g, NULL, GLYPH_INFO_WIDTH0, &ginfo) >= 0) {
181
338k
            fw += hypot(ginfo.width[0].x, ginfo.width[0].y);
182
338k
            ww += pdfont->Widths[i - pdfont->FirstChar];
183
338k
        }
184
438k
    }
185
    /* Only reduce font width, don't expand */
186
26.7k
    if (ww != 0.0 && fw != 0.0 && ww / fw < 1.0) {
187
7.89k
        gs_matrix nmat, smat = {1.0, 0.0, 0.0, 1.0, 0.0, 0.0};
188
7.89k
        double wscale;
189
7.89k
        smat.xx = smat.yy = ww/fw;
190
7.89k
        wscale = 1.0 / smat.xx;
191
192
7.89k
        gs_matrix_multiply(&pbfont->FontMatrix, &smat, &nmat);
193
7.89k
        memcpy(&pbfont->FontMatrix, &nmat, sizeof(pbfont->FontMatrix));
194
195
1.00M
        for (i = pdfont->FirstChar; i <= pdfont->LastChar; i++) {
196
994k
            pdfont->Widths[i - pdfont->FirstChar] *= wscale;
197
994k
        }
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
7.89k
        code = gs_purge_font((gs_font *)pbfont);
207
7.89k
        if (code >= 0)
208
7.89k
            code = gs_definefont(pbfont->dir, (gs_font *)pbfont);
209
7.89k
        if (code >= 0)
210
7.89k
            code = pdfi_fapi_passfont((pdf_font *)pdfont, 0, NULL, NULL, NULL, 0);
211
7.89k
    }
212
213
26.7k
    return code;
214
834k
}
215
216
/* Print a name object to stdout */
217
static void pdfi_print_font_name(pdf_context *ctx, pdf_name *n)
218
864k
{
219
864k
    if (ctx->args.QUIET != true)
220
0
        (void)outwrite(ctx->memory, (const char *)n->data, n->length);
221
864k
}
222
223
static void pdfi_print_font_string(pdf_context *ctx, pdf_string *s)
224
850k
{
225
850k
    if (ctx->args.QUIET != true)
226
0
        (void)outwrite(ctx->memory, (const char *)s->data, s->length);
227
850k
}
228
229
/* Print a null terminated string to stdout */
230
static void pdfi_print_cstring(pdf_context *ctx, const char *str)
231
2.61M
{
232
2.61M
    if (ctx->args.QUIET != true)
233
0
        (void)outwrite(ctx->memory, str, strlen(str));
234
2.61M
}
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.9k
{
244
29.9k
    int code = 0;
245
29.9k
    char fontfname[gp_file_name_sizeof];
246
29.9k
    stream *s;
247
29.9k
    pdf_name *cidname = NULL;
248
29.9k
    gs_const_string fname;
249
250
29.9k
    (void)pdfi_dict_get(ctx, font_dict, "BaseFont", (pdf_obj **)&cidname);
251
252
29.9k
    if (fallback == true) {
253
14.9k
        pdf_string *mname = NULL;
254
14.9k
        pdf_dict *csi = NULL;
255
14.9k
        pdf_name *fbname;
256
14.9k
        const char *cidfbstr = "CIDFallBack";
257
258
14.9k
        code = pdfi_fontmap_lookup_cidfont(ctx, font_dict, NULL, (pdf_obj **)&mname, findex);
259
260
14.9k
        if (mname == NULL || pdfi_type_of(mname) != PDF_STRING) {
261
14.9k
            pdfi_countdown(mname);
262
263
14.9k
            code = pdfi_object_alloc(ctx, PDF_NAME, strlen(cidfbstr), (pdf_obj **)&fbname);
264
14.9k
            if (code >= 0) {
265
14.9k
                pdfi_countup(fbname);
266
14.9k
                memcpy(fbname->data, cidfbstr, strlen(cidfbstr));
267
14.9k
                code = pdfi_fontmap_lookup_cidfont(ctx, font_dict, fbname, (pdf_obj **)&mname, findex);
268
14.9k
                pdfi_countdown(fbname);
269
14.9k
            }
270
271
14.9k
            if (code < 0 || pdfi_type_of(mname) != PDF_STRING) {
272
14.9k
                pdfi_countdown(mname);
273
14.9k
                mname = NULL;
274
14.9k
                code = pdfi_dict_get(ctx, font_dict, "CIDSystemInfo", (pdf_obj **)&csi);
275
14.9k
                if (code >= 0 && pdfi_type_of(csi) == PDF_DICT) {
276
12.1k
                    pdf_string *csi_reg = NULL, *csi_ord = NULL;
277
278
12.1k
                    if (pdfi_dict_get(ctx, csi, "Registry", (pdf_obj **)&csi_reg) >= 0
279
12.1k
                     && pdfi_dict_get(ctx, csi, "Ordering", (pdf_obj **)&csi_ord) >= 0
280
12.1k
                     && pdfi_type_of(csi_reg) == PDF_STRING && pdfi_type_of(csi_ord) == PDF_STRING
281
12.1k
                     && csi_reg->length + csi_ord->length + 1 < gp_file_name_sizeof - 1) {
282
11.9k
                        pdf_name *reg_ord;
283
11.9k
                        memcpy(fontfname, csi_reg->data, csi_reg->length);
284
11.9k
                        memcpy(fontfname + csi_reg->length, "-", 1);
285
11.9k
                        memcpy(fontfname + csi_reg->length + 1, csi_ord->data, csi_ord->length);
286
11.9k
                        fontfname[csi_reg->length + csi_ord->length + 1] = '\0';
287
288
11.9k
                        code = pdfi_name_alloc(ctx, (byte *)fontfname, strlen(fontfname), (pdf_obj **) &reg_ord);
289
11.9k
                        if (code >= 0) {
290
11.9k
                            pdfi_countup(reg_ord);
291
11.9k
                            code = pdfi_fontmap_lookup_cidfont(ctx, font_dict, reg_ord, (pdf_obj **)&mname, findex);
292
11.9k
                            pdfi_countdown(reg_ord);
293
11.9k
                        }
294
11.9k
                    }
295
12.1k
                    pdfi_countdown(csi_reg);
296
12.1k
                    pdfi_countdown(csi_ord);
297
12.1k
                }
298
14.9k
                pdfi_countdown(csi);
299
14.9k
            }
300
301
14.9k
            if (mname == NULL || pdfi_type_of(mname) != PDF_STRING) {
302
14.9k
                pdfi_countdown(mname);
303
14.9k
                mname = NULL;
304
14.9k
                code = pdfi_fontmap_lookup_cidfont(ctx, font_dict, NULL, (pdf_obj **)&mname, findex);
305
14.9k
            }
306
14.9k
        }
307
308
14.9k
        do {
309
14.9k
            if (code < 0 || pdfi_type_of(mname) != PDF_STRING) {
310
14.9k
                const char *fsprefix = "CIDFSubst/";
311
14.9k
                int fsprefixlen = strlen(fsprefix);
312
14.9k
                const char *defcidfallack = "DroidSansFallback.ttf";
313
14.9k
                int defcidfallacklen = strlen(defcidfallack);
314
315
14.9k
                pdfi_countdown(mname);
316
317
14.9k
                if (ctx->args.nocidfallback == true) {
318
0
                    code = gs_note_error(gs_error_invalidfont);
319
0
                }
320
14.9k
                else {
321
14.9k
                    if (ctx->args.cidfsubstpath.data == NULL) {
322
14.9k
                        memcpy(fontfname, fsprefix, fsprefixlen);
323
14.9k
                    }
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.9k
                    if (ctx->args.cidfsubstfont.data == NULL) {
338
14.9k
                        int len = 0;
339
14.9k
                        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.9k
                        else {
357
14.9k
                            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.9k
                            else {
369
14.9k
                                memcpy(fontfname + fsprefixlen, defcidfallack, defcidfallacklen);
370
14.9k
                            }
371
14.9k
                        }
372
14.9k
                    }
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.9k
                    fontfname[fsprefixlen + defcidfallacklen] = '\0';
411
412
14.9k
                    code = pdfi_open_resource_file(ctx, fontfname, strlen(fontfname), &s);
413
14.9k
                    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.9k
                    else {
433
14.9k
                        if (cidname) {
434
14.7k
                            pdfi_print_cstring(ctx, "Loading CIDFont ");
435
14.7k
                            pdfi_print_font_name(ctx, (pdf_name *)cidname);
436
14.7k
                            pdfi_print_cstring(ctx, " substitute from ");
437
14.7k
                        }
438
269
                        else {
439
269
                            pdfi_print_cstring(ctx, "Loading nameless CIDFont from ");
440
269
                        }
441
14.9k
                        sfilename(s, &fname);
442
14.9k
                        if (fname.size < gp_file_name_sizeof) {
443
14.9k
                            memcpy(fontfname, fname.data, fname.size);
444
14.9k
                            fontfname[fname.size] = '\0';
445
14.9k
                        }
446
0
                        else {
447
0
                            strcpy(fontfname, "unnamed file");
448
0
                        }
449
14.9k
                        pdfi_print_cstring(ctx, fontfname);
450
14.9k
                        pdfi_print_cstring(ctx, "\n");
451
452
453
14.9k
                        sfseek(s, 0, SEEK_END);
454
14.9k
                        *buflen = sftell(s);
455
14.9k
                        sfseek(s, 0, SEEK_SET);
456
14.9k
                        *buf = gs_alloc_bytes(ctx->memory, *buflen, "pdfi_open_CIDFont_file(buf)");
457
14.9k
                        if (*buf != NULL) {
458
14.9k
                            sfread(*buf, 1, *buflen, s);
459
14.9k
                        }
460
0
                        else {
461
0
                            code = gs_note_error(gs_error_VMerror);
462
0
                        }
463
14.9k
                        sfclose(s);
464
14.9k
                        break;
465
14.9k
                    }
466
14.9k
                }
467
14.9k
            }
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.9k
        } while (code >= 0);
514
14.9k
    }
515
14.9k
    else {
516
14.9k
        const char *fsprefix = "CIDFont/";
517
14.9k
        const int fsprefixlen = strlen(fsprefix);
518
519
14.9k
        if (cidname == NULL || pdfi_type_of(cidname) != PDF_NAME
520
14.9k
         || fsprefixlen + cidname->length >= gp_file_name_sizeof) {
521
273
            code = gs_note_error(gs_error_invalidfont);
522
273
            goto exit;
523
273
        }
524
525
14.7k
        memcpy(fontfname, fsprefix, fsprefixlen);
526
14.7k
        memcpy(fontfname + fsprefixlen, cidname->data, cidname->length);
527
14.7k
        fontfname[fsprefixlen + cidname->length] = '\0';
528
529
14.7k
        code = pdfi_open_resource_file(ctx, fontfname, strlen(fontfname), &s);
530
14.7k
        if (code < 0) {
531
14.7k
            code = gs_note_error(gs_error_invalidfont);
532
14.7k
        }
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.7k
    }
547
548
29.9k
exit:
549
29.9k
    if (cidname != NULL)
550
29.4k
        pdfi_countdown(cidname);
551
552
29.9k
    return code;
553
29.9k
}
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
125M
    while (1)
591
125M
    {
592
125M
        while (*a == ' ')
593
0
            a++;
594
125M
        while (*b == ' ')
595
5.19k
            b++;
596
125M
        if (*a != *b)
597
107M
            return 1;
598
18.2M
        if (*a == 0)
599
6.97k
            return *a != *b;
600
18.2M
        if (*b == 0)
601
0
            return *a != *b;
602
18.2M
        a++;
603
18.2M
        b++;
604
18.2M
    }
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
6.97k
                return pdfi_base_font_names[i][0];
615
107M
        }
616
22.4M
    }
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
827k
{
622
827k
    bool fixed = ((flags & pdfi_font_flag_fixed) != 0);
623
827k
    bool serif = ((flags & pdfi_font_flag_serif) != 0);
624
827k
    bool italic = ((flags & pdfi_font_flag_italic) != 0);
625
827k
    bool bold = ((flags & pdfi_font_flag_forcebold) != 0);
626
827k
    int code = 0;
627
628
827k
    if (ctx->args.defaultfont_is_name == true && ctx->args.defaultfont.size == 4
629
827k
        && !memcmp(ctx->args.defaultfont.data, "None", 4)) {
630
0
       *name = NULL;
631
0
       *namelen = 0;
632
0
       code = gs_error_invalidfont;
633
0
    }
634
827k
    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
827k
    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
4
                *name = (char *)pdfi_base_font_names[2][0];
652
4
                *namelen = strlen(*name);
653
4
            }
654
234
            else {
655
234
                *name = (char *)pdfi_base_font_names[0][0];
656
234
                *namelen = strlen(*name);
657
234
            }
658
238
        }
659
241
    }
660
827k
    else if (serif) {
661
1.69k
        if (bold) {
662
8
            if (italic) {
663
0
                *name = (char *)pdfi_base_font_names[11][0];
664
0
                *namelen = strlen(*name);
665
0
            }
666
8
            else {
667
8
                *name = (char *)pdfi_base_font_names[9][0];
668
8
                *namelen = strlen(*name);
669
8
            }
670
8
        }
671
1.68k
        else {
672
1.68k
            if (italic) {
673
232
                *name = (char *)pdfi_base_font_names[10][0];
674
232
                *namelen = strlen(*name);
675
232
            }
676
1.45k
            else {
677
1.45k
                *name = (char *)pdfi_base_font_names[8][0];
678
1.45k
                *namelen = strlen(*name);
679
1.45k
            }
680
1.68k
        }
681
825k
    } else {
682
825k
        if (bold) {
683
148
            if (italic) {
684
0
                *name = (char *)pdfi_base_font_names[7][0];
685
0
                *namelen = strlen(*name);
686
0
            }
687
148
            else {
688
148
                *name = (char *)pdfi_base_font_names[5][0];
689
148
                *namelen = strlen(*name);
690
148
            }
691
148
        }
692
825k
        else {
693
825k
            if (italic) {
694
538
                *name = (char *)pdfi_base_font_names[6][0];
695
538
                *namelen = strlen(*name);
696
538
            }
697
824k
            else {
698
824k
                *name = (char *)pdfi_base_font_names[4][0];
699
824k
                *namelen = strlen(*name);
700
824k
            }
701
825k
        }
702
825k
    }
703
827k
    return code;
704
827k
}
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
126k
{
717
1.17M
#define MAKEMAGIC(a, b, c, d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
718
719
126k
    if (buflen >= 4) {
720
126k
        if (MAKEMAGIC(buf[0], buf[1], buf[2], buf[3]) == MAKEMAGIC(0, 1, 0, 0)
721
126k
            || MAKEMAGIC(buf[0], buf[1], buf[2], buf[3]) == MAKEMAGIC('t', 'r', 'u', 'e')
722
126k
            || MAKEMAGIC(buf[0], buf[1], buf[2], buf[3]) == MAKEMAGIC('t', 't', 'c', 'f')) {
723
46.6k
            return tt_font;
724
46.6k
        }
725
79.5k
        else if (MAKEMAGIC(buf[0], buf[1], buf[2], buf[3]) == MAKEMAGIC('O', 'T', 'T', 'O')) {
726
540
            return cff_font; /* OTTO will end up as CFF */
727
540
        }
728
79.0k
        else if (MAKEMAGIC(buf[0], buf[1], buf[2], 0) == MAKEMAGIC('%', '!', 'P', 0)) {
729
65.9k
            return type1_font; /* pfa */
730
65.9k
        }
731
13.0k
        else if (MAKEMAGIC(buf[0], buf[1], buf[2], 0) == MAKEMAGIC(1, 0, 4, 0)) {
732
12.3k
            return cff_font; /* 1C/CFF */
733
12.3k
        }
734
713
        else if (MAKEMAGIC(buf[0], buf[1], 0, 0) == MAKEMAGIC(128, 1, 0, 0)) {
735
163
            return type1_font; /* pfb */
736
163
        }
737
126k
    }
738
571
    return no_type_font;
739
126k
#undef MAKEMAGIC
740
126k
}
741
742
static int pdfi_copy_font(pdf_context *ctx, pdf_font *spdffont, pdf_dict *font_dict, pdf_font **tpdffont)
743
854k
{
744
854k
    int code;
745
854k
    if (pdfi_type_of(spdffont) != PDF_FONT)
746
0
        return_error(gs_error_typecheck);
747
748
854k
    switch(spdffont->pdfi_font_type) {
749
850k
        case e_pdf_font_type1:
750
850k
          code = pdfi_copy_type1_font(ctx, spdffont, font_dict, tpdffont);
751
850k
          break;
752
101
        case e_pdf_font_cff:
753
101
          code = pdfi_copy_cff_font(ctx, spdffont, font_dict, tpdffont);
754
101
          break;
755
3.24k
        case e_pdf_font_truetype:
756
3.24k
          code = pdfi_copy_truetype_font(ctx, spdffont, font_dict, tpdffont);
757
3.24k
          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
854k
    }
764
854k
    return code;
765
854k
}
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
126k
{
775
126k
    int code = gs_error_invalidfont;
776
126k
    if (fbuf != NULL) {
777
        /* First, see if we can glean the type from the magic number */
778
126k
        int sftype = pdfi_fonttype_picker(fbuf, fbuflen);
779
126k
        if (sftype == no_type_font) {
780
571
            if (fftype != no_type_font)
781
551
                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
571
        }
792
        /* fbuf ownership passes to the font loader */
793
126k
        switch (sftype) {
794
66.5k
            case type1_font:
795
66.5k
                code = pdfi_read_type1_font(ctx, (pdf_dict *)font_dict, stream_dict, page_dict, fbuf, fbuflen, ppdffont);
796
66.5k
                fbuf = NULL;
797
66.5k
                break;
798
12.9k
            case cff_font:
799
12.9k
                code = pdfi_read_cff_font(ctx, (pdf_dict *)font_dict, stream_dict, page_dict, fbuf, fbuflen, cidfont, ppdffont);
800
12.9k
                fbuf = NULL;
801
12.9k
                break;
802
46.7k
            case tt_font:
803
46.7k
                {
804
46.7k
                    if (cidfont)
805
23.9k
                        code = pdfi_read_cidtype2_font(ctx, font_dict, stream_dict, page_dict, fbuf, fbuflen, findex, ppdffont);
806
22.8k
                    else
807
22.8k
                        code = pdfi_read_truetype_font(ctx, font_dict, stream_dict, page_dict, fbuf, fbuflen, findex, ppdffont);
808
46.7k
                    fbuf = NULL;
809
46.7k
                }
810
46.7k
                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
126k
        }
815
126k
    }
816
126k
    return code;
817
126k
}
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
25.3k
        pdfi_countdown(basefont);
837
25.3k
        return_error(gs_error_invalidfont);
838
25.3k
    }
839
840
1.65M
    if (substitute == true) {
841
827k
        char *fbname;
842
827k
        int fbnamelen;
843
827k
        int64_t flags = 0;
844
827k
        if (fontdesc != NULL) {
845
24.4k
            (void)pdfi_dict_get_int(ctx, fontdesc, "Flags", &flags);
846
24.4k
        }
847
827k
        code = pdfi_font_substitute_by_flags(ctx, (int)flags, &fbname, &fbnamelen);
848
827k
        if (code < 0)
849
0
            return code;
850
851
827k
        code = pdfi_name_alloc(ctx, (byte *)fbname, strlen(fbname), (pdf_obj **) &fontname);
852
827k
        if (code < 0)
853
0
            return code;
854
827k
        pdfi_countup(fontname);
855
827k
    }
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
6.97k
                        pdfi_countdown(fontname);
889
890
6.97k
                        code = pdfi_name_alloc(ctx, (byte *)fn, strlen(fn), (pdf_obj **) &fontname);
891
6.97k
                        if (code < 0)
892
0
                            return code;
893
6.97k
                        pdfi_countup(fontname);
894
6.97k
                    }
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
101k
            else
935
101k
                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
803k
                pdfi_countdown(fontname);
941
803k
                fontname = mapname;
942
803k
                mapname = NULL;
943
803k
                f_retry = false;
944
803k
                continue;
945
803k
            }
946
851k
            if (code >= 0) {
947
49.9k
                gs_const_string fname;
948
949
49.9k
                sfilename(s, &fname);
950
49.9k
                if (fname.size < gp_file_name_sizeof) {
951
49.9k
                    memcpy(fontfname, fname.data, fname.size);
952
49.9k
                    fontfname[fname.size] = '\0';
953
49.9k
                }
954
0
                else {
955
0
                    strcpy(fontfname, "unnamed file");
956
0
                }
957
49.9k
                sfseek(s, 0, SEEK_END);
958
49.9k
                buflen = sftell(s);
959
49.9k
                sfseek(s, 0, SEEK_SET);
960
49.9k
                buf = gs_alloc_bytes(ctx->memory, buflen, "pdfi_open_t1_font_file(buf)");
961
49.9k
                if (buf != NULL) {
962
49.9k
                    sfread(buf, 1, buflen, s);
963
49.9k
                }
964
0
                else {
965
0
                    code = gs_note_error(gs_error_VMerror);
966
0
                }
967
49.9k
                sfclose(s);
968
                /* Buffer owership moves to the font object */
969
49.9k
                code = pdfi_load_font_buffer(ctx, buf, buflen, no_type_font, NULL, findex, stream_dict, page_dict, NULL, &pdffont, false);
970
49.9k
                if (code >= 0) {
971
49.9k
                    pdffont->filename = NULL;
972
49.9k
                    code = pdfi_object_alloc(ctx, PDF_STRING, strlen(fontfname) , (pdf_obj **)&pdffont->filename);
973
49.9k
                    if (code >= 0) {
974
49.9k
                        pdfi_countup(pdffont->filename);
975
49.9k
                        memcpy(pdffont->filename->data, fontfname, strlen(fontfname));
976
49.9k
                        pdffont->filename->length = strlen(fontfname);
977
49.9k
                    }
978
979
49.9k
                    if (ctx->pdf_substitute_fonts == NULL) {
980
39.5k
                        code = pdfi_dict_alloc(ctx, 16, &ctx->pdf_substitute_fonts);
981
39.5k
                        if (code >= 0)
982
39.5k
                            pdfi_countup(ctx->pdf_substitute_fonts);
983
39.5k
                    }
984
49.9k
                    if (ctx->pdf_substitute_fonts != NULL) {
985
49.9k
                        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
49.9k
                        else
998
49.9k
                            code = 0;
999
1000
49.9k
                        if (code == 0)
1001
49.9k
                            (void)pdfi_dict_put_obj(ctx, ctx->pdf_substitute_fonts, mapname, (pdf_obj *)pdffont, true);
1002
49.9k
                        code = 0;
1003
49.9k
                    }
1004
49.9k
                }
1005
49.9k
            }
1006
851k
        }
1007
1.65M
        break;
1008
2.45M
    } while (1);
1009
1010
1.65M
    if (code >= 0) {
1011
850k
        if (basefont) {
1012
849k
            pdfi_print_cstring(ctx, "Loading font ");
1013
849k
            pdfi_print_font_name(ctx, (pdf_name *)basefont);
1014
849k
            pdfi_print_cstring(ctx, " (or substitute) from ");
1015
849k
        }
1016
867
        else {
1017
867
            pdfi_print_cstring(ctx, "Loading nameless font from ");
1018
867
        }
1019
850k
        pdfi_print_font_string(ctx, pdffont->filename);
1020
850k
        pdfi_print_cstring(ctx, "\n");
1021
1022
850k
        code = pdfi_copy_font(ctx, pdffont, font_dict, &substpdffont);
1023
850k
        pdfi_countdown(pdffont);
1024
850k
    }
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
964k
{
1036
964k
    int code;
1037
964k
    pdf_font *ppdffont = NULL;
1038
964k
    pdf_font *ppdfdescfont = NULL;
1039
964k
    pdf_name *Type = NULL;
1040
964k
    pdf_name *Subtype = NULL;
1041
964k
    pdf_dict *fontdesc = NULL;
1042
964k
    pdf_stream *fontfile = NULL;
1043
964k
    pdf_name *ffsubtype = NULL;
1044
964k
    int fftype = no_type_font;
1045
964k
    byte *fbuf = NULL;
1046
964k
    int64_t fbuflen = 0;
1047
964k
    int substitute = font_embedded;
1048
964k
    int findex = 0;
1049
1050
964k
    code = pdfi_dict_get_type(ctx, font_dict, "Type", PDF_NAME, (pdf_obj **)&Type);
1051
964k
    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
964k
    else {
1056
964k
        if (!pdfi_name_is(Type, "Font")){
1057
7.61k
            code = gs_note_error(gs_error_typecheck);
1058
7.61k
            goto exit;
1059
7.61k
        }
1060
964k
    }
1061
957k
    code = pdfi_dict_get_type(ctx, font_dict, "Subtype", PDF_NAME, (pdf_obj **)&Subtype);
1062
957k
    if (code < 0) {
1063
745
        if ((code = pdfi_set_error_stop(ctx, code, NULL, E_PDF_NO_SUBTYPE, "pdfi_load_font", NULL)) < 0)
1064
0
            goto exit;
1065
745
    }
1066
1067
    /* Beyond Type 0 and Type 3, there is no point trusting the Subtype key */
1068
957k
    if (Subtype != NULL && pdfi_name_is(Subtype, "Type0")) {
1069
42.8k
        if (cidfont == true) {
1070
6
            code = gs_note_error(gs_error_invalidfont);
1071
6
        }
1072
42.8k
        else {
1073
42.8k
            code = pdfi_read_type0_font(ctx, (pdf_dict *)font_dict, stream_dict, page_dict, &ppdffont);
1074
42.8k
        }
1075
42.8k
    }
1076
914k
    else if (Subtype != NULL && pdfi_name_is(Subtype, "Type3")) {
1077
2.84k
        code = pdfi_read_type3_font(ctx, (pdf_dict *)font_dict, stream_dict, page_dict, &ppdffont);
1078
2.84k
        if (code < 0)
1079
571
            goto exit;
1080
2.84k
    }
1081
911k
    else {
1082
911k
        if (Subtype != NULL && !pdfi_name_is(Subtype, "Type1") && !pdfi_name_is(Subtype, "TrueType") && !pdfi_name_is(Subtype, "CIDFont")
1083
911k
            && !pdfi_name_is(Subtype, "CIDFontType2") && !pdfi_name_is(Subtype, "CIDFontType0") && !pdfi_name_is(Subtype, "MMType1")) {
1084
1085
744
            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
744
        }
1089
        /* We should always have a font descriptor here, but we have to carry on
1090
           even if we don't
1091
         */
1092
911k
        code = pdfi_dict_get_type(ctx, font_dict, "FontDescriptor", PDF_DICT, (pdf_obj **)&fontdesc);
1093
911k
        if (fontdesc != NULL && pdfi_type_of(fontdesc) == PDF_DICT) {
1094
82.5k
            pdf_obj *Name = NULL;
1095
1096
82.5k
            code = pdfi_dict_get_type(ctx, (pdf_dict *) fontdesc, "FontName", PDF_NAME, (pdf_obj **)&Name);
1097
82.5k
            if (code < 0)
1098
1.01k
                pdfi_set_warning(ctx, 0, NULL, W_PDF_FDESC_BAD_FONTNAME, "pdfi_load_font", "");
1099
82.5k
            pdfi_countdown(Name);
1100
82.5k
            Name = NULL;
1101
1102
82.5k
            if (cidfont == true) {
1103
15.8k
                code = -1;
1104
15.8k
            }
1105
66.7k
            else {
1106
66.7k
                code = pdfi_find_cache_resource_font(ctx, (pdf_obj *)fontdesc, (pdf_obj **)&ppdfdescfont);
1107
66.7k
                if (code >= 0) {
1108
3.45k
                    code = pdfi_copy_font(ctx, ppdfdescfont, font_dict, &ppdffont);
1109
3.45k
                }
1110
66.7k
            }
1111
1112
82.5k
            if (code < 0) {
1113
79.1k
                code = pdfi_dict_get_type(ctx, (pdf_dict *) fontdesc, "FontFile", PDF_STREAM, (pdf_obj **)&fontfile);
1114
79.1k
                if (code >= 0)
1115
16.5k
                    fftype = type1_font;
1116
62.5k
                else {
1117
62.5k
                    code = pdfi_dict_get_type(ctx, (pdf_dict *) fontdesc, "FontFile2", PDF_STREAM, (pdf_obj **)&fontfile);
1118
62.5k
                    fftype = tt_font;
1119
62.5k
                }
1120
79.1k
                if (code < 0) {
1121
29.6k
                    code = pdfi_dict_get_type(ctx, (pdf_dict *) fontdesc, "FontFile3", PDF_STREAM, (pdf_obj **)&fontfile);
1122
29.6k
                    if (code >= 0 && fontfile != NULL) {
1123
13.4k
                        code = pdfi_dict_get_type(ctx, fontfile->stream_dict, "Subtype", PDF_NAME, (pdf_obj **)&ffsubtype);
1124
13.4k
                        if (code >= 0) {
1125
13.3k
                            if (pdfi_name_is(ffsubtype, "Type1"))
1126
0
                                fftype = type1_font;
1127
13.3k
                            else if (pdfi_name_is(ffsubtype, "Type1C"))
1128
10.3k
                                fftype = cff_font;
1129
3.04k
                            else if (pdfi_name_is(ffsubtype, "OpenType"))
1130
367
                                fftype = cff_font;
1131
2.67k
                            else if (pdfi_name_is(ffsubtype, "CIDFontType0C"))
1132
2.25k
                                fftype = cff_font;
1133
425
                            else if (pdfi_name_is(ffsubtype, "TrueType"))
1134
0
                                fftype = tt_font;
1135
425
                            else
1136
425
                                fftype = no_type_font;
1137
13.3k
                        }
1138
13.4k
                    }
1139
29.6k
                }
1140
79.1k
            }
1141
82.5k
        }
1142
1143
911k
        if (ppdffont == NULL) {
1144
907k
            if (fontfile != NULL) {
1145
62.8k
                code = pdfi_stream_to_buffer(ctx, (pdf_stream *) fontfile, &fbuf, &fbuflen);
1146
62.8k
                pdfi_countdown(fontfile);
1147
62.8k
                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
62.8k
            }
1158
1159
922k
            while (1) {
1160
922k
                if (fbuf != NULL) {
1161
                    /* fbuf overship passes to pdfi_load_font_buffer() */
1162
76.3k
                    code = pdfi_load_font_buffer(ctx, fbuf, fbuflen, fftype, Subtype, findex, stream_dict, page_dict, font_dict, &ppdffont, cidfont);
1163
1164
76.3k
                    if (code < 0 && substitute == font_embedded) {
1165
19.0k
                        char msg[129];
1166
1167
19.0k
                        gs_snprintf(msg, 128, "Cannot process embedded stream for font object %d %d. Attempting to load a substitute font.\n", (int)font_dict->object_num, (int)font_dict->generation_num);
1168
1169
19.0k
                        if ((code = pdfi_set_error_stop(ctx, gs_note_error(gs_error_invalidfont), NULL, E_PDF_BAD_EMBEDDED_FONT, "pdfi_load_font", msg)) < 0) {
1170
0
                            goto exit;
1171
0
                        }
1172
19.0k
                        else {
1173
19.0k
                            code = gs_error_invalidfont;
1174
19.0k
                        }
1175
19.0k
                    }
1176
76.3k
                }
1177
846k
                else {
1178
846k
                    code = gs_error_invalidfont;
1179
846k
                }
1180
1181
922k
                if (code < 0 && code != gs_error_VMerror && substitute == font_embedded) {
1182
865k
                    substitute = font_from_file;
1183
1184
865k
                    if (cidfont == true) {
1185
14.9k
                        code =  pdfi_open_CIDFont_substitute_file(ctx, font_dict, fontdesc, false, &fbuf, &fbuflen, &findex);
1186
14.9k
                        if (code < 0) {
1187
14.9k
                            code =  pdfi_open_CIDFont_substitute_file(ctx, font_dict, fontdesc, true, &fbuf, &fbuflen, &findex);
1188
14.9k
                            substitute |= font_substitute;
1189
14.9k
                        }
1190
1191
14.9k
                        if (code < 0)
1192
0
                            goto exit;
1193
14.9k
                    }
1194
850k
                    else {
1195
850k
                        code = pdfi_load_font_file(ctx, no_type_font, Subtype, stream_dict, page_dict, font_dict, fontdesc, false, &ppdffont);
1196
850k
                        if (code < 0) {
1197
827k
                            code = pdfi_load_font_file(ctx, no_type_font, Subtype, stream_dict, page_dict, font_dict, fontdesc, true, &ppdffont);
1198
827k
                            substitute |= font_substitute;
1199
827k
                        }
1200
850k
                        break;
1201
850k
                    }
1202
14.9k
                    continue;
1203
865k
                }
1204
57.2k
                break;
1205
922k
            }
1206
907k
        }
1207
911k
    }
1208
956k
    if (ppdffont == NULL || code < 0) {
1209
34.5k
        *ppfont = NULL;
1210
34.5k
        code = gs_note_error(gs_error_invalidfont);
1211
34.5k
    }
1212
922k
    else {
1213
922k
        ppdffont->substitute = (substitute != font_embedded);
1214
1215
922k
        if ((substitute & font_substitute) == font_substitute)
1216
834k
            code = pdfi_font_match_glyph_widths(ppdffont);
1217
87.3k
        else if (ppdffont->substitute != true && fontdesc != NULL && ppdfdescfont == NULL
1218
87.3k
            && (ppdffont->pdfi_font_type == e_pdf_font_type1 || ppdffont->pdfi_font_type == e_pdf_font_cff
1219
42.1k
            || ppdffont->pdfi_font_type == e_pdf_font_truetype)) {
1220
33.8k
            pdfi_cache_resource_font(ctx, (pdf_obj *)fontdesc, (pdf_obj *)ppdffont);
1221
33.8k
        }
1222
922k
        *ppfont = (gs_font *)ppdffont->pfont;
1223
922k
     }
1224
1225
964k
exit:
1226
964k
    pdfi_countdown(ppdfdescfont);
1227
964k
    pdfi_countdown(fontdesc);
1228
964k
    pdfi_countdown(Type);
1229
964k
    pdfi_countdown(Subtype);
1230
964k
    pdfi_countdown(ffsubtype);
1231
964k
    return code;
1232
956k
}
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.23M
{
1236
1.23M
    int code;
1237
1.23M
    gs_font *pfont;
1238
1.23M
    pdf_font *pdfif;
1239
1240
1.23M
    switch (pdfi_type_of(font_dict)) {
1241
1.08M
        case PDF_FONT:
1242
1.08M
            pdfi_countup(font_dict);
1243
1.08M
            pfont = (gs_font *)((pdf_font *)font_dict)->pfont;
1244
1.08M
            code = 0;
1245
1.08M
            break;
1246
140k
        case PDF_DICT:
1247
140k
            code = pdfi_load_font(ctx, stream_dict, page_dict, font_dict, &pfont, false);
1248
140k
            break;
1249
18.6k
        default:
1250
18.6k
            code = gs_note_error(gs_error_typecheck);
1251
18.6k
            goto exit;
1252
1.23M
    }
1253
1.22M
    if (code < 0)
1254
34.9k
        goto exit;
1255
1256
    /* Everything looks good, set the font, unless it's the current font */
1257
1.18M
    if (pfont != ctx->pgs->font) {
1258
969k
        code = pdfi_gs_setfont(ctx, pfont);
1259
969k
    }
1260
1.18M
    pdfif = (pdf_font *)pfont->client_data;
1261
1.18M
    pdfi_countdown(pdfif);
1262
1263
1.18M
    if (code < 0)
1264
0
        goto exit;
1265
1266
1.18M
    code = gs_setPDFfontsize(ctx->pgs, point_size);
1267
1.23M
exit:
1268
1.23M
    return code;
1269
1.18M
}
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.98M
{
1273
1.98M
    int code;
1274
1.98M
    pdf_dict *font_dict = NULL;
1275
1276
1.98M
    if (pdfi_type_of(fontname) != PDF_NAME) {
1277
        /* Passing empty string here should fall back to a default font */
1278
22.3k
        return pdfi_font_set_internal_string(ctx, "", point_size);
1279
22.3k
    }
1280
1281
    /* Look fontname up in the resources */
1282
1.96M
    code = pdfi_loop_detector_mark(ctx);
1283
1.96M
    if (code < 0)
1284
0
        goto exit;
1285
1.96M
    code = pdfi_find_resource(ctx, (unsigned char *)"Font", fontname, stream_dict, page_dict, (pdf_obj **)&font_dict);
1286
1.96M
    (void)pdfi_loop_detector_cleartomark(ctx);
1287
1.96M
    if (code < 0)
1288
723k
        goto exit;
1289
1.23M
    code = pdfi_load_dict_font(ctx, stream_dict, page_dict, font_dict, point_size);
1290
1291
1.96M
exit:
1292
1.96M
    pdfi_countdown(font_dict);
1293
1.96M
    return code;
1294
1.23M
}
1295
1296
int pdfi_get_cidfont_glyph_metrics(gs_font *pfont, gs_glyph cid, double *widths, bool vertical)
1297
1.70M
{
1298
1.70M
    pdf_font *pdffont = (pdf_font *)pfont->client_data;
1299
1.70M
    int i, code = 0;
1300
1.70M
    pdf_num *c = NULL, *c2 = NULL;
1301
1.70M
    pdf_obj *o = NULL;
1302
1.70M
    pdf_array *W = NULL, *W2 = NULL, *DW2 = NULL;
1303
1.70M
    double DW;
1304
1305
1.70M
    if (pdffont->pdfi_font_type == e_pdf_cidfont_type0) {
1306
112k
        pdf_cidfont_type0 *cidfont = (pdf_cidfont_type0 *)pdffont;
1307
112k
        DW = cidfont->DW;
1308
112k
        DW2 = cidfont->DW2;
1309
112k
        W = cidfont->W;
1310
112k
        W2 = cidfont->W2;
1311
112k
    }
1312
1.59M
    else if (pdffont->pdfi_font_type == e_pdf_cidfont_type2) {
1313
1.59M
        pdf_cidfont_type2 *cidfont = (pdf_cidfont_type2 *)pdffont;
1314
1.59M
        DW = cidfont->DW;
1315
1.59M
        DW2 = cidfont->DW2;
1316
1.59M
        W = cidfont->W;
1317
1.59M
        W2 = cidfont->W2;
1318
1.59M
    }
1319
0
    else {
1320
0
        return_error(gs_error_invalidfont);
1321
0
    }
1322
1323
1.70M
    widths[GLYPH_W0_WIDTH_INDEX] = DW;
1324
1.70M
    widths[GLYPH_W0_HEIGHT_INDEX] = 0;
1325
1.70M
    if (W != NULL) {
1326
1.53M
        i = 0;
1327
1328
26.0M
        while(1) {
1329
26.0M
            pdf_obj_type type;
1330
1331
26.0M
            if (i + 1>= W->size) break;
1332
25.9M
            code = pdfi_array_get_type(pdffont->ctx, W, i, PDF_INT, (pdf_obj **)&c);
1333
25.9M
            if (code < 0) goto cleanup;
1334
1335
25.9M
            code = pdfi_array_get(pdffont->ctx, W, i + 1, &o);
1336
25.9M
            if (code < 0) goto cleanup;
1337
1338
25.9M
            type = pdfi_type_of(o);
1339
25.9M
            if (type == PDF_INT) {
1340
3.51M
                double d;
1341
3.51M
                c2 = (pdf_num *)o;
1342
3.51M
                o = NULL;
1343
3.51M
                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
183
                    break;
1348
183
                }
1349
1350
3.51M
                code = pdfi_array_get_number(pdffont->ctx, W, i + 2, &d);
1351
3.51M
                if (code < 0) goto cleanup;
1352
3.51M
                if (cid >= c->value.i && cid <= c2->value.i) {
1353
107k
                    widths[GLYPH_W0_WIDTH_INDEX] = d;
1354
107k
                    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
107k
                    break;
1359
107k
                }
1360
3.40M
                else {
1361
3.40M
                    i += 3;
1362
3.40M
                    pdfi_countdown(c2);
1363
3.40M
                    pdfi_countdown(c);
1364
3.40M
                    c = c2 = NULL;
1365
3.40M
                    continue;
1366
3.40M
                }
1367
3.51M
            }
1368
22.4M
            else if (type == PDF_ARRAY) {
1369
22.4M
                pdf_array *a = (pdf_array *)o;
1370
22.4M
                o = NULL;
1371
22.4M
                if (cid >= c->value.i && cid < c->value.i + a->size) {
1372
1.27M
                    code = pdfi_array_get_number(pdffont->ctx, a, cid - c->value.i, &widths[GLYPH_W0_WIDTH_INDEX]);
1373
1.27M
                    if (code >= 0) {
1374
1.27M
                        pdfi_countdown(a);
1375
1.27M
                        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.27M
                        break;
1380
1.27M
                    }
1381
1.27M
                }
1382
21.1M
                pdfi_countdown(a);
1383
21.1M
                pdfi_countdown(c);
1384
21.1M
                c = NULL;
1385
21.1M
                i += 2;
1386
21.1M
                continue;
1387
22.4M
            }
1388
943
            else {
1389
943
                code = gs_note_error(gs_error_typecheck);
1390
943
                goto cleanup;
1391
943
            }
1392
25.9M
        }
1393
1.52M
        pdfi_countdown(c2);
1394
1.52M
        pdfi_countdown(c);
1395
1.52M
        pdfi_countdown(o);
1396
1.52M
        c = c2 = NULL;
1397
1.52M
        o = NULL;
1398
1.52M
    }
1399
1400
1.70M
    if (vertical) {
1401
        /* Default default <sigh>! */
1402
1.70M
        widths[GLYPH_W1_WIDTH_INDEX] = 0;
1403
1.70M
        widths[GLYPH_W1_HEIGHT_INDEX] = -1000.0;
1404
1.70M
        widths[GLYPH_W1_V_X_INDEX] = (widths[GLYPH_W0_WIDTH_INDEX] / 2.0);
1405
1.70M
        widths[GLYPH_W1_V_Y_INDEX] = 880.0;
1406
1407
1.70M
        if (DW2 != NULL && pdfi_type_of(DW2) == PDF_ARRAY
1408
1.70M
            && DW2->size >= 2) {
1409
7.56k
            code = pdfi_array_get_number(pdffont->ctx, (pdf_array *)DW2, 0, &widths[GLYPH_W1_V_Y_INDEX]);
1410
7.56k
            if (code >= 0)
1411
7.56k
                code = pdfi_array_get_number(pdffont->ctx, (pdf_array *)DW2, 1, &widths[GLYPH_W1_HEIGHT_INDEX]);
1412
7.56k
            if (code >= 0) {
1413
7.56k
                widths[GLYPH_W1_V_X_INDEX] = widths[GLYPH_W0_WIDTH_INDEX] / 2.0;
1414
7.56k
                widths[GLYPH_W1_WIDTH_INDEX] = 0.0;
1415
7.56k
            }
1416
7.56k
        }
1417
1.70M
        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
1.70M
    }
1490
1491
1.70M
cleanup:
1492
1.70M
    pdfi_countdown(c2);
1493
1.70M
    pdfi_countdown(c);
1494
1.70M
    pdfi_countdown(o);
1495
1496
1.70M
    return code;
1497
1.70M
}
1498
1499
int pdfi_d0(pdf_context *ctx)
1500
3.46k
{
1501
3.46k
    int code = 0, gsave_level = 0;
1502
3.46k
    double width[2];
1503
1504
3.46k
    if (ctx->text.inside_CharProc == false)
1505
2.69k
        pdfi_set_warning(ctx, 0, NULL, W_PDF_NOTINCHARPROC, "pdfi_d0", NULL);
1506
1507
3.46k
    ctx->text.CharProc_d_type = pdf_type3_d0;
1508
1509
3.46k
    if (pdfi_count_stack(ctx) < 2) {
1510
689
        code = gs_note_error(gs_error_stackunderflow);
1511
689
        goto d0_error;
1512
689
    }
1513
1514
2.77k
    if (pdfi_type_of(ctx->stack_top[-1]) != PDF_INT && pdfi_type_of(ctx->stack_top[-1]) != PDF_REAL) {
1515
625
        code = gs_note_error(gs_error_typecheck);
1516
625
        goto d0_error;
1517
625
    }
1518
2.15k
    if (pdfi_type_of(ctx->stack_top[-2]) != PDF_INT && pdfi_type_of(ctx->stack_top[-2]) != PDF_REAL) {
1519
117
        code = gs_note_error(gs_error_typecheck);
1520
117
        goto d0_error;
1521
117
    }
1522
2.03k
    if(ctx->text.current_enum == NULL) {
1523
1.26k
        code = gs_note_error(gs_error_undefined);
1524
1.26k
        goto d0_error;
1525
1.26k
    }
1526
1527
768
    if (pdfi_type_of(ctx->stack_top[-2]) == PDF_INT)
1528
768
        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
768
    if (pdfi_type_of(ctx->stack_top[-1]) == PDF_INT)
1532
768
        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
768
    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
768
    if (ctx->text.current_enum == NULL) {
1546
0
        code = gs_note_error(gs_error_unknownerror);
1547
0
        goto d0_error;
1548
0
    }
1549
1550
768
    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
768
    if (ctx->pgs->level > gsave_level)
1569
0
        ctx->current_stream_save.gsave_level += ctx->pgs->level - gsave_level;
1570
1571
768
    if (code < 0)
1572
3
        goto d0_error;
1573
765
    pdfi_pop(ctx, 2);
1574
765
    return 0;
1575
1576
2.70k
d0_error:
1577
2.70k
    pdfi_clearstack(ctx);
1578
2.70k
    return code;
1579
768
}
1580
1581
int pdfi_d1(pdf_context *ctx)
1582
41.4k
{
1583
41.4k
    int code = 0, gsave_level;
1584
41.4k
    double wbox[6];
1585
1586
41.4k
    if (ctx->text.inside_CharProc == false)
1587
502
        pdfi_set_warning(ctx, 0, NULL, W_PDF_NOTINCHARPROC, "pdfi_d1", NULL);
1588
1589
41.4k
    ctx->text.CharProc_d_type = pdf_type3_d1;
1590
1591
41.4k
    code = pdfi_destack_reals(ctx, wbox, 6);
1592
41.4k
    if (code < 0)
1593
649
        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
40.8k
    gsave_level = ctx->pgs->level;
1603
1604
40.8k
    if (ctx->text.current_enum == NULL) {
1605
129
        code = gs_note_error(gs_error_unknownerror);
1606
129
        goto d1_error;
1607
129
    }
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
40.6k
    code = gs_text_setcachedevice(ctx->text.current_enum, wbox);
1633
40.6k
#endif
1634
1635
    /* See the comment immediately after gs_text_setcachedvice() in pdfi_d0 above */
1636
40.6k
    if (ctx->pgs->level > gsave_level)
1637
12.7k
        ctx->current_stream_save.gsave_level += ctx->pgs->level - gsave_level;
1638
1639
40.6k
    if (code < 0)
1640
31
        goto d1_error;
1641
40.6k
    return 0;
1642
1643
809
d1_error:
1644
809
    pdfi_clearstack(ctx);
1645
809
    return code;
1646
40.6k
}
1647
1648
int pdfi_Tf(pdf_context *ctx, pdf_dict *stream_dict, pdf_dict *page_dict)
1649
2.02M
{
1650
2.02M
    double point_size = 0;
1651
2.02M
    pdf_obj *point_arg = NULL;
1652
2.02M
    int code = 0;
1653
2.02M
    pdf_name *fontname = NULL;
1654
1655
2.02M
    if (pdfi_count_stack(ctx) < 2) {
1656
32.2k
        pdfi_clearstack(ctx);
1657
32.2k
        return_error(gs_error_stackunderflow);
1658
32.2k
    }
1659
1660
    /* Get refs to the args and pop them */
1661
1.98M
    point_arg = ctx->stack_top[-1];
1662
1.98M
    pdfi_countup(point_arg);
1663
1.98M
    fontname = (pdf_name *)ctx->stack_top[-2];
1664
1.98M
    pdfi_countup(fontname);
1665
1.98M
    pdfi_pop(ctx, 2);
1666
1667
    /* Get the point_size */
1668
1.98M
    code = pdfi_obj_to_real(ctx, point_arg, &point_size);
1669
1.98M
    if (code < 0)
1670
2.76k
        goto exit0;
1671
1672
1.98M
    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.98M
    if (code < 0)
1676
777k
        code = pdfi_font_set_internal_name(ctx, fontname, point_size);
1677
1.98M
 exit0:
1678
1.98M
    pdfi_countdown(fontname);
1679
1.98M
    pdfi_countdown(point_arg);
1680
1.98M
    return code;
1681
1.98M
}
1682
1683
int pdfi_free_font(pdf_obj *font)
1684
986k
{
1685
986k
    pdf_font *f = (pdf_font *)font;
1686
1687
986k
    switch (f->pdfi_font_type) {
1688
16.1k
        case e_pdf_font_type0:
1689
16.1k
            return pdfi_free_font_type0((pdf_obj *)font);
1690
0
            break;
1691
910k
        case e_pdf_font_type1:
1692
910k
            return pdfi_free_font_type1((pdf_obj *)font);
1693
0
            break;
1694
12.2k
        case e_pdf_font_cff:
1695
12.2k
            return pdfi_free_font_cff((pdf_obj *)font);
1696
2.84k
        case e_pdf_font_type3:
1697
2.84k
            return pdfi_free_font_type3((pdf_obj *)font);
1698
0
            break;
1699
26.1k
        case e_pdf_font_truetype:
1700
26.1k
            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.1k
        case e_pdf_cidfont_type2:
1706
16.1k
            return pdfi_free_font_cidtype2((pdf_obj *)font);
1707
0
            break;
1708
1.96k
        case e_pdf_cidfont_type0:
1709
1.96k
            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
986k
    }
1717
0
    return 0;
1718
986k
}
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
22.9k
{
1724
22.9k
    uint esize = Encoding->size;
1725
22.9k
    uint best = esize / 3;  /* must match at least this many */
1726
22.9k
    int i, index, near_index = ENCODING_INDEX_UNKNOWN, code;
1727
1728
180k
    for (index = 0; index < NUM_KNOWN_REAL_ENCODINGS; ++index) {
1729
158k
        uint match = esize;
1730
1731
19.9M
        for (i = esize; --i >= 0;) {
1732
19.8M
            gs_const_string rstr;
1733
19.8M
            pdf_name *ename;
1734
1735
19.8M
            code = pdfi_array_get_type(ctx, Encoding, (uint64_t)i, PDF_NAME, (pdf_obj **)&ename);
1736
19.8M
            if (code < 0) {
1737
16
                return;
1738
16
            }
1739
1740
19.8M
            gs_c_glyph_name(gs_c_known_encode((gs_char)i, index), &rstr);
1741
19.8M
            if (rstr.size == ename->length &&
1742
19.8M
                !memcmp(rstr.data, ename->data, rstr.size)) {
1743
8.10M
                pdfi_countdown(ename);
1744
8.10M
                continue;
1745
8.10M
            }
1746
11.7M
            pdfi_countdown(ename);
1747
11.7M
            if (--match <= best) {
1748
121k
                break;
1749
121k
            }
1750
11.7M
        }
1751
158k
        if (match > best) {
1752
37.3k
            best = match;
1753
37.3k
            near_index = index;
1754
            /* If we have a perfect match, stop now. */
1755
37.3k
            if (best == esize)
1756
768
                break;
1757
37.3k
        }
1758
158k
    }
1759
22.9k
    if (best == esize) *ind = index;
1760
22.9k
    *near_ind = near_index;
1761
22.9k
}
1762
1763
static inline int pdfi_encoding_name_to_index(pdf_name *name)
1764
134k
{
1765
134k
    int ind = gs_error_undefined;
1766
134k
    if (pdfi_type_of(name) == PDF_NAME) {
1767
134k
        if (pdfi_name_is(name, "StandardEncoding")) {
1768
66.6k
            ind = ENCODING_INDEX_STANDARD;
1769
67.4k
        } else if (pdfi_name_is(name, "WinAnsiEncoding")) {
1770
53.6k
            ind = ENCODING_INDEX_WINANSI;
1771
53.6k
        }
1772
13.7k
        else if (pdfi_name_is(name, "MacRomanEncoding")) {
1773
13.3k
            ind = ENCODING_INDEX_MACROMAN;
1774
13.3k
        }
1775
422
        else if (pdfi_name_is(name, "MacExpertEncoding")) {
1776
32
            ind = ENCODING_INDEX_MACEXPERT;
1777
32
        }
1778
390
        else if (pdfi_name_is(name, "SymbolEncoding")) {
1779
0
            ind = ENCODING_INDEX_SYMBOL;
1780
0
        }
1781
390
        else if (pdfi_name_is(name, "DingbatsEncoding")) {
1782
0
            ind = ENCODING_INDEX_DINGBATS;
1783
0
        }
1784
134k
    }
1785
134k
    return ind;
1786
134k
}
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
371
        return code;
1806
130k
    if (ind != NULL) *ind = (gs_encoding_index_t)code;
1807
130k
    gs_encoding = (unsigned char)code;
1808
130k
    code = 0;
1809
1810
33.4M
    for (i = 0;i<256;i++) {
1811
33.3M
        temp = gs_c_known_encode(i, gs_encoding);
1812
33.3M
        gs_c_glyph_name(temp, &str);
1813
33.3M
        code = pdfi_name_alloc(ctx, (byte *)str.data, str.size, (pdf_obj **)&n);
1814
33.3M
        if (code < 0)
1815
0
            return code;
1816
33.3M
        pdfi_countup(n);
1817
33.3M
        code = pdfi_array_put(ctx, Encoding, (uint64_t)i, (pdf_obj *)n);
1818
33.3M
        pdfi_countdown(n);
1819
33.3M
        if (code < 0)
1820
0
            return code;
1821
33.3M
    }
1822
130k
    return 0;
1823
130k
}
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
371
                pdfi_countdown(*Encoding);
1849
371
                *Encoding = NULL;
1850
371
                return code;
1851
371
            }
1852
119k
            nearest_encoding_index = encoding_index;
1853
119k
            break;
1854
23.5k
        case PDF_DICT:
1855
23.5k
        {
1856
23.5k
            pdf_name *n = NULL;
1857
23.5k
            pdf_array *a = NULL;
1858
23.5k
            pdf_obj *o = NULL;
1859
23.5k
            int offset = 0;
1860
23.5k
            bool b_e_known;
1861
1862
23.5k
            if (pdfi_type_of(pdf_Encoding) == PDF_DICT) {
1863
23.5k
                code = pdfi_dict_known(ctx, (pdf_dict *)pdf_Encoding, "BaseEncoding", &b_e_known);
1864
23.5k
                if (code < 0)
1865
0
                    b_e_known = false;
1866
23.5k
            }
1867
0
            else {
1868
0
                b_e_known = false;
1869
0
            }
1870
1871
23.5k
            if (b_e_known == false && font_Encoding != NULL && pdfi_type_of(font_Encoding) == PDF_ARRAY) {
1872
12.5k
                pdf_array *fenc = (pdf_array *)font_Encoding;
1873
3.21M
                for (i = 0; i < pdfi_array_size(fenc) && code >= 0; i++) {
1874
3.20M
                    code = pdfi_array_get(ctx, fenc, (uint64_t)i, &o);
1875
3.20M
                    if (code >= 0)
1876
3.20M
                        code = pdfi_array_put(ctx, (pdf_array *)*Encoding, (uint64_t)i, o);
1877
3.20M
                    pdfi_countdown(o);
1878
3.20M
                }
1879
12.5k
                if (code < 0) {
1880
0
                    pdfi_countdown(*Encoding);
1881
0
                    *Encoding = NULL;
1882
0
                    return code;
1883
0
                }
1884
12.5k
            }
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.51k
                    if (pdfi_encoding_name_to_index(n) < 0) {
1889
19
                        pdfi_set_warning(ctx, 0, NULL, W_PDF_INVALID_FONT_BASEENC, "pdfi_create_Encoding", NULL);
1890
19
                        pdfi_countdown(n);
1891
19
                        n = NULL;
1892
19
                        code = gs_error_undefined;
1893
19
                    }
1894
3.49k
                    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.51k
                }
1898
1899
11.0k
                if (code < 0) {
1900
7.51k
                    code = pdfi_name_alloc(ctx, (byte *)"StandardEncoding", 16, (pdf_obj **)&n);
1901
7.51k
                    if (code < 0) {
1902
0
                        pdfi_countdown(*Encoding);
1903
0
                        *Encoding = NULL;
1904
0
                        return code;
1905
0
                    }
1906
7.51k
                    pdfi_countup(n);
1907
7.51k
                }
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.5k
            code = pdfi_dict_knownget_type(ctx, (pdf_dict *)pdf_Encoding, "Differences", PDF_ARRAY, (pdf_obj **)&a);
1919
23.5k
            if (code <= 0) {
1920
463
                if (code < 0) {
1921
0
                    pdfi_countdown(*Encoding);
1922
0
                    *Encoding = NULL;
1923
0
                }
1924
463
                return code;
1925
463
            }
1926
1927
2.12M
            for (i=0;i < pdfi_array_size(a);i++) {
1928
2.10M
                pdf_obj_type type;
1929
2.10M
                code = pdfi_array_get(ctx, a, (uint64_t)i, &o);
1930
2.10M
                if (code < 0)
1931
9
                    break;
1932
2.10M
                type = pdfi_type_of(o);
1933
2.10M
                if (type == PDF_NAME) {
1934
1.90M
                    if (offset < pdfi_array_size((pdf_array *)*Encoding))
1935
1.90M
                        code = pdfi_array_put(ctx, (pdf_array *)*Encoding, (uint64_t)offset, o);
1936
1.90M
                    pdfi_countdown(o);
1937
1.90M
                    offset++;
1938
1.90M
                    if (code < 0)
1939
0
                        break;
1940
1.90M
                } else if (type == PDF_INT) {
1941
202k
                    offset = ((pdf_num *)o)->value.i;
1942
202k
                    pdfi_countdown(o);
1943
202k
                } else {
1944
81
                    code = gs_note_error(gs_error_typecheck);
1945
81
                    pdfi_countdown(o);
1946
81
                    break;
1947
81
                }
1948
2.10M
            }
1949
23.0k
            pdfi_countdown(a);
1950
23.0k
            if (code < 0) {
1951
90
                pdfi_countdown(*Encoding);
1952
90
                *Encoding = NULL;
1953
90
                return code;
1954
90
            }
1955
22.9k
            if (ppdffont != NULL) /* No sense doing this if we can't record the result */
1956
22.9k
                pdfi_gs_simple_font_encoding_indices(ctx, (pdf_array *)(*Encoding), &encoding_index, &nearest_encoding_index);
1957
22.9k
            break;
1958
23.0k
        }
1959
473
        default:
1960
473
            pdfi_countdown(*Encoding);
1961
473
            *Encoding = NULL;
1962
473
            return gs_note_error(gs_error_typecheck);
1963
143k
    }
1964
142k
    if (ppdffont != NULL) {
1965
86.3k
        ppdffont->pfont->encoding_index = encoding_index;
1966
86.3k
        ppdffont->pfont->nearest_encoding_index = nearest_encoding_index;
1967
86.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
122M
{
1973
122M
    int code;
1974
122M
    unsigned int nindex = 0;
1975
122M
    gs_glyph g = GS_NO_GLYPH;
1976
1977
122M
    if (pfont->FontType == ft_encrypted || pfont->FontType == ft_encrypted2
1978
122M
     || pfont->FontType == ft_user_defined || pfont->FontType == ft_TrueType
1979
122M
     || pfont->FontType == ft_MicroType
1980
122M
     || pfont->FontType == ft_PDF_user_defined) {
1981
122M
        pdf_font *font = (pdf_font *)pfont->client_data;
1982
122M
        pdf_context *ctx = (pdf_context *)font->ctx;
1983
1984
122M
        if (font->Encoding != NULL) { /* safety */
1985
122M
            pdf_name *GlyphName = NULL;
1986
122M
            code = pdfi_array_get(ctx, font->Encoding, (uint64_t)chr, (pdf_obj **)&GlyphName);
1987
122M
            if (code >= 0) {
1988
122M
                if (pdfi_type_of(GlyphName) != PDF_NAME)
1989
                    /* Can't signal an error, just return the 'not found' case */
1990
960
                    return g;
1991
1992
122M
                code = (*ctx->get_glyph_index)(pfont, (byte *)GlyphName->data, GlyphName->length, &nindex);
1993
122M
                pdfi_countdown(GlyphName);
1994
122M
                if (code >= 0)
1995
122M
                    g = (gs_glyph)nindex;
1996
122M
            }
1997
122M
        }
1998
122M
    }
1999
2000
122M
    return g;
2001
122M
}
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.93k
{
2009
7.93k
    int i;
2010
7.93k
    *decoding = NULL;
2011
7.93k
    *substnwp = NULL;
2012
    /* This only makes sense for Adobe orderings */
2013
7.93k
    if (reglen == 5 && !memcmp(reg, "Adobe", 5)) {
2014
43.0k
        for (i = 0; pdfi_cid_decoding_list[i] != NULL; i++) {
2015
36.0k
            if (strlen(pdfi_cid_decoding_list[i]->s_order) == ordlen &&
2016
36.0k
                !memcmp(pdfi_cid_decoding_list[i]->s_order, ord, ordlen)) {
2017
306
                *decoding = (pdfi_cid_decoding_t *)pdfi_cid_decoding_list[i];
2018
306
                break;
2019
306
            }
2020
36.0k
        }
2021
        /* For now, also only for Adobe orderings */
2022
43.2k
        for (i = 0; pdfi_cid_substnwp_list[i] != NULL; i++) {
2023
36.1k
            if (strlen(pdfi_cid_substnwp_list[i]->ordering) == ordlen &&
2024
36.1k
                !memcmp(pdfi_cid_substnwp_list[i]->ordering, ord, ordlen)) {
2025
306
                *substnwp = (pdfi_cid_subst_nwp_table_t *)pdfi_cid_substnwp_list[i];
2026
306
                break;
2027
306
            }
2028
36.1k
        }
2029
7.36k
    }
2030
7.93k
}
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
1.96M
{
2034
1.96M
    int i, l = 0;
2035
1.96M
    int code = gs_error_undefined;
2036
1.96M
    unsigned char *ucode = (unsigned char *)unicode_return;
2037
2038
1.96M
    if (tounicode != NULL) {
2039
545k
        gs_cmap_lookups_enum_t lenum;
2040
545k
        gs_cmap_lookups_enum_init((const gs_cmap_t *)tounicode->gscmap, 0, &lenum);
2041
11.4M
        while (l == 0 && gs_cmap_enum_next_lookup(ctx->memory, &lenum) == 0) {
2042
10.9M
            gs_cmap_lookups_enum_t counter = lenum;
2043
21.8M
            while (l == 0 && gs_cmap_enum_next_entry(&counter) == 0) {
2044
10.9M
                if (counter.entry.value_type == CODE_VALUE_CID) {
2045
10.9M
                    if (counter.entry.key_is_range) {
2046
2.07M
                        unsigned int v0 = 0, v1 = 0;
2047
4.71M
                        for (i = 0; i < counter.entry.key_size; i++) {
2048
2.63M
                            v0 |= (counter.entry.key[0][counter.entry.key_size - i - 1]) << (i * 8);
2049
2.63M
                        }
2050
4.71M
                        for (i = 0; i < counter.entry.key_size; i++) {
2051
2.63M
                            v1 |= (counter.entry.key[1][counter.entry.key_size - i - 1]) << (i * 8);
2052
2.63M
                        }
2053
2054
2.07M
                        if (ch >= v0 && ch <= v1) {
2055
255k
                            unsigned int offs = ch - v0;
2056
2057
255k
                            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
255k
                            else if (counter.entry.value.size == 2) {
2065
254k
                                l = 2;
2066
254k
                                if (ucode != NULL && length >= l) {
2067
212k
                                    ucode[0] = counter.entry.value.data[0] + ((offs >> 8) & 0xff);
2068
212k
                                    ucode[1] = counter.entry.value.data[1] + (offs & 0xff);
2069
212k
                                }
2070
254k
                            }
2071
1.37k
                            else if (counter.entry.value.size == 3) {
2072
20
                                l = 4;
2073
20
                                if (ucode != NULL && length >= l) {
2074
10
                                    ucode[0] = 0;
2075
10
                                    ucode[1] = counter.entry.value.data[0] + ((offs >> 16) & 0xff);
2076
10
                                    ucode[2] = counter.entry.value.data[1] + ((offs >> 8) & 0xff);
2077
10
                                    ucode[3] = counter.entry.value.data[2] + (offs & 0xff);
2078
10
                                }
2079
20
                            }
2080
1.35k
                            else {
2081
1.35k
                                l = 4;
2082
1.35k
                                if (ucode != NULL && length >= l) {
2083
1.35k
                                    ucode[0] = counter.entry.value.data[0] + ((offs >> 24) & 0xff);
2084
1.35k
                                    ucode[1] = counter.entry.value.data[1] + ((offs >> 16) & 0xff);
2085
1.35k
                                    ucode[2] = counter.entry.value.data[2] + ((offs >> 8) & 0xff);
2086
1.35k
                                    ucode[3] = counter.entry.value.data[3] + (offs & 0xff);
2087
1.35k
                                }
2088
1.35k
                            }
2089
255k
                        }
2090
2.07M
                    }
2091
8.85M
                    else {
2092
8.85M
                        unsigned int v = 0;
2093
25.8M
                        for (i = 0; i < counter.entry.key_size; i++) {
2094
16.9M
                            v |= (counter.entry.key[0][counter.entry.key_size - i - 1]) << (i * 8);
2095
16.9M
                        }
2096
8.85M
                        if (ch == v) {
2097
231k
                            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
231k
                            else if (counter.entry.value.size == 2) {
2105
231k
                                l = 2;
2106
231k
                                if (ucode != NULL && length >= l) {
2107
166k
                                    ucode[0] = counter.entry.value.data[0];
2108
166k
                                    ucode[1] = counter.entry.value.data[1];
2109
166k
                                }
2110
231k
                            }
2111
528
                            else if (counter.entry.value.size == 3) {
2112
54
                                l = 4;
2113
54
                                if (ucode != NULL && length >= l) {
2114
31
                                    ucode[0] = 0;
2115
31
                                    ucode[1] = counter.entry.value.data[0];
2116
31
                                    ucode[2] = counter.entry.value.data[1];
2117
31
                                    ucode[3] = counter.entry.value.data[2];
2118
31
                                }
2119
54
                            }
2120
474
                            else {
2121
474
                                l = 4;
2122
474
                                if (ucode != NULL && length >= l) {
2123
388
                                    ucode[0] = counter.entry.value.data[0];
2124
388
                                    ucode[1] = counter.entry.value.data[1];
2125
388
                                    ucode[2] = counter.entry.value.data[2];
2126
388
                                    ucode[3] = counter.entry.value.data[3];
2127
388
                                }
2128
474
                            }
2129
231k
                        }
2130
8.85M
                    }
2131
10.9M
                }
2132
10.9M
            }
2133
10.9M
        }
2134
545k
        if (l > 0)
2135
487k
            code = l;
2136
545k
    }
2137
2138
1.96M
    return code;
2139
1.96M
}
2140
2141
int
2142
pdfi_cidfont_decode_glyph(gs_font *font, gs_glyph glyph, int ch, ushort *u, unsigned int length)
2143
574k
{
2144
574k
    gs_glyph cc = glyph < GS_MIN_CID_GLYPH ? glyph : glyph - GS_MIN_CID_GLYPH;
2145
574k
    pdf_cidfont_t *pcidfont = (pdf_cidfont_t *)font->client_data;
2146
574k
    int code = gs_error_undefined, i;
2147
574k
    uchar *unicode_return = (uchar *)u;
2148
574k
    pdfi_cid_subst_nwp_table_t *substnwp = pcidfont->substnwp;
2149
2150
574k
    code = gs_error_undefined;
2151
577k
    while (1) { /* Loop to make retrying with a substitute CID easier */
2152
        /* Favour the ToUnicode if one exists */
2153
577k
        code = pdfi_tounicode_char_to_unicode(pcidfont->ctx, (pdf_cmap *)pcidfont->ToUnicode, glyph, ch, u, length);
2154
2155
577k
        if (code == gs_error_undefined && pcidfont->decoding) {
2156
10.4k
            const int *n;
2157
2158
10.4k
            if (cc / 256 < pcidfont->decoding->nranges) {
2159
10.2k
                n = (const int *)pcidfont->decoding->ranges[cc / 256][cc % 256];
2160
10.5k
                for (i = 0; i < pcidfont->decoding->val_sizes; i++) {
2161
10.5k
                    unsigned int cmapcc;
2162
10.5k
                    if (n[i] == -1)
2163
3.07k
                        break;
2164
7.48k
                    cc = n[i];
2165
7.48k
                    cmapcc = (unsigned int)cc;
2166
7.48k
                    if (pcidfont->pdfi_font_type == e_pdf_cidfont_type2)
2167
7.48k
                        code = pdfi_fapi_check_cmap_for_GID((gs_font *)pcidfont->pfont, (unsigned int)cc, &cmapcc);
2168
0
                    else
2169
0
                        code = 0;
2170
7.48k
                    if (code >= 0 && cmapcc != 0){
2171
7.19k
                        code = 0;
2172
7.19k
                        break;
2173
7.19k
                    }
2174
7.48k
                }
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
10.2k
                if (code < 0 && n[0] != -1) {
2179
0
                    cc = n[0];
2180
0
                    code = 0;
2181
0
                }
2182
10.2k
            }
2183
10.4k
            if (code >= 0) {
2184
7.19k
                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
7.19k
                else {
2194
7.19k
                    code = 2;
2195
7.19k
                    if (unicode_return != NULL && length >= code) {
2196
3.43k
                        unicode_return[0] = (cc & 0x0000FF00) >> 8;
2197
3.43k
                        unicode_return[1] = (cc & 0x000000FF);
2198
3.43k
                    }
2199
7.19k
                }
2200
7.19k
            }
2201
10.4k
        }
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
577k
        if (code == gs_error_undefined && substnwp) {
2207
6.47k
            for (i = 0; substnwp->subst[i].s_type != 0; i++ ) {
2208
6.13k
                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
6.13k
                if (cc >= substnwp->subst[i].s_dcid
2214
6.13k
                 && cc <= substnwp->subst[i].s_dcid + (substnwp->subst[i].e_scid - substnwp->subst[i].s_scid)) {
2215
2.91k
                    cc = substnwp->subst[i].s_scid + (cc - substnwp->subst[i].s_dcid);
2216
2.91k
                    substnwp = NULL;
2217
2.91k
                    break;
2218
2.91k
                }
2219
6.13k
            }
2220
3.25k
            if (substnwp == NULL)
2221
2.91k
                continue;
2222
3.25k
        }
2223
574k
        break;
2224
577k
    }
2225
574k
    return (code < 0 ? 0 : code);
2226
574k
}
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
628k
{
2232
628k
    pdf_font *pdffont = (pdf_font *)font->client_data;
2233
628k
    int code = 0;
2234
2235
628k
    if (pdffont->pdfi_font_type != e_pdf_cidfont_type0 && pdffont->pdfi_font_type != e_pdf_cidfont_type1
2236
628k
     && pdffont->pdfi_font_type != e_pdf_cidfont_type2 && pdffont->pdfi_font_type != e_pdf_cidfont_type4) {
2237
628k
        code = pdfi_tounicode_char_to_unicode(pdffont->ctx, (pdf_cmap *)pdffont->ToUnicode, glyph, ch, unicode_return, length);
2238
628k
    }
2239
628k
    if (code < 0) code = 0;
2240
2241
628k
    return code;
2242
628k
}
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
6
{
2272
6
    int code = 0;
2273
6
    if (pfont->FontType == ft_encrypted) {
2274
2
        code = pdfi_t1_global_glyph_code(pfont, gstr, pglyph);
2275
2
    }
2276
4
    else if (pfont->FontType == ft_encrypted2) {
2277
4
        code = pdfi_cff_global_glyph_code(pfont, gstr, pglyph);
2278
4
    }
2279
0
    else {
2280
0
        code = gs_note_error(gs_error_invalidaccess);
2281
0
    }
2282
6
    return code;
2283
6
}
2284
2285
int pdfi_map_glyph_name_via_agl(pdf_dict *cstrings, pdf_name *gname, pdf_string **cstring)
2286
913k
{
2287
913k
    single_glyph_list_t *sgl = (single_glyph_list_t *)&(SingleGlyphList);
2288
913k
    int i, code, ucode = gs_error_undefined;
2289
913k
    *cstring = NULL;
2290
2291
913k
    if (gname->length == 7 && strncmp((char *)gname->data, "uni", 3) == 0) {
2292
3.34k
        char u[5] = {0};
2293
3.34k
        memcpy(u, gname->data + 3, 4);
2294
3.34k
        code = sscanf(u, "%x", &ucode);
2295
3.34k
        if (code <= 0)
2296
0
            ucode = gs_error_undefined;
2297
3.34k
    }
2298
2299
913k
    if (ucode == gs_error_undefined) {
2300
3.40G
        for (i = 0; sgl[i].Glyph != 0x00; i++) {
2301
3.40G
            if (sgl[i].Glyph[0] == gname->data[0]
2302
3.40G
                && strlen(sgl[i].Glyph) == gname->length
2303
3.40G
                && !strncmp((char *)sgl[i].Glyph, (char *)gname->data, gname->length)) {
2304
275k
                ucode = (int)sgl[i].Unicode;
2305
275k
                break;
2306
275k
            }
2307
3.40G
        }
2308
909k
    }
2309
913k
    if (ucode > 0) {
2310
1.16G
        for (i = 0; sgl[i].Glyph != 0x00; i++) {
2311
1.16G
            if (sgl[i].Unicode == (unsigned short)ucode) {
2312
281k
                pdf_string *s;
2313
281k
                code = pdfi_dict_get((pdf_context *)cstrings->ctx, cstrings, (char *)sgl[i].Glyph, (pdf_obj **)&s);
2314
281k
                if (code >= 0) {
2315
2.63k
                    *cstring = s;
2316
2.63k
                    break;
2317
2.63k
                }
2318
281k
            }
2319
1.16G
        }
2320
278k
        if (*cstring == NULL) {
2321
276k
            char u[16] = {0};
2322
276k
            code = gs_snprintf(u, 16, "uni%04x", ucode);
2323
276k
            if (code > 0) {
2324
276k
                pdf_string *s;
2325
276k
                code = pdfi_dict_get((pdf_context *)cstrings->ctx, cstrings, u, (pdf_obj **)&s);
2326
276k
                if (code >= 0) {
2327
2
                    *cstring = s;
2328
2
                }
2329
276k
            }
2330
276k
        }
2331
278k
    }
2332
2333
913k
    if (*cstring == NULL)
2334
910k
        code = gs_note_error(gs_error_undefined);
2335
2.63k
    else
2336
2.63k
        code = 0;
2337
2338
913k
    return code;
2339
913k
}
2340
2341
2342
int pdfi_init_font_directory(pdf_context *ctx)
2343
94.6k
{
2344
94.6k
    gs_font_dir *pfdir = ctx->memory->gs_lib_ctx->font_dir;
2345
94.6k
    if (pfdir) {
2346
94.6k
        ctx->font_dir = gs_font_dir_alloc2_limits(ctx->memory, ctx->memory,
2347
94.6k
                   pfdir->smax, pfdir->ccache.bmax, pfdir->fmcache.mmax,
2348
94.6k
                   pfdir->ccache.cmax, pfdir->ccache.upper);
2349
94.6k
        if (ctx->font_dir == NULL) {
2350
0
            return_error(gs_error_VMerror);
2351
0
        }
2352
94.6k
        ctx->font_dir->align_to_pixels = pfdir->align_to_pixels;
2353
94.6k
        ctx->font_dir->grid_fit_tt = pfdir->grid_fit_tt;
2354
94.6k
    }
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
94.6k
    ctx->font_dir->global_glyph_code = pdfi_global_glyph_code;
2362
94.6k
    return 0;
2363
94.6k
}
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
800k
{
2371
800k
    pdf_obj *fname = NULL;
2372
800k
    pdf_obj *fontobjtype = NULL;
2373
800k
    pdf_dict *fdict = NULL;
2374
800k
    int code;
2375
800k
    gs_font *pgsfont = NULL;
2376
800k
    const char *fs = "Font";
2377
800k
    pdf_name *Type1Name = NULL;
2378
2379
800k
    code = pdfi_name_alloc(ctx, (byte *)fontname, length, &fname);
2380
800k
    if (code < 0)
2381
0
        return code;
2382
800k
    pdfi_countup(fname);
2383
2384
800k
    code = pdfi_name_alloc(ctx, (byte *)fs, strlen(fs), &fontobjtype);
2385
800k
    if (code < 0)
2386
0
        goto exit;
2387
800k
    pdfi_countup(fontobjtype);
2388
2389
800k
    code = pdfi_dict_alloc(ctx, 1, &fdict);
2390
800k
    if (code < 0)
2391
0
        goto exit;
2392
800k
    pdfi_countup(fdict);
2393
2394
800k
    code = pdfi_dict_put(ctx, fdict, "BaseFont", fname);
2395
800k
    if (code < 0)
2396
0
        goto exit;
2397
2398
800k
    code = pdfi_dict_put(ctx, fdict, "Type", fontobjtype);
2399
800k
    if (code < 0)
2400
0
        goto exit;
2401
2402
800k
    code = pdfi_obj_charstr_to_name(ctx, "Type1", &Type1Name);
2403
800k
    if (code < 0)
2404
0
        goto exit;
2405
2406
800k
    code = pdfi_dict_put(ctx, fdict, "Subtype", (pdf_obj *)Type1Name);
2407
800k
    if (code < 0)
2408
0
        goto exit;
2409
2410
800k
    code = pdfi_load_font(ctx, NULL, NULL, fdict, &pgsfont, false);
2411
800k
    if (code < 0)
2412
0
        goto exit;
2413
2414
800k
    *ppdffont = (pdf_obj *)pgsfont->client_data;
2415
2416
800k
 exit:
2417
800k
    pdfi_countdown(Type1Name);
2418
800k
    pdfi_countdown(fontobjtype);
2419
800k
    pdfi_countdown(fname);
2420
800k
    pdfi_countdown(fdict);
2421
800k
    return code;
2422
800k
}
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
74.2k
        code = pdfi_dict_knownget(ctx, font->FontDescriptor, "MissingWidth", &obj);
2435
74.2k
        if (code > 0) {
2436
6.24k
            if (pdfi_type_of(obj) == PDF_INT) {
2437
6.24k
                font->MissingWidth = ((pdf_num *) obj)->value.i * scale;
2438
6.24k
            }
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.24k
            pdfi_countdown(obj);
2446
6.24k
            obj = NULL;
2447
6.24k
        }
2448
68.0k
        else {
2449
68.0k
            font->MissingWidth = 0;
2450
68.0k
        }
2451
74.2k
    }
2452
823k
    else {
2453
823k
        font->MissingWidth = 0;
2454
823k
    }
2455
2456
897k
    code = pdfi_dict_knownget_type(ctx, fontdict, "Widths", PDF_ARRAY, (pdf_obj **)&obj);
2457
897k
    if (code > 0) {
2458
79.2k
        if (pdfi_array_size((pdf_array *)obj) < font->LastChar - font->FirstChar + 1) {
2459
2.07k
            code = gs_note_error(gs_error_rangecheck);
2460
2.07k
            goto error;
2461
2.07k
        }
2462
2463
77.1k
        font->Widths = (double *)gs_alloc_bytes(OBJ_MEMORY(font), sizeof(double) * (font->LastChar - font->FirstChar + 1), "pdfi_font_create_widths(Widths)");
2464
77.1k
        if (font->Widths == NULL) {
2465
0
            code = gs_note_error(gs_error_VMerror);
2466
0
            goto error;
2467
0
        }
2468
77.1k
        memset(font->Widths, 0x00, sizeof(double) * (font->LastChar - font->FirstChar + 1));
2469
7.78M
        for (i = 0; i < (font->LastChar - font->FirstChar + 1); i++) {
2470
7.71M
            code = pdfi_array_get_number(ctx, (pdf_array *)obj, (uint64_t)i, &font->Widths[i]);
2471
7.71M
            if (code < 0)
2472
254
                goto error;
2473
7.70M
            font->Widths[i] *= scale;
2474
7.70M
        }
2475
77.1k
    }
2476
897k
error:
2477
897k
    pdfi_countdown(obj);
2478
897k
    if (code < 0) {
2479
5.73k
        gs_free_object(OBJ_MEMORY(font), font->Widths, "pdfi_font_create_widths(Widths)");
2480
5.73k
        font->Widths = NULL;
2481
5.73k
    }
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
947k
{
2487
947k
    double f, l;
2488
947k
    int code;
2489
2490
947k
    if (fontdict == NULL) {
2491
49.9k
        f = (double)0;
2492
49.9k
        l = (double)255;
2493
49.9k
    }
2494
897k
    else {
2495
897k
        code = pdfi_dict_get_number(ctx, fontdict, "FirstChar", &f);
2496
897k
        if (code < 0 || f < 0 || f > 255)
2497
814k
            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
815k
            l = (double)255;
2502
897k
    }
2503
947k
    if (f <= l) {
2504
947k
        font->FirstChar = (int)f;
2505
947k
        font->LastChar = (int)l;
2506
947k
    }
2507
54
    else {
2508
54
        font->FirstChar = 0;
2509
54
        font->LastChar = 255;
2510
54
    }
2511
947k
}
2512
2513
void pdfi_font_set_orig_fonttype(pdf_context *ctx, pdf_font *font)
2514
957k
{
2515
957k
    pdf_name *ftype;
2516
957k
    pdf_dict *fontdict = font->PDF_font;
2517
957k
    int code;
2518
2519
957k
    code = pdfi_dict_get_type(ctx, fontdict, "Subtype", PDF_NAME, (pdf_obj**)&ftype);
2520
957k
    if (code < 0) {
2521
50.6k
        font->orig_FontType = ft_undefined;
2522
50.6k
    }
2523
906k
    else {
2524
906k
        if (pdfi_name_is(ftype, "Type1") || pdfi_name_is(ftype, "MMType1"))
2525
846k
            font->orig_FontType = ft_encrypted;
2526
59.8k
        else if (pdfi_name_is(ftype, "Type1C"))
2527
0
            font->orig_FontType = ft_encrypted2;
2528
59.8k
        else if (pdfi_name_is(ftype, "TrueType"))
2529
40.8k
            font->orig_FontType = ft_TrueType;
2530
18.9k
        else if (pdfi_name_is(ftype, "Type3"))
2531
2.26k
            font->orig_FontType = ft_user_defined;
2532
16.7k
        else if (pdfi_name_is(ftype, "CIDFontType0"))
2533
3.12k
            font->orig_FontType = ft_CID_encrypted;
2534
13.5k
        else if (pdfi_name_is(ftype, "CIDFontType2"))
2535
12.9k
            font->orig_FontType = ft_CID_TrueType;
2536
623
        else
2537
623
            font->orig_FontType = ft_undefined;
2538
906k
    }
2539
957k
    pdfi_countdown(ftype);
2540
957k
}
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
104k
{
2551
104k
    gs_const_string fn;
2552
104k
    int i;
2553
104k
    uint32_t hash = 0;
2554
104k
    long *xvalues;
2555
104k
    int xuidlen = 3;
2556
2557
104k
    sfilename(ctx->main_stream->s, &fn);
2558
104k
    if (fontdict!= NULL && fontdict->object_num != 0) {
2559
49.2k
        const byte *sb;
2560
49.2k
        size_t l;
2561
49.2k
        if (fn.size > 0) {
2562
0
            sb = fn.data;
2563
0
            l = fn.size;
2564
0
        }
2565
49.2k
        else {
2566
49.2k
            s_process_read_buf(ctx->main_stream->s);
2567
49.2k
            sb = sbufptr(ctx->main_stream->s);
2568
49.2k
            l = sbufavailable(ctx->main_stream->s) > 128 ? 128: sbufavailable(ctx->main_stream->s);
2569
49.2k
        }
2570
2571
6.34M
        for (i = 0; i < l; i++) {
2572
6.30M
            hash = ((((hash & 0xf8000000) >> 27) ^ (hash << 5)) & 0x7ffffffff) ^ sb[i];
2573
6.30M
        }
2574
49.2k
        hash = ((((hash & 0xf8000000) >> 27) ^ (hash << 5)) & 0x7ffffffff) ^ fontdict->object_num;
2575
2576
49.2k
        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
555
             uid_XUID_values(&pfont->UID)[1] = hash;
2581
555
             uid_XUID_values(&pfont->UID)[2] = ctx->device_state.HighLevelDevice ? fontdict->object_num : 0;
2582
555
        }
2583
48.6k
        else {
2584
48.6k
            if (uid_is_XUID(&pfont->UID))
2585
1.76k
                xuidlen += uid_XUID_size(&pfont->UID);
2586
46.9k
            else if (uid_is_valid(&pfont->UID))
2587
626
                xuidlen++;
2588
2589
48.6k
            xvalues = (long *)gs_alloc_bytes(pfont->memory, xuidlen * sizeof(long), "pdfi_font_generate_pseudo_XUID");
2590
48.6k
            if (xvalues == NULL) {
2591
0
                return 0;
2592
0
            }
2593
48.6k
            xvalues[0] = 1000000; /* "Private" value */
2594
48.6k
            xvalues[1] = hash;
2595
2596
48.6k
            xvalues[2] = ctx->device_state.HighLevelDevice ? fontdict->object_num : 0;
2597
2598
48.6k
            if (uid_is_XUID(&pfont->UID)) {
2599
10.5k
                for (i = 0; i < uid_XUID_size(&pfont->UID); i++) {
2600
8.80k
                    xvalues[i + 3] = uid_XUID_values(&pfont->UID)[i];
2601
8.80k
                }
2602
1.76k
                uid_free(&pfont->UID, pfont->memory, "pdfi_font_generate_pseudo_XUID");
2603
1.76k
            }
2604
46.9k
            else if (uid_is_valid(&pfont->UID))
2605
626
                xvalues[3] = pfont->UID.id;
2606
2607
48.6k
            uid_set_XUID(&pfont->UID, xvalues, xuidlen);
2608
48.6k
        }
2609
49.2k
    }
2610
104k
    return 0;
2611
104k
}
2612
2613
int pdfi_default_font_info(gs_font *font, const gs_point *pscale, int members, gs_font_info_t *info)
2614
117k
{
2615
117k
    pdf_font *pdff = (pdf_font *)font->client_data;
2616
117k
    int code;
2617
2618
    /* We *must* call this first as it sets info->members = 0; */
2619
117k
    code = pdff->default_font_info(font, pscale, members, info);
2620
117k
    if (code < 0)
2621
5.37k
        return code;
2622
111k
    if ((members & FONT_INFO_EMBEDDED) != 0) {
2623
111k
        info->orig_FontType = pdff->orig_FontType;
2624
111k
        if (pdff->pdfi_font_type == e_pdf_font_type3) {
2625
665
            info->FontEmbedded = (int)(true);
2626
665
            info->members |= FONT_INFO_EMBEDDED;
2627
665
        }
2628
111k
        else {
2629
111k
            info->FontEmbedded = (int)(pdff->substitute == font_embedded);
2630
111k
            info->members |= FONT_INFO_EMBEDDED;
2631
111k
        }
2632
111k
    }
2633
111k
    if (pdff->pdfi_font_type != e_pdf_font_truetype && pdff->pdfi_font_type != e_pdf_cidfont_type2) {
2634
65.0k
        if (((members & FONT_INFO_COPYRIGHT) != 0) && pdff->copyright != NULL) {
2635
38.4k
            info->Copyright.data = pdff->copyright->data;
2636
38.4k
            info->Copyright.size = pdff->copyright->length;
2637
38.4k
            info->members |= FONT_INFO_COPYRIGHT;
2638
38.4k
        }
2639
65.0k
        if (((members & FONT_INFO_NOTICE) != 0) && pdff->notice != NULL) {
2640
41.6k
            info->Notice.data = pdff->notice->data;
2641
41.6k
            info->Notice.size = pdff->notice->length;
2642
41.6k
            info->members |= FONT_INFO_NOTICE;
2643
41.6k
        }
2644
65.0k
        if (((members & FONT_INFO_FAMILY_NAME) != 0) && pdff->familyname != NULL) {
2645
41.5k
            info->FamilyName.data = pdff->familyname->data;
2646
41.5k
            info->FamilyName.size = pdff->familyname->length;
2647
41.5k
            info->members |= FONT_INFO_FAMILY_NAME;
2648
41.5k
        }
2649
65.0k
        if (((members & FONT_INFO_FULL_NAME) != 0) && pdff->fullname != NULL) {
2650
41.5k
            info->FullName.data = pdff->fullname->data;
2651
41.5k
            info->FullName.size = pdff->fullname->length;
2652
41.5k
            info->members |= FONT_INFO_FULL_NAME;
2653
41.5k
        }
2654
65.0k
    }
2655
111k
    return 0;
2656
117k
}
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
800k
{
2663
800k
    int code;
2664
800k
    pdf_font *pdffont = (pdf_font *)fontobj;
2665
2666
800k
    if (pdfi_type_of(pdffont) != PDF_FONT || pdffont->pfont == NULL)
2667
0
        return_error(gs_error_invalidfont);
2668
2669
800k
    code = gs_setPDFfontsize(ctx->pgs, point_size);
2670
800k
    if (code < 0)
2671
0
        return code;
2672
2673
800k
    return pdfi_gs_setfont(ctx, (gs_font *)pdffont->pfont);
2674
800k
}
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
800k
{
2682
800k
    int code = 0;
2683
800k
    pdf_obj *font = NULL;
2684
2685
2686
800k
    code = pdfi_load_font_by_name_string(ctx, fontname, length, &font);
2687
800k
    if (code < 0) goto exit;
2688
2689
800k
    code = pdfi_set_font_internal(ctx, font, point_size);
2690
2691
800k
 exit:
2692
800k
    pdfi_countdown(font);
2693
800k
    return code;
2694
800k
}
2695
2696
int pdfi_font_set_internal_string(pdf_context *ctx, const char *fontname, double point_size)
2697
22.8k
{
2698
22.8k
    return pdfi_font_set_internal_inner(ctx, (const byte *)fontname, strlen(fontname), point_size);
2699
22.8k
}
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
}