1 /* driver.c (Berkeley) 1.2 83/08/09 */ 2 #include <stdio.h> 3 #include <ctype.h> 4 5 float deltx; /* max x value in output, for scaling */ 6 float delty; /* max y value in output, for scaling */ 7 int dbg = 0; 8 int res = 200; /* versatec/varian is default */ 9 FILE *fin; /* input file pointer */ 10 char *cmdname; 11 int crop = 1; /* trim off exterior white space if non-zero */ 12 float hshift = 0.3; /* move this far left for text (in em's) */ 13 float vshift = 0.3; /* this far down */ 14 /* these values are suitable for circuit diagrams */ 15 int linetype = 's'; /* solid is normal */ 16 17 char buf[20000]; 18 char *bp = buf; 19 20 int sxmin; /* lower limit from s command */ 21 int symin; 22 int sxmax = 4096; /* upper */ 23 int symax = 4096; 24 int xmin = 30000; /* min values found in actual data */ 25 int ymin = 30000; 26 int xmax = -30000; /* max */ 27 int ymax = -30000; 28 29 main(argc,argv) 30 char **argv; 31 { 32 float atof(); 33 int c; 34 35 cmdname = argv[0]; 36 while (argc > 1 && *argv[1] == '-') { 37 switch (c = argv[1][1]) { 38 case 'T': 39 if (strcmp(&argv[1][2], "aps") == 0) { 40 res = 720; 41 } else if (strcmp(&argv[1][2], "cat") == 0) { 42 res = 432; 43 } 44 break; 45 case 'c': 46 crop = 0; 47 break; 48 case 'l': 49 delty = atof(&argv[1][2]); 50 break; 51 case 'w': 52 case 's': /* set size */ 53 if (argv[1][2] == 0) { 54 argv++; 55 argc--; 56 deltx = atof(&argv[1][0]); 57 } else 58 deltx = atof(&argv[1][2]); 59 if (c == 's') 60 delty = deltx; 61 break; 62 case 'd': 63 dbg = 1; 64 break; 65 } 66 argc--; 67 argv++; 68 } 69 if (argc <= 1) { 70 fin = stdin; 71 getdata(); 72 } else 73 while (argc-- > 1) { 74 if ((fin = fopen(*++argv, "r")) == NULL) { 75 fprintf(stderr, "%s: can't open %s\n", cmdname, *argv); 76 exit(1); 77 } 78 getdata(); 79 fclose(fin); 80 } 81 print(); 82 exit(0); 83 } 84 85 getdata() /* read the file, collect max, min sizes, etc. */ 86 { 87 char s[100], s1[20], *p; 88 int x, y, x1, y1, x2, y2, r, c; 89 90 while ((c = getc(fin)) != EOF) { 91 switch (c) { 92 case 'M': 93 case 'N': 94 case 'P': 95 fscanf(fin, "%d %d", &x, &y); 96 extreme(x, y); 97 ctobuf(tolower(c)); 98 xytobuf(x, y); 99 break; 100 case 'm': 101 case 'n': 102 case 'p': 103 x = getsi(fin); 104 y = getsi(fin); 105 extreme(x, y); 106 ctobuf(c); 107 xytobuf(x, y); 108 break; 109 case 'L': 110 case 'B': 111 fscanf(fin, "%d %d %d %d", &x, &y, &x1, &y1); 112 extreme(x, y); 113 extreme(x1, y1); 114 ctobuf(tolower(c)); 115 xytobuf(x, y); 116 xytobuf(x1, y1); 117 break; 118 case 'l': 119 case 'b': 120 x = getsi(fin); 121 y = getsi(fin); 122 x1 = getsi(fin); 123 y1 = getsi(fin); 124 extreme(x, y); 125 extreme(x1, y1); 126 ctobuf(c); 127 xytobuf(x, y); 128 xytobuf(x1, y1); 129 break; 130 case 'S': 131 fscanf(fin, "%d %d %d %d", &sxmin, &symin, &sxmax, &symax); 132 break; /* BUG -- ignoring this because it overrides -c */ 133 ctobuf('s'); 134 xytobuf(sxmin, symin); 135 xytobuf(sxmax, symax); 136 break; 137 case 's': 138 sxmin = getsi(fin); 139 symin = getsi(fin); 140 sxmax = getsi(fin); 141 symax = getsi(fin); 142 break; /* BUG -- ignoring this because it overrides -c */ 143 ctobuf(c); 144 xytobuf(sxmin, symin); 145 xytobuf(sxmax, symax); 146 break; 147 case 'T': 148 case 't': 149 fgets(s, sizeof s, fin); 150 for (p = s; *p != '\n'; p++) 151 ; 152 *p = 0; /* zap newline */ 153 ctobuf('t'); 154 stobuf(s); 155 break; 156 case 'E': 157 case 'e': 158 ctobuf('e'); 159 break; 160 case 'A': 161 fscanf(fin, "%d %d %d %d %d %d", &x, &y, &x1, &y1, &x2, &y2); 162 extreme(x, y); /* should use radius */ 163 ctobuf('a'); 164 xytobuf(x, y); 165 xytobuf(x1, y1); 166 xytobuf(x2, y2); 167 break; 168 case 'a': 169 x = getsi(fin); 170 y = getsi(fin); 171 x1 = getsi(fin); 172 y1 = getsi(fin); 173 x2 = getsi(fin); 174 y2 = getsi(fin); 175 extreme(x, y); /* should use radius */ 176 ctobuf('a'); 177 xytobuf(x, y); 178 xytobuf(x1, y1); 179 xytobuf(x2, y2); 180 break; 181 case 'C': 182 fscanf(fin, "%d %d %d", &x, &y, &r); 183 extreme(x+r, y+r); 184 extreme(x-r, y-r); 185 ctobuf('c'); 186 xytobuf(x, y); 187 xtobuf(r); 188 break; 189 case 'c': 190 x = getsi(fin); 191 y = getsi(fin); 192 r = getsi(fin); 193 extreme(x+r, y+r); 194 extreme(x-r, y-r); 195 ctobuf('c'); 196 xytobuf(x, y); 197 xtobuf(r); 198 break; 199 case 'F': 200 case 'f': 201 fgets(s, sizeof s, fin); 202 ctobuf('f'); 203 sscanf(s, "%s", s1); 204 if (strcmp(s1, "solid") == 0) 205 c = 's'; 206 else if (strcmp(s1, "dotted") == 0) 207 c = '.'; 208 else if (strcmp(s1, "longdashed") == 0) 209 c = '_'; 210 else if (strcmp(s1, "shortdashed") == 0) 211 c = '-'; 212 else 213 c = '!'; /* would you believe dotdashed? */ 214 ctobuf(c); 215 break; 216 case 'd': 217 case 'D': 218 fgets(s, 100, fin); 219 /* ignore */ 220 break; 221 default: 222 break; 223 } 224 if (bp >= buf + sizeof buf) { 225 fprintf(stderr, "pltroff: input too big to handle\n"); 226 exit(1); 227 } 228 } 229 *bp = 0; 230 } 231 232 extreme(x, y) /* record max and min x and y values */ 233 { 234 if (x > xmax) 235 xmax = x; 236 if (y > ymax) 237 ymax = y; 238 if (x < xmin) 239 xmin = x; 240 if (y < ymin) 241 ymin = y; 242 } 243 244 ctobuf(c) 245 { 246 *bp++ = c; 247 } 248 249 stobuf(s) 250 char *s; 251 { 252 while (*bp++ = *s++) 253 ; 254 } 255 256 xytobuf(x, y) 257 { 258 *bp++ = x >> 8; 259 *bp++ = x & 0377; 260 *bp++ = y >> 8; 261 *bp++ = y & 0377; 262 } 263 264 xtobuf(x) 265 { 266 *bp++ = x >> 8; 267 *bp++ = x & 0377; 268 } 269 270 print() 271 { 272 char s[100], *p; 273 int x, y, x1, y1, x2, y2, r, c; 274 275 openpl("\n"); /* outputs .PS\n */ 276 for (bp = buf; *bp; ) { 277 switch (c = *bp++) { 278 case 'm': 279 x = getbuf(); 280 y = getbuf(); 281 move(x, y); 282 break; 283 case 'f': /* line mode */ 284 linetype = *bp++; 285 break; 286 case 'l': 287 x = getbuf(); 288 y = getbuf(); 289 x1 = getbuf(); 290 y1 = getbuf(); 291 if (linetype == 's') 292 line(x, y, x1, y1); 293 else 294 dotline(x, y, x1, y1, linetype); 295 break; 296 case 't': 297 for (p = s; *p++ = *bp++; ) 298 ; 299 label(s, 'L', 0); 300 break; 301 case 'e': 302 erase(); 303 break; 304 case 'p': 305 x = getbuf(); 306 y = getbuf(); 307 point(x, y); 308 break; 309 case 'n': 310 x = getbuf(); 311 y = getbuf(); 312 cont(x, y); 313 break; 314 case 's': 315 x = getbuf(); 316 y = getbuf(); 317 x1 = getbuf(); 318 y1 = getbuf(); 319 space(x, y, x1, y1); 320 break; 321 case 'a': 322 x = getbuf(); 323 y = getbuf(); 324 x1 = getbuf(); 325 y1 = getbuf(); 326 x2 = getbuf(); 327 y2 = getbuf(); 328 arc(x, y, x1, y1, x2, y2); 329 break; 330 case 'c': 331 x = getbuf(); 332 y = getbuf(); 333 r = getbuf(); 334 circle(x, y, r); 335 break; 336 case 'b': 337 x = getbuf(); 338 y = getbuf(); 339 x1 = getbuf(); 340 y1 = getbuf(); 341 box(x, y, x1, y1); 342 break; 343 default: 344 break; 345 } 346 } 347 closepl(); 348 } 349 350 dotline(x0, y0, x1, y1, type) /* dotted or dashed line */ 351 int x0, y0, x1, y1; 352 int type; 353 { 354 int prevval = 10; 355 int i, numdots; 356 double a, b, sqrt(), dx, dy; 357 358 dx = x1 - x0; 359 dy = y1 - y0; 360 if (type == '.') { 361 numdots = sqrt(dx*dx + dy*dy) / prevval + 0.5; 362 for (i = 0; i <= numdots; i++) { 363 a = (float) i / (float) numdots; 364 move(x0 + (int)(a * dx), y0 + (int)(a * dy)); 365 dot(); 366 } 367 } else { /* all others */ 368 double d, dashsize, spacesize; 369 d = sqrt(dx*dx + dy*dy) + 0.5; 370 if (d <= 2 * prevval) { 371 line(x0, y0, x1, y1); 372 return; 373 } 374 numdots = d / (2 * prevval - 1) + 1; /* ceiling */ 375 dashsize = prevval; 376 spacesize = (d - numdots * dashsize) / (numdots - 1); 377 for (i = 0; i < numdots-1; i++) { 378 a = i * (dashsize + spacesize) / d; 379 b = a + dashsize / d; 380 line(x0 + (int)(a*dx), y0 + (int)(a*dy), x0 + (int)(b*dx), y0 + (int)(b*dy)); 381 a = b; 382 b = a + spacesize / d; 383 move(x0 + (int)(a*dx), y0 + (int)(a*dy)); 384 } 385 line(x0 + (int)(b * dx), y0 + (int)(b * dy), x1, y1); 386 } 387 } 388 389 getbuf() 390 { 391 int n; 392 393 n = *bp++ << 8; 394 n |= (*bp++ & 0377); 395 return(n); 396 } 397 398 getsi(fin) FILE *fin; { /* get an integer stored in 2 ascii bytes. */ 399 short a, b; 400 if((b = getc(fin)) == EOF) 401 return(EOF); 402 if((a = getc(fin)) == EOF) 403 return(EOF); 404 a = a<<8; 405 return(a|b); 406 } 407