[net.sources] A plot filter for the QMS laser printer

randy@nlm-vax.ARPA (Rand Huntzinger) (07/24/85)

What follows is a shell archive of a plot (3X) library for the QMS laser
printer.  The routines in this library allow programs using the plot function
calls to do graphics on the QMS printer.

---------------------------- Cut Here -----------------------------------------
: This is a shar archieve.  Extract with sh, not csh.
: The rest of this file will extract:
: README Makefile qms.h arc.c box.c circle.c close.c dot.c erase.c label.c line.c linemod.c move.c open.c point.c space.c subr.c
echo extracting - README
sed 's/^X//' > README << '/*EOF'
X
X		Plot routines for the QMS LaserGrafix Printers
X
X
XThis shar archive contains a package of plot routines for translating
Xthe standard UNIX plot format to QMS LaserGrafix QUIC commands.  The
Xroutines link to form a plot library, libqms, which can be linked into
Xuser programs.
X
XIf you have the plot driver program, /usr/src/usr.bin/plot/driver.c in
X4.2 BSD, you can link these routines into the qmsp program which is a
Xfilter (similar to the tek filter) for plot commands.  The input is a
Xstream of plot commands in the form given in plot (5) and the output is
XQUIC commands.  Since I didn't want to get involved with ownership
Xquestions, I simply omitted the driver code from the package.
X
XThere is also a test.c program which produces a test pattern in both
Xportrait and landscape mode.  [The page orientation is selected such that
Xthe longest plot dimension is on the longest dimension of the paper].
X
XThese routines were rather hastily put together and do not represent a
Xpolished product.  Nor have I taken any pains to document this code.
XThey do seem to work in our environment for our purposes.
X
XKNOWN BUGS:
X
XCircles and arcs cannot be plotted with broken lines set using the
Xlinemod procedure.  Only solid lines can be used with these figures.
X
XThere is essentially no error checking at all.
/*EOF
echo extracting - Makefile
sed 's/^X//' > Makefile << '/*EOF'
X#
X#		QMS LaserGrafix "plot driver"
X#
X#	The routines in this package translate UNIX "plot" format graphics
X#	files to the QUIC language used by QMS laser printers.
X#
X#	Original version:
X#
X#	Rand Huntzinger		June 17, 1985	National Library of Medicine
X#
X
XCFLAGS=-g
XLIBS=-lm
XDRIVER=/usr/src/usr.bin/plot/driver.c
XOBJS=	arc.o box.o circle.o close.o dot.o erase.o label.o \
X	line.o linemod.o move.o open.o point.o space.o subr.o
XSRCS=	arc.c box.c circle.c close.c dot.c erase.c label.c \
X	line.c linemod.c move.c open.c point.c space.c subr.c
XHDRS=	qms.h
XMISC=	README Makefile
X
Xall:		libqms qmsp test
X
Xlibqms:		 ${OBJS}
X		ar cu libqms ${OBJS}
X		ranlib libqms
X
Xdriver.c:	$(DRIVER)
X		cp $(DRIVER) driver.c
X
Xqmsp:		libqms driver.o
X		cc -o qmsp driver.o libqms $(LIBS)
X
Xtest:		libqms test.o
X		cc -o test test.o libqms $(LIBS)
X
Xshar:		qmsplot.sh
X
Xqmsplot.sh:	$(MISC) $(HDRS) $(SRCS)
X		shar $(MISC) $(HDRS) $(SRCS) > qmsplot.sh
X		
Xclean:
X		rm -f ${OBJS} errs a.out core
X
X
X
/*EOF
echo extracting - qms.h
sed 's/^X//' > qms.h << '/*EOF'
X/*
X		QMS LaserGrafix "plot driver"
X
X	The routines in this package translate UNIX "plot" format graphics
X	files to the QUIC language used by QMS laser printers.
X
X	Original version:
X
X	Rand Huntzinger		June 17, 1985	National Library of Medicine
X*/
X
X/*	Include file, common definitions. */
X
X/* Constants */
X
X#define		CHXCNTR		36	/* Char centering adjust */
X#define		CHYCNTR		42
X#define		CHWIDTH		71	/* Character width */
X#define		CHFONT		10
X
X/* some frequently used macros */
X
X#define		XC(x)		(int) (((x)+xadj)*xscale)
X#define		YC(y)		(int)((QMSland ? 8500.0 : 11000.0) \
X					-yscale*((y)+yadj))
X#define		QUICON		printf("\r^PY^-^F\r\n")
X#define		FONT(x)		printf("^IS%d^SM%d^G\r\n", x, x)
X#define		QUICOFF		printf("^O\r^-^PN^-\r\n")
X#define		GRAFON		printf("^IGV^PW05\r\n")
X#define		GRAFOFF		printf("^IGE")
X#define		MOVE(x,y)	printf("^U%05d:%05d\r\n", XC(x), YC(y))
X#define		DRAW(x,y)	printf("^D%05d:%05d\r\n", XC(x), YC(y))
X#define		LINE(a,b,x,y)	MOVE(a,b) ; DRAW(x,y)
X#define		POINT(x,y)	LINE(x,y,x,y)
X#define		LTYPE(x)	printf("^V%1x\r\n", x)
X#define		NEWPAGE		printf("^,\r\n")
X#define		ARC(x,y,z,b,e)	printf("^LA%05d%05d%05d%03d%03d05^G\r\n",\
X					XC(x),YC(y),(int)xscale*(z), b, e)
X#define		LANDMODE	printf("^IOL\r\n")
X#define		PORTMODE	printf("^IOP\r\n")
X
X/* externals */
X
X#ifndef	MOD_OPEN
X
Xextern	openpl();		/* Open the plot */
Xextern	QMSinit();		/* Init the plot */
Xextern	int	QMSvec;		/* TRUE if in vector mode */
Xextern	int	QMSinitx;	/* TRUE if initialization done */
Xextern	int	QMSspace;	/* TRUE if space has been set */
Xextern	int	QMSform;	/* TRUE means inhibit eject */
Xextern	int	xcoord,ycoord;	/* Current position */
X
X#endif
X
X#ifndef	MOD_SPACE
X
Xextern	space();		/* Determine space requirements */
Xextern	int	QMSland;	/* Landscape mode flag */
Xextern	double	xscale,yscale;	/* Scaling parameters */
Xextern	double	xadj, yadj;	/* Origin adjustments */
X
X#endif
X
X
X
/*EOF
echo extracting - arc.c
sed 's/^X//' > arc.c << '/*EOF'
X/*
X		QMS LaserGrafix "plot driver"
X
X	The routines in this package translate UNIX "plot" format graphics
X	files to the QUIC language used by QMS laser printers.
X
X	Original version:
X
X	Rand Huntzinger		June 17, 1985	National Library of Medicine
X*/
X
X
X#define		MOD_ARC
X#include	"qms.h"
X#include	<stdio.h>
X# include	<math.h>
X
X#define radius(x,y) sqrt((double)((x-cx)*(x-cx)+(y-cy)*(y-cy)))
X#define PI 3.141593
X
Xextern		double	xscale, yscale, xadj, yadj;
X
Xstatic
Xint	angle(x, y)
X	int	x,y;
X{
X	double a;
X
X	/* Compute an angle backwards degrees (for QMS) */
X
X	a = atan2((double) x, (double) y) * (180.0/PI);
X	if( a >= 0 )
X		return((int) (360.0 - a + 0.5));
X	else
X		return((int) -a - 0.5);
X}
X
X
X/*
X	KNOWN BUG:	The QMS QUIC arc routine used here apparently does
X			not support broken line modes.  So circles and arcs
X			can only be drawn with solid lines.
X*/
X
X
Xarc(cx, cy, xb, yb, xe, ye)
X	int	cx, cy, xb, yb, xe, ye;
X{
X	int	r;
X	int	sa, ea;
X
X	QMSinit();
X
X	/* Determine where to put the arc */
X
X	r = (int) (radius(xb, yb) + radius(xe, ye)) / 2.0;
X	sa = angle(xb, yb);
X	ea = angle(xe, ye);
X	xe = (int) (r * cos(xb) + .5);
X	ye = (int) (r * sin(xb) + .5);
X
X	/* Finally draw the arc */
X
X	ARC(cx, cy, r, ea, sa);
X	move(xe, ye);
X	QMSform = 0;
X
X}
/*EOF
echo extracting - box.c
sed 's/^X//' > box.c << '/*EOF'
X/*
X		QMS LaserGrafix "plot driver"
X
X	The routines in this package translate UNIX "plot" format graphics
X	files to the QUIC language used by QMS laser printers.
X
X	Original version:
X
X	Rand Huntzinger		June 17, 1985	National Library of Medicine
X*/
X
X
Xbox(x0, y0, x1, y1)
X	int	x0, y0, x1, y1;
X{
X	move(x0, y0);
X	cont(x0, y1);
X	cont(x1, y1);
X	cont(x1, y0);
X	cont(x0, y0);
X	move(x1, y1);
X}
/*EOF
echo extracting - circle.c
sed 's/^X//' > circle.c << '/*EOF'
X/*
X		QMS LaserGrafix "plot driver"
X
X	The routines in this package translate UNIX "plot" format graphics
X	files to the QUIC language used by QMS laser printers.
X
X	Original version:
X
X	Rand Huntzinger		June 17, 1985	National Library of Medicine
X*/
X
X
X#define		MOD_CIRCLE
X#include	"qms.h"
X#include	<stdio.h>
Xextern		double	xscale, yscale, xadj, yadj;
X
X
X/*
X	KNOWN BUG:	The QMS QUIC arc routine used here apparently does
X			not support broken line modes.  So circles and arcs
X			can only be drawn with solid lines.
X*/
X
Xcircle(x, y, rx)
X	int	x, y, rx;
X{
X	QMSinit();
X	QMSform = 0;
X	ARC(x, y, rx, 0, 360);
X}
/*EOF
echo extracting - close.c
sed 's/^X//' > close.c << '/*EOF'
X/*
X		QMS LaserGrafix "plot driver"
X
X	The routines in this package translate UNIX "plot" format graphics
X	files to the QUIC language used by QMS laser printers.
X
X	Original version:
X
X	Rand Huntzinger		June 17, 1985	National Library of Medicine
X*/
X
X#define		MOD_ARC
X#include	"qms.h"
X
Xextern	int	PlotOpen, QMSinitx;
X
Xclosepl()
X{
X	/* Dummy version */
X
X	if(QMSvec) {
X		GRAFOFF;
X		QMSvec=0;
X	}
X	QUICOFF;
X	QMSinitx = 0;
X	PlotOpen = 0;
X}
/*EOF
echo extracting - dot.c
sed 's/^X//' > dot.c << '/*EOF'
X/*
X		QMS LaserGrafix "plot driver"
X
X	The routines in this package translate UNIX "plot" format graphics
X	files to the QUIC language used by QMS laser printers.
X
X	Original version:
X
X	Rand Huntzinger		June 17, 1985	National Library of Medicine
X*/
X
X/*
X	I'm not sure exactly what dot should do, so it's not implemented.
X	I'd guess that it displays an array of points judging from the way
X	it's called but there is no documentation anywhere in sight.
X*/
X
X
Xdot(x, y, dx, n, short *pat)
X	int	x, y, dx, n;
X	short	*pat;
X{
X	/* Do nothing */
X}
/*EOF
echo extracting - erase.c
sed 's/^X//' > erase.c << '/*EOF'
X/*
X		QMS LaserGrafix "plot driver"
X
X	The routines in this package translate UNIX "plot" format graphics
X	files to the QUIC language used by QMS laser printers.
X
X	Original version:
X
X	Rand Huntzinger		June 17, 1985	National Library of Medicine
X*/
X
X#define		MOD_ARC
X#include	"qms.h"
X
Xerase()
X{
X	/* Eject the page if necessary */
X
X	if(QMSform)
X		return;
X	QMSform = 1;			/* Clean page */
X	NEWPAGE;
X}
/*EOF
echo extracting - label.c
sed 's/^X//' > label.c << '/*EOF'
X/*
X		QMS LaserGrafix "plot driver"
X
X	The routines in this package translate UNIX "plot" format graphics
X	files to the QUIC language used by QMS laser printers.
X
X	Original version:
X
X	Rand Huntzinger		June 17, 1985	National Library of Medicine
X*/
X
X#define		MOD_LABEL
X#include	"qms.h"
X
Xlabel(s)
X	char	*s;		/* Label string */
X{
X	/* Center the character */
X
X	printf("^U-%05d:+%05d\r\n", CHXCNTR, CHYCNTR);
X
X	/* Get us out of graphics mode */
X
X	if(QMSvec) {
X		GRAFOFF;		/* Turn off graphics */
X		QMSvec = 0;
X	}
X
X	/* Position the text appropriately */
X
X	printf("%s", s);
X
X	/* Readjust the position */
X
X	move(xcoord+strlen(s)*CHWIDTH, ycoord);
X/*	printf("^U+%05d:+%05d\r\n", CHXCNTR, CHYCNTR); */
X	
X
X}
/*EOF
echo extracting - line.c
sed 's/^X//' > line.c << '/*EOF'
X/*
X		QMS LaserGrafix "plot driver"
X
X	The routines in this package translate UNIX "plot" format graphics
X	files to the QUIC language used by QMS laser printers.
X
X	Original version:
X
X	Rand Huntzinger		June 17, 1985	National Library of Medicine
X*/
X
X#define		MOD_LINE
X#include	"qms.h"
X
Xline(x0,y0,x,y)
X	int	x,y,x0,y0;		/* Coordinates */
X{
X	QMSinit();		/* Initialize */
X	if(QMSvec)
X		GRAFON;		/* Turn on vector graphics */
X	QMSform = 0;		/* Page is dirty */
X	LINE(x0,y0,x,y);
X}
/*EOF
echo extracting - linemod.c
sed 's/^X//' > linemod.c << '/*EOF'
X/*
X		QMS LaserGrafix "plot driver"
X
X	The routines in this package translate UNIX "plot" format graphics
X	files to the QUIC language used by QMS laser printers.
X
X	Original version:
X
X	Rand Huntzinger		June 17, 1985	National Library of Medicine
X*/
X
X#define		MOD_ARC
X#include	"qms.h"
X#include	<stdio.h>
X
Xlinemod(s)
X	char	*s;
X{
Xstatic	struct	{
X		char	*str;			/* Type designation */
X		int	tcode;			/* Type code number */
X	} *t, ltypes[] = {
X		{ "dotted",		2 },
X		{ "solid",		0 },
X		{ "longdashed",		4 },
X		{ "shortdashed",	3 },
X		{ "dotdashed",		7 },
X		{ NULL,			0 }	/* End mark */
X	};
X
X	/* Be sure we're in the proper mode */
X
X	QMSinit();
X
X	/* Select a line type */
X
X	for(t = ltypes; t->str != NULL; t++)
X		if(strcmp(t->str, s) == 0) {
X			LTYPE(t->tcode);
X			return;
X		}
X	return;		/* Not found, don't change */
X}
/*EOF
echo extracting - move.c
sed 's/^X//' > move.c << '/*EOF'
X/*
X		QMS LaserGrafix "plot driver"
X
X	The routines in this package translate UNIX "plot" format graphics
X	files to the QUIC language used by QMS laser printers.
X
X	Original version:
X
X	Rand Huntzinger		June 17, 1985	National Library of Medicine
X*/
X
X#define	MOD_MOVE
X#include	"qms.h"
X
Xextern	double	xscale, yscale, xadj, yadj;
Xextern	int	xcoord, ycoord;
X
Xmove(x,y)
X	int	x,y;			/* Coordinates */
X{
X	QMSinit();		/* Initialize */
X	if(!QMSvec) {
X		GRAFON;		/* Turn on vector graphics */
X		QMSvec++;
X	}
X	xcoord = x;
X	ycoord = y;
X	MOVE(x,y);
X}
/*EOF
echo extracting - open.c
sed 's/^X//' > open.c << '/*EOF'
X/*
X		QMS LaserGrafix "plot driver"
X
X	The routines in this package translate UNIX "plot" format graphics
X	files to the QUIC language used by QMS laser printers.
X
X	Original version:
X
X	Rand Huntzinger		June 17, 1985	National Library of Medicine
X*/
X
X#define	MOD_OPEN			/* Define which module we're in */
X
X#include	"qms.h"			/* We need a few commands */
X
X	int	QMSinitx = 0;		/* TRUE => initialization done */
X	int	QMSspace = 0;		/* TRUE => scaling parms known */
X	int	PlotOpen = 0;		/* TRUE => openpl() called */
X	int	QMSvec = 0;		/* TRUE => in vector mode */
X	int	QMSform= 0;		/* TRUE => Don't eject page */
X	int	xcoord, ycoord;		/* Current position */
X
Xopenpl()
X{
X	/* Open basically lets the other plot routines know that
X	   certain parameters are undefined and that the basic
X	   initialization routine must be called before starting
X	   another plot.  That routine, QMSinit, is also in this
X	   module. */
X
X
X	if(PlotOpen)
X		closepl();
X
X	QMSinitx = 0;			/* Not initialized */
X	QMSspace = 0;			/* Space not called */
X	PlotOpen = 1;			/* The plot has been opened */
X	QMSform  = 1;			/* Inhibit page ejects */
X}
X
X
Xextern	double	xadj, yadj;
Xextern	double	xscale, yscale;
X
XQMSinit()
X{
X	/* Initialize the QMS laser printer for plotting.  This means
X	   setting the scale if the user hasn't already, initializing
X	   the software's idea of where we are and the shape of the
X	   plot, and sending the QMS header QUIC commands to establish
X	   the proper state for the printer. */
X
X	/* If the scale hasn't been set, set the scale for full page
X	   plotting in landscape mode */
X
X	if(QMSinitx)			/* Already initialized */
X		return;
X
X	if(!QMSspace)
X		space(0,0,11000,8500);
X
X	QUICON;				/* QUIC mode is on */
X	if(QMSland)
X		LANDMODE;		/* Landscape mode */
X	else	PORTMODE;		/* Portrait mode */
X	FONT(CHFONT);			/* Set the font */
X
X	QMSvec = 0;			/* Not in vector mode */
X	QMSinitx++;			/* Initialized */
X	move(-xadj, -yadj);		/* Initialize position */
X}
/*EOF
echo extracting - point.c
sed 's/^X//' > point.c << '/*EOF'
X/*
X		QMS LaserGrafix "plot driver"
X
X	The routines in this package translate UNIX "plot" format graphics
X	files to the QUIC language used by QMS laser printers.
X
X	Original version:
X
X	Rand Huntzinger		June 17, 1985	National Library of Medicine
X*/
X
X#define		MOD_ARC
X#include	"qms.h"
X
Xpoint(x,y)
X	int	x,y;
X{
X	move(x,y);
X	cont(x,y);
X}
/*EOF
echo extracting - space.c
sed 's/^X//' > space.c << '/*EOF'
X/*
X		QMS LaserGrafix "plot driver"
X
X	The routines in this package translate UNIX "plot" format graphics
X	files to the QUIC language used by QMS laser printers.
X
X	Original version:
X
X	Rand Huntzinger		June 17, 1985	National Library of Medicine
X*/
X
X#include	<stdio.h>
X#include	"qms.h"
X
Xdouble	xscale, yscale;		/* Scaling parameters */
Xdouble	xadj, yadj;		/* Scaling adjustments */
Xint	QMSland;		/* Landscape mode flag */
X
Xspace(x0,y0,x1,y1)
X	int	x0,y0;		/* Lower left hand corner coordinates */
X	int	x1,y1;		/* Upper right hand corner coordinates */
X{
X	/* Determine the scaling parameters for a QMS plot.  If the
X	   width is greater than the length, landscape mode will be used;
X	   otherwise, portrait mode is selected. */
X
X	int	xw, yw;		/* Coordinate widths */
X
X	xadj = -x0+0.5;		/* Origin adjustments */
X	yadj = -y0+0.5;
X
X	/* Compute the scale */
X
X	QMSland = (abs(xw = x1-x0) > abs(yw = y1-y0));
X	xscale = (QMSland ? 11000.0 :  8500.0) / (double) xw;
X	yscale = (QMSland ?  8500.0 : 11000.0) / (double) yw;
X
X	/* Force xscale == yscale so circles and squares "are" */
X
X	if(xscale > yscale)
X		xscale = yscale;
X	else	yscale = xscale;
X
X	QMSspace = 1;		/* Space has been set */
X}
/*EOF
echo extracting - subr.c
sed 's/^X//' > subr.c << '/*EOF'
X/*
X		QMS LaserGrafix "plot driver"
X
X	The routines in this package translate UNIX "plot" format graphics
X	files to the QUIC language used by QMS laser printers.
X
X	Original version:
X
X	Rand Huntzinger		June 17, 1985	National Library of Medicine
X*/
X
X#define		MOD_SUBR
X#include	"qms.h"
X
Xextern	double	xadj, yadj;
Xextern	double	xscale, yscale;
Xextern	int	xcoord, ycoord;
X
Xcont(x,y)
X	int	x,y;			/* Coordinates */
X{
X	QMSinit();		/* Initialize */
X	if(!QMSvec) {
X		GRAFON;		/* Turn on vector graphics */
X		QMSvec++;
X	}
X
X	QMSform = 0;		/* Page not clean */
X	xcoord = x;
X	ycoord = y;
X	DRAW(x,y);
X}
/*EOF