This is a patch for Crispin Goswell's postscript interpreter, which was posted to comp.sources.unix a while back. If you don't have the interpreter, you can get it from one of the comp.sources.unix archives. Soon after the interpreter was posted, I posted these fixes to comp.sources.bugs, but they unfortunately had lines wrapped by our mailer. This first patch is equivalent to that posting (modulo line wrapping) and if you successfully applied that posting, you can skip to the next patch. To install this, you need the 'patch' program which is also available from the comp.sources.unix archives. Change directories to the top-level postscript directory (the one with the file "MANIFEST" in it) and apply this patch with the command: patch -p0 getenv + if the environment variable exists, or + getenv + if it does not. + + + John G. Myers + jm36@andrew.cmu.edu + jgm@k.gp.cs.cmu.edu diff -cr orig/postscript/psrc ./postscript/psrc *** orig/postscript/psrc Sun Jan 3 14:22:51 1988 --- ./postscript/psrc Sun Dec 13 22:58:09 1987 *************** *** 10,17 **** /bind {} def ! /save { gsave /save } def ! /restore { grestore pop } def /raise { errordict exch get exec } def /beep ( ) dup 0 7 put def --- 10,21 ---- /bind {} def ! %% Start mods by jgm ! /$$SAVELEVEL 0 def ! /save { gsave /save /$$SAVELEVEL $$SAVELEVEL 1 add def } def ! /restore { grestore pop /$$SAVELEVEL $$SAVELEVEL 1 sub def } def ! /vmstatus { $$SAVELEVEL 10000 10000 } def ! %% End mods by jgm /raise { errordict exch get exec } def /beep ( ) dup 0 7 put def diff -cr orig/source/array.c ./source/array.c *** orig/source/array.c Sun Jan 3 14:21:55 1988 --- ./source/array.c Sat Dec 12 01:05:28 1987 *************** *** 17,22 **** --- 17,23 ---- static int forAll (), ForAll (), PReadOnly (), PExecOnly (), PrCheck (), PwCheck (); static int PutInterval (), GetInterval (), Put (), Get (), Length (), Copy (), Eq (); + static int PNoAccess (); /*jgm*/ int ExecArray (); Object Marker; *************** *** 53,58 **** --- 54,60 ---- TypeInstallOp (Array, "length", PLength, 1, 1, 0, 0, Array); TypeInstallOp (Array, "copy", Copy, 2, 0, 0, 0, Array, Array); TypeInstallOp (Array, "forall", ForAll, 2, 0, 0, 4, Array, Array); + TypeInstallOp (Array, "noaccess", PNoAccess, 1, 1, 0, 0, Array); /*jgm*/ TypeInstallOp (Array, "executeonly", PExecOnly, 1, 1, 0, 0, Array); TypeInstallOp (Array, "readonly", PReadOnly, 1, 1, 0, 0, Array); TypeInstallOp (Array, "rcheck", PrCheck, 1, 1, 0, 0, Array); *************** *** 385,390 **** --- 387,398 ---- body[i] = Pop (OpStack); return Push (OpStack, array); } + } + + /* PNoAccess by jgm */ + static int PNoAccess (item) Object item; + { + return Push (OpStack, NoAccess (item)); } static int PExecOnly (item) Object item; diff -cr orig/source/cache.c ./source/cache.c *** orig/source/cache.c Sun Jan 3 14:22:42 1988 --- ./source/cache.c Thu Dec 10 21:26:47 1987 *************** *** 501,512 **** if ((ccache = SearchCache (m, BodyFontID (DictLoad (gstate->font, Fid)))) == NULL) return Error (PInvFont); - Message (disk_name); VOID sprintf (disk_name, "%s/cache/%.*s/%3d%3d%3d%3d", library, lengthName (font_name), BodyName (font_name), (int) right.vx, (int) right.vy, (int) bottom.vx, (int) bottom.vy); if ((fp = fopen (disk_name, "w")) == NULL) return Error (PInvFileAccess); --- 501,512 ---- if ((ccache = SearchCache (m, BodyFontID (DictLoad (gstate->font, Fid)))) == NULL) return Error (PInvFont); VOID sprintf (disk_name, "%s/cache/%.*s/%3d%3d%3d%3d", library, lengthName (font_name), BodyName (font_name), (int) right.vx, (int) right.vy, (int) bottom.vx, (int) bottom.vy); + Message (disk_name); /* moved from before to after prev line -- jgm */ if ((fp = fopen (disk_name, "w")) == NULL) return Error (PInvFileAccess); diff -cr orig/source/config.c ./source/config.c *** orig/source/config.c Sun Jan 3 14:19:54 1988 --- ./source/config.c Fri Jan 1 13:58:10 1988 *************** *** 87,91 **** Install ("polytype", DictFrom (Poly)); Install ("fonttype", DictFrom (FontID)); ! Install ("version", StringFrom ("Version 1.4")); } --- 87,91 ---- Install ("polytype", DictFrom (Poly)); Install ("fonttype", DictFrom (FontID)); ! Install ("version", StringFrom ("Version 1.4 with mods by jgm")); /* jgm */ } diff -cr orig/source/control.c ./source/control.c *** orig/source/control.c Sun Jan 3 14:26:55 1988 --- ./source/control.c Sun Dec 13 23:13:46 1987 *************** *** 65,71 **** InstallOp ("loop", PLoop, 1, 0, 0, 4, Array); InstallOp ("exit", PExit, 0, 0, 0, 0); InstallOp ("stop", PStop, 0, 1, 0, 0); ! InstallOp ("stopped", PStopped, 1, 1, 0, 3, Array); InstallOp ("quit", PQuit, 0, 0, 0, 0); InstallOp ("start", PStart, 0, 0, 0, 0); InstallOp ("countexecstack", --- 65,72 ---- InstallOp ("loop", PLoop, 1, 0, 0, 4, Array); InstallOp ("exit", PExit, 0, 0, 0, 0); InstallOp ("stop", PStop, 0, 1, 0, 0); ! /* Changed from "Array" to "Poly" --jgm*/ ! InstallOp ("stopped", PStopped, 1, 1, 0, 3, Poly); InstallOp ("quit", PQuit, 0, 0, 0, 0); InstallOp ("start", PStart, 0, 0, 0, 0); InstallOp ("countexecstack", diff -cr orig/source/dictionary.c ./source/dictionary.c *** orig/source/dictionary.c Sun Jan 3 14:22:55 1988 --- ./source/dictionary.c Sat Dec 12 01:06:49 1987 *************** *** 23,28 **** --- 23,29 ---- static int PDict (), PBegin (), PEnd (), PDef (), PStore (), PKnown (), PLoad (); static int PrCheck (), PwCheck (), PReadOnly (), EqDict (); static int PWhere (), PMaxLength (), PCurrentDict (); + static int PNoAccess (); /*jgm*/ static int hash_tries = 0, hash_collisions = 0, hash_attempts = 0; static int PHashStats (), PDictHash (); *************** *** 57,62 **** --- 58,64 ---- TypeInstallOp (Dictionary, "length", LengthDict, 1, 1, 0, 0, Dictionary); TypeInstallOp (Dictionary, "copy", CopyDict, 2, 0, 0, 0, Dictionary, Dictionary); TypeInstallOp (Dictionary, "forall", ForDict, 2, 0, 0, 4, Dictionary, Array); + TypeInstallOp (Dictionary, "noaccess", PNoAccess, 1, 1, 0, 0, Dictionary); /*jgm*/ TypeInstallOp (Dictionary, "readonly", PReadOnly, 1, 1, 0, 0, Dictionary); TypeInstallOp (Dictionary, "rcheck", PrCheck, 1, 1, 0, 0, Dictionary); TypeInstallOp (Dictionary, "wcheck", PwCheck, 1, 1, 0, 0, Dictionary); *************** *** 511,516 **** --- 513,524 ---- static int PCurrentDict () { return Push (OpStack, Top (DictStack)); + } + + /* PNoAccess by jgm */ + static int PNoAccess (item) Object item; + { + return Push (OpStack, NoAccess (item)); } static int PReadOnly (item) Object item; diff -cr orig/source/image.c ./source/image.c *** orig/source/image.c Sun Jan 3 14:22:32 1988 --- ./source/image.c Mon Dec 28 18:17:04 1987 *************** *** 353,363 **** else { middle2 = NewBitmapHardware (dwidth, h); ! for (i = 0; i < dwidth; i++) ! BitBlt (from, middle2, ! NewDevicePoint ((int) (i/xscale), 0), NewDevicePoint (i, 0), NewDevicePoint (1, h), ROP_OR); } if (dheight > h) --- 353,365 ---- else { middle2 = NewBitmapHardware (dwidth, h); ! /* begin changes by cc4b --jgm */ ! for (i = 0; i < w; i++) ! BitBlt( from, middle2, ! NewDevicePoint (i, 0), NewDevicePoint( (int) (i * xscale), 0), NewDevicePoint (1, h), ROP_OR); + /* end changes by cc4b --jgm */ } if (dheight > h) *************** *** 382,392 **** else { high2 = NewBitmapHardware (dwidth, dheight); ! for (i = 0; i < dheight; i++) ! BitBlt (middle2, high2, ! NewDevicePoint (0, (int) (i/yscale)), NewDevicePoint (0, i), NewDevicePoint (dwidth, 1), ROP_OR); } return high2; } --- 384,397 ---- else { high2 = NewBitmapHardware (dwidth, dheight); ! ! /* begin changes by cc4b --jgm */ ! for (i = 0; i < h; i++ ) ! BitBlt( middle2, high2, ! NewDevicePoint (0, i), NewDevicePoint( 0, (int) (i * yscale)), NewDevicePoint (dwidth, 1), ROP_OR); + /* end changes by cc4b --jgm */ } return high2; } diff -cr orig/source/integer.c ./source/integer.c *** orig/source/integer.c Sun Jan 3 14:21:32 1988 --- ./source/integer.c Thu Dec 10 20:44:17 1987 *************** *** 72,80 **** int StrictMul (a, b) int a, b; { ! int atop, abot, btop, bbot, sum, signed; ! signed = (a < 0) != (b < 0); a = a < 0 ? -a : a; b = b < 0 ? -b : b; abot = a & LowMask; --- 72,81 ---- int StrictMul (a, b) int a, b; { ! /* Variable signed changed to signedp by jgm for ANSI C */ ! int atop, abot, btop, bbot, sum, signedp; ! signedp = (a < 0) != (b < 0); a = a < 0 ? -a : a; b = b < 0 ? -b : b; abot = a & LowMask; *************** *** 86,92 **** sum = ((unsigned) sum >> Word2) + atop * btop; if (sum != 0 || a * b < 0) kill (getpid (), SIGFPE); ! return signed ? -a * b : a * b; } int StrictAdd (a, b) int a, b; --- 87,93 ---- sum = ((unsigned) sum >> Word2) + atop * btop; if (sum != 0 || a * b < 0) kill (getpid (), SIGFPE); ! return signedp ? -a * b : a * b; } int StrictAdd (a, b) int a, b; diff -cr orig/source/main.c ./source/main.c *** orig/source/main.c Sun Jan 3 14:22:13 1988 --- ./source/main.c Sun Dec 13 00:40:04 1987 *************** *** 187,210 **** Object newitem; newitem = Load (item); ! if (TypeOf (newitem) != Condition) ! item = newitem; ! ! if (!xCheck (item)) ! res = Push (OpStack, item); ! else if (TypeOf (item) == Operator) ! res = ExecOperator (item); ! else if (TypeOf (item) == Array) ! res = ExecArray (item); ! else if (TypeOf (item) == File) ! res = ExecFile (item); ! else ! { ! res = Push (OpStack, item); ! exop = Lookup (TypeOf (item), execName); ! if (TypeOf (exop) != Condition) ! VOID Push (ExecStack, exop); ! } } else { --- 187,216 ---- Object newitem; newitem = Load (item); ! /* begin jgm */ ! if (TypeOf (newitem) == Condition) { ! VOID Push(OpStack, item); ! res = Push(ExecStack, DictLoad(ErrorDict,PUndefined)); ! } else { ! /* end jgm */ ! item = newitem; ! ! if (!xCheck (item)) ! res = Push (OpStack, item); ! else if (TypeOf (item) == Operator) ! res = ExecOperator (item); ! else if (TypeOf (item) == Array) ! res = ExecArray (item); ! else if (TypeOf (item) == File) ! res = ExecFile (item); ! else ! { ! res = Push (OpStack, item); ! exop = Lookup (TypeOf (item), execName); ! if (TypeOf (exop) != Condition) ! VOID Push (ExecStack, exop); ! } ! } /* jgm */ } else { *************** *** 340,350 **** return TRUE; } ! PanicIf (cond, s) int cond; char *s; ! { ! if (cond) ! Panic (s); ! } Panic (s) char *s; { --- 346,358 ---- return TRUE; } ! #ifdef needed /* Macroized --jgm */ ! XPanicIf (cond, s) int cond; char *s; ! X { ! X if (cond) ! X Panic (s); ! X } ! #endif Panic (s) char *s; { *************** *** 392,397 **** --- 400,416 ---- return o; } + /* NoAccess by jgm */ + Object NoAccess (o) Object o; + { + if (o.type == Dictionary) + o.u.Dictionary->dict_flags &= ~(READABLE | WRITEABLE | EXECUTABLE); + else + o.flags &= ~(READABLE | WRITEABLE | EXECUTABLE); + return o; + } + + Object ExecOnly (o) Object o; { if (o.type == Dictionary) *************** *** 398,404 **** o.u.Dictionary->dict_flags &= ~(READABLE | WRITEABLE); else o.flags &= ~(READABLE | WRITEABLE); ! return ReadOnly (o); } Object ReadOnly (o) Object o; --- 417,423 ---- o.u.Dictionary->dict_flags &= ~(READABLE | WRITEABLE); else o.flags &= ~(READABLE | WRITEABLE); ! return o; /* Removed redundant call to ReadOnly -- jgm */ } Object ReadOnly (o) Object o; diff -cr orig/source/main.h ./source/main.h *** orig/source/main.h Sun Jan 3 14:19:59 1988 --- ./source/main.h Sat Dec 12 00:58:43 1987 *************** *** 74,79 **** --- 74,80 ---- Object overflow, underflow, *stack_body; } *Stack, StackOb; + Object NoAccess (); /* jgm */ Object SameFlags (), MakeObject (), Cvx (), Cvlit (), ReadOnly (), WriteOnly (), ExecOnly (); int OpCheck (), min (), rCheck (), wCheck (), xCheck (); Object MakeArray (), ParseArray (), getArray (), getIArray (), *BodyArray (); *************** *** 164,166 **** --- 165,170 ---- ((getchbuf = getc (BodyFile(file)->f.f_ptr)), \ ((getchbuf != EOF) ? getchbuf : ((BodyFile(file)->available = 0), Close (file), EOF))) \ : GeneralGetch (file)) + + /* Next line --jgm */ + #define PanicIf(flag,s) do { if (flag) Panic(s); } while (0) diff -cr orig/source/math.c ./source/math.c *** orig/source/math.c Sun Jan 3 14:20:43 1988 --- ./source/math.c Fri Dec 11 22:54:46 1987 *************** *** 108,113 **** --- 108,115 ---- { int olength = length, dval; + if (length == 0) return MakeReal (sign * (double)ival); /*jgm*/ + fval = ival; dval = ParseInteger (&s, &length, 10); fval += dval * pow (10.0, (float)(length - olength)); diff -cr orig/source/makefile ./source/makefile *** orig/source/makefile Sun Jan 3 14:19:33 1988 --- ./source/makefile Sun Jan 3 15:37:00 1988 *************** *** 4,16 **** LIBS=libww.a -lsuntool -lsunwindow -lpixrect -g GRAPHICS=cache.o colour.o device.o fill.o font.o gsave.o image.o mat.o matrix.o\ pat.o path.o state.o stroke.o CFLAGS=-O PS: $(OBJECTS) $(GRAPHICS) hard.o canon.a cc $(CFLAGS) $(OBJECTS) $(GRAPHICS) hard.o canon.a -lm `libs` -o PS ! sunPS: $(OBJECTS) $(GRAPHICS) hard.o canon.a pixrect ! cc $(CFLAGS) $(OBJECTS) $(GRAPHICS) hard.o canon.a -lm -lpixrect -o sunPS CPS: $(OBJECTS) $(GRAPHICS) colour-ww.o trapezoid.o canon.o cc $(CFLAGS) $(OBJECTS) $(GRAPHICS) colour-ww.o canon.o trapezoid.o -lm `libs` -o CPS --- 4,23 ---- LIBS=libww.a -lsuntool -lsunwindow -lpixrect -g GRAPHICS=cache.o colour.o device.o fill.o font.o gsave.o image.o mat.o matrix.o\ pat.o path.o state.o stroke.o + + # For SUN with 68881 + #CFLAGS=-O -f68881 + + # For others CFLAGS=-O + #default: sunPS + PS: $(OBJECTS) $(GRAPHICS) hard.o canon.a cc $(CFLAGS) $(OBJECTS) $(GRAPHICS) hard.o canon.a -lm `libs` -o PS ! sunPS: $(OBJECTS) $(GRAPHICS) pixrect.o canon.a ! cc $(CFLAGS) $(OBJECTS) $(GRAPHICS) pixrect.o canon.a -lm -lpixrect -o sunPS CPS: $(OBJECTS) $(GRAPHICS) colour-ww.o trapezoid.o canon.o cc $(CFLAGS) $(OBJECTS) $(GRAPHICS) colour-ww.o canon.o trapezoid.o -lm `libs` -o CPS *************** *** 31,39 **** all: PS postscript viewer ww: ww.o wwlib installww - - pixrect: pixrect.o - cp pixrect.o hard.o sun: ww wwsun --- 38,43 ---- diff -cr orig/source/misc.c ./source/misc.c *** orig/source/misc.c Sun Jan 3 14:19:36 1988 --- ./source/misc.c Sun Dec 13 22:03:56 1987 *************** *** 17,27 **** --- 17,29 ---- #endif static int PUserTime (); + static int PGetEnv (); /*jgm*/ InitMisc () { InstallOp ("usertime", PUserTime, 0, 1, 0, 0); InstallOp ("==", PolyFirst, 1, 1, 0, 0, Poly); + InstallOp ("getenv", PGetEnv, 1, 1, 0, 0, String); /*jgm*/ } static int PUserTime () *************** *** 32,34 **** --- 34,50 ---- times (&tbuf); return Push (OpStack, MakeInteger ((int) (tbuf.tms_utime * 1000 / HZ))); } + + /* PGetEnv by jgm */ + static int PGetEnv(string) Object string; + { + char *s, *getenv(); + + s = getenv(BodyString(string)); + + if (s != NULL) { + VOID Push(OpStack, MakeString(s, strlen(s))); + } + + return Push(OpStack, MakeBoolean(s != NULL)); + } diff -cr orig/source/string.c ./source/string.c *** orig/source/string.c Sun Jan 3 14:23:16 1988 --- ./source/string.c Sat Dec 12 01:32:44 1987 *************** *** 22,27 **** --- 22,28 ---- static int Exec (), Token (), PString (), Search (), AnchorSearch (), Copy (), EqEq (); static int Length (), ForAll (), Get (), Put (), GetInterval (), PutInterval (), Eq (), Lt (), Le (), Gt (), Ge (), PrCheck (), PwCheck (); static int Cvi (), Cvr (), Cvs (), PReadOnly (), PExecOnly (); + static int PNoAccess (); /* jgm */ InitString () { *************** *** 45,50 **** --- 46,52 ---- TypeInstallOp (String, "put", Put, 3, 0, 0, 0, String, Integer, Integer); TypeInstallOp (String, "getinterval", GetInterval, 3, 1, 0, 0, String, Integer, Integer); TypeInstallOp (String, "putinterval", PutInterval, 3, 0, 0, 0, String, Integer, String); + TypeInstallOp (String, "noaccess", PNoAccess, 1, 1, 0, 0, String); /*jgm*/ TypeInstallOp (String, "executeonly", PExecOnly, 1, 1, 0, 0, String); TypeInstallOp (String, "readonly", PReadOnly, 1, 1, 0, 0, String); TypeInstallOp (String, "rcheck", PrCheck, 1, 1, 0, 0, String); *************** *** 530,535 **** --- 532,543 ---- VOID Push (OpStack, False); return TRUE; + } + + /* PNoAccess by jgm */ + static int PNoAccess (item) Object item; + { + return Push (OpStack, NoAccess (item)); } static int PExecOnly (item) Object item; diff -cr orig/source/viewer.c ./source/viewer.c *** orig/source/viewer.c Sun Jan 3 14:21:58 1988 --- ./source/viewer.c Thu Dec 10 23:12:55 1987 *************** *** 310,318 **** return res; } ! PanicIf (flag, s) int flag; char *s; { - if (flag) fprintf (stderr, "Viewer panic: %s\n", s), exit (1); } --- 310,318 ---- return res; } ! /* Removed conditional & changed PanicIf to Panic --jgm */ ! Panic (s) char *s; { fprintf (stderr, "Viewer panic: %s\n", s), exit (1); } *** /dev/null Mon Jul 25 01:14:13 1988 --- postscript/demos/buildcachefont.ps Thu Jul 28 12:25:02 1988 *************** *** 0 **** --- 1,19 ----- + %! + %% Build the font cache + %% By John G. Myers + + % fontname pointsize cachefont -- + /cachefont { + exch findfont exch scalefont setfont + 5 5 moveto + ( !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ) show + ([\\]^_`abcdefghijklmnopqrstuvwxyz{|}~) show + (\251\252\256\257\261\267\272\320) show + savecurrentfont + erasepage + } def + + [ /Times-Roman /Helvetica /Times-Bold /Times-Italic /Helvetica-Oblique ] + { dup 10 cachefont dup 12 cachefont 14 cachefont } + forall + Make sure you have already applied either 'ps.diff.v1' or my original posting to comp.sources.bugs. To apply this, you need the 'patch' program which is available from the comp.sources.unix archives. Change directories to the top-level postscript directory (the one with the file "MANIFEST" in it) and apply this patch with the command: patch -p0 getenv if it does not. + Version 2: + + Bugs fixed: + + Fixed operators kshow, translate, scale, rotate, reversepath + + Casted NULL to appropriate type when it was passed as a parameter. + + Removed unused variables. + + Enhancements made: + + Each driver must now define the character pointer "DriverType". The + value of this variable is placed in the string produced by the + "version" operator. + + Added operators letter, note, and legal. John G. Myers jm36@andrew.cmu.edu diff -cr ./doc/hard-interface /cmu/math/jm36/src/ps/doc/hard-interface *** ./doc/hard-interface Fri Apr 1 22:41:07 1988 --- /cmu/math/jm36/src/ps/doc/hard-interface Mon Mar 28 20:25:28 1988 *************** *** 15,20 **** --- 15,29 ---- * may be expected to be NULL. */ + /* Begin jgm */ + /* + * DriverType contains a pointer to a string naming the device that this + * is a driver for. The given string will show up in the "version" + * operator. + */ + char *DriverType = ""; + /* End jgm */ + /************************* CREATION OF WINDOWS AND BITMAPS *******************/ struct hardware *InitHardware () {} diff -cr ./doc/hard-interface.c /cmu/math/jm36/src/ps/doc/hard-interface.c *** ./doc/hard-interface.c Fri Apr 1 22:42:05 1988 --- /cmu/math/jm36/src/ps/doc/hard-interface.c Mon Mar 28 20:24:19 1988 *************** *** 17,22 **** --- 17,31 ---- * of access that PostScript is interested in. Any Hardware parameter may be expected to be NULL. */ + /* Begin jgm */ + /* + * DriverType contains a pointer to a string naming the device that this + * is a driver for. The given string will show up in the "version" + * operator. + */ + char *DriverType = ""; + /* End jgm */ + /*********************************** CREATION OF WINDOWS AND BITMAPS *******************/ struct hardware *InitHardware () {} diff -cr ./postscript/psrc /cmu/math/jm36/src/ps/postscript/psrc *** ./postscript/psrc Fri Apr 1 22:48:12 1988 --- /cmu/math/jm36/src/ps/postscript/psrc Wed Mar 23 23:05:53 1988 *************** *** 125,130 **** --- 141,148 ---- } def /kshow { + exch % jgm + showdict begin /p exch def dup length 0 ne { dup 0 get /last exch def *************** *** 132,137 **** --- 150,156 ---- dup length 1 sub 1 exch getinterval { last exch dup /last exch def /p load exec + ( ) dup 0 last put show % jgm } forall } if end *************** *** 467,472 **** --- 493,526 ---- [ 0 f f 0 0 0] w h [] framedevice end } def + + % Begin additions --jgm + + /letter { + 5 dict begin + /m [1.13889 0 0 -1.13889 0 0] def + /f m 0 get def + /h 11 72 mul f mul cvi def + /w 8.5 72 mul f mul 8 div cvi def + m 5 h put + m w h [] framedevice + end + } def + + /note { letter } def + + /legal { + 5 dict begin + /m [1.13889 0 0 -1.13889 0 0] def + /f m 0 get def + /h 14 72 mul f mul cvi def + /w 8.5 72 mul f mul 8 div cvi def + m 5 h put + m w h [] framedevice + end + } def + + % End additions --jgm /ascii-set ( !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~) def diff -cr ./source/X.c /cmu/math/jm36/src/ps/source/X.c *** ./source/X.c Fri Apr 1 22:44:35 1988 --- /cmu/math/jm36/src/ps/source/X.c Fri Mar 11 23:39:36 1988 *************** *** 17,22 **** --- 17,24 ---- #define TRANSFER_SIZE 256 #define XMAX 65535 + char *DriverType = "X10"; /* jgm */ + static int transfer [TRANSFER_SIZE + 1]; static unsigned char reverse [0x100]; diff -cr ./source/array.c /cmu/math/jm36/src/ps/source/array.c *** ./source/array.c Fri Apr 1 22:48:17 1988 --- /cmu/math/jm36/src/ps/source/array.c Sun Mar 6 17:16:25 1988 *************** *** 85,94 **** --- 85,96 ---- return res; } + #ifdef notdef /* jgm */ static Object *Body (item) Object item; { return item.u.Array; } + #endif /* jgm */ #define Body(a) ((a).u.Array) diff -cr ./source/config.c /cmu/math/jm36/src/ps/source/config.c *** ./source/config.c Fri Apr 1 22:48:20 1988 --- /cmu/math/jm36/src/ps/source/config.c Sat Mar 12 00:08:51 1988 *************** *** 20,30 **** Type Real, Name, Operator, String, Poly, Float, FontID; extern Object Absent, Nil, SysDict; ! char default_library[] = "/usr/ral/lib/postscript"; Init () { Nil = MakeObject ((Type) 0); Null = Nil.type = MakeType (SizeNull); EmptyDict (Null); /* needed because of this recursion */ --- 20,33 ---- Type Real, Name, Operator, String, Poly, Float, FontID; extern Object Absent, Nil, SysDict; + extern char *DriverType; ! char default_library[] = "/usr/ral/lib/postscript"; Init () { + char versionbuf[1024]; /* --jgm */ + Nil = MakeObject ((Type) 0); Null = Nil.type = MakeType (SizeNull); EmptyDict (Null); /* needed because of this recursion */ *************** *** 87,91 **** Install ("polytype", DictFrom (Poly)); Install ("fonttype", DictFrom (FontID)); ! Install ("version", StringFrom ("Version 1.4 with mods by jgm")); /* jgm */ } --- 90,98 ---- Install ("polytype", DictFrom (Poly)); Install ("fonttype", DictFrom (FontID)); ! /* Begin jgm */ ! strcpy(versionbuf, DriverType); ! strcat(versionbuf, " version 1.4 with jgm mods v2"); ! Install ("version", StringFrom (versionbuf)); ! /* End jgm */ } diff -cr ./source/device.c /cmu/math/jm36/src/ps/source/device.c *** ./source/device.c Fri Apr 1 22:41:29 1988 --- /cmu/math/jm36/src/ps/source/device.c Sun Mar 6 17:29:48 1988 *************** *** 200,206 **** UnlinkDevice (d); } else ! */BitBlt (NULL, res->dev, NewDevicePoint (0, 0), NewDevicePoint (0, 0), ex, ROP_FALSE); return res; } --- 200,206 ---- UnlinkDevice (d); } else ! */BitBlt ((struct hardware *)NULL, res->dev, NewDevicePoint (0, 0), NewDevicePoint (0, 0), ex, ROP_FALSE); /* cast NULL --jgm */ return res; } diff -cr ./source/file.c /cmu/math/jm36/src/ps/source/file.c *** ./source/file.c Fri Apr 1 22:45:31 1988 --- /cmu/math/jm36/src/ps/source/file.c Sun Mar 6 17:16:15 1988 *************** *** 168,184 **** --- 168,188 ---- #define Getc(a) getc(a) + #ifdef notdef /* jgm */ static int Getchar () { return Getc (stdin); } + #endif /* jgm */ #define Getchar getchar + #ifdef notdef /* jgm */ static int Status (file) Object file; { return Body (file)->available; } + #endif /* jgm */ #define Status(f) (Body(f)->available) *************** *** 306,312 **** Cbreak (FALSE); } ! static cbreak = FALSE, echoing = TRUE; /*ARGSUSED*/ Cbreak (cond) int cond; --- 310,316 ---- Cbreak (FALSE); } ! static /* cbreak = FALSE, (removed --jgm) */ echoing = TRUE; /*ARGSUSED*/ Cbreak (cond) int cond; diff -cr ./source/fill.c /cmu/math/jm36/src/ps/source/fill.c *** ./source/fill.c Fri Apr 1 22:44:44 1988 --- /cmu/math/jm36/src/ps/source/fill.c Sun Mar 6 17:46:45 1988 *************** *** 149,155 **** UnlinkDevice (gstate->clipdevice); gstate->clipdevice = NULL; ! SetClipHardware (gstate->device->dev, NULL); return TRUE; } --- 149,155 ---- UnlinkDevice (gstate->clipdevice); gstate->clipdevice = NULL; ! SetClipHardware (gstate->device->dev, (struct hardware *)NULL); /* cast NULL --jgm */ return TRUE; } *************** *** 226,232 **** static int FillIt (path_a, rule_a, path_b, rule_b, emitfn) Path path_a, path_b; int (*rule_a)(), (*rule_b)(); void (*emitfn)(); { ! Path new; static int edgecmp (); static void Trapezoids (), BuildEdgeList (); --- 226,232 ---- static int FillIt (path_a, rule_a, path_b, rule_b, emitfn) Path path_a, path_b; int (*rule_a)(), (*rule_b)(); void (*emitfn)(); { ! /* Path new; (unused --jgm) */ static int edgecmp (); static void Trapezoids (), BuildEdgeList (); *************** *** 288,298 **** { struct edge *up_edge; int i, count_a = 0, count_b = 0; ! static void RemoveEdges (); for (i = 0; i < ninteresting; i++) { ! static void Emit (); int d_a = 0, d_b = 0; if (interesting[i]->clip) --- 288,298 ---- { struct edge *up_edge; int i, count_a = 0, count_b = 0; ! /* static void RemoveEdges (); (unused --jgm) */ for (i = 0; i < ninteresting; i++) { ! /* static void Emit (); (unused --jgm) */ int d_a = 0, d_b = 0; if (interesting[i]->clip) diff -cr ./source/font.c /cmu/math/jm36/src/ps/source/font.c *** ./source/font.c Fri Apr 1 22:45:11 1988 --- /cmu/math/jm36/src/ps/source/font.c Sun Mar 6 17:11:46 1988 *************** *** 535,541 **** for (;;) { int code = *++s; ! HardPoint offset, cp; offset = Adjust (DExtToInt (last_width), code); loc.hx += offset.hx; --- 535,541 ---- for (;;) { int code = *++s; ! HardPoint offset/* , cp (unused --jgm) */; offset = Adjust (DExtToInt (last_width), code); loc.hx += offset.hx; diff -cr ./source/gsave.c /cmu/math/jm36/src/ps/source/gsave.c *** ./source/gsave.c Fri Apr 1 22:39:48 1988 --- /cmu/math/jm36/src/ps/source/gsave.c Sun Mar 6 17:34:40 1988 *************** *** 75,81 **** SetScreen (gstate->screen.frequency, gstate->screen.rotation, gstate->screen.thresh); if (tflag) SetTransfer (gstate->transfer.tran); ! SetClipHardware (gstate->device->dev, (gstate->clipdevice ? gstate->clipdevice->dev : NULL)); } return TRUE; --- 75,81 ---- SetScreen (gstate->screen.frequency, gstate->screen.rotation, gstate->screen.thresh); if (tflag) SetTransfer (gstate->transfer.tran); ! SetClipHardware (gstate->device->dev, (gstate->clipdevice ? gstate->clipdevice->dev : (struct hardware *)NULL)); /* Cast NULL --jgm */ } return TRUE; diff -cr ./source/image.c /cmu/math/jm36/src/ps/source/image.c *** ./source/image.c Fri Apr 1 22:48:26 1988 --- /cmu/math/jm36/src/ps/source/image.c Sun Mar 6 17:34:36 1988 *************** *** 250,256 **** FillMask (mask, i, dep); BitBlt (from, mask, NewDevicePoint (0, 0), NewDevicePoint (0, 0), HardwareExtent (from), ROP_NXOR); ! BitBlt (NULL, temp, NewDevicePoint (0, 0), NewDevicePoint (0, 0), HardwareExtent (temp), ROP_TRUE); for (j = 0; j < dep; j++) BitBlt (mask, temp, NewDevicePoint (j, 0), NewDevicePoint (0, 0), HardwareExtent (mask), ROP_AND); for (j = 0; j < w; j++) --- 250,256 ---- FillMask (mask, i, dep); BitBlt (from, mask, NewDevicePoint (0, 0), NewDevicePoint (0, 0), HardwareExtent (from), ROP_NXOR); ! BitBlt ((struct hardware *)NULL, temp, NewDevicePoint (0, 0), NewDevicePoint (0, 0), HardwareExtent (temp), ROP_TRUE); /* cast NULL --jgm */ for (j = 0; j < dep; j++) BitBlt (mask, temp, NewDevicePoint (j, 0), NewDevicePoint (0, 0), HardwareExtent (mask), ROP_AND); for (j = 0; j < w; j++) diff -cr ./source/matrix.c /cmu/math/jm36/src/ps/source/matrix.c *** ./source/matrix.c Fri Apr 1 22:43:11 1988 --- /cmu/math/jm36/src/ps/source/matrix.c Wed Mar 23 22:40:28 1988 *************** *** 126,131 **** --- 126,132 ---- static int PTranslate () { Object tx, ty, mat; + Matrix m; float x, y; if (!OpCheck (2, 1)) *************** *** 136,141 **** --- 137,144 ---- return Push (OpStack, mat), Error (PInvAccess); else if (lengthArray (mat) != 6) return Push (OpStack, mat), Error (PRangeCheck); + else if (!ExtractMatrix (&m, mat)) /* --jgm */ + return Push (OpStack, mat), Error (PTypeCheck); /* --jgm */ else { ty = Pop (OpStack); *************** *** 153,159 **** else return Push (OpStack, tx), Push (OpStack, ty), Push (OpStack, mat), Error (PTypeCheck); ! VOID AssignMatrix (mat, NewMatrix (1.0, 0.0, 0.0, 1.0, x, y)); return Push (OpStack, mat); } --- 156,164 ---- else return Push (OpStack, tx), Push (OpStack, ty), Push (OpStack, mat), Error (PTypeCheck); ! /* VOID AssignMatrix (mat, NewMatrix (1.0, 0.0, 0.0, 1.0, x, y)); WRONG --jgm */ ! VOID AssignMatrix (mat, Translate(m, x, y)); /* --jgm */ ! return Push (OpStack, mat); } *************** *** 178,184 **** static int PScale () { Object tx, ty, mat; ! float x, y; if (!OpCheck (2, 1)) return FALSE; --- 183,190 ---- static int PScale () { Object tx, ty, mat; ! Matrix m; /* --jgm */ ! float x, y; if (!OpCheck (2, 1)) return FALSE; *************** *** 188,193 **** --- 194,201 ---- return Push (OpStack, mat), Error (PInvAccess); else if (lengthArray (mat) != 6) return Push (OpStack, mat), Error (PRangeCheck); + else if (!ExtractMatrix (&m, mat)) /* --jgm */ + return Push (OpStack, mat), Error (PTypeCheck); /* --jgm */ else { ty = Pop (OpStack); *************** *** 205,211 **** else return Push (OpStack, tx), Push (OpStack, ty), Push (OpStack, mat), Error (PTypeCheck); ! VOID AssignMatrix (mat, NewMatrix (x, 0.0, 0.0, y, 0.0, 0.0)); return Push (OpStack, mat); } --- 213,220 ---- else return Push (OpStack, tx), Push (OpStack, ty), Push (OpStack, mat), Error (PTypeCheck); ! /* VOID AssignMatrix (mat, NewMatrix (x, 0.0, 0.0, y, 0.0, 0.0)); WRONG --jgm */ ! VOID AssignMatrix (mat, Scale(m, x, y)); /* --jgm */ return Push (OpStack, mat); } *************** *** 249,256 **** a = BodyReal (ang); else return Push (OpStack, ang), Push (OpStack, mat), Error (PTypeCheck); ! ! VOID AssignMatrix (mat, NewMatrix (cos(a), sin(a), -sin(a), -cos(a), 0.0, 0.0)); return Push (OpStack, mat); } --- 258,265 ---- a = BodyReal (ang); else return Push (OpStack, ang), Push (OpStack, mat), Error (PTypeCheck); ! a = Rad(a); /* jgm */ ! VOID AssignMatrix (mat, NewMatrix (cos(a), sin(a), -sin(a), cos(a), 0.0, 0.0)); /* last "-cos" changed to "cos" --jgm */ return Push (OpStack, mat); } diff -cr ./source/name.c /cmu/math/jm36/src/ps/source/name.c *** ./source/name.c Fri Apr 1 22:39:54 1988 --- /cmu/math/jm36/src/ps/source/name.c Sun Mar 6 17:16:20 1988 *************** *** 107,113 **** static int HashName (s, length) unsigned char *s; int length; { ! int i, res = 0; while (length--) res += *s++; --- 107,113 ---- static int HashName (s, length) unsigned char *s; int length; { ! int /* i, (unused --jgm) */ res = 0; while (length--) res += *s++; diff -cr ./source/operator.c /cmu/math/jm36/src/ps/source/operator.c *** ./source/operator.c Fri Apr 1 22:41:54 1988 --- /cmu/math/jm36/src/ps/source/operator.c Sun Mar 6 17:16:23 1988 *************** *** 69,75 **** { Object res; struct op_struct *op; ! int i; res = Cvx (MakeObject (Operator)); res.u.Operator = op = (struct op_struct *) Malloc (sizeof (struct op_struct)); --- 69,75 ---- { Object res; struct op_struct *op; ! /* int i; (unused --jgm) */ res = Cvx (MakeObject (Operator)); res.u.Operator = op = (struct op_struct *) Malloc (sizeof (struct op_struct)); *************** *** 130,139 **** --- 130,141 ---- TypeInstall (type, name, res); } + #ifdef notdef /* jgm */ static struct op_struct *Body (item) Object item; { return item.u.Operator; } + #endif /* jgm */ #define Body(op) ((op).u.Operator) diff -cr ./source/path.c /cmu/math/jm36/src/ps/source/path.c *** ./source/path.c Fri Apr 1 22:43:14 1988 --- /cmu/math/jm36/src/ps/source/path.c Sat Mar 19 17:00:52 1988 *************** *** 194,200 **** if ((res = ReversePath (gstate->path)) == NULL) return Error (PLimitCheck); ! SetPath (&gstate->path, res); return TRUE; } --- 194,201 ---- if ((res = ReversePath (gstate->path)) == NULL) return Error (PLimitCheck); ! /* SetPath (&gstate->path, res); --jgm */ ! gstate->path = res; /* Don't free gstate->path twice. --jgm */ return TRUE; } diff -cr ./source/pixrect.c /cmu/math/jm36/src/ps/source/pixrect.c *** ./source/pixrect.c Fri Apr 1 22:40:34 1988 --- /cmu/math/jm36/src/ps/source/pixrect.c Fri Mar 11 23:35:16 1988 *************** *** 15,20 **** --- 15,22 ---- #include "canon.h" #include + char *DriverType = "Sun pixrect"; /* jgm */ + int rop_map [] = { PIX_SRC & PIX_NOT (PIX_SRC), diff -cr ./source/state.c /cmu/math/jm36/src/ps/source/state.c *** ./source/state.c Fri Apr 1 22:43:34 1988 --- /cmu/math/jm36/src/ps/source/state.c Sun Mar 6 17:33:19 1988 *************** *** 114,120 **** int ErasePage () { ! Paint (NULL, gstate->device->dev, NewDevicePoint (0, 0), NewDevicePoint (0, 0), HardwareExtent (gstate->device->dev), White); --- 114,120 ---- int ErasePage () { ! Paint ((struct hardware *)NULL, gstate->device->dev, /* cast NULL --jgm */ NewDevicePoint (0, 0), NewDevicePoint (0, 0), HardwareExtent (gstate->device->dev), White); diff -cr ./source/ww.c /cmu/math/jm36/src/ps/source/ww.c *** ./source/ww.c Fri Apr 1 22:41:00 1988 --- /cmu/math/jm36/src/ps/source/ww.c Fri Mar 11 23:39:23 1988 *************** *** 14,19 **** --- 14,21 ---- #include "canon.h" #include "wwinfo.h" + char *DriverType = "ww"; /* jgm */ + static void xxrasterop (); static struct hardware *NewHardware (); Make sure you have already applied patch 'ps.diff.v2'. If you already have the file "source/X11.c", move it to a safe place before applying this patch. To apply this, you need the 'patch' program which is available from the comp.sources.unix archives. Change directories to the top-level postscript directory (the one with the file "MANIFEST" in it) and apply this patch with the command: patch -p0 ) print } def --- 69,87 ---- %/tty (|cat -u ) print } def *************** *** 423,429 **** /h 11 72 mul f mul cvi def /w 8.25 72 mul f mul 8 div cvi def m 5 h put ! m w h [] framedevice end } def --- 426,432 ---- /h 11 72 mul f mul cvi def /w 8.25 72 mul f mul 8 div cvi def m 5 h put ! m w h /outputpage load framedevice % jgm end } def *************** *** 435,441 **** /h 11 72 mul f mul cvi def /w 8.25 72 mul f mul 8 div cvi def m 5 h put ! m w h [] framedevice end } def --- 438,444 ---- /h 11 72 mul f mul cvi def /w 8.25 72 mul f mul 8 div cvi def m 5 h put ! m w h /outputpage load framedevice % jgm end } def *************** *** 446,452 **** /h 11 72 mul f mul cvi def /w 8.25 72 mul f mul 8 div cvi def m 5 h put ! m w h [] framedevice end } def --- 449,455 ---- /h 11 72 mul f mul cvi def /w 8.25 72 mul f mul 8 div cvi def m 5 h put ! m w h /outputpage load framedevice % jgm end } def *************** *** 457,463 **** /h 8.25 72 mul f mul cvi def /w 11.75 2 div 72 mul f mul 8 div cvi def m 5 h put ! m w h [] framedevice end } def --- 460,466 ---- /h 8.25 72 mul f mul cvi def /w 11.75 2 div 72 mul f mul 8 div cvi def m 5 h put ! m w h /outputpage load framedevice % jgm end } def *************** *** 467,473 **** /f m 0 get def /h 8.25 72 mul f mul cvi def /w 11.75 72 mul f mul 8 div cvi def ! [ 0 f f 0 0 0] w h [] framedevice end } def --- 470,476 ---- /f m 0 get def /h 8.25 72 mul f mul cvi def /w 11.75 72 mul f mul 8 div cvi def ! [ 0 f f 0 0 0] w h /outputpage load framedevice % jgm end } def *************** *** 480,486 **** /h 11 72 mul f mul cvi def /w 8.5 72 mul f mul 8 div cvi def m 5 h put ! m w h [] framedevice end } def --- 483,489 ---- /h 11 72 mul f mul cvi def /w 8.5 72 mul f mul 8 div cvi def m 5 h put ! m w h /outputpage load framedevice end } def *************** *** 493,499 **** /h 14 72 mul f mul cvi def /w 8.5 72 mul f mul 8 div cvi def m 5 h put ! m w h [] framedevice end } def --- 496,502 ---- /h 14 72 mul f mul cvi def /w 8.5 72 mul f mul 8 div cvi def m 5 h put ! m w h /outputpage load framedevice end } def *** /usr/tmp/ps/source/makefile Thu Jul 28 13:53:39 1988 --- ./source/makefile Thu Jul 28 15:36:09 1988 *************** *** 2,10 **** --- 2,20 ---- integer.o main.o math.o misc.o name.o operator.o\ poly.o property.o real.o save.o stack.o string.o unix.o LIBS=libww.a -lsuntool -lsunwindow -lpixrect -g + XLIB=/usr/lib/libX11.a GRAPHICS=cache.o colour.o device.o fill.o font.o gsave.o image.o mat.o matrix.o\ pat.o path.o state.o stroke.o + SOURCES=array.c boolean.c config.c control.c dictionary.c file.c\ + integer.c main.c math.c misc.c name.c operator.c\ + poly.c property.c real.c save.c stack.c string.c unix.c\ + cache.c colour.c device.c fill.c font.c gsave.c image.c mat.c matrix.c\ + pat.c path.c state.c stroke.c + LINT=lint + LFLAGS= -lm + + # For SUN with 68881 #CFLAGS=-O -f68881 *************** *** 11,39 **** # For others CFLAGS=-O ! #default: sunPS PS: $(OBJECTS) $(GRAPHICS) hard.o canon.a ! cc $(CFLAGS) $(OBJECTS) $(GRAPHICS) hard.o canon.a -lm `libs` -o PS sunPS: $(OBJECTS) $(GRAPHICS) pixrect.o canon.a ! cc $(CFLAGS) $(OBJECTS) $(GRAPHICS) pixrect.o canon.a -lm -lpixrect -o sunPS CPS: $(OBJECTS) $(GRAPHICS) colour-ww.o trapezoid.o canon.o ! cc $(CFLAGS) $(OBJECTS) $(GRAPHICS) colour-ww.o canon.o trapezoid.o -lm `libs` -o CPS postscript: $(OBJECTS) $(GRAPHICS) adapter.o protocol.o ! cc $(CFLAGS) $(OBJECTS) $(GRAPHICS) adapter.o protocol.o -lm -o postscript XPS: $(OBJECTS) $(GRAPHICS) X.o ! cc $(CFLAGS) $(OBJECTS) $(GRAPHICS) X.o -lm -lX -o XPS canon.a: canon.o screen.o trapezoid.o paint.o ar ruv canon.a canon.o screen.o trapezoid.o paint.o ranlib canon.a viewer: protocol.o viewer.o hard.o canon.a ! cc protocol.o viewer.o hard.o canon.a `libs` -o viewer all: PS postscript viewer --- 21,56 ---- # For others CFLAGS=-O ! default: sunPS + xps: $(OBJECTS) $(GRAPHICS) X11.o canon.a $(XLIB) + rm -f xps + $(CC) -o xps $(CFLAGS) $(OBJECTS) $(GRAPHICS) X11.o canon.a -lm $(XLIB) + PS: $(OBJECTS) $(GRAPHICS) hard.o canon.a ! $(CC) $(CFLAGS) $(OBJECTS) $(GRAPHICS) hard.o canon.a -lm `libs` -o PS sunPS: $(OBJECTS) $(GRAPHICS) pixrect.o canon.a ! $(CC) $(CFLAGS) $(OBJECTS) $(GRAPHICS) pixrect.o canon.a -lm -lpixrect -o sunPS CPS: $(OBJECTS) $(GRAPHICS) colour-ww.o trapezoid.o canon.o ! $(CC) $(CFLAGS) $(OBJECTS) $(GRAPHICS) colour-ww.o canon.o trapezoid.o -lm `libs` -o CPS postscript: $(OBJECTS) $(GRAPHICS) adapter.o protocol.o ! $(CC) $(CFLAGS) $(OBJECTS) $(GRAPHICS) adapter.o protocol.o -lm -o postscript XPS: $(OBJECTS) $(GRAPHICS) X.o ! $(CC) $(CFLAGS) $(OBJECTS) $(GRAPHICS) X.o -lm -lX -o XPS + lint: + $(LINT) $(LFLAGS) $(SOURCES) $(LINTFILTER) + canon.a: canon.o screen.o trapezoid.o paint.o ar ruv canon.a canon.o screen.o trapezoid.o paint.o ranlib canon.a viewer: protocol.o viewer.o hard.o canon.a ! $(CC) protocol.o viewer.o hard.o canon.a `libs` -o viewer all: PS postscript viewer *************** *** 44,50 **** orion: orion.o installorion orionlib X.o: ! cc -c X.c wwlib: if [ -f libww.a ]; \ --- 61,67 ---- orion: orion.o installorion orionlib X.o: ! $(CC) -c X.c wwlib: if [ -f libww.a ]; \ *** /dev/null Thu Jul 28 10:26:48 1988 --- ./source/X11.c Wed Jul 27 18:15:31 1988 *************** *** 0 **** --- 1,667 ---- + /* + * Copyright (C) Rutherford Appleton Laboratory 1987 + * + * This source may be copied, distributed, altered or used, but not sold for profit + * or incorporated into a product except under licence from the author. + * It is not in the public domain. + * This notice should remain in the source unaltered, and any changes to the source + * made by persons other than the author should be marked as such. + * + * Crispin Goswell @ Rutherford Appleton Laboratory caag@uk.ac.rl.vd + */ + #include "main.h" + #include "graphics.h" + #include + #include + #include + #include + #include "canon.h" + + char *DriverType = "X11"; /* jgm */ + + static void Punt(str) + char *str; + { + fprintf(stderr, "%s\n", str); + exit(1); + } + + + + static Display *dpy; + + typedef struct _HardwareRec { + Drawable w; + } HardwareRec, *Hardware; + + #ifdef CANON + struct hardware + { + /* + * Each driver is expected to provide its own definition of this + * structure. It is only ever used as a pointer and is never dereferenced + * outside the driver. + */ + int pad; + }; + #endif CANON + + /* + * This file describes the interface that PostScript requires to the graphics + * system at Version 1.4. + * + * ''Hardware'' in this context refers to a pointer to windows and/or bitmaps + * and is the lowest level of access that PostScript is interested in. Any + * Hardware parameter may be expected to be NULL. + */ + + /********************* CREATION OF WINDOWS AND BITMAPS *******************/ + + #define SCREEN 0 /* What to use as our screen number. */ + #define MIN(x, y) (((x) < (y)) ? (x) : (y)) + + static GC fillgc[16]; + + struct hardware *InitHardware () + { + XGCValues values; + int i; + if ((dpy = XOpenDisplay(dpy)) == NULL) + Punt("Could not open display"); + InitTransfer(DisplayHeight(dpy, SCREEN) / 11); + /* This defines our screen as being 11 inches high, no matter what its */ + /* real size. What a hack. */ + values.foreground = AllPlanes; + for (i=0 ; i<16 ; i++) { + values.function = i; + fillgc[i] = XCreateGC(dpy, RootWindow(dpy, SCREEN), + GCFunction | GCForeground, &values); + } + } + /* + * InitHardware () returns a default device which PostScript may use + * immediately (or NULL if not appropriate). Its size and shape are not + * defined. Most typically the user will want to start up another device + * before it is used anyway. No attempt will be made by PostScript to Destroy + * the resulting device. + */ + + static struct hardware *NewHardware(width, height) + int width, height; + { + struct hardware *to; + Hardware hard; + to = (struct hardware *) malloc(sizeof(struct hardware)); + hard = (Hardware) malloc(sizeof(HardwareRec)); + to->hard.addr = (char *) hard; + to->flags = 0; + to->aux = to->clip = NULL; + to->extent = NewDevicePoint(width, height); + hard->w = NULL; + return to; + } + + + struct hardware *NewBitmapHardware (width, height) + int width, height; + { + struct hardware *to = NewHardware(width, height); + Hardware hard = (Hardware) to->hard.addr; + to->flags = NULL; + hard->w = XCreatePixmap(dpy, RootWindow(dpy, SCREEN), width, height, + DefaultDepth(dpy, SCREEN)); + XFillRectangle(dpy, hard->w, fillgc[GXclear], 0, 0, width, height); + + /* { + static int y = 0; + XSetWindowAttributes attributes; + hard->w = XCreateSimpleWindow(dpy, RootWindow(dpy, SCREEN), 700, y, + width, height, 1, BlackPixel(dpy, SCREEN), + WhitePixel(dpy, SCREEN)); + attributes.override_redirect = TRUE; + XChangeWindowAttributes(dpy, hard->w, CWOverrideRedirect, &attributes); + XMapWindow(dpy, hard->w); + y+=30; + }*/ + return to; + } + + struct hardware *NewWindowHardware (width, height) + int width, height; + { + struct hardware *to = NewHardware(width, height); + Hardware hard = (Hardware) to->hard.addr; + XEvent event; + unsigned long vmask; + XSetWindowAttributes xswa; + + to->flags = ISWIN; + /* + hard->w = XCreateSimpleWindow(dpy, RootWindow(dpy, SCREEN), 0, 0, + width, height, 1, BlackPixel(dpy, SCREEN), + 0); + */ + vmask = CWBackPixel|CWBorderPixel|CWBackingStore| + CWBackingPlanes|CWSaveUnder; + xswa.background_pixel = WhitePixel(dpy,SCREEN); + xswa.border_pixel = BlackPixel(dpy,SCREEN); + xswa.backing_store = Always; + xswa.backing_planes = AllPlanes; + xswa.save_under = True; + + hard->w = XCreateWindow(dpy,RootWindow(dpy,SCREEN), + 0,0, + width,height, + 1,DefaultDepth(dpy,SCREEN), + InputOutput,DefaultVisual(dpy,SCREEN), + vmask,&xswa); + + XChangeProperty(dpy,hard->w,XA_WM_NAME,XA_STRING,8, + PropModeReplace,"POSTSCRIPT",10); + + XSelectInput(dpy, hard->w, ExposureMask); + XMapWindow(dpy, hard->w); + XNextEvent(dpy, &event); + XSelectInput(dpy, hard->w, 0); + return to; + } + /* + * NewBitmapHardware () is expected to create a new bitmap. Only one plane + * will be needed. + * + * NewWindowHardware () is expected to create a window on the screen. On a + * colour system this will be expected to support full colour. + */ + + #ifdef CANON + int IsWindowHardware (h) + struct hardware *h; + {} + #endif CANON + /* + * IsWindowHardware () should return TRUE if the hardware is a window, FALSE + * otherwise. NULL is a window. + */ + + void DestroyHardware (h) + struct hardware *h; + { + if (h) { + Hardware hard = (Hardware) h->hard.addr; + if (IsWindowHardware(h)) + XDestroyWindow(dpy, hard->w); + else + XFreePixmap(dpy, hard->w); + } + } + /* + * + * DestroyHardware () should release the resources required by the hardware, + * bitmap or window. This should cause a window device to vanish. NULL is not + * an error (does nothing). + */ + + + #ifdef CANON + Matrix DeviceMatrix (width, height) + int width, height; + {} + #endif CANON + + /* + * + * DeviceMatrix () should return a matrix appropriate to a device of the given + * height and width. For a typical display with a graphics origin at the top + * left of a window, an appropriate definition would be: + * + * Matrix DeviceMatrix (width, height) + * int width, height; + * { + * return NewMatrix (PIXELS_PER_INCH / 72.0, 0.0, 0.0, + * -PIXELS_PER_INCH / 72.0, 0.0, (float) height); + * } + */ + + #ifdef CANON + DevicePoint HardwareExtent (h) + struct hardware *h; + {} + #endif + /* + * HardwareExtent () returns a DevicePoint describing the width and height of + * the argument. NULL has extent NewDevicePoint (0, 0). + */ + + /*************************** OUTPUT PRIMITIVES ******************************/ + + void BitBlt (from, to, fromPoint, toPoint, extent, rop) + struct hardware *from, *to; + DevicePoint toPoint, fromPoint, extent; + int rop; + { + Hardware fromhard, tohard; + static int count = 0; + if (to == NULL) return; + tohard = (Hardware) to->hard.addr; + if (from == NULL) { + XFillRectangle(dpy, tohard->w, fillgc[rop], toPoint.dx, toPoint.dy, + extent.dx, extent.dy); + } else { + fromhard = (Hardware) from->hard.addr; + XCopyArea(dpy, fromhard->w, tohard->w, fillgc[rop], fromPoint.dx, + fromPoint.dy, extent.dx, extent.dy, toPoint.dx, toPoint.dy); + } + if (count++ % 50 == 0) XSync(dpy, 0); + } + + #ifdef CANON + void Paint (from, to, fromPoint, toPoint, extent, colour) + struct hardware *from, *to; + DevicePoint toPoint, fromPoint, extent; + Colour colour; + {} + #endif + + /* + * + * BitBlt () is a full function RasterOp. The 'rop' argument will have values + * as described in the header file hard.h. If the from argument is NULL it is + * taken to be a bitmap full of ones the shape of the fromPoint and extent. If + * the to argument is NULL, this is a no-op. + * + * Paint () is an addition to BitBlt. Bits that are set in the source are + * Painted into the destination in the given colour with a copying rasterop so + * that they replace pixels previously there. If the machine does not support + * colour windows, half-toning should be performed. Colour values have hue, + * saturation and brightness components. on a black and white or greyscale + * system the brightness value will be a FP value between 0.0 (black) and 1.1 + * (white), which can be used as a grey level. + * + * Paint is expected to mask with the clip mask. BitBlt is not, + */ + + #ifdef CANON + void BitBltTrapezoid(to, lefttop, leftbottom, righttop, rightbottom, + top, bottom, rop) + struct hardware *to; + DevicePoint lefttop, leftbottom, righttop, rightbottom; + int top, bottom, rop; + {} + #endif CANON + + #ifdef CANON + void PaintTrapezoid (to, lefttop, leftbottom, righttop, rightbottom, + top, bottom, colour) + struct hardware *to; + DevicePoint lefttop, leftbottom, righttop, rightbottom; + int top, bottom; + Colour colour; + {} + #endif CANON + + /* + * BitBltTrapezoid () and PaintTrapezoid () render a complete trapezoidal + * shape. The corners of the trapezoid may lie far outside the range of + * interesting scan-lines, but the slope of the line should be clipped by the + * top and bottom. The coordinates are half-open. + */ + + void BitBltLine (h, fromPoint, toPoint, rop) + struct hardware *h; + DevicePoint fromPoint, toPoint; + int rop; + { + if (h) { + Hardware hard = (Hardware) h->hard.addr; + XDrawLine(dpy, hard->w, fillgc[rop], fromPoint.dx, fromPoint.dy, + toPoint.dx, toPoint.dy); + } + } + + #ifdef CANON + void PaintLine (h, fromPoint, toPoint, colour) + struct hardware *h; + DevicePoint fromPoint, toPoint; + Colour colour; + {} + #endif CANON + + /* + * + * BitBltLine () is expected to draw a line between the given points + * with the given RasterOp and colour masking. + * The line should be one pixel wide and half-open. + * [Thicker lines are done with BitBlt.] + * + * PaintLine () is expected to Paint a line by analogy with Paint + * and BitBlt. + */ + + void BitBltBlob (to, top, height, left, right, rop) + struct hardware *to; + int top, height, *left, *right, rop; + { + int i; + DevicePoint p1, p2; + for (i=0 ; ihard.addr; + tohard = (Hardware) to->hard.addr; + p1.dx = p1.dy = 0; + for (x=toPoint.dx ; x < toPoint.dx + extent.dx ; x+=from->extent.dx) { + for (y=toPoint.dy ; y < toPoint.dy + extent.dy ; y+=from->extent.dy) { + p2.dx = x; + p2.dy = y; + p3.dx = MIN(toPoint.dx + extent.dx - x, from->extent.dx); + p3.dy = MIN(toPoint.dy + extent.dy - y, from->extent.dy); + BitBlt(from, to, p1, p2, p3, rop); + } + } + } + #endif SLOWANDWRONG + + + void RasterTile (from, to, toPoint, extent, rop) + struct hardware *from, *to; + DevicePoint toPoint, extent; + int rop; + { + Hardware fromhard, tohard; + static GC gc = NULL; + XGCValues values; + int valuemask; + if (to == NULL) return; + if (from == NULL || IsWindowHardware(from)) + Punt("Can only RasterTile from Bitmap."); + fromhard = (Hardware) from->hard.addr; + tohard = (Hardware) to->hard.addr; + values.tile = fromhard->w; + values.fill_style = FillTiled; + values.function = rop; + valuemask = GCFunction | GCTile | GCFillStyle; + if (gc == NULL) + gc = XCreateGC(dpy, RootWindow(dpy, SCREEN), valuemask, &values); + else + XChangeGC(dpy, gc, valuemask, &values); + XFillRectangle(dpy, tohard->w, gc, toPoint.dx, toPoint.dy, + extent.dx, extent.dy); + } + + /* + * RasterTile () replicates the whole of ``from'' over ``to'', but clipped by + * the rectangle bounded by ``toPoint'' and ``extent''. + */ + + /******************* BRIGHTNESS TRANSFER FUNCTION ************************/ + + #ifdef CANON + int TransferSize () + {} + #endif CANON + + #ifdef CANON + void SetTransfer (vec) + float *vec; + {} + #endif CANON + /* + * + * TransferSize () and SetTransfer () control the mapping function between + * user brightnesses and device brightnesses. The interface is expected to + * perform this mapping of brightnesses to a sufficient resolution. + * SetTransfer takes a table of floating point numbers between 0 and 1. User + * brightnesses are scaled to the size of this table and mapped through it. + * The argument table given to SetTransfer () will be deleted after use. + * TransferSize () simply enquires the required size of the table. + * + * It may be appropriate to half-tone on a grayscale or colour device to + * improve rendering if it is not too expensive. TransferSize () returns the + * size of the pattern table. + */ + + /********************** BITMAP CONVERSION ********************************/ + + char *StringFromHardware (h) + struct hardware *h; + { + XImage *image; + Hardware hard; + unsigned char *result, *ptr, c; + int x, y, i; + if (h == NULL) return NULL; + hard = (Hardware) h->hard.addr; + image = XGetImage(dpy, hard->w, 0, 0, h->extent.dx, h->extent.dy, + AllPlanes, ZPixmap); + result = (unsigned char *) malloc(((h->extent.dx + 7) / 8) * h->extent.dy); + ptr = result; + for (y=0 ; yextent.dy ; y++) { + for (x=0 ; xextent.dx ; x+=8) { + c = 0; + for (i=0 ; i<8 ; i++) { + c = c << 1; + if (x+i < h->extent.dx) + c |= XGetPixel(image, x+i, y); + } + } + *ptr++ = c; + } + free((char *) image); + return (char *) result; + } + + struct hardware *HardwareFromString (s, width, height) + char *s; + int width, height; + { + struct hardware *h = NewBitmapHardware(width, height); + Hardware hard = (Hardware) h->hard.addr; + XImage *image; + if (s == NULL) Punt("HardwareFromString called with NULL string!"); + image = XCreateImage(dpy, DefaultVisual(dpy, SCREEN), + DefaultDepth(dpy, SCREEN), ZPixmap, 0, s, + width, height, 8, 0); + image->bitmap_bit_order = MSBFirst; + XPutImage(dpy, hard->w, fillgc[GXcopy], image, 0, 0, 0, 0, width, height); + free((char *) image); + return h; + } + /* + * + * StringFromHardware () produces a string from its argument which describes + * the bitmap. The bitmap is returned in row-major order with the leftmost + * bit of each byte in the most significant position. Rows are padded to byte + * boundaries. Only single plane bitmaps are used. + * + * HardwareFromString () performs the inverse mapping, generating a bitmap + * from a set of bits, given a width and height. Only single plane bitmaps are + * used. + */ + + /************************* HALF-TONE SCREEN *******************************/ + + #ifdef CANON + int ScreenSize (freq, rotation) + float freq, rotation; + {} + #endif CANON + + #ifdef CANON + void BuildScreen (freq, rotation, x, y) + float freq, rotation, *x, *y; + {} + #endif CANON + + #ifdef CANON + void SetScreen (freq, rotation, thresh) + float freq, rotation, *thresh; + {} + #endif CANON + /* + * ScreenSize () allows PostScript to determine how large an array of sample + * points to expect. It should return the length of the side of the sample + * square. + * + * BuildScreen () returns a set of sampling coordinates to PostScript to hand + * to the users spot-function + * + * SetScreen () allows PostScript to set the thresholds for each sample point + * so that half-tone bitmaps can be made. + */ + + /************************* CLIPPING ******************************************/ + + #ifdef CANON + void SetClipHardware (h, clip) + struct hardware *h, *clip; + {} + #endif + /* + * + * SetClipHardware sets hardware which is a clip mask for BitBlt. This mask + * should be ANDed with any output operation. If clip is NULL, masking will + * not be needed. + */ + + /************************ UPDATE CONTROLS **********************************/ + + void HardUpdate () + { + XFlush(dpy, 0); + } + /* + * HardUpdate is a hook to allow devices which do output buffering to flush + * that buffering when appropriate. This allows an interactive user to see + * completed graphics between prompts (it is called as a side-effect of the + * PostScript flush operator). Typically is is a no-op. + */ + + void UpdateControl (h, on) + struct hardware *h; + int on; + {} + /* + * This call can be used to enable batching of output operations. + * UpdateControl (h, FALSE) means ``start of batching'' UpdateControl (h, + * TRUE) means ``end of batching''. It is used to improve performance on + * machines where screen updates have a high locking overhead. It may be a + * no-op. The operation should nest if batching is already in progress: FALSE + * increments a counter, TRUE decrements a counter. Display changes are + * allowed when the counter is non-zero. + */ + + /********************************** CANONICAL IMPLEMENTATION LIBRARY ******************************/ + + /* + * Some parts of the above interface can be supported by a canonical library. + * This library contains: + + SetClipHardware + HardUpdate + IsWindowHardware + HardwareExtent + + PaintTrapezoid + BitBltTrapezoid + + Paint + PaintLine + + DeviceMatrix + InitTransfer + TransferSize + SetTransfer + ScreenSize + BuildScreen + SetScreen + + * + * As the driver matures, the user may provide his own versions of the + * canonical routines. This leaves the following for implementation by + * the user. + * + + InitHardware + NewBitmapHardware + NewWindowHardware + DestroyHardware + HardwareFromString + StringFromHardware + UpdateControl + RasterTile + BitBlt + BitBltLine + BitBltBlob + + * There is a pedagogical implementation in null.c + * + * There are a number of interface issues concerning the canonical driver. + * Firstly, a canonical struct hardware is defined, which contains a union of + * a char * and an int handle. The remainder are expected to use this to store + * device specific information. + * + * InitTransfer() should be called during InitHardware with the number of + * pixels per inch on the display as an argument. + */ + + /* I tacked this lot on the end to avoid altering canon.c - CAAG */ + + int pixels_per_inch; + + int single_rop [] = + { + ROP_FALSE, ROP_DEST, ROP_NOTDEST, ROP_TRUE, + ROP_FALSE, ROP_DEST, ROP_NOTDEST, ROP_TRUE, + ROP_FALSE, ROP_DEST, ROP_NOTDEST, ROP_TRUE, + ROP_FALSE, ROP_DEST, ROP_NOTDEST, ROP_TRUE + }; + + /*ARGSUSED*/ + Matrix DeviceMatrix (width, height) int width, height; + { + return NewMatrix (pixels_per_inch / 72.0, 0.0, 0.0, -pixels_per_inch / 72.0, 0.0, (float) height); + } + + int IsWindowHardware (h) struct hardware *h; + { + return h->flags & ISWIN; + } + + #define IsWindowHardware(h) ((h)->flags & ISWIN) + + DevicePoint HardwareExtent (h) struct hardware *h; + { + if (h) + return h->extent; + else + return NewDevicePoint (0, 0); + } + + void SetClipHardware (h, clip) struct hardware *h, *clip; + { + if (h) + h->clip = clip; + } + diff -cr /usr/tmp/ps/source/array.c ./source/array.c *** /usr/tmp/ps/source/array.c Thu Jul 28 14:01:14 1988 --- ./source/array.c Wed Jul 27 12:02:11 1988 *************** *** 142,151 **** --- 142,165 ---- int ExecArray (item) Object item; { int l = lengthArray (item); + Object res; + register Object *rp = &res; if (l == 0) return TRUE; + /* + * BZS - try some open-coding here + * Push (ExecStack, SameFlags (item, Make (Body (item) + 1, l - 1))); + */ + rp->type = Array; + rp->flags = READABLE | WRITEABLE; + rp->u.Integer = 0; + rp->u.Array = item.u.Array + 1; + rp->Length = l - 1; + rp->flags = item.flags; + Push(ExecStack,res); + /* end open-coding */ if (TypeOf (Body (item) [0]) == Name || TypeOf (Body (item) [0]) == Operator) Push (ExecStack, Body (item) [0]); else diff -cr /usr/tmp/ps/source/config.c ./source/config.c *** /usr/tmp/ps/source/config.c Thu Jul 28 14:01:20 1988 --- ./source/config.c Thu Jul 28 14:07:25 1988 *************** *** 92,98 **** /* Begin jgm */ strcpy(versionbuf, DriverType); ! strcat(versionbuf, " version 1.4 with jgm mods v2"); Install ("version", StringFrom (versionbuf)); /* End jgm */ } --- 92,98 ---- /* Begin jgm */ strcpy(versionbuf, DriverType); ! strcat(versionbuf, " version 1.4 with jgm/bzs mods v3"); Install ("version", StringFrom (versionbuf)); /* End jgm */ } diff -cr /usr/tmp/ps/source/device.c ./source/device.c *** /usr/tmp/ps/source/device.c Thu Jul 28 14:01:23 1988 --- ./source/device.c Sat Apr 30 17:45:35 1988 *************** *** 25,31 **** struct hardware *h; DevicePoint extent; ! InstallOp ("framedevice", FrameDevice, 4, 0, 0, 0, Array, Integer, Integer, Array); InstallOp ("nulldevice", NullDevice, 0, 0, 0, 0); InstallOp ("grabbits", GrabBits, 4, 0, 0, 0, Float, Float, Float, Float); --- 25,31 ---- struct hardware *h; DevicePoint extent; ! InstallOp ("framedevice", FrameDevice, 4, 0, 0, 0, Array, Integer, Integer, Poly /* jgm */); InstallOp ("nulldevice", NullDevice, 0, 0, 0, 0); InstallOp ("grabbits", GrabBits, 4, 0, 0, 0, Float, Float, Float, Float); *************** *** 79,94 **** return TRUE; } - /*ARGSUSED*/ static int FrameDevice (mat, width, height, proc) Object mat, width, height, proc; { Matrix m; if (lengthArray (mat) != 6 || !ExtractMatrix (&m, mat)) return Error (PTypeCheck); if (BodyInteger (width) < 0 || BodyInteger (height) < 0) return Error (PRangeCheck); ! SetDevice (NewWindowDevice (BodyInteger (width) * 8, BodyInteger (height), m)); ErasePage (); return TRUE; --- 79,98 ---- return TRUE; } static int FrameDevice (mat, width, height, proc) Object mat, width, height, proc; { Matrix m; + struct device *d; if (lengthArray (mat) != 6 || !ExtractMatrix (&m, mat)) return Error (PTypeCheck); if (BodyInteger (width) < 0 || BodyInteger (height) < 0) return Error (PRangeCheck); ! /* Begin jgm */ ! d = NewWindowDevice (BodyInteger (width) * 8, BodyInteger (height), m); ! d->output_routine = proc; ! SetDevice (d); ! /* End jgm */ ErasePage (); return TRUE; *************** *** 148,155 **** res->link_count = 0; res->default_clip = clip; res->default_matrix = m; res->dev = dev; ! return res; } --- 152,160 ---- res->link_count = 0; res->default_clip = clip; res->default_matrix = m; + res->output_routine = Nil; res->dev = dev; ! return res; } diff -cr /usr/tmp/ps/source/device.h ./source/device.h *** /usr/tmp/ps/source/device.h Thu Jul 28 13:43:09 1988 --- ./source/device.h Sat Apr 30 16:34:02 1988 *************** *** 9,14 **** --- 9,15 ---- Matrix default_matrix; Path default_clip; int link_count; + Object output_routine; /* jgm */ struct hardware *dev; }; diff -cr /usr/tmp/ps/source/dictionary.c ./source/dictionary.c *** /usr/tmp/ps/source/dictionary.c Thu Jul 28 13:53:28 1988 --- ./source/dictionary.c Wed Jul 27 12:02:12 1988 *************** *** 17,24 **** Object Absent, Nil, SysDict; ! Object DictLookup (), MakeDict (), DictLoad (); static int LengthDict (), CopyDict (), forDict (), ForDict (), PutDict (), GetDict (); static int PDict (), PBegin (), PEnd (), PDef (), PStore (), PKnown (), PLoad (); static int PrCheck (), PwCheck (), PReadOnly (), EqDict (); --- 17,29 ---- Object Absent, Nil, SysDict; ! /* BZS - DictLoad open-coded */ ! #ifndef DictLoad ! Object DictLoad(); ! #endif + Object DictLookup (), MakeDict (); + static int LengthDict (), CopyDict (), forDict (), ForDict (), PutDict (), GetDict (); static int PDict (), PBegin (), PEnd (), PDef (), PStore (), PKnown (), PLoad (); static int PrCheck (), PwCheck (), PReadOnly (), EqDict (); *************** *** 166,171 **** --- 171,182 ---- (a.u.Integer == b.u.Integer || TypeOf (a) == Array && a.Length == 0); } + /* BZS - open code Equal */ + #define Equal(A,B) ((TypeOf(A) == TypeOf(B)) && \ + (A.Length == B.Length) && \ + ((A.u.Integer == B.u.Integer)|| \ + (TypeOf(A) == Array) && (A.Length == 0))) + static DictReplace (hash, key, value, size, h) struct dict_entry *hash; Object key, value; int size, h; { int i; *************** *** 250,258 **** DictStore (SysDict, NameFrom (key), value); } ! static Object DictFind (hash, key, size) struct dict_entry *hash; Object key; int size; { ! int i, h; ++hash_attempts; --- 261,272 ---- DictStore (SysDict, NameFrom (key), value); } ! /* ! * BZS - add some register decls, make global for macrification (remove static) ! */ ! Object DictFind (hash, key, size) struct dict_entry *hash; Object key; int size; { ! register int i, h; ++hash_attempts; *************** *** 266,271 **** --- 280,286 ---- { if (TypeOf (hash[i].entry_key) == Null) return Absent; + if (Equal (key, hash[i].entry_key)) { ++hash_tries; *************** *** 279,289 **** --- 294,308 ---- } return Absent; } + #undef Equal + /* BZS - macro-ified */ + #ifndef DictLoad Object DictLoad (dict, key) Object dict, key; { return DictFind (Body (dict)->dict_body, key, Body (dict)->dict_size); } + #endif Object Lookup (dict, key) Type dict; Object key; { diff -cr /usr/tmp/ps/source/fill.c ./source/fill.c *** /usr/tmp/ps/source/fill.c Thu Jul 28 14:02:56 1988 --- ./source/fill.c Wed Jul 27 12:02:15 1988 *************** *** 35,41 **** * pool */ ! static struct edge { int topX, topY, bottomX, bottomY; short dir; struct edge *pair; --- 35,41 ---- * pool */ ! /* static (removed --jgm) */ struct edge { int topX, topY, bottomX, bottomY; short dir; struct edge *pair; *************** *** 70,75 **** --- 70,126 ---- static int FillIt (); static int EoRule (), NwRule (); + /* + * BZS - Open Code + */ + #define NotThisBit(EDGE,WHERE,EMITFN) { \ + if((EDGE)->pair != NULL) { \ + (*EMITFN)((EDGE),(EDGE)->pair,(EDGE)->startingY,WHERE); \ + (EDGE)->pair->startingY = WHERE; \ + (EDGE)->pair->where = WHERE; \ + (EDGE)->pair->pair = NULL; \ + (EDGE)->pair = NULL; \ + } \ + (EDGE)->startingY = WHERE; \ + (EDGE)->where = WHERE; \ + } + + #define ThisBit(LEFT,RIGHT,WHERE,EMITFN) { \ + if((LEFT)->pair != (RIGHT) || (RIGHT)->up) { \ + if((LEFT)->pair != NULL) { \ + (*EMITFN)(LEFT,(LEFT)->pair,(LEFT)->startingY,(LEFT)->where); \ + (LEFT)->pair->startingY = (LEFT)->pair->where; \ + (LEFT)->pair->pair->startingY = (LEFT)->pair->pair->where; \ + (LEFT)->pair->pair = NULL; \ + } \ + if ((RIGHT)->pair != NULL) { \ + (*EMITFN) (RIGHT, (RIGHT)->pair, (RIGHT)->startingY, (RIGHT)->where); \ + (RIGHT)->pair->startingY = (RIGHT)->pair->where; \ + (RIGHT)->pair->pair->startingY = (RIGHT)->pair->pair->where; \ + (RIGHT)->pair->pair = NULL; \ + } \ + (LEFT)->pair = RIGHT; \ + (RIGHT)->pair = LEFT; \ + (LEFT)->startingY = (RIGHT)->startingY = WHERE; \ + } \ + (LEFT)->where = (RIGHT)->where = WHERE; \ + (LEFT)->up = TRUE; \ + (RIGHT)->up = FALSE; \ + } + + #define UpEdge(COUNT_A,COUNT_B,INC_A,INC_B,RULE_A,RULE_B) \ + ((*RULE_B)(COUNT_B+INC_B) && !(*RULE_A)(COUNT_A) && \ + (*RULE_A)(COUNT_A+INC_A)||(*RULE_A)(COUNT_A+INC_A) && \ + !(*RULE_B)(COUNT_B) && (*RULE_B)(COUNT_B+INC_B)) + + #define DownEdge(COUNT_A,COUNT_B,INC_A,INC_B,RULE_A,RULE_B) \ + ((*RULE_B)(COUNT_B+INC_B) && (*RULE_A)(COUNT_A) && \ + !(*RULE_A)(COUNT_A+INC_A)||(*RULE_A)(COUNT_A+INC_A) && \ + (*RULE_B)(COUNT_B) && !(*RULE_B)(COUNT_B+INC_B)) + + #define Xvalue(AX,AY,BX,BY,CY) \ + ((BX)+((CY)-(BY))*((AX)-(BX))/(float)((AY)-(BY))) + static void EmitTrapezoid (left, right, top, bottom) struct edge *left, *right; int top, bottom; { struct edge *temp; *************** *** 286,320 **** ProcessEdges (rule_a, rule_b, emitfn) int (*rule_a)(), (*rule_b)(); void (*emitfn)(); { ! struct edge *up_edge; ! int i, count_a = 0, count_b = 0; ! /* static void RemoveEdges (); (unused --jgm) */ ! ! for (i = 0; i < ninteresting; i++) ! { ! /* static void Emit (); (unused --jgm) */ ! int d_a = 0, d_b = 0; ! ! if (interesting[i]->clip) ! d_a = interesting[i]->dir; ! else ! d_b = interesting[i]->dir; ! if (UpEdge (count_a, count_b, d_a, d_b, rule_a, rule_b)) ! up_edge = interesting[i]; ! else if (DownEdge (count_a, count_b, d_a, d_b, rule_a, rule_b)) ! ThisBit (up_edge, interesting[i], interestingY, emitfn); ! else ! NotThisBit (interesting[i], interestingY, emitfn); ! ! count_a += d_a; ! count_b += d_b; ! } ! if (count_a || count_b) ! fprintf (stderr, "count_a = %dcount_b = %d\n", count_a, count_b); ! PanicIf (count_a || count_b, "something wrong in area fill"); } ThisBit (left, right, where, emitfn) struct edge *left, *right; int where; void (*emitfn)(); { if (left->pair != right || right->up) --- 337,379 ---- ProcessEdges (rule_a, rule_b, emitfn) int (*rule_a)(), (*rule_b)(); void (*emitfn)(); { ! register struct edge **intp; ! register struct edge *up_edge; ! register int count_a = 0, count_b = 0; ! register int i; ! i = ninteresting; ! intp = interesting; ! while(i-- > 0) { ! register int d_a = 0, d_b = 0; ! ! if ((*intp)->clip) ! d_a = (*intp)->dir; ! else ! d_b = (*intp)->dir; ! ! if (UpEdge (count_a, count_b, d_a, d_b, rule_a, rule_b)) ! up_edge = *intp; ! else if(DownEdge (count_a, count_b, d_a, d_b, rule_a, rule_b)){ ! ThisBit (up_edge,(*intp), interestingY, emitfn); ! } ! else { ! NotThisBit ((*intp),interestingY,emitfn); ! } ! count_a += d_a; ! count_b += d_b; ! ! intp++; ! } ! ! if (count_a || count_b) { ! fprintf (stderr, "count_a = %dcount_b = %d\n", count_a, count_b); ! Panic("something wrong in area fill"); ! } } + /* BZS - Open code */ + #ifndef ThisBit ThisBit (left, right, where, emitfn) struct edge *left, *right; int where; void (*emitfn)(); { if (left->pair != right || right->up) *************** *** 341,347 **** --- 400,412 ---- left->where = right->where = where; left->up = TRUE; right->up = FALSE; } + #endif + /* + * BZS - Open Code this, it can be called hundreds of thousands of times + * in even simple pictures. Mooreforms spend 50% of its time in this. + */ + #ifndef NotThisBit NotThisBit (edge, where, emitfn) struct edge *edge; int where; void (*emitfn)(); { if (edge->pair != NULL) *************** *** 355,364 **** edge->startingY = where; edge->where = where; } static void RemoveEdges (interestingY, emitfn) int interestingY; void (*emitfn)(); { ! int i, j = 0; for (i = 0; i < ninteresting; i++) if (interesting [i]->bottomY > interestingY) --- 420,430 ---- edge->startingY = where; edge->where = where; } + #endif static void RemoveEdges (interestingY, emitfn) int interestingY; void (*emitfn)(); { ! register int i, j = 0; for (i = 0; i < ninteresting; i++) if (interesting [i]->bottomY > interestingY) *************** *** 368,385 **** ninteresting = j; } static int UpEdge (count_a, count_b, inc_a, inc_b, rule_a, rule_b) int count_a, count_b, inc_a, inc_b, (*rule_a) (), (*rule_b) (); { return (*rule_b)(count_b + inc_b) && !(*rule_a) (count_a) && (*rule_a) (count_a + inc_a) || (*rule_a)(count_a + inc_a) && !(*rule_b) (count_b) && (*rule_b) (count_b + inc_b); } ! static int DownEdge (count_a, count_b, inc_a, inc_b, rule_a, rule_b) int count_a, count_b, inc_a, inc_b, (*rule_a) (), (*rule_b) (); { return (*rule_b)(count_b + inc_b) && (*rule_a) (count_a) && !(*rule_a) (count_a + inc_a) || (*rule_a)(count_a + inc_a) && (*rule_b) (count_b) && !(*rule_b) (count_b + inc_b); } ! static int EoRule (n) int n; { return n & 1; --- 434,453 ---- ninteresting = j; } + #ifndef UpEdge static int UpEdge (count_a, count_b, inc_a, inc_b, rule_a, rule_b) int count_a, count_b, inc_a, inc_b, (*rule_a) (), (*rule_b) (); { return (*rule_b)(count_b + inc_b) && !(*rule_a) (count_a) && (*rule_a) (count_a + inc_a) || (*rule_a)(count_a + inc_a) && !(*rule_b) (count_b) && (*rule_b) (count_b + inc_b); } ! #endif ! #ifndef DownEdge static int DownEdge (count_a, count_b, inc_a, inc_b, rule_a, rule_b) int count_a, count_b, inc_a, inc_b, (*rule_a) (), (*rule_b) (); { return (*rule_b)(count_b + inc_b) && (*rule_a) (count_a) && !(*rule_a) (count_a + inc_a) || (*rule_a)(count_a + inc_a) && (*rule_b) (count_b) && !(*rule_b) (count_b + inc_b); } ! #endif static int EoRule (n) int n; { return n & 1; *************** *** 405,419 **** return num / denom; } static int Xvalue (ax, ay, bx, by, cy) int ax, ay, bx, by, cy; { return bx + (cy - by) * (ax - bx) / (float) (ay - by); } static int intercmp (aa, bb) char *aa, *bb; { ! struct edge *a = *(struct edge **) aa, *b = *(struct edge **) bb; ! int sign; sign = Xvalue (a->topX, a->topY, a->bottomX, a->bottomY, interestingY + 1) - Xvalue (b->topX, b->topY, b->bottomX, b->bottomY, interestingY + 1); --- 473,489 ---- return num / denom; } + #ifndef Xvalue static int Xvalue (ax, ay, bx, by, cy) int ax, ay, bx, by, cy; { return bx + (cy - by) * (ax - bx) / (float) (ay - by); } + #endif static int intercmp (aa, bb) char *aa, *bb; { ! register struct edge *a = *(struct edge **) aa, *b = *(struct edge **) bb; ! int sign; sign = Xvalue (a->topX, a->topY, a->bottomX, a->bottomY, interestingY + 1) - Xvalue (b->topX, b->topY, b->bottomX, b->bottomY, interestingY + 1); *************** *** 424,449 **** static void AddInteresting () { ! int i; nextY = infinity; for (; here < nedges && edge[here].topY <= interestingY; here++) /* look at each new interesting edge */ { ! int i, n; ! ! for (i = 0; i < ninteresting; i++) /* look at all possible intersections */ { ! int inter = Yintersect (&edge[here], interesting[i]); ! if (inter >= interestingY && inter <= edge[here].bottomY && inter <= interesting[i]->bottomY) AddLowest (inter); } n = ninteresting++; ! interesting[n] = &edge[here]; ! interesting[n]->pair = NULL; ! interesting[n]->up = FALSE; ! interesting[n]->startingY = interesting[n]->where = edge[here].topY; ! interesting[n]->name = names++; } i = NextLowest (interestingY); if (i) --- 494,526 ---- static void AddInteresting () { ! register int i; ! register struct edge **intp; nextY = infinity; for (; here < nedges && edge[here].topY <= interestingY; here++) /* look at each new interesting edge */ { ! register int i, n; ! ! i = ninteresting; ! intp = interesting; ! while(i-- > 0) /* look at all possible intersections */ { ! int inter = Yintersect (&edge[here], (*intp)); ! if (inter >= interestingY && ! inter <= edge[here].bottomY && ! inter <= (*intp)->bottomY) AddLowest (inter); + intp++; } n = ninteresting++; ! intp = &interesting[n]; ! *intp = &edge[here]; ! (*intp)->pair = NULL; ! (*intp)->up = FALSE; ! (*intp)->startingY = (*intp)->where = edge[here].topY; ! (*intp)->name = names++; } i = NextLowest (interestingY); if (i) *************** *** 450,461 **** nextY = i; if (here != nedges && edge[here].topY < nextY) nextY = edge[here].topY; ! for (i = 0; i < ninteresting; i++) ! { ! if (interesting[i]->topY > interestingY && interesting[i]->topY < nextY) ! nextY = interesting[i]->topY; ! if (interesting[i]->bottomY > interestingY && interesting[i]->bottomY < nextY) ! nextY = interesting[i]->bottomY; } qsort ((char *) interesting, (unsigned) ninteresting, sizeof (struct edge *), intercmp); } --- 527,541 ---- nextY = i; if (here != nedges && edge[here].topY < nextY) nextY = edge[here].topY; ! i = ninteresting; ! intp = interesting; ! while(i-- > 0) ! { ! if ((*intp)->topY > interestingY && (*intp)->topY < nextY) ! nextY = (*intp)->topY; ! if ((*intp)->bottomY > interestingY && (*intp)->bottomY < nextY) ! nextY = (*intp)->bottomY; ! intp++; } qsort ((char *) interesting, (unsigned) ninteresting, sizeof (struct edge *), intercmp); } *************** *** 462,468 **** static void FindInfinity () { ! int i; infinity = edge[0].topY; for (i = 0; i < nedges; i++) --- 542,548 ---- static void FindInfinity () { ! register int i; infinity = edge[0].topY; for (i = 0; i < nedges; i++) *************** *** 503,509 **** static void BuildEdgeList (path, clip) Path path; int clip; { ! Path p; HardPoint move, here; for (p = path->next; p != path; p = p->next) --- 583,589 ---- static void BuildEdgeList (path, clip) Path path; int clip; { ! register Path p; HardPoint move, here; for (p = path->next; p != path; p = p->next) *************** *** 533,539 **** static int NextLowest (y) int y; { int res; ! struct lowest *p; for (p = lowest; p && p->e <= y; p = lowest) /* delete any which are now irrelevent */ { --- 613,619 ---- static int NextLowest (y) int y; { int res; ! register struct lowest *p; for (p = lowest; p && p->e <= y; p = lowest) /* delete any which are now irrelevent */ { *************** *** 551,557 **** static void AddLowest (e) int e; { ! struct lowest *res, *p, *q; for (p = lowest; p && p->e < e; q = p, p = p->higher) ; --- 631,637 ---- static void AddLowest (e) int e; { ! register struct lowest *res, *p, *q; for (p = lowest; p && p->e < e; q = p, p = p->higher) ; diff -cr /usr/tmp/ps/source/font.c ./source/font.c *** /usr/tmp/ps/source/font.c Thu Jul 28 14:02:59 1988 --- ./source/font.c Wed Jul 27 12:02:18 1988 *************** *** 362,372 **** else return NewVector (0.0, 0.0, 1.0); } ! static int BuildHershey (font, code) Object font, code; { Vector met; ! Object *bbox, string, nm; unsigned char *s; Path p; int i, l; --- 362,374 ---- else return NewVector (0.0, 0.0, 1.0); } ! /* ! * BZS - some small changes to allow macrification of DictLoad() ! */ static int BuildHershey (font, code) Object font, code; { Vector met; ! Object *bbox, string, nm, tmp; unsigned char *s; Path p; int i, l; *************** *** 373,381 **** --- 375,391 ---- bbox = BodyArray (DictLoad (font, FontBBox)); nm = BodyArray (DictLoad (font, Encoding)) [BodyInteger (code)]; + /* met = GetMetrics (DictLoad (DictLoad (font, Metrics), nm)); + */ + tmp = DictLoad(font,Metrics); + met = GetMetrics(DictLoad(tmp,nm)); met.vx -= 2; /* hershey bodge - they look better closer */ + /* string = DictLoad (DictLoad (font, CharStrings), nm); + */ + tmp = DictLoad(font,CharStrings); + string = DictLoad(tmp,nm); SetCacheDevice (nm, NewPoint (met.vx, met.vy), BodyReal (bbox[0]), BodyReal (bbox[1]), diff -cr /usr/tmp/ps/source/main.h ./source/main.h *** /usr/tmp/ps/source/main.h Thu Jul 28 13:53:36 1988 --- ./source/main.h Wed Jul 27 12:02:21 1988 *************** *** 166,170 **** --- 166,176 ---- ((getchbuf != EOF) ? getchbuf : ((BodyFile(file)->available = 0), Close (file), EOF))) \ : GeneralGetch (file)) + /* + * BZS - macro-ify some things + */ + Object DictFind(); + #define DictLoad(DICT,KEY) DictFind((DICT.u.Dictionary)->dict_body,KEY,\ + (DICT.u.Dictionary)->dict_size) /* Next line --jgm */ #define PanicIf(flag,s) do { if (flag) Panic(s); } while (0) diff -cr /usr/tmp/ps/source/matrix.c ./source/matrix.c *** /usr/tmp/ps/source/matrix.c Thu Jul 28 14:03:05 1988 --- ./source/matrix.c Wed Jul 27 12:02:22 1988 *************** *** 393,400 **** HardPoint ExtToInt (p) Point p; { Vector v; ! v = Transform (NewVector (p.x, p.y, 1.0), gstate->CTM); return NewHardPoint (v.vx, v.vy); } --- 393,413 ---- HardPoint ExtToInt (p) Point p; { Vector v; ! register Vector *vp; ! register Matrix *mp; ! register Point *pp; ! /* ! * BZS - try open coding this ! * v = Transform (NewVector (p.x, p.y, 1.0), gstate->CTM); + */ + mp = &gstate->CTM; + vp = &v; + pp = &p; + + vp->vx = pp->x * mp->A + pp->y * mp->C + mp->tx; + vp->vy = pp->x * mp->B + pp->y * mp->D + mp->ty; + return NewHardPoint (v.vx, v.vy); } diff -cr /usr/tmp/ps/source/misc.c ./source/misc.c No differences encountered diff -cr /usr/tmp/ps/source/operator.c ./source/operator.c *** /usr/tmp/ps/source/operator.c Thu Jul 28 14:03:10 1988 --- ./source/operator.c Wed Jul 27 12:02:23 1988 *************** *** 203,212 **** * */ int ExecOperator (item) Object item; { ! struct op_struct *op = Body (item); ! int i, res, (*fn)() = op->fn; Object arg[7]; Self = NameOperator (item); --- 203,216 ---- * */ + /* + * BZS - try to speed up a little + */ int ExecOperator (item) Object item; { ! register struct op_struct *op = Body (item); ! register int i, res; ! int (*fn)() = op->fn; Object arg[7]; Self = NameOperator (item); *************** *** 219,225 **** arg[i] = Pop (OpStack); for (i = op->arguments - 1; i >= 0; i--) { ! Type formal = op->argtypes[i], actual = TypeOf (arg[i]); if (formal == Float && actual == Integer) arg[i] = RealInteger (arg[i]); --- 223,229 ---- arg[i] = Pop (OpStack); for (i = op->arguments - 1; i >= 0; i--) { ! register Type formal = op->argtypes[i], actual = TypeOf (arg[i]); if (formal == Float && actual == Integer) arg[i] = RealInteger (arg[i]); diff -cr /usr/tmp/ps/source/screen.c ./source/screen.c *** /usr/tmp/ps/source/screen.c Thu Jul 28 13:44:08 1988 --- ./source/screen.c Sat Apr 30 18:44:06 1988 *************** *** 55,61 **** struct hardware *shade; } *screen = NULL; ! static int screen_size, screen_side; static int FreqSize (freq) float freq; { --- 55,61 ---- struct hardware *shade; } *screen = NULL; ! static int screen_size /* , screen_side (unused --jgm) */; static int FreqSize (freq) float freq; { *************** *** 121,127 **** free ((char *) screen); } p = screen = (struct screen *) Malloc ((unsigned) (((screen_size = size * size) + 1) * sizeof (struct screen))); ! screen_side = size; for (i = 0; i < size; i++) for (j = 0; j < size; j++) { --- 121,127 ---- free ((char *) screen); } p = screen = (struct screen *) Malloc ((unsigned) (((screen_size = size * size) + 1) * sizeof (struct screen))); ! /* screen_side = size; (unused --jgm) */ for (i = 0; i < size; i++) for (j = 0; j < size; j++) { diff -cr /usr/tmp/ps/source/state.c ./source/state.c *** /usr/tmp/ps/source/state.c Thu Jul 28 14:03:20 1988 --- ./source/state.c Sat Apr 30 16:47:57 1988 *************** *** 123,128 **** --- 123,133 ---- static int CopyPage () { + /* Begin jgm */ + if (TypeOf(gstate->device->output_routine) != Null) { + Push(ExecStack, gstate->device->output_routine); + } + /* End jgm */ return TRUE; } diff -cr /usr/tmp/ps/source/stroke.c ./source/stroke.c *** /usr/tmp/ps/source/stroke.c Thu Jul 28 13:48:04 1988 --- ./source/stroke.c Sat Apr 30 18:26:27 1988 *************** *** 358,364 **** int PStrokePath () { Path p, new = NewPath (); ! HardPoint prev, here, move; enum pelem_type last_type = EHeader; float angle, last_angle, width = gstate->line_width; --- 358,364 ---- int PStrokePath () { Path p, new = NewPath (); ! HardPoint /* prev, (unused --jgm) */ here, move; enum pelem_type last_type = EHeader; float angle, last_angle, width = gstate->line_width; *************** *** 370,376 **** switch (p->ptype) { case EMove: ! prev = here; move = here = p->pe.point; break; --- 370,376 ---- switch (p->ptype) { case EMove: ! /* prev = here; (unused --jgm) */ move = here = p->pe.point; break; *************** *** 378,384 **** if (last_type == EMove) break; angle = LineSegment (p, new, IntToExt (here), IntToExt (move), width, last_angle, last_type); ! prev = here; here = move; last_type = EHeader; break; --- 378,384 ---- if (last_type == EMove) break; angle = LineSegment (p, new, IntToExt (here), IntToExt (move), width, last_angle, last_type); ! /* prev = here; (unused --jgm) */ here = move; last_type = EHeader; break; *************** *** 385,391 **** case ELine: angle = LineSegment (p, new, IntToExt (here), IntToExt (p->pe.point), width, last_angle, last_type); ! prev = here; here = p->pe.point; break; --- 385,391 ---- case ELine: angle = LineSegment (p, new, IntToExt (here), IntToExt (p->pe.point), width, last_angle, last_type); ! /* prev = here; (unused --jgm) */ here = p->pe.point; break; *** /dev/null Thu Jul 28 10:26:48 1988 --- wwinfo.h Thu Jul 28 14:36:37 1988 *************** *** 0 **** --- 1,14 ---- + Now that I've gotten your attention... + + If your system doesn't have the wwinfo.h file, that probably means + that you don't have the ww window manager, which is rumored to be + available only to academic sites in the U.K. In that case, a version + of the Postscript Interpreter compiled to produce output for ww + is probably worthless to you. + + Please examine the file source/makefile and select a version that is + appropriate for you--possible choices include "sunPS", "XPS", and + "xps". + + _.John G. Myers +