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