Coverage Report

Created: 2026-07-24 07:44

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