17dd7cddfSDavid du Colombier /* Copyright (C) 1989, 1995, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
27dd7cddfSDavid du Colombier
3*593dc095SDavid du Colombier This software is provided AS-IS with no warranty, either express or
4*593dc095SDavid du Colombier implied.
57dd7cddfSDavid du Colombier
6*593dc095SDavid du Colombier This software is distributed under license and may not be copied,
7*593dc095SDavid du Colombier modified or distributed except as expressly authorized under the terms
8*593dc095SDavid du Colombier of the license contained in the file LICENSE in this distribution.
97dd7cddfSDavid du Colombier
10*593dc095SDavid du Colombier For more information about licensing, please refer to
11*593dc095SDavid du Colombier http://www.ghostscript.com/licensing/. For information on
12*593dc095SDavid du Colombier commercial licensing, go to http://www.artifex.com/licensing/ or
13*593dc095SDavid du Colombier contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14*593dc095SDavid du Colombier San Rafael, CA 94903, U.S.A., +1(415)492-9861.
157dd7cddfSDavid du Colombier */
167dd7cddfSDavid du Colombier
17*593dc095SDavid du Colombier /* $Id: zpath1.c,v 1.5 2002/06/16 03:43:51 lpd Exp $ */
187dd7cddfSDavid du Colombier /* PostScript Level 1 additional path operators */
197dd7cddfSDavid du Colombier #include "memory_.h"
207dd7cddfSDavid du Colombier #include "ghost.h"
217dd7cddfSDavid du Colombier #include "oper.h"
227dd7cddfSDavid du Colombier #include "oparc.h" /* for prototypes */
237dd7cddfSDavid du Colombier #include "estack.h" /* for pathforall */
247dd7cddfSDavid du Colombier #include "ialloc.h"
257dd7cddfSDavid du Colombier #include "igstate.h"
267dd7cddfSDavid du Colombier #include "gsstruct.h"
277dd7cddfSDavid du Colombier #include "gspath.h"
287dd7cddfSDavid du Colombier #include "store.h"
297dd7cddfSDavid du Colombier
307dd7cddfSDavid du Colombier /* Forward references */
31*593dc095SDavid du Colombier private int common_arc(i_ctx_t *,
32*593dc095SDavid du Colombier int (*)(gs_state *, floatp, floatp, floatp, floatp, floatp));
33*593dc095SDavid du Colombier private int common_arct(i_ctx_t *, float *);
347dd7cddfSDavid du Colombier
357dd7cddfSDavid du Colombier /* <x> <y> <r> <ang1> <ang2> arc - */
367dd7cddfSDavid du Colombier int
zarc(i_ctx_t * i_ctx_p)377dd7cddfSDavid du Colombier zarc(i_ctx_t *i_ctx_p)
387dd7cddfSDavid du Colombier {
397dd7cddfSDavid du Colombier return common_arc(i_ctx_p, gs_arc);
407dd7cddfSDavid du Colombier }
417dd7cddfSDavid du Colombier
427dd7cddfSDavid du Colombier /* <x> <y> <r> <ang1> <ang2> arcn - */
437dd7cddfSDavid du Colombier int
zarcn(i_ctx_t * i_ctx_p)447dd7cddfSDavid du Colombier zarcn(i_ctx_t *i_ctx_p)
457dd7cddfSDavid du Colombier {
467dd7cddfSDavid du Colombier return common_arc(i_ctx_p, gs_arcn);
477dd7cddfSDavid du Colombier }
487dd7cddfSDavid du Colombier
497dd7cddfSDavid du Colombier /* Common code for arc[n] */
507dd7cddfSDavid du Colombier private int
common_arc(i_ctx_t * i_ctx_p,int (* aproc)(gs_state *,floatp,floatp,floatp,floatp,floatp))517dd7cddfSDavid du Colombier common_arc(i_ctx_t *i_ctx_p,
52*593dc095SDavid du Colombier int (*aproc)(gs_state *, floatp, floatp, floatp, floatp, floatp))
537dd7cddfSDavid du Colombier {
547dd7cddfSDavid du Colombier os_ptr op = osp;
557dd7cddfSDavid du Colombier double xyra[5]; /* x, y, r, ang1, ang2 */
567dd7cddfSDavid du Colombier int code = num_params(op, 5, xyra);
577dd7cddfSDavid du Colombier
587dd7cddfSDavid du Colombier if (code < 0)
597dd7cddfSDavid du Colombier return code;
607dd7cddfSDavid du Colombier code = (*aproc)(igs, xyra[0], xyra[1], xyra[2], xyra[3], xyra[4]);
617dd7cddfSDavid du Colombier if (code >= 0)
627dd7cddfSDavid du Colombier pop(5);
637dd7cddfSDavid du Colombier return code;
647dd7cddfSDavid du Colombier }
657dd7cddfSDavid du Colombier
667dd7cddfSDavid du Colombier /* <x1> <y1> <x2> <y2> <r> arct - */
677dd7cddfSDavid du Colombier int
zarct(i_ctx_t * i_ctx_p)687dd7cddfSDavid du Colombier zarct(i_ctx_t *i_ctx_p)
697dd7cddfSDavid du Colombier {
707dd7cddfSDavid du Colombier int code = common_arct(i_ctx_p, (float *)0);
717dd7cddfSDavid du Colombier
727dd7cddfSDavid du Colombier if (code < 0)
737dd7cddfSDavid du Colombier return code;
747dd7cddfSDavid du Colombier pop(5);
757dd7cddfSDavid du Colombier return 0;
767dd7cddfSDavid du Colombier }
777dd7cddfSDavid du Colombier
787dd7cddfSDavid du Colombier /* <x1> <y1> <x2> <y2> <r> arcto <xt1> <yt1> <xt2> <yt2> */
797dd7cddfSDavid du Colombier private int
zarcto(i_ctx_t * i_ctx_p)807dd7cddfSDavid du Colombier zarcto(i_ctx_t *i_ctx_p)
817dd7cddfSDavid du Colombier {
827dd7cddfSDavid du Colombier os_ptr op = osp;
837dd7cddfSDavid du Colombier float tanxy[4]; /* xt1, yt1, xt2, yt2 */
847dd7cddfSDavid du Colombier int code = common_arct(i_ctx_p, tanxy);
857dd7cddfSDavid du Colombier
867dd7cddfSDavid du Colombier if (code < 0)
877dd7cddfSDavid du Colombier return code;
887dd7cddfSDavid du Colombier make_real(op - 4, tanxy[0]);
897dd7cddfSDavid du Colombier make_real(op - 3, tanxy[1]);
907dd7cddfSDavid du Colombier make_real(op - 2, tanxy[2]);
917dd7cddfSDavid du Colombier make_real(op - 1, tanxy[3]);
927dd7cddfSDavid du Colombier pop(1);
937dd7cddfSDavid du Colombier return 0;
947dd7cddfSDavid du Colombier }
957dd7cddfSDavid du Colombier
967dd7cddfSDavid du Colombier /* Common code for arct[o] */
977dd7cddfSDavid du Colombier private int
common_arct(i_ctx_t * i_ctx_p,float * tanxy)987dd7cddfSDavid du Colombier common_arct(i_ctx_t *i_ctx_p, float *tanxy)
997dd7cddfSDavid du Colombier {
1007dd7cddfSDavid du Colombier os_ptr op = osp;
1017dd7cddfSDavid du Colombier double args[5]; /* x1, y1, x2, y2, r */
1027dd7cddfSDavid du Colombier int code = num_params(op, 5, args);
1037dd7cddfSDavid du Colombier
1047dd7cddfSDavid du Colombier if (code < 0)
1057dd7cddfSDavid du Colombier return code;
1067dd7cddfSDavid du Colombier return gs_arcto(igs, args[0], args[1], args[2], args[3], args[4], tanxy);
1077dd7cddfSDavid du Colombier }
1087dd7cddfSDavid du Colombier
1097dd7cddfSDavid du Colombier /* - .dashpath - */
1107dd7cddfSDavid du Colombier private int
zdashpath(i_ctx_t * i_ctx_p)1117dd7cddfSDavid du Colombier zdashpath(i_ctx_t *i_ctx_p)
1127dd7cddfSDavid du Colombier {
1137dd7cddfSDavid du Colombier return gs_dashpath(igs);
1147dd7cddfSDavid du Colombier }
1157dd7cddfSDavid du Colombier
1167dd7cddfSDavid du Colombier /* - flattenpath - */
1177dd7cddfSDavid du Colombier private int
zflattenpath(i_ctx_t * i_ctx_p)1187dd7cddfSDavid du Colombier zflattenpath(i_ctx_t *i_ctx_p)
1197dd7cddfSDavid du Colombier {
1207dd7cddfSDavid du Colombier return gs_flattenpath(igs);
1217dd7cddfSDavid du Colombier }
1227dd7cddfSDavid du Colombier
1237dd7cddfSDavid du Colombier /* - reversepath - */
1247dd7cddfSDavid du Colombier private int
zreversepath(i_ctx_t * i_ctx_p)1257dd7cddfSDavid du Colombier zreversepath(i_ctx_t *i_ctx_p)
1267dd7cddfSDavid du Colombier {
1277dd7cddfSDavid du Colombier return gs_reversepath(igs);
1287dd7cddfSDavid du Colombier }
1297dd7cddfSDavid du Colombier
1307dd7cddfSDavid du Colombier /* - strokepath - */
1317dd7cddfSDavid du Colombier private int
zstrokepath(i_ctx_t * i_ctx_p)1327dd7cddfSDavid du Colombier zstrokepath(i_ctx_t *i_ctx_p)
1337dd7cddfSDavid du Colombier {
1347dd7cddfSDavid du Colombier return gs_strokepath(igs);
1357dd7cddfSDavid du Colombier }
1367dd7cddfSDavid du Colombier
1377dd7cddfSDavid du Colombier /* - clippath - */
1387dd7cddfSDavid du Colombier private int
zclippath(i_ctx_t * i_ctx_p)1397dd7cddfSDavid du Colombier zclippath(i_ctx_t *i_ctx_p)
1407dd7cddfSDavid du Colombier {
1417dd7cddfSDavid du Colombier return gs_clippath(igs);
1427dd7cddfSDavid du Colombier }
1437dd7cddfSDavid du Colombier
1447dd7cddfSDavid du Colombier /* <bool> .pathbbox <llx> <lly> <urx> <ury> */
1457dd7cddfSDavid du Colombier private int
zpathbbox(i_ctx_t * i_ctx_p)1467dd7cddfSDavid du Colombier zpathbbox(i_ctx_t *i_ctx_p)
1477dd7cddfSDavid du Colombier {
1487dd7cddfSDavid du Colombier os_ptr op = osp;
1497dd7cddfSDavid du Colombier gs_rect box;
1507dd7cddfSDavid du Colombier int code;
1517dd7cddfSDavid du Colombier
1527dd7cddfSDavid du Colombier check_type(*op, t_boolean);
1537dd7cddfSDavid du Colombier code = gs_upathbbox(igs, &box, op->value.boolval);
1547dd7cddfSDavid du Colombier if (code < 0)
1557dd7cddfSDavid du Colombier return code;
1567dd7cddfSDavid du Colombier push(3);
1577dd7cddfSDavid du Colombier make_real(op - 3, box.p.x);
1587dd7cddfSDavid du Colombier make_real(op - 2, box.p.y);
1597dd7cddfSDavid du Colombier make_real(op - 1, box.q.x);
1607dd7cddfSDavid du Colombier make_real(op, box.q.y);
1617dd7cddfSDavid du Colombier return 0;
1627dd7cddfSDavid du Colombier }
1637dd7cddfSDavid du Colombier
1647dd7cddfSDavid du Colombier /* <moveproc> <lineproc> <curveproc> <closeproc> pathforall - */
165*593dc095SDavid du Colombier private int path_continue(i_ctx_t *);
166*593dc095SDavid du Colombier private int path_cleanup(i_ctx_t *);
1677dd7cddfSDavid du Colombier private int
zpathforall(i_ctx_t * i_ctx_p)1687dd7cddfSDavid du Colombier zpathforall(i_ctx_t *i_ctx_p)
1697dd7cddfSDavid du Colombier {
1707dd7cddfSDavid du Colombier os_ptr op = osp;
1717dd7cddfSDavid du Colombier gs_path_enum *penum;
1727dd7cddfSDavid du Colombier int code;
1737dd7cddfSDavid du Colombier
1747dd7cddfSDavid du Colombier check_proc(op[-3]);
1757dd7cddfSDavid du Colombier check_proc(op[-2]);
1767dd7cddfSDavid du Colombier check_proc(op[-1]);
1777dd7cddfSDavid du Colombier check_proc(*op);
1787dd7cddfSDavid du Colombier check_estack(8);
1797dd7cddfSDavid du Colombier if ((penum = gs_path_enum_alloc(imemory, "pathforall")) == 0)
1807dd7cddfSDavid du Colombier return_error(e_VMerror);
1817dd7cddfSDavid du Colombier code = gs_path_enum_init(penum, igs);
1827dd7cddfSDavid du Colombier if (code < 0) {
1837dd7cddfSDavid du Colombier ifree_object(penum, "path_cleanup");
1847dd7cddfSDavid du Colombier return code;
1857dd7cddfSDavid du Colombier }
1867dd7cddfSDavid du Colombier /* Push a mark, the four procedures, and the path enumerator. */
1877dd7cddfSDavid du Colombier push_mark_estack(es_for, path_cleanup); /* iterator */
1887dd7cddfSDavid du Colombier memcpy(esp + 1, op - 3, 4 * sizeof(ref)); /* 4 procs */
1897dd7cddfSDavid du Colombier esp += 5;
1907dd7cddfSDavid du Colombier make_istruct(esp, 0, penum);
1917dd7cddfSDavid du Colombier push_op_estack(path_continue);
1927dd7cddfSDavid du Colombier pop(4);
1937dd7cddfSDavid du Colombier op -= 4;
1947dd7cddfSDavid du Colombier return o_push_estack;
1957dd7cddfSDavid du Colombier }
1967dd7cddfSDavid du Colombier /* Continuation procedure for pathforall */
197*593dc095SDavid du Colombier private void pf_push(i_ctx_t *, gs_point *, int);
1987dd7cddfSDavid du Colombier private int
path_continue(i_ctx_t * i_ctx_p)1997dd7cddfSDavid du Colombier path_continue(i_ctx_t *i_ctx_p)
2007dd7cddfSDavid du Colombier {
2017dd7cddfSDavid du Colombier gs_path_enum *penum = r_ptr(esp, gs_path_enum);
2027dd7cddfSDavid du Colombier gs_point ppts[3];
2037dd7cddfSDavid du Colombier int code;
2047dd7cddfSDavid du Colombier
2057dd7cddfSDavid du Colombier /* Make sure we have room on the o-stack for the worst case */
2067dd7cddfSDavid du Colombier /* before we enumerate the next path element. */
2077dd7cddfSDavid du Colombier check_ostack(6); /* 3 points for curveto */
2087dd7cddfSDavid du Colombier code = gs_path_enum_next(penum, ppts);
2097dd7cddfSDavid du Colombier switch (code) {
2107dd7cddfSDavid du Colombier case 0: /* all done */
2117dd7cddfSDavid du Colombier esp -= 6;
2127dd7cddfSDavid du Colombier path_cleanup(i_ctx_p);
2137dd7cddfSDavid du Colombier return o_pop_estack;
2147dd7cddfSDavid du Colombier default: /* error */
2157dd7cddfSDavid du Colombier return code;
2167dd7cddfSDavid du Colombier case gs_pe_moveto:
2177dd7cddfSDavid du Colombier esp[2] = esp[-4]; /* moveto proc */
2187dd7cddfSDavid du Colombier pf_push(i_ctx_p, ppts, 1);
2197dd7cddfSDavid du Colombier break;
2207dd7cddfSDavid du Colombier case gs_pe_lineto:
2217dd7cddfSDavid du Colombier esp[2] = esp[-3]; /* lineto proc */
2227dd7cddfSDavid du Colombier pf_push(i_ctx_p, ppts, 1);
2237dd7cddfSDavid du Colombier break;
2247dd7cddfSDavid du Colombier case gs_pe_curveto:
2257dd7cddfSDavid du Colombier esp[2] = esp[-2]; /* curveto proc */
2267dd7cddfSDavid du Colombier pf_push(i_ctx_p, ppts, 3);
2277dd7cddfSDavid du Colombier break;
2287dd7cddfSDavid du Colombier case gs_pe_closepath:
2297dd7cddfSDavid du Colombier esp[2] = esp[-1]; /* closepath proc */
2307dd7cddfSDavid du Colombier break;
2317dd7cddfSDavid du Colombier }
2327dd7cddfSDavid du Colombier push_op_estack(path_continue);
2337dd7cddfSDavid du Colombier ++esp; /* include pushed procedure */
2347dd7cddfSDavid du Colombier return o_push_estack;
2357dd7cddfSDavid du Colombier }
2367dd7cddfSDavid du Colombier /* Internal procedure to push one or more points */
2377dd7cddfSDavid du Colombier private void
pf_push(i_ctx_t * i_ctx_p,gs_point * ppts,int n)2387dd7cddfSDavid du Colombier pf_push(i_ctx_t *i_ctx_p, gs_point * ppts, int n)
2397dd7cddfSDavid du Colombier {
2407dd7cddfSDavid du Colombier os_ptr op = osp;
2417dd7cddfSDavid du Colombier
2427dd7cddfSDavid du Colombier while (n--) {
2437dd7cddfSDavid du Colombier op += 2;
2447dd7cddfSDavid du Colombier make_real(op - 1, ppts->x);
2457dd7cddfSDavid du Colombier make_real(op, ppts->y);
2467dd7cddfSDavid du Colombier ppts++;
2477dd7cddfSDavid du Colombier }
2487dd7cddfSDavid du Colombier osp = op;
2497dd7cddfSDavid du Colombier }
2507dd7cddfSDavid du Colombier /* Clean up after a pathforall */
2517dd7cddfSDavid du Colombier private int
path_cleanup(i_ctx_t * i_ctx_p)2527dd7cddfSDavid du Colombier path_cleanup(i_ctx_t *i_ctx_p)
2537dd7cddfSDavid du Colombier {
2547dd7cddfSDavid du Colombier gs_path_enum *penum = r_ptr(esp + 6, gs_path_enum);
2557dd7cddfSDavid du Colombier
2567dd7cddfSDavid du Colombier gs_path_enum_cleanup(penum);
2577dd7cddfSDavid du Colombier ifree_object(penum, "path_cleanup");
2587dd7cddfSDavid du Colombier return 0;
2597dd7cddfSDavid du Colombier }
2607dd7cddfSDavid du Colombier
2617dd7cddfSDavid du Colombier /* ------ Initialization procedure ------ */
2627dd7cddfSDavid du Colombier
2637dd7cddfSDavid du Colombier const op_def zpath1_op_defs[] =
2647dd7cddfSDavid du Colombier {
2657dd7cddfSDavid du Colombier {"5arc", zarc},
2667dd7cddfSDavid du Colombier {"5arcn", zarcn},
2677dd7cddfSDavid du Colombier {"5arct", zarct},
2687dd7cddfSDavid du Colombier {"5arcto", zarcto},
2697dd7cddfSDavid du Colombier {"0clippath", zclippath},
2707dd7cddfSDavid du Colombier {"0.dashpath", zdashpath},
2717dd7cddfSDavid du Colombier {"0flattenpath", zflattenpath},
2727dd7cddfSDavid du Colombier {"4pathforall", zpathforall},
2737dd7cddfSDavid du Colombier {"0reversepath", zreversepath},
2747dd7cddfSDavid du Colombier {"0strokepath", zstrokepath},
2757dd7cddfSDavid du Colombier {"1.pathbbox", zpathbbox},
2767dd7cddfSDavid du Colombier /* Internal operators */
2777dd7cddfSDavid du Colombier {"0%path_continue", path_continue},
2787dd7cddfSDavid du Colombier op_def_end(0)
2797dd7cddfSDavid du Colombier };
280