[comp.lang.postscript] Adobe Type 1 Font decryption programs

sears@dungeon.enet.dec.com (Chris Sears) (10/25/90)

#!/bin/sh
# This is a shell archive (shar 3.24)
#
# existing files WILL be overwritten
#
# This shar contains:
# length  mode       name
# ------ ---------- ------------------------------------------
#    225 -rw-rw-rw- Makefile
#   2846 -rw-r--r-- README
#   5244 -rw-r--r-- chars.c
#   1829 -rw-rw-rw- eexec.c
#   3688 -rw-rw-rw- header.ps
#    377 -rw-rw-rw- trailer.ps
#    537 -rwxr-xr-x transform
#   9054 -rw-r--r-- un-adobe.hqx
#     42 -rw-r--r-- view_header.ps
#    605 -rw-r--r-- view_trailer.ps
#
if touch 2>&1 | fgrep '[-amc]' > /dev/null
 then TOUCH=touch
 else TOUCH=true
fi
# ============= Makefile ==============
echo "x - extracting Makefile (Text)"
sed 's/^X//' << 'SHAR_EOF' > Makefile &&
XCFLAGS = -g
X
Xall:	eexec chars
X
Xeexec:	eexec.o
X	cc ${CFLAGS} -o eexec eexec.o
X
Xeexec.o:
X	cc ${CFLAGS} -c eexec.c
X
Xchars:	chars.o
X	cc ${CFLAGS} -o chars chars.o
X
Xchars.o:
X	cc ${CFLAGS} -c chars.c
X
Xclean:
X	rm -f *.o eexec chars
SHAR_EOF
$TOUCH -am 0627150690 Makefile &&
chmod 0666 Makefile ||
echo "restore of Makefile failed"
set `wc -c Makefile`;Wc_c=$1
if test "$Wc_c" != "225"; then
	echo original size 225, current size $Wc_c
fi
# ============= README ==============
echo "x - extracting README (Text)"
sed 's/^X//' << 'SHAR_EOF' > README &&
XAdobe Type 1 Font Decryption
X
XChris B. Sears
XDigital Equipment, WSE
XMay 31, 1990
X
XThese utilities decrypt an Adobe Type 1 font and leave a raw PostScript
file as
Xa result.  Most of this procedure is documented in "Adobe Type 1 Font Format"
Xavailable from Adobe Systems.
X
XConverting a Type 1 font program into the outlines is in 2 parts.
XIt assumes that you have a Macintosh, a Unix system and Display Postscript.
X
X1. Using un-adobe, which is in hqx format, convert the Type 1 font into
X   a eexec encoded text file.  Un-adobe.hqx was snarfed off of SUMEX.
X   I can't remember who wrote it but you can find that out when you run
X   the program.
X2. Using transform, a shell script driver, convert the results into a list
X   of simple PostScript programs.
X
XHere is a description of the files in this directory:
X
X    transform: a shell script that uses eexec, chars and DPStest to take
X        an ASCII PostScript PostScript file with an encrypted Adobe Type 1
X        font and generate raw PostScript for the font
X    Makefile: a make(1) description file for compiling exec.c and chars.c
X    eexec.c: decrypts a font file encrypted for the eexec operator
X    chars.c: decrypts a font file of encrypted CharStrings.  chars couldn't
X        easily be written to accept standard input because it repositions
X        itself with fseek() after a charstring has been decrypted.
X    header.ps: a PostScript wrapper that removes font hints, squashes
X        procedures and transforms operators and operands
X    trailer.ps: a PostScript wrapper to send the filtered PostScript to the
X        standard output
X    un-adobe.hqx: a Macintosh application that converts an Adobe PostScript
X        font into an ASCII file for transfer to a UNIX system
X
XTo decrypt a Type 1 font first transform the Adobe font file into a text file
Xon a Macintosh.  This can be done with the Macintosh program in unadobe.hqx.
XNext transfer the encrypted PostScript file from the Macintosh to your UNIX
Xsystem with a file transfer utility like NCSA Telnet or Kermit.  Be sure to
Xtransfer this file in text mode and *not* binary mode).  Once the font file
Xis on your UNIX system, you can perform the decryption with the shell script
Xtransform.
X
Xtransform runs eexec and chars, wraps the output with header.ps and trailer.ps
Xand then runs it through Display PostScript.  To interact with Display
XPostScript we use dpstest(1X) found in /usr/examples/dps/dpstest in the Ultrix
Xrelease.  The result is a flattened simple PostScript file containing only
Xthe following operators:
X
X    currentpoint
X    closepath
X    rcurveto
X    rlineto
X    rmoveto
X    moveto
X    div
X    def
X    { }
X
Xview_header.ps and view_trailer.ps are useful for displaying the font using
XDisplay PostScript. Concatenate view_header.ps, the font file and
Xview_trailer.ps together.  The results can be viewed with DPS.
SHAR_EOF
$TOUCH -am 1024152690 README &&
chmod 0644 README ||
echo "restore of README failed"
set `wc -c README`;Wc_c=$1
if test "$Wc_c" != "2846"; then
	echo original size 2846, current size $Wc_c
fi
# ============= chars.c ==============
echo "x - extracting chars.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > chars.c &&
X/*
X * chars.c -- decrypt an Adobe font file of encrypted CharStrings
X *
X * Chris B. Sears
X */
X#include <stdio.h>
X#include <strings.h>
X
X#define TRUE			1
X#define FALSE			0
X
Xint lenIV = 4;			/* CharString salt length */
X
Xtypedef struct {
X	char *command;
X	int value;
X} Command;
X
XCommand commands[] = {
X	{ "notdefined_c0",	0 },
X	{ "hstem",			1 },
X	{ "notdefined_c2",	2 },
X	{ "vstem",			3 },
X	{ "vmoveto",		4 },
X	{ "chars_rlineto",	5 },
X	{ "hlineto",		6 },
X	{ "vlineto",		7 },
X	{ "rrcurveto",		8 },
X	{ "chars_closepath",9 },
X	{ "callsubr",		10 },
X	{ "return",			11 },
X	{ "escape",			12 },
X	{ "hsbw",			13 },
X	{ "endchar",		14 },
X	{ "notdefined_c15",	15 },
X	{ "notdefined_c16",	16 },
X	{ "notdefined_c17",	17 },
X	{ "notdefined_c18",	18 },
X	{ "notdefined_c19",	19 },
X	{ "notdefined_c20",	20 },
X	{ "chars_rmoveto",	21 },
X	{ "hmoveto",		22 },
X	{ "notdefined_c23",	23 },
X	{ "notdefined_c24",	24 },
X	{ "notdefined_c25",	25 },
X	{ "notdefined_c26",	26 },
X	{ "notdefined_c27",	27 },
X	{ "notdefined_c28",	28 },
X	{ "notdefined_c29",	29 },
X	{ "vhcurveto",		30 },
X	{ "hvcurveto",		31 }
X};
X
XCommand escapes[] = {
X	{ "dotsection",		0 },
X	{ "vstem3",			1 },
X	{ "hstem3",			2 },
X	{ "notdefined_e3",	3 },
X	{ "notdefined_e4",	4 },
X	{ "notdefined_e5",	5 },
X	{ "seac",			6 },
X	{ "sbw",			7 },
X	{ "notdefined_e8",	8 },
X	{ "notdefined_e9",	9 },
X	{ "notdefined_e10",	10 },
X	{ "notdefined_e11",	11 },
X	{ "chars_div",		12 },
X	{ "notdefined_e13",	13 },
X	{ "notdefined_e14",	14 },
X	{ "notdefined_e15",	15 },
X	{ "callothersubr",	16 },
X	{ "chars_pop",		17 },
X	{ "notdefined_e18",	18 },
X	{ "notdefined_e19",	19 },
X	{ "notdefined_e20",	20 },
X	{ "notdefined_e21",	21 },
X	{ "notdefined_e22",	22 },
X	{ "notdefined_e23",	23 },
X	{ "notdefined_e24",	24 },
X	{ "notdefined_e25",	25 },
X	{ "notdefined_e26",	26 },
X	{ "notdefined_e27",	27 },
X	{ "notdefined_e28",	28 },
X	{ "notdefined_e29",	29 },
X	{ "notdefined_e30",	30 },
X	{ "notdefined_e31",	31 },
X	{ "notdefined_e32",	32 },
X	{ "setcurrentpoint",33 }
X};
X
X#define MAX_ESCAPE		33
X
X#define CR				4330
X#define CC1				52845
X#define CC2				22719
X
Xunsigned short int cr, cc1, cc2;
X
Xunsigned char
XDeCrypt(cipher)
X	unsigned char cipher;
X{
X	unsigned char plain;
X
X	plain = (cipher ^ (cr >> 8));
X	cr = (cipher + cr) * cc1 + cc2;
X
X	return plain;
X}
X
Xvoid
Xmain(argc, argv)
X	int argc;
X	char **argv;
X{
X	FILE *in, *out;
X	unsigned char in_buff[BUFSIZ], byte, *rd_pos, *count_pos;
X	int in_size, line_pos, i, count;
X	long value;
X
X	if (argc != 3) {
X		fprintf(stderr, "Usage: %s input output\n", argv[0]);
X		exit(0);
X	}
X
X	if ((in = fopen(argv[1], "r")) == NULL) {
X		fprintf(stderr, "%s: can't open %s\n", argv[0], argv[1]);
X		exit(0);
X	}
X
X	out = fopen(argv[2], "w");
X
X	setbuf(out, NULL);
X
X	/*
X	 * TODO: rewrite this so as not to use a seek and to use stdin.
X	 */
X	for (;;) {
X		line_pos = ftell(in);
X
X		if (fgets(in_buff, BUFSIZ, in) == NULL)
X			break;
X		in_size = strlen(in_buff) - 1;
X
X		if (strncmp("/lenIV", in_buff, 6) == 0)
X			lenIV = atoi(in_buff + 7);
X
X		if ((rd_pos = (unsigned char *) strstr(in_buff, " RD ")) == NULL) {
X			fputs(in_buff, out);
X			continue;
X		}
X
X		/*
X		 * We found an encrypted CharString.
X		 * Back up and determine the number of encrypted characters.
X		 * These have the form: dup 105 9 RD 9bytesofdata noaccess put
X		 */
X		for (count_pos = rd_pos - 1;
X			(count_pos >= in_buff) && (*count_pos != ' ');
X			count_pos--)
X				;
X
X		if (*count_pos == ' ')	/* This can be at the beginning of a line */
X			count_pos++;
X
X		/*
X		 * Write out the beginning of the string without the RD stuff.
X		 */
X		fwrite(in_buff, count_pos - in_buff, 1, out);
X		fprintf(out, "{");
X
X		count = atoi(count_pos);
X
X		/*
X		 * Seek to and read the binary data.
X		 */
X		fseek(in, line_pos + (rd_pos - in_buff) + 4, SEEK_SET);
X		fread(in_buff, BUFSIZ, 1, in);
X
X		/*
X		 * We must restart the decryption machinery for each CharString.
X		 */
X		cr = CR;
X		cc1 = CC1;
X		cc2 = CC2;
X
X		/*
X		 * Skip over the salt.
X		 */
X		for (i = 0; i < lenIV; i++)
X			byte = DeCrypt(in_buff[i]);
X
X		/*
X		 * Translate the buffer.
X		 */
X		for (; i < count;) {
X			byte = DeCrypt(in_buff[i++]);
X			if (byte == 11) {			/* return */
X				fprintf(out, " %s", commands[byte].command);
X				break;
X			} else if (byte == 12) {	/* escape */
X				byte = DeCrypt(in_buff[i++]);
X				if (byte > MAX_ESCAPE)
X					fprintf(out, " not_defined_e%d", byte);
X				else
X					fprintf(out, " %s", escapes[byte].command);
X				continue;
X			} else if (byte < 32)
X				fprintf(out, " %s", commands[byte].command);
X
X			if (byte >= 32) {
X				if (byte <= 246)
X					fprintf(out, " %d", byte  - 139);
X				else if ((byte >= 247) && (byte <= 250))
X					fprintf(out, " %d",
X						(byte  - 247) * 256 + DeCrypt(in_buff[i++]) + 108);
X				else if ((byte >= 251) && (byte <= 254))
X					fprintf(out, " %d",
X						-(byte  - 251) * 256 - DeCrypt(in_buff[i++]) - 108);
X				else if (byte == 255) {
X					value = DeCrypt(in_buff[i++]);
X					value <<= 8;
X					value += DeCrypt(in_buff[i++]);
X					value <<= 8;
X					value += DeCrypt(in_buff[i++]);
X					value <<= 8;
X					value += DeCrypt(in_buff[i++]);
X					fprintf(out, " %d", value);
X				}
X			}
X		}
X
X		fprintf(out, " }");
X
X		/*
X		 * Seek just past the CharString bytes and continue.
X		 */
X		fseek(in, line_pos + (rd_pos - in_buff) + 4 + i, SEEK_SET);
X	}
X
X	fclose(in);
X	fclose(out);
X
X	exit(0);
X}
SHAR_EOF
$TOUCH -am 0601105090 chars.c &&
chmod 0644 chars.c ||
echo "restore of chars.c failed"
set `wc -c chars.c`;Wc_c=$1
if test "$Wc_c" != "5244"; then
	echo original size 5244, current size $Wc_c
fi
# ============= eexec.c ==============
echo "x - extracting eexec.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > eexec.c &&
X/*
X * eexec.c -- decrypt an Adobe font file encrypted for eexec
X *
X * Chris B. Sears
X */
X#include <stdio.h>
X#include <strings.h>
X
X#define TRUE				1
X#define FALSE				0
X
X#define EEXEC_SKIP_BYTES	4
X
Xunsigned short int er =		55665;
Xunsigned short int ec1 =	52845;
Xunsigned short int ec2 =	22719;
X
Xunsigned char
XDeCrypt(ch1, ch2)
X	unsigned char ch1, ch2;
X{
X	unsigned char plain, cipher;
X
X	/*
X	 * Decode hex.
X	 */
X	if ('A' <= ch1 && ch1 <= 'F')
X		ch1 -= 'A' - 10;
X	else if ('a' <= ch1 && ch1 <= 'f')
X		ch1 -= 'a' - 10;
X	else
X		ch1 -= '0';
X
X	if ('A' <= ch2 && ch2 <= 'F')
X		ch2 -= 'A' - 10;
X	else if ('a' <= ch2 && ch2 <= 'f')
X		ch2 -= 'a' - 10;
X	else
X		ch2 -= '0';
X
X	/*
X	 * Decode cipher.
X	 */
X	cipher = ch1 * 16 + ch2;
X
X	plain = (cipher ^ (er >> 8));
X	er = (cipher + er) * ec1 + ec2;
X
X	return plain;
X}
X
Xvoid
Xmain(argc, argv)
X	int argc;
X	char **argv;
X{
X	FILE *in;
X	char in_buff[BUFSIZ], out_buff[BUFSIZ];
X	int i, o, in_size;
X	int skip_salt = TRUE;
X
X	if (argc != 2) {
X		fprintf(stderr, "Usage: %s input\n", argv[0]);
X		exit(0);
X	}
X
X	if ((in = fopen(argv[1], "r")) == NULL) {
X		fprintf(stderr, "%s: can't open %s\n", argv[0], argv[1]);
X		exit(0);
X	}
X
X	/*
X	 * Just copy to output until we see an eexec.
X	 */
X	while (fgets(in_buff, BUFSIZ, in) != NULL) {
X		if (strcmp(in_buff, "currentfile eexec\n") == 0)
X			break;
X		fprintf(stdout, "%s", in_buff);
X	}
X
X	for (;;) {
X		if (fgets(in_buff, BUFSIZ, in) == NULL)
X			break;
X		in_size = strlen(in_buff) - 1;
X
X		/*
X		 * Decrypt a line of hex.
X		 */
X		for (i = o = 0; i < in_size; i += 2)
X			out_buff[o++] = DeCrypt(in_buff[i], in_buff[i + 1]);
X
X		/*
X		 * Skip the salt if this is the first cypher line.
X		 */
X		if (skip_salt) {
X			fwrite(out_buff + EEXEC_SKIP_BYTES, o - EEXEC_SKIP_BYTES, 1, stdout);
X			skip_salt = FALSE;
X		} else
X			fwrite(out_buff, o, 1, stdout);
X	}
X
X	fclose(in);
X
X	exit(0);
X}
SHAR_EOF
$TOUCH -am 0601103390 eexec.c &&
chmod 0666 eexec.c ||
echo "restore of eexec.c failed"
set `wc -c eexec.c`;Wc_c=$1
if test "$Wc_c" != "1829"; then
	echo original size 1829, current size $Wc_c
fi
# ============= header.ps ==============
echo "x - extracting header.ps (Text)"
sed 's/^X//' << 'SHAR_EOF' > header.ps &&
X%!
X%
X% header.ps
X%
X% After interpreting a decrypted Adobe font program there are four
dictionaries.
X%
X%		font (implicit)
X%		FontInfo
X%		Private
X%		CharStrings
X%
X% The strategy is to redefine certain operators, interpret the font and dump
X% the resulting dictionaries while filtering out font hint operators.
X%
X
X/myString 200 string def
X/Helvetica findfont 20 scalefont setfont
X
X/readonly { } def
X/executeonly { } def
X/noaccess { } def
X/definefont { } def
X
X/myWriteString {
X	print
X} def
X
X/numString 20 string def
X
X/printNums {
X	/i exch def
X	i 1 sub -1 0 { index numString cvs print ( ) print } for
X	i { pop } repeat
X} def
X
X/clearStack {
X	cleartomark mark
X} def
X
X%
X% commands for starting and finishing
X%
X/endchar { clearStack } def
X
X/seac {
X	/achar exch def
X	/bchar exch def
X	/ady exch def
X	/adx exch def
X	/asb exch def
X
X	mark Encoding bchar get load exec pop
X	/xOrigin xOrigin adx add def
X	/yOrigin yOrigin ady add def
X	mark Encoding achar get load exec pop clearStack
X} def
X
X/hsbw {
X	pop /xOrigin exch xOrigin add def xOrigin yOrigin 2 printNums
X	(moveto ) myWriteString clearStack
X} def
X
X/sbw {
X	pop pop /yOrigin exch yOrigin add def /xOrigin exch xOrigin add def
xOrigin yOrigin 2 printNums
X	(moveto ) myWriteString clearStack
X} def
X
X%
X% path construction commands
X%
X% convert the operators and operands to rmoveto, rlineto and rcurveto.
X% chars_closepath has different semantics from PostScript closepath.
X%
X/chars_closepath {
X	(currentpoint closepath moveto ) myWriteString clearStack
X} def
X
X/hlineto { 0 2 printNums (rlineto ) myWriteString clearStack } def
X/hmoveto { 0 2 printNums (rmoveto ) myWriteString clearStack } def
X/chars_rlineto { 2 printNums (rlineto ) myWriteString clearStack } def
X/chars_rmoveto { 2 printNums (rmoveto ) myWriteString clearStack } def
X/vlineto { 0 exch 2 printNums (rlineto ) myWriteString clearStack } def
X/vmoveto { 0 exch 2 printNums (rmoveto ) myWriteString clearStack } def
X
X/hvcurveto {
X	/dy3 exch def /dy2 exch def /dx2 exch def /dx1 exch def
X	dx1 0 dx2 dy2 0 dy3 rrcurveto
X} def
X
X/vhcurveto {
X	/dx3 exch def /dy2 exch def /dx2 exch def /dy1 exch def
X	0 dy1 dx2 dy2 dx3 0 rrcurveto
X} def
X
X/rrcurveto {
X	/dy3 exch def /dx3 exch def
X	/dy2 exch def /dx2 exch def
X	/dy1 exch def /dx1 exch def
X	dx1 dy1
X	dx1 dx2 add dy1 dy2 add
X	dx1 dx2 dx3 add add dy1 dy2 dy3 add add
X	6 printNums (rcurveto ) myWriteString clearStack
X} def
X
X%
X% hint commands
X%
X/dotsection { clearStack } def
X/hstem { clearStack } def
X/hstem3 { clearStack } def
X/vstem { clearStack } def
X/vstem3 { clearStack } def
X
X%
X% Arithmetic command
X%
X/chars_div { div } def
X
X%
X% Subroutine commands
X% All OtherSubr routines are hint related
X% For 0, 1, 2 the stack contents are left unchanged.
X% For 3, the trailing pop will push a 3 on the stack.
X% See p. 95 of the Black Book.
X%
X/callothersubr {
X} def
X
X/callsubr {
X	/i exch def
X	i 3 gt { % normal subroutines
X		Subrs i get exec
X	} if
X	i 3 eq { } if
X	i 0 eq {
X%		pop pop pop			% Flex height control parameter and end points
X		/yEnd exch def /xEnd exch def pop
X
X		/y5 exch def /x5 exch def
X		/y4 exch def /x4 exch def
X		/y3 exch def /x3 exch def
X		/y2 exch def /x2 exch def
X		/y1 exch def /x1 exch def
X		/y0 exch def /x0 exch def
X		/yRef exch def /xRef exch def
X
X		x0 xRef add y0 yRef add x1 y1 x2 y2 rrcurveto
X		x3 y3 x4 y4 x5 y5 rrcurveto
X
X%
X% The Flex can be replaced by a lineto.
X%
X%		xEnd yEnd 2 printNums (lineto ) myWriteString
X%
X
X		/chars_rmoveto { 2 printNums (rmoveto ) myWriteString clearStack } def
X	} if
X	i 1 eq {
X		/chars_rmoveto { } def
X	} if
X	i 2 eq {
X	} if
X} def
X
X/return { } def
X/chars_pop { 3 } def	% chars_pop transfers from PS stack to BuildChar stack
X
X%
X% setcurrentpoint shouldn't appear in a charststring program
X%
X
SHAR_EOF
$TOUCH -am 0612185890 header.ps &&
chmod 0666 header.ps ||
echo "restore of header.ps failed"
set `wc -c header.ps`;Wc_c=$1
if test "$Wc_c" != "3688"; then
	echo original size 3688, current size $Wc_c
fi
# ============= trailer.ps ==============
echo "x - extracting trailer.ps (Text)"
sed 's/^X//' << 'SHAR_EOF' > trailer.ps &&
X%!
X%
X% trailer.ps
X%
X% Traverse the dictionaries and arrays.
X%
X
Xbegin
XPrivate begin
XCharStrings begin
X100 dict begin
X
X100 100 moveto
X
XCharStrings {		% name procedure
X	gsave
X		/xOrigin 0 def
X		/yOrigin 0 def
X		(/) myWriteString exch myString cvs myWriteString ( { ) myWriteString
X		mark exch exec cleartomark
X		( } def\n) myWriteString
X	grestore
X	0 40 rmoveto
X} forall
X
Xshowpage
SHAR_EOF
$TOUCH -am 0612181690 trailer.ps &&
chmod 0666 trailer.ps ||
echo "restore of trailer.ps failed"
set `wc -c trailer.ps`;Wc_c=$1
if test "$Wc_c" != "377"; then
	echo original size 377, current size $Wc_c
fi
# ============= transform ==============
echo "x - extracting transform (Text)"
sed 's/^X//' << 'SHAR_EOF' > transform &&
X#!/bin/sh
X#
X# transform -- transform an Adobe Type 1 font file
X#   encrypted with eexec and CharStrings into raw PostScript
X#
X
XPROGRAM=`basename $0`
XTMP1=/tmp/$$.tr1
XTMP2=/tmp/$$.tr2
XTMP3=/tmp/$$.tr3
XTMP4=/tmp/$$.tr4
XTMP5=/tmp/$$.tr5
X
Xtrap 'rm -f /tmp/$$.tr?; exit 0' 0 1 2 15
X
Xcase $# in
X2) ;;
X*) echo "Usage: $PROGRAM \"Adobe Type 1 font file\" \"output file\""
X   exit 1;;
Xesac
X
Xeexec $1 > $TMP1
Xchars $TMP1 $TMP2
Xsed -e '/definefont/,$d' $TMP2 > $TMP3
Xcat header.ps $TMP3 trailer.ps > $TMP4
XDPS > $2 <<end-of-here
X#$TMP4
Xend-of-here
SHAR_EOF
$TOUCH -am 0627142190 transform &&
chmod 0755 transform ||
echo "restore of transform failed"
set `wc -c transform`;Wc_c=$1
if test "$Wc_c" != "537"; then
	echo original size 537, current size $Wc_c
fi
# ============= un-adobe.hqx ==============
echo "x - extracting un-adobe.hqx (Text)"
sed 's/^X//' << 'SHAR_EOF' > un-adobe.hqx &&
XDate: Tue, 13 Mar 90 23:59:57 -0800
XFrom: C43MRP%AVIARY.gm@hac2arpa.hac.com
XSubject: unAdobe.hqx
X
XunAdobe is an application that converts an Adobe type 1 font into printable
XASCII characters that can be edited into a postscript document.  Written by
XJerry Keough and Ted Ede of the Mitre Corp.
X
XEnjoy!
X
XMark Probert
XDelco Electronics
X
X(This file must be converted with BinHex 4.0)
X
X:#h9Z3@4[BQ8ZFfPd!&0*9#&6593K!3!!!"Ld!!!!!2rl8dP8)3!"!!!BY(*-BA8
X"!!!!!!!!!!)!"h9Z3@4[BQ8Y6'pRT3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
X!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%&38%a+5e4&)3#IZ*E*RlL@c!!!(Hi
X!!!!!!!!B,J!!!!#eC`!!!!!!!!!!)T!!!!!%#!LJ!j+!(!i'0%83`)i"p`"!)4#
X%J)%KBGb-+F1QB8%#*J#d+%!!dB%kES+3!(NMTS`!JN'J3''LC!Q9)L!#!J)!T#%
X$3J&McUaj-bH!R6dp+QeBJFdRA*D5+HhJEJF"D!#D@%55KJbC-QimMKS)S&D!L4F
XcEZcBm!3!G!i$E0RTN3KC+fF*&#LLTX`B1NUlN!"pNlF!%6PTl*44kTB"J&`!c#e
Xe@qia!(Y,q3$J"k"2!#Td!fC!!`#"3#G@rU&c%SFeL,!-)%!!)j!!"Zd!6N#i+&d
X&8!XJrpK9HI+M"6mK50`%e`f!!HJA!*cSNU"PaaGq4QkE%0+QRaAQcRhhC-!F3Hr
XITE-mHE%E!4`"d+8c`#5pJTd@Ae5c9bhGJUrpUqPLJ4$X0IHDIK!8L)"d#1LJi([
XakF+!'2L9GL!k,8$4R"+ZP2C'3'$!!F9[`BN)5iF)I&KD#f%K%0a`a4fAA(!&-L"
XG",TBKaf-aL(A"Mp+"0%12dL!J)!8J%3BJ5Fk'L%L0"dbJ"i$F-!#jBSp)3#'*J$
X@4dZAZP$J$'d!%,'"CJ(`8`5C1X6S)cp3a1L%G!CSFkC!DT)*!K+!-0#6!@4B!!d
X3-1`!J!&1l!1!!2l`iJm`rU$cMc,r8$1T%ek!m!886cJ"$@Vq1-1DDbd1iBirm-$
XaJ`MB4)(-2rcmX"X$U#L5(!!2*1F20$r`F*SZ$[M4J4[q["-U(!"!i%+S2`#!#L,
X$k3S2+Sc!`%-!N!"!mJ85`!6#Q3$0bTSX+T0)L`SKQ'Vka$X!+1!TU++f&XGVTCQ
X+UUUXZJUVZ,6D'PDZa2,U+fl!8M"XXFFQZk`cc6iV,J6L5N#ZZHKQqX@kcEfEQML
XMaY'$CNDSpM%!-[bMcXF"L"!FbX,miijk3T`b)cT)k$'!"am-h#X!!m$a$h4#R""
Xc+K2Jp`mjqj'$bK`lSp#"CJ2m)`kbbNSGVUmBe#`!0p,jSmh14M`YN!$89,YJ03!
Xl-k#e*&hcXR-9BJG!YX*Rlkb!eR2UiSmR1mmKK0P6dbh1eFeTMDMHJZ`Xb0pc9cd
XifVkUV8F!`(4YaXkEa0dii)4,(S!QA51ambZ-"qiii3R8(!!5AE1`FbkPPefhVkR
XV!3$AHN2XDc0JDfikjj!!!e!l!+adMFA1[2[+51b#Selc89hMJ2c1d[JZqq-l$jq
Xh2aC-Ikd)c*mHr2!L50H22F1P3JF%(bJ38!"+!("'3!5!i8l5U9#!U40e,2"%(A5
X!!`""B)BdX+%-$TL#AplJ"M+!J!aT#!-EhR!'(9K!!8P`J`$T3%!$PX%#$6"#'Z3
X`"`j#8))8e-%6U)#'-S#J#8QJJK4`-S3hb!%10J`$(G,!3"#%B3jcU%-EA1L'0i"
X!$Q@B!`lG-)FdL-'!DD"$(JKS3a$3SB8JU--FA2J'-eJ4$@QBJ`rK!!FfT'%-1Z5
XK'ea!!aD'FBaP2'-DHrM')R,3$&@FJ`6,`!)#PS%M"%5L#qPJa$'m!3jjF)%&$U!
X#%)#JNBp%`42G%!Bj6"'2FQL$$N'3!!Bh%0+(EJ""%+B`K#3NJBUCh'3"$kK)&EK
X4M'%JSaR4Z--HSJ31B4M$'Q"*48pb-T4"%!0,bR##19L!"&G!$"hS!"B3L''+5LL
X$(#`*JL@8i3ee1!-D31P!+T6"J8Ai5LYVL%M%D*1$U3""$(+!!a`iFiSXG#%-C8K
X$'q*3$R0Fi`94ST*KZZ#I&J#!"))QR3)S!cArJ)Gd$Z!$)IP$"#p!!#VFJ!TrT%)
X#UB""+TJaY$fJ!JT`#-!+J!#N(@LQ!855$Mm)JB3I3D'Pr-ME!-LJ"10!BAi!S%@
XdA#URR38J&F4S%J2Dm!pB'3'RKS$T5hmN"1N%!!0#-%i46"S!H[5$#M"S`9@P!)3
XG!1'UkRN"$cJe"5S8jkUT!-8+[Y!2+#LK&@h&+3eHS&8Sh)J#G'fVG##!#4"d"`S
X[J%"BkbUG"rK#1[P!4PlYUJX)''+aU4M&@pYk"@!3i5K5MGmC01%QTmT"U6$0Q`"
XF3CYrX-i,G,)!U%64XC&"`@8MZ`'0c-D1jl&"9k+J&`-LqMbcqNS!dP'!(l$`"0c
X'E%DXRBiNULB+p`P%X`%K$fb%-"Z%k(CRTP81+b)UR36BJPi)J)%VrS'+G'fU8p"
X!J![iZC+@"&3#U1N(1cUQ@hZPDP@YHP@XI*9G9#@R(`V943)qk`B!rpFGd[Q(%C6
XJ!J#E)5!')"-MSP9JH-LU(qi!,hFPT)FHX*8G5LJ`1ajm+$+KJ3(+UBCm58`##J2
Xi`[IM!9'+)0DEB)%+mK'!Kq9,*JkJq"r2@(&!*$!Fm2i!![+Kaij",')5Dm$&&Qj
X`KPZdB3BJB-RQjC6'60Ba',9R4[19%!JmE$)[PfBrB@D!(mLX$M-[5%+5B,0jUB"
XH8*'$[Q&4J(haP9pB84K9iN+!VX+m!%Kif"rZm,)rDNZX!$'!!)GqfAU@&D!'#!)
XrrN$DXZi-,'@`*p25FB!6&-hS5,dQdi%0lT@rJ'K5bmF!N6Dc!h5&MP-M$FN#0NH
XN2meT"dL!ep*T!!ZbA'FV"!3*ji#!)m-#!4(!TMa&d!F!@#!"$0KJB1R)!!8#)!!
XKi%S#mXK*&*Ea$hP-!4"Q-!F6[N'!"9RX'jb*VUGJ%!-Cc)!'0E$"$A#3!)-J#'%
X)4#L#%4$+0RQj&VDDN5dl@X!(*PaKi2q3!!5DR`H&Q2Pd4T)iVR+5#`%&-0Hjm*0
XIG(9,h4jIPlmcfZkE$q!"m)UA[-6fP%!0!!4m!#%9b3""FFq"!3#B`!%S3%!B$,"
XZ!'#!IbpB!!PDm!pCQ!%NAq$IGQia$$%3i"E%%)-"5,!#%+R$U8K33YF0F!B)"%%
XI!B!$$&BKd,-(!!a1*3$A!b)G!("!#B)!!c'J!i)&!!-A!p$!#BJULi#-Y1NJq!$
X58lB!B3"H!d0S"q)M8(CB"1)-""!"%-"!$a!!3353!"#"iZYJ,AVB!1GK8-!CJ%Y
Xk(Y$M"MK(0K!!!3+Qbk,X)QMmiber"JGi(J33-)-peXeYC2'2q!))+G)4X+jr1%-
X)VfM1#`ibd!m0k%-D#-)k!'#"kGYGjk!!`!dqe(-#B%`'QP)#%-kJ!6rpSaT29hi
XGh*q1"rY$(Q)(!18"i!pe',m1%G9mcaGpZd9p3Q"p"`J!'J"qc-FZk2F&kRF'$1"
Xqd'"rZL"rraH!lq"md#Gp"SL!f!Gq#A"qkEGq#&"6rk!+mq-2KX!rq4F"CL!#!YL
X"$2!$D`!!"'"di"F!jaH"*mKd+XKrA-!r#F!%8`!&hY3'b)+$-H!#-K!%!$!&4!8
X1*V8Srq!0h2%2f#!%VG"d@DJ+*J8$-!"cZX!6GBF&G3F+6L9UZK!!%X!#6@!#%2J
X"Cd!#GJ!!0Y!#!!!#iE!%,I93%e94&j94'p941KF*``!+,H"8j6-0BA"8#V!'%'"
X5rj!!$rp32(9!LIG`LIb6KCJB"LT3GQ[!!CVi$kj!LIM`$l$!2j4SLDI)"rqJ$kV
XBL86P#PQiLR8!!6JJ!!GJ"KDJL`)3#@T!!2rh%VJb"3"J"[6J-r`MIdI3$[S!!N,
X3G3H!!0Xh%!G`!CVa%K%!"G[R!&'`I3EJMFd4MJ$3!%,!GJK`!pX)!"5JMHHB,1C
XM#Xpi$ri`M3"3MGXA%0Q)*[T(MZ!SMZE)!1D)MZV)MS[LM[$B!2+S#rhJ"[`6!jc
X4!!UJ"*hBKD6!2e!JHDT3HdeR"JV!K8dA"4bC#[4J!N$30@L3!(pNChEki!q3!,"
XfEIH5J0!e*!!#A3F!B#!05V#,MU!'MB3(!3!$3i!2!8!"4J)*N8!($!!,J["")K!
X&)B!-4bN#J#!%%5!#H#!!UL!#L!!#JK!0UC!!-A8!#Q2!2`63K%m)!-J'$-!!!Y"
X"!4"PG#r`)4$JMQ%`Dq`b%"L`EJ-`!-6&2mJ'!`"!!Q`T"-83$#D`1N0`$-"J$FJ
Xa"2mQ$)mC##!`!%9R)hA3PX!`Pa4`"N)!Ph4TPhMT)&$BPpr`Pi'jQHIJPTjj"Si
X%(4J3"KkJ")!`M0!3IAM9%aK3PmRLMRi*Q*e5"mJ5#-#!E$i!!#S!!'SJ!%3!##`
X3!-e*")&JQ)XT"&FC#(M`!H-J#H-!#H13!!L`-!KY3!#3!$!)8K!)8d!%E1!15P!
X)d`N)Zf!)daN)4FF(D+Q@8"K4I2FK9,+(EaQJ)##J"*TiQZ)#Rb#BV8PlGSNX!rU
XJ"9UJGJN$F5N((f!15#!*K"+A!Y!6"a!!m(#Aa$F!,h!&Km)&`iPXm-#J4ZHJ%3U
XK-%TqG2!"&'Th'%S*3'#K0HS"'+UK-#!!B$#1m"!3A!8,3I!'pV#M(CU2G[!2iE!
X#a`!$G`N("b!$d-%"!J#&"`!*3G#Ni!#P-*!!%m6h!#9D'PV'QZ$!SK5JSp#K!6d
X+"-J#"LG)Q-N)"88D"'f`M!F`9`VBEIN)#8*!"rm!$LTJ"!)!!9)+!-!J!'B!!fa
XUG'm+!fpR!%T!TfE!!9cP*`$`!@mJ$c@+!8Yk!))D$S9kU)QkU-4h!%"`$Vlj%JT
X!"0p`TQh*SSKDS4HDS4[UMU(UQiiK!8-TSYm3!!1!SJVUPL$`)A**IR*`!##3!!'
X"J!P4N!!-X4LFCBS!XYUDEiQX)U#Xc*S"`3#YdUS2e'ULeTULf(UXlVLY4VHXc@S
X%J2#YdIS2q$#ZCQUZi!!-RiUZ'U#Z(Z#E&!!!(M!SKA)SLC+3!)lK'!hK!3$J!P3
Xk#iKJ"IVPP`H!-Hj#R!FJ!KK!!KNJ#))J#i)!XIpJ$f"J$P5+X4T,#)&!#i%!XL*
XV$CaTTHk)VKBJ!NL!,#,3Q6KlXcUEXjf*I9-3"'IJ!A$`!9`U$NN3"%-+!$#3!!h
XabJrdUJ!8bcm4N!!&Q`S'YA81pkUZ')#Z(1#[GNFe'%!$!T8"K8F'!V"Y8m!G#$!
X,#'!&P-)2CL!!K5Ha82!)5+F!kSS!*1#I03S"BLX"'L!,!Q#ffbB"`J!'!L!"fK!
X&E`X,!8!#Ak!Zl1)Zd$#Vk2TVrLP39!-"-!X"2cX&31!5A$ULA'#h!+J!k1SHbB)
X"FJ!!kXS!J%%"'3!,h(&-5#!&Sm3G%$!,#Z#fX()'4i)%S!X'hY#kN!#V+CcL!i%
X`Ep""!%2!,JBJ!`"3$NNJ$F%!!P%J!TH!E!!!$UdV"8J!"KT!!MVNMKSJ$B2,!*3
X3!&13!(`!)!IrJ,J3X,K[UbrNX'i(N!!XJH!#5B#l)(!&RN)#02S"E1#q-[!"EX!
X!4"!%Z-ZP"B`XFK!!QL)#9r!#!K#l%!!0`5!&3N!*39$!J%'lEb!!2bS"`)#i%Y"
XR-98()dV"E3QRb3)"+D`[r#$!-%$!"Sc!#Xc!3H$!lK["QQ,"'1c"(2`''#$#*"b
X-%)#M'M`%55Zr62Zfr*0i"i`%35!$r#8#NIXK""#l%3!"83`V@[brB%!!e-U@2!F
X$H!!!9*-"''`$!!#CYR#N"'!$!B!(r`!"Jf$&3H)'!K$"2bX,"bJ!-L!!Z&X%m##
XT4a#L!8!$#f!#5Q!*`%!*5d!%h'%!&6!#M!XVL(bAPX$!3f!,32!'"J$(L%X"6%Y
XZr#!&4,"Z$("dG4!&`B#i8"!-#18-3H!1cKF#,E+(-F"X4ZGXc4%#89#B3N!D,#!
X%U,#`5K!!6`F+3#S!S$!!2G!6%L$-$#!#bi`#Q+,&m%B3lK)0#!8-ZI`2`-$,[bN
X"[qb1h(I-GJF+"e$0h)I0-V$-&J!#++#dD5S1J!!-F1%$i`!)i3!)`S`!9YR0Ar$
X0!5&UiT`Dj+c,j``E!J8+&#$2cGBLpFap#&fh6Y$3jPc1%GdZ!VA1TQ%"S&!"mLa
XUAU$&TG[4i`c5*-epk1`q%J!+%j!!dJMGdKjYT,S-#qJX!5-0c!15caS!#LF)",l
XScK`!#Z5"!%-!&b!J!Zj3'L)3*D$3!2+X@LZGd2%'!!apbqAX$1MX!%(G(1e-e%+
X3!-mES-c[l,SB[F`B)-r`p@jG6EPJVF[1X-k1J3'J%0Fpi3!&VFd,Qp0fkp'iM0I
XV60BBS0I6KXkQi3+J3!3@[G'&IGI1apKm(3%T(GM,c!'%lG+TFGLA,G%Bi0M[,!%
Xi[G8kEGPjhFYm(3$bl#i@3`9fqbQT`G1U10CPl4K$VB"+cG4b(343AG$@NLbJi!)
X)VG$Y!YUU@-iq(4CNVFi5hGXDm0X-m04lk(+q!J((lGaA,GI*AGI-,GTL$GflIGB
X+D0T,[3$J[GA+(FkX2G0PAG*TVB#JN!!!UFh5K3d+`iCfR$$'A`!+!)afS4Hj6`!
X+'H!0R#&UD#F)!+k)6S"fH!!+0K$K!8!(SD!"hNF!&Ui'$li"&Zi&,l#9$-(KD-F
X&)mk91'MK8M$'(a!+)Z!#L'$K2[$J)f$K02$J*H!#YfN!3R!*&Ni#&Zi",UiTS#$
XND#HANIX&S@!#-QlK"VhNSB!#6bjYqP$N!Ai#%3i!m1$LSH!"93i!j2$JLLGYf[$
XJ)F$MDZ$M3#jY"b9Ya)$PS!!#@ki,!"i+5"$QVJ!+AGX6*Nim@K`+(5!##+!T),#
Xr05PYNZ$LS-!%2,lPKX$S+5PYIX$S6E$PG2$J+l$P(VlNS*!!!PX1"JqZ!PYZ"3q
XH"&[1"!pZNG)Q"!qq"&Z1!b-q!2R-iA8JHSRhi#iJ!N'`jA!TP+Eajal`!eZC%lB
XqiN1jiY,fRbq3!!!aX+Kd6T`k1AbT#3#mG3iIi!-J%!&r&hKQB!"`-!NGMJ**J!$
XrHJ"RB!$@mJq,B$mX)*3BB!*KiES4i(L"aqY4N!!))T!!!J&KlaVJ!J%3"BH!,0-
X3$,1`$'43'dV!lr)$!@SJ%#SJ!QQ!Jp2J$%S3!6FB!%6q!##`PDSJ#F[-a[p!!Vk
X#J`$JX@dJ%!C!!0i'#*)J#!J3#!(a#F(J#C`K!5U`(P"Bk&33"8M`!U4"%#"!!Gf
XZiH2a!963N!!!i!e+)!&Q`!)LX*al'2#!!!Q(i%,!b`#K`3!I"!*8)!*+82!JF!#
X6!!b4B08Z!!*-S&CJB!HD8AIQi&6FA)DJ%28"8AXi+#3#"IB&ArEF!!KRhac(V35
X(J&0+!!)*!!Q+`(iL!!"4%!L5F281N!$e-KpGC8!!AJm'TP!#5F%%dD#d0ik$)f!
X%!6%"QT%8c9jh,9L'b&"hRlFYR`m$B!#YL4!&8B,iLSpjR"m3**!!"#63$RI2"*(
XJ$#5!$#LJ#"J3I4#!,0r!,JLJi!+eERb!$mmZ!0%qp'HJ!%A[H6jIaVN-!$QHc`$
XJldSJrK+S"R**'J43m4Hr"JT!!NJ3$F%3#mY3"Yi3T,%!r!``"JT9"hL2!,$J%,3
X"khF!)Sp!mAV4i"K%!Q$J#3$"5-&"MHqiUEfapm`fRIq$!Mk2!SJr+!!)3N"5L!$
XH"J"%Jh-'K3$!0)J58maAd)9'acrSJ!6l!Mm!2L#!9U!1k-!!L($rJ"l3!H!LLp`
X"(6"aUN(S%33kK3#-d@qkHfB)q*'k1&!!l)"2539*Db!8&Ap`&(K'&43!J1!4r!0
X"-(X@"3Mi"9)$!Z`%!4$crS%j)!!l33%)J%rJ$bE!2pJ*L'm3q!-JN!!!GJ)J5!#
Xr)"`)$d!J!!4!!MJ%p-!!e%%%S!$`S!bVJe%Y!A`#)1!(kZ"15!#G)#!N!%%J#@R
X"!I!(#3!4&-(%&`(%33+BFhi3'!`"IH!)rH!ri"RjJ#l)MD,##PZK+hb&X$!@bX*
XC5!YVS5fmKEL`&Vk2J2!2U1!Uj"Q!B!!!J[a&14c!!!J%i)!$()"K!!p`J!-i"lJ
X!$RL!1m!"`)%2d!%1!"Mi!@8)+BaK-2!(4f!!$!0r-!B'`6(`"h&J'$`$I`!'aX%
Xj*!*cB"`kJ((`$6r!-)!82f!3D--r-!#!J5r`!`-J((J$2R!!jS!c`!-1i!FB!MM
X!!6l!!!!(cT!!FP#TS`!1K#(P@)8lSDJX"B+`K2j!8F%((P&HK853!2J44k**,)N
XIN4@QST5)%N9L5b5*,M%Q`X5CH"*PBNfNL5pa*'l%T8!#CJa"#!"*B!JiJ4%J%(D
XK3!J!!F!)c"$54aDD)P)N#'kJ$E#ABG*(RSRAqbBJ)*bi%"-!!U,*0*NLeJ5ED"0
XmeJ6#3#GK!p"%QPL5&*!!pXK*(M!RD!#G["1[KdAQb3`"!6ANKZ53!&Ub4N3*'f!
X$4b30R"-aJN5fL"a3$'4J0r!MSF!%P-)"X$&*Mb`8aB"J%"##3J!!$+%2!J%")!m
X)!JI!M$KS#$b"J&-898"3()T&83JdP9C'%,5!6``)CN!T#TbLf,T@SGJL#!,!"KJ
X#A[J2FN)'B![[iaF#J!`!#4D&$4!%8[!8+L"+d"#5Bd$B!*M!12S"h[JFJ8&c"!!
XDdHj)Vp`i1B3M"qJ"$3&4I`!!:
SHAR_EOF
$TOUCH -am 0604153590 un-adobe.hqx &&
chmod 0644 un-adobe.hqx ||
echo "restore of un-adobe.hqx failed"
set `wc -c un-adobe.hqx`;Wc_c=$1
if test "$Wc_c" != "9054"; then
	echo original size 9054, current size $Wc_c
fi
# ============= view_header.ps ==============
echo "x - extracting view_header.ps (Text)"
sed 's/^X//' << 'SHAR_EOF' > view_header.ps &&
X%!
X300 dict dup /font_dict exch def begin
SHAR_EOF
$TOUCH -am 0612145690 view_header.ps &&
chmod 0644 view_header.ps ||
echo "restore of view_header.ps failed"
set `wc -c view_header.ps`;Wc_c=$1
if test "$Wc_c" != "42"; then
	echo original size 42, current size $Wc_c
fi
# ============= view_trailer.ps ==============
echo "x - extracting view_trailer.ps (Text)"
sed 's/^X//' << 'SHAR_EOF' > view_trailer.ps &&
Xend
X
X/Helvetica findfont 30 scalefont setfont
X/myString 30 string def
X/myWriteString {
X	gsave 20 -50 moveto show grestore
X} def
X100 100 translate
X/iChar 0 def
X
Xfont_dict {			% name procedure
X	/proc exch def
X	/name exch def
X	gsave
X		gsave
X		.3 .3 scale
X		gsave 0 0 moveto 0 1000 rlineto
X		1000 0 rlineto 0 -1000 rlineto closepath stroke grestore
X		proc stroke
X		grestore
X		name myString cvs gsave 0 -50 moveto show grestore
X		gsave -50 -50 moveto iChar (    ) cvs show grestore
X		/iChar iChar 1 add def
X		usertime 800 add
X		{ dup usertime lt { pop exit } if } loop
X		erasepage
X	grestore
X} forall
X
Xshowpage
SHAR_EOF
$TOUCH -am 0612183390 view_trailer.ps &&
chmod 0644 view_trailer.ps ||
echo "restore of view_trailer.ps failed"
set `wc -c view_trailer.ps`;Wc_c=$1
if test "$Wc_c" != "605"; then
	echo original size 605, current size $Wc_c
fi
exit 0