4.4BSD/usr/src/contrib/dipress/src/bin/plot2ip/plot2ip.c

Compare this file to the similar file:
Show the results in this format:

/*
 * (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;
}