xref: /csrg-svn/old/vplot/vplot.c (revision 11711)
1*11711Sralph /*  VPLOT: version 4.2				updated 03/24/83
211516Sralph  *
311517Sralph  *  Reads standard graphics input and produces a plot on the
411517Sralph  *  Varian or Versatec
511516Sralph  */
611517Sralph #include <stdio.h>
711516Sralph #include <signal.h>
811517Sralph #include <vfont.h>
911516Sralph 
1011517Sralph #define LPR "/usr/ucb/lpr"
1111517Sralph 
1211517Sralph #define	mapx(x)	((DevRange*((x)-botx)/del)+centx)
1311517Sralph #define	mapy(y)	((DevRange*(del-(y)+boty)/del)-centy)
1411516Sralph #define SOLID -1
1511516Sralph #define DOTTED 014
1611516Sralph #define SHORTDASHED 034
1711516Sralph #define DOTDASHED 054
1811516Sralph #define LONGDASHED 074
1911516Sralph 
20*11711Sralph char *Sid = "@(#)\t03/24/83";
2111517Sralph 
2211516Sralph int	linmod	= SOLID;
2311516Sralph int	done1;
2411516Sralph char	chrtab[][16];
25*11711Sralph char	*obuf;
26*11711Sralph int	bufsize;
2711516Sralph int	lastx;
2811516Sralph int	lasty;
2911517Sralph int	radius, startx, starty, endx, endy;
3011517Sralph double	topx;
3111517Sralph double	topy;
3211517Sralph double	botx;
3311517Sralph double	boty;
3411517Sralph int	centx = 0;
3511517Sralph int	centy = 0;
3611517Sralph double	delx;
3711517Sralph double	dely;
3811517Sralph double	del;
3911516Sralph 
4011517Sralph int	warned = 0;	/* Indicates whether the warning message about
4111517Sralph 			 * unimplemented routines has been printed */
4211517Sralph 
4311517Sralph FILE	*infile;
44*11711Sralph FILE	*pfp;			/* output file */
4511517Sralph char	picture[] = "/usr/tmp/rastAXXXXXX";
4611517Sralph int	run = 13;		/* index of 'a' in picture[] */
4711517Sralph int	DevRange = 1536;	/* output array size (square) in pixels */
48*11711Sralph int	DevRange8 = 1536/8;	/* output array size in bytes */
4911517Sralph int	BytesPerLine = 264;	/* Bytes per raster line (physical) */
5011517Sralph int	lparg = 7;		/* index into lpargs */
5111516Sralph 
5211517Sralph char	*lpargs[50] = { "lpr", "-Pvarian", "-v", "-s", "-r", "-J", "vplot" };
5311517Sralph 
5411517Sralph /* variables for used to print from font file */
5511517Sralph int	fontSet = 0;		/* Has the font file been read */
5611517Sralph struct	header header;
5711517Sralph struct	dispatch dispatch[256];
5811517Sralph char	*bits;
5911517Sralph char	*fontFile = "/usr/lib/vfont/R.6";
6011517Sralph 
6111516Sralph main(argc, argv)
6211517Sralph int argc;
6311516Sralph char **argv;
6411516Sralph {
6511517Sralph 	extern int cleanup();
66*11711Sralph 	register char *cp1, *arg;
67*11711Sralph 	register i;
6811517Sralph 	int again;
6911516Sralph 
7011517Sralph 	infile = stdin;
7111517Sralph 	while (argc > 1 && argv[1][0] == '-') {
7211517Sralph 		argc--;
7311517Sralph 		arg = *++argv;
7411517Sralph 		switch (*++arg) {
7511517Sralph 		case 'W':
76*11711Sralph 			DevRange = 2048;
77*11711Sralph 			DevRange8 = 2048/8;
7811517Sralph 			BytesPerLine = 880;
7911517Sralph 			lpargs[1] = "-Pversatec";
8011517Sralph 			break;
8111517Sralph 		case 'V':
8211517Sralph 			DevRange = 1536;
83*11711Sralph 			DevRange8 = 1536/8;
8411517Sralph 			BytesPerLine = 264;
8511517Sralph 			lpargs[1] = "-Pvarian";
8611517Sralph 			break;
8711517Sralph 		case 'b':
8811517Sralph 			if (argc-- > 1)
8911517Sralph 				lpargs[lparg-1] = *++argv;
9011517Sralph 			break;
9111517Sralph 		default:
9211517Sralph 			fprintf(stderr, "vplot: %s option unknown\n", *argv);
9311517Sralph 			break;
9411517Sralph 		}
9511516Sralph 	}
9611517Sralph 	if (argc > 1) {
9711517Sralph 		if ((infile = fopen(*++argv, "r")) == NULL) {
9811517Sralph 			perror(*argv);
9911517Sralph 			cleanup();
10011517Sralph 		}
10111517Sralph 	}
10211517Sralph 
10311517Sralph 	/* init constants for scaling */
10411517Sralph 	topx = topy = DevRange;
10511517Sralph 	botx = boty = 0;
10611517Sralph 	delx = dely = del = DevRange;
10711517Sralph 	centx = (DevRange - mapx(topx))/2;
10811517Sralph 	centy = mapy(topy)/2;
10911517Sralph 	signal(SIGTERM, cleanup);
11011516Sralph 	if (signal(SIGINT, SIG_IGN) != SIG_IGN)
11111517Sralph 		signal(SIGINT, cleanup);
11211517Sralph 	mktemp(picture);
113*11711Sralph 	if ((obuf = (char *) malloc(bufsize = DevRange * DevRange8)) == NULL) {
114*11711Sralph 		fprintf(stderr, "vplot: ran out of memory\n");
115*11711Sralph 		cleanup();
116*11711Sralph 	}
11711517Sralph 	do {
118*11711Sralph 		if ((pfp = fopen(picture, "w")) == NULL) {
119*11711Sralph 			fprintf(stderr, "vplot: can't create %s\n", picture);
12011517Sralph 			cleanup();
12111516Sralph 		}
12211517Sralph 		i = strlen(picture) + 1;
123*11711Sralph 		if ((arg = (char *) malloc(i)) == NULL) {
12411517Sralph 			fprintf(stderr, "ran out of memory\n");
12511517Sralph 			cleanup();
12611517Sralph 		}
12711517Sralph 		strcpy(arg, picture);
12811517Sralph 		lpargs[lparg++] = arg;
12911517Sralph 		picture[run]++;
130*11711Sralph 		arg = &obuf[bufsize];
131*11711Sralph 		for (cp1 = obuf; cp1 < arg; )
132*11711Sralph 			*cp1++ = 0;
13311517Sralph 
13411517Sralph 		again = getpict();
13511517Sralph 
136*11711Sralph 		for (cp1 = obuf; cp1 < arg; cp1 += DevRange8) {
137*11711Sralph 			fwrite(cp1, sizeof(char), DevRange8, pfp);
138*11711Sralph 			fseek(pfp, (long) BytesPerLine - DevRange8, 1);
13911517Sralph 		}
140*11711Sralph 		fclose(pfp);
14111517Sralph 	} while (again);
14211517Sralph 	lpargs[lparg] = 0;
14311517Sralph 	execv(LPR, lpargs);
14411517Sralph 	fprintf(stderr, "can't exec %s\n", LPR);
14511517Sralph 	cleanup();
14611516Sralph }
14711516Sralph 
14811516Sralph getpict()
14911516Sralph {
15011516Sralph 	register x1, y1;
15111516Sralph 
15211517Sralph 	for (;;) switch (x1 = getc(infile)) {
15311516Sralph 
15411517Sralph 	case '\n':
15511517Sralph 		continue;
15611517Sralph 
15711516Sralph 	case 's':
15811517Sralph 		botx = getinteger(infile);
15911517Sralph 		boty = getinteger(infile);
16011517Sralph 		topx = getinteger(infile);
16111517Sralph 		topy = getinteger(infile);
16211516Sralph 		delx = topx-botx;
16311516Sralph 		dely = topy-boty;
16411516Sralph 		if (dely/delx > 1536./2048.)
16511516Sralph 			del = dely;
16611516Sralph 		else
16711517Sralph 			del = delx;
16811516Sralph 		centx = 0;
16911517Sralph 		centx = (DevRange - mapx(topx))/2;
17011516Sralph 		centy = 0;
17111516Sralph 		centy = mapy(topy) / 2;
17211516Sralph 		continue;
17311516Sralph 
17411517Sralph 	case 'b':
17511517Sralph 		x1 = getc(infile);
17611517Sralph 		continue;
17711517Sralph 
17811516Sralph 	case 'l':
17911516Sralph 		done1 |= 01;
18011517Sralph 		x1 = mapx(getinteger(infile));
18111517Sralph 		y1 = mapy(getinteger(infile));
18211517Sralph 		lastx = mapx(getinteger(infile));
18311517Sralph 		lasty = mapy(getinteger(infile));
18411516Sralph 		line(x1, y1, lastx, lasty);
18511516Sralph 		continue;
18611516Sralph 
18711517Sralph 	case 'c':
18811517Sralph 		x1 = mapx(getinteger(infile));
18911517Sralph 		y1 = mapy(getinteger(infile));
19011517Sralph 		radius = mapx(getinteger(infile));
19111517Sralph 		if (!warned) {
19211517Sralph 			fprintf(stderr,"Circles are Implemented\n");
19311517Sralph 			warned++;
19411517Sralph 		}
19511517Sralph 		circle(x1, y1, radius);
19611517Sralph 		continue;
19711517Sralph 
19811517Sralph 	case 'a':
19911517Sralph 		x1 = mapx(getinteger(infile));
20011517Sralph 		y1 = mapy(getinteger(infile));
20111517Sralph 		startx = mapx(getinteger(infile));
20211517Sralph 		starty = mapy(getinteger(infile));
20311517Sralph 		endx = mapx(getinteger(infile));
20411517Sralph 		endy = mapy(getinteger(infile));
20511517Sralph 		if (!warned) {
20611517Sralph 			fprintf(stderr,"Circles and Arcs are unimplemented\n");
20711517Sralph 			warned++;
20811517Sralph 		}
20911517Sralph 		continue;
21011517Sralph 
21111516Sralph 	case 'm':
21211517Sralph 		lastx = mapx(getinteger(infile));
21311517Sralph 		lasty = mapy(getinteger(infile));
21411516Sralph 		continue;
21511516Sralph 
21611516Sralph 	case 't':
21711517Sralph 		lastx = lastx - 6;
21811517Sralph 		lasty = lasty + 6;
21911516Sralph 		done1 |= 01;
22011517Sralph 		while ((x1 = getc(infile)) != '\n')
22111516Sralph 			plotch(x1);
22211516Sralph 		continue;
22311516Sralph 
22411516Sralph 	case 'e':
22511517Sralph 		if (done1)
22611517Sralph 			return(1);
22711516Sralph 		continue;
22811516Sralph 
22911516Sralph 	case 'p':
23011516Sralph 		done1 |= 01;
23111517Sralph 		lastx = mapx(getinteger(infile));
23211517Sralph 		lasty = mapy(getinteger(infile));
23311516Sralph 		point(lastx, lasty);
23411516Sralph 		point(lastx+1, lasty);
23511516Sralph 		point(lastx, lasty+1);
23611516Sralph 		point(lastx+1, lasty+1);
23711516Sralph 		continue;
23811516Sralph 
23911516Sralph 	case 'n':
24011516Sralph 		done1 |= 01;
24111517Sralph 		x1 = mapx(getinteger(infile));
24211517Sralph 		y1 = mapy(getinteger(infile));
24311516Sralph 		line(lastx, lasty, x1, y1);
24411516Sralph 		lastx = x1;
24511516Sralph 		lasty = y1;
24611516Sralph 		continue;
24711516Sralph 
24811516Sralph 	case 'f':
24911517Sralph 		getinteger(infile);
25011517Sralph 		getc(infile);
25111517Sralph 		switch (getc(infile)) {
25211516Sralph 		case 't':
25311516Sralph 			linmod = DOTTED;
25411516Sralph 			break;
25511516Sralph 		default:
25611516Sralph 		case 'i':
25711516Sralph 			linmod = SOLID;
25811516Sralph 			break;
25911516Sralph 		case 'g':
26011516Sralph 			linmod = LONGDASHED;
26111516Sralph 			break;
26211516Sralph 		case 'r':
26311516Sralph 			linmod = SHORTDASHED;
26411516Sralph 			break;
26511516Sralph 		case 'd':
26611516Sralph 			linmod = DOTDASHED;
26711516Sralph 			break;
26811516Sralph 		}
26911517Sralph 		while ((x1 = getc(infile)) != '\n')
27011517Sralph 			if (x1 == EOF)
27111517Sralph 				return(0);
27211516Sralph 		continue;
27311516Sralph 
27411516Sralph 	case 'd':
27511517Sralph 		getinteger(infile);
27611517Sralph 		getinteger(infile);
27711517Sralph 		getinteger(infile);
27811517Sralph 		x1 = getinteger(infile);
27911516Sralph 		while (--x1 >= 0)
28011517Sralph 			getinteger(infile);
28111516Sralph 		continue;
28211516Sralph 
28311517Sralph 	case 0:		/* ignore null characters */
28411517Sralph 		continue;
28511516Sralph 
28611517Sralph 	case 255:
28711517Sralph 	case EOF:
28811517Sralph 		return(0);
28911517Sralph 
29011516Sralph 	default:
29111517Sralph 		fprintf(stderr, "Input format error %c(%o)\n",x1,x1);
29211517Sralph 		cleanup();
29311516Sralph 	}
29411516Sralph }
29511516Sralph 
29611517Sralph plotch(ch)
29711517Sralph char ch;
29811516Sralph {
29911517Sralph 	register int i,j,k;
30011517Sralph 	register char *ptr,c;
30111517Sralph 	int nbytes;
30211516Sralph 
30311517Sralph 	if (!fontSet)
30411517Sralph 		InitFont();	/* Read font if not already read */
30511517Sralph 
30611517Sralph 	ptr = bits + dispatch[ch].addr;
30711517Sralph 
30811517Sralph 	for (i = dispatch[ch].up; i > -dispatch[ch].down; --i) {
30911517Sralph 		nbytes = (dispatch[ch].right + dispatch[ch].left + 7)/8;
31011517Sralph 		for (j = 0; j < nbytes; j++) {
31111517Sralph 			c = *ptr++;
31211517Sralph 			for (k = 7; k >= 0; k--)
31311517Sralph 				if ((c >> k) & 1)
31411517Sralph 					point(lastx+7-k+j*8-dispatch[ch].left, lasty-i);
31511517Sralph 		}
31611516Sralph 	}
31711517Sralph 	if (ch != ' ')
31811517Sralph 		lastx += dispatch[ch].width;
31911517Sralph 	else
32011517Sralph 		lastx += dispatch['a'].width;
32111516Sralph }
32211516Sralph 
32311517Sralph InitFont()
32411516Sralph {
32511517Sralph 	char *s;
32611517Sralph 	int fonts;
32711517Sralph 	int i;
32811516Sralph 
32911517Sralph 	fontSet = 1;
33011517Sralph 	/* Get the font file */
33111517Sralph 	s = fontFile;
33211517Sralph 	if ((fonts = open(s, 0)) == -1) {
33311517Sralph 		perror(s);
33411517Sralph 		fprintf(stderr, "Can't get font file");
33511517Sralph 		cleanup();
33611516Sralph 	}
33711517Sralph 	/* Get the header and check magic number */
33811517Sralph 	if (read(fonts, &header, sizeof(header)) != sizeof(header)) {
33911517Sralph 		perror(s);
34011517Sralph 		fprintf(stderr, "Bad read in font file");
34111517Sralph 		cleanup();
34211516Sralph 	}
34311517Sralph 	if (header.magic != 0436) {
34411517Sralph 		fprintf(stderr,"Bad magic numer in font file");
34511517Sralph 		cleanup();
34611517Sralph 	}
34711517Sralph 	/* Get dispatches */
34811517Sralph 	if (read(fonts, dispatch, sizeof(dispatch)) != sizeof(dispatch)) {
34911517Sralph 		perror(s);
35011517Sralph 		fprintf(stderr, "Bad read in font file");
35111517Sralph 		cleanup();
35211517Sralph 	}
35311517Sralph 	/* Allocate space for bit map and read in bits */
35411517Sralph 	bits = (char *) malloc(header.size);
35511517Sralph 	if (read(fonts, bits, header.size) != header.size) {
35611517Sralph 		perror(s);
35711517Sralph 		fprintf(stderr,"Can't read bit map in font file");
35811517Sralph 		cleanup();
35911517Sralph 	}
36011517Sralph 	/* Close font file */
36111517Sralph 	if (close(fonts) != 0) {
36211517Sralph 		perror(s);
36311517Sralph 		fprintf(stderr,"Can't close font file");
36411517Sralph 		cleanup();
36511517Sralph 	}
36611516Sralph }
36711516Sralph 
36811516Sralph line(x0, y0, x1, y1)
36911516Sralph register x0, y0;
37011516Sralph {
37111516Sralph 	int dx, dy;
37211516Sralph 	int xinc, yinc;
37311516Sralph 	register res1;
37411516Sralph 	int res2;
37511516Sralph 	int slope;
37611516Sralph 
37711516Sralph 	xinc = 1;
37811516Sralph 	yinc = 1;
37911516Sralph 	if ((dx = x1-x0) < 0) {
38011516Sralph 		xinc = -1;
38111516Sralph 		dx = -dx;
38211516Sralph 	}
38311516Sralph 	if ((dy = y1-y0) < 0) {
38411516Sralph 		yinc = -1;
38511516Sralph 		dy = -dy;
38611516Sralph 	}
38711516Sralph 	slope = xinc*yinc;
38811516Sralph 	res1 = 0;
38911516Sralph 	res2 = 0;
39011516Sralph 	if (dx >= dy) while (x0 != x1) {
39111517Sralph 		if ((x0+slope*y0) & linmod)
39211517Sralph 			point(x0, y0);
39311516Sralph 		if (res1 > res2) {
39411516Sralph 			res2 += dx - res1;
39511516Sralph 			res1 = 0;
39611516Sralph 			y0 += yinc;
39711516Sralph 		}
39811516Sralph 		res1 += dy;
39911516Sralph 		x0 += xinc;
40011516Sralph 	} else while (y0 != y1) {
40111517Sralph 		if ((x0+slope*y0) & linmod)
40211516Sralph 		point(x0, y0);
40311516Sralph 		if (res1 > res2) {
40411516Sralph 			res2 += dy - res1;
40511516Sralph 			res1 = 0;
40611516Sralph 			x0 += xinc;
40711516Sralph 		}
40811516Sralph 		res1 += dx;
40911516Sralph 		y0 += yinc;
41011516Sralph 	}
41111517Sralph 	if ((x1+slope*y1) & linmod)
41211516Sralph 		point(x1, y1);
41311516Sralph }
41411516Sralph 
41511517Sralph #define labs(a) (a >= 0 ? a : -a)
41611517Sralph 
41711517Sralph circle(x,y,c)
41811517Sralph {
41911517Sralph 	register dx, dy;
42011517Sralph 	long ep;
42111517Sralph 	int de;
42211517Sralph 
42311517Sralph 	dx = 0;
42411517Sralph 	ep = 0;
42511517Sralph 	for (dy=c; dy>=dx; dy--) {
42611517Sralph 		for (;;) {
42711517Sralph 			point(x+dx, y+dy);
42811517Sralph 			point(x-dx, y+dy);
42911517Sralph 			point(x+dx, y-dy);
43011517Sralph 			point(x-dx, y-dy);
43111517Sralph 			point(x+dy, y+dx);
43211517Sralph 			point(x-dy, y+dx);
43311517Sralph 			point(x+dy, y-dx);
43411517Sralph 			point(x-dy, y-dx);
43511517Sralph 			ep += 2*dx + 1;
43611517Sralph 			de = -2*dy + 1;
43711517Sralph 			dx++;
43811517Sralph 			if (labs(ep) >= labs(ep+de)) {
43911517Sralph 				ep += de;
44011517Sralph 				break;
44111517Sralph 			}
44211517Sralph 		}
44311517Sralph 	}
44411517Sralph }
44511517Sralph 
44611517Sralph /*
44711517Sralph  * Points should be in the range 0 <= x (or y) <= DevRange.
44811517Sralph  * The origin is the top left-hand corner with increasing x towards the
44911517Sralph  * right and increasing y going down.
45011517Sralph  */
45111516Sralph point(x, y)
45211517Sralph register int x, y;
45311516Sralph {
454*11711Sralph 	register unsigned byte;
45511516Sralph 
456*11711Sralph 	byte = y * DevRange8 + (x >> 3);
457*11711Sralph 	if (byte < bufsize)
458*11711Sralph 		obuf[byte] |= 1 << (7 - (x & 07));
45911516Sralph }
46011516Sralph 
46111517Sralph cleanup()
46211516Sralph {
46311517Sralph 	while (picture[run] != 'a') {
46411517Sralph 		unlink(picture);
46511517Sralph 		picture[run]--;
46611517Sralph 	}
46711516Sralph 	exit(1);
46811516Sralph }
46911516Sralph 
47011517Sralph getinteger(f)
47111517Sralph FILE *f;
47211517Sralph {
47311517Sralph 	register int low, high, result;
47411517Sralph 
47511517Sralph 	low = getc(f);
47611517Sralph 	high = getc(f);
47711517Sralph 	result = ((high << 8) | low);
47811517Sralph 	if (high > 127)
47911517Sralph 		result |= ~0xffff;
48011517Sralph 	return(result);
48111517Sralph }
482