123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279 |
- /* Copyright (C) 1989, 1995, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
-
- This software is provided AS-IS with no warranty, either express or
- implied.
-
- This software is distributed under license and may not be copied,
- modified or distributed except as expressly authorized under the terms
- of the license contained in the file LICENSE in this distribution.
-
- For more information about licensing, please refer to
- http://www.ghostscript.com/licensing/. For information on
- commercial licensing, go to http://www.artifex.com/licensing/ or
- contact Artifex Software, Inc., 101 Lucas Valley Road #110,
- San Rafael, CA 94903, U.S.A., +1(415)492-9861.
- */
- /* $Id: zpath1.c,v 1.5 2002/06/16 03:43:51 lpd Exp $ */
- /* PostScript Level 1 additional path operators */
- #include "memory_.h"
- #include "ghost.h"
- #include "oper.h"
- #include "oparc.h" /* for prototypes */
- #include "estack.h" /* for pathforall */
- #include "ialloc.h"
- #include "igstate.h"
- #include "gsstruct.h"
- #include "gspath.h"
- #include "store.h"
- /* Forward references */
- private int common_arc(i_ctx_t *,
- int (*)(gs_state *, floatp, floatp, floatp, floatp, floatp));
- private int common_arct(i_ctx_t *, float *);
- /* <x> <y> <r> <ang1> <ang2> arc - */
- int
- zarc(i_ctx_t *i_ctx_p)
- {
- return common_arc(i_ctx_p, gs_arc);
- }
- /* <x> <y> <r> <ang1> <ang2> arcn - */
- int
- zarcn(i_ctx_t *i_ctx_p)
- {
- return common_arc(i_ctx_p, gs_arcn);
- }
- /* Common code for arc[n] */
- private int
- common_arc(i_ctx_t *i_ctx_p,
- int (*aproc)(gs_state *, floatp, floatp, floatp, floatp, floatp))
- {
- os_ptr op = osp;
- double xyra[5]; /* x, y, r, ang1, ang2 */
- int code = num_params(op, 5, xyra);
- if (code < 0)
- return code;
- code = (*aproc)(igs, xyra[0], xyra[1], xyra[2], xyra[3], xyra[4]);
- if (code >= 0)
- pop(5);
- return code;
- }
- /* <x1> <y1> <x2> <y2> <r> arct - */
- int
- zarct(i_ctx_t *i_ctx_p)
- {
- int code = common_arct(i_ctx_p, (float *)0);
- if (code < 0)
- return code;
- pop(5);
- return 0;
- }
- /* <x1> <y1> <x2> <y2> <r> arcto <xt1> <yt1> <xt2> <yt2> */
- private int
- zarcto(i_ctx_t *i_ctx_p)
- {
- os_ptr op = osp;
- float tanxy[4]; /* xt1, yt1, xt2, yt2 */
- int code = common_arct(i_ctx_p, tanxy);
- if (code < 0)
- return code;
- make_real(op - 4, tanxy[0]);
- make_real(op - 3, tanxy[1]);
- make_real(op - 2, tanxy[2]);
- make_real(op - 1, tanxy[3]);
- pop(1);
- return 0;
- }
- /* Common code for arct[o] */
- private int
- common_arct(i_ctx_t *i_ctx_p, float *tanxy)
- {
- os_ptr op = osp;
- double args[5]; /* x1, y1, x2, y2, r */
- int code = num_params(op, 5, args);
- if (code < 0)
- return code;
- return gs_arcto(igs, args[0], args[1], args[2], args[3], args[4], tanxy);
- }
- /* - .dashpath - */
- private int
- zdashpath(i_ctx_t *i_ctx_p)
- {
- return gs_dashpath(igs);
- }
- /* - flattenpath - */
- private int
- zflattenpath(i_ctx_t *i_ctx_p)
- {
- return gs_flattenpath(igs);
- }
- /* - reversepath - */
- private int
- zreversepath(i_ctx_t *i_ctx_p)
- {
- return gs_reversepath(igs);
- }
- /* - strokepath - */
- private int
- zstrokepath(i_ctx_t *i_ctx_p)
- {
- return gs_strokepath(igs);
- }
- /* - clippath - */
- private int
- zclippath(i_ctx_t *i_ctx_p)
- {
- return gs_clippath(igs);
- }
- /* <bool> .pathbbox <llx> <lly> <urx> <ury> */
- private int
- zpathbbox(i_ctx_t *i_ctx_p)
- {
- os_ptr op = osp;
- gs_rect box;
- int code;
- check_type(*op, t_boolean);
- code = gs_upathbbox(igs, &box, op->value.boolval);
- if (code < 0)
- return code;
- push(3);
- make_real(op - 3, box.p.x);
- make_real(op - 2, box.p.y);
- make_real(op - 1, box.q.x);
- make_real(op, box.q.y);
- return 0;
- }
- /* <moveproc> <lineproc> <curveproc> <closeproc> pathforall - */
- private int path_continue(i_ctx_t *);
- private int path_cleanup(i_ctx_t *);
- private int
- zpathforall(i_ctx_t *i_ctx_p)
- {
- os_ptr op = osp;
- gs_path_enum *penum;
- int code;
- check_proc(op[-3]);
- check_proc(op[-2]);
- check_proc(op[-1]);
- check_proc(*op);
- check_estack(8);
- if ((penum = gs_path_enum_alloc(imemory, "pathforall")) == 0)
- return_error(e_VMerror);
- code = gs_path_enum_init(penum, igs);
- if (code < 0) {
- ifree_object(penum, "path_cleanup");
- return code;
- }
- /* Push a mark, the four procedures, and the path enumerator. */
- push_mark_estack(es_for, path_cleanup); /* iterator */
- memcpy(esp + 1, op - 3, 4 * sizeof(ref)); /* 4 procs */
- esp += 5;
- make_istruct(esp, 0, penum);
- push_op_estack(path_continue);
- pop(4);
- op -= 4;
- return o_push_estack;
- }
- /* Continuation procedure for pathforall */
- private void pf_push(i_ctx_t *, gs_point *, int);
- private int
- path_continue(i_ctx_t *i_ctx_p)
- {
- gs_path_enum *penum = r_ptr(esp, gs_path_enum);
- gs_point ppts[3];
- int code;
- /* Make sure we have room on the o-stack for the worst case */
- /* before we enumerate the next path element. */
- check_ostack(6); /* 3 points for curveto */
- code = gs_path_enum_next(penum, ppts);
- switch (code) {
- case 0: /* all done */
- esp -= 6;
- path_cleanup(i_ctx_p);
- return o_pop_estack;
- default: /* error */
- return code;
- case gs_pe_moveto:
- esp[2] = esp[-4]; /* moveto proc */
- pf_push(i_ctx_p, ppts, 1);
- break;
- case gs_pe_lineto:
- esp[2] = esp[-3]; /* lineto proc */
- pf_push(i_ctx_p, ppts, 1);
- break;
- case gs_pe_curveto:
- esp[2] = esp[-2]; /* curveto proc */
- pf_push(i_ctx_p, ppts, 3);
- break;
- case gs_pe_closepath:
- esp[2] = esp[-1]; /* closepath proc */
- break;
- }
- push_op_estack(path_continue);
- ++esp; /* include pushed procedure */
- return o_push_estack;
- }
- /* Internal procedure to push one or more points */
- private void
- pf_push(i_ctx_t *i_ctx_p, gs_point * ppts, int n)
- {
- os_ptr op = osp;
- while (n--) {
- op += 2;
- make_real(op - 1, ppts->x);
- make_real(op, ppts->y);
- ppts++;
- }
- osp = op;
- }
- /* Clean up after a pathforall */
- private int
- path_cleanup(i_ctx_t *i_ctx_p)
- {
- gs_path_enum *penum = r_ptr(esp + 6, gs_path_enum);
- gs_path_enum_cleanup(penum);
- ifree_object(penum, "path_cleanup");
- return 0;
- }
- /* ------ Initialization procedure ------ */
- const op_def zpath1_op_defs[] =
- {
- {"5arc", zarc},
- {"5arcn", zarcn},
- {"5arct", zarct},
- {"5arcto", zarcto},
- {"0clippath", zclippath},
- {"0.dashpath", zdashpath},
- {"0flattenpath", zflattenpath},
- {"4pathforall", zpathforall},
- {"0reversepath", zreversepath},
- {"0strokepath", zstrokepath},
- {"1.pathbbox", zpathbbox},
- /* Internal operators */
- {"0%path_continue", path_continue},
- op_def_end(0)
- };
|