[comp.sources.unix] v12i043: Hershey font manipulation tools and data, Part04/05

rsalz@uunet.UU.NET (Rich Salz) (10/26/87)

Submitted-by: lee@uhccux.UUCP (Greg Lee)
Posting-number: Volume 12, Issue 43
Archive-name: hershtools/part04

# 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 the following files:
#	./Makefile
#	./README
#	./eplot.c
#
if `test ! -s ./Makefile`
then
echo "writing ./Makefile"
sed 's/^X//' > ./Makefile << '\Rogue\Monster\'
X#	Makefile 1.0	6/5/87
X#
X# make file for font programs
X#
X#
X
XCFLAGS=	-O -s
XOBJS=	termio.o
XSOURCES= termio.c eplot.c hplot.c
X
Xall:	eplot hplot htrans
X
Xhtrans:	htrans.c
X	${CC} ${CFLAGS} -o htrans htrans.c
X
Xeplot:	${OBJS} eplot.o
X	${CC} ${CFLAGS} -o eplot ${OBJS} eplot.o -ltermlib
X
Xhplot:	${OBJS} hplot.o
X	${CC} ${CFLAGS} -o hplot ${OBJS} hplot.o -ltermlib
X
Xeplot.o:	eplot.c
X	${CC} ${CFLAGS} -c eplot.c
X
Xhplot.o:	hplot.c vfont.c
X	${CC} ${CFLAGS} -c hplot.c
X
X${OBJS}:	termio.h
X
Xclean:
X	rm -f *.o
X
\Rogue\Monster\
else
  echo "will not over write ./Makefile"
fi
if [ `wc -c ./Makefile | awk '{printf $1}'` -ne 492 ]
then
echo `wc -c ./Makefile | awk '{print "Got " $1 ", Expected " 492}'`
fi
if `test ! -s ./README`
then
echo "writing ./README"
sed 's/^X//' > ./README << '\Rogue\Monster\'
XHere are some programs for making use of the Hershey character data.  Eplot
Xand hplot allow the editing of vector fonts and the creation of other fonts
Xfrom them -- vfont format raster fonts, PostScript analytic fonts -- as
Xwell as tfm files for TeX.  The file format for vector fonts is idiosyncratic,
XI'm sorry to say.  I have not had access to the Hershey data in the usual
Xformats.  I have included two sets of four files each containing the Hershey
Xsimplex and triplex Roman characters in the format required for these
Xprograms -- these are sr?.chr and tr?.chr, where the ? is c for capital
Xletters, s for small letters, d for digits, or p for punctuation.  Just
Xin case anyone has the Hershey data in the compressed form I have it in
X(similar the National Bureau of Standards form) I included the utility
Xhtrans, which converts from the compressed form to my form.  (By the way,
XI would really like to have the Hershey data for oriental characters.)
X
XThese programs have compiled ok in the Ultrix 1.2 and Sun 3.0 versions of
XBSD 4.2.
X
XParts of the source (termio.c, termio.h) were taken from the Xum package
Xdistributed in net.sources by John Paul O'Brien, Nova University, Fort
XLauderdale, Florida, {allegra, ucf-cs, usfvax2}!novavax!john, and (vfont.c) from
Xthe Hfont package by William LeFebvre, Department of Computer Science,
XRice University, <phil@Rice.edu>.  These appear to be in the public domain.
XI am grateful to the above for the use of their code, and I hereby place
Xthe rest of the code and documents for these programs in the public domain.
X
XGreg Lee, Sept 12, 1987.
XU.S.mail: 562 Moore Hall, Dept. of Linguistics, Univ. of Hawaii, HONO, HI 96822
XINTERNET: lee@uhccux.uhcc.hawaii.edu
XUUCP:     {ihnp4,dcdwest,ucbvax}!sdcsvax!nosc!uhccux!lee
XBITNET:   lee%uhccux.uhcc.hawaii.edu@rutgers.edu
\Rogue\Monster\
else
  echo "will not over write ./README"
fi
if [ `wc -c ./README | awk '{printf $1}'` -ne 1811 ]
then
echo `wc -c ./README | awk '{print "Got " $1 ", Expected " 1811}'`
fi
if `test ! -s ./eplot.c`
then
echo "writing ./eplot.c"
sed 's/^X//' > ./eplot.c << '\Rogue\Monster\'
X
X#include <stdio.h>
X#define TRUE 1
X#define FALSE 0
X
Xextern char *term_name;
Xchar w300 = FALSE;
X
X#define STSIZE	32000
X#define KEEPSIZE 80
X
X#define getnam(nm) cook_tty(tty_fid);scanf("%s",nm);uncook_tty(tty_fid);
X
Xint	tty_fid;
X
Xchar penstate, debug, /*ibuf[BUFSIZ],*/ ins[90];
XFILE *ibuf;
Xint cnum;
X
Xint itempt, co1, co2, co3, lebear, ribear, x, y;
Xint deltax, deltay, xinc, yinc;
Xint lx,llx,ly,lly, cx,ccx,cy,ccy, x1,x2,y1,y2, a1,a2,d1,d2, i1,i2;
Xint minx, miny, maxx, maxy, base, obase, xheight, ytop, ybot, serifs;
Xint begy,begx;
Xchar itemtype, letter, linelet, retrace, openflag, lighten, hairflag;
X
Xint xheavy, xlight, yheavy, ylight, penwidth, pxangle, pyangle,
X	squarepen, shading, xshade, yshade;
X
X
X#define ESC	27
X#define RIGHTCOL 79
X#define LEFTCOL  0
X#define BOTROW  23
X
X#define PRPTNL  2
X
X#define BLACK	'1'
X#define BLUE	'2'
X#define GREEN	'3'
X#define CYAN	'4'
X#define RED	'5'
X#define MAGENTA '6'
X#define YELLOW	'7'
X#define WHITE	'8'
X
X#define UPPRDOT	','
X#define LOWRDOT	'-'
X#define BOTHDOT '7'
X#define NODOT	' '
Xchar upperdot=UPPRDOT, lowerdot=LOWRDOT, bothdot=BOTHDOT;
X
Xchar	currlet, reallet;
Xunsigned currlines[96];
Xunsigned xpt, penplace,oldpplace, lastplace;
X
X
Xchar	cmd, currch, cch, cbyte, cbyteo, mxflag;
Xint	col, row, xpos, ypos, currlen;
Xchar	erow,ecol, pxc,pyc, penchar;
X
Xchar	ckeep[6][KEEPSIZE], gxoff, gyoff, ib;
X
Xint i, fd;
Xchar ftname[30];
Xchar  duplflag;
X
X/******************/
X
X
X/* char obuf[BUFSIZ];*/
XFILE *obuf;
Xint cocnt;
Xunsigned char sletter;
Xunsigned svpt;
X
X/***************/
X
Xchar gr[100][100];
X
Xchar *_stsz;
Xunsigned stsize, cindex[128], storept;
Xunsigned char psxoff[128], pswidth[128];
Xchar store[STSIZE];
X
X/*****************/
X
Xsavechr()
X{	char fname[30];
X
X	if (storept< 2) {printf("nothing to save\r\n"); return; }
X
X	strcpy(fname,ftname);
X	strcat(fname,".chr");
X	if ((obuf = fopen(fname, "w")) == NULL) exit(1);
X
X	fprintf(obuf, "Height(%d)\n", ytop);
X	if (xheight) fprintf(obuf, "x Height(%d)\n", xheight);
X	if (base) fprintf(obuf, "Base(%d)\n", base);
X
X
X	cocnt = 0;
X
X	for (sletter = 0; sletter < 128 ; sletter++)
X	{
X		if (!(svpt = cindex[sletter])) continue;
X		/*if (kbhit()) return;*/
X
X		if (sletter < ' ') fprintf(obuf, "^%c': ", sletter);
X		else fprintf(obuf, "'%c': ", sletter);
X
X		while (!(dspc(store[svpt], store[svpt+1]))) svpt +=2;
X
X	}
X
X	fprintf(obuf, "\n");
X	fclose(obuf);
X
X}
X
Xdspc(b1, b2)
Xchar b1, b2;
X{
X	co1 = b1 - 64; co2 = b2 - 64;
X
X	if (co1 == -64 && co2 == -64)
X	{	fprintf(obuf," End Char\n");
X		cocnt = 0;
X		return(TRUE);
X	}
X
X
X	if (co1 == -64)
X	{	if (!co2) fprintf(obuf," Pen Up\n    ");
X		else if (b2 == 'H') fprintf(obuf,"\n   Hair ");
X		cocnt = 0;
X	}
X	else
X	{	if (cocnt >8) {cocnt = 0; fprintf(obuf,"\n    ");}
X
X		fprintf(obuf,"(%d,%d)", co1,co2);
X		cocnt++;
X	}
X
X	return(FALSE);
X}
X
X
X
Xsaveasm()
X{	char fname[30];
X
X	if (storept< 2) {printf("nothing to save\r\n"); return; }
X
X	strcpy(fname,ftname);
X	strcat(fname,".a");
X	if ((obuf = fopen(fname, "w")) == NULL) exit(1);
X
X	fprintf(obuf, "\n\tsection  font,data\n");
X	fprintf(obuf, "\tdc.w %d,%d\n", ytop, base);
X	fprintf(obuf, "\txdef\t%s\n%s\n\n", ftname, ftname);
X	fprintf(obuf, "\tinclude\t\"chrdir\"\n\n");
X	fprintf(obuf, ".h20\n\tdc.b -6,6\n  endchar\n");
X
X
X
X	for (sletter = 33; sletter < 128 ; sletter++)
X	{
X
X		if ( (sletter >= 'A' && sletter <= 'Z')
X		  || (sletter >= 'a' && sletter <= 'z') )
X			fprintf(obuf, ".%c\n", sletter);
X		else if (sletter >= '0' && sletter <= '9')
X			fprintf(obuf, ".d%c\n", sletter);
X		else fprintf(obuf, ".h%02.2x\n", sletter);
X
X		if (!(svpt = cindex[sletter]))
X		{	fprintf(obuf, "\tdc.b 0,0\n  endchar\n");
X			continue;
X		}
X
X
X		minx = 63; maxx =  -63;
X		while ( (x=store[svpt]) + (y=store[svpt+1]) )
X		{	svpt += 2;
X			if (!(x)) continue;
X			minx = min(minx, x-64);
X			maxx = max(maxx, x-64);
X		}
X		fprintf(obuf, "\tdc.b %d,%d\n", minx-lebear, maxx+ribear);
X
X		svpt = cindex[sletter];
X
X		while (!(dspca(store[svpt], store[svpt+1]))) svpt +=2;
X
X	}
X
X	fprintf(obuf, "\n\tend\n");
X	fclose(obuf);
X
X}
X
Xdspca(b1, b2)
Xchar b1, b2;
X{
X	co1 = b1 - 64; co2 = b2 - 64;
X
X	if (co1 == -64 && co2 == -64)
X	{	fprintf(obuf,"  endchar\n");
X		return(TRUE);
X	}
X
X
X	if (co1 == -64)
X	{	if (!co2) fprintf(obuf,"  penup\n");
X		/* else if (b2 != 'H')
X		   fprintf(obuf,"\tdc.b -%d,%d\n", co2,co2); */
X	}
X	else
X	{
X		fprintf(obuf,"\tdc.b %d,%d\n", co1,co2);
X	}
X
X	return(FALSE);
X}
X
X
X
Xsaveps()
X{	char fname[30];
X	char *nameoflet();
X	int letcount;
X	int fbb[4];
X
X	if (storept< 2) {printf("nothing to save\r\n"); return; }
X
X	strcpy(fname,ftname);
X	strcat(fname,".ps");
X	if ((obuf = fopen(fname, "w")) == NULL) exit(1);
X
X	fprintf(obuf, "10 dict dup begin\n");
X	fprintf(obuf, "/FontType 3 def\n");
X	fprintf(obuf, "/FontMatrix [.03 0 0 .03 0 0] def\n");
X	fprintf(obuf, "/Encoding 256 array def\n");
X	fprintf(obuf, "0 1 255 {Encoding exch/.notdef put} for\n");
X	fprintf(obuf, "Encoding\n");
X	for (sletter = 0; sletter < 128 ; sletter++)
X	{	if (!(svpt = cindex[sletter])) continue;
X		fprintf(obuf, "dup %d /%s put\n", sletter, nameoflet(sletter));
X	}
X	fprintf(obuf, "pop\n");
X
X#define HLWIDTH 1
X	letcount = 0;
X	for (sletter = 0; sletter < 128 ; sletter++)
X	{	if (!(svpt = cindex[sletter])) continue;
X		letcount++;
X	}
X
X	fprintf(obuf, "/BBox %d dict def\nBBox begin\n", letcount+1);
X	fprintf(obuf, " /.notdef [0 0 0 0] def\n");
X	fbb[0] = fbb[1] = 63; fbb[2] = fbb[3] = -63;
X	for (sletter = 0; sletter < 128 ; sletter++)
X	{	if (!(svpt = cindex[sletter])) continue;
X		co2 = minx = miny = 63; co3 = maxx = maxy = -63;
X		while ( (x=store[svpt]) + (y=store[svpt+1]) )
X		{	svpt += 2;
X			if (!(co1=x)) continue;
X			if (i1 && i2) co1 += fadjust(-base+y-64,i1,i2)-50;
X			co2 = min(co2, co1-64);
X			minx = min(minx, x-64);
X			miny = min(miny, y-64);
X			co3 = max(co3, co1-64);
X			maxx = max(maxx, x-64);
X			maxy = max(maxy, y-64);
X		}
X		psxoff[sletter] = lebear - minx;
X		pswidth[sletter] = lebear + maxx - minx + 1 + ribear;
X		fprintf(obuf, " /%s [%d %d %d %d] def\n", nameoflet(sletter),
X			co2 + psxoff[sletter] - HLWIDTH,
X			-maxy + base - HLWIDTH,
X			co3 + psxoff[sletter] + HLWIDTH,
X			-miny + base + HLWIDTH);
X		fbb[0] = min(fbb[0], co2 + psxoff[sletter] - HLWIDTH);
X		fbb[1] = min(fbb[1], -maxy + base - HLWIDTH);
X		fbb[2] = max(fbb[2], co3 + psxoff[sletter] + HLWIDTH);
X		fbb[3] = max(fbb[3], -miny + base + HLWIDTH);
X	}
X	fprintf(obuf, "end\n");
X	fprintf(obuf, "/FontBBox [%d %d %d %d] def\n",fbb[0],fbb[1],
X				fbb[2],fbb[3]);
X
X	fprintf(obuf, "/Metrics %d dict def\nMetrics begin\n", letcount+1);
X	fprintf(obuf, " /.notdef 0 def\n");
X	for (sletter = 0; sletter < 128 ; sletter++)
X	{	if (!(svpt = cindex[sletter])) continue;
X		fprintf(obuf, " /%s %d def\n", nameoflet(sletter),
X			pswidth[sletter]);
X	}
X	fprintf(obuf, "end\n");
X
X
X	fprintf(obuf, "/CharacterDefs %d dict def\nCharacterDefs begin\n",
X		letcount+1);
X	fprintf(obuf, "/.notdef {} def\n");
X	cocnt = 0;
X	for (sletter = 0; sletter < 128 ; sletter++)
X	{	if (!(svpt = cindex[sletter])) continue;
X		fprintf(obuf, "/%s\n { newpath\n   ", nameoflet(sletter));
X		penstate = 0;
X		while (!(dsps(store[svpt], store[svpt+1]))) svpt +=2;
X	}
X	fprintf(obuf, "end\n");
X
X	pbuildchar();
X
X	fprintf(obuf, "/UniqueID %d def\n\nend\n", ftname[0]);
X
X	fprintf(obuf, "/%s exch definefont pop\n", ftname);
X
X	fclose(obuf);
X
X}
X
X
Xdsps(b1, b2)
Xchar b1, b2;
X{
X	co1 = b1 - 64; co2 = b2 - 64;
X
X	if (co1 == -64 && co2 == -64)
X	{
X		fprintf(obuf, " stroke } def\n");
X		cocnt = 0;
X		return(TRUE);
X	}
X
X
X	if (co1 == -64)
X	{	if (!co2) penstate = 0;
X		/*else if (b2 == 'H') fprintf(obuf,"\n   Hair ");*/
X	}
X	else
X	{	if (cocnt >3) {cocnt = 0; fprintf(obuf,"\n   ");}
X
X		if (i1 && i2) co1 += fadjust(-base+co2,i1,i2) - 50;
X
X		fprintf(obuf," %d %d ", co1+psxoff[sletter],base-co2);
X		if (penstate) fprintf(obuf,"lineto");
X		else fprintf(obuf,"moveto");
X		penstate = 1;
X		cocnt++;
X	}
X
X	return(FALSE);
X}
X
Xchar *nameoflet(c)
Xchar c;
X{ static char *npc[] = {
X	"A", "ctl@",
X	"esc", "fs", "gs", "rs", "us",
X	"space", "exclam", "quotedbl", "numbersign", "dollar",
X	"percent", "ampersand", "quoteright", "parenleft",
X	"parenright", "asterisk", "plus", "comma", "hyphen",
X	"period", "slash",
X	"zero", "one", "two", "three", "four", "five", "six", "seven",
X	"eight", "nine", "colon", "semicolon", "less", "equal",
X	"greater", "question", "at",
X	"bracketleft", "backslash", "bracketright", "asciicircum",
X	"underscore", "quoteleft",
X	"braceleft", "bar", "braceright", "asciitilde", "del"
X  };
X
X	if (c < 0x1B) { npc[1][3] = c + 0x40; return(npc[1]); }
X	if (c < 'A')	return(npc[c - 0x19]);
X	if (c <= 'Z') {	npc[0][0] = c; return(npc[0]); }
X	if (c < 'a')  {	return(npc[c + 39 - 'Z']); }
X	if (c <= 'z') {	npc[0][0] = c; return(npc[0]); }
X	return(npc[c + 45 - 'z']);
X}
X
Xpbuildchar()
X{
X	fprintf(obuf,"/BuildChar\n");
X	fprintf(obuf,"{ 0 begin\n");
X	fprintf(obuf," /char exch def\n /fontdict exch def\n");
X	fprintf(obuf," /charname fontdict /Encoding get char get def\n");
X	fprintf(obuf," fontdict begin\n");
X	fprintf(obuf,"  Metrics charname get 0\n");
X	fprintf(obuf,"  BBox charname get aload pop\n");
X	fprintf(obuf,"  setcachedevice\n");
X	fprintf(obuf,"  %1.1f setlinewidth\n", 2.0*HLWIDTH);
X	fprintf(obuf,"  CharacterDefs charname get exec\n");
X	fprintf(obuf," end\nend\n} def\n");
X	fprintf(obuf,"/BuildChar load 0 3 dict put\n");
X}
X
X
Xsavetfm()
X{	char fname[30];
X	char *nameoflet();
X
X	if (storept< 2) {printf("nothing to save\r\n"); return; }
X
X	strcpy(fname,ftname);
X	strcat(fname,".pl");
X	if ((obuf = fopen(fname, "w")) == NULL) exit(1);
X
X	fprintf(obuf, "\n");
X
X	fprintf(obuf,"(DESIGNSIZE R 10.0)\n");
X	fprintf(obuf,"(COMMENT DESIGNSIZE IS IN POINTS)\n");
X	fprintf(obuf,"(COMMENT OTHER SIZES ARE MULTIPLES OF DESIGNSIZE)\n");
X	fprintf(obuf,"(FONTDIMEN\n");
X	if (i1 && i2)
X		fprintf(obuf,"   (SLANT R %1.6f)\n", (float)-i1/i2);
X	fprintf(obuf,"   (SPACE R 0.357776)\n");
X	fprintf(obuf,"   (STRETCH R 0.153333)\n");
X	fprintf(obuf,"   (SHRINK R 0.1022215)\n");
X	if (xheight)
X	fprintf(obuf,"   (XHEIGHT R %1.6f)\n", (float)xheight/33.33);
X	else
X	fprintf(obuf,"   (XHEIGHT R 0.430555)\n");
X	fprintf(obuf,"   (QUAD R 1.022217)\n");
X	fprintf(obuf,"   (EXTRASPACE R 0.1022215)\n");
X	fprintf(obuf,"   )\n");
X
X	for (sletter = 0; sletter < 128 ; sletter++)
X	{	if (!(svpt = cindex[sletter])) continue;
X		fprintf(obuf,"(CHARACTER O %o\n", sletter);
X		minx = miny = 63; co2 = maxx = maxy = -63;
X		while ( (x=store[svpt]) + (y=store[svpt+1]) )
X		{	svpt += 2;
X			if (!(co1=x)) continue;
X			if (i1 && i2) co1 += fadjust(-base+y-64,i1,i2)-50;
X			minx = min(minx, x-64);
X			miny = min(miny, y-64);
X			maxx = max(maxx, x-64);
X			maxy = max(maxy, y-64);
X			co2 = max(co2, co1-64);
X		}
X		if ((x = lebear + maxx - minx + 1 + ribear) > 0)
X		  fprintf(obuf, "   (CHARWD R %1.6f)\n", (float)x/33.33);
X		if ((x = -miny + base + 1 + HLWIDTH) > 0)
X		  fprintf(obuf, "   (CHARHT R %1.6f)\n", (float)x/33.33);
X		if ((x = maxy - base ) > 0)
X		  fprintf(obuf, "   (CHARDP R %1.6f)\n", (float)x/33.33);
X		if ((x = co2 - maxx ) > 0)
X		  fprintf(obuf, "   (CHARIC R %1.6f)\n", (float)x/33.33);
X		fprintf(obuf, "   )\n");
X	}
X
X	fclose(obuf);
X
X}
X
X/******************/
X
Xmain()
X{	char sp;
X	char key(), conin();
X/* stuff from xum */
X
X	if (term_setup() != 0)
X	{
X		printf("Warning: This program needs to have the\n");
X		printf("TERM environment variable setup before\n");
X		printf("being run. Make sure this is done before\n");
X		printf("executing eplot again (set yourself up like\n");
X		printf("you were going to use vi).\n");
X		exit(1);
X	}
X
X	printf("Terminal is a %s.\n", term_name);
X	if (!strcmp(term_name, "w300")) w300 = TRUE;
X	if (!w300)
X	{	upperdot='^'; lowerdot='j'; bothdot='g';
X	}
X
X	tty_fid = raw_tty("/dev/tty");
X	if (tty_fid == -1)
X	{
X		printf("Error opening terminal for raw i/o\n");
X		exit(1);
X	}
X
X
X	debug = 0;
X
X	stsize = STSIZE;
X
X	printf("\r\nEplot - (c) Greg Lee, Oct. 1984\r\n\n");
X
X	base = 9;
X	ytop = 22;
X	lebear = ribear = 2;
X	strcpy(ftname,"Work");
X	letter = currch = duplflag = 0;
X
X	storept = x1 = x2 = y1 = y2 = a2 = d2 = 1;
X	serifs = 2;
X
X	begy = 50-12;	begx = 50-39;
X
X	do
X	{	printf("\r\n");
X		if (currlet > ' ') printf("%c* ",currlet);
X			else printf("^%c* ",currlet+64);
X		cmd = key();
X	switch (cmd)
X	{
X	case 'e': edit(); break;
X	case 'c': printf("Create letter? : ");
X		  /*scanf("%c",&letter);*/ letter = conin(); putchar(letter);
X		  cindex[letter] = storept;
X		  sto2(0,0);
X		  break;
X	case 'r': rdchr(); break;
X	case 'z': /* setmem(cindex, 128*2+2+stsize, 0);*/
X		  bzero(cindex, 128*sizeof(int));
X		  bzero(store, STSIZE);
X		  storept = 1;
X		  printf("zapped");
X		  break;
X	case 'p': plotlet(); break;
X	case 'v': showgr(); showbits(); break;
X	case 'b': gvar("Base",&base); break;
X	case 'h': gvar("Height",&ytop); break;
X	case 'd': gvar("Depth",&ybot); break;
X	case 'f': printf("FACTORS:\r\n");
X		  gvar("X1",&x1);
X		  gvar("X2",&x2);
X		  gvar("Y1",&y1);
X		  gvar("Y2",&y2);
X		  break;
X	case 't': duplflag = !duplflag;
X		  chkdupl();
X		  if (!duplflag) printf("not "); printf("tall");
X		  break;
X	case 'L': printf("LINE STYLE:\r\n");
X		  gvar("X Heavy",&xheavy);
X		  gvar("X Light",&xlight);
X		  gvar("Y Heavy",&yheavy);
X		  gvar("Y Light",&ylight);
X		  break;
X	case 'I': printf("ITALIC:\r\n");
X		  gvar("I1",&i1);
X		  gvar("I2",&i2);
X		  break;
X	case 'B': printf("BEARINGS:\r\n");
X		  gvar("Left",&lebear);
X		  gvar("Right",&ribear);
X		  break;
X	case 'S': gvar("serifs",&serifs);
X		  break;
X	case 'n': printf(".chr name(%s) = ",ftname);
X		  getnam(ftname);
X		  /*strcat(ftname,".chr");*/
X		  break;
X	case 's': savechr(); break;
X	case 'a': saveasm(); break;
X	case 'P': saveps(); break;
X	case 'T': savetfm(); break;
X	case '?': cmdinfo();
X		  printf("\r\nstore room %d",
X			stsize-storept);
X		  break;
X	case '\\': printf("debug");
X		  if (debug) printf(" off");
X		  debug = !debug;
X	case 'q':
X	case 'x': break;
X	default: conout('?'); printf("%c cmd %d?",cmd,cmd); break;
X	}
X	}
X	while (cmd != 'x' && cmd != 'q');
X
X	reset_tty(tty_fid);
X
X}
X
Xcmdinfo()
X{
X    printf("\r\nRead   Plot      Name .chr   mag.Factors\r\n");
X	printf("Zap    Edit      Save .chr  ^Line style\r\n");
X	printf("Base   Vdisplay ^Serifs     ^Ps file\r\n");
X	printf("Height eXit/Quit Tall       ^Tfm file\r\n");
X	printf("Depth ^Italic   ^Bearings    Asm file\r\n");
X}
X
X
Xgvar(s,v)
Xchar *s; int *v;
X{	char is[80];
X
X	printf(s);
X	printf("(%d) = ", *v);
X	cook_tty(tty_fid);
X	gets(is);
X	if (is[0] >= '0' && is[0] <= '9') sscanf(is,"%d",v);
X	uncook_tty(tty_fid);
X}
X
Xplotlet()
X{
X	printf("Plot a letter? : ");
X	/*scanf("%c", &letter);*/
X	letter = 0x7f & getchar(); putchar(letter);
X	currlet = letter;
X	lplot(letter);
X}
X
X
Xedit()
X{	/*if (!currlet) plotlet();
X	else*/ lplot(currlet);
X
X	penplace = 0;
X
X	edscr();
X
X	gxy(0,22);
X}
X
Xdispline(row)
Xchar row;
X{
X	y = begy + row;
X
X	for (x = begx; x <= begx+79; x++)
X		if (gr[x][y])
X		{	at(x,y);
X			gxy(ecol, erow);
X			putchar(gr[x][y]);
X		}
X}
X
X
Xat(x,y)
Xint x,y;
X{	x -= begx;	y -= begy;
X	if (x >= 0 && x <= 79 && y >= 0 && y <= 23)
X	{ ecol = x; erow = y; return(TRUE); }
X	return(FALSE);
X
X}
X
Xrdchr()
X{	char fname[20];
X
X
X	printf(".chr file?  : ");
X	getnam(fname);
X	if (!fname[0]) return;
X	strcat(fname, ".chr");
X	if ((ibuf = fopen(fname, "r")) == NULL) return;
X
X	while (fgets(ins, 90, ibuf))
X	{	itempt = 0;
X		while (itemtype = scnitem())
X		switch(itemtype)
X		{
X		case 1: if (debug) printf("\r\nCnum %d: ", cnum);
X			letter = 0;
X			break;
X		case 2: if (debug) printf("\r\nChar '%c': ", letter);
X			cindex[letter] = storept;
X			break;
X		case 3: if (debug) printf("(%d,%d)", co1, co2);
X
X			if (i1 && i2) co1 += fadjust(co2,i1,i2)-50;
X
X			co1 = fadjust(co1,x1,x2) - 50;
X			co2 = fadjust(co2,y1,y2) - 50;
X			sto2(co1 + 64, co2 + 64);
X			break;
X		case 4: if (debug) printf(" Pen Up\r\n   ");
X			sto2(0, 64);
X			break;
X		case 5: if (debug) printf(" End Char");
X			sto2(0, 0);
X			break;
X		case 6: if (debug) printf(" Hair");
X			sto2(0, 'H');
X			break;
X		case 65:/* if (debug) printf(" Bounds (-%d,%d)", co1, co2);
X			co2 = fadjust(co2,x1,x2) - 50;
X			sto2(0, co2 + 64);
X			break; */
X		case 66:if (debug) printf("(ignored)");
X			break;
X		}
X	}
X
X
X	fclose(ibuf);
X
X	printf("\r\nUsed %u of buffer (%d remaining).", storept,stsize-storept);
X}
X
Xsto2(x,y)
Xchar x, y;
X{
X	if (letter < 0 || letter > 127) return;
X	if (storept > stsize - 2) return;
X
X	store[storept++] = x;
X	store[storept++] = y;
X
X}
X
Xscnitem()
X{	char dc;
X
X	while (ins[itempt] == ' ' || ins[itempt] == '\t') itempt++;
X
X	if (!ins[itempt]) return(0);
X	if (ins[itempt] == '\n') return(0);
X
X	if (sscanf(ins + itempt, "%d:", &cnum))
X	{	match(':');	return(1); }
X
X	if (sscanf(ins + itempt, "'%c':", &letter))
X	{	match(':');	return(2); }
X
X	if (sscanf(ins + itempt, "^%c':", &letter))
X	{	match(':');	letter &=  0x1F; return(2); }
X
X	if (sscanf(ins + itempt, "Bounds(%d,%d)", &co1, &co2))
X	{	match(')');	return(65); }
X
X	if (sscanf(ins + itempt, "s(%d,%d)", &co1, &co2))
X	{	match(')');	if (serifs) return(3); return(66); }
X
X	if (sscanf(ins + itempt, "S(%d,%d)", &co1, &co2))
X	{	match(')');	if (serifs>1) return(3); return(66); }
X
X	if (sscanf(ins + itempt, "(%d,%d)", &co1, &co2))
X	{	match(')');	return(3); }
X
X	if (sscanf(ins + itempt, "Pen Up%c", &dc))
X	{	match('p');	return(4); }
X
X	if (sscanf(ins + itempt, "End Char%c", &dc))
X	{	match('r');	return(5); }
X
X	if (sscanf(ins + itempt, "Hair%c", &dc))
X	{	match('r');	return(6); }
X
X	if (sscanf(ins + itempt, "Base(%d)", &base))
X	{	match(')');	obase = base; return(66); }
X
X	if (sscanf(ins + itempt, "x Height(%d)", &xheight))
X	{	match(')');	return(66); }
X
X	if (sscanf(ins + itempt, "Height(%d)", &ytop))
X	{	match(')');	return(66); }
X
X	if (sscanf(ins + itempt, "Depth(%d)", &ybot))
X	{	match(')');	return(66); }
X
X	return(0);
X
X}
X
Xmatch(c)
Xchar c;
X{	while (ins[itempt++] != c);
X}
X
Xlplot(let)
Xchar let;
X{	char c1, c2, penstate;
X
X	currch = let;
X	chkdupl();
X
X	/*if (let <= 1 || let > 127) return;*/
X	if (let < 0 || let > 127) return;
X
X	if (!(xpt = cindex[let])) return;
X	/*if (kbhit()) return;*/
X
X	cleargr();
X
X	for (penstate = 0 ; (c1 = store[xpt++])
X			  + (c2 = store[xpt++]) ; )
X	if (!c1)
X	{	penstate = 0;
X		if (c2 == 'H') hairflag = TRUE;
X	}
X
X	else
X	{	lx = cx; ly = cy;
X		cx = c1 - 64; cy = c2 - 64;
X
X		if (penstate) drawline();
X
X		penstate = 1;
X
X	}
X
X	lastplace = xpt - 2;
X
X
X/*	showgr(); */
X
X}
X
Xgoline(here)
Xunsigned here;
X{	char c1, c2;
X
X	if (!here) return(0);
X
X	c1 = store[here];
X	c2 = store[here + 1];
X	if (!c1) return(0);
X
X	penplace = here;
X
X
X	if (at(fadjust(c1-64,x1,x2), fadjust(c2-64,y1,y2)))
X	{	xpos = c1-64;
X		ypos = c2-64;
X		return(TRUE);
X	}
X	return(0);
X}
X
Xchangeit()
X{
X	if (!penplace) return;
X
X	if (!store[penplace]) return;
X
X	store[penplace] = xpos + 64;
X	store[penplace+1] = ypos + 64; 
X}
X
Xdelline()
X{	if (!penplace) return;
X	if (!store[penplace-2] || !store[penplace+2]) delpoint();
X	else
X	{	store[penplace] = 0;
X		store[penplace+1] = 64;
X		penplace = 0;
X		penchar = 0;
X	}
X}
X
X
Xdelpoint()
X{
X	if (!penplace || !store[penplace]) return;
X
X/*	movmem(store+penplace+2, store+penplace, storept-penplace-2);*/
X	bcopy(store+penplace+2, store+penplace, storept-penplace-2);
X	storept -= 2;
X
X	for (letter = 0; letter < 128; letter++)
X		if (cindex[letter] > penplace)
X			cindex[letter] -= 2;
X
X	lastplace -= 2;
X}
X
Xmakeroom(r)
Xint r;
X{
X	bcopy(store+penplace, store+penplace+r, storept-penplace);
X	storept += r;
X
X	for (letter = 0; letter < 128; letter++)
X		if (cindex[letter] > penplace)
X			cindex[letter] += r;
X	lastplace += r;
X}
X
Xnewpoint()
X{	char puflag;
X
X
X	if (!penplace)
X	{
X		penplace = lastplace;
X		makeroom(6);
X
X		store[penplace] = 0;
X		store[penplace+1] = 64;
X		store[penplace+2] = xpos + 64;
X		store[penplace+3] = ypos + 64; 
X		store[penplace+4] = xpos + 64;
X		store[penplace+5] = ypos + 64;
X
X		penplace += 4;
X	}
X	else
X	{
X		if (store[penplace]) penplace += 2;
X		makeroom(2);
X		store[penplace] = xpos + 64;
X		store[penplace+1] = ypos + 64; 
X
X	}
X}
X
X
Xmakehair()
X{	char prev;
X
X
X	if (!penplace || !store[penplace] || !store[penplace+2]) return;
X
X	if (store[penplace-2]) prev = 2; else prev = 0;
X
X	penplace += prev;
X	makeroom(prev + 2);
X
X	store[penplace] = 0;
X	store[penplace+1] = 'H';
X
X	if (prev)
X	{	store[penplace+2] = store[penplace-2];
X		store[penplace+3] = store[penplace-1];
X	}
X
X	penplace += 2;
X}
X
Xxcontract()
X{	unsigned pt;
X	char key();
X
X	key();
X
X	for (pt = currlines['1'-' ']; store[pt] || store[pt+1]; pt += 2)
X	if (store[pt])
X	switch (reallet)
X	{
X	case 'r': if (store[pt] > xpos + 64) store[pt]--;
X		  break;
X	case 'R': if (store[pt] > xpos + 64) store[pt]++;
X		  break;
X	case 'l': if (store[pt] < xpos + 64) store[pt]++;
X		  break;
X	case 'L': if (store[pt] < xpos + 64) store[pt]--;
X		  break;
X	case 'u': if (store[pt+1] < ypos + 64) store[pt+1]++;
X		  break;
X	case 'U': if (store[pt+1] < ypos + 64) store[pt+1]--;
X		  break;
X	case 'd': if (store[pt+1] > ypos + 64) store[pt+1]--;
X		  break;
X	case 'D': if (store[pt+1] > ypos + 64) store[pt+1]++;
X		  break;
X	default:  break;
X	}
X}
X
X
Xsetpos()
X{
X	return(at(fadjust(xpos,x1,x2), fadjust(ypos,y1,y2)));
X}
X
X
Xcleargr()
X{
X	clrscrn();
X	bzero(gr, 100 * 100);
X	bzero(currlines, 96*2);
X	linelet = '0';
X	penwidth = abs(penwidth);
X}
X
X
Xdrawline()
X{
X	if (debug) printf("\r\nDrawing from (%d,%d) to (%d,%d).", lx,ly,cx,cy);
X
X	linelet++;
X	if (linelet > '9' && linelet < 'A') linelet = 'A';
X	else if (linelet > 'Z' && linelet < 'a') linelet = 'a';
X	else if (linelet > 'z') linelet = '!'+1;
X
X	currlines[linelet-' '] = xpt-4;
X
X
X	if (abs(cy) <= abs(ly))
X	{	llx = lx;
X		lly = ly;
X		ccx = cx;
X		ccy = cy;
X	}
X	else
X	{	llx = cx;
X		lly = cy;
X		ccx = lx;
X		ccy = ly;
X	}
X
X
X	x = fadjust(llx,x1,x2);
X	ccx = fadjust(ccx,x1,x2);
X	deltax = abs(ccx - x);
X	if (ccx >= x) xinc = 1; else xinc = -1;
X
X	y = fadjust(lly,y1,y2);
X	ccy = fadjust(ccy,y1,y2);
X	deltay = abs(ccy - y);
X	if (ccy >= y) yinc = 1; else yinc = -1;
X
X	drawdot();
X
X	if (deltax >= deltay) doforx();
X	else dofory();
X
X	hairflag = 0;
X}
X
Xfadjust(u,f1,f2)
Xint u,f1,f2;
X{
X	return( (u * f1 + f2-1)/f2 + 50);
X}
X
X
X
Xdrawdot()
X{
X	if (x<0 || x>99 || y<0 || y>99) return;
X	if (gr[x][y]) return;
X	gr[x][y] = linelet;
X	if (at(x,y))
X	{	gxy(ecol,erow);
X		putchar(linelet);
X	}
X}
X
X
X
Xdoforx()
X{	int err, i;
X
X	err = deltax / 2;
X	i = deltax;
X
X	while (i--)
X	{	err += deltay;
X		if (err >= deltax)
X		{	err -= deltax;
X			y += yinc;
X			if (xheavy) drawdot();
X			if (xlight) {x += xinc; continue;}
X		}
X		x += xinc;
X		if (hairflag && (i&1)) continue;
X		drawdot();
X		if (debug) printf("\r\n   @(%d,%d) [%d,%d]", x-50, y-50, x,y);
X	}
X	
X}
X
Xdofory()
X{	int err, i;
X
X	gr[x][y] = linelet;
X
X	err = deltay / 2;
X	i = deltay;
X
X	while (i--)
X	{	err += deltax;
X		if (err >= deltay)
X		{	err -= deltay;
X			x += xinc;
X			if (yheavy) drawdot();
X			if (ylight) { y+= yinc; continue; }
X		}
X		y += yinc;
X		if (hairflag && (i&1)) continue;
X		drawdot();
X		if (debug) printf("\r\n   @(%d,%d) [%d,%d]", x-50, y-50, x,y);
X	}
X	
X}
X
Xshowgr()
X{	int x, y;
X
X	minx = miny = 99;
X	maxx = maxy = 0;
X
X	for (y = 0; y < 100; y++)
X	{	for (x = 0; x < 100; x++)
X		if (gr[x][y])
X		{	if (x < minx) minx = x;
X			if (y < miny) miny = y;
X			if (x > maxx) maxx = x;
X			if (y > maxy) maxy = y;
X		}
X	}
X
X	if (maxx - minx > KEEPSIZE-1) maxx = minx + KEEPSIZE-1;
X	rdedf();
X}
X
X
X
X
Xchar conin()
X{	return (0x7f & getchar());
X}
X
Xconout(c)
Xchar c;
X{	putchar(c);
X}
X
X
X
Xchar key()
X{	char c;
X
X	reallet = c = 0x7f & getchar();
X	if (c < ' ') c += '@';
X		else if (c >='A' && c <= 'Z')
X		c += ' ';
X	if (c == 'J') return(key());
X	return(c);
X}
X
X
Xdtrans(c, upper)
Xchar c, upper;
X{	if (c == 0x20 || c == 0x5F) return(c);
X
X	if (c >= 0x60) c -= 0x20;
X	else if (c < 0x20) c += 0x20;
X
X	if (upper) return(c);
X
X	if (c < 0x40) c -= 0x20;
X	else c += 0x20;
X
X	return(c);
X}
X
Xchkdupl()
X{
X/*	duplflag = fix[0] & PRPTNL; */
X	if (duplflag) currch = dtrans(currch, TRUE);
X}
X
Xrdedf()
X{	char c;
X	int lbear, rbear;
X	int i, y, lasty, dcurrlen;
X
X	if  (duplflag)	currch = dtrans(currch, TRUE);
X
X	lbear = rbear = 0;
X
X	bzero(ckeep, 6*KEEPSIZE);
X	row = currlen = 0; dcurrlen = 10000;
X
X	y = base + 51 - ytop;
X	lasty = y + (duplflag ? 47 : 23);
X	if (lasty >= 100) lasty = 99;
X
X	for ( ; y <= lasty; row++,y++)
X	{
X		for (i = minx, col = lbear; i <= maxx; col++,i++)
X		 if (gr[i][y]) chngbit(TRUE);
X
X		if (currlen < col + rbear)
X			currlen = col + rbear;
X	}
X}
X
Xchngbit(biton)
Xchar biton;
X{	if (duplflag && row > 23) cchngbit(3, row - 24, biton);
X	else cchngbit(0, row, biton);
X}
X
Xcchngbit(ib, row, biton)
Xchar ib, row;
Xchar biton;
X{	unsigned char bit, mask;
X	
X	bit = row / 3;
X	mask = 128 >> bit; 
X	cbyte = ckeep[ib + (row % 3)][col];
X	if (biton) cbyte |= mask;
X		else cbyte &= ~mask;
X	ckeep[ib + (row % 3)][col] = cbyte;
X}
X
Xgxy(x,y)
Xchar x,y;
X{	if (w300)
X	{	conout(ESC); conout('=');
X		conout(y+' '); conout(x+' ');
X	} else mov_cur(x,y);
X}
X
Xclrscrn()
X{
X	if (w300) conout(0x1A); else cls();
X	penchar = 0;
X	sleep(1);
X}
X
Xshowbits()
X{
X	clrscrn();
X	graph(TRUE);
X	gxoff = 4;
X
X	if (duplflag) gyoff = 0; else gyoff = 6;
X	sshowbits(0);
X	if (duplflag)
X	{	gyoff = 12;
X		sshowbits(3);
X		gyoff = 0;
X	}
X	graph(FALSE);
X	gxy(0,22);
X}
X
Xsshowbits(ib)
Xchar ib;
X{	unsigned char i, j, bit, mask, r;
X
X     if (currlen > 0)
X     {
X	color(RED,WHITE);
X	if (gyoff == 6)
X	{	gxy(gxoff-1,gyoff-1);
X		conout(w300 ? '2':'+');
X		for (i = 0; i < currlen; i++)
X			conout(w300 ? ':':'-');
X		conout(w300 ? '3':'+');
X	}
X	for (i = gyoff; i < (gyoff+12); i++)
X	  {
X		gxy(gxoff-1,i); conout(w300 ? '6':'|');
X		gxy(currlen+gxoff,i); conout(w300 ? '6':'|');
X	  }
X	if (gyoff == 6)
X	{	gxy(gxoff-1,gyoff+12);
X		conout(w300 ? '1':'+');
X		for (i = 0; i < currlen; i++)
X			conout(w300 ? ':':'-');
X		conout(w300 ? '5':'+');
X	}
X	color(BLACK,WHITE);
X     }
X
X	for (i = 0; i < 3; i++)
X	 for (j = 0; j < currlen; j++)
X	  {	cbyte = ckeep[ib+i][j];
X		cbyteo = ckeep[ib + ((i+1) % 3)][j];
X		mask = 0x80;
X		for (bit = 0; bit < 8; bit++, mask >>= 1)
X		 if (
X			 /* if row is even */
X			!((r = i + bit*3) & 1)
X			 /* and there is a dot in this row or the next */
X		     && ((mask & cbyte) | ((i==2 ? mask>>1: mask) & cbyteo))
X		    )
X		 {	gxy(j+gxoff, r/2+gyoff);
X			 /* both dots? */
X			if ((mask & cbyte)&& ((i==2 ? mask>>1: mask) & cbyteo))
X				conout(bothdot);
X			/* dot in this row only? */
X			else if (mask & cbyte)
X				conout(upperdot);
X			else conout(lowerdot);	/* must be dot in next row */
X		 }
X	  }
X}
X
X
Xgraph(yes)
Xchar yes;
X{	if (!w300) return;
X
X	conout(ESC);	conout('H');
X	if (yes) conout(2); else conout(3);
X	conout(ESC);	conout('`');	/* cursor off/on	*/
X	if (yes) conout('0'); else conout('1');
X	if (!yes) color(BLACK, WHITE);
X}
X
Xcolor(fc, bc)
Xchar fc, bc;
X{	if (!w300) return;
X
X	conout(ESC);	conout('g');
X	conout(fc);	conout(bc);
X}
X
Xcheckpoint()
X{	int sx, sy;
X
X	if (!penplace) return;
X	sx = xpos; sy = ypos;
X	if (!goline(penplace)) return;
X	penchar = gr[begx+(pxc=ecol)][begy+(pyc=erow)];
X	xpos = sx; ypos = sy;
X	gxy(pxc,pyc);
X	conout(penchar);
X}
X
X
Xedscr()
X{	char key();
X
X	oldpplace = 0;
X	xpos = 0; ypos = 1;
X	cmd = 'E';
X	while (cmd != 'M')
X	{  if (cmd >= 'A' && cmd <= 'Z')
X		switch (cmd)
X		{
X	  	case 'S': xpos--; break;
X		case 'D': xpos++; break;
X		case 'E': ypos--; break;
X		case 'X': ypos++; break;
X		case 'R': ypos -= 8; break;
X		case 'C': ypos += 8; break;
X	  	case 'A': xpos -= 8; break;
X		case 'F': xpos += 8; break;
X		case 'L': key(); currlet = reallet; penplace = 0;
X		case 'N': lplot(currlet); break;
X		case 'W': begy--;
X			  gxy(0,0); printf("                 ");
X			  conout(ESC); conout('E');
X			  displine(0);
X			  break;
X		case 'Z': begy++;
X			  gxy(0,0); conout(ESC); conout('R');
X			  displine(23);
X			  break;
X		case 'B': if (penplace) goline(penplace-2); break;
X		case 'P': changeit();
X			  lplot(currlet); break;
X		case 'I': newpoint();
X			  lplot(currlet); break;
X		case 'U': penplace = 0; break;
X		case 'G': delpoint();
X			  lplot(currlet); break;
X		case 'Y': delline();
X			  lplot(currlet); break;
X		case 'T': xcontract();
X			  lplot(currlet); break;
X		case 'Q': begy = 50-12;	begx = 50-39;
X			  lplot(currlet); break;
X		case 'H': makehair();
X			  lplot(currlet); break;
X		default:  conout(7);
X	    	}
X		else switch(cmd)
X		{
X		case ' ': if (penplace) goline(penplace+2); break;
X		default:  goline(currlines[reallet-' ']);
X		}
X
X		if (penplace != oldpplace && penchar)
X		{	gxy(pxc,pyc);
X			conout(penchar);
X			penchar = pxc = pyc = 0;
X		}
X
X		if (penplace)
X		{
X			color(WHITE,BLUE);
X			checkpoint();
X		}
X		else	color(RED,YELLOW);
X		gxy(0,0);
X		printf("   (%3d,%3d)    ", xpos, ypos);
X		color(BLACK,WHITE);
X		oldpplace = penplace;
X
X		if (!setpos()) { xpos = 0; ypos = 0; setpos(); }
X
X		gxy(ecol, erow);
X
X		cmd = key();
X	}
X}
X
X
X
Xmax(x,y)
Xint x,y;
X{	if (x >= y) return(x);
X	return(y);
X}
X
Xmin(x,y)
Xint x,y;
X{	if (x >= y) return(y);
X	return(x);
X}
X
\Rogue\Monster\
else
  echo "will not over write ./eplot.c"
fi
if [ `wc -c ./eplot.c | awk '{printf $1}'` -ne 28121 ]
then
echo `wc -c ./eplot.c | awk '{print "Got " $1 ", Expected " 28121}'`
fi
echo "Finished archive 4 of 4"
# if you want to concatenate archives, remove anything after this lineuit. S