Coverage Report

Created: 2025-12-31 07:31

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