xref: /csrg-svn/old/vplot/vplot.c (revision 14500)
1*14500Ssam #ifndef lint
2*14500Ssam static char sccsid[] = "@(#)vplot.c	4.3 (Berkeley) 08/11/83";
3*14500Ssam #endif
4*14500Ssam 
5*14500Ssam /*
611517Sralph  *  Reads standard graphics input and produces a plot on the
711517Sralph  *  Varian or Versatec
811516Sralph  */
911517Sralph #include <stdio.h>
1011516Sralph #include <signal.h>
1111517Sralph #include <vfont.h>
1211516Sralph 
1311517Sralph #define LPR "/usr/ucb/lpr"
1411517Sralph 
1511517Sralph #define	mapx(x)	((DevRange*((x)-botx)/del)+centx)
1611517Sralph #define	mapy(y)	((DevRange*(del-(y)+boty)/del)-centy)
1711516Sralph #define SOLID -1
1811516Sralph #define DOTTED 014
1911516Sralph #define SHORTDASHED 034
2011516Sralph #define DOTDASHED 054
2111516Sralph #define LONGDASHED 074
2211516Sralph 
23*14500Ssam char *Sid = "@(#)\t08/11/83";
2411517Sralph 
2511516Sralph int	linmod	= SOLID;
2611516Sralph int	done1;
2711516Sralph char	chrtab[][16];
2811711Sralph char	*obuf;
2911711Sralph int	bufsize;
3011516Sralph int	lastx;
3111516Sralph int	lasty;
3211517Sralph int	radius, startx, starty, endx, endy;
3311517Sralph double	topx;
3411517Sralph double	topy;
3511517Sralph double	botx;
3611517Sralph double	boty;
3711517Sralph int	centx = 0;
3811517Sralph int	centy = 0;
3911517Sralph double	delx;
4011517Sralph double	dely;
4111517Sralph double	del;
4211516Sralph 
4311517Sralph int	warned = 0;	/* Indicates whether the warning message about
4411517Sralph 			 * unimplemented routines has been printed */
4511517Sralph 
4611517Sralph FILE	*infile;
4711711Sralph FILE	*pfp;			/* output file */
4811517Sralph char	picture[] = "/usr/tmp/rastAXXXXXX";
4911517Sralph int	run = 13;		/* index of 'a' in picture[] */
5011517Sralph int	DevRange = 1536;	/* output array size (square) in pixels */
5111711Sralph int	DevRange8 = 1536/8;	/* output array size in bytes */
5211517Sralph int	BytesPerLine = 264;	/* Bytes per raster line (physical) */
5311517Sralph int	lparg = 7;		/* index into lpargs */
5411516Sralph 
5511517Sralph char	*lpargs[50] = { "lpr", "-Pvarian", "-v", "-s", "-r", "-J", "vplot" };
5611517Sralph 
5711517Sralph /* variables for used to print from font file */
5811517Sralph int	fontSet = 0;		/* Has the font file been read */
5911517Sralph struct	header header;
6011517Sralph struct	dispatch dispatch[256];
6111517Sralph char	*bits;
6211517Sralph char	*fontFile = "/usr/lib/vfont/R.6";
6311517Sralph 
main(argc,argv)6411516Sralph main(argc, argv)
6511517Sralph int argc;
6611516Sralph char **argv;
6711516Sralph {
6811517Sralph 	extern int cleanup();
6911711Sralph 	register char *cp1, *arg;
7011711Sralph 	register i;
7111517Sralph 	int again;
7211516Sralph 
7311517Sralph 	infile = stdin;
7411517Sralph 	while (argc > 1 && argv[1][0] == '-') {
7511517Sralph 		argc--;
7611517Sralph 		arg = *++argv;
7711517Sralph 		switch (*++arg) {
7811517Sralph 		case 'W':
7911711Sralph 			DevRange = 2048;
8011711Sralph 			DevRange8 = 2048/8;
8111517Sralph 			BytesPerLine = 880;
8211517Sralph 			lpargs[1] = "-Pversatec";
8311517Sralph 			break;
8411517Sralph 		case 'V':
8511517Sralph 			DevRange = 1536;
8611711Sralph 			DevRange8 = 1536/8;
8711517Sralph 			BytesPerLine = 264;
8811517Sralph 			lpargs[1] = "-Pvarian";
8911517Sralph 			break;
9011517Sralph 		case 'b':
9111517Sralph 			if (argc-- > 1)
9211517Sralph 				lpargs[lparg-1] = *++argv;
9311517Sralph 			break;
9411517Sralph 		default:
9511517Sralph 			fprintf(stderr, "vplot: %s option unknown\n", *argv);
9611517Sralph 			break;
9711517Sralph 		}
9811516Sralph 	}
9911517Sralph 	if (argc > 1) {
10011517Sralph 		if ((infile = fopen(*++argv, "r")) == NULL) {
10111517Sralph 			perror(*argv);
10211517Sralph 			cleanup();
10311517Sralph 		}
10411517Sralph 	}
10511517Sralph 
10611517Sralph 	/* init constants for scaling */
10711517Sralph 	topx = topy = DevRange;
10811517Sralph 	botx = boty = 0;
10911517Sralph 	delx = dely = del = DevRange;
11011517Sralph 	centx = (DevRange - mapx(topx))/2;
11111517Sralph 	centy = mapy(topy)/2;
11211517Sralph 	signal(SIGTERM, cleanup);
11311516Sralph 	if (signal(SIGINT, SIG_IGN) != SIG_IGN)
11411517Sralph 		signal(SIGINT, cleanup);
11511517Sralph 	mktemp(picture);
11611711Sralph 	if ((obuf = (char *) malloc(bufsize = DevRange * DevRange8)) == NULL) {
11711711Sralph 		fprintf(stderr, "vplot: ran out of memory\n");
11811711Sralph 		cleanup();
11911711Sralph 	}
12011517Sralph 	do {
12111711Sralph 		if ((pfp = fopen(picture, "w")) == NULL) {
12211711Sralph 			fprintf(stderr, "vplot: can't create %s\n", picture);
12311517Sralph 			cleanup();
12411516Sralph 		}
12511517Sralph 		i = strlen(picture) + 1;
12611711Sralph 		if ((arg = (char *) malloc(i)) == NULL) {
12711517Sralph 			fprintf(stderr, "ran out of memory\n");
12811517Sralph 			cleanup();
12911517Sralph 		}
13011517Sralph 		strcpy(arg, picture);
13111517Sralph 		lpargs[lparg++] = arg;
13211517Sralph 		picture[run]++;
13311711Sralph 		arg = &obuf[bufsize];
13411711Sralph 		for (cp1 = obuf; cp1 < arg; )
13511711Sralph 			*cp1++ = 0;
13611517Sralph 
13711517Sralph 		again = getpict();
13811517Sralph 
13911711Sralph 		for (cp1 = obuf; cp1 < arg; cp1 += DevRange8) {
14011711Sralph 			fwrite(cp1, sizeof(char), DevRange8, pfp);
14111711Sralph 			fseek(pfp, (long) BytesPerLine - DevRange8, 1);
14211517Sralph 		}
14311711Sralph 		fclose(pfp);
14411517Sralph 	} while (again);
14511517Sralph 	lpargs[lparg] = 0;
14611517Sralph 	execv(LPR, lpargs);
14711517Sralph 	fprintf(stderr, "can't exec %s\n", LPR);
14811517Sralph 	cleanup();
14911516Sralph }
15011516Sralph 
getpict()15111516Sralph getpict()
15211516Sralph {
15311516Sralph 	register x1, y1;
15411516Sralph 
15511517Sralph 	for (;;) switch (x1 = getc(infile)) {
15611516Sralph 
15711517Sralph 	case '\n':
15811517Sralph 		continue;
15911517Sralph 
16011516Sralph 	case 's':
16111517Sralph 		botx = getinteger(infile);
16211517Sralph 		boty = getinteger(infile);
16311517Sralph 		topx = getinteger(infile);
16411517Sralph 		topy = getinteger(infile);
16511516Sralph 		delx = topx-botx;
16611516Sralph 		dely = topy-boty;
16711516Sralph 		if (dely/delx > 1536./2048.)
16811516Sralph 			del = dely;
16911516Sralph 		else
17011517Sralph 			del = delx;
17111516Sralph 		centx = 0;
17211517Sralph 		centx = (DevRange - mapx(topx))/2;
17311516Sralph 		centy = 0;
17411516Sralph 		centy = mapy(topy) / 2;
17511516Sralph 		continue;
17611516Sralph 
17711517Sralph 	case 'b':
17811517Sralph 		x1 = getc(infile);
17911517Sralph 		continue;
18011517Sralph 
18111516Sralph 	case 'l':
18211516Sralph 		done1 |= 01;
18311517Sralph 		x1 = mapx(getinteger(infile));
18411517Sralph 		y1 = mapy(getinteger(infile));
18511517Sralph 		lastx = mapx(getinteger(infile));
18611517Sralph 		lasty = mapy(getinteger(infile));
18711516Sralph 		line(x1, y1, lastx, lasty);
18811516Sralph 		continue;
18911516Sralph 
19011517Sralph 	case 'c':
19111517Sralph 		x1 = mapx(getinteger(infile));
19211517Sralph 		y1 = mapy(getinteger(infile));
19311517Sralph 		radius = mapx(getinteger(infile));
19411517Sralph 		if (!warned) {
19511517Sralph 			fprintf(stderr,"Circles are Implemented\n");
19611517Sralph 			warned++;
19711517Sralph 		}
19811517Sralph 		circle(x1, y1, radius);
19911517Sralph 		continue;
20011517Sralph 
20111517Sralph 	case 'a':
20211517Sralph 		x1 = mapx(getinteger(infile));
20311517Sralph 		y1 = mapy(getinteger(infile));
20411517Sralph 		startx = mapx(getinteger(infile));
20511517Sralph 		starty = mapy(getinteger(infile));
20611517Sralph 		endx = mapx(getinteger(infile));
20711517Sralph 		endy = mapy(getinteger(infile));
20811517Sralph 		if (!warned) {
20911517Sralph 			fprintf(stderr,"Circles and Arcs are unimplemented\n");
21011517Sralph 			warned++;
21111517Sralph 		}
21211517Sralph 		continue;
21311517Sralph 
21411516Sralph 	case 'm':
21511517Sralph 		lastx = mapx(getinteger(infile));
21611517Sralph 		lasty = mapy(getinteger(infile));
21711516Sralph 		continue;
21811516Sralph 
21911516Sralph 	case 't':
22011517Sralph 		lastx = lastx - 6;
22111517Sralph 		lasty = lasty + 6;
22211516Sralph 		done1 |= 01;
22311517Sralph 		while ((x1 = getc(infile)) != '\n')
22411516Sralph 			plotch(x1);
22511516Sralph 		continue;
22611516Sralph 
22711516Sralph 	case 'e':
22811517Sralph 		if (done1)
22911517Sralph 			return(1);
23011516Sralph 		continue;
23111516Sralph 
23211516Sralph 	case 'p':
23311516Sralph 		done1 |= 01;
23411517Sralph 		lastx = mapx(getinteger(infile));
23511517Sralph 		lasty = mapy(getinteger(infile));
23611516Sralph 		point(lastx, lasty);
23711516Sralph 		point(lastx+1, lasty);
23811516Sralph 		point(lastx, lasty+1);
23911516Sralph 		point(lastx+1, lasty+1);
24011516Sralph 		continue;
24111516Sralph 
24211516Sralph 	case 'n':
24311516Sralph 		done1 |= 01;
24411517Sralph 		x1 = mapx(getinteger(infile));
24511517Sralph 		y1 = mapy(getinteger(infile));
24611516Sralph 		line(lastx, lasty, x1, y1);
24711516Sralph 		lastx = x1;
24811516Sralph 		lasty = y1;
24911516Sralph 		continue;
25011516Sralph 
25111516Sralph 	case 'f':
25211517Sralph 		getinteger(infile);
25311517Sralph 		getc(infile);
25411517Sralph 		switch (getc(infile)) {
25511516Sralph 		case 't':
25611516Sralph 			linmod = DOTTED;
25711516Sralph 			break;
25811516Sralph 		default:
25911516Sralph 		case 'i':
26011516Sralph 			linmod = SOLID;
26111516Sralph 			break;
26211516Sralph 		case 'g':
26311516Sralph 			linmod = LONGDASHED;
26411516Sralph 			break;
26511516Sralph 		case 'r':
26611516Sralph 			linmod = SHORTDASHED;
26711516Sralph 			break;
26811516Sralph 		case 'd':
26911516Sralph 			linmod = DOTDASHED;
27011516Sralph 			break;
27111516Sralph 		}
27211517Sralph 		while ((x1 = getc(infile)) != '\n')
27311517Sralph 			if (x1 == EOF)
27411517Sralph 				return(0);
27511516Sralph 		continue;
27611516Sralph 
27711516Sralph 	case 'd':
27811517Sralph 		getinteger(infile);
27911517Sralph 		getinteger(infile);
28011517Sralph 		getinteger(infile);
28111517Sralph 		x1 = getinteger(infile);
28211516Sralph 		while (--x1 >= 0)
28311517Sralph 			getinteger(infile);
28411516Sralph 		continue;
28511516Sralph 
28611517Sralph 	case 0:		/* ignore null characters */
28711517Sralph 		continue;
28811516Sralph 
28911517Sralph 	case 255:
29011517Sralph 	case EOF:
29111517Sralph 		return(0);
29211517Sralph 
29311516Sralph 	default:
29411517Sralph 		fprintf(stderr, "Input format error %c(%o)\n",x1,x1);
29511517Sralph 		cleanup();
29611516Sralph 	}
29711516Sralph }
29811516Sralph 
plotch(ch)29911517Sralph plotch(ch)
30011517Sralph char ch;
30111516Sralph {
30211517Sralph 	register int i,j,k;
30311517Sralph 	register char *ptr,c;
30411517Sralph 	int nbytes;
30511516Sralph 
30611517Sralph 	if (!fontSet)
30711517Sralph 		InitFont();	/* Read font if not already read */
30811517Sralph 
30911517Sralph 	ptr = bits + dispatch[ch].addr;
31011517Sralph 
31111517Sralph 	for (i = dispatch[ch].up; i > -dispatch[ch].down; --i) {
31211517Sralph 		nbytes = (dispatch[ch].right + dispatch[ch].left + 7)/8;
31311517Sralph 		for (j = 0; j < nbytes; j++) {
31411517Sralph 			c = *ptr++;
31511517Sralph 			for (k = 7; k >= 0; k--)
31611517Sralph 				if ((c >> k) & 1)
31711517Sralph 					point(lastx+7-k+j*8-dispatch[ch].left, lasty-i);
31811517Sralph 		}
31911516Sralph 	}
32011517Sralph 	if (ch != ' ')
32111517Sralph 		lastx += dispatch[ch].width;
32211517Sralph 	else
32311517Sralph 		lastx += dispatch['a'].width;
32411516Sralph }
32511516Sralph 
InitFont()32611517Sralph InitFont()
32711516Sralph {
32811517Sralph 	char *s;
32911517Sralph 	int fonts;
33011517Sralph 	int i;
33111516Sralph 
33211517Sralph 	fontSet = 1;
33311517Sralph 	/* Get the font file */
33411517Sralph 	s = fontFile;
33511517Sralph 	if ((fonts = open(s, 0)) == -1) {
33611517Sralph 		perror(s);
33711517Sralph 		fprintf(stderr, "Can't get font file");
33811517Sralph 		cleanup();
33911516Sralph 	}
34011517Sralph 	/* Get the header and check magic number */
34111517Sralph 	if (read(fonts, &header, sizeof(header)) != sizeof(header)) {
34211517Sralph 		perror(s);
34311517Sralph 		fprintf(stderr, "Bad read in font file");
34411517Sralph 		cleanup();
34511516Sralph 	}
34611517Sralph 	if (header.magic != 0436) {
34711517Sralph 		fprintf(stderr,"Bad magic numer in font file");
34811517Sralph 		cleanup();
34911517Sralph 	}
35011517Sralph 	/* Get dispatches */
35111517Sralph 	if (read(fonts, dispatch, sizeof(dispatch)) != sizeof(dispatch)) {
35211517Sralph 		perror(s);
35311517Sralph 		fprintf(stderr, "Bad read in font file");
35411517Sralph 		cleanup();
35511517Sralph 	}
35611517Sralph 	/* Allocate space for bit map and read in bits */
35711517Sralph 	bits = (char *) malloc(header.size);
35811517Sralph 	if (read(fonts, bits, header.size) != header.size) {
35911517Sralph 		perror(s);
36011517Sralph 		fprintf(stderr,"Can't read bit map in font file");
36111517Sralph 		cleanup();
36211517Sralph 	}
36311517Sralph 	/* Close font file */
36411517Sralph 	if (close(fonts) != 0) {
36511517Sralph 		perror(s);
36611517Sralph 		fprintf(stderr,"Can't close font file");
36711517Sralph 		cleanup();
36811517Sralph 	}
36911516Sralph }
37011516Sralph 
line(x0,y0,x1,y1)37111516Sralph line(x0, y0, x1, y1)
37211516Sralph register x0, y0;
37311516Sralph {
37411516Sralph 	int dx, dy;
37511516Sralph 	int xinc, yinc;
37611516Sralph 	register res1;
37711516Sralph 	int res2;
37811516Sralph 	int slope;
37911516Sralph 
38011516Sralph 	xinc = 1;
38111516Sralph 	yinc = 1;
38211516Sralph 	if ((dx = x1-x0) < 0) {
38311516Sralph 		xinc = -1;
38411516Sralph 		dx = -dx;
38511516Sralph 	}
38611516Sralph 	if ((dy = y1-y0) < 0) {
38711516Sralph 		yinc = -1;
38811516Sralph 		dy = -dy;
38911516Sralph 	}
39011516Sralph 	slope = xinc*yinc;
39111516Sralph 	res1 = 0;
39211516Sralph 	res2 = 0;
39311516Sralph 	if (dx >= dy) while (x0 != x1) {
39411517Sralph 		if ((x0+slope*y0) & linmod)
39511517Sralph 			point(x0, y0);
39611516Sralph 		if (res1 > res2) {
39711516Sralph 			res2 += dx - res1;
39811516Sralph 			res1 = 0;
39911516Sralph 			y0 += yinc;
40011516Sralph 		}
40111516Sralph 		res1 += dy;
40211516Sralph 		x0 += xinc;
40311516Sralph 	} else while (y0 != y1) {
40411517Sralph 		if ((x0+slope*y0) & linmod)
40511516Sralph 		point(x0, y0);
40611516Sralph 		if (res1 > res2) {
40711516Sralph 			res2 += dy - res1;
40811516Sralph 			res1 = 0;
40911516Sralph 			x0 += xinc;
41011516Sralph 		}
41111516Sralph 		res1 += dx;
41211516Sralph 		y0 += yinc;
41311516Sralph 	}
41411517Sralph 	if ((x1+slope*y1) & linmod)
41511516Sralph 		point(x1, y1);
41611516Sralph }
41711516Sralph 
41811517Sralph #define labs(a) (a >= 0 ? a : -a)
41911517Sralph 
circle(x,y,c)42011517Sralph circle(x,y,c)
42111517Sralph {
42211517Sralph 	register dx, dy;
42311517Sralph 	long ep;
42411517Sralph 	int de;
42511517Sralph 
42611517Sralph 	dx = 0;
42711517Sralph 	ep = 0;
42811517Sralph 	for (dy=c; dy>=dx; dy--) {
42911517Sralph 		for (;;) {
43011517Sralph 			point(x+dx, y+dy);
43111517Sralph 			point(x-dx, y+dy);
43211517Sralph 			point(x+dx, y-dy);
43311517Sralph 			point(x-dx, y-dy);
43411517Sralph 			point(x+dy, y+dx);
43511517Sralph 			point(x-dy, y+dx);
43611517Sralph 			point(x+dy, y-dx);
43711517Sralph 			point(x-dy, y-dx);
43811517Sralph 			ep += 2*dx + 1;
43911517Sralph 			de = -2*dy + 1;
44011517Sralph 			dx++;
44111517Sralph 			if (labs(ep) >= labs(ep+de)) {
44211517Sralph 				ep += de;
44311517Sralph 				break;
44411517Sralph 			}
44511517Sralph 		}
44611517Sralph 	}
44711517Sralph }
44811517Sralph 
44911517Sralph /*
45011517Sralph  * Points should be in the range 0 <= x (or y) <= DevRange.
45111517Sralph  * The origin is the top left-hand corner with increasing x towards the
45211517Sralph  * right and increasing y going down.
45311517Sralph  */
point(x,y)45411516Sralph point(x, y)
45511517Sralph register int x, y;
45611516Sralph {
45711711Sralph 	register unsigned byte;
45811516Sralph 
45911711Sralph 	byte = y * DevRange8 + (x >> 3);
46011711Sralph 	if (byte < bufsize)
46111711Sralph 		obuf[byte] |= 1 << (7 - (x & 07));
46211516Sralph }
46311516Sralph 
cleanup()46411517Sralph cleanup()
46511516Sralph {
46611517Sralph 	while (picture[run] != 'a') {
46711517Sralph 		unlink(picture);
46811517Sralph 		picture[run]--;
46911517Sralph 	}
47011516Sralph 	exit(1);
47111516Sralph }
47211516Sralph 
getinteger(f)47311517Sralph getinteger(f)
47411517Sralph FILE *f;
47511517Sralph {
47611517Sralph 	register int low, high, result;
47711517Sralph 
47811517Sralph 	low = getc(f);
47911517Sralph 	high = getc(f);
48011517Sralph 	result = ((high << 8) | low);
48111517Sralph 	if (high > 127)
48211517Sralph 		result |= ~0xffff;
48311517Sralph 	return(result);
48411517Sralph }
485