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