xref: /csrg-svn/old/vplot/vplot.c (revision 11516)
1 /*
2  * Reads standard graphics input
3  * Makes a plot on a 200 dot-per-inch 11" wide
4  * Versatek plotter.
5  *
6  * Creates and leaves /usr/tmp/raster (1000 blocks)
7  * which is the bitmap
8  */
9 #include "stdio.h"
10 #include <signal.h>
11 
12 #define	NB	88
13 #define BSIZ	512
14 #define	mapx(x)	((1536*((x)-botx)/del)+centx)
15 #define	mapy(y)	((1536*(del-(y)+boty)/del)-centy)
16 #define SOLID -1
17 #define DOTTED 014
18 #define SHORTDASHED 034
19 #define DOTDASHED 054
20 #define LONGDASHED 074
21 #define	SETSTATE	(('v'<<8)+1)
22 
23 int	linmod	= SOLID;
24 int	again;
25 int	done1;
26 char	chrtab[][16];
27 int	plotcom[]	= { 0200, 0, 0};
28 int	eotcom[]		= { 0210, 0, 0};
29 char	blocks	[NB][BSIZ];
30 int	obuf[264];
31 int	lastx;
32 int	lasty;
33 double	topx	= 1536;
34 double	topy	= 1536;
35 double	botx	= 0;
36 double	boty	= 0;
37 int	centx;
38 int	centy;
39 double	delx	= 1536;
40 double	dely	= 1536;
41 double	del	= 1536;
42 
43 struct	buf {
44 	int	bno;
45 	char	*block;
46 };
47 struct	buf	bufs[NB];
48 
49 int	in, out;
50 char *picture = "/usr/tmp/raster";
51 
52 main(argc, argv)
53 char **argv;
54 {
55 	extern int onintr();
56 	register i;
57 
58 	if (argc>1) {
59 		in = open(argv[1], 0);
60 		putpict();
61 		exit(0);
62 	}
63 	signal(SIGTERM, onintr);
64 	if (signal(SIGINT, SIG_IGN) != SIG_IGN)
65 		signal(SIGINT, onintr);
66 another:
67 	for (i=0; i<NB; i++) {
68 		bufs[i].bno = -1;
69 		bufs[i].block = blocks[i];
70 	}
71 	out = creat(picture, 0666);
72 	in = open(picture, 0);
73 	zseek(out, 32*32);
74 	write(out, blocks[0], BSIZ);
75 /*delete following code when filsys deals properly with
76 holes in files*/
77 	for(i=0;i<512;i++)
78 		blocks[0][i] = 0;
79 	zseek(out, 0);
80 	for(i=0;i<32*32;i++)
81 		write(out,blocks[0],512);
82 /**/
83 	getpict();
84 	for (i=0; i<NB; i++)
85 		if (bufs[i].bno != -1) {
86 			zseek(out, bufs[i].bno);
87 			write(out, bufs[i].block, BSIZ);
88 		}
89 	putpict();
90 	if (again) {
91 		close(in);
92 		close(out);
93 		goto another;
94 	}
95 	exit(0);
96 }
97 
98 getpict()
99 {
100 	register x1, y1;
101 
102 	again = 0;
103 	for (;;) switch (x1 = getc(stdin)) {
104 
105 	case 's':
106 		botx = getw(stdin);
107 		boty = getw(stdin);
108 		topx = getw(stdin);
109 		topy = getw(stdin);
110 		delx = topx-botx;
111 		dely = topy-boty;
112 		if (dely/delx > 1536./2048.)
113 			del = dely;
114 		else
115 			del = delx * (1566./2048.);
116 		centx = 0;
117 		centx = (2048 - mapx(topx)) / 2;
118 		centy = 0;
119 		centy = mapy(topy) / 2;
120 		continue;
121 
122 	case 'l':
123 		done1 |= 01;
124 		x1 = mapx(getw(stdin));
125 		y1 = mapy(getw(stdin));
126 		lastx = mapx(getw(stdin));
127 		lasty = mapy(getw(stdin));
128 		line(x1, y1, lastx, lasty);
129 		continue;
130 
131 	case 'm':
132 		lastx = mapx(getw(stdin));
133 		lasty = mapy(getw(stdin));
134 		continue;
135 
136 	case 't':
137 		done1 |= 01;
138 		while ((x1 = getc(stdin)) != '\n')
139 			plotch(x1);
140 		continue;
141 
142 	case 'e':
143 		if (done1) {
144 			again++;
145 			return;
146 		}
147 		continue;
148 
149 	case 'p':
150 		done1 |= 01;
151 		lastx = mapx(getw(stdin));
152 		lasty = mapy(getw(stdin));
153 		point(lastx, lasty);
154 		point(lastx+1, lasty);
155 		point(lastx, lasty+1);
156 		point(lastx+1, lasty+1);
157 		continue;
158 
159 	case 'n':
160 		done1 |= 01;
161 		x1 = mapx(getw(stdin));
162 		y1 = mapy(getw(stdin));
163 		line(lastx, lasty, x1, y1);
164 		lastx = x1;
165 		lasty = y1;
166 		continue;
167 
168 	case 'f':
169 		getw(stdin);
170 		getc(stdin);
171 		switch(getc(stdin)) {
172 		case 't':
173 			linmod = DOTTED;
174 			break;
175 		default:
176 		case 'i':
177 			linmod = SOLID;
178 			break;
179 		case 'g':
180 			linmod = LONGDASHED;
181 			break;
182 		case 'r':
183 			linmod = SHORTDASHED;
184 			break;
185 		case 'd':
186 			linmod = DOTDASHED;
187 			break;
188 		}
189 		while((x1=getc(stdin))!='\n')
190 			if(x1==-1) return;
191 		continue;
192 
193 	case 'd':
194 		getw(stdin);
195 		getw(stdin);
196 		getw(stdin);
197 		x1 = getw(stdin);
198 		while (--x1 >= 0)
199 			getw(stdin);
200 		continue;
201 
202 	case -1:
203 		return;
204 
205 	default:
206 		printf("Botch\n");
207 		return;
208 	}
209 }
210 
211 plotch(c)
212 register c;
213 {
214 	register j;
215 	register char *cp;
216 	int i;
217 
218 	if (c<' ' || c >0177)
219 		return;
220 	cp = chrtab[c-' '];
221 	for (i = -16; i<16; i += 2) {
222 		c = *cp++;
223 		for (j=7; j>=0; --j)
224 			if ((c>>j)&1) {
225 				point(lastx+6-j*2, lasty+i);
226 				point(lastx+7-j*2, lasty+i);
227 				point(lastx+6-j*2, lasty+i+1);
228 				point(lastx+7-j*2, lasty+i+1);
229 			}
230 	}
231 	lastx += 16;
232 }
233 
234 int	f; /* versatec file number */
235 putpict()
236 {
237 	register x, *ip, *op;
238 	int y;
239 
240 	if (f==0){
241 		f = open("/dev/vp0", 1);
242 		if (f < 0) {
243 			printf("Cannot open vp\n");
244 			exit(1);
245 		}
246 		ioctl(f, SETSTATE, plotcom);
247 	}
248 	op = obuf;
249 	lseek(in, 0L, 0);
250 	for (y=0; y<2048; y++) {
251 		if ((y&077) == 0)
252 			read(in, blocks[0], 32*BSIZ);
253 		for (x=0; x<32; x++)  {
254 			ip = (int *)&blocks[x][(y&077)<<3];
255 			*op++ = *ip++;
256 			*op++ = *ip++;
257 			*op++ = *ip++;
258 			*op++ = *ip++;
259 		}
260 		*op++ = 0;
261 		*op++ = 0;
262 		*op++ = 0;
263 		*op++ = 0;
264 		if (y&1) {
265 			write(f, (char *)obuf, sizeof(obuf));
266 			op = obuf;
267 		}
268 	}
269 }
270 
271 line(x0, y0, x1, y1)
272 register x0, y0;
273 {
274 	int dx, dy;
275 	int xinc, yinc;
276 	register res1;
277 	int res2;
278 	int slope;
279 
280 	xinc = 1;
281 	yinc = 1;
282 	if ((dx = x1-x0) < 0) {
283 		xinc = -1;
284 		dx = -dx;
285 	}
286 	if ((dy = y1-y0) < 0) {
287 		yinc = -1;
288 		dy = -dy;
289 	}
290 	slope = xinc*yinc;
291 	res1 = 0;
292 	res2 = 0;
293 	if (dx >= dy) while (x0 != x1) {
294 	if((x0+slope*y0)&linmod)
295 	if (((x0>>6) + ((y0&~077)>>1)) == bufs[0].bno)
296 		bufs[0].block[((y0&077)<<3)+((x0>>3)&07)] |= 1 << (7-(x0&07));
297 	else
298 		point(x0, y0);
299 		if (res1 > res2) {
300 			res2 += dx - res1;
301 			res1 = 0;
302 			y0 += yinc;
303 		}
304 		res1 += dy;
305 		x0 += xinc;
306 	} else while (y0 != y1) {
307 	if((x0+slope*y0)&linmod)
308 	if (((x0>>6) + ((y0&~077)>>1)) == bufs[0].bno)
309 		bufs[0].block[((y0&077)<<3)+((x0>>3)&07)] |= 1 << (7-(x0&07));
310 	else
311 		point(x0, y0);
312 		if (res1 > res2) {
313 			res2 += dy - res1;
314 			res1 = 0;
315 			x0 += xinc;
316 		}
317 		res1 += dx;
318 		y0 += yinc;
319 	}
320 	if((x1+slope*y1)&linmod)
321 	if (((x1>>6) + ((y1&~077)>>1)) == bufs[0].bno)
322 		bufs[0].block[((y1&077)<<3)+((x1>>3)&07)] |= 1 << (7-(x1&07));
323 	else
324 		point(x1, y1);
325 }
326 
327 point(x, y)
328 register x, y;
329 {
330 	register bno;
331 
332 	bno = ((x&03700)>>6) + ((y&03700)>>1);
333 	if (bno != bufs[0].bno) {
334 		if (bno < 0 || bno >= 1024)
335 			return;
336 		getblk(bno);
337 	}
338 	bufs[0].block[((y&077)<<3)+((x>>3)&07)] |= 1 << (7-(x&07));
339 }
340 
341 getblk(b)
342 register b;
343 {
344 	register struct buf *bp1, *bp2;
345 	register char *tp;
346 
347 loop:
348 	for (bp1 = bufs; bp1 < &bufs[NB]; bp1++) {
349 		if (bp1->bno == b || bp1->bno == -1) {
350 			tp = bp1->block;
351 			for (bp2 = bp1; bp2>bufs; --bp2) {
352 				bp2->bno = (bp2-1)->bno;
353 				bp2->block = (bp2-1)->block;
354 			}
355 			bufs[0].bno = b;
356 			bufs[0].block = tp;
357 			return;
358 		}
359 	}
360 	zseek(out, bufs[NB-1].bno);
361 	write(out, bufs[NB-1].block, BSIZ);
362 	zseek(in, b);
363 	read(in, bufs[NB-1].block, BSIZ);
364 	bufs[NB-1].bno = b;
365 	goto loop;
366 }
367 
368 onintr()
369 {
370 	exit(1);
371 }
372 
373 zseek(a, b)
374 {
375 	return(lseek(a, (long)b*512, 0));
376 }
377