Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/* Copyright (C) 1989, 1995, 1997, 1998, 1999 Aladdin Enterprises.  All rights reserved.
2
 
3
  This software is provided AS-IS with no warranty, either express or
4
  implied.
5
 
6
  This software is distributed under license and may not be copied,
7
  modified or distributed except as expressly authorized under the terms
8
  of the license contained in the file LICENSE in this distribution.
9
 
10
  For more information about licensing, please refer to
11
  http://www.ghostscript.com/licensing/. For information on
12
  commercial licensing, go to http://www.artifex.com/licensing/ or
13
  contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14
  San Rafael, CA  94903, U.S.A., +1(415)492-9861.
15
*/
16
 
17
/* $Id: zpath1.c,v 1.5 2002/06/16 03:43:51 lpd Exp $ */
18
/* PostScript Level 1 additional path operators */
19
#include "memory_.h"
20
#include "ghost.h"
21
#include "oper.h"
22
#include "oparc.h"		/* for prototypes */
23
#include "estack.h"		/* for pathforall */
24
#include "ialloc.h"
25
#include "igstate.h"
26
#include "gsstruct.h"
27
#include "gspath.h"
28
#include "store.h"
29
 
30
/* Forward references */
31
private int common_arc(i_ctx_t *,
32
	  int (*)(gs_state *, floatp, floatp, floatp, floatp, floatp));
33
private int common_arct(i_ctx_t *, float *);
34
 
35
/* <x> <y> <r> <ang1> <ang2> arc - */
36
int
37
zarc(i_ctx_t *i_ctx_p)
38
{
39
    return common_arc(i_ctx_p, gs_arc);
40
}
41
 
42
/* <x> <y> <r> <ang1> <ang2> arcn - */
43
int
44
zarcn(i_ctx_t *i_ctx_p)
45
{
46
    return common_arc(i_ctx_p, gs_arcn);
47
}
48
 
49
/* Common code for arc[n] */
50
private int
51
common_arc(i_ctx_t *i_ctx_p,
52
      int (*aproc)(gs_state *, floatp, floatp, floatp, floatp, floatp))
53
{
54
    os_ptr op = osp;
55
    double xyra[5];		/* x, y, r, ang1, ang2 */
56
    int code = num_params(op, 5, xyra);
57
 
58
    if (code < 0)
59
	return code;
60
    code = (*aproc)(igs, xyra[0], xyra[1], xyra[2], xyra[3], xyra[4]);
61
    if (code >= 0)
62
	pop(5);
63
    return code;
64
}
65
 
66
/* <x1> <y1> <x2> <y2> <r> arct - */
67
int
68
zarct(i_ctx_t *i_ctx_p)
69
{
70
    int code = common_arct(i_ctx_p, (float *)0);
71
 
72
    if (code < 0)
73
	return code;
74
    pop(5);
75
    return 0;
76
}
77
 
78
/* <x1> <y1> <x2> <y2> <r> arcto <xt1> <yt1> <xt2> <yt2> */
79
private int
80
zarcto(i_ctx_t *i_ctx_p)
81
{
82
    os_ptr op = osp;
83
    float tanxy[4];		/* xt1, yt1, xt2, yt2 */
84
    int code = common_arct(i_ctx_p, tanxy);
85
 
86
    if (code < 0)
87
	return code;
88
    make_real(op - 4, tanxy[0]);
89
    make_real(op - 3, tanxy[1]);
90
    make_real(op - 2, tanxy[2]);
91
    make_real(op - 1, tanxy[3]);
92
    pop(1);
93
    return 0;
94
}
95
 
96
/* Common code for arct[o] */
97
private int
98
common_arct(i_ctx_t *i_ctx_p, float *tanxy)
99
{
100
    os_ptr op = osp;
101
    double args[5];		/* x1, y1, x2, y2, r */
102
    int code = num_params(op, 5, args);
103
 
104
    if (code < 0)
105
	return code;
106
    return gs_arcto(igs, args[0], args[1], args[2], args[3], args[4], tanxy);
107
}
108
 
109
/* - .dashpath - */
110
private int
111
zdashpath(i_ctx_t *i_ctx_p)
112
{
113
    return gs_dashpath(igs);
114
}
115
 
116
/* - flattenpath - */
117
private int
118
zflattenpath(i_ctx_t *i_ctx_p)
119
{
120
    return gs_flattenpath(igs);
121
}
122
 
123
/* - reversepath - */
124
private int
125
zreversepath(i_ctx_t *i_ctx_p)
126
{
127
    return gs_reversepath(igs);
128
}
129
 
130
/* - strokepath - */
131
private int
132
zstrokepath(i_ctx_t *i_ctx_p)
133
{
134
    return gs_strokepath(igs);
135
}
136
 
137
/* - clippath - */
138
private int
139
zclippath(i_ctx_t *i_ctx_p)
140
{
141
    return gs_clippath(igs);
142
}
143
 
144
/* <bool> .pathbbox <llx> <lly> <urx> <ury> */
145
private int
146
zpathbbox(i_ctx_t *i_ctx_p)
147
{
148
    os_ptr op = osp;
149
    gs_rect box;
150
    int code;
151
 
152
    check_type(*op, t_boolean);
153
    code = gs_upathbbox(igs, &box, op->value.boolval);
154
    if (code < 0)
155
	return code;
156
    push(3);
157
    make_real(op - 3, box.p.x);
158
    make_real(op - 2, box.p.y);
159
    make_real(op - 1, box.q.x);
160
    make_real(op, box.q.y);
161
    return 0;
162
}
163
 
164
/* <moveproc> <lineproc> <curveproc> <closeproc> pathforall - */
165
private int path_continue(i_ctx_t *);
166
private int path_cleanup(i_ctx_t *);
167
private int
168
zpathforall(i_ctx_t *i_ctx_p)
169
{
170
    os_ptr op = osp;
171
    gs_path_enum *penum;
172
    int code;
173
 
174
    check_proc(op[-3]);
175
    check_proc(op[-2]);
176
    check_proc(op[-1]);
177
    check_proc(*op);
178
    check_estack(8);
179
    if ((penum = gs_path_enum_alloc(imemory, "pathforall")) == 0)
180
	return_error(e_VMerror);
181
    code = gs_path_enum_init(penum, igs);
182
    if (code < 0) {
183
	ifree_object(penum, "path_cleanup");
184
	return code;
185
    }
186
    /* Push a mark, the four procedures, and the path enumerator. */
187
    push_mark_estack(es_for, path_cleanup);	/* iterator */
188
    memcpy(esp + 1, op - 3, 4 * sizeof(ref));	/* 4 procs */
189
    esp += 5;
190
    make_istruct(esp, 0, penum);
191
    push_op_estack(path_continue);
192
    pop(4);
193
    op -= 4;
194
    return o_push_estack;
195
}
196
/* Continuation procedure for pathforall */
197
private void pf_push(i_ctx_t *, gs_point *, int);
198
private int
199
path_continue(i_ctx_t *i_ctx_p)
200
{
201
    gs_path_enum *penum = r_ptr(esp, gs_path_enum);
202
    gs_point ppts[3];
203
    int code;
204
 
205
    /* Make sure we have room on the o-stack for the worst case */
206
    /* before we enumerate the next path element. */
207
    check_ostack(6);		/* 3 points for curveto */
208
    code = gs_path_enum_next(penum, ppts);
209
    switch (code) {
210
	case 0:		/* all done */
211
	    esp -= 6;
212
	    path_cleanup(i_ctx_p);
213
	    return o_pop_estack;
214
	default:		/* error */
215
	    return code;
216
	case gs_pe_moveto:
217
	    esp[2] = esp[-4];	/* moveto proc */
218
	    pf_push(i_ctx_p, ppts, 1);
219
	    break;
220
	case gs_pe_lineto:
221
	    esp[2] = esp[-3];	/* lineto proc */
222
	    pf_push(i_ctx_p, ppts, 1);
223
	    break;
224
	case gs_pe_curveto:
225
	    esp[2] = esp[-2];	/* curveto proc */
226
	    pf_push(i_ctx_p, ppts, 3);
227
	    break;
228
	case gs_pe_closepath:
229
	    esp[2] = esp[-1];	/* closepath proc */
230
	    break;
231
    }
232
    push_op_estack(path_continue);
233
    ++esp;			/* include pushed procedure */
234
    return o_push_estack;
235
}
236
/* Internal procedure to push one or more points */
237
private void
238
pf_push(i_ctx_t *i_ctx_p, gs_point * ppts, int n)
239
{
240
    os_ptr op = osp;
241
 
242
    while (n--) {
243
	op += 2;
244
	make_real(op - 1, ppts->x);
245
	make_real(op, ppts->y);
246
	ppts++;
247
    }
248
    osp = op;
249
}
250
/* Clean up after a pathforall */
251
private int
252
path_cleanup(i_ctx_t *i_ctx_p)
253
{
254
    gs_path_enum *penum = r_ptr(esp + 6, gs_path_enum);
255
 
256
    gs_path_enum_cleanup(penum);
257
    ifree_object(penum, "path_cleanup");
258
    return 0;
259
}
260
 
261
/* ------ Initialization procedure ------ */
262
 
263
const op_def zpath1_op_defs[] =
264
{
265
    {"5arc", zarc},
266
    {"5arcn", zarcn},
267
    {"5arct", zarct},
268
    {"5arcto", zarcto},
269
    {"0clippath", zclippath},
270
    {"0.dashpath", zdashpath},
271
    {"0flattenpath", zflattenpath},
272
    {"4pathforall", zpathforall},
273
    {"0reversepath", zreversepath},
274
    {"0strokepath", zstrokepath},
275
    {"1.pathbbox", zpathbbox},
276
		/* Internal operators */
277
    {"0%path_continue", path_continue},
278
    op_def_end(0)
279
};