Coverage Report

Created: 2022-10-31 07:00

/src/ghostpdl/devices/vector/gdevpsfx.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2001-2021 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
/* Convert Type 1 Charstrings to Type 2 */
18
#include "math_.h"
19
#include "memory_.h"
20
#include "gx.h"
21
#include "gserrors.h"
22
#include "gxfixed.h"
23
#include "gxmatrix.h"   /* for gsfont.h */
24
#include "gxfont.h"
25
#include "gxfont1.h"
26
#include "gxtype1.h"
27
#include "stream.h"
28
#include "gdevpsf.h"
29
#include "gxgstate.h"
30
31
/* ------ Type 1 Charstring parsing ------ */
32
33
/*
34
 * The parsing code handles numbers on its own; it reports callsubr and
35
 * return operators to the caller, but also executes them.
36
 *
37
 * Only the following elements of the Type 1 state are used:
38
 *  ostack, os_count, ipstack, ips_count
39
 */
40
41
8.46M
#define CE_OFFSET 32    /* offset for extended opcodes */
42
43
typedef struct {
44
    fixed v0, v1;   /* coordinates */
45
    ushort index;   /* sequential index of hint */
46
} cv_stem_hint;
47
typedef struct {
48
    int count;
49
    int current;    /* cache cursor for search */
50
    /*
51
     * For dotsection and Type 1 Charstring hint replacement,
52
     * we store active hints at the bottom of the table, and
53
     * replaced hints at the top.
54
     */
55
    int replaced_count;   /* # of replaced hints at top */
56
    cv_stem_hint data[max_total_stem_hints];
57
} cv_stem_hint_table;
58
59
/* Skip over the initial bytes in a Charstring, if any. */
60
static void
61
skip_iv(gs_type1_state *pcis)
62
3.35M
{
63
3.35M
    int skip = pcis->pfont->data.lenIV;
64
3.35M
    ip_state_t *ipsp = &pcis->ipstack[pcis->ips_count - 1];
65
3.35M
    const byte *cip = ipsp->cs_data.bits.data;
66
3.35M
    crypt_state state = crypt_charstring_seed;
67
68
16.7M
    for (; skip > 0; ++cip, --skip)
69
13.3M
        decrypt_skip_next(*cip, state);
70
3.35M
    ipsp->ip = cip;
71
3.35M
    ipsp->dstate = state;
72
3.35M
}
73
74
/*
75
 * Set up for parsing a Type 1 Charstring.
76
 *
77
 * Only uses the following elements of *pfont:
78
 *  data.lenIV
79
 */
80
static void
81
type1_next_init(gs_type1_state *pcis, const gs_glyph_data_t *pgd,
82
                gs_font_type1 *pfont)
83
1.68M
{
84
1.68M
    gs_type1_interp_init(pcis, NULL, NULL, NULL, NULL, false, 0, pfont);
85
1.68M
    pcis->flex_count = flex_max;
86
1.68M
    pcis->ipstack[0].cs_data = *pgd;
87
1.68M
    skip_iv(pcis);
88
1.68M
}
89
90
/* Clear the Type 1 operand stack. */
91
static inline void
92
type1_clear(gs_type1_state *pcis)
93
29.9M
{
94
29.9M
    pcis->os_count = 0;
95
29.9M
}
96
97
/* Execute a callsubr. */
98
static int
99
type1_callsubr(gs_type1_state *pcis, int index)
100
1.66M
{
101
1.66M
    gs_font_type1 *pfont = pcis->pfont;
102
1.66M
    ip_state_t *ipsp1 = &pcis->ipstack[pcis->ips_count];
103
1.66M
    int code = pfont->data.procs.subr_data(pfont, index, false,
104
1.66M
                                           &ipsp1->cs_data);
105
106
1.66M
    if (code < 0)
107
0
        return_error(code);
108
1.66M
    pcis->ips_count++;
109
1.66M
    skip_iv(pcis);
110
1.66M
    return code;
111
1.66M
}
112
113
/* Add 1 or 3 stem hints. */
114
static int
115
type1_stem1(gs_type1_state *pcis, cv_stem_hint_table *psht, const fixed *pv,
116
            fixed lsb, byte *active_hints)
117
7.97M
{
118
7.97M
    fixed v0 = pv[0] + lsb, v1 = v0 + pv[1];
119
7.97M
    cv_stem_hint *bot = &psht->data[0];
120
7.97M
    cv_stem_hint *orig_top = bot + psht->count;
121
7.97M
    cv_stem_hint *top = orig_top;
122
123
7.97M
    if (psht->count >= max_total_stem_hints)
124
0
        return_error(gs_error_limitcheck);
125
12.1M
    while (top > bot &&
126
12.1M
           (v0 < top[-1].v0 || (v0 == top[-1].v0 && v1 < top[-1].v1))
127
7.97M
           ) {
128
4.19M
        *top = top[-1];
129
4.19M
        top--;
130
4.19M
    }
131
7.97M
    if (top > bot && v0 == top[-1].v0 && v1 == top[-1].v1) {
132
        /* Duplicate hint, don't add it. */
133
4.98M
        memmove(top, top + 1, (char *)orig_top - (char *)top);
134
4.98M
        if (active_hints) {
135
3.98M
            uint index = top[-1].index;
136
137
3.98M
            active_hints[index >> 3] |= 0x80 >> (index & 7);
138
3.98M
        }
139
4.98M
        return 0;
140
4.98M
    }
141
2.98M
    top->v0 = v0;
142
2.98M
    top->v1 = v1;
143
2.98M
    psht->count++;
144
2.98M
    return 0;
145
7.97M
}
146
static void
147
type1_stem3(gs_type1_state *pcis, cv_stem_hint_table *psht, const fixed *pv3,
148
            fixed lsb, byte *active_hints)
149
1.82k
{
150
1.82k
    type1_stem1(pcis, psht, pv3, lsb, active_hints);
151
1.82k
    type1_stem1(pcis, psht, pv3 + 2, lsb, active_hints);
152
1.82k
    type1_stem1(pcis, psht, pv3 + 4, lsb, active_hints);
153
1.82k
}
154
155
/*
156
 * Get the next operator from a Type 1 Charstring.  This procedure handles
157
 * numbers, div, blend, pop, and callsubr/return.
158
 */
159
static int
160
type1_next(gs_type1_state *pcis)
161
34.3M
{
162
34.3M
    ip_state_t *ipsp = &pcis->ipstack[pcis->ips_count - 1];
163
34.3M
    const byte *cip, *cipe;
164
34.3M
    crypt_state state;
165
34.3M
#define CLEAR (csp = pcis->ostack - 1)
166
34.3M
    fixed *csp = &pcis->ostack[pcis->os_count - 1];
167
34.3M
    const bool encrypted = pcis->pfont->data.lenIV >= 0;
168
34.3M
    int c, code, num_results, c0;
169
170
37.6M
 load:
171
37.6M
    cip = ipsp->ip;
172
37.6M
    cipe = ipsp->cs_data.bits.data + ipsp->cs_data.bits.size;
173
37.6M
    state = ipsp->dstate;
174
122M
    for (;;) {
175
122M
        if (cip >= cipe)
176
            /* We used to treat buffer overrun as a simple invalid font, now we assume that
177
             * there is an implicit endchar, so we return a particular error for later
178
             * interception. Returning an error allows any other code to continue as before.
179
             * Part of bug #693170 where the fonts are invalid (no endchar on some glyphs).
180
             */
181
0
            return_error(gs_error_unknownerror);
182
122M
        c0 = *cip++;
183
122M
        charstring_next(c0, state, c, encrypted);
184
122M
        if (c >= c_num1) {
185
            /* This is a number, decode it and push it on the stack. */
186
84.3M
            if (c < c_pos2_0) { /* 1-byte number */
187
64.8M
                decode_push_num1(csp, pcis->ostack, c);
188
64.8M
            } else if (c < cx_num4) { /* 2-byte number */
189
19.5M
                decode_push_num2(csp, pcis->ostack, c, cip, state, encrypted);
190
19.5M
            } else if (c == cx_num4) { /* 4-byte number */
191
6.52k
                long lw;
192
193
6.52k
                decode_num4(lw, cip, state, encrypted);
194
6.52k
                CS_CHECK_PUSH(csp, pcis->ostack);
195
6.52k
                *++csp = int2fixed(lw);
196
6.52k
                if (lw != fixed2long(*csp)) {
197
                    /*
198
                     * The integer was too large to handle in fixed point.
199
                     * Handle this case specially.
200
                     */
201
0
                    code = gs_type1_check_float(&state, encrypted, &cip, csp, lw);
202
0
                    if (code < 0)
203
0
                       return code;
204
0
                }
205
6.52k
            } else   /* not possible */
206
0
                return_error(gs_error_invalidfont);
207
84.3M
            continue;
208
84.3M
        }
209
#ifdef DEBUG
210
        if (gs_debug_c('1')) {
211
            const fixed *p;
212
213
            for (p = pcis->ostack; p <= csp; ++p)
214
                dmprintf1(pcis->pgs->memory, " %g", fixed2float(*p));
215
            if (c == cx_escape) {
216
                crypt_state cstate = state;
217
                int cn;
218
219
                charstring_next(*cip, cstate, cn, encrypted);
220
                dmprintf1(pcis->pgs->memory, " [*%d]\n", cn);
221
            } else
222
                dmprintf1(pcis->pgs->memory, " [%d]\n", c);
223
        }
224
#endif
225
38.4M
        switch ((char_command) c) {
226
33.4M
        default:
227
33.4M
            break;
228
33.4M
        case c_undef0:
229
1
        case c_undef2:
230
1
        case c_undef17:
231
1
            return_error(gs_error_invalidfont);
232
1.66M
        case c_callsubr:
233
1.66M
            code = type1_callsubr(pcis, fixed2int_var(*csp) +
234
1.66M
                                  pcis->pfont->data.subroutineNumberBias);
235
1.66M
            if (code < 0)
236
0
                return_error(code);
237
1.66M
            ipsp->ip = cip, ipsp->dstate = state;
238
1.66M
            --csp;
239
1.66M
            ++ipsp;
240
1.66M
            goto load;
241
1.66M
        case c_return:
242
1.66M
            if (pcis->ips_count > 1) {
243
1.66M
                gs_glyph_data_free(&ipsp->cs_data, "type1_next");
244
1.66M
                pcis->ips_count--;
245
1.66M
                --ipsp;
246
1.66M
            } else
247
0
                return_error(gs_error_invalidfont);
248
1.66M
            goto load;
249
1.66M
        case c_undoc15:
250
            /* See gstype1.h for information on this opcode. */
251
22
            CLEAR;
252
22
            continue;
253
1.66M
        case cx_escape:
254
1.66M
            charstring_next(*cip, state, c, encrypted);
255
1.66M
            ++cip;
256
1.66M
            switch ((char1_extended_command) c) {
257
3.85k
            default:
258
3.85k
                c += CE_OFFSET;
259
3.85k
                break;
260
4.35k
            case ce1_div:
261
4.35k
                csp[-1] = float2fixed((double)csp[-1] / (double)*csp);
262
4.35k
                --csp;
263
4.35k
                continue;
264
0
            case ce1_undoc15: /* see gstype1.h */
265
0
                CLEAR;
266
0
                continue;
267
833k
            case ce1_callothersubr:
268
833k
                switch (fixed2int_var(*csp)) {
269
1.85k
                case 0:
270
1.85k
                    pcis->ignore_pops = 2;
271
1.85k
                    break; /* pass to caller */
272
817k
                case 3:
273
817k
                    pcis->ignore_pops = 1;
274
817k
                    break; /* pass to caller */
275
0
                case 14:
276
0
                    num_results = 1; goto blend;
277
0
                case 15:
278
0
                    num_results = 2; goto blend;
279
0
                case 16:
280
0
                    num_results = 3; goto blend;
281
0
                case 17:
282
0
                    num_results = 4; goto blend;
283
0
                case 18:
284
0
                    num_results = 6;
285
0
                blend:
286
0
                    code = gs_type1_blend(pcis, csp, num_results);
287
0
                    if (code < 0)
288
0
                        return code;
289
0
                    csp -= code;
290
0
                    continue;
291
14.8k
                default:
292
14.8k
                    break; /* pass to caller */
293
833k
                }
294
833k
                break;
295
833k
            case ce1_pop:
296
820k
                if (pcis->ignore_pops != 0) {
297
820k
                    pcis->ignore_pops--;
298
820k
                    continue;
299
820k
                }
300
1.66M
                return_error(gs_error_rangecheck);
301
1.66M
            }
302
837k
            break;
303
38.4M
        }
304
34.3M
        break;
305
38.4M
    }
306
34.3M
    ipsp->ip = cip, ipsp->dstate = state;
307
34.3M
    pcis->ips_count = ipsp + 1 - &pcis->ipstack[0];
308
34.3M
    pcis->os_count = csp + 1 - &pcis->ostack[0];
309
34.3M
    return c;
310
37.6M
}
311
312
/* ------ Output ------ */
313
314
/* Put 2 or 4 bytes on a stream (big-endian). */
315
static void
316
sputc2(stream *s, int i)
317
9.07M
{
318
9.07M
    sputc(s, (byte)(i >> 8));
319
9.07M
    sputc(s, (byte)i);
320
9.07M
}
321
static void
322
sputc4(stream *s, int i)
323
2.10k
{
324
2.10k
    sputc2(s, i >> 16);
325
2.10k
    sputc2(s, i);
326
2.10k
}
327
328
/* Put a Type 2 operator on a stream. */
329
static void
330
type2_put_op(stream *s, int op)
331
8.46M
{
332
8.46M
    if (op >= CE_OFFSET) {
333
925
        spputc(s, cx_escape);
334
925
        spputc(s, (byte)(op - CE_OFFSET));
335
925
    } else
336
8.45M
        sputc(s, (byte)op);
337
8.46M
}
338
339
/* Put a Type 2 number on a stream. */
340
static void
341
type2_put_int(stream *s, int i)
342
37.1M
{
343
37.1M
    if (i >= -107 && i <= 107)
344
28.0M
        sputc(s, (byte)(i + 139));
345
9.06M
    else if (i <= 1131 && i >= 0)
346
6.31M
        sputc2(s, (c_pos2_0 << 8) + i - 108);
347
2.74M
    else if (i >= -1131 && i < 0)
348
2.74M
        sputc2(s, (c_neg2_0 << 8) - i - 108);
349
1.20k
    else if (i >= -32768 && i <= 32767) {
350
1.20k
        spputc(s, c2_shortint);
351
1.20k
        sputc2(s, i);
352
1.20k
    } else {
353
        /*
354
         * We can't represent this number directly: compute it.
355
         * (This can be done much more efficiently in particular cases;
356
         * we'll do this if it ever seems worthwhile.)
357
         */
358
0
        type2_put_int(s, i >> 10);
359
0
        type2_put_int(s, 1024);
360
0
        type2_put_op(s, CE_OFFSET + ce2_mul);
361
0
        type2_put_int(s, i & 1023);
362
0
        type2_put_op(s, CE_OFFSET + ce2_add);
363
0
    }
364
37.1M
}
365
366
/* Put a fixed value on a stream. */
367
static void
368
type2_put_fixed(stream *s, fixed v)
369
37.1M
{
370
37.1M
    if (fixed_is_int(v))
371
37.1M
        type2_put_int(s, fixed2int_var(v));
372
2.10k
    else if (v >= int2fixed(-32768) && v < int2fixed(32768)) {
373
        /* We can represent this as a 16:16 number. */
374
2.10k
        spputc(s, cx_num4);
375
2.10k
        sputc4(s, v << (16 - _fixed_shift));
376
2.10k
    } else {
377
0
        type2_put_int(s, fixed2int_var(v));
378
0
        type2_put_fixed(s, fixed_fraction(v));
379
0
        type2_put_op(s, CE_OFFSET + ce2_add);
380
0
    }
381
37.1M
}
382
383
/* Put a stem hint table on a stream. */
384
static void
385
type2_put_stems(stream *s, int os_count, const cv_stem_hint_table *psht, int op)
386
1.40M
{
387
1.40M
    fixed prev = 0;
388
1.40M
    int pushed = os_count;
389
1.40M
    int i;
390
391
4.39M
    for (i = 0; i < psht->count; ++i, pushed += 2) {
392
2.98M
        fixed v0 = psht->data[i].v0;
393
2.98M
        fixed v1 = psht->data[i].v1;
394
395
2.98M
        if (pushed > ostack_size - 2) {
396
0
            type2_put_op(s, op);
397
0
            pushed = 0;
398
0
        }
399
2.98M
        type2_put_fixed(s, v0 - prev);
400
2.98M
        type2_put_fixed(s, v1 - v0);
401
2.98M
        prev = v1;
402
2.98M
    }
403
1.40M
    type2_put_op(s, op);
404
1.40M
}
405
406
/* Put out a hintmask command. */
407
static void
408
type2_put_hintmask(stream *s, const byte *mask, uint size)
409
608k
{
410
608k
    uint ignore;
411
412
608k
    type2_put_op(s, c2_hintmask);
413
608k
    sputs(s, mask, size, &ignore);
414
608k
}
415
416
/* ------ Main program ------ */
417
418
/*
419
 * Convert a Type 1 Charstring to (unencrypted) Type 2.
420
 * For simplicity, we expand all Subrs in-line.
421
 * We still need to optimize the output using these patterns:
422
 *  (vhcurveto hvcurveto)* (vhcurveto hrcurveto | vrcurveto) =>
423
 *    vhcurveto
424
 *  (hvcurveto vhcurveto)* (hvcurveto vrcurveto | hrcurveto) =>
425
 *    hvcurveto
426
 */
427
8.59M
#define MAX_STACK ostack_size
428
int
429
psf_convert_type1_to_type2(stream *s, const gs_glyph_data_t *pgd,
430
                           gs_font_type1 *pfont)
431
844k
{
432
844k
    gs_type1_state cis;
433
844k
    cv_stem_hint_table hstem_hints; /* horizontal stem hints */
434
844k
    cv_stem_hint_table vstem_hints; /* vertical stem hints */
435
844k
    bool first = true;
436
844k
    bool need_moveto = true;
437
844k
    bool replace_hints = false;
438
844k
    bool hints_changed = false;
439
844k
    bool width_on_stack = false;
440
844k
    enum {
441
844k
        dotsection_in = 0,
442
844k
        dotsection_out = -1
443
844k
    } dotsection_flag = dotsection_out;
444
844k
    byte active_hints[(max_total_stem_hints + 7) / 8];
445
844k
    byte dot_save_hints[(max_total_stem_hints + 7) / 8];
446
844k
    uint hintmask_size;
447
844k
#define HINTS_CHANGED()\
448
4.39M
  BEGIN\
449
4.39M
    hints_changed = replace_hints;\
450
4.39M
    if (hints_changed)\
451
4.39M
        CHECK_OP();   /* see below */\
452
4.39M
  END
453
844k
#define CHECK_HINTS_CHANGED()\
454
6.64M
  BEGIN\
455
6.64M
    if (hints_changed) {\
456
608k
        type2_put_hintmask(s, active_hints, hintmask_size);\
457
608k
        hints_changed = false;\
458
608k
    }\
459
6.64M
  END
460
    /*
461
     * In order to combine Type 1 operators, we usually delay writing
462
     * out operators (but not their operands).  We must keep track of
463
     * the stack depth so we don't exceed it when combining operators.
464
     */
465
844k
    int depth;      /* of operands on stack */
466
844k
    int prev_op;    /* operator to write, -1 if none */
467
844k
#define CLEAR_OP()\
468
6.44M
  (depth = 0, prev_op = -1)
469
844k
#define CHECK_OP()\
470
11.9M
  BEGIN\
471
11.9M
    if (prev_op >= 0) {\
472
5.60M
        type2_put_op(s, prev_op);\
473
5.60M
        CLEAR_OP();\
474
5.60M
    }\
475
11.9M
  END
476
844k
    fixed mx0 = 0, my0 = 0; /* See ce1_setcurrentpoint. */
477
478
    /* Really this is to silence Coverity, but it makes sense and we do it a lot so no penatly */
479
844k
    memset(active_hints, 0, (max_total_stem_hints + 7) / 8);
480
481
    /* In case we do not get an sbw or hsbw op */
482
844k
    cis.lsb.x = cis.lsb.y = cis.width.x = cis.width.y = fixed_0;
483
484
    /*
485
     * Do a first pass to collect hints.  Note that we must also process
486
     * [h]sbw, because the hint coordinates are relative to the lsb.
487
     */
488
844k
    hstem_hints.count = hstem_hints.replaced_count = hstem_hints.current = 0;
489
844k
    vstem_hints.count = vstem_hints.replaced_count = vstem_hints.current = 0;
490
844k
    type1_next_init(&cis, pgd, pfont);
491
17.1M
    for (;;) {
492
17.1M
        int c = type1_next(&cis);
493
17.1M
        fixed *csp = &cis.ostack[cis.os_count - 1];
494
495
17.1M
        switch (c) {
496
11.0M
        default:
497
             /* We used to treat buffer overrun as a simple invalid font, now we assume that
498
             * there is an implicit endchar, this is handled by looking for a specific error.
499
             * Part of bug #693170 where the fonts are invalid (no endchar on some glyphs).
500
             */
501
11.0M
           if (c == gs_error_unknownerror)
502
0
                break;
503
11.0M
            if (c < 0)
504
1
                return c;
505
11.0M
            type1_clear(&cis);
506
11.0M
            continue;
507
844k
        case c1_hsbw:
508
844k
            gs_type1_sbw(&cis, cis.ostack[0], fixed_0, cis.ostack[1], fixed_0);
509
844k
            goto clear;
510
2.36M
        case cx_hstem:
511
2.36M
            type1_stem1(&cis, &hstem_hints, csp - 1, cis.lsb.y, NULL);
512
2.36M
            goto clear;
513
1.61M
        case cx_vstem:
514
1.61M
            type1_stem1(&cis, &vstem_hints, csp - 1, cis.lsb.x, NULL);
515
1.61M
            goto clear;
516
0
        case CE_OFFSET + ce1_sbw:
517
0
            gs_type1_sbw(&cis, cis.ostack[0], cis.ostack[1],
518
0
                         cis.ostack[2], cis.ostack[3]);
519
0
            goto clear;
520
904
        case CE_OFFSET + ce1_vstem3:
521
904
            type1_stem3(&cis, &vstem_hints, csp - 5, cis.lsb.x, NULL);
522
904
            goto clear;
523
9
        case CE_OFFSET + ce1_hstem3:
524
9
            type1_stem3(&cis, &hstem_hints, csp - 5, cis.lsb.y, NULL);
525
4.83M
        clear:
526
4.83M
            type1_clear(&cis);
527
4.83M
            continue;
528
416k
        case ce1_callothersubr:
529
416k
            if (*csp == int2fixed(3))
530
408k
                replace_hints = true;
531
416k
            if (*csp == int2fixed(12) || *csp == int2fixed(13))
532
0
                cis.os_count -= fixed2int(csp[-1]);
533
416k
            cis.os_count -= 2;
534
416k
            continue;
535
90
        case CE_OFFSET + ce1_dotsection:
536
90
            replace_hints = true;
537
90
            continue;
538
0
        case CE_OFFSET + ce1_seac:
539
844k
        case cx_endchar:
540
844k
            break;
541
17.1M
        }
542
844k
        break;
543
17.1M
    }
544
    /*
545
     * Number the hints for hintmask.  We must do this even if we never
546
     * replace hints, because type1_stem# uses the index to set bits in
547
     * active_hints.
548
     */
549
844k
    {
550
844k
        int i;
551
552
2.69M
        for (i = 0; i < hstem_hints.count; ++i)
553
1.85M
            hstem_hints.data[i].index = i;
554
1.97M
        for (i = 0; i < vstem_hints.count; ++i)
555
1.13M
            vstem_hints.data[i].index = i + hstem_hints.count;
556
844k
    }
557
844k
    if (replace_hints) {
558
200k
        hintmask_size =
559
200k
            (hstem_hints.count + vstem_hints.count + 7) / 8;
560
200k
        memset(active_hints, 0, hintmask_size);
561
200k
    } else
562
644k
        hintmask_size = 0;
563
564
    /* Do a second pass to write the result. */
565
844k
    type1_next_init(&cis, pgd, pfont);
566
844k
    CLEAR_OP();
567
17.1M
    for (;;) {
568
17.1M
        int c = type1_next(&cis);
569
17.1M
        fixed *csp = &cis.ostack[cis.os_count - 1];
570
17.1M
#define POP(n)\
571
17.1M
  (csp -= (n), cis.os_count -= (n))
572
17.1M
        int i;
573
17.1M
        fixed mx, my;
574
575
17.1M
        if (need_moveto && ((c >= cx_rlineto && c <= cx_rrcurveto) ||
576
5.68M
            c == cx_vhcurveto || c == cx_hvcurveto))
577
0
        {
578
0
            mx = my = 0;
579
0
            need_moveto = false;
580
0
            CHECK_OP();
581
0
            if (first) {
582
0
                if (width_on_stack) {
583
0
                    type2_put_fixed(s, *csp); /* width */
584
                    /* We need to move all the stored numeric values up by
585
                     * one in the stack, eliminating the width, so that later
586
                     * processing when we handle the drswing operator emits the correct
587
                     * values. This is different to the 'move' case below.
588
                     */
589
0
                    cis.os_count--;
590
0
                    for (i = 0; i < cis.os_count; ++i)
591
0
                        cis.ostack[i] = cis.ostack[i+1];
592
0
                }
593
0
                mx += cis.lsb.x + mx0, my += cis.lsb.y + my0;
594
0
                first = false;
595
0
            }
596
0
            CHECK_HINTS_CHANGED();
597
0
            if (mx == 0) {
598
0
                type2_put_fixed(s, my);
599
0
                depth = 1, prev_op = cx_vmoveto;
600
0
            } else if (my == 0) {
601
0
                type2_put_fixed(s, mx);
602
0
                depth = 1, prev_op = cx_hmoveto;
603
0
            } else {
604
0
                type2_put_fixed(s, mx);
605
0
                type2_put_fixed(s, my);
606
0
                depth = 2, prev_op = cx_rmoveto;
607
0
            }
608
0
        }
609
610
17.1M
        switch (c) {
611
0
        default:
612
             /* We used to treat buffer overrun as a simple invalid font, now we assume that
613
             * there is an implicit endchar, this is handled by looking for a specific error.
614
             * Part of bug #693170 where the fonts are invalid (no endchar on some glyphs).
615
             */
616
0
            if (c == gs_error_unknownerror) {
617
0
                type2_put_op(s, cx_endchar);
618
0
                return 0;
619
0
            }
620
0
            if (c < 0)
621
0
                return c;
622
0
            if (c >= CE_OFFSET)
623
0
                return_error(gs_error_rangecheck);
624
            /* The Type 1 use of all other operators is the same in Type 2. */
625
4.55M
        copy:
626
4.55M
            CHECK_OP();
627
4.55M
            CHECK_HINTS_CHANGED();
628
8.98M
        put:
629
37.3M
            for (i = 0; i < cis.os_count; ++i)
630
28.3M
                type2_put_fixed(s, cis.ostack[i]);
631
8.98M
            depth += cis.os_count;
632
8.98M
            prev_op = c;
633
8.98M
            type1_clear(&cis);
634
8.98M
            continue;
635
2.36M
        case cx_hstem:
636
2.36M
            type1_stem1(&cis, &hstem_hints, csp - 1, cis.lsb.y, active_hints);
637
3.98M
        hint:
638
3.98M
            HINTS_CHANGED();
639
3.98M
            type1_clear(&cis);
640
3.98M
            continue;
641
1.61M
        case cx_vstem:
642
1.61M
            type1_stem1(&cis, &vstem_hints, csp - 1, cis.lsb.x, active_hints);
643
1.61M
            goto hint;
644
904
        case CE_OFFSET + ce1_vstem3:
645
904
            type1_stem3(&cis, &vstem_hints, csp - 5, cis.lsb.x, active_hints);
646
904
            goto hint;
647
9
        case CE_OFFSET + ce1_hstem3:
648
9
            type1_stem3(&cis, &hstem_hints, csp - 5, cis.lsb.y, active_hints);
649
9
            goto hint;
650
90
        case CE_OFFSET + ce1_dotsection:
651
90
            if (dotsection_flag == dotsection_out) {
652
54
                memcpy(dot_save_hints, active_hints, hintmask_size);
653
54
                memset(active_hints, 0, hintmask_size);
654
54
                dotsection_flag = dotsection_in;
655
54
            } else {
656
36
                memcpy(active_hints, dot_save_hints, hintmask_size);
657
36
                dotsection_flag = dotsection_out;
658
36
            }
659
90
            HINTS_CHANGED();
660
90
            continue;
661
1.04M
        case c1_closepath:
662
1.04M
            need_moveto = true;
663
1.04M
            continue;
664
925
        case CE_OFFSET + ce1_setcurrentpoint:
665
925
            if (first) {
666
                /*  A workaround for fonts which use ce1_setcurrentpoint
667
                    in an illegal way for shifting a path.
668
                    See t1_hinter__setcurrentpoint for more information. */
669
0
                mx0 = csp[-1], my0 = *csp;
670
0
            }
671
925
            continue;
672
193k
        case cx_vmoveto:
673
193k
            mx = 0, my = *csp;
674
193k
            POP(1); goto move;
675
58.8k
        case cx_hmoveto:
676
58.8k
            mx = *csp, my = 0;
677
58.8k
            POP(1); goto move;
678
796k
        case cx_rmoveto:
679
796k
            mx = csp[-1], my = *csp;
680
796k
            POP(2);
681
1.04M
        move:
682
1.04M
            need_moveto = false;
683
1.04M
            CHECK_OP();
684
1.04M
            if (first) {
685
772k
                if (cis.os_count)
686
2.05k
                    type2_put_fixed(s, *csp); /* width */
687
772k
                mx += cis.lsb.x + mx0, my += cis.lsb.y + my0;
688
772k
                first = false;
689
772k
            }
690
1.04M
            if (cis.flex_count != flex_max) {
691
                /* We're accumulating points for a flex. */
692
6.47k
                if (type1_next(&cis) != ce1_callothersubr)
693
0
                    return_error(gs_error_rangecheck);
694
6.47k
                csp = &cis.ostack[cis.os_count - 1];
695
6.47k
                if (*csp != int2fixed(2) || csp[-1] != fixed_0)
696
0
                    return_error(gs_error_rangecheck);
697
6.47k
                cis.flex_count++;
698
6.47k
                csp[-1] = mx, *csp = my;
699
6.47k
                continue;
700
6.47k
            }
701
1.04M
            CHECK_HINTS_CHANGED();
702
1.04M
            if (mx == 0) {
703
68.5k
                type2_put_fixed(s, my);
704
68.5k
                depth = 1, prev_op = cx_vmoveto;
705
974k
            } else if (my == 0) {
706
78.3k
                type2_put_fixed(s, mx);
707
78.3k
                depth = 1, prev_op = cx_hmoveto;
708
896k
            } else {
709
896k
                type2_put_fixed(s, mx);
710
896k
                type2_put_fixed(s, my);
711
896k
                depth = 2, prev_op = cx_rmoveto;
712
896k
            }
713
1.04M
            type1_clear(&cis);
714
1.04M
            continue;
715
844k
        case c1_hsbw:
716
844k
            gs_type1_sbw(&cis, cis.ostack[0], fixed_0, cis.ostack[1], fixed_0);
717
            /*
718
             * Leave the l.s.b. on the operand stack for the initial hint,
719
             * moveto, or endchar command.
720
             */
721
844k
            cis.ostack[0] = cis.ostack[1];
722
844k
        sbw:
723
            /* cff_write_Private doesn't write defaultWidthX
724
               when called with the Type 1 font,
725
               so the reader will assume
726
               defaultWidthX = defaultWidthX_DEFAULT
727
               Use the latter here.
728
             */
729
844k
            if (cis.ostack[0] == default_defaultWidthX)
730
229
                cis.os_count = 0;
731
844k
            else {
732
844k
                cis.ostack[0] -= default_defaultWidthX;
733
844k
                cis.os_count = 1;
734
844k
                width_on_stack = true;
735
844k
            }
736
844k
            if (hstem_hints.count) {
737
765k
                if (cis.os_count)
738
765k
                    type2_put_fixed(s, cis.ostack[0]);
739
765k
                type2_put_stems(s, cis.os_count, &hstem_hints,
740
765k
                                (replace_hints ? c2_hstemhm : cx_hstem));
741
765k
                cis.os_count = 0;
742
765k
                width_on_stack = false;
743
765k
            }
744
844k
            if (vstem_hints.count) {
745
642k
                if (cis.os_count)
746
5.06k
                    type2_put_fixed(s, cis.ostack[0]);
747
642k
                type2_put_stems(s, cis.os_count, &vstem_hints,
748
642k
                                (replace_hints ? c2_vstemhm : cx_vstem));
749
642k
                cis.os_count = 0;
750
642k
                width_on_stack = false;
751
642k
            }
752
844k
            continue;
753
0
        case CE_OFFSET + ce1_seac:
754
            /*
755
             * It is an undocumented feature of the Type 2 CharString
756
             * format that endchar + 4 or 5 operands is equivalent to
757
             * seac with an implicit asb operand + endchar with 0 or 1
758
             * operands.  Remove the asb argument from the stack, but
759
             * adjust the adx argument to compensate for the fact that
760
             * Type 2 CharStrings don't have any concept of l.s.b.
761
             */
762
0
            csp[-3] += cis.lsb.x - csp[-4];
763
0
            memmove(csp - 4, csp - 3, sizeof(*csp) * 4);
764
0
            POP(1);
765
            /* (falls through) */
766
844k
        case cx_endchar:
767
844k
            CHECK_OP();
768
917k
            for (i = 0; i < cis.os_count; ++i)
769
72.3k
                type2_put_fixed(s, cis.ostack[i]);
770
844k
            type2_put_op(s, cx_endchar);
771
844k
            return 0;
772
0
        case CE_OFFSET + ce1_sbw:
773
0
            gs_type1_sbw(&cis, cis.ostack[0], cis.ostack[1],
774
0
                         cis.ostack[2], cis.ostack[3]);
775
0
            cis.ostack[0] = cis.ostack[2];
776
0
            goto sbw;
777
410k
        case ce1_callothersubr:
778
410k
            CHECK_OP();
779
410k
            switch (fixed2int_var(*csp)) {
780
0
            default:
781
0
                return_error(gs_error_rangecheck);
782
925
            case 0:
783
                /*
784
                 * The operand stack contains: delta to reference point,
785
                 * 6 deltas for the two curves, fd, final point, 3, 0.
786
                 */
787
925
                csp[-18] += csp[-16], csp[-17] += csp[-15];
788
925
                memmove(csp - 16, csp - 14, sizeof(*csp) * 11);
789
925
                cis.os_count -= 6, csp -= 6;
790
                /*
791
                 * We could optimize by using [h]flex[1],
792
                 * but it isn't worth the trouble.
793
                 */
794
925
                c = CE_OFFSET + ce2_flex;
795
925
                cis.flex_count = flex_max; /* not inside flex */
796
925
                cis.ignore_pops = 2;
797
925
                goto copy;
798
925
            case 1:
799
925
                cis.flex_count = 0;
800
925
                cis.os_count -= 2;
801
925
                continue;
802
            /*case 2:*/   /* detected in *moveto */
803
408k
            case 3:
804
408k
                memset(active_hints, 0, hintmask_size);
805
408k
                HINTS_CHANGED();
806
408k
                cis.ignore_pops = 1;
807
408k
                cis.os_count -= 2;
808
408k
                continue;
809
0
            case 12:
810
0
            case 13:
811
                /* Counter control is not implemented. */
812
0
                cis.os_count -= 2 + fixed2int(csp[-1]);
813
0
                continue;
814
410k
            }
815
            /*
816
             * The remaining cases are strictly for optimization.
817
             */
818
918k
        case cx_rlineto:
819
918k
            if (depth > MAX_STACK - 2)
820
108
                goto copy;
821
918k
            switch (prev_op) {
822
268k
            case cx_rlineto:  /* rlineto+ => rlineto */
823
268k
                goto put;
824
77.4k
            case cx_rrcurveto:  /* rrcurveto+ rlineto => rcurveline */
825
77.4k
                c = c2_rcurveline;
826
77.4k
                goto put;
827
572k
            default:
828
572k
                goto copy;
829
918k
            }
830
1.82M
        case cx_hlineto:  /* hlineto (vlineto hlineto)* [vlineto] => hlineto */
831
1.82M
            if (depth > MAX_STACK - 1 ||
832
1.82M
                prev_op != (depth & 1 ? cx_vlineto : cx_hlineto))
833
930k
                goto copy;
834
898k
            c = prev_op;
835
898k
            goto put;
836
1.68M
        case cx_vlineto:  /* vlineto (hlineto vlineto)* [hlineto] => vlineto */
837
1.68M
            if (depth > MAX_STACK - 1 ||
838
1.68M
                prev_op != (depth & 1 ? cx_hlineto : cx_vlineto))
839
765k
                goto copy;
840
922k
            c = prev_op;
841
922k
            goto put;
842
867k
        case cx_hvcurveto: /* hvcurveto (vhcurveto hvcurveto)* => hvcurveto */
843
                                /* (vhcurveto hvcurveto)+ => vhcurveto  */
844
            /*
845
             * We have to check (depth & 1) because the last curve might
846
             * have 5 parameters rather than 4 (see rrcurveto below).
847
             */
848
867k
            if ((depth & 1) || depth > MAX_STACK - 4 ||
849
867k
                prev_op != (depth & 4 ? cx_vhcurveto : cx_hvcurveto))
850
605k
                goto copy;
851
262k
            c = prev_op;
852
262k
            goto put;
853
958k
        case cx_vhcurveto: /* vhcurveto (hvcurveto vhcurveto)* => vhcurveto */
854
                                /* (hvcurveto vhcurveto)+ => hvcurveto  */
855
            /* See above re the (depth & 1) check. */
856
958k
            if ((depth & 1) || depth > MAX_STACK - 4 ||
857
958k
                prev_op != (depth & 4 ? cx_hvcurveto : cx_vhcurveto))
858
457k
                goto copy;
859
501k
            c = prev_op;
860
501k
            goto put;
861
2.72M
        case cx_rrcurveto:
862
2.72M
            if (depth == 0) {
863
164k
                if (csp[-1] == 0) {
864
                    /* A|0 B C D 0 F rrcurveto => [A] B C D F vvcurveto */
865
20.4k
                    c = c2_vvcurveto;
866
20.4k
                    csp[-1] = csp[0];
867
20.4k
                    if (csp[-5] == 0) {
868
11
                        memmove(csp - 5, csp - 4, sizeof(*csp) * 4);
869
11
                        POP(2);
870
11
                    } else
871
20.4k
                        POP(1);
872
144k
                } else if (*csp == 0) {
873
                    /* A B|0 C D E 0 rrcurveto => [B] A C D E hhcurveto */
874
64.7k
                    c = c2_hhcurveto;
875
64.7k
                    if (csp[-4] == 0) {
876
0
                        memmove(csp - 4, csp - 3, sizeof(*csp) * 3);
877
0
                        POP(2);
878
64.7k
                    } else {
879
64.7k
                        *csp = csp[-5], csp[-5] = csp[-4], csp[-4] = *csp;
880
64.7k
                        POP(1);
881
64.7k
                    }
882
64.7k
                }
883
                /*
884
                 * We could also optimize:
885
                 *   0 B C D E F|0 rrcurveto => B C D E [F] vhcurveto
886
                 *   A 0 C D E|0 F rrcurveto => A C D F [E] hvcurveto
887
                 * but this gets in the way of subsequent optimization
888
                 * of multiple rrcurvetos, so we don't do it.
889
                 */
890
164k
                goto copy;
891
164k
            }
892
2.55M
            if (depth > MAX_STACK - 6)
893
2.39k
                goto copy;
894
2.55M
            switch (prev_op) {
895
42.4k
            case c2_hhcurveto:  /* hrcurveto (x1 0 x2 y2 x3 0 rrcurveto)* => */
896
                                /* hhcurveto */
897
42.4k
                if (csp[-4] == 0 && *csp == 0) {
898
0
                    memmove(csp - 4, csp - 3, sizeof(*csp) * 3);
899
0
                    c = prev_op;
900
0
                    POP(2);
901
0
                    goto put;
902
0
                }
903
42.4k
                goto copy;
904
42.4k
            case c2_vvcurveto:  /* rvcurveto (0 y1 x2 y2 0 y3 rrcurveto)* => */
905
                                /* vvcurveto */
906
14.2k
                if (csp[-5] == 0 && csp[-1] == 0) {
907
0
                    memmove(csp - 5, csp - 4, sizeof(*csp) * 3);
908
0
                    csp[-2] = *csp;
909
0
                    c = prev_op;
910
0
                    POP(2);
911
0
                    goto put;
912
0
                }
913
14.2k
                goto copy;
914
344k
            case cx_hvcurveto:
915
344k
                if (depth & 1)
916
67.2k
                    goto copy;
917
277k
                if (!(depth & 4))
918
152k
                    goto hrc;
919
141k
            vrc:  /* (vhcurveto hvcurveto)+ vrcurveto => vhcurveto */
920
                /* hvcurveto (vhcurveto hvcurveto)* vrcurveto => hvcurveto */
921
141k
                if (csp[-5] != 0)
922
357
                    goto copy;
923
141k
                memmove(csp - 5, csp - 4, sizeof(*csp) * 5);
924
141k
                c = prev_op;
925
141k
                POP(1);
926
141k
                goto put;
927
408k
            case cx_vhcurveto:
928
408k
                if (depth & 1)
929
133k
                    goto copy;
930
274k
                if (!(depth & 4))
931
16.3k
                    goto vrc;
932
410k
            hrc:  /* (hvcurveto vhcurveto)+ hrcurveto => hvcurveto */
933
                /* vhcurveto (hvcurveto vhcurveto)* hrcurveto => vhcurveto */
934
410k
                if (csp[-4] != 0)
935
2.11k
                    goto copy;
936
                /* A 0 C D E F => A C D F E */
937
407k
                memmove(csp - 4, csp - 3, sizeof(*csp) * 2);
938
407k
                csp[-2] = *csp;
939
407k
                c = prev_op;
940
407k
                POP(1);
941
407k
                goto put;
942
170k
            case cx_rlineto:  /* rlineto+ rrcurveto => rlinecurve */
943
170k
                c = c2_rlinecurve;
944
170k
                goto put;
945
775k
            case cx_rrcurveto:  /* rrcurveto+ => rrcurveto */
946
775k
                goto put;
947
798k
            default:
948
798k
                goto copy;
949
2.55M
            }
950
17.1M
        }
951
17.1M
    }
952
844k
}