Bell 32V release
[unix-history] / usr / src / cmd / plot / vplot.c
CommitLineData
2fb69548
TL
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
23int linmod = SOLID;
24int again;
25int done1;
26char chrtab[][16];
27int plotcom[] = { 0200, 0, 0};
28int eotcom[] = { 0210, 0, 0};
29char blocks [NB][BSIZ];
30int obuf[264];
31int lastx;
32int lasty;
33double topx = 1536;
34double topy = 1536;
35double botx = 0;
36double boty = 0;
37int centx;
38int centy;
39double delx = 1536;
40double dely = 1536;
41double del = 1536;
42
43struct buf {
44 int bno;
45 char *block;
46};
47struct buf bufs[NB];
48
49int in, out;
50char *picture = "/usr/tmp/raster";
51
52main(argc, argv)
53char **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);
66another:
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
76holes 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
98getpict()
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
211plotch(c)
212register 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
234int f; /* versatec file number */
235putpict()
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
271line(x0, y0, x1, y1)
272register 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
327point(x, y)
328register 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
341getblk(b)
342register b;
343{
344 register struct buf *bp1, *bp2;
345 register char *tp;
346
347loop:
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
368onintr()
369{
370 exit(1);
371}
372
373zseek(a, b)
374{
375 return(lseek(a, (long)b*512, 0));
376}