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 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 struct Real4110 {
63 long mantissa, exp;
64 }; /* 4110-format real number */
65 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 */
CommentHeader(pparams)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 */
ChGet(psts)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 */
LongGet(psts)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 */
GetAryLong(psts,arylong,ilongMax,pilongMac)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 */
GetString(psts,sc,ichMax)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 */
GetReal4110(psts,preal4110)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 */
GetXhYh(ch,psts,pxh,pyh)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 */
GetAryXhYh(psts,aryxh,aryyh,iMax,piMac)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 */
MoveDown(psts)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 */
MovePos(psts,tymove)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 */
EraseAndHome()710 private EraseAndHome ()
711 {
712 #define scEraseAndHome "erasepage\nxHome yHome m\n"
713
714 fprintf(fpPsDst, scEraseAndHome);
715 }
716
717 /* Process Etb character */
MakeCopy()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 */
VectorGoTo(psts,xhNew,yhNew)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 */
Stroke(psts)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 */
EmitShow(psts,scShow,ichFst,ichLim)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 '\' */
Show(psts,scShow,cchShow)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 */
FsAction(psts)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 */
GsAction(psts)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>? */
ChEscapeAction(psts)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 */
VectorAction(ch,psts)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 */
DoIncrPtPlot(psts)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 */
IncrPtPlotAction(ch,psts)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 */
BypassAction(ch,psts)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 */
CatChName(ch,scDst)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 */
PrintCmd(ch)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 */
PrintEscCmd(ch)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 */
PrintAdrByte(ch,fHiY,fExtra)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 */
PrintLongByte(ch)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
PrintCr()1167 private PrintCr () {
1168 putc('\n', fpDbg);
1169 }
1170
1171 /* 4110 Command Scanner */
Skip4110(ch,psts)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 */
Convert4014()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
main(argc,argv)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