bates@uwstat.UUCP (08/22/85)
The `csh' archive which follows contains a first cut at a PostScript(tm) device driver for S. There are many things that we hope to modify and improve in this but, as it stands, it can still produce some very nice plots. We have had it in use for a couple of months with good results. PostScript(tm) is a page description language developed by Adobe Systems. It is incorporated in the Apple LaserWriter(tm) as well as other laser printers and some phototypesetters. Although it is not required for the use of this driver, the TranScript(tm) software from Adobe Systems is usually used to provide the print filters for a PostScript(tm) printer from a 4.2BSD system. The biggest difficulty with this driver as it stands is that the "*" character, which is the default plot character, is rendered in the Helvetica(tm) font and that asterix is in the superscript position. That means that, if you make a scatter plot with the `plot' function, the asterixes are all a little bit too high. The best solution is to use `plot' with `type="n"' and use `points' with `mark= ' to put the points on the plot. A typical sequence to install this driver is to log in as the S maintainer and cd $SHOME/slocal mkdir ps S FUNCTION -d pscript pscript.i <unbundle the csh archive> S MAKE pscript S MAKE dev.pscript S NEWDOC pscript PostScript and TranScript are trademarks of Adobe Systems LaserWriter is a trademark of Apple Computer Helvetica is a registered trademark of Allied Corp. # to unbundle, csh this file echo pscript.d sed 's/^X//' >pscript.d <<'End of pscript.d' X.BG X.FN pscript X.TL Xpscript: Device driver for PostScript\(tm printers X.CS Xpscript(width, height, horizo) X.PP X.AG width XWidth of plotting region in inches - defaults to 8 X.AG height XHeight of plotting region in inches - defaults to 10 X.AG horizo XChange to horizontal orientation - currently inoperative X.PP XThis function identifies the device driver which produces a file of Xcommands in the PostScript\(tm language to produce the plots. XThis file is named "PostScript.out" and would usually be sent directly Xto the PostScript\(tm printer via a command such as X.PP Xlpr -Pps PostScript.out X.PP XNote that `pscript' appends to the file "PostScript.out" so it is a good Xidea to remove it after you have printed it. XA device must be specified before any graphics functions can be used. X.EX Xpscript Xplot(hstart) Xq # exit from S X Xlpr -Pps -h Po* Xrm Po* X.KW graphics X.WR 'End of pscript.d' echo pscript.i sed 's/^X//' >pscript.i <<'End of pscript.i' X# PostScript device driver function XFUNCTION pscript( X width /REAL,1,7.5/ X height /REAL,1,10.0/ X horizo /LGL,1,FALSE/ X ) XSTATIC(logical streq) XSTRUCTURE(parms/REAL,3/) # w,h,vertical X Xif(streq(TEXT(FNAME),TSTRING(pscripth))|| horizo){ X horizo = TRUE X if(MISSING(width)) width=10 X else if (width > 11) FATAL(Width cannot exceed 11 inches) X if(MISSING(height)) height=7.5 X else if (height > 8.5) FATAL(Height cannot exceed 8.5 inches) X} Xelse { X if (width > 8.5) FATAL(Width cannot exceed 8.5 inches) X if (height > 11) FATAL(Height cannot exceed 11 inches) X} Xparms[1] = width Xparms[2] = height Xif(horizo) parms[3]=1; else parms[3]=0 X XDEVICE_DRIVER XRETURN(parms) XEND 'End of pscript.i' echo ps/ps.pro sed 's/^X//' >ps/ps.pro <<'End of ps/ps.pro' X/M {moveto} def X/L {lineto} def X/oldcex 1 def X/coffset 140 0.375 mul def X X/Stext X { /pos exch def X /srot exch def X /cex exch def X /ypos exch def X /xpos exch def X /str exch def X X xpos ypos moveto X oldcex cex ne X { currentfont cex oldcex div scalefont setfont X /coffset coffset cex oldcex div mul store X /oldcex cex store X } if X gsave X srot rotate X str stringwidth pop neg X pos 0.5 eq X { 2 div } X { pos 0.5 lt X { pop 0 } X if } X ifelse X coffset neg rmoveto X str show X grestore X } store X X/Schar X { /cex exch def X /str exch def X X oldcex cex ne X { currentfont cex oldcex div scalefont setfont X /coffset coffset cex oldcex div mul store X /oldcex cex store X } if X str stringwidth pop neg 2 div coffset neg rmoveto X str show X } store X X0.1 0.1 scale % this version uses integer coordinates at 1/10's of a point X1 setlinecap 1 setlinejoin X/Helvetica findfont 140 scalefont setfont % default font is 14 pt. Helvetica X/oldcex 1 def X/coffset 140 0.375 mul def 'End of ps/ps.pro' echo pscriptsource/pscplot.C sed 's/^X//' >pscriptsource/pscplot.C <<'End of pscriptsource/pscplot.C' X/* S device driver for PostScript printers */ X#include <stdio.h> X#include <strings.h> X Xchar *strcat(); X Xdefine(`PSPRO',`"/usr3/s/slocal/ps/ps.pro"') X Xextern float F77_COM(bgrp)[];/* graphical parameters */ Xdefine(`am',`F77_COM(bgrp)[$1-1]') Xint moved=0; Xchar *dash_patterns[] = { X "[120 40]", X "[]", X "[10 70]", X "[40 40]", X "[80 40]", X "[130 30]", X "[160 20 20 20]", X "[80 20 20 20]", X "[10 130]", X "[60 50]" X}; X Xint widths[] = { 1, 5, 10, 15, 20, 25 }; X XF77_SUB(zparmz) (par, n) Xfloat par[]; Xlong *n; X{ X int i; X FILE *fp, *fopen(); X char c; X X for (i = 1; i <= 39; i++) X am(i) = 0.0; X X am(20) = 80.0; /* char size in rasters (tenths of a X point) */ X am(21) = 140.0; X X am(22) = (8.5 - *par) * 360.0; /* x limits in rasters */ X am(23) = (8.5 + *par) * 360.0; X X am(24) = (11.0 - par[1]) * 360.0; /* y limits in rasters */ X am(25) = (11.0 + par[1]) * 360.0; X X am(26) = 0.5; /* character offset */ X am(27) = 0.5; X X am(28) = 1.0 / 720; /* raster size in inches - raster is 1/10 X point */ X am(29) = am(28); X X am(30) = -423; /* device code number - a magic number X (same as `pic' device) to allow X batch use */ X am(31) = 1; X am(1) = 1; X X freopen("PostScript.out","a",stdout); X printf ("%%! PostScript from S\n");/* initialize device */ X if ((fp = fopen(strcat("SHOME","/slocal/ps/ps.pro"),"r")) == NULL) X FATAL(Unable to open PostScript procedures file) X while (EOF != (c = getc(fp))) /* copy PostScript procedures */ X putchar(c); X F77_SUB(zejecz) (); X} X XF77_SUB(zseekz) (ix, iy) Xlong int *ix, X *iy; X{ X static float line_type = -1, X line_width = -1; X X moved++; X if (line_type != am(8)) { /* set line type if changed */ X line_type = am(8); X printf ("%s 0 setdash\n",dash_patterns[((int) line_type) % 10]); X }; X X if (line_width != am(10)) { /* set line width if changed */ X line_width = am(10); X printf ("%d setlinewidth\n",widths[((int) line_width) % 5]); X }; X X printf ("%d %d M\n", *ix, *iy); X} X XF77_SUB(zlinez) (ix, iy) Xlong int *ix, X *iy; X{ X printf ("%d %d L\n", *ix, *iy); X} X XF77_SUB(zptchz) (ich, crot) Xchar *ich; Xfloat *crot; X{ X printf ("(%c) %g Schar\n", *ich, am(18)/am(89));/* print the character */ X} X XF77_SUB(zejecz) () { X if (moved) X printf ("copypage erasepage\n"); X} X XF77_SUB(zflshz) () { X printf ("stroke\n"); X fflush (stdout); X} X XF77_SUB(zwrapz) () { X printf ("showpage\n"); X fflush (stdout); X} X XF77_SUB(ztextz) (xx, yy, buf, n, pos, m) Xfloat *xx, *yy, *pos; Xchar buf[]; Xint *n, m; X{ X int i; X X if (*n <= 0) { X F77_SUB(zejecz) (); X F77_SUB(zerrpz) ("ztextz","Number of characters not positive",6); X } X putchar('('); X for (i = *n; i--; buf++) { X switch (*buf) { X case '(': X case ')': X putchar('\\'); X } X putchar(*buf); X } X printf ("\) %g %g %g %g %g Stext\n", *xx * am(37) + am(36), X *yy * am(39) + am(38), am(18)/am(89), am(48), *pos); X moved++; X} 'End of pscriptsource/pscplot.C' -- Doug Bates @ wisconsin ARPA: bates@wisc-stat.arpa bates@uwisc (if you have the old host table) UUCP: ...!{allegra,heurikon,ihnp4,seismo,sfwin,ucbvax,uwm-evax}!uwvax!bates