[net.sources] Part 3 of 4 - PostScript programs

stephenf@elecvax.eecs.unsw.oz (Stephen Frede) (05/21/86)

# This is a set of programs which produce PostScript. Included are
# a back end for ditroff, a program which accepts plain text, and a
# program which accepts images.
# Also included are ditroff font width files and some miscellaneous
# PostScript scripts.
# For more details see the file READ_ME in the first part.
# There are 4 parts.
# Stephen Frede	University of New South Wales, Sydney, Australia
# 
# ACSnet:	stephenf@elecvax.oz	ARPA:	stephenf%elecvax.oz@seismo
# CSnet:	stephenf@elecvax.oz@csnet-relay.csnet
# UUCP:	{seimso,ubc-vision,ukc,mcvax,prlb2}!munnari!elecvax.oz!stephenf
# ------------------------------------------------------------------------

# This is a shell archive.  Remove anything before this line, then
# unpack it by saving it in a file and typing "sh file".  (Files
# unpacked will be owned by you and have default permissions.)
#
# This archive contains:
# src/opscript/Makefile src/opscript/ipscript.c src/opscript/lpscript.c src/pscript/READ_ME src/pscript/a4.ps src/pscript/big_greek.ps src/pscript/demo.ps src/pscript/floor.ps src/pscript/genftable.ps src/pscript/grid.ps src/pscript/inc.ps src/pscript/pages.ps src/pscript/papersize.ps src/pscript/pattern.ps src/pscript/setidle.sh src/pscript/setname.sh src/pscript/setpasswd.sh src/pscript/shadow.ps

echo x - src/opscript/Makefile
cat > "src/opscript/Makefile" << '//E*O*F src/opscript/Makefile//'
# SYS should be one of AUSAM, BSD, SYSV, V7
# This is only really important if VERBOSE (below) is 1.
SYS=SYSV
# VERBOSE should be 1 to generate postscript code to echo stuff
# back down the communication line. Otherwise 0.
VERBOSE=1
CFLAGS = -O -DALW -D$(SYS) -DVERBOSE=$(VERBOSE)
INSTALL = :
BINDIR=/bin
#I=/usr/include
I=/srce/include

all: lpscript ipscript


lpscript: $(BINDIR)/lpscript
$(BINDIR)/lpscript: lpscript.c $I/stdio.h $I/string.h pcom.c pscript.h
	$(CC) $(CFLAGS) -o lpscript lpscript.c pcom.c
	$(INSTALL) - lpscript bin 711 $(BINDIR)/lpscript

ipscript: $(BINDIR)/ipscript
$(BINDIR)/ipscript: ipscript.c $I/stdio.h pcom.c pscript.h
	$(CC) $(CFLAGS) -o ipscript ipscript.c pcom.c
	$(INSTALL) - ipscript bin 711 $(BINDIR)/ipscript

lint:	lint.ipscript lint.lpscript

lint.ipscript:
	lint -DALW -D$(SYS) ipscript.c pcom.c > ipscript.lint

lint.lpscript:
	lint -DALW -D$(SYS) lpscript.c pcom.c > lpscript.lint
//E*O*F src/opscript/Makefile//

echo x - src/opscript/ipscript.c
cat > "src/opscript/ipscript.c" << '//E*O*F src/opscript/ipscript.c//'
/*
 *	ipscript.c - version 3.2
 *
 *	Convert bitmap image to postscript
 *
 *		- Stephen Frede, UNSW, Australia (stephenf@elecvax.oz)
 *			...!seismo!munnari!elecvax!stephenf
 *		- fixes MWR, UNSW (michaelr@elecvax.oz)
 */

#ifndef	lint
static char id[] = "ipscript - version 3.2; UNSW, Australia";
#endif	lint

#include	<stdio.h>
#include	"pscript.h"

/* default values for the input bitmap data */
#define	N_SCANSPERIMAGE	256	/* no. scan lines */
#define	N_PIXELSPERSCAN	256	/* pixels per scanline */
#define	N_SCANRES	8	/* no. bits per pixel (input) */
#define	PAPERWIDTH	19.3	/* width (short axis) of paper (cm) */
#define	PAPERLENGTH	28.3	/* length (long axis) of paper (cm) */

/* possible input formats */
#define	I_BYTE		'b'
#define	I_HEX		'x'

#define	BITSINBYTE	8

int	ScansPerImage = N_SCANSPERIMAGE,	/* no. lines in image */
	PixelsPerScan = N_PIXELSPERSCAN,	/* no. pixels in each line */
	scanres = N_SCANRES,		/* input resolution (no. grey levels) */
	CellsPerInch = 60,		/* halftone cells/inch */
	outres = 8,			/* 2^outres output grey levels */
	CellRotation = 45,		/* halftone cell rotation */
	rotation = 0,			/* image rotation */
	headerskip = 0,			/* no. bytes to skip at start */
	greyoffset = 0,			/* brightness */
	PaperType =
#ifdef	ALW
		PT_A4,
#else
		PT_DEFAULT,
#endif	ALW
	inpformat = I_BYTE;		/* format of input data */
float	aspect = 1.5,		/* aspect ratio (x:y) */
	width = 0.0,		/* output width (cm) */
	height = 0.0;		/* output height (cm) */
bool	ManualFeed = FALSE,	/* manual or auto (paper tray) feed */
	NegativeImage = FALSE;	/* reverse black and white */

double	atof();

/* ARGSUSED */
main(argc, argv)
int	argc;
char	**argv;
{
	char	c;
	bool	filesgiven = FALSE,
		status = 0;

	postr = stdout;
	ScansPerImage = N_SCANSPERIMAGE;
	PixelsPerScan = N_PIXELSPERSCAN;
	argv++;		/* skip command name */

	while(*argv)
	{
		if(**argv == '-')
		{
			(*argv)++;	/* skip the '-' */
			c = **argv;	/* command arg */
			(*argv)++;	/* skip arg letter */
			switch(c)
			{
			case 'i':	/* input format */
				if(**argv == 'b')
					inpformat = I_BYTE;
				else if(**argv == 'x')
					inpformat = I_HEX;
				else
				{
					fprintf(stderr, "input format (-i option) only allows 'b' or 'x'\n");
					status++;
					break;
				}
				(*argv)++;
				if(**argv == '\0')
				{
					fprintf(stderr, "input format - expected scan resolution (bits) after `-%c'\n", (*argv)[-1]);
					status++;
					break;
				}
				scanres = atoi(*argv);
				if(scanres < 1 || scanres > 8)
				{
					fprintf(stderr, "input format: illegal scan resolution must be in range 1 - 8\n");
					status++;
				}
				break;

			case 's':
				headerskip = atoi(*argv);
				break;

			case 'g':	/* grey offset (brightness) */
				greyoffset = atoi(*argv);
				break;

			case 'b':	/* bits resolution out */
				outres=atoi(*argv);
				if(outres != 1 && outres != 2 &&
					outres != 4 && outres != 8)
				{
					fprintf(stderr,
						"Illegal output resolution - must be 1, 2, 4 or 8 bits\n");
					status++;
				}
				break;

			case 'y':	/* no. scan lines input */
				ScansPerImage=atoi(*argv);
				break;

			case 'x':	/* pixels per scanline */
				PixelsPerScan = atoi(*argv);
				break;

			case 'a':	/* aspect ratio */
				aspect = atof(*argv);
				break;

			case 'w':	/* width (cm) */
				width = atof(*argv);
				break;

			case 'h':	/* height (cm) */
				height = atof(*argv);
				break;

			case 'f':	/* output pixels/inch */
				CellsPerInch = atoi(*argv);
				break;

			case 'p':	/* pixel rotation */
				CellRotation = atoi(*argv);
				break;

			case 'r':	/* image rotation */
				if(**argv)
					rotation = atoi(*argv);
				else
					rotation = 90;
				break;

			case 'L':	/* 'legal' paper size */
				PaperType = PT_LEGAL;
				break;

			case 'n':	/* negative image */
				NegativeImage = TRUE;
				break;

			case 'S':	/* manual feed */
				ManualFeed = TRUE;
				break;

			default:
				fprintf(stderr, "Unknown option '%c'\n", c);
				status++;
			}
		}
		else
		{
			if(status)
				usage();
			filesgiven = TRUE;
			status += DoImage(*argv);
		}
		argv++;
	}
	if(status && ! filesgiven)
		usage();
	if(! filesgiven)
		status += DoImage("-");

	exit(status);
	/* NOTREACHED */
}

char	*usagetab[] = {
	"Usage: ipscript option file ...",
	"valid options:",
	"\t-r[angle]		output image rotation (degrees)",
	"\t-wWidth			output image width (in cm)",
	"\t-hHeight		output image height (in cm)",
	"\t-aAspect		aspect ratio (width/height)",
	"\t-yScanlines		no. scan lines in input",
	"\t-xScanlength		no. pixels in an input scan line",
	"\t-iFormat		input format: {'b'|'x'}bitsresolution",
	"\t-sSkip			no. bytes header to skip",
	"\t-gGrey			output grey level offset (signed)",
	"\t-bbits			output resolution = 2^bits greylevels",
	"\t-fFrequency		output frequency (pixels/inch)",
	"\t-pAngle			pixel grid rotation (degrees)",
	"\t-fFrequency		output frequency (dots/inch)",
	"\t-n			negative image",
	"\t-S			Use manual feed",
	(char *) 0
};

usage()
{
	char	**p;

	p = usagetab;
	while(*p)
		fprintf(stderr, "%s\n", *p++);
	exit(1);
	/* NOTREACHED */
}

/* postscript initialisation for options currently in effect
 * Assumes default LaserWriter conditions (ie start of job)
 */
init(filename, BytesPerScan)
char	*filename;
int	BytesPerScan;
{
	pcomminit(0.0, (float) rotation, PaperType, ManualFeed,
		"", filename, "ipscript bit image");
	fprintf(postr, "gsave %d %d translate\n", rotation == 0 ? 25 : 18,
						  rotation == 0 ? 0  : 5);

	if(height == 0.0 && width == 0.0)
		width = rotation == 0 ? PAPERWIDTH : PAPERLENGTH;
	if(height == 0.0)
		height = width / aspect;
	else if(width == 0.0)
		width = height * aspect;
	fprintf(postr, "%.1f %.1f scale\n", width * PU_CM, height * PU_CM);

	fprintf(postr, "0 setlinewidth\n");
	fprintf(postr, "/picstr %d string def\n", BytesPerScan);
	fprintf(postr, "/doimage {\n");
	fprintf(postr, "%d %d %d [ %d 0 0 %d 0 %d ]\n",
		PixelsPerScan, ScansPerImage, outres,
		PixelsPerScan, - ScansPerImage, ScansPerImage);
	fprintf(postr, "{ currentfile picstr readhexstring pop } image\n");
	fprintf(postr, "} def\n");
	if(CellsPerInch != PD_PFREQUENCY || CellRotation != PD_PROTATION)
		fprintf(postr, "%d %d {dup mul exch dup mul add 1 exch sub} setscreen\n", CellsPerInch, CellRotation);
	if(NegativeImage)
		fprintf(postr, "{1 exch sub} settransfer\n");
}

DoImage(filename)
char	*filename;
{
	register int	outval,
			PixelInByte,
			ByteInScan,
			PixelInScan,
			ScanInImage;
	int		div,
			inval,
			max;
	FILE		*istr;
	int		BytesPerScan;	/* no. bytes/scanline output */
	int		PixelsInByte;	/* no. pixels/byte output */
	bool		OutRange = FALSE;

	if(strcmp(filename, "-") == 0)
		istr = stdin;
	else if((istr = fopen(filename, "r")) == NULL)
	{
		perror(filename);
		return(1);
	}

	PixelsInByte = BITSINBYTE / outres;
	BytesPerScan = (PixelsPerScan + PixelsInByte - 1) / PixelsInByte;

	init(filename, BytesPerScan);
	max = 1 << scanres;
	div = scanres - outres;

	fprintf(postr, "%% Resolution: %d bits\n",
		outres);
	fprintf(postr, "(bit image start ...\\n) ps\n");
	fprintf(postr, "%%%%EndProlog\n");
	fprintf(postr, "%%%%Page 1 1\n");

	fprintf(postr, "doimage\n");

	for(ByteInScan = 0; ByteInScan < headerskip; ByteInScan++)
		getc(istr);

	for(ScanInImage = 0; ScanInImage < ScansPerImage; ScanInImage++)
	{
		for(ByteInScan = 0, PixelInScan = 0;
			ByteInScan < BytesPerScan; ByteInScan++)
		{
			outval = 0;
			/* build up an output byte */
			for(PixelInByte = 0;
				PixelInByte < PixelsInByte && PixelInScan < PixelsPerScan;
				PixelInByte++, PixelInScan++)
			{
				if(inpformat == I_BYTE)
					inval = getc(istr);
				else
				{	/* I_HEX */
					if(scanres <= 4)
						fscanf(istr, "%1X", &inval);
					else
						fscanf(istr, "%2X", &inval);
				}
				if(feof(istr))
				{
					fprintf(stderr, "Error: insufficient input\n");
					return(1);
				}
				if(greyoffset)
				inval += greyoffset;
				if(inval < 0)
				{
					inval = 0;
					OutRange = TRUE;
				}
				else if(inval >= max)
				{
					inval = max-1;
					OutRange = TRUE;
				}
				if(div >= 0)
					outval = (outval << outres) | (inval >> div);
				else
					outval = (outval << outres) | (inval << -div);
			}
			/* make up a whole byte at the end of a scan line */
			for(; PixelInByte < PixelsInByte; PixelInByte++)
				outval = outval << outres;
			/* do a little bit of formatting to make it readable */
			if(ByteInScan % 10 == 0)
				if(ByteInScan % 30 == 0) putc('\n', postr);
				else putc(' ', postr);
			fprintf(postr, "%X%X", outval >> 4, outval & 017);
		}
		/* end of a scan line */
		fprintf(postr, "\n");
	}

	/* draw a border around the picture */
	if(NegativeImage)
		fprintf(postr, "{} settransfer\n");	/* restore transfer func */
	fprintf(postr,
		"newpath 0 0 moveto 1 0 lineto 1 1 lineto 0 1 lineto closepath stroke\n");

	fprintf(postr, "\ngrestore\nshowpage\n");
	pcommfinish(-1, "");
	if(getc(istr) != EOF)
		fprintf(stderr,
			"Warning: input data after end of image\n");
	if(OutRange)
		fprintf(stderr,
			"Warning: input greyscale range too large - change 'i' or 'g' options\n");
	return(0);
}
//E*O*F src/opscript/ipscript.c//

echo x - src/opscript/lpscript.c
cat > "src/opscript/lpscript.c" << '//E*O*F src/opscript/lpscript.c//'
/*
 *	lpscript - version 3.1
 *
 *	Convert plain text to postscript
 *
 *		- Stephen Frede, UNSW, Australia (stephenf@elecvax.oz)
 *			...!seismo!munnari!elecvax!stephenf
 */

#ifndef	lint
static char id[] = "lpscript - version 3.1; Stephen Frede, UNSW, Australia";
#endif	lint

#include	<stdio.h>
#include	"pscript.h"

#define	PAGEOFFSET	(1.0*PU_CM)
#define	FONTSIZE	10.0		/* default font size (in points) */
#define	TABSIZE		8
#define	FONT		"Courier"
#define	DOUBLESPACE	1.8		/* line spacing for double spacing */


char	usage[] = "Valid lpscript options:\n\t-o[offset]\n\t-r[rotation]\n\
\t-s[fontsize]\n\t-a[fontaspect]\n\t-p[pitch]\n\t-f[font]\n\t-t[tabsize]\n\
\t-h[horizontal_spacing]\n\t[-S]\t(manual feed)\n\t[-L]\t(legal paper type)\n";
int	tabsize = TABSIZE;		/* in character positions */

double	atof();

/* ARGSUSED */
main(argc, argv)
int	argc;
char	**argv;
{
	int	status = 0;	/* exit status (no. errors occured) */
	float	pageoffset = 18.0,
		fontsize = FONTSIZE,
		aspect = 1.0,
		linepitch = 0,
		spacing = 0.0,
		rotation = PD_ROTATION;
	char	*fontname = FONT;
	FILE	*istr;
	bool	manualfeed = FALSE,
		doublespace = FALSE;
	int	pagetype	=
#ifdef	ALW
				PT_A4;
#else	ALW
				PT_DEFAULT;
#endif	ALW

	postr = stdout;
	argv++;		/* skip program name */
	while(*argv && **argv == '-')
	{
		char	c;

		(*argv)++;	/* skip the '-' */
		c = **argv;	/* option letter */
		(*argv)++;	/* skip option letter */
		switch(c)
		{
			case 'o':	/* offset */
				if(**argv == '\0')
					pageoffset = PAGEOFFSET;
				else
					pageoffset = atof(*argv) * PU_CM;
				break;

			case 'r':	/* rotation */
				if(**argv == '\0')
					rotation = 90.0;
				else
					rotation = atof(*argv);
				break;

			case 'p':	/* pitch (line spacing) */
				if(**argv == '\0')
					doublespace = TRUE;
				else
					linepitch = atof(*argv);
				break;

			case 's':	/* font size */
				if(**argv == '\0')
					fontsize = 12.0;
				else
					fontsize = atof(*argv);
				break;

			case 't':	/* tab size */
				if(**argv == '\0')
					tabsize = 4;
				else
					tabsize = (int) atof(*argv);
				break;

			case 'f':	/* font */
				if(**argv == '\0')
					fontname = "Times-Roman";
				else
					fontname = *argv;
				break;

			case 'h':	/* horizontal spacing */
				if(**argv == '\0')
					spacing = 0.25;
				else
					spacing = atof(*argv);
				break;

			case 'a':	/* character aspect ratio */
				if(**argv == '\0')
					aspect = 1.0;
				else
					aspect = atof(*argv);
				break;

			case 'S':	/* manual feed */
				manualfeed = TRUE;
				break;

			case 'L':	/* legal paper type */
				pagetype = PT_LEGAL;
				break;

			default:
				fprintf(stderr, "Unknown option: '%c'\n", c);
				status++;
				break;
		}
		argv++;
	}
	if(status)
	{
		fprintf(stderr, usage);
		exit(status);
		/* NOTREACHED */
	}
	if(doublespace)
		linepitch = fontsize * DOUBLESPACE;
	if(linepitch == 0)
		linepitch = fontsize;
	spacing *= fontsize;
	init(fontsize, aspect, pageoffset, linepitch, rotation, fontname,
		spacing, manualfeed, pagetype);
	if(! *argv)
	{
		fprintf(postr, "(stdin ...\\n) ps\n");
		process(stdin);
	}
	else while(*argv)
	{
		if((istr = fopen(*argv, "r")) == NULL)
		{
			perror(*argv);
			status++;
		}
		else
		{
			fprintf(postr, "('%s' ...\\n) ps\n", *argv);
			process(istr);
			fclose(istr);
		}
		argv++;
	}
	pcommfinish(-1, (char *)0);
	putc('\004', postr);
	exit(status);
	/* NOTREACHED */
}

process(istr)
FILE	*istr;
{
	register int	ch;
	register int	x;	/* used for tab calculations */
	register int	prefix;

	x = 0;
	prefix = 0;
	while((ch=getc(istr)) != EOF)
	{
		if(!prefix)
		{
			putc('(', postr);
			prefix = 1;
		}
		if(ch < ' ' && ch != '\t' && ch != '\n' && ch != '\r' && ch != '\f')
			ch = '?';
		switch(ch)
		{	
		case '\t':
			{
			int	n = x + tabsize - (x % tabsize);

			while(x < n)
				pch(' '), x++;
			}
			break;	
		case '\n':
			x = 0;
			fprintf(postr, ")n\n");
			prefix = 0;
			break;
		case '\r':
			x = 0;
			fprintf(postr, ")r\n");
			prefix = 0;
			break;
		case '\f':
			x = 0;
			fprintf(postr, ")n dpage\n");
			prefix = 0;
			break;
		default:
			pch(ch);
			x++;
		}
	}
	if(prefix)
		fprintf(postr, ")n\n");
	fprintf(postr, "dpage ( ---\\n) ps\n");
}

char	*inittab[] = {
	/* current y coord */
	"/y { currentpoint exch pop } def",

	/* var to prevent trailing blank page */
	"/dopage false def",

	/* print a new page */
	"/dpage { dopage { page /dopage false def } if } def",

	/* print a line then move to the next */
	"/n",
	"{ spacing 0 3 -1 roll ashow",
	"  0 y linepitch add moveto",
	"  /dopage true def",
	"  y pgbot lt { dpage } if",
	"} def",

	/* print a line - then return to start */
	"/r",
	"{ spacing 0 3 -1 roll ashow",
	"  0 y moveto",
	"  /dopage true def",
	"} def",

	(char *)0 };

init(fontsize, aspect, pageoffset, linepitch, rotation, fontname,
	spacing, manualfeed, pagetype)
float	fontsize,
	aspect,
	pageoffset,
	linepitch,
	spacing,
	rotation;
char	*fontname;
bool	manualfeed;
int	pagetype;
{
	register char	**p;

	pcomminit(0.0, rotation, pagetype, manualfeed,
			fontname, (char *)0, "lpscript");
	p = inittab;
	while(*p)
		fprintf(postr, "%s\n", *p++);
	fprintf(postr, "/%s findfont [ %.1f 0 0 %.1f 0 0 ] makefont setfont\n",
		fontname, fontsize, fontsize * aspect);
	fprintf(postr, "/linepitch %.1f def\n", -linepitch);
	fprintf(postr, "/spacing %.1f def\n", spacing);
	/* subtract linespacing (add -'ve) to get top text baseline */
	fprintf(postr, "/pgtop pgtop linepitch add def\n");
	/* calculate bottom text baseline */
	fprintf(postr, "/pgbot currentfont /FontBBox get 1 get neg 1000 div %.1f mul def\n", fontsize * aspect);
	/* apply horizontal offset, if any */
	fprintf(postr, "%.1f 0 translate\n", pageoffset);

	/* save state */
	endinit();
}
//E*O*F src/opscript/lpscript.c//

echo x - src/pscript/READ_ME
cat > "src/pscript/READ_ME" << '//E*O*F src/pscript/READ_ME//'
This directory contains various PostScript scripts.
//E*O*F src/pscript/READ_ME//

echo x - src/pscript/a4.ps
cat > "src/pscript/a4.ps" << '//E*O*F src/pscript/a4.ps//'
/a4
	[
		[ 300 72 div 0 0 -300 72 div -72 3436 ]
		292 3365
		{statusdict /jobstate (printing) put 0 setblink
		margins exch 142 add exch 256 add 8 div round cvi frametoroket
		statusdict /jobstate (busy) put
		1 setblink }
		/framedevice load
		60 45 {dup mul exch dup mul add 1.0 exch sub } /setscreen load
		{} /settransfer load
		/initgraphics load
		/erasepage load
	] cvx
statusdict begin bind end readonly def
//E*O*F src/pscript/a4.ps//

echo x - src/pscript/big_greek.ps
cat > "src/pscript/big_greek.ps" << '//E*O*F src/pscript/big_greek.ps//'
%!
% Print big greek characters

/makeoutlinedict 5 dict def
makeoutlinedict begin
/basefontdict /Symbol findfont def
/outfontdict basefontdict maxlength 1 add dict def
basefontdict
{
	exch dup /FID ne
	{ exch outfontdict 3 1 roll put }
	{ pop pop }
	ifelse
} forall
outfontdict /FontName /Sym_Out put
outfontdict /PaintType 2 put
outfontdict /StrokeWidth 3 put
/Sym_Out outfontdict definefont pop end

/Sym_Out findfont 650 scalefont setfont
/p { 10 200 moveto show showpage } def

% now this is silly
(a) p
(b) p
(c) p
(d) p
(e) p
(f) p
(g) p
(h) p
(i) p
(j) p
(k) p
(l) p
(m) p
(n) p
(o) p
(p) p
(q) p
(r) p
(s) p
(t) p
(u) p
(v) p
(w) p
(x) p
(y) p
(z) p
() p
(A) p
(B) p
(C) p
(D) p
(E) p
(F) p
(G) p
(H) p
(I) p
(J) p
(K) p
(L) p
(M) p
(N) p
(O) p
(P) p
(Q) p
(R) p
(S) p
(T) p
(U) p
(V) p
(W) p
(X) p
(Y) p
(Z) p
//E*O*F src/pscript/big_greek.ps//

echo x - src/pscript/demo.ps
cat > "src/pscript/demo.ps" << '//E*O*F src/pscript/demo.ps//'
%!
% a demo of lots of nifty things you can do on a LaserWriter
% - Stephen Frede

(demo starting) print flush
/cm { 28.3465 mul } def
/ps { print flush } def

clippath pathbbox pop pop translate 10 10 translate
clippath pathbbox /pgtop exch def /pgright exch def pop pop


% greyscale

/width 1 cm def
/step 0.5 cm def
/greyscale {
	/left exch def
	0 step pgtop
	{
		/val exch def
		val pgtop div setgray
		newpath
		% draw a box
		left val moveto
		width 0 rlineto
		0 step rlineto
		0 width sub 0 rlineto
		closepath
		fill
	} for
	0 setgray
} def

0 greyscale

60 15 { dup mul exch dup mul add 1 exch sub } setscreen
1.5 cm greyscale
100 45 { dup mul exch dup mul add 1 exch sub } setscreen
3 cm greyscale
10 45 { dup mul exch dup mul add 1.0 exch sub } setscreen
4.5 cm greyscale
60 45 { dup mul exch dup mul add 1 exch sub } setscreen


6 cm 0 translate

% available fonts

/x 1 cm def /y pgtop 1 cm sub def
/s { show /y y 20 sub def } def
/m { x y moveto } def
/f { findfont 15 scalefont setfont } def
/fm { f m } def
/Times-Roman fm (Times Roman (R)) s
/Times-Bold fm (Times Bold (B)) s
/Times-Italic fm (Times Italic (I)) s
/Times-BoldItalic fm (Times Bold Italic (BI)) s
/Helvetica fm (Helvetica (H)) s
/Helvetica-Bold fm (Helvetica Bold (HB)) s
/Helvetica-Oblique fm (Helvetica Oblique (HO)) s
/Helvetica-BoldOblique fm (Helvetica Bold Oblique (HX)) s
/Courier fm (Courier (C)) s
/Courier-Bold fm (Courier Bold (CB)) s
/Courier-Oblique fm (Courier Oblique (CO)) s
/Courier-BoldOblique fm (Courier Bold Oblique (CX)) s
/Symbol fm (abcdefg ABCDEFG ) show /Times-Roman f ((S)) s

% sizes

x 10 moveto
/currfont /Helvetica findfont def
/r { /txt exch def currfont exch scalefont setfont txt show } def

3 (A) r
4 (B) r
6 (C) r
8 (D) r
10 (E) r
15 (F) r
20 (G) r
30 (H) r
50 (I) r
70 (J) r

% white on black

20 0 rmoveto
currentpoint pop /x exch def
x 0 moveto
0 80 rlineto x 0 rlineto 0 -80 rlineto closepath fill
/currfont /Times-Bold findfont def
1 setgray
x 10 moveto
70 (K) r
50 (L) r
30 (M) r
20 (N) r
15 (O) r
10 (P) r
8 (Q) r
6 (R) r
4 (S) r
3 (T) r

0 setgray

% shadow

/shadow
{
	/text exch def
	1 -0.1 -0.1
	{
		setgray -0.7 0.7 rmoveto
		currentpoint text show moveto
	} for
	0 setgray
} def

/Times-Roman findfont 30 scalefont setfont
7 cm 26 cm moveto
(Shadow) shadow

gsave
/Times-Italic findfont 30 scalefont setfont
/printzip
{ 0 0 moveto (Zip) show } def
12 cm 26 cm translate
.95 -.05 0 { setgray printzip -1 .5 translate} for
1 setgray printzip
grestore

% outline
8 cm 25 cm moveto

/makeoutlinedict 5 dict def
makeoutlinedict begin
/basefontdict /Times-Roman findfont def
/outfontdict basefontdict maxlength 1 add dict def
basefontdict
{
	exch dup /FID ne
	{ exch outfontdict 3 1 roll put }
	{ pop pop }
	ifelse
} forall
outfontdict /FontName /Times_Out put
outfontdict /PaintType 2 put
outfontdict /StrokeWidth 3 put
/Times_Out outfontdict definefont pop end
/Times_Out findfont 30 scalefont setfont

(Outline) show

% ellipse

/ellipsedict 8 dict def ellipsedict /mtrx matrix put
/ellipse {
	ellipsedict begin
	/yrad exch def /xrad exch def /y exch def /x exch def
	/savematrix mtrx currentmatrix def
	x y translate xrad yrad scale
	newpath 0 0 1 0 360 arc
	savematrix setmatrix
	end
} def

% Star Lines

/Times-BoldItalic findfont 27 scalefont setfont
/rays {
	0 1.5 179
	{ gsave
		rotate 0 0 moveto 108 0 lineto stroke grestore
	} for
} def

gsave
10 cm 15 cm moveto
(StarLines) true charpath clip
newpath 54 -15 translate rays
grestore

% circle laser
/Helvetica-Bold findfont 30 scalefont setfont
/oshow	% stack: (string)
{ true charpath stroke } def
/circleofAdobe
{
	15 15 345
	{
		gsave rotate 0 0 moveto (Adobe) oshow grestore
	} for
} def
gsave
4 cm 10 cm translate
0.5 setlinewidth
circleofAdobe
0 0 moveto (Adobe Systems) true charpath gsave 1 setgray fill grestore stroke
grestore

% star lines
/Times-BoldItalic findfont 2 cm scalefont setfont
/rays
  { 0 1.5 179
    { gsave rotate 0 0 moveto 5 cm 0 lineto stroke grestore } for
} def
gsave
1 cm 3.5 cm translate
.25 setlinewidth
newpath 0 0 moveto (StarLines) true charpath clip
newpath 3.9 cm -0.5 cm translate rays
grestore


% pattern

/bitison
{
	/ybit exch def /xbit exch def
	bstring ybit bwidth mul
	xbit 8 idiv add get
	1 7 xbit 8 mod sub bitshift
	and 0 ne
} def

/setpattern
{
	/freq exch def
	/bwidth exch def
	/bpside exch def
	/bstring exch def
	/onbits 0 def /offbits 0 def
	freq 0 {
		/y exch def /x exch def
		/xindex x 1 add 2 div bpside mul cvi def
		/yindex y 1 add 2 div bpside mul cvi def
		xindex yindex bitison
		{ /onbits onbits 1 add def 1 }
		{ /offbits offbits 1 add def 0 }
		ifelse
		} setscreen
	{} settransfer
	offbits offbits onbits add div setgray
} def

<d1e3c5885c3e1d88> 8 1 300 32 div setpattern

5 cm 15 cm 4 cm 1.5 cm ellipse fill

<3e418080e3140808> 8 1 300 32 div setpattern

12 cm 22 cm moveto 14 cm 1 cm -6 cm rlineto -2 cm 0 rlineto closepath fill

3 { copypage } repeat erasepage

(demo finished) print flush


% ---- %

??
//E*O*F src/pscript/demo.ps//

echo x - src/pscript/floor.ps
cat > "src/pscript/floor.ps" << '//E*O*F src/pscript/floor.ps//'
%!
% Machine room floorplan at UNSW
% 1 grid square is a floor tile on the false floor

(floor starts\n) print flush
/a4
	[
		[ 300 72 div 0 0 -300 72 div -72 3436 ]
		292 3365
		{statusdict /jobstate (printing) put 0 setblink
		margins exch 142 add exch 256 add 8 div round cvi frametoroket
		statusdict /jobstate (busy) put
		1 setblink }
		/framedevice load
		60 45 {dup mul exch dup mul add 1.0 exch sub } /setscreen load
		{} /settransfer load
		/initgraphics load
		/erasepage load
	] cvx
statusdict begin bind end readonly def

a4

/metre { 0.608 div } def
/neg { 0 exch sub } def

clippath pathbbox pop pop translate newpath
clippath pathbbox newpath /ymax exch def /xmax exch def pop pop
/xlen 14 def
/ylen 30.5 def

ymax ylen 1 add div dup scale
2 setlinecap
0.01 setlinewidth
/boxfill 0.99 def	% 0 for black, 1 for white, in-between for grey
/textsize 0.2 def
/x0 0.5 def /y0 0.5 def
/xmax x0 xlen add def /ymax y0 ylen add def
/Times-Roman findfont textsize scalefont setfont

/xline { currentpoint xlen 0 rlineto stroke moveto } def
/yline { currentpoint 0 ylen rlineto stroke moveto } def
/doorwid 0.71 metre def

/room
{
	% label x axis
	1 1 14 {
		/x exch def
		x 0.05 sub 0.1 moveto x 2 string cvs show
		x 0.05 sub ymax 0.2 add moveto x 2 string cvs show
	} for
	% label y axis
	1 1 30 {
		/y exch def
		0.1 y 0.05 sub moveto y 2 string cvs show
		xmax 0.2 add y 0.05 sub moveto y 2 string cvs show
	} for
	% doors
	[ 0.1 0.1 ] 0 setdash
	xmax 13.1 moveto currentpoint doorwid 90 180 arc closepath stroke
	xmax 15.4 moveto currentpoint doorwid 180 270 arc closepath stroke
	xmax 22.6 moveto currentpoint doorwid 0 90 arc closepath stroke
	xmax 24.9 moveto currentpoint doorwid 270 360 arc closepath stroke
	[ ] 0 setdash
	% room boundary
	0.5 2 moveto
	5.6 2 lineto
	5.6 0.5 lineto
	xmax 0.5 lineto
	xmax ymax lineto
	1 ymax lineto 0 -0.5 rlineto -0.5 0 rlineto
	x0 21.1 lineto 0.5 0 rlineto 0 -0.7 rlineto -0.5 0 rlineto
	x0 12.3 lineto 0.5 0 rlineto 0 -2 rlineto -0.5 0 rlineto
	closepath
	gsave 0.1 setlinewidth stroke grestore
	clip
} def

/grid
{
	gsave 0.01 setlinewidth
	1 y0 moveto
	14 { yline 1 0 rmoveto } repeat
	x0 1 moveto
	30 { xline 0 1 rmoveto } repeat
} def

% arguments to box: rotation xpos ypos xlen ylen name
/box
{
	/name exch def
	/y exch def
	/x exch def
	gsave
	translate
	rotate
	newpath
	0 0 moveto
	x 0 lineto x y lineto 0 y lineto closepath
	% comment out next line to avoid filling boxes
	gsave boxfill setgray fill grestore % fill the box
	stroke	% draw outline
	name stringwidth y exch sub 2 div 0.05 sub /y exch def
		x exch sub 2 div y moveto
		name show
	grestore
} def

/power1x10	% single 10-amp single phase
{
	/name exch def
	/l 0.2 def
	gsave translate
	0 l moveto
	0 0 moveto 0 l lineto l l lineto l 0 lineto closepath stroke
} def

% arguments to furniture are:
% rotation xpos ypos
% (rotation 0 == front facing window; pos is front left corner)
/compactus { 5.3 1.5 (compactus) box } def
/modem { 1 1 (modem) box } def
/mss { 2 1 (MSS) box } def
/poweroutlet { /n exch def 0.3 0.2 n box } def
/vax750 { 1.3 1.3 (750) box } def
/karri { 2.2 1.3 (karri) box } def
/cdc { 1 1.5 (cdc) box } def
/rp04 { 1.3 1.3 (rp04) box } def
/elecvax { 5.3 1.3 (elecvax) box } def
/rp06 { 1.3 1.3 (rp06) box } def
/cheops { 1 1.8 (cheops) box } def
/rackwidth 0.9 def
/rackdepth 1.2 def
/rack { rackwidth rackdepth } def
/elec35 { rack (35) box } def
/dsl { rack (dsl) box } def
/rk07 { 0.9 1.2 (rk07) box } def
/cadvax { 4.2 1.3 (cadvax) box } def
/pdp { rackwidth 3 mul rackdepth 3 -1 roll box } def
/elec70a { (70a) pdp } def
/elec70b { (70b) pdp } def

% fixed power conduits
/fixedconduit
{
	6.09 30.1 moveto 10 { 0 -8 rlineto 0.09 8 rmoveto } repeat stroke
} def

/fixedoutlets
{
	0 4.3 16.3 (2) poweroutlet
} def

room grid
% fixed items
0 1 30.7 2 0.3 (power) box
-90 14.3 20.5 0.6 0.15 (telecom) box
-90 14.3 10.2 0.6 0.15 (thermo) box
0 9.5 29.6 modem
0 11.5 30 mss
90 2 3 compactus
% fixedoutlets
% movable items
90 5 4 rp04 90 5 5.3 rp04
90 5 7 cdc
90 5 9.4 elecvax
90 5 16.1 rp06 90 5 17.4 rp06 90 5 18.7 rp06
90 5 21 cheops
90 5 23.05 elec35
90 5 25.05 dsl
90 5 26 rk07 90 5 26.9 rk07 90 5 27.8 rk07 90 5 28.7 rk07
0 6.4 27 rp06 0 7.7 27 rp06
0 6.8 24 karri
-90 11 27.6 rp06 -90 11 26.3 rp06
-90 11 23.1 cadvax
-90 11 18 cdc
-90 11 17 rk07
-90 11 12 elec70b
-90 11 9.3 elec70a

(floor finished\n) print flush
4 { copypage } repeat
showpage
//E*O*F src/pscript/floor.ps//

echo x - src/pscript/genftable.ps
cat > "src/pscript/genftable.ps" << '//E*O*F src/pscript/genftable.ps//'
%!
% genftable - Postcript program to produce font tables for ditroff.
%	      Tables are output on the standard output file - which
%	      needs to be captured by the host computer.
%
%	      Note the routine "commondefs" which outputs local
%	      defined (hand built) characters.
%
% Michael Rourke, University of N.S.W., Australia
%

/t 30 string def

/ps
% string ->
{
	print
} def

/pr
% any -->
{
	t cvs ps
} def

/prsp
{
	(\t) ps
} def

/prnl
{
	(\n) ps
} def

/pro
% int -->
{
	dup 0 eq
	{ pr }
	{ dup 8 idiv pro 8 mod pr }
	ifelse
} def

/charsize
% string --> bot top
{
	gsave
	newpath 0 0 moveto false charpath flattenpath pathbbox
	exch pop 3 -1 roll pop
	grestore
} def

/strwidth
% string --> width
{
	stringwidth pop round cvi
} def

/prsize
% string -->
{
	dup strwidth pr prsp
	dup charsize
	top gt { 2 } { 0 } ifelse
	exch bot lt { 1 or } if
	pr prsp
	0 get pro 
} def

/fontinfo
% fontname troffinternal troffname
{
	(\ncat <<"!" > ) ps dup pr prnl
	(# ) ps 2 index pr prnl
	(name ) ps pr prnl
	(internalname ) ps pr prnl
	dup findfont 100 scalefont setfont
	/fixedwidth false def
	/Symbol eq
	{
		/actions symbol-encoding def
		(special\n) ps
	}
	{
		/actions standard-encoding def
		currentfont /FontInfo get /isFixedPitch get
		{
			(# fixed width\n) ps
			/fixedwidth true def
		}
		{
			(ligatures fi fl ff ffi ffl 0\n) ps
		}
		ifelse
	}
	ifelse
	% use "o" to get top and bottom on a normal char
	(o) charsize /top exch def /bot exch def
	% some non ascending chars slightly higher than "o"
	% and some lower so adjust slightly
	/top top 2 add def
	/bot bot 4 sub def
	/encoding currentfont /Encoding get def
	/s 1 string def
	0 1 255
	{
		s 0 2 index put
		encoding exch get dup /.notdef ne
		{
			s 1 index actions exch get
			% charname charstr
			exec
			flush
		}
		{
			pop
		}		
		ifelse
	} for
	actions standard-encoding eq { commondefs } if
	(!\n) ps flush
} def

/commondefs
{
	/fracsize (0) strwidth (\244) strwidth add def		% \244 = '/'
	/Fisize (f) strwidth (\256) strwidth add 5 sub def	% \256 = 'fi'
	/ffsize (f) strwidth 2 mul 5 sub def
	/fl { flush } def
	fixedwidth not
	{
		(ff) ps prsp ffsize pr (\t2\t0100\tff ligature - faked\n) ps fl
		(Fi) ps prsp Fisize pr (\t2\t0100\tffi ligature - faked\n) ps fl
		(Fl) ps prsp Fisize pr (\t2\t0100\tffl ligature - faked\n) ps fl
	} if
	(12) ps prsp fracsize pr (\t2\t0100\t1/2 - faked\n) ps fl
	(13) ps prsp fracsize pr (\t2\t0100\t1/3 - faked\n) ps fl
	(14) ps prsp fracsize pr (\t2\t0100\t1/4 - faked\n) ps fl
	(18) ps prsp fracsize pr (\t2\t0100\t1/8 - faked\n) ps fl
	(23) ps prsp fracsize pr (\t2\t0100\t2/3 - faked\n) ps fl
	(34) ps prsp fracsize pr (\t2\t0100\t3/4 - faked\n) ps fl
	(38) ps prsp fracsize pr (\t2\t0100\t3/8 - faked\n) ps fl
	(58) ps prsp fracsize pr (\t2\t0100\t5/8 - faked\n) ps fl
	(78) ps prsp fracsize pr (\t2\t0100\t7/8 - faked\n) ps fl
	(sq\t100\t3\t0100\tsquare box - faked\n) ps fl
} def

/space
% charname charstr -->
{
	(spacewidth ) ps
	strwidth pr pop prnl
	(charset\n) ps
} def

/norm
% charname charstr -->
{
	dup pr prsp prsize pop prnl
} def

/normdup
% charname charstr dupname -->
{
	3 1 roll norm
	pr prsp (") ps prnl
} def

/gnorm
% charname charstr -->
{
	(*) ps norm
} def

/map
% charname charstr mapname -->
{
	pr prsp prsize prsp pr prnl
} def

/mapdup
% charname charstr mapname dupname -->
{
	4 1 roll map
	pr prsp (") ps prnl
} def

/mapdupdup
% charname charstr mapname dupname dupname -->
{
	5 1 roll mapdup
	pr prsp (") ps prnl
} def

/cmap
% charname charstr mapname -->
{
	fixedwidth { 3 { pop } repeat } { map } ifelse
} def

/standard-encoding 149 dict def
standard-encoding begin
	/space		{ space }		def
	/exclam		{ norm }		def
	/quotedbl	{ norm }		def
	/numbersign	{ norm }		def
	/dollar		{ norm }		def
	/percent	{ norm }		def
	/ampersand	{ norm }		def
	/quoteright	{ norm }		def
	/parenleft	{ norm }		def
	/parenright	{ norm }		def
	/asterisk	{ norm }		def
	/plus		{ norm }		def
	/comma		{ norm }		def
	/hyphen		{ (hy) normdup }	def
	/period		{ norm }		def
	/slash		{ (sl) dup }		def
	/zero		{ norm }		def
	/one		{ norm }		def
	/two		{ norm }		def
	/three		{ norm }		def
	/four		{ norm }		def
	/five		{ norm }		def
	/six		{ norm }		def
	/seven		{ norm }		def
	/eight		{ norm }		def
	/nine		{ norm }		def
	/colon		{ norm }		def
	/semicolon	{ norm }		def
	/less		{ norm }		def
	/equal		{ norm }		def
	/greater	{ norm }		def
	/question	{ norm }		def
	/at		{ norm }		def
	/A		{ norm }		def
	/B		{ norm }		def
	/C		{ norm }		def
	/D		{ norm }		def
	/E		{ norm }		def
	/F		{ norm }		def
	/G		{ norm }		def
	/H		{ norm }		def
	/I		{ norm }		def
	/J		{ norm }		def
	/K		{ norm }		def
	/L		{ norm }		def
	/M		{ norm }		def
	/N		{ norm }		def
	/O		{ norm }		def
	/P		{ norm }		def
	/Q		{ norm }		def
	/R		{ norm }		def
	/S		{ norm }		def
	/T		{ norm }		def
	/U		{ norm }		def
	/V		{ norm }		def
	/W		{ norm }		def
	/X		{ norm }		def
	/Y		{ norm }		def
	/Z		{ norm }		def
	/bracketleft	{ norm }		def
	/backslash	{ norm }		def
	/bracketright	{ norm }		def
	/asciicircum	{ (a^) map }		def
	/underscore	{ (ru) normdup }	def
	/quoteleft	{ norm }		def
	/a		{ norm }		def
	/b		{ norm }		def
	/c		{ norm }		def
	/d		{ norm }		def
	/e		{ norm }		def
	/f		{ norm }		def
	/g		{ norm }		def
	/h		{ norm }		def
	/i		{ norm }		def
	/j		{ norm }		def
	/k		{ norm }		def
	/l		{ norm }		def
	/m		{ norm }		def
	/n		{ norm }		def
	/o		{ norm }		def
	/p		{ norm }		def
	/q		{ norm }		def
	/r		{ norm }		def
	/s		{ norm }		def
	/t		{ norm }		def
	/u		{ norm }		def
	/v		{ norm }		def
	/w		{ norm }		def
	/x		{ norm }		def
	/y		{ norm }		def
	/z		{ norm }		def
	/braceleft	{ norm }		def
	/bar		{ norm }		def
	/braceright	{ norm }		def
	/asciitilde	{ (a~) map }		def
	/exclamdown	{ (I!) map }		def
	/cent		{ (ct) map }		def
	/sterling	{ (po) map }		def
	/fraction	{ }			def
	/yen		{ ($J) map }		def
	/florin		{ }			def
	/section	{ (sc) map }		def
	/currency	{ }			def
	/quotesingle	{ (fm) (n') mapdup }	def
	/quotedblleft	{ (lq) map }		def
	/guillemotleft	{ (d<) map }		def
	/guilsinglleft	{ (l<) map }		def
	/guilsinglright	{ (r>) map }		def
	/fi		{ (fi) cmap }		def
	/fl		{ (fl) cmap }		def
	/endash		{ (\\-) map }		def
	/dagger		{ (dg) map }		def
	/daggerdbl	{ (dd) map }		def
	/periodcentered	{ }			def
	/paragraph	{ (pp) map }		def
	/bullet		{ (bu) map }		def
	/quotesinglbase	{ } 			def
	/quotedblbase	{ }			def
	/quotedblright	{ (rq) map }		def
	/guillemotright	{ (d>) map }		def
	/ellipsis	{ }			def
	/perthousand	{ (pm) cmap }		def
	/questiondown	{ (I?) map }		def
	/grave		{ (ga) (\\`) mapdup }	def
	/acute		{ (aa) (\\') mapdup }	def
	/circumflex	{ (^) map }		def
	/tilde		{ (~) map }		def
	/macron		{ (ma) map }		def
	/breve		{ (be) map }		def
	/dotaccent	{ (dt) map }		def
	/dieresis	{ (..) (um) mapdup }	def
	/ring		{ (ri) map }		def
	/cedilla	{ (cd) map }		def
	/hungarumlaut	{ ('') map }		def
	/ogonek		{ (og) map }		def
	/caron		{ (hc) map }		def
	/emdash		{ (em) map }		def
	/AE		{ (AE) cmap }		def
	/ordfeminine	{ }			def
	/Lslash		{ (PL) map }		def
	/Oslash		{ (O/) map }		def
	/OE		{ (OE) cmap }		def
	/ordmasculine	{ }			def
	/ae		{ (ae) cmap }		def
	/dotlessi	{ (ui) map }		def
	/lslash		{ (Pl) map }		def
	/oslash		{ (o/) map }		def
	/oe		{ (oe) cmap }		def
	/germandbls	{ (ss) map }		def
end

/symbol-encoding 189 dict def
symbol-encoding begin
	/space		{ space }		def
	/exclam		{ norm }		def
	/universal	{ (fa) map }		def
	/numbersign	{ norm }		def
	/existential	{ (te) map }		def
	/percent	{ norm }		def
	/ampersand	{ norm }		def
	/suchthat	{ (cm) map }		def
	/parenleft	{ norm }		def
	/parenright	{ norm }		def
	/asteriskmath	{ (**) map }		def
	/plus		{ (pl) map }		def
	/comma		{ norm }		def
	/minus		{ (mi) normdup }	def
	/period		{ norm }		def
	/slash		{ (sl) map }		def
	/zero		{ norm }		def
	/one		{ norm }		def
	/two		{ norm }		def
	/three		{ norm }		def
	/four		{ norm }		def
	/five		{ norm }		def
	/six		{ norm }		def
	/seven		{ norm }		def
	/eight		{ norm }		def
	/nine		{ norm }		def
	/colon		{ norm }		def
	/semicolon	{ norm }		def
	/less		{ norm }		def
	/equal		{ (eq) normdup }	def
	/greater	{ norm }		def
	/question	{ norm }		def
	/congruent	{ (=~) map }		def
	/Alpha		{ gnorm }		def
	/Beta		{ gnorm }		def
	/Chi		{ (*X) map }		def
	/Delta		{ gnorm }		def
	/Epsilon	{ gnorm }		def
	/Phi		{ gnorm }		def
	/Gamma		{ gnorm }		def
	/Eta		{ (*Y) map }		def
	/Iota		{ gnorm }		def
	/theta1		{ }			def
	/Kappa		{ gnorm }		def
	/Lambda		{ gnorm }		def
	/Mu		{ gnorm }		def
	/Nu		{ gnorm }		def
	/Omicron	{ gnorm }		def
	/Pi		{ gnorm }		def
	/Theta		{ (*H) map }		def
	/Rho		{ gnorm }		def
	/Sigma		{ gnorm }		def
	/Tau		{ gnorm }		def
	/Upsilon	{ gnorm }		def
	/sigma1		{ (ts) map }		def
	/Omega		{ (*W) map }		def
	/Xi		{ (*C) map }		def
	/Psi		{ (*Q) map }		def
	/Zeta		{ gnorm }		def
	/bracketleft	{ norm }		def
	/therefore	{ (tf) map }		def
	/bracketright	{ norm }		def
	/perpendicular	{ (bt) map }		def
	/underscore	{ (ul) map }		def
	/radicalex	{ }			def
	/alpha		{ gnorm }		def
	/beta		{ gnorm }		def
	/chi		{ (*x) map }		def
	/delta		{ gnorm }		def
	/epsilon	{ gnorm }		def
	/phi		{ gnorm }		def
	/gamma		{ gnorm }		def
	/eta		{ (*y) map }		def
	/iota		{ gnorm }		def
	/phi1		{ }			def
	/kappa		{ gnorm }		def
	/lambda		{ gnorm }		def
	/mu		{ gnorm }		def
	/nu		{ gnorm }		def
	/omicron	{ gnorm }		def
	/pi		{ gnorm }		def
	/theta		{ (*h) map }		def
	/rho		{ gnorm }		def
	/sigma		{ gnorm }		def
	/tau		{ gnorm }		def
	/upsilon	{ gnorm }		def
	/omega1		{ }			def
	/omega		{ (*w) map }		def
	/xi		{ (*c) map }		def
	/psi		{ (*q) map }		def
	/zeta		{ gnorm }		def
	/braceleft	{ norm }		def
	/bar		{ (or) normdup }	def
	/braceright	{ norm }		def
	/similar	{ (ap) map }		def
	/Upsilon1	{ }			def
	/minute		{ (mt) map }		def
	/lessequal	{ (<=) map }		def
	/fraction	{ (/) map }		def
	/infinity	{ (if) map }		def
	/florin		{ }			def
	/club		{ (Cc) map }		def
	/diamond	{ (Cd) map }		def
	/heart		{ (Ch) map }		def
	/spade		{ (Cs) map }		def
	/arrowboth	{ (<>) map }		def
	/arrowleft	{ (<-) map }		def
	/arrowup	{ (ua) map }		def
	/arrowright	{ (->) map }		def
	/arrowdown	{ (da) map }		def
	/degree		{ (de) map }		def
	/plusminus	{ (+-) map }		def
	/second		{ (sd) map }		def
	/greaterequal	{ (>=) map }		def
	/multiply	{ (mu) map }		def
	/proportional	{ (pt) map }		def
	/partialdiff	{ (pd) map }		def
	/bullet		{ }			def
	/divide		{ (di) map }		def
	/notequal	{ (!=) map }		def
	/equivalence	{ (==) map }		def
	/approxequal	{ (~=) map }		def
	/ellipsis	{ }			def
	/arrowvertex	{ }			def
	/arrowhorizex	{ }			def
	/carriagereturn	{ (cr) map }		def
	/aleph		{ (al) map }		def
	/Ifraktur	{ }			def
	/Rfraktur	{ }			def
	/weierstrass	{ }			def
	/circlemultiply	{ (ax) map }		def
	/circleplus	{ (a+) map }		def
	/emptyset	{ (es) map }		def
	/intersection	{ (ca) map }		def
	/union		{ (cu) map }		def
	/propersuperset	{ (sp) map }		def
	/reflexsuperset	{ (ip) map }		def
	/notsubset	{ (!s) map }		def
	/propersubset	{ (sb) map }		def
	/reflexsubset	{ (ib) map }		def
	/element	{ (mo) map }		def
	/notelement	{ (!m) (nm) mapdup }	def
	/angle		{ (ag) map }		def
	/gradient	{ (gr) map }		def
	/registerserif	{ }			def
	/copyrightserif	{ }			def
	/trademarkserif	{ }			def
	/product	{ }			def
	/radical	{ (sr) map }		def
	/dotmath	{ (m.) map }		def
	/logicalnot	{ (no) map }		def
	/logicaland	{ (an) (la) mapdup }	def
	/logicalor	{ (lo) map }		def
	/arrowdblboth	{ (io) map }		def
	/arrowdblleft	{ (<:) (lh) mapdup }	def
	/arrowdblup	{ (u=) map }		def
	/arrowdblright	{ (:>) (rh) (im) mapdupdup } def
	/arrowdbldown	{ (d=) map }		def
	/lozenge	{ (dm) map }		def
	/angleleft	{ (L<) map }		def
	/registersans	{ (rg) map }		def
	/copyrightsans	{ (co) map }		def
	/trademarksans	{ (tm) map }		def
	/summation	{ }			def
	/parenlefttp	{ }			def
	/parenleftex	{ }			def
	/parenleftbt	{ }			def
	/bracketlefttp	{ }			def
	/bracketleftex	{ }			def
	/bracketleftbt	{ }			def
	/bracelefttp	{ }			def
	/braceleftmid	{ }			def
	/braceleftbt	{ }			def
	/braceex	{ }			def
	/apple		{ (AL) map }		def
	/angleright	{ (R>) map }		def
	/integral	{ (is) map }		def
	/integraltp	{ }			def
	/integralex	{ }			def
	/integralbt	{ }			def
	/parenrighttp	{ }			def
	/parenrightex	{ }			def
	/parenrightbt	{ }			def
	/bracketrighttp	{ }			def
	/bracketrightex	{ }			def
	/bracketrightbt	{ }			def
	/bracerighttp	{ }			def
	/bracerightmid	{ }			def
	/bracerightbt	{ }			def
end

/Times-Roman		/Roman		/R	fontinfo
/Helvetica		/Helvetica	/H	fontinfo
/Courier		/Courier	/C	fontinfo
/Symbol			/Symbol		/S	fontinfo
/Times-Italic		/Italic		/I	fontinfo
/Times-Bold		/Bold		/B	fontinfo
/Times-BoldItalic	/BoldI		/BI	fontinfo
/Helvetica-Bold		/HelveticaB	/HB	fontinfo
/Helvetica-Oblique	/HelveticaO	/HO	fontinfo
/Helvetica-BoldOblique	/HelveticaBO	/HX	fontinfo
/Courier-Bold		/CourierB	/CB	fontinfo
/Courier-Oblique	/CourierO	/CO	fontinfo
/Courier-BoldOblique	/CourierBO	/CX	fontinfo
//E*O*F src/pscript/genftable.ps//

echo x - src/pscript/grid.ps
cat > "src/pscript/grid.ps" << '//E*O*F src/pscript/grid.ps//'
%!
% print a grid to check linearity of LaserWriter

72 dup scale

clippath pathbbox pop pop translate

0.003 setlinewidth
2 setlinecap

gsave
90
	{ newpath
	  0 0 moveto
	  0 11 lineto
	  stroke
	  0.1 0 translate
	} repeat

grestore

gsave
120
	{ newpath
	  0 0 moveto
	  7 0 lineto
	  stroke
	  0 0.1 translate
	} repeat
grestore

showpage
//E*O*F src/pscript/grid.ps//

echo x - src/pscript/inc.ps
cat > "src/pscript/inc.ps" << '//E*O*F src/pscript/inc.ps//'
%!
/inch { 72 mul } def
/cm { 28.3465 mul } def
//E*O*F src/pscript/inc.ps//

echo x - src/pscript/pages.ps
cat > "src/pscript/pages.ps" << '//E*O*F src/pscript/pages.ps//'
statusdict begin pagecount end ==
//E*O*F src/pscript/pages.ps//

echo x - src/pscript/papersize.ps
cat > "src/pscript/papersize.ps" << '//E*O*F src/pscript/papersize.ps//'
/a4
	[
		[ 300 72 div 0 0 -300 72 div -72 3436 ]
		292 3365
		{statusdict /jobstate (printing) put 0 setblink
		margins exch 142 add exch 256 add 8 div round cvi frametoroket
		statusdict /jobstate (busy) put
		1 setblink }
		/framedevice load
		60 45 {dup mul exch dup mul add 1.0 exch sub } /setscreen load
		{} /settransfer load
		/initgraphics load
		/erasepage load
	] cvx
statusdict begin bind end readonly def
newpath
/inch { 72 mul } def
/cm { 28.3465 mul } def
/Times-Roman findfont 4 cm scalefont setfont
/sp { 0.9 setgray clippath fill 0 setgray 8 cm 15 cm moveto show showpage } def
letter (letter) sp
note (note) sp
legal (legal) sp
a4 (a4) sp
//E*O*F src/pscript/papersize.ps//

echo x - src/pscript/pattern.ps
cat > "src/pscript/pattern.ps" << '//E*O*F src/pscript/pattern.ps//'
/bitison
{
	/ybit exch def /xbit exch def
	bstring ybit bwidth mul
	xbit 8 idiv add get
	1 7 xbit 8 mod sub bitshift
	and 0 ne
} def

/setpattern
{
	/freq exch def
	/bwidth exch def
	/bpside exch def
	/bstring exch def
	/onbits 0 def /offbits 0 def
	freq 0 {
		/y exch def /x exch def
		/xindex x 1 add 2 div bpside mul cvi def
		/yindex y 1 add 2 div bpside mul cvi def
		xindex yindex bitison
		{ /onbits onbits 1 add def 1 }
		{ /offbits offbits 1 add def 0 }
		ifelse
		} setscreen
	{} settransfer
	offbits offbits onbits add div setgray
} def

<d1e3c5885c3e1d88> 8 1 300 32 div setpattern

100 100 moveto 300 0 rlineto 0 300 rlineto -300 0 rlineto closepath fill

newpath 300 300 moveto 300 300 100 
<3e418080e3140808> 8 1 300 32 div setpattern

100 500 moveto 300 0 rlineto 0 300 rlineto -300 0 rlineto closepath fill
showpage
//E*O*F src/pscript/pattern.ps//

echo x - src/pscript/setidle.sh
cat > "src/pscript/setidle.sh" << '//E*O*F src/pscript/setidle.sh//'
# Select the fonts to be idle time scanned
if [ $# != 1 ]
then
	echo "Usage: setidle passwd-number" 1>&2
	exit 1
fi
cat <<!
%!
$1 serverdict begin exitserver
statusdict begin
	mark
	4 100 100 0 94	% Times-Roman 10 point
	5 100 100 0 94	% Times-Bold 10 point
	6 100 100 0 94	% Times-Italic 10 point
	setidlefonts
end
(idle time font scan changed\n) print flush
!
echo "\004"
//E*O*F src/pscript/setidle.sh//

echo x - src/pscript/setname.sh
cat > "src/pscript/setname.sh" << '//E*O*F src/pscript/setname.sh//'
# Set a new printer name
if [ $# != 2 ]
then
	echo "Usage: setname passwd-number name" 1>&2
	exit 1
fi
cat <<!
%!
$1 serverdict begin exitserver
statusdict begin
	($2) setprintername
end
!
echo "\004"
//E*O*F src/pscript/setname.sh//

echo x - src/pscript/setpasswd.sh
cat > "src/pscript/setpasswd.sh" << '//E*O*F src/pscript/setpasswd.sh//'
# Set a new passwd
if [ $# != 2 ]
then
	echo "Usage: setpasswd oldpasswd-number newpasswd-number" 1>&2
	exit 1
fi
cat <<!
%!
$1 serverdict begin exitserver
statusdict begin
	$1 $2 setpassword ==
end
!
echo "\004"
//E*O*F src/pscript/setpasswd.sh//

echo x - src/pscript/shadow.ps
cat > "src/pscript/shadow.ps" << '//E*O*F src/pscript/shadow.ps//'
%!
/Times-Roman findfont 50 scalefont setfont
/cm { 28.3465 mul } def
8 cm 15 cm moveto
/shadow
{
	/text exch def
	1 -0.1 0
	{
		setgray -1 1 rmoveto
		currentpoint text show moveto
	} for
} def

(Shadow) shadow
showpage
//E*O*F src/pscript/shadow.ps//

echo Possible errors detected by \'wc\' [hopefully none]:
temp=/tmp/shar$$
trap "rm -f $temp; exit" 0 1 2 3 15
cat > $temp <<\!!!
     32    116    923 Makefile
    371   1255   9061 ipscript.c
    287    815   5717 lpscript.c
      1      6     52 READ_ME
     15     72    417 a4.ps
     76    186    820 big_greek.ps
    263    935   4966 demo.ps
    184    893   4398 floor.ps
    560   2525  12794 genftable.ps
     32     57    343 grid.ps
      3     13     48 inc.ps
      1      5     34 pages.ps
     24    120    657 papersize.ps
     38    160    833 pattern.ps
     19     73    374 setidle.sh
     14     37    201 setname.sh
     14     38    213 setpasswd.sh
     16     41    221 shadow.ps
   1950   7347  42072 total
!!!
wc  src/opscript/Makefile src/opscript/ipscript.c src/opscript/lpscript.c src/pscript/READ_ME src/pscript/a4.ps src/pscript/big_greek.ps src/pscript/demo.ps src/pscript/floor.ps src/pscript/genftable.ps src/pscript/grid.ps src/pscript/inc.ps src/pscript/pages.ps src/pscript/papersize.ps src/pscript/pattern.ps src/pscript/setidle.sh src/pscript/setname.sh src/pscript/setpasswd.sh src/pscript/shadow.ps | sed 's=[^ ]*/==' | diff -b $temp -
exit 0