1*6317a530Sslatteng /* driver.c	(Berkeley)	1.2	83/08/09	*/
223344256Sslatteng #include <stdio.h>
323344256Sslatteng #include <ctype.h>
423344256Sslatteng 
523344256Sslatteng float	deltx;	/* max x value in output, for scaling */
623344256Sslatteng float	delty;	/* max y value in output, for scaling */
723344256Sslatteng int	dbg	= 0;
8*6317a530Sslatteng int	res	= 200;	/* versatec/varian is default */
923344256Sslatteng FILE	*fin;	/* input file pointer */
1023344256Sslatteng char	*cmdname;
1123344256Sslatteng int	crop	= 1;	/* trim off exterior white space if non-zero */
1223344256Sslatteng float	hshift	= 0.3;	/* move this far left for text (in em's) */
1323344256Sslatteng float	vshift	= 0.3;	/* this far down */
1423344256Sslatteng 			/* these values are suitable for circuit diagrams */
1523344256Sslatteng int	linetype	= 's';	/* solid is normal */
1623344256Sslatteng 
1723344256Sslatteng char	buf[20000];
1823344256Sslatteng char	*bp	= buf;
1923344256Sslatteng 
2023344256Sslatteng int	sxmin;		/* lower limit from s command */
2123344256Sslatteng int	symin;
2223344256Sslatteng int	sxmax	= 4096;	/* upper */
2323344256Sslatteng int	symax	= 4096;
2423344256Sslatteng int	xmin	= 30000;	/* min values found in actual data */
2523344256Sslatteng int	ymin	= 30000;
2623344256Sslatteng int	xmax	= -30000;	/* max */
2723344256Sslatteng int	ymax	= -30000;
2823344256Sslatteng 
main(argc,argv)2923344256Sslatteng main(argc,argv)
3023344256Sslatteng char **argv;
3123344256Sslatteng {
3223344256Sslatteng 	float atof();
3323344256Sslatteng 	int c;
3423344256Sslatteng 
3523344256Sslatteng 	cmdname = argv[0];
3623344256Sslatteng 	while (argc > 1 && *argv[1] == '-') {
3723344256Sslatteng 		switch (c = argv[1][1]) {
3823344256Sslatteng 		case 'T':
3923344256Sslatteng 			if (strcmp(&argv[1][2], "aps") == 0) {
4023344256Sslatteng 				res = 720;
4123344256Sslatteng 			} else if (strcmp(&argv[1][2], "cat") == 0) {
4223344256Sslatteng 				res = 432;
4323344256Sslatteng 			}
4423344256Sslatteng 			break;
4523344256Sslatteng 		case 'c':
4623344256Sslatteng 			crop = 0;
4723344256Sslatteng 			break;
4823344256Sslatteng 		case 'l':
4923344256Sslatteng 			delty = atof(&argv[1][2]);
5023344256Sslatteng 			break;
5123344256Sslatteng 		case 'w':
5223344256Sslatteng 		case 's':	/* set size */
5323344256Sslatteng 			if (argv[1][2] == 0) {
5423344256Sslatteng 				argv++;
5523344256Sslatteng 				argc--;
5623344256Sslatteng 				deltx = atof(&argv[1][0]);
5723344256Sslatteng 			} else
5823344256Sslatteng 				deltx = atof(&argv[1][2]);
5923344256Sslatteng 			if (c == 's')
6023344256Sslatteng 				delty = deltx;
6123344256Sslatteng 			break;
6223344256Sslatteng 		case 'd':
6323344256Sslatteng 			dbg = 1;
6423344256Sslatteng 			break;
6523344256Sslatteng 		}
6623344256Sslatteng 		argc--;
6723344256Sslatteng 		argv++;
6823344256Sslatteng 	}
6923344256Sslatteng 	if (argc <= 1) {
7023344256Sslatteng 		fin = stdin;
7123344256Sslatteng 		getdata();
7223344256Sslatteng 	} else
7323344256Sslatteng 		while (argc-- > 1) {
7423344256Sslatteng 			if ((fin = fopen(*++argv, "r")) == NULL) {
7523344256Sslatteng 				fprintf(stderr, "%s: can't open %s\n", cmdname, *argv);
7623344256Sslatteng 				exit(1);
7723344256Sslatteng 			}
7823344256Sslatteng 			getdata();
7923344256Sslatteng 			fclose(fin);
8023344256Sslatteng 		}
8123344256Sslatteng 	print();
8223344256Sslatteng 	exit(0);
8323344256Sslatteng }
8423344256Sslatteng 
getdata()8523344256Sslatteng getdata()	/* read the file, collect max, min sizes, etc. */
8623344256Sslatteng {
8723344256Sslatteng 	char s[100], s1[20], *p;
8823344256Sslatteng 	int x, y, x1, y1, x2, y2, r, c;
8923344256Sslatteng 
9023344256Sslatteng 	while ((c = getc(fin)) != EOF) {
9123344256Sslatteng 		switch (c) {
9223344256Sslatteng 		case 'M':
9323344256Sslatteng 		case 'N':
9423344256Sslatteng 		case 'P':
9523344256Sslatteng 			fscanf(fin, "%d %d", &x, &y);
9623344256Sslatteng 			extreme(x, y);
9723344256Sslatteng 			ctobuf(tolower(c));
9823344256Sslatteng 			xytobuf(x, y);
9923344256Sslatteng 			break;
10023344256Sslatteng 		case 'm':
10123344256Sslatteng 		case 'n':
10223344256Sslatteng 		case 'p':
10323344256Sslatteng 			x = getsi(fin);
10423344256Sslatteng 			y = getsi(fin);
10523344256Sslatteng 			extreme(x, y);
10623344256Sslatteng 			ctobuf(c);
10723344256Sslatteng 			xytobuf(x, y);
10823344256Sslatteng 			break;
10923344256Sslatteng 		case 'L':
11023344256Sslatteng 		case 'B':
11123344256Sslatteng 			fscanf(fin, "%d %d %d %d", &x, &y, &x1, &y1);
11223344256Sslatteng 			extreme(x, y);
11323344256Sslatteng 			extreme(x1, y1);
11423344256Sslatteng 			ctobuf(tolower(c));
11523344256Sslatteng 			xytobuf(x, y);
11623344256Sslatteng 			xytobuf(x1, y1);
11723344256Sslatteng 			break;
11823344256Sslatteng 		case 'l':
11923344256Sslatteng 		case 'b':
12023344256Sslatteng 			x = getsi(fin);
12123344256Sslatteng 			y = getsi(fin);
12223344256Sslatteng 			x1 = getsi(fin);
12323344256Sslatteng 			y1 = getsi(fin);
12423344256Sslatteng 			extreme(x, y);
12523344256Sslatteng 			extreme(x1, y1);
12623344256Sslatteng 			ctobuf(c);
12723344256Sslatteng 			xytobuf(x, y);
12823344256Sslatteng 			xytobuf(x1, y1);
12923344256Sslatteng 			break;
13023344256Sslatteng 		case 'S':
13123344256Sslatteng 			fscanf(fin, "%d %d %d %d", &sxmin, &symin, &sxmax, &symax);
13223344256Sslatteng 			break;	/* BUG -- ignoring this because it overrides -c */
13323344256Sslatteng 			ctobuf('s');
13423344256Sslatteng 			xytobuf(sxmin, symin);
13523344256Sslatteng 			xytobuf(sxmax, symax);
13623344256Sslatteng 			break;
13723344256Sslatteng 		case 's':
13823344256Sslatteng 			sxmin = getsi(fin);
13923344256Sslatteng 			symin = getsi(fin);
14023344256Sslatteng 			sxmax = getsi(fin);
14123344256Sslatteng 			symax = getsi(fin);
14223344256Sslatteng 			break;	/* BUG -- ignoring this because it overrides -c */
14323344256Sslatteng 			ctobuf(c);
14423344256Sslatteng 			xytobuf(sxmin, symin);
14523344256Sslatteng 			xytobuf(sxmax, symax);
14623344256Sslatteng 			break;
14723344256Sslatteng 		case 'T':
14823344256Sslatteng 		case 't':
14923344256Sslatteng 			fgets(s, sizeof s, fin);
15023344256Sslatteng 			for (p = s; *p != '\n'; p++)
15123344256Sslatteng 				;
15223344256Sslatteng 			*p = 0;	/* zap newline */
15323344256Sslatteng 			ctobuf('t');
15423344256Sslatteng 			stobuf(s);
15523344256Sslatteng 			break;
15623344256Sslatteng 		case 'E':
15723344256Sslatteng 		case 'e':
15823344256Sslatteng 			ctobuf('e');
15923344256Sslatteng 			break;
16023344256Sslatteng 		case 'A':
16123344256Sslatteng 			fscanf(fin, "%d %d %d %d %d %d", &x, &y, &x1, &y1, &x2, &y2);
16223344256Sslatteng 			extreme(x, y);	/* should use radius */
16323344256Sslatteng 			ctobuf('a');
16423344256Sslatteng 			xytobuf(x, y);
16523344256Sslatteng 			xytobuf(x1, y1);
16623344256Sslatteng 			xytobuf(x2, y2);
16723344256Sslatteng 			break;
16823344256Sslatteng 		case 'a':
16923344256Sslatteng 			x = getsi(fin);
17023344256Sslatteng 			y = getsi(fin);
17123344256Sslatteng 			x1 = getsi(fin);
17223344256Sslatteng 			y1 = getsi(fin);
17323344256Sslatteng 			x2 = getsi(fin);
17423344256Sslatteng 			y2 = getsi(fin);
17523344256Sslatteng 			extreme(x, y);	/* should use radius */
17623344256Sslatteng 			ctobuf('a');
17723344256Sslatteng 			xytobuf(x, y);
17823344256Sslatteng 			xytobuf(x1, y1);
17923344256Sslatteng 			xytobuf(x2, y2);
18023344256Sslatteng 			break;
18123344256Sslatteng 		case 'C':
18223344256Sslatteng 			fscanf(fin, "%d %d %d", &x, &y, &r);
18323344256Sslatteng 			extreme(x+r, y+r);
18423344256Sslatteng 			extreme(x-r, y-r);
18523344256Sslatteng 			ctobuf('c');
18623344256Sslatteng 			xytobuf(x, y);
18723344256Sslatteng 			xtobuf(r);
18823344256Sslatteng 			break;
18923344256Sslatteng 		case 'c':
19023344256Sslatteng 			x = getsi(fin);
19123344256Sslatteng 			y = getsi(fin);
19223344256Sslatteng 			r = getsi(fin);
19323344256Sslatteng 			extreme(x+r, y+r);
19423344256Sslatteng 			extreme(x-r, y-r);
19523344256Sslatteng 			ctobuf('c');
19623344256Sslatteng 			xytobuf(x, y);
19723344256Sslatteng 			xtobuf(r);
19823344256Sslatteng 			break;
19923344256Sslatteng 		case 'F':
20023344256Sslatteng 		case 'f':
20123344256Sslatteng 			fgets(s, sizeof s, fin);
20223344256Sslatteng 			ctobuf('f');
20323344256Sslatteng 			sscanf(s, "%s", s1);
20423344256Sslatteng 			if (strcmp(s1, "solid") == 0)
20523344256Sslatteng 				c = 's';
20623344256Sslatteng 			else if (strcmp(s1, "dotted") == 0)
20723344256Sslatteng 				c = '.';
20823344256Sslatteng 			else if (strcmp(s1, "longdashed") == 0)
20923344256Sslatteng 				c = '_';
21023344256Sslatteng 			else if (strcmp(s1, "shortdashed") == 0)
21123344256Sslatteng 				c = '-';
21223344256Sslatteng 			else
21323344256Sslatteng 				c = '!';	/* would you believe dotdashed? */
21423344256Sslatteng 			ctobuf(c);
21523344256Sslatteng 			break;
21623344256Sslatteng 		case 'd':
21723344256Sslatteng 		case 'D':
21823344256Sslatteng 			fgets(s, 100, fin);
21923344256Sslatteng 			/* ignore */
22023344256Sslatteng 			break;
22123344256Sslatteng 		default:
22223344256Sslatteng 			break;
22323344256Sslatteng 		}
22423344256Sslatteng 		if (bp >= buf + sizeof buf) {
22523344256Sslatteng 			fprintf(stderr, "pltroff: input too big to handle\n");
22623344256Sslatteng 			exit(1);
22723344256Sslatteng 		}
22823344256Sslatteng 	}
22923344256Sslatteng 	*bp = 0;
23023344256Sslatteng }
23123344256Sslatteng 
extreme(x,y)23223344256Sslatteng extreme(x, y)	/* record max and min x and y values */
23323344256Sslatteng {
23423344256Sslatteng 	if (x > xmax)
23523344256Sslatteng 		xmax = x;
23623344256Sslatteng 	if (y > ymax)
23723344256Sslatteng 		ymax = y;
23823344256Sslatteng 	if (x < xmin)
23923344256Sslatteng 		xmin = x;
24023344256Sslatteng 	if (y < ymin)
24123344256Sslatteng 		ymin = y;
24223344256Sslatteng }
24323344256Sslatteng 
ctobuf(c)24423344256Sslatteng ctobuf(c)
24523344256Sslatteng {
24623344256Sslatteng 	*bp++ = c;
24723344256Sslatteng }
24823344256Sslatteng 
stobuf(s)24923344256Sslatteng stobuf(s)
25023344256Sslatteng char *s;
25123344256Sslatteng {
25223344256Sslatteng 	while (*bp++ = *s++)
25323344256Sslatteng 		;
25423344256Sslatteng }
25523344256Sslatteng 
xytobuf(x,y)25623344256Sslatteng xytobuf(x, y)
25723344256Sslatteng {
25823344256Sslatteng 	*bp++ = x >> 8;
25923344256Sslatteng 	*bp++ = x & 0377;
26023344256Sslatteng 	*bp++ = y >> 8;
26123344256Sslatteng 	*bp++ = y & 0377;
26223344256Sslatteng }
26323344256Sslatteng 
xtobuf(x)26423344256Sslatteng xtobuf(x)
26523344256Sslatteng {
26623344256Sslatteng 	*bp++ = x >> 8;
26723344256Sslatteng 	*bp++ = x & 0377;
26823344256Sslatteng }
26923344256Sslatteng 
print()27023344256Sslatteng print()
27123344256Sslatteng {
27223344256Sslatteng 	char s[100], *p;
27323344256Sslatteng 	int x, y, x1, y1, x2, y2, r, c;
27423344256Sslatteng 
27523344256Sslatteng 	openpl("\n");	/* outputs .PS\n */
27623344256Sslatteng 	for (bp = buf; *bp; ) {
27723344256Sslatteng 		switch (c = *bp++) {
27823344256Sslatteng 		case 'm':
27923344256Sslatteng 			x = getbuf();
28023344256Sslatteng 			y = getbuf();
28123344256Sslatteng 			move(x, y);
28223344256Sslatteng 			break;
28323344256Sslatteng 		case 'f':	/* line mode */
28423344256Sslatteng 			linetype = *bp++;
28523344256Sslatteng 			break;
28623344256Sslatteng 		case 'l':
28723344256Sslatteng 			x = getbuf();
28823344256Sslatteng 			y = getbuf();
28923344256Sslatteng 			x1 = getbuf();
29023344256Sslatteng 			y1 = getbuf();
29123344256Sslatteng 			if (linetype == 's')
29223344256Sslatteng 				line(x, y, x1, y1);
29323344256Sslatteng 			else
29423344256Sslatteng 				dotline(x, y, x1, y1, linetype);
29523344256Sslatteng 			break;
29623344256Sslatteng 		case 't':
29723344256Sslatteng 			for (p = s; *p++ = *bp++; )
29823344256Sslatteng 				;
29923344256Sslatteng 			label(s, 'L', 0);
30023344256Sslatteng 			break;
30123344256Sslatteng 		case 'e':
30223344256Sslatteng 			erase();
30323344256Sslatteng 			break;
30423344256Sslatteng 		case 'p':
30523344256Sslatteng 			x = getbuf();
30623344256Sslatteng 			y = getbuf();
30723344256Sslatteng 			point(x, y);
30823344256Sslatteng 			break;
30923344256Sslatteng 		case 'n':
31023344256Sslatteng 			x = getbuf();
31123344256Sslatteng 			y = getbuf();
31223344256Sslatteng 			cont(x, y);
31323344256Sslatteng 			break;
31423344256Sslatteng 		case 's':
31523344256Sslatteng 			x = getbuf();
31623344256Sslatteng 			y = getbuf();
31723344256Sslatteng 			x1 = getbuf();
31823344256Sslatteng 			y1 = getbuf();
31923344256Sslatteng 			space(x, y, x1, y1);
32023344256Sslatteng 			break;
32123344256Sslatteng 		case 'a':
32223344256Sslatteng 			x = getbuf();
32323344256Sslatteng 			y = getbuf();
32423344256Sslatteng 			x1 = getbuf();
32523344256Sslatteng 			y1 = getbuf();
32623344256Sslatteng 			x2 = getbuf();
32723344256Sslatteng 			y2 = getbuf();
32823344256Sslatteng 			arc(x, y, x1, y1, x2, y2);
32923344256Sslatteng 			break;
33023344256Sslatteng 		case 'c':
33123344256Sslatteng 			x = getbuf();
33223344256Sslatteng 			y = getbuf();
33323344256Sslatteng 			r = getbuf();
33423344256Sslatteng 			circle(x, y, r);
33523344256Sslatteng 			break;
33623344256Sslatteng 		case 'b':
33723344256Sslatteng 			x = getbuf();
33823344256Sslatteng 			y = getbuf();
33923344256Sslatteng 			x1 = getbuf();
34023344256Sslatteng 			y1 = getbuf();
34123344256Sslatteng 			box(x, y, x1, y1);
34223344256Sslatteng 			break;
34323344256Sslatteng 		default:
34423344256Sslatteng 			break;
34523344256Sslatteng 		}
34623344256Sslatteng 	}
34723344256Sslatteng 	closepl();
34823344256Sslatteng }
34923344256Sslatteng 
dotline(x0,y0,x1,y1,type)35023344256Sslatteng dotline(x0, y0, x1, y1, type) /* dotted or dashed line */
35123344256Sslatteng int x0, y0, x1, y1;
35223344256Sslatteng int type;
35323344256Sslatteng {
35423344256Sslatteng 	int prevval = 10;
35523344256Sslatteng 	int i, numdots;
35623344256Sslatteng 	double a, b, sqrt(), dx, dy;
35723344256Sslatteng 
35823344256Sslatteng 	dx = x1 - x0;
35923344256Sslatteng 	dy = y1 - y0;
36023344256Sslatteng 	if (type == '.') {
36123344256Sslatteng 		numdots = sqrt(dx*dx + dy*dy) / prevval + 0.5;
36223344256Sslatteng 		for (i = 0; i <= numdots; i++) {
36323344256Sslatteng 			a = (float) i / (float) numdots;
36423344256Sslatteng 			move(x0 + (int)(a * dx), y0 + (int)(a * dy));
36523344256Sslatteng 			dot();
36623344256Sslatteng 		}
36723344256Sslatteng 	} else {	/* all others */
36823344256Sslatteng 		double d, dashsize, spacesize;
36923344256Sslatteng 		d = sqrt(dx*dx + dy*dy) + 0.5;
37023344256Sslatteng 		if (d <= 2 * prevval) {
37123344256Sslatteng 			line(x0, y0, x1, y1);
37223344256Sslatteng 			return;
37323344256Sslatteng 		}
37423344256Sslatteng 		numdots = d / (2 * prevval - 1) + 1;	/* ceiling */
37523344256Sslatteng 		dashsize = prevval;
37623344256Sslatteng 		spacesize = (d - numdots * dashsize) / (numdots - 1);
37723344256Sslatteng 		for (i = 0; i < numdots-1; i++) {
37823344256Sslatteng 			a = i * (dashsize + spacesize) / d;
37923344256Sslatteng 			b = a + dashsize / d;
38023344256Sslatteng 			line(x0 + (int)(a*dx), y0 + (int)(a*dy), x0 + (int)(b*dx), y0 + (int)(b*dy));
38123344256Sslatteng 			a = b;
38223344256Sslatteng 			b = a + spacesize / d;
38323344256Sslatteng 			move(x0 + (int)(a*dx), y0 + (int)(a*dy));
38423344256Sslatteng 		}
38523344256Sslatteng 		line(x0 + (int)(b * dx), y0 + (int)(b * dy), x1, y1);
38623344256Sslatteng 	}
38723344256Sslatteng }
38823344256Sslatteng 
getbuf()38923344256Sslatteng getbuf()
39023344256Sslatteng {
39123344256Sslatteng 	int n;
39223344256Sslatteng 
39323344256Sslatteng 	n = *bp++ << 8;
39423344256Sslatteng 	n |= (*bp++ & 0377);
39523344256Sslatteng 	return(n);
39623344256Sslatteng }
39723344256Sslatteng 
getsi(fin)39823344256Sslatteng getsi(fin)  FILE *fin; {	/* get an integer stored in 2 ascii bytes. */
39923344256Sslatteng 	short a, b;
40023344256Sslatteng 	if((b = getc(fin)) == EOF)
40123344256Sslatteng 		return(EOF);
40223344256Sslatteng 	if((a = getc(fin)) == EOF)
40323344256Sslatteng 		return(EOF);
40423344256Sslatteng 	a = a<<8;
40523344256Sslatteng 	return(a|b);
40623344256Sslatteng }
407