keves@net1.ucsd.edu (Brian Keves) (01/14/88)
Here are the responses I received from my request for a postscript device driver for S. Thanks very much to all who responded. The first three responses give information, the last two contain sources. ----------------- Brian Keves ARPA: keves@sdcsvax.ucsd.edu P.O. Box 12238 UUCP: sdcsvax!keves La Jolla, CA 92037-0620 BITNET: keves@ucsd PHONE: 619-534-3839 Please leave a message ORGANIZATION: Lab for Mathematics and Statistics @ UCSD Any opinions expressed are strictly my own and do not necessarily reflect the opinions of my employer or UC Regents. --- From alan@cunixc.columbia.edu Mon Jan 11 20:04:11 1988 From: Alan Crosswell <alan@cunixc.columbia.edu> Subject: Re: Need postscript device driver for S Newsgroups: sci.math.stat,comp.lang.postscript Organization: Columbia University Get a newer S distribution from AT&T. A postscript driver is now included. Here's the ~s/VERSION file that we have: Fri Feb 28 07:56:08 EST 1986 Alan Crosswell User Services Columbia University Center for Computing Activities --- From uw-beaver!fluke!battan@sdcsvax Wed Jan 13 00:48:37 1988 From: uw-beaver!tc.fluke.COM!battan@sdcsvax (Jim Battan) Subject: Re: Need postscript device driver for S Newsgroups: sci.math.stat,comp.lang.postscript Organization: John Fluke Mfg. Co., Inc., Everett, WA If no one else offers, I've got one. But I'm quite busy, so choose me as a last resort. -- Jim Battan Domain: battan@tc.fluke.COM Voice: +1 206 356 6469 UUCP: {uw-beaver,decvax!microsof,ucbvax!lbl-csam,allegra,sun}!fluke!battan --- From ucbvax!violet.berkeley.edu!forags@sdcsvax Mon Jan 11 17:50:06 1988 Subject: Re: Need postscript device driver for S Newsgroups: sci.math.stat,comp.lang.postscript Organization: University of California, Berkeley Call Fran Rizzardi at Academic Computing Services at Berkeley. (415) 642-6406 or ATSS 8-582-6406 I think she mentioned such a driver at a consultants' meeting a couple of months ago. Al Stangenberger Dept. of Forestry & Resource Mgt. forags@violet.berkeley.edu 145 Mulford Hall uucp: ucbvax!ucbviolet!forags Univ. of California (415) 642-4424 Berkeley, CA 94720 --- From this point on, I include the two sources that I received. I haven't had time to figure out which one works the best, but I wanted to include both because there is quite a bit of useful information in both letters. [BWK] --- From spector%springer.Berkeley.EDU@Berkeley.EDU Mon Jan 11 16:05:50 1988 From: spector%springer.Berkeley.EDU@berkeley.edu (Philip Spector) Subject: Postscript Driver for S Brian - The following Bourne shell archive should put the postscript device driver in ~s/slocal/x. It assumes that you have a bunch of S programs like MAKE, INSTALL,etc., which you probably do. Just store the program in a file, say, sps and then type "/bin/sh sps". Let me know if it works. - Phil ------------------------ cut below this line --------------------------- if test -f ~s/slocal then echo 'slocal should be a directory, not a file' exit fi if test ! -d ~s/slocal then echo 'creating slocal directory' mkdir ~s/slocal fi cd ~s/slocal if test ! -d x then echo 'creating x directory in slocal' fi if test ! -d postscriptsource then mkdir postscriptsource fi /bin/sh <<'$$$$$$$$$$' echo ./postscript.d 1>&2 cat >./postscript.d <<'End of ./postscript.d' .BG .FN postscript .TL postscript: Device driver for PostScript\(tm printers .CS postscript(width, height, horizo, font, ptsize) .PP .AG width Width of plotting region in inches (default is 8 inches) .AG height Height of plotting region in inches (default is 10 inches) .AG horizo Change to horizontal orientation (default is FALSE) .AG font Font number (default is 5 which is Helvetica - see below) .AG ptsize Point size for cex = 1 (default is 14 pt.) .PP This function identifies the device driver which produces a file of commands in the PostScript language to produce the plots. This file is named "PostScript.out" and would usually be sent directly to the PostScript\(tm printer via a command such as .PP lpr -Pps PostScript.out .PP Note that `postscript' erases any existing "PostScript.out". .PP The available fonts are the standard fonts for a PostScript printer and are identified by the numbers .nf 1 Times-Roman 2 Times-Italic 3 Times-Bold 4 Times-BoldItalic 5 Helvetica 6 Helvetica-Oblique 7 Helvetica-Bold 8 Helvetica-BoldOblique 9 Courier 10 Courier-Oblique 11 Courier-Bold 12 Courier-BoldOblique 13 Symbol .fi .PP A device must be specified before any graphics functions can be used. .KW graphics .WR End of ./postscript.d echo ./postscriptsource/postscript.C 1>&2 cat >./postscriptsource/postscript.C <<'End of ./postscriptsource/postscript.C' /* S device driver for PostScript printers */ #include <stdio.h> #include <time.h> #include <pwd.h> INCLUDE(device) char *getenv(), *getlogin (), *ctime (), *user; long time (), tloc; struct passwd *getpwuid (); extern float F77_COM(bgrp)[]; /* graphical parameters */ define(`am',`F77_COM(bgrp)[$1-1]') /* for ease of writing, F77_COM should be defined for the C preprocessor rather than the m4 preprocessor */ #define am(i) (bgrp_[i-1]) #define MAXLINES 500 #define Ltype ((int)am(8)) #define Lwidth ((int)am(9)) #define Color ((int)am(10)) #define Font ((int)am(79)) #define Cex (am(18)) #define Srot (am(48)) #define Adjust (am(100)) #define Rxmin ((int)am(22)) #define Rxmax ((int)am(23)) #define Rymin ((int)am(24)) #define Rymax ((int)am(25)) #define Xorigin (am(36)) #define Yorigin (am(38)) #define Xscale (am(37)) #define Yscale (am(39)) #define UxR(x) ((int)((x) * Xscale + Xorigin)) #define UyR(y) ((int)((y) * Yscale + Yorigin)) #define RxU(x) (((x) - Xorigin) / Xscale) #define RyU(y) (((y) - Yorigin) / Yscale) #define Xmin ((int)am(32)) #define Xmax ((int)am(33)) #define Ymin ((int)am(34)) #define Ymax ((int)am(35)) #define Max(a,b) ((a)>(b)?(a):(b)) static int moved=0, lines=0, npage=1, clipped = 0; static int line_type = -1, line_width = -1; static long current_color = -1; static int OXmin = 0, OXmax = -1, OYmin = 0, OYmax = -1; static char *dash_patterns[] = { "[120 40]", "[]", "[10 20]", "[40 40]", "[80 40]", "[130 30]", "[160 20 20 20]", "[80 20 20 20]", "[10 130]", "[60 50]" }; static char *fontnames[] = { "Times-Roman", "Times-Italic", "Times-Bold", "Times-BoldItalic", "Helvetica", "Helvetica-Oblique", "Helvetica-Bold", "Helvetica-BoldOblique", "Courier", "Courier-Oblique", "Courier-Bold", "Courier-BoldOblique", "Symbol" }; static int widths[] = { 1, 5, 10, 15, 20, 25, 30, 35, 40, 45 }; #define NCOLOR 10.0 #define NLTYPE (sizeof(dash_patterns)/sizeof(dash_patterns[0])) #define NLWIDTH (sizeof(widths)/sizeof(widths[0])) #define NFONT (sizeof(fontnames)/sizeof(fontnames[0])) F77_SUB(zparmz) (par, n) float par[]; long *n; { int i, horizontal, font; float xmax, ymax; for (i = 1; i <= 39; i++) am(i) = 0.0; am(21) = 10 * par[4]; /* char size in rasters (tenths of a point) */ am(20) = 80 * par[4]/14; /* average width of a character */ if (*n>2 && par[2]) { horizontal = 1; xmax = 11.; ymax = 8.5;} else { horizontal = 0; xmax=8.5; ymax=11.;} am(22) = (xmax - par[0]) * 360.0; /* x limits in rasters */ am(23) = (xmax + par[0]) * 360.0; am(24) = (ymax - par[1]) * 360.0; /* y limits in rasters */ am(25) = (ymax + par[1]) * 360.0; am(26) = 0.5; /* character offset */ am(27) = 0.5; am(28) = 1.0 / 720; /* raster size in inches */ am(29) = am(28); /* raster is 1/10 point */ am(30) = -998; /* device code number */ am(31) = 1; am(1) = 1; freopen("PostScript.out","w",stdout); printf("%%!PS-Adobe-1.0\n"); user = getenv ("NAME"); if (user == NULL) user = getlogin (); if (user == NULL) user = (getpwuid (getuid ())) -> pw_name; printf ("%%%%Creator: %s\n", user); tloc = time (0); printf("%%%%CreationDate: %s", ctime (&tloc)); printf("%%%%Pages: (atend)\n"); printf("%%%%DocumentFonts: Helvetica Symbol\n"); printf("%%%%BoundingBox: %g %g %g %g\n", am(22)/10, am(24)/10, am(23)/10, am(25))/10; printf("%%%%EndComments\n"); printf("/$Sdict 25 dict def $Sdict begin\n%% variables\n\n"); printf("/basesize %g def\n", par[4]*10.0); put_header(); if(horizontal) printf("90 rotate\n0 %d translate\n",(int) (-ymax*720)); font = par[3]; if (font < 0 || font >= NFONT) font = 4; printf("/%s F\n", fontnames[font]); printf("%%%%EndProlog\n"); F77_SUB(zejecz)(); } F77_SUB(ztextz) (xx, yy, buf, n, pos) float *xx, *yy, *pos; char buf[]; int *n; { int nn = *n; if (nn <= 0) { F77_SUB(zflshz) (); F77_SUB(zerrpz) ("ztextz","Number of characters not positive",0L,0L); return; } set_pars(); printf("%g %g %g %d %d ", Adjust, Srot, Cex, UxR(*xx), UyR(*yy)); putchar('('); while(nn--) { switch(*buf) { case '(': case ')': putchar('\\'); } putchar(*buf++); } printf(") T\n"); moved++; } F77_SUB(zpntsz) (xx, yy, n) float *xx, *yy; int *n; { int nn = *n; if (nn <= 0) { F77_SUB(zflshz) (); F77_SUB(zerrpz) ("zpntsz","Number of points not positive",0L,0L); return; } set_pars(); if (am(15) < 32) { /* draw marks for non-printing ascii */ nn = (long) am(15); F77_SUB(dmarkz) (xx, yy, n, nn); return; } printf("(%c) %g Pchar\n", (char) am(15), Cex); while(nn--) printf("%d %d P\n", UxR(*xx++), UyR(*yy++)); } F77_SUB(zlinsz) (xx, yy, n) float *xx, *yy; int *n; { int nn = *n, i; if (nn < 2) { F77_SUB(zflshz) (); F77_SUB(zerrpz) ("zlinsz","Needs at least 2 points",0L,0L); return; } set_pars(); printf("%d %d M\n", UxR(xx[0]), UyR(yy[0])); for(i = 1; i < nn; i++) { printf("%d %d L\n", UxR(xx[i]), UyR(yy[i])); if(i % MAXLINES == 0) printf("S %d %d M\n", UxR(xx[i]), UyR(yy[i])); } printf("S\n"); } F77_SUB(zpolyz) (xx, yy, n) float *xx, *yy; long *n; { int nn = *n, i; if (nn < 3) { F77_SUB(zflshz) (); F77_SUB(zerrpz) ("zpolyz","Needs at least 3 points",0L,0L); return; } set_pars(); printf("newpath %d %d M\n", UxR(*xx++), UyR(*yy++)); while(--nn) printf("%d %d L\n", UxR(*xx++), UyR(*yy++)); printf("closepath fill\n"); } F77_SUB(zsegsz) (x1, y1, x2, y2, n) float *x1, *y1, *x2, *y2; long *n; { int nn = *n, i; if (nn <= 0) { F77_SUB(zflshz) (); F77_SUB(zerrpz) ("zsegsz","Number of points must be positive",0L,0L); return; } set_pars(); while(nn--) printf("%d %d M %d %d L S\n", UxR(*x1++), UyR(*y1++), UxR(*x2++), UyR(*y2++)); } F77_SUB(zejecz) () { if (moved) { if (clipped) { printf("grestore\n"); clipped = 0; } printf ("gsave showpage grestore\n"); npage++; } /* isolate each page */ printf ("%%%%Page: %d %d\n",npage,npage); moved = 0; lines = 0; clipped = 0; line_type = -1; line_width = -1; current_color = -1; OXmin = 0; OXmax = -1; } F77_SUB(zflshz) () { if (lines) { printf("S\n"); lines = 0; } fflush (stdout); } F77_SUB(zwrapz) () { if (clipped) printf("grestore\n"); printf ("gsave showpage grestore\n"); printf("%%%%Trailer\n%%%%Pages: %d\nend\n",npage); fflush (stdout); } static set_pars() { int lwid; if (Xmin != OXmin || Xmax != OXmax || Ymin != OYmin || Ymax != OYmax) /* set clipping region if changed */ { if (clipped++) printf("grestore\n"); lwid = (widths[Lwidth % NLWIDTH] + 1)/2; OXmin = Xmin; OXmax = Xmax; OYmin = Ymin; OYmax = Ymax; printf("gsave newpath\n"); printf( "%d %d M %d %d L %d %d L %d %d L closepath clip newpath\n", OXmin-lwid, OYmin-lwid, OXmax+lwid, OYmin-lwid, OXmax+lwid, OYmax+lwid, OXmin-lwid, OYmax+lwid); /* reset line type, etc. because of */ /* the gsave */ current_color = line_width = line_type = -1; }; if (line_type != Ltype) /* set line type if changed */ { line_type = Ltype; printf ("%s 0 setdash\n",dash_patterns[line_type % NLTYPE]); }; if (line_width != Lwidth) /* set line width if changed */ { line_width = Lwidth; printf ("%d setlinewidth\n",widths[line_width % NLWIDTH]); }; if(current_color != Color) /* set color if changed */ { if(Color == 0) printf("1.0 setgray\n"); else printf("%g setgray\n", ((Color-1)%10)/NCOLOR); current_color = Color; } moved++; } /* low-level routines for older S */ /* device drivers - should not be */ /* needed */ F77_SUB(zseekz) (ix, iy) long int *ix, *iy; { if (lines) { printf("S\n"); lines = 0; } set_pars(); printf ("%d %d M\n", *ix, *iy); } F77_SUB(zlinez) (ix, iy) long *ix, *iy; { printf ("%d %d L\n", *ix, *iy); if(++lines > MAXLINES) { printf ("S\n%d %d M\n", *ix, *iy); lines = 0; } } F77_SUB(zfillz) () { printf ("fill\n"); } /* PostScript header definitions */ char *header[] = { "", "/oldcex 1 def", "/cex 1 def", "/ratio 1 def", "/pch (*) def", "/coffset basesize -0.345 mul def % vertical offset for characters", "/pcxshift 0 def", "", "% procedures", "", "/checksize % adjust font size if needed. Stack: cex", " {", " /cex exch def", " oldcex cex ne % scale sizes", " { ", " /ratio cex oldcex div def", " /TextFont TextFont ratio scalefont def", " /PchFont PchFont ratio scalefont def", " /coffset coffset ratio mul def", " /oldcex cex def", " } if", " } def", "", "/Pchar % define the plot character. Stack: string cex", " {", " checksize", " /pch exch def", " pch (.) eq % replace period by bullet", " { (\\267) pch copy pop } if", " pch (,) eq % replace comma by middot", " { (\\264) pch copy pop } if", " /PchFont TextFont def", " pch (*) eq pch (+) eq or % switch to symbol font for these characters", " { /PchFont /Symbol findfont basesize oldcex mul scalefont def } if", " PchFont setfont", " pch stringwidth pop neg 2 div /pcxshift exch def", " } def", "", "/M {moveto} def % move to a point. Stack: x y", "", "/L {lineto} def % line to a point. Stack: x y", "", "/S {stroke} def", "", "/P % plot a character at a point. Stack: x y", " {", " M % move to the point", " pcxshift coffset rmoveto % offset for the character", " pch show", " } def", "", "/T % show a text string. Stack: adj srot cex x y string", " { /str exch def", " M % move to the point (pops x and y)", " checksize % change size if necessary (pops cex)", " TextFont setfont", " dup rotate exch % (moves adj to top)", " str stringwidth pop neg mul % pops adj", " coffset rmoveto", " str show", " neg rotate", " } def", "", "/Sub %add a subscript. Stack: string srot", " {", " oldcex 0.75 mul checksize", " TextFont setfont", " dup rotate", " oldcex -0.5 mul basesize mul 0 exch rmoveto", " exch show", " oldcex 0.5 mul basesize mul 0 exch rmoveto", " neg rotate", " oldcex 4 3 div mul checksize TextFont setfont", " } def", "", "/Sup %add a superscript. Stack: string srot", " {", " oldcex 0.75 mul checksize", " TextFont setfont", " dup rotate", " oldcex 0.5 mul basesize mul 0 exch rmoveto", " exch show", " oldcex -0.5 mul basesize mul 0 exch rmoveto", " neg rotate", " oldcex 4 3 div mul checksize TextFont setfont", " } def", "", "/F % change the base font. Stack: fontname", " {", " /TextFont exch findfont basesize oldcex mul scalefont def", " /PchFont TextFont def", " } def", "", "/ST % text in Symbol font. Stack: (as for T)", " {", " /Symbol F T /Helvetica F", " } def", "", "0.1 0.1 scale %integer coordinates in 1/10's of a point", "1 setlinecap 1 setlinejoin", 0 }; static put_header() { char **p; for (p = header; *p; p++) printf("%s\n", *p); } /* Routine needed for the link using */ /* the old libraries */ f77_abort () { abort(); } End of ./postscriptsource/postscript.C echo ./postscript.i 1>&2 cat >./postscript.i <<'End of ./postscript.i' # PostScript device driver function FUNCTION postscript( width /REAL,1,7.5/ height /REAL,1,10.0/ horizo /LGL,1,FALSE/ font /INT,1,5/ ptsize /REAL,1,14.0/ ) STATIC(logical streq) STRUCTURE(parms/REAL,5/) # w,h,vertical if(streq(TEXT(FNAME),TSTRING(postscripth))|| horizo){ horizo = TRUE if(MISSING(width)) width=10 else if (width > 11) FATAL(Width cannot exceed 11 inches) if(MISSING(height)) height=7.5 else if (height > 8.5) FATAL(Height cannot exceed 8.5 inches) } else { if (width > 8.5) FATAL(Width cannot exceed 8.5 inches) if (height > 11) FATAL(Height cannot exceed 11 inches) } parms[1] = width parms[2] = height if(horizo) parms[3]=1; else parms[3]=0 parms[4] = font - 1 parms[5] = ptsize DEVICE_DRIVER RETURN(parms) END End of ./postscript.i echo appending ./Smakefile 1>&2 cat >>./Smakefile <<'End of ./Smakefile' i.postscript.C: ; echo 'INCLUDE(u/cinter)CINTER(postscript,-d)' >i.postscript.C postscript: i.postscript.o postscript.x # -d $(F77) $(LDFLAGS) $(STRIP) -o x/postscript i.postscript.o postscript.x $(LIBR) @touch postscript @echo postscript loaded dev.postscript: cd postscriptsource; S COMPILEALL $(F77) $(LDFLAGS) $(STRIP) -o x/dev.postscript $L/device.z $L/defer.z postscriptsource/*.o $(GRZLIB) @echo postscript driver loaded End of ./Smakefile $$$$$$$$$$ S MAKE postscript S MAKE dev.postscript S NEWDOC postscript.d --- From bill%hilbert.ms@beaver.cs.washington.edu Mon Jan 11 18:28:50 1988 From: bill%hilbert.ms@beaver.cs.washington.edu (Bill Dunlap) Subject: postscript graphics Brian -- Here is the postscript driver we use. It is called "pscript". I think it originally came from Wisconsin (several years ago) and I've made some modifications to it over the years. I recently wrote a new version of the basic graphics driver which is able to generate a PostScript file corresponding to what is on your screen. Thus if you are using the vt240 driver and have a picture on the screen, you type "printgraph" and a PostScript description of the picture is generated and sent to the printer. This is not a screen dump; the PostScript is generated from a display list. I'll be glad to send it but it includes a fair bit of S source code so I would need to see a liscence first. It is basically two libraries to replace $L/inddev.z and $L/device.z and the commands "printgraph" and "replot". I use it with vt240, crt (a curses based graphics driver for nongraphics terminals), and tek10. Well here is the pscript stuff. Clip at the dotted line and put the resulting file in ~s/slocal/pscript.shar. Then: cd ~s/slocal sh pscript.shar cd pscript S MAKE all. and you should be done. S MAKE clean will tidy things up. Use S MAKE virgin if you want to delete any machine dependent stuff. --------------------------------------------------------------- #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create: # pscript # This archive created: Mon Jan 11 17:36:35 1988 export PATH; PATH=/bin:/usr/bin:$PATH if test ! -d 'pscript' then mkdir 'pscript' fi cd 'pscript' if test ! -d 'pscriptsource' then mkdir 'pscriptsource' fi cd 'pscriptsource' if test -f 'pscplot.C' then echo shar: "will not over-write existing file 'pscplot.C'" else cat << \SHAR_EOF > 'pscplot.C' /* S device driver for PostScript printers */ #include <stdio.h> #include <strings.h> extern float F77_COM(bgrp)[];/* graphical parameters */ define(`am',`F77_COM(bgrp)[$1-1]') int moved=0; /* 1 if plot has anything on it */ int num_since_stroke=0; /* protect against current path getting too long */ int max_since_stroke=500; /* can be about 1500, I think, but let's be safe */ char *dash_patterns[] = { "[10 20 30 40 50 60]", /* 10 */ "[]", /* 1 */ "[10 20]", /* 2 */ "[80 30 10 30]", /* 3 */ "[130 30]", /* 4 */ "[130 20 8 20 8 20 8 20]", /* 5 */ "[160 20 20 20]", /* 6 */ "[5 20 5 20 5 20 5 50]", /* 7 */ "[40 40]", /* 8 */ "[60 20 5 20]" /* 9 */ }; int widths[] = { 1, 5, 10, 15, 20, 25 }; F77_SUB(zparmz) (par, n) float par[]; long *n; { int i; FILE *fp, *fopen(); char c; for (i = 1; i <= 39; i++) am(i) = 0.0; am(20) = 80.0; /* char size in rasters (tenths of a point) */ am(21) = 140.0; if (par[2]==0) { /* vertical plot */ am(22) = (8.5 - *par) * 360.0; /* x limits in rasters */ am(23) = (8.5 + *par) * 360.0; am(24) = (11.0 - par[1]) * 360.0; /* y limits in rasters */ am(25) = (11.0 + par[1]) * 360.0; } else { am(22) = (11.0 - *par) * 360.0; /* x limits in rasters */ am(23) = (11.0 + *par) * 360.0; am(24) = (8.5 - par[1]) * 360.0; /* y limits in rasters */ am(25) = (8.5 + par[1]) * 360.0; } am(26) = 0.5; /* character offset */ am(27) = 0.5; am(28) = 1.0 / 720; /* raster size in inches - raster is 1/10 point */ am(29) = am(28); am(30) = -423; /* device code number - a magic number (same as `pic' device) to allow batch use */ am(31) = 1; am(1) = 1; freopen("PostScript.out", "a", stdout) ; printf ("%%! PostScript from S\n");/* initialize device */ print_prolog() ; if (par[2]) { /* horizontal plot */ printf("90 rotate\n"); printf("0 -6120 translate\n"); } F77_SUB(zejecz) (); } F77_SUB(zseekz) (ix, iy) long int *ix, *iy; { static float line_type = -1, line_width = -1; moved++; if (line_type != am(8)) { /* set line type if changed */ line_type = am(8); printf ("%s 0 setdash\n",dash_patterns[((int) line_type) % 10]); }; if (line_width != am(10)) { /* set line width if changed */ line_width = am(10); printf ("%d setlinewidth\n",widths[((int) line_width) % 5]); }; printf ("%d %d M\n", *ix, *iy); } F77_SUB(zlinez) (ix, iy) long int *ix, *iy; { printf ("%d %d L\n", *ix, *iy); /* get "limitcheck" error if path is too long */ /* stroke and start new path occasionaly */ num_since_stroke++; if (num_since_stroke >= max_since_stroke) { printf("stroke %% to avoid limitcheck\n%d %d M\n", *ix, *iy); num_since_stroke = 0; } } F77_SUB(zptchz) (ich, crot) char *ich; float *crot; { if (*ich == '*') { printf ("(\\267) %g Schar\n", am(18)/am(89) );/* print the character */ } else { printf ("(%c) %g Schar\n", *ich,am(18)/am(89) );/* print the character */ } } F77_SUB(zejecz) () { if (moved) printf ("copypage erasepage %% end of one plot\n"); } F77_SUB(zflshz) () { if (num_since_stroke>0) printf ("stroke\n"); num_since_stroke = 0; fflush (stdout); } F77_SUB(zwrapz) () { printf ("showpage %% end of all S plots\n"); fflush (stdout); } F77_SUB(ztextz) (xx, yy, buf, n, pos, m) float *xx, *yy, *pos; char buf[]; int *n, m; { int i; if (*n <= 0) { F77_SUB(zejecz) (); F77_SUB(zerrpz) ("ztextz","Number of characters not positive",6); } putchar('('); for (i = *n; i--; buf++) { switch (*buf) { case '(': case ')': putchar('\\'); } putchar(*buf); } printf ("\) %g %g %g %g %g Stext\n", *xx * am(37) + am(36), *yy * am(39) + am(38), am(18)/am(89), am(48), *pos); moved++; } SHAR_EOF fi if test -f 'zpolyz.C' then echo shar: "will not over-write existing file 'zpolyz.C'" else cat << \SHAR_EOF > 'zpolyz.C' /* zpolyz - filled polygon with n vertices at user coordinates x,y */ #include <stdio.h> extern float F77_COM(bgrp)[]; F77_SUB(zpolyz)(x, y, n) float *x, *y; long *n; { long *ix, *iy; int i, j; float col; char *calloc(); i = *n; ix = (long*) calloc(i, sizeof(long)); iy = (long*) calloc(i, sizeof(long)); for (j=0;j<i;j++) { ix[j] = F77_COM(bgrp)[35] + F77_COM(bgrp)[36]*x[j] + 0.5; iy[j] = F77_COM(bgrp)[37] + F77_COM(bgrp)[38]*y[j] + 0.5; } /* draw the polygon */ printf("newpath\n"); printf("%d %d moveto\n", ix[0], iy[0]); for (j=1;j<i;j++) printf("%d %d lineto\n", ix[j], iy[j]); printf("closepath\n"); /* set color for fill (actually pattern) */ /* col is gray scale, 0 is black, 1 is white(==invisible) */ /* users idea of color is integer between 1 and 6 */ col = (float)(F77_COM(bgrp)[9]-1) / 6.0; col = col<0.0 ? -col : col; col = col>=1.0 ? .98 : col; printf("%f setgray\n", col); /* fill in polygon */ printf("fill\n"); /* reset color to black */ printf("0.0 setgray\n"); /* fill in polygon */ /* free up allocated space */ free(iy) ; free(ix) ; } SHAR_EOF fi if test -f 'print_prolog.c' then echo shar: "will not over-write existing file 'print_prolog.c'" else cat << \SHAR_EOF > 'print_prolog.c' #include <stdio.h> print_prolog() { fprintf(stdout, "/M {moveto} def\n") ; fprintf(stdout, "/L {lineto} def\n") ; fprintf(stdout, "/oldcex 1 def\n") ; fprintf(stdout, "/coffset 140 0.375 mul def\n") ; fprintf(stdout, "/Stext\n") ; fprintf(stdout, " { /pos exch def\n") ; fprintf(stdout, " /srot exch def\n") ; fprintf(stdout, " /cex exch def\n") ; fprintf(stdout, " /ypos exch def\n") ; fprintf(stdout, " /xpos exch def\n") ; fprintf(stdout, " /str exch def\n") ; fprintf(stdout, " \n") ; fprintf(stdout, " xpos ypos moveto\n") ; fprintf(stdout, " oldcex cex ne\n") ; fprintf(stdout, " { currentfont cex oldcex div scalefont setfont\n") ; fprintf(stdout, " /coffset coffset cex oldcex div mul store\n") ; fprintf(stdout, " /oldcex cex store\n") ; fprintf(stdout, " } if\n") ; fprintf(stdout, " gsave\n") ; fprintf(stdout, " srot rotate\n") ; fprintf(stdout, " str stringwidth pop neg\n") ; fprintf(stdout, " pos 0.5 eq\n") ; fprintf(stdout, " { 2 div }\n") ; fprintf(stdout, " { pos 0.5 lt\n") ; fprintf(stdout, " { pop 0 }\n") ; fprintf(stdout, " if }\n") ; fprintf(stdout, " ifelse\n") ; fprintf(stdout, " coffset neg rmoveto\n") ; fprintf(stdout, " str show\n") ; fprintf(stdout, " grestore\n") ; fprintf(stdout, " } store\n") ; fprintf(stdout, "/Schar\n") ; fprintf(stdout, " { /cex exch def\n") ; fprintf(stdout, " /str exch def\n") ; fprintf(stdout, " oldcex cex ne\n") ; fprintf(stdout, " { currentfont cex oldcex div scalefont setfont\n") ; fprintf(stdout, " /coffset coffset cex oldcex div mul store\n") ; fprintf(stdout, " /oldcex cex store\n") ; fprintf(stdout, " } if\n") ; fprintf(stdout, " str stringwidth pop neg 2 div coffset neg rmoveto\n") ; fprintf(stdout, " str show\n") ; fprintf(stdout, " } store\n") ; fprintf(stdout, "0.1 0.1 scale %% this version uses integer coordinates at 1/10's of a point\n") ; fprintf(stdout, "1 setlinecap 1 setlinejoin\n") ; fprintf(stdout, "/Helvetica findfont 140 scalefont setfont %% default font is 14 pt. Helvetica\n") ; fprintf(stdout, "/oldcex 1 def\n") ; fprintf(stdout, "/coffset 140 0.375 mul def\n") ; fprintf(stdout, "%% end of S header\n") ; } SHAR_EOF fi cd .. if test -f 'pscript.d' then echo shar: "will not over-write existing file 'pscript.d'" else cat << \SHAR_EOF > 'pscript.d' .BG .FN pscript .TL pscript: Device driver for PostScript\(tm printers .CS pscript(width, height, horizo) .PP .AG width Width of plotting region in inches - defaults to 10 if horizo=T, 8 otherwise. .AG height Height of plotting region in inches - defaults to 8 is horizo=T, 10 otherwise. .AG horizo If TRUE (the default), the x axis lies along the long side of the paper (a.k.a. "landscape" mode); if FALSE, the long side is vertical (a.k.a. "portrait" mode). (The width and height variables refer to the x and y axis directions, respectively.) .PP This function identifies the device driver which produces a file of commands in the PostScript\(tm language to produce the plots. This file is named "PostScript.out" and would usually be sent directly to the PostScript\(tm printer via a command such as .PP lpr -Pstat PostScript.out .PP Note that `pscript' appends to the file "PostScript.out" so it is a good idea to remove it after you have printed it. A device must be specified before any graphics functions can be used. .EX % S > pscript > plot(hstart) > q # exit from S % lpr -Pstat -r PostScript.out This last line is specific to Berkeley (BSD) Unix systems. The -Pstat means to send the file to the printer called "stat"; it must be a PostScript printer such as the Apple LaserWriter. You must exit S before printing the file; you cannot simply escape to the shell and print it because a trailer must be put at the end of the file to make it work. .KW graphics .WR SHAR_EOF fi if test -f 'pscript.i' then echo shar: "will not over-write existing file 'pscript.i'" else cat << \SHAR_EOF > 'pscript.i' # PostScript device driver function FUNCTION pscript( width /REAL,1,7.5/ height /REAL,1,10.0/ horizo /LGL,1,TRUE/ ) STATIC(logical streq) STRUCTURE(parms/REAL,3/) # w,h,vertical if(streq(TEXT(FNAME),TSTRING(pscripth))|| horizo){ horizo = TRUE if(MISSING(width)) width=10 else if (width > 11) FATAL(Width cannot exceed 11 inches) if(MISSING(height)) height=7.5 else if (height > 8.5) FATAL(Height cannot exceed 8.5 inches) } else { if (width > 8.5) FATAL(Width cannot exceed 8.5 inches) if (height > 11) FATAL(Height cannot exceed 11 inches) } parms[1] = width parms[2] = height if(horizo) parms[3]=1; else parms[3]=0 DEVICE_DRIVER RETURN(parms) END SHAR_EOF fi if test ! -d 'x' then mkdir 'x' fi cd 'x' cd .. if test ! -d '.help' then mkdir '.help' fi cd '.help' cd .. if test -f 'Smakefile' then echo shar: "will not over-write existing file 'Smakefile'" else cat << \SHAR_EOF > 'Smakefile' #Used by S MAKE utility DEST=.. all : pscript dev.pscript help help : cp pscript.d $(DEST)/.help/pscript clean : rm -f *.o i.*.C *.x rm -f pscriptsource/*.o virgin : clean rm -f pscript rm -fr sdata swork sdump sedit rm -f x/* i.pscript.C: ; echo 'INCLUDE(u/cinter)CINTER(pscript,-d)' >i.pscript.C pscript: i.pscript.o pscript.x # -d $(F77) $(LDFLAGS) $(STRIP) -o $(DEST)/x/pscript i.pscript.o pscript.x $(LIBR) @touch pscript @echo pscript loaded dev.pscript: cd pscriptsource; S COMPILEALL $(F77) $(LDFLAGS) $(STRIP) -o $(DEST)/x/dev.pscript $L/device.z $L/defer.z pscriptsource/*.o $(GRZLIB) @echo pscript driver loaded SHAR_EOF fi cd .. exit 0 # End of shell archive ----------------- Brian Keves ARPA: keves@sdcsvax.ucsd.edu P.O. Box 12238 UUCP: sdcsvax!keves La Jolla, CA 92037-0620 BITNET: keves@ucsd