1*20010Sjaap #ifndef lint
2*20010Sjaap static char *sccsid = "@(#)dhar.c	1.1	CWI 1.1	05/09/85";
3*20010Sjaap #endif
4*20010Sjaap /*
5*20010Sjaap  * Drive the Harris 7500 tyepsetter
6*20010Sjaap  *		    75XX
7*20010Sjaap  * Other machines of that harris serie will probably run as well with this
8*20010Sjaap  *
9*20010Sjaap  * Author: jaap akkerhuis, Oc 1982, Mathematisch Cetrum.
10*20010Sjaap  *
11*20010Sjaap  */
12*20010Sjaap /*
13*20010Sjaap output language from troff:
14*20010Sjaap all numbers are character strings
15*20010Sjaap 
16*20010Sjaap sn	size in points
17*20010Sjaap fn	font as number from 1-n
18*20010Sjaap cx	ascii character x
19*20010Sjaap Cxyz	funny char xyz. terminated by white space
20*20010Sjaap Hn	go to absolute horizontal position n
21*20010Sjaap Vn	go to absolute vertical position n (down is positive)
22*20010Sjaap hn	go n units horizontally (relative)
23*20010Sjaap vn	ditto vertically
24*20010Sjaap nnc	move right nn, then print c (exactly 2 digits!)
25*20010Sjaap 		(this wart is an optimization that shrinks output file size
26*20010Sjaap 		 about 35% and run-time about 15% while preserving ascii-ness)
27*20010Sjaap Dt ...\n	draw operation 't':
28*20010Sjaap 	Dl x y		line from here by x,y
29*20010Sjaap 	Dc d		circle of diameter d with left side here
30*20010Sjaap 	De x y		ellipse of axes x,y with left side here
31*20010Sjaap 	Da x y r	arc counter-clockwise by x,y of radius r
32*20010Sjaap 	D~ x y x y ...	wiggly line by x,y then x,y ...
33*20010Sjaap w	paddable words space -- no action needed
34*20010Sjaap nb a	end of line (information only -- no action needed)
35*20010Sjaap 	b = space before line, a = after
36*20010Sjaap p	new page begins -- set v to 0
37*20010Sjaap tstring print string as plain text
38*20010Sjaap #...\n	comment
39*20010Sjaap x ...\n	device control functions:
40*20010Sjaap 	x i	init
41*20010Sjaap 	x T s	name of device is s
42*20010Sjaap 	x r n h v	resolution is n/inch
43*20010Sjaap 		h = min horizontal motion, v = min vert
44*20010Sjaap 	x p	pause (can restart)
45*20010Sjaap 	x s	stop -- done for ever
46*20010Sjaap 	x t	generate trailer
47*20010Sjaap 	x f n s	font position n contains font s
48*20010Sjaap 	x H n	set character height to n
49*20010Sjaap 	x S n	set slant to N
50*20010Sjaap 
51*20010Sjaap 	Subcommands like "i" are often spelled out like "init".
52*20010Sjaap */
53*20010Sjaap /*
54*20010Sjaap  * MC:jna
55*20010Sjaap  * The output language signs { and } are not described
56*20010Sjaap  *
57*20010Sjaap  */
58*20010Sjaap 
59*20010Sjaap #include	<stdio.h>
60*20010Sjaap #include	<ctype.h>
61*20010Sjaap #include	<signal.h>
62*20010Sjaap 
63*20010Sjaap #include "../dev.h"
64*20010Sjaap #define	NFONT	10
65*20010Sjaap 
66*20010Sjaap int	output	= 0;	/* do we do output at all? */
67*20010Sjaap int	nolist	= 0;	/* output page list if > 0 */
68*20010Sjaap int	olist[20];	/* pairs of page numbers */
69*20010Sjaap int	spage	= 9999;	/* stop every spage pages */
70*20010Sjaap int	scount	= 0;
71*20010Sjaap 
72*20010Sjaap struct	dev	dev;
73*20010Sjaap struct font *fontbase[NFONT+1];
74*20010Sjaap short	*pstab;
75*20010Sjaap int	nsizes;
76*20010Sjaap int	nfonts;
77*20010Sjaap int	smnt;	/* index of first special font */
78*20010Sjaap int	nchtab;
79*20010Sjaap char	*chname;
80*20010Sjaap short	*chtab;
81*20010Sjaap char	*fitab[NFONT+1];
82*20010Sjaap char	*widthtab[NFONT+1];	/* widtab would be a better name */
83*20010Sjaap char	*codetab[NFONT+1];	/* device codes */
84*20010Sjaap short	*fonttab[NFONT+1];	/*MC:jna optional fontcodes */
85*20010Sjaap 
86*20010Sjaap #define	FATAL	1
87*20010Sjaap #define	BMASK	0377
88*20010Sjaap #define BYTE	8
89*20010Sjaap int	dbg	= 0;
90*20010Sjaap int	eflag;
91*20010Sjaap int	cflag;
92*20010Sjaap int	res;		/* input assumed computed according to this resolution */
93*20010Sjaap int	tf = 0;		/* output file will be har.in or standout */
94*20010Sjaap char	*fontdir	= "/usr/local/lib/ditroff/font";
95*20010Sjaap extern char devname[];
96*20010Sjaap 
97*20010Sjaap #define	abs(n)	((n) >= 0 ? (n) : -(n))
98*20010Sjaap 
99*20010Sjaap int	font	= 1;	/* current font */
100*20010Sjaap int	hpos;		/* horizontal position where we are supposed to be next (left = 0) */
101*20010Sjaap int	lastw;		/*  width of last printed char, (for t_text()) */
102*20010Sjaap int	vpos;		/* current vertical position (down positive) */
103*20010Sjaap int	horig;		/* h origin of current block; hpos rel to this */
104*20010Sjaap int	vorig;
105*20010Sjaap int	htrue	= 0;
106*20010Sjaap int	vtrue	= 0;
107*20010Sjaap int	DX	= 4;	/* step size in x for drawing */
108*20010Sjaap int	DY	= 4;	/* step size in y for drawing */
109*20010Sjaap int	drawdot	= '.';	/* draw with this character */
110*20010Sjaap int	drawsize = 1;	/* shrink by this factor when drawing */
111*20010Sjaap 			/* drawsize will be set in t_init as well! */
112*20010Sjaap 
113*20010Sjaap main(argc, argv)
114*20010Sjaap char *argv[];
115*20010Sjaap {
116*20010Sjaap 	FILE *fp;
117*20010Sjaap 	int i;
118*20010Sjaap 	int done();
119*20010Sjaap 	while (argc > 1 && argv[1][0] == '-') {
120*20010Sjaap 		switch (argv[1][1]) {
121*20010Sjaap 		case 'f':
122*20010Sjaap 		case 'F':
123*20010Sjaap 			fontdir = argv[2];
124*20010Sjaap 			argv++;
125*20010Sjaap 			argc--;
126*20010Sjaap 			break;
127*20010Sjaap 		case 't':
128*20010Sjaap 			tf = 1;	/* stdout */
129*20010Sjaap 			break;
130*20010Sjaap 		case 'o':
131*20010Sjaap 			outlist(&argv[1][2]);
132*20010Sjaap 			break;
133*20010Sjaap 		case 'd':
134*20010Sjaap 			dbg = atoi(&argv[1][2]);
135*20010Sjaap 			if (dbg == 0) dbg = 1;
136*20010Sjaap 			break;
137*20010Sjaap 		case 's':
138*20010Sjaap 			spage = atoi(&argv[1][2]);
139*20010Sjaap 			if (spage <= 0)
140*20010Sjaap 				spage = 9999;
141*20010Sjaap 			break;
142*20010Sjaap 		case 'e':
143*20010Sjaap 			eflag++;
144*20010Sjaap 			break;
145*20010Sjaap 		case 'c':
146*20010Sjaap 			cflag++;
147*20010Sjaap 			break;
148*20010Sjaap 		}
149*20010Sjaap 		argc--;
150*20010Sjaap 		argv++;
151*20010Sjaap 	}
152*20010Sjaap 				/*
153*20010Sjaap 				 * Stop every 4 pages to prevent the
154*20010Sjaap 				 * Harris to Cut the paper every 6 feet,
155*20010Sjaap 				 * wat will likely to be in the middle of
156*20010Sjaap 				 * a page. Every for page is proved to be
157*20010Sjaap 				 * reasonable.
158*20010Sjaap 				 */
159*20010Sjaap 	if (spage == 0 || 9999)
160*20010Sjaap 		spage = 4;
161*20010Sjaap 
162*20010Sjaap 	if (signal(SIGINT, done) == SIG_IGN) {
163*20010Sjaap 		signal(SIGINT, SIG_IGN);
164*20010Sjaap 		signal(SIGQUIT, SIG_IGN);
165*20010Sjaap 		signal(SIGHUP, SIG_IGN);
166*20010Sjaap 	} else {
167*20010Sjaap 		signal(SIGQUIT, done);
168*20010Sjaap 		signal(SIGHUP, done);
169*20010Sjaap 	}
170*20010Sjaap 	signal(SIGTERM, done);
171*20010Sjaap 	if (argc <= 1)
172*20010Sjaap 		conv(stdin);
173*20010Sjaap 	else
174*20010Sjaap 		while (--argc > 0) {
175*20010Sjaap 			if (strcmp(*++argv, "-") == 0)
176*20010Sjaap 				fp = stdin;
177*20010Sjaap 			else if ((fp = fopen(*argv, "r")) == NULL)
178*20010Sjaap 				error(FATAL, "can't open %s", *argv);
179*20010Sjaap 				conv(fp);
180*20010Sjaap 			fclose(fp);
181*20010Sjaap 		}
182*20010Sjaap 	account();
183*20010Sjaap 	done();
184*20010Sjaap }
185*20010Sjaap 
186*20010Sjaap outlist(s)	/* process list of page numbers to be printed */
187*20010Sjaap char *s;
188*20010Sjaap {
189*20010Sjaap 	int n1, n2, i;
190*20010Sjaap 
191*20010Sjaap 	nolist = 0;
192*20010Sjaap 	while (*s) {
193*20010Sjaap 		n1 = 0;
194*20010Sjaap 		if (isdigit(*s))
195*20010Sjaap 			do
196*20010Sjaap 				n1 = 10 * n1 + *s++ - '0';
197*20010Sjaap 			while (isdigit(*s));
198*20010Sjaap 		else
199*20010Sjaap 			n1 = -9999;
200*20010Sjaap 		n2 = n1;
201*20010Sjaap 		if (*s == '-') {
202*20010Sjaap 			s++;
203*20010Sjaap 			n2 = 0;
204*20010Sjaap 			if (isdigit(*s))
205*20010Sjaap 				do
206*20010Sjaap 					n2 = 10 * n2 + *s++ - '0';
207*20010Sjaap 				while (isdigit(*s));
208*20010Sjaap 			else
209*20010Sjaap 				n2 = 9999;
210*20010Sjaap 		}
211*20010Sjaap 		olist[nolist++] = n1;
212*20010Sjaap 		olist[nolist++] = n2;
213*20010Sjaap 		if (*s != '\0')
214*20010Sjaap 			s++;
215*20010Sjaap 	}
216*20010Sjaap 	olist[nolist] = 0;
217*20010Sjaap 	if (dbg)
218*20010Sjaap 		for (i=0; i<nolist; i += 2)
219*20010Sjaap 			printf("%3d %3d\n", olist[i], olist[i+1]);
220*20010Sjaap }
221*20010Sjaap 
222*20010Sjaap conv(fp)
223*20010Sjaap register FILE *fp;
224*20010Sjaap {
225*20010Sjaap 	register int c, k;
226*20010Sjaap 	int m, n, i, n1, m1;
227*20010Sjaap 	char str[100], buf[300];
228*20010Sjaap 
229*20010Sjaap 	while ((c = getc(fp)) != EOF) {
230*20010Sjaap 		switch (c) {
231*20010Sjaap 		case '\n':	/* when input is text */
232*20010Sjaap 		case ' ':
233*20010Sjaap 		case 0:		/* occasional noise creeps in */
234*20010Sjaap 			break;
235*20010Sjaap 		case '{':	/* push down current environment */
236*20010Sjaap 			t_push();
237*20010Sjaap 			break;
238*20010Sjaap 		case '}':
239*20010Sjaap 			t_pop();
240*20010Sjaap 			break;
241*20010Sjaap 		case '0': case '1': case '2': case '3': case '4':
242*20010Sjaap 		case '5': case '6': case '7': case '8': case '9':
243*20010Sjaap 			/* two motion digits plus a character */
244*20010Sjaap 			hmot((c-'0')*10 + getc(fp)-'0');
245*20010Sjaap 			put1(getc(fp));
246*20010Sjaap 			break;
247*20010Sjaap 		case 'c':	/* single ascii character */
248*20010Sjaap 			put1(getc(fp));
249*20010Sjaap 			break;
250*20010Sjaap 		case 'C':
251*20010Sjaap 			fscanf(fp, "%s", str);
252*20010Sjaap 			put1s(str);
253*20010Sjaap 			break;
254*20010Sjaap 		case 't':	/* straight text */
255*20010Sjaap 			fgets(buf, sizeof(buf), fp);
256*20010Sjaap 			t_text(buf);
257*20010Sjaap 			break;
258*20010Sjaap 		case 'D':	/* draw function */
259*20010Sjaap 			fgets(buf, sizeof(buf), fp);
260*20010Sjaap 			switch (buf[0]) {
261*20010Sjaap 			case 'l':	/* draw a line */
262*20010Sjaap 				sscanf(buf+1, "%d %d", &n, &m);
263*20010Sjaap 				drawline(n, m, ".");
264*20010Sjaap 				break;
265*20010Sjaap 			case 'c':	/* circle */
266*20010Sjaap 				sscanf(buf+1, "%d", &n);
267*20010Sjaap 				drawcirc(n);
268*20010Sjaap 				break;
269*20010Sjaap 			case 'e':	/* ellipse */
270*20010Sjaap 				sscanf(buf+1, "%d %d", &m, &n);
271*20010Sjaap 				drawellip(m, n);
272*20010Sjaap 				break;
273*20010Sjaap 			case 'a':	/* arc */
274*20010Sjaap 				sscanf(buf+1, "%d %d %d %d", &n, &m, &n1, &m1);
275*20010Sjaap 				drawarc(n, m, n1, m1);
276*20010Sjaap 				break;
277*20010Sjaap 			case '~':	/* wiggly line */
278*20010Sjaap 				drawwig(buf+1);
279*20010Sjaap 				break;
280*20010Sjaap 			default:
281*20010Sjaap 				error(FATAL, "unknown drawing function %s\n", buf);
282*20010Sjaap 				break;
283*20010Sjaap 			}
284*20010Sjaap 			break;
285*20010Sjaap 		case 's':
286*20010Sjaap 			fscanf(fp, "%d", &n);	/* ignore fractional sizes */
287*20010Sjaap 			setsize(t_size(n));
288*20010Sjaap 			break;
289*20010Sjaap 		case 'f':
290*20010Sjaap 			fscanf(fp, "%s", str);
291*20010Sjaap 			setfont(t_font(str));
292*20010Sjaap 			break;
293*20010Sjaap 		case 'H':	/* absolute horizontal motion */
294*20010Sjaap 			/* fscanf(fp, "%d", &n); */
295*20010Sjaap 			while ((c = getc(fp)) == ' ')
296*20010Sjaap 				;
297*20010Sjaap 			k = 0;
298*20010Sjaap 			do {
299*20010Sjaap 				k = 10 * k + c - '0';
300*20010Sjaap 			} while (isdigit(c = getc(fp)));
301*20010Sjaap 			ungetc(c, fp);
302*20010Sjaap 			hgoto(k);
303*20010Sjaap 			break;
304*20010Sjaap 		case 'h':	/* relative horizontal motion */
305*20010Sjaap 			/* fscanf(fp, "%d", &n); */
306*20010Sjaap 			while ((c = getc(fp)) == ' ')
307*20010Sjaap 				;
308*20010Sjaap 			k = 0;
309*20010Sjaap 			do {
310*20010Sjaap 				k = 10 * k + c - '0';
311*20010Sjaap 			} while (isdigit(c = getc(fp)));
312*20010Sjaap 			ungetc(c, fp);
313*20010Sjaap 			hmot(k);
314*20010Sjaap 			break;
315*20010Sjaap 		case 'w':	/* word space */
316*20010Sjaap 			break;
317*20010Sjaap 		case 'V':
318*20010Sjaap 			fscanf(fp, "%d", &n);
319*20010Sjaap 			vgoto(n);
320*20010Sjaap 			break;
321*20010Sjaap 		case 'v':
322*20010Sjaap 			fscanf(fp, "%d", &n);
323*20010Sjaap 			vmot(n);
324*20010Sjaap 			break;
325*20010Sjaap 		case 'p':	/* new page */
326*20010Sjaap 			fscanf(fp, "%d", &n);
327*20010Sjaap 			t_page(n);
328*20010Sjaap 			break;
329*20010Sjaap 		case 'n':	/* end of line */
330*20010Sjaap 			while (getc(fp) != '\n')
331*20010Sjaap 				;
332*20010Sjaap 			t_newline();
333*20010Sjaap 			break;
334*20010Sjaap 		case '#':	/* comment */
335*20010Sjaap 			while (getc(fp) != '\n')
336*20010Sjaap 				;
337*20010Sjaap 			break;
338*20010Sjaap 		case 'x':	/* device control */
339*20010Sjaap 			devcntrl(fp);
340*20010Sjaap 			break;
341*20010Sjaap 		default:
342*20010Sjaap 			error(!FATAL, "unknown input character %o %c\n", c, c);
343*20010Sjaap 			done();
344*20010Sjaap 		}
345*20010Sjaap 	}
346*20010Sjaap }
347*20010Sjaap 
348*20010Sjaap devcntrl(fp)	/* interpret device control functions */
349*20010Sjaap FILE *fp;
350*20010Sjaap {
351*20010Sjaap         char str[20], str1[50], buf[50];
352*20010Sjaap 	int c, n;
353*20010Sjaap 
354*20010Sjaap 	fscanf(fp, "%s", str);
355*20010Sjaap 	switch (str[0]) {	/* crude for now */
356*20010Sjaap 	case 'i':	/* initialize */
357*20010Sjaap 		fileinit();
358*20010Sjaap 		t_init(0);
359*20010Sjaap 		break;
360*20010Sjaap 	case 'T':	/* device name */
361*20010Sjaap 		fscanf(fp, "%s", devname);
362*20010Sjaap 		break;
363*20010Sjaap 	case 't':	/* trailer */
364*20010Sjaap 		t_trailer();
365*20010Sjaap 		break;
366*20010Sjaap 	case 'p':	/* pause -- can restart */
367*20010Sjaap 		t_reset('p');
368*20010Sjaap 		break;
369*20010Sjaap 	case 's':	/* stop */
370*20010Sjaap 		t_reset('s');
371*20010Sjaap 		break;
372*20010Sjaap 	case 'r':	/* resolution assumed when prepared */
373*20010Sjaap 		fscanf(fp, "%d", &res);
374*20010Sjaap 		break;
375*20010Sjaap 	case 'f':	/* font used */
376*20010Sjaap 		fscanf(fp, "%d %s", &n, str);
377*20010Sjaap 		fgets(buf, sizeof buf, fp);	/* in case there's a filename */
378*20010Sjaap 		ungetc('\n', fp);	/* fgets goes too far */
379*20010Sjaap 		str1[0] = 0;	/* in case there's nothing to come in */
380*20010Sjaap 		sscanf(buf, "%s", str1);
381*20010Sjaap 		loadfont(n, str, str1);
382*20010Sjaap 		break;
383*20010Sjaap 	/* these don't belong here... */
384*20010Sjaap 	case 'H':	/* char height */
385*20010Sjaap 		fscanf(fp, "%d", &n);
386*20010Sjaap 		t_charht(t_size(n));
387*20010Sjaap 		break;
388*20010Sjaap 	case 'S':	/* slant */
389*20010Sjaap 		fscanf(fp, "%d", &n);
390*20010Sjaap 		t_slant(n);
391*20010Sjaap 		break;
392*20010Sjaap 	}
393*20010Sjaap 	while ((c = getc(fp)) != '\n')	/* skip rest of input line */
394*20010Sjaap 		if (c == EOF)
395*20010Sjaap 			break;
396*20010Sjaap }
397*20010Sjaap 
398*20010Sjaap fileinit()	/* read in font and code files, etc. */
399*20010Sjaap {
400*20010Sjaap 	int i, fin, nw;
401*20010Sjaap 	char *malloc(), *filebase, *p;
402*20010Sjaap 	char temp[60];
403*20010Sjaap 
404*20010Sjaap 	/* open table for device,
405*20010Sjaap 	/* read in resolution, size info, font info, etc.
406*20010Sjaap 	/* and set params
407*20010Sjaap 	*/
408*20010Sjaap 	sprintf(temp, "%s/dev%s/DESC.out", fontdir, devname);
409*20010Sjaap 	if ((fin = open(temp, 0)) < 0)
410*20010Sjaap 		error(FATAL, "can't open tables for %s\n", temp);
411*20010Sjaap 	read(fin, &dev, sizeof(struct dev));
412*20010Sjaap 	nfonts = dev.nfonts;
413*20010Sjaap 	nsizes = dev.nsizes;
414*20010Sjaap 	nchtab = dev.nchtab;
415*20010Sjaap 	filebase = malloc(dev.filesize);	/* enough room for whole file */
416*20010Sjaap 	read(fin, filebase, dev.filesize);	/* all at once */
417*20010Sjaap 	pstab = (short *) filebase;
418*20010Sjaap 	chtab = pstab + nsizes + 1;
419*20010Sjaap 	chname = (char *) (chtab + dev.nchtab);
420*20010Sjaap 	p = chname + dev.lchname;
421*20010Sjaap 	for (i = 1; i <= nfonts; i++) {
422*20010Sjaap 		fontbase[i] = (struct font *) p;
423*20010Sjaap 		nw = *p & BMASK;	/* 1st thing is width count */
424*20010Sjaap 		if (smnt == 0 && fontbase[i]->specfont == 1)
425*20010Sjaap 			smnt = i;	/* first special font */
426*20010Sjaap 		p += sizeof(struct font);	/* that's what's on the beginning */
427*20010Sjaap 		widthtab[i] = p;
428*20010Sjaap 		codetab[i] = p + 2 * nw;
429*20010Sjaap 		fitab[i] = p + 3 * nw;
430*20010Sjaap 		p += 3 * nw + dev.nchtab + 128 - 32;
431*20010Sjaap 		if(fontbase[i]->fonttab == 1) {	/*MC:jna There is a fonttable */
432*20010Sjaap 			fonttab[i] = (short *)p;	/*MC:jna get it */
433*20010Sjaap 			p += nw * sizeof( short );	/* and skip it */
434*20010Sjaap 		}
435*20010Sjaap 		t_fp(i, fontbase[i]->namefont, fontbase[i]->intname);
436*20010Sjaap 		if(dbg > 2) fontprint(i);
437*20010Sjaap 	}
438*20010Sjaap 	/*MC:jna
439*20010Sjaap 	 *
440*20010Sjaap 	 * Make space for the font cache for NCH characters
441*20010Sjaap 	 * also reserve space for fonttable, if any is to come
442*20010Sjaap          *
443*20010Sjaap 	 */
444*20010Sjaap 	fontbase[0] = (struct font *) malloc(3*255 + dev.nchtab + (128-32) + sizeof (struct font) + 255 * sizeof( short));
445*20010Sjaap 	widthtab[0] = (char *) fontbase[0] + sizeof (struct font);
446*20010Sjaap 	fontbase[0]->nwfont = 255;
447*20010Sjaap 	fontbase[0]->fonttab = 2;	/* there is room for a fonttable! */
448*20010Sjaap 	close(fin);
449*20010Sjaap }
450*20010Sjaap 
451*20010Sjaap fontprint(i)	/* debugging print of font i (0,...) */
452*20010Sjaap {
453*20010Sjaap 	int j, k, n;
454*20010Sjaap 	char *p;
455*20010Sjaap 
456*20010Sjaap 	printf("font %d:\n", i);
457*20010Sjaap 	p = (char *) fontbase[i];
458*20010Sjaap 	n = fontbase[i]->nwfont & BMASK;
459*20010Sjaap 	printf("base=0%o, nchars=%d, spec=%d, name=%s, widtab=0%o, fitab=0%o\n",
460*20010Sjaap 		p, n, fontbase[i]->specfont, fontbase[i]->namefont, widthtab[i], fitab[i]);
461*20010Sjaap 	if( fontbase[i]->fonttab == 1)
462*20010Sjaap 		printf("base fonttab=0%o\n", fonttab[i]);
463*20010Sjaap 	printf("widths:\n");
464*20010Sjaap 	for (j=0; j <= n; j++) {
465*20010Sjaap 		printf(" %2d", widthtab[i][j] & BMASK);
466*20010Sjaap 		if (j % 20 == 19) printf("\n");
467*20010Sjaap 	}
468*20010Sjaap 	printf("\ncodetab:\n");
469*20010Sjaap 	for (j=0; j <= n; j++) {
470*20010Sjaap 		printf(" %2d", codetab[i][j] & BMASK);
471*20010Sjaap 		if (j % 20 == 19) printf("\n");
472*20010Sjaap 	}
473*20010Sjaap 	printf("\nfitab:\n");
474*20010Sjaap 	for (j=0; j <= dev.nchtab + 128-32; j++) {
475*20010Sjaap 		printf(" %2d", fitab[i][j] & BMASK);
476*20010Sjaap 		if (j % 20 == 19) printf("\n");
477*20010Sjaap 	}
478*20010Sjaap 	if(fontbase[i]->fonttab == 1) {
479*20010Sjaap 		printf("\nfonttab:\n");
480*20010Sjaap 		for (j=0; j <= n; j++) {
481*20010Sjaap 			printf(" %d", fonttab[i][j] );
482*20010Sjaap 			if (j % 20 == 19) printf("\n");
483*20010Sjaap 		}
484*20010Sjaap 	}
485*20010Sjaap 	printf("\n");
486*20010Sjaap }
487*20010Sjaap 
488*20010Sjaap loadfont(n, s, s1)	/* load font info for font s on position n (0...) */
489*20010Sjaap int n;
490*20010Sjaap char *s, *s1;
491*20010Sjaap {
492*20010Sjaap 	char temp[60];
493*20010Sjaap 	int fin, nw, norig, forig;
494*20010Sjaap 	char *p;
495*20010Sjaap 
496*20010Sjaap 	if (n < 0 || n > NFONT)
497*20010Sjaap 		error(FATAL, "illegal fp command %d %s", n, s);
498*20010Sjaap 	if (strcmp(s, fontbase[n]->namefont) == 0)
499*20010Sjaap 		return;
500*20010Sjaap 	if (s1 == NULL || s1[0] == '\0')
501*20010Sjaap 		sprintf(temp, "%s/dev%s/%s.out", fontdir, devname, s);
502*20010Sjaap 	else
503*20010Sjaap 		sprintf(temp, "%s/%s.out", s1, s);
504*20010Sjaap 	if ((fin = open(temp, 0)) < 0)
505*20010Sjaap 		error(FATAL, "can't open font table %s", temp);
506*20010Sjaap 	norig = fontbase[n]->nwfont & BMASK;
507*20010Sjaap 	forig = fontbase[n]->fonttab;
508*20010Sjaap if(dbg > 3)
509*20010Sjaap 	printf("nworig, %d, fonttaborig %d\n", norig, forig);
510*20010Sjaap 	/*
511*20010Sjaap 	 *MC:jna norig is the original amount of chars in
512*20010Sjaap 	 * the (premounted) font)
513*20010Sjaap 	 *
514*20010Sjaap 	 * first geuss there is no fonttab
515*20010Sjaap 	 */
516*20010Sjaap 	read(fin, fontbase[n], 3*norig + nchtab+128-32 + sizeof(struct font));
517*20010Sjaap 	if ((fontbase[n]->nwfont & BMASK) > norig || (forig == 0 && fontbase[n]->fonttab == 1))
518*20010Sjaap 		error(FATAL, "Font %s too big for position %d\n", s, n);
519*20010Sjaap 		/*
520*20010Sjaap 		 *MC:jna This means it is wise to make the default mounted
521*20010Sjaap 		 * fonts larger then any other mounttable fonts.
522*20010Sjaap 		 * And because of the kludge with the fonttable,
523*20010Sjaap 		 * Make sure that they all contain fonttables!
524*20010Sjaap 		 * It will make your life easier.
525*20010Sjaap 		 */
526*20010Sjaap 	nw = fontbase[n]->nwfont & BMASK;
527*20010Sjaap if(dbg > 3)
528*20010Sjaap 	printf("nw %d\n", nw);
529*20010Sjaap 	if(fontbase[n]->fonttab == 1) {
530*20010Sjaap 		lseek(fin, 0L, 0);
531*20010Sjaap 		read(fin, fontbase[n], 3*norig + nchtab+128-32 + nw*sizeof(short) + sizeof(struct font));
532*20010Sjaap 		/*
533*20010Sjaap 		 * There turned out to be a fonttab, so we have to read it in
534*20010Sjaap 		 *MC:jna a bit stupid, but the laziest way (for me)
535*20010Sjaap 		 */
536*20010Sjaap 	}
537*20010Sjaap 	close(fin);
538*20010Sjaap 	widthtab[n] = (char *) fontbase[n] + sizeof(struct font);
539*20010Sjaap 	codetab[n] = (char *) widthtab[n] + 2 * nw;
540*20010Sjaap 	fitab[n] = (char *) widthtab[n] + 3 * nw;
541*20010Sjaap 	if(fontbase[n]->fonttab == 1)
542*20010Sjaap 		fonttab[n] = (short *) (widthtab[n] + 3*nw + nchtab+128-32);
543*20010Sjaap 	t_fp(n, fontbase[n]->namefont, fontbase[n]->intname);
544*20010Sjaap 	fontbase[n]->nwfont = norig;	/* so can later use full original size */
545*20010Sjaap 	if(fontbase[n]->fonttab == 0 && forig != 0)
546*20010Sjaap 		fontbase[n]->fonttab = 2;
547*20010Sjaap 					/* so we signal that there is place
548*20010Sjaap 					 * for a fonttab! */
549*20010Sjaap 
550*20010Sjaap 	if (dbg > 2) fontprint(n);
551*20010Sjaap }
552*20010Sjaap 
553*20010Sjaap done()
554*20010Sjaap {
555*20010Sjaap 	t_reset('s');
556*20010Sjaap 	exit(0);
557*20010Sjaap }
558*20010Sjaap 
559*20010Sjaap extern int ex();
560*20010Sjaap 
561*20010Sjaap /*VARARGS*/
562*20010Sjaap error(f, s, a1, a2, a3, a4, a5, a6, a7)
563*20010Sjaap int f;
564*20010Sjaap {
565*20010Sjaap 	fprintf(stderr, "dhar: ");
566*20010Sjaap 	fprintf(stderr, s, a1, a2, a3, a4, a5, a6, a7);
567*20010Sjaap 	fprintf(stderr, "\n");
568*20010Sjaap 	fflush(stderr);
569*20010Sjaap 	if (f) {
570*20010Sjaap 		ex();
571*20010Sjaap 		exit(1);
572*20010Sjaap 	}
573*20010Sjaap }
574*20010Sjaap 
575*20010Sjaap /******************************************************************************
576*20010Sjaap  ******************************************************************************
577*20010Sjaap  *
578*20010Sjaap  * Here begins the stuff that really depends on the harris
579*20010Sjaap  *
580*20010Sjaap  * For the time being, no use is made of the ruling functions of the Harris
581*20010Sjaap  *
582*20010Sjaap  ******************************************************************************
583*20010Sjaap  ******************************************************************************
584*20010Sjaap  */
585*20010Sjaap 
586*20010Sjaap /*
587*20010Sjaap  * The basic idea is to delay the output as long as possible
588*20010Sjaap  * until you really have to.
589*20010Sjaap  * Until that time we just keep a machine status.
590*20010Sjaap  *
591*20010Sjaap  */
592*20010Sjaap 
593*20010Sjaap #include "hcodes.h"
594*20010Sjaap 
595*20010Sjaap char	devname[20] = "har";
596*20010Sjaap int	fcut;
597*20010Sjaap int	nocutting;
598*20010Sjaap int	papuse;
599*20010Sjaap char	harcode;
600*20010Sjaap 
601*20010Sjaap t_init(reinit)	/* initialize device */
602*20010Sjaap int reinit;
603*20010Sjaap {
604*20010Sjaap 	register int i;
605*20010Sjaap 	extern int size;
606*20010Sjaap 
607*20010Sjaap 	hpos = vpos = 0;
608*20010Sjaap 
609*20010Sjaap 	if( strcmp( devname, "har") != NULL )
610*20010Sjaap 		error(FATAL, "This input is not for the harris");
611*20010Sjaap 
612*20010Sjaap 	if (!tf)
613*20010Sjaap 		if ( ( tf = creat("@har.in", 0664)) < 0)
614*20010Sjaap 			error(FATAL, "Cannot create outputfile");
615*20010Sjaap 
616*20010Sjaap 	/* if there is a drawing character, use it */
617*20010Sjaap 	for ( i = 0; i < nchtab; i++)
618*20010Sjaap 		if (strcmp(&chname[chtab[i]], "l.") == 0)
619*20010Sjaap 			break;
620*20010Sjaap 	if ( i < nchtab) {
621*20010Sjaap 		drawdot = i + 128;
622*20010Sjaap 		drawsize = 1;
623*20010Sjaap 	} else {
624*20010Sjaap 		drawdot = '.';
625*20010Sjaap 		drawsize = 3; 	/* 1/3 size */
626*20010Sjaap 	}
627*20010Sjaap 
628*20010Sjaap 	output = 1;
629*20010Sjaap 
630*20010Sjaap 	oput(VMV); oput(0); oput(0);
631*20010Sjaap 				/* See Harris Manual appendix D */
632*20010Sjaap 	oput(HPO);oput(0);oput(0);
633*20010Sjaap 
634*20010Sjaap 		/* some initial size */
635*20010Sjaap 	size = 10;
636*20010Sjaap 	putsize();
637*20010Sjaap 	putfont(999);
638*20010Sjaap 	oput(STA);oput(0);oput(0360);
639*20010Sjaap 
640*20010Sjaap 	if( eflag ) {
641*20010Sjaap 		operator("Translating");
642*20010Sjaap 		oput(EST);	/* enable slave Translator */
643*20010Sjaap 		fprintf(stderr,"Slave code translator enabled\n");
644*20010Sjaap 	} else
645*20010Sjaap 		operator("dhar started");
646*20010Sjaap 
647*20010Sjaap 	oput(OB0);		/* reset oblique */
648*20010Sjaap 	oput(NAD);		/* No automatic displacement */
649*20010Sjaap 	output = 0;
650*20010Sjaap }
651*20010Sjaap 
652*20010Sjaap /*
653*20010Sjaap  * The reason of struct state is never explained by bwk
654*20010Sjaap  * but it looks like an stack of environments being pushed and popped
655*20010Sjaap  *
656*20010Sjaap  */
657*20010Sjaap 
658*20010Sjaap #define	MAXSTATE	5
659*20010Sjaap 
660*20010Sjaap struct state {
661*20010Sjaap 	int	ssize;
662*20010Sjaap 	int	sfont;
663*20010Sjaap 	int	shpos;
664*20010Sjaap 	int	svpos;
665*20010Sjaap 	int	shorig;
666*20010Sjaap 	int	svorig;
667*20010Sjaap };
668*20010Sjaap struct	state	state[MAXSTATE];
669*20010Sjaap struct	state	*statep = state;
670*20010Sjaap 
671*20010Sjaap t_push()	/* begin a new block */
672*20010Sjaap {
673*20010Sjaap 	extern size;
674*20010Sjaap 
675*20010Sjaap 	error(!FATAL, "Different environment entered!");
676*20010Sjaap 	hflush();
677*20010Sjaap 	statep->ssize = size;
678*20010Sjaap 	statep->sfont = font;
679*20010Sjaap 	statep->shorig = horig;
680*20010Sjaap 	statep->svorig = vorig;
681*20010Sjaap 	statep->shpos = hpos;
682*20010Sjaap 	statep->svpos = vpos;
683*20010Sjaap 	horig = hpos;
684*20010Sjaap 	vorig = vpos;
685*20010Sjaap 	hpos = vpos = 0;
686*20010Sjaap 	if (statep++ >= state+MAXSTATE)
687*20010Sjaap 		error(FATAL, "{ nested too deep");
688*20010Sjaap 	hpos = vpos = 0;
689*20010Sjaap }
690*20010Sjaap 
691*20010Sjaap t_pop()	/* pop to previous state */
692*20010Sjaap {
693*20010Sjaap 	extern size;
694*20010Sjaap 	if (--statep < state)
695*20010Sjaap 		error(FATAL, "extra }");
696*20010Sjaap 	size = statep->ssize;
697*20010Sjaap 	font = statep->sfont;
698*20010Sjaap 	hpos = statep->shpos;
699*20010Sjaap 	vpos = statep->svpos;
700*20010Sjaap 	horig = statep->shorig;
701*20010Sjaap 	vorig = statep->svorig;
702*20010Sjaap }
703*20010Sjaap 
704*20010Sjaap int	pageno	= 0;
705*20010Sjaap 
706*20010Sjaap t_page(n)	/* do whatever new page functions */
707*20010Sjaap {
708*20010Sjaap 	int i;
709*20010Sjaap 
710*20010Sjaap 	if (output) {
711*20010Sjaap 		papuse++;
712*20010Sjaap 		/*
713*20010Sjaap 		 * accounting in pages, for the time being.
714*20010Sjaap 		 * New harprot should do the real accounting
715*20010Sjaap 		 */
716*20010Sjaap 		if (++scount >= spage) {
717*20010Sjaap 			t_reset('p');
718*20010Sjaap 			scount = 0;
719*20010Sjaap 		}
720*20010Sjaap 	}
721*20010Sjaap 	vpos = 0;
722*20010Sjaap 	output = 1;
723*20010Sjaap 	++pageno;
724*20010Sjaap 	if (nolist == 0)
725*20010Sjaap 		return;	/* no -o specified */
726*20010Sjaap 	output = 0;
727*20010Sjaap 	for (i = 0; i < nolist; i += 2)
728*20010Sjaap 		if (n >= olist[i] && n <= olist[i+1]) {
729*20010Sjaap 			output = 1;
730*20010Sjaap 			break;
731*20010Sjaap 		}
732*20010Sjaap }
733*20010Sjaap 
734*20010Sjaap t_newline()	/* do whatever for the end of a line */
735*20010Sjaap {
736*20010Sjaap 	hpos = 0;	/* because we're now back at the left margin */
737*20010Sjaap }
738*20010Sjaap 
739*20010Sjaap /*
740*20010Sjaap  * A PSZ command on the Harris will change the horizontal & vertical size
741*20010Sjaap  * A HPZ command will change just the Horizontal size.
742*20010Sjaap  *
743*20010Sjaap  * so size will contain horizontal size, and versize the vertical
744*20010Sjaap  */
745*20010Sjaap int	size;		/* current sizenumber (a legal index in pstab) */
746*20010Sjaap int	horsize;	/* current horizontal size */
747*20010Sjaap int	versize;	/* current vertcal size */
748*20010Sjaap int	vsizeflag;	/* if set, versize differs from size */
749*20010Sjaap 
750*20010Sjaap t_size(n)	/* convert integer to internal size number*/
751*20010Sjaap int n;
752*20010Sjaap {
753*20010Sjaap 	int i;
754*20010Sjaap 
755*20010Sjaap 	if (n <= pstab[0])
756*20010Sjaap 		return(1);
757*20010Sjaap 	else if (n >= pstab[nsizes-1])
758*20010Sjaap 		return(nsizes);
759*20010Sjaap 	for (i = 0; n > pstab[i]; i++)
760*20010Sjaap 		;
761*20010Sjaap 	return(i+1);
762*20010Sjaap }
763*20010Sjaap 
764*20010Sjaap t_charht(n)	/* set character height to n */
765*20010Sjaap int n;
766*20010Sjaap {
767*20010Sjaap 	versize = pstab[n-1];
768*20010Sjaap 	if( versize != horsize )
769*20010Sjaap 		vsizeflag = 1;
770*20010Sjaap 	putsize();
771*20010Sjaap }
772*20010Sjaap 
773*20010Sjaap int sltab[]	= {   0,  9,  12,  15, -1};	/* possible slanting factors */
774*20010Sjaap int slctab[]	= { OB0, OB1, OB2, OB3 };	/* slanting codes */
775*20010Sjaap int slant;		/* current general slanting factor (of slant cmd) */
776*20010Sjaap int fslant;		/* slanting factor of current font */
777*20010Sjaap 
778*20010Sjaap /*
779*20010Sjaap  * current font has to be slanted, the slant will be set to fslant.
780*20010Sjaap  * if the has been a slant command, the slant will be set to "slant",
781*20010Sjaap  * overiding the fslant.
782*20010Sjaap  * if slant is reset to 0, and there fslant != 0, slant will be set to "fslant"
783*20010Sjaap  *
784*20010Sjaap  * fslant will be manupulated by setfont (slanting can be an attribute
785*20010Sjaap  * to a (Harris-)font.
786*20010Sjaap  *
787*20010Sjaap  * There are to many slants in this comment
788*20010Sjaap  */
789*20010Sjaap 
790*20010Sjaap t_slant(n)	/* do slant cmd */
791*20010Sjaap int n;
792*20010Sjaap {	slant = n;
793*20010Sjaap 	setslant(n);
794*20010Sjaap }
795*20010Sjaap 
796*20010Sjaap setslant(n)	/* set slant to n */
797*20010Sjaap int n;
798*20010Sjaap {	int j;
799*20010Sjaap 	static int aslant;	/* the actual slanting factor */
800*20010Sjaap 
801*20010Sjaap 	if( n == aslant)
802*20010Sjaap 		return;
803*20010Sjaap 	if( n == 0 && fslant) {		/* back to slant of font */
804*20010Sjaap 		setslant( fslant );
805*20010Sjaap 		return;
806*20010Sjaap 	}
807*20010Sjaap 	for (j = 0; n > ( aslant = sltab[j]); j++)
808*20010Sjaap 		if ( aslant == -1) {
809*20010Sjaap 			aslant = sltab[--j];
810*20010Sjaap 			break;
811*20010Sjaap 		}
812*20010Sjaap 	hflush();
813*20010Sjaap 	oput( slctab[j] );
814*20010Sjaap 	if (dbg)
815*20010Sjaap 		printf("slant to %d\n", aslant);
816*20010Sjaap }
817*20010Sjaap 
818*20010Sjaap slantfont(n)	/* set fontslant */
819*20010Sjaap int n;
820*20010Sjaap {
821*20010Sjaap 	fslant = n;
822*20010Sjaap 	if(slant)
823*20010Sjaap 		return;		/* slant of slanting command
824*20010Sjaap 				 * overrides fslant */
825*20010Sjaap 	setslant( fslant);	/* set slanting */
826*20010Sjaap }
827*20010Sjaap 
828*20010Sjaap t_font(s)	/* convert string to internal font number */
829*20010Sjaap char *s;
830*20010Sjaap {
831*20010Sjaap 	int n;
832*20010Sjaap 
833*20010Sjaap 	n = atoi(s);
834*20010Sjaap 	if (n < 0 || n > nfonts)
835*20010Sjaap 		n = 1;
836*20010Sjaap 	return(n);
837*20010Sjaap }
838*20010Sjaap 
839*20010Sjaap t_text(s)	/* print string s as text, the real \! implemantation */
840*20010Sjaap char *s;
841*20010Sjaap {
842*20010Sjaap 	int c, w;
843*20010Sjaap 	char str[100];
844*20010Sjaap 
845*20010Sjaap 	error(!FATAL, "t_text not well implented (yet)!");
846*20010Sjaap 	if (!output)
847*20010Sjaap 		return;
848*20010Sjaap 	while (c = *s++) {
849*20010Sjaap 		if (c == '\\') {
850*20010Sjaap 			switch (c = *s++) {
851*20010Sjaap 			case '\\':
852*20010Sjaap 			case 'e':
853*20010Sjaap 				put1('\\');
854*20010Sjaap 				break;
855*20010Sjaap 			case '(':
856*20010Sjaap 				str[0] = *s++;
857*20010Sjaap 				str[1] = *s++;
858*20010Sjaap 				str[2] = '\0';
859*20010Sjaap 				put1s(str);
860*20010Sjaap 				break;
861*20010Sjaap 			}
862*20010Sjaap 		} else {
863*20010Sjaap 			put1(c);
864*20010Sjaap 		}
865*20010Sjaap 		hmot(lastw);
866*20010Sjaap 		if (dbg) printf("width = %d\n", lastw);
867*20010Sjaap 	}
868*20010Sjaap }
869*20010Sjaap 
870*20010Sjaap t_reset(c)
871*20010Sjaap {
872*20010Sjaap 	int n;
873*20010Sjaap 
874*20010Sjaap 	if (output)
875*20010Sjaap 		/*
876*20010Sjaap 		 papuse++
877*20010Sjaap 		 */
878*20010Sjaap 		 ;
879*20010Sjaap 	switch(c) {
880*20010Sjaap 	case 'p':
881*20010Sjaap 		cut();	/*
882*20010Sjaap 			 * interpret pauses as comment for cutting
883*20010Sjaap 			 * the paper
884*20010Sjaap 			 */
885*20010Sjaap 		if(dbg)
886*20010Sjaap 			printf("reset p\n");
887*20010Sjaap 		break;
888*20010Sjaap 	case 's':
889*20010Sjaap 		cut();
890*20010Sjaap 		nocutting++;
891*20010Sjaap 		if(dbg)
892*20010Sjaap 			printf("reset s\n");
893*20010Sjaap 		ex();
894*20010Sjaap 		break;
895*20010Sjaap 	default:
896*20010Sjaap 		error(!FATAL, "Unknown reset function");
897*20010Sjaap 		break;
898*20010Sjaap 	}
899*20010Sjaap }
900*20010Sjaap 
901*20010Sjaap cut()
902*20010Sjaap {
903*20010Sjaap 	if (cflag || nocutting)
904*20010Sjaap 		return;
905*20010Sjaap 	hflush();
906*20010Sjaap 	oput(CUT);
907*20010Sjaap 	hpos = 0;
908*20010Sjaap 	fcut = 1;
909*20010Sjaap 	if (dbg)
910*20010Sjaap 		printf("Cut\n");
911*20010Sjaap }
912*20010Sjaap 
913*20010Sjaap account()	/* record paper use */
914*20010Sjaap {
915*20010Sjaap 	/* Don somewhere els */
916*20010Sjaap }
917*20010Sjaap 
918*20010Sjaap t_trailer()
919*20010Sjaap {
920*20010Sjaap }
921*20010Sjaap 
922*20010Sjaap hflush()	/* do the actual motion */
923*20010Sjaap {
924*20010Sjaap 	if (!output)
925*20010Sjaap 		return;
926*20010Sjaap 	hor_move( hpos - htrue );
927*20010Sjaap }
928*20010Sjaap 
929*20010Sjaap hor_move( amount )
930*20010Sjaap int amount;
931*20010Sjaap {	int high, low;
932*20010Sjaap 
933*20010Sjaap #ifdef VAX
934*20010Sjaap 	if ( abs(amount) > 0177777)
935*20010Sjaap 		error(FATAL, "Impossible escape");
936*20010Sjaap #endif
937*20010Sjaap 	if ( amount == 0 && harcode == 0)
938*20010Sjaap 		return;		/* really nothing to do */
939*20010Sjaap 	if(dbg > 1)
940*20010Sjaap 		printf("h_move %d\n", amount);
941*20010Sjaap 	low = amount & BMASK;
942*20010Sjaap 	high = ( amount >> BYTE) & BMASK;
943*20010Sjaap 	/*
944*20010Sjaap 	 * if there is a code wating for output,
945*20010Sjaap 	 * send that one to be output, plus the movement,
946*20010Sjaap 	 * else send the MAB
947*20010Sjaap 	 * and the movement
948*20010Sjaap 	 */
949*20010Sjaap 	oput( harcode ? harcode : MAB);
950*20010Sjaap 	harcode = 0;
951*20010Sjaap 	oput(high);
952*20010Sjaap 	oput(low);
953*20010Sjaap 	htrue = hpos;
954*20010Sjaap }
955*20010Sjaap 
956*20010Sjaap 
957*20010Sjaap hmot(n)
958*20010Sjaap {
959*20010Sjaap 	hpos += n;
960*20010Sjaap }
961*20010Sjaap 
962*20010Sjaap hgoto(n)
963*20010Sjaap {
964*20010Sjaap 	hpos = n;
965*20010Sjaap }
966*20010Sjaap 
967*20010Sjaap vgoto(n)
968*20010Sjaap {
969*20010Sjaap 	vmot(n - vpos);
970*20010Sjaap }
971*20010Sjaap 
972*20010Sjaap vmot(n)	/* generate n units of vertical motion */
973*20010Sjaap int n;
974*20010Sjaap {
975*20010Sjaap 	if (!output)
976*20010Sjaap 		return;
977*20010Sjaap 	if (n != 0) {
978*20010Sjaap 		ver_move( n );
979*20010Sjaap 		vpos += n;
980*20010Sjaap 	}
981*20010Sjaap }
982*20010Sjaap 
983*20010Sjaap ver_move( amount )
984*20010Sjaap int amount;
985*20010Sjaap {	int high, low;
986*20010Sjaap 
987*20010Sjaap #ifdef VAX
988*20010Sjaap 	if ( abs(amount) > 0177777)
989*20010Sjaap 		error(FATAL, "Impossible leading");
990*20010Sjaap #endif
991*20010Sjaap 	if(dbg > 1)
992*20010Sjaap 		printf("v_move %d\n", amount);
993*20010Sjaap 	low = amount & BMASK;
994*20010Sjaap 	high = ( amount >> BYTE) & BMASK;
995*20010Sjaap 	hflush();
996*20010Sjaap 	oput(VMV);
997*20010Sjaap 	oput(high);
998*20010Sjaap 	oput(low);
999*20010Sjaap }
1000*20010Sjaap 
1001*20010Sjaap put1s(s)	/* s is a funny char name */
1002*20010Sjaap char *s;
1003*20010Sjaap {
1004*20010Sjaap 	int i;
1005*20010Sjaap 
1006*20010Sjaap 	if (!output)
1007*20010Sjaap 		return;
1008*20010Sjaap /*
1009*20010Sjaap 	if(strcmp("ul", s) == 0) {
1010*20010Sjaap 		set_ul();
1011*20010Sjaap 		return;
1012*20010Sjaap 	}
1013*20010Sjaap 	if(strcmp("ru", s) == 0) {
1014*20010Sjaap 		set_ru();
1015*20010Sjaap 		return;
1016*20010Sjaap 	}
1017*20010Sjaap */
1018*20010Sjaap 	for (i = 0; i < nchtab; i++)
1019*20010Sjaap 		if (strcmp(&chname[chtab[i]], s) == 0)
1020*20010Sjaap 			break;
1021*20010Sjaap /*
1022*20010Sjaap printf("i+128: %d,s: %s, chname: %s\n", i+128, s, &chname[chtab[i]]);
1023*20010Sjaap */
1024*20010Sjaap 	if (i < nchtab)
1025*20010Sjaap 		put1(i + 128);
1026*20010Sjaap 	else
1027*20010Sjaap 		if(dbg)
1028*20010Sjaap 			printf("Special char %s doesn't exist\n", s);
1029*20010Sjaap }
1030*20010Sjaap 
1031*20010Sjaap /*
1032*20010Sjaap  * The Harris doesn'nt have a proper underrule or rule
1033*20010Sjaap  *
1034*20010Sjaap  * Try to generate one with the RULE command.
1035*20010Sjaap  *
1036*20010Sjaap  */
1037*20010Sjaap 
1038*20010Sjaap #define UL_DOWN	7	/* 7 half decipoints at pointsize 10 */
1039*20010Sjaap 
1040*20010Sjaap set_ul()
1041*20010Sjaap {	int move;
1042*20010Sjaap 	int tmp;
1043*20010Sjaap 
1044*20010Sjaap 	hflush();
1045*20010Sjaap 	move = UL_DOWN * versize;
1046*20010Sjaap 	ver_move( move);
1047*20010Sjaap 	tmp = get_width("ul") / 2;
1048*20010Sjaap 		/*
1049*20010Sjaap 		 * we assume that dev.unitwidth is 10, so getwidth
1050*20010Sjaap 		 * will return the value in half decipoints!
1051*20010Sjaap 		 */
1052*20010Sjaap 	set_line(tmp);
1053*20010Sjaap 	ver_move( -move);
1054*20010Sjaap }
1055*20010Sjaap 
1056*20010Sjaap #define RU_DOWN	1	/* 2 half decipoints at pointsize 10 */
1057*20010Sjaap 
1058*20010Sjaap set_ru()
1059*20010Sjaap {
1060*20010Sjaap 	int tmp, move;
1061*20010Sjaap 
1062*20010Sjaap 	hflush();
1063*20010Sjaap 	move = RU_DOWN * versize;
1064*20010Sjaap 	ver_move( move);
1065*20010Sjaap 	tmp = get_width("ul") / 2;
1066*20010Sjaap 	set_line(tmp);
1067*20010Sjaap 	ver_move( -move);
1068*20010Sjaap }
1069*20010Sjaap 
1070*20010Sjaap #define HEIGHT	6	/* thickness (decipoints) at pointsize 10 */
1071*20010Sjaap #define MIN_VAL	2	/* Minimum value for rule height & length */
1072*20010Sjaap #define MAX_H	720	/* Maximum for height */
1073*20010Sjaap #define MAX_L	8160	/* Maximum length of the SMC 68 Pica machine */
1074*20010Sjaap 
1075*20010Sjaap /*
1076*20010Sjaap  * set line of length decipoints.
1077*20010Sjaap  */
1078*20010Sjaap 
1079*20010Sjaap set_line( length )
1080*20010Sjaap int length;
1081*20010Sjaap {
1082*20010Sjaap 	int height;
1083*20010Sjaap 	char one, two, three, four;
1084*20010Sjaap 
1085*20010Sjaap 	/*
1086*20010Sjaap 	printf("Line %d decipoints\n", i);
1087*20010Sjaap 	*/
1088*20010Sjaap 
1089*20010Sjaap 	height = (HEIGHT * versize + dev.unitwidth/2) / dev.unitwidth;
1090*20010Sjaap 	if ( height < MIN_VAL)
1091*20010Sjaap 		height = MIN_VAL;
1092*20010Sjaap 	if (height > MAX_H)
1093*20010Sjaap 		height = MAX_H;
1094*20010Sjaap 	if (length > MAX_L)
1095*20010Sjaap 		length = MAX_L;
1096*20010Sjaap 	if (dbg)
1097*20010Sjaap 		printf("Line: length %d height %d\n", length, height);
1098*20010Sjaap 
1099*20010Sjaap 	one = ( height >> BYTE ) | RUL;
1100*20010Sjaap 	two = height & BMASK;
1101*20010Sjaap 	three = length >> BYTE;
1102*20010Sjaap 	four = length & BMASK;
1103*20010Sjaap 	oput(one); oput(two); oput(three); oput(four);
1104*20010Sjaap }
1105*20010Sjaap 
1106*20010Sjaap /*
1107*20010Sjaap  * get the width of a char, to be used only by set_ul() and set-ru()
1108*20010Sjaap  */
1109*20010Sjaap 
1110*20010Sjaap int
1111*20010Sjaap get_width( s )
1112*20010Sjaap char *s;
1113*20010Sjaap {
1114*20010Sjaap 	int c;
1115*20010Sjaap 	int width;
1116*20010Sjaap 	int j, i, k, ofont;
1117*20010Sjaap 	char *pw;
1118*20010Sjaap 
1119*20010Sjaap 	for (c = 0; c < nchtab; c++)
1120*20010Sjaap 		if (strcmp(&chname[chtab[c]], s) == 0)
1121*20010Sjaap 			break;
1122*20010Sjaap 	if (c < nchtab)
1123*20010Sjaap 		c += 128-32;
1124*20010Sjaap 	if (c <= 0 || c >= nchtab + 128-32) {
1125*20010Sjaap 		if (dbg) printf("non-exist 0%o\n", c+32);
1126*20010Sjaap 		return;
1127*20010Sjaap 	}
1128*20010Sjaap 	k = ofont = font;
1129*20010Sjaap 	i = fitab[font][c] & BMASK;
1130*20010Sjaap 	if (i != 0) {	/* it's on this font */
1131*20010Sjaap 		pw = widthtab[font];
1132*20010Sjaap 	} else if (smnt > 0) {		/* on special (we hope) */
1133*20010Sjaap 		for (k=smnt, j=0; j <= nfonts; j++, k = (k+1) % (nfonts+1))
1134*20010Sjaap 			/*
1135*20010Sjaap 			 * Look for the character, start at the special font
1136*20010Sjaap 			 * and search further in a wrap around manner
1137*20010Sjaap 			 */
1138*20010Sjaap 			if ((i = fitab[k][c] & BMASK) != 0) {
1139*20010Sjaap 				pw = widthtab[k];
1140*20010Sjaap 				setfont(k);
1141*20010Sjaap 				break;
1142*20010Sjaap 			}
1143*20010Sjaap 	}
1144*20010Sjaap 	if (i == 0 || (width = pw[i] & BMASK) == 0 || k > nfonts) {
1145*20010Sjaap 		/* device drivers do width & 077, not really necessary */
1146*20010Sjaap 		if (dbg) {
1147*20010Sjaap 				printf("Width not found \\(%s\n", s);
1148*20010Sjaap 		}
1149*20010Sjaap 		return;
1150*20010Sjaap 	}
1151*20010Sjaap 	width = (width * horsize + dev.unitwidth/2) / dev.unitwidth;
1152*20010Sjaap 	if (font != ofont)
1153*20010Sjaap 		setfont(ofont);
1154*20010Sjaap 	return( width);
1155*20010Sjaap }
1156*20010Sjaap 
1157*20010Sjaap /* font position info: */
1158*20010Sjaap 
1159*20010Sjaap struct {
1160*20010Sjaap 	char *name;
1161*20010Sjaap 	int number;
1162*20010Sjaap } fontname[NFONT+1];
1163*20010Sjaap 
1164*20010Sjaap put1(c)	/* output char c */
1165*20010Sjaap int c;
1166*20010Sjaap {
1167*20010Sjaap 	char *pw;
1168*20010Sjaap 	register char *p;
1169*20010Sjaap 	register int i, k;
1170*20010Sjaap 	int j, ofont, code;
1171*20010Sjaap 	short f;
1172*20010Sjaap 
1173*20010Sjaap 	if (!output)
1174*20010Sjaap 		return;
1175*20010Sjaap 	c -= 32;
1176*20010Sjaap 	if (c <= 0) {
1177*20010Sjaap 		if (dbg) printf("non-exist 0%o\n", c+32);
1178*20010Sjaap 		lastw = widthtab[font][0] * pstab[size-1] /dev.unitwidth;
1179*20010Sjaap 		return;
1180*20010Sjaap 	}
1181*20010Sjaap 	k = ofont = font;
1182*20010Sjaap 	i = fitab[font][c] & BMASK;
1183*20010Sjaap 	if (i != 0) {	/* it's on this font */
1184*20010Sjaap 		p = codetab[font];
1185*20010Sjaap 		pw = widthtab[font];
1186*20010Sjaap 	} else if (smnt > 0) {		/* on special (we hope) */
1187*20010Sjaap 		for (k=smnt, j=0; j <= nfonts; j++, k = (k+1) % (nfonts+1))
1188*20010Sjaap 			/*
1189*20010Sjaap 			 * Look for the character, start at the special font
1190*20010Sjaap 			 * and search further in a wrap around manner
1191*20010Sjaap 			 */
1192*20010Sjaap 			if ((i = fitab[k][c] & BMASK) != 0) {
1193*20010Sjaap 				p = codetab[k];
1194*20010Sjaap 				pw = widthtab[k];
1195*20010Sjaap 				setfont(k);
1196*20010Sjaap 				break;
1197*20010Sjaap 			}
1198*20010Sjaap 	}
1199*20010Sjaap 	if (i == 0 || (code = p[i] & BMASK) == 0 || k > nfonts) {
1200*20010Sjaap 		if (dbg) {
1201*20010Sjaap 			if (isprint(c+32) && isascii(c+32))
1202*20010Sjaap 				printf("not found %c\n", c+32);
1203*20010Sjaap 			else
1204*20010Sjaap 				printf("not found \\(%s\n", &chname[chtab[c -128+32]]);
1205*20010Sjaap 		}
1206*20010Sjaap 		return;
1207*20010Sjaap 	}
1208*20010Sjaap 	if (fontbase[k]->fonttab == 1)
1209*20010Sjaap 		f = fonttab[k][i];
1210*20010Sjaap 	else
1211*20010Sjaap 		f = fontname[k].number;
1212*20010Sjaap 	hflush();
1213*20010Sjaap 	if (dbg) {
1214*20010Sjaap 		if (isprint(c+32) && isascii(c+32)) { /* My God! */
1215*20010Sjaap 			printf("%c %d %d\n", c+32, code, f);
1216*20010Sjaap 		}
1217*20010Sjaap 		else
1218*20010Sjaap 			printf("\\(%s %d %d\n", &chname[chtab[c -128+32]], code, f);
1219*20010Sjaap 	}
1220*20010Sjaap 	if(code == 0 || code > 0200) {
1221*20010Sjaap 		error(FATAL,"Illegal code 0%o found for char %03o\n", code, c+32);
1222*20010Sjaap 	}
1223*20010Sjaap 	putcode(code, f);	/* character is < 254 */
1224*20010Sjaap 	if (font != ofont)	/* char on special font, reset	*/
1225*20010Sjaap 		setfont(ofont);
1226*20010Sjaap 	lastw = pw[i] & BMASK;
1227*20010Sjaap /*HIRO*/
1228*20010Sjaap if( dbg)
1229*20010Sjaap 	fprintf(stderr,"lastw %d pw[i] %d\n", lastw,pw[i]);
1230*20010Sjaap 	lastw = (lastw * pstab[size-1] + dev.unitwidth/2) / dev.unitwidth;
1231*20010Sjaap }
1232*20010Sjaap 
1233*20010Sjaap putcode(code, f)
1234*20010Sjaap char code; short f;
1235*20010Sjaap {
1236*20010Sjaap 	static short phfont;
1237*20010Sjaap 
1238*20010Sjaap #ifdef VAX
1239*20010Sjaap 	if ( f > 0177777)
1240*20010Sjaap 		error(FATAL, "Impossible font selected");
1241*20010Sjaap #endif
1242*20010Sjaap 
1243*20010Sjaap 	if( harcode) {	/* if character pending */
1244*20010Sjaap 		hflush();	/* update position and flush pending char */
1245*20010Sjaap 	}
1246*20010Sjaap 	if ( f != phfont ) {
1247*20010Sjaap 		if(dbg > 1)
1248*20010Sjaap 			printf("font to %d\n", f);
1249*20010Sjaap 		putfont(f);
1250*20010Sjaap 	}
1251*20010Sjaap 	harcode = code;
1252*20010Sjaap 	phfont = f;
1253*20010Sjaap }
1254*20010Sjaap 
1255*20010Sjaap putfont(f)
1256*20010Sjaap int f;
1257*20010Sjaap {	int high, low;
1258*20010Sjaap 
1259*20010Sjaap 	low = f & BMASK;
1260*20010Sjaap 	high = (f >> BYTE ) & BMASK;
1261*20010Sjaap 	oput(FNT);
1262*20010Sjaap 	oput(high);
1263*20010Sjaap 	oput(low);
1264*20010Sjaap }
1265*20010Sjaap 
1266*20010Sjaap setsize(n)	/* set point size to a true pointsize */
1267*20010Sjaap int n;
1268*20010Sjaap {
1269*20010Sjaap 
1270*20010Sjaap 	if (!output)
1271*20010Sjaap 		return;
1272*20010Sjaap 	horsize = pstab[n-1];
1273*20010Sjaap 	vsizeflag = 0;
1274*20010Sjaap 	size = n;
1275*20010Sjaap 	putsize();
1276*20010Sjaap }
1277*20010Sjaap 
1278*20010Sjaap /*
1279*20010Sjaap  * Do the actual sizechange(s).
1280*20010Sjaap  */
1281*20010Sjaap 
1282*20010Sjaap putsize()
1283*20010Sjaap {
1284*20010Sjaap 	if(!vsizeflag) {
1285*20010Sjaap 		flushchar();
1286*20010Sjaap 		sizecmd( PSZ, horsize);
1287*20010Sjaap 	}
1288*20010Sjaap 	else {
1289*20010Sjaap 		flushchar();
1290*20010Sjaap 		sizecmd( PSZ, versize);
1291*20010Sjaap 		sizecmd( HPZ, horsize);
1292*20010Sjaap 	}
1293*20010Sjaap }
1294*20010Sjaap 
1295*20010Sjaap sizecmd( cmd, n)
1296*20010Sjaap int	cmd, n;
1297*20010Sjaap {
1298*20010Sjaap 	int i, low, high;
1299*20010Sjaap 
1300*20010Sjaap 	i = 10 * n;
1301*20010Sjaap 	if(dbg)
1302*20010Sjaap 		printf("size to %d\n", n);
1303*20010Sjaap 	if( i > 01777)
1304*20010Sjaap 		error(FATAL, "Impossible pointsize requested");
1305*20010Sjaap 	low = i & BMASK;
1306*20010Sjaap 	high = (i >> BYTE) & BMASK;
1307*20010Sjaap 	if( high > 03 )
1308*20010Sjaap 		error(FATAL, "system error in point size cmd");
1309*20010Sjaap 	oput( cmd | high);
1310*20010Sjaap 	oput(low);
1311*20010Sjaap }
1312*20010Sjaap 
1313*20010Sjaap t_fp(n, s, si)	/* font position n now contains font s, intname si */
1314*20010Sjaap int n;
1315*20010Sjaap char *s, *si;
1316*20010Sjaap {
1317*20010Sjaap 	fontname[n].name = s;
1318*20010Sjaap 	fontname[n].number = atoi(si);
1319*20010Sjaap }
1320*20010Sjaap 
1321*20010Sjaap setfont(n)	/* set font to n (internal)*/
1322*20010Sjaap int n;
1323*20010Sjaap {
1324*20010Sjaap 	if (!output)
1325*20010Sjaap 		return;
1326*20010Sjaap 	if (n < 0 || n > NFONT)
1327*20010Sjaap 		error(FATAL, "illegal font %d\n", n);
1328*20010Sjaap 	font = n;
1329*20010Sjaap 	slantfont(fontbase[n]->slant & BMASK);
1330*20010Sjaap }
1331*20010Sjaap 
1332*20010Sjaap /*
1333*20010Sjaap putint(n)
1334*20010Sjaap {
1335*20010Sjaap 	if (dbg) {
1336*20010Sjaap 		printf("%02d\n", n);
1337*20010Sjaap 		return;
1338*20010Sjaap 	}
1339*20010Sjaap 	putc(n>>8, tf);
1340*20010Sjaap 	putc(n, tf);
1341*20010Sjaap }
1342*20010Sjaap */
1343