ftp.nice.ch/peanuts/GeneralData/Documents/adobe/DPS.Purple.Scroll.tar.gz#/NX_Scroll/iinterpreter.c

This is iinterpreter.c in view mode; [Download] [Up]

/*
 * (a)  (C) 1990 by Adobe Systems Incorporated. All rights reserved.
 *
 * (b)  If this Sample Code is distributed as part of the Display PostScript
 *	System Software Development Kit from Adobe Systems Incorporated,
 *	then this copy is designated as Development Software and its use is
 *	subject to the terms of the License Agreement attached to such Kit.
 *
 * (c)  If this Sample Code is distributed independently, then the following
 *	terms apply:
 *
 * (d)  This file may be freely copied and redistributed as long as:
 *	1) Parts (a), (d), (e) and (f) continue to be included in the file,
 *	2) If the file has been modified in any way, a notice of such
 *      modification is conspicuously indicated.
 *
 * (e)  PostScript, Display PostScript, and Adobe are registered trademarks of
 *	Adobe Systems Incorporated.
 * 
 * (f) THE INFORMATION BELOW IS FURNISHED AS IS, IS SUBJECT TO
 *	CHANGE WITHOUT NOTICE, AND SHOULD NOT BE CONSTRUED
 *	AS A COMMITMENT BY ADOBE SYSTEMS INCORPORATED.
 *	ADOBE SYSTEMS INCORPORATED ASSUMES NO RESPONSIBILITY
 *	OR LIABILITY FOR ANY ERRORS OR INACCURACIES, MAKES NO
 *	WARRANTY OF ANY KIND (EXPRESS, IMPLIED OR STATUTORY)
 *	WITH RESPECT TO THIS INFORMATION, AND EXPRESSLY
 *	DISCLAIMS ANY AND ALL WARRANTIES OF MERCHANTABILITY, 
 *	FITNESS FOR PARTICULAR PURPOSES AND NONINFRINGEMENT
 *	OF THIRD PARTY RIGHTS.
 */

/*
 *	iinterpreter.c
 *
 *	Version:	2.0
 *	Author:	Ken Anderson, Ken Fromm
 *	History:
 *			03-07-91		Added this comment.
 */

#import "iinterpreterhooks.h"
#import "ierror.h"
#import <appkit/nextstd.h>
#import <appkit/graphics.h>
#import <dpsclient/dpsclient.h>
#import <objc/hashtable.h>

#define  STACKSIZE		256		/* Maximum stack size. */
#define  ELEMENTSIZE	128		/* Max size of one link in string expression */

typedef enum {
	UNDEFINED,
	INTEGER,
	REAL,
	STRING,
	NAME,
	ARRAY,
	MARK
}  ElementType;

typedef struct _Any {
	ElementType	type;
	union {
		int		integer;
		float		real;
		char		*name;
		struct {
			char		*data;
			int		len;
		}  string;		
		struct {
			char		*data;
			int		len;
		}  array;
	}  element;
}  Any;

static int			istackdepth;		/* number of elements */
static Any		*istacktop;		/* ptr to top of stack */
static Any		*istack;			/* ptr to bottom of stack */

static NXPoint		icurrentpoint,
				istartpoint;

static BOOL		inocurrentpoint,
				ierror;

static NXRect		ipathbbox;

BOOL iiferror()
{
	return ierror;
}

void ireset()
{
	istackdepth = 0;
	istacktop = istack;
	ierror = NO;
}

void iinitialize()
{
	ii_initPathStruct();
	ii_initGraphicStruct();
	
	NX_MALLOC(istack, Any, STACKSIZE * sizeof(Any));
	inocurrentpoint = YES;
	ireset();
}

void iclear()
{
	if (!ierror)
		ireset();
}

void ipop()
{
	if (!ierror)
	{
		if (istackdepth > 0)
		{
			if (istacktop->type == STRING)
			{
				NX_FREE(istacktop->element.string.data);
			}
			else if (istacktop->type == NAME)
			{
				NX_FREE(istacktop->element.name);
			}

			istackdepth--;
			istacktop--;
		}
		else
			ierrorlog("Error: stack underrflow", &ierror);
	}
}
void ipopint(int *aval)
{
	if (!ierror)
	{
		if (istackdepth > 0)
		{
			if (istacktop->type == INTEGER)
			{
				*aval = istacktop->element.integer;
				istackdepth--;
				istacktop--;
			}
			else
				ierrorlog("Error: typecheck", &ierror);
		}
		else
			ierrorlog("Error: stack underrflow", &ierror);
	}
}

void ipopreal(float *aval)
{
	if (!ierror)
	{
		if (istackdepth > 0)
		{
			if (istacktop->type == REAL || istacktop->type == INTEGER)
			{
				if (istacktop->type == REAL)
					*aval = istacktop->element.real;
				else
					*aval = (float) istacktop->element.integer;
				istackdepth--;
				istacktop--;
			}
			else
				ierrorlog("Error: typecheck", &ierror);
		}
		else
			ierrorlog("Error: stack underrflow", &ierror);
	}
}

void ipopstring(char **str_ptr, int *len)
{
	if (!ierror)
	{
		if (istackdepth > 0)
		{
			if (istacktop->type == STRING)
			{
				*str_ptr = istacktop->element.string.data;
				*len = istacktop->element.string.len;
				istackdepth--;
				istacktop--;
			}
			else
				ierrorlog("Error: typecheck", &ierror);
		}
		else
			ierrorlog("Error: stack underrflow", &ierror);
	}
}

void ipopname(char **name_ptr)
{
	if (!ierror)
	{
		if (istackdepth > 0)
		{
			if (istacktop->type == NAME)
			{
				*name_ptr = istacktop->element.name;
				istackdepth--;
				istacktop--;
			}
			else
				ierrorlog("Error: typecheck", &ierror);
		}
		else
			ierrorlog("Error: stack underrflow", &ierror);
	}
}

void ipushint(int aval)
{
	if (!ierror)
	{
		if (istackdepth < STACKSIZE)
		{
			istackdepth++;
			istacktop++;
			istacktop->type = INTEGER;
			istacktop->element.integer = aval;
		}
		else
			ierrorlog("Error: stack overflow", &ierror);
	}
}

void ipushreal(float aval)
{
	if (!ierror)
	{
		if (istackdepth < STACKSIZE)
		{
			istackdepth++;
			istacktop++;
			istacktop->type = REAL;
			istacktop->element.real = aval;
		}
		else
			 ierrorlog("Error: stack overflow", &ierror);
	}
}

void  ipushstring(char *str, int len)
{
	if (!ierror)
	{
		if (istackdepth < STACKSIZE)
		{
			istackdepth++;
			istacktop++;
			istacktop->type = STRING;
		
			NX_MALLOC(istacktop->element.string.data, char, len+1);
			strncpy(istacktop->element.string.data, str, len);
			istacktop->element.string.data[len] = 0;
			istacktop->element.string.len = len;			
		}
		else
			ierrorlog("Error: stack overflow", &ierror);
	}
}

void  ipushname(char *name, int len)
{
	if (!ierror)
	{
		if (istackdepth < STACKSIZE)
		{
			istackdepth++;
			istacktop++;
			istacktop->type = NAME;
			istack->element.name = NXCopyStringBuffer(name);
		}
		else
			ierrorlog("Error: stack overflow", &ierror);
	}
}

void iroll(int n, int j)
{
	int		a, b;

	Any		temp;

	if (!ierror)
	{
		if (istackdepth -n >= 0)
		{
			for (a = j; a > 0; a--)
			{
				temp = *istacktop;
				for (b = 1; b < n; b++)
					istack[istackdepth - (b-1)] = istack[istackdepth - b];			
				istack[istackdepth - (n - 1)] = temp;
			}
		}
		else
			ierrorlog("Error: stack underflow", &ierror);
	}
}

static void icheckBounds(NXPoint  *pts, int num_pts, BOOL relative)
{
	int			i;

	NXPoint		pt;

	if (inocurrentpoint && num_pts > 0)
	{
		ipathbbox.origin.x = pts->x;
		ipathbbox.origin.y = pts->y;
		ipathbbox.size.width = 0;
		ipathbbox.size.height = 0;
	}

	for (i = 0; i < num_pts; i++)
	{
		pt = pts[i];	
		if (relative)
		{
			pt.x += icurrentpoint.x;
			pt.y += icurrentpoint.y;
		}
		
		if (pt.x < ipathbbox.origin.x )
		{
			ipathbbox.size.width += ipathbbox.origin.x - pt.x;
			ipathbbox.origin.x = pt.x;
		}
		else if (pt.x - ipathbbox.origin.x > ipathbbox.size.width)
			ipathbbox.size.width = pt.x - ipathbbox.origin.x;
	
		if (pt.y < ipathbbox.origin.y)
		{
			ipathbbox.size.height += ipathbbox.origin.y - pt.y;
			ipathbbox.origin.y = pt.y;
		}
		else if (pt.y - ipathbbox.origin.y > ipathbbox.size.height)
			ipathbbox.size.height = pt.y - ipathbbox.origin.y;
	}
}

void iinsertPathOp(int dps_op, int num_args)
{
	BOOL	relative_op = YES, start_path = NO;

	int		i, num_pts;
	
	NXPoint	pts[3];

	if (!ierror)
	{
		switch(dps_op)
		{
			case dps_rmoveto:
				start_path = YES;
				break;
			case dps_moveto:
				start_path = YES;
			case dps_lineto:
			case dps_curveto:
			case dps_closepath:
				relative_op = NO;
				break;
			default:	;	
		}

		if ((relative_op || dps_op == dps_closepath) && inocurrentpoint)
		{
			ierrorlog("Error: no currentpoint", &ierror);
		}
		else
		{
			/* Take points off stack and place back to front into pt array. */
			num_pts = num_args/2;
			for (i = num_pts - 1;  i >= 0;  i--)
			{
				ipopreal(&pts[i].y);
				ipopreal(&pts[i].x);
			}

			if (!ierror)
			{
				/*  Path from end to start and check bounds. */	
				icheckBounds(pts, num_pts, relative_op);
				ii_insertPathCoord(pts, num_pts, dps_op, &icurrentpoint);

				if (relative_op)
				{
					icurrentpoint.x += pts[num_pts-1].x;
					icurrentpoint.y += pts[num_pts-1].y;
				}
				else if (dps_op == dps_closepath)
					icurrentpoint = istartpoint;
				else
					icurrentpoint = pts[num_pts-1];
				
				if (start_path)
					istartpoint = icurrentpoint;

				inocurrentpoint = NO;
			}
		}
	}
}

void iinsertPath(int path_type)
{
	if (!ierror)
	{
		ii_insertPath(path_type, &ipathbbox);
		ii_resetPathStruct();
		inocurrentpoint = YES;
	}
}

void iinsertPage(int page)
{	
	if (!ierror)
	{
		ii_insertPage(page);

		ii_resetPathStruct();
		inocurrentpoint = YES;
	}
}

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.