Coverage Report

Created: 2026-10-28 08:05

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.04M
{
48
1.04M
    int code = 0;
49
1.04M
    pdfi_int_gstate *igs = (pdfi_int_gstate *)ctx->pgs->client_data;
50
1.04M
    pdf_font *old_font = igs->current_font;
51
52
1.04M
    code = gs_setfont(ctx->pgs, pfont);
53
1.04M
    if (code >= 0) {
54
1.04M
        igs->current_font = (pdf_font *)pfont->client_data;
55
1.04M
        pdfi_countup(igs->current_font);
56
1.04M
        pdfi_countdown(old_font);
57
1.04M
    }
58
1.04M
    return code;
59
1.04M
}
60
61
static void pdfi_cache_resource_font(pdf_context *ctx, pdf_obj *fontdesc, pdf_obj *ppdffont)
62
28.6k
{
63
28.6k
    resource_font_cache_t *entry = NULL;
64
28.6k
    int i;
65
66
28.6k
    if (ctx->resource_font_cache == NULL) {
67
17.5k
        ctx->resource_font_cache = (resource_font_cache_t *)gs_alloc_bytes(ctx->memory, RESOURCE_FONT_CACHE_BLOCK_SIZE * sizeof(pdfi_name_entry_t), "pdfi_cache_resource_font");
68
17.5k
        if (ctx->resource_font_cache == NULL)
69
0
            return;
70
17.5k
        ctx->resource_font_cache_size = RESOURCE_FONT_CACHE_BLOCK_SIZE;
71
17.5k
        memset(ctx->resource_font_cache, 0x00, RESOURCE_FONT_CACHE_BLOCK_SIZE * sizeof(pdfi_name_entry_t));
72
17.5k
        entry = &ctx->resource_font_cache[0];
73
17.5k
    }
74
75
78.7k
    for (i = 0; entry == NULL && i < ctx->resource_font_cache_size; i++) {
76
50.0k
        if (ctx->resource_font_cache[i].pdffont == NULL) {
77
11.0k
            entry = &ctx->resource_font_cache[i];
78
11.0k
        }
79
38.9k
        else if (i == ctx->resource_font_cache_size - 1) {
80
3
            entry = (resource_font_cache_t *)gs_resize_object(ctx->memory, ctx->resource_font_cache, sizeof(pdfi_name_entry_t) * (ctx->resource_font_cache_size + RESOURCE_FONT_CACHE_BLOCK_SIZE), "pdfi_cache_resource_font");
81
3
            if (entry == NULL)
82
0
                break;
83
3
            memset(entry + ctx->resource_font_cache_size, 0x00, RESOURCE_FONT_CACHE_BLOCK_SIZE * sizeof(pdfi_name_entry_t));
84
3
            ctx->resource_font_cache = entry;
85
3
            entry = &ctx->resource_font_cache[ctx->resource_font_cache_size];
86
3
            ctx->resource_font_cache_size += RESOURCE_FONT_CACHE_BLOCK_SIZE;
87
3
        }
88
50.0k
    }
89
28.6k
    if (entry != NULL) {
90
28.6k
        entry->desc_obj_num = fontdesc->object_num;
91
28.6k
        entry->pdffont = ppdffont;
92
28.6k
        pdfi_countup(ppdffont);
93
28.6k
    }
94
28.6k
}
95
96
void pdfi_purge_cache_resource_font(pdf_context *ctx)
97
99.5k
{
98
99.5k
    int i;
99
661k
    for (i = 0; i < ctx->resource_font_cache_size; i++) {
100
562k
       pdfi_countdown(ctx->resource_font_cache[i].pdffont);
101
562k
    }
102
99.5k
    gs_free_object(ctx->memory, ctx->resource_font_cache, "pdfi_purge_cache_resource_font");
103
99.5k
    ctx->resource_font_cache = NULL;
104
99.5k
    ctx->resource_font_cache_size = 0;
105
99.5k
}
106
107
static int pdfi_find_cache_resource_font(pdf_context *ctx, pdf_obj *fontdesc, pdf_obj **ppdffont)
108
59.7k
{
109
59.7k
    int i, code = gs_error_undefined;
110
604k
    for (i = 0; i < ctx->resource_font_cache_size; i++) {
111
548k
        if (ctx->resource_font_cache[i].desc_obj_num == fontdesc->object_num) {
112
3.62k
           *ppdffont = ctx->resource_font_cache[i].pdffont;
113
3.62k
           pdfi_countup(*ppdffont);
114
3.62k
           code = 0;
115
3.62k
           break;
116
3.62k
        }
117
548k
    }
118
59.7k
    return code;
119
59.7k
}
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
556k
{
141
556k
    bool ignore = false;
142
556k
    int i;
143
556k
    pdf_name *nm = (pdf_name *)basefont;
144
145
556k
    if (basefont != NULL && pdfi_type_of(basefont) == PDF_NAME) {
146
2.53M
        for (i = 0; known_symbolic_font_names[i].name != NULL; i++) {
147
2.02M
            if (nm->length == known_symbolic_font_names[i].namelen
148
18.4k
             && !strncmp((char *)nm->data, known_symbolic_font_names[i].name, nm->length)) {
149
2.13k
                ignore = true;
150
2.13k
                break;
151
2.13k
            }
152
2.02M
        }
153
507k
    }
154
556k
    return ignore;
155
556k
}
156
157
static int
158
pdfi_font_match_glyph_widths(pdf_font *pdfont)
159
456k
{
160
456k
    int code = 0;
161
456k
    int i;
162
456k
    int sindex, lindex;
163
456k
    gs_font_base *pbfont = pdfont->pfont;
164
456k
    double fw = 0.0, ww = 0.0;
165
166
456k
    if (pdfont->LastChar <  pdfont->FirstChar || pdfont->Widths == NULL)
167
432k
        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
23.6k
    sindex = pdfont->FirstChar < 96 ? 96 : pdfont->FirstChar;
171
23.6k
    lindex = pdfont->LastChar > 122 ? 123 : pdfont->LastChar + 1;
172
173
415k
    for (i = sindex; i < lindex; i++) {
174
391k
        gs_glyph_info_t ginfo = {0};
175
391k
        gs_glyph g;
176
391k
        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
391k
        if (g != GS_NO_GLYPH && pdfont->Widths[i - pdfont->FirstChar] != 0.0
180
291k
          && (*pbfont->procs.glyph_info)((gs_font *)pbfont, g, NULL, GLYPH_INFO_WIDTH0, &ginfo) >= 0) {
181
290k
            fw += hypot(ginfo.width[0].x, ginfo.width[0].y);
182
290k
            ww += pdfont->Widths[i - pdfont->FirstChar];
183
290k
        }
184
391k
    }
185
    /* Only reduce font width, don't expand */
186
23.6k
    if (ww != 0.0 && fw != 0.0 && ww / fw < 1.0) {
187
7.43k
        gs_matrix nmat, smat = {1.0, 0.0, 0.0, 1.0, 0.0, 0.0};
188
7.43k
        double wscale;
189
7.43k
        smat.xx = smat.yy = ww/fw;
190
7.43k
        wscale = 1.0 / smat.xx;
191
192
7.43k
        gs_matrix_multiply(&pbfont->FontMatrix, &smat, &nmat);
193
7.43k
        memcpy(&pbfont->FontMatrix, &nmat, sizeof(pbfont->FontMatrix));
194
195
929k
        for (i = pdfont->FirstChar; i <= pdfont->LastChar; i++) {
196
922k
            pdfont->Widths[i - pdfont->FirstChar] *= wscale;
197
922k
        }
198
199
        /* Purging a font can be expensive, but in this case, we know
200
           we have no scaled instances (pdfi doesn't work that way)
201
           and we know we have no fm pairs, nor glyphs to purge (we
202
           *just* created the font!).
203
           So "purging" the font is really just removing it from the
204
           doubly linked list of font objects in the font directory
205
         */
206
7.43k
        code = gs_purge_font((gs_font *)pbfont);
207
7.43k
        if (code >= 0)
208
7.43k
            code = gs_definefont(pbfont->dir, (gs_font *)pbfont);
209
7.43k
        if (code >= 0)
210
7.43k
            code = pdfi_fapi_passfont((pdf_font *)pdfont, 0, NULL, NULL, NULL, 0);
211
7.43k
    }
212
213
23.6k
    return code;
214
456k
}
215
216
/* Print a name object to stdout */
217
static void pdfi_print_font_name(pdf_context *ctx, pdf_name *n)
218
485k
{
219
485k
    if (ctx->args.QUIET != true)
220
0
        (void)outwrite(ctx->memory, (const char *)n->data, n->length);
221
485k
}
222
223
static void pdfi_print_font_string(pdf_context *ctx, pdf_string *s)
224
473k
{
225
473k
    if (ctx->args.QUIET != true)
226
0
        (void)outwrite(ctx->memory, (const char *)s->data, s->length);
227
473k
}
228
229
/* Print a null terminated string to stdout */
230
static void pdfi_print_cstring(pdf_context *ctx, const char *str)
231
1.47M
{
232
1.47M
    if (ctx->args.QUIET != true)
233
0
        (void)outwrite(ctx->memory, str, strlen(str));
234
1.47M
}
235
236
/* Call with a CIDFont name to try to find the CIDFont on disk
237
   call if with ffname NULL to load the default fallback CIDFont
238
   substitue
239
   Currently only loads substitute - DroidSansFallback
240
 */
241
static int
242
pdfi_open_CIDFont_substitute_file(pdf_context *ctx, pdf_dict *font_dict, pdf_dict *fontdesc, bool fallback, byte ** buf, int64_t * buflen, int *findex)
243
26.8k
{
244
26.8k
    int code = 0;
245
26.8k
    char fontfname[gp_file_name_sizeof];
246
26.8k
    stream *s;
247
26.8k
    pdf_name *cidname = NULL;
248
26.8k
    gs_const_string fname;
249
250
26.8k
    (void)pdfi_dict_get(ctx, font_dict, "BaseFont", (pdf_obj **)&cidname);
251
252
26.8k
    if (fallback == true) {
253
13.4k
        pdf_string *mname = NULL;
254
13.4k
        pdf_dict *csi = NULL;
255
13.4k
        pdf_name *fbname;
256
13.4k
        const char *cidfbstr = "CIDFallBack";
257
258
13.4k
        code = pdfi_fontmap_lookup_cidfont(ctx, font_dict, NULL, (pdf_obj **)&mname, findex);
259
260
13.4k
        if (mname == NULL || pdfi_type_of(mname) != PDF_STRING) {
261
13.4k
            pdfi_countdown(mname);
262
263
13.4k
            code = pdfi_object_alloc(ctx, PDF_NAME, strlen(cidfbstr), (pdf_obj **)&fbname);
264
13.4k
            if (code >= 0) {
265
13.4k
                pdfi_countup(fbname);
266
13.4k
                memcpy(fbname->data, cidfbstr, strlen(cidfbstr));
267
13.4k
                code = pdfi_fontmap_lookup_cidfont(ctx, font_dict, fbname, (pdf_obj **)&mname, findex);
268
13.4k
                pdfi_countdown(fbname);
269
13.4k
            }
270
271
13.4k
            if (code < 0 || pdfi_type_of(mname) != PDF_STRING) {
272
13.4k
                pdfi_countdown(mname);
273
13.4k
                mname = NULL;
274
13.4k
                code = pdfi_dict_get(ctx, font_dict, "CIDSystemInfo", (pdf_obj **)&csi);
275
13.4k
                if (code >= 0 && pdfi_type_of(csi) == PDF_DICT) {
276
10.9k
                    pdf_string *csi_reg = NULL, *csi_ord = NULL;
277
278
10.9k
                    if (pdfi_dict_get(ctx, csi, "Registry", (pdf_obj **)&csi_reg) >= 0
279
10.9k
                     && pdfi_dict_get(ctx, csi, "Ordering", (pdf_obj **)&csi_ord) >= 0
280
10.8k
                     && pdfi_type_of(csi_reg) == PDF_STRING && pdfi_type_of(csi_ord) == PDF_STRING
281
10.8k
                     && csi_reg->length + csi_ord->length + 1 < gp_file_name_sizeof - 1) {
282
10.8k
                        pdf_name *reg_ord;
283
10.8k
                        memcpy(fontfname, csi_reg->data, csi_reg->length);
284
10.8k
                        memcpy(fontfname + csi_reg->length, "-", 1);
285
10.8k
                        memcpy(fontfname + csi_reg->length + 1, csi_ord->data, csi_ord->length);
286
10.8k
                        fontfname[csi_reg->length + csi_ord->length + 1] = '\0';
287
288
10.8k
                        code = pdfi_name_alloc(ctx, (byte *)fontfname, strlen(fontfname), (pdf_obj **) &reg_ord);
289
10.8k
                        if (code >= 0) {
290
10.8k
                            pdfi_countup(reg_ord);
291
10.8k
                            code = pdfi_fontmap_lookup_cidfont(ctx, font_dict, reg_ord, (pdf_obj **)&mname, findex);
292
10.8k
                            pdfi_countdown(reg_ord);
293
10.8k
                        }
294
10.8k
                    }
295
10.9k
                    pdfi_countdown(csi_reg);
296
10.9k
                    pdfi_countdown(csi_ord);
297
10.9k
                }
298
13.4k
                pdfi_countdown(csi);
299
13.4k
            }
300
301
13.4k
            if (mname == NULL || pdfi_type_of(mname) != PDF_STRING) {
302
13.4k
                pdfi_countdown(mname);
303
13.4k
                mname = NULL;
304
13.4k
                code = pdfi_fontmap_lookup_cidfont(ctx, font_dict, NULL, (pdf_obj **)&mname, findex);
305
13.4k
            }
306
13.4k
        }
307
308
13.4k
        do {
309
13.4k
            if (code < 0 || pdfi_type_of(mname) != PDF_STRING) {
310
13.4k
                const char *fsprefix = "CIDFSubst/";
311
13.4k
                int fsprefixlen = strlen(fsprefix);
312
13.4k
                const char *defcidfallack = "DroidSansFallback.ttf";
313
13.4k
                int defcidfallacklen = strlen(defcidfallack);
314
315
13.4k
                pdfi_countdown(mname);
316
317
13.4k
                if (ctx->args.nocidfallback == true) {
318
0
                    if (ctx->args.pdfstoponerror == true)
319
0
                        code = gs_note_error(gs_error_Fatal);
320
0
                    else
321
0
                        code = gs_note_error(gs_error_invalidfont);
322
0
                }
323
13.4k
                else {
324
13.4k
                    if (ctx->args.cidfsubstpath.data == NULL) {
325
13.4k
                        memcpy(fontfname, fsprefix, fsprefixlen);
326
13.4k
                    }
327
0
                    else {
328
0
                        if (ctx->args.cidfsubstpath.size > gp_file_name_sizeof - 1) {
329
0
                            code = gs_note_error(gs_error_rangecheck);
330
0
                            if ((code = pdfi_set_warning_stop(ctx, code, NULL, W_PDF_BAD_CONFIG, "pdfi_open_CIDFont_substitute_file", "CIDFSubstPath parameter too long")) < 0)
331
0
                                goto exit;
332
0
                            memcpy(fontfname, fsprefix, fsprefixlen);
333
0
                        }
334
0
                        else {
335
0
                            memcpy(fontfname, ctx->args.cidfsubstpath.data, ctx->args.cidfsubstpath.size);
336
0
                            fsprefixlen = ctx->args.cidfsubstpath.size;
337
0
                        }
338
0
                    }
339
340
13.4k
                    if (ctx->args.cidfsubstfont.data == NULL) {
341
13.4k
                        int len = 0;
342
13.4k
                        if (gp_getenv("CIDFSUBSTFONT", (char *)0, &len) < 0) {
343
0
                            if (len + fsprefixlen + 1 > gp_file_name_sizeof) {
344
0
                                code = gs_note_error(gs_error_rangecheck);
345
0
                                if ((code = pdfi_set_warning_stop(ctx, code, NULL, W_PDF_BAD_CONFIG, "pdfi_open_CIDFont_substitute_file", "CIDFSUBSTFONT environment variable too long")) < 0)
346
0
                                    goto exit;
347
348
0
                                if (defcidfallacklen + fsprefixlen > gp_file_name_sizeof - 1) {
349
0
                                    pdfi_set_warning(ctx, code, NULL, W_PDF_BAD_CONFIG, "pdfi_open_CIDFont_substitute_file", "CIDFSubstPath parameter too long");
350
0
                                    memcpy(fontfname, defcidfallack, defcidfallacklen);
351
0
                                    fsprefixlen = 0;
352
0
                                } else
353
0
                                    memcpy(fontfname + fsprefixlen, defcidfallack, defcidfallacklen);
354
0
                            }
355
0
                            else {
356
0
                                (void)gp_getenv("CIDFSUBSTFONT", (char *)(fontfname + fsprefixlen), &defcidfallacklen);
357
0
                            }
358
0
                        }
359
13.4k
                        else {
360
13.4k
                            if (fsprefixlen + defcidfallacklen > gp_file_name_sizeof - 1) {
361
0
                                code = gs_note_error(gs_error_rangecheck);
362
0
                                if ((code = pdfi_set_warning_stop(ctx, code, NULL, W_PDF_BAD_CONFIG, "pdfi_open_CIDFont_substitute_file", "CIDFSUBSTFONT environment variable too long")) < 0)
363
0
                                    goto exit;
364
365
0
                                memcpy(fontfname, defcidfallack, defcidfallacklen);
366
                                /* cidfsubstfont should either be a font name we find in the search path(s)
367
                                   or an absolute path.
368
                                 */
369
0
                                fsprefixlen = 0;
370
0
                            }
371
13.4k
                            else {
372
13.4k
                                memcpy(fontfname + fsprefixlen, defcidfallack, defcidfallacklen);
373
13.4k
                            }
374
13.4k
                        }
375
13.4k
                    }
376
0
                    else {
377
0
                        if (ctx->args.cidfsubstfont.size + fsprefixlen > gp_file_name_sizeof - 1) {
378
0
                            code = gs_note_error(gs_error_rangecheck);
379
0
                            if ((code = pdfi_set_warning_stop(ctx, code, NULL, W_PDF_BAD_CONFIG, "pdfi_open_CIDFont_substitute_file", "CIDFSubstFont parameter too long")) < 0)
380
0
                                goto exit;
381
382
0
                            if (fsprefixlen + defcidfallacklen > gp_file_name_sizeof - 1) {
383
0
                                pdfi_set_warning(ctx, code, NULL, W_PDF_BAD_CONFIG, "pdfi_open_CIDFont_substitute_file", "CIDFSubstPath parameter too long");
384
0
                                memcpy(fontfname, defcidfallack, defcidfallacklen);
385
0
                                fsprefixlen = 0;
386
0
                            }
387
0
                            else
388
0
                                memcpy(fontfname + fsprefixlen, defcidfallack, defcidfallacklen);
389
0
                        }
390
0
                        else {
391
0
                            if (ctx->args.cidfsubstfont.size > gp_file_name_sizeof - 1) {
392
0
                                code = gs_note_error(gs_error_rangecheck);
393
0
                                if ((code = pdfi_set_warning_stop(ctx, code, NULL, W_PDF_BAD_CONFIG, "pdfi_open_CIDFont_substitute_file", "CIDFSubstFont parameter too long")) < 0)
394
0
                                    goto exit;
395
396
0
                                memcpy(fontfname, defcidfallack, defcidfallacklen);
397
0
                                defcidfallacklen = ctx->args.cidfsubstfont.size;
398
                                /* cidfsubstfont should either be a font name we find in the search path(s)
399
                                   or an absolute path.
400
                                 */
401
0
                                fsprefixlen = 0;
402
0
                            }
403
0
                            else {
404
0
                                memcpy(fontfname, ctx->args.cidfsubstfont.data, ctx->args.cidfsubstfont.size);
405
0
                                defcidfallacklen = ctx->args.cidfsubstfont.size;
406
                                /* cidfsubstfont should either be a font name we find in the search path(s)
407
                                   or an absolute path.
408
                                 */
409
0
                                fsprefixlen = 0;
410
0
                            }
411
0
                        }
412
0
                    }
413
13.4k
                    fontfname[fsprefixlen + defcidfallacklen] = '\0';
414
415
13.4k
                    code = pdfi_open_resource_file(ctx, fontfname, strlen(fontfname), &s);
416
13.4k
                    if (code < 0) {
417
0
                        pdf_name *fn;
418
0
                        code = pdfi_object_alloc(ctx, PDF_NAME, strlen(fontfname), (pdf_obj **)&fn);
419
0
                        if (code < 0) {
420
0
                            code = gs_note_error(gs_error_invalidfont);
421
0
                        }
422
0
                        else {
423
0
                            pdfi_countup(fn);
424
0
                            memcpy(fn->data, fontfname, strlen(fontfname));
425
0
                            pdfi_countdown(mname);
426
0
                            mname = NULL;
427
0
                            code = pdfi_fontmap_lookup_cidfont(ctx, font_dict, fn, (pdf_obj **)&mname, findex);
428
0
                            pdfi_countdown(fn);
429
0
                            if (code < 0)
430
0
                                code = gs_note_error(gs_error_invalidfont);
431
0
                            else
432
0
                                continue;
433
0
                        }
434
0
                    }
435
13.4k
                    else {
436
13.4k
                        if (cidname) {
437
13.2k
                            pdfi_print_cstring(ctx, "Loading CIDFont ");
438
13.2k
                            pdfi_print_font_name(ctx, (pdf_name *)cidname);
439
13.2k
                            pdfi_print_cstring(ctx, " substitute from ");
440
13.2k
                        }
441
154
                        else {
442
154
                            pdfi_print_cstring(ctx, "Loading nameless CIDFont from ");
443
154
                        }
444
13.4k
                        sfilename(s, &fname);
445
13.4k
                        if (fname.size < gp_file_name_sizeof) {
446
13.4k
                            memcpy(fontfname, fname.data, fname.size);
447
13.4k
                            fontfname[fname.size] = '\0';
448
13.4k
                        }
449
0
                        else {
450
0
                            strcpy(fontfname, "unnamed file");
451
0
                        }
452
13.4k
                        pdfi_print_cstring(ctx, fontfname);
453
13.4k
                        pdfi_print_cstring(ctx, "\n");
454
455
456
13.4k
                        sfseek(s, 0, SEEK_END);
457
13.4k
                        *buflen = sftell(s);
458
13.4k
                        sfseek(s, 0, SEEK_SET);
459
13.4k
                        *buf = gs_alloc_bytes(ctx->memory, *buflen, "pdfi_open_CIDFont_file(buf)");
460
13.4k
                        if (*buf != NULL) {
461
13.4k
                            sfread(*buf, 1, *buflen, s);
462
13.4k
                        }
463
0
                        else {
464
0
                            code = gs_note_error(gs_error_VMerror);
465
0
                        }
466
13.4k
                        sfclose(s);
467
13.4k
                        break;
468
13.4k
                    }
469
13.4k
                }
470
13.4k
            }
471
0
            else {
472
0
                if (mname->length + 1 > gp_file_name_sizeof) {
473
0
                    pdfi_countdown(mname);
474
0
                    return_error(gs_error_invalidfont);
475
0
                }
476
0
                memcpy(fontfname, mname->data, mname->length);
477
0
                fontfname[mname->length] = '\0';
478
0
                code = pdfi_open_resource_file(ctx, (const char *)fontfname, mname->length, &s);
479
0
                pdfi_countdown(mname);
480
0
                if (code < 0) {
481
0
                    code = gs_note_error(gs_error_invalidfont);
482
0
                }
483
0
                else {
484
0
                    if (cidname) {
485
0
                        pdfi_print_cstring(ctx, "Loading CIDFont ");
486
0
                        pdfi_print_font_name(ctx, (pdf_name *)cidname);
487
0
                        pdfi_print_cstring(ctx, " (or substitute) from ");
488
0
                    }
489
0
                    else {
490
0
                        pdfi_print_cstring(ctx, "Loading nameless CIDFont from ");
491
0
                    }
492
0
                    sfilename(s, &fname);
493
0
                    if (fname.size < gp_file_name_sizeof) {
494
0
                        memcpy(fontfname, fname.data, fname.size);
495
0
                        fontfname[fname.size] = '\0';
496
0
                    }
497
0
                    else {
498
0
                        strcpy(fontfname, "unnamed file");
499
0
                    }
500
0
                    pdfi_print_cstring(ctx, fontfname);
501
0
                    pdfi_print_cstring(ctx, "\n");
502
0
                    sfseek(s, 0, SEEK_END);
503
0
                    *buflen = sftell(s);
504
0
                    sfseek(s, 0, SEEK_SET);
505
0
                    *buf = gs_alloc_bytes(ctx->memory, *buflen, "pdfi_open_CIDFont_file(buf)");
506
0
                    if (*buf != NULL) {
507
0
                        sfread(*buf, 1, *buflen, s);
508
0
                    }
509
0
                    else {
510
0
                        code = gs_note_error(gs_error_VMerror);
511
0
                    }
512
0
                    sfclose(s);
513
0
                    break;
514
0
                }
515
0
            }
516
13.4k
        } while (code >= 0);
517
13.4k
    }
518
13.4k
    else {
519
13.4k
        const char *fsprefix = "CIDFont/";
520
13.4k
        const int fsprefixlen = strlen(fsprefix);
521
522
13.4k
        if (cidname == NULL || pdfi_type_of(cidname) != PDF_NAME
523
13.2k
         || fsprefixlen + cidname->length >= gp_file_name_sizeof) {
524
159
            code = gs_note_error(gs_error_invalidfont);
525
159
            goto exit;
526
159
        }
527
528
13.2k
        memcpy(fontfname, fsprefix, fsprefixlen);
529
13.2k
        memcpy(fontfname + fsprefixlen, cidname->data, cidname->length);
530
13.2k
        fontfname[fsprefixlen + cidname->length] = '\0';
531
532
13.2k
        code = pdfi_open_resource_file(ctx, fontfname, strlen(fontfname), &s);
533
13.2k
        if (code < 0) {
534
13.2k
            code = gs_note_error(gs_error_invalidfont);
535
13.2k
        }
536
0
        else {
537
0
            sfseek(s, 0, SEEK_END);
538
0
            *buflen = sftell(s);
539
0
            sfseek(s, 0, SEEK_SET);
540
0
            *buf = gs_alloc_bytes(ctx->memory, *buflen, "pdfi_open_CIDFont_file(buf)");
541
0
            if (*buf != NULL) {
542
0
                sfread(*buf, 1, *buflen, s);
543
0
            }
544
0
            else {
545
0
                code = gs_note_error(gs_error_invalidfont);
546
0
            }
547
0
            sfclose(s);
548
0
        }
549
13.2k
    }
550
551
26.8k
exit:
552
26.8k
    if (cidname != NULL)
553
26.5k
        pdfi_countdown(cidname);
554
555
26.8k
    return code;
556
26.8k
}
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
57.9M
{
593
67.0M
    while (1)
594
67.0M
    {
595
67.0M
        while (*a == ' ')
596
0
            a++;
597
67.0M
        while (*b == ' ')
598
1.63k
            b++;
599
67.0M
        if (*a != *b)
600
57.9M
            return 1;
601
9.11M
        if (*a == 0)
602
7.53k
            return *a != *b;
603
9.11M
        if (*b == 0)
604
0
            return *a != *b;
605
9.11M
        a++;
606
9.11M
        b++;
607
9.11M
    }
608
0
    return 0; /* Shouldn't happen */
609
57.9M
}
610
611
static const char *pdfi_clean_font_name(const char *fontname)
612
869k
{
613
869k
    int i, k;
614
12.9M
    for (i = 0; i < (sizeof(pdfi_base_font_names)/sizeof(pdfi_base_font_names[0])); i++) {
615
70.0M
        for (k = 0; pdfi_base_font_names[i][k]; k++) {
616
57.9M
            if (!strncmp_ignore_space(pdfi_base_font_names[i][k], (const char *)fontname))
617
7.53k
                return pdfi_base_font_names[i][0];
618
57.9M
        }
619
12.1M
    }
620
861k
    return NULL;
621
869k
}
622
623
static int pdfi_font_substitute_by_flags(pdf_context *ctx, unsigned int flags, char **name, int *namelen)
624
450k
{
625
450k
    bool fixed = ((flags & pdfi_font_flag_fixed) != 0);
626
450k
    bool serif = ((flags & pdfi_font_flag_serif) != 0);
627
450k
    bool italic = ((flags & pdfi_font_flag_italic) != 0);
628
450k
    bool bold = ((flags & pdfi_font_flag_forcebold) != 0);
629
450k
    int code = 0;
630
631
450k
    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
450k
    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
450k
    else if (fixed) {
642
237
        if (bold) {
643
8
            if (italic) {
644
8
                *name = (char *)pdfi_base_font_names[3][0];
645
8
                *namelen = strlen(*name);
646
8
            }
647
0
            else {
648
0
                *name = (char *)pdfi_base_font_names[1][0];
649
0
                *namelen = strlen(*name);
650
0
            }
651
8
        }
652
229
        else {
653
229
            if (italic) {
654
4
                *name = (char *)pdfi_base_font_names[2][0];
655
4
                *namelen = strlen(*name);
656
4
            }
657
225
            else {
658
225
                *name = (char *)pdfi_base_font_names[0][0];
659
225
                *namelen = strlen(*name);
660
225
            }
661
229
        }
662
237
    }
663
449k
    else if (serif) {
664
1.88k
        if (bold) {
665
10
            if (italic) {
666
0
                *name = (char *)pdfi_base_font_names[11][0];
667
0
                *namelen = strlen(*name);
668
0
            }
669
10
            else {
670
10
                *name = (char *)pdfi_base_font_names[9][0];
671
10
                *namelen = strlen(*name);
672
10
            }
673
10
        }
674
1.87k
        else {
675
1.87k
            if (italic) {
676
152
                *name = (char *)pdfi_base_font_names[10][0];
677
152
                *namelen = strlen(*name);
678
152
            }
679
1.71k
            else {
680
1.71k
                *name = (char *)pdfi_base_font_names[8][0];
681
1.71k
                *namelen = strlen(*name);
682
1.71k
            }
683
1.87k
        }
684
447k
    } else {
685
447k
        if (bold) {
686
145
            if (italic) {
687
0
                *name = (char *)pdfi_base_font_names[7][0];
688
0
                *namelen = strlen(*name);
689
0
            }
690
145
            else {
691
145
                *name = (char *)pdfi_base_font_names[5][0];
692
145
                *namelen = strlen(*name);
693
145
            }
694
145
        }
695
447k
        else {
696
447k
            if (italic) {
697
537
                *name = (char *)pdfi_base_font_names[6][0];
698
537
                *namelen = strlen(*name);
699
537
            }
700
447k
            else {
701
447k
                *name = (char *)pdfi_base_font_names[4][0];
702
447k
                *namelen = strlen(*name);
703
447k
            }
704
447k
        }
705
447k
    }
706
450k
    return code;
707
450k
}
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
112k
{
720
1.03M
#define MAKEMAGIC(a, b, c, d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
721
722
112k
    if (buflen >= 4) {
723
112k
        if (MAKEMAGIC(buf[0], buf[1], buf[2], buf[3]) == MAKEMAGIC(0, 1, 0, 0)
724
74.1k
            || MAKEMAGIC(buf[0], buf[1], buf[2], buf[3]) == MAKEMAGIC('t', 'r', 'u', 'e')
725
69.3k
            || MAKEMAGIC(buf[0], buf[1], buf[2], buf[3]) == MAKEMAGIC('t', 't', 'c', 'f')) {
726
43.6k
            return tt_font;
727
43.6k
        }
728
69.3k
        else if (MAKEMAGIC(buf[0], buf[1], buf[2], buf[3]) == MAKEMAGIC('O', 'T', 'T', 'O')) {
729
539
            return cff_font; /* OTTO will end up as CFF */
730
539
        }
731
68.8k
        else if (MAKEMAGIC(buf[0], buf[1], buf[2], 0) == MAKEMAGIC('%', '!', 'P', 0)) {
732
57.5k
            return type1_font; /* pfa */
733
57.5k
        }
734
11.2k
        else if (MAKEMAGIC(buf[0], buf[1], buf[2], 0) == MAKEMAGIC(1, 0, 4, 0)) {
735
10.5k
            return cff_font; /* 1C/CFF */
736
10.5k
        }
737
750
        else if (MAKEMAGIC(buf[0], buf[1], 0, 0) == MAKEMAGIC(128, 1, 0, 0)) {
738
182
            return type1_font; /* pfb */
739
182
        }
740
112k
    }
741
584
    return no_type_font;
742
112k
#undef MAKEMAGIC
743
112k
}
744
745
static int pdfi_copy_font(pdf_context *ctx, pdf_font *spdffont, pdf_dict *font_dict, pdf_font **tpdffont)
746
477k
{
747
477k
    int code;
748
477k
    if (pdfi_type_of(spdffont) != PDF_FONT)
749
0
        return_error(gs_error_typecheck);
750
751
477k
    switch(spdffont->pdfi_font_type) {
752
473k
        case e_pdf_font_type1:
753
473k
          code = pdfi_copy_type1_font(ctx, spdffont, font_dict, tpdffont);
754
473k
          break;
755
55
        case e_pdf_font_cff:
756
55
          code = pdfi_copy_cff_font(ctx, spdffont, font_dict, tpdffont);
757
55
          break;
758
3.44k
        case e_pdf_font_truetype:
759
3.44k
          code = pdfi_copy_truetype_font(ctx, spdffont, font_dict, tpdffont);
760
3.44k
          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
477k
    }
767
477k
    return code;
768
477k
}
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
112k
{
778
112k
    int code = gs_error_invalidfont;
779
112k
    if (fbuf != NULL) {
780
        /* First, see if we can glean the type from the magic number */
781
112k
        int sftype = pdfi_fonttype_picker(fbuf, fbuflen);
782
112k
        if (sftype == no_type_font) {
783
584
            if (fftype != no_type_font)
784
563
                sftype = fftype;
785
21
            else {
786
                /* If we don't have a Subtype, can't work it out, try Type 1 */
787
21
                if (Subtype == NULL || pdfi_name_is(Subtype, "Type1") || pdfi_name_is(Subtype, "MMType1"))
788
19
                    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
21
            }
794
584
        }
795
        /* fbuf ownership passes to the font loader */
796
112k
        switch (sftype) {
797
58.0k
            case type1_font:
798
58.0k
                code = pdfi_read_type1_font(ctx, (pdf_dict *)font_dict, stream_dict, page_dict, fbuf, fbuflen, ppdffont);
799
58.0k
                fbuf = NULL;
800
58.0k
                break;
801
11.1k
            case cff_font:
802
11.1k
                code = pdfi_read_cff_font(ctx, (pdf_dict *)font_dict, stream_dict, page_dict, fbuf, fbuflen, cidfont, ppdffont);
803
11.1k
                fbuf = NULL;
804
11.1k
                break;
805
43.7k
            case tt_font:
806
43.7k
                {
807
43.7k
                    if (cidfont)
808
20.9k
                        code = pdfi_read_cidtype2_font(ctx, font_dict, stream_dict, page_dict, fbuf, fbuflen, findex, ppdffont);
809
22.7k
                    else
810
22.7k
                        code = pdfi_read_truetype_font(ctx, font_dict, stream_dict, page_dict, fbuf, fbuflen, findex, ppdffont);
811
43.7k
                    fbuf = NULL;
812
43.7k
                }
813
43.7k
                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
112k
        }
818
112k
    }
819
112k
    return code;
820
112k
}
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
923k
{
824
923k
    int code;
825
923k
    char fontfname[gp_file_name_sizeof];
826
923k
    pdf_obj *basefont = NULL, *mapname = NULL;
827
923k
    pdf_obj *fontname = NULL;
828
923k
    stream *s = NULL;
829
923k
    const char *fn;
830
923k
    int findex = 0;
831
923k
    byte *buf;
832
923k
    int buflen;
833
923k
    pdf_font *pdffont = NULL;
834
923k
    pdf_font *substpdffont = NULL;
835
923k
    bool f_retry = true;
836
837
923k
    code = pdfi_dict_knownget_type(ctx, font_dict, "BaseFont", PDF_NAME, &basefont);
838
923k
    if (substitute == false && (code < 0 || basefont == NULL || ((pdf_name *)basefont)->length == 0)) {
839
19.1k
        pdfi_countdown(basefont);
840
19.1k
        return_error(gs_error_invalidfont);
841
19.1k
    }
842
843
904k
    if (substitute == true) {
844
450k
        char *fbname;
845
450k
        int fbnamelen;
846
450k
        int64_t flags = 0;
847
450k
        if (fontdesc != NULL) {
848
21.7k
            (void)pdfi_dict_get_int(ctx, fontdesc, "Flags", &flags);
849
21.7k
        }
850
450k
        code = pdfi_font_substitute_by_flags(ctx, (int)flags, &fbname, &fbnamelen);
851
450k
        if (code < 0)
852
0
            return code;
853
854
450k
        code = pdfi_name_alloc(ctx, (byte *)fbname, strlen(fbname), (pdf_obj **) &fontname);
855
450k
        if (code < 0)
856
0
            return code;
857
450k
        pdfi_countup(fontname);
858
450k
    }
859
454k
    else {
860
454k
        fontname = basefont;
861
454k
        pdfi_countup(fontname);
862
454k
    }
863
864
904k
    if (((pdf_name *)fontname)->length < gp_file_name_sizeof) {
865
904k
        memcpy(fontfname, ((pdf_name *)fontname)->data, ((pdf_name *)fontname)->length);
866
904k
        fontfname[((pdf_name *)fontname)->length] = '\0';
867
904k
        pdfi_countdown(fontname);
868
869
904k
        code = pdfi_name_alloc(ctx, (byte *)fontfname, strlen(fontfname), (pdf_obj **) &fontname);
870
904k
        if (code < 0)
871
0
            return code;
872
904k
        pdfi_countup(fontname);
873
904k
    }
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.33M
    do {
880
1.33M
        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.33M
        else {
884
1.33M
            code = pdfi_fontmap_lookup_font(ctx, font_dict, (pdf_name *) fontname, &mapname, &findex);
885
1.33M
            if (code < 0) {
886
869k
                if (((pdf_name *)fontname)->length < gp_file_name_sizeof) {
887
869k
                    memcpy(fontfname, ((pdf_name *)fontname)->data, ((pdf_name *)fontname)->length);
888
869k
                    fontfname[((pdf_name *)fontname)->length] = '\0';
889
869k
                    fn = pdfi_clean_font_name(fontfname);
890
869k
                    if (fn != NULL) {
891
7.53k
                        pdfi_countdown(fontname);
892
893
7.53k
                        code = pdfi_name_alloc(ctx, (byte *)fn, strlen(fn), (pdf_obj **) &fontname);
894
7.53k
                        if (code < 0)
895
0
                            return code;
896
7.53k
                        pdfi_countup(fontname);
897
7.53k
                    }
898
869k
                }
899
869k
                code = pdfi_fontmap_lookup_font(ctx, font_dict, (pdf_name *) fontname, &mapname, &findex);
900
869k
                if (code < 0) {
901
861k
                    mapname = fontname;
902
861k
                    pdfi_countup(mapname);
903
861k
                    code = 0;
904
861k
                }
905
869k
            }
906
1.33M
            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.33M
            if (pdfi_type_of(mapname) == PDF_NAME || pdfi_type_of(mapname) == PDF_STRING) {
912
1.33M
                pdf_name *mname = (pdf_name *) mapname;
913
1.33M
                if (mname->length + 1 < gp_file_name_sizeof) {
914
1.33M
                    memcpy(fontfname, mname->data, mname->length);
915
1.33M
                    fontfname[mname->length] = '\0';
916
1.33M
                }
917
3
                else {
918
3
                    pdfi_countdown(mapname);
919
3
                    pdfi_countdown(fontname);
920
3
                    return_error(gs_error_invalidfileaccess);
921
3
                }
922
1.33M
            }
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.33M
            if (ctx->pdf_substitute_fonts != NULL) {
930
1.24M
                code = pdfi_dict_knownget_type(ctx, ctx->pdf_substitute_fonts, fontfname, PDF_FONT, (pdf_obj **)&pdffont);
931
1.24M
                if (code == 1 && pdffont->filename == NULL) {
932
0
                    pdfi_countdown(pdffont);
933
0
                    pdffont = NULL;
934
0
                    code = 0;
935
0
                }
936
1.24M
            }
937
95.1k
            else
938
95.1k
                code = 0;
939
1.33M
        }
940
1.33M
        if (code != 1) {
941
911k
            code = pdfi_open_font_file(ctx, fontfname, strlen(fontfname), &s);
942
911k
            if (code < 0 && f_retry && pdfi_type_of(mapname) == PDF_NAME) {
943
433k
                pdfi_countdown(fontname);
944
433k
                fontname = mapname;
945
433k
                mapname = NULL;
946
433k
                f_retry = false;
947
433k
                continue;
948
433k
            }
949
477k
            if (code >= 0) {
950
47.0k
                gs_const_string fname;
951
952
47.0k
                sfilename(s, &fname);
953
47.0k
                if (fname.size < gp_file_name_sizeof) {
954
47.0k
                    memcpy(fontfname, fname.data, fname.size);
955
47.0k
                    fontfname[fname.size] = '\0';
956
47.0k
                }
957
0
                else {
958
0
                    strcpy(fontfname, "unnamed file");
959
0
                }
960
47.0k
                sfseek(s, 0, SEEK_END);
961
47.0k
                buflen = sftell(s);
962
47.0k
                sfseek(s, 0, SEEK_SET);
963
47.0k
                buf = gs_alloc_bytes(ctx->memory, buflen, "pdfi_open_t1_font_file(buf)");
964
47.0k
                if (buf != NULL) {
965
47.0k
                    sfread(buf, 1, buflen, s);
966
47.0k
                }
967
0
                else {
968
0
                    code = gs_note_error(gs_error_VMerror);
969
0
                }
970
47.0k
                sfclose(s);
971
                /* Buffer owership moves to the font object */
972
47.0k
                code = pdfi_load_font_buffer(ctx, buf, buflen, no_type_font, NULL, findex, stream_dict, page_dict, NULL, &pdffont, false);
973
47.0k
                if (code >= 0) {
974
47.0k
                    pdffont->filename = NULL;
975
47.0k
                    code = pdfi_object_alloc(ctx, PDF_STRING, strlen(fontfname) , (pdf_obj **)&pdffont->filename);
976
47.0k
                    if (code >= 0) {
977
47.0k
                        pdfi_countup(pdffont->filename);
978
47.0k
                        memcpy(pdffont->filename->data, fontfname, strlen(fontfname));
979
47.0k
                        pdffont->filename->length = strlen(fontfname);
980
47.0k
                    }
981
982
47.0k
                    if (ctx->pdf_substitute_fonts == NULL) {
983
37.2k
                        code = pdfi_dict_alloc(ctx, 16, &ctx->pdf_substitute_fonts);
984
37.2k
                        if (code >= 0)
985
37.2k
                            pdfi_countup(ctx->pdf_substitute_fonts);
986
37.2k
                    }
987
47.0k
                    if (ctx->pdf_substitute_fonts != NULL) {
988
47.0k
                        if (pdfi_type_of(mapname) == PDF_STRING) {
989
0
                            pdf_name *n = NULL;
990
0
                            pdf_string *mn = (pdf_string *)mapname;
991
992
0
                            code = pdfi_name_alloc(ctx, mn->data, mn->length, (pdf_obj **)&n);
993
0
                            if (code >= 0) {
994
0
                                pdfi_countdown(mapname);
995
0
                                mapname = (pdf_obj *)n;
996
0
                                pdfi_countup(mapname);
997
0
                                code = 0;
998
0
                            }
999
0
                        }
1000
47.0k
                        else
1001
47.0k
                            code = 0;
1002
1003
47.0k
                        if (code == 0)
1004
47.0k
                            (void)pdfi_dict_put_obj(ctx, ctx->pdf_substitute_fonts, mapname, (pdf_obj *)pdffont, true);
1005
47.0k
                        code = 0;
1006
47.0k
                    }
1007
47.0k
                }
1008
47.0k
            }
1009
477k
        }
1010
904k
        break;
1011
1.33M
    } while (1);
1012
1013
904k
    if (code >= 0) {
1014
473k
        if (basefont) {
1015
472k
            pdfi_print_cstring(ctx, "Loading font ");
1016
472k
            pdfi_print_font_name(ctx, (pdf_name *)basefont);
1017
472k
            pdfi_print_cstring(ctx, " (or substitute) from ");
1018
472k
        }
1019
841
        else {
1020
841
            pdfi_print_cstring(ctx, "Loading nameless font from ");
1021
841
        }
1022
473k
        pdfi_print_font_string(ctx, pdffont->filename);
1023
473k
        pdfi_print_cstring(ctx, "\n");
1024
1025
473k
        code = pdfi_copy_font(ctx, pdffont, font_dict, &substpdffont);
1026
473k
        pdfi_countdown(pdffont);
1027
473k
    }
1028
1029
904k
    *ppdffont = substpdffont;
1030
1031
904k
    pdfi_countdown(basefont);
1032
904k
    pdfi_countdown(mapname);
1033
904k
    pdfi_countdown(fontname);
1034
904k
    return code;
1035
904k
}
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
567k
{
1039
567k
    int code;
1040
567k
    pdf_font *ppdffont = NULL;
1041
567k
    pdf_font *ppdfdescfont = NULL;
1042
567k
    pdf_name *Type = NULL;
1043
567k
    pdf_name *Subtype = NULL;
1044
567k
    pdf_dict *fontdesc = NULL;
1045
567k
    pdf_stream *fontfile = NULL;
1046
567k
    pdf_name *ffsubtype = NULL;
1047
567k
    int fftype = no_type_font;
1048
567k
    byte *fbuf = NULL;
1049
567k
    int64_t fbuflen = 0;
1050
567k
    int substitute = font_embedded;
1051
567k
    int findex = 0;
1052
1053
567k
    code = pdfi_dict_get_type(ctx, font_dict, "Type", PDF_NAME, (pdf_obj **)&Type);
1054
567k
    if (code < 0) {
1055
658
        if ((code = pdfi_set_error_stop(ctx, code, NULL, E_PDF_MISSINGTYPE, "pdfi_load_font", NULL)) < 0)
1056
0
            goto exit;
1057
658
    }
1058
566k
    else {
1059
566k
        if (!pdfi_name_is(Type, "Font")){
1060
2.81k
            code = gs_note_error(gs_error_typecheck);
1061
2.81k
            goto exit;
1062
2.81k
        }
1063
566k
    }
1064
564k
    code = pdfi_dict_get_type(ctx, font_dict, "Subtype", PDF_NAME, (pdf_obj **)&Subtype);
1065
564k
    if (code < 0) {
1066
693
        if ((code = pdfi_set_error_stop(ctx, code, NULL, E_PDF_NO_SUBTYPE, "pdfi_load_font", NULL)) < 0)
1067
0
            goto exit;
1068
693
    }
1069
1070
    /* Beyond Type 0 and Type 3, there is no point trusting the Subtype key */
1071
564k
    if (Subtype != NULL && pdfi_name_is(Subtype, "Type0")) {
1072
36.0k
        if (cidfont == true) {
1073
6
            code = gs_note_error(gs_error_invalidfont);
1074
6
        }
1075
36.0k
        else {
1076
36.0k
            code = pdfi_read_type0_font(ctx, (pdf_dict *)font_dict, stream_dict, page_dict, &ppdffont);
1077
36.0k
        }
1078
36.0k
    }
1079
528k
    else if (Subtype != NULL && pdfi_name_is(Subtype, "Type3")) {
1080
2.66k
        code = pdfi_read_type3_font(ctx, (pdf_dict *)font_dict, stream_dict, page_dict, &ppdffont);
1081
2.66k
        if (code < 0)
1082
510
            goto exit;
1083
2.66k
    }
1084
526k
    else {
1085
526k
        if (Subtype != NULL && !pdfi_name_is(Subtype, "Type1") && !pdfi_name_is(Subtype, "TrueType") && !pdfi_name_is(Subtype, "CIDFont")
1086
22.9k
            && !pdfi_name_is(Subtype, "CIDFontType2") && !pdfi_name_is(Subtype, "CIDFontType0") && !pdfi_name_is(Subtype, "MMType1")) {
1087
1088
714
            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
714
        }
1092
        /* We should always have a font descriptor here, but we have to carry on
1093
           even if we don't
1094
         */
1095
526k
        code = pdfi_dict_get_type(ctx, font_dict, "FontDescriptor", PDF_DICT, (pdf_obj **)&fontdesc);
1096
526k
        if (fontdesc != NULL && pdfi_type_of(fontdesc) == PDF_DICT) {
1097
73.4k
            pdf_obj *Name = NULL;
1098
1099
73.4k
            code = pdfi_dict_get_type(ctx, (pdf_dict *) fontdesc, "FontName", PDF_NAME, (pdf_obj **)&Name);
1100
73.4k
            if (code < 0)
1101
995
                pdfi_set_warning(ctx, 0, NULL, W_PDF_FDESC_BAD_FONTNAME, "pdfi_load_font", "");
1102
73.4k
            pdfi_countdown(Name);
1103
73.4k
            Name = NULL;
1104
1105
73.4k
            if (cidfont == true) {
1106
13.6k
                code = -1;
1107
13.6k
            }
1108
59.7k
            else {
1109
59.7k
                code = pdfi_find_cache_resource_font(ctx, (pdf_obj *)fontdesc, (pdf_obj **)&ppdfdescfont);
1110
59.7k
                if (code >= 0) {
1111
3.62k
                    code = pdfi_copy_font(ctx, ppdfdescfont, font_dict, &ppdffont);
1112
3.62k
                }
1113
59.7k
            }
1114
1115
73.4k
            if (code < 0) {
1116
69.8k
                code = pdfi_dict_get_type(ctx, (pdf_dict *) fontdesc, "FontFile", PDF_STREAM, (pdf_obj **)&fontfile);
1117
69.8k
                if (code >= 0)
1118
10.7k
                    fftype = type1_font;
1119
59.0k
                else {
1120
59.0k
                    code = pdfi_dict_get_type(ctx, (pdf_dict *) fontdesc, "FontFile2", PDF_STREAM, (pdf_obj **)&fontfile);
1121
59.0k
                    fftype = tt_font;
1122
59.0k
                }
1123
69.8k
                if (code < 0) {
1124
27.4k
                    code = pdfi_dict_get_type(ctx, (pdf_dict *) fontdesc, "FontFile3", PDF_STREAM, (pdf_obj **)&fontfile);
1125
27.4k
                    if (code >= 0 && fontfile != NULL) {
1126
11.7k
                        code = pdfi_dict_get_type(ctx, fontfile->stream_dict, "Subtype", PDF_NAME, (pdf_obj **)&ffsubtype);
1127
11.7k
                        if (code >= 0) {
1128
11.6k
                            if (pdfi_name_is(ffsubtype, "Type1"))
1129
0
                                fftype = type1_font;
1130
11.6k
                            else if (pdfi_name_is(ffsubtype, "Type1C"))
1131
8.92k
                                fftype = cff_font;
1132
2.71k
                            else if (pdfi_name_is(ffsubtype, "OpenType"))
1133
366
                                fftype = cff_font;
1134
2.35k
                            else if (pdfi_name_is(ffsubtype, "CIDFontType0C"))
1135
1.84k
                                fftype = cff_font;
1136
511
                            else if (pdfi_name_is(ffsubtype, "TrueType"))
1137
0
                                fftype = tt_font;
1138
511
                            else
1139
511
                                fftype = no_type_font;
1140
11.6k
                        }
1141
11.7k
                    }
1142
27.4k
                }
1143
69.8k
            }
1144
73.4k
        }
1145
1146
526k
        if (ppdffont == NULL) {
1147
522k
            if (fontfile != NULL) {
1148
54.1k
                code = pdfi_stream_to_buffer(ctx, (pdf_stream *) fontfile, &fbuf, &fbuflen);
1149
54.1k
                pdfi_countdown(fontfile);
1150
54.1k
                if (code < 0 || fbuflen == 0) {
1151
1.59k
                    char obj[129];
1152
1.59k
                    pdfi_print_cstring(ctx, "**** Warning: cannot process embedded stream for font object ");
1153
1.59k
                    gs_snprintf(obj, 128, "%d %d\n", (int)font_dict->object_num, (int)font_dict->generation_num);
1154
1.59k
                    pdfi_print_cstring(ctx, obj);
1155
1.59k
                    pdfi_print_cstring(ctx, "**** Attempting to load a substitute font.\n");
1156
1.59k
                    gs_free_object(ctx->memory, fbuf, "pdfi_load_font(fbuf)");
1157
1.59k
                    fbuf = NULL;
1158
1.59k
                    code = gs_note_error(gs_error_invalidfont);
1159
1.59k
                }
1160
54.1k
            }
1161
1162
535k
            while (1) {
1163
535k
                if (fbuf != NULL) {
1164
                    /* fbuf overship passes to pdfi_load_font_buffer() */
1165
65.9k
                    code = pdfi_load_font_buffer(ctx, fbuf, fbuflen, fftype, Subtype, findex, stream_dict, page_dict, font_dict, &ppdffont, cidfont);
1166
1167
65.9k
                    if (code < 0 && substitute == font_embedded) {
1168
16.9k
                        char msg[129];
1169
1170
16.9k
                        gs_snprintf(msg, 128, "Cannot process embedded stream for font object %d %d. Attempting to load a substitute font.\n", (int)font_dict->object_num, (int)font_dict->generation_num);
1171
1172
16.9k
                        if ((code = pdfi_set_error_stop(ctx, gs_note_error(gs_error_invalidfont), NULL, E_PDF_BAD_EMBEDDED_FONT, "pdfi_load_font", msg)) < 0) {
1173
0
                            goto exit;
1174
0
                        }
1175
16.9k
                        else {
1176
16.9k
                            code = gs_error_invalidfont;
1177
16.9k
                        }
1178
16.9k
                    }
1179
65.9k
                }
1180
469k
                else {
1181
469k
                    code = gs_error_invalidfont;
1182
469k
                }
1183
1184
535k
                if (code < 0 && code != gs_error_VMerror && substitute == font_embedded) {
1185
486k
                    substitute = font_from_file;
1186
1187
486k
                    if (cidfont == true) {
1188
13.4k
                        code =  pdfi_open_CIDFont_substitute_file(ctx, font_dict, fontdesc, false, &fbuf, &fbuflen, &findex);
1189
13.4k
                        if (code < 0) {
1190
13.4k
                            code =  pdfi_open_CIDFont_substitute_file(ctx, font_dict, fontdesc, true, &fbuf, &fbuflen, &findex);
1191
13.4k
                            substitute |= font_substitute;
1192
13.4k
                        }
1193
1194
13.4k
                        if (code < 0)
1195
0
                            goto exit;
1196
13.4k
                    }
1197
473k
                    else {
1198
473k
                        code = pdfi_load_font_file(ctx, no_type_font, Subtype, stream_dict, page_dict, font_dict, fontdesc, false, &ppdffont);
1199
473k
                        if (code < 0) {
1200
450k
                            code = pdfi_load_font_file(ctx, no_type_font, Subtype, stream_dict, page_dict, font_dict, fontdesc, true, &ppdffont);
1201
450k
                            substitute |= font_substitute;
1202
450k
                        }
1203
473k
                        break;
1204
473k
                    }
1205
13.4k
                    continue;
1206
486k
                }
1207
48.9k
                break;
1208
535k
            }
1209
522k
        }
1210
526k
    }
1211
564k
    if (ppdffont == NULL || code < 0) {
1212
29.8k
        *ppfont = NULL;
1213
29.8k
        if (code != gs_error_Fatal)
1214
29.8k
            code = gs_note_error(gs_error_invalidfont);
1215
29.8k
    }
1216
534k
    else {
1217
534k
        ppdffont->substitute = (substitute != font_embedded);
1218
1219
534k
        if ((substitute & font_substitute) == font_substitute)
1220
456k
            code = pdfi_font_match_glyph_widths(ppdffont);
1221
77.7k
        else if (ppdffont->substitute != true && fontdesc != NULL && ppdfdescfont == NULL
1222
35.3k
            && (ppdffont->pdfi_font_type == e_pdf_font_type1 || ppdffont->pdfi_font_type == e_pdf_font_cff
1223
28.6k
            || ppdffont->pdfi_font_type == e_pdf_font_truetype)) {
1224
28.6k
            pdfi_cache_resource_font(ctx, (pdf_obj *)fontdesc, (pdf_obj *)ppdffont);
1225
28.6k
        }
1226
534k
        *ppfont = (gs_font *)ppdffont->pfont;
1227
534k
     }
1228
1229
567k
exit:
1230
567k
    pdfi_countdown(ppdfdescfont);
1231
567k
    pdfi_countdown(fontdesc);
1232
567k
    pdfi_countdown(Type);
1233
567k
    pdfi_countdown(Subtype);
1234
567k
    pdfi_countdown(ffsubtype);
1235
567k
    return code;
1236
564k
}
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
809k
{
1240
809k
    int code;
1241
809k
    gs_font *pfont;
1242
809k
    pdf_font *pdfif;
1243
1244
809k
    switch (pdfi_type_of(font_dict)) {
1245
680k
        case PDF_FONT:
1246
680k
            pdfi_countup(font_dict);
1247
680k
            pfont = (gs_font *)((pdf_font *)font_dict)->pfont;
1248
680k
            code = 0;
1249
680k
            break;
1250
121k
        case PDF_DICT:
1251
121k
            code = pdfi_load_font(ctx, stream_dict, page_dict, font_dict, &pfont, false);
1252
121k
            break;
1253
7.67k
        default:
1254
7.67k
            code = gs_note_error(gs_error_typecheck);
1255
7.67k
            goto exit;
1256
809k
    }
1257
801k
    if (code < 0)
1258
26.2k
        goto exit;
1259
1260
    /* Everything looks good, set the font, unless it's the current font */
1261
775k
    if (pfont != ctx->pgs->font) {
1262
615k
        code = pdfi_gs_setfont(ctx, pfont);
1263
615k
    }
1264
775k
    pdfif = (pdf_font *)pfont->client_data;
1265
775k
    pdfi_countdown(pdfif);
1266
1267
775k
    if (code < 0)
1268
0
        goto exit;
1269
1270
775k
    code = gs_setPDFfontsize(ctx->pgs, point_size);
1271
809k
exit:
1272
809k
    return code;
1273
775k
}
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.20M
{
1277
1.20M
    int code;
1278
1.20M
    pdf_dict *font_dict = NULL;
1279
1280
1.20M
    if (pdfi_type_of(fontname) != PDF_NAME) {
1281
        /* Passing empty string here should fall back to a default font */
1282
16.2k
        return pdfi_font_set_internal_string(ctx, "", point_size);
1283
16.2k
    }
1284
1285
    /* Look fontname up in the resources */
1286
1.18M
    code = pdfi_loop_detector_mark(ctx);
1287
1.18M
    if (code < 0)
1288
0
        goto exit;
1289
1.18M
    code = pdfi_find_resource(ctx, (unsigned char *)"Font", fontname, stream_dict, page_dict, (pdf_obj **)&font_dict);
1290
1.18M
    (void)pdfi_loop_detector_cleartomark(ctx);
1291
1.18M
    if (code < 0)
1292
375k
        goto exit;
1293
809k
    code = pdfi_load_dict_font(ctx, stream_dict, page_dict, font_dict, point_size);
1294
1295
1.18M
exit:
1296
1.18M
    pdfi_countdown(font_dict);
1297
1.18M
    return code;
1298
809k
}
1299
1300
int pdfi_get_cidfont_glyph_metrics(gs_font *pfont, gs_glyph cid, double *widths, bool vertical)
1301
1.06M
{
1302
1.06M
    pdf_font *pdffont = (pdf_font *)pfont->client_data;
1303
1.06M
    int i, code = 0;
1304
1.06M
    pdf_num *c = NULL, *c2 = NULL;
1305
1.06M
    pdf_obj *o = NULL;
1306
1.06M
    pdf_array *W = NULL, *W2 = NULL, *DW2 = NULL;
1307
1.06M
    double DW;
1308
1309
1.06M
    if (pdffont->pdfi_font_type == e_pdf_cidfont_type0) {
1310
61.7k
        pdf_cidfont_type0 *cidfont = (pdf_cidfont_type0 *)pdffont;
1311
61.7k
        DW = cidfont->DW;
1312
61.7k
        DW2 = cidfont->DW2;
1313
61.7k
        W = cidfont->W;
1314
61.7k
        W2 = cidfont->W2;
1315
61.7k
    }
1316
1.00M
    else if (pdffont->pdfi_font_type == e_pdf_cidfont_type2) {
1317
1.00M
        pdf_cidfont_type2 *cidfont = (pdf_cidfont_type2 *)pdffont;
1318
1.00M
        DW = cidfont->DW;
1319
1.00M
        DW2 = cidfont->DW2;
1320
1.00M
        W = cidfont->W;
1321
1.00M
        W2 = cidfont->W2;
1322
1.00M
    }
1323
0
    else {
1324
0
        return_error(gs_error_invalidfont);
1325
0
    }
1326
1327
1.06M
    widths[GLYPH_W0_WIDTH_INDEX] = DW;
1328
1.06M
    widths[GLYPH_W0_HEIGHT_INDEX] = 0;
1329
1.06M
    if (W != NULL) {
1330
949k
        i = 0;
1331
1332
22.8M
        while(1) {
1333
22.8M
            pdf_obj_type type;
1334
1335
22.8M
            if (i + 1>= W->size) break;
1336
22.8M
            code = pdfi_array_get_type(pdffont->ctx, W, i, PDF_INT, (pdf_obj **)&c);
1337
22.8M
            if (code < 0) goto cleanup;
1338
1339
22.8M
            code = pdfi_array_get(pdffont->ctx, W, i + 1, &o);
1340
22.8M
            if (code < 0) goto cleanup;
1341
1342
22.8M
            type = pdfi_type_of(o);
1343
22.8M
            if (type == PDF_INT) {
1344
1.82M
                double d;
1345
1.82M
                c2 = (pdf_num *)o;
1346
1.82M
                o = NULL;
1347
1.82M
                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
166
                    break;
1352
166
                }
1353
1354
1.82M
                code = pdfi_array_get_number(pdffont->ctx, W, i + 2, &d);
1355
1.82M
                if (code < 0) goto cleanup;
1356
1.82M
                if (cid >= c->value.i && cid <= c2->value.i) {
1357
63.1k
                    widths[GLYPH_W0_WIDTH_INDEX] = d;
1358
63.1k
                    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
63.1k
                    break;
1363
63.1k
                }
1364
1.75M
                else {
1365
1.75M
                    i += 3;
1366
1.75M
                    pdfi_countdown(c2);
1367
1.75M
                    pdfi_countdown(c);
1368
1.75M
                    c = c2 = NULL;
1369
1.75M
                    continue;
1370
1.75M
                }
1371
1.82M
            }
1372
20.9M
            else if (type == PDF_ARRAY) {
1373
20.9M
                pdf_array *a = (pdf_array *)o;
1374
20.9M
                o = NULL;
1375
20.9M
                if (cid >= c->value.i && cid < c->value.i + a->size) {
1376
815k
                    code = pdfi_array_get_number(pdffont->ctx, a, cid - c->value.i, &widths[GLYPH_W0_WIDTH_INDEX]);
1377
815k
                    if (code >= 0) {
1378
815k
                        pdfi_countdown(a);
1379
815k
                        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
815k
                        break;
1384
815k
                    }
1385
815k
                }
1386
20.1M
                pdfi_countdown(a);
1387
20.1M
                pdfi_countdown(c);
1388
20.1M
                c = NULL;
1389
20.1M
                i += 2;
1390
20.1M
                continue;
1391
20.9M
            }
1392
680
            else {
1393
680
                code = gs_note_error(gs_error_typecheck);
1394
680
                goto cleanup;
1395
680
            }
1396
22.8M
        }
1397
947k
        pdfi_countdown(c2);
1398
947k
        pdfi_countdown(c);
1399
947k
        pdfi_countdown(o);
1400
947k
        c = c2 = NULL;
1401
947k
        o = NULL;
1402
947k
    }
1403
1404
1.06M
    if (vertical) {
1405
        /* Default default <sigh>! */
1406
1.06M
        widths[GLYPH_W1_WIDTH_INDEX] = 0;
1407
1.06M
        widths[GLYPH_W1_HEIGHT_INDEX] = -1000.0;
1408
1.06M
        widths[GLYPH_W1_V_X_INDEX] = (widths[GLYPH_W0_WIDTH_INDEX] / 2.0);
1409
1.06M
        widths[GLYPH_W1_V_Y_INDEX] = 880.0;
1410
1411
1.06M
        if (DW2 != NULL && pdfi_type_of(DW2) == PDF_ARRAY
1412
8.70k
            && DW2->size >= 2) {
1413
8.70k
            code = pdfi_array_get_number(pdffont->ctx, (pdf_array *)DW2, 0, &widths[GLYPH_W1_V_Y_INDEX]);
1414
8.70k
            if (code >= 0)
1415
8.70k
                code = pdfi_array_get_number(pdffont->ctx, (pdf_array *)DW2, 1, &widths[GLYPH_W1_HEIGHT_INDEX]);
1416
8.70k
            if (code >= 0) {
1417
8.70k
                widths[GLYPH_W1_V_X_INDEX] = widths[GLYPH_W0_WIDTH_INDEX] / 2.0;
1418
8.70k
                widths[GLYPH_W1_WIDTH_INDEX] = 0.0;
1419
8.70k
            }
1420
8.70k
        }
1421
1.06M
        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.06M
    }
1494
1495
1.06M
cleanup:
1496
1.06M
    pdfi_countdown(c2);
1497
1.06M
    pdfi_countdown(c);
1498
1.06M
    pdfi_countdown(o);
1499
1500
1.06M
    return code;
1501
1.06M
}
1502
1503
int pdfi_d0(pdf_context *ctx)
1504
3.65k
{
1505
3.65k
    int code = 0, gsave_level = 0;
1506
3.65k
    double width[2];
1507
1508
3.65k
    if (ctx->text.inside_CharProc == false)
1509
2.92k
        pdfi_set_warning(ctx, 0, NULL, W_PDF_NOTINCHARPROC, "pdfi_d0", NULL);
1510
1511
3.65k
    ctx->text.CharProc_d_type = pdf_type3_d0;
1512
1513
3.65k
    if (pdfi_count_stack(ctx) < 2) {
1514
756
        code = gs_note_error(gs_error_stackunderflow);
1515
756
        goto d0_error;
1516
756
    }
1517
1518
2.90k
    if (pdfi_type_of(ctx->stack_top[-1]) != PDF_INT && pdfi_type_of(ctx->stack_top[-1]) != PDF_REAL) {
1519
744
        code = gs_note_error(gs_error_typecheck);
1520
744
        goto d0_error;
1521
744
    }
1522
2.15k
    if (pdfi_type_of(ctx->stack_top[-2]) != PDF_INT && pdfi_type_of(ctx->stack_top[-2]) != PDF_REAL) {
1523
106
        code = gs_note_error(gs_error_typecheck);
1524
106
        goto d0_error;
1525
106
    }
1526
2.05k
    if(ctx->text.current_enum == NULL) {
1527
1.31k
        code = gs_note_error(gs_error_undefined);
1528
1.31k
        goto d0_error;
1529
1.31k
    }
1530
1531
734
    if (pdfi_type_of(ctx->stack_top[-2]) == PDF_INT)
1532
734
        width[0] = (double)((pdf_num *)ctx->stack_top[-2])->value.i;
1533
0
    else
1534
0
        width[0] = ((pdf_num *)ctx->stack_top[-2])->value.d;
1535
734
    if (pdfi_type_of(ctx->stack_top[-1]) == PDF_INT)
1536
734
        width[1] = (double)((pdf_num *)ctx->stack_top[-1])->value.i;
1537
0
    else
1538
0
        width[1] = ((pdf_num *)ctx->stack_top[-1])->value.d;
1539
1540
734
    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
734
    if (ctx->text.current_enum == NULL) {
1550
0
        code = gs_note_error(gs_error_unknownerror);
1551
0
        goto d0_error;
1552
0
    }
1553
1554
734
    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
734
    if (ctx->pgs->level > gsave_level)
1573
0
        ctx->current_stream_save.gsave_level += ctx->pgs->level - gsave_level;
1574
1575
734
    if (code < 0)
1576
3
        goto d0_error;
1577
731
    pdfi_pop(ctx, 2);
1578
731
    return 0;
1579
1580
2.92k
d0_error:
1581
2.92k
    pdfi_clearstack(ctx);
1582
2.92k
    return code;
1583
734
}
1584
1585
int pdfi_d1(pdf_context *ctx)
1586
38.7k
{
1587
38.7k
    int code = 0, gsave_level;
1588
38.7k
    double wbox[6];
1589
1590
38.7k
    if (ctx->text.inside_CharProc == false)
1591
957
        pdfi_set_warning(ctx, 0, NULL, W_PDF_NOTINCHARPROC, "pdfi_d1", NULL);
1592
1593
38.7k
    ctx->text.CharProc_d_type = pdf_type3_d1;
1594
1595
38.7k
    code = pdfi_destack_reals(ctx, wbox, 6);
1596
38.7k
    if (code < 0)
1597
912
        goto d1_error;
1598
1599
    /*
1600
     * We don't intend to retain this, instead we will use (effectively) xyshow to apply
1601
     * width overrides at the text level.
1602
    if (font && font->Widths && ctx->current_chr >= font->FirstChar && ctx->current_chr <= font->LastChar)
1603
        wbox[0] = font->Widths[font->ctx->current_chr - font->FirstChar];
1604
     */
1605
1606
37.8k
    gsave_level = ctx->pgs->level;
1607
1608
37.8k
    if (ctx->text.current_enum == NULL) {
1609
390
        code = gs_note_error(gs_error_unknownerror);
1610
390
        goto d1_error;
1611
390
    }
1612
1613
#if 0
1614
    /* This code stops us caching the bitmap and filling it. This is required if the 'pdf-differences'
1615
     * test Type3WordSpacing/Type3Test.pdf is to be rendered with a red stroke. Currently the cache
1616
     * results in a bitmap which is filled with the current fill colour, stroke colours are not
1617
     * implemented. I believe that, since the spec references the PLRM implementation of 'd1' that
1618
     * this is correct. I further suspect that the authors of the test used viewers which do not implement
1619
     * a cache at all, and redraw the glyph every time it is used. This has implications for other parts
1620
     * of the graphics state, such as dash patterns, line joins and caps etc.
1621
     *
1622
     * The change in rendering results in many small differences, particularly at low resolution and PDF generated
1623
     * by pdfwrite from PCL input.
1624
     *
1625
     * We need to clip the glyph description to the bounding box, because that's how the cache works with
1626
     * a bitmap, if we don't do this then some glyphs are fully rendered which should only be partially
1627
     * rendered. However, adding this causes two test files to render incorrectly (PostScript files
1628
     * converted to PDF via pdfwrite). This is what decided me to revert this code.
1629
     */
1630
    code = gs_rectclip(ctx->pgs, (const gs_rect *)&wbox[2], 1);
1631
    if (code < 0)
1632
        goto d1_error;
1633
1634
    code = gs_text_setcharwidth(ctx->text.current_enum, wbox);
1635
#else
1636
37.4k
    code = gs_text_setcachedevice(ctx->text.current_enum, wbox);
1637
37.4k
#endif
1638
1639
    /* See the comment immediately after gs_text_setcachedvice() in pdfi_d0 above */
1640
37.4k
    if (ctx->pgs->level > gsave_level)
1641
11.9k
        ctx->current_stream_save.gsave_level += ctx->pgs->level - gsave_level;
1642
1643
37.4k
    if (code < 0)
1644
23
        goto d1_error;
1645
37.4k
    return 0;
1646
1647
1.32k
d1_error:
1648
1.32k
    pdfi_clearstack(ctx);
1649
1.32k
    return code;
1650
37.4k
}
1651
1652
int pdfi_Tf(pdf_context *ctx, pdf_dict *stream_dict, pdf_dict *page_dict)
1653
1.22M
{
1654
1.22M
    double point_size = 0;
1655
1.22M
    pdf_obj *point_arg = NULL;
1656
1.22M
    int code = 0;
1657
1.22M
    pdf_name *fontname = NULL;
1658
1659
1.22M
    if (pdfi_count_stack(ctx) < 2) {
1660
26.4k
        pdfi_clearstack(ctx);
1661
26.4k
        return_error(gs_error_stackunderflow);
1662
26.4k
    }
1663
1664
    /* Get refs to the args and pop them */
1665
1.20M
    point_arg = ctx->stack_top[-1];
1666
1.20M
    pdfi_countup(point_arg);
1667
1.20M
    fontname = (pdf_name *)ctx->stack_top[-2];
1668
1.20M
    pdfi_countup(fontname);
1669
1.20M
    pdfi_pop(ctx, 2);
1670
1671
    /* Get the point_size */
1672
1.20M
    code = pdfi_obj_to_real(ctx, point_arg, &point_size);
1673
1.20M
    if (code < 0)
1674
2.89k
        goto exit0;
1675
1676
1.20M
    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.20M
    if (code != gs_error_Fatal && code < 0)
1680
409k
        code = pdfi_font_set_internal_name(ctx, fontname, point_size);
1681
1.20M
 exit0:
1682
1.20M
    pdfi_countdown(fontname);
1683
1.20M
    pdfi_countdown(point_arg);
1684
1.20M
    return code;
1685
1.20M
}
1686
1687
int pdfi_free_font(pdf_obj *font)
1688
594k
{
1689
594k
    pdf_font *f = (pdf_font *)font;
1690
1691
594k
    switch (f->pdfi_font_type) {
1692
13.2k
        case e_pdf_font_type0:
1693
13.2k
            return pdfi_free_font_type0((pdf_obj *)font);
1694
0
            break;
1695
526k
        case e_pdf_font_type1:
1696
526k
            return pdfi_free_font_type1((pdf_obj *)font);
1697
0
            break;
1698
10.5k
        case e_pdf_font_cff:
1699
10.5k
            return pdfi_free_font_cff((pdf_obj *)font);
1700
2.66k
        case e_pdf_font_type3:
1701
2.66k
            return pdfi_free_font_type3((pdf_obj *)font);
1702
0
            break;
1703
26.1k
        case e_pdf_font_truetype:
1704
26.1k
            return pdfi_free_font_truetype((pdf_obj *)font);
1705
0
            break;
1706
0
        case e_pdf_font_microtype:
1707
0
            return pdfi_free_font_microtype((pdf_obj *)font);
1708
0
            break;
1709
14.0k
        case e_pdf_cidfont_type2:
1710
14.0k
            return pdfi_free_font_cidtype2((pdf_obj *)font);
1711
0
            break;
1712
1.50k
        case e_pdf_cidfont_type0:
1713
1.50k
            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
594k
    }
1721
0
    return 0;
1722
594k
}
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.9k
{
1728
18.9k
    uint esize = Encoding->size;
1729
18.9k
    uint best = esize / 3;  /* must match at least this many */
1730
18.9k
    int i, index, near_index = ENCODING_INDEX_UNKNOWN, code;
1731
1732
148k
    for (index = 0; index < NUM_KNOWN_REAL_ENCODINGS; ++index) {
1733
130k
        uint match = esize;
1734
1735
15.9M
        for (i = esize; --i >= 0;) {
1736
15.8M
            gs_const_string rstr;
1737
15.8M
            pdf_name *ename;
1738
1739
15.8M
            code = pdfi_array_get_type(ctx, Encoding, (uint64_t)i, PDF_NAME, (pdf_obj **)&ename);
1740
15.8M
            if (code < 0) {
1741
19
                return;
1742
19
            }
1743
1744
15.8M
            gs_c_glyph_name(gs_c_known_encode((gs_char)i, index), &rstr);
1745
15.8M
            if (rstr.size == ename->length &&
1746
7.44M
                !memcmp(rstr.data, ename->data, rstr.size)) {
1747
6.96M
                pdfi_countdown(ename);
1748
6.96M
                continue;
1749
6.96M
            }
1750
8.91M
            pdfi_countdown(ename);
1751
8.91M
            if (--match <= best) {
1752
97.2k
                break;
1753
97.2k
            }
1754
8.91M
        }
1755
130k
        if (match > best) {
1756
32.7k
            best = match;
1757
32.7k
            near_index = index;
1758
            /* If we have a perfect match, stop now. */
1759
32.7k
            if (best == esize)
1760
737
                break;
1761
32.7k
        }
1762
130k
    }
1763
18.8k
    if (best == esize) *ind = index;
1764
18.8k
    *near_ind = near_index;
1765
18.8k
}
1766
1767
static inline int pdfi_encoding_name_to_index(pdf_name *name)
1768
123k
{
1769
123k
    int ind = gs_error_undefined;
1770
123k
    if (pdfi_type_of(name) == PDF_NAME) {
1771
123k
        if (pdfi_name_is(name, "StandardEncoding")) {
1772
59.6k
            ind = ENCODING_INDEX_STANDARD;
1773
64.2k
        } else if (pdfi_name_is(name, "WinAnsiEncoding")) {
1774
53.3k
            ind = ENCODING_INDEX_WINANSI;
1775
53.3k
        }
1776
10.9k
        else if (pdfi_name_is(name, "MacRomanEncoding")) {
1777
10.5k
            ind = ENCODING_INDEX_MACROMAN;
1778
10.5k
        }
1779
409
        else if (pdfi_name_is(name, "MacExpertEncoding")) {
1780
32
            ind = ENCODING_INDEX_MACEXPERT;
1781
32
        }
1782
377
        else if (pdfi_name_is(name, "SymbolEncoding")) {
1783
0
            ind = ENCODING_INDEX_SYMBOL;
1784
0
        }
1785
377
        else if (pdfi_name_is(name, "DingbatsEncoding")) {
1786
0
            ind = ENCODING_INDEX_DINGBATS;
1787
0
        }
1788
123k
    }
1789
123k
    return ind;
1790
123k
}
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
120k
{
1798
120k
    int i, code = 0;
1799
120k
    unsigned char gs_encoding;
1800
120k
    gs_glyph temp;
1801
120k
    gs_const_string str;
1802
120k
    pdf_name *n = NULL;
1803
1804
120k
    if (pdfi_array_size(Encoding) < 256)
1805
0
        return gs_note_error(gs_error_rangecheck);
1806
1807
120k
    code = pdfi_encoding_name_to_index(name);
1808
120k
    if (code < 0)
1809
363
        return code;
1810
120k
    if (ind != NULL) *ind = (gs_encoding_index_t)code;
1811
120k
    gs_encoding = (unsigned char)code;
1812
120k
    code = 0;
1813
1814
30.9M
    for (i = 0;i<256;i++) {
1815
30.8M
        temp = gs_c_known_encode(i, gs_encoding);
1816
30.8M
        gs_c_glyph_name(temp, &str);
1817
30.8M
        code = pdfi_name_alloc(ctx, (byte *)str.data, str.size, (pdf_obj **)&n);
1818
30.8M
        if (code < 0)
1819
0
            return code;
1820
30.8M
        pdfi_countup(n);
1821
30.8M
        code = pdfi_array_put(ctx, Encoding, (uint64_t)i, (pdf_obj *)n);
1822
30.8M
        pdfi_countdown(n);
1823
30.8M
        if (code < 0)
1824
0
            return code;
1825
30.8M
    }
1826
120k
    return 0;
1827
120k
}
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
129k
{
1840
129k
    int code = 0, i;
1841
129k
    gs_encoding_index_t encoding_index = ENCODING_INDEX_UNKNOWN, nearest_encoding_index = ENCODING_INDEX_UNKNOWN;
1842
1843
129k
    code = pdfi_array_alloc(ctx, 256, (pdf_array **)Encoding);
1844
129k
    if (code < 0)
1845
0
        return code;
1846
129k
    pdfi_countup(*Encoding);
1847
1848
129k
    switch (pdfi_type_of(pdf_Encoding)) {
1849
109k
        case PDF_NAME:
1850
109k
            code = pdfi_build_Encoding(ctx, (pdf_name *)pdf_Encoding, (pdf_array *)*Encoding, &encoding_index);
1851
109k
            if (code < 0) {
1852
363
                pdfi_countdown(*Encoding);
1853
363
                *Encoding = NULL;
1854
363
                return code;
1855
363
            }
1856
109k
            nearest_encoding_index = encoding_index;
1857
109k
            break;
1858
19.4k
        case PDF_DICT:
1859
19.4k
        {
1860
19.4k
            pdf_name *n = NULL;
1861
19.4k
            pdf_array *a = NULL;
1862
19.4k
            pdf_obj *o = NULL;
1863
19.4k
            int offset = 0;
1864
19.4k
            bool b_e_known;
1865
1866
19.4k
            if (pdfi_type_of(pdf_Encoding) == PDF_DICT) {
1867
19.4k
                code = pdfi_dict_known(ctx, (pdf_dict *)pdf_Encoding, "BaseEncoding", &b_e_known);
1868
19.4k
                if (code < 0)
1869
0
                    b_e_known = false;
1870
19.4k
            }
1871
0
            else {
1872
0
                b_e_known = false;
1873
0
            }
1874
1875
19.4k
            if (b_e_known == false && font_Encoding != NULL && pdfi_type_of(font_Encoding) == PDF_ARRAY) {
1876
8.23k
                pdf_array *fenc = (pdf_array *)font_Encoding;
1877
2.11M
                for (i = 0; i < pdfi_array_size(fenc) && code >= 0; i++) {
1878
2.10M
                    code = pdfi_array_get(ctx, fenc, (uint64_t)i, &o);
1879
2.10M
                    if (code >= 0)
1880
2.10M
                        code = pdfi_array_put(ctx, (pdf_array *)*Encoding, (uint64_t)i, o);
1881
2.10M
                    pdfi_countdown(o);
1882
2.10M
                }
1883
8.23k
                if (code < 0) {
1884
0
                    pdfi_countdown(*Encoding);
1885
0
                    *Encoding = NULL;
1886
0
                    return code;
1887
0
                }
1888
8.23k
            }
1889
11.2k
            else {
1890
11.2k
                code = pdfi_dict_get(ctx, (pdf_dict *)pdf_Encoding, "BaseEncoding", (pdf_obj **)&n);
1891
11.2k
                if (code >= 0) {
1892
3.23k
                    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.22k
                    else if (pdfi_name_is(n, "StandardEncoding") == true) {
1899
0
                        pdfi_set_warning(ctx, 0, NULL, W_PDF_INVALID_FONT_BASEENC, "pdfi_create_Encoding", NULL);
1900
0
                    }
1901
3.23k
                }
1902
1903
11.2k
                if (code < 0) {
1904
7.97k
                    code = pdfi_name_alloc(ctx, (byte *)"StandardEncoding", 16, (pdf_obj **)&n);
1905
7.97k
                    if (code < 0) {
1906
0
                        pdfi_countdown(*Encoding);
1907
0
                        *Encoding = NULL;
1908
0
                        return code;
1909
0
                    }
1910
7.97k
                    pdfi_countup(n);
1911
7.97k
                }
1912
1913
11.2k
                code = pdfi_build_Encoding(ctx, n, (pdf_array *)*Encoding, NULL);
1914
11.2k
                if (code < 0) {
1915
0
                    pdfi_countdown(*Encoding);
1916
0
                    *Encoding = NULL;
1917
0
                    pdfi_countdown(n);
1918
0
                    return code;
1919
0
                }
1920
11.2k
                pdfi_countdown(n);
1921
11.2k
            }
1922
19.4k
            code = pdfi_dict_knownget_type(ctx, (pdf_dict *)pdf_Encoding, "Differences", PDF_ARRAY, (pdf_obj **)&a);
1923
19.4k
            if (code <= 0) {
1924
449
                if (code < 0) {
1925
0
                    pdfi_countdown(*Encoding);
1926
0
                    *Encoding = NULL;
1927
0
                }
1928
449
                return code;
1929
449
            }
1930
1931
1.79M
            for (i=0;i < pdfi_array_size(a);i++) {
1932
1.77M
                pdf_obj_type type;
1933
1.77M
                code = pdfi_array_get(ctx, a, (uint64_t)i, &o);
1934
1.77M
                if (code < 0)
1935
10
                    break;
1936
1.77M
                type = pdfi_type_of(o);
1937
1.77M
                if (type == PDF_NAME) {
1938
1.61M
                    if (offset < pdfi_array_size((pdf_array *)*Encoding))
1939
1.60M
                        code = pdfi_array_put(ctx, (pdf_array *)*Encoding, (uint64_t)offset, o);
1940
1.61M
                    pdfi_countdown(o);
1941
1.61M
                    offset++;
1942
1.61M
                    if (code < 0)
1943
0
                        break;
1944
1.61M
                } else if (type == PDF_INT) {
1945
162k
                    offset = ((pdf_num *)o)->value.i;
1946
162k
                    pdfi_countdown(o);
1947
162k
                } else {
1948
65
                    code = gs_note_error(gs_error_typecheck);
1949
65
                    pdfi_countdown(o);
1950
65
                    break;
1951
65
                }
1952
1.77M
            }
1953
18.9k
            pdfi_countdown(a);
1954
18.9k
            if (code < 0) {
1955
75
                pdfi_countdown(*Encoding);
1956
75
                *Encoding = NULL;
1957
75
                return code;
1958
75
            }
1959
18.9k
            if (ppdffont != NULL) /* No sense doing this if we can't record the result */
1960
18.9k
                pdfi_gs_simple_font_encoding_indices(ctx, (pdf_array *)(*Encoding), &encoding_index, &nearest_encoding_index);
1961
18.9k
            break;
1962
18.9k
        }
1963
450
        default:
1964
450
            pdfi_countdown(*Encoding);
1965
450
            *Encoding = NULL;
1966
450
            return gs_note_error(gs_error_typecheck);
1967
129k
    }
1968
128k
    if (ppdffont != NULL) {
1969
78.4k
        ppdffont->pfont->encoding_index = encoding_index;
1970
78.4k
        ppdffont->pfont->nearest_encoding_index = nearest_encoding_index;
1971
78.4k
    }
1972
128k
    return 0;
1973
129k
}
1974
1975
gs_glyph pdfi_encode_char(gs_font * pfont, gs_char chr, gs_glyph_space_t not_used)
1976
74.3M
{
1977
74.3M
    int code;
1978
74.3M
    unsigned int nindex = 0;
1979
74.3M
    gs_glyph g = GS_NO_GLYPH;
1980
1981
74.3M
    if (pfont->FontType == ft_encrypted || pfont->FontType == ft_encrypted2
1982
578k
     || pfont->FontType == ft_user_defined || pfont->FontType == ft_TrueType
1983
578k
     || pfont->FontType == ft_MicroType
1984
74.3M
     || pfont->FontType == ft_PDF_user_defined) {
1985
74.3M
        pdf_font *font = (pdf_font *)pfont->client_data;
1986
74.3M
        pdf_context *ctx = (pdf_context *)font->ctx;
1987
1988
74.3M
        if (font->Encoding != NULL) { /* safety */
1989
74.3M
            pdf_name *GlyphName = NULL;
1990
74.3M
            code = pdfi_array_get(ctx, font->Encoding, (uint64_t)chr, (pdf_obj **)&GlyphName);
1991
74.3M
            if (code >= 0) {
1992
74.3M
                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
74.3M
                code = (*ctx->get_glyph_index)(pfont, (byte *)GlyphName->data, GlyphName->length, &nindex);
1997
74.3M
                pdfi_countdown(GlyphName);
1998
74.3M
                if (code >= 0)
1999
74.3M
                    g = (gs_glyph)nindex;
2000
74.3M
            }
2001
74.3M
        }
2002
74.3M
    }
2003
2004
74.3M
    return g;
2005
74.3M
}
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.94k
{
2013
6.94k
    int i;
2014
6.94k
    *decoding = NULL;
2015
6.94k
    *substnwp = NULL;
2016
    /* This only makes sense for Adobe orderings */
2017
6.94k
    if (reglen == 5 && !memcmp(reg, "Adobe", 5)) {
2018
37.2k
        for (i = 0; pdfi_cid_decoding_list[i] != NULL; i++) {
2019
31.1k
            if (strlen(pdfi_cid_decoding_list[i]->s_order) == ordlen &&
2020
593
                !memcmp(pdfi_cid_decoding_list[i]->s_order, ord, ordlen)) {
2021
253
                *decoding = (pdfi_cid_decoding_t *)pdfi_cid_decoding_list[i];
2022
253
                break;
2023
253
            }
2024
31.1k
        }
2025
        /* For now, also only for Adobe orderings */
2026
37.3k
        for (i = 0; pdfi_cid_substnwp_list[i] != NULL; i++) {
2027
31.2k
            if (strlen(pdfi_cid_substnwp_list[i]->ordering) == ordlen &&
2028
593
                !memcmp(pdfi_cid_substnwp_list[i]->ordering, ord, ordlen)) {
2029
253
                *substnwp = (pdfi_cid_subst_nwp_table_t *)pdfi_cid_substnwp_list[i];
2030
253
                break;
2031
253
            }
2032
31.2k
        }
2033
6.36k
    }
2034
6.94k
}
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.51M
{
2038
1.51M
    int i, l = 0;
2039
1.51M
    int code = gs_error_undefined;
2040
1.51M
    unsigned char *ucode = (unsigned char *)unicode_return;
2041
2042
1.51M
    if (tounicode != NULL) {
2043
724k
        gs_cmap_lookups_enum_t lenum;
2044
724k
        gs_cmap_lookups_enum_init((const gs_cmap_t *)tounicode->gscmap, 0, &lenum);
2045
31.8M
        while (l == 0 && gs_cmap_enum_next_lookup(ctx->memory, &lenum) == 0) {
2046
31.0M
            gs_cmap_lookups_enum_t counter = lenum;
2047
62.1M
            while (l == 0 && gs_cmap_enum_next_entry(&counter) == 0) {
2048
31.0M
                if (counter.entry.value_type == CODE_VALUE_CID) {
2049
31.0M
                    if (counter.entry.key_is_range) {
2050
7.29M
                        unsigned int v0 = 0, v1 = 0;
2051
16.2M
                        for (i = 0; i < counter.entry.key_size; i++) {
2052
8.95M
                            v0 |= (counter.entry.key[0][counter.entry.key_size - i - 1]) << (i * 8);
2053
8.95M
                        }
2054
16.2M
                        for (i = 0; i < counter.entry.key_size; i++) {
2055
8.95M
                            v1 |= (counter.entry.key[1][counter.entry.key_size - i - 1]) << (i * 8);
2056
8.95M
                        }
2057
2058
7.29M
                        if (ch >= v0 && ch <= v1) {
2059
148k
                            unsigned int offs = ch - v0;
2060
2061
148k
                            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
148k
                            else if (counter.entry.value.size == 2) {
2069
147k
                                l = 2;
2070
147k
                                if (ucode != NULL && length >= l) {
2071
108k
                                    ucode[0] = counter.entry.value.data[0] + ((offs >> 8) & 0xff);
2072
108k
                                    ucode[1] = counter.entry.value.data[1] + (offs & 0xff);
2073
108k
                                }
2074
147k
                            }
2075
1.36k
                            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.34k
                            else {
2085
1.34k
                                l = 4;
2086
1.34k
                                if (ucode != NULL && length >= l) {
2087
1.34k
                                    ucode[0] = counter.entry.value.data[0] + ((offs >> 24) & 0xff);
2088
1.34k
                                    ucode[1] = counter.entry.value.data[1] + ((offs >> 16) & 0xff);
2089
1.34k
                                    ucode[2] = counter.entry.value.data[2] + ((offs >> 8) & 0xff);
2090
1.34k
                                    ucode[3] = counter.entry.value.data[3] + (offs & 0xff);
2091
1.34k
                                }
2092
1.34k
                            }
2093
148k
                        }
2094
7.29M
                    }
2095
23.7M
                    else {
2096
23.7M
                        unsigned int v = 0;
2097
70.4M
                        for (i = 0; i < counter.entry.key_size; i++) {
2098
46.6M
                            v |= (counter.entry.key[0][counter.entry.key_size - i - 1]) << (i * 8);
2099
46.6M
                        }
2100
23.7M
                        if (ch == v) {
2101
165k
                            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
165k
                            else if (counter.entry.value.size == 2) {
2109
164k
                                l = 2;
2110
164k
                                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
164k
                            }
2115
527
                            else if (counter.entry.value.size == 3) {
2116
52
                                l = 4;
2117
52
                                if (ucode != NULL && length >= l) {
2118
33
                                    ucode[0] = 0;
2119
33
                                    ucode[1] = counter.entry.value.data[0];
2120
33
                                    ucode[2] = counter.entry.value.data[1];
2121
33
                                    ucode[3] = counter.entry.value.data[2];
2122
33
                                }
2123
52
                            }
2124
475
                            else {
2125
475
                                l = 4;
2126
475
                                if (ucode != NULL && length >= l) {
2127
391
                                    ucode[0] = counter.entry.value.data[0];
2128
391
                                    ucode[1] = counter.entry.value.data[1];
2129
391
                                    ucode[2] = counter.entry.value.data[2];
2130
391
                                    ucode[3] = counter.entry.value.data[3];
2131
391
                                }
2132
475
                            }
2133
165k
                        }
2134
23.7M
                    }
2135
31.0M
                }
2136
31.0M
            }
2137
31.0M
        }
2138
724k
        if (l > 0)
2139
314k
            code = l;
2140
724k
    }
2141
2142
1.51M
    return code;
2143
1.51M
}
2144
2145
int
2146
pdfi_cidfont_decode_glyph(gs_font *font, gs_glyph glyph, int ch, ushort *u, unsigned int length)
2147
500k
{
2148
500k
    gs_glyph cc = glyph < GS_MIN_CID_GLYPH ? glyph : glyph - GS_MIN_CID_GLYPH;
2149
500k
    pdf_cidfont_t *pcidfont = (pdf_cidfont_t *)font->client_data;
2150
500k
    int code = gs_error_undefined, i;
2151
500k
    uchar *unicode_return = (uchar *)u;
2152
500k
    pdfi_cid_subst_nwp_table_t *substnwp = pcidfont->substnwp;
2153
2154
500k
    code = gs_error_undefined;
2155
503k
    while (1) { /* Loop to make retrying with a substitute CID easier */
2156
        /* Favour the ToUnicode if one exists */
2157
503k
        code = pdfi_tounicode_char_to_unicode(pcidfont->ctx, (pdf_cmap *)pcidfont->ToUnicode, glyph, ch, u, length);
2158
2159
503k
        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
503k
        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
500k
        break;
2228
503k
    }
2229
500k
    return (code < 0 ? 0 : code);
2230
500k
}
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
500k
{
2236
500k
    pdf_font *pdffont = (pdf_font *)font->client_data;
2237
500k
    int code = 0;
2238
2239
500k
    if (pdffont->pdfi_font_type != e_pdf_cidfont_type0 && pdffont->pdfi_font_type != e_pdf_cidfont_type1
2240
499k
     && pdffont->pdfi_font_type != e_pdf_cidfont_type2 && pdffont->pdfi_font_type != e_pdf_cidfont_type4) {
2241
499k
        code = pdfi_tounicode_char_to_unicode(pdffont->ctx, (pdf_cmap *)pdffont->ToUnicode, glyph, ch, unicode_return, length);
2242
499k
    }
2243
500k
    if (code < 0) code = 0;
2244
2245
500k
    return code;
2246
500k
}
2247
2248
int pdfi_glyph_index(gs_font *pfont, byte *str, uint size, uint *glyph)
2249
4.47k
{
2250
4.47k
    int code = 0;
2251
4.47k
    pdf_font *font = (pdf_font *)pfont->client_data;
2252
2253
4.47k
    code = pdfi_get_name_index(font->ctx, (char *)str, size, glyph);
2254
2255
4.47k
    return code;
2256
4.47k
}
2257
2258
int pdfi_glyph_name(gs_font * pfont, gs_glyph glyph, gs_const_string * pstr)
2259
1.58k
{
2260
1.58k
    int code = gs_error_invalidfont;
2261
2262
1.58k
    if (pfont->FontType == ft_encrypted || pfont->FontType == ft_encrypted2
2263
0
     || pfont->FontType == ft_user_defined || pfont->FontType == ft_TrueType
2264
1.58k
     || pfont->FontType == ft_PDF_user_defined || pfont->FontType == ft_MicroType) {
2265
1.58k
        pdf_font *font = (pdf_font *)pfont->client_data;
2266
2267
1.58k
        code = pdfi_name_from_index(font->ctx, glyph, (unsigned char **)&pstr->data, &pstr->size);
2268
1.58k
    }
2269
2270
1.58k
    return code;
2271
1.58k
}
2272
2273
2274
static int pdfi_global_glyph_code(const gs_font *pfont, gs_const_string *gstr, gs_glyph *pglyph)
2275
10
{
2276
10
    int code = 0;
2277
10
    if (pfont->FontType == ft_encrypted) {
2278
3
        code = pdfi_t1_global_glyph_code(pfont, gstr, pglyph);
2279
3
    }
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
10
    return code;
2287
10
}
2288
2289
int pdfi_map_glyph_name_via_agl(pdf_dict *cstrings, pdf_name *gname, pdf_string **cstring)
2290
368k
{
2291
368k
    single_glyph_list_t *sgl = (single_glyph_list_t *)&(SingleGlyphList);
2292
368k
    int i, code, ucode = gs_error_undefined;
2293
368k
    *cstring = NULL;
2294
2295
368k
    if (gname->length == 7 && strncmp((char *)gname->data, "uni", 3) == 0) {
2296
3.35k
        char u[5] = {0};
2297
3.35k
        memcpy(u, gname->data + 3, 4);
2298
3.35k
        code = sscanf(u, "%x", &ucode);
2299
3.35k
        if (code <= 0)
2300
0
            ucode = gs_error_undefined;
2301
3.35k
    }
2302
2303
368k
    if (ucode == gs_error_undefined) {
2304
1.36G
        for (i = 0; sgl[i].Glyph != 0x00; i++) {
2305
1.36G
            if (sgl[i].Glyph[0] == gname->data[0]
2306
28.9M
                && strlen(sgl[i].Glyph) == gname->length
2307
462k
                && !strncmp((char *)sgl[i].Glyph, (char *)gname->data, gname->length)) {
2308
111k
                ucode = (int)sgl[i].Unicode;
2309
111k
                break;
2310
111k
            }
2311
1.36G
        }
2312
364k
    }
2313
368k
    if (ucode > 0) {
2314
478M
        for (i = 0; sgl[i].Glyph != 0x00; i++) {
2315
478M
            if (sgl[i].Unicode == (unsigned short)ucode) {
2316
117k
                pdf_string *s;
2317
117k
                code = pdfi_dict_get((pdf_context *)cstrings->ctx, cstrings, (char *)sgl[i].Glyph, (pdf_obj **)&s);
2318
117k
                if (code >= 0) {
2319
2.65k
                    *cstring = s;
2320
2.65k
                    break;
2321
2.65k
                }
2322
117k
            }
2323
478M
        }
2324
115k
        if (*cstring == NULL) {
2325
112k
            char u[16] = {0};
2326
112k
            code = gs_snprintf(u, 16, "uni%04x", ucode);
2327
112k
            if (code > 0) {
2328
112k
                pdf_string *s;
2329
112k
                code = pdfi_dict_get((pdf_context *)cstrings->ctx, cstrings, u, (pdf_obj **)&s);
2330
112k
                if (code >= 0) {
2331
2
                    *cstring = s;
2332
2
                }
2333
112k
            }
2334
112k
        }
2335
115k
    }
2336
2337
368k
    if (*cstring == NULL)
2338
365k
        code = gs_note_error(gs_error_undefined);
2339
2.65k
    else
2340
2.65k
        code = 0;
2341
2342
368k
    return code;
2343
368k
}
2344
2345
2346
int pdfi_init_font_directory(pdf_context *ctx)
2347
105k
{
2348
105k
    gs_font_dir *pfdir = ctx->memory->gs_lib_ctx->font_dir;
2349
105k
    if (pfdir) {
2350
89.0k
        ctx->font_dir = gs_font_dir_alloc2_limits(ctx->memory, ctx->memory,
2351
89.0k
                   pfdir->smax, pfdir->ccache.bmax, pfdir->fmcache.mmax,
2352
89.0k
                   pfdir->ccache.cmax, pfdir->ccache.upper);
2353
89.0k
        if (ctx->font_dir == NULL) {
2354
0
            return_error(gs_error_VMerror);
2355
0
        }
2356
89.0k
        ctx->font_dir->align_to_pixels = pfdir->align_to_pixels;
2357
89.0k
        ctx->font_dir->grid_fit_tt = pfdir->grid_fit_tt;
2358
89.0k
    }
2359
16.0k
    else {
2360
16.0k
        ctx->font_dir = gs_font_dir_alloc2(ctx->memory, ctx->memory);
2361
16.0k
        if (ctx->font_dir == NULL) {
2362
0
            return_error(gs_error_VMerror);
2363
0
        }
2364
16.0k
    }
2365
105k
    ctx->font_dir->global_glyph_code = pdfi_global_glyph_code;
2366
105k
    return 0;
2367
105k
}
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
425k
{
2375
425k
    pdf_obj *fname = NULL;
2376
425k
    pdf_obj *fontobjtype = NULL;
2377
425k
    pdf_dict *fdict = NULL;
2378
425k
    int code;
2379
425k
    gs_font *pgsfont = NULL;
2380
425k
    const char *fs = "Font";
2381
425k
    pdf_name *Type1Name = NULL;
2382
2383
425k
    code = pdfi_name_alloc(ctx, (byte *)fontname, length, &fname);
2384
425k
    if (code < 0)
2385
0
        return code;
2386
425k
    pdfi_countup(fname);
2387
2388
425k
    code = pdfi_name_alloc(ctx, (byte *)fs, strlen(fs), &fontobjtype);
2389
425k
    if (code < 0)
2390
0
        goto exit;
2391
425k
    pdfi_countup(fontobjtype);
2392
2393
425k
    code = pdfi_dict_alloc(ctx, 1, &fdict);
2394
425k
    if (code < 0)
2395
0
        goto exit;
2396
425k
    pdfi_countup(fdict);
2397
2398
425k
    code = pdfi_dict_put(ctx, fdict, "BaseFont", fname);
2399
425k
    if (code < 0)
2400
0
        goto exit;
2401
2402
425k
    code = pdfi_dict_put(ctx, fdict, "Type", fontobjtype);
2403
425k
    if (code < 0)
2404
0
        goto exit;
2405
2406
425k
    code = pdfi_obj_charstr_to_name(ctx, "Type1", &Type1Name);
2407
425k
    if (code < 0)
2408
0
        goto exit;
2409
2410
425k
    code = pdfi_dict_put(ctx, fdict, "Subtype", (pdf_obj *)Type1Name);
2411
425k
    if (code < 0)
2412
0
        goto exit;
2413
2414
425k
    code = pdfi_load_font(ctx, NULL, NULL, fdict, &pgsfont, false);
2415
425k
    if (code < 0)
2416
0
        goto exit;
2417
2418
425k
    *ppdffont = (pdf_obj *)pgsfont->client_data;
2419
2420
425k
 exit:
2421
425k
    pdfi_countdown(Type1Name);
2422
425k
    pdfi_countdown(fontobjtype);
2423
425k
    pdfi_countdown(fname);
2424
425k
    pdfi_countdown(fdict);
2425
425k
    return code;
2426
425k
}
2427
2428
2429
int pdfi_font_create_widths(pdf_context *ctx, pdf_dict *fontdict, pdf_font *font, double scale)
2430
515k
{
2431
515k
    int code = 0;
2432
515k
    pdf_obj *obj = NULL;
2433
515k
    int i;
2434
2435
515k
    font->Widths = NULL;
2436
2437
515k
    if (font->FontDescriptor != NULL) {
2438
67.0k
        code = pdfi_dict_knownget(ctx, font->FontDescriptor, "MissingWidth", &obj);
2439
67.0k
        if (code > 0) {
2440
5.82k
            if (pdfi_type_of(obj) == PDF_INT) {
2441
5.82k
                font->MissingWidth = ((pdf_num *) obj)->value.i * scale;
2442
5.82k
            }
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.82k
            pdfi_countdown(obj);
2450
5.82k
            obj = NULL;
2451
5.82k
        }
2452
61.2k
        else {
2453
61.2k
            font->MissingWidth = 0;
2454
61.2k
        }
2455
67.0k
    }
2456
447k
    else {
2457
447k
        font->MissingWidth = 0;
2458
447k
    }
2459
2460
515k
    code = pdfi_dict_knownget_type(ctx, fontdict, "Widths", PDF_ARRAY, (pdf_obj **)&obj);
2461
515k
    if (code > 0) {
2462
71.4k
        if (pdfi_array_size((pdf_array *)obj) < font->LastChar - font->FirstChar + 1) {
2463
2.28k
            code = gs_note_error(gs_error_rangecheck);
2464
2.28k
            goto error;
2465
2.28k
        }
2466
2467
69.1k
        font->Widths = (double *)gs_alloc_bytes(OBJ_MEMORY(font), (size_t)sizeof(double) * (font->LastChar - font->FirstChar + 1), "pdfi_font_create_widths(Widths)");
2468
69.1k
        if (font->Widths == NULL) {
2469
0
            code = gs_note_error(gs_error_VMerror);
2470
0
            goto error;
2471
0
        }
2472
69.1k
        memset(font->Widths, 0x00, sizeof(double) * (font->LastChar - font->FirstChar + 1));
2473
7.02M
        for (i = 0; i < (font->LastChar - font->FirstChar + 1); i++) {
2474
6.95M
            code = pdfi_array_get_number(ctx, (pdf_array *)obj, (uint64_t)i, &font->Widths[i]);
2475
6.95M
            if (code < 0)
2476
238
                goto error;
2477
6.95M
            font->Widths[i] *= scale;
2478
6.95M
        }
2479
69.1k
    }
2480
515k
error:
2481
515k
    pdfi_countdown(obj);
2482
515k
    if (code < 0) {
2483
5.83k
        gs_free_object(OBJ_MEMORY(font), font->Widths, "pdfi_font_create_widths(Widths)");
2484
5.83k
        font->Widths = NULL;
2485
5.83k
    }
2486
515k
    return code;
2487
515k
}
2488
2489
void pdfi_font_set_first_last_char(pdf_context *ctx, pdf_dict *fontdict, pdf_font *font)
2490
562k
{
2491
562k
    double f, l;
2492
562k
    int code;
2493
2494
562k
    if (fontdict == NULL) {
2495
47.0k
        f = (double)0;
2496
47.0k
        l = (double)255;
2497
47.0k
    }
2498
515k
    else {
2499
515k
        code = pdfi_dict_get_number(ctx, fontdict, "FirstChar", &f);
2500
515k
        if (code < 0 || f < 0 || f > 255)
2501
440k
            f = (double)0;
2502
2503
515k
        code = pdfi_dict_get_number(ctx, fontdict, "LastChar", &l);
2504
515k
        if (code < 0 || l < 0 || l > 255)
2505
440k
            l = (double)255;
2506
515k
    }
2507
562k
    if (f <= l) {
2508
562k
        font->FirstChar = (int)f;
2509
562k
        font->LastChar = (int)l;
2510
562k
    }
2511
55
    else {
2512
55
        font->FirstChar = 0;
2513
55
        font->LastChar = 255;
2514
55
    }
2515
562k
}
2516
2517
void pdfi_font_set_orig_fonttype(pdf_context *ctx, pdf_font *font)
2518
569k
{
2519
569k
    pdf_name *ftype;
2520
569k
    pdf_dict *fontdict = font->PDF_font;
2521
569k
    int code;
2522
2523
569k
    code = pdfi_dict_get_type(ctx, fontdict, "Subtype", PDF_NAME, (pdf_obj**)&ftype);
2524
569k
    if (code < 0) {
2525
47.7k
        font->orig_FontType = ft_undefined;
2526
47.7k
    }
2527
521k
    else {
2528
521k
        if (pdfi_name_is(ftype, "Type1") || pdfi_name_is(ftype, "MMType1"))
2529
463k
            font->orig_FontType = ft_encrypted;
2530
58.3k
        else if (pdfi_name_is(ftype, "Type1C"))
2531
0
            font->orig_FontType = ft_encrypted2;
2532
58.3k
        else if (pdfi_name_is(ftype, "TrueType"))
2533
41.6k
            font->orig_FontType = ft_TrueType;
2534
16.6k
        else if (pdfi_name_is(ftype, "Type3"))
2535
2.15k
            font->orig_FontType = ft_user_defined;
2536
14.4k
        else if (pdfi_name_is(ftype, "CIDFontType0"))
2537
2.72k
            font->orig_FontType = ft_CID_encrypted;
2538
11.7k
        else if (pdfi_name_is(ftype, "CIDFontType2"))
2539
11.1k
            font->orig_FontType = ft_CID_TrueType;
2540
649
        else
2541
649
            font->orig_FontType = ft_undefined;
2542
521k
    }
2543
569k
    pdfi_countdown(ftype);
2544
569k
}
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
94.0k
{
2555
94.0k
    gs_const_string fn;
2556
94.0k
    int i;
2557
94.0k
    uint32_t hash = 0;
2558
94.0k
    long *xvalues;
2559
94.0k
    int xuidlen = 3;
2560
2561
94.0k
    sfilename(ctx->main_stream->s, &fn);
2562
94.0k
    if (fontdict!= NULL && fontdict->object_num != 0) {
2563
41.4k
        const byte *sb;
2564
41.4k
        size_t l;
2565
41.4k
        if (fn.size > 0) {
2566
15
            sb = fn.data;
2567
15
            l = fn.size;
2568
15
        }
2569
41.4k
        else {
2570
41.4k
            s_process_read_buf(ctx->main_stream->s);
2571
41.4k
            sb = sbufptr(ctx->main_stream->s);
2572
41.4k
            l = sbufavailable(ctx->main_stream->s) > 128 ? 128: sbufavailable(ctx->main_stream->s);
2573
41.4k
        }
2574
2575
5.34M
        for (i = 0; i < l; i++) {
2576
5.30M
            hash = ((((hash & 0xf8000000) >> 27) ^ (hash << 5)) & 0x7ffffffff) ^ sb[i];
2577
5.30M
        }
2578
41.4k
        hash = ((((hash & 0xf8000000) >> 27) ^ (hash << 5)) & 0x7ffffffff) ^ fontdict->object_num;
2579
2580
41.4k
        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
382
             uid_XUID_values(&pfont->UID)[1] = hash;
2585
382
             uid_XUID_values(&pfont->UID)[2] = ctx->device_state.HighLevelDevice ? fontdict->object_num : 0;
2586
382
        }
2587
41.0k
        else {
2588
41.0k
            if (uid_is_XUID(&pfont->UID))
2589
1.77k
                xuidlen += uid_XUID_size(&pfont->UID);
2590
39.3k
            else if (uid_is_valid(&pfont->UID))
2591
575
                xuidlen++;
2592
2593
41.0k
            xvalues = (long *)gs_alloc_bytes(pfont->memory, (size_t)xuidlen * sizeof(long), "pdfi_font_generate_pseudo_XUID");
2594
41.0k
            if (xvalues == NULL) {
2595
0
                return 0;
2596
0
            }
2597
41.0k
            xvalues[0] = 1000000; /* "Private" value */
2598
41.0k
            xvalues[1] = hash;
2599
2600
41.0k
            xvalues[2] = ctx->device_state.HighLevelDevice ? fontdict->object_num : 0;
2601
2602
41.0k
            if (uid_is_XUID(&pfont->UID)) {
2603
11.1k
                for (i = 0; i < uid_XUID_size(&pfont->UID); i++) {
2604
9.42k
                    xvalues[i + 3] = uid_XUID_values(&pfont->UID)[i];
2605
9.42k
                }
2606
1.77k
                uid_free(&pfont->UID, pfont->memory, "pdfi_font_generate_pseudo_XUID");
2607
1.77k
            }
2608
39.3k
            else if (uid_is_valid(&pfont->UID))
2609
575
                xvalues[3] = pfont->UID.id;
2610
2611
41.0k
            uid_set_XUID(&pfont->UID, xvalues, xuidlen);
2612
41.0k
        }
2613
41.4k
    }
2614
94.0k
    return 0;
2615
94.0k
}
2616
2617
int pdfi_default_font_info(gs_font *font, const gs_point *pscale, int members, gs_font_info_t *info)
2618
94.9k
{
2619
94.9k
    pdf_font *pdff = (pdf_font *)font->client_data;
2620
94.9k
    int code;
2621
2622
    /* We *must* call this first as it sets info->members = 0; */
2623
94.9k
    code = pdff->default_font_info(font, pscale, members, info);
2624
94.9k
    if (code < 0)
2625
6.91k
        return code;
2626
88.0k
    if ((members & FONT_INFO_EMBEDDED) != 0) {
2627
88.0k
        info->orig_FontType = pdff->orig_FontType;
2628
88.0k
        if (pdff->pdfi_font_type == e_pdf_font_type3) {
2629
641
            info->FontEmbedded = (int)(true);
2630
641
            info->members |= FONT_INFO_EMBEDDED;
2631
641
        }
2632
87.4k
        else {
2633
87.4k
            info->FontEmbedded = (int)(pdff->substitute == font_embedded);
2634
87.4k
            info->members |= FONT_INFO_EMBEDDED;
2635
87.4k
        }
2636
88.0k
    }
2637
88.0k
    if (pdff->pdfi_font_type != e_pdf_font_truetype && pdff->pdfi_font_type != e_pdf_cidfont_type2) {
2638
53.5k
        if (((members & FONT_INFO_COPYRIGHT) != 0) && pdff->copyright != NULL) {
2639
32.1k
            info->Copyright.data = pdff->copyright->data;
2640
32.1k
            info->Copyright.size = pdff->copyright->length;
2641
32.1k
            info->members |= FONT_INFO_COPYRIGHT;
2642
32.1k
        }
2643
53.5k
        if (((members & FONT_INFO_NOTICE) != 0) && pdff->notice != NULL) {
2644
33.9k
            info->Notice.data = pdff->notice->data;
2645
33.9k
            info->Notice.size = pdff->notice->length;
2646
33.9k
            info->members |= FONT_INFO_NOTICE;
2647
33.9k
        }
2648
53.5k
        if (((members & FONT_INFO_FAMILY_NAME) != 0) && pdff->familyname != NULL) {
2649
33.9k
            info->FamilyName.data = pdff->familyname->data;
2650
33.9k
            info->FamilyName.size = pdff->familyname->length;
2651
33.9k
            info->members |= FONT_INFO_FAMILY_NAME;
2652
33.9k
        }
2653
53.5k
        if (((members & FONT_INFO_FULL_NAME) != 0) && pdff->fullname != NULL) {
2654
33.9k
            info->FullName.data = pdff->fullname->data;
2655
33.9k
            info->FullName.size = pdff->fullname->length;
2656
33.9k
            info->members |= FONT_INFO_FULL_NAME;
2657
33.9k
        }
2658
53.5k
    }
2659
88.0k
    return 0;
2660
94.9k
}
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
425k
{
2667
425k
    int code;
2668
425k
    pdf_font *pdffont = (pdf_font *)fontobj;
2669
2670
425k
    if (pdfi_type_of(pdffont) != PDF_FONT || pdffont->pfont == NULL)
2671
0
        return_error(gs_error_invalidfont);
2672
2673
425k
    code = gs_setPDFfontsize(ctx->pgs, point_size);
2674
425k
    if (code < 0)
2675
0
        return code;
2676
2677
425k
    return pdfi_gs_setfont(ctx, (gs_font *)pdffont->pfont);
2678
425k
}
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
425k
{
2686
425k
    int code = 0;
2687
425k
    pdf_obj *font = NULL;
2688
2689
2690
425k
    code = pdfi_load_font_by_name_string(ctx, fontname, length, &font);
2691
425k
    if (code < 0) goto exit;
2692
2693
425k
    code = pdfi_set_font_internal(ctx, font, point_size);
2694
2695
425k
 exit:
2696
425k
    pdfi_countdown(font);
2697
425k
    return code;
2698
425k
}
2699
2700
int pdfi_font_set_internal_string(pdf_context *ctx, const char *fontname, double point_size)
2701
16.6k
{
2702
16.6k
    return pdfi_font_set_internal_inner(ctx, (const byte *)fontname, strlen(fontname), point_size);
2703
16.6k
}
2704
2705
int pdfi_font_set_internal_name(pdf_context *ctx, pdf_name *fontname, double point_size)
2706
409k
{
2707
409k
    if (pdfi_type_of(fontname) != PDF_NAME)
2708
0
        return_error(gs_error_typecheck);
2709
409k
    else
2710
409k
        return pdfi_font_set_internal_inner(ctx, fontname->data, fontname->length, point_size);
2711
409k
}