Coverage Report

Created: 2022-10-31 07:00

/src/ghostpdl/pdf/pdf_font.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2018-2022 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.,  1305 Grant Avenue - Suite 200, Novato,
13
   CA 94945, U.S.A., +1(415)492-9861, 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_font0.h"
35
#include "pdf_fmap.h"
36
#include "gscencs.h"            /* For gs_c_known_encode and gs_c_glyph_name */
37
#include "gsagl.h"
38
39
#include "strmio.h"
40
#include "stream.h"
41
#include "gsstate.h"            /* For gs_setPDFfontsize() */
42
43
extern single_glyph_list_t SingleGlyphList[];
44
45
static int pdfi_gs_setfont(pdf_context *ctx, gs_font *pfont)
46
428k
{
47
428k
    int code = 0;
48
428k
    pdfi_int_gstate *igs = (pdfi_int_gstate *)ctx->pgs->client_data;
49
428k
    pdf_font *old_font = igs->current_font;
50
51
428k
    code = gs_setfont(ctx->pgs, pfont);
52
428k
    if (code >= 0) {
53
428k
        igs->current_font = (pdf_font *)pfont->client_data;
54
428k
        pdfi_countup(igs->current_font);
55
428k
        pdfi_countdown(old_font);
56
428k
    }
57
428k
    return code;
58
428k
}
59
60
/* These are fonts for which we have to ignore "named" encodings */
61
typedef struct known_symbolic_font_name_s
62
{
63
    const char *name;
64
    const int namelen;
65
} known_symbolic_font_name_t;
66
67
#define DEFINE_NAME_LEN(s) #s, sizeof(#s) - 1
68
static const known_symbolic_font_name_t known_symbolic_font_names[] =
69
{
70
  {DEFINE_NAME_LEN(Symbol)},
71
  {DEFINE_NAME_LEN(Wingdings2)},
72
  {DEFINE_NAME_LEN(Wingdings)},
73
  {DEFINE_NAME_LEN(ZapfDingbats)},
74
  {NULL , 0}
75
};
76
#undef DEFINE_NAME_LEN
77
78
bool pdfi_font_known_symbolic(pdf_obj *basefont)
79
208k
{
80
208k
    bool ignore = false;
81
208k
    int i;
82
208k
    pdf_name *nm = (pdf_name *)basefont;
83
84
208k
    if (basefont != NULL && pdfi_type_of(basefont) == PDF_NAME) {
85
935k
        for (i = 0; known_symbolic_font_names[i].name != NULL; i++) {
86
749k
            if (nm->length == known_symbolic_font_names[i].namelen
87
749k
             && !strncmp((char *)nm->data, known_symbolic_font_names[i].name, nm->length)) {
88
2.03k
                ignore = true;
89
2.03k
                break;
90
2.03k
            }
91
749k
        }
92
187k
    }
93
208k
    return ignore;
94
208k
}
95
96
static int
97
pdfi_font_match_glyph_widths(pdf_font *pdfont)
98
151k
{
99
151k
    int code = 0;
100
151k
    int i;
101
151k
    int sindex, lindex;
102
151k
    gs_font_base *pbfont = pdfont->pfont;
103
151k
    double fw = 0.0, ww = 0.0;
104
105
151k
    if (pdfont->LastChar <  pdfont->FirstChar || pdfont->Widths == NULL)
106
142k
        return 0; /* Technically invalid - carry on, hope for the best */
107
108
    /* For "best" results, restrict to what we *hope* are A-Z,a-z */
109
8.70k
    sindex = pdfont->FirstChar < 96 ? 96 : pdfont->FirstChar;
110
8.70k
    lindex = pdfont->LastChar > 122 ? 123 : pdfont->LastChar + 1;
111
112
192k
    for (i = sindex; i < lindex; i++) {
113
184k
        gs_glyph_info_t ginfo = {0};
114
184k
        gs_glyph g;
115
184k
        g = pbfont->procs.encode_char((gs_font *)pbfont, i, GLYPH_SPACE_NAME);
116
117
        /* We're only interested in non-zero Widths entries for glyphs that actually exist in the font */
118
184k
        if (g != GS_NO_GLYPH && pdfont->Widths[i - pdfont->FirstChar] != 0.0
119
184k
          && (*pbfont->procs.glyph_info)((gs_font *)pbfont, g, NULL, GLYPH_INFO_WIDTH0, &ginfo) >= 0) {
120
119k
            fw += hypot(ginfo.width[0].x, ginfo.width[0].y);
121
119k
            ww += pdfont->Widths[i - pdfont->FirstChar];
122
119k
        }
123
184k
    }
124
    /* Only reduce font width, don't expand */
125
8.70k
    if (ww != 0.0 && fw != 0.0 && ww / fw < 1.0) {
126
4.99k
        gs_matrix nmat, smat = {1.0, 0.0, 0.0, 1.0, 0.0, 0.0};
127
4.99k
        double wscale;
128
4.99k
        smat.xx = smat.yy = ww/fw;
129
4.99k
        wscale = 1.0 / smat.xx;
130
131
4.99k
        gs_matrix_multiply(&pbfont->FontMatrix, &smat, &nmat);
132
4.99k
        memcpy(&pbfont->FontMatrix, &nmat, sizeof(pbfont->FontMatrix));
133
134
572k
        for (i = pdfont->FirstChar; i <= pdfont->LastChar; i++) {
135
567k
            pdfont->Widths[i - pdfont->FirstChar] *= wscale;
136
567k
        }
137
138
        /* Purging a font can be expensive, but in this case, we know
139
           we have no scaled instances (pdfi doesn't work that way)
140
           and we know we have no fm pairs, nor glyphs to purge (we
141
           *just* created the font!).
142
           So "purging" the font is really just removing it from the
143
           doubly linked list of font objects in the font directory
144
         */
145
4.99k
        code = gs_purge_font((gs_font *)pbfont);
146
4.99k
        if (code >= 0)
147
4.99k
            code = gs_definefont(pbfont->dir, (gs_font *)pbfont);
148
4.99k
        if (code >= 0)
149
4.99k
            code = pdfi_fapi_passfont((pdf_font *)pdfont, 0, NULL, NULL, NULL, 0);
150
4.99k
    }
151
152
8.70k
    return code;
153
151k
}
154
155
/* Print a name object to stdout */
156
static void pdfi_print_font_name(pdf_context *ctx, pdf_name *n)
157
167k
{
158
167k
    if (ctx->args.QUIET != true)
159
0
        (void)outwrite(ctx->memory, (const char *)n->data, n->length);
160
167k
}
161
162
static void pdfi_print_font_string(pdf_context *ctx, pdf_string *s)
163
165k
{
164
165k
    if (ctx->args.QUIET != true)
165
0
        (void)outwrite(ctx->memory, (const char *)s->data, s->length);
166
165k
}
167
168
/* Print a null terminated string to stdout */
169
static void pdfi_print_cstring(pdf_context *ctx, const char *str)
170
527k
{
171
527k
    if (ctx->args.QUIET != true)
172
0
        (void)outwrite(ctx->memory, str, strlen(str));
173
527k
}
174
175
/* Call with a CIDFont name to try to find the CIDFont on disk
176
   call if with ffname NULL to load the default fallback CIDFont
177
   substitue
178
   Currently only loads subsitute - DroidSansFallback
179
 */
180
static int
181
pdfi_open_CIDFont_substitute_file(pdf_context *ctx, pdf_dict *font_dict, pdf_dict *fontdesc, bool fallback, byte ** buf, int64_t * buflen, int *findex)
182
5.09k
{
183
5.09k
    int code = 0;
184
5.09k
    char fontfname[gp_file_name_sizeof];
185
5.09k
    stream *s;
186
5.09k
    pdf_name *cidname = NULL;
187
5.09k
    gs_const_string fname;
188
189
5.09k
    (void)pdfi_dict_get(ctx, font_dict, "BaseFont", (pdf_obj **)&cidname);
190
191
5.09k
    if (fallback == true) {
192
2.54k
        pdf_string *mname = NULL;
193
2.54k
        pdf_dict *csi = NULL;
194
195
2.54k
        code = pdfi_dict_get(ctx, font_dict, "CIDSystemInfo", (pdf_obj **)&csi);
196
2.54k
        if (code >= 0 && pdfi_type_of(csi) == PDF_DICT) {
197
2.39k
            pdf_string *csi_reg = NULL, *csi_ord = NULL;
198
199
2.39k
            if (pdfi_dict_get(ctx, csi, "Registry", (pdf_obj **)&csi_reg) >= 0
200
2.39k
             && pdfi_dict_get(ctx, csi, "Ordering", (pdf_obj **)&csi_ord) >= 0
201
2.39k
             && pdfi_type_of(csi_reg) == PDF_STRING && pdfi_type_of(csi_ord) == PDF_STRING
202
2.39k
             && csi_reg->length + csi_ord->length + 1 < gp_file_name_sizeof - 1) {
203
2.38k
                pdf_name *reg_ord;
204
2.38k
                memcpy(fontfname, csi_reg->data, csi_reg->length);
205
2.38k
                memcpy(fontfname + csi_reg->length, "-", 1);
206
2.38k
                memcpy(fontfname + csi_reg->length + 1, csi_ord->data, csi_ord->length);
207
2.38k
                fontfname[csi_reg->length + csi_ord->length + 1] = '\0';
208
209
2.38k
                code = pdfi_name_alloc(ctx, (byte *)fontfname, strlen(fontfname), (pdf_obj **) &reg_ord);
210
2.38k
                if (code >= 0) {
211
2.38k
                    pdfi_countup(reg_ord);
212
2.38k
                    code = pdf_fontmap_lookup_cidfont(ctx, font_dict, reg_ord, (pdf_obj **)&mname, findex);
213
2.38k
                    pdfi_countdown(reg_ord);
214
2.38k
                }
215
2.38k
            }
216
2.39k
            pdfi_countdown(csi_reg);
217
2.39k
            pdfi_countdown(csi_ord);
218
2.39k
        }
219
2.54k
        pdfi_countdown(csi);
220
221
2.54k
        if (mname == NULL || pdfi_type_of(mname) != PDF_STRING)
222
2.54k
            code = pdf_fontmap_lookup_cidfont(ctx, font_dict, NULL, (pdf_obj **)&mname, findex);
223
224
2.54k
        if (code < 0 || pdfi_type_of(mname) != PDF_STRING) {
225
2.54k
            const char *fsprefix = "CIDFSubst/";
226
2.54k
            int fsprefixlen = strlen(fsprefix);
227
2.54k
            const char *defcidfallack = "DroidSansFallback.ttf";
228
2.54k
            int defcidfallacklen = strlen(defcidfallack);
229
230
2.54k
            pdfi_countdown(mname);
231
232
2.54k
            if (ctx->args.nocidfallback == true) {
233
0
                code = gs_note_error(gs_error_invalidfont);
234
0
            }
235
2.54k
            else {
236
2.54k
                if (ctx->args.cidfsubstpath.data == NULL) {
237
2.54k
                    memcpy(fontfname, fsprefix, fsprefixlen);
238
2.54k
                }
239
0
                else {
240
0
                    memcpy(fontfname, ctx->args.cidfsubstpath.data, ctx->args.cidfsubstpath.size);
241
0
                    fsprefixlen = ctx->args.cidfsubstpath.size;
242
0
                }
243
244
2.54k
                if (ctx->args.cidfsubstfont.data == NULL) {
245
2.54k
                    int len = 0;
246
2.54k
                    if (gp_getenv("CIDFSUBSTFONT", (char *)0, &len) < 0 && len + fsprefixlen + 1 < gp_file_name_sizeof) {
247
0
                        (void)gp_getenv("CIDFSUBSTFONT", (char *)(fontfname + fsprefixlen), &defcidfallacklen);
248
0
                    }
249
2.54k
                    else {
250
2.54k
                        memcpy(fontfname + fsprefixlen, defcidfallack, defcidfallacklen);
251
2.54k
                    }
252
2.54k
                }
253
0
                else {
254
0
                    memcpy(fontfname, ctx->args.cidfsubstfont.data, ctx->args.cidfsubstfont.size);
255
0
                    defcidfallacklen = ctx->args.cidfsubstfont.size;
256
0
                }
257
2.54k
                fontfname[fsprefixlen + defcidfallacklen] = '\0';
258
259
2.54k
                code = pdfi_open_resource_file(ctx, fontfname, strlen(fontfname), &s);
260
2.54k
                if (code < 0) {
261
0
                    code = gs_note_error(gs_error_invalidfont);
262
0
                }
263
2.54k
                else {
264
2.54k
                    if (cidname) {
265
2.54k
                        pdfi_print_cstring(ctx, "Loading CIDFont ");
266
2.54k
                        pdfi_print_font_name(ctx, (pdf_name *)cidname);
267
2.54k
                        pdfi_print_cstring(ctx, " substitute from ");
268
2.54k
                    }
269
6
                    else {
270
6
                        pdfi_print_cstring(ctx, "Loading nameless CIDFont from ");
271
6
                    }
272
2.54k
                    sfilename(s, &fname);
273
2.54k
                    if (fname.size < gp_file_name_sizeof) {
274
2.54k
                        memcpy(fontfname, fname.data, fname.size);
275
2.54k
                        fontfname[fname.size] = '\0';
276
2.54k
                    }
277
0
                    else {
278
0
                        strcpy(fontfname, "unnamed file");
279
0
                    }
280
2.54k
                    pdfi_print_cstring(ctx, fontfname);
281
2.54k
                    pdfi_print_cstring(ctx, "\n");
282
283
284
2.54k
                    sfseek(s, 0, SEEK_END);
285
2.54k
                    *buflen = sftell(s);
286
2.54k
                    sfseek(s, 0, SEEK_SET);
287
2.54k
                    *buf = gs_alloc_bytes(ctx->memory, *buflen, "pdfi_open_CIDFont_file(buf)");
288
2.54k
                    if (*buf != NULL) {
289
2.53k
                        sfread(*buf, 1, *buflen, s);
290
2.53k
                    }
291
13
                    else {
292
13
                        code = gs_note_error(gs_error_VMerror);
293
13
                    }
294
2.54k
                    sfclose(s);
295
2.54k
                }
296
2.54k
            }
297
2.54k
        }
298
0
        else {
299
0
            if (mname->length + 1 > gp_file_name_sizeof) {
300
0
                pdfi_countdown(mname);
301
0
                return_error(gs_error_invalidfont);
302
0
            }
303
0
            memcpy(fontfname, mname->data, mname->length);
304
0
            fontfname[mname->length] = '\0';
305
0
            code = pdfi_open_resource_file(ctx, (const char *)fontfname, mname->length, &s);
306
0
            pdfi_countdown(mname);
307
0
            if (code < 0) {
308
0
                code = gs_note_error(gs_error_invalidfont);
309
0
            }
310
0
            else {
311
0
                if (cidname) {
312
0
                    pdfi_print_cstring(ctx, "Loading CIDFont ");
313
0
                    pdfi_print_font_name(ctx, (pdf_name *)cidname);
314
0
                    pdfi_print_cstring(ctx, " (or substitute) from ");
315
0
                }
316
0
                else {
317
0
                    pdfi_print_cstring(ctx, "Loading nameless CIDFont from ");
318
0
                }
319
0
                sfilename(s, &fname);
320
0
                if (fname.size < gp_file_name_sizeof) {
321
0
                    memcpy(fontfname, fname.data, fname.size);
322
0
                    fontfname[fname.size] = '\0';
323
0
                }
324
0
                else {
325
0
                    strcpy(fontfname, "unnamed file");
326
0
                }
327
0
                pdfi_print_cstring(ctx, fontfname);
328
0
                pdfi_print_cstring(ctx, "\n");
329
0
                sfseek(s, 0, SEEK_END);
330
0
                *buflen = sftell(s);
331
0
                sfseek(s, 0, SEEK_SET);
332
0
                *buf = gs_alloc_bytes(ctx->memory, *buflen, "pdfi_open_CIDFont_file(buf)");
333
0
                if (*buf != NULL) {
334
0
                    sfread(*buf, 1, *buflen, s);
335
0
                }
336
0
                else {
337
0
                    code = gs_note_error(gs_error_VMerror);
338
0
                }
339
0
                sfclose(s);
340
0
            }
341
0
        }
342
2.54k
    }
343
2.54k
    else {
344
2.54k
        const char *fsprefix = "CIDFont/";
345
2.54k
        const int fsprefixlen = strlen(fsprefix);
346
347
2.54k
        if (cidname == NULL || pdfi_type_of(cidname) != PDF_NAME
348
2.54k
         || fsprefixlen + cidname->length >= gp_file_name_sizeof) {
349
8
            code = gs_note_error(gs_error_invalidfont);
350
8
            goto exit;
351
8
        }
352
353
2.53k
        memcpy(fontfname, fsprefix, fsprefixlen);
354
2.53k
        memcpy(fontfname + fsprefixlen, cidname->data, cidname->length);
355
2.53k
        fontfname[fsprefixlen + cidname->length] = '\0';
356
357
2.53k
        code = pdfi_open_resource_file(ctx, fontfname, strlen(fontfname), &s);
358
2.53k
        if (code < 0) {
359
2.53k
            code = gs_note_error(gs_error_invalidfont);
360
2.53k
        }
361
0
        else {
362
0
            sfseek(s, 0, SEEK_END);
363
0
            *buflen = sftell(s);
364
0
            sfseek(s, 0, SEEK_SET);
365
0
            *buf = gs_alloc_bytes(ctx->memory, *buflen, "pdfi_open_CIDFont_file(buf)");
366
0
            if (*buf != NULL) {
367
0
                sfread(*buf, 1, *buflen, s);
368
0
            }
369
0
            else {
370
0
                code = gs_note_error(gs_error_invalidfont);
371
0
            }
372
0
            sfclose(s);
373
0
        }
374
2.53k
    }
375
376
5.09k
exit:
377
5.09k
    if (cidname != NULL)
378
5.08k
        pdfi_countdown(cidname);
379
380
5.09k
    return code;
381
5.09k
}
382
383
enum
384
{
385
    pdfi_font_flag_none =        0x00000,
386
    pdfi_font_flag_fixed =       0x00001,
387
    pdfi_font_flag_serif =       0x00002,
388
    pdfi_font_flag_symbolic =    0x00004,
389
    pdfi_font_flag_script =      0x00008,
390
    pdfi_font_flag_nonsymbolic = 0x00020,
391
    pdfi_font_flag_italic =      0x00040,
392
    pdfi_font_flag_allcap =      0x10000,
393
    pdfi_font_flag_smallcap =    0x20000,
394
    pdfi_font_flag_forcebold =   0x40000
395
};
396
397
/* Barefaced theft from mupdf! */
398
static const char *pdfi_base_font_names[][10] =
399
{
400
  { "Courier", "CourierNew", "CourierNewPSMT", "CourierStd", NULL },
401
  { "Courier-Bold", "CourierNew,Bold", "Courier,Bold", "CourierNewPS-BoldMT", "CourierNew-Bold", NULL },
402
  { "Courier-Oblique", "CourierNew,Italic", "Courier,Italic", "CourierNewPS-ItalicMT", "CourierNew-Italic", NULL },
403
  { "Courier-BoldOblique", "CourierNew,BoldItalic", "Courier,BoldItalic", "CourierNewPS-BoldItalicMT", "CourierNew-BoldItalic", NULL },
404
  { "Helvetica", "ArialMT", "Arial", NULL },
405
  { "Helvetica-Bold", "Arial-BoldMT", "Arial,Bold", "Arial-Bold", "Helvetica,Bold", NULL },
406
  { "Helvetica-Oblique", "Arial-ItalicMT", "Arial,Italic", "Arial-Italic", "Helvetica,Italic", "Helvetica-Italic", NULL },
407
  { "Helvetica-BoldOblique", "Arial-BoldItalicMT", "Arial,BoldItalic", "Arial-BoldItalic", "Helvetica,BoldItalic", "Helvetica-BoldItalic", NULL },
408
  { "Times-Roman", "TimesNewRomanPSMT", "TimesNewRoman", "TimesNewRomanPS", NULL },
409
  { "Times-Bold", "TimesNewRomanPS-BoldMT", "TimesNewRoman,Bold", "TimesNewRomanPS-Bold", "TimesNewRoman-Bold", NULL },
410
  { "Times-Italic", "TimesNewRomanPS-ItalicMT", "TimesNewRoman,Italic", "TimesNewRomanPS-Italic", "TimesNewRoman-Italic", NULL },
411
  { "Times-BoldItalic", "TimesNewRomanPS-BoldItalicMT", "TimesNewRoman,BoldItalic", "TimesNewRomanPS-BoldItalic", "TimesNewRoman-BoldItalic", NULL },
412
  { "Symbol", "Symbol,Italic", "Symbol,Bold", "Symbol,BoldItalic", "SymbolMT", "SymbolMT,Italic", "SymbolMT,Bold", "SymbolMT,BoldItalic", NULL },
413
  { "ZapfDingbats", NULL }
414
};
415
416
static int strncmp_ignore_space(const char *a, const char *b)
417
19.7M
{
418
23.9M
    while (1)
419
23.9M
    {
420
23.9M
        while (*a == ' ')
421
0
            a++;
422
23.9M
        while (*b == ' ')
423
1.54k
            b++;
424
23.9M
        if (*a != *b)
425
19.7M
            return 1;
426
4.14M
        if (*a == 0)
427
5.40k
            return *a != *b;
428
4.14M
        if (*b == 0)
429
0
            return *a != *b;
430
4.14M
        a++;
431
4.14M
        b++;
432
4.14M
    }
433
0
    return 0; /* Shouldn't happen */
434
19.7M
}
435
436
static const char *pdfi_clean_font_name(const char *fontname)
437
298k
{
438
298k
    int i, k;
439
4.42M
    for (i = 0; i < (sizeof(pdfi_base_font_names)/sizeof(pdfi_base_font_names[0])); i++) {
440
23.9M
        for (k = 0; pdfi_base_font_names[i][k]; k++) {
441
19.7M
            if (!strncmp_ignore_space(pdfi_base_font_names[i][k], (const char *)fontname))
442
5.40k
                return pdfi_base_font_names[i][0];
443
19.7M
        }
444
4.13M
    }
445
293k
    return NULL;
446
298k
}
447
448
static int pdfi_font_substitute_by_flags(pdf_context *ctx, unsigned int flags, char **name, int *namelen)
449
152k
{
450
152k
    bool fixed = ((flags & pdfi_font_flag_fixed) != 0);
451
152k
    bool serif = ((flags & pdfi_font_flag_serif) != 0);
452
152k
    bool italic = ((flags & pdfi_font_flag_italic) != 0);
453
152k
    bool bold = ((flags & pdfi_font_flag_forcebold) != 0);
454
152k
    int code = 0;
455
456
152k
    if (ctx->args.defaultfont_is_name == true && ctx->args.defaultfont.size == 4
457
152k
        && !memcmp(ctx->args.defaultfont.data, "None", 4)) {
458
0
       *name = NULL;
459
0
       *namelen = 0;
460
0
       code = gs_error_invalidfont;
461
0
    }
462
152k
    else if (ctx->args.defaultfont.data != NULL && ctx->args.defaultfont.size > 0) {
463
0
        *name = (char *)ctx->args.defaultfont.data;
464
0
        *namelen = ctx->args.defaultfont.size;
465
0
    }
466
152k
    else if (fixed) {
467
43
        if (bold) {
468
1
            if (italic) {
469
1
                *name = (char *)pdfi_base_font_names[3][0];
470
1
                *namelen = strlen(*name);
471
1
            }
472
0
            else {
473
0
                *name = (char *)pdfi_base_font_names[1][0];
474
0
                *namelen = strlen(*name);
475
0
            }
476
1
        }
477
42
        else {
478
42
            if (italic) {
479
0
                *name = (char *)pdfi_base_font_names[2][0];
480
0
                *namelen = strlen(*name);
481
0
            }
482
42
            else {
483
42
                *name = (char *)pdfi_base_font_names[0][0];
484
42
                *namelen = strlen(*name);
485
42
            }
486
42
        }
487
43
    }
488
152k
    else if (serif) {
489
1.23k
        if (bold) {
490
1
            if (italic) {
491
0
                *name = (char *)pdfi_base_font_names[11][0];
492
0
                *namelen = strlen(*name);
493
0
            }
494
1
            else {
495
1
                *name = (char *)pdfi_base_font_names[9][0];
496
1
                *namelen = strlen(*name);
497
1
            }
498
1
        }
499
1.23k
        else {
500
1.23k
            if (italic) {
501
64
                *name = (char *)pdfi_base_font_names[10][0];
502
64
                *namelen = strlen(*name);
503
64
            }
504
1.17k
            else {
505
1.17k
                *name = (char *)pdfi_base_font_names[8][0];
506
1.17k
                *namelen = strlen(*name);
507
1.17k
            }
508
1.23k
        }
509
150k
    } else {
510
150k
        if (bold) {
511
35
            if (italic) {
512
0
                *name = (char *)pdfi_base_font_names[7][0];
513
0
                *namelen = strlen(*name);
514
0
            }
515
35
            else {
516
35
                *name = (char *)pdfi_base_font_names[5][0];
517
35
                *namelen = strlen(*name);
518
35
            }
519
35
        }
520
150k
        else {
521
150k
            if (italic) {
522
502
                *name = (char *)pdfi_base_font_names[6][0];
523
502
                *namelen = strlen(*name);
524
502
            }
525
150k
            else {
526
150k
                *name = (char *)pdfi_base_font_names[4][0];
527
150k
                *namelen = strlen(*name);
528
150k
            }
529
150k
        }
530
150k
    }
531
152k
    return code;
532
152k
}
533
534
enum {
535
  no_type_font = -1,
536
  type0_font = 0,
537
  type1_font = 1,
538
  cff_font = 2,
539
  type3_font = 3,
540
  tt_font = 42
541
};
542
543
static int pdfi_fonttype_picker(byte *buf, int64_t buflen)
544
49.8k
{
545
438k
#define MAKEMAGIC(a, b, c, d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
546
547
49.8k
    if (buflen >= 4) {
548
49.8k
        if (MAKEMAGIC(buf[0], buf[1], buf[2], buf[3]) == MAKEMAGIC(0, 1, 0, 0)
549
49.8k
            || MAKEMAGIC(buf[0], buf[1], buf[2], buf[3]) == MAKEMAGIC('t', 'r', 'u', 'e')
550
49.8k
            || MAKEMAGIC(buf[0], buf[1], buf[2], buf[3]) == MAKEMAGIC('t', 't', 'c', 'f')) {
551
21.4k
            return tt_font;
552
21.4k
        }
553
28.3k
        else if (MAKEMAGIC(buf[0], buf[1], buf[2], buf[3]) == MAKEMAGIC('O', 'T', 'T', 'O')) {
554
157
            return cff_font; /* OTTO will end up as CFF */
555
157
        }
556
28.1k
        else if (MAKEMAGIC(buf[0], buf[1], buf[2], 0) == MAKEMAGIC('%', '!', 'P', 0)) {
557
24.8k
            return type1_font; /* pfa */
558
24.8k
        }
559
3.34k
        else if (MAKEMAGIC(buf[0], buf[1], buf[2], 0) == MAKEMAGIC(1, 0, 4, 0)) {
560
3.10k
            return cff_font; /* 1C/CFF */
561
3.10k
        }
562
237
        else if (MAKEMAGIC(buf[0], buf[1], 0, 0) == MAKEMAGIC(128, 1, 0, 0)) {
563
25
            return type1_font; /* pfb */
564
25
        }
565
49.8k
    }
566
222
    return no_type_font;
567
49.8k
#undef MAKEMAGIC
568
49.8k
}
569
570
static int pdfi_copy_font(pdf_context *ctx, pdf_font *spdffont, pdf_dict *font_dict, pdf_font **tpdffont)
571
165k
{
572
165k
    int code;
573
165k
    if (pdfi_type_of(spdffont) != PDF_FONT)
574
0
        return_error(gs_error_typecheck);
575
576
165k
    switch(spdffont->pdfi_font_type) {
577
165k
        case e_pdf_font_type1:
578
165k
          code = pdfi_copy_type1_font(ctx, spdffont, font_dict, tpdffont);
579
165k
          break;
580
0
        case e_pdf_font_cff:
581
0
          code = pdfi_copy_cff_font(ctx, spdffont, font_dict, tpdffont);
582
0
          break;
583
0
        case e_pdf_font_truetype:
584
0
          code = pdfi_copy_truetype_font(ctx, spdffont, font_dict, tpdffont);
585
0
          break;
586
0
        default:
587
0
            return_error(gs_error_invalidfont);
588
165k
    }
589
165k
    return code;
590
165k
}
591
592
enum {
593
  font_embedded = 0,
594
  font_from_file = 1,
595
  font_substitute = 2
596
};
597
598
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)
599
49.8k
{
600
49.8k
    int code = gs_error_invalidfont;
601
49.8k
    if (fbuf != NULL) {
602
        /* First, see if we can glean the type from the magic number */
603
49.8k
        int sftype = pdfi_fonttype_picker(fbuf, fbuflen);
604
49.8k
        if (sftype == no_type_font) {
605
222
            if (fftype != no_type_font)
606
216
                sftype = fftype;
607
6
            else {
608
                /* If we don't have a Subtype, can't work it out, try Type 1 */
609
6
                if (Subtype == NULL || pdfi_name_is(Subtype, "Type1") || pdfi_name_is(Subtype, "MMType1"))
610
6
                    sftype = type1_font;
611
0
                else if (pdfi_name_is(Subtype, "Type1C"))
612
0
                    sftype = cff_font;
613
0
                else if (pdfi_name_is(Subtype, "TrueType"))
614
0
                    sftype = tt_font;
615
6
            }
616
222
        }
617
        /* fbuf ownership passes to the font loader */
618
49.8k
        switch (sftype) {
619
25.0k
            case type1_font:
620
25.0k
                code = pdfi_read_type1_font(ctx, (pdf_dict *)font_dict, stream_dict, page_dict, fbuf, fbuflen, ppdffont);
621
25.0k
                fbuf = NULL;
622
25.0k
                break;
623
3.27k
            case cff_font:
624
3.27k
                code = pdfi_read_cff_font(ctx, (pdf_dict *)font_dict, stream_dict, page_dict, fbuf, fbuflen, cidfont, ppdffont);
625
3.27k
                fbuf = NULL;
626
3.27k
                break;
627
21.5k
            case tt_font:
628
21.5k
                {
629
21.5k
                    if (cidfont)
630
4.61k
                        code = pdfi_read_cidtype2_font(ctx, font_dict, stream_dict, page_dict, fbuf, fbuflen, findex, ppdffont);
631
16.8k
                    else
632
16.8k
                        code = pdfi_read_truetype_font(ctx, font_dict, stream_dict, page_dict, fbuf, fbuflen, findex, ppdffont);
633
21.5k
                    fbuf = NULL;
634
21.5k
                }
635
21.5k
                break;
636
0
            default:
637
0
                gs_free_object(ctx->memory, fbuf, "pdfi_load_font_buffer(fbuf)");
638
0
                code = gs_note_error(gs_error_invalidfont);
639
49.8k
        }
640
49.8k
    }
641
49.8k
    return code;
642
49.8k
}
643
644
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)
645
317k
{
646
317k
    int code;
647
317k
    char fontfname[gp_file_name_sizeof];
648
317k
    pdf_obj *basefont = NULL, *mapname = NULL;
649
317k
    pdf_obj *fontname = NULL;
650
317k
    stream *s;
651
317k
    const char *fn;
652
317k
    int findex = 0;
653
317k
    byte *buf;
654
317k
    int buflen;
655
317k
    pdf_font *pdffont = NULL;
656
317k
    pdf_font *substpdffont = NULL;
657
317k
    bool f_retry = true;
658
659
317k
    code = pdfi_dict_knownget_type(ctx, font_dict, "BaseFont", PDF_NAME, &basefont);
660
317k
    if (substitute == false && (code < 0 || basefont == NULL || ((pdf_name *)basefont)->length == 0)) {
661
5.40k
        pdfi_countdown(basefont);
662
5.40k
        return_error(gs_error_invalidfont);
663
5.40k
    }
664
665
312k
    if (substitute == true) {
666
152k
        char *fbname;
667
152k
        int fbnamelen;
668
152k
        int64_t flags = 0;
669
152k
        if (fontdesc != NULL) {
670
8.58k
            (void)pdfi_dict_get_int(ctx, fontdesc, "Flags", &flags);
671
8.58k
        }
672
152k
        code = pdfi_font_substitute_by_flags(ctx, (int)flags, &fbname, &fbnamelen);
673
152k
        if (code < 0)
674
0
            return code;
675
676
152k
        code = pdfi_name_alloc(ctx, (byte *)fbname, strlen(fbname), (pdf_obj **) &fontname);
677
152k
        if (code < 0)
678
0
            return code;
679
152k
        pdfi_countup(fontname);
680
152k
    }
681
160k
    else {
682
160k
        fontname = basefont;
683
160k
        pdfi_countup(fontname);
684
160k
    }
685
686
312k
    if (((pdf_name *)fontname)->length < gp_file_name_sizeof) {
687
312k
        memcpy(fontfname, ((pdf_name *)fontname)->data, ((pdf_name *)fontname)->length);
688
312k
        fontfname[((pdf_name *)fontname)->length] = '\0';
689
312k
        pdfi_countdown(fontname);
690
691
312k
        code = pdfi_name_alloc(ctx, (byte *)fontfname, strlen(fontfname), (pdf_obj **) &fontname);
692
312k
        if (code < 0)
693
0
            return code;
694
312k
        pdfi_countup(fontname);
695
312k
    }
696
697
461k
    do {
698
461k
        code = pdf_fontmap_lookup_font(ctx, (pdf_name *) fontname, &mapname, &findex);
699
461k
        if (code < 0) {
700
298k
            if (((pdf_name *)fontname)->length < gp_file_name_sizeof) {
701
298k
                memcpy(fontfname, ((pdf_name *)fontname)->data, ((pdf_name *)fontname)->length);
702
298k
                fontfname[((pdf_name *)fontname)->length] = '\0';
703
298k
                fn = pdfi_clean_font_name(fontfname);
704
298k
                if (fn != NULL) {
705
5.40k
                    pdfi_countdown(fontname);
706
707
5.40k
                    code = pdfi_name_alloc(ctx, (byte *)fn, strlen(fn), (pdf_obj **) &fontname);
708
5.40k
                    if (code < 0)
709
0
                        return code;
710
5.40k
                    pdfi_countup(fontname);
711
5.40k
                }
712
298k
            }
713
298k
            code = pdf_fontmap_lookup_font(ctx, (pdf_name *) fontname, &mapname, &findex);
714
298k
            if (code < 0) {
715
293k
                mapname = fontname;
716
293k
                pdfi_countup(mapname);
717
293k
                code = 0;
718
293k
            }
719
298k
        }
720
461k
        if (pdfi_type_of(mapname) == PDF_NAME || pdfi_type_of(mapname) == PDF_STRING) {
721
461k
            pdf_name *mname = (pdf_name *) mapname;
722
461k
            if (mname->length + 1 < gp_file_name_sizeof) {
723
461k
                memcpy(fontfname, mname->data, mname->length);
724
461k
                fontfname[mname->length] = '\0';
725
461k
            }
726
0
            else {
727
0
                pdfi_countdown(mapname);
728
0
                pdfi_countdown(fontname);
729
0
                return_error(gs_error_invalidfileaccess);
730
0
            }
731
461k
        }
732
0
        else {
733
0
            pdfi_countdown(mapname);
734
0
            pdfi_countdown(fontname);
735
0
            return_error(gs_error_invalidfileaccess);
736
0
        }
737
738
461k
        if (ctx->pdf_substitute_fonts != NULL) {
739
422k
            code = pdfi_dict_knownget_type(ctx, ctx->pdf_substitute_fonts, fontfname, PDF_FONT, (pdf_obj **)&pdffont);
740
422k
            if (code == 1 && pdffont->filename == NULL) {
741
0
                pdfi_countdown(pdffont);
742
0
                pdffont = NULL;
743
0
                code = 0;
744
0
            }
745
422k
        }
746
38.5k
        else
747
38.5k
            code = 0;
748
749
461k
        if (code != 1) {
750
316k
            code = pdfi_open_font_file(ctx, fontfname, strlen(fontfname), &s);
751
316k
            if (code < 0 && f_retry && pdfi_type_of(mapname) == PDF_NAME) {
752
149k
                pdfi_countdown(fontname);
753
149k
                fontname = mapname;
754
149k
                mapname = NULL;
755
149k
                f_retry = false;
756
149k
                continue;
757
149k
            }
758
167k
            if (code >= 0) {
759
20.4k
                gs_const_string fname;
760
761
20.4k
                sfilename(s, &fname);
762
20.4k
                if (fname.size < gp_file_name_sizeof) {
763
20.4k
                    memcpy(fontfname, fname.data, fname.size);
764
20.4k
                    fontfname[fname.size] = '\0';
765
20.4k
                }
766
0
                else {
767
0
                    strcpy(fontfname, "unnamed file");
768
0
                }
769
20.4k
                sfseek(s, 0, SEEK_END);
770
20.4k
                buflen = sftell(s);
771
20.4k
                sfseek(s, 0, SEEK_SET);
772
20.4k
                buf = gs_alloc_bytes(ctx->memory, buflen, "pdfi_open_t1_font_file(buf)");
773
20.4k
                if (buf != NULL) {
774
20.3k
                    sfread(buf, 1, buflen, s);
775
20.3k
                }
776
75
                else {
777
75
                    code = gs_note_error(gs_error_VMerror);
778
75
                }
779
20.4k
                sfclose(s);
780
                /* On success, the buffer owership moves to the font object */
781
20.4k
                code = pdfi_load_font_buffer(ctx, buf, buflen, no_type_font, NULL, findex, stream_dict, page_dict, NULL, &pdffont, false);
782
20.4k
                if (code < 0) {
783
75
                    gs_free_object(ctx->memory, buf, "pdfi_load_font_file");
784
75
                }
785
20.3k
                else {
786
20.3k
                    pdffont->filename = NULL;
787
20.3k
                    code = pdfi_object_alloc(ctx, PDF_STRING, strlen(fontfname) , (pdf_obj **)&pdffont->filename);
788
20.3k
                    if (code >= 0) {
789
20.3k
                        pdfi_countup(pdffont->filename);
790
20.3k
                        memcpy(pdffont->filename->data, fontfname, strlen(fontfname));
791
20.3k
                        pdffont->filename->length = strlen(fontfname);
792
20.3k
                    }
793
794
20.3k
                    if (ctx->pdf_substitute_fonts == NULL) {
795
14.8k
                        code = pdfi_dict_alloc(ctx, 16, &ctx->pdf_substitute_fonts);
796
14.8k
                        if (code >= 0)
797
14.8k
                            pdfi_countup(ctx->pdf_substitute_fonts);
798
14.8k
                    }
799
20.3k
                    if (ctx->pdf_substitute_fonts != NULL) {
800
20.3k
                        if (pdfi_type_of(mapname) == PDF_STRING) {
801
0
                            pdf_name *n = NULL;
802
0
                            pdf_string *mn = (pdf_string *)mapname;
803
804
0
                            code = pdfi_name_alloc(ctx, mn->data, mn->length, (pdf_obj **)&n);
805
0
                            if (code >= 0) {
806
0
                                pdfi_countdown(mapname);
807
0
                                mapname = (pdf_obj *)n;
808
0
                                pdfi_countup(mapname);
809
0
                                code = 0;
810
0
                            }
811
0
                        }
812
20.3k
                        else
813
20.3k
                            code = 0;
814
815
20.3k
                        if (code == 0)
816
20.3k
                            (void)pdfi_dict_put_obj(ctx, ctx->pdf_substitute_fonts, mapname, (pdf_obj *)pdffont, true);
817
20.3k
                        code = 0;
818
20.3k
                    }
819
20.3k
                }
820
20.4k
            }
821
167k
        }
822
312k
        break;
823
461k
    } while (1);
824
825
312k
    if (code >= 0) {
826
165k
        if (basefont) {
827
165k
            pdfi_print_cstring(ctx, "Loading font ");
828
165k
            pdfi_print_font_name(ctx, (pdf_name *)basefont);
829
165k
            pdfi_print_cstring(ctx, " (or substitute) from ");
830
165k
        }
831
142
        else {
832
142
            pdfi_print_cstring(ctx, "Loading nameless font from ");
833
142
        }
834
165k
        pdfi_print_font_string(ctx, pdffont->filename);
835
165k
        pdfi_print_cstring(ctx, "\n");
836
837
165k
        code = pdfi_copy_font(ctx, pdffont, font_dict, &substpdffont);
838
165k
        pdfi_countdown(pdffont);
839
165k
    }
840
841
312k
    *ppdffont = substpdffont;
842
843
312k
    pdfi_countdown(basefont);
844
312k
    pdfi_countdown(mapname);
845
312k
    pdfi_countdown(fontname);
846
312k
    return code;
847
312k
}
848
849
int pdfi_load_font(pdf_context *ctx, pdf_dict *stream_dict, pdf_dict *page_dict, pdf_dict *font_dict, gs_font **ppfont, bool cidfont)
850
197k
{
851
197k
    int code;
852
197k
    pdf_font *ppdffont = NULL;
853
197k
    pdf_name *Type = NULL;
854
197k
    pdf_name *Subtype = NULL;
855
197k
    pdf_dict *fontdesc = NULL;
856
197k
    pdf_stream *fontfile = NULL;
857
197k
    pdf_name *ffsubtype = NULL;
858
197k
    int fftype = no_type_font;
859
197k
    byte *fbuf = NULL;
860
197k
    int64_t fbuflen = 0;
861
197k
    int substitute = font_embedded;
862
197k
    int findex = -1;
863
864
197k
    code = pdfi_dict_get_type(ctx, font_dict, "Type", PDF_NAME, (pdf_obj **)&Type);
865
197k
    if (code < 0) {
866
68
        pdfi_set_error(ctx, 0, NULL, E_PDF_MISSINGTYPE, "pdfi_load_font", NULL);
867
68
    }
868
197k
    else {
869
197k
        if (!pdfi_name_is(Type, "Font")){
870
1.57k
            code = gs_note_error(gs_error_typecheck);
871
1.57k
            goto exit;
872
1.57k
        }
873
197k
    }
874
195k
    code = pdfi_dict_get_type(ctx, font_dict, "Subtype", PDF_NAME, (pdf_obj **)&Subtype);
875
195k
    if (code < 0) {
876
143k
        pdfi_set_error(ctx, 0, NULL, E_PDF_NO_SUBTYPE, "pdfi_load_font", NULL);
877
143k
    }
878
879
    /* Beyond Type 0 and Type 3, there is no point trusting the Subtype key */
880
195k
    if (code >= 0 && pdfi_name_is(Subtype, "Type0")) {
881
6.85k
        if (cidfont == true) {
882
3
            code = gs_note_error(gs_error_invalidfont);
883
3
        }
884
6.85k
        else {
885
6.85k
            code = pdfi_read_type0_font(ctx, (pdf_dict *)font_dict, stream_dict, page_dict, &ppdffont);
886
6.85k
        }
887
6.85k
    }
888
188k
    else if (code >= 0 && pdfi_name_is(Subtype, "Type3")) {
889
622
        code = pdfi_read_type3_font(ctx, (pdf_dict *)font_dict, stream_dict, page_dict, &ppdffont);
890
622
        if (code < 0)
891
91
            goto exit;
892
622
    }
893
188k
    else {
894
        /* We should always have a font descriptor here, but we have to carry on
895
           even if we don't
896
         */
897
188k
        code = pdfi_dict_get_type(ctx, font_dict, "FontDescriptor", PDF_DICT, (pdf_obj**)&fontdesc);
898
188k
        if (fontdesc != NULL && pdfi_type_of(fontdesc) == PDF_DICT) {
899
35.1k
            code = pdfi_dict_get_type(ctx, (pdf_dict *) fontdesc, "FontFile", PDF_STREAM, (pdf_obj**)&fontfile);
900
35.1k
            if (code >= 0)
901
4.71k
                fftype = type1_font;
902
30.4k
            else {
903
30.4k
                code = pdfi_dict_get_type(ctx, (pdf_dict *) fontdesc, "FontFile2", PDF_STREAM, (pdf_obj**)&fontfile);
904
30.4k
                fftype = tt_font;
905
30.4k
            }
906
35.1k
            if (code < 0) {
907
11.2k
                code = pdfi_dict_get_type(ctx, (pdf_dict *) fontdesc, "FontFile3", PDF_STREAM, (pdf_obj**)&fontfile);
908
11.2k
                if (code >= 0 && fontfile != NULL) {
909
3.31k
                    code = pdfi_dict_get_type(ctx, fontfile->stream_dict, "Subtype", PDF_NAME, (pdf_obj **)&ffsubtype);
910
3.31k
                    if (code >= 0) {
911
3.31k
                        if (pdfi_name_is(ffsubtype, "Type1"))
912
0
                            fftype = type1_font;
913
3.31k
                        else if (pdfi_name_is(ffsubtype, "Type1C"))
914
2.63k
                            fftype = cff_font;
915
676
                        else if (pdfi_name_is(ffsubtype, "OpenType"))
916
96
                            fftype = cff_font;
917
580
                        else if (pdfi_name_is(ffsubtype, "CIDFontType0C"))
918
538
                            fftype = cff_font;
919
42
                        else if (pdfi_name_is(ffsubtype, "TrueType"))
920
0
                            fftype = tt_font;
921
42
                        else
922
42
                            fftype = no_type_font;
923
3.31k
                    }
924
3.31k
                }
925
11.2k
            }
926
35.1k
        }
927
928
188k
        if (fontfile != NULL) {
929
27.2k
            code = pdfi_stream_to_buffer(ctx, (pdf_stream *) fontfile, &fbuf, &fbuflen);
930
27.2k
            pdfi_countdown(fontfile);
931
27.2k
            if (fbuflen == 0) {
932
314
                gs_free_object(ctx->memory, fbuf, "pdfi_load_font(fbuf)");
933
314
                fbuf = NULL;
934
314
                code = gs_note_error(gs_error_invalidfont);
935
314
            }
936
27.2k
        }
937
938
190k
        while (1) {
939
190k
            if (fbuf != NULL) {
940
                /* fbuf overship passes to pdfi_load_font_buffer() */
941
29.4k
                code = pdfi_load_font_buffer(ctx, fbuf, fbuflen, fftype, Subtype, findex, stream_dict, page_dict, font_dict, &ppdffont, cidfont);
942
943
29.4k
                if (code < 0 && substitute == font_embedded) {
944
6.99k
                    if (ctx->args.pdfstoponerror == true) {
945
0
                        goto exit;
946
0
                    }
947
6.99k
                    else {
948
6.99k
                        char obj[129];
949
6.99k
                        pdfi_print_cstring(ctx, "**** Warning: cannot process embedded stream for font object ");
950
6.99k
                        gs_snprintf(obj, 128, "%d %d\n", (int)font_dict->object_num, (int)font_dict->generation_num);
951
6.99k
                        pdfi_print_cstring(ctx, obj);
952
6.99k
                        pdfi_print_cstring(ctx, "**** Attempting to load a substitute font.\n");
953
6.99k
                    }
954
6.99k
                }
955
29.4k
            }
956
161k
            else {
957
161k
                code = gs_error_invalidfont;
958
161k
            }
959
960
190k
            if (code < 0 && code != gs_error_VMerror && substitute == font_embedded) {
961
168k
                substitute = font_from_file;
962
963
168k
                if (cidfont == true) {
964
2.54k
                    code =  pdfi_open_CIDFont_substitute_file(ctx, font_dict, fontdesc, false, &fbuf, &fbuflen, &findex);
965
2.54k
                    if (code < 0) {
966
2.54k
                        code =  pdfi_open_CIDFont_substitute_file(ctx, font_dict, fontdesc, true, &fbuf, &fbuflen, &findex);
967
2.54k
                        substitute |= font_substitute;
968
2.54k
                    }
969
970
2.54k
                    if (code < 0)
971
13
                        goto exit;
972
2.54k
                }
973
165k
                else {
974
165k
                    code = pdfi_load_font_file(ctx, no_type_font, Subtype, stream_dict, page_dict, font_dict, fontdesc, false, &ppdffont);
975
165k
                    if (code < 0) {
976
152k
                        code = pdfi_load_font_file(ctx, no_type_font, Subtype, stream_dict, page_dict, font_dict, fontdesc, true, &ppdffont);
977
152k
                        substitute |= font_substitute;
978
152k
                    }
979
165k
                    break;
980
165k
                }
981
2.53k
                continue;
982
168k
            }
983
22.7k
            break;
984
190k
        }
985
188k
    }
986
987
195k
    if (ppdffont == NULL || code < 0) {
988
4.81k
        *ppfont = NULL;
989
4.81k
        code = gs_note_error(gs_error_invalidfont);
990
4.81k
    }
991
190k
    else {
992
190k
        if (cidfont) {
993
3.46k
            ((pdf_cidfont_t *)ppdffont)->substitute = (substitute != font_embedded);
994
3.46k
        }
995
187k
        else {
996
187k
            if ((substitute & font_substitute) == font_substitute)
997
151k
                code = pdfi_font_match_glyph_widths(ppdffont);
998
187k
        }
999
190k
        *ppfont = (gs_font *)ppdffont->pfont;
1000
190k
     }
1001
1002
197k
exit:
1003
197k
    pdfi_countdown(fontdesc);
1004
197k
    pdfi_countdown(Type);
1005
197k
    pdfi_countdown(Subtype);
1006
197k
    pdfi_countdown(ffsubtype);
1007
197k
    return code;
1008
195k
}
1009
1010
int pdfi_load_dict_font(pdf_context *ctx, pdf_dict *stream_dict, pdf_dict *page_dict, pdf_dict *font_dict, double point_size)
1011
360k
{
1012
360k
    int code;
1013
360k
    gs_font *pfont;
1014
360k
    pdf_font *pdfif;
1015
1016
360k
    switch (pdfi_type_of(font_dict)) {
1017
304k
        case PDF_FONT:
1018
304k
            pdfi_countup(font_dict);
1019
304k
            pfont = (gs_font *)((pdf_font *)font_dict)->pfont;
1020
304k
            code = 0;
1021
304k
            break;
1022
49.4k
        case PDF_DICT:
1023
49.4k
            code = pdfi_load_font(ctx, stream_dict, page_dict, font_dict, &pfont, false);
1024
49.4k
            break;
1025
5.96k
        default:
1026
5.96k
            code = gs_note_error(gs_error_typecheck);
1027
5.96k
            goto exit;
1028
360k
    }
1029
354k
    if (code < 0)
1030
4.85k
        goto exit;
1031
1032
    /* Everything looks good, set the font, unless it's the current font */
1033
349k
    if (pfont != ctx->pgs->font) {
1034
286k
        code = pdfi_gs_setfont(ctx, pfont);
1035
286k
    }
1036
349k
    pdfif = (pdf_font *)pfont->client_data;
1037
349k
    pdfi_countdown(pdfif);
1038
1039
349k
    if (code < 0)
1040
0
        goto exit;
1041
1042
349k
    code = gs_setPDFfontsize(ctx->pgs, point_size);
1043
360k
exit:
1044
360k
    return code;
1045
349k
}
1046
1047
static int pdfi_load_resource_font(pdf_context *ctx, pdf_dict *stream_dict, pdf_dict *page_dict, pdf_name *fontname, double point_size)
1048
492k
{
1049
492k
    int code;
1050
492k
    pdf_dict *font_dict = NULL;
1051
1052
492k
    if (pdfi_type_of(fontname) != PDF_NAME) {
1053
        /* Passing empty string here should fall back to a default font */
1054
4.73k
        return pdfi_font_set_internal_string(ctx, "", point_size);
1055
4.73k
    }
1056
1057
    /* Look fontname up in the resources */
1058
487k
    code = pdfi_loop_detector_mark(ctx);
1059
487k
    if (code < 0)
1060
0
        goto exit;
1061
487k
    code = pdfi_find_resource(ctx, (unsigned char *)"Font", fontname, stream_dict, page_dict, (pdf_obj **)&font_dict);
1062
487k
    (void)pdfi_loop_detector_cleartomark(ctx);
1063
487k
    if (code < 0)
1064
127k
        goto exit;
1065
360k
    code = pdfi_load_dict_font(ctx, stream_dict, page_dict, font_dict, point_size);
1066
1067
487k
exit:
1068
487k
    pdfi_countdown(font_dict);
1069
487k
    return code;
1070
360k
}
1071
1072
int pdfi_get_cidfont_glyph_metrics(gs_font *pfont, gs_glyph cid, double *widths, bool vertical)
1073
437k
{
1074
437k
    pdf_font *pdffont = (pdf_font *)pfont->client_data;
1075
437k
    int i, code = 0;
1076
437k
    pdf_num *c = NULL, *c2 = NULL;
1077
437k
    pdf_obj *o = NULL;
1078
437k
    pdf_array *W = NULL, *W2 = NULL, *DW2 = NULL;
1079
437k
    double DW;
1080
1081
437k
    if (pdffont->pdfi_font_type == e_pdf_cidfont_type0) {
1082
11.0k
        pdf_cidfont_type0 *cidfont = (pdf_cidfont_type0 *)pdffont;
1083
11.0k
        DW = (double)cidfont->DW;
1084
11.0k
        DW2 = cidfont->DW2;
1085
11.0k
        W = cidfont->W;
1086
11.0k
        W2 = cidfont->W2;
1087
11.0k
    }
1088
426k
    else if (pdffont->pdfi_font_type == e_pdf_cidfont_type2) {
1089
426k
        pdf_cidfont_type2 *cidfont = (pdf_cidfont_type2 *)pdffont;
1090
426k
        DW = (double)cidfont->DW;
1091
426k
        DW2 = cidfont->DW2;
1092
426k
        W = cidfont->W;
1093
426k
        W2 = cidfont->W2;
1094
426k
    }
1095
0
    else {
1096
0
        return_error(gs_error_invalidfont);
1097
0
    }
1098
1099
437k
    widths[GLYPH_W0_WIDTH_INDEX] = DW;
1100
437k
    widths[GLYPH_W0_HEIGHT_INDEX] = 0;
1101
437k
    if (W != NULL) {
1102
421k
        i = 0;
1103
1104
6.37M
        while(1) {
1105
6.37M
            pdf_obj_type type;
1106
1107
6.37M
            if (i + 1>= W->size) break;
1108
6.33M
            code = pdfi_array_get_type(pdffont->ctx, W, i, PDF_INT, (pdf_obj **)&c);
1109
6.33M
            if (code < 0) goto cleanup;
1110
1111
6.33M
            code = pdfi_array_get(pdffont->ctx, W, i + 1, &o);
1112
6.33M
            if (code < 0) goto cleanup;
1113
1114
6.33M
            type = pdfi_type_of(o);
1115
6.33M
            if (type == PDF_INT) {
1116
1.02M
                double d;
1117
1.02M
                c2 = (pdf_num *)o;
1118
1.02M
                o = NULL;
1119
1.02M
                if (i + 2 >= W->size){
1120
                    /* We countdown and NULL c, c2 and o after exit from the loop
1121
                     * in order to avoid doing so in the break statements
1122
                     */
1123
83
                    break;
1124
83
                }
1125
1126
1.02M
                code = pdfi_array_get_number(pdffont->ctx, W, i + 2, &d);
1127
1.02M
                if (code < 0) goto cleanup;
1128
1.02M
                if (cid >= c->value.i && cid <= c2->value.i) {
1129
67.0k
                    widths[GLYPH_W0_WIDTH_INDEX] = d;
1130
67.0k
                    widths[GLYPH_W0_HEIGHT_INDEX] = 0.0;
1131
                    /* We countdown and NULL c, c2 and o after exit from the loop
1132
                     * in order to avoid doing so in the break statements
1133
                     */
1134
67.0k
                    break;
1135
67.0k
                }
1136
961k
                else {
1137
961k
                    i += 3;
1138
961k
                    pdfi_countdown(c2);
1139
961k
                    pdfi_countdown(c);
1140
961k
                    c = c2 = NULL;
1141
961k
                    continue;
1142
961k
                }
1143
1.02M
            }
1144
5.30M
            else if (type == PDF_ARRAY) {
1145
5.30M
                pdf_array *a = (pdf_array *)o;
1146
5.30M
                o = NULL;
1147
5.30M
                if (cid >= c->value.i && cid < c->value.i + a->size) {
1148
311k
                    code = pdfi_array_get_number(pdffont->ctx, a, cid - c->value.i, &widths[GLYPH_W0_WIDTH_INDEX]);
1149
311k
                    if (code >= 0) {
1150
311k
                        pdfi_countdown(a);
1151
311k
                        widths[GLYPH_W0_HEIGHT_INDEX] = 0.0;
1152
                        /* We countdown and NULL c, c2 and o on exit from the loop
1153
                         * in order to avoid doing so in the break statements
1154
                         */
1155
311k
                        break;
1156
311k
                    }
1157
311k
                }
1158
4.99M
                pdfi_countdown(a);
1159
4.99M
                pdfi_countdown(c);
1160
4.99M
                c = NULL;
1161
4.99M
                i += 2;
1162
4.99M
                continue;
1163
5.30M
            }
1164
45
            else {
1165
45
                code = gs_note_error(gs_error_typecheck);
1166
45
                goto cleanup;
1167
45
            }
1168
6.33M
        }
1169
420k
        pdfi_countdown(c2);
1170
420k
        pdfi_countdown(c);
1171
420k
        pdfi_countdown(o);
1172
420k
        c = c2 = NULL;
1173
420k
        o = NULL;
1174
420k
    }
1175
1176
437k
    if (vertical) {
1177
        /* Default default <sigh>! */
1178
437k
        widths[GLYPH_W1_WIDTH_INDEX] = 0;
1179
437k
        widths[GLYPH_W1_HEIGHT_INDEX] = -1000.0;
1180
437k
        widths[GLYPH_W1_V_X_INDEX] = (widths[GLYPH_W0_WIDTH_INDEX] / 2.0);
1181
437k
        widths[GLYPH_W1_V_Y_INDEX] = 880.0;
1182
1183
437k
        if (DW2 != NULL && pdfi_type_of(DW2) == PDF_ARRAY
1184
437k
            && DW2->size >= 2) {
1185
860
            code = pdfi_array_get_number(pdffont->ctx, (pdf_array *)DW2, 0, &widths[GLYPH_W1_V_Y_INDEX]);
1186
860
            if (code >= 0)
1187
860
                code = pdfi_array_get_number(pdffont->ctx, (pdf_array *)DW2, 1, &widths[GLYPH_W1_HEIGHT_INDEX]);
1188
860
            if (code >= 0) {
1189
860
                widths[GLYPH_W1_V_X_INDEX] = widths[GLYPH_W0_WIDTH_INDEX] / 2.0;
1190
860
                widths[GLYPH_W1_WIDTH_INDEX] = 0.0;
1191
860
            }
1192
860
        }
1193
437k
        if (W2 != NULL && pdfi_type_of(W2) == PDF_ARRAY) {
1194
0
            i = 0;
1195
0
            while(1) {
1196
0
                pdf_obj_type type;
1197
0
                if (i + 1 >= W2->size) break;
1198
0
                (void)pdfi_array_get(pdffont->ctx, W2, i, (pdf_obj **)&c);
1199
0
                if (pdfi_type_of(c) != PDF_INT) {
1200
0
                    code = gs_note_error(gs_error_typecheck);
1201
0
                    goto cleanup;
1202
0
                }
1203
0
                code = pdfi_array_get(pdffont->ctx, W2, i + 1, (pdf_obj **)&o);
1204
0
                if (code < 0) goto cleanup;
1205
0
                type = pdfi_type_of(o);
1206
0
                if (type == PDF_INT) {
1207
0
                    if (cid >= c->value.i && cid <= ((pdf_num *)o)->value.i) {
1208
0
                        if (i + 4 >= W2->size) {
1209
                            /* We countdown and NULL c, and o on exit from the function
1210
                             * so we don't need to do so in the break statements
1211
                             */
1212
0
                            break;
1213
0
                        }
1214
0
                        code = pdfi_array_get_number(pdffont->ctx, W2, i + 1, &widths[GLYPH_W1_HEIGHT_INDEX]);
1215
0
                        if (code < 0) goto cleanup;
1216
0
                        code = pdfi_array_get_number(pdffont->ctx, W2, i + 1, &widths[GLYPH_W1_V_X_INDEX]);
1217
0
                        if (code < 0) goto cleanup;
1218
0
                        code = pdfi_array_get_number(pdffont->ctx, W2, i + 1, &widths[GLYPH_W1_V_Y_INDEX]);
1219
0
                        if (code < 0) goto cleanup;
1220
                        /* We countdown and NULL c, and o on exit from the function
1221
                         * so we don't need to do so in the break statements
1222
                         */
1223
0
                        break;
1224
0
                    }
1225
0
                    i += 5;
1226
0
                }
1227
0
                else if (type == PDF_ARRAY) {
1228
0
                    pdf_array *a = (pdf_array *)o;
1229
0
                    int l = a->size - (a->size % 3);
1230
0
                    o = NULL;
1231
0
                    if (cid >= c->value.i && cid < c->value.i + (l / 3)) {
1232
0
                        int index = (cid - c->value.i) * 3;
1233
0
                        code = pdfi_array_get_number(pdffont->ctx, a, index, &widths[GLYPH_W1_HEIGHT_INDEX]);
1234
0
                        if (code < 0) {
1235
0
                            pdfi_countdown(a);
1236
0
                            goto cleanup;
1237
0
                        }
1238
0
                        code = pdfi_array_get_number(pdffont->ctx, a, index + 1, &widths[GLYPH_W1_V_X_INDEX]);
1239
0
                        if (code < 0) {
1240
0
                            pdfi_countdown(a);
1241
0
                            goto cleanup;
1242
0
                        }
1243
0
                        code = pdfi_array_get_number(pdffont->ctx, a, index + 2, &widths[GLYPH_W1_V_Y_INDEX]);
1244
0
                        pdfi_countdown(a);
1245
0
                        if (code < 0) goto cleanup;
1246
1247
                        /* We countdown and NULL c, and o on exit from the function
1248
                         * so we don't need to do so in the break statements
1249
                         */
1250
0
                        break;
1251
0
                    } else
1252
0
                        pdfi_countdown(a);
1253
0
                    i += 2;
1254
0
                }
1255
0
                else {
1256
0
                    code = gs_note_error(gs_error_typecheck);
1257
0
                    goto cleanup;
1258
0
                }
1259
0
                pdfi_countdown(o);
1260
0
                pdfi_countdown(c);
1261
0
                o = NULL;
1262
0
                c = NULL;
1263
0
            }
1264
0
        }
1265
437k
    }
1266
1267
437k
cleanup:
1268
437k
    pdfi_countdown(c2);
1269
437k
    pdfi_countdown(c);
1270
437k
    pdfi_countdown(o);
1271
1272
437k
    return code;
1273
437k
}
1274
1275
int pdfi_d0(pdf_context *ctx)
1276
207
{
1277
207
    int code = 0, gsave_level = 0;
1278
207
    double width[2];
1279
1280
207
    if (ctx->text.inside_CharProc == false)
1281
147
        pdfi_set_warning(ctx, 0, NULL, W_PDF_NOTINCHARPROC, "pdfi_d0", NULL);
1282
1283
207
    ctx->text.CharProc_d_type = pdf_type3_d0;
1284
1285
207
    if (pdfi_count_stack(ctx) < 2) {
1286
61
        code = gs_note_error(gs_error_stackunderflow);
1287
61
        goto d0_error;
1288
61
    }
1289
1290
146
    if (pdfi_type_of(ctx->stack_top[-1]) != PDF_INT && pdfi_type_of(ctx->stack_top[-1]) != PDF_REAL) {
1291
4
        code = gs_note_error(gs_error_typecheck);
1292
4
        goto d0_error;
1293
4
    }
1294
142
    if (pdfi_type_of(ctx->stack_top[-2]) != PDF_INT && pdfi_type_of(ctx->stack_top[-2]) != PDF_REAL) {
1295
28
        code = gs_note_error(gs_error_typecheck);
1296
28
        goto d0_error;
1297
28
    }
1298
114
    if(ctx->text.current_enum == NULL) {
1299
54
        code = gs_note_error(gs_error_undefined);
1300
54
        goto d0_error;
1301
54
    }
1302
1303
60
    if (pdfi_type_of(ctx->stack_top[-1]) == PDF_INT)
1304
60
        width[0] = (double)((pdf_num *)ctx->stack_top[-1])->value.i;
1305
0
    else
1306
0
        width[0] = ((pdf_num *)ctx->stack_top[-1])->value.d;
1307
60
    if (pdfi_type_of(ctx->stack_top[-2]) == PDF_INT)
1308
60
        width[1] = (double)((pdf_num *)ctx->stack_top[-1])->value.i;
1309
0
    else
1310
0
        width[1] = ((pdf_num *)ctx->stack_top[-1])->value.d;
1311
1312
60
    gsave_level = ctx->pgs->level;
1313
1314
    /*
1315
     * We don't intend to retain this, instead we will use (effectively) xyshow to apply
1316
     * width overrides at the text level.
1317
    if (font && font->Widths && ctx->current_chr >= font->FirstChar && ctx->current_chr <= font->LastChar)
1318
        width[0] = font->Widths[font->ctx->current_chr - font->FirstChar];
1319
     */
1320
1321
60
    if (ctx->text.current_enum == NULL) {
1322
0
        code = gs_note_error(gs_error_unknownerror);
1323
0
        goto d0_error;
1324
0
    }
1325
1326
60
    code = gs_text_setcharwidth(ctx->text.current_enum, width);
1327
1328
    /* Nasty hackery. setcachedevice potentially pushes a new device into the graphics state
1329
     * and there's no way to remove that device again without grestore'ing back to a point
1330
     * before the device was loaded. To facilitate this, setcachedevice will do a gs_gsave()
1331
     * before changing the device. Note, the grestore for this is done back in show_update()
1332
     * which is not reached until after the CharProc has been executed.
1333
     *
1334
     * This is a problem for us when running a PDF content stream, because after running the
1335
     * stream we check the gsave level and, if its not the same as it was when we started
1336
     * the stream, we pdfi_grestore() back until it is. This mismatch of the gsave levels
1337
     * causes all sorts of trouble with the font and we can end up counting the pdf_font
1338
     * object down and discarding the font we're tryign to use.
1339
     *
1340
     * The solution (ugly though it is) is to patch up the saved gsave_level in the
1341
     * context to expect that we have one more gsave level on exit. That wasy we won't
1342
     * try and pdf_grestore() back to an earlier point.
1343
     */
1344
60
    if (ctx->pgs->level > gsave_level)
1345
0
        ctx->current_stream_save.gsave_level += ctx->pgs->level - gsave_level;
1346
1347
60
    if (code < 0)
1348
0
        goto d0_error;
1349
60
    pdfi_pop(ctx, 2);
1350
60
    return 0;
1351
1352
147
d0_error:
1353
147
    pdfi_clearstack(ctx);
1354
147
    return code;
1355
60
}
1356
1357
int pdfi_d1(pdf_context *ctx)
1358
7.10k
{
1359
7.10k
    int code = 0, gsave_level;
1360
7.10k
    double wbox[6];
1361
1362
7.10k
    if (ctx->text.inside_CharProc == false)
1363
52
        pdfi_set_warning(ctx, 0, NULL, W_PDF_NOTINCHARPROC, "pdfi_d1", NULL);
1364
1365
7.10k
    ctx->text.CharProc_d_type = pdf_type3_d1;
1366
1367
7.10k
    code = pdfi_destack_reals(ctx, wbox, 6);
1368
7.10k
    if (code < 0)
1369
61
        goto d1_error;
1370
1371
    /*
1372
     * We don't intend to retain this, instead we will use (effectively) xyshow to apply
1373
     * width overrides at the text level.
1374
    if (font && font->Widths && ctx->current_chr >= font->FirstChar && ctx->current_chr <= font->LastChar)
1375
        wbox[0] = font->Widths[font->ctx->current_chr - font->FirstChar];
1376
     */
1377
1378
7.03k
    gsave_level = ctx->pgs->level;
1379
1380
7.03k
    if (ctx->text.current_enum == NULL) {
1381
16
        code = gs_note_error(gs_error_unknownerror);
1382
16
        goto d1_error;
1383
16
    }
1384
1385
7.02k
    code = gs_text_setcachedevice(ctx->text.current_enum, wbox);
1386
1387
    /* See the comment immediately after gs_text_setcachedvice() in pdfi_d0 above */
1388
7.02k
    if (ctx->pgs->level > gsave_level)
1389
6.15k
        ctx->current_stream_save.gsave_level += ctx->pgs->level - gsave_level;
1390
1391
7.02k
    if (code < 0)
1392
0
        goto d1_error;
1393
7.02k
    return 0;
1394
1395
77
d1_error:
1396
77
    pdfi_clearstack(ctx);
1397
77
    return code;
1398
7.02k
}
1399
1400
int pdfi_Tf(pdf_context *ctx, pdf_dict *stream_dict, pdf_dict *page_dict)
1401
498k
{
1402
498k
    double point_size = 0;
1403
498k
    pdf_obj *point_arg = NULL;
1404
498k
    int code = 0;
1405
498k
    pdf_name *fontname = NULL;
1406
1407
498k
    if (pdfi_count_stack(ctx) < 2) {
1408
5.28k
        pdfi_clearstack(ctx);
1409
5.28k
        return_error(gs_error_stackunderflow);
1410
5.28k
    }
1411
1412
    /* Get refs to the args and pop them */
1413
493k
    point_arg = ctx->stack_top[-1];
1414
493k
    pdfi_countup(point_arg);
1415
493k
    fontname = (pdf_name *)ctx->stack_top[-2];
1416
493k
    pdfi_countup(fontname);
1417
493k
    pdfi_pop(ctx, 2);
1418
1419
    /* Get the point_size */
1420
493k
    code = pdfi_obj_to_real(ctx, point_arg, &point_size);
1421
493k
    if (code < 0)
1422
1.11k
        goto exit0;
1423
1424
492k
    code = pdfi_load_resource_font(ctx, stream_dict, page_dict, fontname, point_size);
1425
1426
    /* If we failed to load font, try to load an internal one */
1427
492k
    if (code < 0)
1428
138k
        code = pdfi_font_set_internal_name(ctx, fontname, point_size);
1429
493k
 exit0:
1430
493k
    pdfi_countdown(fontname);
1431
493k
    pdfi_countdown(point_arg);
1432
493k
    return code;
1433
492k
}
1434
1435
int pdfi_free_font(pdf_obj *font)
1436
217k
{
1437
217k
    pdf_font *f = (pdf_font *)font;
1438
1439
217k
    switch (f->pdfi_font_type) {
1440
4.02k
        case e_pdf_font_type0:
1441
4.02k
            return pdfi_free_font_type0((pdf_obj *)font);
1442
0
            break;
1443
189k
        case e_pdf_font_type1:
1444
189k
            return pdfi_free_font_type1((pdf_obj *)font);
1445
0
            break;
1446
2.98k
        case e_pdf_font_cff:
1447
2.98k
            return pdfi_free_font_cff((pdf_obj *)font);
1448
622
        case e_pdf_font_type3:
1449
622
            return pdfi_free_font_type3((pdf_obj *)font);
1450
0
            break;
1451
16.8k
        case e_pdf_font_truetype:
1452
16.8k
            return pdfi_free_font_truetype((pdf_obj *)font);
1453
0
            break;
1454
3.43k
        case e_pdf_cidfont_type2:
1455
3.43k
            return pdfi_free_font_cidtype2((pdf_obj *)font);
1456
0
            break;
1457
497
        case e_pdf_cidfont_type0:
1458
497
            return pdfi_free_font_cidtype0((pdf_obj *)font);
1459
0
            break;
1460
0
        case e_pdf_cidfont_type1:
1461
0
        case e_pdf_cidfont_type4:
1462
0
        default:
1463
0
            return gs_note_error(gs_error_typecheck);
1464
0
            break;
1465
217k
    }
1466
0
    return 0;
1467
217k
}
1468
1469
static inline int pdfi_encoding_name_to_index(pdf_name *name)
1470
59.8k
{
1471
59.8k
    int ind = gs_error_undefined;
1472
59.8k
    if (pdfi_type_of(name) == PDF_NAME) {
1473
59.8k
        if (pdfi_name_is(name, "StandardEncoding")) {
1474
26.2k
            ind = ENCODING_INDEX_STANDARD;
1475
33.5k
        } else {
1476
33.5k
            if (pdfi_name_is(name, "WinAnsiEncoding")){
1477
26.6k
                ind = ENCODING_INDEX_WINANSI;
1478
26.6k
            } else {
1479
6.90k
                if (pdfi_name_is(name, "MacRomanEncoding")){
1480
6.70k
                    ind = ENCODING_INDEX_MACROMAN;
1481
6.70k
                } else {
1482
201
                    if (pdfi_name_is(name, "MacExpertEncoding")){
1483
10
                        ind = ENCODING_INDEX_MACEXPERT;
1484
10
                    }
1485
201
                }
1486
6.90k
            }
1487
33.5k
        }
1488
59.8k
    }
1489
59.8k
    return ind;
1490
59.8k
}
1491
1492
/*
1493
 * Routine to fill in an array with each of the glyph names from a given
1494
 * 'standard' Encoding.
1495
 */
1496
static int pdfi_build_Encoding(pdf_context *ctx, pdf_name *name, pdf_array *Encoding)
1497
58.9k
{
1498
58.9k
    int i, code = 0;
1499
58.9k
    unsigned char gs_encoding;
1500
58.9k
    gs_glyph temp;
1501
58.9k
    gs_const_string str;
1502
58.9k
    pdf_name *n = NULL;
1503
1504
58.9k
    if (pdfi_array_size(Encoding) < 256)
1505
0
        return gs_note_error(gs_error_rangecheck);
1506
1507
58.9k
    code = pdfi_encoding_name_to_index(name);
1508
58.9k
    if (code < 0)
1509
189
        return code;
1510
58.7k
    gs_encoding = (unsigned char)code;
1511
58.7k
    code = 0;
1512
1513
15.1M
    for (i = 0;i<256;i++) {
1514
15.0M
        temp = gs_c_known_encode(i, gs_encoding);
1515
15.0M
        gs_c_glyph_name(temp, &str);
1516
15.0M
        code = pdfi_name_alloc(ctx, (byte *)str.data, str.size, (pdf_obj **)&n);
1517
15.0M
        if (code < 0)
1518
0
            return code;
1519
15.0M
        pdfi_countup(n);
1520
15.0M
        code = pdfi_array_put(ctx, Encoding, (uint64_t)i, (pdf_obj *)n);
1521
15.0M
        pdfi_countdown(n);
1522
15.0M
        if (code < 0)
1523
0
            return code;
1524
15.0M
    }
1525
58.7k
    return 0;
1526
58.7k
}
1527
1528
/*
1529
 * Create and fill in a pdf_array with an Encoding for a font. pdf_Encoding must be either
1530
 * a name (eg StandardEncoding) or a dictionary. If its a name we use that to create the
1531
 * entries, if its a dictionary we start by getting the BaseEncoding and using that to
1532
 * create an array of glyph names as above, *or* for a symbolic font, we use the "predef_Encoding"
1533
 * which is the encoding from the font description itself (i.e. the /Encoding array
1534
 * from a Type 1 font. We then get the Differences array from the dictionary and use that to
1535
 * refine the Encoding.
1536
 */
1537
int pdfi_create_Encoding(pdf_context *ctx, pdf_obj *pdf_Encoding, pdf_obj *font_Encoding, pdf_obj **Encoding)
1538
62.5k
{
1539
62.5k
    int code = 0, i;
1540
1541
62.5k
    code = pdfi_array_alloc(ctx, 256, (pdf_array **)Encoding);
1542
62.5k
    if (code < 0)
1543
0
        return code;
1544
62.5k
    pdfi_countup(*Encoding);
1545
1546
62.5k
    switch (pdfi_type_of(pdf_Encoding)) {
1547
53.6k
        case PDF_NAME:
1548
53.6k
            code = pdfi_build_Encoding(ctx, (pdf_name *)pdf_Encoding, (pdf_array *)*Encoding);
1549
53.6k
            if (code < 0) {
1550
189
                pdfi_countdown(*Encoding);
1551
189
                *Encoding = NULL;
1552
189
                return code;
1553
189
            }
1554
53.4k
            break;
1555
53.4k
        case PDF_DICT:
1556
8.90k
        {
1557
8.90k
            pdf_name *n = NULL;
1558
8.90k
            pdf_array *a = NULL;
1559
8.90k
            pdf_obj *o = NULL;
1560
8.90k
            int offset = 0;
1561
8.90k
            bool b_e_known;
1562
1563
8.90k
            if (pdfi_type_of(pdf_Encoding) == PDF_DICT) {
1564
8.90k
                code = pdfi_dict_known(ctx, (pdf_dict *)pdf_Encoding, "BaseEncoding", &b_e_known);
1565
8.90k
                if (code < 0)
1566
0
                    b_e_known = false;
1567
8.90k
            }
1568
0
            else {
1569
0
                b_e_known = false;
1570
0
            }
1571
1572
8.90k
            if (b_e_known == false && font_Encoding != NULL && pdfi_type_of(font_Encoding) == PDF_ARRAY) {
1573
3.56k
                pdf_array *fenc = (pdf_array *)font_Encoding;
1574
916k
                for (i = 0; i < pdfi_array_size(fenc) && code >= 0; i++) {
1575
913k
                    code = pdfi_array_get(ctx, fenc, (uint64_t)i, &o);
1576
913k
                    if (code >= 0)
1577
913k
                        code = pdfi_array_put(ctx, (pdf_array *)*Encoding, (uint64_t)i, o);
1578
913k
                    pdfi_countdown(o);
1579
913k
                }
1580
3.56k
                if (code < 0) {
1581
0
                    pdfi_countdown(*Encoding);
1582
0
                    *Encoding = NULL;
1583
0
                    return code;
1584
0
                }
1585
3.56k
            }
1586
5.33k
            else {
1587
5.33k
                code = pdfi_dict_get(ctx, (pdf_dict *)pdf_Encoding, "BaseEncoding", (pdf_obj **)&n);
1588
5.33k
                if (code >= 0) {
1589
860
                    if (pdfi_encoding_name_to_index(n) < 0) {
1590
2
                        pdfi_set_warning(ctx, 0, NULL, W_PDF_INVALID_FONT_BASEENC, "pdfi_create_Encoding", NULL);
1591
2
                        pdfi_countdown(n);
1592
2
                        n = NULL;
1593
2
                        code = gs_error_undefined;
1594
2
                    }
1595
858
                    else if (pdfi_name_is(n, "StandardEncoding") == true) {
1596
0
                        pdfi_set_warning(ctx, 0, NULL, W_PDF_INVALID_FONT_BASEENC, "pdfi_create_Encoding", NULL);
1597
0
                    }
1598
860
                }
1599
1600
5.33k
                if (code < 0) {
1601
4.47k
                    code = pdfi_name_alloc(ctx, (byte *)"StandardEncoding", 16, (pdf_obj **)&n);
1602
4.47k
                    if (code < 0) {
1603
0
                        pdfi_countdown(*Encoding);
1604
0
                        *Encoding = NULL;
1605
0
                        return code;
1606
0
                    }
1607
4.47k
                    pdfi_countup(n);
1608
4.47k
                }
1609
1610
5.33k
                code = pdfi_build_Encoding(ctx, n, (pdf_array *)*Encoding);
1611
5.33k
                if (code < 0) {
1612
0
                    pdfi_countdown(*Encoding);
1613
0
                    *Encoding = NULL;
1614
0
                    pdfi_countdown(n);
1615
0
                    return code;
1616
0
                }
1617
5.33k
                pdfi_countdown(n);
1618
5.33k
            }
1619
8.90k
            code = pdfi_dict_knownget_type(ctx, (pdf_dict *)pdf_Encoding, "Differences", PDF_ARRAY, (pdf_obj **)&a);
1620
8.90k
            if (code <= 0) {
1621
100
                if (code < 0) {
1622
0
                    pdfi_countdown(*Encoding);
1623
0
                    *Encoding = NULL;
1624
0
                }
1625
100
                return code;
1626
100
            }
1627
1628
1.01M
            for (i=0;i < pdfi_array_size(a);i++) {
1629
1.00M
                pdf_obj_type type;
1630
1.00M
                code = pdfi_array_get(ctx, a, (uint64_t)i, &o);
1631
1.00M
                if (code < 0)
1632
0
                    break;
1633
1.00M
                type = pdfi_type_of(o);
1634
1.00M
                if (type == PDF_NAME) {
1635
923k
                    if (offset < pdfi_array_size((pdf_array *)*Encoding))
1636
922k
                        code = pdfi_array_put(ctx, (pdf_array *)*Encoding, (uint64_t)offset, o);
1637
923k
                    pdfi_countdown(o);
1638
923k
                    offset++;
1639
923k
                    if (code < 0)
1640
0
                        break;
1641
923k
                } else if (type == PDF_INT) {
1642
82.4k
                    offset = ((pdf_num *)o)->value.i;
1643
82.4k
                    pdfi_countdown(o);
1644
82.4k
                } else {
1645
11
                    code = gs_note_error(gs_error_typecheck);
1646
11
                    pdfi_countdown(o);
1647
11
                    break;
1648
11
                }
1649
1.00M
            }
1650
8.80k
            pdfi_countdown(a);
1651
8.80k
            if (code < 0) {
1652
11
                pdfi_countdown(*Encoding);
1653
11
                *Encoding = NULL;
1654
11
                return code;
1655
11
            }
1656
8.78k
            break;
1657
8.80k
        }
1658
8.78k
        default:
1659
24
            pdfi_countdown(*Encoding);
1660
24
            *Encoding = NULL;
1661
24
            return gs_note_error(gs_error_typecheck);
1662
62.5k
    }
1663
62.2k
    return 0;
1664
62.5k
}
1665
1666
gs_glyph pdfi_encode_char(gs_font * pfont, gs_char chr, gs_glyph_space_t not_used)
1667
36.8M
{
1668
36.8M
    int code;
1669
36.8M
    unsigned int nindex = 0;
1670
36.8M
    gs_glyph g = GS_NO_GLYPH;
1671
1672
36.8M
    if (pfont->FontType == ft_encrypted || pfont->FontType == ft_encrypted2
1673
36.8M
     || pfont->FontType == ft_user_defined || pfont->FontType == ft_TrueType
1674
36.8M
     || pfont->FontType == ft_PDF_user_defined) {
1675
36.8M
        pdf_font *font = (pdf_font *)pfont->client_data;
1676
36.8M
        pdf_context *ctx = (pdf_context *)font->ctx;
1677
1678
36.8M
        if (font->Encoding != NULL) { /* safety */
1679
36.8M
            pdf_name *GlyphName = NULL;
1680
36.8M
            code = pdfi_array_get(ctx, font->Encoding, (uint64_t)chr, (pdf_obj **)&GlyphName);
1681
36.8M
            if (code >= 0) {
1682
36.8M
                if (pdfi_type_of(GlyphName) != PDF_NAME)
1683
                    /* Can't signal an error, just return the 'not found' case */
1684
0
                    return g;
1685
1686
36.8M
                code = (*ctx->get_glyph_index)(pfont, (byte *)GlyphName->data, GlyphName->length, &nindex);
1687
36.8M
                pdfi_countdown(GlyphName);
1688
36.8M
                if (code >= 0)
1689
36.8M
                    g = (gs_glyph)nindex;
1690
36.8M
            }
1691
36.8M
        }
1692
36.8M
    }
1693
1694
36.8M
    return g;
1695
36.8M
}
1696
1697
int pdfi_tounicode_char_to_unicode(pdf_context *ctx, pdf_cmap *tounicode, gs_glyph glyph, int ch, ushort *unicode_return, unsigned int length)
1698
418k
{
1699
418k
    int i, l = 0;
1700
418k
    int code = gs_error_undefined;
1701
418k
    unsigned char *ucode = (unsigned char *)unicode_return;
1702
1703
418k
    if (tounicode != NULL) {
1704
120k
        gs_cmap_lookups_enum_t lenum;
1705
120k
        gs_cmap_lookups_enum_init((const gs_cmap_t *)tounicode->gscmap, 0, &lenum);
1706
41.2M
        while (l == 0 && gs_cmap_enum_next_lookup(ctx->memory, &lenum) == 0) {
1707
41.0M
            gs_cmap_lookups_enum_t counter = lenum;
1708
82.1M
            while (l == 0 && gs_cmap_enum_next_entry(&counter) == 0) {
1709
41.0M
                if (counter.entry.value_type == CODE_VALUE_CID) {
1710
41.0M
                    unsigned int v = 0;
1711
122M
                    for (i = 0; i < counter.entry.key_size; i++) {
1712
81.5M
                        v |= (counter.entry.key[0][counter.entry.key_size - i - 1]) << (i * 8);
1713
81.5M
                    }
1714
41.0M
                    if (ch == v) {
1715
111k
                        if (counter.entry.value.size == 1) {
1716
0
                            l = 2;
1717
0
                            if (ucode != NULL && length >= l) {
1718
0
                                ucode[0] = counter.entry.value.data[0];
1719
0
                                ucode[1] = counter.entry.value.data[1];
1720
0
                            }
1721
0
                        }
1722
111k
                        else if (counter.entry.value.size == 2) {
1723
111k
                            l = 2;
1724
111k
                            if (ucode != NULL && length >= l) {
1725
79.1k
                                ucode[0] = counter.entry.value.data[0];
1726
79.1k
                                ucode[1] = counter.entry.value.data[1];
1727
79.1k
                            }
1728
111k
                        }
1729
484
                        else if (counter.entry.value.size == 3) {
1730
8
                            l = 4;
1731
8
                            if (ucode != NULL && length >= l) {
1732
4
                                ucode[0] = counter.entry.value.data[0];
1733
4
                                ucode[1] = counter.entry.value.data[1];
1734
4
                                ucode[2] = counter.entry.value.data[2];
1735
4
                                ucode[3] = 0;
1736
4
                            }
1737
8
                        }
1738
476
                        else {
1739
476
                            l = 4;
1740
476
                            if (ucode != NULL && length >= l) {
1741
444
                                ucode[0] = counter.entry.value.data[0];
1742
444
                                ucode[1] = counter.entry.value.data[1];
1743
444
                                ucode[2] = counter.entry.value.data[1];
1744
444
                                ucode[3] = counter.entry.value.data[3];
1745
444
                            }
1746
476
                        }
1747
111k
                    }
1748
41.0M
                }
1749
41.0M
            }
1750
41.0M
        }
1751
120k
        if (l > 0)
1752
111k
            code = l;
1753
120k
    }
1754
1755
418k
    return code;
1756
418k
}
1757
1758
/* Get the unicode valude for a glyph FIXME - not written yet
1759
 */
1760
int pdfi_decode_glyph(gs_font * font, gs_glyph glyph, int ch, ushort *unicode_return, unsigned int length)
1761
310k
{
1762
310k
    pdf_font *pdffont = (pdf_font *)font->client_data;
1763
310k
    int code = 0;
1764
1765
310k
    if (pdffont->pdfi_font_type != e_pdf_cidfont_type0 && pdffont->pdfi_font_type != e_pdf_cidfont_type1
1766
310k
     && pdffont->pdfi_font_type != e_pdf_cidfont_type2 && pdffont->pdfi_font_type != e_pdf_cidfont_type4) {
1767
284k
        code = pdfi_tounicode_char_to_unicode(pdffont->ctx, (pdf_cmap *)pdffont->ToUnicode, glyph, ch, unicode_return, length);
1768
284k
    }
1769
310k
    if (code < 0) code = 0;
1770
1771
310k
    return code;
1772
310k
}
1773
1774
int pdfi_glyph_index(gs_font *pfont, byte *str, uint size, uint *glyph)
1775
0
{
1776
0
    int code = 0;
1777
0
    pdf_font *font = (pdf_font *)pfont->client_data;
1778
1779
0
    code = pdfi_get_name_index(font->ctx, (char *)str, size, glyph);
1780
1781
0
    return code;
1782
0
}
1783
1784
int pdfi_glyph_name(gs_font * pfont, gs_glyph glyph, gs_const_string * pstr)
1785
0
{
1786
0
    int code = gs_error_invalidfont;
1787
1788
0
    if (pfont->FontType == ft_encrypted || pfont->FontType == ft_encrypted2
1789
0
     || pfont->FontType == ft_user_defined || pfont->FontType == ft_TrueType
1790
0
     || pfont->FontType == ft_PDF_user_defined) {
1791
0
        pdf_font *font = (pdf_font *)pfont->client_data;
1792
1793
0
        code = pdfi_name_from_index(font->ctx, glyph, (unsigned char **)&pstr->data, &pstr->size);
1794
0
    }
1795
1796
0
    return code;
1797
0
}
1798
1799
1800
static int pdfi_global_glyph_code(const gs_font *pfont, gs_const_string *gstr, gs_glyph *pglyph)
1801
7
{
1802
7
    int code = 0;
1803
7
    if (pfont->FontType == ft_encrypted) {
1804
0
        code = pdfi_t1_global_glyph_code(pfont, gstr, pglyph);
1805
0
    }
1806
7
    else if (pfont->FontType == ft_encrypted2) {
1807
7
        code = pdfi_cff_global_glyph_code(pfont, gstr, pglyph);
1808
7
    }
1809
0
    else {
1810
0
        code = gs_note_error(gs_error_invalidaccess);
1811
0
    }
1812
7
    return code;
1813
7
}
1814
1815
int pdfi_map_glyph_name_via_agl(pdf_dict *cstrings, pdf_name *gname, pdf_string **cstring)
1816
128k
{
1817
128k
    single_glyph_list_t *sgl = (single_glyph_list_t *)&(SingleGlyphList);
1818
128k
    int i, code, ucode = gs_error_undefined;
1819
128k
    *cstring = NULL;
1820
1821
128k
    if (gname->length == 7 && strncmp((char *)gname->data, "uni", 3) == 0) {
1822
384
        char u[5] = {0};
1823
384
        memcpy(u, gname->data + 3, 4);
1824
384
        code = sscanf(u, "%x", &ucode);
1825
384
        if (code <= 0)
1826
0
            ucode = gs_error_undefined;
1827
384
    }
1828
1829
128k
    if (ucode == gs_error_undefined) {
1830
463M
        for (i = 0; sgl[i].Glyph != 0x00; i++) {
1831
463M
            if (sgl[i].Glyph[0] == gname->data[0]
1832
463M
                && strlen(sgl[i].Glyph) == gname->length
1833
463M
                && !strncmp((char *)sgl[i].Glyph, (char *)gname->data, gname->length)) {
1834
54.1k
                ucode = (int)sgl[i].Unicode;
1835
54.1k
                break;
1836
54.1k
            }
1837
463M
        }
1838
128k
    }
1839
128k
    if (ucode > 0) {
1840
228M
        for (i = 0; sgl[i].Glyph != 0x00; i++) {
1841
228M
            if (sgl[i].Unicode == (unsigned short)ucode) {
1842
54.8k
                pdf_string *s;
1843
54.8k
                code = pdfi_dict_get((pdf_context *)cstrings->ctx, cstrings, (char *)sgl[i].Glyph, (pdf_obj **)&s);
1844
54.8k
                if (code >= 0) {
1845
334
                    *cstring = s;
1846
334
                    break;
1847
334
                }
1848
54.8k
            }
1849
228M
        }
1850
54.5k
        if (*cstring == NULL) {
1851
54.2k
            char u[16] = {0};
1852
54.2k
            code = gs_snprintf(u, 16, "uni%04x", ucode);
1853
54.2k
            if (code > 0) {
1854
54.2k
                pdf_string *s;
1855
54.2k
                code = pdfi_dict_get((pdf_context *)cstrings->ctx, cstrings, u, (pdf_obj **)&s);
1856
54.2k
                if (code >= 0) {
1857
0
                    *cstring = s;
1858
0
                }
1859
54.2k
            }
1860
54.2k
        }
1861
54.5k
    }
1862
1863
128k
    if (*cstring == NULL)
1864
128k
        code = gs_note_error(gs_error_undefined);
1865
334
    else
1866
334
        code = 0;
1867
1868
128k
    return code;
1869
128k
}
1870
1871
int pdfi_init_font_directory(pdf_context *ctx)
1872
40.8k
{
1873
40.8k
    ctx->font_dir = gs_font_dir_alloc2(ctx->memory, ctx->memory);
1874
40.8k
    if (ctx->font_dir == NULL) {
1875
0
        return_error(gs_error_VMerror);
1876
0
    }
1877
40.8k
    ctx->font_dir->global_glyph_code = pdfi_global_glyph_code;
1878
40.8k
    return 0;
1879
40.8k
}
1880
1881
/* Loads a (should be!) non-embedded font by name
1882
   Only currently works for Type 1 fonts set.
1883
 */
1884
int pdfi_load_font_by_name_string(pdf_context *ctx, const byte *fontname, size_t length,
1885
                                  pdf_obj **ppdffont)
1886
143k
{
1887
143k
    pdf_obj *fname = NULL;
1888
143k
    pdf_obj *fontobjtype = NULL;
1889
143k
    pdf_dict *fdict = NULL;
1890
143k
    int code;
1891
143k
    gs_font *pgsfont = NULL;
1892
143k
    const char *fs = "Font";
1893
1894
143k
    code = pdfi_name_alloc(ctx, (byte *)fontname, length, &fname);
1895
143k
    if (code < 0)
1896
0
        return code;
1897
143k
    pdfi_countup(fname);
1898
1899
143k
    code = pdfi_name_alloc(ctx, (byte *)fs, strlen(fs), &fontobjtype);
1900
143k
    if (code < 0)
1901
0
        goto exit;
1902
143k
    pdfi_countup(fontobjtype);
1903
1904
143k
    code = pdfi_dict_alloc(ctx, 1, &fdict);
1905
143k
    if (code < 0)
1906
0
        goto exit;
1907
143k
    pdfi_countup(fdict);
1908
1909
143k
    code = pdfi_dict_put(ctx, fdict, "BaseFont", fname);
1910
143k
    if (code < 0)
1911
0
        goto exit;
1912
1913
143k
    code = pdfi_dict_put(ctx, fdict, "Type", fontobjtype);
1914
143k
    if (code < 0)
1915
0
        goto exit;
1916
1917
143k
    code = pdfi_load_font(ctx, NULL, NULL, fdict, &pgsfont, false);
1918
143k
    if (code < 0)
1919
422
        goto exit;
1920
1921
142k
    *ppdffont = (pdf_obj *)pgsfont->client_data;
1922
1923
143k
 exit:
1924
143k
    pdfi_countdown(fontobjtype);
1925
143k
    pdfi_countdown(fname);
1926
143k
    pdfi_countdown(fdict);
1927
143k
    return code;
1928
142k
}
1929
1930
1931
int pdfi_font_create_widths(pdf_context *ctx, pdf_dict *fontdict, pdf_font *font, double scale)
1932
188k
{
1933
188k
    int code = 0;
1934
188k
    pdf_obj *obj = NULL;
1935
188k
    int i;
1936
1937
188k
    font->Widths = NULL;
1938
1939
188k
    if (font->FontDescriptor != NULL) {
1940
35.9k
        code = pdfi_dict_knownget(ctx, font->FontDescriptor, "MissingWidth", &obj);
1941
35.9k
        if (code > 0) {
1942
1.30k
            if (pdfi_type_of(obj) == PDF_INT) {
1943
1.30k
                font->MissingWidth = ((pdf_num *) obj)->value.i * scale;
1944
1.30k
            }
1945
0
            else if (pdfi_type_of(obj) == PDF_REAL) {
1946
0
                font->MissingWidth = ((pdf_num *) obj)->value.d  * scale;
1947
0
            }
1948
0
            else {
1949
0
                font->MissingWidth = 0;
1950
0
            }
1951
1.30k
            pdfi_countdown(obj);
1952
1.30k
            obj = NULL;
1953
1.30k
        }
1954
34.6k
        else {
1955
34.6k
            font->MissingWidth = 0;
1956
34.6k
        }
1957
35.9k
    }
1958
152k
    else {
1959
152k
        font->MissingWidth = 1000.0 * scale;
1960
152k
    }
1961
1962
188k
    code = pdfi_dict_knownget_type(ctx, fontdict, "Widths", PDF_ARRAY, (pdf_obj **)&obj);
1963
188k
    if (code > 0) {
1964
37.0k
        if (pdfi_array_size((pdf_array *)obj) < font->LastChar - font->FirstChar + 1) {
1965
531
            code = gs_note_error(gs_error_rangecheck);
1966
531
            goto error;
1967
531
        }
1968
1969
36.5k
        font->Widths = (double *)gs_alloc_bytes(OBJ_MEMORY(font), sizeof(double) * (font->LastChar - font->FirstChar + 1), "pdfi_font_create_widths(Widths)");
1970
36.5k
        if (font->Widths == NULL) {
1971
0
            code = gs_note_error(gs_error_VMerror);
1972
0
            goto error;
1973
0
        }
1974
36.5k
        memset(font->Widths, 0x00, sizeof(double) * (font->LastChar - font->FirstChar + 1));
1975
4.24M
        for (i = 0; i < (font->LastChar - font->FirstChar + 1); i++) {
1976
4.20M
            code = pdfi_array_get_number(ctx, (pdf_array *)obj, (uint64_t)i, &font->Widths[i]);
1977
4.20M
            if (code < 0)
1978
60
                goto error;
1979
4.20M
            font->Widths[i] *= scale;
1980
4.20M
        }
1981
36.5k
    }
1982
188k
error:
1983
188k
    pdfi_countdown(obj);
1984
188k
    if (code < 0) {
1985
1.42k
        gs_free_object(OBJ_MEMORY(font), font->Widths, "pdfi_font_create_widths(Widths)");
1986
1.42k
        font->Widths = NULL;
1987
1.42k
    }
1988
188k
    return code;
1989
188k
}
1990
1991
void pdfi_font_set_first_last_char(pdf_context *ctx, pdf_dict *fontdict, pdf_font *font)
1992
208k
{
1993
208k
    double f, l;
1994
208k
    int code;
1995
1996
208k
    if (fontdict == NULL) {
1997
20.3k
        f = (double)0;
1998
20.3k
        l = (double)255;
1999
20.3k
    }
2000
188k
    else {
2001
188k
        code = pdfi_dict_get_number(ctx, fontdict, "FirstChar", &f);
2002
188k
        if (code < 0 || f < 0 || f > 255)
2003
150k
            f = (double)0;
2004
2005
188k
        code = pdfi_dict_get_number(ctx, fontdict, "LastChar", &l);
2006
188k
        if (code < 0 || l < 0 || l > 255)
2007
150k
            l = (double)255;
2008
188k
    }
2009
208k
    if (f <= l) {
2010
208k
        font->FirstChar = f;
2011
208k
        font->LastChar = l;
2012
208k
    }
2013
12
    else {
2014
12
        font->FirstChar = 0;
2015
12
        font->LastChar = 255;
2016
12
    }
2017
208k
}
2018
2019
/* Patch or create a new XUID based on the existing UID/XUID, a simple hash
2020
   of the input file name and the font dictionary object number.
2021
   This allows improved glyph cache efficiency, also ensures pdfwrite understands
2022
   which fonts are repetitions, and which are different.
2023
   Currently cannot return an error - if we can't allocate the new XUID values array,
2024
   we just skip it, and assume the font is compliant.
2025
 */
2026
int pdfi_font_generate_pseudo_XUID(pdf_context *ctx, pdf_dict *fontdict, gs_font_base *pfont)
2027
208k
{
2028
208k
    gs_const_string fn;
2029
208k
    int i;
2030
208k
    uint32_t hash = 0;
2031
208k
    long *xvalues;
2032
208k
    int xuidlen = 3;
2033
2034
208k
    sfilename(ctx->main_stream->s, &fn);
2035
208k
    if (fn.size > 0 && fontdict!= NULL && fontdict->object_num != 0) {
2036
0
        for (i = 0; i < fn.size; i++) {
2037
0
            hash = ((((hash & 0xf8000000) >> 27) ^ (hash << 5)) & 0x7ffffffff) ^ fn.data[i];
2038
0
        }
2039
0
        hash = ((((hash & 0xf8000000) >> 27) ^ (hash << 5)) & 0x7ffffffff) ^ fontdict->object_num;
2040
0
        if (uid_is_XUID(&pfont->UID))
2041
0
            xuidlen += uid_XUID_size(&pfont->UID);
2042
0
        else if (uid_is_valid(&pfont->UID))
2043
0
            xuidlen++;
2044
2045
0
        xvalues = (long *)gs_alloc_bytes(pfont->memory, xuidlen * sizeof(long), "pdfi_font_generate_pseudo_XUID");
2046
0
        if (xvalues == NULL) {
2047
0
            return 0;
2048
0
        }
2049
0
        xvalues[0] = 1000000; /* "Private" value */
2050
0
        xvalues[1] = hash;
2051
2052
0
        xvalues[2] = ctx->device_state.HighLevelDevice ? pfont->id : 0;
2053
2054
0
        if (uid_is_XUID(&pfont->UID)) {
2055
0
            for (i = 0; i < uid_XUID_size(&pfont->UID); i++) {
2056
0
                xvalues[i + 3] = uid_XUID_values(&pfont->UID)[i];
2057
0
            }
2058
0
            uid_free(&pfont->UID, pfont->memory, "pdfi_font_generate_pseudo_XUID");
2059
0
        }
2060
0
        else if (uid_is_valid(&pfont->UID))
2061
0
            xvalues[3] = pfont->UID.id;
2062
2063
0
        uid_set_XUID(&pfont->UID, xvalues, xuidlen);
2064
0
    }
2065
208k
    return 0;
2066
208k
}
2067
2068
/* Convenience function for using fonts created by
2069
   pdfi_load_font_by_name_string
2070
 */
2071
int pdfi_set_font_internal(pdf_context *ctx, pdf_obj *fontobj, double point_size)
2072
142k
{
2073
142k
    int code;
2074
142k
    pdf_font *pdffont = (pdf_font *)fontobj;
2075
2076
142k
    if (pdfi_type_of(pdffont) != PDF_FONT || pdffont->pfont == NULL)
2077
0
        return_error(gs_error_invalidfont);
2078
2079
142k
    code = gs_setPDFfontsize(ctx->pgs, point_size);
2080
142k
    if (code < 0)
2081
0
        return code;
2082
2083
142k
    return pdfi_gs_setfont(ctx, (gs_font *)pdffont->pfont);
2084
142k
}
2085
2086
/* Convenience function for setting font by name
2087
 * Keeps one ref to the font, which will be in the graphics state font ->client_data
2088
 */
2089
static int pdfi_font_set_internal_inner(pdf_context *ctx, const byte *fontname, size_t length,
2090
                                        double point_size)
2091
143k
{
2092
143k
    int code = 0;
2093
143k
    pdf_obj *font = NULL;
2094
2095
2096
143k
    code = pdfi_load_font_by_name_string(ctx, fontname, length, &font);
2097
143k
    if (code < 0) goto exit;
2098
2099
142k
    code = pdfi_set_font_internal(ctx, font, point_size);
2100
2101
143k
 exit:
2102
143k
    pdfi_countdown(font);
2103
143k
    return code;
2104
142k
}
2105
2106
int pdfi_font_set_internal_string(pdf_context *ctx, const char *fontname, double point_size)
2107
4.80k
{
2108
4.80k
    return pdfi_font_set_internal_inner(ctx, (const byte *)fontname, strlen(fontname), point_size);
2109
4.80k
}
2110
2111
int pdfi_font_set_internal_name(pdf_context *ctx, pdf_name *fontname, double point_size)
2112
138k
{
2113
138k
    if (pdfi_type_of(fontname) != PDF_NAME)
2114
0
        return_error(gs_error_typecheck);
2115
138k
    else
2116
138k
        return pdfi_font_set_internal_inner(ctx, fontname->data, fontname->length, point_size);
2117
138k
}