Coverage Report

Created: 2022-10-31 07:00

/src/ghostpdl/psi/zbfont.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2001-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
17
/* Font creation utilities */
18
#include "memory_.h"
19
#include "string_.h"
20
#include "ghost.h"
21
#include "oper.h"
22
#include "gxfixed.h"
23
#include "gscencs.h"
24
#include "gsmatrix.h"
25
#include "gxdevice.h"
26
#include "gxfont.h"
27
#include "bfont.h"
28
#include "ialloc.h"
29
#include "idict.h"
30
#include "idparam.h"
31
#include "ilevel.h"
32
#include "iname.h"
33
#include "inamedef.h"   /* for inlining name_index */
34
#include "interp.h"   /* for initial_enter_name */
35
#include "ipacked.h"
36
#include "istruct.h"
37
#include "store.h"
38
#include "gsstate.h" /* for gs_currentcpsimode() */
39
/* Structure descriptor and GC procedures for font_data */
40
public_st_font_data();
41
static
42
CLEAR_MARKS_PROC(font_data_clear_marks)
43
244k
{
44
244k
    ref_struct_clear_marks(cmem, vptr, offset_of(font_data, u.type42.mru_sfnts_index)/*size*/, pstype);
45
244k
}
46
static
47
ENUM_PTRS_BEGIN_PROC(font_data_enum_ptrs)
48
2.36M
{
49
2.36M
    return ref_struct_enum_ptrs(mem, vptr, offset_of(font_data, u.type42.mru_sfnts_index)/*size*/, index, pep, pstype, gcst);
50
2.36M
}
51
ENUM_PTRS_END_PROC
52
static
53
236k
RELOC_PTRS_BEGIN(font_data_reloc_ptrs)
54
236k
{
55
236k
    ref_struct_reloc_ptrs(vptr, offset_of(font_data, u.type42.mru_sfnts_index)/*size*/, pstype, gcst);
56
236k
}
57
236k
RELOC_PTRS_END
58
59
/* <string|name> <font_dict> .buildfont3 <string|name> <font> */
60
/* Build a type 3 (user-defined) font. */
61
static int
62
zbuildfont3(i_ctx_t *i_ctx_p)
63
89.4k
{
64
89.4k
    os_ptr op = osp;
65
89.4k
    int code;
66
89.4k
    build_proc_refs build;
67
89.4k
    gs_font_base *pfont;
68
69
89.4k
    check_type(*op, t_dictionary);
70
89.4k
    code = build_gs_font_procs(op, &build);
71
89.4k
    if (code < 0)
72
4
        return code;
73
89.4k
    code = build_gs_simple_font(i_ctx_p, op, &pfont, ft_user_defined,
74
89.4k
                                &st_gs_font_base, &build, bf_options_none);
75
89.4k
    if (code < 0)
76
4
        return code;
77
89.4k
    return define_gs_font(i_ctx_p, (gs_font *) pfont);
78
89.4k
}
79
80
/* Encode a character. */
81
gs_glyph
82
zfont_encode_char(gs_font *pfont, gs_char chr, gs_glyph_space_t gspace)
83
9.90M
{
84
9.90M
    font_data *pdata = pfont_data(pfont);
85
9.90M
    const ref *pencoding = &pdata->Encoding;
86
9.90M
    ulong index = chr;  /* work around VAX widening bug */
87
9.90M
    ref cname;
88
9.90M
    int code = array_get(pfont->memory, pencoding, (long)index, &cname);
89
90
9.90M
    if (code < 0 || !r_has_type(&cname, t_name))
91
1
        return GS_NO_GLYPH;
92
9.90M
    if (pfont->FontType == ft_user_defined && r_type(&pdata->BuildGlyph) == t_null) {
93
652k
        ref nsref, tname;
94
95
652k
        name_string_ref(pfont->memory, &cname, &nsref);
96
652k
        if (r_size(&nsref) == 7 &&
97
652k
            !memcmp(nsref.value.const_bytes, ".notdef", r_size(&nsref))) {
98
            /* A special support for high level devices.
99
               They need a glyph name but the font doesn't provide one
100
               due to an instandard BuildChar.
101
               Such fonts don't conform to PLRM section 5.3.7,
102
               but we've got real examples that we want to handle (Bug 686982).
103
               Construct a name here.
104
               Low level devices don't pass here, because regular PS interpretation
105
               doesn't need such names.
106
            */
107
44.2k
            char buf[20];
108
44.2k
            int code;
109
110
44.2k
            if (gspace == GLYPH_SPACE_NOGEN)
111
0
                return GS_NO_GLYPH;
112
44.2k
            gs_snprintf(buf, sizeof(buf), "j%ld", chr); /* 'j' is arbutrary. */
113
44.2k
            code = name_ref(pfont->memory, (const byte *)buf, strlen(buf), &tname, 1);
114
44.2k
            if (code < 0) {
115
                /* Can't propagate the error due to interface limitation,
116
                   return with .notdef */
117
0
            } else
118
44.2k
                cname = tname;
119
44.2k
        }
120
652k
    }
121
9.90M
    return (gs_glyph)name_index(pfont->memory, &cname);
122
9.90M
}
123
124
/* Get the name of a glyph. */
125
static int
126
zfont_glyph_name(gs_font *font, gs_glyph index, gs_const_string *pstr)
127
51.4M
{
128
51.4M
    ref nref, sref;
129
130
51.4M
    if (index >= GS_MIN_CID_GLYPH) { /* Fabricate a numeric name. */
131
202
        char cid_name[sizeof(gs_glyph) * 3 + 1];
132
202
        int code;
133
134
202
        gs_snprintf(cid_name, sizeof(cid_name), "%lu", (ulong) index);
135
202
        code = name_ref(font->memory, (const byte *)cid_name, strlen(cid_name),
136
202
                        &nref, 1);
137
202
        if (code < 0)
138
0
            return code;
139
51.4M
    } else {
140
51.4M
        name_index_ref(font->memory, index, &nref);
141
51.4M
        if (nref.value.pname == NULL)
142
0
            return_error(gs_error_unknownerror);
143
51.4M
    }
144
51.4M
    name_string_ref(font->memory, &nref, &sref);
145
51.4M
    pstr->data = sref.value.const_bytes;
146
51.4M
    pstr->size = r_size(&sref);
147
51.4M
    return 0;
148
51.4M
}
149
150
void get_zfont_glyph_name( int (**proc)(gs_font *font, gs_glyph glyph, gs_const_string *pstr) )
151
40.8k
{
152
40.8k
    *proc = zfont_glyph_name;
153
40.8k
}
154
155
static gs_char
156
gs_font_map_glyph_by_dict(const gs_memory_t *mem, const ref *map, gs_glyph glyph, ushort *u, unsigned int length)
157
13.1k
{
158
13.1k
    ref *v, n;
159
13.1k
    uchar *unicode_return = (uchar *)u;
160
13.1k
    if (glyph >= GS_MIN_CID_GLYPH) {
161
0
        uint cid = glyph - GS_MIN_CID_GLYPH;
162
163
0
        if (dict_find_string(map, "CIDCount", &v) > 0) {
164
            /* This is a CIDDEcoding resource. */
165
0
            make_int(&n, cid / 256);
166
0
            if (dict_find(map, &n, &v) > 0) {
167
0
                ref vv;
168
169
0
                if (array_get(mem, v, cid % 256, &vv) == 0 && r_type(&vv) == t_integer) {
170
0
                    if (v->value.intval > 65535) {
171
0
                        if (length < 4)
172
0
                            return 4;
173
0
                        unicode_return[0] = v->value.intval >> 24;
174
0
                        unicode_return[1] = (v->value.intval & 0x00FF0000) >> 16;
175
0
                        unicode_return[2] = (v->value.intval & 0x0000FF00) >> 8;
176
0
                        unicode_return[3] = v->value.intval & 0xFF;
177
0
                        return 4;
178
0
                    } else {
179
0
                        if (length < 2)
180
0
                            return 2;
181
0
                        unicode_return[0] = v->value.intval >> 8;
182
0
                        unicode_return[1] = v->value.intval & 0xFF;
183
0
                        return 2;
184
0
                    }
185
0
                }
186
0
            }
187
0
            return 0; /* Absent in the map. */
188
0
        }
189
        /* This is GlyphNames2Unicode dictionary. */
190
0
        make_int(&n, cid);
191
0
    } else
192
13.1k
        name_index_ref(mem, glyph, &n);
193
13.1k
     if (dict_find(map, &n, &v) > 0) {
194
12.9k
        if (r_has_type(v, t_string)) {
195
0
            int l = r_size(v);
196
197
0
            if (length < l)
198
0
                return l;
199
0
            memcpy(unicode_return, v->value.const_bytes, l);
200
0
            return l;
201
0
        }
202
12.9k
        if (r_type(v) == t_integer) {
203
12.9k
            if (v->value.intval > 65535) {
204
0
                if (length < 4)
205
0
                    return 4;
206
0
                unicode_return[0] = v->value.intval >> 24;
207
0
                unicode_return[1] = (v->value.intval & 0x00FF0000) >> 16;
208
0
                unicode_return[2] = (v->value.intval & 0x0000FF00) >> 8;
209
0
                unicode_return[3] = v->value.intval & 0xFF;
210
0
                return 4;
211
12.9k
            } else {
212
12.9k
                if (length < 2)
213
6.45k
                    return 2;
214
6.45k
                unicode_return[0] = v->value.intval >> 8;
215
6.45k
                unicode_return[1] = v->value.intval & 0xFF;
216
6.45k
                return 2;
217
12.9k
            }
218
12.9k
        }
219
12.9k
    }
220
201
    return 0; /* Absent in the map. */
221
13.1k
}
222
223
/* Get Unicode UTF-16 code for a glyph. */
224
int
225
gs_font_map_glyph_to_unicode(gs_font *font, gs_glyph glyph, int ch, ushort *u, unsigned int length)
226
25.4k
{
227
25.4k
    font_data *pdata = pfont_data(font);
228
25.4k
    const ref *UnicodeDecoding;
229
25.4k
    uchar *unicode_return = (uchar *)u;
230
231
25.4k
    if (r_type(&pdata->GlyphNames2Unicode) == t_dictionary) {
232
0
        int c = gs_font_map_glyph_by_dict(font->memory,
233
0
                                              &pdata->GlyphNames2Unicode, glyph, u, length);
234
235
0
        if (c != 0)
236
0
            return c;
237
0
        if (ch != -1) { /* -1 indicates a CIDFont */
238
            /* Its possible that we have a GlyphNames2Unicode dictionary
239
             * which contains integers and Unicode values, rather than names
240
             * and Unicode values. This happens if the input was PDF, the font
241
             * has a ToUnicode Cmap, but no Encoding. In this case we need to
242
             * use the character code as an index into the dictionary. Try that
243
             * now before we fall back to the UnicodeDecoding.
244
             */
245
0
            ref *v, n;
246
247
0
            make_int(&n, ch);
248
0
            if (dict_find(&pdata->GlyphNames2Unicode, &n, &v) > 0) {
249
0
                if (r_has_type(v, t_string)) {
250
0
                    int l = r_size(v);
251
252
0
                    if (l > length)
253
0
                        return l;
254
255
0
                    memcpy(unicode_return, v->value.const_bytes, l * sizeof(short));
256
0
                    return l;
257
0
                }
258
0
                if (r_type(v) == t_integer) {
259
0
                    if (v->value.intval > 65535) {
260
0
                        if (length < 4)
261
0
                            return 4;
262
0
                        unicode_return[0] = v->value.intval >> 24;
263
0
                        unicode_return[1] = (v->value.intval & 0x00FF0000) >> 16;
264
0
                        unicode_return[2] = (v->value.intval & 0x0000FF00) >> 8;
265
0
                        unicode_return[3] = v->value.intval & 0xFF;
266
0
                        return 4;
267
0
                    } else {
268
0
                        if (length < 2)
269
0
                            return 2;
270
0
                        unicode_return[0] = v->value.intval >> 8;
271
0
                        unicode_return[1] = v->value.intval & 0xFF;
272
0
                        return 2;
273
0
                    }
274
0
                }
275
0
            }
276
0
        }
277
        /*
278
         * Fall through, because test.ps for SF bug #529103 requres
279
         * to examine both tables. Due to that the Unicode Decoding resource
280
         * can't be a default value for FontInfo.GlyphNames2Unicode .
281
         */
282
0
    }
283
25.4k
    if (glyph <= GS_MIN_CID_GLYPH && glyph != GS_NO_GLYPH) {
284
25.4k
        UnicodeDecoding = zfont_get_to_unicode_map(font->dir);
285
25.4k
        if (UnicodeDecoding != NULL && r_type(UnicodeDecoding) == t_dictionary)
286
13.1k
            return gs_font_map_glyph_by_dict(font->memory, UnicodeDecoding, glyph, u, length);
287
25.4k
    }
288
12.3k
    return 0; /* No map. */
289
25.4k
}
290
291
/* ------ Initialization procedure ------ */
292
293
const op_def zbfont_op_defs[] =
294
{
295
    {"2.buildfont3", zbuildfont3},
296
    op_def_end(0)
297
};
298
299
/* ------ Subroutines ------ */
300
301
/* Convert strings to executable names for build_proc_refs. */
302
int
303
build_proc_name_refs(const gs_memory_t *mem, build_proc_refs * pbuild,
304
                     const char *bcstr, const char *bgstr)
305
88.0k
{
306
88.0k
    int code;
307
308
88.0k
    if (!bcstr)
309
88.0k
        make_null(&pbuild->BuildChar);
310
88.0k
    else {
311
88.0k
        if ((code = name_ref(mem, (const byte *)bcstr,
312
88.0k
                             strlen(bcstr), &pbuild->BuildChar, 0)) < 0)
313
0
            return code;
314
88.0k
        r_set_attrs(&pbuild->BuildChar, a_executable);
315
88.0k
    }
316
88.0k
    if (!bgstr)
317
88.0k
        make_null(&pbuild->BuildGlyph);
318
88.0k
    else {
319
88.0k
        if ((code = name_ref(mem, (const byte *)bgstr,
320
88.0k
                             strlen(bgstr), &pbuild->BuildGlyph, 0)) < 0)
321
0
            return code;
322
88.0k
        r_set_attrs(&pbuild->BuildGlyph, a_executable);
323
88.0k
    }
324
88.0k
    return 0;
325
88.0k
}
326
327
/* Get the BuildChar and/or BuildGlyph routines from a (base) font. */
328
int
329
build_gs_font_procs(os_ptr op, build_proc_refs * pbuild)
330
89.4k
{
331
89.4k
    int ccode, gcode;
332
89.4k
    ref *pBuildChar;
333
89.4k
    ref *pBuildGlyph;
334
335
89.4k
    check_type(*op, t_dictionary);
336
89.4k
    ccode = dict_find_string(op, "BuildChar", &pBuildChar);
337
89.4k
    gcode = dict_find_string(op, "BuildGlyph", &pBuildGlyph);
338
89.4k
    if (ccode <= 0) {
339
4
        if (gcode <= 0)
340
4
            return_error(gs_error_invalidfont);
341
0
        make_null(&pbuild->BuildChar);
342
89.4k
    } else {
343
89.4k
        check_proc(*pBuildChar);
344
89.4k
        pbuild->BuildChar = *pBuildChar;
345
89.4k
    }
346
89.4k
    if (gcode <= 0)
347
89.4k
        make_null(&pbuild->BuildGlyph);
348
0
    else {
349
0
        check_proc(*pBuildGlyph);
350
0
        pbuild->BuildGlyph = *pBuildGlyph;
351
0
    }
352
89.4k
    return 0;
353
89.4k
}
354
355
static int font_with_same_UID_and_another_metrics(const gs_font *pfont0, const gs_font *pfont1)
356
4
{
357
4
    const gs_font_base *pbfont0 = (const gs_font_base *)pfont0;
358
4
    const gs_font_base *pbfont1 = (const gs_font_base *)pfont1;
359
360
4
    if (uid_equal(&pbfont0->UID, &pbfont1->UID)) {
361
4
        const ref *pfdict0 = &pfont_data(gs_font_parent(pbfont0))->dict;
362
4
        const ref *pfdict1 = &pfont_data(gs_font_parent(pbfont1))->dict;
363
4
        ref *pmdict0, *pmdict1;
364
365
4
        if (pbfont0->WMode || dict_find_string(pfdict0, "Metrics", &pmdict0) <= 0)
366
4
            pmdict0 = NULL;
367
4
        if (pbfont1->WMode || dict_find_string(pfdict1, "Metrics", &pmdict1) <= 0)
368
4
            pmdict1 = NULL;
369
4
        if (!pmdict0 != !pmdict1)
370
0
            return 1;
371
4
        if (pmdict0 != NULL && !obj_eq(pfont0->memory, pmdict0, pmdict1))
372
0
            return 1;
373
4
        if (!pbfont0->WMode || dict_find_string(pfdict0, "Metrics2", &pmdict0) <= 0)
374
4
            pmdict0 = NULL;
375
4
        if (!pbfont0->WMode || dict_find_string(pfdict1, "Metrics2", &pmdict1) <= 0)
376
4
            pmdict1 = NULL;
377
4
        if (!pmdict0 != !pmdict1)
378
0
            return 1;
379
4
        if (pmdict0 != NULL && !obj_eq(pfont0->memory, pmdict0, pmdict1))
380
0
            return 1;
381
4
    }
382
4
    return 0;
383
4
}
384
385
/* Do the common work for building a primitive font -- one whose execution */
386
/* algorithm is implemented in C (Type 1, Type 2, Type 4, or Type 42). */
387
/* The caller guarantees that *op is a dictionary. */
388
int
389
build_gs_primitive_font(i_ctx_t *i_ctx_p, os_ptr op, gs_font_base ** ppfont,
390
                        font_type ftype, gs_memory_type_ptr_t pstype,
391
                        const build_proc_refs * pbuild,
392
                        build_font_options_t options)
393
44.0k
{
394
44.0k
    ref *pcharstrings = 0;
395
44.0k
    ref CharStrings;
396
44.0k
    gs_font_base *pfont;
397
44.0k
    font_data *pdata;
398
44.0k
    int code;
399
400
44.0k
    if (dict_find_string(op, "CharStrings", &pcharstrings) <= 0) {
401
0
        if (!(options & bf_CharStrings_optional))
402
0
            return_error(gs_error_invalidfont);
403
44.0k
    } else {
404
44.0k
        ref *ignore;
405
406
44.0k
        if (!r_has_type(pcharstrings, t_dictionary))
407
0
            return_error(gs_error_invalidfont);
408
44.0k
        if ((options & bf_notdef_required) != 0 &&
409
44.0k
            dict_find_string(pcharstrings, ".notdef", &ignore) <= 0
410
44.0k
            )
411
0
            return_error(gs_error_invalidfont);
412
        /*
413
         * Since build_gs_simple_font may resize the dictionary and cause
414
         * pointers to become invalid, save CharStrings.
415
         */
416
44.0k
        CharStrings = *pcharstrings;
417
44.0k
    }
418
44.0k
    code = build_gs_outline_font(i_ctx_p, op, ppfont, ftype, pstype, pbuild,
419
44.0k
                                 options, build_gs_simple_font);
420
44.0k
    if (code != 0)
421
13
        return code;
422
44.0k
    pfont = *ppfont;
423
44.0k
    pdata = pfont_data(pfont);
424
44.0k
    if (pcharstrings)
425
44.0k
        ref_assign(&pdata->CharStrings, &CharStrings);
426
0
    else
427
44.0k
        make_null(&pdata->CharStrings);
428
    /* Check that the UniqueIDs match.  This is part of the */
429
    /* Adobe protection scheme, but we may as well emulate it. */
430
44.0k
    if (uid_is_valid(&pfont->UID) &&
431
44.0k
        !dict_check_uid_param(op, &pfont->UID)
432
44.0k
        )
433
0
        uid_set_invalid(&pfont->UID);
434
44.0k
    if (uid_is_valid(&pfont->UID)) {
435
5
        const gs_font *pfont0 = (const gs_font *)pfont;
436
437
5
        code = gs_font_find_similar(ifont_dir, &pfont0,
438
5
                       font_with_same_UID_and_another_metrics);
439
5
        if (code < 0)
440
0
            return code; /* Must not happen. */
441
5
        if (code)
442
0
            uid_set_invalid(&pfont->UID);
443
5
    }
444
44.0k
    return 0;
445
44.0k
}
446
447
/* Build a FDArray entry for a CIDFontType 0 font. */
448
/* Note that as of Adobe PostScript version 3011, this may be either */
449
/* a Type 1 or Type 2 font. */
450
static int
451
build_FDArray_sub_font(i_ctx_t *i_ctx_p, ref *op,
452
                       gs_font_base **ppfont,
453
                       font_type ftype, gs_memory_type_ptr_t pstype,
454
                       const build_proc_refs * pbuild,
455
                       build_font_options_t ignore_options)
456
0
{
457
0
    gs_font *pfont;
458
0
    int code = build_gs_sub_font(i_ctx_p, op, &pfont, ftype, pstype, pbuild,
459
0
                                 NULL, op);
460
461
0
    if (code >= 0)
462
0
        *ppfont = (gs_font_base *)pfont;
463
0
    return code;
464
0
}
465
int
466
build_gs_FDArray_font(i_ctx_t *i_ctx_p, ref *op,
467
                      gs_font_base **ppfont,
468
                      font_type ftype, gs_memory_type_ptr_t pstype,
469
                      const build_proc_refs * pbuild)
470
0
{
471
0
    gs_font_base *pfont;
472
0
    font_data *pdata;
473
0
    int code = build_gs_outline_font(i_ctx_p, op, &pfont, ftype, pstype,
474
0
                                     pbuild, bf_options_none,
475
0
                                     build_FDArray_sub_font);
476
0
    static const double bbox[4] = { 0, 0, 0, 0 };
477
0
    gs_uid uid;
478
479
0
    if (code < 0)
480
0
        return code;
481
0
    pdata = pfont_data(pfont);
482
    /* Fill in members normally set by build_gs_primitive_font. */
483
0
    make_null(&pdata->CharStrings);
484
    /* Fill in members normally set by build_gs_simple_font. */
485
0
    uid_set_invalid(&uid);
486
0
    init_gs_simple_font(pfont, bbox, &uid);
487
0
    pfont->encoding_index = ENCODING_INDEX_UNKNOWN;
488
0
    pfont->nearest_encoding_index = ENCODING_INDEX_UNKNOWN;
489
    /* Fill in members normally set by build_gs_font. */
490
0
    pfont->key_name = pfont->font_name;
491
0
    *ppfont = pfont;
492
0
    return 0;
493
0
}
494
495
/* Do the common work for building an outline font -- a non-composite font */
496
/* for which PaintType and StrokeWidth are meaningful. */
497
/* The caller guarantees that *op is a dictionary. */
498
int
499
build_gs_outline_font(i_ctx_t *i_ctx_p, os_ptr op, gs_font_base ** ppfont,
500
                      font_type ftype, gs_memory_type_ptr_t pstype,
501
                      const build_proc_refs * pbuild,
502
                      build_font_options_t options,
503
                      build_base_font_proc_t build_base_font)
504
44.0k
{
505
44.0k
    int painttype;
506
44.0k
    float strokewidth;
507
44.0k
    gs_font_base *pfont;
508
44.0k
    int code = dict_int_param(op, "PaintType", 0, 3, 0, &painttype);
509
510
44.0k
    if (code < 0)
511
0
        return code;
512
44.0k
    code = dict_float_param(op, "StrokeWidth", 0.0, &strokewidth);
513
44.0k
    if (code < 0)
514
0
        return code;
515
44.0k
    code = build_base_font(i_ctx_p, op, ppfont, ftype, pstype, pbuild,
516
44.0k
                           options);
517
44.0k
    if (code != 0)
518
13
        return code;
519
44.0k
    pfont = *ppfont;
520
44.0k
    pfont->PaintType = painttype;
521
44.0k
    pfont->StrokeWidth = strokewidth;
522
44.0k
    return 0;
523
44.0k
}
524
525
void
526
get_GlyphNames2Unicode(i_ctx_t *i_ctx_p, gs_font *pfont, ref *pdref)
527
133k
{
528
133k
    ref *pfontinfo = NULL, *g2u = NULL;
529
133k
    font_data *pdata;
530
531
133k
    if (dict_find_string(pdref, "FontInfo", &pfontinfo) <= 0 ||
532
133k
            !r_has_type(pfontinfo, t_dictionary) ||
533
133k
            dict_find_string(pfontinfo, "GlyphNames2Unicode", &g2u) <= 0 ||
534
133k
            !r_has_type(pfontinfo, t_dictionary))
535
133k
        return;
536
    /*
537
     * Since build_gs_font may resize the dictionary and cause
538
     * pointers to become invalid, save Glyph2Unicode
539
     */
540
0
    pdata = pfont_data(pfont);
541
0
    ref_assign_new(&pdata->GlyphNames2Unicode, g2u);
542
0
}
543
544
/* Do the common work for building a font of any non-composite FontType. */
545
/* The caller guarantees that *op is a dictionary. */
546
int
547
build_gs_simple_font(i_ctx_t *i_ctx_p, os_ptr op, gs_font_base ** ppfont,
548
                     font_type ftype, gs_memory_type_ptr_t pstype,
549
                     const build_proc_refs * pbuild,
550
                     build_font_options_t options)
551
133k
{
552
133k
    double bbox[4];
553
133k
    gs_uid uid;
554
133k
    int code;
555
133k
    gs_font_base *pfont;
556
133k
    uint space = ialloc_space(idmemory);
557
558
133k
    code = font_bbox_param(imemory, op, bbox);
559
133k
    if (code < 0)
560
0
        return code;
561
    /*
562
     * Make sure that we allocate uid
563
     * in the same VM as the font dictionary
564
     * (see build_gs_sub_font).
565
     */
566
133k
    ialloc_set_space(idmemory, r_space(op));
567
133k
    code = dict_uid_param(op, &uid, 0, imemory, i_ctx_p);
568
133k
    ialloc_set_space(idmemory, space);
569
133k
    if (code < 0)
570
0
        return code;
571
133k
    if ((options & bf_UniqueID_ignored) && uid_is_UniqueID(&uid))
572
0
        uid_set_invalid(&uid);
573
133k
    code = build_gs_font(i_ctx_p, op, (gs_font **) ppfont, ftype, pstype,
574
133k
                         pbuild, options);
575
133k
    if (code != 0)    /* invalid or scaled font */
576
115
        return code;
577
133k
    pfont = *ppfont;
578
133k
    pfont->procs.init_fstack = gs_default_init_fstack;
579
133k
    pfont->procs.define_font = gs_no_define_font;
580
133k
    pfont->procs.decode_glyph = gs_font_map_glyph_to_unicode;
581
133k
    pfont->procs.make_font = zbase_make_font;
582
133k
    pfont->procs.next_char_glyph = gs_default_next_char_glyph;
583
133k
    pfont->FAPI = 0;
584
133k
    pfont->FAPI_font_data = 0;
585
133k
    init_gs_simple_font(pfont, bbox, &uid);
586
133k
    lookup_gs_simple_font_encoding(pfont);
587
133k
    get_GlyphNames2Unicode(i_ctx_p, (gs_font *)pfont, op);
588
133k
    return 0;
589
133k
}
590
591
/* Initialize the FontBBox and UID of a non-composite font. */
592
void
593
init_gs_simple_font(gs_font_base *pfont, const double bbox[4],
594
                    const gs_uid *puid)
595
133k
{
596
133k
    pfont->FontBBox.p.x = bbox[0];
597
133k
    pfont->FontBBox.p.y = bbox[1];
598
133k
    pfont->FontBBox.q.x = bbox[2];
599
133k
    pfont->FontBBox.q.y = bbox[3];
600
133k
    pfont->UID = *puid;
601
133k
}
602
603
/* Compare the encoding of a simple font with the registered encodings. */
604
void
605
lookup_gs_simple_font_encoding(gs_font_base * pfont)
606
133k
{
607
133k
    const ref *pfe = &pfont_data(pfont)->Encoding;
608
133k
    int index = -1;
609
610
133k
    pfont->encoding_index = index;
611
133k
    if (r_type(pfe) == t_array && r_size(pfe) <= 256) {
612
        /* Look for an encoding that's "close". */
613
133k
        uint esize = r_size(pfe);
614
133k
        int near_index = -1;
615
133k
        uint best = esize / 3;  /* must match at least this many */
616
133k
        gs_const_string fstrs[256];
617
133k
        int i;
618
619
        /* Get the string names of the glyphs in the font's Encoding. */
620
34.2M
        for (i = 0; i < esize; ++i) {
621
34.1M
            ref fchar;
622
623
34.1M
            if (array_get(pfont->memory, pfe, (long)i, &fchar) < 0 ||
624
34.1M
                !r_has_type(&fchar, t_name)
625
34.1M
                )
626
882
                fstrs[i].data = 0, fstrs[i].size = 0;
627
34.1M
            else {
628
34.1M
                ref nsref;
629
630
34.1M
                name_string_ref(pfont->memory, &fchar, &nsref);
631
34.1M
                fstrs[i].data = nsref.value.const_bytes;
632
34.1M
                fstrs[i].size = r_size(&nsref);
633
34.1M
            }
634
34.1M
        }
635
        /* Compare them against the known encodings. */
636
134k
        for (index = 0; index < NUM_KNOWN_REAL_ENCODINGS; ++index) {
637
134k
            uint match = esize;
638
639
34.4M
            for (i = esize; --i >= 0;) {
640
34.2M
                gs_const_string rstr;
641
642
34.2M
                gs_c_glyph_name(gs_c_known_encode((gs_char)i, index), &rstr);
643
34.2M
                if (rstr.size == fstrs[i].size &&
644
34.2M
                    !memcmp(rstr.data, fstrs[i].data, rstr.size)
645
34.2M
                    )
646
34.1M
                    continue;
647
140k
                if (--match <= best)
648
826
                    break;
649
140k
            }
650
134k
            if (match > best) {
651
133k
                best = match;
652
133k
                near_index = index;
653
                /* If we have a perfect match, stop now. */
654
133k
                if (best == esize)
655
133k
                    break;
656
133k
            }
657
134k
        }
658
133k
        index = near_index;
659
133k
        if (best == esize)
660
133k
            pfont->encoding_index = index;
661
133k
    }
662
133k
    pfont->nearest_encoding_index = index;
663
133k
}
664
665
/* Get FontMatrix and FontName parameters. */
666
static int
667
sub_font_params(gs_memory_t *mem, const ref *op, gs_matrix *pmat, gs_matrix *pomat, ref *pfname)
668
133k
{
669
133k
    ref *pmatrix, *pfontname, *pfontstyle, *porigfont, *pfontinfo;
670
671
133k
    if (dict_find_string(op, "FontMatrix", &pmatrix) <= 0 ||
672
133k
        read_matrix(mem, pmatrix, pmat) < 0
673
133k
        )
674
4
        return_error(gs_error_invalidfont);
675
133k
    if (dict_find_string(op, "OrigFont", &porigfont) <= 0)
676
0
        porigfont = NULL;
677
133k
    if (porigfont != NULL && !r_has_type(porigfont, t_dictionary))
678
0
        return_error(gs_error_typecheck);
679
680
133k
    if (pomat!= NULL) {
681
133k
        if (porigfont == NULL ||
682
133k
            dict_find_string(porigfont, "FontMatrix", &pmatrix) <= 0 ||
683
133k
            read_matrix(mem, pmatrix, pomat) < 0
684
133k
            )
685
0
            memset(pomat, 0, sizeof(*pomat));
686
133k
    }
687
    /* Use the FontInfo/OrigFontName key preferrentially (created by MS PSCRIPT driver) */
688
133k
    if ((dict_find_string((porigfont != NULL ? porigfont : op), "FontInfo", &pfontinfo) > 0) &&
689
133k
        r_has_type(pfontinfo, t_dictionary) &&
690
133k
        (dict_find_string(pfontinfo, "OrigFontName", &pfontname) > 0) && (r_has_type(pfontname, t_name) || r_has_type(pfontname, t_string))) {
691
0
        if ((dict_find_string(pfontinfo, "OrigFontStyle", &pfontstyle) > 0) && (r_has_type(pfontname, t_name) || r_has_type(pfontname, t_string)) &&
692
0
                r_size(pfontstyle) > 0) {
693
0
            const byte *tmpStr1 = pfontname->value.const_bytes;
694
0
            const byte *tmpStr2 = pfontstyle->value.const_bytes;
695
0
            int fssize1 = r_size(pfontname), fssize2 = r_size(pfontstyle), fssize = fssize1 + fssize2 + 1;
696
0
            byte *sfname = gs_alloc_string(mem, fssize, "sub_font_params");
697
698
0
            if (sfname == NULL)
699
0
                return_error(gs_error_VMerror);
700
0
            memcpy(sfname, tmpStr1, fssize1);
701
0
            sfname[fssize1]=',' ;
702
0
            memcpy(sfname + fssize1 + 1, tmpStr2, fssize2);
703
0
            make_string(pfname, a_readonly, fssize, sfname);
704
0
        } else
705
0
            get_font_name(mem, pfname, pfontname);
706
133k
    } else if (dict_find_string((porigfont != NULL ? porigfont : op), ".Alias", &pfontname) > 0) {
707
        /* If we emulate the font, we want the requested name rather than a substitute. */
708
36.4k
        get_font_name(mem, pfname, pfontname);
709
96.9k
    } else if (dict_find_string((porigfont != NULL ? porigfont : op), "FontName", &pfontname) > 0) {
710
96.7k
        get_font_name(mem, pfname, pfontname);
711
96.7k
    } else
712
130
        make_empty_string(pfname, a_readonly);
713
133k
    return 0;
714
133k
}
715
716
/* Do the common work for building a font of any FontType. */
717
/* The caller guarantees that *op is a dictionary. */
718
/* op[-1] must be the key under which the font is being registered */
719
/* in FontDirectory, normally a name or string. */
720
/* Return 0 for a new font, 1 for a font made by makefont or scalefont, */
721
/* or a negative error code. */
722
int
723
build_gs_font(i_ctx_t *i_ctx_p, os_ptr op, gs_font ** ppfont, font_type ftype,
724
              gs_memory_type_ptr_t pstype, const build_proc_refs * pbuild,
725
              build_font_options_t options)
726
133k
{
727
133k
    ref kname;      /* t_string */
728
133k
    ref *pftype;
729
133k
    ref *pencoding = 0;
730
133k
    bool bitmapwidths;
731
133k
    int exactsize, inbetweensize, transformedchar;
732
133k
    int wmode;
733
133k
    int code;
734
133k
    gs_font *pfont;
735
133k
    ref *pfid;
736
133k
    ref *aop = dict_access_ref(op);
737
133k
    bool cpsi_mode = gs_currentcpsimode(imemory);
738
739
133k
    get_font_name(imemory, &kname, op - 1);
740
133k
    if (dict_find_string(op, "FontType", &pftype) <= 0 ||
741
133k
        !r_has_type(pftype, t_integer) ||
742
133k
        pftype->value.intval != (int)ftype
743
133k
        )
744
0
        return_error(gs_error_invalidfont);
745
133k
    if (dict_find_string(op, "Encoding", &pencoding) <= 0) {
746
0
        if (!(options & bf_Encoding_optional))
747
0
            return_error(gs_error_invalidfont);
748
0
        pencoding = 0;
749
133k
    } else {
750
133k
        if (!r_is_array(pencoding))
751
0
            return_error(gs_error_invalidfont);
752
133k
    }
753
133k
    if (pencoding) {   /* observed Adobe behavior */
754
133k
        int count = r_size(pencoding);
755
133k
        int type = ftype ? t_name : t_integer;
756
133k
        bool fixit = false;
757
758
34.5M
        while (count--) {
759
34.4M
           ref r;
760
34.4M
           if ((code = array_get(imemory, pencoding, count, &r)) < 0 ||
761
34.4M
             !(r_has_type(&r, type) || r_has_type(&r, t_null))) {
762
0
               if (!cpsi_mode && ftype == ft_user_defined) {
763
0
                   if (code < 0 || r_has_type(&r, t_null)) {
764
0
                       return_error(gs_error_typecheck);
765
0
                   }
766
0
                   fixit = true;
767
0
                   break;
768
0
               }
769
0
               else {
770
0
                   return_error(gs_error_typecheck);
771
0
               }
772
0
           }
773
34.4M
        }
774
775
        /* For at least Type 3 fonts, Adobe Distiller will "fix" an Encoding array, as in, for example
776
         * Bug 692681 where the arrays contain integers rather than names. Once the font is instantiated
777
         * the integers have been converted to names.
778
         * It is preferable to to this manipulation here, rather than in Postscript, because we are less
779
         * restricted by read-only attributes and VM save levels.
780
         */
781
133k
        if (fixit) {
782
0
            ref penc;
783
0
            uint size = 0;
784
0
            char buf[32], *bptr;
785
0
            avm_space curglob = ialloc_space(idmemory);
786
0
            avm_space useglob = r_is_local(pencoding) ? avm_local : avm_global;
787
788
0
            ialloc_set_space(idmemory, useglob);
789
790
0
            count = r_size(pencoding);
791
0
            if ((code = ialloc_ref_array(&penc, (r_type_attrs(pencoding) & a_readonly), count, "build_gs_font")) < 0)
792
0
                 return code;
793
794
0
            while (count--) {
795
0
               ref r;
796
0
               if (array_get(imemory, pencoding, count, &r) < 0){
797
0
                   return_error(gs_error_typecheck);
798
0
               }
799
               /* For type 3, we know the Encoding entries must be names */
800
0
               if (r_has_type(&r, t_name)){
801
0
                   ref_assign(&(penc.value.refs[count]), &r);
802
0
               }
803
0
               else {
804
805
0
                   if ((code = obj_cvs(imemory, &r, (byte *)buf, 32, &size, (const byte **)(&bptr))) < 0) {
806
0
                       return(code);
807
0
                   }
808
0
                   if ((code = name_ref(imemory, (const byte *)bptr, size, &r, true)) < 0)
809
0
                        return code;
810
0
                   ref_assign(&(penc.value.refs[count]), &r);
811
0
               }
812
0
            }
813
814
0
            if ((code = dict_put_string(osp, "Encoding", &penc, NULL)) < 0)
815
0
               return code;
816
0
            ialloc_set_space(idmemory, curglob);
817
0
        }
818
133k
    }
819
133k
    if ((code = dict_int_param(op, "WMode", 0, 1, 0, &wmode)) < 0 ||
820
133k
        (code = dict_bool_param(op, "BitmapWidths", false, &bitmapwidths)) < 0 ||
821
133k
        (code = dict_int_param(op, "ExactSize", 0, 2, fbit_use_bitmaps, &exactsize)) < 0 ||
822
133k
        (code = dict_int_param(op, "InBetweenSize", 0, 2, fbit_use_outlines, &inbetweensize)) < 0 ||
823
133k
        (code = dict_int_param(op, "TransformedChar", 0, 2, fbit_use_outlines, &transformedchar)) < 0
824
133k
        )
825
0
        return code;
826
133k
    code = dict_find_string(op, "FID", &pfid);
827
133k
    if (code > 0 && r_has_type(pfid, t_fontID)) { /* silently ignore invalid FID per CET 13-05.ps */
828
        /*
829
         * If this font has a FID entry already, it might be a scaled font
830
         * made by makefont or scalefont; in a Level 2 environment, it might
831
         * be an existing font being registered under a second name, or a
832
         * re-encoded font (which was invalid in Level 1, but dvips did it
833
         * anyway).
834
         */
835
111
        pfont = r_ptr(pfid, gs_font);
836
        /*
837
         * If the following condition is false this is a re-encoded font,
838
         * or some other questionable situation in which the FID
839
         * was preserved.  Pretend the FID wasn't there.
840
         */
841
111
        if (obj_eq(pfont->memory, pfont_dict(pfont), op)) {
842
111
            if (pfont->base == pfont) { /* original font */
843
111
                if (!level2_enabled)
844
0
                    return_error(gs_error_invalidfont);
845
111
                *ppfont = pfont;
846
111
                return 1;
847
111
            } else {   /* This was made by makefont or scalefont. */
848
                /* Just insert the new name. */
849
0
                gs_matrix mat;
850
0
                ref fname;      /* t_string */
851
852
0
                code = sub_font_params(imemory, op, &mat, NULL, &fname);
853
0
                if (code < 0)
854
0
                    return code;
855
0
                code = 1;
856
0
                copy_font_name(&pfont->font_name, &fname);
857
0
                goto set_name;
858
0
            }
859
111
        }
860
111
    }
861
    /* This is a new font. */
862
133k
    if (!r_has_attr(aop, a_write))
863
0
        return_error(gs_error_invalidaccess);
864
133k
    {
865
133k
        ref encoding;
866
867
        /*
868
         * Since add_FID may resize the dictionary and cause
869
         * pencoding to become invalid, save the Encoding.
870
         */
871
133k
        if (pencoding) {
872
133k
            encoding = *pencoding;
873
133k
            pencoding = &encoding;
874
133k
        }
875
133k
        code = build_gs_sub_font(i_ctx_p, op, &pfont, ftype, pstype,
876
133k
                                 pbuild, pencoding, op);
877
133k
        if (code < 0)
878
4
            return code;
879
133k
    }
880
133k
    pfont->BitmapWidths = bitmapwidths;
881
133k
    pfont->ExactSize = (fbit_type)exactsize;
882
133k
    pfont->InBetweenSize = (fbit_type)inbetweensize;
883
133k
    pfont->TransformedChar = (fbit_type)transformedchar;
884
133k
    pfont->WMode = wmode;
885
133k
    pfont->procs.font_info = zfont_info;
886
133k
    code = 0;
887
133k
set_name:
888
133k
    copy_font_name(&pfont->key_name, &kname);
889
133k
    *ppfont = pfont;
890
133k
    return code;
891
133k
}
892
893
/* Create a sub-font -- a font or an entry in the FDArray of a CIDFontType 0 */
894
/* font.  Default BitmapWidths, ExactSize, InBetweenSize, TransformedChar, */
895
/* and WMode; do not fill in key_name. */
896
/* The caller guarantees that *op is a dictionary. */
897
int
898
build_gs_sub_font(i_ctx_t *i_ctx_p, const ref *op, gs_font **ppfont,
899
                  font_type ftype, gs_memory_type_ptr_t pstype,
900
                  const build_proc_refs * pbuild, const ref *pencoding,
901
                  ref *fid_op)
902
133k
{
903
133k
    gs_matrix mat, omat;
904
133k
    ref fname;      /* t_string */
905
133k
    gs_font *pfont;
906
133k
    font_data *pdata;
907
    /*
908
     * Make sure that we allocate the font data
909
     * in the same VM as the font dictionary.
910
     */
911
133k
    uint space = ialloc_space(idmemory);
912
133k
    int code = sub_font_params(imemory, op, &mat, &omat, &fname);
913
914
133k
    if (code < 0)
915
4
        return code;
916
133k
    ialloc_set_space(idmemory, r_space(op));
917
133k
    pfont = gs_font_alloc(imemory, pstype, &gs_font_procs_default, NULL,
918
133k
                          "buildfont(font)");
919
133k
    pdata = ialloc_struct(font_data, &st_font_data,
920
133k
                          "buildfont(data)");
921
133k
    if (pfont == 0 || pdata == 0)
922
0
        code = gs_note_error(gs_error_VMerror);
923
133k
    else if (fid_op)
924
133k
        code = add_FID(i_ctx_p, fid_op, pfont, iimemory);
925
133k
    if (code < 0) {
926
0
        ifree_object(pdata, "buildfont(data)");
927
0
        ifree_object(pfont, "buildfont(font)");
928
0
        ialloc_set_space(idmemory, space);
929
0
        return code;
930
0
    }
931
133k
    refset_null((ref *) pdata, sizeof(font_data) / sizeof(ref));
932
133k
    ref_assign_new(&pdata->dict, op);
933
133k
    ref_assign_new(&pdata->BuildChar, &pbuild->BuildChar);
934
133k
    ref_assign_new(&pdata->BuildGlyph, &pbuild->BuildGlyph);
935
133k
    if (pencoding)
936
133k
        ref_assign_new(&pdata->Encoding, pencoding);
937
133k
    pfont->client_data = pdata;
938
133k
    pfont->FontType = ftype;
939
133k
    pfont->FontMatrix = mat;
940
133k
    pfont->orig_FontMatrix = omat;
941
133k
    pfont->BitmapWidths = false;
942
133k
    pfont->ExactSize = fbit_use_bitmaps;
943
133k
    pfont->InBetweenSize = fbit_use_outlines;
944
133k
    pfont->TransformedChar = fbit_use_outlines;
945
133k
    pfont->WMode = 0;
946
133k
    pfont->procs.encode_char = zfont_encode_char;
947
133k
    pfont->procs.glyph_name = zfont_glyph_name;
948
133k
    ialloc_set_space(idmemory, space);
949
133k
    copy_font_name(&pfont->font_name, &fname);
950
133k
    *ppfont = pfont;
951
133k
    return 0;
952
133k
}
953
954
/* Get the string corresponding to a font name. */
955
/* If the font name isn't a name or a string, return an empty string. */
956
void
957
get_font_name(const gs_memory_t *mem, ref * pfname, const ref * op)
958
266k
{
959
266k
    switch (r_type(op)) {
960
89.2k
        case t_string:
961
89.2k
            *pfname = *op;
962
89.2k
            break;
963
129k
        case t_name:
964
129k
            name_string_ref(mem, op, pfname);
965
129k
            break;
966
48.0k
        default:
967
            /* This is weird, but legal.... */
968
48.0k
            make_empty_string(pfname, a_readonly);
969
266k
    }
970
266k
}
971
972
/* Copy a font name into the gs_font structure. */
973
void
974
copy_font_name(gs_font_name * pfstr, const ref * pfname)
975
266k
{
976
266k
    uint size = r_size(pfname);
977
978
266k
    if (size > gs_font_name_max)
979
848
        size = gs_font_name_max;
980
266k
    memcpy(&pfstr->chars[0], pfname->value.const_bytes, size);
981
    /* Following is only for debugging printout. */
982
266k
    pfstr->chars[size] = 0;
983
266k
    pfstr->size = size;
984
266k
}
985
986
/* Finish building a font, by calling gs_definefont if needed. */
987
int
988
define_gs_font(i_ctx_t *i_ctx_p, gs_font * pfont)
989
133k
{
990
133k
    return (pfont->base == pfont && pfont->dir == 0 ?
991
            /* i.e., unregistered original font */
992
133k
            gs_definefont(ifont_dir, pfont) :
993
133k
            0);
994
133k
}