xref: /csrg-svn/old/vfilters/vplotf/vplotf.c (revision 42811)
120203Sdist /*
220203Sdist  * Copyright (c) 1983 Regents of the University of California.
333682Sbostic  * All rights reserved.
433682Sbostic  *
5*42811Sbostic  * %sccs.include.redist.c%
620203Sdist  */
720203Sdist 
813948Ssam #ifndef lint
933682Sbostic char copyright[] =
1033682Sbostic "@(#) Copyright (c) 1983 Regents of the University of California.\n\
1133682Sbostic  All rights reserved.\n";
1233682Sbostic #endif /* not lint */
1313948Ssam 
1433682Sbostic #ifndef lint
15*42811Sbostic static char sccsid[] = "@(#)vplotf.c	5.5 (Berkeley) 06/01/90";
1633682Sbostic #endif /* not lint */
1733682Sbostic 
1812203Sralph /*
1912203Sralph  *  Lpd filter to read standard graphics input and produce a plot on the
2012203Sralph  *  Varian or Versatec
2112203Sralph  */
2212203Sralph 
2312203Sralph #include <stdio.h>
2412203Sralph #include <vfont.h>
2512203Sralph #include <sys/vcmd.h>
2612203Sralph 
2712203Sralph #define	mapx(x)	((DevRange*((x)-botx)/del)+centx)
2812203Sralph #define	mapy(y)	((DevRange*(del-(y)+boty)/del)-centy)
2912203Sralph #define SOLID -1
3012203Sralph #define DOTTED 014
3112203Sralph #define SHORTDASHED 034
3212203Sralph #define DOTDASHED 054
3312203Sralph #define LONGDASHED 074
3412203Sralph 
3512693Sralph static char *Sid = "@(#)\t5/16/83";
3612203Sralph 
3712203Sralph int	linmod = SOLID;
3812203Sralph int	done1;
3912203Sralph char	chrtab[][16];
4012203Sralph char	*obuf;
4112203Sralph int	bufsize;
4212203Sralph int	lastx;
4312203Sralph int	lasty;
4412203Sralph int	radius, startx, starty, endx, endy;
4512203Sralph double	topx;
4612203Sralph double	topy;
4712203Sralph double	botx;
4812203Sralph double	boty;
4912203Sralph int	centx = 0;
5012203Sralph int	centy = 0;
5112203Sralph double	delx;
5212203Sralph double	dely;
5312203Sralph double	del;
5412203Sralph 
5512203Sralph int	warned = 0;	/* Indicates whether the warning message about
5612203Sralph 			 * unimplemented routines has been printed */
5712203Sralph 
5812203Sralph int	plotmd[] = {VPLOT};
5912203Sralph int	prtmd[]  = {VPRINT};
6012693Sralph int	varian;			/* 0 for versatec, 1 for varian. */
6112693Sralph int	BYTES_PER_LINE;		/* number of bytes per raster line. */
6212693Sralph int	PAGE_LINES;		/* number of raster lines per page. */
6312203Sralph int	DevRange = 1536;	/* output array size (square) in pixels */
6412203Sralph int	DevRange8 = 1536/8;	/* output array size in bytes */
6512203Sralph int	lines;			/* number of raster lines printed */
6612203Sralph char	zeros[880];		/* one raster line */
6712203Sralph 
6812203Sralph char	*name, *host, *acctfile;
6912203Sralph 
7012693Sralph /* variables used to print from font file */
7112203Sralph int	fontSet = 0;		/* Has the font file been read */
7212203Sralph struct	header header;
7312203Sralph struct	dispatch dispatch[256];
7412203Sralph char	*bits;
7512693Sralph char	*fontFile = "/usr/lib/vfont/R.8";
7612203Sralph 
main(argc,argv)7712203Sralph main(argc, argv)
7812203Sralph 	int argc;
7912203Sralph 	char *argv[];
8012203Sralph {
8112203Sralph 	register char *cp, *arg;
8212203Sralph 	register n, again;
8312203Sralph 
8412203Sralph 	while (--argc) {
8512203Sralph 		if (**++argv == '-') {
8612203Sralph 			switch (argv[0][1]) {
8712693Sralph 			case 'x':
8812693Sralph 				BYTES_PER_LINE = atoi(&argv[0][2]) / 8;
8912693Sralph 				if (varian = BYTES_PER_LINE == 264) {
9012693Sralph 					DevRange = 1536;
9112693Sralph 					DevRange8 = 1536/8;
9212693Sralph 				} else {
9312693Sralph 					DevRange = 2048;
9412693Sralph 					DevRange8 = 2048/8;
9512693Sralph 				}
9612693Sralph 				break;
9712693Sralph 
9812693Sralph 			case 'y':
9912693Sralph 				PAGE_LINES = atoi(&argv[0][2]);
10012693Sralph 				break;
10112693Sralph 
10212203Sralph 			case 'n':
10312203Sralph 				argc--;
10412203Sralph 				name = *++argv;
10512203Sralph 				break;
10612203Sralph 
10712203Sralph 			case 'h':
10812203Sralph 				argc--;
10912203Sralph 				host = *++argv;
11012203Sralph 			}
11112203Sralph 		} else
11212203Sralph 			acctfile = *argv;
11312203Sralph 	}
11412203Sralph 
11512203Sralph 	/* init constants for scaling */
11612203Sralph 	topx = topy = DevRange;
11712203Sralph 	botx = boty = 0;
11812203Sralph 	delx = dely = del = DevRange;
11912203Sralph 	centx = (DevRange - mapx(topx))/2;
12012203Sralph 	centy = mapy(topy)/2;
12112203Sralph 
12212203Sralph 	if ((obuf = (char *) malloc(bufsize = DevRange * DevRange8)) == NULL) {
12312203Sralph 		fprintf(stderr, "vplotf: ran out of memory\n");
12412203Sralph 		exit(2);
12512203Sralph 	}
12612203Sralph 
12712203Sralph 	do {
12812203Sralph 		arg = &obuf[bufsize];
12912203Sralph 		for (cp = obuf; cp < arg; )
13012203Sralph 			*cp++ = 0;
13112203Sralph 
13212203Sralph 		again = getpict();
13312203Sralph 
13412203Sralph 		ioctl(1, VSETSTATE, plotmd);
13512693Sralph 		n = BYTES_PER_LINE - DevRange8;
13612203Sralph 		for (cp = obuf; cp < arg; cp += DevRange8) {
13712203Sralph 			if (write(1, cp, DevRange8) != DevRange8)
13812203Sralph 				exit(1);
13912203Sralph 			if (n && write(1, zeros, n) != n)
14012203Sralph 				exit(1);
14112203Sralph 			lines++;
14212203Sralph 		}
14312203Sralph 		ioctl(1, VSETSTATE, prtmd);
14412203Sralph 		if (varian)
14512203Sralph 			write(1, "\f", 2);
14612203Sralph 		else
14712203Sralph 			write(1, "\n\n\n\n\n", 6);
14812203Sralph 	} while (again);
14912203Sralph 
15012203Sralph 	account(name, host, *argv);
15112203Sralph 	exit(0);
15212203Sralph }
15312203Sralph 
account(who,from,acctfile)15412203Sralph account(who, from, acctfile)
15512203Sralph 	char *who, *from, *acctfile;
15612203Sralph {
15712203Sralph 	register FILE *a;
15812203Sralph 
15912203Sralph 	if (who == NULL || acctfile == NULL)
16012203Sralph 		return;
16112203Sralph 	if (access(acctfile, 02) || (a = fopen(acctfile, "a")) == NULL)
16212203Sralph 		return;
16312203Sralph 	/*
16412203Sralph 	 * Varian accounting is done by 8.5 inch pages;
16512203Sralph 	 * Versatec accounting is by the (12 inch) foot.
16612203Sralph 	 */
16716168Sralph 	fprintf(a, "t%6.2f\t", (double)lines / (double)PAGE_LINES);
16812203Sralph 	if (from != NULL)
16912203Sralph 		fprintf(a, "%s:", from);
17012203Sralph 	fprintf(a, "%s\n", who);
17112203Sralph 	fclose(a);
17212203Sralph }
17312203Sralph 
getpict()17412203Sralph getpict()
17512203Sralph {
17612203Sralph 	register x1, y1;
17712203Sralph 
17812203Sralph 	for (;;) switch (x1 = getc(stdin)) {
17912203Sralph 
18012203Sralph 	case '\n':
18112203Sralph 		continue;
18212203Sralph 
18312203Sralph 	case 's':
18412203Sralph 		botx = getinteger(stdin);
18512203Sralph 		boty = getinteger(stdin);
18612203Sralph 		topx = getinteger(stdin);
18712203Sralph 		topy = getinteger(stdin);
18812203Sralph 		delx = topx-botx;
18912203Sralph 		dely = topy-boty;
19012203Sralph 		if (dely/delx > 1536./2048.)
19112203Sralph 			del = dely;
19212203Sralph 		else
19312203Sralph 			del = delx;
19412203Sralph 		centx = 0;
19512203Sralph 		centx = (DevRange - mapx(topx))/2;
19612203Sralph 		centy = 0;
19712203Sralph 		centy = mapy(topy) / 2;
19812203Sralph 		continue;
19912203Sralph 
20012203Sralph 	case 'b':
20112203Sralph 		x1 = getc(stdin);
20212203Sralph 		continue;
20312203Sralph 
20412203Sralph 	case 'l':
20512203Sralph 		done1 |= 01;
20612203Sralph 		x1 = mapx(getinteger(stdin));
20712203Sralph 		y1 = mapy(getinteger(stdin));
20812203Sralph 		lastx = mapx(getinteger(stdin));
20912203Sralph 		lasty = mapy(getinteger(stdin));
21012203Sralph 		line(x1, y1, lastx, lasty);
21112203Sralph 		continue;
21212203Sralph 
21312203Sralph 	case 'c':
21412203Sralph 		x1 = mapx(getinteger(stdin));
21512203Sralph 		y1 = mapy(getinteger(stdin));
21612203Sralph 		radius = mapx(getinteger(stdin));
21712203Sralph 		circle(x1, y1, radius);
21812203Sralph 		continue;
21912203Sralph 
22012203Sralph 	case 'a':
22112203Sralph 		x1 = mapx(getinteger(stdin));
22212203Sralph 		y1 = mapy(getinteger(stdin));
22312203Sralph 		startx = mapx(getinteger(stdin));
22412203Sralph 		starty = mapy(getinteger(stdin));
22512203Sralph 		endx = mapx(getinteger(stdin));
22612203Sralph 		endy = mapy(getinteger(stdin));
22712203Sralph 		if (!warned) {
22812203Sralph 			fprintf(stderr,"Arcs are unimplemented\n");
22912203Sralph 			warned++;
23012203Sralph 		}
23112203Sralph 		continue;
23212203Sralph 
23312203Sralph 	case 'm':
23412203Sralph 		lastx = mapx(getinteger(stdin));
23512203Sralph 		lasty = mapy(getinteger(stdin));
23612203Sralph 		continue;
23712203Sralph 
23812203Sralph 	case 't':
23912203Sralph 		lastx = lastx - 6;
24012203Sralph 		lasty = lasty + 6;
24112203Sralph 		done1 |= 01;
24212203Sralph 		while ((x1 = getc(stdin)) != '\n')
24312203Sralph 			plotch(x1);
24412203Sralph 		continue;
24512203Sralph 
24612203Sralph 	case 'e':
24712203Sralph 		if (done1)
24812203Sralph 			return(1);
24912203Sralph 		continue;
25012203Sralph 
25112203Sralph 	case 'p':
25212203Sralph 		done1 |= 01;
25312203Sralph 		lastx = mapx(getinteger(stdin));
25412203Sralph 		lasty = mapy(getinteger(stdin));
25512203Sralph 		point(lastx, lasty);
25612203Sralph 		point(lastx+1, lasty);
25712203Sralph 		point(lastx, lasty+1);
25812203Sralph 		point(lastx+1, lasty+1);
25912203Sralph 		continue;
26012203Sralph 
26112203Sralph 	case 'n':
26212203Sralph 		done1 |= 01;
26312203Sralph 		x1 = mapx(getinteger(stdin));
26412203Sralph 		y1 = mapy(getinteger(stdin));
26512203Sralph 		line(lastx, lasty, x1, y1);
26612203Sralph 		lastx = x1;
26712203Sralph 		lasty = y1;
26812203Sralph 		continue;
26912203Sralph 
27012203Sralph 	case 'f':
27112203Sralph 		getinteger(stdin);
27212203Sralph 		getc(stdin);
27312203Sralph 		switch (getc(stdin)) {
27412203Sralph 		case 't':
27512203Sralph 			linmod = DOTTED;
27612203Sralph 			break;
27712203Sralph 		default:
27812203Sralph 		case 'i':
27912203Sralph 			linmod = SOLID;
28012203Sralph 			break;
28112203Sralph 		case 'g':
28212203Sralph 			linmod = LONGDASHED;
28312203Sralph 			break;
28412203Sralph 		case 'r':
28512203Sralph 			linmod = SHORTDASHED;
28612203Sralph 			break;
28712203Sralph 		case 'd':
28812203Sralph 			linmod = DOTDASHED;
28912203Sralph 			break;
29012203Sralph 		}
29112203Sralph 		while ((x1 = getc(stdin)) != '\n')
29212203Sralph 			if (x1 == EOF)
29312203Sralph 				return(0);
29412203Sralph 		continue;
29512203Sralph 
29612203Sralph 	case 'd':
29712203Sralph 		getinteger(stdin);
29812203Sralph 		getinteger(stdin);
29912203Sralph 		getinteger(stdin);
30012203Sralph 		x1 = getinteger(stdin);
30112203Sralph 		while (--x1 >= 0)
30212203Sralph 			getinteger(stdin);
30312203Sralph 		continue;
30412203Sralph 
30512203Sralph 	case 0:		/* ignore null characters */
30612203Sralph 		continue;
30712203Sralph 
30812203Sralph 	case 255:
30912203Sralph 	case EOF:
31012203Sralph 		return(0);
31112203Sralph 
31212203Sralph 	default:
31312203Sralph 		fprintf(stderr, "Input format error %c(%o)\n",x1,x1);
31412203Sralph 		exit(2);
31512203Sralph 	}
31612203Sralph }
31712203Sralph 
plotch(ch)31812203Sralph plotch(ch)
31912203Sralph char ch;
32012203Sralph {
32112203Sralph 	register int i,j,k;
32212203Sralph 	register char *ptr,c;
32312203Sralph 	int nbytes;
32412203Sralph 
32512203Sralph 	if (!fontSet)
32612203Sralph 		InitFont();	/* Read font if not already read */
32712203Sralph 
32812203Sralph 	ptr = bits + dispatch[ch].addr;
32912203Sralph 
33012203Sralph 	for (i = dispatch[ch].up; i > -dispatch[ch].down; --i) {
33112203Sralph 		nbytes = (dispatch[ch].right + dispatch[ch].left + 7)/8;
33212203Sralph 		for (j = 0; j < nbytes; j++) {
33312203Sralph 			c = *ptr++;
33412203Sralph 			for (k = 7; k >= 0; k--)
33512203Sralph 				if ((c >> k) & 1)
33612203Sralph 					point(lastx+7-k+j*8-dispatch[ch].left, lasty-i);
33712203Sralph 		}
33812203Sralph 	}
33912203Sralph 	if (ch != ' ')
34012203Sralph 		lastx += dispatch[ch].width;
34112203Sralph 	else
34212203Sralph 		lastx += dispatch['a'].width;
34312203Sralph }
34412203Sralph 
InitFont()34512203Sralph InitFont()
34612203Sralph {
34712203Sralph 	char *s;
34812203Sralph 	int fonts;
34912203Sralph 	int i;
35012203Sralph 
35112203Sralph 	fontSet = 1;
35212203Sralph 	/* Get the font file */
35312203Sralph 	s = fontFile;
35412203Sralph 	if ((fonts = open(s, 0)) == -1) {
35512203Sralph 		perror(s);
35612203Sralph 		fprintf(stderr, "Can't get font file");
35712203Sralph 		exit(2);
35812203Sralph 	}
35912203Sralph 	/* Get the header and check magic number */
36012203Sralph 	if (read(fonts, &header, sizeof(header)) != sizeof(header)) {
36112203Sralph 		perror(s);
36212203Sralph 		fprintf(stderr, "Bad read in font file");
36312203Sralph 		exit(2);
36412203Sralph 	}
36512203Sralph 	if (header.magic != 0436) {
36612203Sralph 		fprintf(stderr,"Bad magic numer in font file");
36712203Sralph 		exit(2);
36812203Sralph 	}
36912203Sralph 	/* Get dispatches */
37012203Sralph 	if (read(fonts, dispatch, sizeof(dispatch)) != sizeof(dispatch)) {
37112203Sralph 		perror(s);
37212203Sralph 		fprintf(stderr, "Bad read in font file");
37312203Sralph 		exit(2);
37412203Sralph 	}
37512203Sralph 	/* Allocate space for bit map and read in bits */
37612203Sralph 	bits = (char *) malloc(header.size);
37712203Sralph 	if (read(fonts, bits, header.size) != header.size) {
37812203Sralph 		perror(s);
37912203Sralph 		fprintf(stderr,"Can't read bit map in font file");
38012203Sralph 		exit(2);
38112203Sralph 	}
38212203Sralph 	/* Close font file */
38312203Sralph 	if (close(fonts) != 0) {
38412203Sralph 		perror(s);
38512203Sralph 		fprintf(stderr,"Can't close font file");
38612203Sralph 		exit(2);
38712203Sralph 	}
38812203Sralph }
38912203Sralph 
line(x0,y0,x1,y1)39012203Sralph line(x0, y0, x1, y1)
39112203Sralph register x0, y0;
39212203Sralph {
39312203Sralph 	int dx, dy;
39412203Sralph 	int xinc, yinc;
39512203Sralph 	register res1;
39612203Sralph 	int res2;
39712203Sralph 	int slope;
39812203Sralph 
39912203Sralph 	xinc = 1;
40012203Sralph 	yinc = 1;
40112203Sralph 	if ((dx = x1-x0) < 0) {
40212203Sralph 		xinc = -1;
40312203Sralph 		dx = -dx;
40412203Sralph 	}
40512203Sralph 	if ((dy = y1-y0) < 0) {
40612203Sralph 		yinc = -1;
40712203Sralph 		dy = -dy;
40812203Sralph 	}
40912203Sralph 	slope = xinc*yinc;
41012203Sralph 	res1 = 0;
41112203Sralph 	res2 = 0;
41212203Sralph 	if (dx >= dy) while (x0 != x1) {
41312203Sralph 		if ((x0+slope*y0) & linmod)
41412203Sralph 			point(x0, y0);
41512203Sralph 		if (res1 > res2) {
41612203Sralph 			res2 += dx - res1;
41712203Sralph 			res1 = 0;
41812203Sralph 			y0 += yinc;
41912203Sralph 		}
42012203Sralph 		res1 += dy;
42112203Sralph 		x0 += xinc;
42212203Sralph 	} else while (y0 != y1) {
42312203Sralph 		if ((x0+slope*y0) & linmod)
42412203Sralph 		point(x0, y0);
42512203Sralph 		if (res1 > res2) {
42612203Sralph 			res2 += dy - res1;
42712203Sralph 			res1 = 0;
42812203Sralph 			x0 += xinc;
42912203Sralph 		}
43012203Sralph 		res1 += dx;
43112203Sralph 		y0 += yinc;
43212203Sralph 	}
43312203Sralph 	if ((x1+slope*y1) & linmod)
43412203Sralph 		point(x1, y1);
43512203Sralph }
43612203Sralph 
43725470Smckusick #define labs(a) ((a) >= 0 ? (a) : -(a))
43812203Sralph 
circle(x,y,c)43912203Sralph circle(x,y,c)
44012203Sralph {
44112203Sralph 	register dx, dy;
44212203Sralph 	long ep;
44312203Sralph 	int de;
44412203Sralph 
44512203Sralph 	dx = 0;
44612203Sralph 	ep = 0;
44712203Sralph 	for (dy=c; dy>=dx; dy--) {
44812203Sralph 		for (;;) {
44912203Sralph 			point(x+dx, y+dy);
45012203Sralph 			point(x-dx, y+dy);
45112203Sralph 			point(x+dx, y-dy);
45212203Sralph 			point(x-dx, y-dy);
45312203Sralph 			point(x+dy, y+dx);
45412203Sralph 			point(x-dy, y+dx);
45512203Sralph 			point(x+dy, y-dx);
45612203Sralph 			point(x-dy, y-dx);
45712203Sralph 			ep += 2*dx + 1;
45812203Sralph 			de = -2*dy + 1;
45912203Sralph 			dx++;
46012203Sralph 			if (labs(ep) >= labs(ep+de)) {
46112203Sralph 				ep += de;
46212203Sralph 				break;
46312203Sralph 			}
46412203Sralph 		}
46512203Sralph 	}
46612203Sralph }
46712203Sralph 
46812203Sralph /*
46912203Sralph  * Points should be in the range 0 <= x (or y) <= DevRange.
47012203Sralph  * The origin is the top left-hand corner with increasing x towards the
47112203Sralph  * right and increasing y going down.
47212203Sralph  */
point(x,y)47312203Sralph point(x, y)
47412203Sralph register unsigned x, y;
47512203Sralph {
47612203Sralph 	register unsigned byte;
47712203Sralph 
47812203Sralph 	if (x < DevRange && y < DevRange) {
47912203Sralph 		byte = y * DevRange8 + (x >> 3);
48012203Sralph 		obuf[byte] |= 1 << (7 - (x & 07));
48112203Sralph 	}
48212203Sralph }
48312203Sralph 
getinteger(f)48412203Sralph getinteger(f)
48512203Sralph FILE *f;
48612203Sralph {
48712203Sralph 	register int low, high, result;
48812203Sralph 
48912203Sralph 	low = getc(f);
49012203Sralph 	high = getc(f);
49112203Sralph 	result = ((high << 8) | low);
49212203Sralph 	if (high > 127)
49312203Sralph 		result |= ~0xffff;
49412203Sralph 	return(result);
49512203Sralph }
496