Coverage Report

Created: 2026-09-14 07:34

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ghostpdl/pdf/pdf_font.c
Line
Count
Source
1
/* Copyright (C) 2018-2026 Artifex Software, Inc.
2
   All Rights Reserved.
3
4
   This software is provided AS-IS with no warranty, either express or
5
   implied.
6
7
   This software is distributed under license and may not be copied,
8
   modified or distributed except as expressly authorized under the terms
9
   of the license contained in the file LICENSE in this distribution.
10
11
   Refer to licensing information at http://www.artifex.com or contact
12
   Artifex Software, Inc.,  39 Mesa Street, Suite 108A, San Francisco,
13
   CA 94129, USA, for further information.
14
*/
15
16
/* Font operations for the PDF interpreter */
17
18
#include "pdf_int.h"
19
#include "pdf_font_types.h"
20
#include "pdf_gstate.h"
21
#include "pdf_file.h"
22
#include "pdf_dict.h"
23
#include "pdf_loop_detect.h"
24
#include "pdf_array.h"
25
#include "pdf_font.h"
26
#include "pdf_stack.h"
27
#include "pdf_misc.h"
28
#include "pdf_doc.h"
29
#include "pdf_font0.h"
30
#include "pdf_font1.h"
31
#include "pdf_font1C.h"
32
#include "pdf_font3.h"
33
#include "pdf_fontTT.h"
34
#include "pdf_fontmt.h"
35
#include "pdf_font0.h"
36
#include "pdf_fmap.h"
37
#include "gscencs.h"            /* For gs_c_known_encode and gs_c_glyph_name */
38
#include "gsagl.h"
39
40
#include "strmio.h"
41
#include "stream.h"
42
#include "gsstate.h"            /* For gs_setPDFfontsize() */
43
44
extern single_glyph_list_t SingleGlyphList[];
45
46
static int pdfi_gs_setfont(pdf_context *ctx, gs_font *pfont)
47
1.00M
{
48
1.00M
    int code = 0;
49
1.00M
    pdfi_int_gstate *igs = (pdfi_int_gstate *)ctx->pgs->client_data;
50
1.00M
    pdf_font *old_font = igs->current_font;
51
52
1.00M
    code = gs_setfont(ctx->pgs, pfont);
53
1.00M
    if (code >= 0) {
54
1.00M
        igs->current_font = (pdf_font *)pfont->client_data;
55
1.00M
        pdfi_countup(igs->current_font);
56
1.00M
        pdfi_countdown(old_font);
57
1.00M
    }
58
1.00M
    return code;
59
1.00M
}
60
61
static void pdfi_cache_resource_font(pdf_context *ctx, pdf_obj *fontdesc, pdf_obj *ppdffont)
62
26.9k
{
63
26.9k
    resource_font_cache_t *entry = NULL;
64
26.9k
    int i;
65
66
26.9k
    if (ctx->resource_font_cache == NULL) {
67
16.3k
        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
16.3k
        if (ctx->resource_font_cache == NULL)
69
0
            return;
70
16.3k
        ctx->resource_font_cache_size = RESOURCE_FONT_CACHE_BLOCK_SIZE;
71
16.3k
        memset(ctx->resource_font_cache, 0x00, RESOURCE_FONT_CACHE_BLOCK_SIZE * sizeof(pdfi_name_entry_t));
72
16.3k
        entry = &ctx->resource_font_cache[0];
73
16.3k
    }
74
75
74.4k
    for (i = 0; entry == NULL && i < ctx->resource_font_cache_size; i++) {
76
47.4k
        if (ctx->resource_font_cache[i].pdffont == NULL) {
77
10.6k
            entry = &ctx->resource_font_cache[i];
78
10.6k
        }
79
36.8k
        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
47.4k
    }
89
26.9k
    if (entry != NULL) {
90
26.9k
        entry->desc_obj_num = fontdesc->object_num;
91
26.9k
        entry->pdffont = ppdffont;
92
26.9k
        pdfi_countup(ppdffont);
93
26.9k
    }
94
26.9k
}
95
96
void pdfi_purge_cache_resource_font(pdf_context *ctx)
97
92.4k
{
98
92.4k
    int i;
99
615k
    for (i = 0; i < ctx->resource_font_cache_size; i++) {
100
522k
       pdfi_countdown(ctx->resource_font_cache[i].pdffont);
101
522k
    }
102
92.4k
    gs_free_object(ctx->memory, ctx->resource_font_cache, "pdfi_purge_cache_resource_font");
103
92.4k
    ctx->resource_font_cache = NULL;
104
92.4k
    ctx->resource_font_cache_size = 0;
105
92.4k
}
106
107
static int pdfi_find_cache_resource_font(pdf_context *ctx, pdf_obj *fontdesc, pdf_obj **ppdffont)
108
55.4k
{
109
55.4k
    int i, code = gs_error_undefined;
110
572k
    for (i = 0; i < ctx->resource_font_cache_size; i++) {
111
520k
        if (ctx->resource_font_cache[i].desc_obj_num == fontdesc->object_num) {
112
3.30k
           *ppdffont = ctx->resource_font_cache[i].pdffont;
113
3.30k
           pdfi_countup(*ppdffont);
114
3.30k
           code = 0;
115
3.30k
           break;
116
3.30k
        }
117
520k
    }
118
55.4k
    return code;
119
55.4k
}
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
525k
{
141
525k
    bool ignore = false;
142
525k
    int i;
143
525k
    pdf_name *nm = (pdf_name *)basefont;
144
145
525k
    if (basefont != NULL && pdfi_type_of(basefont) == PDF_NAME) {
146
2.39M
        for (i = 0; known_symbolic_font_names[i].name != NULL; i++) {
147
1.92M
            if (nm->length == known_symbolic_font_names[i].namelen
148
17.3k
             && !strncmp((char *)nm->data, known_symbolic_font_names[i].name, nm->length)) {
149
1.88k
                ignore = true;
150
1.88k
                break;
151
1.88k
            }
152
1.92M
        }
153
480k
    }
154
525k
    return ignore;
155
525k
}
156
157
static int
158
pdfi_font_match_glyph_widths(pdf_font *pdfont)
159
432k
{
160
432k
    int code = 0;
161
432k
    int i;
162
432k
    int sindex, lindex;
163
432k
    gs_font_base *pbfont = pdfont->pfont;
164
432k
    double fw = 0.0, ww = 0.0;
165
166
432k
    if (pdfont->LastChar <  pdfont->FirstChar || pdfont->Widths == NULL)
167
411k
        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
21.8k
    sindex = pdfont->FirstChar < 96 ? 96 : pdfont->FirstChar;
171
21.8k
    lindex = pdfont->LastChar > 122 ? 123 : pdfont->LastChar + 1;
172
173
380k
    for (i = sindex; i < lindex; i++) {
174
358k
        gs_glyph_info_t ginfo = {0};
175
358k
        gs_glyph g;
176
358k
        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
358k
        if (g != GS_NO_GLYPH && pdfont->Widths[i - pdfont->FirstChar] != 0.0
180
267k
          && (*pbfont->procs.glyph_info)((gs_font *)pbfont, g, NULL, GLYPH_INFO_WIDTH0, &ginfo) >= 0) {
181
266k
            fw += hypot(ginfo.width[0].x, ginfo.width[0].y);
182
266k
            ww += pdfont->Widths[i - pdfont->FirstChar];
183
266k
        }
184
358k
    }
185
    /* Only reduce font width, don't expand */
186
21.8k
    if (ww != 0.0 && fw != 0.0 && ww / fw < 1.0) {
187
6.78k
        gs_matrix nmat, smat = {1.0, 0.0, 0.0, 1.0, 0.0, 0.0};
188
6.78k
        double wscale;
189
6.78k
        smat.xx = smat.yy = ww/fw;
190
6.78k
        wscale = 1.0 / smat.xx;
191
192
6.78k
        gs_matrix_multiply(&pbfont->FontMatrix, &smat, &nmat);
193
6.78k
        memcpy(&pbfont->FontMatrix, &nmat, sizeof(pbfont->FontMatrix));
194
195
844k
        for (i = pdfont->FirstChar; i <= pdfont->LastChar; i++) {
196
837k
            pdfont->Widths[i - pdfont->FirstChar] *= wscale;
197
837k
        }
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
6.78k
        code = gs_purge_font((gs_font *)pbfont);
207
6.78k
        if (code >= 0)
208
6.78k
            code = gs_definefont(pbfont->dir, (gs_font *)pbfont);
209
6.78k
        if (code >= 0)
210
6.78k
            code = pdfi_fapi_passfont((pdf_font *)pdfont, 0, NULL, NULL, NULL, 0);
211
6.78k
    }
212
213
21.8k
    return code;
214
432k
}
215
216
/* Print a name object to stdout */
217
static void pdfi_print_font_name(pdf_context *ctx, pdf_name *n)
218
459k
{
219
459k
    if (ctx->args.QUIET != true)
220
0
        (void)outwrite(ctx->memory, (const char *)n->data, n->length);
221
459k
}
222
223
static void pdfi_print_font_string(pdf_context *ctx, pdf_string *s)
224
448k
{
225
448k
    if (ctx->args.QUIET != true)
226
0
        (void)outwrite(ctx->memory, (const char *)s->data, s->length);
227
448k
}
228
229
/* Print a null terminated string to stdout */
230
static void pdfi_print_cstring(pdf_context *ctx, const char *str)
231
1.39M
{
232
1.39M
    if (ctx->args.QUIET != true)
233
0
        (void)outwrite(ctx->memory, str, strlen(str));
234
1.39M
}
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
25.2k
{
244
25.2k
    int code = 0;
245
25.2k
    char fontfname[gp_file_name_sizeof];
246
25.2k
    stream *s;
247
25.2k
    pdf_name *cidname = NULL;
248
25.2k
    gs_const_string fname;
249
250
25.2k
    (void)pdfi_dict_get(ctx, font_dict, "BaseFont", (pdf_obj **)&cidname);
251
252
25.2k
    if (fallback == true) {
253
12.6k
        pdf_string *mname = NULL;
254
12.6k
        pdf_dict *csi = NULL;
255
12.6k
        pdf_name *fbname;
256
12.6k
        const char *cidfbstr = "CIDFallBack";
257
258
12.6k
        code = pdfi_fontmap_lookup_cidfont(ctx, font_dict, NULL, (pdf_obj **)&mname, findex);
259
260
12.6k
        if (mname == NULL || pdfi_type_of(mname) != PDF_STRING) {
261
12.6k
            pdfi_countdown(mname);
262
263
12.6k
            code = pdfi_object_alloc(ctx, PDF_NAME, strlen(cidfbstr), (pdf_obj **)&fbname);
264
12.6k
            if (code >= 0) {
265
12.6k
                pdfi_countup(fbname);
266
12.6k
                memcpy(fbname->data, cidfbstr, strlen(cidfbstr));
267
12.6k
                code = pdfi_fontmap_lookup_cidfont(ctx, font_dict, fbname, (pdf_obj **)&mname, findex);
268
12.6k
                pdfi_countdown(fbname);
269
12.6k
            }
270
271
12.6k
            if (code < 0 || pdfi_type_of(mname) != PDF_STRING) {
272
12.6k
                pdfi_countdown(mname);
273
12.6k
                mname = NULL;
274
12.6k
                code = pdfi_dict_get(ctx, font_dict, "CIDSystemInfo", (pdf_obj **)&csi);
275
12.6k
                if (code >= 0 && pdfi_type_of(csi) == PDF_DICT) {
276
10.2k
                    pdf_string *csi_reg = NULL, *csi_ord = NULL;
277
278
10.2k
                    if (pdfi_dict_get(ctx, csi, "Registry", (pdf_obj **)&csi_reg) >= 0
279
10.2k
                     && pdfi_dict_get(ctx, csi, "Ordering", (pdf_obj **)&csi_ord) >= 0
280
10.1k
                     && pdfi_type_of(csi_reg) == PDF_STRING && pdfi_type_of(csi_ord) == PDF_STRING
281
10.1k
                     && csi_reg->length + csi_ord->length + 1 < gp_file_name_sizeof - 1) {
282
10.1k
                        pdf_name *reg_ord;
283
10.1k
                        memcpy(fontfname, csi_reg->data, csi_reg->length);
284
10.1k
                        memcpy(fontfname + csi_reg->length, "-", 1);
285
10.1k
                        memcpy(fontfname + csi_reg->length + 1, csi_ord->data, csi_ord->length);
286
10.1k
                        fontfname[csi_reg->length + csi_ord->length + 1] = '\0';
287
288
10.1k
                        code = pdfi_name_alloc(ctx, (byte *)fontfname, strlen(fontfname), (pdf_obj **) &reg_ord);
289
10.1k
                        if (code >= 0) {
290
10.1k
                            pdfi_countup(reg_ord);
291
10.1k
                            code = pdfi_fontmap_lookup_cidfont(ctx, font_dict, reg_ord, (pdf_obj **)&mname, findex);
292
10.1k
                            pdfi_countdown(reg_ord);
293
10.1k
                        }
294
10.1k
                    }
295
10.2k
                    pdfi_countdown(csi_reg);
296
10.2k
                    pdfi_countdown(csi_ord);
297
10.2k
                }
298
12.6k
                pdfi_countdown(csi);
299
12.6k
            }
300
301
12.6k
            if (mname == NULL || pdfi_type_of(mname) != PDF_STRING) {
302
12.6k
                pdfi_countdown(mname);
303
12.6k
                mname = NULL;
304
12.6k
                code = pdfi_fontmap_lookup_cidfont(ctx, font_dict, NULL, (pdf_obj **)&mname, findex);
305
12.6k
            }
306
12.6k
        }
307
308
12.6k
        do {
309
12.6k
            if (code < 0 || pdfi_type_of(mname) != PDF_STRING) {
310
12.6k
                const char *fsprefix = "CIDFSubst/";
311
12.6k
                int fsprefixlen = strlen(fsprefix);
312
12.6k
                const char *defcidfallack = "DroidSansFallback.ttf";
313
12.6k
                int defcidfallacklen = strlen(defcidfallack);
314
315
12.6k
                pdfi_countdown(mname);
316
317
12.6k
                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
12.6k
                else {
324
12.6k
                    if (ctx->args.cidfsubstpath.data == NULL) {
325
12.6k
                        memcpy(fontfname, fsprefix, fsprefixlen);
326
12.6k
                    }
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
12.6k
                    if (ctx->args.cidfsubstfont.data == NULL) {
341
12.6k
                        int len = 0;
342
12.6k
                        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
12.6k
                        else {
360
12.6k
                            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
12.6k
                            else {
372
12.6k
                                memcpy(fontfname + fsprefixlen, defcidfallack, defcidfallacklen);
373
12.6k
                            }
374
12.6k
                        }
375
12.6k
                    }
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
12.6k
                    fontfname[fsprefixlen + defcidfallacklen] = '\0';
414
415
12.6k
                    code = pdfi_open_resource_file(ctx, fontfname, strlen(fontfname), &s);
416
12.6k
                    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
12.6k
                    else {
436
12.6k
                        if (cidname) {
437
12.4k
                            pdfi_print_cstring(ctx, "Loading CIDFont ");
438
12.4k
                            pdfi_print_font_name(ctx, (pdf_name *)cidname);
439
12.4k
                            pdfi_print_cstring(ctx, " substitute from ");
440
12.4k
                        }
441
145
                        else {
442
145
                            pdfi_print_cstring(ctx, "Loading nameless CIDFont from ");
443
145
                        }
444
12.6k
                        sfilename(s, &fname);
445
12.6k
                        if (fname.size < gp_file_name_sizeof) {
446
12.6k
                            memcpy(fontfname, fname.data, fname.size);
447
12.6k
                            fontfname[fname.size] = '\0';
448
12.6k
                        }
449
0
                        else {
450
0
                            strcpy(fontfname, "unnamed file");
451
0
                        }
452
12.6k
                        pdfi_print_cstring(ctx, fontfname);
453
12.6k
                        pdfi_print_cstring(ctx, "\n");
454
455
456
12.6k
                        sfseek(s, 0, SEEK_END);
457
12.6k
                        *buflen = sftell(s);
458
12.6k
                        sfseek(s, 0, SEEK_SET);
459
12.6k
                        *buf = gs_alloc_bytes(ctx->memory, *buflen, "pdfi_open_CIDFont_file(buf)");
460
12.6k
                        if (*buf != NULL) {
461
12.6k
                            sfread(*buf, 1, *buflen, s);
462
12.6k
                        }
463
0
                        else {
464
0
                            code = gs_note_error(gs_error_VMerror);
465
0
                        }
466
12.6k
                        sfclose(s);
467
12.6k
                        break;
468
12.6k
                    }
469
12.6k
                }
470
12.6k
            }
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
12.6k
        } while (code >= 0);
517
12.6k
    }
518
12.6k
    else {
519
12.6k
        const char *fsprefix = "CIDFont/";
520
12.6k
        const int fsprefixlen = strlen(fsprefix);
521
522
12.6k
        if (cidname == NULL || pdfi_type_of(cidname) != PDF_NAME
523
12.4k
         || fsprefixlen + cidname->length >= gp_file_name_sizeof) {
524
149
            code = gs_note_error(gs_error_invalidfont);
525
149
            goto exit;
526
149
        }
527
528
12.4k
        memcpy(fontfname, fsprefix, fsprefixlen);
529
12.4k
        memcpy(fontfname + fsprefixlen, cidname->data, cidname->length);
530
12.4k
        fontfname[fsprefixlen + cidname->length] = '\0';
531
532
12.4k
        code = pdfi_open_resource_file(ctx, fontfname, strlen(fontfname), &s);
533
12.4k
        if (code < 0) {
534
12.4k
            code = gs_note_error(gs_error_invalidfont);
535
12.4k
        }
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.4k
    }
550
551
25.2k
exit:
552
25.2k
    if (cidname != NULL)
553
24.9k
        pdfi_countdown(cidname);
554
555
25.2k
    return code;
556
25.2k
}
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
55.1M
{
593
63.4M
    while (1)
594
63.4M
    {
595
63.4M
        while (*a == ' ')
596
0
            a++;
597
63.4M
        while (*b == ' ')
598
957
            b++;
599
63.4M
        if (*a != *b)
600
55.1M
            return 1;
601
8.33M
        if (*a == 0)
602
6.79k
            return *a != *b;
603
8.32M
        if (*b == 0)
604
0
            return *a != *b;
605
8.32M
        a++;
606
8.32M
        b++;
607
8.32M
    }
608
0
    return 0; /* Shouldn't happen */
609
55.1M
}
610
611
static const char *pdfi_clean_font_name(const char *fontname)
612
827k
{
613
827k
    int i, k;
614
12.3M
    for (i = 0; i < (sizeof(pdfi_base_font_names)/sizeof(pdfi_base_font_names[0])); i++) {
615
66.6M
        for (k = 0; pdfi_base_font_names[i][k]; k++) {
616
55.1M
            if (!strncmp_ignore_space(pdfi_base_font_names[i][k], (const char *)fontname))
617
6.79k
                return pdfi_base_font_names[i][0];
618
55.1M
        }
619
11.5M
    }
620
820k
    return NULL;
621
827k
}
622
623
static int pdfi_font_substitute_by_flags(pdf_context *ctx, unsigned int flags, char **name, int *namelen)
624
426k
{
625
426k
    bool fixed = ((flags & pdfi_font_flag_fixed) != 0);
626
426k
    bool serif = ((flags & pdfi_font_flag_serif) != 0);
627
426k
    bool italic = ((flags & pdfi_font_flag_italic) != 0);
628
426k
    bool bold = ((flags & pdfi_font_flag_forcebold) != 0);
629
426k
    int code = 0;
630
631
426k
    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
426k
    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
426k
    else if (fixed) {
642
217
        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
212
        else {
653
212
            if (italic) {
654
2
                *name = (char *)pdfi_base_font_names[2][0];
655
2
                *namelen = strlen(*name);
656
2
            }
657
210
            else {
658
210
                *name = (char *)pdfi_base_font_names[0][0];
659
210
                *namelen = strlen(*name);
660
210
            }
661
212
        }
662
217
    }
663
426k
    else if (serif) {
664
1.77k
        if (bold) {
665
9
            if (italic) {
666
0
                *name = (char *)pdfi_base_font_names[11][0];
667
0
                *namelen = strlen(*name);
668
0
            }
669
9
            else {
670
9
                *name = (char *)pdfi_base_font_names[9][0];
671
9
                *namelen = strlen(*name);
672
9
            }
673
9
        }
674
1.76k
        else {
675
1.76k
            if (italic) {
676
131
                *name = (char *)pdfi_base_font_names[10][0];
677
131
                *namelen = strlen(*name);
678
131
            }
679
1.63k
            else {
680
1.63k
                *name = (char *)pdfi_base_font_names[8][0];
681
1.63k
                *namelen = strlen(*name);
682
1.63k
            }
683
1.76k
        }
684
424k
    } else {
685
424k
        if (bold) {
686
139
            if (italic) {
687
0
                *name = (char *)pdfi_base_font_names[7][0];
688
0
                *namelen = strlen(*name);
689
0
            }
690
139
            else {
691
139
                *name = (char *)pdfi_base_font_names[5][0];
692
139
                *namelen = strlen(*name);
693
139
            }
694
139
        }
695
424k
        else {
696
424k
            if (italic) {
697
482
                *name = (char *)pdfi_base_font_names[6][0];
698
482
                *namelen = strlen(*name);
699
482
            }
700
424k
            else {
701
424k
                *name = (char *)pdfi_base_font_names[4][0];
702
424k
                *namelen = strlen(*name);
703
424k
            }
704
424k
        }
705
424k
    }
706
426k
    return code;
707
426k
}
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
105k
{
720
968k
#define MAKEMAGIC(a, b, c, d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
721
722
105k
    if (buflen >= 4) {
723
105k
        if (MAKEMAGIC(buf[0], buf[1], buf[2], buf[3]) == MAKEMAGIC(0, 1, 0, 0)
724
69.0k
            || MAKEMAGIC(buf[0], buf[1], buf[2], buf[3]) == MAKEMAGIC('t', 'r', 'u', 'e')
725
64.6k
            || MAKEMAGIC(buf[0], buf[1], buf[2], buf[3]) == MAKEMAGIC('t', 't', 'c', 'f')) {
726
40.7k
            return tt_font;
727
40.7k
        }
728
64.6k
        else if (MAKEMAGIC(buf[0], buf[1], buf[2], buf[3]) == MAKEMAGIC('O', 'T', 'T', 'O')) {
729
516
            return cff_font; /* OTTO will end up as CFF */
730
516
        }
731
64.1k
        else if (MAKEMAGIC(buf[0], buf[1], buf[2], 0) == MAKEMAGIC('%', '!', 'P', 0)) {
732
53.8k
            return type1_font; /* pfa */
733
53.8k
        }
734
10.3k
        else if (MAKEMAGIC(buf[0], buf[1], buf[2], 0) == MAKEMAGIC(1, 0, 4, 0)) {
735
9.63k
            return cff_font; /* 1C/CFF */
736
9.63k
        }
737
671
        else if (MAKEMAGIC(buf[0], buf[1], 0, 0) == MAKEMAGIC(128, 1, 0, 0)) {
738
192
            return type1_font; /* pfb */
739
192
        }
740
105k
    }
741
495
    return no_type_font;
742
105k
#undef MAKEMAGIC
743
105k
}
744
745
static int pdfi_copy_font(pdf_context *ctx, pdf_font *spdffont, pdf_dict *font_dict, pdf_font **tpdffont)
746
451k
{
747
451k
    int code;
748
451k
    if (pdfi_type_of(spdffont) != PDF_FONT)
749
0
        return_error(gs_error_typecheck);
750
751
451k
    switch(spdffont->pdfi_font_type) {
752
448k
        case e_pdf_font_type1:
753
448k
          code = pdfi_copy_type1_font(ctx, spdffont, font_dict, tpdffont);
754
448k
          break;
755
60
        case e_pdf_font_cff:
756
60
          code = pdfi_copy_cff_font(ctx, spdffont, font_dict, tpdffont);
757
60
          break;
758
3.12k
        case e_pdf_font_truetype:
759
3.12k
          code = pdfi_copy_truetype_font(ctx, spdffont, font_dict, tpdffont);
760
3.12k
          break;
761
0
        case e_pdf_font_microtype:
762
0
          code = pdfi_copy_microtype_font(ctx, spdffont, font_dict, tpdffont);
763
0
          break;
764
0
        default:
765
0
            return_error(gs_error_invalidfont);
766
451k
    }
767
451k
    return code;
768
451k
}
769
770
enum {
771
  font_embedded = 0,
772
  font_from_file = 1,
773
  font_substitute = 2
774
};
775
776
static int pdfi_load_font_buffer(pdf_context *ctx, byte *fbuf, int64_t fbuflen, int fftype, pdf_name *Subtype, int findex, pdf_dict *stream_dict, pdf_dict *page_dict, pdf_dict *font_dict, pdf_font **ppdffont, bool cidfont)
777
105k
{
778
105k
    int code = gs_error_invalidfont;
779
105k
    if (fbuf != NULL) {
780
        /* First, see if we can glean the type from the magic number */
781
105k
        int sftype = pdfi_fonttype_picker(fbuf, fbuflen);
782
105k
        if (sftype == no_type_font) {
783
495
            if (fftype != no_type_font)
784
475
                sftype = fftype;
785
20
            else {
786
                /* If we don't have a Subtype, can't work it out, try Type 1 */
787
20
                if (Subtype == NULL || pdfi_name_is(Subtype, "Type1") || pdfi_name_is(Subtype, "MMType1"))
788
18
                    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
20
            }
794
495
        }
795
        /* fbuf ownership passes to the font loader */
796
105k
        switch (sftype) {
797
54.3k
            case type1_font:
798
54.3k
                code = pdfi_read_type1_font(ctx, (pdf_dict *)font_dict, stream_dict, page_dict, fbuf, fbuflen, ppdffont);
799
54.3k
                fbuf = NULL;
800
54.3k
                break;
801
10.2k
            case cff_font:
802
10.2k
                code = pdfi_read_cff_font(ctx, (pdf_dict *)font_dict, stream_dict, page_dict, fbuf, fbuflen, cidfont, ppdffont);
803
10.2k
                fbuf = NULL;
804
10.2k
                break;
805
40.8k
            case tt_font:
806
40.8k
                {
807
40.8k
                    if (cidfont)
808
19.7k
                        code = pdfi_read_cidtype2_font(ctx, font_dict, stream_dict, page_dict, fbuf, fbuflen, findex, ppdffont);
809
21.0k
                    else
810
21.0k
                        code = pdfi_read_truetype_font(ctx, font_dict, stream_dict, page_dict, fbuf, fbuflen, findex, ppdffont);
811
40.8k
                    fbuf = NULL;
812
40.8k
                }
813
40.8k
                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
105k
        }
818
105k
    }
819
105k
    return code;
820
105k
}
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
874k
{
824
874k
    int code;
825
874k
    char fontfname[gp_file_name_sizeof];
826
874k
    pdf_obj *basefont = NULL, *mapname = NULL;
827
874k
    pdf_obj *fontname = NULL;
828
874k
    stream *s = NULL;
829
874k
    const char *fn;
830
874k
    int findex = 0;
831
874k
    byte *buf;
832
874k
    int buflen;
833
874k
    pdf_font *pdffont = NULL;
834
874k
    pdf_font *substpdffont = NULL;
835
874k
    bool f_retry = true;
836
837
874k
    code = pdfi_dict_knownget_type(ctx, font_dict, "BaseFont", PDF_NAME, &basefont);
838
874k
    if (substitute == false && (code < 0 || basefont == NULL || ((pdf_name *)basefont)->length == 0)) {
839
16.4k
        pdfi_countdown(basefont);
840
16.4k
        return_error(gs_error_invalidfont);
841
16.4k
    }
842
843
858k
    if (substitute == true) {
844
426k
        char *fbname;
845
426k
        int fbnamelen;
846
426k
        int64_t flags = 0;
847
426k
        if (fontdesc != NULL) {
848
20.0k
            (void)pdfi_dict_get_int(ctx, fontdesc, "Flags", &flags);
849
20.0k
        }
850
426k
        code = pdfi_font_substitute_by_flags(ctx, (int)flags, &fbname, &fbnamelen);
851
426k
        if (code < 0)
852
0
            return code;
853
854
426k
        code = pdfi_name_alloc(ctx, (byte *)fbname, strlen(fbname), (pdf_obj **) &fontname);
855
426k
        if (code < 0)
856
0
            return code;
857
426k
        pdfi_countup(fontname);
858
426k
    }
859
431k
    else {
860
431k
        fontname = basefont;
861
431k
        pdfi_countup(fontname);
862
431k
    }
863
864
858k
    if (((pdf_name *)fontname)->length < gp_file_name_sizeof) {
865
858k
        memcpy(fontfname, ((pdf_name *)fontname)->data, ((pdf_name *)fontname)->length);
866
858k
        fontfname[((pdf_name *)fontname)->length] = '\0';
867
858k
        pdfi_countdown(fontname);
868
869
858k
        code = pdfi_name_alloc(ctx, (byte *)fontfname, strlen(fontfname), (pdf_obj **) &fontname);
870
858k
        if (code < 0)
871
0
            return code;
872
858k
        pdfi_countup(fontname);
873
858k
    }
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.27M
    do {
880
1.27M
        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.27M
        else {
884
1.27M
            code = pdfi_fontmap_lookup_font(ctx, font_dict, (pdf_name *) fontname, &mapname, &findex);
885
1.27M
            if (code < 0) {
886
827k
                if (((pdf_name *)fontname)->length < gp_file_name_sizeof) {
887
827k
                    memcpy(fontfname, ((pdf_name *)fontname)->data, ((pdf_name *)fontname)->length);
888
827k
                    fontfname[((pdf_name *)fontname)->length] = '\0';
889
827k
                    fn = pdfi_clean_font_name(fontfname);
890
827k
                    if (fn != NULL) {
891
6.79k
                        pdfi_countdown(fontname);
892
893
6.79k
                        code = pdfi_name_alloc(ctx, (byte *)fn, strlen(fn), (pdf_obj **) &fontname);
894
6.79k
                        if (code < 0)
895
0
                            return code;
896
6.79k
                        pdfi_countup(fontname);
897
6.79k
                    }
898
827k
                }
899
827k
                code = pdfi_fontmap_lookup_font(ctx, font_dict, (pdf_name *) fontname, &mapname, &findex);
900
827k
                if (code < 0) {
901
820k
                    mapname = fontname;
902
820k
                    pdfi_countup(mapname);
903
820k
                    code = 0;
904
820k
                }
905
827k
            }
906
1.27M
            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.27M
            if (pdfi_type_of(mapname) == PDF_NAME || pdfi_type_of(mapname) == PDF_STRING) {
912
1.27M
                pdf_name *mname = (pdf_name *) mapname;
913
1.27M
                if (mname->length + 1 < gp_file_name_sizeof) {
914
1.27M
                    memcpy(fontfname, mname->data, mname->length);
915
1.27M
                    fontfname[mname->length] = '\0';
916
1.27M
                }
917
3
                else {
918
3
                    pdfi_countdown(mapname);
919
3
                    pdfi_countdown(fontname);
920
3
                    return_error(gs_error_invalidfileaccess);
921
3
                }
922
1.27M
            }
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.27M
            if (ctx->pdf_substitute_fonts != NULL) {
930
1.18M
                code = pdfi_dict_knownget_type(ctx, ctx->pdf_substitute_fonts, fontfname, PDF_FONT, (pdf_obj **)&pdffont);
931
1.18M
                if (code == 1 && pdffont->filename == NULL) {
932
0
                    pdfi_countdown(pdffont);
933
0
                    pdffont = NULL;
934
0
                    code = 0;
935
0
                }
936
1.18M
            }
937
88.2k
            else
938
88.2k
                code = 0;
939
1.27M
        }
940
1.27M
        if (code != 1) {
941
866k
            code = pdfi_open_font_file(ctx, fontfname, strlen(fontfname), &s);
942
866k
            if (code < 0 && f_retry && pdfi_type_of(mapname) == PDF_NAME) {
943
412k
                pdfi_countdown(fontname);
944
412k
                fontname = mapname;
945
412k
                mapname = NULL;
946
412k
                f_retry = false;
947
412k
                continue;
948
412k
            }
949
453k
            if (code >= 0) {
950
43.4k
                gs_const_string fname;
951
952
43.4k
                sfilename(s, &fname);
953
43.4k
                if (fname.size < gp_file_name_sizeof) {
954
43.4k
                    memcpy(fontfname, fname.data, fname.size);
955
43.4k
                    fontfname[fname.size] = '\0';
956
43.4k
                }
957
0
                else {
958
0
                    strcpy(fontfname, "unnamed file");
959
0
                }
960
43.4k
                sfseek(s, 0, SEEK_END);
961
43.4k
                buflen = sftell(s);
962
43.4k
                sfseek(s, 0, SEEK_SET);
963
43.4k
                buf = gs_alloc_bytes(ctx->memory, buflen, "pdfi_open_t1_font_file(buf)");
964
43.4k
                if (buf != NULL) {
965
43.4k
                    sfread(buf, 1, buflen, s);
966
43.4k
                }
967
0
                else {
968
0
                    code = gs_note_error(gs_error_VMerror);
969
0
                }
970
43.4k
                sfclose(s);
971
                /* Buffer owership moves to the font object */
972
43.4k
                code = pdfi_load_font_buffer(ctx, buf, buflen, no_type_font, NULL, findex, stream_dict, page_dict, NULL, &pdffont, false);
973
43.4k
                if (code >= 0) {
974
43.4k
                    pdffont->filename = NULL;
975
43.4k
                    code = pdfi_object_alloc(ctx, PDF_STRING, strlen(fontfname) , (pdf_obj **)&pdffont->filename);
976
43.4k
                    if (code >= 0) {
977
43.4k
                        pdfi_countup(pdffont->filename);
978
43.4k
                        memcpy(pdffont->filename->data, fontfname, strlen(fontfname));
979
43.4k
                        pdffont->filename->length = strlen(fontfname);
980
43.4k
                    }
981
982
43.4k
                    if (ctx->pdf_substitute_fonts == NULL) {
983
34.5k
                        code = pdfi_dict_alloc(ctx, 16, &ctx->pdf_substitute_fonts);
984
34.5k
                        if (code >= 0)
985
34.5k
                            pdfi_countup(ctx->pdf_substitute_fonts);
986
34.5k
                    }
987
43.4k
                    if (ctx->pdf_substitute_fonts != NULL) {
988
43.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
43.4k
                        else
1001
43.4k
                            code = 0;
1002
1003
43.4k
                        if (code == 0)
1004
43.4k
                            (void)pdfi_dict_put_obj(ctx, ctx->pdf_substitute_fonts, mapname, (pdf_obj *)pdffont, true);
1005
43.4k
                        code = 0;
1006
43.4k
                    }
1007
43.4k
                }
1008
43.4k
            }
1009
453k
        }
1010
858k
        break;
1011
1.27M
    } while (1);
1012
1013
858k
    if (code >= 0) {
1014
448k
        if (basefont) {
1015
447k
            pdfi_print_cstring(ctx, "Loading font ");
1016
447k
            pdfi_print_font_name(ctx, (pdf_name *)basefont);
1017
447k
            pdfi_print_cstring(ctx, " (or substitute) from ");
1018
447k
        }
1019
813
        else {
1020
813
            pdfi_print_cstring(ctx, "Loading nameless font from ");
1021
813
        }
1022
448k
        pdfi_print_font_string(ctx, pdffont->filename);
1023
448k
        pdfi_print_cstring(ctx, "\n");
1024
1025
448k
        code = pdfi_copy_font(ctx, pdffont, font_dict, &substpdffont);
1026
448k
        pdfi_countdown(pdffont);
1027
448k
    }
1028
1029
858k
    *ppdffont = substpdffont;
1030
1031
858k
    pdfi_countdown(basefont);
1032
858k
    pdfi_countdown(mapname);
1033
858k
    pdfi_countdown(fontname);
1034
858k
    return code;
1035
858k
}
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
536k
{
1039
536k
    int code;
1040
536k
    pdf_font *ppdffont = NULL;
1041
536k
    pdf_font *ppdfdescfont = NULL;
1042
536k
    pdf_name *Type = NULL;
1043
536k
    pdf_name *Subtype = NULL;
1044
536k
    pdf_dict *fontdesc = NULL;
1045
536k
    pdf_stream *fontfile = NULL;
1046
536k
    pdf_name *ffsubtype = NULL;
1047
536k
    int fftype = no_type_font;
1048
536k
    byte *fbuf = NULL;
1049
536k
    int64_t fbuflen = 0;
1050
536k
    int substitute = font_embedded;
1051
536k
    int findex = 0;
1052
1053
536k
    code = pdfi_dict_get_type(ctx, font_dict, "Type", PDF_NAME, (pdf_obj **)&Type);
1054
536k
    if (code < 0) {
1055
613
        if ((code = pdfi_set_error_stop(ctx, code, NULL, E_PDF_MISSINGTYPE, "pdfi_load_font", NULL)) < 0)
1056
0
            goto exit;
1057
613
    }
1058
536k
    else {
1059
536k
        if (!pdfi_name_is(Type, "Font")){
1060
3.00k
            code = gs_note_error(gs_error_typecheck);
1061
3.00k
            goto exit;
1062
3.00k
        }
1063
536k
    }
1064
533k
    code = pdfi_dict_get_type(ctx, font_dict, "Subtype", PDF_NAME, (pdf_obj **)&Subtype);
1065
533k
    if (code < 0) {
1066
648
        if ((code = pdfi_set_error_stop(ctx, code, NULL, E_PDF_NO_SUBTYPE, "pdfi_load_font", NULL)) < 0)
1067
0
            goto exit;
1068
648
    }
1069
1070
    /* Beyond Type 0 and Type 3, there is no point trusting the Subtype key */
1071
533k
    if (Subtype != NULL && pdfi_name_is(Subtype, "Type0")) {
1072
33.6k
        if (cidfont == true) {
1073
5
            code = gs_note_error(gs_error_invalidfont);
1074
5
        }
1075
33.6k
        else {
1076
33.6k
            code = pdfi_read_type0_font(ctx, (pdf_dict *)font_dict, stream_dict, page_dict, &ppdffont);
1077
33.6k
        }
1078
33.6k
    }
1079
500k
    else if (Subtype != NULL && pdfi_name_is(Subtype, "Type3")) {
1080
2.59k
        code = pdfi_read_type3_font(ctx, (pdf_dict *)font_dict, stream_dict, page_dict, &ppdffont);
1081
2.59k
        if (code < 0)
1082
483
            goto exit;
1083
2.59k
    }
1084
497k
    else {
1085
497k
        if (Subtype != NULL && !pdfi_name_is(Subtype, "Type1") && !pdfi_name_is(Subtype, "TrueType") && !pdfi_name_is(Subtype, "CIDFont")
1086
21.5k
            && !pdfi_name_is(Subtype, "CIDFontType2") && !pdfi_name_is(Subtype, "CIDFontType0") && !pdfi_name_is(Subtype, "MMType1")) {
1087
1088
736
            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
736
        }
1092
        /* We should always have a font descriptor here, but we have to carry on
1093
           even if we don't
1094
         */
1095
497k
        code = pdfi_dict_get_type(ctx, font_dict, "FontDescriptor", PDF_DICT, (pdf_obj **)&fontdesc);
1096
497k
        if (fontdesc != NULL && pdfi_type_of(fontdesc) == PDF_DICT) {
1097
68.3k
            pdf_obj *Name = NULL;
1098
1099
68.3k
            code = pdfi_dict_get_type(ctx, (pdf_dict *) fontdesc, "FontName", PDF_NAME, (pdf_obj **)&Name);
1100
68.3k
            if (code < 0)
1101
931
                pdfi_set_warning(ctx, 0, NULL, W_PDF_FDESC_BAD_FONTNAME, "pdfi_load_font", "");
1102
68.3k
            pdfi_countdown(Name);
1103
68.3k
            Name = NULL;
1104
1105
68.3k
            if (cidfont == true) {
1106
12.8k
                code = -1;
1107
12.8k
            }
1108
55.4k
            else {
1109
55.4k
                code = pdfi_find_cache_resource_font(ctx, (pdf_obj *)fontdesc, (pdf_obj **)&ppdfdescfont);
1110
55.4k
                if (code >= 0) {
1111
3.30k
                    code = pdfi_copy_font(ctx, ppdfdescfont, font_dict, &ppdffont);
1112
3.30k
                }
1113
55.4k
            }
1114
1115
68.3k
            if (code < 0) {
1116
65.0k
                code = pdfi_dict_get_type(ctx, (pdf_dict *) fontdesc, "FontFile", PDF_STREAM, (pdf_obj **)&fontfile);
1117
65.0k
                if (code >= 0)
1118
10.7k
                    fftype = type1_font;
1119
54.2k
                else {
1120
54.2k
                    code = pdfi_dict_get_type(ctx, (pdf_dict *) fontdesc, "FontFile2", PDF_STREAM, (pdf_obj **)&fontfile);
1121
54.2k
                    fftype = tt_font;
1122
54.2k
                }
1123
65.0k
                if (code < 0) {
1124
24.9k
                    code = pdfi_dict_get_type(ctx, (pdf_dict *) fontdesc, "FontFile3", PDF_STREAM, (pdf_obj **)&fontfile);
1125
24.9k
                    if (code >= 0 && fontfile != NULL) {
1126
10.6k
                        code = pdfi_dict_get_type(ctx, fontfile->stream_dict, "Subtype", PDF_NAME, (pdf_obj **)&ffsubtype);
1127
10.6k
                        if (code >= 0) {
1128
10.5k
                            if (pdfi_name_is(ffsubtype, "Type1"))
1129
0
                                fftype = type1_font;
1130
10.5k
                            else if (pdfi_name_is(ffsubtype, "Type1C"))
1131
8.08k
                                fftype = cff_font;
1132
2.49k
                            else if (pdfi_name_is(ffsubtype, "OpenType"))
1133
344
                                fftype = cff_font;
1134
2.15k
                            else if (pdfi_name_is(ffsubtype, "CIDFontType0C"))
1135
1.73k
                                fftype = cff_font;
1136
420
                            else if (pdfi_name_is(ffsubtype, "TrueType"))
1137
0
                                fftype = tt_font;
1138
420
                            else
1139
420
                                fftype = no_type_font;
1140
10.5k
                        }
1141
10.6k
                    }
1142
24.9k
                }
1143
65.0k
            }
1144
68.3k
        }
1145
1146
497k
        if (ppdffont == NULL) {
1147
494k
            if (fontfile != NULL) {
1148
50.7k
                code = pdfi_stream_to_buffer(ctx, (pdf_stream *) fontfile, &fbuf, &fbuflen);
1149
50.7k
                pdfi_countdown(fontfile);
1150
50.7k
                if (code < 0 || fbuflen == 0) {
1151
1.39k
                    char obj[129];
1152
1.39k
                    pdfi_print_cstring(ctx, "**** Warning: cannot process embedded stream for font object ");
1153
1.39k
                    gs_snprintf(obj, 128, "%d %d\n", (int)font_dict->object_num, (int)font_dict->generation_num);
1154
1.39k
                    pdfi_print_cstring(ctx, obj);
1155
1.39k
                    pdfi_print_cstring(ctx, "**** Attempting to load a substitute font.\n");
1156
1.39k
                    gs_free_object(ctx->memory, fbuf, "pdfi_load_font(fbuf)");
1157
1.39k
                    fbuf = NULL;
1158
1.39k
                    code = gs_note_error(gs_error_invalidfont);
1159
1.39k
                }
1160
50.7k
            }
1161
1162
506k
            while (1) {
1163
506k
                if (fbuf != NULL) {
1164
                    /* fbuf overship passes to pdfi_load_font_buffer() */
1165
61.9k
                    code = pdfi_load_font_buffer(ctx, fbuf, fbuflen, fftype, Subtype, findex, stream_dict, page_dict, font_dict, &ppdffont, cidfont);
1166
1167
61.9k
                    if (code < 0 && substitute == font_embedded) {
1168
15.8k
                        char msg[129];
1169
1170
15.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
15.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
15.8k
                        else {
1176
15.8k
                            code = gs_error_invalidfont;
1177
15.8k
                        }
1178
15.8k
                    }
1179
61.9k
                }
1180
444k
                else {
1181
444k
                    code = gs_error_invalidfont;
1182
444k
                }
1183
1184
506k
                if (code < 0 && code != gs_error_VMerror && substitute == font_embedded) {
1185
460k
                    substitute = font_from_file;
1186
1187
460k
                    if (cidfont == true) {
1188
12.6k
                        code =  pdfi_open_CIDFont_substitute_file(ctx, font_dict, fontdesc, false, &fbuf, &fbuflen, &findex);
1189
12.6k
                        if (code < 0) {
1190
12.6k
                            code =  pdfi_open_CIDFont_substitute_file(ctx, font_dict, fontdesc, true, &fbuf, &fbuflen, &findex);
1191
12.6k
                            substitute |= font_substitute;
1192
12.6k
                        }
1193
1194
12.6k
                        if (code < 0)
1195
0
                            goto exit;
1196
12.6k
                    }
1197
448k
                    else {
1198
448k
                        code = pdfi_load_font_file(ctx, no_type_font, Subtype, stream_dict, page_dict, font_dict, fontdesc, false, &ppdffont);
1199
448k
                        if (code < 0) {
1200
426k
                            code = pdfi_load_font_file(ctx, no_type_font, Subtype, stream_dict, page_dict, font_dict, fontdesc, true, &ppdffont);
1201
426k
                            substitute |= font_substitute;
1202
426k
                        }
1203
448k
                        break;
1204
448k
                    }
1205
12.6k
                    continue;
1206
460k
                }
1207
46.1k
                break;
1208
506k
            }
1209
494k
        }
1210
497k
    }
1211
533k
    if (ppdffont == NULL || code < 0) {
1212
27.7k
        *ppfont = NULL;
1213
27.7k
        if (code != gs_error_Fatal)
1214
27.7k
            code = gs_note_error(gs_error_invalidfont);
1215
27.7k
    }
1216
505k
    else {
1217
505k
        ppdffont->substitute = (substitute != font_embedded);
1218
1219
505k
        if ((substitute & font_substitute) == font_substitute)
1220
432k
            code = pdfi_font_match_glyph_widths(ppdffont);
1221
72.6k
        else if (ppdffont->substitute != true && fontdesc != NULL && ppdfdescfont == NULL
1222
33.4k
            && (ppdffont->pdfi_font_type == e_pdf_font_type1 || ppdffont->pdfi_font_type == e_pdf_font_cff
1223
26.9k
            || ppdffont->pdfi_font_type == e_pdf_font_truetype)) {
1224
26.9k
            pdfi_cache_resource_font(ctx, (pdf_obj *)fontdesc, (pdf_obj *)ppdffont);
1225
26.9k
        }
1226
505k
        *ppfont = (gs_font *)ppdffont->pfont;
1227
505k
     }
1228
1229
536k
exit:
1230
536k
    pdfi_countdown(ppdfdescfont);
1231
536k
    pdfi_countdown(fontdesc);
1232
536k
    pdfi_countdown(Type);
1233
536k
    pdfi_countdown(Subtype);
1234
536k
    pdfi_countdown(ffsubtype);
1235
536k
    return code;
1236
533k
}
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
781k
{
1240
781k
    int code;
1241
781k
    gs_font *pfont;
1242
781k
    pdf_font *pdfif;
1243
1244
781k
    switch (pdfi_type_of(font_dict)) {
1245
660k
        case PDF_FONT:
1246
660k
            pdfi_countup(font_dict);
1247
660k
            pfont = (gs_font *)((pdf_font *)font_dict)->pfont;
1248
660k
            code = 0;
1249
660k
            break;
1250
113k
        case PDF_DICT:
1251
113k
            code = pdfi_load_font(ctx, stream_dict, page_dict, font_dict, &pfont, false);
1252
113k
            break;
1253
7.53k
        default:
1254
7.53k
            code = gs_note_error(gs_error_typecheck);
1255
7.53k
            goto exit;
1256
781k
    }
1257
773k
    if (code < 0)
1258
24.7k
        goto exit;
1259
1260
    /* Everything looks good, set the font, unless it's the current font */
1261
749k
    if (pfont != ctx->pgs->font) {
1262
595k
        code = pdfi_gs_setfont(ctx, pfont);
1263
595k
    }
1264
749k
    pdfif = (pdf_font *)pfont->client_data;
1265
749k
    pdfi_countdown(pdfif);
1266
1267
749k
    if (code < 0)
1268
0
        goto exit;
1269
1270
749k
    code = gs_setPDFfontsize(ctx->pgs, point_size);
1271
781k
exit:
1272
781k
    return code;
1273
749k
}
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.15M
{
1277
1.15M
    int code;
1278
1.15M
    pdf_dict *font_dict = NULL;
1279
1280
1.15M
    if (pdfi_type_of(fontname) != PDF_NAME) {
1281
        /* Passing empty string here should fall back to a default font */
1282
13.7k
        return pdfi_font_set_internal_string(ctx, "", point_size);
1283
13.7k
    }
1284
1285
    /* Look fontname up in the resources */
1286
1.13M
    code = pdfi_loop_detector_mark(ctx);
1287
1.13M
    if (code < 0)
1288
0
        goto exit;
1289
1.13M
    code = pdfi_find_resource(ctx, (unsigned char *)"Font", fontname, stream_dict, page_dict, (pdf_obj **)&font_dict);
1290
1.13M
    (void)pdfi_loop_detector_cleartomark(ctx);
1291
1.13M
    if (code < 0)
1292
357k
        goto exit;
1293
781k
    code = pdfi_load_dict_font(ctx, stream_dict, page_dict, font_dict, point_size);
1294
1295
1.13M
exit:
1296
1.13M
    pdfi_countdown(font_dict);
1297
1.13M
    return code;
1298
781k
}
1299
1300
int pdfi_get_cidfont_glyph_metrics(gs_font *pfont, gs_glyph cid, double *widths, bool vertical)
1301
1.01M
{
1302
1.01M
    pdf_font *pdffont = (pdf_font *)pfont->client_data;
1303
1.01M
    int i, code = 0;
1304
1.01M
    pdf_num *c = NULL, *c2 = NULL;
1305
1.01M
    pdf_obj *o = NULL;
1306
1.01M
    pdf_array *W = NULL, *W2 = NULL, *DW2 = NULL;
1307
1.01M
    double DW;
1308
1309
1.01M
    if (pdffont->pdfi_font_type == e_pdf_cidfont_type0) {
1310
57.2k
        pdf_cidfont_type0 *cidfont = (pdf_cidfont_type0 *)pdffont;
1311
57.2k
        DW = cidfont->DW;
1312
57.2k
        DW2 = cidfont->DW2;
1313
57.2k
        W = cidfont->W;
1314
57.2k
        W2 = cidfont->W2;
1315
57.2k
    }
1316
962k
    else if (pdffont->pdfi_font_type == e_pdf_cidfont_type2) {
1317
962k
        pdf_cidfont_type2 *cidfont = (pdf_cidfont_type2 *)pdffont;
1318
962k
        DW = cidfont->DW;
1319
962k
        DW2 = cidfont->DW2;
1320
962k
        W = cidfont->W;
1321
962k
        W2 = cidfont->W2;
1322
962k
    }
1323
0
    else {
1324
0
        return_error(gs_error_invalidfont);
1325
0
    }
1326
1327
1.01M
    widths[GLYPH_W0_WIDTH_INDEX] = DW;
1328
1.01M
    widths[GLYPH_W0_HEIGHT_INDEX] = 0;
1329
1.01M
    if (W != NULL) {
1330
906k
        i = 0;
1331
1332
21.4M
        while(1) {
1333
21.4M
            pdf_obj_type type;
1334
1335
21.4M
            if (i + 1>= W->size) break;
1336
21.4M
            code = pdfi_array_get_type(pdffont->ctx, W, i, PDF_INT, (pdf_obj **)&c);
1337
21.4M
            if (code < 0) goto cleanup;
1338
1339
21.4M
            code = pdfi_array_get(pdffont->ctx, W, i + 1, &o);
1340
21.4M
            if (code < 0) goto cleanup;
1341
1342
21.4M
            type = pdfi_type_of(o);
1343
21.4M
            if (type == PDF_INT) {
1344
1.75M
                double d;
1345
1.75M
                c2 = (pdf_num *)o;
1346
1.75M
                o = NULL;
1347
1.75M
                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
1.75M
                code = pdfi_array_get_number(pdffont->ctx, W, i + 2, &d);
1355
1.75M
                if (code < 0) goto cleanup;
1356
1.75M
                if (cid >= c->value.i && cid <= c2->value.i) {
1357
59.9k
                    widths[GLYPH_W0_WIDTH_INDEX] = d;
1358
59.9k
                    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
59.9k
                    break;
1363
59.9k
                }
1364
1.69M
                else {
1365
1.69M
                    i += 3;
1366
1.69M
                    pdfi_countdown(c2);
1367
1.69M
                    pdfi_countdown(c);
1368
1.69M
                    c = c2 = NULL;
1369
1.69M
                    continue;
1370
1.69M
                }
1371
1.75M
            }
1372
19.6M
            else if (type == PDF_ARRAY) {
1373
19.6M
                pdf_array *a = (pdf_array *)o;
1374
19.6M
                o = NULL;
1375
19.6M
                if (cid >= c->value.i && cid < c->value.i + a->size) {
1376
774k
                    code = pdfi_array_get_number(pdffont->ctx, a, cid - c->value.i, &widths[GLYPH_W0_WIDTH_INDEX]);
1377
774k
                    if (code >= 0) {
1378
774k
                        pdfi_countdown(a);
1379
774k
                        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
774k
                        break;
1384
774k
                    }
1385
774k
                }
1386
18.9M
                pdfi_countdown(a);
1387
18.9M
                pdfi_countdown(c);
1388
18.9M
                c = NULL;
1389
18.9M
                i += 2;
1390
18.9M
                continue;
1391
19.6M
            }
1392
664
            else {
1393
664
                code = gs_note_error(gs_error_typecheck);
1394
664
                goto cleanup;
1395
664
            }
1396
21.4M
        }
1397
904k
        pdfi_countdown(c2);
1398
904k
        pdfi_countdown(c);
1399
904k
        pdfi_countdown(o);
1400
904k
        c = c2 = NULL;
1401
904k
        o = NULL;
1402
904k
    }
1403
1404
1.01M
    if (vertical) {
1405
        /* Default default <sigh>! */
1406
1.01M
        widths[GLYPH_W1_WIDTH_INDEX] = 0;
1407
1.01M
        widths[GLYPH_W1_HEIGHT_INDEX] = -1000.0;
1408
1.01M
        widths[GLYPH_W1_V_X_INDEX] = (widths[GLYPH_W0_WIDTH_INDEX] / 2.0);
1409
1.01M
        widths[GLYPH_W1_V_Y_INDEX] = 880.0;
1410
1411
1.01M
        if (DW2 != NULL && pdfi_type_of(DW2) == PDF_ARRAY
1412
8.66k
            && DW2->size >= 2) {
1413
8.66k
            code = pdfi_array_get_number(pdffont->ctx, (pdf_array *)DW2, 0, &widths[GLYPH_W1_V_Y_INDEX]);
1414
8.66k
            if (code >= 0)
1415
8.66k
                code = pdfi_array_get_number(pdffont->ctx, (pdf_array *)DW2, 1, &widths[GLYPH_W1_HEIGHT_INDEX]);
1416
8.66k
            if (code >= 0) {
1417
8.66k
                widths[GLYPH_W1_V_X_INDEX] = widths[GLYPH_W0_WIDTH_INDEX] / 2.0;
1418
8.66k
                widths[GLYPH_W1_WIDTH_INDEX] = 0.0;
1419
8.66k
            }
1420
8.66k
        }
1421
1.01M
        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.01M
    }
1494
1495
1.01M
cleanup:
1496
1.01M
    pdfi_countdown(c2);
1497
1.01M
    pdfi_countdown(c);
1498
1.01M
    pdfi_countdown(o);
1499
1500
1.01M
    return code;
1501
1.01M
}
1502
1503
int pdfi_d0(pdf_context *ctx)
1504
3.08k
{
1505
3.08k
    int code = 0, gsave_level = 0;
1506
3.08k
    double width[2];
1507
1508
3.08k
    if (ctx->text.inside_CharProc == false)
1509
2.34k
        pdfi_set_warning(ctx, 0, NULL, W_PDF_NOTINCHARPROC, "pdfi_d0", NULL);
1510
1511
3.08k
    ctx->text.CharProc_d_type = pdf_type3_d0;
1512
1513
3.08k
    if (pdfi_count_stack(ctx) < 2) {
1514
665
        code = gs_note_error(gs_error_stackunderflow);
1515
665
        goto d0_error;
1516
665
    }
1517
1518
2.41k
    if (pdfi_type_of(ctx->stack_top[-1]) != PDF_INT && pdfi_type_of(ctx->stack_top[-1]) != PDF_REAL) {
1519
741
        code = gs_note_error(gs_error_typecheck);
1520
741
        goto d0_error;
1521
741
    }
1522
1.67k
    if (pdfi_type_of(ctx->stack_top[-2]) != PDF_INT && pdfi_type_of(ctx->stack_top[-2]) != PDF_REAL) {
1523
102
        code = gs_note_error(gs_error_typecheck);
1524
102
        goto d0_error;
1525
102
    }
1526
1.57k
    if(ctx->text.current_enum == NULL) {
1527
833
        code = gs_note_error(gs_error_undefined);
1528
833
        goto d0_error;
1529
833
    }
1530
1531
741
    if (pdfi_type_of(ctx->stack_top[-2]) == PDF_INT)
1532
740
        width[0] = (double)((pdf_num *)ctx->stack_top[-2])->value.i;
1533
1
    else
1534
1
        width[0] = ((pdf_num *)ctx->stack_top[-2])->value.d;
1535
741
    if (pdfi_type_of(ctx->stack_top[-1]) == PDF_INT)
1536
739
        width[1] = (double)((pdf_num *)ctx->stack_top[-1])->value.i;
1537
2
    else
1538
2
        width[1] = ((pdf_num *)ctx->stack_top[-1])->value.d;
1539
1540
741
    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
741
    if (ctx->text.current_enum == NULL) {
1550
0
        code = gs_note_error(gs_error_unknownerror);
1551
0
        goto d0_error;
1552
0
    }
1553
1554
741
    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
741
    if (ctx->pgs->level > gsave_level)
1573
0
        ctx->current_stream_save.gsave_level += ctx->pgs->level - gsave_level;
1574
1575
741
    if (code < 0)
1576
3
        goto d0_error;
1577
738
    pdfi_pop(ctx, 2);
1578
738
    return 0;
1579
1580
2.34k
d0_error:
1581
2.34k
    pdfi_clearstack(ctx);
1582
2.34k
    return code;
1583
741
}
1584
1585
int pdfi_d1(pdf_context *ctx)
1586
37.5k
{
1587
37.5k
    int code = 0, gsave_level;
1588
37.5k
    double wbox[6];
1589
1590
37.5k
    if (ctx->text.inside_CharProc == false)
1591
543
        pdfi_set_warning(ctx, 0, NULL, W_PDF_NOTINCHARPROC, "pdfi_d1", NULL);
1592
1593
37.5k
    ctx->text.CharProc_d_type = pdf_type3_d1;
1594
1595
37.5k
    code = pdfi_destack_reals(ctx, wbox, 6);
1596
37.5k
    if (code < 0)
1597
626
        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
36.9k
    gsave_level = ctx->pgs->level;
1607
1608
36.9k
    if (ctx->text.current_enum == NULL) {
1609
188
        code = gs_note_error(gs_error_unknownerror);
1610
188
        goto d1_error;
1611
188
    }
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
36.7k
    code = gs_text_setcachedevice(ctx->text.current_enum, wbox);
1637
36.7k
#endif
1638
1639
    /* See the comment immediately after gs_text_setcachedvice() in pdfi_d0 above */
1640
36.7k
    if (ctx->pgs->level > gsave_level)
1641
10.5k
        ctx->current_stream_save.gsave_level += ctx->pgs->level - gsave_level;
1642
1643
36.7k
    if (code < 0)
1644
21
        goto d1_error;
1645
36.7k
    return 0;
1646
1647
835
d1_error:
1648
835
    pdfi_clearstack(ctx);
1649
835
    return code;
1650
36.7k
}
1651
1652
int pdfi_Tf(pdf_context *ctx, pdf_dict *stream_dict, pdf_dict *page_dict)
1653
1.17M
{
1654
1.17M
    double point_size = 0;
1655
1.17M
    pdf_obj *point_arg = NULL;
1656
1.17M
    int code = 0;
1657
1.17M
    pdf_name *fontname = NULL;
1658
1659
1.17M
    if (pdfi_count_stack(ctx) < 2) {
1660
22.8k
        pdfi_clearstack(ctx);
1661
22.8k
        return_error(gs_error_stackunderflow);
1662
22.8k
    }
1663
1664
    /* Get refs to the args and pop them */
1665
1.15M
    point_arg = ctx->stack_top[-1];
1666
1.15M
    pdfi_countup(point_arg);
1667
1.15M
    fontname = (pdf_name *)ctx->stack_top[-2];
1668
1.15M
    pdfi_countup(fontname);
1669
1.15M
    pdfi_pop(ctx, 2);
1670
1671
    /* Get the point_size */
1672
1.15M
    code = pdfi_obj_to_real(ctx, point_arg, &point_size);
1673
1.15M
    if (code < 0)
1674
2.50k
        goto exit0;
1675
1676
1.15M
    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.15M
    if (code != gs_error_Fatal && code < 0)
1680
390k
        code = pdfi_font_set_internal_name(ctx, fontname, point_size);
1681
1.15M
 exit0:
1682
1.15M
    pdfi_countdown(fontname);
1683
1.15M
    pdfi_countdown(point_arg);
1684
1.15M
    return code;
1685
1.15M
}
1686
1687
int pdfi_free_font(pdf_obj *font)
1688
561k
{
1689
561k
    pdf_font *f = (pdf_font *)font;
1690
1691
561k
    switch (f->pdfi_font_type) {
1692
12.4k
        case e_pdf_font_type0:
1693
12.4k
            return pdfi_free_font_type0((pdf_obj *)font);
1694
0
            break;
1695
497k
        case e_pdf_font_type1:
1696
497k
            return pdfi_free_font_type1((pdf_obj *)font);
1697
0
            break;
1698
9.70k
        case e_pdf_font_cff:
1699
9.70k
            return pdfi_free_font_cff((pdf_obj *)font);
1700
2.59k
        case e_pdf_font_type3:
1701
2.59k
            return pdfi_free_font_type3((pdf_obj *)font);
1702
0
            break;
1703
24.2k
        case e_pdf_font_truetype:
1704
24.2k
            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.2k
        case e_pdf_cidfont_type2:
1710
13.2k
            return pdfi_free_font_cidtype2((pdf_obj *)font);
1711
0
            break;
1712
1.45k
        case e_pdf_cidfont_type0:
1713
1.45k
            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
561k
    }
1721
0
    return 0;
1722
561k
}
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
18.0k
{
1728
18.0k
    uint esize = Encoding->size;
1729
18.0k
    uint best = esize / 3;  /* must match at least this many */
1730
18.0k
    int i, index, near_index = ENCODING_INDEX_UNKNOWN, code;
1731
1732
141k
    for (index = 0; index < NUM_KNOWN_REAL_ENCODINGS; ++index) {
1733
124k
        uint match = esize;
1734
1735
15.3M
        for (i = esize; --i >= 0;) {
1736
15.3M
            gs_const_string rstr;
1737
15.3M
            pdf_name *ename;
1738
1739
15.3M
            code = pdfi_array_get_type(ctx, Encoding, (uint64_t)i, PDF_NAME, (pdf_obj **)&ename);
1740
15.3M
            if (code < 0) {
1741
16
                return;
1742
16
            }
1743
1744
15.3M
            gs_c_glyph_name(gs_c_known_encode((gs_char)i, index), &rstr);
1745
15.3M
            if (rstr.size == ename->length &&
1746
7.10M
                !memcmp(rstr.data, ename->data, rstr.size)) {
1747
6.64M
                pdfi_countdown(ename);
1748
6.64M
                continue;
1749
6.64M
            }
1750
8.67M
            pdfi_countdown(ename);
1751
8.67M
            if (--match <= best) {
1752
93.1k
                break;
1753
93.1k
            }
1754
8.67M
        }
1755
124k
        if (match > best) {
1756
31.2k
            best = match;
1757
31.2k
            near_index = index;
1758
            /* If we have a perfect match, stop now. */
1759
31.2k
            if (best == esize)
1760
692
                break;
1761
31.2k
        }
1762
124k
    }
1763
18.0k
    if (best == esize) *ind = index;
1764
18.0k
    *near_ind = near_index;
1765
18.0k
}
1766
1767
static inline int pdfi_encoding_name_to_index(pdf_name *name)
1768
114k
{
1769
114k
    int ind = gs_error_undefined;
1770
114k
    if (pdfi_type_of(name) == PDF_NAME) {
1771
114k
        if (pdfi_name_is(name, "StandardEncoding")) {
1772
55.4k
            ind = ENCODING_INDEX_STANDARD;
1773
59.1k
        } else if (pdfi_name_is(name, "WinAnsiEncoding")) {
1774
49.0k
            ind = ENCODING_INDEX_WINANSI;
1775
49.0k
        }
1776
10.1k
        else if (pdfi_name_is(name, "MacRomanEncoding")) {
1777
9.73k
            ind = ENCODING_INDEX_MACROMAN;
1778
9.73k
        }
1779
405
        else if (pdfi_name_is(name, "MacExpertEncoding")) {
1780
32
            ind = ENCODING_INDEX_MACEXPERT;
1781
32
        }
1782
373
        else if (pdfi_name_is(name, "SymbolEncoding")) {
1783
0
            ind = ENCODING_INDEX_SYMBOL;
1784
0
        }
1785
373
        else if (pdfi_name_is(name, "DingbatsEncoding")) {
1786
0
            ind = ENCODING_INDEX_DINGBATS;
1787
0
        }
1788
114k
    }
1789
114k
    return ind;
1790
114k
}
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
111k
{
1798
111k
    int i, code = 0;
1799
111k
    unsigned char gs_encoding;
1800
111k
    gs_glyph temp;
1801
111k
    gs_const_string str;
1802
111k
    pdf_name *n = NULL;
1803
1804
111k
    if (pdfi_array_size(Encoding) < 256)
1805
0
        return gs_note_error(gs_error_rangecheck);
1806
1807
111k
    code = pdfi_encoding_name_to_index(name);
1808
111k
    if (code < 0)
1809
359
        return code;
1810
111k
    if (ind != NULL) *ind = (gs_encoding_index_t)code;
1811
111k
    gs_encoding = (unsigned char)code;
1812
111k
    code = 0;
1813
1814
28.5M
    for (i = 0;i<256;i++) {
1815
28.4M
        temp = gs_c_known_encode(i, gs_encoding);
1816
28.4M
        gs_c_glyph_name(temp, &str);
1817
28.4M
        code = pdfi_name_alloc(ctx, (byte *)str.data, str.size, (pdf_obj **)&n);
1818
28.4M
        if (code < 0)
1819
0
            return code;
1820
28.4M
        pdfi_countup(n);
1821
28.4M
        code = pdfi_array_put(ctx, Encoding, (uint64_t)i, (pdf_obj *)n);
1822
28.4M
        pdfi_countdown(n);
1823
28.4M
        if (code < 0)
1824
0
            return code;
1825
28.4M
    }
1826
111k
    return 0;
1827
111k
}
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
120k
{
1840
120k
    int code = 0, i;
1841
120k
    gs_encoding_index_t encoding_index = ENCODING_INDEX_UNKNOWN, nearest_encoding_index = ENCODING_INDEX_UNKNOWN;
1842
1843
120k
    code = pdfi_array_alloc(ctx, 256, (pdf_array **)Encoding);
1844
120k
    if (code < 0)
1845
0
        return code;
1846
120k
    pdfi_countup(*Encoding);
1847
1848
120k
    switch (pdfi_type_of(pdf_Encoding)) {
1849
101k
        case PDF_NAME:
1850
101k
            code = pdfi_build_Encoding(ctx, (pdf_name *)pdf_Encoding, (pdf_array *)*Encoding, &encoding_index);
1851
101k
            if (code < 0) {
1852
359
                pdfi_countdown(*Encoding);
1853
359
                *Encoding = NULL;
1854
359
                return code;
1855
359
            }
1856
100k
            nearest_encoding_index = encoding_index;
1857
100k
            break;
1858
18.5k
        case PDF_DICT:
1859
18.5k
        {
1860
18.5k
            pdf_name *n = NULL;
1861
18.5k
            pdf_array *a = NULL;
1862
18.5k
            pdf_obj *o = NULL;
1863
18.5k
            int offset = 0;
1864
18.5k
            bool b_e_known;
1865
1866
18.5k
            if (pdfi_type_of(pdf_Encoding) == PDF_DICT) {
1867
18.5k
                code = pdfi_dict_known(ctx, (pdf_dict *)pdf_Encoding, "BaseEncoding", &b_e_known);
1868
18.5k
                if (code < 0)
1869
0
                    b_e_known = false;
1870
18.5k
            }
1871
0
            else {
1872
0
                b_e_known = false;
1873
0
            }
1874
1875
18.5k
            if (b_e_known == false && font_Encoding != NULL && pdfi_type_of(font_Encoding) == PDF_ARRAY) {
1876
8.17k
                pdf_array *fenc = (pdf_array *)font_Encoding;
1877
2.09M
                for (i = 0; i < pdfi_array_size(fenc) && code >= 0; i++) {
1878
2.08M
                    code = pdfi_array_get(ctx, fenc, (uint64_t)i, &o);
1879
2.08M
                    if (code >= 0)
1880
2.08M
                        code = pdfi_array_put(ctx, (pdf_array *)*Encoding, (uint64_t)i, o);
1881
2.08M
                    pdfi_countdown(o);
1882
2.08M
                }
1883
8.17k
                if (code < 0) {
1884
0
                    pdfi_countdown(*Encoding);
1885
0
                    *Encoding = NULL;
1886
0
                    return code;
1887
0
                }
1888
8.17k
            }
1889
10.3k
            else {
1890
10.3k
                code = pdfi_dict_get(ctx, (pdf_dict *)pdf_Encoding, "BaseEncoding", (pdf_obj **)&n);
1891
10.3k
                if (code >= 0) {
1892
3.04k
                    if (pdfi_encoding_name_to_index(n) < 0) {
1893
14
                        pdfi_set_warning(ctx, 0, NULL, W_PDF_INVALID_FONT_BASEENC, "pdfi_create_Encoding", NULL);
1894
14
                        pdfi_countdown(n);
1895
14
                        n = NULL;
1896
14
                        code = gs_error_undefined;
1897
14
                    }
1898
3.03k
                    else if (pdfi_name_is(n, "StandardEncoding") == true) {
1899
3
                        pdfi_set_warning(ctx, 0, NULL, W_PDF_INVALID_FONT_BASEENC, "pdfi_create_Encoding", NULL);
1900
3
                    }
1901
3.04k
                }
1902
1903
10.3k
                if (code < 0) {
1904
7.35k
                    code = pdfi_name_alloc(ctx, (byte *)"StandardEncoding", 16, (pdf_obj **)&n);
1905
7.35k
                    if (code < 0) {
1906
0
                        pdfi_countdown(*Encoding);
1907
0
                        *Encoding = NULL;
1908
0
                        return code;
1909
0
                    }
1910
7.35k
                    pdfi_countup(n);
1911
7.35k
                }
1912
1913
10.3k
                code = pdfi_build_Encoding(ctx, n, (pdf_array *)*Encoding, NULL);
1914
10.3k
                if (code < 0) {
1915
0
                    pdfi_countdown(*Encoding);
1916
0
                    *Encoding = NULL;
1917
0
                    pdfi_countdown(n);
1918
0
                    return code;
1919
0
                }
1920
10.3k
                pdfi_countdown(n);
1921
10.3k
            }
1922
18.5k
            code = pdfi_dict_knownget_type(ctx, (pdf_dict *)pdf_Encoding, "Differences", PDF_ARRAY, (pdf_obj **)&a);
1923
18.5k
            if (code <= 0) {
1924
411
                if (code < 0) {
1925
0
                    pdfi_countdown(*Encoding);
1926
0
                    *Encoding = NULL;
1927
0
                }
1928
411
                return code;
1929
411
            }
1930
1931
1.71M
            for (i=0;i < pdfi_array_size(a);i++) {
1932
1.69M
                pdf_obj_type type;
1933
1.69M
                code = pdfi_array_get(ctx, a, (uint64_t)i, &o);
1934
1.69M
                if (code < 0)
1935
8
                    break;
1936
1.69M
                type = pdfi_type_of(o);
1937
1.69M
                if (type == PDF_NAME) {
1938
1.53M
                    if (offset < pdfi_array_size((pdf_array *)*Encoding))
1939
1.53M
                        code = pdfi_array_put(ctx, (pdf_array *)*Encoding, (uint64_t)offset, o);
1940
1.53M
                    pdfi_countdown(o);
1941
1.53M
                    offset++;
1942
1.53M
                    if (code < 0)
1943
0
                        break;
1944
1.53M
                } else if (type == PDF_INT) {
1945
156k
                    offset = ((pdf_num *)o)->value.i;
1946
156k
                    pdfi_countdown(o);
1947
156k
                } else {
1948
58
                    code = gs_note_error(gs_error_typecheck);
1949
58
                    pdfi_countdown(o);
1950
58
                    break;
1951
58
                }
1952
1.69M
            }
1953
18.1k
            pdfi_countdown(a);
1954
18.1k
            if (code < 0) {
1955
66
                pdfi_countdown(*Encoding);
1956
66
                *Encoding = NULL;
1957
66
                return code;
1958
66
            }
1959
18.0k
            if (ppdffont != NULL) /* No sense doing this if we can't record the result */
1960
18.0k
                pdfi_gs_simple_font_encoding_indices(ctx, (pdf_array *)(*Encoding), &encoding_index, &nearest_encoding_index);
1961
18.0k
            break;
1962
18.1k
        }
1963
432
        default:
1964
432
            pdfi_countdown(*Encoding);
1965
432
            *Encoding = NULL;
1966
432
            return gs_note_error(gs_error_typecheck);
1967
120k
    }
1968
118k
    if (ppdffont != NULL) {
1969
72.6k
        ppdffont->pfont->encoding_index = encoding_index;
1970
72.6k
        ppdffont->pfont->nearest_encoding_index = nearest_encoding_index;
1971
72.6k
    }
1972
118k
    return 0;
1973
120k
}
1974
1975
gs_glyph pdfi_encode_char(gs_font * pfont, gs_char chr, gs_glyph_space_t not_used)
1976
76.2M
{
1977
76.2M
    int code;
1978
76.2M
    unsigned int nindex = 0;
1979
76.2M
    gs_glyph g = GS_NO_GLYPH;
1980
1981
76.2M
    if (pfont->FontType == ft_encrypted || pfont->FontType == ft_encrypted2
1982
606k
     || pfont->FontType == ft_user_defined || pfont->FontType == ft_TrueType
1983
606k
     || pfont->FontType == ft_MicroType
1984
76.2M
     || pfont->FontType == ft_PDF_user_defined) {
1985
76.2M
        pdf_font *font = (pdf_font *)pfont->client_data;
1986
76.2M
        pdf_context *ctx = (pdf_context *)font->ctx;
1987
1988
76.2M
        if (font->Encoding != NULL) { /* safety */
1989
76.2M
            pdf_name *GlyphName = NULL;
1990
76.2M
            code = pdfi_array_get(ctx, font->Encoding, (uint64_t)chr, (pdf_obj **)&GlyphName);
1991
76.2M
            if (code >= 0) {
1992
76.2M
                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
76.2M
                code = (*ctx->get_glyph_index)(pfont, (byte *)GlyphName->data, GlyphName->length, &nindex);
1997
76.2M
                pdfi_countdown(GlyphName);
1998
76.2M
                if (code >= 0)
1999
76.2M
                    g = (gs_glyph)nindex;
2000
76.2M
            }
2001
76.2M
        }
2002
76.2M
    }
2003
2004
76.2M
    return g;
2005
76.2M
}
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.52k
{
2013
6.52k
    int i;
2014
6.52k
    *decoding = NULL;
2015
6.52k
    *substnwp = NULL;
2016
    /* This only makes sense for Adobe orderings */
2017
6.52k
    if (reglen == 5 && !memcmp(reg, "Adobe", 5)) {
2018
35.0k
        for (i = 0; pdfi_cid_decoding_list[i] != NULL; i++) {
2019
29.3k
            if (strlen(pdfi_cid_decoding_list[i]->s_order) == ordlen &&
2020
551
                !memcmp(pdfi_cid_decoding_list[i]->s_order, ord, ordlen)) {
2021
233
                *decoding = (pdfi_cid_decoding_t *)pdfi_cid_decoding_list[i];
2022
233
                break;
2023
233
            }
2024
29.3k
        }
2025
        /* For now, also only for Adobe orderings */
2026
35.1k
        for (i = 0; pdfi_cid_substnwp_list[i] != NULL; i++) {
2027
29.4k
            if (strlen(pdfi_cid_substnwp_list[i]->ordering) == ordlen &&
2028
551
                !memcmp(pdfi_cid_substnwp_list[i]->ordering, ord, ordlen)) {
2029
233
                *substnwp = (pdfi_cid_subst_nwp_table_t *)pdfi_cid_substnwp_list[i];
2030
233
                break;
2031
233
            }
2032
29.4k
        }
2033
5.98k
    }
2034
6.52k
}
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.54M
{
2038
1.54M
    int i, l = 0;
2039
1.54M
    int code = gs_error_undefined;
2040
1.54M
    unsigned char *ucode = (unsigned char *)unicode_return;
2041
2042
1.54M
    if (tounicode != NULL) {
2043
364k
        gs_cmap_lookups_enum_t lenum;
2044
364k
        gs_cmap_lookups_enum_init((const gs_cmap_t *)tounicode->gscmap, 0, &lenum);
2045
8.75M
        while (l == 0 && gs_cmap_enum_next_lookup(ctx->memory, &lenum) == 0) {
2046
8.38M
            gs_cmap_lookups_enum_t counter = lenum;
2047
16.7M
            while (l == 0 && gs_cmap_enum_next_entry(&counter) == 0) {
2048
8.38M
                if (counter.entry.value_type == CODE_VALUE_CID) {
2049
8.38M
                    if (counter.entry.key_is_range) {
2050
1.52M
                        unsigned int v0 = 0, v1 = 0;
2051
3.50M
                        for (i = 0; i < counter.entry.key_size; i++) {
2052
1.97M
                            v0 |= (counter.entry.key[0][counter.entry.key_size - i - 1]) << (i * 8);
2053
1.97M
                        }
2054
3.50M
                        for (i = 0; i < counter.entry.key_size; i++) {
2055
1.97M
                            v1 |= (counter.entry.key[1][counter.entry.key_size - i - 1]) << (i * 8);
2056
1.97M
                        }
2057
2058
1.52M
                        if (ch >= v0 && ch <= v1) {
2059
144k
                            unsigned int offs = ch - v0;
2060
2061
144k
                            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
144k
                            else if (counter.entry.value.size == 2) {
2069
143k
                                l = 2;
2070
143k
                                if (ucode != NULL && length >= l) {
2071
106k
                                    ucode[0] = counter.entry.value.data[0] + ((offs >> 8) & 0xff);
2072
106k
                                    ucode[1] = counter.entry.value.data[1] + (offs & 0xff);
2073
106k
                                }
2074
143k
                            }
2075
1.28k
                            else if (counter.entry.value.size == 3) {
2076
22
                                l = 4;
2077
22
                                if (ucode != NULL && length >= l) {
2078
11
                                    ucode[0] = 0;
2079
11
                                    ucode[1] = counter.entry.value.data[0] + ((offs >> 16) & 0xff);
2080
11
                                    ucode[2] = counter.entry.value.data[1] + ((offs >> 8) & 0xff);
2081
11
                                    ucode[3] = counter.entry.value.data[2] + (offs & 0xff);
2082
11
                                }
2083
22
                            }
2084
1.25k
                            else {
2085
1.25k
                                l = 4;
2086
1.25k
                                if (ucode != NULL && length >= l) {
2087
1.25k
                                    ucode[0] = counter.entry.value.data[0] + ((offs >> 24) & 0xff);
2088
1.25k
                                    ucode[1] = counter.entry.value.data[1] + ((offs >> 16) & 0xff);
2089
1.25k
                                    ucode[2] = counter.entry.value.data[2] + ((offs >> 8) & 0xff);
2090
1.25k
                                    ucode[3] = counter.entry.value.data[3] + (offs & 0xff);
2091
1.25k
                                }
2092
1.25k
                            }
2093
144k
                        }
2094
1.52M
                    }
2095
6.85M
                    else {
2096
6.85M
                        unsigned int v = 0;
2097
19.5M
                        for (i = 0; i < counter.entry.key_size; i++) {
2098
12.6M
                            v |= (counter.entry.key[0][counter.entry.key_size - i - 1]) << (i * 8);
2099
12.6M
                        }
2100
6.85M
                        if (ch == v) {
2101
167k
                            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
167k
                            else if (counter.entry.value.size == 2) {
2109
166k
                                l = 2;
2110
166k
                                if (ucode != NULL && length >= l) {
2111
113k
                                    ucode[0] = counter.entry.value.data[0];
2112
113k
                                    ucode[1] = counter.entry.value.data[1];
2113
113k
                                }
2114
166k
                            }
2115
524
                            else if (counter.entry.value.size == 3) {
2116
57
                                l = 4;
2117
57
                                if (ucode != NULL && length >= l) {
2118
34
                                    ucode[0] = 0;
2119
34
                                    ucode[1] = counter.entry.value.data[0];
2120
34
                                    ucode[2] = counter.entry.value.data[1];
2121
34
                                    ucode[3] = counter.entry.value.data[2];
2122
34
                                }
2123
57
                            }
2124
467
                            else {
2125
467
                                l = 4;
2126
467
                                if (ucode != NULL && length >= l) {
2127
381
                                    ucode[0] = counter.entry.value.data[0];
2128
381
                                    ucode[1] = counter.entry.value.data[1];
2129
381
                                    ucode[2] = counter.entry.value.data[2];
2130
381
                                    ucode[3] = counter.entry.value.data[3];
2131
381
                                }
2132
467
                            }
2133
167k
                        }
2134
6.85M
                    }
2135
8.38M
                }
2136
8.38M
            }
2137
8.38M
        }
2138
364k
        if (l > 0)
2139
312k
            code = l;
2140
364k
    }
2141
2142
1.54M
    return code;
2143
1.54M
}
2144
2145
int
2146
pdfi_cidfont_decode_glyph(gs_font *font, gs_glyph glyph, int ch, ushort *u, unsigned int length)
2147
490k
{
2148
490k
    gs_glyph cc = glyph < GS_MIN_CID_GLYPH ? glyph : glyph - GS_MIN_CID_GLYPH;
2149
490k
    pdf_cidfont_t *pcidfont = (pdf_cidfont_t *)font->client_data;
2150
490k
    int code = gs_error_undefined, i;
2151
490k
    uchar *unicode_return = (uchar *)u;
2152
490k
    pdfi_cid_subst_nwp_table_t *substnwp = pcidfont->substnwp;
2153
2154
490k
    code = gs_error_undefined;
2155
493k
    while (1) { /* Loop to make retrying with a substitute CID easier */
2156
        /* Favour the ToUnicode if one exists */
2157
493k
        code = pdfi_tounicode_char_to_unicode(pcidfont->ctx, (pdf_cmap *)pcidfont->ToUnicode, glyph, ch, u, length);
2158
2159
493k
        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
493k
        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
490k
        break;
2228
493k
    }
2229
490k
    return (code < 0 ? 0 : code);
2230
490k
}
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
540k
{
2236
540k
    pdf_font *pdffont = (pdf_font *)font->client_data;
2237
540k
    int code = 0;
2238
2239
540k
    if (pdffont->pdfi_font_type != e_pdf_cidfont_type0 && pdffont->pdfi_font_type != e_pdf_cidfont_type1
2240
539k
     && pdffont->pdfi_font_type != e_pdf_cidfont_type2 && pdffont->pdfi_font_type != e_pdf_cidfont_type4) {
2241
539k
        code = pdfi_tounicode_char_to_unicode(pdffont->ctx, (pdf_cmap *)pdffont->ToUnicode, glyph, ch, unicode_return, length);
2242
539k
    }
2243
540k
    if (code < 0) code = 0;
2244
2245
540k
    return code;
2246
540k
}
2247
2248
int pdfi_glyph_index(gs_font *pfont, byte *str, uint size, uint *glyph)
2249
1.88k
{
2250
1.88k
    int code = 0;
2251
1.88k
    pdf_font *font = (pdf_font *)pfont->client_data;
2252
2253
1.88k
    code = pdfi_get_name_index(font->ctx, (char *)str, size, glyph);
2254
2255
1.88k
    return code;
2256
1.88k
}
2257
2258
int pdfi_glyph_name(gs_font * pfont, gs_glyph glyph, gs_const_string * pstr)
2259
1.10k
{
2260
1.10k
    int code = gs_error_invalidfont;
2261
2262
1.10k
    if (pfont->FontType == ft_encrypted || pfont->FontType == ft_encrypted2
2263
0
     || pfont->FontType == ft_user_defined || pfont->FontType == ft_TrueType
2264
1.10k
     || pfont->FontType == ft_PDF_user_defined || pfont->FontType == ft_MicroType) {
2265
1.10k
        pdf_font *font = (pdf_font *)pfont->client_data;
2266
2267
1.10k
        code = pdfi_name_from_index(font->ctx, glyph, (unsigned char **)&pstr->data, &pstr->size);
2268
1.10k
    }
2269
2270
1.10k
    return code;
2271
1.10k
}
2272
2273
2274
static int pdfi_global_glyph_code(const gs_font *pfont, gs_const_string *gstr, gs_glyph *pglyph)
2275
11
{
2276
11
    int code = 0;
2277
11
    if (pfont->FontType == ft_encrypted) {
2278
4
        code = pdfi_t1_global_glyph_code(pfont, gstr, pglyph);
2279
4
    }
2280
7
    else if (pfont->FontType == ft_encrypted2) {
2281
7
        code = pdfi_cff_global_glyph_code(pfont, gstr, pglyph);
2282
7
    }
2283
0
    else {
2284
0
        code = gs_note_error(gs_error_invalidaccess);
2285
0
    }
2286
11
    return code;
2287
11
}
2288
2289
int pdfi_map_glyph_name_via_agl(pdf_dict *cstrings, pdf_name *gname, pdf_string **cstring)
2290
392k
{
2291
392k
    single_glyph_list_t *sgl = (single_glyph_list_t *)&(SingleGlyphList);
2292
392k
    int i, code, ucode = gs_error_undefined;
2293
392k
    *cstring = NULL;
2294
2295
392k
    if (gname->length == 7 && strncmp((char *)gname->data, "uni", 3) == 0) {
2296
3.23k
        char u[5] = {0};
2297
3.23k
        memcpy(u, gname->data + 3, 4);
2298
3.23k
        code = sscanf(u, "%x", &ucode);
2299
3.23k
        if (code <= 0)
2300
0
            ucode = gs_error_undefined;
2301
3.23k
    }
2302
2303
392k
    if (ucode == gs_error_undefined) {
2304
1.43G
        for (i = 0; sgl[i].Glyph != 0x00; i++) {
2305
1.43G
            if (sgl[i].Glyph[0] == gname->data[0]
2306
29.5M
                && strlen(sgl[i].Glyph) == gname->length
2307
492k
                && !strncmp((char *)sgl[i].Glyph, (char *)gname->data, gname->length)) {
2308
132k
                ucode = (int)sgl[i].Unicode;
2309
132k
                break;
2310
132k
            }
2311
1.43G
        }
2312
389k
    }
2313
392k
    if (ucode > 0) {
2314
564M
        for (i = 0; sgl[i].Glyph != 0x00; i++) {
2315
564M
            if (sgl[i].Unicode == (unsigned short)ucode) {
2316
137k
                pdf_string *s;
2317
137k
                code = pdfi_dict_get((pdf_context *)cstrings->ctx, cstrings, (char *)sgl[i].Glyph, (pdf_obj **)&s);
2318
137k
                if (code >= 0) {
2319
2.49k
                    *cstring = s;
2320
2.49k
                    break;
2321
2.49k
                }
2322
137k
            }
2323
564M
        }
2324
135k
        if (*cstring == NULL) {
2325
133k
            char u[16] = {0};
2326
133k
            code = gs_snprintf(u, 16, "uni%04x", ucode);
2327
133k
            if (code > 0) {
2328
133k
                pdf_string *s;
2329
133k
                code = pdfi_dict_get((pdf_context *)cstrings->ctx, cstrings, u, (pdf_obj **)&s);
2330
133k
                if (code >= 0) {
2331
2
                    *cstring = s;
2332
2
                }
2333
133k
            }
2334
133k
        }
2335
135k
    }
2336
2337
392k
    if (*cstring == NULL)
2338
389k
        code = gs_note_error(gs_error_undefined);
2339
2.50k
    else
2340
2.50k
        code = 0;
2341
2342
392k
    return code;
2343
392k
}
2344
2345
2346
int pdfi_init_font_directory(pdf_context *ctx)
2347
94.1k
{
2348
94.1k
    gs_font_dir *pfdir = ctx->memory->gs_lib_ctx->font_dir;
2349
94.1k
    if (pfdir) {
2350
83.0k
        ctx->font_dir = gs_font_dir_alloc2_limits(ctx->memory, ctx->memory,
2351
83.0k
                   pfdir->smax, pfdir->ccache.bmax, pfdir->fmcache.mmax,
2352
83.0k
                   pfdir->ccache.cmax, pfdir->ccache.upper);
2353
83.0k
        if (ctx->font_dir == NULL) {
2354
0
            return_error(gs_error_VMerror);
2355
0
        }
2356
83.0k
        ctx->font_dir->align_to_pixels = pfdir->align_to_pixels;
2357
83.0k
        ctx->font_dir->grid_fit_tt = pfdir->grid_fit_tt;
2358
83.0k
    }
2359
11.0k
    else {
2360
11.0k
        ctx->font_dir = gs_font_dir_alloc2(ctx->memory, ctx->memory);
2361
11.0k
        if (ctx->font_dir == NULL) {
2362
0
            return_error(gs_error_VMerror);
2363
0
        }
2364
11.0k
    }
2365
94.1k
    ctx->font_dir->global_glyph_code = pdfi_global_glyph_code;
2366
94.1k
    return 0;
2367
94.1k
}
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
404k
{
2375
404k
    pdf_obj *fname = NULL;
2376
404k
    pdf_obj *fontobjtype = NULL;
2377
404k
    pdf_dict *fdict = NULL;
2378
404k
    int code;
2379
404k
    gs_font *pgsfont = NULL;
2380
404k
    const char *fs = "Font";
2381
404k
    pdf_name *Type1Name = NULL;
2382
2383
404k
    code = pdfi_name_alloc(ctx, (byte *)fontname, length, &fname);
2384
404k
    if (code < 0)
2385
0
        return code;
2386
404k
    pdfi_countup(fname);
2387
2388
404k
    code = pdfi_name_alloc(ctx, (byte *)fs, strlen(fs), &fontobjtype);
2389
404k
    if (code < 0)
2390
0
        goto exit;
2391
404k
    pdfi_countup(fontobjtype);
2392
2393
404k
    code = pdfi_dict_alloc(ctx, 1, &fdict);
2394
404k
    if (code < 0)
2395
0
        goto exit;
2396
404k
    pdfi_countup(fdict);
2397
2398
404k
    code = pdfi_dict_put(ctx, fdict, "BaseFont", fname);
2399
404k
    if (code < 0)
2400
0
        goto exit;
2401
2402
404k
    code = pdfi_dict_put(ctx, fdict, "Type", fontobjtype);
2403
404k
    if (code < 0)
2404
0
        goto exit;
2405
2406
404k
    code = pdfi_obj_charstr_to_name(ctx, "Type1", &Type1Name);
2407
404k
    if (code < 0)
2408
0
        goto exit;
2409
2410
404k
    code = pdfi_dict_put(ctx, fdict, "Subtype", (pdf_obj *)Type1Name);
2411
404k
    if (code < 0)
2412
0
        goto exit;
2413
2414
404k
    code = pdfi_load_font(ctx, NULL, NULL, fdict, &pgsfont, false);
2415
404k
    if (code < 0)
2416
0
        goto exit;
2417
2418
404k
    *ppdffont = (pdf_obj *)pgsfont->client_data;
2419
2420
404k
 exit:
2421
404k
    pdfi_countdown(Type1Name);
2422
404k
    pdfi_countdown(fontobjtype);
2423
404k
    pdfi_countdown(fname);
2424
404k
    pdfi_countdown(fdict);
2425
404k
    return code;
2426
404k
}
2427
2428
2429
int pdfi_font_create_widths(pdf_context *ctx, pdf_dict *fontdict, pdf_font *font, double scale)
2430
487k
{
2431
487k
    int code = 0;
2432
487k
    pdf_obj *obj = NULL;
2433
487k
    int i;
2434
2435
487k
    font->Widths = NULL;
2436
2437
487k
    if (font->FontDescriptor != NULL) {
2438
62.2k
        code = pdfi_dict_knownget(ctx, font->FontDescriptor, "MissingWidth", &obj);
2439
62.2k
        if (code > 0) {
2440
5.36k
            if (pdfi_type_of(obj) == PDF_INT) {
2441
5.36k
                font->MissingWidth = ((pdf_num *) obj)->value.i * scale;
2442
5.36k
            }
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.36k
            pdfi_countdown(obj);
2450
5.36k
            obj = NULL;
2451
5.36k
        }
2452
56.9k
        else {
2453
56.9k
            font->MissingWidth = 0;
2454
56.9k
        }
2455
62.2k
    }
2456
424k
    else {
2457
424k
        font->MissingWidth = 0;
2458
424k
    }
2459
2460
487k
    code = pdfi_dict_knownget_type(ctx, fontdict, "Widths", PDF_ARRAY, (pdf_obj **)&obj);
2461
487k
    if (code > 0) {
2462
66.4k
        if (pdfi_array_size((pdf_array *)obj) < font->LastChar - font->FirstChar + 1) {
2463
2.07k
            code = gs_note_error(gs_error_rangecheck);
2464
2.07k
            goto error;
2465
2.07k
        }
2466
2467
64.3k
        font->Widths = (double *)gs_alloc_bytes(OBJ_MEMORY(font), (size_t)sizeof(double) * (font->LastChar - font->FirstChar + 1), "pdfi_font_create_widths(Widths)");
2468
64.3k
        if (font->Widths == NULL) {
2469
0
            code = gs_note_error(gs_error_VMerror);
2470
0
            goto error;
2471
0
        }
2472
64.3k
        memset(font->Widths, 0x00, sizeof(double) * (font->LastChar - font->FirstChar + 1));
2473
6.46M
        for (i = 0; i < (font->LastChar - font->FirstChar + 1); i++) {
2474
6.39M
            code = pdfi_array_get_number(ctx, (pdf_array *)obj, (uint64_t)i, &font->Widths[i]);
2475
6.39M
            if (code < 0)
2476
224
                goto error;
2477
6.39M
            font->Widths[i] *= scale;
2478
6.39M
        }
2479
64.3k
    }
2480
487k
error:
2481
487k
    pdfi_countdown(obj);
2482
487k
    if (code < 0) {
2483
5.41k
        gs_free_object(OBJ_MEMORY(font), font->Widths, "pdfi_font_create_widths(Widths)");
2484
5.41k
        font->Widths = NULL;
2485
5.41k
    }
2486
487k
    return code;
2487
487k
}
2488
2489
void pdfi_font_set_first_last_char(pdf_context *ctx, pdf_dict *fontdict, pdf_font *font)
2490
530k
{
2491
530k
    double f, l;
2492
530k
    int code;
2493
2494
530k
    if (fontdict == NULL) {
2495
43.4k
        f = (double)0;
2496
43.4k
        l = (double)255;
2497
43.4k
    }
2498
487k
    else {
2499
487k
        code = pdfi_dict_get_number(ctx, fontdict, "FirstChar", &f);
2500
487k
        if (code < 0 || f < 0 || f > 255)
2501
417k
            f = (double)0;
2502
2503
487k
        code = pdfi_dict_get_number(ctx, fontdict, "LastChar", &l);
2504
487k
        if (code < 0 || l < 0 || l > 255)
2505
417k
            l = (double)255;
2506
487k
    }
2507
530k
    if (f <= l) {
2508
530k
        font->FirstChar = (int)f;
2509
530k
        font->LastChar = (int)l;
2510
530k
    }
2511
52
    else {
2512
52
        font->FirstChar = 0;
2513
52
        font->LastChar = 255;
2514
52
    }
2515
530k
}
2516
2517
void pdfi_font_set_orig_fonttype(pdf_context *ctx, pdf_font *font)
2518
537k
{
2519
537k
    pdf_name *ftype;
2520
537k
    pdf_dict *fontdict = font->PDF_font;
2521
537k
    int code;
2522
2523
537k
    code = pdfi_dict_get_type(ctx, fontdict, "Subtype", PDF_NAME, (pdf_obj**)&ftype);
2524
537k
    if (code < 0) {
2525
44.0k
        font->orig_FontType = ft_undefined;
2526
44.0k
    }
2527
493k
    else {
2528
493k
        if (pdfi_name_is(ftype, "Type1") || pdfi_name_is(ftype, "MMType1"))
2529
439k
            font->orig_FontType = ft_encrypted;
2530
54.0k
        else if (pdfi_name_is(ftype, "Type1C"))
2531
0
            font->orig_FontType = ft_encrypted2;
2532
54.0k
        else if (pdfi_name_is(ftype, "TrueType"))
2533
38.2k
            font->orig_FontType = ft_TrueType;
2534
15.7k
        else if (pdfi_name_is(ftype, "Type3"))
2535
2.11k
            font->orig_FontType = ft_user_defined;
2536
13.6k
        else if (pdfi_name_is(ftype, "CIDFontType0"))
2537
2.53k
            font->orig_FontType = ft_CID_encrypted;
2538
11.1k
        else if (pdfi_name_is(ftype, "CIDFontType2"))
2539
10.4k
            font->orig_FontType = ft_CID_TrueType;
2540
632
        else
2541
632
            font->orig_FontType = ft_undefined;
2542
493k
    }
2543
537k
    pdfi_countdown(ftype);
2544
537k
}
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
87.6k
{
2555
87.6k
    gs_const_string fn;
2556
87.6k
    int i;
2557
87.6k
    uint32_t hash = 0;
2558
87.6k
    long *xvalues;
2559
87.6k
    int xuidlen = 3;
2560
2561
87.6k
    sfilename(ctx->main_stream->s, &fn);
2562
87.6k
    if (fontdict!= NULL && fontdict->object_num != 0) {
2563
39.2k
        const byte *sb;
2564
39.2k
        size_t l;
2565
39.2k
        if (fn.size > 0) {
2566
6
            sb = fn.data;
2567
6
            l = fn.size;
2568
6
        }
2569
39.2k
        else {
2570
39.2k
            s_process_read_buf(ctx->main_stream->s);
2571
39.2k
            sb = sbufptr(ctx->main_stream->s);
2572
39.2k
            l = sbufavailable(ctx->main_stream->s) > 128 ? 128: sbufavailable(ctx->main_stream->s);
2573
39.2k
        }
2574
2575
5.05M
        for (i = 0; i < l; i++) {
2576
5.01M
            hash = ((((hash & 0xf8000000) >> 27) ^ (hash << 5)) & 0x7ffffffff) ^ sb[i];
2577
5.01M
        }
2578
39.2k
        hash = ((((hash & 0xf8000000) >> 27) ^ (hash << 5)) & 0x7ffffffff) ^ fontdict->object_num;
2579
2580
39.2k
        if (uid_is_XUID(&pfont->UID) && uid_XUID_size(&pfont->UID) > 2 && uid_XUID_values(&pfont->UID)[0] == 1000000) {
2581
            /* This is already a pseudo XUID, probably because we are copying an existing font object
2582
             * So just update the hash and the object number
2583
             */
2584
415
             uid_XUID_values(&pfont->UID)[1] = hash;
2585
415
             uid_XUID_values(&pfont->UID)[2] = ctx->device_state.HighLevelDevice ? fontdict->object_num : 0;
2586
415
        }
2587
38.8k
        else {
2588
38.8k
            if (uid_is_XUID(&pfont->UID))
2589
1.62k
                xuidlen += uid_XUID_size(&pfont->UID);
2590
37.2k
            else if (uid_is_valid(&pfont->UID))
2591
548
                xuidlen++;
2592
2593
38.8k
            xvalues = (long *)gs_alloc_bytes(pfont->memory, (size_t)xuidlen * sizeof(long), "pdfi_font_generate_pseudo_XUID");
2594
38.8k
            if (xvalues == NULL) {
2595
0
                return 0;
2596
0
            }
2597
38.8k
            xvalues[0] = 1000000; /* "Private" value */
2598
38.8k
            xvalues[1] = hash;
2599
2600
38.8k
            xvalues[2] = ctx->device_state.HighLevelDevice ? fontdict->object_num : 0;
2601
2602
38.8k
            if (uid_is_XUID(&pfont->UID)) {
2603
10.2k
                for (i = 0; i < uid_XUID_size(&pfont->UID); i++) {
2604
8.57k
                    xvalues[i + 3] = uid_XUID_values(&pfont->UID)[i];
2605
8.57k
                }
2606
1.62k
                uid_free(&pfont->UID, pfont->memory, "pdfi_font_generate_pseudo_XUID");
2607
1.62k
            }
2608
37.2k
            else if (uid_is_valid(&pfont->UID))
2609
548
                xvalues[3] = pfont->UID.id;
2610
2611
38.8k
            uid_set_XUID(&pfont->UID, xvalues, xuidlen);
2612
38.8k
        }
2613
39.2k
    }
2614
87.6k
    return 0;
2615
87.6k
}
2616
2617
int pdfi_default_font_info(gs_font *font, const gs_point *pscale, int members, gs_font_info_t *info)
2618
100k
{
2619
100k
    pdf_font *pdff = (pdf_font *)font->client_data;
2620
100k
    int code;
2621
2622
    /* We *must* call this first as it sets info->members = 0; */
2623
100k
    code = pdff->default_font_info(font, pscale, members, info);
2624
100k
    if (code < 0)
2625
7.36k
        return code;
2626
93.1k
    if ((members & FONT_INFO_EMBEDDED) != 0) {
2627
93.1k
        info->orig_FontType = pdff->orig_FontType;
2628
93.1k
        if (pdff->pdfi_font_type == e_pdf_font_type3) {
2629
715
            info->FontEmbedded = (int)(true);
2630
715
            info->members |= FONT_INFO_EMBEDDED;
2631
715
        }
2632
92.4k
        else {
2633
92.4k
            info->FontEmbedded = (int)(pdff->substitute == font_embedded);
2634
92.4k
            info->members |= FONT_INFO_EMBEDDED;
2635
92.4k
        }
2636
93.1k
    }
2637
93.1k
    if (pdff->pdfi_font_type != e_pdf_font_truetype && pdff->pdfi_font_type != e_pdf_cidfont_type2) {
2638
56.5k
        if (((members & FONT_INFO_COPYRIGHT) != 0) && pdff->copyright != NULL) {
2639
33.4k
            info->Copyright.data = pdff->copyright->data;
2640
33.4k
            info->Copyright.size = pdff->copyright->length;
2641
33.4k
            info->members |= FONT_INFO_COPYRIGHT;
2642
33.4k
        }
2643
56.5k
        if (((members & FONT_INFO_NOTICE) != 0) && pdff->notice != NULL) {
2644
35.8k
            info->Notice.data = pdff->notice->data;
2645
35.8k
            info->Notice.size = pdff->notice->length;
2646
35.8k
            info->members |= FONT_INFO_NOTICE;
2647
35.8k
        }
2648
56.5k
        if (((members & FONT_INFO_FAMILY_NAME) != 0) && pdff->familyname != NULL) {
2649
35.8k
            info->FamilyName.data = pdff->familyname->data;
2650
35.8k
            info->FamilyName.size = pdff->familyname->length;
2651
35.8k
            info->members |= FONT_INFO_FAMILY_NAME;
2652
35.8k
        }
2653
56.5k
        if (((members & FONT_INFO_FULL_NAME) != 0) && pdff->fullname != NULL) {
2654
35.8k
            info->FullName.data = pdff->fullname->data;
2655
35.8k
            info->FullName.size = pdff->fullname->length;
2656
35.8k
            info->members |= FONT_INFO_FULL_NAME;
2657
35.8k
        }
2658
56.5k
    }
2659
93.1k
    return 0;
2660
100k
}
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
404k
{
2667
404k
    int code;
2668
404k
    pdf_font *pdffont = (pdf_font *)fontobj;
2669
2670
404k
    if (pdfi_type_of(pdffont) != PDF_FONT || pdffont->pfont == NULL)
2671
0
        return_error(gs_error_invalidfont);
2672
2673
404k
    code = gs_setPDFfontsize(ctx->pgs, point_size);
2674
404k
    if (code < 0)
2675
0
        return code;
2676
2677
404k
    return pdfi_gs_setfont(ctx, (gs_font *)pdffont->pfont);
2678
404k
}
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
404k
{
2686
404k
    int code = 0;
2687
404k
    pdf_obj *font = NULL;
2688
2689
2690
404k
    code = pdfi_load_font_by_name_string(ctx, fontname, length, &font);
2691
404k
    if (code < 0) goto exit;
2692
2693
404k
    code = pdfi_set_font_internal(ctx, font, point_size);
2694
2695
404k
 exit:
2696
404k
    pdfi_countdown(font);
2697
404k
    return code;
2698
404k
}
2699
2700
int pdfi_font_set_internal_string(pdf_context *ctx, const char *fontname, double point_size)
2701
14.0k
{
2702
14.0k
    return pdfi_font_set_internal_inner(ctx, (const byte *)fontname, strlen(fontname), point_size);
2703
14.0k
}
2704
2705
int pdfi_font_set_internal_name(pdf_context *ctx, pdf_name *fontname, double point_size)
2706
390k
{
2707
390k
    if (pdfi_type_of(fontname) != PDF_NAME)
2708
0
        return_error(gs_error_typecheck);
2709
390k
    else
2710
390k
        return pdfi_font_set_internal_inner(ctx, fontname->data, fontname->length, point_size);
2711
390k
}