/* Copyright (C) 1989, 1990 Aladdin Enterprises.  All rights reserved.
   Distributed by Free Software Foundation, Inc.

This file is part of Ghostscript.

Ghostscript is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY.  No author or distributor accepts responsibility
to anyone for the consequences of using it or for whether it serves any
particular purpose or works at all, unless he says so in writing.  Refer
to the Ghostscript General Public License for full details.

Everyone is granted permission to copy, modify and redistribute
Ghostscript, but only under the conditions described in the Ghostscript
General Public License.  A copy of this license is supposed to have been
given to you along with Ghostscript so you can know your rights and
responsibilities.  It should be in a file named COPYING.  Among other
things, the copyright notice and this notice must be preserved on all
copies.  */

/* zpath2.c */
/* Non-constructor path operators for GhostScript */
#include "ghost.h"
#include "oper.h"
#include "errors.h"
#include "alloc.h"
#include "estack.h"	/* for pathforall */
#include "gspath.h"
#include "state.h"
#include "store.h"

/* flattenpath */
int
zflattenpath(register ref *op)
{	return gs_flattenpath(igs);
}

/* reversepath */
int
zreversepath(register ref *op)
{	return gs_reversepath(igs);
}

/* strokepath */
int
zstrokepath(register ref *op)
{	return gs_strokepath(igs);
}

/* clippath */
int
zclippath(register ref *op)
{	return gs_clippath(igs);
}

/* pathbbox */
int
zpathbbox(register ref *op)
{	gs_rect box;
	int code = gs_pathbbox(igs, &box);
	if ( code < 0 ) return code;
	push(4);
	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;
}

/* pathforall */
private int path_continue(P1(ref *));
int
zpathforall(register ref *op)
{	gs_path_enum *penum;
	check_op(4);
	check_estack(8);
	if ( (penum = (gs_path_enum *)alloc(1, gs_path_enum_sizeof, "pathforall")) == 0 )
	  return e_VMerror;
	gs_path_enum_init(penum, igs);
	/* Push a mark, the four procedures, and a pseudo-integer */
	/* in which value.bytes points to the path enumerator, */
	/* and then call the continuation procedure. */
	mark_estack(es_for);	/* iterator */
	*++esp = op[-3];	/* moveto proc */
	*++esp = op[-2];	/* lineto proc */
	*++esp = op[-1];	/* curveto proc */
	*++esp = *op;		/* closepath proc */
	++esp;
	make_tv(esp, t_integer, bytes, (byte *)penum);
	pop(4);  op -= 4;
	return path_continue(op);
}
/* Continuation procedure for pathforall */
private int pf_push(P3(gs_point *, int, ref *));
private int
path_continue(register ref *op)
{	gs_path_enum *penum = (gs_path_enum *)esp->value.bytes;
	gs_point ppts[3];
	int code;
	code = gs_path_enum_next(penum, ppts);
	switch ( code )
	  {
	case 0:			/* all done */
	    { alloc_free((char *)penum, 1, gs_path_enum_sizeof, "pathforall");
	      esp -= 6;
	      return o_check_estack;
	    }
	default:		/* error */
	    return code;
	case gs_pe_moveto:
	    esp[2] = esp[-4];			/* moveto proc */
	    code = pf_push(ppts, 1, op);
	    break;
	case gs_pe_lineto:
	    esp[2] = esp[-3];			/* lineto proc */
	    code = pf_push(ppts, 1, op);
	    break;
	case gs_pe_curveto:
	    esp[2] = esp[-2];			/* curveto proc */
	    code = pf_push(ppts, 3, op);
	    break;
	case gs_pe_closepath:
	    esp[2] = esp[-1];			/* closepath proc */
	    code = 0;
	    break;
	  }
	if ( code < 0 ) return code;	/* ostack overflow in pf_push */
	push_op_estack(path_continue);
	++esp;		/* include pushed procedure */
	return o_check_estack;
}
/* Internal procedure to push one or more points */
private int
pf_push(gs_point *ppts, int n, ref *op)
{	while ( n-- )
	  { push(2);
	    make_real(op - 1, ppts->x);
	    make_real(op, ppts->y);
	    ppts++;
	  }
	return 0;
}

/* initclip */
int
zinitclip(register ref *op)
{	return gs_initclip(igs);
}

/* clip */
int
zclip(register ref *op)
{	return gs_clip(igs);
}

/* eoclip */
int
zeoclip(register ref *op)
{	return gs_eoclip(igs);
}

/* ------ Initialization procedure ------ */

void
zpath2_op_init()
{	static op_def my_defs[] = {
		{"0clip", zclip},
		{"0clippath", zclippath},
		{"0eoclip", zeoclip},
		{"0flattenpath", zflattenpath},
		{"0initclip", zinitclip},
		{"0pathbbox", zpathbbox},
		{"4pathforall", zpathforall},
		{"0reversepath", zreversepath},
		{"0strokepath", zstrokepath},
		op_def_end
	};
	z_op_init(my_defs);
}
