120010Sjaap #ifndef lint
2*33775Sjaap static char *sccsid = "@(#)dhar.c	1.4	CWI 1.4	03/23/88";
320010Sjaap #endif
420010Sjaap /*
520010Sjaap  * Drive the Harris 7500 tyepsetter
620010Sjaap  *		    75XX
720010Sjaap  * Other machines of that harris serie will probably run as well with this
820010Sjaap  *
920010Sjaap  * Author: jaap akkerhuis, Oc 1982, Mathematisch Cetrum.
1020010Sjaap  *
1120010Sjaap  */
1220010Sjaap /*
1320010Sjaap output language from troff:
1420010Sjaap all numbers are character strings
1520010Sjaap 
1620010Sjaap sn	size in points
1720010Sjaap fn	font as number from 1-n
1820010Sjaap cx	ascii character x
1920010Sjaap Cxyz	funny char xyz. terminated by white space
2020010Sjaap Hn	go to absolute horizontal position n
2120010Sjaap Vn	go to absolute vertical position n (down is positive)
2220010Sjaap hn	go n units horizontally (relative)
2320010Sjaap vn	ditto vertically
2420010Sjaap nnc	move right nn, then print c (exactly 2 digits!)
2520010Sjaap 		(this wart is an optimization that shrinks output file size
2620010Sjaap 		 about 35% and run-time about 15% while preserving ascii-ness)
2720010Sjaap Dt ...\n	draw operation 't':
2820010Sjaap 	Dl x y		line from here by x,y
2920010Sjaap 	Dc d		circle of diameter d with left side here
3020010Sjaap 	De x y		ellipse of axes x,y with left side here
3120010Sjaap 	Da x y r	arc counter-clockwise by x,y of radius r
3220010Sjaap 	D~ x y x y ...	wiggly line by x,y then x,y ...
3320010Sjaap w	paddable words space -- no action needed
3420010Sjaap nb a	end of line (information only -- no action needed)
3520010Sjaap 	b = space before line, a = after
3620010Sjaap p	new page begins -- set v to 0
3720010Sjaap tstring print string as plain text
3820010Sjaap #...\n	comment
3920010Sjaap x ...\n	device control functions:
4020010Sjaap 	x i	init
4120010Sjaap 	x T s	name of device is s
4220010Sjaap 	x r n h v	resolution is n/inch
4320010Sjaap 		h = min horizontal motion, v = min vert
4420010Sjaap 	x p	pause (can restart)
4520010Sjaap 	x s	stop -- done for ever
4620010Sjaap 	x t	generate trailer
4720010Sjaap 	x f n s	font position n contains font s
4820010Sjaap 	x H n	set character height to n
4920010Sjaap 	x S n	set slant to N
5020010Sjaap 
5120010Sjaap 	Subcommands like "i" are often spelled out like "init".
5220010Sjaap */
5320010Sjaap /*
5420010Sjaap  * MC:jna
5520010Sjaap  * The output language signs { and } are not described
5620010Sjaap  *
5720010Sjaap  */
5820010Sjaap 
5920010Sjaap #include	<stdio.h>
6020010Sjaap #include	<ctype.h>
6120010Sjaap #include	<signal.h>
6220010Sjaap 
6320010Sjaap #include "../dev.h"
6420010Sjaap #define	NFONT	10
6520010Sjaap 
6620010Sjaap int	output	= 0;	/* do we do output at all? */
6720010Sjaap int	nolist	= 0;	/* output page list if > 0 */
6820010Sjaap int	olist[20];	/* pairs of page numbers */
6920010Sjaap int	spage	= 9999;	/* stop every spage pages */
7020010Sjaap int	scount	= 0;
7120010Sjaap 
7220010Sjaap struct	dev	dev;
7325286Sjaap struct Font *fontbase[NFONT+1];
7420010Sjaap short	*pstab;
7520010Sjaap int	nsizes;
7620010Sjaap int	nfonts;
7720010Sjaap int	smnt;	/* index of first special font */
7820010Sjaap int	nchtab;
7920010Sjaap char	*chname;
8020010Sjaap short	*chtab;
8120010Sjaap char	*fitab[NFONT+1];
8220010Sjaap char	*widthtab[NFONT+1];	/* widtab would be a better name */
8320010Sjaap char	*codetab[NFONT+1];	/* device codes */
8433654Sjaap #if	pdp
8533654Sjaap #define	tosh(a,b)	(a)[2*(b)] & BMASK | ((a)[2*(b) + 1] & BMASK) << BYTE
8633654Sjaap typedef	char f_code;
8733654Sjaap f_code	*fonttab[2*(NFONT+1)];	/*MC:jna optional fontcodes */
8833654Sjaap #endif pdp
89*33775Sjaap #if	tahoe || sun
9033654Sjaap #define	tosh(a,b)	(a)[2*(b) + 1] & BMASK | ((a)[2*(b)] & BMASK) << BYTE
9133654Sjaap typedef	char f_code;
9233654Sjaap f_code	*fonttab[2*(NFONT+1)];	/*MC:jna optional fontcodes */
93*33775Sjaap #endif tahoe || sun
9433654Sjaap #if	vax
9533654Sjaap #define	tosh(a,b)	(a)[b]
9633654Sjaap typedef	short f_code;
9733654Sjaap f_code	*fonttab[NFONT+1];	/*MC:jna optional fontcodes */
9833654Sjaap #endif vax
9920010Sjaap 
10020010Sjaap #define	FATAL	1
10120010Sjaap #define	BMASK	0377
10220010Sjaap #define BYTE	8
10320010Sjaap int	dbg	= 0;
10420010Sjaap int	eflag;
10520010Sjaap int	cflag;
10620010Sjaap int	res;		/* input assumed computed according to this resolution */
10720010Sjaap int	tf = 0;		/* output file will be har.in or standout */
10820010Sjaap char	*fontdir	= "/usr/local/lib/ditroff/font";
10920010Sjaap extern char devname[];
11020010Sjaap 
11120010Sjaap #define	abs(n)	((n) >= 0 ? (n) : -(n))
11220010Sjaap 
11320010Sjaap int	font	= 1;	/* current font */
11420010Sjaap int	hpos;		/* horizontal position where we are supposed to be next (left = 0) */
11520010Sjaap int	lastw;		/*  width of last printed char, (for t_text()) */
11620010Sjaap int	vpos;		/* current vertical position (down positive) */
11720010Sjaap int	horig;		/* h origin of current block; hpos rel to this */
11820010Sjaap int	vorig;
11920010Sjaap int	htrue	= 0;
12020010Sjaap int	vtrue	= 0;
12120010Sjaap int	DX	= 4;	/* step size in x for drawing */
12220010Sjaap int	DY	= 4;	/* step size in y for drawing */
12320010Sjaap int	drawdot	= '.';	/* draw with this character */
12420010Sjaap int	drawsize = 1;	/* shrink by this factor when drawing */
12520010Sjaap 			/* drawsize will be set in t_init as well! */
12620010Sjaap 
main(argc,argv)12720010Sjaap main(argc, argv)
12820010Sjaap char *argv[];
12920010Sjaap {
13020010Sjaap 	FILE *fp;
13120010Sjaap 	int i;
13220010Sjaap 	int done();
13320010Sjaap 	while (argc > 1 && argv[1][0] == '-') {
13420010Sjaap 		switch (argv[1][1]) {
13520010Sjaap 		case 'f':
13620010Sjaap 		case 'F':
13720010Sjaap 			fontdir = argv[2];
13820010Sjaap 			argv++;
13920010Sjaap 			argc--;
14020010Sjaap 			break;
14120010Sjaap 		case 't':
14220010Sjaap 			tf = 1;	/* stdout */
14320010Sjaap 			break;
14420010Sjaap 		case 'o':
14520010Sjaap 			outlist(&argv[1][2]);
14620010Sjaap 			break;
14720010Sjaap 		case 'd':
14820010Sjaap 			dbg = atoi(&argv[1][2]);
14920010Sjaap 			if (dbg == 0) dbg = 1;
15020010Sjaap 			break;
15120010Sjaap 		case 's':
15220010Sjaap 			spage = atoi(&argv[1][2]);
15320010Sjaap 			if (spage <= 0)
15420010Sjaap 				spage = 9999;
15520010Sjaap 			break;
15620010Sjaap 		case 'e':
15720010Sjaap 			eflag++;
15820010Sjaap 			break;
15920010Sjaap 		case 'c':
16020010Sjaap 			cflag++;
16120010Sjaap 			break;
16220010Sjaap 		}
16320010Sjaap 		argc--;
16420010Sjaap 		argv++;
16520010Sjaap 	}
16620010Sjaap 				/*
16720010Sjaap 				 * Stop every 4 pages to prevent the
16820010Sjaap 				 * Harris to Cut the paper every 6 feet,
16920010Sjaap 				 * wat will likely to be in the middle of
17020010Sjaap 				 * a page. Every for page is proved to be
17120010Sjaap 				 * reasonable.
17220010Sjaap 				 */
17320010Sjaap 	if (spage == 0 || 9999)
17420010Sjaap 		spage = 4;
17520010Sjaap 
17620010Sjaap 	if (signal(SIGINT, done) == SIG_IGN) {
17720010Sjaap 		signal(SIGINT, SIG_IGN);
17820010Sjaap 		signal(SIGQUIT, SIG_IGN);
17920010Sjaap 		signal(SIGHUP, SIG_IGN);
18020010Sjaap 	} else {
18120010Sjaap 		signal(SIGQUIT, done);
18220010Sjaap 		signal(SIGHUP, done);
18320010Sjaap 	}
18420010Sjaap 	signal(SIGTERM, done);
18520010Sjaap 	if (argc <= 1)
18620010Sjaap 		conv(stdin);
18720010Sjaap 	else
18820010Sjaap 		while (--argc > 0) {
18920010Sjaap 			if (strcmp(*++argv, "-") == 0)
19020010Sjaap 				fp = stdin;
19120010Sjaap 			else if ((fp = fopen(*argv, "r")) == NULL)
19220010Sjaap 				error(FATAL, "can't open %s", *argv);
19320010Sjaap 				conv(fp);
19420010Sjaap 			fclose(fp);
19520010Sjaap 		}
19620010Sjaap 	account();
19720010Sjaap 	done();
19820010Sjaap }
19920010Sjaap 
outlist(s)20020010Sjaap outlist(s)	/* process list of page numbers to be printed */
20120010Sjaap char *s;
20220010Sjaap {
20320010Sjaap 	int n1, n2, i;
20420010Sjaap 
20520010Sjaap 	nolist = 0;
20620010Sjaap 	while (*s) {
20720010Sjaap 		n1 = 0;
20820010Sjaap 		if (isdigit(*s))
20920010Sjaap 			do
21020010Sjaap 				n1 = 10 * n1 + *s++ - '0';
21120010Sjaap 			while (isdigit(*s));
21220010Sjaap 		else
21320010Sjaap 			n1 = -9999;
21420010Sjaap 		n2 = n1;
21520010Sjaap 		if (*s == '-') {
21620010Sjaap 			s++;
21720010Sjaap 			n2 = 0;
21820010Sjaap 			if (isdigit(*s))
21920010Sjaap 				do
22020010Sjaap 					n2 = 10 * n2 + *s++ - '0';
22120010Sjaap 				while (isdigit(*s));
22220010Sjaap 			else
22320010Sjaap 				n2 = 9999;
22420010Sjaap 		}
22520010Sjaap 		olist[nolist++] = n1;
22620010Sjaap 		olist[nolist++] = n2;
22720010Sjaap 		if (*s != '\0')
22820010Sjaap 			s++;
22920010Sjaap 	}
23020010Sjaap 	olist[nolist] = 0;
23120010Sjaap 	if (dbg)
23220010Sjaap 		for (i=0; i<nolist; i += 2)
23320010Sjaap 			printf("%3d %3d\n", olist[i], olist[i+1]);
23420010Sjaap }
23520010Sjaap 
conv(fp)23620010Sjaap conv(fp)
23720010Sjaap register FILE *fp;
23820010Sjaap {
23920010Sjaap 	register int c, k;
24020010Sjaap 	int m, n, i, n1, m1;
24120010Sjaap 	char str[100], buf[300];
24220010Sjaap 
24320010Sjaap 	while ((c = getc(fp)) != EOF) {
24420010Sjaap 		switch (c) {
24520010Sjaap 		case '\n':	/* when input is text */
24620010Sjaap 		case ' ':
24720010Sjaap 		case 0:		/* occasional noise creeps in */
24820010Sjaap 			break;
24920010Sjaap 		case '{':	/* push down current environment */
25020010Sjaap 			t_push();
25120010Sjaap 			break;
25220010Sjaap 		case '}':
25320010Sjaap 			t_pop();
25420010Sjaap 			break;
25520010Sjaap 		case '0': case '1': case '2': case '3': case '4':
25620010Sjaap 		case '5': case '6': case '7': case '8': case '9':
25720010Sjaap 			/* two motion digits plus a character */
25820010Sjaap 			hmot((c-'0')*10 + getc(fp)-'0');
25920010Sjaap 			put1(getc(fp));
26020010Sjaap 			break;
26120010Sjaap 		case 'c':	/* single ascii character */
26220010Sjaap 			put1(getc(fp));
26320010Sjaap 			break;
26420010Sjaap 		case 'C':
26520010Sjaap 			fscanf(fp, "%s", str);
26620010Sjaap 			put1s(str);
26720010Sjaap 			break;
26820010Sjaap 		case 't':	/* straight text */
26920010Sjaap 			fgets(buf, sizeof(buf), fp);
27020010Sjaap 			t_text(buf);
27120010Sjaap 			break;
27220010Sjaap 		case 'D':	/* draw function */
27320010Sjaap 			fgets(buf, sizeof(buf), fp);
27420010Sjaap 			switch (buf[0]) {
27520010Sjaap 			case 'l':	/* draw a line */
27620010Sjaap 				sscanf(buf+1, "%d %d", &n, &m);
27720010Sjaap 				drawline(n, m, ".");
27820010Sjaap 				break;
27920010Sjaap 			case 'c':	/* circle */
28020010Sjaap 				sscanf(buf+1, "%d", &n);
28120010Sjaap 				drawcirc(n);
28220010Sjaap 				break;
28320010Sjaap 			case 'e':	/* ellipse */
28420010Sjaap 				sscanf(buf+1, "%d %d", &m, &n);
28520010Sjaap 				drawellip(m, n);
28620010Sjaap 				break;
28720010Sjaap 			case 'a':	/* arc */
28820010Sjaap 				sscanf(buf+1, "%d %d %d %d", &n, &m, &n1, &m1);
28920010Sjaap 				drawarc(n, m, n1, m1);
29020010Sjaap 				break;
29120010Sjaap 			case '~':	/* wiggly line */
29220010Sjaap 				drawwig(buf+1);
29320010Sjaap 				break;
29420010Sjaap 			default:
29520010Sjaap 				error(FATAL, "unknown drawing function %s\n", buf);
29620010Sjaap 				break;
29720010Sjaap 			}
29820010Sjaap 			break;
29920010Sjaap 		case 's':
30020010Sjaap 			fscanf(fp, "%d", &n);	/* ignore fractional sizes */
30120010Sjaap 			setsize(t_size(n));
30220010Sjaap 			break;
30320010Sjaap 		case 'f':
30420010Sjaap 			fscanf(fp, "%s", str);
30520010Sjaap 			setfont(t_font(str));
30620010Sjaap 			break;
30720010Sjaap 		case 'H':	/* absolute horizontal motion */
30820010Sjaap 			/* fscanf(fp, "%d", &n); */
30920010Sjaap 			while ((c = getc(fp)) == ' ')
31020010Sjaap 				;
31120010Sjaap 			k = 0;
31220010Sjaap 			do {
31320010Sjaap 				k = 10 * k + c - '0';
31420010Sjaap 			} while (isdigit(c = getc(fp)));
31520010Sjaap 			ungetc(c, fp);
31620010Sjaap 			hgoto(k);
31720010Sjaap 			break;
31820010Sjaap 		case 'h':	/* relative horizontal motion */
31920010Sjaap 			/* fscanf(fp, "%d", &n); */
32020010Sjaap 			while ((c = getc(fp)) == ' ')
32120010Sjaap 				;
32220010Sjaap 			k = 0;
32320010Sjaap 			do {
32420010Sjaap 				k = 10 * k + c - '0';
32520010Sjaap 			} while (isdigit(c = getc(fp)));
32620010Sjaap 			ungetc(c, fp);
32720010Sjaap 			hmot(k);
32820010Sjaap 			break;
32920010Sjaap 		case 'w':	/* word space */
33020010Sjaap 			break;
33120010Sjaap 		case 'V':
33220010Sjaap 			fscanf(fp, "%d", &n);
33320010Sjaap 			vgoto(n);
33420010Sjaap 			break;
33520010Sjaap 		case 'v':
33620010Sjaap 			fscanf(fp, "%d", &n);
33720010Sjaap 			vmot(n);
33820010Sjaap 			break;
33920010Sjaap 		case 'p':	/* new page */
34020010Sjaap 			fscanf(fp, "%d", &n);
34120010Sjaap 			t_page(n);
34220010Sjaap 			break;
34320010Sjaap 		case 'n':	/* end of line */
34420010Sjaap 			while (getc(fp) != '\n')
34520010Sjaap 				;
34620010Sjaap 			t_newline();
34720010Sjaap 			break;
34820010Sjaap 		case '#':	/* comment */
34920010Sjaap 			while (getc(fp) != '\n')
35020010Sjaap 				;
35120010Sjaap 			break;
35220010Sjaap 		case 'x':	/* device control */
35320010Sjaap 			devcntrl(fp);
35420010Sjaap 			break;
35520010Sjaap 		default:
35620010Sjaap 			error(!FATAL, "unknown input character %o %c\n", c, c);
35720010Sjaap 			done();
35820010Sjaap 		}
35920010Sjaap 	}
36020010Sjaap }
36120010Sjaap 
devcntrl(fp)36220010Sjaap devcntrl(fp)	/* interpret device control functions */
36320010Sjaap FILE *fp;
36420010Sjaap {
36520010Sjaap         char str[20], str1[50], buf[50];
36620010Sjaap 	int c, n;
36720010Sjaap 
36820010Sjaap 	fscanf(fp, "%s", str);
36920010Sjaap 	switch (str[0]) {	/* crude for now */
37020010Sjaap 	case 'i':	/* initialize */
37120010Sjaap 		fileinit();
37220010Sjaap 		t_init(0);
37320010Sjaap 		break;
37420010Sjaap 	case 'T':	/* device name */
37520010Sjaap 		fscanf(fp, "%s", devname);
37620010Sjaap 		break;
37720010Sjaap 	case 't':	/* trailer */
37820010Sjaap 		t_trailer();
37920010Sjaap 		break;
38020010Sjaap 	case 'p':	/* pause -- can restart */
38120010Sjaap 		t_reset('p');
38220010Sjaap 		break;
38320010Sjaap 	case 's':	/* stop */
38420010Sjaap 		t_reset('s');
38520010Sjaap 		break;
38620010Sjaap 	case 'r':	/* resolution assumed when prepared */
38720010Sjaap 		fscanf(fp, "%d", &res);
38820010Sjaap 		break;
38920010Sjaap 	case 'f':	/* font used */
39020010Sjaap 		fscanf(fp, "%d %s", &n, str);
39120010Sjaap 		fgets(buf, sizeof buf, fp);	/* in case there's a filename */
39220010Sjaap 		ungetc('\n', fp);	/* fgets goes too far */
39320010Sjaap 		str1[0] = 0;	/* in case there's nothing to come in */
39420010Sjaap 		sscanf(buf, "%s", str1);
39520010Sjaap 		loadfont(n, str, str1);
39620010Sjaap 		break;
39720010Sjaap 	/* these don't belong here... */
39820010Sjaap 	case 'H':	/* char height */
39920010Sjaap 		fscanf(fp, "%d", &n);
40020010Sjaap 		t_charht(t_size(n));
40120010Sjaap 		break;
40220010Sjaap 	case 'S':	/* slant */
40320010Sjaap 		fscanf(fp, "%d", &n);
40420010Sjaap 		t_slant(n);
40520010Sjaap 		break;
40620010Sjaap 	}
40720010Sjaap 	while ((c = getc(fp)) != '\n')	/* skip rest of input line */
40820010Sjaap 		if (c == EOF)
40920010Sjaap 			break;
41020010Sjaap }
41120010Sjaap 
fileinit()41220010Sjaap fileinit()	/* read in font and code files, etc. */
41320010Sjaap {
41420010Sjaap 	int i, fin, nw;
41520010Sjaap 	char *malloc(), *filebase, *p;
41620010Sjaap 	char temp[60];
41720010Sjaap 
41820010Sjaap 	/* open table for device,
41920010Sjaap 	/* read in resolution, size info, font info, etc.
42020010Sjaap 	/* and set params
42120010Sjaap 	*/
42220010Sjaap 	sprintf(temp, "%s/dev%s/DESC.out", fontdir, devname);
42320010Sjaap 	if ((fin = open(temp, 0)) < 0)
42420010Sjaap 		error(FATAL, "can't open tables for %s\n", temp);
42520010Sjaap 	read(fin, &dev, sizeof(struct dev));
42620010Sjaap 	nfonts = dev.nfonts;
42720010Sjaap 	nsizes = dev.nsizes;
42820010Sjaap 	nchtab = dev.nchtab;
42920010Sjaap 	filebase = malloc(dev.filesize);	/* enough room for whole file */
43020010Sjaap 	read(fin, filebase, dev.filesize);	/* all at once */
43120010Sjaap 	pstab = (short *) filebase;
43220010Sjaap 	chtab = pstab + nsizes + 1;
43320010Sjaap 	chname = (char *) (chtab + dev.nchtab);
43420010Sjaap 	p = chname + dev.lchname;
43520010Sjaap 	for (i = 1; i <= nfonts; i++) {
43625286Sjaap 		fontbase[i] = (struct Font *) p;
43720010Sjaap 		nw = *p & BMASK;	/* 1st thing is width count */
43820010Sjaap 		if (smnt == 0 && fontbase[i]->specfont == 1)
43920010Sjaap 			smnt = i;	/* first special font */
44025286Sjaap 		p += sizeof(struct Font);	/* that's what's on the beginning */
44120010Sjaap 		widthtab[i] = p;
44220010Sjaap 		codetab[i] = p + 2 * nw;
44320010Sjaap 		fitab[i] = p + 3 * nw;
44420010Sjaap 		p += 3 * nw + dev.nchtab + 128 - 32;
44520010Sjaap 		if(fontbase[i]->fonttab == 1) {	/*MC:jna There is a fonttable */
44633654Sjaap 			fonttab[i] = (f_code *)p;	/*MC:jna get it */
44720010Sjaap 			p += nw * sizeof( short );	/* and skip it */
44820010Sjaap 		}
44920010Sjaap 		t_fp(i, fontbase[i]->namefont, fontbase[i]->intname);
45020010Sjaap 		if(dbg > 2) fontprint(i);
45120010Sjaap 	}
45220010Sjaap 	/*MC:jna
45320010Sjaap 	 *
45420010Sjaap 	 * Make space for the font cache for NCH characters
45520010Sjaap 	 * also reserve space for fonttable, if any is to come
45620010Sjaap          *
45720010Sjaap 	 */
45825286Sjaap 	fontbase[0] = (struct Font *) malloc(3*255 + dev.nchtab + (128-32) + sizeof (struct Font) + 255 * sizeof( short));
45925286Sjaap 	widthtab[0] = (char *) fontbase[0] + sizeof (struct Font);
46020010Sjaap 	fontbase[0]->nwfont = 255;
46120010Sjaap 	fontbase[0]->fonttab = 2;	/* there is room for a fonttable! */
46220010Sjaap 	close(fin);
46320010Sjaap }
46420010Sjaap 
fontprint(i)46520010Sjaap fontprint(i)	/* debugging print of font i (0,...) */
46620010Sjaap {
46720010Sjaap 	int j, k, n;
46820010Sjaap 	char *p;
46920010Sjaap 
47020010Sjaap 	printf("font %d:\n", i);
47120010Sjaap 	p = (char *) fontbase[i];
47220010Sjaap 	n = fontbase[i]->nwfont & BMASK;
47320010Sjaap 	printf("base=0%o, nchars=%d, spec=%d, name=%s, widtab=0%o, fitab=0%o\n",
47420010Sjaap 		p, n, fontbase[i]->specfont, fontbase[i]->namefont, widthtab[i], fitab[i]);
47520010Sjaap 	if( fontbase[i]->fonttab == 1)
47620010Sjaap 		printf("base fonttab=0%o\n", fonttab[i]);
47720010Sjaap 	printf("widths:\n");
47820010Sjaap 	for (j=0; j <= n; j++) {
47920010Sjaap 		printf(" %2d", widthtab[i][j] & BMASK);
48020010Sjaap 		if (j % 20 == 19) printf("\n");
48120010Sjaap 	}
48220010Sjaap 	printf("\ncodetab:\n");
48320010Sjaap 	for (j=0; j <= n; j++) {
48420010Sjaap 		printf(" %2d", codetab[i][j] & BMASK);
48520010Sjaap 		if (j % 20 == 19) printf("\n");
48620010Sjaap 	}
48720010Sjaap 	printf("\nfitab:\n");
48820010Sjaap 	for (j=0; j <= dev.nchtab + 128-32; j++) {
48920010Sjaap 		printf(" %2d", fitab[i][j] & BMASK);
49020010Sjaap 		if (j % 20 == 19) printf("\n");
49120010Sjaap 	}
49220010Sjaap 	if(fontbase[i]->fonttab == 1) {
49320010Sjaap 		printf("\nfonttab:\n");
49420010Sjaap 		for (j=0; j <= n; j++) {
49520010Sjaap 			printf(" %d", fonttab[i][j] );
49620010Sjaap 			if (j % 20 == 19) printf("\n");
49720010Sjaap 		}
49820010Sjaap 	}
49920010Sjaap 	printf("\n");
50020010Sjaap }
50120010Sjaap 
loadfont(n,s,s1)50220010Sjaap loadfont(n, s, s1)	/* load font info for font s on position n (0...) */
50320010Sjaap int n;
50420010Sjaap char *s, *s1;
50520010Sjaap {
50620010Sjaap 	char temp[60];
50720010Sjaap 	int fin, nw, norig, forig;
50820010Sjaap 	char *p;
50920010Sjaap 
51020010Sjaap 	if (n < 0 || n > NFONT)
51120010Sjaap 		error(FATAL, "illegal fp command %d %s", n, s);
51220010Sjaap 	if (strcmp(s, fontbase[n]->namefont) == 0)
51320010Sjaap 		return;
51420010Sjaap 	if (s1 == NULL || s1[0] == '\0')
51520010Sjaap 		sprintf(temp, "%s/dev%s/%s.out", fontdir, devname, s);
51620010Sjaap 	else
51720010Sjaap 		sprintf(temp, "%s/%s.out", s1, s);
51820010Sjaap 	if ((fin = open(temp, 0)) < 0)
51920010Sjaap 		error(FATAL, "can't open font table %s", temp);
52020010Sjaap 	norig = fontbase[n]->nwfont & BMASK;
52120010Sjaap 	forig = fontbase[n]->fonttab;
52220010Sjaap if(dbg > 3)
52320010Sjaap 	printf("nworig, %d, fonttaborig %d\n", norig, forig);
52420010Sjaap 	/*
52520010Sjaap 	 *MC:jna norig is the original amount of chars in
52620010Sjaap 	 * the (premounted) font)
52720010Sjaap 	 *
52820010Sjaap 	 * first geuss there is no fonttab
52920010Sjaap 	 */
53025286Sjaap 	read(fin, fontbase[n], 3*norig + nchtab+128-32 + sizeof(struct Font));
53120010Sjaap 	if ((fontbase[n]->nwfont & BMASK) > norig || (forig == 0 && fontbase[n]->fonttab == 1))
53220010Sjaap 		error(FATAL, "Font %s too big for position %d\n", s, n);
53320010Sjaap 		/*
53420010Sjaap 		 *MC:jna This means it is wise to make the default mounted
53520010Sjaap 		 * fonts larger then any other mounttable fonts.
53620010Sjaap 		 * And because of the kludge with the fonttable,
53720010Sjaap 		 * Make sure that they all contain fonttables!
53820010Sjaap 		 * It will make your life easier.
53920010Sjaap 		 */
54020010Sjaap 	nw = fontbase[n]->nwfont & BMASK;
54120010Sjaap if(dbg > 3)
54220010Sjaap 	printf("nw %d\n", nw);
54320010Sjaap 	if(fontbase[n]->fonttab == 1) {
54420010Sjaap 		lseek(fin, 0L, 0);
54525286Sjaap 		read(fin, fontbase[n], 3*norig + nchtab+128-32 + nw*sizeof(short) + sizeof(struct Font));
54620010Sjaap 		/*
54720010Sjaap 		 * There turned out to be a fonttab, so we have to read it in
54820010Sjaap 		 *MC:jna a bit stupid, but the laziest way (for me)
54920010Sjaap 		 */
55020010Sjaap 	}
55120010Sjaap 	close(fin);
55225286Sjaap 	widthtab[n] = (char *) fontbase[n] + sizeof(struct Font);
55320010Sjaap 	codetab[n] = (char *) widthtab[n] + 2 * nw;
55420010Sjaap 	fitab[n] = (char *) widthtab[n] + 3 * nw;
55520010Sjaap 	if(fontbase[n]->fonttab == 1)
55633654Sjaap 		fonttab[n] = (f_code *) (widthtab[n] + 3*nw + nchtab+128-32);
55720010Sjaap 	t_fp(n, fontbase[n]->namefont, fontbase[n]->intname);
55820010Sjaap 	fontbase[n]->nwfont = norig;	/* so can later use full original size */
55920010Sjaap 	if(fontbase[n]->fonttab == 0 && forig != 0)
56020010Sjaap 		fontbase[n]->fonttab = 2;
56120010Sjaap 					/* so we signal that there is place
56220010Sjaap 					 * for a fonttab! */
56320010Sjaap 
56420010Sjaap 	if (dbg > 2) fontprint(n);
56520010Sjaap }
56620010Sjaap 
done()56720010Sjaap done()
56820010Sjaap {
56920010Sjaap 	t_reset('s');
57020010Sjaap 	exit(0);
57120010Sjaap }
57220010Sjaap 
57320010Sjaap extern int ex();
57420010Sjaap 
57520010Sjaap /*VARARGS*/
error(f,s,a1,a2,a3,a4,a5,a6,a7)57620010Sjaap error(f, s, a1, a2, a3, a4, a5, a6, a7)
57720010Sjaap int f;
57820010Sjaap {
57920010Sjaap 	fprintf(stderr, "dhar: ");
58020010Sjaap 	fprintf(stderr, s, a1, a2, a3, a4, a5, a6, a7);
58120010Sjaap 	fprintf(stderr, "\n");
58220010Sjaap 	fflush(stderr);
58320010Sjaap 	if (f) {
58420010Sjaap 		ex();
58520010Sjaap 		exit(1);
58620010Sjaap 	}
58720010Sjaap }
58820010Sjaap 
58920010Sjaap /******************************************************************************
59020010Sjaap  ******************************************************************************
59120010Sjaap  *
59220010Sjaap  * Here begins the stuff that really depends on the harris
59320010Sjaap  *
59420010Sjaap  * For the time being, no use is made of the ruling functions of the Harris
59520010Sjaap  *
59620010Sjaap  ******************************************************************************
59720010Sjaap  ******************************************************************************
59820010Sjaap  */
59920010Sjaap 
60020010Sjaap /*
60120010Sjaap  * The basic idea is to delay the output as long as possible
60220010Sjaap  * until you really have to.
60320010Sjaap  * Until that time we just keep a machine status.
60420010Sjaap  *
60520010Sjaap  */
60620010Sjaap 
60720010Sjaap #include "hcodes.h"
60820010Sjaap 
60920010Sjaap char	devname[20] = "har";
61020010Sjaap int	fcut;
61120010Sjaap int	nocutting;
61233654Sjaap unsigned	short	papuse;
61320010Sjaap char	harcode;
61420010Sjaap 
t_init(reinit)61520010Sjaap t_init(reinit)	/* initialize device */
61620010Sjaap int reinit;
61720010Sjaap {
61820010Sjaap 	register int i;
61920010Sjaap 	extern int size;
62020010Sjaap 
62120010Sjaap 	hpos = vpos = 0;
62220010Sjaap 
62320010Sjaap 	if( strcmp( devname, "har") != NULL )
62420010Sjaap 		error(FATAL, "This input is not for the harris");
62520010Sjaap 
62620010Sjaap 	if (!tf)
62720010Sjaap 		if ( ( tf = creat("@har.in", 0664)) < 0)
62820010Sjaap 			error(FATAL, "Cannot create outputfile");
62920010Sjaap 
63020010Sjaap 	/* if there is a drawing character, use it */
63120010Sjaap 	for ( i = 0; i < nchtab; i++)
63220010Sjaap 		if (strcmp(&chname[chtab[i]], "l.") == 0)
63320010Sjaap 			break;
63420010Sjaap 	if ( i < nchtab) {
63520010Sjaap 		drawdot = i + 128;
63620010Sjaap 		drawsize = 1;
63720010Sjaap 	} else {
63820010Sjaap 		drawdot = '.';
63920010Sjaap 		drawsize = 3; 	/* 1/3 size */
64020010Sjaap 	}
64120010Sjaap 
64220010Sjaap 	output = 1;
64320010Sjaap 
64420010Sjaap 	oput(VMV); oput(0); oput(0);
64520010Sjaap 				/* See Harris Manual appendix D */
64620010Sjaap 	oput(HPO);oput(0);oput(0);
64720010Sjaap 
64820010Sjaap 		/* some initial size */
64920010Sjaap 	size = 10;
65020010Sjaap 	putsize();
65120010Sjaap 	putfont(999);
65220010Sjaap 	oput(STA);oput(0);oput(0360);
65320010Sjaap 
65420010Sjaap 	if( eflag ) {
65520010Sjaap 		operator("Translating");
65620010Sjaap 		oput(EST);	/* enable slave Translator */
65720010Sjaap 		fprintf(stderr,"Slave code translator enabled\n");
65820010Sjaap 	} else
65920010Sjaap 		operator("dhar started");
66020010Sjaap 
66120010Sjaap 	oput(OB0);		/* reset oblique */
66220010Sjaap 	oput(NAD);		/* No automatic displacement */
66320010Sjaap 	output = 0;
66420010Sjaap }
66520010Sjaap 
66620010Sjaap /*
66720010Sjaap  * The reason of struct state is never explained by bwk
66820010Sjaap  * but it looks like an stack of environments being pushed and popped
66920010Sjaap  *
67020010Sjaap  */
67120010Sjaap 
67220010Sjaap #define	MAXSTATE	5
67320010Sjaap 
67420010Sjaap struct state {
67520010Sjaap 	int	ssize;
67620010Sjaap 	int	sfont;
67720010Sjaap 	int	shpos;
67820010Sjaap 	int	svpos;
67920010Sjaap 	int	shorig;
68020010Sjaap 	int	svorig;
68120010Sjaap };
68220010Sjaap struct	state	state[MAXSTATE];
68320010Sjaap struct	state	*statep = state;
68420010Sjaap 
t_push()68520010Sjaap t_push()	/* begin a new block */
68620010Sjaap {
68720010Sjaap 	extern size;
68820010Sjaap 
68920010Sjaap 	error(!FATAL, "Different environment entered!");
69020010Sjaap 	hflush();
69120010Sjaap 	statep->ssize = size;
69220010Sjaap 	statep->sfont = font;
69320010Sjaap 	statep->shorig = horig;
69420010Sjaap 	statep->svorig = vorig;
69520010Sjaap 	statep->shpos = hpos;
69620010Sjaap 	statep->svpos = vpos;
69720010Sjaap 	horig = hpos;
69820010Sjaap 	vorig = vpos;
69920010Sjaap 	hpos = vpos = 0;
70020010Sjaap 	if (statep++ >= state+MAXSTATE)
70120010Sjaap 		error(FATAL, "{ nested too deep");
70220010Sjaap 	hpos = vpos = 0;
70320010Sjaap }
70420010Sjaap 
t_pop()70520010Sjaap t_pop()	/* pop to previous state */
70620010Sjaap {
70720010Sjaap 	extern size;
70820010Sjaap 	if (--statep < state)
70920010Sjaap 		error(FATAL, "extra }");
71020010Sjaap 	size = statep->ssize;
71120010Sjaap 	font = statep->sfont;
71220010Sjaap 	hpos = statep->shpos;
71320010Sjaap 	vpos = statep->svpos;
71420010Sjaap 	horig = statep->shorig;
71520010Sjaap 	vorig = statep->svorig;
71620010Sjaap }
71720010Sjaap 
71820010Sjaap int	pageno	= 0;
71920010Sjaap 
t_page(n)72020010Sjaap t_page(n)	/* do whatever new page functions */
72120010Sjaap {
72220010Sjaap 	int i;
72320010Sjaap 
72420010Sjaap 	if (output) {
72520010Sjaap 		papuse++;
72620010Sjaap 		/*
72720010Sjaap 		 * accounting in pages, for the time being.
72820010Sjaap 		 * New harprot should do the real accounting
72920010Sjaap 		 */
73020010Sjaap 		if (++scount >= spage) {
73120010Sjaap 			t_reset('p');
73220010Sjaap 			scount = 0;
73320010Sjaap 		}
73420010Sjaap 	}
73520010Sjaap 	vpos = 0;
73620010Sjaap 	output = 1;
73720010Sjaap 	++pageno;
73820010Sjaap 	if (nolist == 0)
73920010Sjaap 		return;	/* no -o specified */
74020010Sjaap 	output = 0;
74120010Sjaap 	for (i = 0; i < nolist; i += 2)
74220010Sjaap 		if (n >= olist[i] && n <= olist[i+1]) {
74320010Sjaap 			output = 1;
74420010Sjaap 			break;
74520010Sjaap 		}
74620010Sjaap }
74720010Sjaap 
t_newline()74820010Sjaap t_newline()	/* do whatever for the end of a line */
74920010Sjaap {
75020010Sjaap 	hpos = 0;	/* because we're now back at the left margin */
75120010Sjaap }
75220010Sjaap 
75320010Sjaap /*
75420010Sjaap  * A PSZ command on the Harris will change the horizontal & vertical size
75520010Sjaap  * A HPZ command will change just the Horizontal size.
75620010Sjaap  *
75720010Sjaap  * so size will contain horizontal size, and versize the vertical
75820010Sjaap  */
75920010Sjaap int	size;		/* current sizenumber (a legal index in pstab) */
76020010Sjaap int	horsize;	/* current horizontal size */
76120010Sjaap int	versize;	/* current vertcal size */
76220010Sjaap int	vsizeflag;	/* if set, versize differs from size */
76320010Sjaap 
t_size(n)76420010Sjaap t_size(n)	/* convert integer to internal size number*/
76520010Sjaap int n;
76620010Sjaap {
76720010Sjaap 	int i;
76820010Sjaap 
76920010Sjaap 	if (n <= pstab[0])
77020010Sjaap 		return(1);
77120010Sjaap 	else if (n >= pstab[nsizes-1])
77220010Sjaap 		return(nsizes);
77320010Sjaap 	for (i = 0; n > pstab[i]; i++)
77420010Sjaap 		;
77520010Sjaap 	return(i+1);
77620010Sjaap }
77720010Sjaap 
t_charht(n)77820010Sjaap t_charht(n)	/* set character height to n */
77920010Sjaap int n;
78020010Sjaap {
78120010Sjaap 	versize = pstab[n-1];
78220010Sjaap 	if( versize != horsize )
78320010Sjaap 		vsizeflag = 1;
78420010Sjaap 	putsize();
78520010Sjaap }
78620010Sjaap 
78720010Sjaap int sltab[]	= {   0,  9,  12,  15, -1};	/* possible slanting factors */
78820010Sjaap int slctab[]	= { OB0, OB1, OB2, OB3 };	/* slanting codes */
78920010Sjaap int slant;		/* current general slanting factor (of slant cmd) */
79020010Sjaap int fslant;		/* slanting factor of current font */
79120010Sjaap 
79220010Sjaap /*
79320010Sjaap  * current font has to be slanted, the slant will be set to fslant.
79420010Sjaap  * if the has been a slant command, the slant will be set to "slant",
79520010Sjaap  * overiding the fslant.
79620010Sjaap  * if slant is reset to 0, and there fslant != 0, slant will be set to "fslant"
79720010Sjaap  *
79820010Sjaap  * fslant will be manupulated by setfont (slanting can be an attribute
79920010Sjaap  * to a (Harris-)font.
80020010Sjaap  *
80120010Sjaap  * There are to many slants in this comment
80220010Sjaap  */
80320010Sjaap 
t_slant(n)80420010Sjaap t_slant(n)	/* do slant cmd */
80520010Sjaap int n;
80620010Sjaap {	slant = n;
80720010Sjaap 	setslant(n);
80820010Sjaap }
80920010Sjaap 
setslant(n)81020010Sjaap setslant(n)	/* set slant to n */
81120010Sjaap int n;
81220010Sjaap {	int j;
81320010Sjaap 	static int aslant;	/* the actual slanting factor */
81420010Sjaap 
81520010Sjaap 	if( n == aslant)
81620010Sjaap 		return;
81720010Sjaap 	if( n == 0 && fslant) {		/* back to slant of font */
81820010Sjaap 		setslant( fslant );
81920010Sjaap 		return;
82020010Sjaap 	}
82120010Sjaap 	for (j = 0; n > ( aslant = sltab[j]); j++)
82220010Sjaap 		if ( aslant == -1) {
82320010Sjaap 			aslant = sltab[--j];
82420010Sjaap 			break;
82520010Sjaap 		}
82620010Sjaap 	hflush();
82720010Sjaap 	oput( slctab[j] );
82820010Sjaap 	if (dbg)
82920010Sjaap 		printf("slant to %d\n", aslant);
83020010Sjaap }
83120010Sjaap 
slantfont(n)83220010Sjaap slantfont(n)	/* set fontslant */
83320010Sjaap int n;
83420010Sjaap {
83520010Sjaap 	fslant = n;
83620010Sjaap 	if(slant)
83720010Sjaap 		return;		/* slant of slanting command
83820010Sjaap 				 * overrides fslant */
83920010Sjaap 	setslant( fslant);	/* set slanting */
84020010Sjaap }
84120010Sjaap 
t_font(s)84220010Sjaap t_font(s)	/* convert string to internal font number */
84320010Sjaap char *s;
84420010Sjaap {
84520010Sjaap 	int n;
84620010Sjaap 
84720010Sjaap 	n = atoi(s);
84820010Sjaap 	if (n < 0 || n > nfonts)
84920010Sjaap 		n = 1;
85020010Sjaap 	return(n);
85120010Sjaap }
85220010Sjaap 
t_text(s)85320010Sjaap t_text(s)	/* print string s as text, the real \! implemantation */
85420010Sjaap char *s;
85520010Sjaap {
85620010Sjaap 	int c, w;
85720010Sjaap 	char str[100];
85820010Sjaap 
85920010Sjaap 	error(!FATAL, "t_text not well implented (yet)!");
86020010Sjaap 	if (!output)
86120010Sjaap 		return;
86220010Sjaap 	while (c = *s++) {
86320010Sjaap 		if (c == '\\') {
86420010Sjaap 			switch (c = *s++) {
86520010Sjaap 			case '\\':
86620010Sjaap 			case 'e':
86720010Sjaap 				put1('\\');
86820010Sjaap 				break;
86920010Sjaap 			case '(':
87020010Sjaap 				str[0] = *s++;
87120010Sjaap 				str[1] = *s++;
87220010Sjaap 				str[2] = '\0';
87320010Sjaap 				put1s(str);
87420010Sjaap 				break;
87520010Sjaap 			}
87620010Sjaap 		} else {
87720010Sjaap 			put1(c);
87820010Sjaap 		}
87920010Sjaap 		hmot(lastw);
88020010Sjaap 		if (dbg) printf("width = %d\n", lastw);
88120010Sjaap 	}
88220010Sjaap }
88320010Sjaap 
t_reset(c)88420010Sjaap t_reset(c)
88520010Sjaap {
88620010Sjaap 	int n;
88720010Sjaap 
88820010Sjaap 	if (output)
88920010Sjaap 		/*
89020010Sjaap 		 papuse++
89120010Sjaap 		 */
89220010Sjaap 		 ;
89320010Sjaap 	switch(c) {
89420010Sjaap 	case 'p':
89520010Sjaap 		cut();	/*
89620010Sjaap 			 * interpret pauses as comment for cutting
89720010Sjaap 			 * the paper
89820010Sjaap 			 */
89920010Sjaap 		if(dbg)
90020010Sjaap 			printf("reset p\n");
90120010Sjaap 		break;
90220010Sjaap 	case 's':
90320010Sjaap 		cut();
90420010Sjaap 		nocutting++;
90520010Sjaap 		if(dbg)
90620010Sjaap 			printf("reset s\n");
90720010Sjaap 		ex();
90820010Sjaap 		break;
90920010Sjaap 	default:
91020010Sjaap 		error(!FATAL, "Unknown reset function");
91120010Sjaap 		break;
91220010Sjaap 	}
91320010Sjaap }
91420010Sjaap 
cut()91520010Sjaap cut()
91620010Sjaap {
91720010Sjaap 	if (cflag || nocutting)
91820010Sjaap 		return;
91920010Sjaap 	hflush();
92020010Sjaap 	oput(CUT);
92120010Sjaap 	hpos = 0;
92220010Sjaap 	fcut = 1;
92320010Sjaap 	if (dbg)
92420010Sjaap 		printf("Cut\n");
92520010Sjaap }
92620010Sjaap 
account()92720010Sjaap account()	/* record paper use */
92820010Sjaap {
92920010Sjaap 	/* Don somewhere els */
93020010Sjaap }
93120010Sjaap 
t_trailer()93220010Sjaap t_trailer()
93320010Sjaap {
93420010Sjaap }
93520010Sjaap 
hflush()93620010Sjaap hflush()	/* do the actual motion */
93720010Sjaap {
93820010Sjaap 	if (!output)
93920010Sjaap 		return;
94020010Sjaap 	hor_move( hpos - htrue );
94120010Sjaap }
94220010Sjaap 
hor_move(amount)94320010Sjaap hor_move( amount )
94420010Sjaap int amount;
94520010Sjaap {	int high, low;
94620010Sjaap 
94733654Sjaap #if	vax || tahoe
94820010Sjaap 	if ( abs(amount) > 0177777)
94920010Sjaap 		error(FATAL, "Impossible escape");
95020010Sjaap #endif
95120010Sjaap 	if ( amount == 0 && harcode == 0)
95220010Sjaap 		return;		/* really nothing to do */
95320010Sjaap 	if(dbg > 1)
95420010Sjaap 		printf("h_move %d\n", amount);
95520010Sjaap 	low = amount & BMASK;
95620010Sjaap 	high = ( amount >> BYTE) & BMASK;
95720010Sjaap 	/*
95820010Sjaap 	 * if there is a code wating for output,
95920010Sjaap 	 * send that one to be output, plus the movement,
96020010Sjaap 	 * else send the MAB
96120010Sjaap 	 * and the movement
96220010Sjaap 	 */
96320010Sjaap 	oput( harcode ? harcode : MAB);
96420010Sjaap 	harcode = 0;
96520010Sjaap 	oput(high);
96620010Sjaap 	oput(low);
96720010Sjaap 	htrue = hpos;
96820010Sjaap }
96920010Sjaap 
97020010Sjaap 
hmot(n)97120010Sjaap hmot(n)
97220010Sjaap {
97320010Sjaap 	hpos += n;
97420010Sjaap }
97520010Sjaap 
hgoto(n)97620010Sjaap hgoto(n)
97720010Sjaap {
97820010Sjaap 	hpos = n;
97920010Sjaap }
98020010Sjaap 
vgoto(n)98120010Sjaap vgoto(n)
98220010Sjaap {
98320010Sjaap 	vmot(n - vpos);
98420010Sjaap }
98520010Sjaap 
vmot(n)98620010Sjaap vmot(n)	/* generate n units of vertical motion */
98720010Sjaap int n;
98820010Sjaap {
98920010Sjaap 	if (!output)
99020010Sjaap 		return;
99120010Sjaap 	if (n != 0) {
99220010Sjaap 		ver_move( n );
99320010Sjaap 		vpos += n;
99420010Sjaap 	}
99520010Sjaap }
99620010Sjaap 
ver_move(amount)99720010Sjaap ver_move( amount )
99820010Sjaap int amount;
99920010Sjaap {	int high, low;
100020010Sjaap 
100133654Sjaap #if	vax || tahoe
100220010Sjaap 	if ( abs(amount) > 0177777)
100320010Sjaap 		error(FATAL, "Impossible leading");
100420010Sjaap #endif
100520010Sjaap 	if(dbg > 1)
100620010Sjaap 		printf("v_move %d\n", amount);
100720010Sjaap 	low = amount & BMASK;
100820010Sjaap 	high = ( amount >> BYTE) & BMASK;
100920010Sjaap 	hflush();
101020010Sjaap 	oput(VMV);
101120010Sjaap 	oput(high);
101220010Sjaap 	oput(low);
101320010Sjaap }
101420010Sjaap 
put1s(s)101520010Sjaap put1s(s)	/* s is a funny char name */
101620010Sjaap char *s;
101720010Sjaap {
101820010Sjaap 	int i;
101920010Sjaap 
102020010Sjaap 	if (!output)
102120010Sjaap 		return;
102220010Sjaap /*
102320010Sjaap 	if(strcmp("ul", s) == 0) {
102420010Sjaap 		set_ul();
102520010Sjaap 		return;
102620010Sjaap 	}
102720010Sjaap 	if(strcmp("ru", s) == 0) {
102820010Sjaap 		set_ru();
102920010Sjaap 		return;
103020010Sjaap 	}
103120010Sjaap */
103220010Sjaap 	for (i = 0; i < nchtab; i++)
103320010Sjaap 		if (strcmp(&chname[chtab[i]], s) == 0)
103420010Sjaap 			break;
103520010Sjaap /*
103620010Sjaap printf("i+128: %d,s: %s, chname: %s\n", i+128, s, &chname[chtab[i]]);
103720010Sjaap */
103820010Sjaap 	if (i < nchtab)
103920010Sjaap 		put1(i + 128);
104020010Sjaap 	else
104120010Sjaap 		if(dbg)
104220010Sjaap 			printf("Special char %s doesn't exist\n", s);
104320010Sjaap }
104420010Sjaap 
104520010Sjaap /*
104620010Sjaap  * The Harris doesn'nt have a proper underrule or rule
104720010Sjaap  *
104820010Sjaap  * Try to generate one with the RULE command.
104920010Sjaap  *
105020010Sjaap  */
105120010Sjaap 
105220010Sjaap #define UL_DOWN	7	/* 7 half decipoints at pointsize 10 */
105320010Sjaap 
set_ul()105420010Sjaap set_ul()
105520010Sjaap {	int move;
105620010Sjaap 	int tmp;
105720010Sjaap 
105820010Sjaap 	hflush();
105920010Sjaap 	move = UL_DOWN * versize;
106020010Sjaap 	ver_move( move);
106120010Sjaap 	tmp = get_width("ul") / 2;
106220010Sjaap 		/*
106320010Sjaap 		 * we assume that dev.unitwidth is 10, so getwidth
106420010Sjaap 		 * will return the value in half decipoints!
106520010Sjaap 		 */
106620010Sjaap 	set_line(tmp);
106720010Sjaap 	ver_move( -move);
106820010Sjaap }
106920010Sjaap 
107020010Sjaap #define RU_DOWN	1	/* 2 half decipoints at pointsize 10 */
107120010Sjaap 
set_ru()107220010Sjaap set_ru()
107320010Sjaap {
107420010Sjaap 	int tmp, move;
107520010Sjaap 
107620010Sjaap 	hflush();
107720010Sjaap 	move = RU_DOWN * versize;
107820010Sjaap 	ver_move( move);
107920010Sjaap 	tmp = get_width("ul") / 2;
108020010Sjaap 	set_line(tmp);
108120010Sjaap 	ver_move( -move);
108220010Sjaap }
108320010Sjaap 
108420010Sjaap #define HEIGHT	6	/* thickness (decipoints) at pointsize 10 */
108520010Sjaap #define MIN_VAL	2	/* Minimum value for rule height & length */
108620010Sjaap #define MAX_H	720	/* Maximum for height */
108720010Sjaap #define MAX_L	8160	/* Maximum length of the SMC 68 Pica machine */
108820010Sjaap 
108920010Sjaap /*
109020010Sjaap  * set line of length decipoints.
109120010Sjaap  */
109220010Sjaap 
set_line(length)109320010Sjaap set_line( length )
109420010Sjaap int length;
109520010Sjaap {
109620010Sjaap 	int height;
109720010Sjaap 	char one, two, three, four;
109820010Sjaap 
109920010Sjaap 	/*
110020010Sjaap 	printf("Line %d decipoints\n", i);
110120010Sjaap 	*/
110220010Sjaap 
110320010Sjaap 	height = (HEIGHT * versize + dev.unitwidth/2) / dev.unitwidth;
110420010Sjaap 	if ( height < MIN_VAL)
110520010Sjaap 		height = MIN_VAL;
110620010Sjaap 	if (height > MAX_H)
110720010Sjaap 		height = MAX_H;
110820010Sjaap 	if (length > MAX_L)
110920010Sjaap 		length = MAX_L;
111020010Sjaap 	if (dbg)
111120010Sjaap 		printf("Line: length %d height %d\n", length, height);
111220010Sjaap 
111320010Sjaap 	one = ( height >> BYTE ) | RUL;
111420010Sjaap 	two = height & BMASK;
111520010Sjaap 	three = length >> BYTE;
111620010Sjaap 	four = length & BMASK;
111720010Sjaap 	oput(one); oput(two); oput(three); oput(four);
111820010Sjaap }
111920010Sjaap 
112020010Sjaap /*
112120010Sjaap  * get the width of a char, to be used only by set_ul() and set-ru()
112220010Sjaap  */
112320010Sjaap 
112420010Sjaap int
get_width(s)112520010Sjaap get_width( s )
112620010Sjaap char *s;
112720010Sjaap {
112820010Sjaap 	int c;
112920010Sjaap 	int width;
113020010Sjaap 	int j, i, k, ofont;
113120010Sjaap 	char *pw;
113220010Sjaap 
113320010Sjaap 	for (c = 0; c < nchtab; c++)
113420010Sjaap 		if (strcmp(&chname[chtab[c]], s) == 0)
113520010Sjaap 			break;
113620010Sjaap 	if (c < nchtab)
113720010Sjaap 		c += 128-32;
113820010Sjaap 	if (c <= 0 || c >= nchtab + 128-32) {
113920010Sjaap 		if (dbg) printf("non-exist 0%o\n", c+32);
114020010Sjaap 		return;
114120010Sjaap 	}
114220010Sjaap 	k = ofont = font;
114320010Sjaap 	i = fitab[font][c] & BMASK;
114420010Sjaap 	if (i != 0) {	/* it's on this font */
114520010Sjaap 		pw = widthtab[font];
114620010Sjaap 	} else if (smnt > 0) {		/* on special (we hope) */
114720010Sjaap 		for (k=smnt, j=0; j <= nfonts; j++, k = (k+1) % (nfonts+1))
114820010Sjaap 			/*
114920010Sjaap 			 * Look for the character, start at the special font
115020010Sjaap 			 * and search further in a wrap around manner
115120010Sjaap 			 */
115220010Sjaap 			if ((i = fitab[k][c] & BMASK) != 0) {
115320010Sjaap 				pw = widthtab[k];
115420010Sjaap 				setfont(k);
115520010Sjaap 				break;
115620010Sjaap 			}
115720010Sjaap 	}
115820010Sjaap 	if (i == 0 || (width = pw[i] & BMASK) == 0 || k > nfonts) {
115920010Sjaap 		/* device drivers do width & 077, not really necessary */
116020010Sjaap 		if (dbg) {
116120010Sjaap 				printf("Width not found \\(%s\n", s);
116220010Sjaap 		}
116320010Sjaap 		return;
116420010Sjaap 	}
116520010Sjaap 	width = (width * horsize + dev.unitwidth/2) / dev.unitwidth;
116620010Sjaap 	if (font != ofont)
116720010Sjaap 		setfont(ofont);
116820010Sjaap 	return( width);
116920010Sjaap }
117020010Sjaap 
117120010Sjaap /* font position info: */
117220010Sjaap 
117320010Sjaap struct {
117420010Sjaap 	char *name;
117520010Sjaap 	int number;
117620010Sjaap } fontname[NFONT+1];
117720010Sjaap 
put1(c)117820010Sjaap put1(c)	/* output char c */
117920010Sjaap int c;
118020010Sjaap {
118120010Sjaap 	char *pw;
118220010Sjaap 	register char *p;
118320010Sjaap 	register int i, k;
118420010Sjaap 	int j, ofont, code;
118520010Sjaap 	short f;
118620010Sjaap 
118720010Sjaap 	if (!output)
118820010Sjaap 		return;
118920010Sjaap 	c -= 32;
119020010Sjaap 	if (c <= 0) {
119120010Sjaap 		if (dbg) printf("non-exist 0%o\n", c+32);
119220010Sjaap 		lastw = widthtab[font][0] * pstab[size-1] /dev.unitwidth;
119320010Sjaap 		return;
119420010Sjaap 	}
119520010Sjaap 	k = ofont = font;
119620010Sjaap 	i = fitab[font][c] & BMASK;
119720010Sjaap 	if (i != 0) {	/* it's on this font */
119820010Sjaap 		p = codetab[font];
119920010Sjaap 		pw = widthtab[font];
120020010Sjaap 	} else if (smnt > 0) {		/* on special (we hope) */
120120010Sjaap 		for (k=smnt, j=0; j <= nfonts; j++, k = (k+1) % (nfonts+1))
120220010Sjaap 			/*
120320010Sjaap 			 * Look for the character, start at the special font
120420010Sjaap 			 * and search further in a wrap around manner
120520010Sjaap 			 */
120620010Sjaap 			if ((i = fitab[k][c] & BMASK) != 0) {
120720010Sjaap 				p = codetab[k];
120820010Sjaap 				pw = widthtab[k];
120920010Sjaap 				setfont(k);
121020010Sjaap 				break;
121120010Sjaap 			}
121220010Sjaap 	}
121320010Sjaap 	if (i == 0 || (code = p[i] & BMASK) == 0 || k > nfonts) {
121420010Sjaap 		if (dbg) {
121520010Sjaap 			if (isprint(c+32) && isascii(c+32))
121620010Sjaap 				printf("not found %c\n", c+32);
121720010Sjaap 			else
121820010Sjaap 				printf("not found \\(%s\n", &chname[chtab[c -128+32]]);
121920010Sjaap 		}
122020010Sjaap 		return;
122120010Sjaap 	}
122220010Sjaap 	if (fontbase[k]->fonttab == 1)
122333654Sjaap 		f = tosh( fonttab[k], i);
122420010Sjaap 	else
122520010Sjaap 		f = fontname[k].number;
122620010Sjaap 	hflush();
122720010Sjaap 	if (dbg) {
122820010Sjaap 		if (isprint(c+32) && isascii(c+32)) { /* My God! */
122920010Sjaap 			printf("%c %d %d\n", c+32, code, f);
123020010Sjaap 		}
123120010Sjaap 		else
123220010Sjaap 			printf("\\(%s %d %d\n", &chname[chtab[c -128+32]], code, f);
123320010Sjaap 	}
123420010Sjaap 	if(code == 0 || code > 0200) {
123520010Sjaap 		error(FATAL,"Illegal code 0%o found for char %03o\n", code, c+32);
123620010Sjaap 	}
123720010Sjaap 	putcode(code, f);	/* character is < 254 */
123820010Sjaap 	if (font != ofont)	/* char on special font, reset	*/
123920010Sjaap 		setfont(ofont);
124020010Sjaap 	lastw = pw[i] & BMASK;
124120010Sjaap /*HIRO*/
124220010Sjaap if( dbg)
124320010Sjaap 	fprintf(stderr,"lastw %d pw[i] %d\n", lastw,pw[i]);
124420010Sjaap 	lastw = (lastw * pstab[size-1] + dev.unitwidth/2) / dev.unitwidth;
124520010Sjaap }
124620010Sjaap 
putcode(code,f)124720010Sjaap putcode(code, f)
124820010Sjaap char code; short f;
124920010Sjaap {
125020010Sjaap 	static short phfont;
125120010Sjaap 
125233654Sjaap #if	vax || tahoe
125320010Sjaap 	if ( f > 0177777)
125420010Sjaap 		error(FATAL, "Impossible font selected");
125520010Sjaap #endif
125620010Sjaap 
125720010Sjaap 	if( harcode) {	/* if character pending */
125820010Sjaap 		hflush();	/* update position and flush pending char */
125920010Sjaap 	}
126020010Sjaap 	if ( f != phfont ) {
126120010Sjaap 		if(dbg > 1)
126220010Sjaap 			printf("font to %d\n", f);
126320010Sjaap 		putfont(f);
126420010Sjaap 	}
126520010Sjaap 	harcode = code;
126620010Sjaap 	phfont = f;
126720010Sjaap }
126820010Sjaap 
putfont(f)126920010Sjaap putfont(f)
127020010Sjaap int f;
127120010Sjaap {	int high, low;
127220010Sjaap 
127320010Sjaap 	low = f & BMASK;
127420010Sjaap 	high = (f >> BYTE ) & BMASK;
127520010Sjaap 	oput(FNT);
127620010Sjaap 	oput(high);
127720010Sjaap 	oput(low);
127820010Sjaap }
127920010Sjaap 
setsize(n)128020010Sjaap setsize(n)	/* set point size to a true pointsize */
128120010Sjaap int n;
128220010Sjaap {
128320010Sjaap 
128420010Sjaap 	if (!output)
128520010Sjaap 		return;
128620010Sjaap 	horsize = pstab[n-1];
128720010Sjaap 	vsizeflag = 0;
128820010Sjaap 	size = n;
128920010Sjaap 	putsize();
129020010Sjaap }
129120010Sjaap 
129220010Sjaap /*
129320010Sjaap  * Do the actual sizechange(s).
129420010Sjaap  */
129520010Sjaap 
putsize()129620010Sjaap putsize()
129720010Sjaap {
129820010Sjaap 	if(!vsizeflag) {
129920010Sjaap 		flushchar();
130020010Sjaap 		sizecmd( PSZ, horsize);
130120010Sjaap 	}
130220010Sjaap 	else {
130320010Sjaap 		flushchar();
130420010Sjaap 		sizecmd( PSZ, versize);
130520010Sjaap 		sizecmd( HPZ, horsize);
130620010Sjaap 	}
130720010Sjaap }
130820010Sjaap 
sizecmd(cmd,n)130920010Sjaap sizecmd( cmd, n)
131020010Sjaap int	cmd, n;
131120010Sjaap {
131220010Sjaap 	int i, low, high;
131320010Sjaap 
131420010Sjaap 	i = 10 * n;
131520010Sjaap 	if(dbg)
131620010Sjaap 		printf("size to %d\n", n);
131720010Sjaap 	if( i > 01777)
131820010Sjaap 		error(FATAL, "Impossible pointsize requested");
131920010Sjaap 	low = i & BMASK;
132020010Sjaap 	high = (i >> BYTE) & BMASK;
132120010Sjaap 	if( high > 03 )
132220010Sjaap 		error(FATAL, "system error in point size cmd");
132320010Sjaap 	oput( cmd | high);
132420010Sjaap 	oput(low);
132520010Sjaap }
132620010Sjaap 
t_fp(n,s,si)132720010Sjaap t_fp(n, s, si)	/* font position n now contains font s, intname si */
132820010Sjaap int n;
132920010Sjaap char *s, *si;
133020010Sjaap {
133120010Sjaap 	fontname[n].name = s;
133220010Sjaap 	fontname[n].number = atoi(si);
133320010Sjaap }
133420010Sjaap 
setfont(n)133520010Sjaap setfont(n)	/* set font to n (internal)*/
133620010Sjaap int n;
133720010Sjaap {
133820010Sjaap 	if (!output)
133920010Sjaap 		return;
134020010Sjaap 	if (n < 0 || n > NFONT)
134120010Sjaap 		error(FATAL, "illegal font %d\n", n);
134220010Sjaap 	font = n;
134320010Sjaap 	slantfont(fontbase[n]->slant & BMASK);
134420010Sjaap }
134520010Sjaap 
134620010Sjaap /*
134720010Sjaap putint(n)
134820010Sjaap {
134920010Sjaap 	if (dbg) {
135020010Sjaap 		printf("%02d\n", n);
135120010Sjaap 		return;
135220010Sjaap 	}
135320010Sjaap 	putc(n>>8, tf);
135420010Sjaap 	putc(n, tf);
135520010Sjaap }
135620010Sjaap */
1357