1 #ifndef lint 2 static char Notice[] = "Copyright (c) 1985 Adobe Systems Incorporated"; 3 static char *RCSID = "$Header: ps4014.c,v 2.1 85/11/24 11:49:18 shore Rel $"; 4 #endif 5 /* ps4014.c 6 * 7 * Copyright (c) 1985 Adobe Systems Incorporated 8 * 9 * tektronics 4014 to PostScript filter 10 * 11 * Edit History: 12 * Original Version: Tom Malloy 13 * Andrew Shore: Mon Nov 4 13:46:08 1985 14 * End Edit History. 15 * 16 * RCSLOG: 17 * $Log: ps4014.c,v $ 18 * Revision 2.1 85/11/24 11:49:18 shore 19 * Product Release 2.0 20 * 21 * Revision 1.1 85/11/20 00:16:33 shore 22 * Initial revision 23 * 24 * 25 */ 26 27 #include <stdio.h> 28 #include <pwd.h> 29 #ifdef SYSV 30 extern struct passwd *getpwuid(); 31 #include <string.h> 32 #else 33 #include <strings.h> 34 #endif 35 #include <setjmp.h> 36 #include "transcript.h" 37 38 /* move this to transcript.h some day */ 39 private char scProlog[512]; 40 41 private struct Params { 42 char *scSrcFile; /* string name of 4014 source file */ 43 char *scDstFile; /* string name of PS destination file */ 44 char *scDbgFile; /* string name of debug output file */ 45 short fCrGenLf; /* true if carriage return generates line 46 feed */ 47 short fLfGenCr; /* true if line feed generates carriage 48 return */ 49 short fMarg2; /* true if there are two left margins for 50 text, one a left and one in the middle 51 of the page */ 52 short fDbg; /* true if debug output should be 53 generated */ 54 float xRtInch; /* top, left location of output on page */ 55 float yBotInch; 56 float dxWidInch; /* width, height of output */ 57 float dyHtInch; 58 int fLandscape; /* do landscape page */ 59 }; 60 61 62 private struct Real4110 { 63 long mantissa, exp; 64 }; /* 4110-format real number */ 65 private struct Sts { 66 short md; /* current mode */ 67 int xh; /* current x-position (in 4096ths) */ 68 int yh; /* current y-position (in 4096ths) */ 69 char chHiY, chHiX, chExtra, chLoY; 70 /* current values for the vector-mode address bytes that may be omitted 71 when sending an address - see GetXhYh */ 72 short syline; /* current line style from 4014 input 73 viewpoint */ 74 short sychar; /* current character style */ 75 short charset; /* normal or alternate character set */ 76 short sylinePrt; /* current line style from printers 77 viewpoint */ 78 short sycharPrt; /* current character style from printers 79 viewpoint */ 80 short charsetPrt; /* normal or alternate characters from 81 printers viewpoint */ 82 short fPenDown; /* true implies vector command draws false 83 implies vector command moves */ 84 short fMovePending; /* true implies 4014 position and 85 PostScript position are different */ 86 short fVectorDrawn; /* true implies Stroke command is pending 87 on current PostScript path */ 88 short dir; /* current incremental point plot 89 direction */ 90 int cincr; /* count of increments tom move/draw in 91 current incremental point plot 92 direction */ 93 int xhLeftMarg; /* current left margin */ 94 }; 95 96 #define mdAlpha 0 /* Alpha mode */ 97 #define mdVector 1 /* Vector graphics mode */ 98 #define mdPtPlot 2 /* Point plot mode */ 99 #define mdSpecPtPlot 3 /* Special point plot mode */ 100 #define mdIncrPtPlot 4 /* Incremental point plot mode */ 101 #define mdBypass 5 /* Bypass mode */ 102 103 #define chFstSyline '`' /* first valid line style command 104 character */ 105 #define chLstSyline 'w' /* last valid line style command character */ 106 107 #define sylineNormal 0 /* normal line style */ 108 #define sylineDot 1 /* dotted line style */ 109 #define sylineDotDashed 2 /* dot-dashed line style */ 110 #define sylineShortDash 3 /* short dash line style */ 111 #define sylineLongDash 4 /* long dash line style */ 112 #define sylineMax 5 /* number of valid line styles */ 113 #define mskSyline 7 /* mask for extracting line style indexes 114 from line style command characters. */ 115 116 #define chFstSychar '8' /* first valid character style command 117 character */ 118 #define chLstSychar ';' /* last valid character style command 119 character */ 120 121 #define sycharLarge 0 /* character style: large character */ 122 #define sychar2 1 /* character style 2 */ 123 #define sychar3 2 /* charactr style 3 */ 124 #define sycharSmall 3 /* charactr style: small characters */ 125 #define sycharMax 4 /* number of valid character styles */ 126 127 #define charsetStd 0 /* normal character set */ 128 #define charsetAlt 1 /* Alternate character set */ 129 130 #define chFstShow ' ' /* first valid printable character */ 131 #define chLstShow 126 /* last valid printable character */ 132 #define chFstCoord ' ' /* first valid graphics address byte */ 133 #define chLstCoord 127 /* last valid graphcs address byte */ 134 #define chFstLoX '@' /* first valid low x byte */ 135 #define chFstLoY '`' /* last valid low x byte */ 136 #define mskLoBits 3 /* mask for extracting low order address 137 bits from extra byte */ 138 #define mskBit4 16 /* mask for extracting margin bit from 139 extra byte */ 140 #define shiftHiByte 7 /* number of bits to shift high-byte 141 address bits in composed address */ 142 #define shiftLoByte 2 /* number of bits to shift low-byte 143 address bits in composed address */ 144 #define shiftYExtra 2 /* number of bits to shift extra byte to 145 right align the low order y bits */ 146 147 /* Some 4110 command code definitions */ 148 #define chFst4110 'I' /* first valid 4110 command code character 149 */ 150 #define chLst4110 'Z' /* last valid 4110 command code character 151 */ 152 #define chFstEsc2 'A' /* first valid character for the second 153 character of a 2-byte 4110 command code 154 sequence */ 155 #define chLstEsc2 'Z' /* last valid character for the second 156 character of a 2-byte 4110 command code 157 sequence */ 158 #define chFstHiInt '@' /* first valid character for non-low-order 159 portion of integer parameter */ 160 #define chLstHiInt 127 /* last valid character for non-low-order 161 portion of integer parameter */ 162 #define chFstLoPosInt '0' /* first valid character for low-order 163 portion of positive integer */ 164 #define chLstLoPosInt '?' /* last valid character for low-order 165 portion of positive integer */ 166 #define chFstLoNegInt 32 /* first valid character for low-order 167 portion of negative integer */ 168 #define chLstLoNegInt '/' /* last valid character for low-order 169 portion of positive integer */ 170 171 /* Some useful ASCII command character defintions */ 172 #define chNull 0x0 173 #define chEnq 0x5 174 #define chBell 0x7 175 #define chBs 0x8 176 #define chTab 0x9 177 #define chLf 0xA 178 #define chVTab 0xB 179 #define chFf 0xC 180 #define chCr 0xD 181 #define chSo 0xE 182 #define chSi 0xF 183 #define chEtb 0x17 184 #define chCan 0x18 185 #define chSub 0x1A 186 #define chEsc 0x1B 187 #define chFs 0x1C 188 #define chGs 0x1D 189 #define chRs 0x1E 190 #define chUs 0x1F 191 #define chSp 0x20 192 #define chDel 0x7F 193 194 /* Types of 4014 postion movement commands */ 195 #define tymoveNil 0 196 #define tymoveLeft 1 197 #define tymoveRt 2 198 #define tymoveUp 3 199 #define tymoveDown 4 200 #define tymoveGDown 5 201 #define tymoveXMarg 6 202 #define tymoveMax 7 203 204 /* masks for extracting movement direction 205 from incremental point plot commands */ 206 #define mskDir 0xF 207 #define mskDirUp 4 208 #define mskDirRt 1 209 #define mskDirDown 8 210 #define mskDirLeft 2 211 #define dirNil 0 212 213 /* Some x and y coordinates (in 4096ths) */ 214 #define xhHome 0 215 #define xhMarg1 0 216 #define xhMarg2 2048 217 #define yhHome 3071 218 #define xhMax 4096 219 #define yhMax 3120 220 221 /* Constants and parser tables for 4110 parser */ 222 223 /* parameter types */ 224 #define typrmNil 0 225 #define typrmLong 1 /* 32-bit integer parameter */ 226 #define typrmAryLong 2 /* array of 32-bit integers */ 227 #define typrmXhYh 3 /* vector mode xy-coordinate */ 228 #define typrmString 4 /* 4110 format string */ 229 #define typrmCh 5 /* character */ 230 #define typrmReal4110 6 /* 4110 format real number */ 231 #define typrmAryXhYh 7 /* array of vector mode corrdinates */ 232 #define typrmMax 8 /* number of valid parameter types */ 233 234 #define iprmMax 4 /* maximum number of parameters to a 4110 235 command */ 236 /* Identifiers for some, but not all, commonly used 237 parameter sequences for 4110 commands */ 238 #define ifmtNil 0 239 #define ifmtL 1 240 #define ifmtLL 2 241 #define ifmtLLL 3 242 #define ifmtLLLL 4 243 #define ifmtXhYh 9 244 #define ifmtMax 31 /* total number of distinct parameter 245 seqeunces */ 246 247 #define cchEsc1 18 /* number of valid 4110 command character 248 that can follow an <Esc> */ 249 #define chEsc1Fst 'I' /* first valid 4110 command character */ 250 #define chEsc1Lst 'Z' /* last valid 4110 command character */ 251 #define cchEsc2 26 /* number of valid command characters for 252 the second character in two character 253 4110 command sequences */ 254 #define chEsc2Fst 'A' /* first valid character for second 255 character in a 4110 command sequence */ 256 #define chEsc2Lst 'Z' /* last valid character for second 257 character in a 4110 command sequence */ 258 259 /* Parser table 1. Indexed by ifmt, a parameter sequence id. Yields 260 an array of four elements each of which identifies the type of 261 the i-th parameter in the sequence. */ 262 private char aryfmt[ifmtMax][iprmMax] = 263 { 264 {typrmNil, typrmNil, typrmNil, typrmNil}, 265 {typrmLong, typrmNil, typrmNil, typrmNil}, 266 {typrmLong, typrmLong, typrmNil, typrmNil}, 267 {typrmLong, typrmLong, typrmLong, typrmNil}, 268 {typrmLong, typrmLong, typrmLong, typrmLong}, /*[5]*/ 269 {typrmAryLong, typrmNil, typrmNil, typrmNil}, 270 {typrmAryLong, typrmAryLong, typrmNil, typrmNil}, 271 {typrmLong, typrmAryLong, typrmNil, typrmNil}, 272 {typrmLong, typrmAryLong, typrmAryLong, typrmNil}, 273 {typrmXhYh, typrmNil, typrmNil, typrmNil}, /*[10]*/ 274 {typrmXhYh, typrmXhYh, typrmNil, typrmNil}, 275 {typrmLong, typrmXhYh, typrmNil, typrmNil}, 276 {typrmXhYh, typrmLong, typrmNil, typrmNil}, 277 {typrmLong, typrmLong, typrmXhYh, typrmXhYh}, 278 {typrmXhYh, typrmXhYh, typrmLong, typrmNil}, /*[15]*/ 279 {typrmLong, typrmXhYh, typrmXhYh, typrmXhYh}, 280 {typrmAryXhYh, typrmNil, typrmNil, typrmNil}, 281 {typrmString, typrmNil, typrmNil, typrmNil}, 282 {typrmString, typrmString, typrmNil, typrmNil}, 283 {typrmString, typrmString, typrmString, typrmNil}, 284 /*[20]*/ {typrmString, typrmLong, typrmNil, typrmNil}, 285 {typrmString, typrmString, typrmLong, typrmNil}, 286 {typrmString, typrmLong, typrmLong, typrmNil}, 287 {typrmString, typrmLong, typrmString, typrmLong}, 288 {typrmCh, typrmNil, typrmNil, typrmNil}, /*[25]*/ 289 {typrmCh, typrmCh, typrmNil, typrmNil}, 290 {typrmLong, typrmString, typrmNil, typrmNil}, 291 {typrmReal4110, typrmNil, typrmNil, typrmNil}, 292 {typrmString, typrmLong, typrmString, typrmString}, 293 {typrmString, typrmAryLong, typrmNil, typrmNil}, 294 {typrmString, typrmLong, typrmLong, typrmLong} 295 }; 296 297 /* Parser table 2. Indexed by the two characters of a 4110 command 298 sequence. Yields a parameter sequence index, which can be used to 299 retreive the parameter types from aryfmt. */ 300 private char aryaryifmt[cchEsc1][cchEsc2] = 301 { 302 /*['I']*/ { 303 ifmtL, ifmtNil, ifmtLL, ifmtL, ifmtLL, ifmtLLL, ifmtLLL, 304 ifmtL, ifmtLL, ifmtNil, ifmtNil, ifmtL, ifmtL, ifmtL, 305 ifmtNil, ifmtL, 25, ifmtLL, ifmtLLL, ifmtL, ifmtL, 306 13, 10, 11, ifmtNil, ifmtNil 307 }, 308 /*['J']*/ { 309 ifmtNil, 17, 19, 19, ifmtNil, 17, ifmtNil, 310 ifmtL, ifmtNil, 17, 17, 17, ifmtNil, ifmtNil, 311 ifmtNil, 20, 17, 19, 19, ifmtNil, ifmtL, 312 28, ifmtNil, ifmtNil, ifmtNil, ifmtNil 313 }, 314 /*['K']*/ { 315 ifmtL, ifmtNil, ifmtNil, 7, ifmtL, ifmtL, ifmtNil, 316 ifmtL, ifmtL, ifmtNil, ifmtNil, ifmtL, ifmtL, ifmtL, ifmtNil, 317 ifmtL, ifmtNil, ifmtL, ifmtL, ifmtL, ifmtNil, ifmtNil, 318 ifmtNil, ifmtL, ifmtNil, ifmtNil 319 }, 320 /*['L']*/ { 321 ifmtNil, ifmtL, ifmtL, ifmtNil, ifmtNil, ifmtXhYh, ifmtXhYh, 322 ifmtXhYh, ifmtLLL, ifmtL, ifmtL, ifmtL, ifmtL, ifmtNil, 323 ifmtNil, 12, ifmtNil, ifmtNil, ifmtL, 17, ifmtNil, 324 ifmtL, ifmtNil, ifmtXhYh, ifmtNil, ifmtNil 325 }, 326 /*['M']*/ { 327 27, ifmtLL, ifmtLLL, ifmtLLLL, ifmtNil, ifmtL, ifmtL, 328 ifmtNil, ifmtL, ifmtNil, ifmtNil, ifmtL, ifmtL, ifmtNil, 329 ifmtNil, ifmtL, ifmtL, 27, ifmtLLL, ifmtL, ifmtNil, 330 ifmtL, ifmtL, ifmtNil, ifmtL, ifmtLLL 331 }, 332 /*['N']*/ { 333 ifmtNil, ifmtL, ifmtLL, ifmtL, 5, ifmtL, ifmtNil, 334 ifmtNil, ifmtNil, ifmtNil, ifmtL, ifmtL, ifmtL, ifmtNil, 335 ifmtNil, ifmtL, ifmtL, ifmtLL, 5, 5, ifmtL, 336 ifmtNil, ifmtNil, ifmtNil, ifmtNil, ifmtNil 337 }, 338 /*['O']*/ { 339 ifmtNil, ifmtL, ifmtLL, ifmtL, ifmtLL, ifmtNil, ifmtNil, 340 6, ifmtNil, ifmtNil, ifmtNil, ifmtL, ifmtLL, 6, 341 ifmtNil, ifmtLLLL, ifmtNil, ifmtNil, ifmtLL, ifmtL, ifmtNil, 342 ifmtNil, ifmtNil, ifmtNil, ifmtNil, ifmtNil 343 }, 344 /*['P']*/ { 345 21, 22, 19, ifmtNil, 29, 30, ifmtNil, 346 ifmtNil, 22, ifmtNil, ifmtNil, 18, 29, ifmtNil, 347 ifmtNil, 20, 17, 20, ifmtNil, ifmtNil, ifmtNil, 348 ifmtNil, ifmtNil, ifmtNil, ifmtNil, ifmtNil 349 }, 350 /*['Q']*/ { 351 ifmtNil, ifmtL, ifmtNil, ifmtL, ifmtNil, ifmtL, ifmtNil, 352 ifmtNil, ifmtNil, ifmtNil, ifmtNil, ifmtLLL, ifmtL, ifmtL, 353 ifmtL, ifmtNil, ifmtNil, ifmtL, ifmtNil, ifmtNil, ifmtL, 354 ifmtNil, ifmtNil, ifmtNil, ifmtNil, ifmtNil 355 }, 356 /*['R']*/ { 357 ifmtLLL, ifmtL, ifmtL, 5, ifmtL, ifmtL, 7, 358 ifmtXhYh, 5, ifmtL, ifmtL, 5, ifmtNil, 5, 359 ifmtNil, 26, 5, 14, 10, ifmtLLL, ifmtLLL, 360 10, 10, 15, ifmtNil, ifmtNil 361 }, 362 /*['S']*/ { 363 8, ifmtNil, ifmtNil, ifmtLL, ifmtL, ifmtNil, ifmtLLL, 364 ifmtLL, 31, ifmtNil, ifmtL, 6, ifmtLL, ifmtNil, 365 ifmtL, ifmtXhYh, 26, ifmtLL, ifmtLL, ifmtLL, ifmtNil, 366 ifmtLL, ifmtNil, 11, ifmtNil, ifmtLL 367 }, 368 /*['T']*/ { 369 ifmtNil, ifmtLLL, ifmtNil, ifmtNil, ifmtNil, ifmtNil, 7, 370 ifmtNil, ifmtNil, ifmtNil, ifmtNil, ifmtNil, ifmtLLL, 371 ifmtNil, ifmtNil, ifmtNil, ifmtNil, ifmtNil, ifmtNil, ifmtNil, 372 ifmtNil, ifmtNil, ifmtNil, ifmtNil, ifmtNil, ifmtNil 373 }, 374 /*['U']*/ { 375 ifmtNil, ifmtL, ifmtNil, ifmtNil, ifmtNil, ifmtNil, ifmtNil, 376 ifmtNil, ifmtNil, ifmtNil, ifmtNil, ifmtNil, ifmtNil, ifmtNil, 377 ifmtNil, ifmtNil, ifmtNil, 16, ifmtNil, ifmtNil, ifmtNil, 378 ifmtNil, 10, ifmtL, ifmtNil, ifmtNil 379 } 380 }; 381 382 private jmp_buf env; 383 384 /* these strange numbers were arrived at by the following observations: */ 385 /* Table 3-2 in spec gives the spacing values in mils */ 386 /* Using "Point Spacing" section on page 3-26 we compute that there are */ 387 /* approximately 286 points/inch on a 10.9 x 14.5 inch image area 388 /* I rounded to "reasonable" 4096th's of an inch */ 389 private int rgdxhSpace[sycharMax] = { 390 56, 51, 34, 31 391 }; 392 private int rgdyhSpace[sycharMax] = { 393 90, 81, 53, 48 394 }; 395 396 private FILE * fpSrc, *fpPsDst, *fpDbg; 397 private struct Params params; 398 399 private char *prog; 400 401 /* Outputs a conforming PostScript header to destination file */ 402 private CommentHeader(pparams) 403 struct Params *pparams; 404 { 405 long clock; 406 struct passwd *pswd; 407 char hostname[40]; 408 fprintf(fpPsDst, "%%!\n"); /* no reversal */ 409 fprintf(fpPsDst, "%%%%Creator: "); 410 pswd = getpwuid(getuid ()); 411 VOIDC gethostname(hostname, sizeof hostname); 412 fprintf(fpPsDst,"%s:%s (%s)\n",hostname,pswd->pw_name,pswd->pw_gecos); 413 414 fprintf(fpPsDst, "%%%%Title: %s\n", 415 ((pparams->scSrcFile == NULL) ? "stdin" : pparams->scSrcFile)); 416 417 fprintf(fpPsDst, "%%%%CreationDate: %s", 418 (VOIDC time(&clock), ctime(&clock))); 419 } 420 421 /* Filter some input characters that are ignored under all(?) circumstances */ 422 private ChGet(psts) 423 struct Sts *psts; 424 { 425 int ch; 426 427 while (TRUE) { 428 ch = getc (fpSrc); 429 switch (ch) { 430 case chEsc: 431 ch = ChEscapeAction (psts); 432 if (ch = chDel) 433 return (chDel); 434 else 435 longjmp (env, 1); 436 break; 437 case chFs: 438 FsAction (psts); 439 longjmp (env, 1); 440 break; 441 case chGs: 442 GsAction (psts); 443 longjmp (env, 1); 444 break; 445 } 446 if ((ch >= chEsc) || (ch == EOF) || ((ch >= chBell) && (ch < chSo))) 447 break; 448 } 449 return (ch); 450 } 451 452 /* Parse a 4110 31-bit integer parameter */ 453 private long LongGet(psts) 454 struct Sts *psts; 455 { 456 char ch; 457 long longT; 458 459 longT = 0; 460 while (TRUE) { 461 ch = ChGet (psts); 462 if (params.fDbg) 463 PrintLongByte (ch); 464 if ((ch >= chFstHiInt) && (ch <= chLstHiInt)) 465 longT = longT * 64 + (ch - chFstHiInt); 466 else 467 break; 468 } 469 if ((ch >= chFstLoPosInt) && (ch <= chLstLoPosInt)) 470 longT = longT * 16 + (ch - chFstLoPosInt); 471 else if ((ch >= chFstLoNegInt) && (ch <= chLstLoNegInt)) 472 longT = -(longT * 16 + (ch - chFstLoNegInt)); 473 else { 474 fprintf(stderr, 475 "%s: Error while parsing int, expecting low int char. ch = %d\n", 476 prog, ch); 477 longT = 0; 478 } 479 if (params.fDbg) 480 fprintf(fpDbg, "long: %ld\n", longT); 481 return (longT); 482 } 483 484 /* Parse an array of 32-bit integers */ 485 private GetAryLong (psts, arylong, ilongMax, pilongMac) 486 struct Sts *psts; 487 long arylong[]; 488 int ilongMax, *pilongMac; 489 { 490 int ilong, ilongMac; 491 492 if (params.fDbg) 493 fprintf(fpDbg, "AryLong - ilongMac = "); 494 ilongMac = LongGet (psts); 495 *pilongMac = (ilongMac < ilongMax) ? ilongMac : ilongMax; 496 for (ilong = 0; ilong < *pilongMac; ilong++) 497 arylong[ilong] = LongGet (psts); 498 for (ilong = *pilongMac; ilong < ilongMac; ilong++) VOIDC LongGet(psts); 499 } 500 501 /* Parse a 4100-format string parameter */ 502 private GetString (psts, sc, ichMax) 503 struct Sts *psts; 504 char *sc; 505 int ichMax; 506 { 507 int ich, ichMac; 508 char chT; 509 long longT; 510 511 if (params.fDbg) 512 fprintf(fpDbg, "String - length = "); 513 longT = LongGet (psts); 514 ichMac = (longT < ichMax - 1) ? longT : ichMax - 1; 515 for (ich = 0; ich < ichMac; ich++) { 516 sc[ich] = ChGet (psts); 517 if (params.fDbg) 518 PrintCmd (sc[ich]); 519 } 520 sc[ichMac] = '\0'; 521 for (ich = ichMac; ich < longT; ich++) { 522 chT = ChGet (psts); 523 if (params.fDbg) 524 PrintCmd (chT); 525 } 526 } 527 528 /* parse a 4110-format real parameter */ 529 private GetReal4110 (psts, preal4110) 530 struct Sts *psts; 531 struct Real4110 *preal4110; 532 { 533 if (params.fDbg) 534 fprintf(fpDbg, "Real4110: \n"); 535 preal4110->mantissa = LongGet (psts); 536 preal4110->exp = LongGet (psts); 537 } 538 539 /* parse a 4014 xy-coordinate */ 540 private GetXhYh (ch, psts, pxh, pyh) 541 char ch; 542 struct Sts *psts; 543 int *pxh, *pyh; 544 { 545 char chNxt; 546 547 if ((ch >= chFstCoord) && (ch < chFstLoX)) {/* it is a High Y */ 548 if (params.fDbg) 549 PrintAdrByte (ch, TRUE, FALSE); 550 psts->chHiY = ch; 551 ch = ChGet (psts); 552 } 553 554 if (ch >= chFstLoY) { 555 chNxt = ChGet (psts); 556 if ( /* psts->fHiRes && */ (chNxt >= chFstLoY)) { 557 if (params.fDbg) 558 PrintAdrByte (ch, FALSE, TRUE); 559 psts->chExtra = ch; 560 ch = chNxt; 561 chNxt = ChGet (psts); 562 } 563 if (params.fDbg) 564 PrintAdrByte (ch, FALSE, FALSE); 565 psts->chLoY = ch; 566 ch = chNxt; 567 } 568 if ((ch >= chFstCoord) && (ch < chFstLoX)) {/* it is a High X */ 569 if (params.fDbg) 570 PrintAdrByte (ch, FALSE, FALSE); 571 psts->chHiX = ch; 572 ch = ChGet (psts); 573 } 574 if ((ch < chFstLoX) || (ch >= chFstLoY)) { 575 fprintf(stderr, 576 "%s: Expecting Lo X Coordinate. ch = %d\n", prog, ch); 577 if (params.fDbg) 578 fprintf(fpDbg, 579 "Error: Expecting Lo X Coordinate. ch = %d\n", ch); 580 ch = chFstLoX; 581 } 582 if (params.fDbg) 583 PrintAdrByte (ch, FALSE, FALSE); 584 585 *pyh = ((psts->chHiY - chFstCoord) << shiftHiByte) 586 | ((psts->chExtra >> shiftYExtra) & mskLoBits) 587 | ((psts->chLoY - chFstLoY) << shiftLoByte); 588 *pxh = ((psts->chHiX - chFstCoord) << shiftHiByte) 589 | (psts->chExtra & mskLoBits) 590 | ((ch - chFstLoX) << shiftLoByte); 591 if (params.fDbg) 592 fprintf(fpDbg, "*pxh: %d or 0X%x, *pyh: %d or 0X%x\n", 593 *pxh, *pxh, *pyh, *pyh); 594 } 595 596 /* parse an array of xy-coordinates */ 597 private GetAryXhYh (psts, aryxh, aryyh, iMax, piMac) 598 struct Sts *psts; 599 int *aryxh, *aryyh; 600 int iMax, *piMac; 601 { 602 int i, iMac, xhT, yhT; 603 604 if (params.fDbg) 605 fprintf(fpDbg, "AryXyYh - length = "); 606 iMac = LongGet (psts); 607 *piMac = (iMac < iMax) ? iMac : iMax; 608 for (i = 0; i < *piMac; i++) 609 GetXhYh (ChGet (psts), psts, &aryxh[i], &aryyh[i]); 610 for (i = *piMac; i < iMac; i++) 611 GetXhYh (ChGet (psts), psts, &xhT, &yhT); 612 } 613 614 #define scMoveTo "%d %d m\n" 615 /* char *rgscMoveCmd[tymoveMax] = 616 { "", 617 "%d ml\n", 618 "%d mr\n", 619 "%d mu\n", 620 "%d md\n", 621 "%d md\n", 622 "" 623 }; 624 */ 625 626 /* Process a line-feed from the 4014 file: 627 Update the current position in the Sts - do NOT output any PostScript. 628 All PostScript marking commands move issue moveto commands 629 whenever necessary */ 630 private MoveDown (psts) 631 struct Sts *psts; 632 { 633 int xhLeftNew; 634 635 psts->yh -= rgdyhSpace[psts->sychar]; 636 if (psts->yh < 0) { 637 psts->yh = yhHome; 638 if (params.fMarg2) { 639 xhLeftNew = (psts->xhLeftMarg == xhMarg1) ? xhMarg2 : xhMarg1; 640 psts->xh = xhLeftNew + (psts->xh - psts->xhLeftMarg); 641 psts->xhLeftMarg = xhLeftNew; 642 } 643 } 644 } 645 646 /* Move the current position. No PostScript move commands are emitted. 647 PostScript marking commands (i.e. stroke) issue moveto's when needed */ 648 private MovePos (psts, tymove) 649 struct Sts *psts; 650 short tymove; 651 { 652 /* char *scMoveCmd; 653 #define scXMarg1 "%d cr1\n" 654 #define scXMarg2 "cr2\n" 655 656 if (psts->fMovePending) 657 fprintf(fpPsDst, scMoveTo, psts->xh, psts->yh); 658 psts->fMovePending = FALSE; 659 */ 660 switch (tymove) { 661 case tymoveNil: 662 return; 663 case tymoveLeft: 664 psts->xh -= rgdxhSpace[psts->sychar]; 665 if (psts->xh < psts->xhLeftMarg) 666 psts->xh = psts->xhLeftMarg; 667 /* fprintf(fpPsDst, rgscMoveCmd[tymove], psts->sychar); */ 668 break; 669 case tymoveRt: 670 psts->xh += rgdxhSpace[psts->sychar]; 671 if (psts->xh > xhMax) { 672 MoveDown (psts); 673 psts->xh = psts->xhLeftMarg; 674 } 675 /* fprintf(fpPsDst, rgscMoveCmd[tymove], psts->sychar); */ 676 break; 677 case tymoveUp: 678 psts->yh += rgdyhSpace[psts->sychar]; 679 /* fprintf(fpPsDst, rgscMoveCmd[tymove], psts->sychar); */ 680 break; 681 case tymoveGDown: 682 case tymoveDown: 683 MoveDown (psts); 684 if (params.fLfGenCr) 685 psts->xh = psts->xhLeftMarg; 686 /* if (params.fLfGenCr) 687 { fprintf(fpPsDst, scXMarg1, psts->sychar); 688 psts->xh = xhLeftMarg; 689 } 690 else fprintf(fpPsDst, rgscMoveCmd[tymove], psts->sychar); 691 */ 692 break; 693 case tymoveXMarg: 694 if (params.fCrGenLf) 695 MoveDown (psts); 696 psts->xh = psts->xhLeftMarg; 697 /* if (params.fCrGenLf) 698 { fprintf(fpPsDst, scXMarg1, psts->sychar); 699 psts->yh -= rgdyhSpace[psts->sychar]; 700 } 701 else fprintf(fpPsDst, scXMarg2); 702 */ 703 break; 704 } 705 psts->fMovePending = TRUE; 706 } 707 708 709 /* Process form feed */ 710 private EraseAndHome () 711 { 712 #define scEraseAndHome "erasepage\nxHome yHome m\n" 713 714 fprintf(fpPsDst, scEraseAndHome); 715 } 716 717 /* Process Etb character */ 718 private MakeCopy () 719 { 720 #define scMakeCopy "showpage\n" 721 722 fprintf(fpPsDst, scMakeCopy); 723 } 724 725 /* Process a movement/drawing command in on of the graphics modes */ 726 private VectorGoTo (psts, xhNew, yhNew) 727 struct Sts *psts; 728 int xhNew, yhNew; 729 { 730 #define scLineTo "%d %d rl\n" 731 732 if (psts->fPenDown) { 733 if (psts->syline != psts->sylinePrt) { 734 fprintf(fpPsDst, "%d SetLineStyle\n", psts->syline); 735 psts->sylinePrt = psts->syline; 736 } 737 if (psts->md == mdVector) { 738 if (psts->fMovePending) 739 fprintf(fpPsDst, scMoveTo, psts->xh, psts->yh); 740 fprintf(fpPsDst, scLineTo, xhNew - psts->xh, yhNew - psts->yh); 741 } 742 else { /* md = mdPtPlot */ 743 fprintf(fpPsDst, scMoveTo, xhNew, yhNew); 744 fprintf(fpPsDst, scLineTo, 0, 0); 745 } 746 psts->fVectorDrawn = TRUE; 747 } 748 psts->fMovePending = (!psts->fPenDown); 749 psts->xh = xhNew; 750 psts->yh = yhNew; 751 } 752 753 /* Emit a stoke command if there are any vector's pending */ 754 private Stroke (psts) 755 struct Sts *psts; 756 { 757 if (psts->fVectorDrawn && psts->fPenDown) { 758 fprintf(fpPsDst, "s\n"); 759 psts->fVectorDrawn = FALSE; 760 } 761 } 762 763 /* Emit a show command */ 764 private EmitShow (psts, scShow, ichFst, ichLim) 765 struct Sts *psts; 766 char scShow[]; 767 int ichFst, ichLim; 768 { 769 int ich; 770 771 if (psts->fMovePending) 772 fprintf(fpPsDst, scMoveTo, psts->xh, psts->yh); 773 psts->fMovePending = FALSE; 774 if (psts->sychar != psts->sycharPrt) { 775 fprintf(fpPsDst, "%d SetCharStyle\n", psts->sychar); 776 psts->sycharPrt = psts->sychar; 777 } 778 779 if (ichFst < ichLim) { 780 putc('\(', fpPsDst); 781 for (ich = ichFst; ich < ichLim; ich++) 782 putc(scShow[ich], fpPsDst); 783 fprintf(fpPsDst, ")sh\n"); 784 } 785 } 786 787 /* Output a string of characters to PostScript file. Deal with 788 line overflow and special character '\' */ 789 private Show (psts, scShow, cchShow) 790 struct Sts *psts; 791 char scShow[]; 792 int cchShow; 793 { 794 int ichFst, ich; 795 int xh, dxhSpace; 796 797 scShow[cchShow] = '\0'; 798 799 dxhSpace = rgdxhSpace[psts->sychar]; 800 ichFst = ich = 0; 801 xh = psts->xh; 802 while (ich < cchShow) { 803 if (scShow[ich] == '\\') 804 ich++; 805 xh += dxhSpace; 806 if (xh >= xhMax) { 807 EmitShow (psts, scShow, ichFst, ich); 808 ichFst = ich; 809 MoveDown (psts); 810 xh = psts->xh = psts->xhLeftMarg; 811 psts->fMovePending = TRUE; 812 } 813 ich++; 814 } 815 816 if (params.fDbg) 817 fprintf(fpDbg, "Show(%s)\n", scShow); 818 819 EmitShow (psts, scShow, ichFst, cchShow); 820 psts->xh = xh; 821 } 822 823 /* Process the <Fs> character */ 824 private FsAction (psts) 825 struct Sts *psts; 826 { 827 if (params.fDbg) 828 PrintCmd (chFs); 829 Stroke (psts); 830 psts->md = mdPtPlot; 831 } 832 833 /* Process the Graphic Shift character */ 834 private GsAction (psts) 835 struct Sts *psts; 836 { 837 if (params.fDbg) 838 PrintCmd (chGs); 839 Stroke (psts); 840 psts->fPenDown = FALSE; 841 psts->md = mdVector; 842 psts->syline = sylineNormal; 843 } 844 845 /* Process a sequence beginning with an Escape character. Return 846 the character following the Escape or the Del character if the 847 escape sequence is <Esc>? */ 848 private ChEscapeAction (psts) 849 struct Sts *psts; 850 { 851 int ch; 852 short sylineT; 853 854 ch = getc (fpSrc); 855 if (params.fDbg) 856 PrintEscCmd (ch); 857 while (ch != EOF) { 858 switch (ch) { 859 case chEnq: 860 Stroke (psts); 861 psts->md = mdBypass; 862 goto Done; 863 case chBell: 864 psts->fPenDown = TRUE; 865 goto Done; 866 case chBs: 867 MovePos (psts, tymoveLeft); 868 goto Done; 869 case chTab: 870 MovePos (psts, tymoveRt); 871 goto Done; 872 case chVTab: 873 MovePos (psts, tymoveUp); 874 goto Done; 875 case chFf: 876 EraseAndHome (); 877 goto Done; 878 case chSo: 879 psts->charset = charsetAlt; 880 goto Done; 881 case chSi: 882 psts->charset = charsetStd; 883 goto Done; 884 case chEtb: 885 Stroke (psts); 886 MakeCopy (); 887 goto Done; 888 case chCan: 889 Stroke (psts); 890 psts->md = mdBypass; 891 goto Done; 892 case chSub: 893 Stroke (psts); 894 psts->md = mdBypass; 895 goto Done; 896 case chFs: 897 Stroke (psts); 898 psts->md = mdSpecPtPlot; 899 goto Done; 900 case chGs: 901 GsAction (psts); 902 goto Done; 903 case chRs: 904 Stroke (psts); 905 psts->md = mdIncrPtPlot; 906 psts->dir = dirNil; 907 goto Done; 908 case chUs: 909 Stroke (psts); 910 psts->md = mdAlpha; 911 goto Done; 912 case '?': 913 ch = chDel; 914 goto Done; 915 default: 916 if ((ch >= chFstSychar) && (ch <= chLstSychar)) { 917 psts->sychar = (ch - chFstSychar); 918 goto Done; 919 } 920 else if ((ch >= chFstSyline) && (ch <= chLstSyline)) { 921 sylineT = ((ch - chFstSyline) & mskSyline); 922 if (sylineT < sylineMax) 923 psts->syline = sylineT; 924 else 925 psts->syline = sylineNormal; 926 /* What about Defocused? */ 927 goto Done; 928 } 929 else if ((ch >= chFst4110) && (ch <= chLst4110)) { 930 Skip4110 (ch, psts); 931 goto Done; 932 } 933 break; 934 } 935 ch = getc (fpSrc); 936 if (params.fDbg) 937 PrintCmd (ch); 938 } 939 Done: 940 if (params.fDbg) 941 PrintCr (); 942 return (ch); 943 } 944 945 /* Process some characters in one of the vector modes */ 946 private VectorAction (ch, psts) 947 char ch; 948 struct Sts *psts; 949 { 950 int xhNew, yhNew; 951 952 if ((ch >= chFstCoord) && (ch <= chLstCoord)) { 953 if (psts->md == mdIncrPtPlot) 954 IncrPtPlotAction (ch, psts); 955 else { 956 if ((psts->md != mdVector) && (psts->md != mdPtPlot)) 957 fprintf(stderr, "%s: Unimplemented vector mode: %d\n", 958 prog, psts->md); 959 960 GetXhYh (ch, psts, &xhNew, &yhNew); 961 VectorGoTo (psts, xhNew, yhNew); 962 psts->fPenDown = TRUE; 963 } 964 } 965 else { 966 if (params.fDbg) 967 PrintCmd (ch); 968 switch (ch) { 969 case chLf: 970 MovePos (psts, tymoveGDown); 971 break; 972 case chCr: 973 if (psts->fVectorDrawn) 974 MovePos (psts, tymoveXMarg); 975 psts->md = mdAlpha; 976 break; 977 case chUs: 978 psts->md = mdAlpha; 979 break; 980 } 981 } 982 } 983 984 /* Finish processing a sequence of characters in Incremental 985 Point Plot Mode by issuing an appropriate VectorGoTo */ 986 private DoIncrPtPlot (psts) 987 struct Sts *psts; 988 { 989 int xhNew; 990 int yhNew; 991 992 xhNew = psts->xh; 993 yhNew = psts->yh; 994 if (psts->dir & mskDirUp) 995 yhNew += psts->cincr; 996 else if (psts->dir & mskDirDown) 997 yhNew -= psts->cincr; 998 if (psts->dir & mskDirLeft) 999 xhNew -= psts->cincr; 1000 else if (psts->dir & mskDirRt) 1001 xhNew += psts->cincr; 1002 VectorGoTo (psts, xhNew, yhNew); 1003 psts->cincr = 0; 1004 } 1005 1006 /* Process a character in Incremental Point Plot Mode */ 1007 private IncrPtPlotAction (ch, psts) 1008 char ch; 1009 struct Sts *psts; 1010 { 1011 short fPenDown; 1012 short dir; 1013 1014 if (params.fDbg) 1015 PrintCmd (ch); 1016 fPenDown = psts->fPenDown; 1017 dir = psts->dir; 1018 if (ch == chSp) 1019 fPenDown = FALSE; 1020 else if (ch == 'P') 1021 fPenDown = TRUE; 1022 else 1023 dir = (ch & mskDir); 1024 if ((psts->dir == dir) && (psts->fPenDown == fPenDown) 1025 && (psts->dir != dirNil)) 1026 psts->cincr++; 1027 else { 1028 if (psts->dir != dirNil) 1029 DoIncrPtPlot (psts); 1030 psts->dir = dir; 1031 psts->cincr = 1; 1032 psts->fPenDown = fPenDown; 1033 } 1034 } 1035 1036 /* Process a character in bypass mode */ 1037 private BypassAction (ch, psts) 1038 char ch; 1039 struct Sts *psts; 1040 { 1041 if (params.fDbg) 1042 PrintCmd (ch); 1043 switch (ch) { 1044 case chLf: 1045 MovePos (psts, tymoveGDown); 1046 break; 1047 case chCr: 1048 MovePos (psts, tymoveXMarg); 1049 psts->md = mdAlpha; 1050 break; 1051 case chUs: 1052 psts->md = mdAlpha; 1053 break; 1054 } 1055 } 1056 1057 /* Some debug print routines and data */ 1058 private char *rgsc[0x21] = 1059 { 1060 "<Null>", "<Soh>", "<Stx>", "<Etx>", 1061 "<Eot>", "<Enq>", "<Ack>", "<Bell>", 1062 "<Bs>", "<Tab>", "<Lf>", "<VTab>", 1063 "<Ff>", "<Cr>", "<So>", "<Si>", 1064 "<Dle>", "<Dcl>", "<Dc2>", "<Dc3>", 1065 "<Dc4>", "<Nak>", "<Syn>", "<Etb>", 1066 "<Can>", "<Em>", "<Sub>", "<Esc>", 1067 "<Fs>", "<Gs>", "<Rs>", "<Us>", 1068 "<Sp>" 1069 }; 1070 1071 /* Concatenate a human-readable form of a character code to 1072 the supplied string */ 1073 private CatChName (ch, scDst) 1074 char ch; 1075 char scDst[]; 1076 { 1077 char *sc; 1078 char scT[3]; 1079 1080 if (ch < 0x21) 1081 sc = rgsc[ch]; 1082 else if (ch == chDel) 1083 sc = "<Del>"; 1084 else { 1085 scT[0] = ch; 1086 scT[1] = '\0'; 1087 sc = scT; 1088 } 1089 VOIDC strcat(scDst, sc); 1090 } 1091 1092 /* Output a line of test output for the given command character */ 1093 private PrintCmd (ch) 1094 char ch; 1095 { 1096 char scPrint[100]; 1097 1098 scPrint[0] = '\0'; 1099 CatChName (ch, scPrint); 1100 VOIDC strcat(scPrint, "\n"); 1101 fprintf(fpDbg, scPrint); 1102 } 1103 1104 /* Print a line of test output for and Escape command */ 1105 private PrintEscCmd (ch) 1106 char ch; 1107 { 1108 char scPrint[100]; 1109 1110 VOIDC strcpy(scPrint, "<Esc> "); 1111 CatChName(ch, scPrint); 1112 fprintf(fpDbg, scPrint); 1113 } 1114 1115 /* Print some diagnostic info on a vector-mode address byte */ 1116 private PrintAdrByte (ch, fHiY, fExtra) 1117 char ch; 1118 char fHiY, fExtra; 1119 { 1120 if (ch < chFstCoord) { 1121 fprintf(fpDbg, "Bad Vector Command"); 1122 PrintCmd (ch); 1123 } 1124 else if (ch < chFstLoX) { 1125 if (fHiY) 1126 fprintf(fpDbg, "yHi: %x ", ch - chFstCoord); 1127 else 1128 fprintf(fpDbg, "xHi: %x ", ch - chFstCoord); 1129 } 1130 else if (ch < chFstLoY) 1131 fprintf(fpDbg, "xLo: %x\n", ch - chFstLoX); 1132 else if (ch <= chLstCoord) { 1133 if (fExtra) 1134 fprintf(fpDbg, "x12: %x y12: %x margin bit: %s ", 1135 ch & mskLoBits, 1136 (ch >> shiftYExtra) & mskLoBits, 1137 (ch & mskBit4) ? "TRUE" : "FALSE"); 1138 else 1139 fprintf(fpDbg, "yLo: %x ", ch - chFstLoY); 1140 } 1141 else { 1142 fprintf(fpDbg, "Bad Vector Command"); 1143 PrintCmd (ch); 1144 } 1145 } 1146 1147 /* Print some diagnostic info on a 32-bit integer parameter byte */ 1148 private PrintLongByte (ch) 1149 char ch; 1150 { 1151 if (ch < chFstLoNegInt) { 1152 fprintf(fpDbg, "Bad Integer Command"); 1153 PrintCmd (ch); 1154 } 1155 else if (ch < chFstLoPosInt) 1156 fprintf(fpDbg, "iLoNeg: (-) %x, ", ch - chFstLoNegInt); 1157 else if (ch < chFstHiInt) 1158 fprintf(fpDbg, "iLoPos: %x, ", ch - chFstLoPosInt); 1159 else if (ch <= chLstHiInt) 1160 fprintf(fpDbg, "iHi: %x, ", ch - chFstHiInt); 1161 else { 1162 fprintf(fpDbg, "Bad Vector Command"); 1163 PrintCmd (ch); 1164 } 1165 } 1166 1167 private PrintCr () { 1168 putc('\n', fpDbg); 1169 } 1170 1171 /* 4110 Command Scanner */ 1172 private Skip4110 (ch, psts) 1173 struct Sts *psts; 1174 char ch; 1175 { 1176 char chNxt; 1177 int ifmt, i, iprm, xh, yh; 1178 char *pfmt; 1179 long longT; 1180 #define ichScMax 32 1181 char sc[ichScMax]; 1182 struct Real4110 realT; 1183 1184 chNxt = ChGet (psts); 1185 if (params.fDbg) { 1186 PrintCmd (chNxt); 1187 fprintf(fpDbg, " "); 1188 } 1189 if ((ch < chFst4110) || (ch > chLst4110) || (chNxt < chFstEsc2) 1190 || (chNxt > chLstEsc2)) { 1191 if (params.fDbg) 1192 fprintf(fpDbg, "Bad 4110 command: %c%c\n", ch, chNxt); 1193 fprintf(stderr, "%s: Bad 4110 command: %c%c\n", prog, ch, chNxt); 1194 return; 1195 } 1196 if ((ch == 'S') && (chNxt == 'I')) { 1197 /* this one command takes five parameters 1198 */ 1199 longT = LongGet (psts); 1200 GetReal4110 (psts, &realT); 1201 GetReal4110 (psts, &realT); 1202 GetReal4110 (psts, &realT); 1203 GetXhYh (ChGet (psts), psts, &xh, &yh); 1204 return; 1205 } 1206 ifmt = aryaryifmt[ch - chFst4110][chNxt - chFstEsc2]; 1207 pfmt = aryfmt[ifmt]; 1208 for (iprm = 0; iprm < iprmMax; iprm++) { 1209 switch (pfmt[iprm]) { 1210 case typrmNil: 1211 goto Exit; 1212 case typrmLong: 1213 longT = LongGet (psts); 1214 break; 1215 case typrmAryLong: 1216 GetAryLong (psts, &longT, 1, &i); 1217 break; 1218 case typrmXhYh: 1219 GetXhYh (ChGet (psts), psts, &xh, &yh); 1220 break; 1221 case typrmAryXhYh: 1222 GetAryXhYh (psts, &xh, &yh, 1, &i); 1223 break; 1224 case typrmString: 1225 GetString (psts, sc, ichScMax); 1226 break; 1227 case typrmReal4110: 1228 GetReal4110 (psts, &realT); 1229 break; 1230 case typrmCh: 1231 VOIDC ChGet (psts); 1232 break; 1233 } 1234 } 1235 Exit: 1236 return; 1237 } 1238 1239 /* 4104 Parser */ 1240 private Convert4014 () { 1241 struct Sts stsCur; 1242 #define chLim 0x80 1243 short rgtymove[chLim]; 1244 short tymoveT; 1245 int ch; 1246 #define ichShowMax 500 1247 char scShow[ichShowMax]; 1248 int ichShowCur; 1249 int chT; 1250 1251 ichShowCur = 0; 1252 stsCur.md = mdAlpha; 1253 stsCur.xh = xhHome; 1254 stsCur.xhLeftMarg = xhHome; 1255 stsCur.yh = yhHome; 1256 stsCur.syline = stsCur.sylinePrt = sylineNormal; 1257 stsCur.sychar = stsCur.sycharPrt = sycharLarge; 1258 stsCur.charset = stsCur.charsetPrt = charsetStd; 1259 stsCur.fPenDown = FALSE; 1260 stsCur.fMovePending = FALSE; 1261 stsCur.fVectorDrawn = FALSE; 1262 stsCur.cincr = 0; 1263 1264 for (chT = 0; chT < chLim; chT++) 1265 rgtymove[chT] = tymoveNil; 1266 rgtymove[chBs] = tymoveLeft; 1267 rgtymove[chTab] = tymoveRt; 1268 rgtymove[chLf] = tymoveDown; 1269 rgtymove[chVTab] = tymoveUp; 1270 rgtymove[chCr] = tymoveXMarg; 1271 rgtymove[chSp] = tymoveRt; 1272 1273 VOIDC setjmp(env); 1274 1275 ch = getc(fpSrc); 1276 while (ch != EOF) { 1277 if ((stsCur.md != mdIncrPtPlot) && (stsCur.cincr != 0)) 1278 DoIncrPtPlot (&stsCur); 1279 if ((stsCur.md == mdAlpha) && 1280 (ch >= chFstShow) && (ch <= chLstShow)) { 1281 if (ichShowCur >= ichShowMax - 2) { 1282 Show (&stsCur, scShow, ichShowCur); 1283 ichShowCur = 0; 1284 } 1285 if ((ch == '(') || (ch == ')') || (ch == '\\')) 1286 scShow[ichShowCur++] = '\\'; 1287 scShow[ichShowCur++] = ch; 1288 } 1289 else { 1290 if (ichShowCur > 0) { 1291 Show (&stsCur, scShow, ichShowCur); 1292 ichShowCur = 0; 1293 } 1294 switch (ch) { 1295 case chEsc: 1296 ch = ChEscapeAction (&stsCur); 1297 if (ch == chDel) 1298 continue; 1299 break; 1300 case chBell: 1301 if (params.fDbg) 1302 PrintCmd (ch); 1303 stsCur.fPenDown = TRUE; 1304 break; 1305 case chFs: 1306 FsAction (&stsCur); 1307 break; 1308 case chGs: 1309 GsAction (&stsCur); 1310 break; 1311 case chRs: 1312 if (params.fDbg) 1313 PrintCmd (ch); 1314 Stroke (&stsCur); 1315 stsCur.md = mdIncrPtPlot; 1316 stsCur.dir = dirNil; 1317 break; 1318 default: 1319 switch (stsCur.md) { 1320 case mdAlpha: 1321 Stroke (&stsCur); 1322 if ((tymoveT = rgtymove[ch]) != tymoveNil) 1323 MovePos (&stsCur, tymoveT); 1324 if (params.fDbg) 1325 PrintCmd (ch); 1326 break; 1327 case mdVector: 1328 case mdPtPlot: 1329 case mdSpecPtPlot: 1330 case mdIncrPtPlot: 1331 VectorAction (ch, &stsCur); 1332 break; 1333 case mdBypass: 1334 BypassAction (ch, &stsCur); 1335 break; 1336 default: 1337 fprintf(stderr, "%s: Illegal mode\n",prog); 1338 exit (2); 1339 break; 1340 } 1341 break; 1342 } 1343 } 1344 ch = getc (fpSrc); 1345 } 1346 MakeCopy (); 1347 } 1348 1349 #define ARGS "RCNmp:d:l:s:S:" 1350 #define USAGE "ps4014 [-RCNm] [-p outfile] [-l left,bottom] [-s width,height] [-S width] [file]" 1351 1352 main(argc, argv) 1353 int argc; 1354 char *argv[]; 1355 { 1356 register int argp; 1357 extern int optind; 1358 extern char *optarg; 1359 char *libdir; 1360 1361 params.scSrcFile = NULL; 1362 params.scDstFile = NULL; 1363 params.scDbgFile = NULL; 1364 params.fDbg = FALSE; 1365 params.fLfGenCr = TRUE; 1366 params.fCrGenLf = TRUE; 1367 params.fMarg2 = FALSE; 1368 /* these numbers make the image occupy almost the whole page 1369 with the correct proportions */ 1370 params.xRtInch = 0.38; 1371 params.yBotInch = 0.35; 1372 params.dxWidInch = 10.24; 1373 params.dyHtInch = 7.8; 1374 params.fLandscape = TRUE; 1375 1376 prog = *argv; 1377 1378 while ((argp = getopt(argc, argv, ARGS)) != EOF) { 1379 switch (argp) { 1380 case 'R': 1381 params.fLandscape = FALSE; 1382 break; 1383 case 'C': 1384 params.fCrGenLf = FALSE; 1385 break; 1386 case 'N': 1387 params.fLfGenCr = FALSE; 1388 break; 1389 case 'm': 1390 params.fMarg2 = TRUE; 1391 break; 1392 case 'p': 1393 params.scDstFile = optarg; 1394 break; 1395 case 'd': 1396 params.scDbgFile = optarg; 1397 break; 1398 case 'l': 1399 if (sscanf(optarg, " %f,%f", 1400 ¶ms.xRtInch,¶ms.yBotInch) != 2) { 1401 fprintf(stderr,"%s: bad parameter -l%s\n",prog,optarg); 1402 exit(2); 1403 } 1404 break; 1405 case 's': 1406 if (sscanf(optarg, " %f,%f", 1407 ¶ms.dxWidInch,¶ms.dyHtInch) != 2) { 1408 fprintf(stderr,"%s: bad parameter -s%s\n",prog,optarg); 1409 exit(2); 1410 } 1411 break; 1412 case 'S': 1413 if (sscanf(optarg, " %f", 1414 ¶ms.dxWidInch) != 1) { 1415 fprintf(stderr,"%s: bad parameter -S%s\n",prog,optarg); 1416 exit(2); 1417 } 1418 params.dyHtInch = 0; 1419 break; 1420 case '?': 1421 default: 1422 fprintf(stderr,"%s: bad option -%c\n",prog,argp); 1423 exit(2); 1424 } 1425 } 1426 if ((optind + 1) < argc) { 1427 fprintf(stderr,"%s: %s\n", USAGE); 1428 exit(2); 1429 } 1430 if (optind < argc) { 1431 params.scSrcFile = argv[optind]; 1432 if ((fpSrc = fopen(params.scSrcFile, "r")) == NULL) { 1433 fprintf(stderr,"%s: can't open %s\n",prog,params.scSrcFile); 1434 exit(2); 1435 } 1436 } 1437 else fpSrc = stdin; 1438 1439 if (params.scDstFile == NULL) 1440 fpPsDst = stdout; 1441 else { 1442 if ((fpPsDst = fopen(params.scDstFile, "w")) == NULL) { 1443 fprintf(stderr,"%s: can't open output file %s\n", 1444 prog,params.scDstFile); 1445 exit(2); 1446 } 1447 } 1448 if (params.scDbgFile != NULL) { 1449 if ((fpDbg = fopen(params.scDbgFile, "w")) == NULL) { 1450 fprintf(stderr,"%s: can't open debug file %s\n", 1451 prog, params.scDbgFile); 1452 exit(2); 1453 } 1454 params.fDbg = TRUE; 1455 } 1456 if ((libdir = envget("PSLIBDIR")) == NULL) libdir = LibDir; 1457 VOIDC mstrcat(scProlog,libdir,PS4014PRO,sizeof scProlog); 1458 CommentHeader (¶ms); 1459 putc('\n', fpPsDst); 1460 1461 if (copyfile(scProlog,fpPsDst) != 0) { 1462 fprintf(stderr,"%s: trouble copying prolog file %s\n",prog,scProlog); 1463 exit(2); 1464 } 1465 /* rotate and translate before we scale */ 1466 if (params.fLandscape) 1467 fprintf(fpPsDst, "90 rotate 0 -8.5 inch translate\n"); 1468 fprintf(fpPsDst, "%g inch %g inch translate\n", 1469 params.xRtInch, params.yBotInch); 1470 if (params.dyHtInch == 0) { /* we got a dxWidInch but not a dyHtInch */ 1471 /* -> we are scaling y axis proportional to x axis */ 1472 params.dyHtInch = (params.dxWidInch * yhMax) / xhMax; 1473 } 1474 fprintf(fpPsDst, "/dxWidInch %g def\n", params.dxWidInch); 1475 fprintf(fpPsDst, "/dyHtInch %g def\n", params.dyHtInch); 1476 fprintf(fpPsDst, 1477 "ScaleCoords\n0 SetCharStyle\n0 SetLineStyle\nxHome yHome moveto\n"); 1478 1479 Convert4014 (); 1480 1481 fprintf(fpPsDst, "\n%%%%Trailer\ngrestore\n"); 1482 fprintf(fpPsDst, "ps4014sav restore\n"); 1483 1484 VOIDC fclose(fpPsDst); 1485 VOIDC fclose(fpSrc); 1486 if (fpDbg != NULL) VOIDC fclose(fpDbg); 1487 exit(0); 1488 1489 } 1490