|
|
1.1 root 1: /*
2: * (c) Copyright 1986, Xerox Corporation
3: *
4: * pl2ip: convert Unix plot format to and interpress master
5: *
6: * Generally, this program is straightforward. The main complication comes
7: * from the desire to string contigious lines into one Interpress trajectory.
8: * The main modivation for this is to provide for nice dashed lines on printers
9: * that accept IP 3.0 and higher. It can also be used to round the corners
10: * of other lines.
11: *
12: * HISTORY
13: * 22-Apr-86 Lee Moore (lee) at Xerox Webster Research Center
14: * Created.
15: *
16: */
17:
18: #include <stdio.h>
19: #include "iptokens.h"
20: #include "operator.h"
21: #include "literal.h"
22:
23: /* #define DEBUG /* */
24:
25: #define MAXSTRINGSIZE 128
26:
27: #define TRUE 1
28: #define FALSE 0
29:
30: #define F_font 10
31: #define STROKE_WIDTH 15L /* was 50 */ /* width for drawing lines */
32: #define STROKEEND_BUTT 1L /* end lines hard */
33:
34: int HaveTrajectory = FALSE, /* is a trajectory being built? */
35: CurrentX = 0, /* the current X position */
36: CurrentY = 0, /* the current Y position */
37: Pitch = 10; /* pitch of the default font */
38:
39:
40: /*
41: * declare the Unix plot commands
42: */
43:
44: #define MOVECMD 'm'
45: #define CONTCMD 'n'
46: #define POINTCMD 'p'
47: #define LINECMD 'l'
48: #define LABELCMD 't'
49: #define ARCCMD 'a'
50: #define CIRCLECMD 'c'
51: #define ERASECMD 'e'
52: #define LINEMODCMD 'f'
53: #define SPACECMD 's'
54:
55:
56: main(argc, argv)
57: int argc;
58: char *argv[]; {
59: char *outputName = NULL;
60: int command, ipFD,
61: textSize = 8, /* size of text (in points) */
62: c;
63: extern int optind;
64: extern char *optarg;
65:
66: while ((c = getopt(argc, argv, "o:s:")) != EOF)
67: switch (c) {
68: case 'o':
69: outputName = optarg;
70: break;
71:
72: case 's':
73: textSize = atoi(optarg);
74: break;
75: }
76:
77:
78: if( outputName != NULL ) {
79: if( (ipFD = creat(outputName, 0644)) < 0 ) {
80: fprintf(stderr, "pl2ip: can't open %s for writing\n", outputName);
81: exit(1);
82: }
83: } else
84: ipFD = 1; /* std. output */
85:
86: ip_select(ipFD);
87: AppendOp(OP_beginBlock);
88: AppendOp(OP_beginBody);
89: AppendOp(OP_endBody); /* end preamble */
90: AppendOp(OP_beginBody); /* begin page 1 */
91: #ifdef notdef
92: SetupFont("Xerox/XC1-1-1/Classic", (10.*2.54)/(72.0*100.0), F_font);
93: Setfont(F_font);
94: #else
95: AppendIdentifier("Xerox");
96: AppendIdentifier("XC1-1-1");
97: AppendIdentifier("Terminal");
98: AppendInteger(3L);
99: AppendOp(OP_makevec);
100: AppendOp(OP_findfont);
101: AppendRational(4096L * textSize, 36L*13);
102: AppendOp(OP_scale);
103: AppendOp(OP_modifyfont);
104: AppendInteger((long) I_font);
105: AppendOp(OP_iset);
106: #endif
107:
108: /* set coordinate system */
109: AppendRational( (long)(6.5*2.54*100.0 + .5), 4096L*100L*100L);
110: AppendOp(OP_scale);
111: AppendOp(OP_concatt);
112:
113: /* set the stroke width */
114: AppendInteger(STROKE_WIDTH); /* stroke width */
115: AppendInteger(15L); /* stroke width imager variable */
116: AppendOp(OP_iset);
117:
118: #ifdef notdef
119: /* set stroke end */
120: AppendInteger(STROKEEND_BUTT);
121: AppendInteger(16L); /* stroke end imager variable */
122: AppendOp(OP_iset);
123: #endif
124:
125: while( (command = getchar()) != EOF ) {
126: switch( command ) {
127: case MOVECMD: move(); break;
128: case CONTCMD: cont(); break;
129: case POINTCMD: point(); break;
130: case LINECMD: line(); break;
131: case LABELCMD: label(); break;
132: case ARCCMD: arc(); break;
133: case CIRCLECMD: circle(); break;
134: case ERASECMD: erase(); break;
135: case LINEMODCMD: lineMod(); break;
136: case SPACECMD: space(); break;
137:
138: default:
139: printf("unknown command: ");
140:
141: if( command <= ' ' || command >= 0177 )
142: printf("\\%03o", command);
143: else
144: putchar(command);
145:
146: putchar('\n');
147: }
148: }
149:
150: if( HaveTrajectory )
151: ShowTrajectory();
152:
153: /* wrap it up */
154: AppendOp(OP_endBody);
155: AppendOp(OP_endBlock);
156: ip_flush();
157: exit(0);
158: }
159:
160: getShort() {
161: unsigned char c;
162:
163: c = getchar();
164: return (getchar() << 8) | c;
165: }
166:
167:
168: /*
169: * move: The next four bytes give a new currect point
170: *
171: * The problem here is that there are two kind of moves: those
172: * for lines and those for characters. We try to keep the apart.
173: */
174:
175: move() {
176: if( HaveTrajectory )
177: ShowTrajectory();
178:
179: CurrentX = getShort();
180: CurrentY = getShort();
181: #ifdef DEBUG
182: printf("move to (%d, %d)\n", CurrentX, CurrentY);
183: #endif DEBUG
184: }
185:
186:
187: /*
188: * cont: Draw a line from the current point to the point given by the next
189: * four bytes. See plot(1g)
190: */
191:
192: cont() {
193: int x, y;
194:
195: x = getShort();
196: y = getShort();
197: #ifdef DEBUG
198: printf("continue to (%d, %d)\n", x, y);
199: #endif DEBUG
200:
201: if( ! HaveTrajectory ) {
202: AppendInteger((long) CurrentX);
203: AppendInteger((long) CurrentY);
204: AppendOp(OP_moveto);
205: HaveTrajectory = TRUE;
206: }
207:
208: AppendInteger((long) x);
209: AppendInteger((long) y);
210: AppendOp(OP_lineto);
211: CurrentX = x;
212: CurrentY = y;
213: }
214:
215:
216: /*
217: * point: Plot the point given by the next four bytes.
218: */
219:
220: point() {
221: int x, y;
222:
223: if( HaveTrajectory )
224: ShowTrajectory();
225:
226: x = getShort();
227: y = getShort();
228: #ifdef DEBUG
229: printf("point at (%d, %d)\n", x, y);
230: #endif DEBUG
231: AppendInteger((long) x);
232: AppendInteger((long) y);
233: CurrentX = x;
234: CurrentY = y;
235: }
236:
237:
238: /*
239: * line: Draw a line from the point given by the next four bytes to the point
240: * given by the following four bytes.
241: */
242:
243: line() {
244: int x0, y0, x1, y1;
245:
246: x0 = getShort();
247: y0 = getShort();
248: x1 = getShort();
249: y1 = getShort();
250: #ifdef DEBUG
251: printf("line from (%d, %d) to (%d, %d)\n", x0, y0, x1, y1);
252: #endif DEBUG
253:
254: if( ! HaveTrajectory ) {
255: AppendInteger((long) x0);
256: AppendInteger((long) y0);
257: AppendOp(OP_moveto); }
258: else
259: if( x0 != CurrentX || y0 != CurrentY ) {
260: ShowTrajectory();
261:
262: AppendInteger((long) x0);
263: AppendInteger((long) y0);
264: AppendOp(OP_moveto); }
265:
266: AppendInteger((long) x1);
267: AppendInteger((long) y1);
268: AppendOp(OP_lineto);
269: HaveTrajectory = TRUE;
270: CurrentX = x1;
271: CurrentY = y1;
272: }
273:
274:
275: /*
276: * label: Place the following ASCII string so that its first character falls
277: * on the current point. The string is terminated by a newline.
278: *
279: * Unspoken in the documentation but implied by practice is
280: * that the current position is changed to the end of text string.
281: * This artifact can cause problems because we don't know the width
282: * of characters in a font.
283: */
284:
285: label() {
286: char labelString[MAXSTRINGSIZE];
287:
288: if( HaveTrajectory ) {
289: printf("pl2ip: opps trying to put text at end of line!\n");
290: ShowTrajectory();
291: }
292:
293: (void) gets(labelString);
294: #ifdef DEBUG
295: printf("output label string: '%s'\n", labelString);
296: #endif DEBUG
297: AppendInteger((long) CurrentX);
298: AppendInteger((long) CurrentY);
299: AppendOp(OP_setxy);
300: AppendString(labelString);
301: AppendOp(OP_show);
302:
303: CurrentX += strlen(labelString)*(4096.0/(Pitch * 6.5)) + .4999999;
304: }
305:
306:
307: /*
308: * arc: The first four bytes give the center, the next four give the starting
309: * proint and the last four give the end point of a circular arc. The
310: * least significant coordinate of the end point is used to only to
311: * determine the quadrant. The arc is drawn counter-clockwise.
312: */
313:
314: arc() {
315: #ifdef DEBUG
316: int centerX, centerY,
317: startX, startY,
318: endX, endY;
319:
320: if( HaveTrajectory )
321: ShowTrajectory();
322:
323: centerX = getShort();
324: centerY = getShort();
325: startX = getShort();
326: startY = getShort();
327: endX = getShort();
328: endY = getShort();
329: printf("arc with center (%d, %d), starting at (%d, %d) and ending at (%d, %d)\n", centerX, centerY, startX, startY, endX, endY);
330: #endif DEBUG
331: }
332:
333:
334: /*
335: * circle: The first four bytes give the center of the circle, the next
336: * two the radius.
337: */
338:
339: circle() {
340: #ifdef DEBUG
341: int centerX, centerY,
342: radius;
343:
344: if( HaveTrajectory )
345: ShowTrajectory();
346:
347: centerX = getShort();
348: centerY = getShort();
349: radius = getShort();
350: printf("circle at (%d, %d) with radius %d\n", centerX, centerY, radius);
351: #endif DEBUG
352: }
353:
354:
355: /*
356: * erase: Start another frame of output
357: */
358:
359: erase() {
360: if( HaveTrajectory )
361: ShowTrajectory();
362:
363: #ifdef DEBUG
364: printf("erase\n");
365: #endif DEBUG
366: }
367:
368:
369: /*
370: * linemod: Take the following string, up to a newline, as the style for
371: * drawing further lines. The syles are 'dotted', 'solid', 'longdashed',
372: * 'shortdashed', and 'dotdashed'.
373: */
374:
375: lineMod() {
376: char lineType[MAXSTRINGSIZE];
377:
378: if( HaveTrajectory )
379: ShowTrajectory();
380:
381: (void) gets(lineType);
382: #ifdef DEBUG
383: printf("change line mode to '%s'\n", lineType);
384: #endif DEBUG
385: }
386:
387: /*
388: * space: The next four bytes give the lower left corner of the plotting area;
389: * the following four give the upper right corner. The plot will be
390: * magnified or reduced to fit the device as closely as possible.
391: */
392:
393: space() {
394: #ifdef DEBUG
395: int lowerLeftX, lowerLeftY,
396: upperRightX, upperRightY;
397:
398: lowerLeftX = getShort();
399: lowerLeftY = getShort();
400: upperRightX = getShort();
401: upperRightY = getShort();
402: printf("space with lower left at (%d, %d) and upper right at (%d, %d)\n", lowerLeftX, lowerLeftY, upperRightX, upperRightY);
403: #endif DEBUG
404: }
405:
406:
407: /*
408: * draw the current trajectory
409: */
410:
411: ShowTrajectory() {
412: AppendOp(OP_maskstroke);
413: HaveTrajectory = FALSE;
414: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.