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 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.