[alt.sources] face2ps -- The last FaceSaver to PostScript program written in C

nelson@sun.soe.clarkson.edu (Russ Nelson) (07/26/89)

#!/bin/sh
# shar:	Shell Archiver  (v1.22)
#
#	Run the following text with /bin/sh to create:
#	  README
#	  card.ps
#	  dartboard.ps
#	  face2ps.c
#	  face2ps.ps
#	  interp.ps
#	  labels.ps
#	  lineup.ps
#
sed 's/^X//' << 'SHAR_EOF' > README &&
XFace2ps is a general-purpose FaceSaver-to-PostScript translator.  The
Xonly FaceSaver images that are generally available have been created
Xat the two most recent Usenix's.  They have been in {106,98}w x 128h x
X8d.  I have created a number of faces that are not in either of those
Xresolutions, hence my need for face2ps.
X
XNo copyright claimed.
X
XTo get information on getting faces from UUNET via e-mail, send a mail
Xmessage to faceserver@uunet.uu.net (or uunet!faceserver) with the
Xsubject line of "help".
X
XTo get the faces via anonymous FTP, ftp to uunet.uu.net and cd to the
X"faces" directory.
X
XRather than impose its own idea of how a face should be printed,
Xface2ps simply converts the face file into a form compatible with
XPostScript.  Before doing so, it outputs an appropriate PostScript
Xprolog.  Various prologs exist:
X
X	face2ps   - Prints a 8.5"x6.5" and a 1"x1" face on the same page.
X	lineup    - Prints up to 25 faces on a single page.
X	card      - Prints a business card.
X	dartboard - Prints a full-page dartboard.
X	labels    * Prints a page of sticky labels.
X	interp    * Prints a full-page face, interpolating between pixels.
X
X* not working yet, but included anyway.
X
XFace2ps.c requires an ANSI compiler, because I made liberal use of
XANSI constructs like string pasting.  Using "gcc -o face2ps face2ps.c"
Xunder Unix or "tcc face2ps" under MS-LOSS is sufficient, so no
Xmakefile is included.  Before compiling, you must change the define
Xat the beginning of face2ps that gives the absolute pathname to the
Xprologs.
X
XThere are only two switches:
X
X-p prolog
X
X	Sets the prolog to be used, i.e. "-p card".  If this switch is
Xnot used, then the name of the prolog is taken from the name of the
Xprogram.  Hence, the default prolog is face2ps.  Under Unix, you can
Xlink the file to the names of the different prologs.  Under MS-LOSS,
Xyou must make several copies of the executable with different names.
X
X-D define=value
X
X	Use of this switch will generate /define value def in the PostScript
Xoutput.  None of the current prologs use it, but it's there anyway.
X
XFace2ps outputs things in the following order:
X
X	the prolog
X	anything defined with -D
X	A definition of "count" to be the number of faces to follow.
X	start
X	 data for the first face
X	face
X	 data for the second face, if any
X	face
X	...
X	finish
X
Xwhere start, face, and finish are defined by the prolog.  Reading
Xface2ps.ps and examining the output of face2ps will show you how
Xthings arranged much faster than reading any documentation.  But in a
Xnutshell, each header entry in the face file is sent to the output as
Xa /header (contents) def.  The face data is sent as /imagedata <> def.
XThis means that huge amounts of memory are used, but is so convenient
Xthat I chose to leave it as is.
X
XThis software should really be considered alpha test, because I'm sure
Xthat several people are going to object to the ANSIness of the C
Xprogram.  Also, I hope that someone out there feels like getting the
Xthree non-functional prologs working, or perhaps writes their own prolog,
Xor improves one of the existing ones.
X
XSo, keep me informed:
X--russ (nelson@clutx [.bitnet | .clarkson.edu])|(70441.205@compuserve.com)
SHAR_EOF
chmod 0644 README || echo "restore of README fails"
sed 's/^X//' << 'SHAR_EOF' > card.ps &&
X%! PS-Adobe-2.0
X%% Creator: card
X%% DocumentFonts: Helvetica Courier
X%% EndComments
X
X% a business-card printer.  I got it from Dave Goldblatt, who got it from
X% Pat Naughton, who got it from Mike Patton may actually be the original
X% author.
X
X/ctrat { /y exch def dup stringwidth pop card_width exch sub 2 div y moveto show } def
X/lftat { margin exch moveto show } def
X/rgtat { /y exch def dup stringwidth pop margin add card_width exch sub y moveto show } def
X
X/Helvetica findfont
Xdup  8 scalefont /smallfont exch def /small { smallfont setfont } def
Xdup 10 scalefont /normalfont exch def /normal { normalfont setfont } def
Xdup 15 scalefont /bigfont exch def /big { bigfont setfont } def
Xdup 20 scalefont /hugefont exch def /huge { hugefont setfont } def
Xpop
X/Courier findfont
X    10 scalefont /ttfont exch def /tt { ttfont setfont} def
Xnormal
X
X/start {
X	% Parameters
X	/card_width	255 def
X	/card_height	135 def
X	/sep	5 def
X	/ncols	2 def
X	/margin	6 def
X
X	50 50 translate
X
X	/xpos 0 def
X	/ypos 0 def
X	/colnumber 0 def
X
X	/deltax card_width  sep add def
X	/deltay card_height sep add def
X} bind def
X
X%% string1 string2 append string
X% appends two strings
X/append {
X	2 copy length exch length add	% find the length of the new.
X	string dup
X% string1 string2 string string
X	4 2 roll
X% string string string1 string2
X	2 index 0 3 index
X% string string string1 string2 string 0 string1
X	putinterval	% stuff the first string in.
X% string string string1 string2
X	exch length exch putinterval
X} bind def
X
X% key fetch string
X/fetch {
X	dup where {
X		exch get
X	} {
X		pop ()
X	} ifelse
X} bind def
X
X/card {
X	gsave
X
X	xpos ypos translate
X
X	/xpos xpos deltax add store
X	/colnumber colnumber 1 add store
X	colnumber ncols ge {
X		/xpos 0 store
X		/colnumber 0 store
X		/ypos ypos deltay add store
X	} if
X
X	0 0 moveto
X	card_width 0 lineto
X	card_width card_height lineto
X	0 card_height lineto
X	closepath
X	gsave stroke grestore
X	clip
X	newpath
X
X	small
X	/Address1 fetch 122 rgtat
X	/Address2 fetch 113 rgtat
X	/CityStateZip fetch 104 rgtat
X
X	huge
X	% concatenate FirstName and LastName.
X	FirstName ( ) append
X	LastName append 65 ctrat
X
X	normal
X	/Company fetch 52 ctrat
X
X	tt
X	/Telephone fetch 21 ctrat
X	/E-mail fetch 10 ctrat
X
X	gsave
X	2 81 translate
X	52 52 scale
X	xratio yratio scale
X	width height depth [ width 0 0 height 0 0 ]
X	{ imagedata } image
X	grestore
X
X	grestore
X
X} bind def
X
X/face {
X	card card card card card card card card card card
X	showpage
X	/xpos 0 store
X	/ypos 0 store
X	/colnumber 0 store
X} def
X
X/finish {} def
X
X%%EndProlog
SHAR_EOF
chmod 0644 card.ps || echo "restore of card.ps fails"
sed 's/^X//' << 'SHAR_EOF' > dartboard.ps &&
X%! PS-Adobe-2.0
X%% Creator: dartboard
X%% DocumentFonts: Helvetica
X%% EndComments
X
X% Here is a program which will print out a face in full-page format, having
X% converted it to look like a dartboard.  Great for those people to whose
X% faces you have access for which you have a particular dislike.  The Official
X% David Tilbrook Dartboard, for example, is extremely popular at a number of
X% sites in the United States, Canada, and Europe.
X
X% Dartboard program by Daniel V. Klein (dvk@sei.cmu.edu) Copyright 1989.
X
X% pointsize of their user info.
X/pt 18 def
X
X% initialize some global stuff.
X/start {
X	currentscreen /p exch def
X	pop pop 50 45 /p load setscreen
X
X	% This transfer function prevents pure white on 300 dpi laser printers
X
X	{ 1.05 mul 0.05 add dup .99 gt { pop .99 } if } settransfer
X} bind def
X
X% we can handle multiple faces, no problem.
X/face {
X	/Helvetica findfont pt scalefont setfont
X	currentscreen /p exch store
X	pop pop 50 45 /p load setscreen
X
X	% This transfer function prevents pure white on 300 dpi laser printers
X
X	{ 1.05 mul 0.05 add dup .99 gt { pop .99 } if } settransfer
X
X	% output their name, e-mail address, and organization.
X	gsave
X	72 72 translate
X	108 pt 2 add moveto
X	(The Official ) show FirstName show ( ) show LastName show ( Dartboard) show
X	grestore
X
X	% big copy of their face
X	% we should really center this, but I'm too lazy to figure out how
X	% to do this while taking xratio and yratio into account.
X	gsave
X	72 144 translate
X	576 576 scale
X	xratio yratio scale
X	width height depth [ width 0 0 height 0 0 ]
X	{ imagedata } image
X	grestore
X
X	gsave
X	% This transfer function darkens the circles of the dartboard
X	{ 1.2 div } settransfer
X	initmatrix
X	7 setflat newpath
X	4.25 72 mul 6 72 mul 1 55 mul 0 360 arc
X	4.25 72 mul 6 72 mul 2 55 mul 0 360 arc
X	4.25 72 mul 6 72 mul 3 55 mul 0 360 arc
X	4.25 72 mul 6 72 mul 4 55 mul 0 360 arc
X	4.25 72 mul 6 72 mul 5 55 mul 0 360 arc
X	4.25 72 mul 6 72 mul 6 55 mul 0 360 arc
X	4.25 72 mul 6 72 mul 7 55 mul 0 360 arc
X	4.25 72 mul 6 72 mul 8 55 mul 0 360 arc
X	eoclip
X	72 144 translate
X	576 576 scale
X	xratio yratio scale
X	width height depth [ width 0 0 height 0 0 ]
X	{ imagedata } image
X	grestore
X
X	showpage
X} bind def
X
X% we don't need to do anything when we finish.
X/finish {} def
X
X%% EndProlog
SHAR_EOF
chmod 0644 dartboard.ps || echo "restore of dartboard.ps fails"
sed 's/^X//' << 'SHAR_EOF' > face2ps.c &&
X/* Convert a Usenix Face to PostScript. */
X
X/* This program outputs things in the following order:
X *
X * the prolog
X * anything defined with -D
X * defines "count" to be the number of faces to follow.
X * start
X *  data for the first face
X * face
X *  data for the second face, if any
X * face
X * finish
X */
X
X#ifdef __MSDOS__
Xchar absolute_format[] = "/faces/%s.ps";  /* full pathname to the prologs */
X#else
Xchar absolute_format[] = "./%s.ps";  /* full pathname to the prologs */
X#endif
X
X#ifdef __TURBOC__
X#include <stdlib.h>
X#else
X#include <malloc.h>
X#endif
X#include <stdio.h>
X#include <ctype.h>
X#include <string.h>
X
Xchar *program;				/* the name of this program */
X
X/* getopt stuff */
Xextern int optind;			/* index of which argument is next */
Xextern char *optarg;			/* pointer to argument of this option */
X
Xchar *prolog_name = NULL;		/* the name of the prolog file */
X
Xint height, width, depth;		/* as per PicData: */
Xint iheight, iwidth, idepth;		/* as per Image: */
Xchar *defines;				/* accumulated -D options */
X
Xvoid doprolog(char *fn);
Xvoid doface(char *fn);
X
Xdo_define(char *arg)
X{
X	char *equals = strchr(arg, '=');
X	static char define_string[] = "/%s %s def\n";
X
X	if (!equals) {
X		fprintf(stderr, "%s: \"%s\" is missing an equals sign",
X		    program, arg);
X		exit(1);
X	}
X	defines = realloc(defines, strlen(defines) + strlen(define_string)
X	    + strlen(arg) + 1);
X	if (!defines) {
X		fprintf(stderr, "%s: ran out of memory on \"%s\"\n",
X		    program, arg);
X		exit(1);
X	}
X	*equals++ = '\0';
X	sprintf(defines + strlen(defines), define_string, arg, equals);
X}
X
Xchar *
Xlonggets(FILE *fd)
X{
X	int length = 256;
X	char *cp = malloc(length);
X	int slen = 0;
X
X	if (!cp) {
X		fprintf(stderr, "%s: ran out of memory\n", program);
X		exit(1);
X	}
X	slen = 0;
X	*cp = '\0';
X	while (fgets(cp + slen, length - slen, fd) != NULL) {
X		slen = strlen(cp);
X		if (cp[slen-1] == '\n')
X			break;
X		cp = realloc(cp, length *= 2);
X		if (!cp) {
X			fprintf(stderr, "%s: ran out of memory\n", program);
X			exit(1);
X		}
X	}
X	return cp;
X}
X
Xmain(argc,argv)
Xint argc;
Xchar *argv[];
X{
X	int option;			/* the option letter */
X
X#ifdef __MSDOS__
X	char *progend;
X	program = max(strrchr(argv[0], '\\'),strrchr(argv[0], '/'));
X	progend = strchr(program, '.');
X	if (progend)
X		*progend = '\0';
X#else
X	program = strrchr(argv[0], '/');
X#endif
X	program++;
X
X	if (setvbuf(stdout, 0, _IOFBF, 4096)) {
X		fprintf(stderr, "%s: ran out of memory on setvbuf to stdout\n",
X		    program);
X		exit(1);
X	}
X
X	defines = strdup("");
X
X	while((option=getopt(argc, argv, "p:D:")) != EOF) switch(option){
X	case 'p':
X		prolog_name = optarg;
X		break;
X	case 'D':
X		do_define(optarg);
X		break;
X	default:
Xusage:
X		fprintf(stderr, "usage: %s [-pD] [face-file(s)...]", program);
X		exit(1);
X	}
X
X	/* The default prolog name is the same name as the program.  This lets
X	 * us link the filename to different prologs under Unix.  MS-LOSS loses.
X	 */
X	if (!prolog_name)
X		prolog_name = program;
X
X	doprolog(prolog_name);
X
X	/* now that we've output the prolog, output the -D defines, before
X	 * we do "start".
X	 */
X	fputs(defines, stdout);
X	free(defines);
X
X	/* now output the count and the "start"
X	 */
X	printf("/count %d def\n"
X	    "start\n", argc - optind);
X
X	/* process the remaining arguments (if any)
X	 */
X	while (optind < argc) {
X		doface(argv[optind++]);
X	}
X	printf("finish\n"
X	    "%%%%EndTrailer\n");
X}
X
X
Xvoid
Xdoprolog(char *fn)
X{
X	FILE *fp;			/* the input file */
X	char *inl;			/* points to lines from the FILE *fp. */
X	char *absolute_fn;
X
X	absolute_fn = malloc(strlen(absolute_format) + strlen(fn));
X	if (!absolute_fn) {
X		fprintf(stderr, "%s: ran out of memory\n", program);
X		exit(1);
X	}
X
X	sprintf(absolute_fn, absolute_format, fn);
X
X	fp = fopen(absolute_fn,"r");
X	if (fp == NULL) {
X		fprintf(stderr,"%s: can't open %s for input\n",
X		    program, absolute_fn);
X		exit (1);
X	}
X
X	if (setvbuf(fp, 0, _IOFBF, 4096)) {
X		fprintf(stderr, "%s: ran out of memory on setvbuf to fp\n",
X		    program);
X		exit(1);
X	}
X
X	/* Copy the prolog over */
X	while (inl = longgets(fp),*inl) {
X		printf("%s",inl);
X		free(inl);
X	}
X
X	fclose(fp);
X}
X
Xvoid
Xdoface(char *fn)
X{
X	FILE *fp;			/* the input file */
X	char *inl;			/* points to lines from the FILE *fp. */
X	fp = fopen(fn,"r");
X	if (fp == NULL) {
X		fprintf(stderr,"%s: can't open %s for input\n",
X		    program, fn);
X		exit (1);
X	}
X
X	if (setvbuf(fp, 0, _IOFBF, 4096)) {
X		fprintf(stderr, "%s: ran out of memory on setvbuf to fp\n",
X		    program);
X		exit(1);
X	}
X
X	/* create a dictionary big enough for everything */
X	printf("20 dict begin\n");
X
X	/* Get the header -- exit the loop on the first blank line. */
X	while((inl = longgets(fp)) && *inl != '\n'){
X		char *colon = strchr(inl, ':');
X		char *nl = strrchr(inl, '\n');
X
X		/* make sure we got a newline */
X		if (!nl) {
X			fprintf(stderr, "%s: the following header entry has no newline:\n\t%s\n", program, inl);
X			exit(1);
X		}
X
X		/* nuke the newline and any trailing spaces. */
X		while (isspace(*nl))
X			--nl;
X		nl[1] = '\0';
X
X		/* make sure we got a colon */
X		if (!colon) {
X			fprintf(stderr, "%s: the following header entry has no colon:\n\t%s\n", program, inl);
X			exit(1);
X		}
X
X		/* nuke the colon and skip any trailing spaces. */
X		*colon++ = '\0';
X		while (isspace(*colon))
X			colon++;
X
X		/* handle PicData: and Image: specially */
X		if (!strcmp(inl, "PicData")){
X			if (sscanf(colon,"%d %d %d",&width,&height,&depth)
X			    != 3) {
X				fprintf(stderr, "%s: %s: "
X				    "should have three numbers following it:"
X				    "\"%s\"\n", program, inl, colon);
X				exit(1);
X			} else {
X				printf("/width %d def\n"
X				    "/height %d def\n"
X				    "/depth %d def\n", width, height, depth);
X			}
X		} else if (!strcmp(inl, "Image")){
X			if (sscanf(colon,"%d %d %d",&iwidth,&iheight,&idepth)
X			    != 3) {
X				fprintf(stderr, "%s: %s: "
X				    "should have three numbers following it:"
X				    "\"%s\"\n", program, inl, colon);
X				exit(1);
X			} else {
X				printf("/iwidth %d def\n"
X				    "/iheight %d def\n"
X				    "/idepth %d def\n",
X				    iwidth, iheight, idepth);
X			}
X		} else {
X			/* headers get defined as their names, quoting parens */
X			printf("/%s (", inl);
X			for ( ;*colon;colon++) if (*colon == '(' ||
X			    *colon == ')' ||
X			    *colon == '\\' ||
X			    *colon < ' ')
X				printf("\\%03o", *colon);
X			else
X				putchar(*colon);
X			printf(") def\n");
X		}
X
X		free(inl);
X	}
X
X	/* we feed a NULL pointer to free iff the file is munged. */
X	free(inl);
X
X	/* we output the x ratio and y ratio in such a manner that the face
X	 * is never larger than the scale that you give for it, but the
X	 * aspect ratio is preserved */
X	if (iwidth > iheight)
X		printf("/xratio 1 def\n"
X		    "/yratio %f def\n", (float)iheight / (float)iwidth);
X	else
X		printf("/xratio %f def\n"
X		    "/yratio 1 def\n", (float)iwidth / (float)iheight);
X
X	printf("/imagedata {<\n");
X
X	/* Copy the image data over */
X	while (inl = longgets(fp),*inl) {
X		printf("%s",inl);
X		free(inl);
X	}
X
X	/* finish off the imagedata, do the face, and drop the dictionary */
X	printf(">} def\nface\nend\n");
X
X	fclose(fp);
X}
SHAR_EOF
chmod 0644 face2ps.c || echo "restore of face2ps.c fails"
sed 's/^X//' << 'SHAR_EOF' > face2ps.ps &&
X%! PS-Adobe-2.0
X%% Creator: face2ps
X%% DocumentFonts: Helvetica
X%% EndComments
X
X% pointsize of their user info.
X/pt 18 def
X
X% initialize some global stuff.
X/start {
X	currentscreen /p exch def
X	pop pop 50 45 /p load setscreen
X
X	% This transfer function prevents pure white on 300 dpi laser printers
X
X	{ 1.05 mul 0.05 add dup .99 gt { pop .99 } if } settransfer
X} bind def
X
X% we can handle multiple faces, no problem.
X/face {
X	/Helvetica findfont pt scalefont setfont
X	currentscreen /p exch store
X	pop pop 50 45 /p load setscreen
X
X	% This transfer function prevents pure white on 300 dpi laser printers
X
X	{ 1.05 mul 0.05 add dup .99 gt { pop .99 } if } settransfer
X
X	% output their name, e-mail address, and organization.
X	gsave
X	72 72 translate
X	108 pt 2 add moveto
X	FirstName show ( ) show LastName show
X
X	108 0 moveto
X	E-mail show
X
X	/Company where {
X		pop
X		108 pt 2 add neg moveto
X		Company show
X	} if
X	grestore
X
X	% big copy of their face
X	gsave
X	72 144 translate
X	500 500 scale
X	xratio yratio scale
X	width height depth [ width 0 0 height 0 0 ]
X	{ imagedata } image
X	grestore
X
X	% little copy of their face
X	gsave
X	72 72 translate
X	50 50 scale
X	xratio yratio scale
X	width height depth [ width 0 0 height 0 0 ]
X	{ imagedata } image
X	grestore
X
X	showpage
X} bind def
X
X% we don't need to do anything when we finish.
X/finish {} def
X
X%% EndProlog
SHAR_EOF
chmod 0644 face2ps.ps || echo "restore of face2ps.ps fails"
sed 's/^X//' << 'SHAR_EOF' > interp.ps &&
X%! PS-Adobe-2.0
X%% Creator: face2ps
X%% EndComments
X%
X% prints facesaver images to fill 8.5" x 11" pages
X% uses interpolation to increase pixel count for smoother images
X% warning: this takes a few minutes to run on our printer
X% author: Greg Paris <gmp@rayssd.ray.com>
X%
X
X% initialize some global stuff.
X/start {
X} bind def
X
X%
X% horiz: read in image line, interpolate into nxtstr
X%	leaves nothing new on the stack
X%
X/horiz {					% read then horiz interpolate
X    currentfile pikstr readhexstring pop pop	% read inline data
X    /pi 0 def					% index into pikstr
X    /ii 0 def					% index into nxtstr
X    {
X	/pv pikstr pi get def			% current picstr value
X	/pi pi 1 add def			% increment picstr index
X	nxtstr ii pv put			% put current value
X	/ii ii 1 add def			% increment nxtstr index
X	pi width lt {				% to end of picstr
X	    /nv pikstr pi get def		% next picstr value
X	    /pwgt horint def			% previous pixel weight
X	    /nwgt 0 def				% next pixel weight
X	    horint 1 sub {			% repeat horint - 1 times
X		/pwgt pwgt 1 sub def		% decrement previous weight
X		/nwgt nwgt 1 add def		% increment next weight
X		nxtstr ii
X		    pv pwgt mul nv nwgt mul add	% weighted sum
X		    horint div round cvi	% weighted average
X		    put				% put at next position
X		/ii ii 1 add def		% increment nxtstr index
X	    } repeat
X	} { exit } ifelse
X    } loop
X} bind def
X
X%
X% vert: interpolates between prvstr and newstr to produce curstr
X%	leaves nothing new on the stack
X%
X/vert {						% interpolate vertically
X    /pwgt lineno verint mod def			% previous pixel weight
X    /nwgt verint pwgt sub def			% next pixel weight
X    /ii 0 def					% set index into line
X    horsiz {					% over line length
X	/pv prvstr ii get def			% previous pixel
X	/nv nxtstr ii get def			% next pixel
X	curstr ii
X	    pv pwgt mul nv nwgt mul add		% weighted sum
X	    verint div round cvi		% weighted average
X	    put					% put at next position
X	/ii ii 1 add def			% increment index into line
X    } repeat
X} bind def
X
X%
X% getnext: use interpolation when necessary to produce the next line
X%	modifies prvstr and nxtstr ; increments lineno
X%	leaves curstr on the stack
X%
X/getnext {					% produce next image line
X    lineno verint mod 0 eq {			% at an original line?
X	lineno 0 eq { horiz } if		% get first line
X	nxtstr prvstr copy pop			% copy nxtstr to prvstr
X	lineno versiz 1 sub lt { horiz } if	% get next line
X	prvstr curstr copy pop			% previous is current
X    } { vert } ifelse				% interpolate line
X    /lineno lineno 1 add def			% increment line count
X    curstr					% leave curstr on stack
X} bind def
X
X%
X% face: print a facesaver image on an 8.5" x 11" page
X%
X/face {						% main routine
X    /horint 2 def				% horizontal interpolation rate
X    /verint 2 def				% vertical interpolation rate
X
X    /lineno 0 def				% current line number
X    /horsiz width 1 sub horint mul 1 add def	% interpolated picture width
X    /versiz height 1 sub verint mul 1 add def	% interpolated picture height
X
X    /pikstr width string def			% input image lines
X    /prvstr horsiz string def			% previous image line
X    /curstr horsiz string def			% current image line
X    /nxtstr horsiz string def			% next image line
X
X    0.5 72 mul dup translate			% image corner indented 0.5"
X    7.5 72 mul dup scale			% scale for 0.5" side borders
X    xratio yratio scale				% correct non-squareness
X    /lineno 0 def				% reset line number
X    horsiz versiz 8				% dimensions of source image
X    [horsiz 0 0 versiz 0 0]			% map to unit square
X    { getnext } image				% build image, line by line
X    showpage					% display the image
X} bind def
X
X% we don't need to do anything when we finish.
X/finish {} def
X
X%% EndProlog
SHAR_EOF
chmod 0644 interp.ps || echo "restore of interp.ps fails"
sed 's/^X//' << 'SHAR_EOF' > labels.ps &&
X%!PS-Adobe-1.0
X%%Title:Thirty labels
X%%DocumentFonts: (atend)
X%%Creator: Lou Katz
X%%CreationDate: 06/22/89
X%%Pages: 1
X%%BoundingBox: 0 0 612 792
X
X%%% This is an unpublished work of Metron Computerware, Ltd. that is
X%%% proprietary to Metron Computerware, Ltd.
X%%% It is supplied to the UNIX community for use with FaceSaver images.
X%%% Modified for use by face2ps by Russell Nelson
X
X%%EndComments
X
X/start {
X    /data { 9 array } def
X    /contrast { 1.05 mul 0.15 add dup 0.99 gt { pop .99 } if } bind def
X} bind def
X
X/longestline {
X    /longest 0 def
X    /ptr 1 def
X    1 1 7 {
X	data ptr get
X	/Helvetica  findfont 9 scalefont setfont
X	stringwidth pop dup
X	longest gt { /longest exch def } { pop } ifelse
X	/ptr ptr 1 add def
X	pop
X    } for
X    /ptr 1 def
X} bind def
X
X% print all three columns
X/face {
X    save
X    /colno 0 def
X    longestline
X    gsave
X	0 1 3 cvi {row 197 0 translate /colno colno 1 add def} repeat
X    grestore
X    showpage    % Uncomment if you don't user a postscript spooler
X    restore
X} bind def
X
X% print a line of text
X/line {
X    /Helvetica  findfont 9 scalefont setfont
X    data ptr get dup
X    stringwidth pop
X    0 gt {                              % if line is non-empty
X	/baseln baseln 10 sub def
X    } if
X    gsave
X	0 baseln translate
X	0 0 moveto
X	longest 123.8821 gt { longest 123.8821 exch div 1 scale }  if
X	show
X	/ptr ptr 1 add def
X    grestore
X} bind def
X
X% print a single label
X/label {
X    /baseln 0 def
X    gsave
X	16 -6 moveto
X	/Helvetica-Oblique findfont 5.5 scalefont setfont
X	.2 0 (FaceSaver 6/89)
X	ashow
X    grestore
X    gsave
X	/ptr 1 def
X	65.1179 60.39 translate         % Start of line, from bottom of label
X	1 1 7 {gsave line grestore pop} for
X    grestore
X    gsave
X	16 57.39 translate              % Location of picture top
X	45.1179 57.39 neg scale		% this scale needs to be adjusted some.
X	xratio yratio scale
X	{ contrast } settransfer
X	width height depth
X	[width 0 0 height neg 0 height]
X	{ imagedata } image
X    grestore
X} bind def
X
X% print an entire column of labels
X/row {
X    gsave
X	/Helvetica findfont 14 scalefont setfont
X	data 1 get dup stringwidth pop
X	197 exch sub 2 div 16 add 14 moveto
X	show
X	% set start of first label at bottom of page
X	% adjust the second number below for label feed/slippage.
X	% Larger numbers move up the page, in points.
X	10 46 translate
X	gsave
X	    0 1 10 cvi {label 0 72.1 translate} repeat
X	grestore
X	/Helvetica findfont 9 scalefont setfont
X	(USENIX FaceSaver - June 89) dup stringwidth pop
X	197 exch sub 2 div 8 add 724 moveto
X	-.2 0 3 -1 roll ashow
X    grestore
X} bind def
X
X/finish {} def
X
X%%EndProlog
SHAR_EOF
chmod 0644 labels.ps || echo "restore of labels.ps fails"
sed 's/^X//' << 'SHAR_EOF' > lineup.ps &&
X%! PS-Adobe-2.0
X%% Creator: printface v2
X%% DocumentFonts: Helvetica
X%% EndComments
X
X% set up our starting position.
X/start {
X	currentscreen /p exch def
X	pop pop 50 45 /p load setscreen
X
X	% pointsize of their user info.
X	/pt 7 def
X
X	% This transfer function prevents pure white on 300 dpi laser printers
X
X	{ 1.05 mul 0.05 add dup .99 gt { pop .99 } if } settransfer
X
X	% Parameters
X	/lmarg 50 def
X	/tmarg 50 def
X	/width 100 def
X	/height 110 pt 3 mul add def
X	/sep 5 def
X	/margin 6 def
X
X	/deltax width sep add def
X	/deltay height sep add def
X
X	/ncols 8.5 72 mul lmarg sub width div cvi def
X	/nrows 11 72 mul tmarg sub height div cvi def
X
X	/xpos lmarg def
X	/ypos 11 72 mul tmarg sub deltay sub def
X	/colnumber 0 def
X	/rownumber 0 def
X} bind def
X
X% do each face.
X/face {
X	gsave
X	xpos ypos translate
X
X	/Helvetica findfont pt scalefont setfont
X
X	% output their name, e-mail address, and organization.
X	0 pt 2 mul moveto
X	FirstName show ( ) show LastName show
X
X	/E-mail where {
X		pop
X		0 pt moveto
X		E-mail show
X	} if
X
X	/Company where {
X		pop
X		0 0 moveto
X		Company show
X	} if
X
X	% their face
X	gsave
X	0 pt 3 mul translate
X	80 80 scale
X	xratio yratio scale
X	width height depth [ width 0 0 height 0 0 ]
X	{ imagedata } image
X	grestore
X
X	% move to the next position.
X	/xpos xpos deltax add store
X	/colnumber colnumber 1 add store
X	colnumber ncols ge {
X		/xpos lmarg store
X		/colnumber 0 store
X		/ypos ypos deltay sub store
X		/rownumber rownumber 1 add store
X	} if
X	rownumber nrows ge {
X		showpage
X		/ypos 11 72 mul tmarg sub deltay sub store
X		/rownumber 0 store
X	} if
X
X	grestore
X} bind def
X
X% finish off the page.
X/finish {
X	showpage
X} bind def
X
X%% EndProlog
SHAR_EOF
chmod 0644 lineup.ps || echo "restore of lineup.ps fails"
exit 0
-- 
--russ (nelson@clutx [.bitnet | .clarkson.edu])|(70441.205@compuserve.com)