Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!uunet!rsalz From: rsalz@uunet.UU.NET (Rich Salz) Newsgroups: comp.sources.unix Subject: v12i057: A PostScript interpreter, Part08/18 Message-ID: <2855@uunet.UU.NET> Date: Fri, 6-Nov-87 14:01:44 EST Article-I.D.: uunet.2855 Posted: Fri Nov 6 14:01:44 1987 Date-Received: Sun, 8-Nov-87 15:40:51 EST Organization: UUNET Communications Services, Arlington, VA Lines: 3704 Approved: rs@uunet.UU.NET Submitted-by: Crispin Goswell Posting-number: Volume 12, Issue 57 Archive-name: postscript/part08 #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh 'postscript/fonts/Times/italic.r' <<'END_OF_FILE' XCharStrings X/a Xput XMetrics X/a[-3 X21] Xput XCharStrings X/b Xput XMetrics X/b[2 X19] Xput XCharStrings X/c Xput XMetrics X/c[-3 X18] Xput XCharStrings X/d Xput XMetrics X/d[2 X21] Xput XCharStrings X/e Xput XMetrics X/e[-3 X18] Xput XCharStrings X/f Xput XMetrics X/f[5 X15] Xput XCharStrings X/g Xput XMetrics X/g[-1 X20] Xput XCharStrings X/h Xput XMetrics X/h[2 X21] Xput XCharStrings X/i Xput XMetrics X/i[6 X13] Xput XCharStrings X/j Xput XMetrics X/j[6 X13] Xput XCharStrings X/k Xput XMetrics X/k[2 X20] Xput XCharStrings X/l Xput XMetrics X/l[7 X12] Xput XCharStrings X/m Xput XMetrics X/m[-1 X33] Xput XCharStrings X/n Xput XMetrics X/n[-1 X23] Xput XCharStrings X/o Xput XMetrics X/o[-3 X18] Xput XCharStrings X/p Xput XMetrics X/p[1 X21] Xput XCharStrings X/q Xput XMetrics X/q[-3 X20] Xput XCharStrings X/r Xput XMetrics X/r[-1 X17] Xput XCharStrings X/s Xput XMetrics X/s[-2 X17] Xput XCharStrings X/t Xput XMetrics X/t[5 X14] Xput XCharStrings X/u Xput XMetrics X/u[-1 X23] Xput XCharStrings X/v Xput XMetrics X/v[-1 X20] Xput XCharStrings X/w Xput XMetrics X/w[-1 X29] Xput XCharStrings X/x Xput XMetrics X/x[-2 X20] Xput XCharStrings X/y Xput XMetrics X/y[-1 X21] Xput XCharStrings X/z Xput XMetrics X/z[-3 X20] Xput XCharStrings X/A Xput XMetrics X/A[2 X20] Xput XCharStrings X/B Xput XMetrics X/B[0 X24] Xput XCharStrings X/C Xput XMetrics X/C[2 X21] Xput XCharStrings X/D Xput XMetrics X/D[0 X23] Xput XCharStrings X/E Xput XMetrics X/E[0 X23] Xput XCharStrings X/F Xput XMetrics X/F[0 X22] Xput XCharStrings X/G Xput XMetrics X/G[2 X22] Xput XCharStrings X/H Xput XMetrics X/H[0 X26] Xput XCharStrings X/I Xput XMetrics X/I[6 X13] Xput XCharStrings X/J Xput XMetrics X/J[3 X18] Xput XCharStrings X/K Xput XMetrics X/K[0 X23] Xput XCharStrings X/L Xput XMetrics X/L[2 X20] Xput XCharStrings X/M Xput XMetrics X/M[0 X27] Xput XCharStrings X/N Xput XMetrics X/N[0 X25] Xput XCharStrings X/O Xput XMetrics X/O[1 X22] Xput XCharStrings X/P Xput XMetrics X/P[0 X23] Xput XCharStrings X/Q Xput XMetrics X/Q[1 X22] Xput XCharStrings X/R Xput XMetrics X/R[0 X24] Xput XCharStrings X/S Xput XMetrics X/S[1 X23] Xput XCharStrings X/T Xput XMetrics X/T[2 X21] Xput XCharStrings X/U Xput XMetrics X/U[0 X25] Xput XCharStrings X/V Xput XMetrics X/V[2 X20] Xput XCharStrings X/W Xput XMetrics X/W[-1 X26] Xput XCharStrings X/X Xput XMetrics X/X[1 X22] Xput XCharStrings X/Y Xput XMetrics X/Y[2 X21] Xput XCharStrings X/Z Xput XMetrics X/Z[1 X22] Xput XCharStrings X/ff X Xput XMetrics X/ff X[2 X26] Xput XCharStrings X/fi X Xput XMetrics X/fi X[2 X24] Xput XCharStrings X/fl X Xput XMetrics X/fl X[2 X24] Xput XCharStrings X/ffi X Xput XMetrics X/ffi X[2 X35] Xput XCharStrings X/ffl X Xput XMetrics X/ffl X[2 X35] Xput XCharStrings X/dotlessi X Xput XMetrics X/dotlessi X[-1 X13] Xput XCharStrings X/space X<8000 X8563C X4400 X008D7 X3848 X> Xput XMetrics X/space X[64 X0] Xput END_OF_FILE if test 10938 -ne `wc -c <'postscript/fonts/Times/italic.r'`; then echo shar: \"'postscript/fonts/Times/italic.r'\" unpacked with wrong size! fi # end of 'postscript/fonts/Times/italic.r' fi if test -f 'source/hard-interface.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'source/hard-interface.c'\" else echo shar: Extracting \"'source/hard-interface.c'\" \(10584 characters\) sed "s/^X//" >'source/hard-interface.c' <<'END_OF_FILE' X/* X * Copyright (C) Rutherford Appleton Laboratory 1987 X * X * This source may be copied, distributed, altered or used, but not sold for profit X * or incorporated into a product except under licence from the author. X * It is not in the public domain. X * This notice should remain in the source unaltered, and any changes to the source X * made by persons other than the author should be marked as such. X * X * Crispin Goswell @ Rutherford Appleton Laboratory caag@uk.ac.rl.vd X */ X#include "main.h" X#include "graphics.h" X Xstruct hardware X { X /* X * Each driver is expected to provide its own definition of this structure. X * It is only ever used as a pointer and is never dereferenced outside the driver. X */ X int pad; X }; X X/* X * This file describes the interface that PostScript requires to the graphics system at Version 1.4. X * X * ''Hardware'' in this context refers to a pointer to windows and/or bitmaps and is the lowest level X * of access that PostScript is interested in. Any Hardware parameter may be expected to be NULL. X */ X X/*********************************** CREATION OF WINDOWS AND BITMAPS *******************/ X Xstruct hardware *InitHardware () {} X/* X * InitHardware () returns a default device which PostScript may use immediately (or NULL if not appropriate). X * Its size and shape are not defined. Most typically the user will want to start up another device X * before it is used anyway. No attempt will be made by PostScript to Destroy the resulting X * device. X */ X Xstruct hardware *NewBitmapHardware (width, height) int width, height; {} X Xstruct hardware *NewWindowHardware (width, height) int width, height; {} X/* X * NewBitmapHardware () is expected to create a new bitmap. Only one plane will be needed. X * X * NewWindowHardware () is expected to create a window on the screen. On a colour system this will X * be expected to support full colour. X */ X Xint IsWindowHardware (h) struct hardware *h; {} X/* X * IsWindowHardware () should return TRUE if the hardware is a window, FALSE otherwise. X * NULL is a window. X */ X Xvoid DestroyHardware (h) struct hardware *h; {} X/* X * DestroyHardware () should release the resources required by the hardware, bitmap or window. X * This should cause a window device to vanish. NULL is not an error (does nothing). X */ X X XMatrix DeviceMatrix (width, height) int width, height; {} X X/* X * X * DeviceMatrix () should return a matrix appropriate to a device of the given height and width. X * For a typical display with a graphics origin at the top left of a window, X * an appropriate definition would be: X * X * Matrix DeviceMatrix (width, height) int width, height; X * { X * return NewMatrix (PIXELS_PER_INCH / 72.0, 0.0, 0.0, -PIXELS_PER_INCH / 72.0, 0.0, (float) height); X * } X */ X XDevicePoint HardwareExtent (h) struct hardware *h; {} X/* HardwareExtent () returns a DevicePoint describing the width and height of the argument. X * NULL has extent NewDevicePoint (0, 0). X */ X X/******************************************* OUTPUT PRIMITIVES ******************************/ X Xvoid BitBlt (from, to, fromPoint, toPoint, extent, rop) X struct hardware *from, *to; X DevicePoint toPoint, fromPoint, extent; X int rop; X {} X Xvoid Paint (from, to, fromPoint, toPoint, extent, colour) X struct hardware *from, *to; X DevicePoint toPoint, fromPoint, extent; X Colour colour; X {} X X/* X * BitBlt () is a full function RasterOp. The 'rop' argument X * will have values as described in the header file hard.h. If the from argument is NULL it is taken to be X * a bitmap full of ones the shape of the fromPoint and extent. If the to argument is NULL, this is a no-op. X * X * Paint () is an addition to BitBlt. Bits that are set in the source are Painted into the destination X * in the given colour with a copying rasterop so that they replace pixels previously there. If the X * machine does not support colour windows, half-toning should be performed. X * Colour values have hue, saturation and brightness components. on a black and white or greyscale X * system the brightness value will be a FP value between 0.0 (black) and 1.1 (white), which can be X * used as a grey level. X * X * Paint is expected to mask with the clip mask. BitBlt is not, X */ X Xvoid BitBltTrapezoid (to, lefttop, leftbottom, righttop, rightbottom, top, bottom, rop) X struct hardware *to; X DevicePoint lefttop, leftbottom, righttop, rightbottom; X int top, bottom, rop; X {} X Xvoid PaintTrapezoid (to, lefttop, leftbottom, righttop, rightbottom, top, bottom, colour) X struct hardware *to; X DevicePoint lefttop, leftbottom, righttop, rightbottom; X int top, bottom; X Colour colour; X {} X X/* X * BitBltTrapezoid () and PaintTrapezoid () render a complete trapezoidal shape. X * The corners of the trapezoid may lie far outside the range of interesting scan-lines, but the slope X * of the line should be clipped by the top and bottom. The coordinates are half-open. X */ X Xvoid BitBltLine (h, fromPoint, toPoint, rop) X struct hardware *h; X DevicePoint fromPoint, toPoint; X int rop; X {} X Xvoid PaintLine (h, fromPoint, toPoint, colour) X struct hardware *h; X DevicePoint fromPoint, toPoint; X Colour colour; X {} X X/* X * BitBltLine () is expected to draw a line between the given points X * with the given RasterOp and colour masking. X * The line should be one pixel wide and half-open. X * [Thicker lines are done with BitBlt.] X * X * PaintLine () is expected to Paint a line by analogy with Paint and BitBlt. X */ X Xvoid BitBltBlob (to, top, height, left, right, rop) X struct hardware *to; X int top, height, *left, *right, rop; X {} X X /* X * BitBltBlob () takes a set of pixel coordinates and fills the trapezon figure X * half open. X */ X Xvoid RasterTile (from, to, toPoint, extent, rop) X struct hardware *from, *to; X DevicePoint toPoint, extent; X int rop; X {} X X/* X * RasterTile () replicates the whole of ``from'' over ``to'', but clipped by the X * rectangle bounded by ``toPoint'' and ``extent''. X */ X X/*********************************** BRIGHTNESS TRANSFER FUNCTION ************************/ X Xint TransferSize () {} X Xvoid SetTransfer (vec) float *vec; {} X/* X * TransferSize () and SetTransfer () control the mapping function between user brightnesses X * and device brightnesses. The interface is expected to perform this mapping of brightnesses X * to a sufficient resolution. SetTransfer takes a table of floating point numbers between X * 0 and 1. User brightnesses are scaled to the size of this table and mapped through it. X * The argument table given to SetTransfer () will be deleted after use. TransferSize () simply X * enquires the required size of the table. X * X * It may be appropriate to half-tone on a grayscale or colour device to improve rendering if it is not too X * expensive. TransferSize () returns the size of the pattern table. X */ X X/********************************** BITMAP CONVERSION ********************************/ X Xchar *StringFromHardware (h) struct hardware *h; {} X Xstruct hardware *HardwareFromString (s, width, height) char *s; int width, height; {} X/* X * StringFromHardware () produces a string from its argument which describes the bitmap. X * The bitmap is returned in row-major order with the leftmost bit of each byte in the most significant X * position. Rows are padded to byte boundaries. Only single plane bitmaps are used. X * X * HardwareFromString () performs the inverse mapping, generating a bitmap from a set of bits, given X * a width and height. Only single plane bitmaps are used. X */ X X/************************************* HALF-TONE SCREEN ***********************************/ X Xint ScreenSize (freq, rotation) float freq, rotation; {} X Xvoid BuildScreen (freq, rotation, x, y) float freq, rotation, *x, *y; {} X Xvoid SetScreen (freq, rotation, thresh) float freq, rotation, *thresh; {} X/* X * ScreenSize () allows PostScript to determine how large an array of sample points to expect. X * It should return the length of the side of the sample square. X * X * BuildScreen () returns a set of sampling coordinates to PostScript to hand to the users spot-function X * X * SetScreen () allows PostScript to set the thresholds for each sample point so that half-tone bitmaps X * can be made. X */ X X/************************************* CLIPPING **********************************************/ X Xvoid SetClipHardware (h, clip) struct hardware *h, *clip; {} X/* X * SetClipHardware sets hardware which is a clip mask for BitBlt. This mask should be ANDed with any output X * operation. If clip is NULL, masking will not be needed. X */ X X/**************************************** UPDATE CONTROLS ******************************************/ X Xvoid HardUpdate () {} X/* X * HardUpdate is a hook to allow devices which do output buffering to flush that buffering when appropriate. X * This allows an interactive user to see completed graphics between prompts (it is called as a side-effect X * of the PostScript flush operator). Typically is is a no-op. X */ X Xvoid UpdateControl (h, on) struct hardware *h; int on; {} X/* X * This call can be used to enable batching of output operations. UpdateControl (h, FALSE) means ``start of X * batching'' UpdateControl (h, TRUE) means ``end of batching''. It is used to improve performance on machines X * where screen updates have a high locking overhead. It may be a no-op. X * The operation should nest if batching is already in progress: FALSE increments a counter, X * TRUE decrements a counter. Display changes are allowed when the counter is non-zero. X */ X X/********************************** CANONICAL IMPLEMENTATION LIBRARY ******************************/ X X/* X * Some parts of the above interface can be supported by a canonical library. X * This library contains: X XSetClipHardware XHardUpdate XIsWindowHardware XHardwareExtent X XPaintTrapezoid XBitBltTrapezoid X XPaint XPaintLine X XDeviceMatrix XInitTransfer XTransferSize XSetTransfer XScreenSize XBuildScreen XSetScreen X X * X * As the driver matures, the user may provide his own versions of the canonical routines. X * This leaves the following for implementation by the user. X * X XInitHardware XNewBitmapHardware XNewWindowHardware XDestroyHardware XHardwareFromString XStringFromHardware XUpdateControl XRasterTile XBitBlt XBitBltLine XBitBltBlob X X * There is a pedagogical implementation in null.c X * X * There are a number of interface issues concerning the canonical driver. X * Firstly, a canonical struct hardware is defined, which contains a union of X * a char * and an int handle. The remainder are expected to use this to store X * device specific information. X * X * InitTransfer() should be called during InitHardware with the number of pixels X * per inch on the display as an argument. X */ END_OF_FILE if test 10584 -ne `wc -c <'source/hard-interface.c'`; then echo shar: \"'source/hard-interface.c'\" unpacked with wrong size! fi # end of 'source/hard-interface.c' fi if test -f 'source/main.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'source/main.c'\" else echo shar: Extracting \"'source/main.c'\" \(10508 characters\) sed "s/^X//" >'source/main.c' <<'END_OF_FILE' X/* X * Copyright (C) Rutherford Appleton Laboratory 1987 X * X * This source may be copied, distributed, altered or used, but not sold for profit X * or incorporated into a product except under licence from the author. X * It is not in the public domain. X * This notice should remain in the source unaltered, and any changes to the source X * made by persons other than the author should be marked as such. X * X * Crispin Goswell @ Rutherford Appleton Laboratory caag@uk.ac.rl.vd X */ X#include X#include "main.h" X X#define ERRORDICTSIZE 25 X XObject PDictFull; XObject PDictOverflow, PInvFont, PSyntaxError; XObject PDictUnderflow, PInvRestore, PTypeCheck; XObject PExecOverflow, PIOError, PUndefined; XObject PExecUnderflow, PLimitCheck, PUnFilename; XObject PInterrupt, PNoCurrentPoint, PUnResult; XObject PInvAccess, PRangeCheck, PUnMatched; XObject PInvExit, POpOverflow, PUnregistered; XObject PInvFileAccess, POpUnderflow, PVMError; X XObject Lbracket, Rbracket, Nil, Marker; XObject OpInterp, ErrorDict; X Xstatic int ErrorFn (); Xstatic Object InsErr (); Xstatic void InitErrors (), InitArguments (), Interpreter (); Xstatic Object OpError, error_name, execName; X Xstatic catchint (); Xstatic int EnableInterrupts (); X Xchar *library; X Xstatic int files_present = 0, interrupted = FALSE, protected = 0; Xint interactive = FALSE, verbose = FALSE; XFILE *vfp = NULL; X Xmain (argc, argv) int argc; char **argv; X { X char profile[BUFSIZE], rcfile [BUFSIZE], *getenv (); X FILE *fp; X int here; X X library = getenv ("POSTSCRIPTLIB"); X if (library == NULL) X library = default_library; X X VOID sprintf (rcfile, "%s/psrc", library); X X if (close (dup (9)) == 0) X { X verbose = TRUE; X vfp = fdopen (9, "w"); X } X Message ("POSTSCRIPT"); X Init (); X Message ("Init Errors"); X InitErrors (); X Message ("Init Arguments"); X X VOID Push (ExecStack, Cvx (NameFrom ("executive"))); X X here = Height (ExecStack); X X Install ("Library", StringFrom (library)); X X InitArguments (argc, argv); X interactive = interactive || isatty (0) && !files_present; X ReverseStack (ExecStack, Height (ExecStack) - here); X X VOID strcpy (profile, getenv ("HOME") ? getenv ("HOME") : "/etc"); X VOID strcat (profile, "/.postscript"); X X if (fp = fopen (profile, "r")) X VOID Push (ExecStack, Cvx (FileFrom (fp))); X X if (!interactive) X VOID Push (ExecStack, X Cvx (StringFrom (files_present ? X "/executive null def" : X "/executive (%stdin) (r) file cvx def"))); X X if ((fp = fopen (rcfile, "r")) == NULL) X fprintf (stderr, "%s: cannot open %s\n", argv[0], rcfile), X exit (1); X else X VOID Push (ExecStack, Cvx (FileFrom (fp))); X InstallOp ("enableinterrupts", EnableInterrupts, 0, 0, 0, 0); X/* SysDict = ReadOnly (SysDict); */ X Message ("Entering Interpreter"); X Interpreter (); X } X XMessage (s) char *s; X { X if (vfp != NULL) X fprintf (vfp, "%s\n", s), fflush (vfp); X } X XProtect () X { X ++protected; X } X XUnprotect () X { X --protected; X } X Xstatic int EnableInterrupts () X { X if (interactive) X VOID signal (SIGINT, catchint); X return TRUE; X } X Xstatic void InitArguments (argc, argv) int argc; char **argv; X { X int i, command = FALSE; X X for (i = 1; i < argc; i++) X { X FILE *fp; X X if (command) X { X command = FALSE; X VOID Push (ExecStack, Cvx (StringFrom (argv[i]))); X } X else if (*argv[i] == '-') X switch (argv[i][1]) X { X case 'i': X interactive = TRUE; X break; X X case 'c': X ++files_present; X command = TRUE; X break; X X case 's': case '\0': X ++files_present; X VOID Push (ExecStack, Cvx (Fstdin)); X break; X X default: X fprintf (stderr, "%s: unknown option '%c'\n", argv[0], argv[i][1]); X exit (1); X } X else X { X ++files_present; X if (fp = Fopen (argv[i], "r")) X VOID Push (ExecStack, Cvx (FileFrom (fp))); X else X fprintf (stderr, "%s: cannot open %s\n", argv[0], argv[i]); X } X } X } X Xstatic void Interpreter () X { X Self = execName = NameFrom ("exec"); X while (Height (ExecStack) != 0) X { X int res; X Object item, exop; X X item = Pop (ExecStack); X if (!xCheck (item)) X res = Push (OpStack, item); X else if (TypeOf (item) == Operator) X res = ExecOperator (item); X else if (TypeOf (item) == Array) X res = ExecArray (item); X else if (TypeOf (item) == File) X res = ExecFile (item); X else if (TypeOf (item) == Name) /* names get special treatment for speed */ X { X Object newitem; X X newitem = Load (item); X if (TypeOf (newitem) != Condition) X item = newitem; X X if (!xCheck (item)) X res = Push (OpStack, item); X else if (TypeOf (item) == Operator) X res = ExecOperator (item); X else if (TypeOf (item) == Array) X res = ExecArray (item); X else if (TypeOf (item) == File) X res = ExecFile (item); X else X { X res = Push (OpStack, item); X exop = Lookup (TypeOf (item), execName); X if (TypeOf (exop) != Condition) X VOID Push (ExecStack, exop); X } X } X else X { X res = Push (OpStack, item); X exop = Lookup (TypeOf (item), execName); X if (TypeOf (exop) != Condition) X VOID Push (ExecStack, exop); X } X X if (interrupted && !protected) X { X interrupted = FALSE; X error_name = PInterrupt; X res = FALSE; X } X X if (!res) X { X Object error_op; X X VOID Push (OpStack, Self); X error_op = DictLoad (ErrorDict, error_name); X if (TypeOf (error_op) == Condition) X VOID Push (ExecStack, OpError); X else X VOID Push (ExecStack, error_op); X Cbreak (TRUE); X } X } X } X Xstatic void InitErrors () X { X ErrorDict = MakeDict (ERRORDICTSIZE); X PDictFull = InsErr (ErrorDict, "dictfull", ErrorFn); X PDictOverflow = InsErr (ErrorDict, "dictstackoverflow", ErrorFn); X PDictUnderflow = InsErr (ErrorDict, "dictstackunderflow", ErrorFn); X PExecOverflow = InsErr (ErrorDict, "execstackoverflow", ErrorFn); X PExecUnderflow = InsErr (ErrorDict, "execstackunderflow", ErrorFn); X PInterrupt = InsErr (ErrorDict, "interrupt", ErrorFn); X PInvAccess = InsErr (ErrorDict, "invalidaccess", ErrorFn); X PInvExit = InsErr (ErrorDict, "invalidexit", ErrorFn); X PInvFileAccess = InsErr (ErrorDict, "invalidfileaccess", ErrorFn); X PInvFont = InsErr (ErrorDict, "invalidfont", ErrorFn); X PInvRestore = InsErr (ErrorDict, "invalidrestore", ErrorFn); X PIOError = InsErr (ErrorDict, "ioerror", ErrorFn); X PLimitCheck = InsErr (ErrorDict, "limitcheck", ErrorFn); X PNoCurrentPoint = InsErr (ErrorDict, "nocurrentpoint", ErrorFn); X PRangeCheck = InsErr (ErrorDict, "rangecheck", ErrorFn); X POpOverflow = InsErr (ErrorDict, "stackoverflow", ErrorFn); X POpUnderflow = InsErr (ErrorDict, "stackunderflow", ErrorFn); X PSyntaxError = InsErr (ErrorDict, "syntaxerror", ErrorFn); X PTypeCheck = InsErr (ErrorDict, "typecheck", ErrorFn); X PUndefined = InsErr (ErrorDict, "undefined", ErrorFn); X PUnFilename = InsErr (ErrorDict, "undefinedfilename", ErrorFn); X PUnResult = InsErr (ErrorDict, "undefinedresult", ErrorFn); X PUnMatched = InsErr (ErrorDict, "unmatchedmark", ErrorFn); X PUnregistered = InsErr (ErrorDict, "unregistered", ErrorFn); X PVMError = InsErr (ErrorDict, "VMerror", ErrorFn); X Install ("errordict", ErrorDict); X OpError = MakeOp ("(errorfn)", ErrorFn, 1, 0, 0, 1, Name); X } X X/* X * This is the code to deal with user interrupts X * In order to do this cleanly, we effectively poll for interrupts in the X * main interpreter loop (above). Possibly any routine which could take an X * inordinate amount of time out of this loop should also poll the `interrupted' X * variable and generate an error if one is found. X * Currently none do - "run"ning a file is done by the interpreter above. X * X */ X Xstatic catchint () X { X VOID signal (SIGINT, catchint); X interrupted = TRUE; X } X Xint Interrupted () X { X return interrupted && !protected; X } X X/* X * An intrinsic operator generates an error condition by returning FALSE. X * The usual way to do this is to call Error with the PostScript name of X * the error condition. X * X */ X Xstatic Object InsErr (dict, name, fn) Object dict; char *name; int (*fn)(); X { X Object op; X X DictStore (dict, op = NameFrom (name), MakeOp (name, fn, 1, 0, 0, 1, Name)); X return op; X } X Xstatic ErrorFn (name) Object name; X { X PrintName (Self); X printf (" in operator "); X PrintName (name); X putchar ('\n'); X return Push (ExecStack, Cvx (NameFrom ("stop"))); X } X Xint Error (error) Object error; X { X error_name = error; X return FALSE; X } X XObject MakeObject (type) Type type; X { X Object res; X X res.type = type; X res.flags = READABLE | WRITEABLE; X res.Length = res.u.Integer = 0; X X return res; X } X Xint OpCheck (args, res) int args, res; X { X if (OpStack->stack_fill < args) X return Error (POpUnderflow); X else if (OpStack->stack_fill - args + res > OpStack->stack_size) X return Error (POpOverflow); X else X return TRUE; X } X XPanicIf (cond, s) int cond; char *s; X { X if (cond) X Panic (s); X } X XPanic (s) char *s; X { X fprintf (stderr, "PostScript panic: %s\n", s); X fprintf (stderr, "Please report this fault to the support person for this program\n"); X Cleanup (); X exit (1); X } X Xint min (a, b) int a, b; X { X return a < b ? a : b; X } X Xint rCheck (object) Object object; X { X if (object.type == Dictionary) X return object.u.Dictionary->dict_flags & READABLE; X else X return object.flags & READABLE; X } X Xint wCheck (object) Object object; X { X if (object.type == Dictionary) X return object.u.Dictionary->dict_flags & WRITEABLE; X else X return object.flags & WRITEABLE; X } X Xint xCheck (object) Object object; X { X return object.flags & EXECUTABLE; X } X XObject Cvx (o) Object o; X { X o.flags |= EXECUTABLE; X return o; X } X XObject Cvlit (o) Object o; X { X o.flags &= ~EXECUTABLE; X return o; X } X XObject ExecOnly (o) Object o; X { X if (o.type == Dictionary) X o.u.Dictionary->dict_flags &= ~(READABLE | WRITEABLE); X else X o.flags &= ~(READABLE | WRITEABLE); X return ReadOnly (o); X } X XObject ReadOnly (o) Object o; X { X if (o.type == Dictionary) X o.u.Dictionary->dict_flags &= ~WRITEABLE; X else X o.flags &= ~WRITEABLE; X return o; X } X XObject WriteOnly (o) Object o; X { X if (o.type == Dictionary) X o.u.Dictionary->dict_flags &= ~READABLE; X else X o.flags &= ~READABLE; X return o; X } X XObject SameFlags (a, b) Object a, b; X { X b.flags = a.flags; X return b; X } X Xint Max (a, b) int a, b; X { X return a > b ? a : b; X } X Xint Min (a, b) int a, b; X { X return a < b ? a : b; X } END_OF_FILE if test 10508 -ne `wc -c <'source/main.c'`; then echo shar: \"'source/main.c'\" unpacked with wrong size! fi # end of 'source/main.c' fi if test -f 'source/matrix.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'source/matrix.c'\" else echo shar: Extracting \"'source/matrix.c'\" \(10133 characters\) sed "s/^X//" >'source/matrix.c' <<'END_OF_FILE' X/* X * Copyright (C) Rutherford Appleton Laboratory 1987 X * X * This source may be copied, distributed, altered or used, but not sold for profit X * or incorporated into a product except under licence from the author. X * It is not in the public domain. X * This notice should remain in the source unaltered, and any changes to the source X * made by persons other than the author should be marked as such. X * X * Crispin Goswell @ Rutherford Appleton Laboratory caag@uk.ac.rl.vd X */ X#include "main.h" X#include "graphics.h" X XObject AssignMatrix (); Xextern Matrix identity; Xstatic int PMatrix (); Xstatic int PIdentMatrix (); Xstatic int PDefaultMatrix (); Xstatic int PCurrentMatrix (); Xstatic int PSetMatrix (); Xstatic int PTranslate (); Xstatic int PScale (); Xstatic int PRotate (); Xstatic int PConcat (); Xstatic int PConcatMatrix (); Xstatic int PTransform (); Xstatic int PDTransform (); Xstatic int PITransform (); Xstatic int PIDTransform (); Xstatic int PInvertMatrix (); X XInitMatrix () X { X InstallOp ("matrix", PMatrix, 0, 1, 0, 0); X InstallOp ("initmatrix", PInitMatrix, 0, 0, 0, 0); X InstallOp ("identmatrix", PIdentMatrix, 1, 1, 0, 0, Array); X InstallOp ("defaultmatrix", PDefaultMatrix, 1, 1, 0, 0, Array); X InstallOp ("currentmatrix", PCurrentMatrix, 1, 1, 0, 0, Array); X InstallOp ("setmatrix", PSetMatrix, 1, 0, 0, 0, Array); X InstallOp ("translate", PTranslate, 0, 0, 0, 0); X InstallOp ("scale", PScale, 0, 0, 0, 0); X InstallOp ("rotate", PRotate, 0, 0, 0, 0); X InstallOp ("concat", PConcat, 1, 0, 0, 0, Array); X InstallOp ("concatmatrix", PConcatMatrix, 3, 1, 0, 0, Array, Array, Array); X InstallOp ("transform", PTransform, 0, 0, 0, 0); X InstallOp ("dtransform", PDTransform, 0, 0, 0, 0); X InstallOp ("itransform", PITransform, 0, 0, 0, 0); X InstallOp ("idtransform", PIDTransform, 0, 0, 0, 0); X InstallOp ("invertmatrix", PInvertMatrix, 2, 1, 0, 0, Array, Array); X } X XObject MatrixFrom (m) Matrix m; X { X return AssignMatrix (MakeArray ((Object *) Malloc (6 * sizeof (Object)), 6), m); X } X Xint ExtractMatrix (pm, o) Matrix *pm; Object o; X { X int i; X float temp[6]; X X for (i = 0; i < 6; i++) X { X Object item; X X item = getArray (o, i); X if (TypeOf (item) == Integer) X temp[i] = (float) BodyInteger (item); X else if (TypeOf (item) == Real) X temp[i] = BodyReal (item); X else X return FALSE; X } X X *pm = NewMatrix (temp[0], temp[1], temp[2], temp[3], temp[4], temp[5]); X return TRUE; X } X Xstatic int PMatrix () X { X return Push (OpStack, MatrixFrom (identity)); X } X Xint PInitMatrix () X { X gstate->CTM = gstate->device->default_matrix; X X return TRUE; X } X Xstatic int PIdentMatrix (array) Object array; X { X if (lengthArray (array) != 6) X return Error (PRangeCheck); X VOID AssignMatrix (array, identity); X return Push (OpStack, array); X } X Xstatic int PDefaultMatrix (array) Object array; X { X if (lengthArray (array) != 6) X return Error (PRangeCheck); X VOID AssignMatrix (array, gstate->device->default_matrix); X return Push (OpStack, array); X } X Xstatic int PCurrentMatrix (array) Object array; X { X if (lengthArray (array) != 6) X return Error (PRangeCheck); X VOID AssignMatrix (array, gstate->CTM); X return Push (OpStack, array); X } X Xstatic int PSetMatrix (array) Object array; X { X if (lengthArray (array) != 6) X return Error (PRangeCheck); X else if (!ExtractMatrix (&gstate->CTM, array)) X return Error (PTypeCheck); X else X return TRUE; X } X Xstatic int PTranslate () X { X Object tx, ty, mat; X float x, y; X X if (!OpCheck (2, 1)) X return FALSE; X mat = Pop (OpStack); X if (TypeOf (mat) == Array) X if (!wCheck (mat)) X return Push (OpStack, mat), Error (PInvAccess); X else if (lengthArray (mat) != 6) X return Push (OpStack, mat), Error (PRangeCheck); X else X { X ty = Pop (OpStack); X if (TypeOf (ty) == Integer) X y = (float) BodyInteger (ty); X else if (TypeOf (ty) == Real) X y = BodyReal (ty); X else X return Push (OpStack, ty), Push (OpStack, mat), Error (PTypeCheck); X tx = Pop (OpStack); X if (TypeOf (tx) == Integer) X x = (float) BodyInteger (tx); X else if (TypeOf (tx) == Real) X x = BodyReal (tx); X else X return Push (OpStack, tx), Push (OpStack, ty), Push (OpStack, mat), Error (PTypeCheck); X X VOID AssignMatrix (mat, NewMatrix (1.0, 0.0, 0.0, 1.0, x, y)); X X return Push (OpStack, mat); X } X else if (TypeOf (mat) == Integer) X y = (float) BodyInteger (mat); X else if (TypeOf (mat) == Real) X y = BodyReal (mat); X else X return Push (OpStack, mat), Error (PTypeCheck); X X tx = Pop (OpStack); X if (TypeOf (tx) == Integer) X x = (float) BodyInteger (tx); X else if (TypeOf (tx) == Real) X x = BodyReal (tx); X else X return Push (OpStack, tx), Push (OpStack, mat), Error (PTypeCheck); X gstate->CTM = Translate (gstate->CTM, x, y); X return TRUE; X } X Xstatic int PScale () X { X Object tx, ty, mat; X float x, y; X X if (!OpCheck (2, 1)) X return FALSE; X mat = Pop (OpStack); X if (TypeOf (mat) == Array) X if (!wCheck (mat)) X return Push (OpStack, mat), Error (PInvAccess); X else if (lengthArray (mat) != 6) X return Push (OpStack, mat), Error (PRangeCheck); X else X { X ty = Pop (OpStack); X if (TypeOf (ty) == Integer) X y = (float) BodyInteger (ty); X else if (TypeOf (ty) == Real) X y = BodyReal (ty); X else X return Push (OpStack, ty), Push (OpStack, mat), Error (PTypeCheck); X tx = Pop (OpStack); X if (TypeOf (tx) == Integer) X x = (float) BodyInteger (tx); X else if (TypeOf (tx) == Real) X x = BodyReal (tx); X else X return Push (OpStack, tx), Push (OpStack, ty), Push (OpStack, mat), Error (PTypeCheck); X X VOID AssignMatrix (mat, NewMatrix (x, 0.0, 0.0, y, 0.0, 0.0)); X X return Push (OpStack, mat); X } X else if (TypeOf (mat) == Integer) X y = (float) BodyInteger (mat); X else if (TypeOf (mat) == Real) X y = BodyReal (mat); X else X return Push (OpStack, mat), Error (PTypeCheck); X X tx = Pop (OpStack); X if (TypeOf (tx) == Integer) X x = (float) BodyInteger (tx); X else if (TypeOf (tx) == Real) X x = BodyReal (tx); X else X return Push (OpStack, tx), Push (OpStack, mat), Error (PTypeCheck); X gstate->CTM = Scale (gstate->CTM, x, y); X return TRUE; X } X Xstatic int PRotate () X { X Object ang, mat; X float a; X X if (!OpCheck (1, 1)) X return FALSE; X mat = Pop (OpStack); X if (TypeOf (mat) == Array) X if (!wCheck (mat)) X return Push (OpStack, mat), Error (PInvAccess); X else if (lengthArray (mat) != 6) X return Push (OpStack, mat), Error (PRangeCheck); X else X { X ang = Pop (OpStack); X if (TypeOf (ang) == Integer) X a = (float) BodyInteger (ang); X else if (TypeOf (ang) == Real) X a = BodyReal (ang); X else X return Push (OpStack, ang), Push (OpStack, mat), Error (PTypeCheck); X X VOID AssignMatrix (mat, NewMatrix (cos(a), sin(a), -sin(a), -cos(a), 0.0, 0.0)); X X return Push (OpStack, mat); X } X else if (TypeOf (mat) == Integer) X a = (float) BodyInteger (mat); X else if (TypeOf (mat) == Real) X a = BodyReal (mat); X else X return Push (OpStack, mat), Error (PTypeCheck); X X gstate->CTM = Rotate (gstate->CTM, Rad (a)); X return TRUE; X } X Xstatic int PConcat (mat) Object mat; X { X Matrix m; X X if (!ExtractMatrix (&m, mat)) X return Error (PTypeCheck); X gstate->CTM = MatMult (m, gstate->CTM); X return TRUE; X } X Xstatic int PConcatMatrix (mat1, mat2, mat3) Object mat1, mat2, mat3; X { X Matrix m1, m2; X X if (!ExtractMatrix (&m1, mat1) || !ExtractMatrix (&m2, mat2) || X lengthArray (mat3) != 6) X return Error (PTypeCheck); X VOID AssignMatrix (mat3, MatMult (m1, m2)); X VOID Push (OpStack, mat3); X return TRUE; X } X Xstatic int Transfn (fn) Vector (*fn)(); X { X Matrix m; X Object tx, ty, mat; X Vector v; X float x, y; X int mflag = FALSE; X X m = gstate->CTM; X if (!OpCheck (2, 1)) X return FALSE; X X mat = Pop (OpStack); X if (TypeOf (mat) == Array) X { X if (lengthArray (mat) != 6 || !ExtractMatrix (&m, mat)) X return Push (OpStack, mat), Error (PTypeCheck); X mflag = TRUE; X } X else X VOID Push (OpStack, mat); X X if (!OpCheck (2, 1)) X return Push (OpStack, mat), FALSE; X ty = Pop (OpStack); X if (TypeOf (ty) == Integer) X y = (float) BodyInteger (ty); X else if (TypeOf (ty) == Real) X y = BodyReal (ty); X else X { X VOID Push (OpStack, ty); X if (mflag) X VOID Push (OpStack, mat); X return Error (PTypeCheck); X } X tx = Pop (OpStack); X if (TypeOf (tx) == Integer) X x = (float) BodyInteger (tx); X else if (TypeOf (tx) == Real) X x = BodyReal (tx); X else X { X VOID Push (OpStack, tx); X VOID Push (OpStack, ty); X if (mflag) X VOID Push (OpStack, mat); X return Error (PTypeCheck); X } X X v = (*fn) (NewVector (x, y, 1.0), m); X X return Push (OpStack, MakeReal (v.vx)), Push (OpStack, MakeReal (v.vy)); X } X Xstatic int PTransform () X { X return Transfn (Transform); X } X Xstatic int PDTransform () X { X return Transfn (DTransform); X } X Xstatic int PITransform () X { X return Transfn (ITransform); X } X Xstatic int PIDTransform () X { X return Transfn (IDTransform); X } X Xstatic int PInvertMatrix (mat1, mat2) Object mat1, mat2; X { X Matrix m; X X if (!ExtractMatrix (&m, mat1) || lengthArray (mat2) != 6) X return Error (PTypeCheck); X VOID AssignMatrix (mat2, MatInvert (m)); X VOID Push (OpStack, mat2); X return TRUE; X } X XPoint IntToExt (p) HardPoint p; X { X Vector v; X X v = Transform (NewVector ((float) p.hx, (float) p.hy, 1.0), MatInvert (gstate->CTM)); X return NewPoint (v.vx, v.vy); X } X XHardPoint ExtToInt (p) Point p; X { X Vector v; X X v = Transform (NewVector (p.x, p.y, 1.0), gstate->CTM); X return NewHardPoint (v.vx, v.vy); X } X XMatrix PointTranslate (m, p) Matrix m; Point p; X { X return Translate (m, p.x, p.y); X } X XMatrix HardPointTranslate (m, p) Matrix m; HardPoint p; X { X m.tx += p.hx; X m.ty += p.hy; X X return m; X } X XObject AssignMatrix (o, m) Object o; Matrix m; X { X Object *vec = BodyArray (o); X X vec[0] = MakeReal (m.A); X vec[1] = MakeReal (m.B); X vec[2] = MakeReal (m.C); X vec[3] = MakeReal (m.D); X vec[4] = MakeReal (m.tx); X vec[5] = MakeReal (m.ty); X X return o; X } END_OF_FILE if test 10133 -ne `wc -c <'source/matrix.c'`; then echo shar: \"'source/matrix.c'\" unpacked with wrong size! fi # end of 'source/matrix.c' fi if test -f 'source/path.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'source/path.c'\" else echo shar: Extracting \"'source/path.c'\" \(10211 characters\) sed "s/^X//" >'source/path.c' <<'END_OF_FILE' X/* X * Copyright (C) Rutherford Appleton Laboratory 1987 X * X * This source may be copied, distributed, altered or used, but not sold for profit X * or incorporated into a product except under licence from the author. X * It is not in the public domain. X * This notice should remain in the source unaltered, and any changes to the source X * made by persons other than the author should be marked as such. X * X * Crispin Goswell @ Rutherford Appleton Laboratory caag@uk.ac.rl.vd X */ X#include "main.h" X X#include "graphics.h" X X#define PATHFORALLDEPTH 500 X Xstatic int PCurrentPoint (); Xstatic int PMoveTo (); Xstatic int PRMoveTo (); Xstatic int PLineTo (); Xstatic int PRLineTo (); Xstatic int PArc (); Xstatic int PArcN (); Xstatic int PArcTo (); Xstatic int PCurveTo (); Xstatic int PRCurveTo (); Xstatic int PClosePath (); Xstatic int PPathBBox (); Xstatic int PReversePath (); Xstatic int PPathForAll (); X Xstatic int PathForAll (); Xstatic int PPathProc (); X Xint PFlattenPath (); X XObject OpPathForAll; X XInitPath () X { X OpPathForAll = MakeOp ("(oppathforall)", PathForAll, 0, 6, 7, 7); X X InstallOp ("newpath", PNewPath, 0, 0, 0, 0); X InstallOp ("currentpoint", PCurrentPoint, 0, 2, 0, 0); X InstallOp ("moveto", PMoveTo, 2, 0, 0, 0, Float, Float); X InstallOp ("rmoveto", PRMoveTo, 2, 0, 0, 0, Float, Float); X InstallOp ("lineto", PLineTo, 2, 0, 0, 0, Float, Float); X InstallOp ("rlineto", PRLineTo, 2, 0, 0, 0, Float, Float); X InstallOp ("arc", PArc, 5, 0, 0, 0, Float, Float, Float, Float, Float); X InstallOp ("arcn", PArcN, 5, 0, 0, 0, Float, Float, Float, Float, Float); X InstallOp ("arcto", PArcTo, 5, 4, 0, 0, Float, Float, Float, Float, Float); X InstallOp ("curveto", PCurveTo, 6, 0, 0, 0, Float, Float, Float, Float, Float, Float); X InstallOp ("rcurveto", PRCurveTo, 6, 0, 0, 0, Float, Float, Float, Float, Float, Float); X InstallOp ("closepath", PClosePath, 0, 0, 0, 0); X InstallOp ("pathbbox", PPathBBox, 0, 4, 0, 0); X InstallOp ("flattenpath", PFlattenPath, 0, 0, 0, 0); X InstallOp ("reversepath", PReversePath, 0, 0, 0, 0); X InstallOp ("pathforall", PPathForAll, 4, 0, 0, 6, Array, Array, Array, Array); X InstallOp ("pathproc", PPathProc, 0, 1, 0, 0); X gstate->path = NewPath (); X gstate->clip = NewPath (); X } X Xint PNewPath () X { X gstate->cp_defined = FALSE; X PathFree (gstate->path); X gstate->path = NewPath (); X return TRUE; X } X Xstatic int PCurrentPoint () X { X Point cp; X X if (!gstate->cp_defined) X return Error (PNoCurrentPoint); X cp = IntToExt (gstate->cp); X VOID Push (OpStack, MakeReal (PointX (cp))); X VOID Push (OpStack, MakeReal (PointY (cp))); X return TRUE; X } X Xstatic int PMoveTo (x, y) Object x, y; X { X return MoveTo (gstate->path, ExtToInt (NewPoint (BodyReal (x), BodyReal (y)))); X } X Xstatic int PRMoveTo (x, y) Object x, y; X { X if (!gstate->cp_defined) X return Error (PNoCurrentPoint); X return MoveTo (gstate->path, ExtToInt (MovePoint (NewPoint (BodyReal (x), BodyReal (y)), IntToExt (gstate->cp)))); X } X Xstatic int PLineTo (x, y) Object x, y; X { X if (!gstate->cp_defined) X return Error (PNoCurrentPoint); X return LineTo (gstate->path, ExtToInt (NewPoint (BodyReal (x), BodyReal (y)))); X } X X Xstatic int PRLineTo (x, y) Object x, y; X { X if (!gstate->cp_defined) X return Error (PNoCurrentPoint); X return LineTo (gstate->path, ExtToInt (MovePoint (NewPoint (BodyReal (x), BodyReal (y)), IntToExt (gstate->cp)))); X } X Xstatic int PArc (x, y, rad, ang1, ang2) Object x, y, rad, ang1, ang2; X { X Point centre, start; X float a1 = Rad (BodyReal (ang1)), a2 = Rad (BodyReal (ang2)); X float r = BodyReal (rad); X X start = NewPoint (cos (a1) * r, sin (a1) * r); X centre = NewPoint (BodyReal (x), BodyReal (y)); X if (!(*(EmptyPath (gstate->path) ? MoveTo : LineTo)) (gstate->path, ExtToInt (MovePoint (centre, start)))) X return FALSE; X return Arc (gstate->path, 1, centre, r, a1, a2); X } X Xstatic int PArcN (x, y, rad, ang1, ang2) Object x, y, rad, ang1, ang2; X { X Point centre, start; X float a1 = Rad (BodyReal (ang1)), a2 = Rad (BodyReal (ang2)); X float r = BodyReal (rad); X X start = NewPoint (cos (a1) * r, sin (a1) * r); X centre = NewPoint (BodyReal (x), BodyReal (y)); X if (!(*(EmptyPath (gstate->path) ? MoveTo : LineTo)) (gstate->path, ExtToInt (MovePoint (centre, start)))) X return FALSE; X return Arc (gstate->path, -1, centre, r, a1, a2); X } X Xstatic int PArcTo (X1, Y1, X2, Y2, rad) Object X1, Y1, X2, Y2, rad; X { X float xt1, xt2, yt1, yt2; X if (!gstate->cp_defined) X return Error (PNoCurrentPoint); X X return ArcTo (gstate->path, gstate->cp, X BodyReal (X1), BodyReal (Y1), BodyReal (X2), BodyReal (Y2), BodyReal (rad), X &xt1, &yt1, &xt2, &yt2) && X Push (OpStack, MakeReal (xt1)) && X Push (OpStack, MakeReal (yt1)) && X Push (OpStack, MakeReal (xt2)) && X Push (OpStack, MakeReal (yt2)); X } X Xstatic int PCurveTo (x0, y0, x1, y1, x2, y2) Object x0, y0, x1, y1, x2, y2; X { X if (!gstate->cp_defined) X return Error (PNoCurrentPoint); X return CurveTo (gstate->path, X ExtToInt (NewPoint (BodyReal (x0), BodyReal (y0))), X ExtToInt (NewPoint (BodyReal (x1), BodyReal (y1))), X ExtToInt (NewPoint (BodyReal (x2), BodyReal (y2)))); X } X Xstatic int PRCurveTo (x0, y0, x1, y1, x2, y2) Object x0, y0, x1, y1, x2, y2; X { X Point cp; X X if (!gstate->cp_defined) X return Error (PNoCurrentPoint); X cp = IntToExt (gstate->cp); X return CurveTo (gstate->path, X ExtToInt (MovePoint (cp, NewPoint (BodyReal (x0), BodyReal (y0)))), X ExtToInt (MovePoint (cp, NewPoint (BodyReal (x1), BodyReal (y1)))), X ExtToInt (MovePoint (cp, NewPoint (BodyReal (x2), BodyReal (y2))))); X } X Xstatic int PClosePath () X { X return ClosePath (gstate->path); X } X Xint PFlattenPath () X { X Path res; X X if ((res = FlattenPath (gstate->path)) == NULL) X return Error (PLimitCheck); X SetPath (&gstate->path, res); X return TRUE; X } X Xstatic int PReversePath () X { X Path res; X X if ((res = ReversePath (gstate->path)) == NULL) X return Error (PLimitCheck); X SetPath (&gstate->path, res); X return TRUE; X } X Xstatic Path pathforall [PATHFORALLDEPTH], *pathp = pathforall; Xstatic int path_depth = 0; X Xstatic int PPathForAll (move, line, curve, close) Object move, line, curve, close; X { X Path res; X X if ((res = PathCopy (gstate->path)) == NULL || path_depth == PATHFORALLDEPTH - 1) X return Error (PLimitCheck); X *++pathp = res; X ++path_depth; X VOID Push (ExecStack, Nil); X VOID Push (ExecStack, move); X VOID Push (ExecStack, line); X VOID Push (ExecStack, curve); X VOID Push (ExecStack, close); X VOID Push (ExecStack, OpPathForAll); X return TRUE; X } X Xstatic int PathForAll () X { X Path res; X Object move, line, curve, close, fn; X Point p; X X close = Pop (ExecStack); X curve = Pop (ExecStack); X line = Pop (ExecStack); X move = Pop (ExecStack); X if (EmptyPath (*pathp)) X { X PathFree (*pathp--); X --path_depth; X VOID Pop (ExecStack); X return TRUE; X } X res = (*pathp)->next; X switch (res->ptype) X { X case EMove: X p = IntToExt (res->pe.point); X VOID Push (OpStack, MakeReal (p.x)); X VOID Push (OpStack, MakeReal (p.y)); X fn = move; X break; X X case ELine: X p = IntToExt (res->pe.point); X VOID Push (OpStack, MakeReal (p.x)); X VOID Push (OpStack, MakeReal (p.y)); X fn = line; X break; X X case ECurve: X p = IntToExt (res->pe.curve.x0); X VOID Push (OpStack, MakeReal (p.x)); X VOID Push (OpStack, MakeReal (p.y)); X p = IntToExt (res->pe.curve.x1); X VOID Push (OpStack, MakeReal (p.x)); X VOID Push (OpStack, MakeReal (p.y)); X p = IntToExt (res->pe.curve.x2); X VOID Push (OpStack, MakeReal (p.x)); X VOID Push (OpStack, MakeReal (p.y)); X fn = curve; X break; X X case EClose: X fn = close; X break; X X default: X Panic ("OpPathForAll - encounters unknown path element"); X } X VOID Push (ExecStack, move); X VOID Push (ExecStack, line); X VOID Push (ExecStack, curve); X VOID Push (ExecStack, close); X VOID Push (ExecStack, OpPathForAll); X VOID Push (ExecStack, fn); X X PathDelete (res->next); X return TRUE; X } X Xstatic int PPathProc () X { X Object *body, *p; X int sum = 0; X Path pa; X Point po; X X for (pa = gstate->path->next; pa != gstate->path; pa = pa->next) X switch (pa->ptype) X { X case EMove: case ELine: sum += 3; break; X case ECurve: sum += 7; break; X case EClose: ++sum; break; X } X X p = body = (Object *) Malloc ((unsigned) sizeof (Object) * sum); X for (pa = gstate->path->next; pa != gstate->path; pa = pa->next) X switch (pa->ptype) X { X case EMove: X po = IntToExt (pa->pe.point); X *p++ = MakeReal (po.x); X *p++ = MakeReal (po.y); X *p++ = Cvx (NameFrom ("moveto")); X break; X X case ELine: X po = IntToExt (pa->pe.point); X *p++ = MakeReal (po.x); X *p++ = MakeReal (po.y); X *p++ = Cvx (NameFrom ("lineto")); X break; X X case ECurve: X po = IntToExt (pa->pe.curve.x0); X *p++ = MakeReal (po.x); X *p++ = MakeReal (po.y); X po = IntToExt (pa->pe.curve.x1); X *p++ = MakeReal (po.x); X *p++ = MakeReal (po.y); X po = IntToExt (pa->pe.curve.x2); X *p++ = MakeReal (po.x); X *p++ = MakeReal (po.y); X *p++ = Cvx (NameFrom ("curve")); X break; X X case EClose: X *p++ = Cvx (NameFrom ("closepath")); X break; X } X return Push (OpStack, Cvx (MakeArray (body, sum))); X } X Xstatic int PPathBBox () X { X Point right_top, left_bottom, left_top, right_bottom; X float left, right, top, bottom, uleft, uright, utop, ubottom; X X if (!PathBBox (&left, &right, &top, &bottom)) X return FALSE; X X left_bottom = IntToExt (NewHardPoint (left, bottom)); X right_bottom = IntToExt (NewHardPoint (right, bottom)); X right_top = IntToExt (NewHardPoint (right, top)); X left_top = IntToExt (NewHardPoint (left, top)); X X uleft = uright = left_bottom.x; utop = ubottom = left_bottom.y; X UserBound (&uleft, &uright, &utop, &ubottom, left_top); X UserBound (&uleft, &uright, &utop, &ubottom, right_top); X UserBound (&uleft, &uright, &utop, &ubottom, right_bottom); X X VOID Push (OpStack, MakeReal (uleft)); X VOID Push (OpStack, MakeReal (ubottom)); X VOID Push (OpStack, MakeReal (uright)); X VOID Push (OpStack, MakeReal (utop)); X X return TRUE; X } END_OF_FILE if test 10211 -ne `wc -c <'source/path.c'`; then echo shar: \"'source/path.c'\" unpacked with wrong size! fi # end of 'source/path.c' fi echo shar: End of archive 8 \(of 18\). cp /dev/null ark8isdone MISSING="" for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 18 archives. rm -f ark[1-9]isdone ark[1-9][0-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 J