Coverage Report

Created: 2026-04-09 07:06

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
937k
{
48
937k
    int code = 0;
49
937k
    pdfi_int_gstate *igs = (pdfi_int_gstate *)ctx->pgs->client_data;
50
937k
    pdf_font *old_font = igs->current_font;
51
52
937k
    code = gs_setfont(ctx->pgs, pfont);
53
937k
    if (code >= 0) {
54
937k
        igs->current_font = (pdf_font *)pfont->client_data;
55
937k
        pdfi_countup(igs->current_font);
56
937k
        pdfi_countdown(old_font);
57
937k
    }
58
937k
    return code;
59
937k
}
60
61
static void pdfi_cache_resource_font(pdf_context *ctx, pdf_obj *fontdesc, pdf_obj *ppdffont)
62
27.2k
{
63
27.2k
    resource_font_cache_t *entry = NULL;
64
27.2k
    int i;
65
66
27.2k
    if (ctx->resource_font_cache == NULL) {
67
17.1k
        ctx->resource_font_cache = (resource_font_cache_t *)gs_alloc_bytes(ctx->memory, RESOURCE_FONT_CACHE_BLOCK_SIZE * sizeof(pdfi_name_entry_t), "pdfi_cache_resource_font");
68
17.1k
        if (ctx->resource_font_cache == NULL)
69
0
            return;
70
17.1k
        ctx->resource_font_cache_size = RESOURCE_FONT_CACHE_BLOCK_SIZE;
71
17.1k
        memset(ctx->resource_font_cache, 0x00, RESOURCE_FONT_CACHE_BLOCK_SIZE * sizeof(pdfi_name_entry_t));
72
17.1k
        entry = &ctx->resource_font_cache[0];
73
17.1k
    }
74
75
71.5k
    for (i = 0; entry == NULL && i < ctx->resource_font_cache_size; i++) {
76
44.3k
        if (ctx->resource_font_cache[i].pdffont == NULL) {
77
10.0k
            entry = &ctx->resource_font_cache[i];
78
10.0k
        }
79
34.3k
        else if (i == ctx->resource_font_cache_size - 1) {
80
2
            entry = (resource_font_cache_t *)gs_resize_object(ctx->memory, ctx->resource_font_cache, sizeof(pdfi_name_entry_t) * (ctx->resource_font_cache_size + RESOURCE_FONT_CACHE_BLOCK_SIZE), "pdfi_cache_resource_font");
81
2
            if (entry == NULL)
82
0
                break;
83
2
            memset(entry + ctx->resource_font_cache_size, 0x00, RESOURCE_FONT_CACHE_BLOCK_SIZE * sizeof(pdfi_name_entry_t));
84
2
            ctx->resource_font_cache = entry;
85
2
            entry = &ctx->resource_font_cache[ctx->resource_font_cache_size];
86
2
            ctx->resource_font_cache_size += RESOURCE_FONT_CACHE_BLOCK_SIZE;
87
2
        }
88
44.3k
    }
89
27.2k
    if (entry != NULL) {
90
27.2k
        entry->desc_obj_num = fontdesc->object_num;
91
27.2k
        entry->pdffont = ppdffont;
92
27.2k
        pdfi_countup(ppdffont);
93
27.2k
    }
94
27.2k
}
95
96
void pdfi_purge_cache_resource_font(pdf_context *ctx)
97
94.9k
{
98
94.9k
    int i;
99
643k
    for (i = 0; i < ctx->resource_font_cache_size; i++) {
100
548k
       pdfi_countdown(ctx->resource_font_cache[i].pdffont);
101
548k
    }
102
94.9k
    gs_free_object(ctx->memory, ctx->resource_font_cache, "pdfi_purge_cache_resource_font");
103
94.9k
    ctx->resource_font_cache = NULL;
104
94.9k
    ctx->resource_font_cache_size = 0;
105
94.9k
}
106
107
static int pdfi_find_cache_resource_font(pdf_context *ctx, pdf_obj *fontdesc, pdf_obj **ppdffont)
108
57.1k
{
109
57.1k
    int i, code = gs_error_undefined;
110
565k
    for (i = 0; i < ctx->resource_font_cache_size; i++) {
111
511k
        if (ctx->resource_font_cache[i].desc_obj_num == fontdesc->object_num) {
112
3.26k
           *ppdffont = ctx->resource_font_cache[i].pdffont;
113
3.26k
           pdfi_countup(*ppdffont);
114
3.26k
           code = 0;
115
3.26k
           break;
116
3.26k
        }
117
511k
    }
118
57.1k
    return code;
119
57.1k
}
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
509k
{
141
509k
    bool ignore = false;
142
509k
    int i;
143
509k
    pdf_name *nm = (pdf_name *)basefont;
144
145
509k
    if (basefont != NULL && pdfi_type_of(basefont) == PDF_NAME) {
146
2.31M
        for (i = 0; known_symbolic_font_names[i].name != NULL; i++) {
147
1.85M
            if (nm->length == known_symbolic_font_names[i].namelen
148
17.7k
             && !strncmp((char *)nm->data, known_symbolic_font_names[i].name, nm->length)) {
149
2.15k
                ignore = true;
150
2.15k
                break;
151
2.15k
            }
152
1.85M
        }
153
462k
    }
154
509k
    return ignore;
155
509k
}
156
157
static int
158
pdfi_font_match_glyph_widths(pdf_font *pdfont)
159
413k
{
160
413k
    int code = 0;
161
413k
    int i;
162
413k
    int sindex, lindex;
163
413k
    gs_font_base *pbfont = pdfont->pfont;
164
413k
    double fw = 0.0, ww = 0.0;
165
166
413k
    if (pdfont->LastChar <  pdfont->FirstChar || pdfont->Widths == NULL)
167
390k
        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
22.9k
    sindex = pdfont->FirstChar < 96 ? 96 : pdfont->FirstChar;
171
22.9k
    lindex = pdfont->LastChar > 122 ? 123 : pdfont->LastChar + 1;
172
173
406k
    for (i = sindex; i < lindex; i++) {
174
383k
        gs_glyph_info_t ginfo = {0};
175
383k
        gs_glyph g;
176
383k
        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
383k
        if (g != GS_NO_GLYPH && pdfont->Widths[i - pdfont->FirstChar] != 0.0
180
284k
          && (*pbfont->procs.glyph_info)((gs_font *)pbfont, g, NULL, GLYPH_INFO_WIDTH0, &ginfo) >= 0) {
181
283k
            fw += hypot(ginfo.width[0].x, ginfo.width[0].y);
182
283k
            ww += pdfont->Widths[i - pdfont->FirstChar];
183
283k
        }
184
383k
    }
185
    /* Only reduce font width, don't expand */
186
22.9k
    if (ww != 0.0 && fw != 0.0 && ww / fw < 1.0) {
187
7.26k
        gs_matrix nmat, smat = {1.0, 0.0, 0.0, 1.0, 0.0, 0.0};
188
7.26k
        double wscale;
189
7.26k
        smat.xx = smat.yy = ww/fw;
190
7.26k
        wscale = 1.0 / smat.xx;
191
192
7.26k
        gs_matrix_multiply(&pbfont->FontMatrix, &smat, &nmat);
193
7.26k
        memcpy(&pbfont->FontMatrix, &nmat, sizeof(pbfont->FontMatrix));
194
195
903k
        for (i = pdfont->FirstChar; i <= pdfont->LastChar; i++) {
196
896k
            pdfont->Widths[i - pdfont->FirstChar] *= wscale;
197
896k
        }
198
199
        /* Purging a font can be expensive, but in this case, we know
200
           we have no scaled instances (pdfi doesn't work that way)
201
           and we know we have no fm pairs, nor glyphs to purge (we
202
           *just* created the font!).
203
           So "purging" the font is really just removing it from the
204
           doubly linked list of font objects in the font directory
205
         */
206
7.26k
        code = gs_purge_font((gs_font *)pbfont);
207
7.26k
        if (code >= 0)
208
7.26k
            code = gs_definefont(pbfont->dir, (gs_font *)pbfont);
209
7.26k
        if (code >= 0)
210
7.26k
            code = pdfi_fapi_passfont((pdf_font *)pdfont, 0, NULL, NULL, NULL, 0);
211
7.26k
    }
212
213
22.9k
    return code;
214
413k
}
215
216
/* Print a name object to stdout */
217
static void pdfi_print_font_name(pdf_context *ctx, pdf_name *n)
218
441k
{
219
441k
    if (ctx->args.QUIET != true)
220
0
        (void)outwrite(ctx->memory, (const char *)n->data, n->length);
221
441k
}
222
223
static void pdfi_print_font_string(pdf_context *ctx, pdf_string *s)
224
429k
{
225
429k
    if (ctx->args.QUIET != true)
226
0
        (void)outwrite(ctx->memory, (const char *)s->data, s->length);
227
429k
}
228
229
/* Print a null terminated string to stdout */
230
static void pdfi_print_cstring(pdf_context *ctx, const char *str)
231
1.34M
{
232
1.34M
    if (ctx->args.QUIET != true)
233
0
        (void)outwrite(ctx->memory, str, strlen(str));
234
1.34M
}
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
26.0k
{
244
26.0k
    int code = 0;
245
26.0k
    char fontfname[gp_file_name_sizeof];
246
26.0k
    stream *s;
247
26.0k
    pdf_name *cidname = NULL;
248
26.0k
    gs_const_string fname;
249
250
26.0k
    (void)pdfi_dict_get(ctx, font_dict, "BaseFont", (pdf_obj **)&cidname);
251
252
26.0k
    if (fallback == true) {
253
13.0k
        pdf_string *mname = NULL;
254
13.0k
        pdf_dict *csi = NULL;
255
13.0k
        pdf_name *fbname;
256
13.0k
        const char *cidfbstr = "CIDFallBack";
257
258
13.0k
        code = pdfi_fontmap_lookup_cidfont(ctx, font_dict, NULL, (pdf_obj **)&mname, findex);
259
260
13.0k
        if (mname == NULL || pdfi_type_of(mname) != PDF_STRING) {
261
13.0k
            pdfi_countdown(mname);
262
263
13.0k
            code = pdfi_object_alloc(ctx, PDF_NAME, strlen(cidfbstr), (pdf_obj **)&fbname);
264
13.0k
            if (code >= 0) {
265
13.0k
                pdfi_countup(fbname);
266
13.0k
                memcpy(fbname->data, cidfbstr, strlen(cidfbstr));
267
13.0k
                code = pdfi_fontmap_lookup_cidfont(ctx, font_dict, fbname, (pdf_obj **)&mname, findex);
268
13.0k
                pdfi_countdown(fbname);
269
13.0k
            }
270
271
13.0k
            if (code < 0 || pdfi_type_of(mname) != PDF_STRING) {
272
13.0k
                pdfi_countdown(mname);
273
13.0k
                mname = NULL;
274
13.0k
                code = pdfi_dict_get(ctx, font_dict, "CIDSystemInfo", (pdf_obj **)&csi);
275
13.0k
                if (code >= 0 && pdfi_type_of(csi) == PDF_DICT) {
276
10.6k
                    pdf_string *csi_reg = NULL, *csi_ord = NULL;
277
278
10.6k
                    if (pdfi_dict_get(ctx, csi, "Registry", (pdf_obj **)&csi_reg) >= 0
279
10.5k
                     && pdfi_dict_get(ctx, csi, "Ordering", (pdf_obj **)&csi_ord) >= 0
280
10.5k
                     && pdfi_type_of(csi_reg) == PDF_STRING && pdfi_type_of(csi_ord) == PDF_STRING
281
10.5k
                     && csi_reg->length + csi_ord->length + 1 < gp_file_name_sizeof - 1) {
282
10.5k
                        pdf_name *reg_ord;
283
10.5k
                        memcpy(fontfname, csi_reg->data, csi_reg->length);
284
10.5k
                        memcpy(fontfname + csi_reg->length, "-", 1);
285
10.5k
                        memcpy(fontfname + csi_reg->length + 1, csi_ord->data, csi_ord->length);
286
10.5k
                        fontfname[csi_reg->length + csi_ord->length + 1] = '\0';
287
288
10.5k
                        code = pdfi_name_alloc(ctx, (byte *)fontfname, strlen(fontfname), (pdf_obj **) &reg_ord);
289
10.5k
                        if (code >= 0) {
290
10.5k
                            pdfi_countup(reg_ord);
291
10.5k
                            code = pdfi_fontmap_lookup_cidfont(ctx, font_dict, reg_ord, (pdf_obj **)&mname, findex);
292
10.5k
                            pdfi_countdown(reg_ord);
293
10.5k
                        }
294
10.5k
                    }
295
10.6k
                    pdfi_countdown(csi_reg);
296
10.6k
                    pdfi_countdown(csi_ord);
297
10.6k
                }
298
13.0k
                pdfi_countdown(csi);
299
13.0k
            }
300
301
13.0k
            if (mname == NULL || pdfi_type_of(mname) != PDF_STRING) {
302
13.0k
                pdfi_countdown(mname);
303
13.0k
                mname = NULL;
304
13.0k
                code = pdfi_fontmap_lookup_cidfont(ctx, font_dict, NULL, (pdf_obj **)&mname, findex);
305
13.0k
            }
306
13.0k
        }
307
308
13.0k
        do {
309
13.0k
            if (code < 0 || pdfi_type_of(mname) != PDF_STRING) {
310
13.0k
                const char *fsprefix = "CIDFSubst/";
311
13.0k
                int fsprefixlen = strlen(fsprefix);
312
13.0k
                const char *defcidfallack = "DroidSansFallback.ttf";
313
13.0k
                int defcidfallacklen = strlen(defcidfallack);
314
315
13.0k
                pdfi_countdown(mname);
316
317
13.0k
                if (ctx->args.nocidfallback == true) {
318
0
                    if (ctx->args.pdfstoponerror == true)
319
0
                        code = gs_note_error(gs_error_Fatal);
320
0
                    else
321
0
                        code = gs_note_error(gs_error_invalidfont);
322
0
                }
323
13.0k
                else {
324
13.0k
                    if (ctx->args.cidfsubstpath.data == NULL) {
325
13.0k
                        memcpy(fontfname, fsprefix, fsprefixlen);
326
13.0k
                    }
327
0
                    else {
328
0
                        if (ctx->args.cidfsubstpath.size > gp_file_name_sizeof - 1) {
329
0
                            code = gs_note_error(gs_error_rangecheck);
330
0
                            if ((code = pdfi_set_warning_stop(ctx, code, NULL, W_PDF_BAD_CONFIG, "pdfi_open_CIDFont_substitute_file", "CIDFSubstPath parameter too long")) < 0)
331
0
                                goto exit;
332
0
                            memcpy(fontfname, fsprefix, fsprefixlen);
333
0
                        }
334
0
                        else {
335
0
                            memcpy(fontfname, ctx->args.cidfsubstpath.data, ctx->args.cidfsubstpath.size);
336
0
                            fsprefixlen = ctx->args.cidfsubstpath.size;
337
0
                        }
338
0
                    }
339
340
13.0k
                    if (ctx->args.cidfsubstfont.data == NULL) {
341
13.0k
                        int len = 0;
342
13.0k
                        if (gp_getenv("CIDFSUBSTFONT", (char *)0, &len) < 0) {
343
0
                            if (len + fsprefixlen + 1 > gp_file_name_sizeof) {
344
0
                                code = gs_note_error(gs_error_rangecheck);
345
0
                                if ((code = pdfi_set_warning_stop(ctx, code, NULL, W_PDF_BAD_CONFIG, "pdfi_open_CIDFont_substitute_file", "CIDFSUBSTFONT environment variable too long")) < 0)
346
0
                                    goto exit;
347
348
0
                                if (defcidfallacklen + fsprefixlen > gp_file_name_sizeof - 1) {
349
0
                                    pdfi_set_warning(ctx, code, NULL, W_PDF_BAD_CONFIG, "pdfi_open_CIDFont_substitute_file", "CIDFSubstPath parameter too long");
350
0
                                    memcpy(fontfname, defcidfallack, defcidfallacklen);
351
0
                                    fsprefixlen = 0;
352
0
                                } else
353
0
                                    memcpy(fontfname + fsprefixlen, defcidfallack, defcidfallacklen);
354
0
                            }
355
0
                            else {
356
0
                                (void)gp_getenv("CIDFSUBSTFONT", (char *)(fontfname + fsprefixlen), &defcidfallacklen);
357
0
                            }
358
0
                        }
359
13.0k
                        else {
360
13.0k
                            if (fsprefixlen + defcidfallacklen > gp_file_name_sizeof - 1) {
361
0
                                code = gs_note_error(gs_error_rangecheck);
362
0
                                if ((code = pdfi_set_warning_stop(ctx, code, NULL, W_PDF_BAD_CONFIG, "pdfi_open_CIDFont_substitute_file", "CIDFSUBSTFONT environment variable too long")) < 0)
363
0
                                    goto exit;
364
365
0
                                memcpy(fontfname, defcidfallack, defcidfallacklen);
366
                                /* cidfsubstfont should either be a font name we find in the search path(s)
367
                                   or an absolute path.
368
                                 */
369
0
                                fsprefixlen = 0;
370
0
                            }
371
13.0k
                            else {
372
13.0k
                                memcpy(fontfname + fsprefixlen, defcidfallack, defcidfallacklen);
373
13.0k
                            }
374
13.0k
                        }
375
13.0k
                    }
376
0
                    else {
377
0
                        if (ctx->args.cidfsubstfont.size + fsprefixlen > gp_file_name_sizeof - 1) {
378
0
                            code = gs_note_error(gs_error_rangecheck);
379
0
                            if ((code = pdfi_set_warning_stop(ctx, code, NULL, W_PDF_BAD_CONFIG, "pdfi_open_CIDFont_substitute_file", "CIDFSubstFont parameter too long")) < 0)
380
0
                                goto exit;
381
382
0
                            if (fsprefixlen + defcidfallacklen > gp_file_name_sizeof - 1) {
383
0
                                pdfi_set_warning(ctx, code, NULL, W_PDF_BAD_CONFIG, "pdfi_open_CIDFont_substitute_file", "CIDFSubstPath parameter too long");
384
0
                                memcpy(fontfname, defcidfallack, defcidfallacklen);
385
0
                                fsprefixlen = 0;
386
0
                            }
387
0
                            else
388
0
                                memcpy(fontfname + fsprefixlen, defcidfallack, defcidfallacklen);
389
0
                        }
390
0
                        else {
391
0
                            if (ctx->args.cidfsubstfont.size > gp_file_name_sizeof - 1) {
392
0
                                code = gs_note_error(gs_error_rangecheck);
393
0
                                if ((code = pdfi_set_warning_stop(ctx, code, NULL, W_PDF_BAD_CONFIG, "pdfi_open_CIDFont_substitute_file", "CIDFSubstFont parameter too long")) < 0)
394
0
                                    goto exit;
395
396
0
                                memcpy(fontfname, defcidfallack, defcidfallacklen);
397
0
                                defcidfallacklen = ctx->args.cidfsubstfont.size;
398
                                /* cidfsubstfont should either be a font name we find in the search path(s)
399
                                   or an absolute path.
400
                                 */
401
0
                                fsprefixlen = 0;
402
0
                            }
403
0
                            else {
404
0
                                memcpy(fontfname, ctx->args.cidfsubstfont.data, ctx->args.cidfsubstfont.size);
405
0
                                defcidfallacklen = ctx->args.cidfsubstfont.size;
406
                                /* cidfsubstfont should either be a font name we find in the search path(s)
407
                                   or an absolute path.
408
                                 */
409
0
                                fsprefixlen = 0;
410
0
                            }
411
0
                        }
412
0
                    }
413
13.0k
                    fontfname[fsprefixlen + defcidfallacklen] = '\0';
414
415
13.0k
                    code = pdfi_open_resource_file(ctx, fontfname, strlen(fontfname), &s);
416
13.0k
                    if (code < 0) {
417
0
                        pdf_name *fn;
418
0
                        code = pdfi_object_alloc(ctx, PDF_NAME, strlen(fontfname), (pdf_obj **)&fn);
419
0
                        if (code < 0) {
420
0
                            code = gs_note_error(gs_error_invalidfont);
421
0
                        }
422
0
                        else {
423
0
                            pdfi_countup(fn);
424
0
                            memcpy(fn->data, fontfname, strlen(fontfname));
425
0
                            pdfi_countdown(mname);
426
0
                            mname = NULL;
427
0
                            code = pdfi_fontmap_lookup_cidfont(ctx, font_dict, fn, (pdf_obj **)&mname, findex);
428
0
                            pdfi_countdown(fn);
429
0
                            if (code < 0)
430
0
                                code = gs_note_error(gs_error_invalidfont);
431
0
                            else
432
0
                                continue;
433
0
                        }
434
0
                    }
435
13.0k
                    else {
436
13.0k
                        if (cidname) {
437
12.8k
                            pdfi_print_cstring(ctx, "Loading CIDFont ");
438
12.8k
                            pdfi_print_font_name(ctx, (pdf_name *)cidname);
439
12.8k
                            pdfi_print_cstring(ctx, " substitute from ");
440
12.8k
                        }
441
165
                        else {
442
165
                            pdfi_print_cstring(ctx, "Loading nameless CIDFont from ");
443
165
                        }
444
13.0k
                        sfilename(s, &fname);
445
13.0k
                        if (fname.size < gp_file_name_sizeof) {
446
13.0k
                            memcpy(fontfname, fname.data, fname.size);
447
13.0k
                            fontfname[fname.size] = '\0';
448
13.0k
                        }
449
0
                        else {
450
0
                            strcpy(fontfname, "unnamed file");
451
0
                        }
452
13.0k
                        pdfi_print_cstring(ctx, fontfname);
453
13.0k
                        pdfi_print_cstring(ctx, "\n");
454
455
456
13.0k
                        sfseek(s, 0, SEEK_END);
457
13.0k
                        *buflen = sftell(s);
458
13.0k
                        sfseek(s, 0, SEEK_SET);
459
13.0k
                        *buf = gs_alloc_bytes(ctx->memory, *buflen, "pdfi_open_CIDFont_file(buf)");
460
13.0k
                        if (*buf != NULL) {
461
13.0k
                            sfread(*buf, 1, *buflen, s);
462
13.0k
                        }
463
0
                        else {
464
0
                            code = gs_note_error(gs_error_VMerror);
465
0
                        }
466
13.0k
                        sfclose(s);
467
13.0k
                        break;
468
13.0k
                    }
469
13.0k
                }
470
13.0k
            }
471
0
            else {
472
0
                if (mname->length + 1 > gp_file_name_sizeof) {
473
0
                    pdfi_countdown(mname);
474
0
                    return_error(gs_error_invalidfont);
475
0
                }
476
0
                memcpy(fontfname, mname->data, mname->length);
477
0
                fontfname[mname->length] = '\0';
478
0
                code = pdfi_open_resource_file(ctx, (const char *)fontfname, mname->length, &s);
479
0
                pdfi_countdown(mname);
480
0
                if (code < 0) {
481
0
                    code = gs_note_error(gs_error_invalidfont);
482
0
                }
483
0
                else {
484
0
                    if (cidname) {
485
0
                        pdfi_print_cstring(ctx, "Loading CIDFont ");
486
0
                        pdfi_print_font_name(ctx, (pdf_name *)cidname);
487
0
                        pdfi_print_cstring(ctx, " (or substitute) from ");
488
0
                    }
489
0
                    else {
490
0
                        pdfi_print_cstring(ctx, "Loading nameless CIDFont from ");
491
0
                    }
492
0
                    sfilename(s, &fname);
493
0
                    if (fname.size < gp_file_name_sizeof) {
494
0
                        memcpy(fontfname, fname.data, fname.size);
495
0
                        fontfname[fname.size] = '\0';
496
0
                    }
497
0
                    else {
498
0
                        strcpy(fontfname, "unnamed file");
499
0
                    }
500
0
                    pdfi_print_cstring(ctx, fontfname);
501
0
                    pdfi_print_cstring(ctx, "\n");
502
0
                    sfseek(s, 0, SEEK_END);
503
0
                    *buflen = sftell(s);
504
0
                    sfseek(s, 0, SEEK_SET);
505
0
                    *buf = gs_alloc_bytes(ctx->memory, *buflen, "pdfi_open_CIDFont_file(buf)");
506
0
                    if (*buf != NULL) {
507
0
                        sfread(*buf, 1, *buflen, s);
508
0
                    }
509
0
                    else {
510
0
                        code = gs_note_error(gs_error_VMerror);
511
0
                    }
512
0
                    sfclose(s);
513
0
                    break;
514
0
                }
515
0
            }
516
13.0k
        } while (code >= 0);
517
13.0k
    }
518
13.0k
    else {
519
13.0k
        const char *fsprefix = "CIDFont/";
520
13.0k
        const int fsprefixlen = strlen(fsprefix);
521
522
13.0k
        if (cidname == NULL || pdfi_type_of(cidname) != PDF_NAME
523
12.8k
         || fsprefixlen + cidname->length >= gp_file_name_sizeof) {
524
170
            code = gs_note_error(gs_error_invalidfont);
525
170
            goto exit;
526
170
        }
527
528
12.8k
        memcpy(fontfname, fsprefix, fsprefixlen);
529
12.8k
        memcpy(fontfname + fsprefixlen, cidname->data, cidname->length);
530
12.8k
        fontfname[fsprefixlen + cidname->length] = '\0';
531
532
12.8k
        code = pdfi_open_resource_file(ctx, fontfname, strlen(fontfname), &s);
533
12.8k
        if (code < 0) {
534
12.8k
            code = gs_note_error(gs_error_invalidfont);
535
12.8k
        }
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
12.8k
    }
550
551
26.0k
exit:
552
26.0k
    if (cidname != NULL)
553
25.7k
        pdfi_countdown(cidname);
554
555
26.0k
    return code;
556
26.0k
}
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
52.3M
{
593
60.5M
    while (1)
594
60.5M
    {
595
60.5M
        while (*a == ' ')
596
0
            a++;
597
60.5M
        while (*b == ' ')
598
668
            b++;
599
60.5M
        if (*a != *b)
600
52.2M
            return 1;
601
8.26M
        if (*a == 0)
602
7.58k
            return *a != *b;
603
8.25M
        if (*b == 0)
604
0
            return *a != *b;
605
8.25M
        a++;
606
8.25M
        b++;
607
8.25M
    }
608
0
    return 0; /* Shouldn't happen */
609
52.3M
}
610
611
static const char *pdfi_clean_font_name(const char *fontname)
612
785k
{
613
785k
    int i, k;
614
11.7M
    for (i = 0; i < (sizeof(pdfi_base_font_names)/sizeof(pdfi_base_font_names[0])); i++) {
615
63.2M
        for (k = 0; pdfi_base_font_names[i][k]; k++) {
616
52.3M
            if (!strncmp_ignore_space(pdfi_base_font_names[i][k], (const char *)fontname))
617
7.58k
                return pdfi_base_font_names[i][0];
618
52.3M
        }
619
10.9M
    }
620
777k
    return NULL;
621
785k
}
622
623
static int pdfi_font_substitute_by_flags(pdf_context *ctx, unsigned int flags, char **name, int *namelen)
624
406k
{
625
406k
    bool fixed = ((flags & pdfi_font_flag_fixed) != 0);
626
406k
    bool serif = ((flags & pdfi_font_flag_serif) != 0);
627
406k
    bool italic = ((flags & pdfi_font_flag_italic) != 0);
628
406k
    bool bold = ((flags & pdfi_font_flag_forcebold) != 0);
629
406k
    int code = 0;
630
631
406k
    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
406k
    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
406k
    else if (fixed) {
642
208
        if (bold) {
643
5
            if (italic) {
644
5
                *name = (char *)pdfi_base_font_names[3][0];
645
5
                *namelen = strlen(*name);
646
5
            }
647
0
            else {
648
0
                *name = (char *)pdfi_base_font_names[1][0];
649
0
                *namelen = strlen(*name);
650
0
            }
651
5
        }
652
203
        else {
653
203
            if (italic) {
654
2
                *name = (char *)pdfi_base_font_names[2][0];
655
2
                *namelen = strlen(*name);
656
2
            }
657
201
            else {
658
201
                *name = (char *)pdfi_base_font_names[0][0];
659
201
                *namelen = strlen(*name);
660
201
            }
661
203
        }
662
208
    }
663
406k
    else if (serif) {
664
1.94k
        if (bold) {
665
10
            if (italic) {
666
0
                *name = (char *)pdfi_base_font_names[11][0];
667
0
                *namelen = strlen(*name);
668
0
            }
669
10
            else {
670
10
                *name = (char *)pdfi_base_font_names[9][0];
671
10
                *namelen = strlen(*name);
672
10
            }
673
10
        }
674
1.93k
        else {
675
1.93k
            if (italic) {
676
138
                *name = (char *)pdfi_base_font_names[10][0];
677
138
                *namelen = strlen(*name);
678
138
            }
679
1.79k
            else {
680
1.79k
                *name = (char *)pdfi_base_font_names[8][0];
681
1.79k
                *namelen = strlen(*name);
682
1.79k
            }
683
1.93k
        }
684
404k
    } else {
685
404k
        if (bold) {
686
148
            if (italic) {
687
0
                *name = (char *)pdfi_base_font_names[7][0];
688
0
                *namelen = strlen(*name);
689
0
            }
690
148
            else {
691
148
                *name = (char *)pdfi_base_font_names[5][0];
692
148
                *namelen = strlen(*name);
693
148
            }
694
148
        }
695
404k
        else {
696
404k
            if (italic) {
697
508
                *name = (char *)pdfi_base_font_names[6][0];
698
508
                *namelen = strlen(*name);
699
508
            }
700
403k
            else {
701
403k
                *name = (char *)pdfi_base_font_names[4][0];
702
403k
                *namelen = strlen(*name);
703
403k
            }
704
404k
        }
705
404k
    }
706
406k
    return code;
707
406k
}
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
109k
{
720
995k
#define MAKEMAGIC(a, b, c, d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
721
722
109k
    if (buflen >= 4) {
723
109k
        if (MAKEMAGIC(buf[0], buf[1], buf[2], buf[3]) == MAKEMAGIC(0, 1, 0, 0)
724
70.5k
            || MAKEMAGIC(buf[0], buf[1], buf[2], buf[3]) == MAKEMAGIC('t', 'r', 'u', 'e')
725
66.1k
            || MAKEMAGIC(buf[0], buf[1], buf[2], buf[3]) == MAKEMAGIC('t', 't', 'c', 'f')) {
726
42.9k
            return tt_font;
727
42.9k
        }
728
66.1k
        else if (MAKEMAGIC(buf[0], buf[1], buf[2], buf[3]) == MAKEMAGIC('O', 'T', 'T', 'O')) {
729
529
            return cff_font; /* OTTO will end up as CFF */
730
529
        }
731
65.6k
        else if (MAKEMAGIC(buf[0], buf[1], buf[2], 0) == MAKEMAGIC('%', '!', 'P', 0)) {
732
55.0k
            return type1_font; /* pfa */
733
55.0k
        }
734
10.5k
        else if (MAKEMAGIC(buf[0], buf[1], buf[2], 0) == MAKEMAGIC(1, 0, 4, 0)) {
735
9.97k
            return cff_font; /* 1C/CFF */
736
9.97k
        }
737
622
        else if (MAKEMAGIC(buf[0], buf[1], 0, 0) == MAKEMAGIC(128, 1, 0, 0)) {
738
167
            return type1_font; /* pfb */
739
167
        }
740
109k
    }
741
477
    return no_type_font;
742
109k
#undef MAKEMAGIC
743
109k
}
744
745
static int pdfi_copy_font(pdf_context *ctx, pdf_font *spdffont, pdf_dict *font_dict, pdf_font **tpdffont)
746
433k
{
747
433k
    int code;
748
433k
    if (pdfi_type_of(spdffont) != PDF_FONT)
749
0
        return_error(gs_error_typecheck);
750
751
433k
    switch(spdffont->pdfi_font_type) {
752
429k
        case e_pdf_font_type1:
753
429k
          code = pdfi_copy_type1_font(ctx, spdffont, font_dict, tpdffont);
754
429k
          break;
755
49
        case e_pdf_font_cff:
756
49
          code = pdfi_copy_cff_font(ctx, spdffont, font_dict, tpdffont);
757
49
          break;
758
3.10k
        case e_pdf_font_truetype:
759
3.10k
          code = pdfi_copy_truetype_font(ctx, spdffont, font_dict, tpdffont);
760
3.10k
          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
433k
    }
767
433k
    return code;
768
433k
}
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
109k
{
778
109k
    int code = gs_error_invalidfont;
779
109k
    if (fbuf != NULL) {
780
        /* First, see if we can glean the type from the magic number */
781
109k
        int sftype = pdfi_fonttype_picker(fbuf, fbuflen);
782
109k
        if (sftype == no_type_font) {
783
477
            if (fftype != no_type_font)
784
452
                sftype = fftype;
785
25
            else {
786
                /* If we don't have a Subtype, can't work it out, try Type 1 */
787
25
                if (Subtype == NULL || pdfi_name_is(Subtype, "Type1") || pdfi_name_is(Subtype, "MMType1"))
788
23
                    sftype = type1_font;
789
2
                else if (pdfi_name_is(Subtype, "Type1C"))
790
0
                    sftype = cff_font;
791
2
                else if (pdfi_name_is(Subtype, "TrueType"))
792
0
                    sftype = tt_font;
793
25
            }
794
477
        }
795
        /* fbuf ownership passes to the font loader */
796
109k
        switch (sftype) {
797
55.5k
            case type1_font:
798
55.5k
                code = pdfi_read_type1_font(ctx, (pdf_dict *)font_dict, stream_dict, page_dict, fbuf, fbuflen, ppdffont);
799
55.5k
                fbuf = NULL;
800
55.5k
                break;
801
10.5k
            case cff_font:
802
10.5k
                code = pdfi_read_cff_font(ctx, (pdf_dict *)font_dict, stream_dict, page_dict, fbuf, fbuflen, cidfont, ppdffont);
803
10.5k
                fbuf = NULL;
804
10.5k
                break;
805
43.0k
            case tt_font:
806
43.0k
                {
807
43.0k
                    if (cidfont)
808
20.5k
                        code = pdfi_read_cidtype2_font(ctx, font_dict, stream_dict, page_dict, fbuf, fbuflen, findex, ppdffont);
809
22.5k
                    else
810
22.5k
                        code = pdfi_read_truetype_font(ctx, font_dict, stream_dict, page_dict, fbuf, fbuflen, findex, ppdffont);
811
43.0k
                    fbuf = NULL;
812
43.0k
                }
813
43.0k
                break;
814
2
            default:
815
2
                gs_free_object(ctx->memory, fbuf, "pdfi_load_font_buffer(fbuf)");
816
2
                code = gs_note_error(gs_error_invalidfont);
817
109k
        }
818
109k
    }
819
109k
    return code;
820
109k
}
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
836k
{
824
836k
    int code;
825
836k
    char fontfname[gp_file_name_sizeof];
826
836k
    pdf_obj *basefont = NULL, *mapname = NULL;
827
836k
    pdf_obj *fontname = NULL;
828
836k
    stream *s = NULL;
829
836k
    const char *fn;
830
836k
    int findex = 0;
831
836k
    byte *buf;
832
836k
    int buflen;
833
836k
    pdf_font *pdffont = NULL;
834
836k
    pdf_font *substpdffont = NULL;
835
836k
    bool f_retry = true;
836
837
836k
    code = pdfi_dict_knownget_type(ctx, font_dict, "BaseFont", PDF_NAME, &basefont);
838
836k
    if (substitute == false && (code < 0 || basefont == NULL || ((pdf_name *)basefont)->length == 0)) {
839
17.6k
        pdfi_countdown(basefont);
840
17.6k
        return_error(gs_error_invalidfont);
841
17.6k
    }
842
843
818k
    if (substitute == true) {
844
406k
        char *fbname;
845
406k
        int fbnamelen;
846
406k
        int64_t flags = 0;
847
406k
        if (fontdesc != NULL) {
848
21.0k
            (void)pdfi_dict_get_int(ctx, fontdesc, "Flags", &flags);
849
21.0k
        }
850
406k
        code = pdfi_font_substitute_by_flags(ctx, (int)flags, &fbname, &fbnamelen);
851
406k
        if (code < 0)
852
0
            return code;
853
854
406k
        code = pdfi_name_alloc(ctx, (byte *)fbname, strlen(fbname), (pdf_obj **) &fontname);
855
406k
        if (code < 0)
856
0
            return code;
857
406k
        pdfi_countup(fontname);
858
406k
    }
859
412k
    else {
860
412k
        fontname = basefont;
861
412k
        pdfi_countup(fontname);
862
412k
    }
863
864
818k
    if (((pdf_name *)fontname)->length < gp_file_name_sizeof) {
865
818k
        memcpy(fontfname, ((pdf_name *)fontname)->data, ((pdf_name *)fontname)->length);
866
818k
        fontfname[((pdf_name *)fontname)->length] = '\0';
867
818k
        pdfi_countdown(fontname);
868
869
818k
        code = pdfi_name_alloc(ctx, (byte *)fontfname, strlen(fontfname), (pdf_obj **) &fontname);
870
818k
        if (code < 0)
871
0
            return code;
872
818k
        pdfi_countup(fontname);
873
818k
    }
874
3
    else {
875
        /* Just to ensure that fontfname is a valid, though empty, string */
876
3
        fontfname[0] = '\0';
877
3
    }
878
879
1.21M
    do {
880
1.21M
        if (f_retry == true && pdfi_font_file_exists(ctx, (const char *)((pdf_name *)fontname)->data, ((pdf_name *)fontname)->length) == true) {
881
0
            code = 0;
882
0
        }
883
1.21M
        else {
884
1.21M
            code = pdfi_fontmap_lookup_font(ctx, font_dict, (pdf_name *) fontname, &mapname, &findex);
885
1.21M
            if (code < 0) {
886
785k
                if (((pdf_name *)fontname)->length < gp_file_name_sizeof) {
887
785k
                    memcpy(fontfname, ((pdf_name *)fontname)->data, ((pdf_name *)fontname)->length);
888
785k
                    fontfname[((pdf_name *)fontname)->length] = '\0';
889
785k
                    fn = pdfi_clean_font_name(fontfname);
890
785k
                    if (fn != NULL) {
891
7.58k
                        pdfi_countdown(fontname);
892
893
7.58k
                        code = pdfi_name_alloc(ctx, (byte *)fn, strlen(fn), (pdf_obj **) &fontname);
894
7.58k
                        if (code < 0)
895
0
                            return code;
896
7.58k
                        pdfi_countup(fontname);
897
7.58k
                    }
898
785k
                }
899
785k
                code = pdfi_fontmap_lookup_font(ctx, font_dict, (pdf_name *) fontname, &mapname, &findex);
900
785k
                if (code < 0) {
901
777k
                    mapname = fontname;
902
777k
                    pdfi_countup(mapname);
903
777k
                    code = 0;
904
777k
                }
905
785k
            }
906
1.21M
            if (pdfi_type_of(mapname) == PDF_FONT) {
907
0
                pdffont = (pdf_font *)mapname;
908
0
                pdfi_countup(pdffont);
909
0
                break;
910
0
            }
911
1.21M
            if (pdfi_type_of(mapname) == PDF_NAME || pdfi_type_of(mapname) == PDF_STRING) {
912
1.21M
                pdf_name *mname = (pdf_name *) mapname;
913
1.21M
                if (mname->length + 1 < gp_file_name_sizeof) {
914
1.21M
                    memcpy(fontfname, mname->data, mname->length);
915
1.21M
                    fontfname[mname->length] = '\0';
916
1.21M
                }
917
3
                else {
918
3
                    pdfi_countdown(mapname);
919
3
                    pdfi_countdown(fontname);
920
3
                    return_error(gs_error_invalidfileaccess);
921
3
                }
922
1.21M
            }
923
0
            else {
924
0
                pdfi_countdown(mapname);
925
0
                pdfi_countdown(fontname);
926
0
                return_error(gs_error_invalidfileaccess);
927
0
            }
928
929
1.21M
            if (ctx->pdf_substitute_fonts != NULL) {
930
1.11M
                code = pdfi_dict_knownget_type(ctx, ctx->pdf_substitute_fonts, fontfname, PDF_FONT, (pdf_obj **)&pdffont);
931
1.11M
                if (code == 1 && pdffont->filename == NULL) {
932
0
                    pdfi_countdown(pdffont);
933
0
                    pdffont = NULL;
934
0
                    code = 0;
935
0
                }
936
1.11M
            }
937
91.3k
            else
938
91.3k
                code = 0;
939
1.21M
        }
940
1.21M
        if (code != 1) {
941
825k
            code = pdfi_open_font_file(ctx, fontfname, strlen(fontfname), &s);
942
825k
            if (code < 0 && f_retry && pdfi_type_of(mapname) == PDF_NAME) {
943
391k
                pdfi_countdown(fontname);
944
391k
                fontname = mapname;
945
391k
                mapname = NULL;
946
391k
                f_retry = false;
947
391k
                continue;
948
391k
            }
949
434k
            if (code >= 0) {
950
45.4k
                gs_const_string fname;
951
952
45.4k
                sfilename(s, &fname);
953
45.4k
                if (fname.size < gp_file_name_sizeof) {
954
45.4k
                    memcpy(fontfname, fname.data, fname.size);
955
45.4k
                    fontfname[fname.size] = '\0';
956
45.4k
                }
957
0
                else {
958
0
                    strcpy(fontfname, "unnamed file");
959
0
                }
960
45.4k
                sfseek(s, 0, SEEK_END);
961
45.4k
                buflen = sftell(s);
962
45.4k
                sfseek(s, 0, SEEK_SET);
963
45.4k
                buf = gs_alloc_bytes(ctx->memory, buflen, "pdfi_open_t1_font_file(buf)");
964
45.4k
                if (buf != NULL) {
965
45.4k
                    sfread(buf, 1, buflen, s);
966
45.4k
                }
967
0
                else {
968
0
                    code = gs_note_error(gs_error_VMerror);
969
0
                }
970
45.4k
                sfclose(s);
971
                /* Buffer owership moves to the font object */
972
45.4k
                code = pdfi_load_font_buffer(ctx, buf, buflen, no_type_font, NULL, findex, stream_dict, page_dict, NULL, &pdffont, false);
973
45.4k
                if (code >= 0) {
974
45.4k
                    pdffont->filename = NULL;
975
45.4k
                    code = pdfi_object_alloc(ctx, PDF_STRING, strlen(fontfname) , (pdf_obj **)&pdffont->filename);
976
45.4k
                    if (code >= 0) {
977
45.4k
                        pdfi_countup(pdffont->filename);
978
45.4k
                        memcpy(pdffont->filename->data, fontfname, strlen(fontfname));
979
45.4k
                        pdffont->filename->length = strlen(fontfname);
980
45.4k
                    }
981
982
45.4k
                    if (ctx->pdf_substitute_fonts == NULL) {
983
35.8k
                        code = pdfi_dict_alloc(ctx, 16, &ctx->pdf_substitute_fonts);
984
35.8k
                        if (code >= 0)
985
35.8k
                            pdfi_countup(ctx->pdf_substitute_fonts);
986
35.8k
                    }
987
45.4k
                    if (ctx->pdf_substitute_fonts != NULL) {
988
45.4k
                        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
45.4k
                        else
1001
45.4k
                            code = 0;
1002
1003
45.4k
                        if (code == 0)
1004
45.4k
                            (void)pdfi_dict_put_obj(ctx, ctx->pdf_substitute_fonts, mapname, (pdf_obj *)pdffont, true);
1005
45.4k
                        code = 0;
1006
45.4k
                    }
1007
45.4k
                }
1008
45.4k
            }
1009
434k
        }
1010
818k
        break;
1011
1.21M
    } while (1);
1012
1013
818k
    if (code >= 0) {
1014
429k
        if (basefont) {
1015
429k
            pdfi_print_cstring(ctx, "Loading font ");
1016
429k
            pdfi_print_font_name(ctx, (pdf_name *)basefont);
1017
429k
            pdfi_print_cstring(ctx, " (or substitute) from ");
1018
429k
        }
1019
812
        else {
1020
812
            pdfi_print_cstring(ctx, "Loading nameless font from ");
1021
812
        }
1022
429k
        pdfi_print_font_string(ctx, pdffont->filename);
1023
429k
        pdfi_print_cstring(ctx, "\n");
1024
1025
429k
        code = pdfi_copy_font(ctx, pdffont, font_dict, &substpdffont);
1026
429k
        pdfi_countdown(pdffont);
1027
429k
    }
1028
1029
818k
    *ppdffont = substpdffont;
1030
1031
818k
    pdfi_countdown(basefont);
1032
818k
    pdfi_countdown(mapname);
1033
818k
    pdfi_countdown(fontname);
1034
818k
    return code;
1035
818k
}
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
520k
{
1039
520k
    int code;
1040
520k
    pdf_font *ppdffont = NULL;
1041
520k
    pdf_font *ppdfdescfont = NULL;
1042
520k
    pdf_name *Type = NULL;
1043
520k
    pdf_name *Subtype = NULL;
1044
520k
    pdf_dict *fontdesc = NULL;
1045
520k
    pdf_stream *fontfile = NULL;
1046
520k
    pdf_name *ffsubtype = NULL;
1047
520k
    int fftype = no_type_font;
1048
520k
    byte *fbuf = NULL;
1049
520k
    int64_t fbuflen = 0;
1050
520k
    int substitute = font_embedded;
1051
520k
    int findex = 0;
1052
1053
520k
    code = pdfi_dict_get_type(ctx, font_dict, "Type", PDF_NAME, (pdf_obj **)&Type);
1054
520k
    if (code < 0) {
1055
596
        if ((code = pdfi_set_error_stop(ctx, code, NULL, E_PDF_MISSINGTYPE, "pdfi_load_font", NULL)) < 0)
1056
0
            goto exit;
1057
596
    }
1058
519k
    else {
1059
519k
        if (!pdfi_name_is(Type, "Font")){
1060
2.69k
            code = gs_note_error(gs_error_typecheck);
1061
2.69k
            goto exit;
1062
2.69k
        }
1063
519k
    }
1064
517k
    code = pdfi_dict_get_type(ctx, font_dict, "Subtype", PDF_NAME, (pdf_obj **)&Subtype);
1065
517k
    if (code < 0) {
1066
655
        if ((code = pdfi_set_error_stop(ctx, code, NULL, E_PDF_NO_SUBTYPE, "pdfi_load_font", NULL)) < 0)
1067
0
            goto exit;
1068
655
    }
1069
1070
    /* Beyond Type 0 and Type 3, there is no point trusting the Subtype key */
1071
517k
    if (Subtype != NULL && pdfi_name_is(Subtype, "Type0")) {
1072
34.8k
        if (cidfont == true) {
1073
7
            code = gs_note_error(gs_error_invalidfont);
1074
7
        }
1075
34.8k
        else {
1076
34.8k
            code = pdfi_read_type0_font(ctx, (pdf_dict *)font_dict, stream_dict, page_dict, &ppdffont);
1077
34.8k
        }
1078
34.8k
    }
1079
482k
    else if (Subtype != NULL && pdfi_name_is(Subtype, "Type3")) {
1080
2.57k
        code = pdfi_read_type3_font(ctx, (pdf_dict *)font_dict, stream_dict, page_dict, &ppdffont);
1081
2.57k
        if (code < 0)
1082
495
            goto exit;
1083
2.57k
    }
1084
480k
    else {
1085
480k
        if (Subtype != NULL && !pdfi_name_is(Subtype, "Type1") && !pdfi_name_is(Subtype, "TrueType") && !pdfi_name_is(Subtype, "CIDFont")
1086
22.1k
            && !pdfi_name_is(Subtype, "CIDFontType2") && !pdfi_name_is(Subtype, "CIDFontType0") && !pdfi_name_is(Subtype, "MMType1")) {
1087
1088
717
            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
717
        }
1092
        /* We should always have a font descriptor here, but we have to carry on
1093
           even if we don't
1094
         */
1095
480k
        code = pdfi_dict_get_type(ctx, font_dict, "FontDescriptor", PDF_DICT, (pdf_obj **)&fontdesc);
1096
480k
        if (fontdesc != NULL && pdfi_type_of(fontdesc) == PDF_DICT) {
1097
70.4k
            pdf_obj *Name = NULL;
1098
1099
70.4k
            code = pdfi_dict_get_type(ctx, (pdf_dict *) fontdesc, "FontName", PDF_NAME, (pdf_obj **)&Name);
1100
70.4k
            if (code < 0)
1101
967
                pdfi_set_warning(ctx, 0, NULL, W_PDF_FDESC_BAD_FONTNAME, "pdfi_load_font", "");
1102
70.4k
            pdfi_countdown(Name);
1103
70.4k
            Name = NULL;
1104
1105
70.4k
            if (cidfont == true) {
1106
13.2k
                code = -1;
1107
13.2k
            }
1108
57.1k
            else {
1109
57.1k
                code = pdfi_find_cache_resource_font(ctx, (pdf_obj *)fontdesc, (pdf_obj **)&ppdfdescfont);
1110
57.1k
                if (code >= 0) {
1111
3.26k
                    code = pdfi_copy_font(ctx, ppdfdescfont, font_dict, &ppdffont);
1112
3.26k
                }
1113
57.1k
            }
1114
1115
70.4k
            if (code < 0) {
1116
67.2k
                code = pdfi_dict_get_type(ctx, (pdf_dict *) fontdesc, "FontFile", PDF_STREAM, (pdf_obj **)&fontfile);
1117
67.2k
                if (code >= 0)
1118
9.85k
                    fftype = type1_font;
1119
57.3k
                else {
1120
57.3k
                    code = pdfi_dict_get_type(ctx, (pdf_dict *) fontdesc, "FontFile2", PDF_STREAM, (pdf_obj **)&fontfile);
1121
57.3k
                    fftype = tt_font;
1122
57.3k
                }
1123
67.2k
                if (code < 0) {
1124
26.0k
                    code = pdfi_dict_get_type(ctx, (pdf_dict *) fontdesc, "FontFile3", PDF_STREAM, (pdf_obj **)&fontfile);
1125
26.0k
                    if (code >= 0 && fontfile != NULL) {
1126
11.0k
                        code = pdfi_dict_get_type(ctx, fontfile->stream_dict, "Subtype", PDF_NAME, (pdf_obj **)&ffsubtype);
1127
11.0k
                        if (code >= 0) {
1128
10.9k
                            if (pdfi_name_is(ffsubtype, "Type1"))
1129
0
                                fftype = type1_font;
1130
10.9k
                            else if (pdfi_name_is(ffsubtype, "Type1C"))
1131
8.47k
                                fftype = cff_font;
1132
2.47k
                            else if (pdfi_name_is(ffsubtype, "OpenType"))
1133
355
                                fftype = cff_font;
1134
2.12k
                            else if (pdfi_name_is(ffsubtype, "CIDFontType0C"))
1135
1.67k
                                fftype = cff_font;
1136
443
                            else if (pdfi_name_is(ffsubtype, "TrueType"))
1137
0
                                fftype = tt_font;
1138
443
                            else
1139
443
                                fftype = no_type_font;
1140
10.9k
                        }
1141
11.0k
                    }
1142
26.0k
                }
1143
67.2k
            }
1144
70.4k
        }
1145
1146
480k
        if (ppdffont == NULL) {
1147
476k
            if (fontfile != NULL) {
1148
52.2k
                code = pdfi_stream_to_buffer(ctx, (pdf_stream *) fontfile, &fbuf, &fbuflen);
1149
52.2k
                pdfi_countdown(fontfile);
1150
52.2k
                if (code < 0 || fbuflen == 0) {
1151
1.58k
                    char obj[129];
1152
1.58k
                    pdfi_print_cstring(ctx, "**** Warning: cannot process embedded stream for font object ");
1153
1.58k
                    gs_snprintf(obj, 128, "%d %d\n", (int)font_dict->object_num, (int)font_dict->generation_num);
1154
1.58k
                    pdfi_print_cstring(ctx, obj);
1155
1.58k
                    pdfi_print_cstring(ctx, "**** Attempting to load a substitute font.\n");
1156
1.58k
                    gs_free_object(ctx->memory, fbuf, "pdfi_load_font(fbuf)");
1157
1.58k
                    fbuf = NULL;
1158
1.58k
                    code = gs_note_error(gs_error_invalidfont);
1159
1.58k
                }
1160
52.2k
            }
1161
1162
489k
            while (1) {
1163
489k
                if (fbuf != NULL) {
1164
                    /* fbuf overship passes to pdfi_load_font_buffer() */
1165
63.6k
                    code = pdfi_load_font_buffer(ctx, fbuf, fbuflen, fftype, Subtype, findex, stream_dict, page_dict, font_dict, &ppdffont, cidfont);
1166
1167
63.6k
                    if (code < 0 && substitute == font_embedded) {
1168
16.8k
                        char msg[129];
1169
1170
16.8k
                        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
16.8k
                        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
16.8k
                        else {
1176
16.8k
                            code = gs_error_invalidfont;
1177
16.8k
                        }
1178
16.8k
                    }
1179
63.6k
                }
1180
426k
                else {
1181
426k
                    code = gs_error_invalidfont;
1182
426k
                }
1183
1184
489k
                if (code < 0 && code != gs_error_VMerror && substitute == font_embedded) {
1185
442k
                    substitute = font_from_file;
1186
1187
442k
                    if (cidfont == true) {
1188
13.0k
                        code =  pdfi_open_CIDFont_substitute_file(ctx, font_dict, fontdesc, false, &fbuf, &fbuflen, &findex);
1189
13.0k
                        if (code < 0) {
1190
13.0k
                            code =  pdfi_open_CIDFont_substitute_file(ctx, font_dict, fontdesc, true, &fbuf, &fbuflen, &findex);
1191
13.0k
                            substitute |= font_substitute;
1192
13.0k
                        }
1193
1194
13.0k
                        if (code < 0)
1195
0
                            goto exit;
1196
13.0k
                    }
1197
429k
                    else {
1198
429k
                        code = pdfi_load_font_file(ctx, no_type_font, Subtype, stream_dict, page_dict, font_dict, fontdesc, false, &ppdffont);
1199
429k
                        if (code < 0) {
1200
406k
                            code = pdfi_load_font_file(ctx, no_type_font, Subtype, stream_dict, page_dict, font_dict, fontdesc, true, &ppdffont);
1201
406k
                            substitute |= font_substitute;
1202
406k
                        }
1203
429k
                        break;
1204
429k
                    }
1205
13.0k
                    continue;
1206
442k
                }
1207
46.8k
                break;
1208
489k
            }
1209
476k
        }
1210
480k
    }
1211
516k
    if (ppdffont == NULL || code < 0) {
1212
28.8k
        *ppfont = NULL;
1213
28.8k
        if (code != gs_error_Fatal)
1214
28.8k
            code = gs_note_error(gs_error_invalidfont);
1215
28.8k
    }
1216
488k
    else {
1217
488k
        ppdffont->substitute = (substitute != font_embedded);
1218
1219
488k
        if ((substitute & font_substitute) == font_substitute)
1220
413k
            code = pdfi_font_match_glyph_widths(ppdffont);
1221
75.0k
        else if (ppdffont->substitute != true && fontdesc != NULL && ppdfdescfont == NULL
1222
33.7k
            && (ppdffont->pdfi_font_type == e_pdf_font_type1 || ppdffont->pdfi_font_type == e_pdf_font_cff
1223
27.2k
            || ppdffont->pdfi_font_type == e_pdf_font_truetype)) {
1224
27.2k
            pdfi_cache_resource_font(ctx, (pdf_obj *)fontdesc, (pdf_obj *)ppdffont);
1225
27.2k
        }
1226
488k
        *ppfont = (gs_font *)ppdffont->pfont;
1227
488k
     }
1228
1229
520k
exit:
1230
520k
    pdfi_countdown(ppdfdescfont);
1231
520k
    pdfi_countdown(fontdesc);
1232
520k
    pdfi_countdown(Type);
1233
520k
    pdfi_countdown(Subtype);
1234
520k
    pdfi_countdown(ffsubtype);
1235
520k
    return code;
1236
516k
}
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
744k
{
1240
744k
    int code;
1241
744k
    gs_font *pfont;
1242
744k
    pdf_font *pdfif;
1243
1244
744k
    switch (pdfi_type_of(font_dict)) {
1245
620k
        case PDF_FONT:
1246
620k
            pdfi_countup(font_dict);
1247
620k
            pfont = (gs_font *)((pdf_font *)font_dict)->pfont;
1248
620k
            code = 0;
1249
620k
            break;
1250
116k
        case PDF_DICT:
1251
116k
            code = pdfi_load_font(ctx, stream_dict, page_dict, font_dict, &pfont, false);
1252
116k
            break;
1253
7.91k
        default:
1254
7.91k
            code = gs_note_error(gs_error_typecheck);
1255
7.91k
            goto exit;
1256
744k
    }
1257
737k
    if (code < 0)
1258
25.3k
        goto exit;
1259
1260
    /* Everything looks good, set the font, unless it's the current font */
1261
711k
    if (pfont != ctx->pgs->font) {
1262
554k
        code = pdfi_gs_setfont(ctx, pfont);
1263
554k
    }
1264
711k
    pdfif = (pdf_font *)pfont->client_data;
1265
711k
    pdfi_countdown(pdfif);
1266
1267
711k
    if (code < 0)
1268
0
        goto exit;
1269
1270
711k
    code = gs_setPDFfontsize(ctx->pgs, point_size);
1271
744k
exit:
1272
744k
    return code;
1273
711k
}
1274
1275
static int pdfi_load_resource_font(pdf_context *ctx, pdf_dict *stream_dict, pdf_dict *page_dict, pdf_name *fontname, double point_size)
1276
1.09M
{
1277
1.09M
    int code;
1278
1.09M
    pdf_dict *font_dict = NULL;
1279
1280
1.09M
    if (pdfi_type_of(fontname) != PDF_NAME) {
1281
        /* Passing empty string here should fall back to a default font */
1282
14.6k
        return pdfi_font_set_internal_string(ctx, "", point_size);
1283
14.6k
    }
1284
1285
    /* Look fontname up in the resources */
1286
1.07M
    code = pdfi_loop_detector_mark(ctx);
1287
1.07M
    if (code < 0)
1288
0
        goto exit;
1289
1.07M
    code = pdfi_find_resource(ctx, (unsigned char *)"Font", fontname, stream_dict, page_dict, (pdf_obj **)&font_dict);
1290
1.07M
    (void)pdfi_loop_detector_cleartomark(ctx);
1291
1.07M
    if (code < 0)
1292
334k
        goto exit;
1293
744k
    code = pdfi_load_dict_font(ctx, stream_dict, page_dict, font_dict, point_size);
1294
1295
1.07M
exit:
1296
1.07M
    pdfi_countdown(font_dict);
1297
1.07M
    return code;
1298
744k
}
1299
1300
int pdfi_get_cidfont_glyph_metrics(gs_font *pfont, gs_glyph cid, double *widths, bool vertical)
1301
1.12M
{
1302
1.12M
    pdf_font *pdffont = (pdf_font *)pfont->client_data;
1303
1.12M
    int i, code = 0;
1304
1.12M
    pdf_num *c = NULL, *c2 = NULL;
1305
1.12M
    pdf_obj *o = NULL;
1306
1.12M
    pdf_array *W = NULL, *W2 = NULL, *DW2 = NULL;
1307
1.12M
    double DW;
1308
1309
1.12M
    if (pdffont->pdfi_font_type == e_pdf_cidfont_type0) {
1310
58.2k
        pdf_cidfont_type0 *cidfont = (pdf_cidfont_type0 *)pdffont;
1311
58.2k
        DW = cidfont->DW;
1312
58.2k
        DW2 = cidfont->DW2;
1313
58.2k
        W = cidfont->W;
1314
58.2k
        W2 = cidfont->W2;
1315
58.2k
    }
1316
1.06M
    else if (pdffont->pdfi_font_type == e_pdf_cidfont_type2) {
1317
1.06M
        pdf_cidfont_type2 *cidfont = (pdf_cidfont_type2 *)pdffont;
1318
1.06M
        DW = cidfont->DW;
1319
1.06M
        DW2 = cidfont->DW2;
1320
1.06M
        W = cidfont->W;
1321
1.06M
        W2 = cidfont->W2;
1322
1.06M
    }
1323
0
    else {
1324
0
        return_error(gs_error_invalidfont);
1325
0
    }
1326
1327
1.12M
    widths[GLYPH_W0_WIDTH_INDEX] = DW;
1328
1.12M
    widths[GLYPH_W0_HEIGHT_INDEX] = 0;
1329
1.12M
    if (W != NULL) {
1330
1.00M
        i = 0;
1331
1332
23.2M
        while(1) {
1333
23.2M
            pdf_obj_type type;
1334
1335
23.2M
            if (i + 1>= W->size) break;
1336
23.1M
            code = pdfi_array_get_type(pdffont->ctx, W, i, PDF_INT, (pdf_obj **)&c);
1337
23.1M
            if (code < 0) goto cleanup;
1338
1339
23.1M
            code = pdfi_array_get(pdffont->ctx, W, i + 1, &o);
1340
23.1M
            if (code < 0) goto cleanup;
1341
1342
23.1M
            type = pdfi_type_of(o);
1343
23.1M
            if (type == PDF_INT) {
1344
2.32M
                double d;
1345
2.32M
                c2 = (pdf_num *)o;
1346
2.32M
                o = NULL;
1347
2.32M
                if (i + 2 >= W->size){
1348
                    /* We countdown and NULL c, c2 and o after exit from the loop
1349
                     * in order to avoid doing so in the break statements
1350
                     */
1351
138
                    break;
1352
138
                }
1353
1354
2.32M
                code = pdfi_array_get_number(pdffont->ctx, W, i + 2, &d);
1355
2.32M
                if (code < 0) goto cleanup;
1356
2.32M
                if (cid >= c->value.i && cid <= c2->value.i) {
1357
75.4k
                    widths[GLYPH_W0_WIDTH_INDEX] = d;
1358
75.4k
                    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
75.4k
                    break;
1363
75.4k
                }
1364
2.25M
                else {
1365
2.25M
                    i += 3;
1366
2.25M
                    pdfi_countdown(c2);
1367
2.25M
                    pdfi_countdown(c);
1368
2.25M
                    c = c2 = NULL;
1369
2.25M
                    continue;
1370
2.25M
                }
1371
2.32M
            }
1372
20.8M
            else if (type == PDF_ARRAY) {
1373
20.8M
                pdf_array *a = (pdf_array *)o;
1374
20.8M
                o = NULL;
1375
20.8M
                if (cid >= c->value.i && cid < c->value.i + a->size) {
1376
835k
                    code = pdfi_array_get_number(pdffont->ctx, a, cid - c->value.i, &widths[GLYPH_W0_WIDTH_INDEX]);
1377
835k
                    if (code >= 0) {
1378
835k
                        pdfi_countdown(a);
1379
835k
                        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
835k
                        break;
1384
835k
                    }
1385
835k
                }
1386
20.0M
                pdfi_countdown(a);
1387
20.0M
                pdfi_countdown(c);
1388
20.0M
                c = NULL;
1389
20.0M
                i += 2;
1390
20.0M
                continue;
1391
20.8M
            }
1392
687
            else {
1393
687
                code = gs_note_error(gs_error_typecheck);
1394
687
                goto cleanup;
1395
687
            }
1396
23.1M
        }
1397
1.00M
        pdfi_countdown(c2);
1398
1.00M
        pdfi_countdown(c);
1399
1.00M
        pdfi_countdown(o);
1400
1.00M
        c = c2 = NULL;
1401
1.00M
        o = NULL;
1402
1.00M
    }
1403
1404
1.12M
    if (vertical) {
1405
        /* Default default <sigh>! */
1406
1.12M
        widths[GLYPH_W1_WIDTH_INDEX] = 0;
1407
1.12M
        widths[GLYPH_W1_HEIGHT_INDEX] = -1000.0;
1408
1.12M
        widths[GLYPH_W1_V_X_INDEX] = (widths[GLYPH_W0_WIDTH_INDEX] / 2.0);
1409
1.12M
        widths[GLYPH_W1_V_Y_INDEX] = 880.0;
1410
1411
1.12M
        if (DW2 != NULL && pdfi_type_of(DW2) == PDF_ARRAY
1412
8.56k
            && DW2->size >= 2) {
1413
8.56k
            code = pdfi_array_get_number(pdffont->ctx, (pdf_array *)DW2, 0, &widths[GLYPH_W1_V_Y_INDEX]);
1414
8.56k
            if (code >= 0)
1415
8.56k
                code = pdfi_array_get_number(pdffont->ctx, (pdf_array *)DW2, 1, &widths[GLYPH_W1_HEIGHT_INDEX]);
1416
8.56k
            if (code >= 0) {
1417
8.56k
                widths[GLYPH_W1_V_X_INDEX] = widths[GLYPH_W0_WIDTH_INDEX] / 2.0;
1418
8.56k
                widths[GLYPH_W1_WIDTH_INDEX] = 0.0;
1419
8.56k
            }
1420
8.56k
        }
1421
1.12M
        if (W2 != NULL && pdfi_type_of(W2) == PDF_ARRAY) {
1422
0
            i = 0;
1423
0
            while(1) {
1424
0
                pdf_obj_type type;
1425
0
                if (i + 1 >= W2->size) break;
1426
0
                (void)pdfi_array_get(pdffont->ctx, W2, i, (pdf_obj **)&c);
1427
0
                if (pdfi_type_of(c) != PDF_INT) {
1428
0
                    code = gs_note_error(gs_error_typecheck);
1429
0
                    goto cleanup;
1430
0
                }
1431
0
                code = pdfi_array_get(pdffont->ctx, W2, i + 1, (pdf_obj **)&o);
1432
0
                if (code < 0) goto cleanup;
1433
0
                type = pdfi_type_of(o);
1434
0
                if (type == PDF_INT) {
1435
0
                    if (cid >= c->value.i && cid <= ((pdf_num *)o)->value.i) {
1436
0
                        if (i + 4 >= W2->size) {
1437
                            /* We countdown and NULL c, and o on exit from the function
1438
                             * so we don't need to do so in the break statements
1439
                             */
1440
0
                            break;
1441
0
                        }
1442
0
                        code = pdfi_array_get_number(pdffont->ctx, W2, i + 2, &widths[GLYPH_W1_HEIGHT_INDEX]);
1443
0
                        if (code < 0) goto cleanup;
1444
0
                        code = pdfi_array_get_number(pdffont->ctx, W2, i + 3, &widths[GLYPH_W1_V_X_INDEX]);
1445
0
                        if (code < 0) goto cleanup;
1446
0
                        code = pdfi_array_get_number(pdffont->ctx, W2, i + 4, &widths[GLYPH_W1_V_Y_INDEX]);
1447
0
                        if (code < 0) goto cleanup;
1448
                        /* We countdown and NULL c, and o on exit from the function
1449
                         * so we don't need to do so in the break statements
1450
                         */
1451
0
                        break;
1452
0
                    }
1453
0
                    i += 5;
1454
0
                }
1455
0
                else if (type == PDF_ARRAY) {
1456
0
                    pdf_array *a = (pdf_array *)o;
1457
0
                    int l = a->size - (a->size % 3);
1458
0
                    o = NULL;
1459
0
                    if (cid >= c->value.i && cid < c->value.i + (l / 3)) {
1460
0
                        int index = (cid - c->value.i) * 3;
1461
0
                        code = pdfi_array_get_number(pdffont->ctx, a, index, &widths[GLYPH_W1_HEIGHT_INDEX]);
1462
0
                        if (code < 0) {
1463
0
                            pdfi_countdown(a);
1464
0
                            goto cleanup;
1465
0
                        }
1466
0
                        code = pdfi_array_get_number(pdffont->ctx, a, index + 1, &widths[GLYPH_W1_V_X_INDEX]);
1467
0
                        if (code < 0) {
1468
0
                            pdfi_countdown(a);
1469
0
                            goto cleanup;
1470
0
                        }
1471
0
                        code = pdfi_array_get_number(pdffont->ctx, a, index + 2, &widths[GLYPH_W1_V_Y_INDEX]);
1472
0
                        pdfi_countdown(a);
1473
0
                        if (code < 0) goto cleanup;
1474
1475
                        /* We countdown and NULL c, and o on exit from the function
1476
                         * so we don't need to do so in the break statements
1477
                         */
1478
0
                        break;
1479
0
                    } else
1480
0
                        pdfi_countdown(a);
1481
0
                    i += 2;
1482
0
                }
1483
0
                else {
1484
0
                    code = gs_note_error(gs_error_typecheck);
1485
0
                    goto cleanup;
1486
0
                }
1487
0
                pdfi_countdown(o);
1488
0
                pdfi_countdown(c);
1489
0
                o = NULL;
1490
0
                c = NULL;
1491
0
            }
1492
0
        }
1493
1.12M
    }
1494
1495
1.12M
cleanup:
1496
1.12M
    pdfi_countdown(c2);
1497
1.12M
    pdfi_countdown(c);
1498
1.12M
    pdfi_countdown(o);
1499
1500
1.12M
    return code;
1501
1.12M
}
1502
1503
int pdfi_d0(pdf_context *ctx)
1504
3.35k
{
1505
3.35k
    int code = 0, gsave_level = 0;
1506
3.35k
    double width[2];
1507
1508
3.35k
    if (ctx->text.inside_CharProc == false)
1509
2.63k
        pdfi_set_warning(ctx, 0, NULL, W_PDF_NOTINCHARPROC, "pdfi_d0", NULL);
1510
1511
3.35k
    ctx->text.CharProc_d_type = pdf_type3_d0;
1512
1513
3.35k
    if (pdfi_count_stack(ctx) < 2) {
1514
872
        code = gs_note_error(gs_error_stackunderflow);
1515
872
        goto d0_error;
1516
872
    }
1517
1518
2.48k
    if (pdfi_type_of(ctx->stack_top[-1]) != PDF_INT && pdfi_type_of(ctx->stack_top[-1]) != PDF_REAL) {
1519
744
        code = gs_note_error(gs_error_typecheck);
1520
744
        goto d0_error;
1521
744
    }
1522
1.74k
    if (pdfi_type_of(ctx->stack_top[-2]) != PDF_INT && pdfi_type_of(ctx->stack_top[-2]) != PDF_REAL) {
1523
108
        code = gs_note_error(gs_error_typecheck);
1524
108
        goto d0_error;
1525
108
    }
1526
1.63k
    if(ctx->text.current_enum == NULL) {
1527
910
        code = gs_note_error(gs_error_undefined);
1528
910
        goto d0_error;
1529
910
    }
1530
1531
723
    if (pdfi_type_of(ctx->stack_top[-2]) == PDF_INT)
1532
723
        width[0] = (double)((pdf_num *)ctx->stack_top[-2])->value.i;
1533
0
    else
1534
0
        width[0] = ((pdf_num *)ctx->stack_top[-2])->value.d;
1535
723
    if (pdfi_type_of(ctx->stack_top[-1]) == PDF_INT)
1536
723
        width[1] = (double)((pdf_num *)ctx->stack_top[-1])->value.i;
1537
0
    else
1538
0
        width[1] = ((pdf_num *)ctx->stack_top[-1])->value.d;
1539
1540
723
    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
723
    if (ctx->text.current_enum == NULL) {
1550
0
        code = gs_note_error(gs_error_unknownerror);
1551
0
        goto d0_error;
1552
0
    }
1553
1554
723
    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
723
    if (ctx->pgs->level > gsave_level)
1573
0
        ctx->current_stream_save.gsave_level += ctx->pgs->level - gsave_level;
1574
1575
723
    if (code < 0)
1576
4
        goto d0_error;
1577
719
    pdfi_pop(ctx, 2);
1578
719
    return 0;
1579
1580
2.63k
d0_error:
1581
2.63k
    pdfi_clearstack(ctx);
1582
2.63k
    return code;
1583
723
}
1584
1585
int pdfi_d1(pdf_context *ctx)
1586
37.8k
{
1587
37.8k
    int code = 0, gsave_level;
1588
37.8k
    double wbox[6];
1589
1590
37.8k
    if (ctx->text.inside_CharProc == false)
1591
574
        pdfi_set_warning(ctx, 0, NULL, W_PDF_NOTINCHARPROC, "pdfi_d1", NULL);
1592
1593
37.8k
    ctx->text.CharProc_d_type = pdf_type3_d1;
1594
1595
37.8k
    code = pdfi_destack_reals(ctx, wbox, 6);
1596
37.8k
    if (code < 0)
1597
660
        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
37.2k
    gsave_level = ctx->pgs->level;
1607
1608
37.2k
    if (ctx->text.current_enum == NULL) {
1609
176
        code = gs_note_error(gs_error_unknownerror);
1610
176
        goto d1_error;
1611
176
    }
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
37.0k
    code = gs_text_setcachedevice(ctx->text.current_enum, wbox);
1637
37.0k
#endif
1638
1639
    /* See the comment immediately after gs_text_setcachedvice() in pdfi_d0 above */
1640
37.0k
    if (ctx->pgs->level > gsave_level)
1641
10.9k
        ctx->current_stream_save.gsave_level += ctx->pgs->level - gsave_level;
1642
1643
37.0k
    if (code < 0)
1644
23
        goto d1_error;
1645
37.0k
    return 0;
1646
1647
859
d1_error:
1648
859
    pdfi_clearstack(ctx);
1649
859
    return code;
1650
37.0k
}
1651
1652
int pdfi_Tf(pdf_context *ctx, pdf_dict *stream_dict, pdf_dict *page_dict)
1653
1.12M
{
1654
1.12M
    double point_size = 0;
1655
1.12M
    pdf_obj *point_arg = NULL;
1656
1.12M
    int code = 0;
1657
1.12M
    pdf_name *fontname = NULL;
1658
1659
1.12M
    if (pdfi_count_stack(ctx) < 2) {
1660
25.9k
        pdfi_clearstack(ctx);
1661
25.9k
        return_error(gs_error_stackunderflow);
1662
25.9k
    }
1663
1664
    /* Get refs to the args and pop them */
1665
1.09M
    point_arg = ctx->stack_top[-1];
1666
1.09M
    pdfi_countup(point_arg);
1667
1.09M
    fontname = (pdf_name *)ctx->stack_top[-2];
1668
1.09M
    pdfi_countup(fontname);
1669
1.09M
    pdfi_pop(ctx, 2);
1670
1671
    /* Get the point_size */
1672
1.09M
    code = pdfi_obj_to_real(ctx, point_arg, &point_size);
1673
1.09M
    if (code < 0)
1674
2.54k
        goto exit0;
1675
1676
1.09M
    code = pdfi_load_resource_font(ctx, stream_dict, page_dict, fontname, point_size);
1677
1678
    /* If we failed to load font, try to load an internal one */
1679
1.09M
    if (code != gs_error_Fatal && code < 0)
1680
368k
        code = pdfi_font_set_internal_name(ctx, fontname, point_size);
1681
1.09M
 exit0:
1682
1.09M
    pdfi_countdown(fontname);
1683
1.09M
    pdfi_countdown(point_arg);
1684
1.09M
    return code;
1685
1.09M
}
1686
1687
int pdfi_free_font(pdf_obj *font)
1688
546k
{
1689
546k
    pdf_font *f = (pdf_font *)font;
1690
1691
546k
    switch (f->pdfi_font_type) {
1692
12.7k
        case e_pdf_font_type0:
1693
12.7k
            return pdfi_free_font_type0((pdf_obj *)font);
1694
0
            break;
1695
480k
        case e_pdf_font_type1:
1696
480k
            return pdfi_free_font_type1((pdf_obj *)font);
1697
0
            break;
1698
9.88k
        case e_pdf_font_cff:
1699
9.88k
            return pdfi_free_font_cff((pdf_obj *)font);
1700
2.57k
        case e_pdf_font_type3:
1701
2.57k
            return pdfi_free_font_type3((pdf_obj *)font);
1702
0
            break;
1703
25.6k
        case e_pdf_font_truetype:
1704
25.6k
            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
13.8k
        case e_pdf_cidfont_type2:
1710
13.8k
            return pdfi_free_font_cidtype2((pdf_obj *)font);
1711
0
            break;
1712
1.40k
        case e_pdf_cidfont_type0:
1713
1.40k
            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
546k
    }
1721
0
    return 0;
1722
546k
}
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
17.9k
{
1728
17.9k
    uint esize = Encoding->size;
1729
17.9k
    uint best = esize / 3;  /* must match at least this many */
1730
17.9k
    int i, index, near_index = ENCODING_INDEX_UNKNOWN, code;
1731
1732
141k
    for (index = 0; index < NUM_KNOWN_REAL_ENCODINGS; ++index) {
1733
123k
        uint match = esize;
1734
1735
15.0M
        for (i = esize; --i >= 0;) {
1736
15.0M
            gs_const_string rstr;
1737
15.0M
            pdf_name *ename;
1738
1739
15.0M
            code = pdfi_array_get_type(ctx, Encoding, (uint64_t)i, PDF_NAME, (pdf_obj **)&ename);
1740
15.0M
            if (code < 0) {
1741
18
                return;
1742
18
            }
1743
1744
15.0M
            gs_c_glyph_name(gs_c_known_encode((gs_char)i, index), &rstr);
1745
15.0M
            if (rstr.size == ename->length &&
1746
7.13M
                !memcmp(rstr.data, ename->data, rstr.size)) {
1747
6.68M
                pdfi_countdown(ename);
1748
6.68M
                continue;
1749
6.68M
            }
1750
8.33M
            pdfi_countdown(ename);
1751
8.33M
            if (--match <= best) {
1752
92.0k
                break;
1753
92.0k
            }
1754
8.33M
        }
1755
123k
        if (match > best) {
1756
31.6k
            best = match;
1757
31.6k
            near_index = index;
1758
            /* If we have a perfect match, stop now. */
1759
31.6k
            if (best == esize)
1760
674
                break;
1761
31.6k
        }
1762
123k
    }
1763
17.9k
    if (best == esize) *ind = index;
1764
17.9k
    *near_ind = near_index;
1765
17.9k
}
1766
1767
static inline int pdfi_encoding_name_to_index(pdf_name *name)
1768
119k
{
1769
119k
    int ind = gs_error_undefined;
1770
119k
    if (pdfi_type_of(name) == PDF_NAME) {
1771
119k
        if (pdfi_name_is(name, "StandardEncoding")) {
1772
57.4k
            ind = ENCODING_INDEX_STANDARD;
1773
62.5k
        } else if (pdfi_name_is(name, "WinAnsiEncoding")) {
1774
52.3k
            ind = ENCODING_INDEX_WINANSI;
1775
52.3k
        }
1776
10.1k
        else if (pdfi_name_is(name, "MacRomanEncoding")) {
1777
9.74k
            ind = ENCODING_INDEX_MACROMAN;
1778
9.74k
        }
1779
396
        else if (pdfi_name_is(name, "MacExpertEncoding")) {
1780
32
            ind = ENCODING_INDEX_MACEXPERT;
1781
32
        }
1782
364
        else if (pdfi_name_is(name, "SymbolEncoding")) {
1783
0
            ind = ENCODING_INDEX_SYMBOL;
1784
0
        }
1785
364
        else if (pdfi_name_is(name, "DingbatsEncoding")) {
1786
0
            ind = ENCODING_INDEX_DINGBATS;
1787
0
        }
1788
119k
    }
1789
119k
    return ind;
1790
119k
}
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
116k
{
1798
116k
    int i, code = 0;
1799
116k
    unsigned char gs_encoding;
1800
116k
    gs_glyph temp;
1801
116k
    gs_const_string str;
1802
116k
    pdf_name *n = NULL;
1803
1804
116k
    if (pdfi_array_size(Encoding) < 256)
1805
0
        return gs_note_error(gs_error_rangecheck);
1806
1807
116k
    code = pdfi_encoding_name_to_index(name);
1808
116k
    if (code < 0)
1809
351
        return code;
1810
116k
    if (ind != NULL) *ind = (gs_encoding_index_t)code;
1811
116k
    gs_encoding = (unsigned char)code;
1812
116k
    code = 0;
1813
1814
29.9M
    for (i = 0;i<256;i++) {
1815
29.8M
        temp = gs_c_known_encode(i, gs_encoding);
1816
29.8M
        gs_c_glyph_name(temp, &str);
1817
29.8M
        code = pdfi_name_alloc(ctx, (byte *)str.data, str.size, (pdf_obj **)&n);
1818
29.8M
        if (code < 0)
1819
0
            return code;
1820
29.8M
        pdfi_countup(n);
1821
29.8M
        code = pdfi_array_put(ctx, Encoding, (uint64_t)i, (pdf_obj *)n);
1822
29.8M
        pdfi_countdown(n);
1823
29.8M
        if (code < 0)
1824
0
            return code;
1825
29.8M
    }
1826
116k
    return 0;
1827
116k
}
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
124k
{
1840
124k
    int code = 0, i;
1841
124k
    gs_encoding_index_t encoding_index = ENCODING_INDEX_UNKNOWN, nearest_encoding_index = ENCODING_INDEX_UNKNOWN;
1842
1843
124k
    code = pdfi_array_alloc(ctx, 256, (pdf_array **)Encoding);
1844
124k
    if (code < 0)
1845
0
        return code;
1846
124k
    pdfi_countup(*Encoding);
1847
1848
124k
    switch (pdfi_type_of(pdf_Encoding)) {
1849
105k
        case PDF_NAME:
1850
105k
            code = pdfi_build_Encoding(ctx, (pdf_name *)pdf_Encoding, (pdf_array *)*Encoding, &encoding_index);
1851
105k
            if (code < 0) {
1852
351
                pdfi_countdown(*Encoding);
1853
351
                *Encoding = NULL;
1854
351
                return code;
1855
351
            }
1856
105k
            nearest_encoding_index = encoding_index;
1857
105k
            break;
1858
18.4k
        case PDF_DICT:
1859
18.4k
        {
1860
18.4k
            pdf_name *n = NULL;
1861
18.4k
            pdf_array *a = NULL;
1862
18.4k
            pdf_obj *o = NULL;
1863
18.4k
            int offset = 0;
1864
18.4k
            bool b_e_known;
1865
1866
18.4k
            if (pdfi_type_of(pdf_Encoding) == PDF_DICT) {
1867
18.4k
                code = pdfi_dict_known(ctx, (pdf_dict *)pdf_Encoding, "BaseEncoding", &b_e_known);
1868
18.4k
                if (code < 0)
1869
0
                    b_e_known = false;
1870
18.4k
            }
1871
0
            else {
1872
0
                b_e_known = false;
1873
0
            }
1874
1875
18.4k
            if (b_e_known == false && font_Encoding != NULL && pdfi_type_of(font_Encoding) == PDF_ARRAY) {
1876
7.49k
                pdf_array *fenc = (pdf_array *)font_Encoding;
1877
1.92M
                for (i = 0; i < pdfi_array_size(fenc) && code >= 0; i++) {
1878
1.91M
                    code = pdfi_array_get(ctx, fenc, (uint64_t)i, &o);
1879
1.91M
                    if (code >= 0)
1880
1.91M
                        code = pdfi_array_put(ctx, (pdf_array *)*Encoding, (uint64_t)i, o);
1881
1.91M
                    pdfi_countdown(o);
1882
1.91M
                }
1883
7.49k
                if (code < 0) {
1884
0
                    pdfi_countdown(*Encoding);
1885
0
                    *Encoding = NULL;
1886
0
                    return code;
1887
0
                }
1888
7.49k
            }
1889
10.9k
            else {
1890
10.9k
                code = pdfi_dict_get(ctx, (pdf_dict *)pdf_Encoding, "BaseEncoding", (pdf_obj **)&n);
1891
10.9k
                if (code >= 0) {
1892
3.12k
                    if (pdfi_encoding_name_to_index(n) < 0) {
1893
13
                        pdfi_set_warning(ctx, 0, NULL, W_PDF_INVALID_FONT_BASEENC, "pdfi_create_Encoding", NULL);
1894
13
                        pdfi_countdown(n);
1895
13
                        n = NULL;
1896
13
                        code = gs_error_undefined;
1897
13
                    }
1898
3.11k
                    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
3.12k
                }
1902
1903
10.9k
                if (code < 0) {
1904
7.85k
                    code = pdfi_name_alloc(ctx, (byte *)"StandardEncoding", 16, (pdf_obj **)&n);
1905
7.85k
                    if (code < 0) {
1906
0
                        pdfi_countdown(*Encoding);
1907
0
                        *Encoding = NULL;
1908
0
                        return code;
1909
0
                    }
1910
7.85k
                    pdfi_countup(n);
1911
7.85k
                }
1912
1913
10.9k
                code = pdfi_build_Encoding(ctx, n, (pdf_array *)*Encoding, NULL);
1914
10.9k
                if (code < 0) {
1915
0
                    pdfi_countdown(*Encoding);
1916
0
                    *Encoding = NULL;
1917
0
                    pdfi_countdown(n);
1918
0
                    return code;
1919
0
                }
1920
10.9k
                pdfi_countdown(n);
1921
10.9k
            }
1922
18.4k
            code = pdfi_dict_knownget_type(ctx, (pdf_dict *)pdf_Encoding, "Differences", PDF_ARRAY, (pdf_obj **)&a);
1923
18.4k
            if (code <= 0) {
1924
406
                if (code < 0) {
1925
0
                    pdfi_countdown(*Encoding);
1926
0
                    *Encoding = NULL;
1927
0
                }
1928
406
                return code;
1929
406
            }
1930
1931
1.70M
            for (i=0;i < pdfi_array_size(a);i++) {
1932
1.68M
                pdf_obj_type type;
1933
1.68M
                code = pdfi_array_get(ctx, a, (uint64_t)i, &o);
1934
1.68M
                if (code < 0)
1935
8
                    break;
1936
1.68M
                type = pdfi_type_of(o);
1937
1.68M
                if (type == PDF_NAME) {
1938
1.52M
                    if (offset < pdfi_array_size((pdf_array *)*Encoding))
1939
1.52M
                        code = pdfi_array_put(ctx, (pdf_array *)*Encoding, (uint64_t)offset, o);
1940
1.52M
                    pdfi_countdown(o);
1941
1.52M
                    offset++;
1942
1.52M
                    if (code < 0)
1943
0
                        break;
1944
1.52M
                } else if (type == PDF_INT) {
1945
156k
                    offset = ((pdf_num *)o)->value.i;
1946
156k
                    pdfi_countdown(o);
1947
156k
                } else {
1948
68
                    code = gs_note_error(gs_error_typecheck);
1949
68
                    pdfi_countdown(o);
1950
68
                    break;
1951
68
                }
1952
1.68M
            }
1953
18.0k
            pdfi_countdown(a);
1954
18.0k
            if (code < 0) {
1955
76
                pdfi_countdown(*Encoding);
1956
76
                *Encoding = NULL;
1957
76
                return code;
1958
76
            }
1959
17.9k
            if (ppdffont != NULL) /* No sense doing this if we can't record the result */
1960
17.9k
                pdfi_gs_simple_font_encoding_indices(ctx, (pdf_array *)(*Encoding), &encoding_index, &nearest_encoding_index);
1961
17.9k
            break;
1962
18.0k
        }
1963
451
        default:
1964
451
            pdfi_countdown(*Encoding);
1965
451
            *Encoding = NULL;
1966
451
            return gs_note_error(gs_error_typecheck);
1967
124k
    }
1968
123k
    if (ppdffont != NULL) {
1969
75.9k
        ppdffont->pfont->encoding_index = encoding_index;
1970
75.9k
        ppdffont->pfont->nearest_encoding_index = nearest_encoding_index;
1971
75.9k
    }
1972
123k
    return 0;
1973
124k
}
1974
1975
gs_glyph pdfi_encode_char(gs_font * pfont, gs_char chr, gs_glyph_space_t not_used)
1976
61.4M
{
1977
61.4M
    int code;
1978
61.4M
    unsigned int nindex = 0;
1979
61.4M
    gs_glyph g = GS_NO_GLYPH;
1980
1981
61.4M
    if (pfont->FontType == ft_encrypted || pfont->FontType == ft_encrypted2
1982
568k
     || pfont->FontType == ft_user_defined || pfont->FontType == ft_TrueType
1983
568k
     || pfont->FontType == ft_MicroType
1984
61.4M
     || pfont->FontType == ft_PDF_user_defined) {
1985
61.4M
        pdf_font *font = (pdf_font *)pfont->client_data;
1986
61.4M
        pdf_context *ctx = (pdf_context *)font->ctx;
1987
1988
61.4M
        if (font->Encoding != NULL) { /* safety */
1989
61.4M
            pdf_name *GlyphName = NULL;
1990
61.4M
            code = pdfi_array_get(ctx, font->Encoding, (uint64_t)chr, (pdf_obj **)&GlyphName);
1991
61.4M
            if (code >= 0) {
1992
61.4M
                if (pdfi_type_of(GlyphName) != PDF_NAME)
1993
                    /* Can't signal an error, just return the 'not found' case */
1994
960
                    return g;
1995
1996
61.4M
                code = (*ctx->get_glyph_index)(pfont, (byte *)GlyphName->data, GlyphName->length, &nindex);
1997
61.4M
                pdfi_countdown(GlyphName);
1998
61.4M
                if (code >= 0)
1999
61.4M
                    g = (gs_glyph)nindex;
2000
61.4M
            }
2001
61.4M
        }
2002
61.4M
    }
2003
2004
61.4M
    return g;
2005
61.4M
}
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
6.80k
{
2013
6.80k
    int i;
2014
6.80k
    *decoding = NULL;
2015
6.80k
    *substnwp = NULL;
2016
    /* This only makes sense for Adobe orderings */
2017
6.80k
    if (reglen == 5 && !memcmp(reg, "Adobe", 5)) {
2018
36.6k
        for (i = 0; pdfi_cid_decoding_list[i] != NULL; i++) {
2019
30.6k
            if (strlen(pdfi_cid_decoding_list[i]->s_order) == ordlen &&
2020
601
                !memcmp(pdfi_cid_decoding_list[i]->s_order, ord, ordlen)) {
2021
245
                *decoding = (pdfi_cid_decoding_t *)pdfi_cid_decoding_list[i];
2022
245
                break;
2023
245
            }
2024
30.6k
        }
2025
        /* For now, also only for Adobe orderings */
2026
36.7k
        for (i = 0; pdfi_cid_substnwp_list[i] != NULL; i++) {
2027
30.7k
            if (strlen(pdfi_cid_substnwp_list[i]->ordering) == ordlen &&
2028
601
                !memcmp(pdfi_cid_substnwp_list[i]->ordering, ord, ordlen)) {
2029
245
                *substnwp = (pdfi_cid_subst_nwp_table_t *)pdfi_cid_substnwp_list[i];
2030
245
                break;
2031
245
            }
2032
30.7k
        }
2033
6.25k
    }
2034
6.80k
}
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
1.46M
{
2038
1.46M
    int i, l = 0;
2039
1.46M
    int code = gs_error_undefined;
2040
1.46M
    unsigned char *ucode = (unsigned char *)unicode_return;
2041
2042
1.46M
    if (tounicode != NULL) {
2043
347k
        gs_cmap_lookups_enum_t lenum;
2044
347k
        gs_cmap_lookups_enum_init((const gs_cmap_t *)tounicode->gscmap, 0, &lenum);
2045
8.31M
        while (l == 0 && gs_cmap_enum_next_lookup(ctx->memory, &lenum) == 0) {
2046
7.96M
            gs_cmap_lookups_enum_t counter = lenum;
2047
15.9M
            while (l == 0 && gs_cmap_enum_next_entry(&counter) == 0) {
2048
7.96M
                if (counter.entry.value_type == CODE_VALUE_CID) {
2049
7.96M
                    if (counter.entry.key_is_range) {
2050
1.40M
                        unsigned int v0 = 0, v1 = 0;
2051
3.28M
                        for (i = 0; i < counter.entry.key_size; i++) {
2052
1.88M
                            v0 |= (counter.entry.key[0][counter.entry.key_size - i - 1]) << (i * 8);
2053
1.88M
                        }
2054
3.28M
                        for (i = 0; i < counter.entry.key_size; i++) {
2055
1.88M
                            v1 |= (counter.entry.key[1][counter.entry.key_size - i - 1]) << (i * 8);
2056
1.88M
                        }
2057
2058
1.40M
                        if (ch >= v0 && ch <= v1) {
2059
150k
                            unsigned int offs = ch - v0;
2060
2061
150k
                            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
150k
                            else if (counter.entry.value.size == 2) {
2069
149k
                                l = 2;
2070
149k
                                if (ucode != NULL && length >= l) {
2071
119k
                                    ucode[0] = counter.entry.value.data[0] + ((offs >> 8) & 0xff);
2072
119k
                                    ucode[1] = counter.entry.value.data[1] + (offs & 0xff);
2073
119k
                                }
2074
149k
                            }
2075
1.29k
                            else if (counter.entry.value.size == 3) {
2076
20
                                l = 4;
2077
20
                                if (ucode != NULL && length >= l) {
2078
10
                                    ucode[0] = 0;
2079
10
                                    ucode[1] = counter.entry.value.data[0] + ((offs >> 16) & 0xff);
2080
10
                                    ucode[2] = counter.entry.value.data[1] + ((offs >> 8) & 0xff);
2081
10
                                    ucode[3] = counter.entry.value.data[2] + (offs & 0xff);
2082
10
                                }
2083
20
                            }
2084
1.27k
                            else {
2085
1.27k
                                l = 4;
2086
1.27k
                                if (ucode != NULL && length >= l) {
2087
1.27k
                                    ucode[0] = counter.entry.value.data[0] + ((offs >> 24) & 0xff);
2088
1.27k
                                    ucode[1] = counter.entry.value.data[1] + ((offs >> 16) & 0xff);
2089
1.27k
                                    ucode[2] = counter.entry.value.data[2] + ((offs >> 8) & 0xff);
2090
1.27k
                                    ucode[3] = counter.entry.value.data[3] + (offs & 0xff);
2091
1.27k
                                }
2092
1.27k
                            }
2093
150k
                        }
2094
1.40M
                    }
2095
6.56M
                    else {
2096
6.56M
                        unsigned int v = 0;
2097
18.9M
                        for (i = 0; i < counter.entry.key_size; i++) {
2098
12.4M
                            v |= (counter.entry.key[0][counter.entry.key_size - i - 1]) << (i * 8);
2099
12.4M
                        }
2100
6.56M
                        if (ch == v) {
2101
149k
                            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
149k
                            else if (counter.entry.value.size == 2) {
2109
148k
                                l = 2;
2110
148k
                                if (ucode != NULL && length >= l) {
2111
110k
                                    ucode[0] = counter.entry.value.data[0];
2112
110k
                                    ucode[1] = counter.entry.value.data[1];
2113
110k
                                }
2114
148k
                            }
2115
530
                            else if (counter.entry.value.size == 3) {
2116
51
                                l = 4;
2117
51
                                if (ucode != NULL && length >= l) {
2118
31
                                    ucode[0] = 0;
2119
31
                                    ucode[1] = counter.entry.value.data[0];
2120
31
                                    ucode[2] = counter.entry.value.data[1];
2121
31
                                    ucode[3] = counter.entry.value.data[2];
2122
31
                                }
2123
51
                            }
2124
479
                            else {
2125
479
                                l = 4;
2126
479
                                if (ucode != NULL && length >= l) {
2127
395
                                    ucode[0] = counter.entry.value.data[0];
2128
395
                                    ucode[1] = counter.entry.value.data[1];
2129
395
                                    ucode[2] = counter.entry.value.data[2];
2130
395
                                    ucode[3] = counter.entry.value.data[3];
2131
395
                                }
2132
479
                            }
2133
149k
                        }
2134
6.56M
                    }
2135
7.96M
                }
2136
7.96M
            }
2137
7.96M
        }
2138
347k
        if (l > 0)
2139
300k
            code = l;
2140
347k
    }
2141
2142
1.46M
    return code;
2143
1.46M
}
2144
2145
int
2146
pdfi_cidfont_decode_glyph(gs_font *font, gs_glyph glyph, int ch, ushort *u, unsigned int length)
2147
445k
{
2148
445k
    gs_glyph cc = glyph < GS_MIN_CID_GLYPH ? glyph : glyph - GS_MIN_CID_GLYPH;
2149
445k
    pdf_cidfont_t *pcidfont = (pdf_cidfont_t *)font->client_data;
2150
445k
    int code = gs_error_undefined, i;
2151
445k
    uchar *unicode_return = (uchar *)u;
2152
445k
    pdfi_cid_subst_nwp_table_t *substnwp = pcidfont->substnwp;
2153
2154
445k
    code = gs_error_undefined;
2155
448k
    while (1) { /* Loop to make retrying with a substitute CID easier */
2156
        /* Favour the ToUnicode if one exists */
2157
448k
        code = pdfi_tounicode_char_to_unicode(pcidfont->ctx, (pdf_cmap *)pcidfont->ToUnicode, glyph, ch, u, length);
2158
2159
448k
        if (code == gs_error_undefined && pcidfont->decoding) {
2160
10.4k
            const int *n;
2161
2162
10.4k
            if (cc / 256 < pcidfont->decoding->nranges) {
2163
10.2k
                n = (const int *)pcidfont->decoding->ranges[cc / 256][cc % 256];
2164
10.5k
                for (i = 0; i < pcidfont->decoding->val_sizes; i++) {
2165
10.5k
                    unsigned int cmapcc;
2166
10.5k
                    if (n[i] == -1)
2167
3.07k
                        break;
2168
7.48k
                    cc = n[i];
2169
7.48k
                    cmapcc = (unsigned int)cc;
2170
7.48k
                    if (pcidfont->pdfi_font_type == e_pdf_cidfont_type2)
2171
7.48k
                        code = pdfi_fapi_check_cmap_for_GID((gs_font *)pcidfont->pfont, (unsigned int)cc, &cmapcc);
2172
0
                    else
2173
0
                        code = 0;
2174
7.48k
                    if (code >= 0 && cmapcc != 0){
2175
7.19k
                        code = 0;
2176
7.19k
                        break;
2177
7.19k
                    }
2178
7.48k
                }
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
10.2k
                if (code < 0 && n[0] != -1) {
2183
0
                    cc = n[0];
2184
0
                    code = 0;
2185
0
                }
2186
10.2k
            }
2187
10.4k
            if (code >= 0) {
2188
7.19k
                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
7.19k
                else {
2198
7.19k
                    code = 2;
2199
7.19k
                    if (unicode_return != NULL && length >= code) {
2200
3.43k
                        unicode_return[0] = (cc & 0x0000FF00) >> 8;
2201
3.43k
                        unicode_return[1] = (cc & 0x000000FF);
2202
3.43k
                    }
2203
7.19k
                }
2204
7.19k
            }
2205
10.4k
        }
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
448k
        if (code == gs_error_undefined && substnwp) {
2211
6.47k
            for (i = 0; substnwp->subst[i].s_type != 0; i++ ) {
2212
6.13k
                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
6.13k
                if (cc >= substnwp->subst[i].s_dcid
2218
5.65k
                 && cc <= substnwp->subst[i].s_dcid + (substnwp->subst[i].e_scid - substnwp->subst[i].s_scid)) {
2219
2.91k
                    cc = substnwp->subst[i].s_scid + (cc - substnwp->subst[i].s_dcid);
2220
2.91k
                    substnwp = NULL;
2221
2.91k
                    break;
2222
2.91k
                }
2223
6.13k
            }
2224
3.25k
            if (substnwp == NULL)
2225
2.91k
                continue;
2226
3.25k
        }
2227
445k
        break;
2228
448k
    }
2229
445k
    return (code < 0 ? 0 : code);
2230
445k
}
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
468k
{
2236
468k
    pdf_font *pdffont = (pdf_font *)font->client_data;
2237
468k
    int code = 0;
2238
2239
468k
    if (pdffont->pdfi_font_type != e_pdf_cidfont_type0 && pdffont->pdfi_font_type != e_pdf_cidfont_type1
2240
467k
     && pdffont->pdfi_font_type != e_pdf_cidfont_type2 && pdffont->pdfi_font_type != e_pdf_cidfont_type4) {
2241
467k
        code = pdfi_tounicode_char_to_unicode(pdffont->ctx, (pdf_cmap *)pdffont->ToUnicode, glyph, ch, unicode_return, length);
2242
467k
    }
2243
468k
    if (code < 0) code = 0;
2244
2245
468k
    return code;
2246
468k
}
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
3
{
2276
3
    int code = 0;
2277
3
    if (pfont->FontType == ft_encrypted) {
2278
1
        code = pdfi_t1_global_glyph_code(pfont, gstr, pglyph);
2279
1
    }
2280
2
    else if (pfont->FontType == ft_encrypted2) {
2281
2
        code = pdfi_cff_global_glyph_code(pfont, gstr, pglyph);
2282
2
    }
2283
0
    else {
2284
0
        code = gs_note_error(gs_error_invalidaccess);
2285
0
    }
2286
3
    return code;
2287
3
}
2288
2289
int pdfi_map_glyph_name_via_agl(pdf_dict *cstrings, pdf_name *gname, pdf_string **cstring)
2290
342k
{
2291
342k
    single_glyph_list_t *sgl = (single_glyph_list_t *)&(SingleGlyphList);
2292
342k
    int i, code, ucode = gs_error_undefined;
2293
342k
    *cstring = NULL;
2294
2295
342k
    if (gname->length == 7 && strncmp((char *)gname->data, "uni", 3) == 0) {
2296
3.26k
        char u[5] = {0};
2297
3.26k
        memcpy(u, gname->data + 3, 4);
2298
3.26k
        code = sscanf(u, "%x", &ucode);
2299
3.26k
        if (code <= 0)
2300
0
            ucode = gs_error_undefined;
2301
3.26k
    }
2302
2303
342k
    if (ucode == gs_error_undefined) {
2304
1.29G
        for (i = 0; sgl[i].Glyph != 0x00; i++) {
2305
1.29G
            if (sgl[i].Glyph[0] == gname->data[0]
2306
29.1M
                && strlen(sgl[i].Glyph) == gname->length
2307
419k
                && !strncmp((char *)sgl[i].Glyph, (char *)gname->data, gname->length)) {
2308
78.7k
                ucode = (int)sgl[i].Unicode;
2309
78.7k
                break;
2310
78.7k
            }
2311
1.29G
        }
2312
338k
    }
2313
342k
    if (ucode > 0) {
2314
339M
        for (i = 0; sgl[i].Glyph != 0x00; i++) {
2315
339M
            if (sgl[i].Unicode == (unsigned short)ucode) {
2316
84.5k
                pdf_string *s;
2317
84.5k
                code = pdfi_dict_get((pdf_context *)cstrings->ctx, cstrings, (char *)sgl[i].Glyph, (pdf_obj **)&s);
2318
84.5k
                if (code >= 0) {
2319
2.61k
                    *cstring = s;
2320
2.61k
                    break;
2321
2.61k
                }
2322
84.5k
            }
2323
339M
        }
2324
82.0k
        if (*cstring == NULL) {
2325
79.4k
            char u[16] = {0};
2326
79.4k
            code = gs_snprintf(u, 16, "uni%04x", ucode);
2327
79.4k
            if (code > 0) {
2328
79.4k
                pdf_string *s;
2329
79.4k
                code = pdfi_dict_get((pdf_context *)cstrings->ctx, cstrings, u, (pdf_obj **)&s);
2330
79.4k
                if (code >= 0) {
2331
5
                    *cstring = s;
2332
5
                }
2333
79.4k
            }
2334
79.4k
        }
2335
82.0k
    }
2336
2337
342k
    if (*cstring == NULL)
2338
339k
        code = gs_note_error(gs_error_undefined);
2339
2.61k
    else
2340
2.61k
        code = 0;
2341
2342
342k
    return code;
2343
342k
}
2344
2345
2346
int pdfi_init_font_directory(pdf_context *ctx)
2347
94.5k
{
2348
94.5k
    gs_font_dir *pfdir = ctx->memory->gs_lib_ctx->font_dir;
2349
94.5k
    if (pfdir) {
2350
85.6k
        ctx->font_dir = gs_font_dir_alloc2_limits(ctx->memory, ctx->memory,
2351
85.6k
                   pfdir->smax, pfdir->ccache.bmax, pfdir->fmcache.mmax,
2352
85.6k
                   pfdir->ccache.cmax, pfdir->ccache.upper);
2353
85.6k
        if (ctx->font_dir == NULL) {
2354
0
            return_error(gs_error_VMerror);
2355
0
        }
2356
85.6k
        ctx->font_dir->align_to_pixels = pfdir->align_to_pixels;
2357
85.6k
        ctx->font_dir->grid_fit_tt = pfdir->grid_fit_tt;
2358
85.6k
    }
2359
8.97k
    else {
2360
8.97k
        ctx->font_dir = gs_font_dir_alloc2(ctx->memory, ctx->memory);
2361
8.97k
        if (ctx->font_dir == NULL) {
2362
0
            return_error(gs_error_VMerror);
2363
0
        }
2364
8.97k
    }
2365
94.5k
    ctx->font_dir->global_glyph_code = pdfi_global_glyph_code;
2366
94.5k
    return 0;
2367
94.5k
}
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
383k
{
2375
383k
    pdf_obj *fname = NULL;
2376
383k
    pdf_obj *fontobjtype = NULL;
2377
383k
    pdf_dict *fdict = NULL;
2378
383k
    int code;
2379
383k
    gs_font *pgsfont = NULL;
2380
383k
    const char *fs = "Font";
2381
383k
    pdf_name *Type1Name = NULL;
2382
2383
383k
    code = pdfi_name_alloc(ctx, (byte *)fontname, length, &fname);
2384
383k
    if (code < 0)
2385
0
        return code;
2386
383k
    pdfi_countup(fname);
2387
2388
383k
    code = pdfi_name_alloc(ctx, (byte *)fs, strlen(fs), &fontobjtype);
2389
383k
    if (code < 0)
2390
0
        goto exit;
2391
383k
    pdfi_countup(fontobjtype);
2392
2393
383k
    code = pdfi_dict_alloc(ctx, 1, &fdict);
2394
383k
    if (code < 0)
2395
0
        goto exit;
2396
383k
    pdfi_countup(fdict);
2397
2398
383k
    code = pdfi_dict_put(ctx, fdict, "BaseFont", fname);
2399
383k
    if (code < 0)
2400
0
        goto exit;
2401
2402
383k
    code = pdfi_dict_put(ctx, fdict, "Type", fontobjtype);
2403
383k
    if (code < 0)
2404
0
        goto exit;
2405
2406
383k
    code = pdfi_obj_charstr_to_name(ctx, "Type1", &Type1Name);
2407
383k
    if (code < 0)
2408
0
        goto exit;
2409
2410
383k
    code = pdfi_dict_put(ctx, fdict, "Subtype", (pdf_obj *)Type1Name);
2411
383k
    if (code < 0)
2412
0
        goto exit;
2413
2414
383k
    code = pdfi_load_font(ctx, NULL, NULL, fdict, &pgsfont, false);
2415
383k
    if (code < 0)
2416
0
        goto exit;
2417
2418
383k
    *ppdffont = (pdf_obj *)pgsfont->client_data;
2419
2420
383k
 exit:
2421
383k
    pdfi_countdown(Type1Name);
2422
383k
    pdfi_countdown(fontobjtype);
2423
383k
    pdfi_countdown(fname);
2424
383k
    pdfi_countdown(fdict);
2425
383k
    return code;
2426
383k
}
2427
2428
2429
int pdfi_font_create_widths(pdf_context *ctx, pdf_dict *fontdict, pdf_font *font, double scale)
2430
469k
{
2431
469k
    int code = 0;
2432
469k
    pdf_obj *obj = NULL;
2433
469k
    int i;
2434
2435
469k
    font->Widths = NULL;
2436
2437
469k
    if (font->FontDescriptor != NULL) {
2438
64.6k
        code = pdfi_dict_knownget(ctx, font->FontDescriptor, "MissingWidth", &obj);
2439
64.6k
        if (code > 0) {
2440
5.44k
            if (pdfi_type_of(obj) == PDF_INT) {
2441
5.44k
                font->MissingWidth = ((pdf_num *) obj)->value.i * scale;
2442
5.44k
            }
2443
1
            else if (pdfi_type_of(obj) == PDF_REAL) {
2444
1
                font->MissingWidth = ((pdf_num *) obj)->value.d  * scale;
2445
1
            }
2446
0
            else {
2447
0
                font->MissingWidth = 0;
2448
0
            }
2449
5.44k
            pdfi_countdown(obj);
2450
5.44k
            obj = NULL;
2451
5.44k
        }
2452
59.2k
        else {
2453
59.2k
            font->MissingWidth = 0;
2454
59.2k
        }
2455
64.6k
    }
2456
405k
    else {
2457
405k
        font->MissingWidth = 0;
2458
405k
    }
2459
2460
469k
    code = pdfi_dict_knownget_type(ctx, fontdict, "Widths", PDF_ARRAY, (pdf_obj **)&obj);
2461
469k
    if (code > 0) {
2462
68.9k
        if (pdfi_array_size((pdf_array *)obj) < font->LastChar - font->FirstChar + 1) {
2463
2.13k
            code = gs_note_error(gs_error_rangecheck);
2464
2.13k
            goto error;
2465
2.13k
        }
2466
2467
66.8k
        font->Widths = (double *)gs_alloc_bytes(OBJ_MEMORY(font), (size_t)sizeof(double) * (font->LastChar - font->FirstChar + 1), "pdfi_font_create_widths(Widths)");
2468
66.8k
        if (font->Widths == NULL) {
2469
0
            code = gs_note_error(gs_error_VMerror);
2470
0
            goto error;
2471
0
        }
2472
66.8k
        memset(font->Widths, 0x00, sizeof(double) * (font->LastChar - font->FirstChar + 1));
2473
6.84M
        for (i = 0; i < (font->LastChar - font->FirstChar + 1); i++) {
2474
6.77M
            code = pdfi_array_get_number(ctx, (pdf_array *)obj, (uint64_t)i, &font->Widths[i]);
2475
6.77M
            if (code < 0)
2476
236
                goto error;
2477
6.77M
            font->Widths[i] *= scale;
2478
6.77M
        }
2479
66.8k
    }
2480
469k
error:
2481
469k
    pdfi_countdown(obj);
2482
469k
    if (code < 0) {
2483
5.45k
        gs_free_object(OBJ_MEMORY(font), font->Widths, "pdfi_font_create_widths(Widths)");
2484
5.45k
        font->Widths = NULL;
2485
5.45k
    }
2486
469k
    return code;
2487
469k
}
2488
2489
void pdfi_font_set_first_last_char(pdf_context *ctx, pdf_dict *fontdict, pdf_font *font)
2490
515k
{
2491
515k
    double f, l;
2492
515k
    int code;
2493
2494
515k
    if (fontdict == NULL) {
2495
45.4k
        f = (double)0;
2496
45.4k
        l = (double)255;
2497
45.4k
    }
2498
469k
    else {
2499
469k
        code = pdfi_dict_get_number(ctx, fontdict, "FirstChar", &f);
2500
469k
        if (code < 0 || f < 0 || f > 255)
2501
397k
            f = (double)0;
2502
2503
469k
        code = pdfi_dict_get_number(ctx, fontdict, "LastChar", &l);
2504
469k
        if (code < 0 || l < 0 || l > 255)
2505
397k
            l = (double)255;
2506
469k
    }
2507
515k
    if (f <= l) {
2508
515k
        font->FirstChar = (int)f;
2509
515k
        font->LastChar = (int)l;
2510
515k
    }
2511
52
    else {
2512
52
        font->FirstChar = 0;
2513
52
        font->LastChar = 255;
2514
52
    }
2515
515k
}
2516
2517
void pdfi_font_set_orig_fonttype(pdf_context *ctx, pdf_font *font)
2518
522k
{
2519
522k
    pdf_name *ftype;
2520
522k
    pdf_dict *fontdict = font->PDF_font;
2521
522k
    int code;
2522
2523
522k
    code = pdfi_dict_get_type(ctx, fontdict, "Subtype", PDF_NAME, (pdf_obj**)&ftype);
2524
522k
    if (code < 0) {
2525
46.0k
        font->orig_FontType = ft_undefined;
2526
46.0k
    }
2527
476k
    else {
2528
476k
        if (pdfi_name_is(ftype, "Type1") || pdfi_name_is(ftype, "MMType1"))
2529
419k
            font->orig_FontType = ft_encrypted;
2530
56.8k
        else if (pdfi_name_is(ftype, "Type1C"))
2531
0
            font->orig_FontType = ft_encrypted2;
2532
56.8k
        else if (pdfi_name_is(ftype, "TrueType"))
2533
40.6k
            font->orig_FontType = ft_TrueType;
2534
16.2k
        else if (pdfi_name_is(ftype, "Type3"))
2535
2.08k
            font->orig_FontType = ft_user_defined;
2536
14.1k
        else if (pdfi_name_is(ftype, "CIDFontType0"))
2537
2.50k
            font->orig_FontType = ft_CID_encrypted;
2538
11.6k
        else if (pdfi_name_is(ftype, "CIDFontType2"))
2539
10.9k
            font->orig_FontType = ft_CID_TrueType;
2540
665
        else
2541
665
            font->orig_FontType = ft_undefined;
2542
476k
    }
2543
522k
    pdfi_countdown(ftype);
2544
522k
}
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
90.4k
{
2555
90.4k
    gs_const_string fn;
2556
90.4k
    int i;
2557
90.4k
    uint32_t hash = 0;
2558
90.4k
    long *xvalues;
2559
90.4k
    int xuidlen = 3;
2560
2561
90.4k
    sfilename(ctx->main_stream->s, &fn);
2562
90.4k
    if (fontdict!= NULL && fontdict->object_num != 0) {
2563
39.8k
        const byte *sb;
2564
39.8k
        size_t l;
2565
39.8k
        if (fn.size > 0) {
2566
0
            sb = fn.data;
2567
0
            l = fn.size;
2568
0
        }
2569
39.8k
        else {
2570
39.8k
            s_process_read_buf(ctx->main_stream->s);
2571
39.8k
            sb = sbufptr(ctx->main_stream->s);
2572
39.8k
            l = sbufavailable(ctx->main_stream->s) > 128 ? 128: sbufavailable(ctx->main_stream->s);
2573
39.8k
        }
2574
2575
5.14M
        for (i = 0; i < l; i++) {
2576
5.10M
            hash = ((((hash & 0xf8000000) >> 27) ^ (hash << 5)) & 0x7ffffffff) ^ sb[i];
2577
5.10M
        }
2578
39.8k
        hash = ((((hash & 0xf8000000) >> 27) ^ (hash << 5)) & 0x7ffffffff) ^ fontdict->object_num;
2579
2580
39.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
371
             uid_XUID_values(&pfont->UID)[1] = hash;
2585
371
             uid_XUID_values(&pfont->UID)[2] = ctx->device_state.HighLevelDevice ? fontdict->object_num : 0;
2586
371
        }
2587
39.5k
        else {
2588
39.5k
            if (uid_is_XUID(&pfont->UID))
2589
1.62k
                xuidlen += uid_XUID_size(&pfont->UID);
2590
37.8k
            else if (uid_is_valid(&pfont->UID))
2591
592
                xuidlen++;
2592
2593
39.5k
            xvalues = (long *)gs_alloc_bytes(pfont->memory, (size_t)xuidlen * sizeof(long), "pdfi_font_generate_pseudo_XUID");
2594
39.5k
            if (xvalues == NULL) {
2595
0
                return 0;
2596
0
            }
2597
39.5k
            xvalues[0] = 1000000; /* "Private" value */
2598
39.5k
            xvalues[1] = hash;
2599
2600
39.5k
            xvalues[2] = ctx->device_state.HighLevelDevice ? fontdict->object_num : 0;
2601
2602
39.5k
            if (uid_is_XUID(&pfont->UID)) {
2603
10.1k
                for (i = 0; i < uid_XUID_size(&pfont->UID); i++) {
2604
8.51k
                    xvalues[i + 3] = uid_XUID_values(&pfont->UID)[i];
2605
8.51k
                }
2606
1.62k
                uid_free(&pfont->UID, pfont->memory, "pdfi_font_generate_pseudo_XUID");
2607
1.62k
            }
2608
37.8k
            else if (uid_is_valid(&pfont->UID))
2609
592
                xvalues[3] = pfont->UID.id;
2610
2611
39.5k
            uid_set_XUID(&pfont->UID, xvalues, xuidlen);
2612
39.5k
        }
2613
39.8k
    }
2614
90.4k
    return 0;
2615
90.4k
}
2616
2617
int pdfi_default_font_info(gs_font *font, const gs_point *pscale, int members, gs_font_info_t *info)
2618
88.0k
{
2619
88.0k
    pdf_font *pdff = (pdf_font *)font->client_data;
2620
88.0k
    int code;
2621
2622
    /* We *must* call this first as it sets info->members = 0; */
2623
88.0k
    code = pdff->default_font_info(font, pscale, members, info);
2624
88.0k
    if (code < 0)
2625
4.71k
        return code;
2626
83.3k
    if ((members & FONT_INFO_EMBEDDED) != 0) {
2627
83.3k
        info->orig_FontType = pdff->orig_FontType;
2628
83.3k
        if (pdff->pdfi_font_type == e_pdf_font_type3) {
2629
630
            info->FontEmbedded = (int)(true);
2630
630
            info->members |= FONT_INFO_EMBEDDED;
2631
630
        }
2632
82.6k
        else {
2633
82.6k
            info->FontEmbedded = (int)(pdff->substitute == font_embedded);
2634
82.6k
            info->members |= FONT_INFO_EMBEDDED;
2635
82.6k
        }
2636
83.3k
    }
2637
83.3k
    if (pdff->pdfi_font_type != e_pdf_font_truetype && pdff->pdfi_font_type != e_pdf_cidfont_type2) {
2638
50.4k
        if (((members & FONT_INFO_COPYRIGHT) != 0) && pdff->copyright != NULL) {
2639
30.7k
            info->Copyright.data = pdff->copyright->data;
2640
30.7k
            info->Copyright.size = pdff->copyright->length;
2641
30.7k
            info->members |= FONT_INFO_COPYRIGHT;
2642
30.7k
        }
2643
50.4k
        if (((members & FONT_INFO_NOTICE) != 0) && pdff->notice != NULL) {
2644
31.9k
            info->Notice.data = pdff->notice->data;
2645
31.9k
            info->Notice.size = pdff->notice->length;
2646
31.9k
            info->members |= FONT_INFO_NOTICE;
2647
31.9k
        }
2648
50.4k
        if (((members & FONT_INFO_FAMILY_NAME) != 0) && pdff->familyname != NULL) {
2649
31.9k
            info->FamilyName.data = pdff->familyname->data;
2650
31.9k
            info->FamilyName.size = pdff->familyname->length;
2651
31.9k
            info->members |= FONT_INFO_FAMILY_NAME;
2652
31.9k
        }
2653
50.4k
        if (((members & FONT_INFO_FULL_NAME) != 0) && pdff->fullname != NULL) {
2654
31.9k
            info->FullName.data = pdff->fullname->data;
2655
31.9k
            info->FullName.size = pdff->fullname->length;
2656
31.9k
            info->members |= FONT_INFO_FULL_NAME;
2657
31.9k
        }
2658
50.4k
    }
2659
83.3k
    return 0;
2660
88.0k
}
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
383k
{
2667
383k
    int code;
2668
383k
    pdf_font *pdffont = (pdf_font *)fontobj;
2669
2670
383k
    if (pdfi_type_of(pdffont) != PDF_FONT || pdffont->pfont == NULL)
2671
0
        return_error(gs_error_invalidfont);
2672
2673
383k
    code = gs_setPDFfontsize(ctx->pgs, point_size);
2674
383k
    if (code < 0)
2675
0
        return code;
2676
2677
383k
    return pdfi_gs_setfont(ctx, (gs_font *)pdffont->pfont);
2678
383k
}
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
383k
{
2686
383k
    int code = 0;
2687
383k
    pdf_obj *font = NULL;
2688
2689
2690
383k
    code = pdfi_load_font_by_name_string(ctx, fontname, length, &font);
2691
383k
    if (code < 0) goto exit;
2692
2693
383k
    code = pdfi_set_font_internal(ctx, font, point_size);
2694
2695
383k
 exit:
2696
383k
    pdfi_countdown(font);
2697
383k
    return code;
2698
383k
}
2699
2700
int pdfi_font_set_internal_string(pdf_context *ctx, const char *fontname, double point_size)
2701
15.0k
{
2702
15.0k
    return pdfi_font_set_internal_inner(ctx, (const byte *)fontname, strlen(fontname), point_size);
2703
15.0k
}
2704
2705
int pdfi_font_set_internal_name(pdf_context *ctx, pdf_name *fontname, double point_size)
2706
368k
{
2707
368k
    if (pdfi_type_of(fontname) != PDF_NAME)
2708
0
        return_error(gs_error_typecheck);
2709
368k
    else
2710
368k
        return pdfi_font_set_internal_inner(ctx, fontname->data, fontname->length, point_size);
2711
368k
}