Coverage Report

Created: 2025-06-10 07:27

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