Coverage Report

Created: 2026-02-14 07:09

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