1*6317a530Sslatteng /* driver.c (Berkeley) 1.2 83/08/09 */
223344256Sslatteng #include <stdio.h>
323344256Sslatteng #include <ctype.h>
423344256Sslatteng
523344256Sslatteng float deltx; /* max x value in output, for scaling */
623344256Sslatteng float delty; /* max y value in output, for scaling */
723344256Sslatteng int dbg = 0;
8*6317a530Sslatteng int res = 200; /* versatec/varian is default */
923344256Sslatteng FILE *fin; /* input file pointer */
1023344256Sslatteng char *cmdname;
1123344256Sslatteng int crop = 1; /* trim off exterior white space if non-zero */
1223344256Sslatteng float hshift = 0.3; /* move this far left for text (in em's) */
1323344256Sslatteng float vshift = 0.3; /* this far down */
1423344256Sslatteng /* these values are suitable for circuit diagrams */
1523344256Sslatteng int linetype = 's'; /* solid is normal */
1623344256Sslatteng
1723344256Sslatteng char buf[20000];
1823344256Sslatteng char *bp = buf;
1923344256Sslatteng
2023344256Sslatteng int sxmin; /* lower limit from s command */
2123344256Sslatteng int symin;
2223344256Sslatteng int sxmax = 4096; /* upper */
2323344256Sslatteng int symax = 4096;
2423344256Sslatteng int xmin = 30000; /* min values found in actual data */
2523344256Sslatteng int ymin = 30000;
2623344256Sslatteng int xmax = -30000; /* max */
2723344256Sslatteng int ymax = -30000;
2823344256Sslatteng
main(argc,argv)2923344256Sslatteng main(argc,argv)
3023344256Sslatteng char **argv;
3123344256Sslatteng {
3223344256Sslatteng float atof();
3323344256Sslatteng int c;
3423344256Sslatteng
3523344256Sslatteng cmdname = argv[0];
3623344256Sslatteng while (argc > 1 && *argv[1] == '-') {
3723344256Sslatteng switch (c = argv[1][1]) {
3823344256Sslatteng case 'T':
3923344256Sslatteng if (strcmp(&argv[1][2], "aps") == 0) {
4023344256Sslatteng res = 720;
4123344256Sslatteng } else if (strcmp(&argv[1][2], "cat") == 0) {
4223344256Sslatteng res = 432;
4323344256Sslatteng }
4423344256Sslatteng break;
4523344256Sslatteng case 'c':
4623344256Sslatteng crop = 0;
4723344256Sslatteng break;
4823344256Sslatteng case 'l':
4923344256Sslatteng delty = atof(&argv[1][2]);
5023344256Sslatteng break;
5123344256Sslatteng case 'w':
5223344256Sslatteng case 's': /* set size */
5323344256Sslatteng if (argv[1][2] == 0) {
5423344256Sslatteng argv++;
5523344256Sslatteng argc--;
5623344256Sslatteng deltx = atof(&argv[1][0]);
5723344256Sslatteng } else
5823344256Sslatteng deltx = atof(&argv[1][2]);
5923344256Sslatteng if (c == 's')
6023344256Sslatteng delty = deltx;
6123344256Sslatteng break;
6223344256Sslatteng case 'd':
6323344256Sslatteng dbg = 1;
6423344256Sslatteng break;
6523344256Sslatteng }
6623344256Sslatteng argc--;
6723344256Sslatteng argv++;
6823344256Sslatteng }
6923344256Sslatteng if (argc <= 1) {
7023344256Sslatteng fin = stdin;
7123344256Sslatteng getdata();
7223344256Sslatteng } else
7323344256Sslatteng while (argc-- > 1) {
7423344256Sslatteng if ((fin = fopen(*++argv, "r")) == NULL) {
7523344256Sslatteng fprintf(stderr, "%s: can't open %s\n", cmdname, *argv);
7623344256Sslatteng exit(1);
7723344256Sslatteng }
7823344256Sslatteng getdata();
7923344256Sslatteng fclose(fin);
8023344256Sslatteng }
8123344256Sslatteng print();
8223344256Sslatteng exit(0);
8323344256Sslatteng }
8423344256Sslatteng
getdata()8523344256Sslatteng getdata() /* read the file, collect max, min sizes, etc. */
8623344256Sslatteng {
8723344256Sslatteng char s[100], s1[20], *p;
8823344256Sslatteng int x, y, x1, y1, x2, y2, r, c;
8923344256Sslatteng
9023344256Sslatteng while ((c = getc(fin)) != EOF) {
9123344256Sslatteng switch (c) {
9223344256Sslatteng case 'M':
9323344256Sslatteng case 'N':
9423344256Sslatteng case 'P':
9523344256Sslatteng fscanf(fin, "%d %d", &x, &y);
9623344256Sslatteng extreme(x, y);
9723344256Sslatteng ctobuf(tolower(c));
9823344256Sslatteng xytobuf(x, y);
9923344256Sslatteng break;
10023344256Sslatteng case 'm':
10123344256Sslatteng case 'n':
10223344256Sslatteng case 'p':
10323344256Sslatteng x = getsi(fin);
10423344256Sslatteng y = getsi(fin);
10523344256Sslatteng extreme(x, y);
10623344256Sslatteng ctobuf(c);
10723344256Sslatteng xytobuf(x, y);
10823344256Sslatteng break;
10923344256Sslatteng case 'L':
11023344256Sslatteng case 'B':
11123344256Sslatteng fscanf(fin, "%d %d %d %d", &x, &y, &x1, &y1);
11223344256Sslatteng extreme(x, y);
11323344256Sslatteng extreme(x1, y1);
11423344256Sslatteng ctobuf(tolower(c));
11523344256Sslatteng xytobuf(x, y);
11623344256Sslatteng xytobuf(x1, y1);
11723344256Sslatteng break;
11823344256Sslatteng case 'l':
11923344256Sslatteng case 'b':
12023344256Sslatteng x = getsi(fin);
12123344256Sslatteng y = getsi(fin);
12223344256Sslatteng x1 = getsi(fin);
12323344256Sslatteng y1 = getsi(fin);
12423344256Sslatteng extreme(x, y);
12523344256Sslatteng extreme(x1, y1);
12623344256Sslatteng ctobuf(c);
12723344256Sslatteng xytobuf(x, y);
12823344256Sslatteng xytobuf(x1, y1);
12923344256Sslatteng break;
13023344256Sslatteng case 'S':
13123344256Sslatteng fscanf(fin, "%d %d %d %d", &sxmin, &symin, &sxmax, &symax);
13223344256Sslatteng break; /* BUG -- ignoring this because it overrides -c */
13323344256Sslatteng ctobuf('s');
13423344256Sslatteng xytobuf(sxmin, symin);
13523344256Sslatteng xytobuf(sxmax, symax);
13623344256Sslatteng break;
13723344256Sslatteng case 's':
13823344256Sslatteng sxmin = getsi(fin);
13923344256Sslatteng symin = getsi(fin);
14023344256Sslatteng sxmax = getsi(fin);
14123344256Sslatteng symax = getsi(fin);
14223344256Sslatteng break; /* BUG -- ignoring this because it overrides -c */
14323344256Sslatteng ctobuf(c);
14423344256Sslatteng xytobuf(sxmin, symin);
14523344256Sslatteng xytobuf(sxmax, symax);
14623344256Sslatteng break;
14723344256Sslatteng case 'T':
14823344256Sslatteng case 't':
14923344256Sslatteng fgets(s, sizeof s, fin);
15023344256Sslatteng for (p = s; *p != '\n'; p++)
15123344256Sslatteng ;
15223344256Sslatteng *p = 0; /* zap newline */
15323344256Sslatteng ctobuf('t');
15423344256Sslatteng stobuf(s);
15523344256Sslatteng break;
15623344256Sslatteng case 'E':
15723344256Sslatteng case 'e':
15823344256Sslatteng ctobuf('e');
15923344256Sslatteng break;
16023344256Sslatteng case 'A':
16123344256Sslatteng fscanf(fin, "%d %d %d %d %d %d", &x, &y, &x1, &y1, &x2, &y2);
16223344256Sslatteng extreme(x, y); /* should use radius */
16323344256Sslatteng ctobuf('a');
16423344256Sslatteng xytobuf(x, y);
16523344256Sslatteng xytobuf(x1, y1);
16623344256Sslatteng xytobuf(x2, y2);
16723344256Sslatteng break;
16823344256Sslatteng case 'a':
16923344256Sslatteng x = getsi(fin);
17023344256Sslatteng y = getsi(fin);
17123344256Sslatteng x1 = getsi(fin);
17223344256Sslatteng y1 = getsi(fin);
17323344256Sslatteng x2 = getsi(fin);
17423344256Sslatteng y2 = getsi(fin);
17523344256Sslatteng extreme(x, y); /* should use radius */
17623344256Sslatteng ctobuf('a');
17723344256Sslatteng xytobuf(x, y);
17823344256Sslatteng xytobuf(x1, y1);
17923344256Sslatteng xytobuf(x2, y2);
18023344256Sslatteng break;
18123344256Sslatteng case 'C':
18223344256Sslatteng fscanf(fin, "%d %d %d", &x, &y, &r);
18323344256Sslatteng extreme(x+r, y+r);
18423344256Sslatteng extreme(x-r, y-r);
18523344256Sslatteng ctobuf('c');
18623344256Sslatteng xytobuf(x, y);
18723344256Sslatteng xtobuf(r);
18823344256Sslatteng break;
18923344256Sslatteng case 'c':
19023344256Sslatteng x = getsi(fin);
19123344256Sslatteng y = getsi(fin);
19223344256Sslatteng r = getsi(fin);
19323344256Sslatteng extreme(x+r, y+r);
19423344256Sslatteng extreme(x-r, y-r);
19523344256Sslatteng ctobuf('c');
19623344256Sslatteng xytobuf(x, y);
19723344256Sslatteng xtobuf(r);
19823344256Sslatteng break;
19923344256Sslatteng case 'F':
20023344256Sslatteng case 'f':
20123344256Sslatteng fgets(s, sizeof s, fin);
20223344256Sslatteng ctobuf('f');
20323344256Sslatteng sscanf(s, "%s", s1);
20423344256Sslatteng if (strcmp(s1, "solid") == 0)
20523344256Sslatteng c = 's';
20623344256Sslatteng else if (strcmp(s1, "dotted") == 0)
20723344256Sslatteng c = '.';
20823344256Sslatteng else if (strcmp(s1, "longdashed") == 0)
20923344256Sslatteng c = '_';
21023344256Sslatteng else if (strcmp(s1, "shortdashed") == 0)
21123344256Sslatteng c = '-';
21223344256Sslatteng else
21323344256Sslatteng c = '!'; /* would you believe dotdashed? */
21423344256Sslatteng ctobuf(c);
21523344256Sslatteng break;
21623344256Sslatteng case 'd':
21723344256Sslatteng case 'D':
21823344256Sslatteng fgets(s, 100, fin);
21923344256Sslatteng /* ignore */
22023344256Sslatteng break;
22123344256Sslatteng default:
22223344256Sslatteng break;
22323344256Sslatteng }
22423344256Sslatteng if (bp >= buf + sizeof buf) {
22523344256Sslatteng fprintf(stderr, "pltroff: input too big to handle\n");
22623344256Sslatteng exit(1);
22723344256Sslatteng }
22823344256Sslatteng }
22923344256Sslatteng *bp = 0;
23023344256Sslatteng }
23123344256Sslatteng
extreme(x,y)23223344256Sslatteng extreme(x, y) /* record max and min x and y values */
23323344256Sslatteng {
23423344256Sslatteng if (x > xmax)
23523344256Sslatteng xmax = x;
23623344256Sslatteng if (y > ymax)
23723344256Sslatteng ymax = y;
23823344256Sslatteng if (x < xmin)
23923344256Sslatteng xmin = x;
24023344256Sslatteng if (y < ymin)
24123344256Sslatteng ymin = y;
24223344256Sslatteng }
24323344256Sslatteng
ctobuf(c)24423344256Sslatteng ctobuf(c)
24523344256Sslatteng {
24623344256Sslatteng *bp++ = c;
24723344256Sslatteng }
24823344256Sslatteng
stobuf(s)24923344256Sslatteng stobuf(s)
25023344256Sslatteng char *s;
25123344256Sslatteng {
25223344256Sslatteng while (*bp++ = *s++)
25323344256Sslatteng ;
25423344256Sslatteng }
25523344256Sslatteng
xytobuf(x,y)25623344256Sslatteng xytobuf(x, y)
25723344256Sslatteng {
25823344256Sslatteng *bp++ = x >> 8;
25923344256Sslatteng *bp++ = x & 0377;
26023344256Sslatteng *bp++ = y >> 8;
26123344256Sslatteng *bp++ = y & 0377;
26223344256Sslatteng }
26323344256Sslatteng
xtobuf(x)26423344256Sslatteng xtobuf(x)
26523344256Sslatteng {
26623344256Sslatteng *bp++ = x >> 8;
26723344256Sslatteng *bp++ = x & 0377;
26823344256Sslatteng }
26923344256Sslatteng
print()27023344256Sslatteng print()
27123344256Sslatteng {
27223344256Sslatteng char s[100], *p;
27323344256Sslatteng int x, y, x1, y1, x2, y2, r, c;
27423344256Sslatteng
27523344256Sslatteng openpl("\n"); /* outputs .PS\n */
27623344256Sslatteng for (bp = buf; *bp; ) {
27723344256Sslatteng switch (c = *bp++) {
27823344256Sslatteng case 'm':
27923344256Sslatteng x = getbuf();
28023344256Sslatteng y = getbuf();
28123344256Sslatteng move(x, y);
28223344256Sslatteng break;
28323344256Sslatteng case 'f': /* line mode */
28423344256Sslatteng linetype = *bp++;
28523344256Sslatteng break;
28623344256Sslatteng case 'l':
28723344256Sslatteng x = getbuf();
28823344256Sslatteng y = getbuf();
28923344256Sslatteng x1 = getbuf();
29023344256Sslatteng y1 = getbuf();
29123344256Sslatteng if (linetype == 's')
29223344256Sslatteng line(x, y, x1, y1);
29323344256Sslatteng else
29423344256Sslatteng dotline(x, y, x1, y1, linetype);
29523344256Sslatteng break;
29623344256Sslatteng case 't':
29723344256Sslatteng for (p = s; *p++ = *bp++; )
29823344256Sslatteng ;
29923344256Sslatteng label(s, 'L', 0);
30023344256Sslatteng break;
30123344256Sslatteng case 'e':
30223344256Sslatteng erase();
30323344256Sslatteng break;
30423344256Sslatteng case 'p':
30523344256Sslatteng x = getbuf();
30623344256Sslatteng y = getbuf();
30723344256Sslatteng point(x, y);
30823344256Sslatteng break;
30923344256Sslatteng case 'n':
31023344256Sslatteng x = getbuf();
31123344256Sslatteng y = getbuf();
31223344256Sslatteng cont(x, y);
31323344256Sslatteng break;
31423344256Sslatteng case 's':
31523344256Sslatteng x = getbuf();
31623344256Sslatteng y = getbuf();
31723344256Sslatteng x1 = getbuf();
31823344256Sslatteng y1 = getbuf();
31923344256Sslatteng space(x, y, x1, y1);
32023344256Sslatteng break;
32123344256Sslatteng case 'a':
32223344256Sslatteng x = getbuf();
32323344256Sslatteng y = getbuf();
32423344256Sslatteng x1 = getbuf();
32523344256Sslatteng y1 = getbuf();
32623344256Sslatteng x2 = getbuf();
32723344256Sslatteng y2 = getbuf();
32823344256Sslatteng arc(x, y, x1, y1, x2, y2);
32923344256Sslatteng break;
33023344256Sslatteng case 'c':
33123344256Sslatteng x = getbuf();
33223344256Sslatteng y = getbuf();
33323344256Sslatteng r = getbuf();
33423344256Sslatteng circle(x, y, r);
33523344256Sslatteng break;
33623344256Sslatteng case 'b':
33723344256Sslatteng x = getbuf();
33823344256Sslatteng y = getbuf();
33923344256Sslatteng x1 = getbuf();
34023344256Sslatteng y1 = getbuf();
34123344256Sslatteng box(x, y, x1, y1);
34223344256Sslatteng break;
34323344256Sslatteng default:
34423344256Sslatteng break;
34523344256Sslatteng }
34623344256Sslatteng }
34723344256Sslatteng closepl();
34823344256Sslatteng }
34923344256Sslatteng
dotline(x0,y0,x1,y1,type)35023344256Sslatteng dotline(x0, y0, x1, y1, type) /* dotted or dashed line */
35123344256Sslatteng int x0, y0, x1, y1;
35223344256Sslatteng int type;
35323344256Sslatteng {
35423344256Sslatteng int prevval = 10;
35523344256Sslatteng int i, numdots;
35623344256Sslatteng double a, b, sqrt(), dx, dy;
35723344256Sslatteng
35823344256Sslatteng dx = x1 - x0;
35923344256Sslatteng dy = y1 - y0;
36023344256Sslatteng if (type == '.') {
36123344256Sslatteng numdots = sqrt(dx*dx + dy*dy) / prevval + 0.5;
36223344256Sslatteng for (i = 0; i <= numdots; i++) {
36323344256Sslatteng a = (float) i / (float) numdots;
36423344256Sslatteng move(x0 + (int)(a * dx), y0 + (int)(a * dy));
36523344256Sslatteng dot();
36623344256Sslatteng }
36723344256Sslatteng } else { /* all others */
36823344256Sslatteng double d, dashsize, spacesize;
36923344256Sslatteng d = sqrt(dx*dx + dy*dy) + 0.5;
37023344256Sslatteng if (d <= 2 * prevval) {
37123344256Sslatteng line(x0, y0, x1, y1);
37223344256Sslatteng return;
37323344256Sslatteng }
37423344256Sslatteng numdots = d / (2 * prevval - 1) + 1; /* ceiling */
37523344256Sslatteng dashsize = prevval;
37623344256Sslatteng spacesize = (d - numdots * dashsize) / (numdots - 1);
37723344256Sslatteng for (i = 0; i < numdots-1; i++) {
37823344256Sslatteng a = i * (dashsize + spacesize) / d;
37923344256Sslatteng b = a + dashsize / d;
38023344256Sslatteng line(x0 + (int)(a*dx), y0 + (int)(a*dy), x0 + (int)(b*dx), y0 + (int)(b*dy));
38123344256Sslatteng a = b;
38223344256Sslatteng b = a + spacesize / d;
38323344256Sslatteng move(x0 + (int)(a*dx), y0 + (int)(a*dy));
38423344256Sslatteng }
38523344256Sslatteng line(x0 + (int)(b * dx), y0 + (int)(b * dy), x1, y1);
38623344256Sslatteng }
38723344256Sslatteng }
38823344256Sslatteng
getbuf()38923344256Sslatteng getbuf()
39023344256Sslatteng {
39123344256Sslatteng int n;
39223344256Sslatteng
39323344256Sslatteng n = *bp++ << 8;
39423344256Sslatteng n |= (*bp++ & 0377);
39523344256Sslatteng return(n);
39623344256Sslatteng }
39723344256Sslatteng
getsi(fin)39823344256Sslatteng getsi(fin) FILE *fin; { /* get an integer stored in 2 ascii bytes. */
39923344256Sslatteng short a, b;
40023344256Sslatteng if((b = getc(fin)) == EOF)
40123344256Sslatteng return(EOF);
40223344256Sslatteng if((a = getc(fin)) == EOF)
40323344256Sslatteng return(EOF);
40423344256Sslatteng a = a<<8;
40523344256Sslatteng return(a|b);
40623344256Sslatteng }
407