Coverage Report

Created: 2026-04-01 07:17

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.04M
{
48
1.04M
    int code = 0;
49
1.04M
    pdfi_int_gstate *igs = (pdfi_int_gstate *)ctx->pgs->client_data;
50
1.04M
    pdf_font *old_font = igs->current_font;
51
52
1.04M
    code = gs_setfont(ctx->pgs, pfont);
53
1.04M
    if (code >= 0) {
54
1.04M
        igs->current_font = (pdf_font *)pfont->client_data;
55
1.04M
        pdfi_countup(igs->current_font);
56
1.04M
        pdfi_countdown(old_font);
57
1.04M
    }
58
1.04M
    return code;
59
1.04M
}
60
61
static void pdfi_cache_resource_font(pdf_context *ctx, pdf_obj *fontdesc, pdf_obj *ppdffont)
62
28.8k
{
63
28.8k
    resource_font_cache_t *entry = NULL;
64
28.8k
    int i;
65
66
28.8k
    if (ctx->resource_font_cache == NULL) {
67
17.5k
        ctx->resource_font_cache = (resource_font_cache_t *)gs_alloc_bytes(ctx->memory, RESOURCE_FONT_CACHE_BLOCK_SIZE * sizeof(pdfi_name_entry_t), "pdfi_cache_resource_font");
68
17.5k
        if (ctx->resource_font_cache == NULL)
69
0
            return;
70
17.5k
        ctx->resource_font_cache_size = RESOURCE_FONT_CACHE_BLOCK_SIZE;
71
17.5k
        memset(ctx->resource_font_cache, 0x00, RESOURCE_FONT_CACHE_BLOCK_SIZE * sizeof(pdfi_name_entry_t));
72
17.5k
        entry = &ctx->resource_font_cache[0];
73
17.5k
    }
74
75
78.3k
    for (i = 0; entry == NULL && i < ctx->resource_font_cache_size; i++) {
76
49.5k
        if (ctx->resource_font_cache[i].pdffont == NULL) {
77
11.2k
            entry = &ctx->resource_font_cache[i];
78
11.2k
        }
79
38.3k
        else if (i == ctx->resource_font_cache_size - 1) {
80
2
            entry = (resource_font_cache_t *)gs_resize_object(ctx->memory, ctx->resource_font_cache, sizeof(pdfi_name_entry_t) * (ctx->resource_font_cache_size + RESOURCE_FONT_CACHE_BLOCK_SIZE), "pdfi_cache_resource_font");
81
2
            if (entry == NULL)
82
0
                break;
83
2
            memset(entry + ctx->resource_font_cache_size, 0x00, RESOURCE_FONT_CACHE_BLOCK_SIZE * sizeof(pdfi_name_entry_t));
84
2
            ctx->resource_font_cache = entry;
85
2
            entry = &ctx->resource_font_cache[ctx->resource_font_cache_size];
86
2
            ctx->resource_font_cache_size += RESOURCE_FONT_CACHE_BLOCK_SIZE;
87
2
        }
88
49.5k
    }
89
28.8k
    if (entry != NULL) {
90
28.8k
        entry->desc_obj_num = fontdesc->object_num;
91
28.8k
        entry->pdffont = ppdffont;
92
28.8k
        pdfi_countup(ppdffont);
93
28.8k
    }
94
28.8k
}
95
96
void pdfi_purge_cache_resource_font(pdf_context *ctx)
97
104k
{
98
104k
    int i;
99
667k
    for (i = 0; i < ctx->resource_font_cache_size; i++) {
100
563k
       pdfi_countdown(ctx->resource_font_cache[i].pdffont);
101
563k
    }
102
104k
    gs_free_object(ctx->memory, ctx->resource_font_cache, "pdfi_purge_cache_resource_font");
103
104k
    ctx->resource_font_cache = NULL;
104
104k
    ctx->resource_font_cache_size = 0;
105
104k
}
106
107
static int pdfi_find_cache_resource_font(pdf_context *ctx, pdf_obj *fontdesc, pdf_obj **ppdffont)
108
60.8k
{
109
60.8k
    int i, code = gs_error_undefined;
110
609k
    for (i = 0; i < ctx->resource_font_cache_size; i++) {
111
552k
        if (ctx->resource_font_cache[i].desc_obj_num == fontdesc->object_num) {
112
3.78k
           *ppdffont = ctx->resource_font_cache[i].pdffont;
113
3.78k
           pdfi_countup(*ppdffont);
114
3.78k
           code = 0;
115
3.78k
           break;
116
3.78k
        }
117
552k
    }
118
60.8k
    return code;
119
60.8k
}
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
574k
{
141
574k
    bool ignore = false;
142
574k
    int i;
143
574k
    pdf_name *nm = (pdf_name *)basefont;
144
145
574k
    if (basefont != NULL && pdfi_type_of(basefont) == PDF_NAME) {
146
2.61M
        for (i = 0; known_symbolic_font_names[i].name != NULL; i++) {
147
2.09M
            if (nm->length == known_symbolic_font_names[i].namelen
148
19.2k
             && !strncmp((char *)nm->data, known_symbolic_font_names[i].name, nm->length)) {
149
1.97k
                ignore = true;
150
1.97k
                break;
151
1.97k
            }
152
2.09M
        }
153
522k
    }
154
574k
    return ignore;
155
574k
}
156
157
static int
158
pdfi_font_match_glyph_widths(pdf_font *pdfont)
159
471k
{
160
471k
    int code = 0;
161
471k
    int i;
162
471k
    int sindex, lindex;
163
471k
    gs_font_base *pbfont = pdfont->pfont;
164
471k
    double fw = 0.0, ww = 0.0;
165
166
471k
    if (pdfont->LastChar <  pdfont->FirstChar || pdfont->Widths == NULL)
167
446k
        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
24.9k
    sindex = pdfont->FirstChar < 96 ? 96 : pdfont->FirstChar;
171
24.9k
    lindex = pdfont->LastChar > 122 ? 123 : pdfont->LastChar + 1;
172
173
434k
    for (i = sindex; i < lindex; i++) {
174
409k
        gs_glyph_info_t ginfo = {0};
175
409k
        gs_glyph g;
176
409k
        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
409k
        if (g != GS_NO_GLYPH && pdfont->Widths[i - pdfont->FirstChar] != 0.0
180
305k
          && (*pbfont->procs.glyph_info)((gs_font *)pbfont, g, NULL, GLYPH_INFO_WIDTH0, &ginfo) >= 0) {
181
304k
            fw += hypot(ginfo.width[0].x, ginfo.width[0].y);
182
304k
            ww += pdfont->Widths[i - pdfont->FirstChar];
183
304k
        }
184
409k
    }
185
    /* Only reduce font width, don't expand */
186
24.9k
    if (ww != 0.0 && fw != 0.0 && ww / fw < 1.0) {
187
7.51k
        gs_matrix nmat, smat = {1.0, 0.0, 0.0, 1.0, 0.0, 0.0};
188
7.51k
        double wscale;
189
7.51k
        smat.xx = smat.yy = ww/fw;
190
7.51k
        wscale = 1.0 / smat.xx;
191
192
7.51k
        gs_matrix_multiply(&pbfont->FontMatrix, &smat, &nmat);
193
7.51k
        memcpy(&pbfont->FontMatrix, &nmat, sizeof(pbfont->FontMatrix));
194
195
944k
        for (i = pdfont->FirstChar; i <= pdfont->LastChar; i++) {
196
937k
            pdfont->Widths[i - pdfont->FirstChar] *= wscale;
197
937k
        }
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.51k
        code = gs_purge_font((gs_font *)pbfont);
207
7.51k
        if (code >= 0)
208
7.51k
            code = gs_definefont(pbfont->dir, (gs_font *)pbfont);
209
7.51k
        if (code >= 0)
210
7.51k
            code = pdfi_fapi_passfont((pdf_font *)pdfont, 0, NULL, NULL, NULL, 0);
211
7.51k
    }
212
213
24.9k
    return code;
214
471k
}
215
216
/* Print a name object to stdout */
217
static void pdfi_print_font_name(pdf_context *ctx, pdf_name *n)
218
501k
{
219
501k
    if (ctx->args.QUIET != true)
220
0
        (void)outwrite(ctx->memory, (const char *)n->data, n->length);
221
501k
}
222
223
static void pdfi_print_font_string(pdf_context *ctx, pdf_string *s)
224
488k
{
225
488k
    if (ctx->args.QUIET != true)
226
0
        (void)outwrite(ctx->memory, (const char *)s->data, s->length);
227
488k
}
228
229
/* Print a null terminated string to stdout */
230
static void pdfi_print_cstring(pdf_context *ctx, const char *str)
231
1.52M
{
232
1.52M
    if (ctx->args.QUIET != true)
233
0
        (void)outwrite(ctx->memory, str, strlen(str));
234
1.52M
}
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
29.4k
{
244
29.4k
    int code = 0;
245
29.4k
    char fontfname[gp_file_name_sizeof];
246
29.4k
    stream *s;
247
29.4k
    pdf_name *cidname = NULL;
248
29.4k
    gs_const_string fname;
249
250
29.4k
    (void)pdfi_dict_get(ctx, font_dict, "BaseFont", (pdf_obj **)&cidname);
251
252
29.4k
    if (fallback == true) {
253
14.7k
        pdf_string *mname = NULL;
254
14.7k
        pdf_dict *csi = NULL;
255
14.7k
        pdf_name *fbname;
256
14.7k
        const char *cidfbstr = "CIDFallBack";
257
258
14.7k
        code = pdfi_fontmap_lookup_cidfont(ctx, font_dict, NULL, (pdf_obj **)&mname, findex);
259
260
14.7k
        if (mname == NULL || pdfi_type_of(mname) != PDF_STRING) {
261
14.7k
            pdfi_countdown(mname);
262
263
14.7k
            code = pdfi_object_alloc(ctx, PDF_NAME, strlen(cidfbstr), (pdf_obj **)&fbname);
264
14.7k
            if (code >= 0) {
265
14.7k
                pdfi_countup(fbname);
266
14.7k
                memcpy(fbname->data, cidfbstr, strlen(cidfbstr));
267
14.7k
                code = pdfi_fontmap_lookup_cidfont(ctx, font_dict, fbname, (pdf_obj **)&mname, findex);
268
14.7k
                pdfi_countdown(fbname);
269
14.7k
            }
270
271
14.7k
            if (code < 0 || pdfi_type_of(mname) != PDF_STRING) {
272
14.7k
                pdfi_countdown(mname);
273
14.7k
                mname = NULL;
274
14.7k
                code = pdfi_dict_get(ctx, font_dict, "CIDSystemInfo", (pdf_obj **)&csi);
275
14.7k
                if (code >= 0 && pdfi_type_of(csi) == PDF_DICT) {
276
11.9k
                    pdf_string *csi_reg = NULL, *csi_ord = NULL;
277
278
11.9k
                    if (pdfi_dict_get(ctx, csi, "Registry", (pdf_obj **)&csi_reg) >= 0
279
11.9k
                     && pdfi_dict_get(ctx, csi, "Ordering", (pdf_obj **)&csi_ord) >= 0
280
11.8k
                     && pdfi_type_of(csi_reg) == PDF_STRING && pdfi_type_of(csi_ord) == PDF_STRING
281
11.8k
                     && csi_reg->length + csi_ord->length + 1 < gp_file_name_sizeof - 1) {
282
11.8k
                        pdf_name *reg_ord;
283
11.8k
                        memcpy(fontfname, csi_reg->data, csi_reg->length);
284
11.8k
                        memcpy(fontfname + csi_reg->length, "-", 1);
285
11.8k
                        memcpy(fontfname + csi_reg->length + 1, csi_ord->data, csi_ord->length);
286
11.8k
                        fontfname[csi_reg->length + csi_ord->length + 1] = '\0';
287
288
11.8k
                        code = pdfi_name_alloc(ctx, (byte *)fontfname, strlen(fontfname), (pdf_obj **) &reg_ord);
289
11.8k
                        if (code >= 0) {
290
11.8k
                            pdfi_countup(reg_ord);
291
11.8k
                            code = pdfi_fontmap_lookup_cidfont(ctx, font_dict, reg_ord, (pdf_obj **)&mname, findex);
292
11.8k
                            pdfi_countdown(reg_ord);
293
11.8k
                        }
294
11.8k
                    }
295
11.9k
                    pdfi_countdown(csi_reg);
296
11.9k
                    pdfi_countdown(csi_ord);
297
11.9k
                }
298
14.7k
                pdfi_countdown(csi);
299
14.7k
            }
300
301
14.7k
            if (mname == NULL || pdfi_type_of(mname) != PDF_STRING) {
302
14.7k
                pdfi_countdown(mname);
303
14.7k
                mname = NULL;
304
14.7k
                code = pdfi_fontmap_lookup_cidfont(ctx, font_dict, NULL, (pdf_obj **)&mname, findex);
305
14.7k
            }
306
14.7k
        }
307
308
14.7k
        do {
309
14.7k
            if (code < 0 || pdfi_type_of(mname) != PDF_STRING) {
310
14.7k
                const char *fsprefix = "CIDFSubst/";
311
14.7k
                int fsprefixlen = strlen(fsprefix);
312
14.7k
                const char *defcidfallack = "DroidSansFallback.ttf";
313
14.7k
                int defcidfallacklen = strlen(defcidfallack);
314
315
14.7k
                pdfi_countdown(mname);
316
317
14.7k
                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
14.7k
                else {
324
14.7k
                    if (ctx->args.cidfsubstpath.data == NULL) {
325
14.7k
                        memcpy(fontfname, fsprefix, fsprefixlen);
326
14.7k
                    }
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
14.7k
                    if (ctx->args.cidfsubstfont.data == NULL) {
341
14.7k
                        int len = 0;
342
14.7k
                        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
14.7k
                        else {
360
14.7k
                            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
14.7k
                            else {
372
14.7k
                                memcpy(fontfname + fsprefixlen, defcidfallack, defcidfallacklen);
373
14.7k
                            }
374
14.7k
                        }
375
14.7k
                    }
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
14.7k
                    fontfname[fsprefixlen + defcidfallacklen] = '\0';
414
415
14.7k
                    code = pdfi_open_resource_file(ctx, fontfname, strlen(fontfname), &s);
416
14.7k
                    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
14.7k
                    else {
436
14.7k
                        if (cidname) {
437
14.5k
                            pdfi_print_cstring(ctx, "Loading CIDFont ");
438
14.5k
                            pdfi_print_font_name(ctx, (pdf_name *)cidname);
439
14.5k
                            pdfi_print_cstring(ctx, " substitute from ");
440
14.5k
                        }
441
182
                        else {
442
182
                            pdfi_print_cstring(ctx, "Loading nameless CIDFont from ");
443
182
                        }
444
14.7k
                        sfilename(s, &fname);
445
14.7k
                        if (fname.size < gp_file_name_sizeof) {
446
14.7k
                            memcpy(fontfname, fname.data, fname.size);
447
14.7k
                            fontfname[fname.size] = '\0';
448
14.7k
                        }
449
0
                        else {
450
0
                            strcpy(fontfname, "unnamed file");
451
0
                        }
452
14.7k
                        pdfi_print_cstring(ctx, fontfname);
453
14.7k
                        pdfi_print_cstring(ctx, "\n");
454
455
456
14.7k
                        sfseek(s, 0, SEEK_END);
457
14.7k
                        *buflen = sftell(s);
458
14.7k
                        sfseek(s, 0, SEEK_SET);
459
14.7k
                        *buf = gs_alloc_bytes(ctx->memory, *buflen, "pdfi_open_CIDFont_file(buf)");
460
14.7k
                        if (*buf != NULL) {
461
14.7k
                            sfread(*buf, 1, *buflen, s);
462
14.7k
                        }
463
0
                        else {
464
0
                            code = gs_note_error(gs_error_VMerror);
465
0
                        }
466
14.7k
                        sfclose(s);
467
14.7k
                        break;
468
14.7k
                    }
469
14.7k
                }
470
14.7k
            }
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
14.7k
        } while (code >= 0);
517
14.7k
    }
518
14.7k
    else {
519
14.7k
        const char *fsprefix = "CIDFont/";
520
14.7k
        const int fsprefixlen = strlen(fsprefix);
521
522
14.7k
        if (cidname == NULL || pdfi_type_of(cidname) != PDF_NAME
523
14.5k
         || fsprefixlen + cidname->length >= gp_file_name_sizeof) {
524
190
            code = gs_note_error(gs_error_invalidfont);
525
190
            goto exit;
526
190
        }
527
528
14.5k
        memcpy(fontfname, fsprefix, fsprefixlen);
529
14.5k
        memcpy(fontfname + fsprefixlen, cidname->data, cidname->length);
530
14.5k
        fontfname[fsprefixlen + cidname->length] = '\0';
531
532
14.5k
        code = pdfi_open_resource_file(ctx, fontfname, strlen(fontfname), &s);
533
14.5k
        if (code < 0) {
534
14.5k
            code = gs_note_error(gs_error_invalidfont);
535
14.5k
        }
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
14.5k
    }
550
551
29.4k
exit:
552
29.4k
    if (cidname != NULL)
553
29.1k
        pdfi_countdown(cidname);
554
555
29.4k
    return code;
556
29.4k
}
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
59.7M
{
593
69.0M
    while (1)
594
69.0M
    {
595
69.0M
        while (*a == ' ')
596
0
            a++;
597
69.0M
        while (*b == ' ')
598
786
            b++;
599
69.0M
        if (*a != *b)
600
59.7M
            return 1;
601
9.37M
        if (*a == 0)
602
7.67k
            return *a != *b;
603
9.36M
        if (*b == 0)
604
0
            return *a != *b;
605
9.36M
        a++;
606
9.36M
        b++;
607
9.36M
    }
608
0
    return 0; /* Shouldn't happen */
609
59.7M
}
610
611
static const char *pdfi_clean_font_name(const char *fontname)
612
896k
{
613
896k
    int i, k;
614
13.3M
    for (i = 0; i < (sizeof(pdfi_base_font_names)/sizeof(pdfi_base_font_names[0])); i++) {
615
72.2M
        for (k = 0; pdfi_base_font_names[i][k]; k++) {
616
59.7M
            if (!strncmp_ignore_space(pdfi_base_font_names[i][k], (const char *)fontname))
617
7.67k
                return pdfi_base_font_names[i][0];
618
59.7M
        }
619
12.4M
    }
620
888k
    return NULL;
621
896k
}
622
623
static int pdfi_font_substitute_by_flags(pdf_context *ctx, unsigned int flags, char **name, int *namelen)
624
463k
{
625
463k
    bool fixed = ((flags & pdfi_font_flag_fixed) != 0);
626
463k
    bool serif = ((flags & pdfi_font_flag_serif) != 0);
627
463k
    bool italic = ((flags & pdfi_font_flag_italic) != 0);
628
463k
    bool bold = ((flags & pdfi_font_flag_forcebold) != 0);
629
463k
    int code = 0;
630
631
463k
    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
463k
    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
463k
    else if (fixed) {
642
233
        if (bold) {
643
5
            if (italic) {
644
5
                *name = (char *)pdfi_base_font_names[3][0];
645
5
                *namelen = strlen(*name);
646
5
            }
647
0
            else {
648
0
                *name = (char *)pdfi_base_font_names[1][0];
649
0
                *namelen = strlen(*name);
650
0
            }
651
5
        }
652
228
        else {
653
228
            if (italic) {
654
2
                *name = (char *)pdfi_base_font_names[2][0];
655
2
                *namelen = strlen(*name);
656
2
            }
657
226
            else {
658
226
                *name = (char *)pdfi_base_font_names[0][0];
659
226
                *namelen = strlen(*name);
660
226
            }
661
228
        }
662
233
    }
663
463k
    else if (serif) {
664
1.88k
        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.86k
        else {
675
1.86k
            if (italic) {
676
147
                *name = (char *)pdfi_base_font_names[10][0];
677
147
                *namelen = strlen(*name);
678
147
            }
679
1.72k
            else {
680
1.72k
                *name = (char *)pdfi_base_font_names[8][0];
681
1.72k
                *namelen = strlen(*name);
682
1.72k
            }
683
1.86k
        }
684
461k
    } else {
685
461k
        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
461k
        else {
696
461k
            if (italic) {
697
553
                *name = (char *)pdfi_base_font_names[6][0];
698
553
                *namelen = strlen(*name);
699
553
            }
700
461k
            else {
701
461k
                *name = (char *)pdfi_base_font_names[4][0];
702
461k
                *namelen = strlen(*name);
703
461k
            }
704
461k
        }
705
461k
    }
706
463k
    return code;
707
463k
}
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
118k
{
720
1.09M
#define MAKEMAGIC(a, b, c, d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
721
722
118k
    if (buflen >= 4) {
723
118k
        if (MAKEMAGIC(buf[0], buf[1], buf[2], buf[3]) == MAKEMAGIC(0, 1, 0, 0)
724
78.0k
            || MAKEMAGIC(buf[0], buf[1], buf[2], buf[3]) == MAKEMAGIC('t', 'r', 'u', 'e')
725
73.1k
            || MAKEMAGIC(buf[0], buf[1], buf[2], buf[3]) == MAKEMAGIC('t', 't', 'c', 'f')) {
726
45.7k
            return tt_font;
727
45.7k
        }
728
73.1k
        else if (MAKEMAGIC(buf[0], buf[1], buf[2], buf[3]) == MAKEMAGIC('O', 'T', 'T', 'O')) {
729
617
            return cff_font; /* OTTO will end up as CFF */
730
617
        }
731
72.4k
        else if (MAKEMAGIC(buf[0], buf[1], buf[2], 0) == MAKEMAGIC('%', '!', 'P', 0)) {
732
60.5k
            return type1_font; /* pfa */
733
60.5k
        }
734
11.9k
        else if (MAKEMAGIC(buf[0], buf[1], buf[2], 0) == MAKEMAGIC(1, 0, 4, 0)) {
735
11.1k
            return cff_font; /* 1C/CFF */
736
11.1k
        }
737
722
        else if (MAKEMAGIC(buf[0], buf[1], 0, 0) == MAKEMAGIC(128, 1, 0, 0)) {
738
199
            return type1_font; /* pfb */
739
199
        }
740
118k
    }
741
549
    return no_type_font;
742
118k
#undef MAKEMAGIC
743
118k
}
744
745
static int pdfi_copy_font(pdf_context *ctx, pdf_font *spdffont, pdf_dict *font_dict, pdf_font **tpdffont)
746
491k
{
747
491k
    int code;
748
491k
    if (pdfi_type_of(spdffont) != PDF_FONT)
749
0
        return_error(gs_error_typecheck);
750
751
491k
    switch(spdffont->pdfi_font_type) {
752
488k
        case e_pdf_font_type1:
753
488k
          code = pdfi_copy_type1_font(ctx, spdffont, font_dict, tpdffont);
754
488k
          break;
755
63
        case e_pdf_font_cff:
756
63
          code = pdfi_copy_cff_font(ctx, spdffont, font_dict, tpdffont);
757
63
          break;
758
3.59k
        case e_pdf_font_truetype:
759
3.59k
          code = pdfi_copy_truetype_font(ctx, spdffont, font_dict, tpdffont);
760
3.59k
          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
491k
    }
767
491k
    return code;
768
491k
}
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
118k
{
778
118k
    int code = gs_error_invalidfont;
779
118k
    if (fbuf != NULL) {
780
        /* First, see if we can glean the type from the magic number */
781
118k
        int sftype = pdfi_fonttype_picker(fbuf, fbuflen);
782
118k
        if (sftype == no_type_font) {
783
549
            if (fftype != no_type_font)
784
522
                sftype = fftype;
785
27
            else {
786
                /* If we don't have a Subtype, can't work it out, try Type 1 */
787
27
                if (Subtype == NULL || pdfi_name_is(Subtype, "Type1") || pdfi_name_is(Subtype, "MMType1"))
788
25
                    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
27
            }
794
549
        }
795
        /* fbuf ownership passes to the font loader */
796
118k
        switch (sftype) {
797
61.1k
            case type1_font:
798
61.1k
                code = pdfi_read_type1_font(ctx, (pdf_dict *)font_dict, stream_dict, page_dict, fbuf, fbuflen, ppdffont);
799
61.1k
                fbuf = NULL;
800
61.1k
                break;
801
11.8k
            case cff_font:
802
11.8k
                code = pdfi_read_cff_font(ctx, (pdf_dict *)font_dict, stream_dict, page_dict, fbuf, fbuflen, cidfont, ppdffont);
803
11.8k
                fbuf = NULL;
804
11.8k
                break;
805
45.9k
            case tt_font:
806
45.9k
                {
807
45.9k
                    if (cidfont)
808
22.8k
                        code = pdfi_read_cidtype2_font(ctx, font_dict, stream_dict, page_dict, fbuf, fbuflen, findex, ppdffont);
809
23.1k
                    else
810
23.1k
                        code = pdfi_read_truetype_font(ctx, font_dict, stream_dict, page_dict, fbuf, fbuflen, findex, ppdffont);
811
45.9k
                    fbuf = NULL;
812
45.9k
                }
813
45.9k
                break;
814
2
            default:
815
2
                gs_free_object(ctx->memory, fbuf, "pdfi_load_font_buffer(fbuf)");
816
2
                code = gs_note_error(gs_error_invalidfont);
817
118k
        }
818
118k
    }
819
118k
    return code;
820
118k
}
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
952k
{
824
952k
    int code;
825
952k
    char fontfname[gp_file_name_sizeof];
826
952k
    pdf_obj *basefont = NULL, *mapname = NULL;
827
952k
    pdf_obj *fontname = NULL;
828
952k
    stream *s = NULL;
829
952k
    const char *fn;
830
952k
    int findex = 0;
831
952k
    byte *buf;
832
952k
    int buflen;
833
952k
    pdf_font *pdffont = NULL;
834
952k
    pdf_font *substpdffont = NULL;
835
952k
    bool f_retry = true;
836
837
952k
    code = pdfi_dict_knownget_type(ctx, font_dict, "BaseFont", PDF_NAME, &basefont);
838
952k
    if (substitute == false && (code < 0 || basefont == NULL || ((pdf_name *)basefont)->length == 0)) {
839
19.5k
        pdfi_countdown(basefont);
840
19.5k
        return_error(gs_error_invalidfont);
841
19.5k
    }
842
843
932k
    if (substitute == true) {
844
463k
        char *fbname;
845
463k
        int fbnamelen;
846
463k
        int64_t flags = 0;
847
463k
        if (fontdesc != NULL) {
848
22.7k
            (void)pdfi_dict_get_int(ctx, fontdesc, "Flags", &flags);
849
22.7k
        }
850
463k
        code = pdfi_font_substitute_by_flags(ctx, (int)flags, &fbname, &fbnamelen);
851
463k
        if (code < 0)
852
0
            return code;
853
854
463k
        code = pdfi_name_alloc(ctx, (byte *)fbname, strlen(fbname), (pdf_obj **) &fontname);
855
463k
        if (code < 0)
856
0
            return code;
857
463k
        pdfi_countup(fontname);
858
463k
    }
859
468k
    else {
860
468k
        fontname = basefont;
861
468k
        pdfi_countup(fontname);
862
468k
    }
863
864
932k
    if (((pdf_name *)fontname)->length < gp_file_name_sizeof) {
865
932k
        memcpy(fontfname, ((pdf_name *)fontname)->data, ((pdf_name *)fontname)->length);
866
932k
        fontfname[((pdf_name *)fontname)->length] = '\0';
867
932k
        pdfi_countdown(fontname);
868
869
932k
        code = pdfi_name_alloc(ctx, (byte *)fontfname, strlen(fontfname), (pdf_obj **) &fontname);
870
932k
        if (code < 0)
871
0
            return code;
872
932k
        pdfi_countup(fontname);
873
932k
    }
874
3
    else {
875
        /* Just to ensure that fontfname is a valid, though empty, string */
876
3
        fontfname[0] = '\0';
877
3
    }
878
879
1.37M
    do {
880
1.37M
        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.37M
        else {
884
1.37M
            code = pdfi_fontmap_lookup_font(ctx, font_dict, (pdf_name *) fontname, &mapname, &findex);
885
1.37M
            if (code < 0) {
886
896k
                if (((pdf_name *)fontname)->length < gp_file_name_sizeof) {
887
896k
                    memcpy(fontfname, ((pdf_name *)fontname)->data, ((pdf_name *)fontname)->length);
888
896k
                    fontfname[((pdf_name *)fontname)->length] = '\0';
889
896k
                    fn = pdfi_clean_font_name(fontfname);
890
896k
                    if (fn != NULL) {
891
7.67k
                        pdfi_countdown(fontname);
892
893
7.67k
                        code = pdfi_name_alloc(ctx, (byte *)fn, strlen(fn), (pdf_obj **) &fontname);
894
7.67k
                        if (code < 0)
895
0
                            return code;
896
7.67k
                        pdfi_countup(fontname);
897
7.67k
                    }
898
896k
                }
899
896k
                code = pdfi_fontmap_lookup_font(ctx, font_dict, (pdf_name *) fontname, &mapname, &findex);
900
896k
                if (code < 0) {
901
888k
                    mapname = fontname;
902
888k
                    pdfi_countup(mapname);
903
888k
                    code = 0;
904
888k
                }
905
896k
            }
906
1.37M
            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.37M
            if (pdfi_type_of(mapname) == PDF_NAME || pdfi_type_of(mapname) == PDF_STRING) {
912
1.37M
                pdf_name *mname = (pdf_name *) mapname;
913
1.37M
                if (mname->length + 1 < gp_file_name_sizeof) {
914
1.37M
                    memcpy(fontfname, mname->data, mname->length);
915
1.37M
                    fontfname[mname->length] = '\0';
916
1.37M
                }
917
3
                else {
918
3
                    pdfi_countdown(mapname);
919
3
                    pdfi_countdown(fontname);
920
3
                    return_error(gs_error_invalidfileaccess);
921
3
                }
922
1.37M
            }
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.37M
            if (ctx->pdf_substitute_fonts != NULL) {
930
1.27M
                code = pdfi_dict_knownget_type(ctx, ctx->pdf_substitute_fonts, fontfname, PDF_FONT, (pdf_obj **)&pdffont);
931
1.27M
                if (code == 1 && pdffont->filename == NULL) {
932
0
                    pdfi_countdown(pdffont);
933
0
                    pdffont = NULL;
934
0
                    code = 0;
935
0
                }
936
1.27M
            }
937
101k
            else
938
101k
                code = 0;
939
1.37M
        }
940
1.37M
        if (code != 1) {
941
940k
            code = pdfi_open_font_file(ctx, fontfname, strlen(fontfname), &s);
942
940k
            if (code < 0 && f_retry && pdfi_type_of(mapname) == PDF_NAME) {
943
446k
                pdfi_countdown(fontname);
944
446k
                fontname = mapname;
945
446k
                mapname = NULL;
946
446k
                f_retry = false;
947
446k
                continue;
948
446k
            }
949
494k
            if (code >= 0) {
950
49.8k
                gs_const_string fname;
951
952
49.8k
                sfilename(s, &fname);
953
49.8k
                if (fname.size < gp_file_name_sizeof) {
954
49.8k
                    memcpy(fontfname, fname.data, fname.size);
955
49.8k
                    fontfname[fname.size] = '\0';
956
49.8k
                }
957
0
                else {
958
0
                    strcpy(fontfname, "unnamed file");
959
0
                }
960
49.8k
                sfseek(s, 0, SEEK_END);
961
49.8k
                buflen = sftell(s);
962
49.8k
                sfseek(s, 0, SEEK_SET);
963
49.8k
                buf = gs_alloc_bytes(ctx->memory, buflen, "pdfi_open_t1_font_file(buf)");
964
49.8k
                if (buf != NULL) {
965
49.8k
                    sfread(buf, 1, buflen, s);
966
49.8k
                }
967
0
                else {
968
0
                    code = gs_note_error(gs_error_VMerror);
969
0
                }
970
49.8k
                sfclose(s);
971
                /* Buffer owership moves to the font object */
972
49.8k
                code = pdfi_load_font_buffer(ctx, buf, buflen, no_type_font, NULL, findex, stream_dict, page_dict, NULL, &pdffont, false);
973
49.8k
                if (code >= 0) {
974
49.8k
                    pdffont->filename = NULL;
975
49.8k
                    code = pdfi_object_alloc(ctx, PDF_STRING, strlen(fontfname) , (pdf_obj **)&pdffont->filename);
976
49.8k
                    if (code >= 0) {
977
49.8k
                        pdfi_countup(pdffont->filename);
978
49.8k
                        memcpy(pdffont->filename->data, fontfname, strlen(fontfname));
979
49.8k
                        pdffont->filename->length = strlen(fontfname);
980
49.8k
                    }
981
982
49.8k
                    if (ctx->pdf_substitute_fonts == NULL) {
983
39.9k
                        code = pdfi_dict_alloc(ctx, 16, &ctx->pdf_substitute_fonts);
984
39.9k
                        if (code >= 0)
985
39.9k
                            pdfi_countup(ctx->pdf_substitute_fonts);
986
39.9k
                    }
987
49.8k
                    if (ctx->pdf_substitute_fonts != NULL) {
988
49.8k
                        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
49.8k
                        else
1001
49.8k
                            code = 0;
1002
1003
49.8k
                        if (code == 0)
1004
49.8k
                            (void)pdfi_dict_put_obj(ctx, ctx->pdf_substitute_fonts, mapname, (pdf_obj *)pdffont, true);
1005
49.8k
                        code = 0;
1006
49.8k
                    }
1007
49.8k
                }
1008
49.8k
            }
1009
494k
        }
1010
932k
        break;
1011
1.37M
    } while (1);
1012
1013
932k
    if (code >= 0) {
1014
488k
        if (basefont) {
1015
487k
            pdfi_print_cstring(ctx, "Loading font ");
1016
487k
            pdfi_print_font_name(ctx, (pdf_name *)basefont);
1017
487k
            pdfi_print_cstring(ctx, " (or substitute) from ");
1018
487k
        }
1019
906
        else {
1020
906
            pdfi_print_cstring(ctx, "Loading nameless font from ");
1021
906
        }
1022
488k
        pdfi_print_font_string(ctx, pdffont->filename);
1023
488k
        pdfi_print_cstring(ctx, "\n");
1024
1025
488k
        code = pdfi_copy_font(ctx, pdffont, font_dict, &substpdffont);
1026
488k
        pdfi_countdown(pdffont);
1027
488k
    }
1028
1029
932k
    *ppdffont = substpdffont;
1030
1031
932k
    pdfi_countdown(basefont);
1032
932k
    pdfi_countdown(mapname);
1033
932k
    pdfi_countdown(fontname);
1034
932k
    return code;
1035
932k
}
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
588k
{
1039
588k
    int code;
1040
588k
    pdf_font *ppdffont = NULL;
1041
588k
    pdf_font *ppdfdescfont = NULL;
1042
588k
    pdf_name *Type = NULL;
1043
588k
    pdf_name *Subtype = NULL;
1044
588k
    pdf_dict *fontdesc = NULL;
1045
588k
    pdf_stream *fontfile = NULL;
1046
588k
    pdf_name *ffsubtype = NULL;
1047
588k
    int fftype = no_type_font;
1048
588k
    byte *fbuf = NULL;
1049
588k
    int64_t fbuflen = 0;
1050
588k
    int substitute = font_embedded;
1051
588k
    int findex = 0;
1052
1053
588k
    code = pdfi_dict_get_type(ctx, font_dict, "Type", PDF_NAME, (pdf_obj **)&Type);
1054
588k
    if (code < 0) {
1055
679
        if ((code = pdfi_set_error_stop(ctx, code, NULL, E_PDF_MISSINGTYPE, "pdfi_load_font", NULL)) < 0)
1056
0
            goto exit;
1057
679
    }
1058
587k
    else {
1059
587k
        if (!pdfi_name_is(Type, "Font")){
1060
3.07k
            code = gs_note_error(gs_error_typecheck);
1061
3.07k
            goto exit;
1062
3.07k
        }
1063
587k
    }
1064
585k
    code = pdfi_dict_get_type(ctx, font_dict, "Subtype", PDF_NAME, (pdf_obj **)&Subtype);
1065
585k
    if (code < 0) {
1066
747
        if ((code = pdfi_set_error_stop(ctx, code, NULL, E_PDF_NO_SUBTYPE, "pdfi_load_font", NULL)) < 0)
1067
0
            goto exit;
1068
747
    }
1069
1070
    /* Beyond Type 0 and Type 3, there is no point trusting the Subtype key */
1071
585k
    if (Subtype != NULL && pdfi_name_is(Subtype, "Type0")) {
1072
39.4k
        if (cidfont == true) {
1073
9
            code = gs_note_error(gs_error_invalidfont);
1074
9
        }
1075
39.3k
        else {
1076
39.3k
            code = pdfi_read_type0_font(ctx, (pdf_dict *)font_dict, stream_dict, page_dict, &ppdffont);
1077
39.3k
        }
1078
39.4k
    }
1079
545k
    else if (Subtype != NULL && pdfi_name_is(Subtype, "Type3")) {
1080
2.99k
        code = pdfi_read_type3_font(ctx, (pdf_dict *)font_dict, stream_dict, page_dict, &ppdffont);
1081
2.99k
        if (code < 0)
1082
570
            goto exit;
1083
2.99k
    }
1084
542k
    else {
1085
542k
        if (Subtype != NULL && !pdfi_name_is(Subtype, "Type1") && !pdfi_name_is(Subtype, "TrueType") && !pdfi_name_is(Subtype, "CIDFont")
1086
24.9k
            && !pdfi_name_is(Subtype, "CIDFontType2") && !pdfi_name_is(Subtype, "CIDFontType0") && !pdfi_name_is(Subtype, "MMType1")) {
1087
1088
835
            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
835
        }
1092
        /* We should always have a font descriptor here, but we have to carry on
1093
           even if we don't
1094
         */
1095
542k
        code = pdfi_dict_get_type(ctx, font_dict, "FontDescriptor", PDF_DICT, (pdf_obj **)&fontdesc);
1096
542k
        if (fontdesc != NULL && pdfi_type_of(fontdesc) == PDF_DICT) {
1097
75.5k
            pdf_obj *Name = NULL;
1098
1099
75.5k
            code = pdfi_dict_get_type(ctx, (pdf_dict *) fontdesc, "FontName", PDF_NAME, (pdf_obj **)&Name);
1100
75.5k
            if (code < 0)
1101
1.06k
                pdfi_set_warning(ctx, 0, NULL, W_PDF_FDESC_BAD_FONTNAME, "pdfi_load_font", "");
1102
75.5k
            pdfi_countdown(Name);
1103
75.5k
            Name = NULL;
1104
1105
75.5k
            if (cidfont == true) {
1106
14.7k
                code = -1;
1107
14.7k
            }
1108
60.8k
            else {
1109
60.8k
                code = pdfi_find_cache_resource_font(ctx, (pdf_obj *)fontdesc, (pdf_obj **)&ppdfdescfont);
1110
60.8k
                if (code >= 0) {
1111
3.78k
                    code = pdfi_copy_font(ctx, ppdfdescfont, font_dict, &ppdffont);
1112
3.78k
                }
1113
60.8k
            }
1114
1115
75.5k
            if (code < 0) {
1116
71.7k
                code = pdfi_dict_get_type(ctx, (pdf_dict *) fontdesc, "FontFile", PDF_STREAM, (pdf_obj **)&fontfile);
1117
71.7k
                if (code >= 0)
1118
11.0k
                    fftype = type1_font;
1119
60.7k
                else {
1120
60.7k
                    code = pdfi_dict_get_type(ctx, (pdf_dict *) fontdesc, "FontFile2", PDF_STREAM, (pdf_obj **)&fontfile);
1121
60.7k
                    fftype = tt_font;
1122
60.7k
                }
1123
71.7k
                if (code < 0) {
1124
28.3k
                    code = pdfi_dict_get_type(ctx, (pdf_dict *) fontdesc, "FontFile3", PDF_STREAM, (pdf_obj **)&fontfile);
1125
28.3k
                    if (code >= 0 && fontfile != NULL) {
1126
12.3k
                        code = pdfi_dict_get_type(ctx, fontfile->stream_dict, "Subtype", PDF_NAME, (pdf_obj **)&ffsubtype);
1127
12.3k
                        if (code >= 0) {
1128
12.2k
                            if (pdfi_name_is(ffsubtype, "Type1"))
1129
0
                                fftype = type1_font;
1130
12.2k
                            else if (pdfi_name_is(ffsubtype, "Type1C"))
1131
9.48k
                                fftype = cff_font;
1132
2.80k
                            else if (pdfi_name_is(ffsubtype, "OpenType"))
1133
408
                                fftype = cff_font;
1134
2.39k
                            else if (pdfi_name_is(ffsubtype, "CIDFontType0C"))
1135
1.91k
                                fftype = cff_font;
1136
473
                            else if (pdfi_name_is(ffsubtype, "TrueType"))
1137
0
                                fftype = tt_font;
1138
473
                            else
1139
473
                                fftype = no_type_font;
1140
12.2k
                        }
1141
12.3k
                    }
1142
28.3k
                }
1143
71.7k
            }
1144
75.5k
        }
1145
1146
542k
        if (ppdffont == NULL) {
1147
538k
            if (fontfile != NULL) {
1148
55.8k
                code = pdfi_stream_to_buffer(ctx, (pdf_stream *) fontfile, &fbuf, &fbuflen);
1149
55.8k
                pdfi_countdown(fontfile);
1150
55.8k
                if (code < 0 || fbuflen == 0) {
1151
1.48k
                    char obj[129];
1152
1.48k
                    pdfi_print_cstring(ctx, "**** Warning: cannot process embedded stream for font object ");
1153
1.48k
                    gs_snprintf(obj, 128, "%d %d\n", (int)font_dict->object_num, (int)font_dict->generation_num);
1154
1.48k
                    pdfi_print_cstring(ctx, obj);
1155
1.48k
                    pdfi_print_cstring(ctx, "**** Attempting to load a substitute font.\n");
1156
1.48k
                    gs_free_object(ctx->memory, fbuf, "pdfi_load_font(fbuf)");
1157
1.48k
                    fbuf = NULL;
1158
1.48k
                    code = gs_note_error(gs_error_invalidfont);
1159
1.48k
                }
1160
55.8k
            }
1161
1162
553k
            while (1) {
1163
553k
                if (fbuf != NULL) {
1164
                    /* fbuf overship passes to pdfi_load_font_buffer() */
1165
69.0k
                    code = pdfi_load_font_buffer(ctx, fbuf, fbuflen, fftype, Subtype, findex, stream_dict, page_dict, font_dict, &ppdffont, cidfont);
1166
1167
69.0k
                    if (code < 0 && substitute == font_embedded) {
1168
18.3k
                        char msg[129];
1169
1170
18.3k
                        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
18.3k
                        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
18.3k
                        else {
1176
18.3k
                            code = gs_error_invalidfont;
1177
18.3k
                        }
1178
18.3k
                    }
1179
69.0k
                }
1180
484k
                else {
1181
484k
                    code = gs_error_invalidfont;
1182
484k
                }
1183
1184
553k
                if (code < 0 && code != gs_error_VMerror && substitute == font_embedded) {
1185
502k
                    substitute = font_from_file;
1186
1187
502k
                    if (cidfont == true) {
1188
14.7k
                        code =  pdfi_open_CIDFont_substitute_file(ctx, font_dict, fontdesc, false, &fbuf, &fbuflen, &findex);
1189
14.7k
                        if (code < 0) {
1190
14.7k
                            code =  pdfi_open_CIDFont_substitute_file(ctx, font_dict, fontdesc, true, &fbuf, &fbuflen, &findex);
1191
14.7k
                            substitute |= font_substitute;
1192
14.7k
                        }
1193
1194
14.7k
                        if (code < 0)
1195
0
                            goto exit;
1196
14.7k
                    }
1197
488k
                    else {
1198
488k
                        code = pdfi_load_font_file(ctx, no_type_font, Subtype, stream_dict, page_dict, font_dict, fontdesc, false, &ppdffont);
1199
488k
                        if (code < 0) {
1200
463k
                            code = pdfi_load_font_file(ctx, no_type_font, Subtype, stream_dict, page_dict, font_dict, fontdesc, true, &ppdffont);
1201
463k
                            substitute |= font_substitute;
1202
463k
                        }
1203
488k
                        break;
1204
488k
                    }
1205
14.7k
                    continue;
1206
502k
                }
1207
50.7k
                break;
1208
553k
            }
1209
538k
        }
1210
542k
    }
1211
584k
    if (ppdffont == NULL || code < 0) {
1212
32.9k
        *ppfont = NULL;
1213
32.9k
        if (code != gs_error_Fatal)
1214
32.9k
            code = gs_note_error(gs_error_invalidfont);
1215
32.9k
    }
1216
551k
    else {
1217
551k
        ppdffont->substitute = (substitute != font_embedded);
1218
1219
551k
        if ((substitute & font_substitute) == font_substitute)
1220
471k
            code = pdfi_font_match_glyph_widths(ppdffont);
1221
80.3k
        else if (ppdffont->substitute != true && fontdesc != NULL && ppdfdescfont == NULL
1222
35.9k
            && (ppdffont->pdfi_font_type == e_pdf_font_type1 || ppdffont->pdfi_font_type == e_pdf_font_cff
1223
28.8k
            || ppdffont->pdfi_font_type == e_pdf_font_truetype)) {
1224
28.8k
            pdfi_cache_resource_font(ctx, (pdf_obj *)fontdesc, (pdf_obj *)ppdffont);
1225
28.8k
        }
1226
551k
        *ppfont = (gs_font *)ppdffont->pfont;
1227
551k
     }
1228
1229
588k
exit:
1230
588k
    pdfi_countdown(ppdfdescfont);
1231
588k
    pdfi_countdown(fontdesc);
1232
588k
    pdfi_countdown(Type);
1233
588k
    pdfi_countdown(Subtype);
1234
588k
    pdfi_countdown(ffsubtype);
1235
588k
    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
811k
{
1240
811k
    int code;
1241
811k
    gs_font *pfont;
1242
811k
    pdf_font *pdfif;
1243
1244
811k
    switch (pdfi_type_of(font_dict)) {
1245
675k
        case PDF_FONT:
1246
675k
            pdfi_countup(font_dict);
1247
675k
            pfont = (gs_font *)((pdf_font *)font_dict)->pfont;
1248
675k
            code = 0;
1249
675k
            break;
1250
127k
        case PDF_DICT:
1251
127k
            code = pdfi_load_font(ctx, stream_dict, page_dict, font_dict, &pfont, false);
1252
127k
            break;
1253
8.51k
        default:
1254
8.51k
            code = gs_note_error(gs_error_typecheck);
1255
8.51k
            goto exit;
1256
811k
    }
1257
802k
    if (code < 0)
1258
29.0k
        goto exit;
1259
1260
    /* Everything looks good, set the font, unless it's the current font */
1261
773k
    if (pfont != ctx->pgs->font) {
1262
603k
        code = pdfi_gs_setfont(ctx, pfont);
1263
603k
    }
1264
773k
    pdfif = (pdf_font *)pfont->client_data;
1265
773k
    pdfi_countdown(pdfif);
1266
1267
773k
    if (code < 0)
1268
0
        goto exit;
1269
1270
773k
    code = gs_setPDFfontsize(ctx->pgs, point_size);
1271
811k
exit:
1272
811k
    return code;
1273
773k
}
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.21M
{
1277
1.21M
    int code;
1278
1.21M
    pdf_dict *font_dict = NULL;
1279
1280
1.21M
    if (pdfi_type_of(fontname) != PDF_NAME) {
1281
        /* Passing empty string here should fall back to a default font */
1282
16.3k
        return pdfi_font_set_internal_string(ctx, "", point_size);
1283
16.3k
    }
1284
1285
    /* Look fontname up in the resources */
1286
1.19M
    code = pdfi_loop_detector_mark(ctx);
1287
1.19M
    if (code < 0)
1288
0
        goto exit;
1289
1.19M
    code = pdfi_find_resource(ctx, (unsigned char *)"Font", fontname, stream_dict, page_dict, (pdf_obj **)&font_dict);
1290
1.19M
    (void)pdfi_loop_detector_cleartomark(ctx);
1291
1.19M
    if (code < 0)
1292
384k
        goto exit;
1293
811k
    code = pdfi_load_dict_font(ctx, stream_dict, page_dict, font_dict, point_size);
1294
1295
1.19M
exit:
1296
1.19M
    pdfi_countdown(font_dict);
1297
1.19M
    return code;
1298
811k
}
1299
1300
int pdfi_get_cidfont_glyph_metrics(gs_font *pfont, gs_glyph cid, double *widths, bool vertical)
1301
1.64M
{
1302
1.64M
    pdf_font *pdffont = (pdf_font *)pfont->client_data;
1303
1.64M
    int i, code = 0;
1304
1.64M
    pdf_num *c = NULL, *c2 = NULL;
1305
1.64M
    pdf_obj *o = NULL;
1306
1.64M
    pdf_array *W = NULL, *W2 = NULL, *DW2 = NULL;
1307
1.64M
    double DW;
1308
1309
1.64M
    if (pdffont->pdfi_font_type == e_pdf_cidfont_type0) {
1310
75.7k
        pdf_cidfont_type0 *cidfont = (pdf_cidfont_type0 *)pdffont;
1311
75.7k
        DW = cidfont->DW;
1312
75.7k
        DW2 = cidfont->DW2;
1313
75.7k
        W = cidfont->W;
1314
75.7k
        W2 = cidfont->W2;
1315
75.7k
    }
1316
1.56M
    else if (pdffont->pdfi_font_type == e_pdf_cidfont_type2) {
1317
1.56M
        pdf_cidfont_type2 *cidfont = (pdf_cidfont_type2 *)pdffont;
1318
1.56M
        DW = cidfont->DW;
1319
1.56M
        DW2 = cidfont->DW2;
1320
1.56M
        W = cidfont->W;
1321
1.56M
        W2 = cidfont->W2;
1322
1.56M
    }
1323
0
    else {
1324
0
        return_error(gs_error_invalidfont);
1325
0
    }
1326
1327
1.64M
    widths[GLYPH_W0_WIDTH_INDEX] = DW;
1328
1.64M
    widths[GLYPH_W0_HEIGHT_INDEX] = 0;
1329
1.64M
    if (W != NULL) {
1330
1.49M
        i = 0;
1331
1332
30.7M
        while(1) {
1333
30.7M
            pdf_obj_type type;
1334
1335
30.7M
            if (i + 1>= W->size) break;
1336
30.6M
            code = pdfi_array_get_type(pdffont->ctx, W, i, PDF_INT, (pdf_obj **)&c);
1337
30.6M
            if (code < 0) goto cleanup;
1338
1339
30.6M
            code = pdfi_array_get(pdffont->ctx, W, i + 1, &o);
1340
30.6M
            if (code < 0) goto cleanup;
1341
1342
30.6M
            type = pdfi_type_of(o);
1343
30.6M
            if (type == PDF_INT) {
1344
3.36M
                double d;
1345
3.36M
                c2 = (pdf_num *)o;
1346
3.36M
                o = NULL;
1347
3.36M
                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.36M
                code = pdfi_array_get_number(pdffont->ctx, W, i + 2, &d);
1355
3.36M
                if (code < 0) goto cleanup;
1356
3.36M
                if (cid >= c->value.i && cid <= c2->value.i) {
1357
203k
                    widths[GLYPH_W0_WIDTH_INDEX] = d;
1358
203k
                    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
203k
                    break;
1363
203k
                }
1364
3.16M
                else {
1365
3.16M
                    i += 3;
1366
3.16M
                    pdfi_countdown(c2);
1367
3.16M
                    pdfi_countdown(c);
1368
3.16M
                    c = c2 = NULL;
1369
3.16M
                    continue;
1370
3.16M
                }
1371
3.36M
            }
1372
27.3M
            else if (type == PDF_ARRAY) {
1373
27.3M
                pdf_array *a = (pdf_array *)o;
1374
27.3M
                o = NULL;
1375
27.3M
                if (cid >= c->value.i && cid < c->value.i + a->size) {
1376
1.15M
                    code = pdfi_array_get_number(pdffont->ctx, a, cid - c->value.i, &widths[GLYPH_W0_WIDTH_INDEX]);
1377
1.15M
                    if (code >= 0) {
1378
1.15M
                        pdfi_countdown(a);
1379
1.15M
                        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.15M
                        break;
1384
1.15M
                    }
1385
1.15M
                }
1386
26.1M
                pdfi_countdown(a);
1387
26.1M
                pdfi_countdown(c);
1388
26.1M
                c = NULL;
1389
26.1M
                i += 2;
1390
26.1M
                continue;
1391
27.3M
            }
1392
699
            else {
1393
699
                code = gs_note_error(gs_error_typecheck);
1394
699
                goto cleanup;
1395
699
            }
1396
30.6M
        }
1397
1.48M
        pdfi_countdown(c2);
1398
1.48M
        pdfi_countdown(c);
1399
1.48M
        pdfi_countdown(o);
1400
1.48M
        c = c2 = NULL;
1401
1.48M
        o = NULL;
1402
1.48M
    }
1403
1404
1.63M
    if (vertical) {
1405
        /* Default default <sigh>! */
1406
1.63M
        widths[GLYPH_W1_WIDTH_INDEX] = 0;
1407
1.63M
        widths[GLYPH_W1_HEIGHT_INDEX] = -1000.0;
1408
1.63M
        widths[GLYPH_W1_V_X_INDEX] = (widths[GLYPH_W0_WIDTH_INDEX] / 2.0);
1409
1.63M
        widths[GLYPH_W1_V_Y_INDEX] = 880.0;
1410
1411
1.63M
        if (DW2 != NULL && pdfi_type_of(DW2) == PDF_ARRAY
1412
12.2k
            && DW2->size >= 2) {
1413
12.2k
            code = pdfi_array_get_number(pdffont->ctx, (pdf_array *)DW2, 0, &widths[GLYPH_W1_V_Y_INDEX]);
1414
12.2k
            if (code >= 0)
1415
12.2k
                code = pdfi_array_get_number(pdffont->ctx, (pdf_array *)DW2, 1, &widths[GLYPH_W1_HEIGHT_INDEX]);
1416
12.2k
            if (code >= 0) {
1417
12.2k
                widths[GLYPH_W1_V_X_INDEX] = widths[GLYPH_W0_WIDTH_INDEX] / 2.0;
1418
12.2k
                widths[GLYPH_W1_WIDTH_INDEX] = 0.0;
1419
12.2k
            }
1420
12.2k
        }
1421
1.63M
        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.63M
    }
1494
1495
1.64M
cleanup:
1496
1.64M
    pdfi_countdown(c2);
1497
1.64M
    pdfi_countdown(c);
1498
1.64M
    pdfi_countdown(o);
1499
1500
1.64M
    return code;
1501
1.63M
}
1502
1503
int pdfi_d0(pdf_context *ctx)
1504
3.66k
{
1505
3.66k
    int code = 0, gsave_level = 0;
1506
3.66k
    double width[2];
1507
1508
3.66k
    if (ctx->text.inside_CharProc == false)
1509
2.76k
        pdfi_set_warning(ctx, 0, NULL, W_PDF_NOTINCHARPROC, "pdfi_d0", NULL);
1510
1511
3.66k
    ctx->text.CharProc_d_type = pdf_type3_d0;
1512
1513
3.66k
    if (pdfi_count_stack(ctx) < 2) {
1514
907
        code = gs_note_error(gs_error_stackunderflow);
1515
907
        goto d0_error;
1516
907
    }
1517
1518
2.76k
    if (pdfi_type_of(ctx->stack_top[-1]) != PDF_INT && pdfi_type_of(ctx->stack_top[-1]) != PDF_REAL) {
1519
807
        code = gs_note_error(gs_error_typecheck);
1520
807
        goto d0_error;
1521
807
    }
1522
1.95k
    if (pdfi_type_of(ctx->stack_top[-2]) != PDF_INT && pdfi_type_of(ctx->stack_top[-2]) != PDF_REAL) {
1523
118
        code = gs_note_error(gs_error_typecheck);
1524
118
        goto d0_error;
1525
118
    }
1526
1.83k
    if(ctx->text.current_enum == NULL) {
1527
933
        code = gs_note_error(gs_error_undefined);
1528
933
        goto d0_error;
1529
933
    }
1530
1531
903
    if (pdfi_type_of(ctx->stack_top[-2]) == PDF_INT)
1532
901
        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
903
    if (pdfi_type_of(ctx->stack_top[-1]) == PDF_INT)
1536
901
        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
903
    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
903
    if (ctx->text.current_enum == NULL) {
1550
0
        code = gs_note_error(gs_error_unknownerror);
1551
0
        goto d0_error;
1552
0
    }
1553
1554
903
    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
903
    if (ctx->pgs->level > gsave_level)
1573
0
        ctx->current_stream_save.gsave_level += ctx->pgs->level - gsave_level;
1574
1575
903
    if (code < 0)
1576
5
        goto d0_error;
1577
898
    pdfi_pop(ctx, 2);
1578
898
    return 0;
1579
1580
2.77k
d0_error:
1581
2.77k
    pdfi_clearstack(ctx);
1582
2.77k
    return code;
1583
903
}
1584
1585
int pdfi_d1(pdf_context *ctx)
1586
40.9k
{
1587
40.9k
    int code = 0, gsave_level;
1588
40.9k
    double wbox[6];
1589
1590
40.9k
    if (ctx->text.inside_CharProc == false)
1591
613
        pdfi_set_warning(ctx, 0, NULL, W_PDF_NOTINCHARPROC, "pdfi_d1", NULL);
1592
1593
40.9k
    ctx->text.CharProc_d_type = pdf_type3_d1;
1594
1595
40.9k
    code = pdfi_destack_reals(ctx, wbox, 6);
1596
40.9k
    if (code < 0)
1597
759
        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
40.1k
    gsave_level = ctx->pgs->level;
1607
1608
40.1k
    if (ctx->text.current_enum == NULL) {
1609
201
        code = gs_note_error(gs_error_unknownerror);
1610
201
        goto d1_error;
1611
201
    }
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
39.9k
    code = gs_text_setcachedevice(ctx->text.current_enum, wbox);
1637
39.9k
#endif
1638
1639
    /* See the comment immediately after gs_text_setcachedvice() in pdfi_d0 above */
1640
39.9k
    if (ctx->pgs->level > gsave_level)
1641
11.4k
        ctx->current_stream_save.gsave_level += ctx->pgs->level - gsave_level;
1642
1643
39.9k
    if (code < 0)
1644
28
        goto d1_error;
1645
39.9k
    return 0;
1646
1647
988
d1_error:
1648
988
    pdfi_clearstack(ctx);
1649
988
    return code;
1650
39.9k
}
1651
1652
int pdfi_Tf(pdf_context *ctx, pdf_dict *stream_dict, pdf_dict *page_dict)
1653
1.24M
{
1654
1.24M
    double point_size = 0;
1655
1.24M
    pdf_obj *point_arg = NULL;
1656
1.24M
    int code = 0;
1657
1.24M
    pdf_name *fontname = NULL;
1658
1659
1.24M
    if (pdfi_count_stack(ctx) < 2) {
1660
27.0k
        pdfi_clearstack(ctx);
1661
27.0k
        return_error(gs_error_stackunderflow);
1662
27.0k
    }
1663
1664
    /* Get refs to the args and pop them */
1665
1.21M
    point_arg = ctx->stack_top[-1];
1666
1.21M
    pdfi_countup(point_arg);
1667
1.21M
    fontname = (pdf_name *)ctx->stack_top[-2];
1668
1.21M
    pdfi_countup(fontname);
1669
1.21M
    pdfi_pop(ctx, 2);
1670
1671
    /* Get the point_size */
1672
1.21M
    code = pdfi_obj_to_real(ctx, point_arg, &point_size);
1673
1.21M
    if (code < 0)
1674
2.86k
        goto exit0;
1675
1676
1.21M
    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.21M
    if (code != gs_error_Fatal && code < 0)
1680
421k
        code = pdfi_font_set_internal_name(ctx, fontname, point_size);
1681
1.21M
 exit0:
1682
1.21M
    pdfi_countdown(fontname);
1683
1.21M
    pdfi_countdown(point_arg);
1684
1.21M
    return code;
1685
1.21M
}
1686
1687
int pdfi_free_font(pdf_obj *font)
1688
615k
{
1689
615k
    pdf_font *f = (pdf_font *)font;
1690
1691
615k
    switch (f->pdfi_font_type) {
1692
14.0k
        case e_pdf_font_type0:
1693
14.0k
            return pdfi_free_font_type0((pdf_obj *)font);
1694
0
            break;
1695
543k
        case e_pdf_font_type1:
1696
543k
            return pdfi_free_font_type1((pdf_obj *)font);
1697
0
            break;
1698
11.2k
        case e_pdf_font_cff:
1699
11.2k
            return pdfi_free_font_cff((pdf_obj *)font);
1700
2.99k
        case e_pdf_font_type3:
1701
2.99k
            return pdfi_free_font_type3((pdf_obj *)font);
1702
0
            break;
1703
26.6k
        case e_pdf_font_truetype:
1704
26.6k
            return pdfi_free_font_truetype((pdf_obj *)font);
1705
0
            break;
1706
0
        case e_pdf_font_microtype:
1707
0
            return pdfi_free_font_microtype((pdf_obj *)font);
1708
0
            break;
1709
15.2k
        case e_pdf_cidfont_type2:
1710
15.2k
            return pdfi_free_font_cidtype2((pdf_obj *)font);
1711
0
            break;
1712
1.62k
        case e_pdf_cidfont_type0:
1713
1.62k
            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
615k
    }
1721
0
    return 0;
1722
615k
}
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
19.3k
{
1728
19.3k
    uint esize = Encoding->size;
1729
19.3k
    uint best = esize / 3;  /* must match at least this many */
1730
19.3k
    int i, index, near_index = ENCODING_INDEX_UNKNOWN, code;
1731
1732
151k
    for (index = 0; index < NUM_KNOWN_REAL_ENCODINGS; ++index) {
1733
132k
        uint match = esize;
1734
1735
16.0M
        for (i = esize; --i >= 0;) {
1736
16.0M
            gs_const_string rstr;
1737
16.0M
            pdf_name *ename;
1738
1739
16.0M
            code = pdfi_array_get_type(ctx, Encoding, (uint64_t)i, PDF_NAME, (pdf_obj **)&ename);
1740
16.0M
            if (code < 0) {
1741
20
                return;
1742
20
            }
1743
1744
16.0M
            gs_c_glyph_name(gs_c_known_encode((gs_char)i, index), &rstr);
1745
16.0M
            if (rstr.size == ename->length &&
1746
7.51M
                !memcmp(rstr.data, ename->data, rstr.size)) {
1747
7.03M
                pdfi_countdown(ename);
1748
7.03M
                continue;
1749
7.03M
            }
1750
9.02M
            pdfi_countdown(ename);
1751
9.02M
            if (--match <= best) {
1752
99.9k
                break;
1753
99.9k
            }
1754
9.02M
        }
1755
132k
        if (match > best) {
1756
32.9k
            best = match;
1757
32.9k
            near_index = index;
1758
            /* If we have a perfect match, stop now. */
1759
32.9k
            if (best == esize)
1760
755
                break;
1761
32.9k
        }
1762
132k
    }
1763
19.3k
    if (best == esize) *ind = index;
1764
19.3k
    *near_ind = near_index;
1765
19.3k
}
1766
1767
static inline int pdfi_encoding_name_to_index(pdf_name *name)
1768
129k
{
1769
129k
    int ind = gs_error_undefined;
1770
129k
    if (pdfi_type_of(name) == PDF_NAME) {
1771
129k
        if (pdfi_name_is(name, "StandardEncoding")) {
1772
62.9k
            ind = ENCODING_INDEX_STANDARD;
1773
66.6k
        } else if (pdfi_name_is(name, "WinAnsiEncoding")) {
1774
55.3k
            ind = ENCODING_INDEX_WINANSI;
1775
55.3k
        }
1776
11.3k
        else if (pdfi_name_is(name, "MacRomanEncoding")) {
1777
10.8k
            ind = ENCODING_INDEX_MACROMAN;
1778
10.8k
        }
1779
493
        else if (pdfi_name_is(name, "MacExpertEncoding")) {
1780
42
            ind = ENCODING_INDEX_MACEXPERT;
1781
42
        }
1782
451
        else if (pdfi_name_is(name, "SymbolEncoding")) {
1783
0
            ind = ENCODING_INDEX_SYMBOL;
1784
0
        }
1785
451
        else if (pdfi_name_is(name, "DingbatsEncoding")) {
1786
0
            ind = ENCODING_INDEX_DINGBATS;
1787
0
        }
1788
129k
    }
1789
129k
    return ind;
1790
129k
}
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
126k
{
1798
126k
    int i, code = 0;
1799
126k
    unsigned char gs_encoding;
1800
126k
    gs_glyph temp;
1801
126k
    gs_const_string str;
1802
126k
    pdf_name *n = NULL;
1803
1804
126k
    if (pdfi_array_size(Encoding) < 256)
1805
0
        return gs_note_error(gs_error_rangecheck);
1806
1807
126k
    code = pdfi_encoding_name_to_index(name);
1808
126k
    if (code < 0)
1809
433
        return code;
1810
125k
    if (ind != NULL) *ind = (gs_encoding_index_t)code;
1811
125k
    gs_encoding = (unsigned char)code;
1812
125k
    code = 0;
1813
1814
32.2M
    for (i = 0;i<256;i++) {
1815
32.1M
        temp = gs_c_known_encode(i, gs_encoding);
1816
32.1M
        gs_c_glyph_name(temp, &str);
1817
32.1M
        code = pdfi_name_alloc(ctx, (byte *)str.data, str.size, (pdf_obj **)&n);
1818
32.1M
        if (code < 0)
1819
0
            return code;
1820
32.1M
        pdfi_countup(n);
1821
32.1M
        code = pdfi_array_put(ctx, Encoding, (uint64_t)i, (pdf_obj *)n);
1822
32.1M
        pdfi_countdown(n);
1823
32.1M
        if (code < 0)
1824
0
            return code;
1825
32.1M
    }
1826
125k
    return 0;
1827
125k
}
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
134k
{
1840
134k
    int code = 0, i;
1841
134k
    gs_encoding_index_t encoding_index = ENCODING_INDEX_UNKNOWN, nearest_encoding_index = ENCODING_INDEX_UNKNOWN;
1842
1843
134k
    code = pdfi_array_alloc(ctx, 256, (pdf_array **)Encoding);
1844
134k
    if (code < 0)
1845
0
        return code;
1846
134k
    pdfi_countup(*Encoding);
1847
1848
134k
    switch (pdfi_type_of(pdf_Encoding)) {
1849
114k
        case PDF_NAME:
1850
114k
            code = pdfi_build_Encoding(ctx, (pdf_name *)pdf_Encoding, (pdf_array *)*Encoding, &encoding_index);
1851
114k
            if (code < 0) {
1852
433
                pdfi_countdown(*Encoding);
1853
433
                *Encoding = NULL;
1854
433
                return code;
1855
433
            }
1856
114k
            nearest_encoding_index = encoding_index;
1857
114k
            break;
1858
19.9k
        case PDF_DICT:
1859
19.9k
        {
1860
19.9k
            pdf_name *n = NULL;
1861
19.9k
            pdf_array *a = NULL;
1862
19.9k
            pdf_obj *o = NULL;
1863
19.9k
            int offset = 0;
1864
19.9k
            bool b_e_known;
1865
1866
19.9k
            if (pdfi_type_of(pdf_Encoding) == PDF_DICT) {
1867
19.9k
                code = pdfi_dict_known(ctx, (pdf_dict *)pdf_Encoding, "BaseEncoding", &b_e_known);
1868
19.9k
                if (code < 0)
1869
0
                    b_e_known = false;
1870
19.9k
            }
1871
0
            else {
1872
0
                b_e_known = false;
1873
0
            }
1874
1875
19.9k
            if (b_e_known == false && font_Encoding != NULL && pdfi_type_of(font_Encoding) == PDF_ARRAY) {
1876
8.35k
                pdf_array *fenc = (pdf_array *)font_Encoding;
1877
2.14M
                for (i = 0; i < pdfi_array_size(fenc) && code >= 0; i++) {
1878
2.13M
                    code = pdfi_array_get(ctx, fenc, (uint64_t)i, &o);
1879
2.13M
                    if (code >= 0)
1880
2.13M
                        code = pdfi_array_put(ctx, (pdf_array *)*Encoding, (uint64_t)i, o);
1881
2.13M
                    pdfi_countdown(o);
1882
2.13M
                }
1883
8.35k
                if (code < 0) {
1884
0
                    pdfi_countdown(*Encoding);
1885
0
                    *Encoding = NULL;
1886
0
                    return code;
1887
0
                }
1888
8.35k
            }
1889
11.5k
            else {
1890
11.5k
                code = pdfi_dict_get(ctx, (pdf_dict *)pdf_Encoding, "BaseEncoding", (pdf_obj **)&n);
1891
11.5k
                if (code >= 0) {
1892
3.51k
                    if (pdfi_encoding_name_to_index(n) < 0) {
1893
18
                        pdfi_set_warning(ctx, 0, NULL, W_PDF_INVALID_FONT_BASEENC, "pdfi_create_Encoding", NULL);
1894
18
                        pdfi_countdown(n);
1895
18
                        n = NULL;
1896
18
                        code = gs_error_undefined;
1897
18
                    }
1898
3.49k
                    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.51k
                }
1902
1903
11.5k
                if (code < 0) {
1904
8.06k
                    code = pdfi_name_alloc(ctx, (byte *)"StandardEncoding", 16, (pdf_obj **)&n);
1905
8.06k
                    if (code < 0) {
1906
0
                        pdfi_countdown(*Encoding);
1907
0
                        *Encoding = NULL;
1908
0
                        return code;
1909
0
                    }
1910
8.06k
                    pdfi_countup(n);
1911
8.06k
                }
1912
1913
11.5k
                code = pdfi_build_Encoding(ctx, n, (pdf_array *)*Encoding, NULL);
1914
11.5k
                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.5k
                pdfi_countdown(n);
1921
11.5k
            }
1922
19.9k
            code = pdfi_dict_knownget_type(ctx, (pdf_dict *)pdf_Encoding, "Differences", PDF_ARRAY, (pdf_obj **)&a);
1923
19.9k
            if (code <= 0) {
1924
486
                if (code < 0) {
1925
0
                    pdfi_countdown(*Encoding);
1926
0
                    *Encoding = NULL;
1927
0
                }
1928
486
                return code;
1929
486
            }
1930
1931
1.77M
            for (i=0;i < pdfi_array_size(a);i++) {
1932
1.75M
                pdf_obj_type type;
1933
1.75M
                code = pdfi_array_get(ctx, a, (uint64_t)i, &o);
1934
1.75M
                if (code < 0)
1935
11
                    break;
1936
1.75M
                type = pdfi_type_of(o);
1937
1.75M
                if (type == PDF_NAME) {
1938
1.59M
                    if (offset < pdfi_array_size((pdf_array *)*Encoding))
1939
1.59M
                        code = pdfi_array_put(ctx, (pdf_array *)*Encoding, (uint64_t)offset, o);
1940
1.59M
                    pdfi_countdown(o);
1941
1.59M
                    offset++;
1942
1.59M
                    if (code < 0)
1943
0
                        break;
1944
1.59M
                } else if (type == PDF_INT) {
1945
164k
                    offset = ((pdf_num *)o)->value.i;
1946
164k
                    pdfi_countdown(o);
1947
164k
                } else {
1948
74
                    code = gs_note_error(gs_error_typecheck);
1949
74
                    pdfi_countdown(o);
1950
74
                    break;
1951
74
                }
1952
1.75M
            }
1953
19.4k
            pdfi_countdown(a);
1954
19.4k
            if (code < 0) {
1955
85
                pdfi_countdown(*Encoding);
1956
85
                *Encoding = NULL;
1957
85
                return code;
1958
85
            }
1959
19.3k
            if (ppdffont != NULL) /* No sense doing this if we can't record the result */
1960
19.3k
                pdfi_gs_simple_font_encoding_indices(ctx, (pdf_array *)(*Encoding), &encoding_index, &nearest_encoding_index);
1961
19.3k
            break;
1962
19.4k
        }
1963
493
        default:
1964
493
            pdfi_countdown(*Encoding);
1965
493
            *Encoding = NULL;
1966
493
            return gs_note_error(gs_error_typecheck);
1967
134k
    }
1968
133k
    if (ppdffont != NULL) {
1969
80.7k
        ppdffont->pfont->encoding_index = encoding_index;
1970
80.7k
        ppdffont->pfont->nearest_encoding_index = nearest_encoding_index;
1971
80.7k
    }
1972
133k
    return 0;
1973
134k
}
1974
1975
gs_glyph pdfi_encode_char(gs_font * pfont, gs_char chr, gs_glyph_space_t not_used)
1976
73.4M
{
1977
73.4M
    int code;
1978
73.4M
    unsigned int nindex = 0;
1979
73.4M
    gs_glyph g = GS_NO_GLYPH;
1980
1981
73.4M
    if (pfont->FontType == ft_encrypted || pfont->FontType == ft_encrypted2
1982
652k
     || pfont->FontType == ft_user_defined || pfont->FontType == ft_TrueType
1983
652k
     || pfont->FontType == ft_MicroType
1984
73.4M
     || pfont->FontType == ft_PDF_user_defined) {
1985
73.4M
        pdf_font *font = (pdf_font *)pfont->client_data;
1986
73.4M
        pdf_context *ctx = (pdf_context *)font->ctx;
1987
1988
73.4M
        if (font->Encoding != NULL) { /* safety */
1989
73.4M
            pdf_name *GlyphName = NULL;
1990
73.4M
            code = pdfi_array_get(ctx, font->Encoding, (uint64_t)chr, (pdf_obj **)&GlyphName);
1991
73.4M
            if (code >= 0) {
1992
73.4M
                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
73.4M
                code = (*ctx->get_glyph_index)(pfont, (byte *)GlyphName->data, GlyphName->length, &nindex);
1997
73.4M
                pdfi_countdown(GlyphName);
1998
73.4M
                if (code >= 0)
1999
73.4M
                    g = (gs_glyph)nindex;
2000
73.4M
            }
2001
73.4M
        }
2002
73.4M
    }
2003
2004
73.4M
    return g;
2005
73.4M
}
2006
2007
extern const pdfi_cid_decoding_t *pdfi_cid_decoding_list[];
2008
extern const pdfi_cid_subst_nwp_table_t *pdfi_cid_substnwp_list[];
2009
2010
void pdfi_cidfont_cid_subst_tables(const char *reg, const int reglen, const char *ord,
2011
                const int ordlen, pdfi_cid_decoding_t **decoding, pdfi_cid_subst_nwp_table_t **substnwp)
2012
7.66k
{
2013
7.66k
    int i;
2014
7.66k
    *decoding = NULL;
2015
7.66k
    *substnwp = NULL;
2016
    /* This only makes sense for Adobe orderings */
2017
7.66k
    if (reglen == 5 && !memcmp(reg, "Adobe", 5)) {
2018
41.1k
        for (i = 0; pdfi_cid_decoding_list[i] != NULL; i++) {
2019
34.3k
            if (strlen(pdfi_cid_decoding_list[i]->s_order) == ordlen &&
2020
692
                !memcmp(pdfi_cid_decoding_list[i]->s_order, ord, ordlen)) {
2021
328
                *decoding = (pdfi_cid_decoding_t *)pdfi_cid_decoding_list[i];
2022
328
                break;
2023
328
            }
2024
34.3k
        }
2025
        /* For now, also only for Adobe orderings */
2026
41.2k
        for (i = 0; pdfi_cid_substnwp_list[i] != NULL; i++) {
2027
34.5k
            if (strlen(pdfi_cid_substnwp_list[i]->ordering) == ordlen &&
2028
692
                !memcmp(pdfi_cid_substnwp_list[i]->ordering, ord, ordlen)) {
2029
328
                *substnwp = (pdfi_cid_subst_nwp_table_t *)pdfi_cid_substnwp_list[i];
2030
328
                break;
2031
328
            }
2032
34.5k
        }
2033
7.05k
    }
2034
7.66k
}
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
671k
        gs_cmap_lookups_enum_t lenum;
2044
671k
        gs_cmap_lookups_enum_init((const gs_cmap_t *)tounicode->gscmap, 0, &lenum);
2045
11.7M
        while (l == 0 && gs_cmap_enum_next_lookup(ctx->memory, &lenum) == 0) {
2046
11.0M
            gs_cmap_lookups_enum_t counter = lenum;
2047
22.0M
            while (l == 0 && gs_cmap_enum_next_entry(&counter) == 0) {
2048
11.0M
                if (counter.entry.value_type == CODE_VALUE_CID) {
2049
11.0M
                    if (counter.entry.key_is_range) {
2050
2.40M
                        unsigned int v0 = 0, v1 = 0;
2051
5.62M
                        for (i = 0; i < counter.entry.key_size; i++) {
2052
3.21M
                            v0 |= (counter.entry.key[0][counter.entry.key_size - i - 1]) << (i * 8);
2053
3.21M
                        }
2054
5.62M
                        for (i = 0; i < counter.entry.key_size; i++) {
2055
3.21M
                            v1 |= (counter.entry.key[1][counter.entry.key_size - i - 1]) << (i * 8);
2056
3.21M
                        }
2057
2058
2.40M
                        if (ch >= v0 && ch <= v1) {
2059
382k
                            unsigned int offs = ch - v0;
2060
2061
382k
                            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
382k
                            else if (counter.entry.value.size == 2) {
2069
381k
                                l = 2;
2070
381k
                                if (ucode != NULL && length >= l) {
2071
227k
                                    ucode[0] = counter.entry.value.data[0] + ((offs >> 8) & 0xff);
2072
227k
                                    ucode[1] = counter.entry.value.data[1] + (offs & 0xff);
2073
227k
                                }
2074
381k
                            }
2075
1.53k
                            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.50k
                            else {
2085
1.50k
                                l = 4;
2086
1.50k
                                if (ucode != NULL && length >= l) {
2087
1.39k
                                    ucode[0] = counter.entry.value.data[0] + ((offs >> 24) & 0xff);
2088
1.39k
                                    ucode[1] = counter.entry.value.data[1] + ((offs >> 16) & 0xff);
2089
1.39k
                                    ucode[2] = counter.entry.value.data[2] + ((offs >> 8) & 0xff);
2090
1.39k
                                    ucode[3] = counter.entry.value.data[3] + (offs & 0xff);
2091
1.39k
                                }
2092
1.50k
                            }
2093
382k
                        }
2094
2.40M
                    }
2095
8.64M
                    else {
2096
8.64M
                        unsigned int v = 0;
2097
24.8M
                        for (i = 0; i < counter.entry.key_size; i++) {
2098
16.2M
                            v |= (counter.entry.key[0][counter.entry.key_size - i - 1]) << (i * 8);
2099
16.2M
                        }
2100
8.64M
                        if (ch == v) {
2101
220k
                            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
220k
                            else if (counter.entry.value.size == 2) {
2109
219k
                                l = 2;
2110
219k
                                if (ucode != NULL && length >= l) {
2111
148k
                                    ucode[0] = counter.entry.value.data[0];
2112
148k
                                    ucode[1] = counter.entry.value.data[1];
2113
148k
                                }
2114
219k
                            }
2115
812
                            else if (counter.entry.value.size == 3) {
2116
56
                                l = 4;
2117
56
                                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
56
                            }
2124
756
                            else {
2125
756
                                l = 4;
2126
756
                                if (ucode != NULL && length >= l) {
2127
529
                                    ucode[0] = counter.entry.value.data[0];
2128
529
                                    ucode[1] = counter.entry.value.data[1];
2129
529
                                    ucode[2] = counter.entry.value.data[2];
2130
529
                                    ucode[3] = counter.entry.value.data[3];
2131
529
                                }
2132
756
                            }
2133
220k
                        }
2134
8.64M
                    }
2135
11.0M
                }
2136
11.0M
            }
2137
11.0M
        }
2138
671k
        if (l > 0)
2139
603k
            code = l;
2140
671k
    }
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.22M
{
2148
1.22M
    gs_glyph cc = glyph < GS_MIN_CID_GLYPH ? glyph : glyph - GS_MIN_CID_GLYPH;
2149
1.22M
    pdf_cidfont_t *pcidfont = (pdf_cidfont_t *)font->client_data;
2150
1.22M
    int code = gs_error_undefined, i;
2151
1.22M
    uchar *unicode_return = (uchar *)u;
2152
1.22M
    pdfi_cid_subst_nwp_table_t *substnwp = pcidfont->substnwp;
2153
2154
1.22M
    code = gs_error_undefined;
2155
1.23M
    while (1) { /* Loop to make retrying with a substitute CID easier */
2156
        /* Favour the ToUnicode if one exists */
2157
1.23M
        code = pdfi_tounicode_char_to_unicode(pcidfont->ctx, (pdf_cmap *)pcidfont->ToUnicode, glyph, ch, u, length);
2158
2159
1.23M
        if (code == gs_error_undefined && pcidfont->decoding) {
2160
21.2k
            const int *n;
2161
2162
21.2k
            if (cc / 256 < pcidfont->decoding->nranges) {
2163
21.0k
                n = (const int *)pcidfont->decoding->ranges[cc / 256][cc % 256];
2164
21.8k
                for (i = 0; i < pcidfont->decoding->val_sizes; i++) {
2165
21.8k
                    unsigned int cmapcc;
2166
21.8k
                    if (n[i] == -1)
2167
3.73k
                        break;
2168
18.1k
                    cc = n[i];
2169
18.1k
                    cmapcc = (unsigned int)cc;
2170
18.1k
                    if (pcidfont->pdfi_font_type == e_pdf_cidfont_type2)
2171
18.1k
                        code = pdfi_fapi_check_cmap_for_GID((gs_font *)pcidfont->pfont, (unsigned int)cc, &cmapcc);
2172
0
                    else
2173
0
                        code = 0;
2174
18.1k
                    if (code >= 0 && cmapcc != 0){
2175
17.2k
                        code = 0;
2176
17.2k
                        break;
2177
17.2k
                    }
2178
18.1k
                }
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
21.0k
                if (code < 0 && n[0] != -1) {
2183
0
                    cc = n[0];
2184
0
                    code = 0;
2185
0
                }
2186
21.0k
            }
2187
21.2k
            if (code >= 0) {
2188
17.3k
                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.3k
                else {
2198
17.3k
                    code = 2;
2199
17.3k
                    if (unicode_return != NULL && length >= code) {
2200
8.28k
                        unicode_return[0] = (cc & 0x0000FF00) >> 8;
2201
8.28k
                        unicode_return[1] = (cc & 0x000000FF);
2202
8.28k
                    }
2203
17.3k
                }
2204
17.3k
            }
2205
21.2k
        }
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.23M
        if (code == gs_error_undefined && substnwp) {
2211
9.81k
            for (i = 0; substnwp->subst[i].s_type != 0; i++ ) {
2212
9.30k
                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.30k
                if (cc >= substnwp->subst[i].s_dcid
2218
7.17k
                 && 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.30k
            }
2224
3.91k
            if (substnwp == NULL)
2225
3.40k
                continue;
2226
3.91k
        }
2227
1.22M
        break;
2228
1.23M
    }
2229
1.22M
    return (code < 0 ? 0 : code);
2230
1.22M
}
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
687k
{
2236
687k
    pdf_font *pdffont = (pdf_font *)font->client_data;
2237
687k
    int code = 0;
2238
2239
687k
    if (pdffont->pdfi_font_type != e_pdf_cidfont_type0 && pdffont->pdfi_font_type != e_pdf_cidfont_type1
2240
682k
     && pdffont->pdfi_font_type != e_pdf_cidfont_type2 && pdffont->pdfi_font_type != e_pdf_cidfont_type4) {
2241
682k
        code = pdfi_tounicode_char_to_unicode(pdffont->ctx, (pdf_cmap *)pdffont->ToUnicode, glyph, ch, unicode_return, length);
2242
682k
    }
2243
687k
    if (code < 0) code = 0;
2244
2245
687k
    return code;
2246
687k
}
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
17
{
2276
17
    int code = 0;
2277
17
    if (pfont->FontType == ft_encrypted) {
2278
1
        code = pdfi_t1_global_glyph_code(pfont, gstr, pglyph);
2279
1
    }
2280
16
    else if (pfont->FontType == ft_encrypted2) {
2281
16
        code = pdfi_cff_global_glyph_code(pfont, gstr, pglyph);
2282
16
    }
2283
0
    else {
2284
0
        code = gs_note_error(gs_error_invalidaccess);
2285
0
    }
2286
17
    return code;
2287
17
}
2288
2289
int pdfi_map_glyph_name_via_agl(pdf_dict *cstrings, pdf_name *gname, pdf_string **cstring)
2290
388k
{
2291
388k
    single_glyph_list_t *sgl = (single_glyph_list_t *)&(SingleGlyphList);
2292
388k
    int i, code, ucode = gs_error_undefined;
2293
388k
    *cstring = NULL;
2294
2295
388k
    if (gname->length == 7 && strncmp((char *)gname->data, "uni", 3) == 0) {
2296
3.98k
        char u[5] = {0};
2297
3.98k
        memcpy(u, gname->data + 3, 4);
2298
3.98k
        code = sscanf(u, "%x", &ucode);
2299
3.98k
        if (code <= 0)
2300
0
            ucode = gs_error_undefined;
2301
3.98k
    }
2302
2303
388k
    if (ucode == gs_error_undefined) {
2304
1.44G
        for (i = 0; sgl[i].Glyph != 0x00; i++) {
2305
1.44G
            if (sgl[i].Glyph[0] == gname->data[0]
2306
31.4M
                && strlen(sgl[i].Glyph) == gname->length
2307
494k
                && !strncmp((char *)sgl[i].Glyph, (char *)gname->data, gname->length)) {
2308
108k
                ucode = (int)sgl[i].Unicode;
2309
108k
                break;
2310
108k
            }
2311
1.44G
        }
2312
384k
    }
2313
388k
    if (ucode > 0) {
2314
466M
        for (i = 0; sgl[i].Glyph != 0x00; i++) {
2315
466M
            if (sgl[i].Unicode == (unsigned short)ucode) {
2316
115k
                pdf_string *s;
2317
115k
                code = pdfi_dict_get((pdf_context *)cstrings->ctx, cstrings, (char *)sgl[i].Glyph, (pdf_obj **)&s);
2318
115k
                if (code >= 0) {
2319
3.00k
                    *cstring = s;
2320
3.00k
                    break;
2321
3.00k
                }
2322
115k
            }
2323
466M
        }
2324
112k
        if (*cstring == NULL) {
2325
109k
            char u[16] = {0};
2326
109k
            code = gs_snprintf(u, 16, "uni%04x", ucode);
2327
109k
            if (code > 0) {
2328
109k
                pdf_string *s;
2329
109k
                code = pdfi_dict_get((pdf_context *)cstrings->ctx, cstrings, u, (pdf_obj **)&s);
2330
109k
                if (code >= 0) {
2331
5
                    *cstring = s;
2332
5
                }
2333
109k
            }
2334
109k
        }
2335
112k
    }
2336
2337
388k
    if (*cstring == NULL)
2338
385k
        code = gs_note_error(gs_error_undefined);
2339
3.01k
    else
2340
3.01k
        code = 0;
2341
2342
388k
    return code;
2343
388k
}
2344
2345
2346
int pdfi_init_font_directory(pdf_context *ctx)
2347
107k
{
2348
107k
    gs_font_dir *pfdir = ctx->memory->gs_lib_ctx->font_dir;
2349
107k
    if (pfdir) {
2350
98.9k
        ctx->font_dir = gs_font_dir_alloc2_limits(ctx->memory, ctx->memory,
2351
98.9k
                   pfdir->smax, pfdir->ccache.bmax, pfdir->fmcache.mmax,
2352
98.9k
                   pfdir->ccache.cmax, pfdir->ccache.upper);
2353
98.9k
        if (ctx->font_dir == NULL) {
2354
0
            return_error(gs_error_VMerror);
2355
0
        }
2356
98.9k
        ctx->font_dir->align_to_pixels = pfdir->align_to_pixels;
2357
98.9k
        ctx->font_dir->grid_fit_tt = pfdir->grid_fit_tt;
2358
98.9k
    }
2359
8.09k
    else {
2360
8.09k
        ctx->font_dir = gs_font_dir_alloc2(ctx->memory, ctx->memory);
2361
8.09k
        if (ctx->font_dir == NULL) {
2362
0
            return_error(gs_error_VMerror);
2363
0
        }
2364
8.09k
    }
2365
107k
    ctx->font_dir->global_glyph_code = pdfi_global_glyph_code;
2366
107k
    return 0;
2367
107k
}
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
438k
{
2375
438k
    pdf_obj *fname = NULL;
2376
438k
    pdf_obj *fontobjtype = NULL;
2377
438k
    pdf_dict *fdict = NULL;
2378
438k
    int code;
2379
438k
    gs_font *pgsfont = NULL;
2380
438k
    const char *fs = "Font";
2381
438k
    pdf_name *Type1Name = NULL;
2382
2383
438k
    code = pdfi_name_alloc(ctx, (byte *)fontname, length, &fname);
2384
438k
    if (code < 0)
2385
0
        return code;
2386
438k
    pdfi_countup(fname);
2387
2388
438k
    code = pdfi_name_alloc(ctx, (byte *)fs, strlen(fs), &fontobjtype);
2389
438k
    if (code < 0)
2390
0
        goto exit;
2391
438k
    pdfi_countup(fontobjtype);
2392
2393
438k
    code = pdfi_dict_alloc(ctx, 1, &fdict);
2394
438k
    if (code < 0)
2395
0
        goto exit;
2396
438k
    pdfi_countup(fdict);
2397
2398
438k
    code = pdfi_dict_put(ctx, fdict, "BaseFont", fname);
2399
438k
    if (code < 0)
2400
0
        goto exit;
2401
2402
438k
    code = pdfi_dict_put(ctx, fdict, "Type", fontobjtype);
2403
438k
    if (code < 0)
2404
0
        goto exit;
2405
2406
438k
    code = pdfi_obj_charstr_to_name(ctx, "Type1", &Type1Name);
2407
438k
    if (code < 0)
2408
0
        goto exit;
2409
2410
438k
    code = pdfi_dict_put(ctx, fdict, "Subtype", (pdf_obj *)Type1Name);
2411
438k
    if (code < 0)
2412
0
        goto exit;
2413
2414
438k
    code = pdfi_load_font(ctx, NULL, NULL, fdict, &pgsfont, false);
2415
438k
    if (code < 0)
2416
0
        goto exit;
2417
2418
438k
    *ppdffont = (pdf_obj *)pgsfont->client_data;
2419
2420
438k
 exit:
2421
438k
    pdfi_countdown(Type1Name);
2422
438k
    pdfi_countdown(fontobjtype);
2423
438k
    pdfi_countdown(fname);
2424
438k
    pdfi_countdown(fdict);
2425
438k
    return code;
2426
438k
}
2427
2428
2429
int pdfi_font_create_widths(pdf_context *ctx, pdf_dict *fontdict, pdf_font *font, double scale)
2430
530k
{
2431
530k
    int code = 0;
2432
530k
    pdf_obj *obj = NULL;
2433
530k
    int i;
2434
2435
530k
    font->Widths = NULL;
2436
2437
530k
    if (font->FontDescriptor != NULL) {
2438
68.8k
        code = pdfi_dict_knownget(ctx, font->FontDescriptor, "MissingWidth", &obj);
2439
68.8k
        if (code > 0) {
2440
6.32k
            if (pdfi_type_of(obj) == PDF_INT) {
2441
6.32k
                font->MissingWidth = ((pdf_num *) obj)->value.i * scale;
2442
6.32k
            }
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.32k
            pdfi_countdown(obj);
2450
6.32k
            obj = NULL;
2451
6.32k
        }
2452
62.4k
        else {
2453
62.4k
            font->MissingWidth = 0;
2454
62.4k
        }
2455
68.8k
    }
2456
462k
    else {
2457
462k
        font->MissingWidth = 0;
2458
462k
    }
2459
2460
530k
    code = pdfi_dict_knownget_type(ctx, fontdict, "Widths", PDF_ARRAY, (pdf_obj **)&obj);
2461
530k
    if (code > 0) {
2462
73.6k
        if (pdfi_array_size((pdf_array *)obj) < font->LastChar - font->FirstChar + 1) {
2463
2.27k
            code = gs_note_error(gs_error_rangecheck);
2464
2.27k
            goto error;
2465
2.27k
        }
2466
2467
71.3k
        font->Widths = (double *)gs_alloc_bytes(OBJ_MEMORY(font), (size_t)sizeof(double) * (font->LastChar - font->FirstChar + 1), "pdfi_font_create_widths(Widths)");
2468
71.3k
        if (font->Widths == NULL) {
2469
0
            code = gs_note_error(gs_error_VMerror);
2470
0
            goto error;
2471
0
        }
2472
71.3k
        memset(font->Widths, 0x00, sizeof(double) * (font->LastChar - font->FirstChar + 1));
2473
7.16M
        for (i = 0; i < (font->LastChar - font->FirstChar + 1); i++) {
2474
7.09M
            code = pdfi_array_get_number(ctx, (pdf_array *)obj, (uint64_t)i, &font->Widths[i]);
2475
7.09M
            if (code < 0)
2476
280
                goto error;
2477
7.09M
            font->Widths[i] *= scale;
2478
7.09M
        }
2479
71.3k
    }
2480
530k
error:
2481
530k
    pdfi_countdown(obj);
2482
530k
    if (code < 0) {
2483
6.05k
        gs_free_object(OBJ_MEMORY(font), font->Widths, "pdfi_font_create_widths(Widths)");
2484
6.05k
        font->Widths = NULL;
2485
6.05k
    }
2486
530k
    return code;
2487
530k
}
2488
2489
void pdfi_font_set_first_last_char(pdf_context *ctx, pdf_dict *fontdict, pdf_font *font)
2490
580k
{
2491
580k
    double f, l;
2492
580k
    int code;
2493
2494
580k
    if (fontdict == NULL) {
2495
49.8k
        f = (double)0;
2496
49.8k
        l = (double)255;
2497
49.8k
    }
2498
530k
    else {
2499
530k
        code = pdfi_dict_get_number(ctx, fontdict, "FirstChar", &f);
2500
530k
        if (code < 0 || f < 0 || f > 255)
2501
453k
            f = (double)0;
2502
2503
530k
        code = pdfi_dict_get_number(ctx, fontdict, "LastChar", &l);
2504
530k
        if (code < 0 || l < 0 || l > 255)
2505
453k
            l = (double)255;
2506
530k
    }
2507
580k
    if (f <= l) {
2508
580k
        font->FirstChar = (int)f;
2509
580k
        font->LastChar = (int)l;
2510
580k
    }
2511
67
    else {
2512
67
        font->FirstChar = 0;
2513
67
        font->LastChar = 255;
2514
67
    }
2515
580k
}
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
50.5k
        font->orig_FontType = ft_undefined;
2526
50.5k
    }
2527
538k
    else {
2528
538k
        if (pdfi_name_is(ftype, "Type1") || pdfi_name_is(ftype, "MMType1"))
2529
478k
            font->orig_FontType = ft_encrypted;
2530
60.2k
        else if (pdfi_name_is(ftype, "Type1C"))
2531
0
            font->orig_FontType = ft_encrypted2;
2532
60.2k
        else if (pdfi_name_is(ftype, "TrueType"))
2533
42.1k
            font->orig_FontType = ft_TrueType;
2534
18.1k
        else if (pdfi_name_is(ftype, "Type3"))
2535
2.42k
            font->orig_FontType = ft_user_defined;
2536
15.6k
        else if (pdfi_name_is(ftype, "CIDFontType0"))
2537
2.88k
            font->orig_FontType = ft_CID_encrypted;
2538
12.7k
        else if (pdfi_name_is(ftype, "CIDFontType2"))
2539
12.0k
            font->orig_FontType = ft_CID_TrueType;
2540
769
        else
2541
769
            font->orig_FontType = ft_undefined;
2542
538k
    }
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
98.3k
{
2555
98.3k
    gs_const_string fn;
2556
98.3k
    int i;
2557
98.3k
    uint32_t hash = 0;
2558
98.3k
    long *xvalues;
2559
98.3k
    int xuidlen = 3;
2560
2561
98.3k
    sfilename(ctx->main_stream->s, &fn);
2562
98.3k
    if (fontdict!= NULL && fontdict->object_num != 0) {
2563
42.6k
        const byte *sb;
2564
42.6k
        size_t l;
2565
42.6k
        if (fn.size > 0) {
2566
0
            sb = fn.data;
2567
0
            l = fn.size;
2568
0
        }
2569
42.6k
        else {
2570
42.6k
            s_process_read_buf(ctx->main_stream->s);
2571
42.6k
            sb = sbufptr(ctx->main_stream->s);
2572
42.6k
            l = sbufavailable(ctx->main_stream->s) > 128 ? 128: sbufavailable(ctx->main_stream->s);
2573
42.6k
        }
2574
2575
5.50M
        for (i = 0; i < l; i++) {
2576
5.45M
            hash = ((((hash & 0xf8000000) >> 27) ^ (hash << 5)) & 0x7ffffffff) ^ sb[i];
2577
5.45M
        }
2578
42.6k
        hash = ((((hash & 0xf8000000) >> 27) ^ (hash << 5)) & 0x7ffffffff) ^ fontdict->object_num;
2579
2580
42.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
414
             uid_XUID_values(&pfont->UID)[1] = hash;
2585
414
             uid_XUID_values(&pfont->UID)[2] = ctx->device_state.HighLevelDevice ? fontdict->object_num : 0;
2586
414
        }
2587
42.2k
        else {
2588
42.2k
            if (uid_is_XUID(&pfont->UID))
2589
1.89k
                xuidlen += uid_XUID_size(&pfont->UID);
2590
40.3k
            else if (uid_is_valid(&pfont->UID))
2591
676
                xuidlen++;
2592
2593
42.2k
            xvalues = (long *)gs_alloc_bytes(pfont->memory, (size_t)xuidlen * sizeof(long), "pdfi_font_generate_pseudo_XUID");
2594
42.2k
            if (xvalues == NULL) {
2595
0
                return 0;
2596
0
            }
2597
42.2k
            xvalues[0] = 1000000; /* "Private" value */
2598
42.2k
            xvalues[1] = hash;
2599
2600
42.2k
            xvalues[2] = ctx->device_state.HighLevelDevice ? fontdict->object_num : 0;
2601
2602
42.2k
            if (uid_is_XUID(&pfont->UID)) {
2603
11.8k
                for (i = 0; i < uid_XUID_size(&pfont->UID); i++) {
2604
9.95k
                    xvalues[i + 3] = uid_XUID_values(&pfont->UID)[i];
2605
9.95k
                }
2606
1.89k
                uid_free(&pfont->UID, pfont->memory, "pdfi_font_generate_pseudo_XUID");
2607
1.89k
            }
2608
40.3k
            else if (uid_is_valid(&pfont->UID))
2609
676
                xvalues[3] = pfont->UID.id;
2610
2611
42.2k
            uid_set_XUID(&pfont->UID, xvalues, xuidlen);
2612
42.2k
        }
2613
42.6k
    }
2614
98.3k
    return 0;
2615
98.3k
}
2616
2617
int pdfi_default_font_info(gs_font *font, const gs_point *pscale, int members, gs_font_info_t *info)
2618
139k
{
2619
139k
    pdf_font *pdff = (pdf_font *)font->client_data;
2620
139k
    int code;
2621
2622
    /* We *must* call this first as it sets info->members = 0; */
2623
139k
    code = pdff->default_font_info(font, pscale, members, info);
2624
139k
    if (code < 0)
2625
6.90k
        return code;
2626
132k
    if ((members & FONT_INFO_EMBEDDED) != 0) {
2627
132k
        info->orig_FontType = pdff->orig_FontType;
2628
132k
        if (pdff->pdfi_font_type == e_pdf_font_type3) {
2629
828
            info->FontEmbedded = (int)(true);
2630
828
            info->members |= FONT_INFO_EMBEDDED;
2631
828
        }
2632
131k
        else {
2633
131k
            info->FontEmbedded = (int)(pdff->substitute == font_embedded);
2634
131k
            info->members |= FONT_INFO_EMBEDDED;
2635
131k
        }
2636
132k
    }
2637
132k
    if (pdff->pdfi_font_type != e_pdf_font_truetype && pdff->pdfi_font_type != e_pdf_cidfont_type2) {
2638
73.6k
        if (((members & FONT_INFO_COPYRIGHT) != 0) && pdff->copyright != NULL) {
2639
43.7k
            info->Copyright.data = pdff->copyright->data;
2640
43.7k
            info->Copyright.size = pdff->copyright->length;
2641
43.7k
            info->members |= FONT_INFO_COPYRIGHT;
2642
43.7k
        }
2643
73.6k
        if (((members & FONT_INFO_NOTICE) != 0) && pdff->notice != NULL) {
2644
46.4k
            info->Notice.data = pdff->notice->data;
2645
46.4k
            info->Notice.size = pdff->notice->length;
2646
46.4k
            info->members |= FONT_INFO_NOTICE;
2647
46.4k
        }
2648
73.6k
        if (((members & FONT_INFO_FAMILY_NAME) != 0) && pdff->familyname != NULL) {
2649
46.2k
            info->FamilyName.data = pdff->familyname->data;
2650
46.2k
            info->FamilyName.size = pdff->familyname->length;
2651
46.2k
            info->members |= FONT_INFO_FAMILY_NAME;
2652
46.2k
        }
2653
73.6k
        if (((members & FONT_INFO_FULL_NAME) != 0) && pdff->fullname != NULL) {
2654
46.3k
            info->FullName.data = pdff->fullname->data;
2655
46.3k
            info->FullName.size = pdff->fullname->length;
2656
46.3k
            info->members |= FONT_INFO_FULL_NAME;
2657
46.3k
        }
2658
73.6k
    }
2659
132k
    return 0;
2660
139k
}
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
438k
{
2667
438k
    int code;
2668
438k
    pdf_font *pdffont = (pdf_font *)fontobj;
2669
2670
438k
    if (pdfi_type_of(pdffont) != PDF_FONT || pdffont->pfont == NULL)
2671
0
        return_error(gs_error_invalidfont);
2672
2673
438k
    code = gs_setPDFfontsize(ctx->pgs, point_size);
2674
438k
    if (code < 0)
2675
0
        return code;
2676
2677
438k
    return pdfi_gs_setfont(ctx, (gs_font *)pdffont->pfont);
2678
438k
}
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
438k
{
2686
438k
    int code = 0;
2687
438k
    pdf_obj *font = NULL;
2688
2689
2690
438k
    code = pdfi_load_font_by_name_string(ctx, fontname, length, &font);
2691
438k
    if (code < 0) goto exit;
2692
2693
438k
    code = pdfi_set_font_internal(ctx, font, point_size);
2694
2695
438k
 exit:
2696
438k
    pdfi_countdown(font);
2697
438k
    return code;
2698
438k
}
2699
2700
int pdfi_font_set_internal_string(pdf_context *ctx, const char *fontname, double point_size)
2701
16.7k
{
2702
16.7k
    return pdfi_font_set_internal_inner(ctx, (const byte *)fontname, strlen(fontname), point_size);
2703
16.7k
}
2704
2705
int pdfi_font_set_internal_name(pdf_context *ctx, pdf_name *fontname, double point_size)
2706
421k
{
2707
421k
    if (pdfi_type_of(fontname) != PDF_NAME)
2708
0
        return_error(gs_error_typecheck);
2709
421k
    else
2710
421k
        return pdfi_font_set_internal_inner(ctx, fontname->data, fontname->length, point_size);
2711
421k
}