Coverage Report

Created: 2022-10-31 07:00

/src/ghostpdl/psi/zpath1.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
/* PostScript Level 1 additional path operators */
18
#include "memory_.h"
19
#include "ghost.h"
20
#include "oper.h"
21
#include "oparc.h"    /* for prototypes */
22
#include "estack.h"   /* for pathforall */
23
#include "ialloc.h"
24
#include "igstate.h"
25
#include "gsstruct.h"
26
#include "gspath.h"
27
#include "store.h"
28
29
/* Forward references */
30
static int common_arc(i_ctx_t *,
31
          int (*)(gs_gstate *, double, double, double, double, double));
32
static int common_arct(i_ctx_t *, float *);
33
34
/* <x> <y> <r> <ang1> <ang2> arc - */
35
int
36
zarc(i_ctx_t *i_ctx_p)
37
28.2k
{
38
28.2k
    return common_arc(i_ctx_p, gs_arc);
39
28.2k
}
40
41
/* <x> <y> <r> <ang1> <ang2> arcn - */
42
int
43
zarcn(i_ctx_t *i_ctx_p)
44
55
{
45
55
    return common_arc(i_ctx_p, gs_arcn);
46
55
}
47
48
/* Common code for arc[n] */
49
static int
50
common_arc(i_ctx_t *i_ctx_p,
51
      int (*aproc)(gs_gstate *, double, double, double, double, double))
52
28.3k
{
53
28.3k
    os_ptr op = osp;
54
28.3k
    double xyra[5];   /* x, y, r, ang1, ang2 */
55
28.3k
    int code = num_params(op, 5, xyra);
56
57
28.3k
    if (code < 0)
58
35
        return code;
59
28.3k
    code = (*aproc)(igs, xyra[0], xyra[1], xyra[2], xyra[3], xyra[4]);
60
28.3k
    if (code >= 0)
61
28.2k
        pop(5);
62
28.3k
    return code;
63
28.3k
}
64
65
/* <x1> <y1> <x2> <y2> <r> arct - */
66
int
67
zarct(i_ctx_t *i_ctx_p)
68
19
{
69
19
    int code = common_arct(i_ctx_p, (float *)0);
70
71
19
    if (code < 0)
72
19
        return code;
73
0
    pop(5);
74
0
    return 0;
75
19
}
76
77
/* <x1> <y1> <x2> <y2> <r> arcto <xt1> <yt1> <xt2> <yt2> */
78
static int
79
zarcto(i_ctx_t *i_ctx_p)
80
27
{
81
27
    os_ptr op = osp;
82
27
    float tanxy[4];   /* xt1, yt1, xt2, yt2 */
83
27
    int code = common_arct(i_ctx_p, tanxy);
84
85
27
    if (code < 0)
86
27
        return code;
87
0
    make_real(op - 4, tanxy[0]);
88
0
    make_real(op - 3, tanxy[1]);
89
0
    make_real(op - 2, tanxy[2]);
90
0
    make_real(op - 1, tanxy[3]);
91
0
    pop(1);
92
0
    return 0;
93
27
}
94
95
/* Common code for arct[o] */
96
static int
97
common_arct(i_ctx_t *i_ctx_p, float *tanxy)
98
46
{
99
46
    os_ptr op = osp;
100
46
    double args[5];   /* x1, y1, x2, y2, r */
101
46
    int code = num_params(op, 5, args);
102
103
46
    if (code < 0)
104
34
        return code;
105
12
    return gs_arcto(igs, args[0], args[1], args[2], args[3], args[4], tanxy);
106
46
}
107
108
/* - .dashpath - */
109
static int
110
zdashpath(i_ctx_t *i_ctx_p)
111
0
{
112
0
    return gs_dashpath(igs);
113
0
}
114
115
/* - flattenpath - */
116
static int
117
zflattenpath(i_ctx_t *i_ctx_p)
118
1.29k
{
119
1.29k
    return gs_flattenpath(igs);
120
1.29k
}
121
122
/* - reversepath - */
123
static int
124
zreversepath(i_ctx_t *i_ctx_p)
125
43
{
126
43
    return gs_reversepath(igs);
127
43
}
128
129
/* - strokepath - */
130
static int
131
zstrokepath(i_ctx_t *i_ctx_p)
132
121
{
133
121
    return gs_strokepath(igs);
134
121
}
135
136
/* - clippath - */
137
static int
138
zclippath(i_ctx_t *i_ctx_p)
139
4.45k
{
140
4.45k
    return gs_clippath(igs);
141
4.45k
}
142
143
/* <bool> .pathbbox <llx> <lly> <urx> <ury> */
144
static int
145
z1pathbbox(i_ctx_t *i_ctx_p)
146
5.58k
{
147
5.58k
    os_ptr op = osp;
148
5.58k
    gs_rect box;
149
5.58k
    int code;
150
151
5.58k
    check_type(*op, t_boolean);
152
5.58k
    code = gs_upathbbox(igs, &box, op->value.boolval);
153
5.58k
    if (code < 0)
154
14
        return code;
155
5.58k
    push(3);
156
5.56k
    make_real(op - 3, box.p.x);
157
5.56k
    make_real(op - 2, box.p.y);
158
5.56k
    make_real(op - 1, box.q.x);
159
5.56k
    make_real(op, box.q.y);
160
5.56k
    return 0;
161
5.56k
}
162
163
/*
164
 * In order to match Adobe output on a Genoa test, pathbbox must be an
165
 * operator, not an operator procedure, even though it has a trivial
166
 * definition as a procedure.
167
 */
168
static int
169
zpathbbox(i_ctx_t *i_ctx_p)
170
5.58k
{
171
5.58k
    os_ptr op = osp;
172
5.58k
    int code;
173
174
5.58k
    push(1);
175
5.58k
    make_false(op);
176
5.58k
    code = z1pathbbox(i_ctx_p);
177
5.58k
    if (code < 0) {
178
14
        pop(1);      /* remove the Boolean */
179
14
    }
180
5.58k
    return code;
181
5.58k
}
182
183
/* <moveproc> <lineproc> <curveproc> <closeproc> pathforall - */
184
static int path_continue(i_ctx_t *);
185
static int path_cleanup(i_ctx_t *);
186
static int
187
zpathforall(i_ctx_t *i_ctx_p)
188
12
{
189
12
    os_ptr op = osp;
190
12
    gs_path_enum *penum;
191
12
    int code;
192
193
12
    check_proc(op[-3]);
194
12
    check_proc(op[-2]);
195
0
    check_proc(op[-1]);
196
0
    check_proc(*op);
197
0
    check_estack(8);
198
199
0
    if ((penum = gs_path_enum_alloc(imemory, "pathforall")) == 0)
200
0
        return_error(gs_error_VMerror);
201
0
    code = gs_path_enum_init(imemory, penum, igs);
202
0
    if (code < 0) {
203
0
        ifree_object(penum, "path_cleanup");
204
0
        return code;
205
0
    }
206
    /* Push a mark, the four procedures, and the path enumerator. */
207
0
    push_mark_estack(es_for, path_cleanup); /* iterator */
208
0
    memcpy(esp + 1, op - 3, 4 * sizeof(ref)); /* 4 procs */
209
0
    esp += 5;
210
0
    make_istruct(esp, 0, penum);
211
0
    push_op_estack(path_continue);
212
0
    pop(4);
213
0
    op -= 4;
214
0
    return o_push_estack;
215
0
}
216
/* Continuation procedure for pathforall */
217
static void pf_push(i_ctx_t *, gs_point *, int);
218
static int
219
path_continue(i_ctx_t *i_ctx_p)
220
0
{
221
0
    gs_path_enum *penum = r_ptr(esp, gs_path_enum);
222
0
    gs_point ppts[3];
223
0
    int code;
224
225
    /* Make sure we have room on the o-stack for the worst case */
226
    /* before we enumerate the next path element. */
227
0
    check_ostack(6);   /* 3 points for curveto */
228
0
    code = gs_path_enum_next(penum, ppts);
229
0
    switch (code) {
230
0
        case 0:   /* all done */
231
0
            esp -= 6;
232
0
            path_cleanup(i_ctx_p);
233
0
            return o_pop_estack;
234
0
        default:    /* error */
235
0
            esp -= 6;
236
0
            path_cleanup(i_ctx_p);
237
0
            return code;
238
0
        case gs_pe_moveto:
239
0
            esp[2] = esp[-4]; /* moveto proc */
240
0
            pf_push(i_ctx_p, ppts, 1);
241
0
            break;
242
0
        case gs_pe_lineto:
243
0
            esp[2] = esp[-3]; /* lineto proc */
244
0
            pf_push(i_ctx_p, ppts, 1);
245
0
            break;
246
0
        case gs_pe_curveto:
247
0
            esp[2] = esp[-2]; /* curveto proc */
248
0
            pf_push(i_ctx_p, ppts, 3);
249
0
            break;
250
0
        case gs_pe_closepath:
251
0
            esp[2] = esp[-1]; /* closepath proc */
252
0
            break;
253
0
    }
254
0
    push_op_estack(path_continue);
255
0
    ++esp;     /* include pushed procedure */
256
0
    return o_push_estack;
257
0
}
258
/* Internal procedure to push one or more points */
259
static void
260
pf_push(i_ctx_t *i_ctx_p, gs_point * ppts, int n)
261
0
{
262
0
    os_ptr op = osp;
263
264
0
    while (n--) {
265
0
        op += 2;
266
0
        make_real(op - 1, ppts->x);
267
0
        make_real(op, ppts->y);
268
0
        ppts++;
269
0
    }
270
0
    osp = op;
271
0
}
272
/* Clean up after a pathforall */
273
static int
274
path_cleanup(i_ctx_t *i_ctx_p)
275
0
{
276
0
    gs_path_enum *penum = r_ptr(esp + 6, gs_path_enum);
277
278
0
    gs_path_enum_cleanup(penum);
279
0
    ifree_object(penum, "path_cleanup");
280
0
    return 0;
281
0
}
282
283
/* ------ Initialization procedure ------ */
284
285
const op_def zpath1_op_defs[] =
286
{
287
    {"5arc", zarc},
288
    {"5arcn", zarcn},
289
    {"5arct", zarct},
290
    {"5arcto", zarcto},
291
    {"0clippath", zclippath},
292
    {"0.dashpath", zdashpath},
293
    {"0flattenpath", zflattenpath},
294
    {"4pathforall", zpathforall},
295
    {"0reversepath", zreversepath},
296
    {"0strokepath", zstrokepath},
297
    {"1.pathbbox", z1pathbbox},
298
    {"0pathbbox", zpathbbox},
299
                /* Internal operators */
300
    {"0%path_continue", path_continue},
301
    op_def_end(0)
302
};