|
|
BSD 4.3tahoe
/*
* (c) Copyright 1986, Xerox Corporation
*
* pl2ip: convert Unix plot format to and interpress master
*
* Generally, this program is straightforward. The main complication comes
* from the desire to string contigious lines into one Interpress trajectory.
* The main modivation for this is to provide for nice dashed lines on printers
* that accept IP 3.0 and higher. It can also be used to round the corners
* of other lines.
*
* HISTORY
* 22-Apr-86 Lee Moore (lee) at Xerox Webster Research Center
* Created.
*
*/
#include <stdio.h>
#include "iptokens.h"
#include "operator.h"
#include "literal.h"
/* #define DEBUG /* */
#define MAXSTRINGSIZE 128
#define TRUE 1
#define FALSE 0
#define F_font 10
#define STROKE_WIDTH 15L /* was 50 */ /* width for drawing lines */
#define STROKEEND_BUTT 1L /* end lines hard */
int HaveTrajectory = FALSE, /* is a trajectory being built? */
CurrentX = 0, /* the current X position */
CurrentY = 0, /* the current Y position */
Pitch = 10; /* pitch of the default font */
/*
* declare the Unix plot commands
*/
#define MOVECMD 'm'
#define CONTCMD 'n'
#define POINTCMD 'p'
#define LINECMD 'l'
#define LABELCMD 't'
#define ARCCMD 'a'
#define CIRCLECMD 'c'
#define ERASECMD 'e'
#define LINEMODCMD 'f'
#define SPACECMD 's'
main(argc, argv)
int argc;
char *argv[]; {
char *outputName = NULL;
int command, ipFD,
textSize = 8, /* size of text (in points) */
c;
extern int optind;
extern char *optarg;
while ((c = getopt(argc, argv, "o:s:")) != EOF)
switch (c) {
case 'o':
outputName = optarg;
break;
case 's':
textSize = atoi(optarg);
break;
}
if( outputName != NULL ) {
if( (ipFD = creat(outputName, 0644)) < 0 ) {
fprintf(stderr, "pl2ip: can't open %s for writing\n", outputName);
exit(1);
}
} else
ipFD = 1; /* std. output */
ip_select(ipFD);
AppendOp(OP_beginBlock);
AppendOp(OP_beginBody);
AppendOp(OP_endBody); /* end preamble */
AppendOp(OP_beginBody); /* begin page 1 */
#ifdef notdef
SetupFont("Xerox/XC1-1-1/Classic", (10.*2.54)/(72.0*100.0), F_font);
Setfont(F_font);
#else
AppendIdentifier("Xerox");
AppendIdentifier("XC1-1-1");
AppendIdentifier("Terminal");
AppendInteger(3L);
AppendOp(OP_makevec);
AppendOp(OP_findfont);
AppendRational(4096L * textSize, 36L*13);
AppendOp(OP_scale);
AppendOp(OP_modifyfont);
AppendInteger((long) I_font);
AppendOp(OP_iset);
#endif
/* set coordinate system */
AppendRational( (long)(6.5*2.54*100.0 + .5), 4096L*100L*100L);
AppendOp(OP_scale);
AppendOp(OP_concatt);
/* set the stroke width */
AppendInteger(STROKE_WIDTH); /* stroke width */
AppendInteger(15L); /* stroke width imager variable */
AppendOp(OP_iset);
#ifdef notdef
/* set stroke end */
AppendInteger(STROKEEND_BUTT);
AppendInteger(16L); /* stroke end imager variable */
AppendOp(OP_iset);
#endif
while( (command = getchar()) != EOF ) {
switch( command ) {
case MOVECMD: move(); break;
case CONTCMD: cont(); break;
case POINTCMD: point(); break;
case LINECMD: line(); break;
case LABELCMD: label(); break;
case ARCCMD: arc(); break;
case CIRCLECMD: circle(); break;
case ERASECMD: erase(); break;
case LINEMODCMD: lineMod(); break;
case SPACECMD: space(); break;
default:
printf("unknown command: ");
if( command <= ' ' || command >= 0177 )
printf("\\%03o", command);
else
putchar(command);
putchar('\n');
}
}
if( HaveTrajectory )
ShowTrajectory();
/* wrap it up */
AppendOp(OP_endBody);
AppendOp(OP_endBlock);
ip_flush();
exit(0);
}
getShort() {
unsigned char c;
c = getchar();
return (getchar() << 8) | c;
}
/*
* move: The next four bytes give a new currect point
*
* The problem here is that there are two kind of moves: those
* for lines and those for characters. We try to keep the apart.
*/
move() {
if( HaveTrajectory )
ShowTrajectory();
CurrentX = getShort();
CurrentY = getShort();
#ifdef DEBUG
printf("move to (%d, %d)\n", CurrentX, CurrentY);
#endif DEBUG
}
/*
* cont: Draw a line from the current point to the point given by the next
* four bytes. See plot(1g)
*/
cont() {
int x, y;
x = getShort();
y = getShort();
#ifdef DEBUG
printf("continue to (%d, %d)\n", x, y);
#endif DEBUG
if( ! HaveTrajectory ) {
AppendInteger((long) CurrentX);
AppendInteger((long) CurrentY);
AppendOp(OP_moveto);
HaveTrajectory = TRUE;
}
AppendInteger((long) x);
AppendInteger((long) y);
AppendOp(OP_lineto);
CurrentX = x;
CurrentY = y;
}
/*
* point: Plot the point given by the next four bytes.
*/
point() {
int x, y;
if( HaveTrajectory )
ShowTrajectory();
x = getShort();
y = getShort();
#ifdef DEBUG
printf("point at (%d, %d)\n", x, y);
#endif DEBUG
AppendInteger((long) x);
AppendInteger((long) y);
CurrentX = x;
CurrentY = y;
}
/*
* line: Draw a line from the point given by the next four bytes to the point
* given by the following four bytes.
*/
line() {
int x0, y0, x1, y1;
x0 = getShort();
y0 = getShort();
x1 = getShort();
y1 = getShort();
#ifdef DEBUG
printf("line from (%d, %d) to (%d, %d)\n", x0, y0, x1, y1);
#endif DEBUG
if( ! HaveTrajectory ) {
AppendInteger((long) x0);
AppendInteger((long) y0);
AppendOp(OP_moveto); }
else
if( x0 != CurrentX || y0 != CurrentY ) {
ShowTrajectory();
AppendInteger((long) x0);
AppendInteger((long) y0);
AppendOp(OP_moveto); }
AppendInteger((long) x1);
AppendInteger((long) y1);
AppendOp(OP_lineto);
HaveTrajectory = TRUE;
CurrentX = x1;
CurrentY = y1;
}
/*
* label: Place the following ASCII string so that its first character falls
* on the current point. The string is terminated by a newline.
*
* Unspoken in the documentation but implied by practice is
* that the current position is changed to the end of text string.
* This artifact can cause problems because we don't know the width
* of characters in a font.
*/
label() {
char labelString[MAXSTRINGSIZE];
if( HaveTrajectory ) {
printf("pl2ip: opps trying to put text at end of line!\n");
ShowTrajectory();
}
(void) gets(labelString);
#ifdef DEBUG
printf("output label string: '%s'\n", labelString);
#endif DEBUG
AppendInteger((long) CurrentX);
AppendInteger((long) CurrentY);
AppendOp(OP_setxy);
AppendString(labelString);
AppendOp(OP_show);
CurrentX += strlen(labelString)*(4096.0/(Pitch * 6.5)) + .4999999;
}
/*
* arc: The first four bytes give the center, the next four give the starting
* proint and the last four give the end point of a circular arc. The
* least significant coordinate of the end point is used to only to
* determine the quadrant. The arc is drawn counter-clockwise.
*/
arc() {
#ifdef DEBUG
int centerX, centerY,
startX, startY,
endX, endY;
if( HaveTrajectory )
ShowTrajectory();
centerX = getShort();
centerY = getShort();
startX = getShort();
startY = getShort();
endX = getShort();
endY = getShort();
printf("arc with center (%d, %d), starting at (%d, %d) and ending at (%d, %d)\n", centerX, centerY, startX, startY, endX, endY);
#endif DEBUG
}
/*
* circle: The first four bytes give the center of the circle, the next
* two the radius.
*/
circle() {
#ifdef DEBUG
int centerX, centerY,
radius;
if( HaveTrajectory )
ShowTrajectory();
centerX = getShort();
centerY = getShort();
radius = getShort();
printf("circle at (%d, %d) with radius %d\n", centerX, centerY, radius);
#endif DEBUG
}
/*
* erase: Start another frame of output
*/
erase() {
if( HaveTrajectory )
ShowTrajectory();
#ifdef DEBUG
printf("erase\n");
#endif DEBUG
}
/*
* linemod: Take the following string, up to a newline, as the style for
* drawing further lines. The syles are 'dotted', 'solid', 'longdashed',
* 'shortdashed', and 'dotdashed'.
*/
lineMod() {
char lineType[MAXSTRINGSIZE];
if( HaveTrajectory )
ShowTrajectory();
(void) gets(lineType);
#ifdef DEBUG
printf("change line mode to '%s'\n", lineType);
#endif DEBUG
}
/*
* space: The next four bytes give the lower left corner of the plotting area;
* the following four give the upper right corner. The plot will be
* magnified or reduced to fit the device as closely as possible.
*/
space() {
#ifdef DEBUG
int lowerLeftX, lowerLeftY,
upperRightX, upperRightY;
lowerLeftX = getShort();
lowerLeftY = getShort();
upperRightX = getShort();
upperRightY = getShort();
printf("space with lower left at (%d, %d) and upper right at (%d, %d)\n", lowerLeftX, lowerLeftY, upperRightX, upperRightY);
#endif DEBUG
}
/*
* draw the current trajectory
*/
ShowTrajectory() {
AppendOp(OP_maskstroke);
HaveTrajectory = FALSE;
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.