Coverage Report

Created: 2025-06-24 07:01

/src/ghostpdl/psi/zfcid1.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2001-2023 Artifex Software, Inc.
2
   All Rights Reserved.
3
4
   This software is provided AS-IS with no warranty, either express or
5
   implied.
6
7
   This software is distributed under license and may not be copied,
8
   modified or distributed except as expressly authorized under the terms
9
   of the license contained in the file LICENSE in this distribution.
10
11
   Refer to licensing information at http://www.artifex.com or contact
12
   Artifex Software, Inc.,  39 Mesa Street, Suite 108A, San Francisco,
13
   CA 94129, USA, for further information.
14
*/
15
16
17
/* CIDFontType 1 and 2 operators */
18
#include "memory_.h"
19
#include "ghost.h"
20
#include "oper.h"
21
#include "gsmatrix.h"
22
#include "gsccode.h"
23
#include "gsstruct.h"
24
#include "gsgcache.h"
25
#include "gsutil.h"
26
#include "gxfcid.h"
27
#include "gxfcache.h"
28
#include "bfont.h"
29
#include "icid.h"
30
#include "idict.h"
31
#include "idparam.h"
32
#include "ifcid.h"
33
#include "ichar1.h"
34
#include "ifont42.h"
35
#include "store.h"
36
#include "stream.h"
37
#include "files.h"
38
39
/* ---------------- CIDFontType 1 (FontType 10) ---------------- */
40
41
/* <string|name> <font_dict> .buildfont10 <string|name> <font> */
42
static int
43
zbuildfont10(i_ctx_t *i_ctx_p)
44
1
{
45
1
    os_ptr op = osp;
46
1
    build_proc_refs build;
47
1
    int code;
48
1
    gs_cid_system_info_t cidsi;
49
1
    gs_font_base *pfont;
50
51
1
    check_op(2);
52
1
    code = build_gs_font_procs(op, &build);
53
1
    if (code < 0)
54
1
        return code;
55
0
    code = cid_font_system_info_param(&cidsi, op);
56
0
    if (code < 0)
57
0
        return code;
58
0
    make_null(&build.BuildChar); /* only BuildGlyph */
59
0
    code = build_gs_simple_font(i_ctx_p, op, &pfont, ft_CID_user_defined,
60
0
                                &st_gs_font_cid1, &build,
61
0
                                bf_Encoding_optional |
62
0
                                bf_UniqueID_ignored);
63
0
    if (code < 0)
64
0
        return code;
65
0
    ((gs_font_cid1 *)pfont)->cidata.CIDSystemInfo = cidsi;
66
0
    return define_gs_font(i_ctx_p, (gs_font *)pfont);
67
0
}
68
69
/* ---------------- CIDFontType 2 (FontType 11) ---------------- */
70
71
/* ------ Accessing ------ */
72
73
/* Map a glyph CID to a TrueType glyph number using the CIDMap. */
74
static int
75
z11_CIDMap_proc(gs_font_cid2 *pfont, gs_glyph glyph)
76
0
{
77
0
    const ref *pcidmap = &pfont_data(pfont)->u.type42.CIDMap;
78
0
    ulong cid = glyph - GS_MIN_CID_GLYPH;
79
0
    int gdbytes = pfont->cidata.common.GDBytes;
80
0
    int gnum = 0;
81
0
    const byte *data;
82
0
    int i, code = -1;
83
0
    ref rcid;
84
0
    ref *prgnum;
85
0
    ref *p, *fdict = pfont_dict(pfont);
86
87
0
    if (r_has_type(fdict, t_dictionary) && dict_find_string(fdict, "Path", &p)) {
88
0
        ref *Decoding = NULL, *TT_cmap = NULL, *SubstNWP = NULL, src_type, dst_type;
89
0
        uint c;
90
91
0
        code = dict_find_string(fdict, "Decoding", &Decoding);
92
0
        if (code > 0)
93
0
            code = dict_find_string(fdict, "TT_cmap", &TT_cmap);
94
0
        if (code > 0)
95
0
            code = dict_find_string(fdict, "SubstNWP", &SubstNWP);
96
0
        if (code > 0) {
97
0
            code = cid_to_TT_charcode(pfont->memory, Decoding, TT_cmap, SubstNWP, cid, &c, &src_type, &dst_type);
98
0
            if (code >= 0)
99
0
                gnum = c;
100
0
        }
101
0
    }
102
103
0
    if (code < 0) {
104
0
        switch (r_type(pcidmap)) {
105
0
        case t_string:
106
0
            if (cid >= r_size(pcidmap) / gdbytes)
107
0
                return_error(gs_error_rangecheck);
108
0
            data = pcidmap->value.const_bytes + cid * gdbytes;
109
0
            break;
110
0
        case t_integer:
111
0
            return cid + pcidmap->value.intval;
112
0
        case t_dictionary:
113
0
            make_int(&rcid, cid);
114
0
            code = dict_find(pcidmap, &rcid, &prgnum);
115
0
            if (code <= 0)
116
0
                return (code < 0 ? code : gs_note_error(gs_error_undefined));
117
0
            if (!r_has_type(prgnum, t_integer))
118
0
                return_error(gs_error_typecheck);
119
0
            return prgnum->value.intval;
120
0
        default:      /* array type */
121
0
            code = string_array_access_proc(pfont->memory, pcidmap, 1, cid * gdbytes,
122
0
                                            gdbytes, NULL, NULL, &data);
123
124
0
            if (code < 0)
125
0
                return code;
126
0
            if ( code > 0 )
127
0
                return_error(gs_error_invalidfont);
128
0
        }
129
0
        for (i = 0; i < gdbytes; ++i)
130
0
            gnum = (gnum << 8) + data[i];
131
0
    }
132
0
    if (gnum >= pfont->data.trueNumGlyphs)
133
0
        return_error(gs_error_invalidfont);
134
0
    return gnum;
135
0
}
136
137
/* Handle MetricsCount when accessing outline or metrics information. */
138
static int
139
z11_get_outline(gs_font_type42 * pfont, uint glyph_index,
140
                gs_glyph_data_t *pgd)
141
0
{
142
0
    gs_font_cid2 *const pfcid = (gs_font_cid2 *)pfont;
143
0
    int skip = pfcid->cidata.MetricsCount << 1;
144
0
    int code = pfcid->cidata.orig_procs.get_outline(pfont, glyph_index, pgd);
145
146
0
    if (code >= 0) {
147
0
        uint size = pgd->bits.size;
148
149
0
        if (size <= skip) {
150
0
            gs_glyph_data_free(pgd, "z11_get_outline");
151
0
            gs_glyph_data_from_null(pgd);
152
0
        } else {
153
0
            gs_glyph_data_substring(pgd, skip, size - skip);
154
0
        }
155
0
    }
156
0
    return code;
157
0
}
158
159
0
#define GET_U16_MSB(p) (((uint)((p)[0]) << 8) + (p)[1])
160
0
#define GET_S16_MSB(p) (int)((GET_U16_MSB(p) ^ 0x8000) - 0x8000)
161
162
static int
163
z11_get_metrics(gs_font_type42 * pfont, uint glyph_index,
164
                gs_type42_metrics_options_t options, float sbw[4])
165
0
{
166
0
    gs_font_cid2 *const pfcid = (gs_font_cid2 *)pfont;
167
0
    int skip = pfcid->cidata.MetricsCount << 1;
168
0
    gs_glyph_data_t gdata;
169
0
    const byte *pmetrics;
170
0
    int lsb, width;
171
0
    int code = 0;
172
0
    int wmode = gs_type42_metrics_options_wmode(options);
173
174
0
    gdata.memory = pfont->memory;
175
0
    if (wmode >= skip >> 2 ||
176
0
        (code = pfcid->cidata.orig_procs.get_outline(pfont, glyph_index, &gdata)) < 0 ||
177
0
        gdata.bits.size < skip
178
0
        )
179
0
        return pfcid->cidata.orig_procs.get_metrics(pfont, glyph_index, options, sbw);
180
0
    if(gs_type42_metrics_options_bbox_requested(options)) {
181
0
        code = pfcid->cidata.orig_procs.get_metrics(pfont, glyph_index,
182
0
                        gs_type42_metrics_options_BBOX, sbw);;
183
0
        if (code < 0)
184
0
            return code;
185
0
    }
186
0
    if (gs_type42_metrics_options_sbw_requested(options)) {
187
0
        pmetrics = gdata.bits.data + skip - 4 - (wmode << 2);
188
0
        lsb = GET_S16_MSB(pmetrics + 2);
189
0
        width = GET_U16_MSB(pmetrics + 0);
190
0
        {
191
0
            double factor = 1.0 / pfont->data.unitsPerEm;
192
193
0
            if (wmode) {
194
0
                sbw[0] = 0, sbw[1] = -lsb * factor;
195
0
                sbw[2] = 0, sbw[3] = -width * factor;
196
0
            } else {
197
0
                sbw[0] = lsb * factor, sbw[1] = 0;
198
0
                sbw[2] = width * factor, sbw[3] = 0;
199
0
            }
200
0
        }
201
0
    }
202
0
    gs_glyph_data_free(&gdata, "z11_get_metrics");
203
0
    return 0;
204
0
}
205
206
static int
207
z11_glyph_info_aux(gs_font *font, gs_glyph glyph, const gs_matrix *pmat,
208
                     int members, gs_glyph_info_t *info)
209
0
{
210
0
    gs_font_cid2 *fontCID2 = (gs_font_cid2 *)font;
211
0
    uint glyph_index;
212
0
    int code = (glyph > GS_MIN_GLYPH_INDEX
213
0
            ? glyph - GS_MIN_GLYPH_INDEX
214
0
            : fontCID2->cidata.CIDMap_proc(fontCID2, glyph));
215
216
0
    if(code < 0)
217
0
        return code;
218
0
    glyph_index = (uint)code;
219
0
    return gs_type42_glyph_info_by_gid(font, glyph, pmat, members, info, glyph_index);
220
0
}
221
222
static int
223
z11_glyph_info(gs_font *font, gs_glyph glyph, const gs_matrix *pmat,
224
                     int members, gs_glyph_info_t *info)
225
0
{
226
0
    int wmode = (members & GLYPH_INFO_WIDTH0 ? 0 : 1);
227
228
0
    return z1_glyph_info_generic(font, glyph, pmat, members, info,
229
0
                                    &z11_glyph_info_aux, wmode);
230
0
}
231
232
/* Enumerate glyphs (keys) from GlyphDirectory instead of loca / glyf. */
233
static int
234
z11_enumerate_glyph(gs_font *font, int *pindex,
235
                         gs_glyph_space_t glyph_space, gs_glyph *pglyph)
236
0
{
237
0
    gs_font_cid2 *pfont = (gs_font_cid2 *)font;
238
0
    int code0 = z11_CIDMap_proc(pfont, GS_MIN_CID_GLYPH);
239
0
    int code;
240
241
0
    if(*pindex > pfont->cidata.common.CIDCount)
242
0
        return_error(gs_error_rangecheck);
243
244
0
    for (;;) {
245
0
        code = z11_CIDMap_proc(pfont, GS_MIN_CID_GLYPH + *pindex);
246
247
0
        if (code < 0) {
248
0
            *pindex = 0;
249
0
            return 0;
250
0
        }
251
0
        (*pindex)++;
252
0
        if (*pindex == 1 || code != code0)
253
0
            break;
254
        /* else skip an underfined glyph */
255
0
    }
256
0
    if (glyph_space == GLYPH_SPACE_INDEX)
257
0
        *pglyph = GS_MIN_GLYPH_INDEX + (uint)code;
258
0
    else
259
0
        *pglyph = GS_MIN_CID_GLYPH + (uint)(*pindex - 1);
260
0
    return 0;
261
0
}
262
263
static uint
264
z11_get_glyph_index(gs_font_type42 *pfont, gs_glyph glyph)
265
0
{
266
0
    int code = z11_CIDMap_proc((gs_font_cid2 *)pfont, glyph);
267
268
0
    return (code < 0 ? 0 /* notdef */: (uint)code);
269
0
}
270
271
static int
272
z11_glyph_outline(gs_font *font, int WMode, gs_glyph glyph, const gs_matrix *pmat,
273
                  gx_path *ppath, double sbw[4])
274
0
{
275
0
    return gs_type42_glyph_outline(font, WMode,
276
0
            z11_get_glyph_index((gs_font_type42 *)font, glyph) + GS_MIN_GLYPH_INDEX,
277
0
                                   pmat, ppath, sbw);
278
0
}
279
280
static int
281
get_subst_CID_on_WMode(gs_subst_CID_on_WMode_t *subst, ref *t, int WMode)
282
0
{
283
0
    ref r, *a, e;;
284
285
0
    make_int(&r, WMode);
286
0
    if (dict_find(t, &r, &a) > 0 && r_type(a) == t_array) {
287
0
        int n = r_size(a), i;
288
0
        uint *s;
289
290
0
        s = (uint *)gs_alloc_byte_array(subst->rc.memory, n, sizeof(int), "zbuildfont11");
291
0
        if (s == NULL)
292
0
            return_error(gs_error_VMerror);
293
0
        for (i = 0; i < n; i++) {
294
0
            array_get(subst->rc.memory, a, (long)i, &e);
295
0
            if (r_type(&e) != t_integer)
296
0
                return_error(gs_error_invalidfont);
297
0
            s[i] = e.value.intval;
298
0
        }
299
0
        subst->data[WMode] = s;
300
0
        subst->size[WMode] = n;
301
0
    }
302
0
    return 0;
303
0
}
304
305
static GS_NOTIFY_PROC(release_subst_CID_on_WMode);
306
307
static int
308
release_subst_CID_on_WMode(void *data, void *event)
309
0
{
310
0
    gs_font_cid2 *pfcid = (gs_font_cid2 *)data;
311
0
    gs_subst_CID_on_WMode_t *subst = pfcid->subst_CID_on_WMode;
312
313
0
    gs_font_notify_unregister((gs_font *)pfcid, release_subst_CID_on_WMode, data);
314
0
    pfcid->subst_CID_on_WMode = NULL;
315
0
    rc_adjust(subst, -2, "release_subst_CID_on_WMode");
316
0
    return 0;
317
0
}
318
319
static uint
320
font11_substitute_glyph_index_vertical(gs_font_type42 *pfont, uint glyph_index,
321
                                          int WMode, gs_glyph glyph)
322
0
{
323
0
    gs_font_cid2 *pfcid = (gs_font_cid2 *)pfont;
324
0
    uint cid = (glyph >= GS_MIN_CID_GLYPH ? glyph - GS_MIN_CID_GLYPH : glyph);
325
0
    int WMode1 = !WMode;\
326
0
    gs_subst_CID_on_WMode_t *s = pfcid->subst_CID_on_WMode;
327
328
0
    if (s != NULL) {
329
0
        uint *subst = s->data[WMode1];
330
0
        int bi, ei, i;
331
332
        /* Binary search for cid in subst (2-int elements) : */
333
0
        bi = 0;
334
0
        ei = pfcid->subst_CID_on_WMode->size[WMode1];
335
336
0
        if (ei > 0) {
337
0
            for (;;) {
338
0
                i = ((bi + ei) / 2) & ~1;
339
0
                if (subst[i] == cid) {
340
0
                    WMode = WMode1;
341
0
                    break;
342
0
                }
343
0
                if (bi + 2 >= ei)
344
0
                    break;
345
0
                if (subst[i] > cid)
346
0
                    ei = i;
347
0
                else
348
0
                    bi = i;
349
0
            }
350
0
        }
351
0
    }
352
0
    return gs_type42_substitute_glyph_index_vertical(pfont, glyph_index, WMode, glyph);
353
0
}
354
355
/* ------ Defining ------ */
356
357
extern_st(st_subst_CID_on_WMode);
358
359
/* <string|name> <font_dict> .buildfont11 <string|name> <font> */
360
static int
361
zbuildfont11(i_ctx_t *i_ctx_p)
362
7
{
363
7
    os_ptr op = osp;
364
7
    gs_font_cid_data common;
365
7
    gs_font_type42 *pfont;
366
7
    gs_font_cid2 *pfcid;
367
7
    int MetricsCount;
368
7
    ref rcidmap, ignore_gdir, file, *pfile, cfnstr, *pCIDFontName, CIDFontName, *t;
369
7
    ulong loca_glyph_pos[2][2];
370
7
    int code;
371
372
7
    check_op(2);
373
0
    code = cid_font_data_param(op, &common, &ignore_gdir);
374
0
    if (code < 0)
375
0
        return code;
376
377
0
    code = dict_find_string(op, "CIDFontName", &pCIDFontName);
378
0
    if (code <= 0) {
379
0
        if (code == 0)
380
0
            return_error(gs_error_undefined);
381
0
        return code;
382
0
    }
383
0
    code = dict_int_param(op, "MetricsCount", 0, 4, 0, &MetricsCount);
384
0
    if (code < 0)
385
0
        return code;
386
    /*
387
     * Since build_gs_simple_font may resize the dictionary and cause
388
     * pointers to become invalid, save CIDFontName
389
     */
390
0
    CIDFontName = *pCIDFontName;
391
0
    if (MetricsCount & 1) /* only allowable values are 0, 2, 4 */
392
0
        return_error(gs_error_rangecheck);
393
0
    code = dict_find_string(op, "File", &pfile);
394
0
    if (code < 0 && code != gs_error_undefined)
395
0
        return code;
396
0
    if (code > 0) {
397
0
        ref *file_table_pos, *a, v;
398
0
        const char *name[2] = {"loca", "glyf"};
399
0
        int i, j;
400
401
        /*
402
         * Since build_gs_simple_font may resize the dictionary and cause
403
         * pointers to become invalid, save File and CIDFontName
404
         */
405
0
        file = *pfile;
406
0
        check_read_type(file, t_file);
407
0
        code = dict_find_string(op, "file_table_pos", &file_table_pos);
408
0
        if (code <= 0 || r_type(file_table_pos) != t_dictionary)
409
0
            return_error(gs_error_invalidfont);
410
0
        for (i = 0; i < 2; i++) {
411
0
            code = dict_find_string(file_table_pos, name[i], &a);
412
0
            if (code <= 0 || r_type(a) != t_array)
413
0
                return_error(gs_error_invalidfont);
414
0
            for (j = 0; j < 2; j++) {
415
0
                code = array_get(imemory, a, j, &v);
416
0
                if (code < 0 || r_type(&v) != t_integer)
417
0
                    return_error(gs_error_invalidfont);
418
0
                loca_glyph_pos[i][j] = v.value.intval;
419
0
            }
420
0
        }
421
0
    } else
422
0
        pfile = NULL;
423
0
    code = font_string_array_param(imemory, op, "CIDMap", &rcidmap);
424
0
    switch (code) {
425
0
    case 0:     /* in PLRM3 */
426
0
    gdb:
427
        /* GDBytes is required for indexing a string or string array. */
428
0
        if (common.GDBytes == 0)
429
0
            return_error(gs_error_rangecheck);
430
0
        break;
431
0
    default:
432
0
        return code;
433
0
    case gs_error_typecheck:
434
0
        switch (r_type(&rcidmap)) {
435
0
        case t_string:    /* in PLRM3 */
436
0
            goto gdb;
437
0
        case t_dictionary:  /* added in 3011 */
438
0
        case t_integer:   /* added in 3011 */
439
0
            break;
440
0
        default:
441
0
            return code;
442
0
        }
443
0
        break;
444
0
    }
445
0
    code = build_gs_TrueType_font(i_ctx_p, op, &pfont, ft_CID_TrueType,
446
0
                                  &st_gs_font_cid2,
447
0
                                  (const char *)0, "%Type11BuildGlyph",
448
0
                                  bf_Encoding_optional |
449
0
                                  bf_UniqueID_ignored |
450
0
                                  bf_CharStrings_optional |
451
0
                                  (pfile != NULL ? bf_has_font_file : 0));
452
0
    if (code < 0)
453
0
        return code;
454
0
    pfcid = (gs_font_cid2 *)pfont;
455
0
    if (dict_find_string(op, "subst_CID_on_WMode", &t) > 0 && r_type(t) == t_dictionary) {
456
0
        gs_subst_CID_on_WMode_t *subst = NULL;
457
0
        ref *o;
458
0
        gs_font *font;
459
460
0
        if (dict_find_string(t, "Ordering", &o) <= 0 || r_type(o) != t_string)
461
0
            return_error(gs_error_invalidfont);
462
0
        for (font = ifont_dir->orig_fonts; font != NULL; font = font->next) {
463
0
            if (font->FontType == ft_CID_TrueType) {
464
0
                gs_font_cid2 *pfcid1 = (gs_font_cid2 *)font;
465
0
                if (pfcid1->subst_CID_on_WMode != NULL &&
466
                    /* We want the subst_CID_on_WMode to exist in same local/global
467
                     * VM as the CIDFont object that will hold a reference to it
468
                     */
469
0
                    pfcid1->memory == pfcid->memory &&
470
0
                    bytes_compare(o->value.const_bytes, r_size(o),
471
0
                            pfcid1->cidata.common.CIDSystemInfo.Ordering.data,
472
0
                            pfcid1->cidata.common.CIDSystemInfo.Ordering.size)) {
473
0
                    subst = pfcid1->subst_CID_on_WMode;
474
0
                    break;
475
0
                }
476
0
            }
477
0
        }
478
479
0
        if (subst == NULL) {
480
0
            rc_alloc_struct_1(subst, gs_subst_CID_on_WMode_t, &st_subst_CID_on_WMode,
481
0
                            pfcid->memory, return_error(gs_error_VMerror), "zbuildfont11");
482
0
            subst->data[0] = subst->data[1] = 0;
483
0
            pfcid->subst_CID_on_WMode = subst;
484
0
            code = get_subst_CID_on_WMode(subst, t, 0);
485
0
            if (code < 0)
486
0
                return code;
487
0
            code = get_subst_CID_on_WMode(subst, t, 1);
488
0
            if (code < 0)
489
0
                return code;
490
0
        } else {
491
0
            pfcid->subst_CID_on_WMode = subst;
492
0
            rc_increment(subst);
493
0
        }
494
0
        code = gs_font_notify_register((gs_font *)pfcid, release_subst_CID_on_WMode, (void *)pfcid);
495
0
        if (code < 0)
496
0
            return code;
497
0
        rc_increment(subst);
498
0
   }
499
0
    pfcid->cidata.common = common;
500
0
    pfcid->cidata.MetricsCount = MetricsCount;
501
0
    ref_assign(&pfont_data(pfont)->u.type42.CIDMap, &rcidmap);
502
0
    pfcid->cidata.CIDMap_proc = z11_CIDMap_proc;
503
0
    pfcid->data.substitute_glyph_index_vertical = font11_substitute_glyph_index_vertical;
504
0
    pfont->procs.enumerate_glyph = z11_enumerate_glyph;
505
0
    pfont->procs.glyph_info = z11_glyph_info;
506
0
    pfont->procs.glyph_outline = z11_glyph_outline;
507
0
    pfont->data.get_glyph_index = z11_get_glyph_index;
508
0
    if (pfcid->font_name.size == 0) {
509
0
        get_font_name(imemory, &cfnstr, &CIDFontName);
510
0
        copy_font_name(&pfcid->font_name, &cfnstr);
511
0
    }
512
0
    if (MetricsCount) {
513
        /* "Wrap" the glyph accessor procedures. */
514
0
        pfcid->cidata.orig_procs.get_outline = pfont->data.get_outline;
515
0
        pfont->data.get_outline = z11_get_outline;
516
0
        pfcid->cidata.orig_procs.get_metrics = pfont->data.get_metrics;
517
0
        pfont->data.get_metrics = z11_get_metrics;
518
0
    } else if(pfile != NULL) {
519
        /*
520
         * We assume that disk fonts has no MetricsCount.
521
         * We could do not, but the number of virtual function wariants increases.
522
         */
523
0
        stream *s;
524
525
0
        check_read_file(i_ctx_p, s, &file);
526
0
        pfont->data.loca = loca_glyph_pos[0][0];
527
0
        pfont->data.glyf = loca_glyph_pos[1][0];
528
0
        pfont->data.get_outline = gs_get_glyph_data_cached;
529
0
        pfont->data.gdcache = gs_glyph_cache__alloc(pfont, s, gs_type42_get_outline_from_TT_file);
530
0
    }
531
0
    return define_gs_font(i_ctx_p, (gs_font *)pfont);
532
0
}
533
534
/* <cid11font> <cid> .type11mapcid <glyph_index> */
535
static int
536
ztype11mapcid(i_ctx_t *i_ctx_p)
537
0
{
538
0
    os_ptr op = osp;
539
0
    gs_font *pfont;
540
0
    int code;
541
542
0
    check_op(2);
543
0
    code = font_param(op - 1, &pfont);
544
0
    if (code < 0)
545
0
        return code;
546
0
    check_type(*op, t_integer);
547
#if defined(TEST)
548
    /* Allow a Type 42 font here, for testing .wrapfont. */
549
    if (pfont->FontType == ft_TrueType) {
550
        /* Use the CID as the glyph index. */
551
        if (op->value.intval < 0 ||
552
            op->value.intval >= ((gs_font_type42 *)pfont)->data.numGlyphs
553
            )
554
            return_error(gs_error_rangecheck);
555
        code = (int)op->value.intval;
556
    } else
557
#endif
558
0
    {
559
0
        if (pfont->FontType != ft_CID_TrueType)
560
0
            return_error(gs_error_invalidfont);
561
0
        code = z11_CIDMap_proc((gs_font_cid2 *)pfont,
562
0
                        (gs_glyph)(GS_MIN_CID_GLYPH + op->value.intval));
563
0
    }
564
0
    if (code < 0)
565
0
        return code;
566
0
    make_int(op - 1, code);
567
0
    pop(1);
568
0
    return 0;
569
0
}
570
571
/* <Decoding> <TT_cmap> <SubstNWP> <GDBytes> <CIDMap> .fillCIDMap - */
572
static int
573
zfillCIDMap(i_ctx_t *i_ctx_p)
574
0
{
575
0
    os_ptr op = osp;
576
0
    ref *Decoding = op - 4, *TT_cmap = op - 3, *SubstNWP = op - 2,
577
0
        *GDBytes = op - 1, *CIDMap = op;
578
0
    int code;
579
580
0
    check_op(5);
581
0
    check_type(*Decoding, t_dictionary);
582
0
    check_type(*TT_cmap, t_dictionary);
583
0
    check_type(*SubstNWP, t_array);
584
0
    check_type(*GDBytes, t_integer);
585
0
    check_type(*CIDMap, t_array);
586
0
    code = cid_fill_CIDMap(imemory, Decoding, TT_cmap, SubstNWP, GDBytes->value.intval, CIDMap);
587
0
    pop(5);
588
0
    return code;
589
0
}
590
591
static int
592
zfillIdentityCIDMap(i_ctx_t *i_ctx_p)
593
0
{
594
0
    os_ptr op = osp;
595
    /* ref *Decoding = op - 4; */
596
    /* ref *TT_cmap  = op - 3; */
597
    /* ref *SubstNWP = op - 2; */
598
    /* ref *GDBytes  = op - 1; */
599
0
    ref *CIDMap = op;
600
0
    int code;
601
602
0
    check_op(1);
603
0
    check_type(*CIDMap, t_array);
604
0
    code = cid_fill_Identity_CIDMap(imemory, CIDMap);
605
0
    pop(1);
606
0
    return code;
607
0
}
608
609
/* ------ Initialization procedure ------ */
610
611
const op_def zfcid1_op_defs[] =
612
{
613
    {"2.buildfont10", zbuildfont10},
614
    {"2.buildfont11", zbuildfont11},
615
    {"2.type11mapcid", ztype11mapcid},
616
    {"2.fillCIDMap", zfillCIDMap},
617
    {"2.fillIdentityCIDMap", zfillIdentityCIDMap},
618
    op_def_end(0)
619
};