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