Coverage Report

Created: 2026-08-08 08:00

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