stevens@hsi.UUCP (Richard Stevens) (01/30/88)
# This is a shell archive. Remove anything before this line
# then unpack it by saving it in a file and typing "sh file"
# (Files unpacked will be owned by you and have default permissions).
# This archive contains the following files:
# ./README
# ./Makefile
# ./3b1.h
# ./plot.h
# ./3b1label.c
# ./3b1plot.c
# ./arc.c
# ./box.c
# ./circle.c
# ./close.c
# ./cont.c
# ./dot.c
# ./drawline.c
# ./ellipse.c
# ./erase.c
# ./exit.c
# ./label.c
# ./line.c
# ./linemod.c
# ./main.c
# ./move.c
# ./open.c
# ./point.c
# ./space.c
# ./varsinit.c
# ./test/Makefile
# ./test/test1.c
# ./test/test2.c
#
if `test ! -s ./README`
then
echo "extracting ./README ..."
sed 's/^X//' > ./README << 'END__of_the__FILE'
X This directory contains a UNIX plot(1) filter for the
XAT&T UNIX PC, aka 3b1, aka PC7300. Note that on the UNIX PC
XAT&T distributes the plot(3) library (/usr/lib/libplot.a) but
Xthey don't provide a plot(1) filter or any description of how
Xto use this library. What would also be nice
Xis a version of the graph(1) command that was with Version 7
Xand all the BSD Versions of UNIX.
X
X No manual pages are provided here - find an old Version 7
Xmanual or any BSD manual. Take a look at plot(1), plot(3) and
Xespecially plot(5).
X
X This plot driver has been written very generically
Xwith all device dependencies in 2 C files and 1 header file,
Xso it should be easily modified for some other raster display.
X
X Hints, suggestions, comments and disclaimers:
X
X- Integer arithmetic is used everywhere possible, due to the
X slow floating point on the 3b1.
X
X- Bresenham's line drawing algorithm has been made as fast as
X possible. One other area to look at is to handle vertical
X and horizontal lines as special cases. Also, since we're
X using a 2-dimensional array to store the raster image,
X keeping the address of the line we're currently on, and
X incrementing just this pointer, instead of going through
X a doubly subscripted array reference for every point,
X could be a big winner. This could help on the 3b1,
X since we've already used all 6 "short" register variables
X in the loop, but there are still 3 pointer register variables
X remaining.
X
X- I haven't coded the arc() function. I don't know of an easy
X implementation and don't have any real need for it.
X
X- I'm no pro with the 3b1 graphics, and given the awful and sparse
X documentation provided with the system, I'm doubtful anyone
X outside AT&T really is. If anyone can improve on the
X way in which I've done the graphics on the 3b1, I'd be glad
X to hear of any suggested improvements.
X
X- I should learn getopt() one of these days.
X
XIf you find any problems, or make any improvements to the program,
Xplease let me know.
X
X Richard Stevens
X Health Systems International, New Haven, CT
X { uunet, ihnp4 } ! hsi ! stevens
END__of_the__FILE
if test `wc -c < ./README` -ne 2079
then
echo "\tWAIT A MINUTE ... Expecting file size of 2079 bytes"
echo "\t but got a file size of `wc -c < ./README` bytes"
echo "\tWARNING ......... Suggest you check file contents."
fi
else
echo "will not over write ./README"
fi
if `test ! -s ./Makefile`
then
echo "extracting ./Makefile ..."
sed 's/^X//' > ./Makefile << 'END__of_the__FILE'
X#
X# Makefile, using 3b1 shared libraries.
X#
Xinclude $(MAKEINC)/Makepre.h
X
XCFLAGS= -O
XOBJS= 3b1label.o 3b1plot.o \
X arc.o box.o circle.o close.o cont.o \
X dot.o drawline.o ellipse.o erase.o exit.o \
X label.o line.o linemod.o \
X main.o move.o open.o point.o space.o varsinit.o
X
Xall: plot
X
Xplot: ${OBJS}
X $(LD) $(LDFLAGS) $(SHAREDLIB) $(OBJS) $(LIBM) -o plot
X
X${OBJS}: plot.h 3b1.h
X
Xclean:
X rm -f ${OBJS} errs a.out core plot
X
Xinclude $(MAKEINC)/Makepost.h
END__of_the__FILE
if test `wc -c < ./Makefile` -ne 456
then
echo "\tWAIT A MINUTE ... Expecting file size of 456 bytes"
echo "\t but got a file size of `wc -c < ./Makefile` bytes"
echo "\tWARNING ......... Suggest you check file contents."
fi
else
echo "will not over write ./Makefile"
fi
if `test ! -s ./3b1.h`
then
echo "extracting ./3b1.h ..."
sed 's/^X//' > ./3b1.h << 'END__of_the__FILE'
X/*
X * This file contains the 3b1-specific plotting definitions.
X * This file is included by "plot.h".
X */
X
X#include <tam.h>
X /* <tam.h> includes <sys/windows.h> and <kcodes.h> */
X
X/*
X * The range of the 3b1 device coordinates is 0..XMAX, 0..YMAX.
X * Note that on the 3b1 the top of the screen is 0 and the bottom is YMAX
X * (this is different from some user coordinates, which have the point
X * (0,0) as the lower left).
X *
X * Significant characteristics of the 3b1 bit mapped display:
X *
X * screen width = 720 pixels = 8.14 inches
X * 720 = 80 columns at 9 pixels per column
X * screen height = 288 pixels = 4.85 inches
X * 288 = 24 lines at 12 pixels per line
X *
X * pixel width = 287 micrometers -> ~ 88 pixels/inch horizontally
X * pixel height = 428 micrometers -> ~ 60 pixels/inch vertically
X *
X * For a square image on the 3b1 screen requires a width of
X * 430 pixels (4.85 inches) and a height of 288 pixels (4.85 inches).
X * This means to draw what the user sees as a circle requires
X * the software to draw an ellipse.
X */
X
X#define XMAX 719
X#define YMAX 287
X
X#define XMAX_UNITY 429 /* for unity aspect ratio */
X#define YMAX_UNITY 287
X
X#define WIN_SWIDTH (WINWIDTH / 16) /* screen width in shorts */
X /* WINWIDTH is the width of the window in
X pixels - 720 for 3b1 - see <sys/window.h> */
X /* WINHEIGHT is the height - (348 - 4*12)=300 pixels
X for 3b1 - see <sys/window.h> */
X#define WIN_BWIDTH (2 * WIN_SWIDTH) /* screen width in bytes */
X#define XMASKBIT 4 /* bits in bit addr in short */
X /* faster to do (i>>4) than (i/16) */
X
X/*
X * The array bitmap[][] is the memory image we keep of the actual display
X * bitmap. Pixels are turned on and off using the PLOT() macro below.
X *
X * +-------------------------------------------------------+
X * | bitmap[ 0][0] ... bitmap[ 0][719/16] |
X * | bitmap[ 1][0] ... bitmap[ 1][719/16] |
X * | bitmap[ 2][0] ... bitmap[ 2][719/16] |
X * | ... ... |
X * | |
X * | bitmap[286][0] ... bitmap[286][719/16] |
X * | bitmap[287][0] ... bitmap[287][719/16] |
X * +-------------------------------------------------------+
X *
X * Note that each element of bitmap[][] corresponds to 16 consecutive
X * pixels in a given row. The LSB (rightmost) bit of each 16-bit short
X * integer element of bitmap[][] corresponds to the leftmost pixel
X * on the display, and the MSB (leftmost) bit corresponds to the
X * righmost pixel. The mapping between the pixel's x-value (0-719) and
X * its actual bit value (0x0001 - 0x8000) is handled by the mask[] array.
X */
X
X#define PLOT(x,y) bitmap[y][(x) >> XMASKBIT] |= mask[x]
X /* turn on (inclusive-OR) a given pixel */
X
Xextern unsigned short bitmap[WINHEIGHT][WIN_SWIDTH];
X
Xextern unsigned short mask[]; /* initialized in 3b1plot.c */
X
Xextern short win; /* window identifier */
X
Xextern unsigned short patblack[];
Xextern unsigned short patwhite[];
Xextern unsigned short patgray[];
Xextern unsigned short patltgray[];
X
Xextern char *fontfile; /* for labels */
END__of_the__FILE
if test `wc -c < ./3b1.h` -ne 3021
then
echo "\tWAIT A MINUTE ... Expecting file size of 3021 bytes"
echo "\t but got a file size of `wc -c < ./3b1.h` bytes"
echo "\tWARNING ......... Suggest you check file contents."
fi
else
echo "will not over write ./3b1.h"
fi
if `test ! -s ./plot.h`
then
echo "extracting ./plot.h ..."
sed 's/^X//' > ./plot.h << 'END__of_the__FILE'
X/*
X * Displays plot files on AT&T 3b1 (UNIX pc).
X * See plot(5) for a description of the input stream.
X */
X
X#include <stdio.h>
X#include <math.h>
X
X#include "3b1.h" /* file with 3b1 specifics */
X
Xtypedef double FLOAT; /* double is faster than float on 3b1 */
X
X/*
X * Specify the limits of the device's display area.
X * The user can change this with command line arguments to
X * the plot(1) program. Changing this allows one to use the
X * whole screen area, if desired (but it won't have a unity
X * aspect ratio), or a smaller area (if an aspect ratio of 1
X * is desired), or anything in between.
X */
X
Xextern int xmax; /* device plotting area is [0, xmax) */
Xextern int ymax; /* device plotting area is [0, ymax) */
X
X/*
X * There are 2 coordinate systems in use: the user coordinates
X * (usually [0,4096) when the points were generated by graph(1)),
X * and the device coordinates. Both coordinate systems use integers
X * for the x and y coordinate values.
X *
X * There are two sets of macros for scaling and conversion from
X * user coordinates to device coodinates:
X *
X * Xscale() and Yscale() scale an x or y value from user
X * coordinates to device coordinates.
X *
X * Xuser2dev() and Yuser2dev() convert an x or y user
X * coordinate to a corresponding device coordinate.
X *
X * The difference is that the conversion from a user coordinate to
X * a device coordinate may involve more than scaling. On the 3b1,
X * for example, it also involves a translation since the 3b1's zero
X * point is the upper left corner, while the zero point for plot
X * is the lower left corner.
X */
X
X#define Xscale(x) ((int) (((x) - lowx) * scalex + 0.5))
X#define Yscale(y) ((int) (((y) - lowy) * scaley + 0.5))
X
X#define Xuser2dev(x) Xscale(x)
X#define Yuser2dev(y) ((ymax-1) - Yscale(y))
X
Xextern int currentx; /* in device coordinates */
Xextern int currenty;
X
Xextern int lowx; /* in user coordinates */
Xextern int lowy;
X
Xextern FLOAT scalex; /* calculated in space.c */
Xextern FLOAT scaley;
END__of_the__FILE
if test `wc -c < ./plot.h` -ne 1999
then
echo "\tWAIT A MINUTE ... Expecting file size of 1999 bytes"
echo "\t but got a file size of `wc -c < ./plot.h` bytes"
echo "\tWARNING ......... Suggest you check file contents."
fi
else
echo "will not over write ./plot.h"
fi
if `test ! -s ./3b1label.c`
then
echo "extracting ./3b1label.c ..."
sed 's/^X//' > ./3b1label.c << 'END__of_the__FILE'
X/*
X * Handle writing text messages to the 3b1 display.
X *
X * Things are more complicated than they should be, since we must
X * plot the actual bit maps of each character. The 3b1's "window puts()"
X * function is only capable of writing characters to screen locations
X * that are multiples of a single line (multiple of 12 pixels in y) or a
X * single column (multiple of 9 pixels in x). To place arbitrary text
X * anywhere on the screen is harder.
X */
X
X#include <stdio.h>
X#include "plot.h"
X#include <sys/font.h>
X
X#define FONTFILE "/usr/lib/wfont/system.r.8.ft"
X /* change this, if desired */
X
X#define MAXFONTFILESIZE 15000 /* greater than largest file size (in bytes)
X in /usr/lib/wfont */
X
Xchar *fontfile = FONTFILE;
Xstatic int firsttime = 1; /* set to 0 after first time through */
X
Xlong font[MAXFONTFILESIZE / sizeof(long)];
X /* read entire font file into here */
X /* must be long aligned */
X /* a union would be "cleaner" */
Xunsigned short *srcbase;
Xunsigned short srcwidth, srcx, srcy, dstx, dsty;
Xint width, height;
X
X_3b1label(str)
Xchar *str;
X{
X register int fd, rc;
X char c, mesg[200];
X register struct fntdef *fntptr;
X register struct fcdef *fcptr;
X
X if (firsttime) {
X firsttime = 0;
X
X /*
X * The first time this function is called, we open the
X * font file and read it into our buffer. Note that we
X * read the *whole* font file at once.
X */
X
X if ((fd = open(fontfile, 0)) < 0) {
X sprintf(mesg, "can't open font file: %s", fontfile);
X err(mesg);
X }
X
X if ((rc = read(fd, (char *) font, sizeof(font))) < 0)
X err("read error");
X
X close(fd);
X
X /*
X * Look at the header to make certain all is OK, and get
X * the necessary parameters from it.
X */
X
X fntptr = (struct fntdef *) font;
X
X if (fntptr->ff_magic != FMAGIC)
X err("invalid magic number for font file");
X } else {
X fntptr = (struct fntdef *) font;
X }
X
X /*
X * Now comes the fun. We must take the actual bit map of
X * each character in the string and turn on the appropriate
X * bits in the bitmap[][] array.
X * We use the wrastop() operation for the actual memory-to-memory
X * bit operation.
X *
X * We assume that the position specified by "currentx" and
X * "currenty" is the baseline of the characters.
X * Since we're going to all this work anyways, we might as
X * well generate the characters proportionally spaced, using
X * the "fc_hs" value for each character, with one bit between
X * each character.
X */
X
X while (c = *str++) {
X fcptr = &(fntptr->ff_fc[c - 0x20]);
X /* the "struct fcdef" for this character */
X
X srcbase = (unsigned short *) ((char *) &(fcptr->fc_mr) +
X fcptr->fc_mr);
X srcwidth = ((fcptr->fc_hs + 15) / 16) * 2; /* in bytes */
X srcx = 0;
X srcy = 0;
X dstx = currentx;
X dsty = currenty + fcptr->fc_va;
X width = fcptr->fc_hs;
X height = fcptr->fc_vs;
X
X rc = wrastop(win, srcbase, srcwidth, bitmap, WIN_BWIDTH,
X srcx, srcy, dstx, dsty,
X width, height,
X SRCSRC, DSTOR, (unsigned short *) 0);
X if (rc < 0)
X err("wrastop error for font character");
X
X currentx += fcptr->fc_hs + 1;
X /* +1 to space 1 pixel to next char */
X }
X}
END__of_the__FILE
if test `wc -c < ./3b1label.c` -ne 3128
then
echo "\tWAIT A MINUTE ... Expecting file size of 3128 bytes"
echo "\t but got a file size of `wc -c < ./3b1label.c` bytes"
echo "\tWARNING ......... Suggest you check file contents."
fi
else
echo "will not over write ./3b1label.c"
fi
if `test ! -s ./3b1plot.c`
then
echo "extracting ./3b1plot.c ..."
sed 's/^X//' > ./3b1plot.c << 'END__of_the__FILE'
X/*
X * Define the 3b1-specific variables.
X * The intent is to make "3b1.h" and this file self-standing.
X */
X
X#include <stdio.h>
X#include "3b1.h"
X
Xshort win = 0; /* window descriptor */
XWSTAT wstat; /* window status */
X
Xstruct umdata mouse; /* mouse information */
Xstruct mousein {
X int x; /* mouse x-pos */
X int y; /* mouse y-pos */
X int button; /* mouse button info */
X int reason; /* mouse reason codes */
X} mousein;
X
Xunsigned short bitmap[WINHEIGHT][WIN_SWIDTH];
X
X/*
X * Initialization for the 3b1.
X */
X
X_3b1init()
X{
X if (win > 0) {
X /*
X * We've already been called to open the display.
X * We'll zero out our bitmap array, and physically
X * erase the screen.
X */
X
X _3b1erase();
X clear(); /* should be use wrastop() instead ?? */
X wcmd(win, "");
X return;
X }
X
X win = open("/dev/window", 2);
X if (win < 0)
X err("can't open /dev/window");
X
X close(0); dup(win);
X close(1); dup(win);
X close(2); dup(win);
X
X winit();
X
X keypad(0, 1); /* return 8-bit character codes, see <kcodes.h> */
X
X win = wcreate(1, 0, 24, 80, NBORDER);
X /* 24 by 80, no border - largest area available */
X if (win < 0)
X err("wcreate failed");
X
X wputs(win, "\033[=1C"); /* turn off cursor, see escape(7) */
X
X#ifdef notdef /* not needed for plot filter */
X mouse.um_flags = MSUP | MSDOWN; /* establish mouse control */
X mouse.um_x = 0;
X mouse.um_y = 0;
X mouse.um_w = 0;
X mouse.um_h = 0;
X mouse.um_icon = (struct icon *) 0;
X if (wsetmouse(win, &mouse) < 0)
X err("wsetmouse");
X#endif
X}
X
X/*
X * Plot the bitmap[][] array.
X */
X
X_3b1plot()
X{
X register int rc;
X
X rc = wrastop(win, bitmap, WIN_BWIDTH, 0, 0,
X 0, 0, 0, 0,
X XMAX + 1, YMAX + 1,
X SRCSRC, DSTOR, patwhite);
X if (rc < 0)
X err("wrastop() error");
X
X /*
X * Wait for the user to enter a key to continue the program.
X */
X
X wcmd(win, "Press any key to continue");
X
X rc = wgetc(win); /* get the 8-bit key code */
X}
X
X/*
X * Erase our screen buffer, the bitmap[][] array.
X * Would a wrastop() with a pattern of black be faster ??
X */
X
X_3b1erase()
X{
X register unsigned short *usptr;
X register int i;
X
X usptr = &bitmap[0][0];
X for (i = 0; i < (WINHEIGHT * WIN_SWIDTH); i++)
X *usptr++ = 0;
X}
X
X_3b1exit(rc)
Xint rc;
X{
X wexit(rc); /* a graceful exit */
X}
X
Xchar errmesg3b1[100]; /* make extern to look at in core dump */
X
X/*
X * Handle errors in 3b1 plotting. Print something, then dump core.
X * Errors from the screen i/o routines usually aren't "obvious".
X */
X
Xerr(str)
Xchar *str;
X{
X extern char *pname; /* set by main() from argv[0] */
X
X sprintf(errmesg3b1, "%s: ", pname);
X strcat(errmesg3b1, str);
X perror(errmesg3b1); /* in case errno has some information */
X
X sleep(5); /* give user a chance to read it, before
X the screen is cleared. */
X abort();
X exit(1); /* shouldn't get here ... */
X}
X
X/*
X * Define and initialize the mask[] array.
X * You could define only 16 entries in this array, and change the PLOT()
X * macro to "or" in mask[x & 16] instead of mask[x], however, we'll trade
X * the space for the faster execution time.
X */
X
Xunsigned short mask[720] = { /* x pixels in the range [0,719] */
X /* 90 (=720/8) lines of initialization */
X 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
X 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000,
X 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
X 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000,
X 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
X 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000,
X 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
X 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000,
X 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
X 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000,
X
X 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
X 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000,
X 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
X 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000,
X 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
X 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000,
X 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
X 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000,
X 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
X 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000,
X
X 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
X 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000,
X 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
X 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000,
X 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
X 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000,
X 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
X 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000,
X 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
X 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000,
X
X 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
X 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000,
X 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
X 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000,
X 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
X 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000,
X 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
X 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000,
X 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
X 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000,
X
X 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
X 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000,
X 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
X 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000,
X 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
X 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000,
X 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
X 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000,
X 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
X 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000,
X
X 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
X 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000,
X 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
X 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000,
X 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
X 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000,
X 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
X 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000,
X 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
X 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000,
X
X 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
X 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000,
X 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
X 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000,
X 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
X 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000,
X 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
X 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000,
X 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
X 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000,
X
X 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
X 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000,
X 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
X 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000,
X 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
X 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000,
X 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
X 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000,
X 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
X 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000,
X
X 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
X 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000,
X 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
X 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000,
X 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
X 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000,
X 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
X 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000,
X 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
X 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000
X};
END__of_the__FILE
if test `wc -c < ./3b1plot.c` -ne 8974
then
echo "\tWAIT A MINUTE ... Expecting file size of 8974 bytes"
echo "\t but got a file size of `wc -c < ./3b1plot.c` bytes"
echo "\tWARNING ......... Suggest you check file contents."
fi
else
echo "will not over write ./3b1plot.c"
fi
if `test ! -s ./arc.c`
then
echo "extracting ./arc.c ..."
sed 's/^X//' > ./arc.c << 'END__of_the__FILE'
X/*
X * Draw a circular arc.
X * We are given the center point, the starting point and the ending
X * point. We must draw the arc counter-clockwise.
X * The beginning and ending points must be distinct.
X * The "current point" is undefined after this operation.
X */
X
X#include "plot.h"
X
Xpl_arc(xc, yc, xbeg, ybeg, xend, yend)
Xint xc, yc; /* center of arc, user coordinates */
Xint xbeg, ybeg; /* starting point, user coordinates */
Xint xend, yend; /* ending point, user coordinates */
X{
X /* TO DO */
X}
END__of_the__FILE
if test `wc -c < ./arc.c` -ne 496
then
echo "\tWAIT A MINUTE ... Expecting file size of 496 bytes"
echo "\t but got a file size of `wc -c < ./arc.c` bytes"
echo "\tWARNING ......... Suggest you check file contents."
fi
else
echo "will not over write ./arc.c"
fi
if `test ! -s ./box.c`
then
echo "extracting ./box.c ..."
sed 's/^X//' > ./box.c << 'END__of_the__FILE'
X/*
X * Draw a box, given the coordinates of two opposite corners.
X * We just call the other primitive routines to do all the work.
X */
X
Xpl_box(x0, y0, x1, y1)
Xint x0, y0; /* start in user coordinates */
Xint x1, y1; /* end in user coordinates */
X{
X pl_move(x0, y0); /* go to starting point */
X
X pl_cont(x0, y1); /* first side */
X pl_cont(x1, y1); /* second side (ending point) */
X pl_cont(x1, y0); /* third side */
X pl_cont(x0, y0); /* last side, takes us back to the start */
X
X pl_move(x1, y1); /* so we must move to the end */
X}
END__of_the__FILE
if test `wc -c < ./box.c` -ne 531
then
echo "\tWAIT A MINUTE ... Expecting file size of 531 bytes"
echo "\t but got a file size of `wc -c < ./box.c` bytes"
echo "\tWARNING ......... Suggest you check file contents."
fi
else
echo "will not over write ./box.c"
fi
if `test ! -s ./circle.c`
then
echo "extracting ./circle.c ..."
sed 's/^X//' > ./circle.c << 'END__of_the__FILE'
X/*
X * Draw a circle, given the center point and the radius.
X * The "current point" is undefined after this operation.
X *
X * Given that the x-scale factor and the y-scale factor may be
X * different, there is no guarantee that what the user thinks is
X * a circle will really appear as a circle. Furthermore, on
X * devices with a non-unity aspect ratio, to draw what appears to
X * be a circle requires that we draw an ellipse. So, we just go
X * ahead and call the generic ellipse routine to draw the circle,
X * which will handle all the cases.
X */
X
X#include "plot.h"
X
Xpl_circle(xc, yc, r)
Xshort xc, yc; /* center point, user coordinates */
Xshort r; /* radius, user coordinates */
X{
X register int a, b;
X
X xc = Xuser2dev(xc); /* convert to device coordinates */
X yc = Yuser2dev(yc);
X
X a = Xscale(r); /* x "radius" */
X b = Yscale(r); /* y "radius" */
X
X ellipse(xc, yc, a, b);
X}
END__of_the__FILE
if test `wc -c < ./circle.c` -ne 880
then
echo "\tWAIT A MINUTE ... Expecting file size of 880 bytes"
echo "\t but got a file size of `wc -c < ./circle.c` bytes"
echo "\tWARNING ......... Suggest you check file contents."
fi
else
echo "will not over write ./circle.c"
fi
if `test ! -s ./close.c`
then
echo "extracting ./close.c ..."
sed 's/^X//' > ./close.c << 'END__of_the__FILE'
X/*
X * Close the plotting device - called at the end of every plot file.
X */
X
X#include "plot.h"
X
Xpl_close()
X{
X _3b1plot(); /* do the actual plotting */
X}
END__of_the__FILE
if test `wc -c < ./close.c` -ne 154
then
echo "\tWAIT A MINUTE ... Expecting file size of 154 bytes"
echo "\t but got a file size of `wc -c < ./close.c` bytes"
echo "\tWARNING ......... Suggest you check file contents."
fi
else
echo "will not over write ./close.c"
fi
if `test ! -s ./cont.c`
then
echo "extracting ./cont.c ..."
sed 's/^X//' > ./cont.c << 'END__of_the__FILE'
X/*
X * Draw a line from the current point to the specified point.
X */
X
X#include "plot.h"
X
Xpl_cont(x, y)
Xint x, y;
X{
X register int endx, endy;
X
X endx = Xuser2dev(x); /* scale and remember the end points */
X endy = Yuser2dev(y);
X
X draw_line(currentx, currenty, endx, endy);
X
X currentx = endx; /* end point becomes current */
X currenty = endy;
X}
END__of_the__FILE
if test `wc -c < ./cont.c` -ne 342
then
echo "\tWAIT A MINUTE ... Expecting file size of 342 bytes"
echo "\t but got a file size of `wc -c < ./cont.c` bytes"
echo "\tWARNING ......... Suggest you check file contents."
fi
else
echo "will not over write ./cont.c"
fi
if `test ! -s ./dot.c`
then
echo "extracting ./dot.c ..."
sed 's/^X//' > ./dot.c << 'END__of_the__FILE'
X/*
X * Plot an array of points.
X *
X * From what I can determine, there ain't many of the real
X * plot filters that even support this operation, other than some
X * oddball DEC terminal that must have had a hardware operation
X * that did exactly this.
X */
X
Xpl_dot(xi, yi, dx, n, pat)
Xint xi, yi;
Xint dx;
Xint n; /* #elements in pat[] */
Xint pat[];
X{
X /* TODO */
X}
END__of_the__FILE
if test `wc -c < ./dot.c` -ne 361
then
echo "\tWAIT A MINUTE ... Expecting file size of 361 bytes"
echo "\t but got a file size of `wc -c < ./dot.c` bytes"
echo "\tWARNING ......... Suggest you check file contents."
fi
else
echo "will not over write ./dot.c"
fi
if `test ! -s ./drawline.c`
then
echo "extracting ./drawline.c ..."
sed 's/^X//' > ./drawline.c << 'END__of_the__FILE'
X/*
X * Draw a line from (x0,y0) to (x1,y1), where the 4 arguments are
X * in device coordinates and the 4 arguments must each be a short
X * (since the arithmetic is done using shorts, for speed).
X */
X
X#include "plot.h" /* need the definition of PLOT() */
X
X#ifndef ABS
X#define ABS(x) ((x) < 0 ? (-(x)) : (x))
X#endif
X
X#define SWAPSHORT(s1, s2) { d = s1; s1 = s2; s2 = d; }
X /* swap two shorts - beware of a side effect - this
X macro uses the automatic variable "d" defined below,
X since "d" will be in a register, and since "d" isn't
X being used when the macro is invoked. */
X
Xdraw_line(x0, y0, x1, y1)
Xshort x0, y0, x1, y1; /* all in device coordinates */
X{
X register short d, x, y, incr1, incr2, xend;
X short dx, dy, rotate;
X
X /*
X * Now starts Bresenham's algorithm. See Foley and Van Dam,
X * pages 433-436 for some of the details.
X * The variable names below are the same as in the text.
X *
X * Optimized to use short integer arithmetic, and further optimized
X * by taking some of the logic tests out of the main loop (making
X * 4 copies of the main loop, one for each case - space versus
X * time tradeoff).
X */
X
X dy = y1 - y0;
X dx = x1 - x0;
X
X /*
X * The octants are numbered 1 through 8, counterclockwise,
X * starting with octant 1 being east-northeast.
X * If we are in octants 2, 3, 6, or 7, then rotate the line
X * about the line x=y. This maps octant 2 into 1,
X * octant 3 into 8, octant 6 into 5 and octant 7 into 4.
X * We must remember this rotation for later, as we will
X * re-rotate the points when we plot them.
X */
X
X if (ABS(dx) >= ABS(dy))
X rotate = 0;
X else {
X rotate = 1;
X SWAPSHORT(x0, y0);
X SWAPSHORT(x1, y1);
X SWAPSHORT(dx, dy);
X }
X
X if (dx < 0) {
X /*
X * We're in octants 4 or 5.
X * Swap the starting and ending points, mapping
X * octant 4 to 8, and octant 5 to 1.
X * This will generate the points in reverse order
X * for octants 3 and 5 (i.e., we'll go from the end
X * to the beginning), but who cares?
X */
X
X SWAPSHORT(x0, x1); /* swap start and end points */
X SWAPSHORT(y0, y1);
X dx = -dx; /* dx becomes positive */
X dy = -dy; /* dy can be positive or negative */
X }
X
X /*
X * At this point we're guaranteed that dx >= 0, and x0 < x1.
X */
X
X if (dy < 0) {
X /*
X * Octants 3, 4, 7 or 8.
X * x will be: x1, x1-1, x1-2, ..., x0.
X */
X
X xend = x0;
X y = y1;
X
X incr1 = 2 * (-dy); /* remember that dy < 0 */
X d = incr1 - dx; /* 2*dy - dx */
X incr2 = d - dx; /* 2*dy - 2*dx = 2*(dy - dx) */
X
X if (rotate) { /* main loop, octants 3 or 7 */
X
X for (x = x1; x >= xend; x--) {
X PLOT(y, x);
X
X if (d > 0) {
X y++;
X d += incr2;
X } else
X d += incr1;
X }
X
X } else { /* main loop, octants 4 or 8 */
X
X for (x = x1; x >= xend; x--) {
X PLOT(x, y);
X
X if (d > 0) {
X y++;
X d += incr2;
X } else
X d += incr1;
X }
X }
X
X } else {
X /*
X * Octants 1, 2, 5 or 6.
X * x will be: x0, x0+1, x0+2, ..., x1.
X */
X
X xend = x1;
X y = y0;
X
X incr1 = 2 * dy;
X d = incr1 - dx; /* 2*dy - dx */
X incr2 = d - dx; /* 2*dy - 2*dx = 2*(dy - dx) */
X
X if (rotate) { /* main loop, octants 2 or 6 */
X
X for (x = x0; x <= xend; x++) {
X PLOT(y, x);
X
X if (d > 0) {
X y++;
X d += incr2;
X } else
X d += incr1;
X }
X } else { /* main loop, octants 1 or 5 */
X
X for (x = x0; x <= xend; x++) {
X PLOT(x, y);
X
X if (d > 0) {
X y++;
X d += incr2;
X } else
X d += incr1;
X }
X }
X }
X}
END__of_the__FILE
if test `wc -c < ./drawline.c` -ne 3419
then
echo "\tWAIT A MINUTE ... Expecting file size of 3419 bytes"
echo "\t but got a file size of `wc -c < ./drawline.c` bytes"
echo "\tWARNING ......... Suggest you check file contents."
fi
else
echo "will not over write ./drawline.c"
fi
if `test ! -s ./ellipse.c`
then
echo "extracting ./ellipse.c ..."
sed 's/^X//' > ./ellipse.c << 'END__of_the__FILE'
X/*
X * Draw an ellipse.
X *
X * The algorithm is from "An Efficient Ellipse-Drawing Algorithm" by
X * Jerry R. Van Aken, IEEE CG&A, September 1984, pp. 24-35,
X * specifically, Figure 10 on page 32.
X */
X
X#include "plot.h" /* need definition of PLOT() */
X
Xellipse(centerx, centery, a, b)
Xint centerx, centery; /* center of ellipse, in device coordinates */
Xint a, b; /* a = "radius" in x, b = "radius" in y */
X{
X register long d1, d2;
X register short x, y;
X register long t1, t2, t3, t4, t5, t6, t7, t8, t9;
X
X /* intermediate terms to speed up loop */
X t1 = a * a; t2 = t1 << 1; t3 = t2 << 1;
X t4 = b * b; t5 = t4 << 1; t6 = t5 << 1;
X t7 = a * t5; t8 = t7 << 1; t9 = 0L;
X
X d1 = t2 - t7 + (t4 >> 1); /* error terms */
X d2 = (t1 >> 1) - t8 + t5;
X
X x = a;
X y = 0;
X
X while (d2 < 0) { /* region 1 of ellipse */
X /* draw 4 points using symmetry */
X PLOT(centerx + x, centery + y);
X PLOT(centerx + x, centery - y);
X PLOT(centerx - x, centery + y);
X PLOT(centerx - x, centery - y);
X
X y++; /* always move up here */
X t9 += t3;
X if (d1 < 0) { /* move straight up */
X d1 += t9 + t2;
X d2 += t9;
X } else { /* move up and left */
X x--;
X t8 -= t6;
X d1 += t9 + t2 - t8;
X d2 += t9 + t5 - t8;
X }
X }
X
X do { /* region 2 of ellipse */
X /* draw 4 points using symmetry */
X PLOT(centerx + x, centery + y);
X PLOT(centerx + x, centery - y);
X PLOT(centerx - x, centery + y);
X PLOT(centerx - x, centery - y);
X
X x--; /* always move left here */
X t8 -= t6;
X if (d2 < 0) { /* move up and left */
X y++;
X t9 += t3;
X d2 += t9 + t5 - t8;
X } else /* move straight left */
X d2 += t5 - t8;
X } while (x >= 0);
X}
END__of_the__FILE
if test `wc -c < ./ellipse.c` -ne 1658
then
echo "\tWAIT A MINUTE ... Expecting file size of 1658 bytes"
echo "\t but got a file size of `wc -c < ./ellipse.c` bytes"
echo "\tWARNING ......... Suggest you check file contents."
fi
else
echo "will not over write ./ellipse.c"
fi
if `test ! -s ./erase.c`
then
echo "extracting ./erase.c ..."
sed 's/^X//' > ./erase.c << 'END__of_the__FILE'
X/*
X * Erase the screen.
X */
X
X#include "plot.h"
X
Xpl_erase()
X{
X _3b1erase();
X}
END__of_the__FILE
if test `wc -c < ./erase.c` -ne 77
then
echo "\tWAIT A MINUTE ... Expecting file size of 77 bytes"
echo "\t but got a file size of `wc -c < ./erase.c` bytes"
echo "\tWARNING ......... Suggest you check file contents."
fi
else
echo "will not over write ./erase.c"
fi
if `test ! -s ./exit.c`
then
echo "extracting ./exit.c ..."
sed 's/^X//' > ./exit.c << 'END__of_the__FILE'
X/*
X * All done. Called when all the plotfiles have been processed.
X * This routine should do any cleanup required by the device,
X * then exit(0) to the system.
X */
X
X#include <signal.h>
X#include "plot.h"
X
Xpl_exit(rc)
Xint rc;
X{
X signal(SIGINT, SIG_IGN); /* disable interupt catching */
X
X _3b1exit(rc); /* close the device and exit */
X
X exit(rc); /* shouldn't get here */
X}
END__of_the__FILE
if test `wc -c < ./exit.c` -ne 374
then
echo "\tWAIT A MINUTE ... Expecting file size of 374 bytes"
echo "\t but got a file size of `wc -c < ./exit.c` bytes"
echo "\tWARNING ......... Suggest you check file contents."
fi
else
echo "will not over write ./exit.c"
fi
if `test ! -s ./label.c`
then
echo "extracting ./label.c ..."
sed 's/^X//' > ./label.c << 'END__of_the__FILE'
X/*
X * Place the following string so that its first character
X * falls on the current point. The currentx and currenty
X * must be updated to point to the end of the string.
X */
X
Xpl_label(str)
Xchar *str;
X{
X _3b1label(str);
X}
END__of_the__FILE
if test `wc -c < ./label.c` -ne 224
then
echo "\tWAIT A MINUTE ... Expecting file size of 224 bytes"
echo "\t but got a file size of `wc -c < ./label.c` bytes"
echo "\tWARNING ......... Suggest you check file contents."
fi
else
echo "will not over write ./label.c"
fi
if `test ! -s ./line.c`
then
echo "extracting ./line.c ..."
sed 's/^X//' > ./line.c << 'END__of_the__FILE'
X/*
X * Draw a line from a specified starting point to a specified
X * ending point.
X */
X
X#include "plot.h"
X
Xpl_line(x0, y0, x1, y1)
Xint x0, y0; /* starting point of line, user coordinates */
Xint x1, y1; /* ending point of line, user coodinates */
X{
X currentx = Xuser2dev(x1); /* current will become end of line */
X currenty = Yuser2dev(y1);
X
X draw_line(Xuser2dev(x0), Yuser2dev(y0), currentx, currenty);
X}
END__of_the__FILE
if test `wc -c < ./line.c` -ne 406
then
echo "\tWAIT A MINUTE ... Expecting file size of 406 bytes"
echo "\t but got a file size of `wc -c < ./line.c` bytes"
echo "\tWARNING ......... Suggest you check file contents."
fi
else
echo "will not over write ./line.c"
fi
if `test ! -s ./linemod.c`
then
echo "extracting ./linemod.c ..."
sed 's/^X//' > ./linemod.c << 'END__of_the__FILE'
X/*
X * Modify the line drawing.
X *
X * NOT IMPLEMENTED.
X */
X
Xpl_linemod(str)
Xchar *str;
X{
X if (strcmp(str, "dotted") == 0) {
X return;
X } else if (strcmp(str, "solid") == 0) {
X return;
X } else if (strcmp(str, "longdashed") == 0) {
X return;
X } else if (strcmp(str, "shortdashed") == 0) {
X return;
X } else if (strcmp(str, "dotdashed") == 0) {
X return;
X } else {
X return;
X }
X}
END__of_the__FILE
if test `wc -c < ./linemod.c` -ne 377
then
echo "\tWAIT A MINUTE ... Expecting file size of 377 bytes"
echo "\t but got a file size of `wc -c < ./linemod.c` bytes"
echo "\tWARNING ......... Suggest you check file contents."
fi
else
echo "will not over write ./linemod.c"
fi
if `test ! -s ./main.c`
then
echo "extracting ./main.c ..."
sed 's/^X//' > ./main.c << 'END__of_the__FILE'
X/*
X * Generic driver for plot(1) filters.
X *
X * plot [ -x xresolution ] [ -y yresolution ] [ -F fontfile ] [ -d ]
X * [ -u ] [ plotfile ... ]
X *
X * The -x and -y options allow you to specify the number of pixels to
X * be used in each direction.
X *
X * The -u option sets the x and y resolutions so that the aspect
X * ratio of the displayed picture is unity.
X *
X * The -d option prints out the contents of the plot file instead
X * of plotting it (debug mode).
X *
X * The -F option allows you to specify an alternate font file that
X * will be used for the label commands.
X *
X * The optional plotfile arguments are files containing plot(5)
X * format plot data. If no plotfile arguments are specified,
X * the standard input is read. We handle more than one plotfile
X * argument, clearing the screen between each, but I'm not sure
X * how usefule this is.
X */
X
X#include "plot.h"
X
Xchar *pname; /* name by which we are invoked, for error mesg */
Xint debug = 0; /* set to 1 for debug output only */
X
Xmain(argc, argv)
Xint argc;
Xchar *argv[];
X{
X FILE *fopen();
X register FILE *fp;
X register char *s;
X register int i;
X
X pname = argv[0];
X while ((--argc > 0) && ((*++argv)[0] == '-'))
X for (s = argv[0]+1; *s != '\0'; s++)
X switch (*s) {
X case 'F': /* font file for labels */
X argc--;
X fontfile = *++argv;
X break;
X
X case 'd': /* debug output */
X debug = 1;
X break;
X
X case 'u': /* set aspect ratio = unity */
X xmax = XMAX_UNITY;
X ymax = YMAX_UNITY;
X break;
X
X case 'x':
X argc--;
X xmax = atoi(*++argv) - 1;
X if ((xmax <= 1) || (xmax > XMAX)) {
X fprintf(stderr, "%s: invalid -x value\n", pname);
X exit(1);
X }
X break;
X
X case 'y':
X argc--;
X ymax = atoi(*++argv) - 1;
X if ((ymax <= 1) || (ymax > YMAX)) {
X fprintf(stderr, "%s: invalid -y value\n", pname);
X exit(1);
X }
X break;
X
X default:
X fprintf(stderr, "%s: illegal option %c\n",
X pname, *s);
X exit(1);
X }
X
X i = 0;
X fp = stdin; /* default to stdin, if no plotfile argument */
X do {
X if ((argc > 0) && (fp = fopen(argv[i], "r")) == NULL) {
X fprintf(stderr, "%s: can't open %s\n", pname, argv[i]);
X continue;
X }
X
X doplot(fp);
X
X } while (++i < argc);
X
X pl_exit(0); /* cleanup and return to OS */
X}
X
X/*
X * Plot a single file.
X */
X
Xdoplot(fp)
Xregister FILE *fp;
X{
X register int c, xi, yi, x0, y0, x1, y1, r, dx, n, i;
X int pat[256];
X char s[256];
X int getsi();
X void getstr();
X
X if (fp == stdin) {
X /*
X * If we're reading the plot commands from stdin
X * (i.e., a pipe) then we'll reopen stdin on another
X * file descriptor, so that fd 0 can be saved for the
X * screen.
X */
X
X FILE *fopen();
X
X if ((fp = fdopen(dup(0), "r")) == NULL)
X err("can't fdopen stdin for reading");
X }
X
X if (debug)
X printf("openpl\n");
X else
X pl_open();
X
X while((c = getc(fp)) != EOF) {
X switch(c) {
X case 'm':
X xi = getsi(fp);
X yi = getsi(fp);
X if(debug)
X printf("move %d %d\n", xi, yi);
X else
X pl_move(xi, yi);
X break;
X
X case 'l':
X x0 = getsi(fp);
X y0 = getsi(fp);
X x1 = getsi(fp);
X y1 = getsi(fp);
X if(debug)
X printf("line %d %d, %d %d\n", x0, y0, x1, y1);
X else
X pl_line(x0, y0, x1, y1);
X break;
X
X case 't':
X getstr(s, fp);
X if(debug)
X printf("label '%s'\n", s);
X else
X pl_label(s);
X break;
X
X case 'e':
X if(debug)
X printf("erase\n");
X else
X pl_erase();
X break;
X
X case 'p':
X xi = getsi(fp);
X yi = getsi(fp);
X if(debug)
X printf("point %d %d\n", xi, yi);
X else
X pl_point(xi, yi);
X break;
X
X case 'n':
X xi = getsi(fp);
X yi = getsi(fp);
X if(debug)
X printf("cont %d %d\n", xi, yi);
X else
X pl_cont(xi, yi);
X break;
X
X case 's':
X x0 = getsi(fp);
X y0 = getsi(fp);
X x1 = getsi(fp);
X y1 = getsi(fp);
X if(debug)
X printf("space %d %d, %d %d\n", x0, y0, x1, y1);
X else
X pl_space(x0, y0, x1, y1);
X break;
X
X case 'a':
X xi = getsi(fp);
X yi = getsi(fp);
X x0 = getsi(fp);
X y0 = getsi(fp);
X x1 = getsi(fp);
X y1 = getsi(fp);
X if(debug)
X printf("arc %d %d, %d %d, %d %d\n",
X xi, yi, x0, y0, x1, y1);
X else
X pl_arc(xi, yi, x0, y0, x1, y1);
X break;
X
X case 'c':
X xi = getsi(fp);
X yi = getsi(fp);
X r = getsi(fp);
X if(debug)
X printf("circle %d %d, %d\n", xi, yi, r);
X else
X pl_circle(xi, yi, r);
X break;
X
X case 'f':
X getstr(s, fp);
X if(debug)
X printf("linemod %s\n", s);
X else
X pl_linemod(s);
X break;
X
X case 'd':
X xi = getsi(fp);
X yi = getsi(fp);
X dx = getsi(fp);
X n = getsi(fp);
X for(i = 0; i < n; i++)
X pat[i] = getsi(fp);
X if(debug)
X printf("dot %d %d, %d, %d\n, xi, yi, dx, n");
X else
X pl_dot(xi, yi, dx, n, pat);
X break;
X
X default:
X err("unknown plot command");
X exit(1);
X }
X }
X fclose(fp);
X
X if(debug)
X printf("closepl\n");
X else
X pl_close();
X}
X
X/*
X * Get a "short integer" that is stored in two consecutive bytes.
X */
X
Xint
Xgetsi(fp)
Xregister FILE *fp;
X{
X register int a, b;
X
X if ((b = getc(fp)) == EOF)
X return(EOF);
X if ((a = getc(fp)) == EOF)
X return(EOF);
X a <<= 8;
X return(a | b);
X}
X
X/*
X * Get a string (all characters up to the next newline).
X * The newline is not stored, but is replaced with a null byte.
X * Used for the "label" and "linemod" plotting commands.
X */
X
Xvoid
Xgetstr(s, fp)
Xregister char *s;
Xregister FILE *fp;
X{
X for( ; *s = getc(fp); s++)
X if(*s == '\n')
X break;
X *s = '\0'; /* overwrites newline with null */
X}
END__of_the__FILE
if test `wc -c < ./main.c` -ne 5377
then
echo "\tWAIT A MINUTE ... Expecting file size of 5377 bytes"
echo "\t but got a file size of `wc -c < ./main.c` bytes"
echo "\tWARNING ......... Suggest you check file contents."
fi
else
echo "will not over write ./main.c"
fi
if `test ! -s ./move.c`
then
echo "extracting ./move.c ..."
sed 's/^X//' > ./move.c << 'END__of_the__FILE'
X/*
X * Move to the new current point.
X */
X
X#include "plot.h"
X
Xpl_move(x, y)
Xint x, y; /* new current point, in user coordinates */
X{
X currentx = Xuser2dev(x); /* convert to device coordinates */
X currenty = Yuser2dev(y);
X}
END__of_the__FILE
if test `wc -c < ./move.c` -ne 223
then
echo "\tWAIT A MINUTE ... Expecting file size of 223 bytes"
echo "\t but got a file size of `wc -c < ./move.c` bytes"
echo "\tWARNING ......... Suggest you check file contents."
fi
else
echo "will not over write ./move.c"
fi
if `test ! -s ./open.c`
then
echo "extracting ./open.c ..."
sed 's/^X//' > ./open.c << 'END__of_the__FILE'
X/*
X * Open the graphics device - called at the beginning of every plot file.
X */
X
X#include <signal.h>
X#include "plot.h"
X
Xpl_open()
X{
X int pl_close();
X
X signal(SIGINT, pl_close); /* catch interupts */
X
X currentx = 0; /* default current point */
X currenty = 0;
X
X _3b1init(); /* 3b1 specific initialization */
X
X pl_space(0, 0, XMAX, YMAX); /* in case caller doesn't specify */
X}
END__of_the__FILE
if test `wc -c < ./open.c` -ne 380
then
echo "\tWAIT A MINUTE ... Expecting file size of 380 bytes"
echo "\t but got a file size of `wc -c < ./open.c` bytes"
echo "\tWARNING ......... Suggest you check file contents."
fi
else
echo "will not over write ./open.c"
fi
if `test ! -s ./point.c`
then
echo "extracting ./point.c ..."
sed 's/^X//' > ./point.c << 'END__of_the__FILE'
X/*
X * Plot a point at the specified position.
X */
X
X#include "plot.h"
X
Xpl_point(x, y)
Xint x, y; /* in user coordinates */
X{
X pl_move(x, y); /* sets the new current point */
X
X PLOT(currentx, currenty);
X}
END__of_the__FILE
if test `wc -c < ./point.c` -ne 204
then
echo "\tWAIT A MINUTE ... Expecting file size of 204 bytes"
echo "\t but got a file size of `wc -c < ./point.c` bytes"
echo "\tWARNING ......... Suggest you check file contents."
fi
else
echo "will not over write ./point.c"
fi
if `test ! -s ./space.c`
then
echo "extracting ./space.c ..."
sed 's/^X//' > ./space.c << 'END__of_the__FILE'
X/*
X * Specify the user coordinates of the drawing area.
X * Note that the specified "upper right corner" is just outside the
X * plotting area. So if you specify space(0, 0, 4096, 4096), the actual
X * display area is from the lower left corner of (0, 0) to the upper
X * right corner of (4095, 4095).
X */
X
X#include "plot.h"
X
Xpl_space(x0, y0, x1, y1)
Xint x0, y0; /* lower left corner, in user coordinates */
Xint x1, y1; /* upper right corner, in user coordinates */
X{
X lowx = x0;
X lowy = y0;
X scalex = xmax / (FLOAT)(x1 - lowx);
X scaley = ymax / (FLOAT)(y1 - lowy);
X}
END__of_the__FILE
if test `wc -c < ./space.c` -ne 567
then
echo "\tWAIT A MINUTE ... Expecting file size of 567 bytes"
echo "\t but got a file size of `wc -c < ./space.c` bytes"
echo "\tWARNING ......... Suggest you check file contents."
fi
else
echo "will not over write ./space.c"
fi
if `test ! -s ./varsinit.c`
then
echo "extracting ./varsinit.c ..."
sed 's/^X//' > ./varsinit.c << 'END__of_the__FILE'
X/*
X * Definitions of externs.
X */
X
X#include "plot.h"
X
Xint xmax = XMAX; /* in device coordinates */
Xint ymax = YMAX;
X
Xint currentx = 0; /* in device coordinates */
Xint currenty = 0;
X
Xint lowx = 0; /* in user coordinates */
Xint lowy = 0;
X
XFLOAT scalex = 1.0;
XFLOAT scaley = 1.0;
END__of_the__FILE
if test `wc -c < ./varsinit.c` -ne 284
then
echo "\tWAIT A MINUTE ... Expecting file size of 284 bytes"
echo "\t but got a file size of `wc -c < ./varsinit.c` bytes"
echo "\tWARNING ......... Suggest you check file contents."
fi
else
echo "will not over write ./varsinit.c"
fi
if `test ! -d ./test`
then
mkdir ./test
echo "mkdir ./test"
fi
if `test ! -s ./test/Makefile`
then
echo "extracting ./test/Makefile ..."
sed 's/^X//' > ./test/Makefile << 'END__of_the__FILE'
X#
Xinclude $(MAKEINC)/Makepre.h
X
XCFLAGS=
X
Xall: test1 test2
X
Xtest1: test1.o
X $(LD) $(LDFLAGS) $(SHAREDLIB) test1.o -lplot -o test1
X
Xtest2: test2.o
X $(LD) $(LDFLAGS) $(SHAREDLIB) test2.o -lplot -o test2
X
Xinclude $(MAKEINC)/Makepost.h
END__of_the__FILE
if test `wc -c < ./test/Makefile` -ne 235
then
echo "\tWAIT A MINUTE ... Expecting file size of 235 bytes"
echo "\t but got a file size of `wc -c < ./test/Makefile` bytes"
echo "\tWARNING ......... Suggest you check file contents."
fi
else
echo "will not over write ./test/Makefile"
fi
if `test ! -s ./test/test1.c`
then
echo "extracting ./test/test1.c ..."
sed 's/^X//' > ./test/test1.c << 'END__of_the__FILE'
Xmain()
X{
X openpl();
X space(0, 0, 4096, 4096);
X erase();
X
X /*
X * Draw a box around the whole screen.
X */
X
X line(0, 0, 0, 4000);
X cont(4000, 4000);
X cont(4000, 0);
X cont(0, 0);
X
X /*
X * Draw a diagonal from (0,0) to (4000,4000), then another
X * one from (0,4000) to (4000,0).
X */
X
X move(0, 0);
X cont(4000, 4000);
X move(0, 4000);
X cont(4000, 0);
X
X /*
X * Draw 3 x lines and 3 y lines.
X */
X
X line(0, 1000, 4000, 1000);
X line(0, 2000, 4000, 2000);
X line(0, 3000, 4000, 3000);
X
X line(1000, 0, 1000, 4000);
X line(2000, 0, 2000, 4000);
X line(3000, 0, 3000, 4000);
X
X /*
X * Draw some circles at the center.
X */
X
X circle(2000, 2000, 250);
X circle(2000, 2000, 500);
X circle(2000, 2000, 750);
X circle(2000, 2000, 1000);
X circle(2000, 2000, 1250);
X circle(2000, 2000, 1500);
X circle(2000, 2000, 1750);
X circle(2000, 2000, 2000);
X
X /*
X * Draw a circle at (1000, 3000) to make sure the circle
X * algorithm starts and ends at the right place.
X */
X
X circle(1000, 3000, 1000);
X
X closepl();
X}
END__of_the__FILE
if test `wc -c < ./test/test1.c` -ne 986
then
echo "\tWAIT A MINUTE ... Expecting file size of 986 bytes"
echo "\t but got a file size of `wc -c < ./test/test1.c` bytes"
echo "\tWARNING ......... Suggest you check file contents."
fi
else
echo "will not over write ./test/test1.c"
fi
if `test ! -s ./test/test2.c`
then
echo "extracting ./test/test2.c ..."
sed 's/^X//' > ./test/test2.c << 'END__of_the__FILE'
Xmain()
X{
X openpl();
X space(0, 0, 4096, 4096);
X erase();
X
X /*
X * Draw a box around the whole screen.
X */
X
X line(0, 0, 0, 4000);
X cont(4000, 4000);
X cont(4000, 0);
X cont(0, 0);
X
X /*
X * Draw 3 x lines and 3 y lines.
X */
X
X line(0, 1000, 4000, 1000);
X line(0, 2000, 4000, 2000);
X line(0, 3000, 4000, 3000);
X
X line(1000, 0, 1000, 4000);
X line(2000, 0, 2000, 4000);
X line(3000, 0, 3000, 4000);
X
X /*
X * Draw 8 diagonal lines, one for each octant, to test
X * the line drawing algorithm.
X */
X
X line(0, 0, 4000, 2000); /* octant 1 */
X line(0, 0, 2000, 4000); /* octant 2 */
X line(4000, 0, 2000, 4000); /* octant 3 */
X line(4000, 0, 0, 2000); /* octant 4 */
X line(4000, 4000, 0, 2000); /* octant 5 */
X line(4000, 4000, 2000, 0); /* octant 6 */
X line(0, 4000, 2000, 0); /* octant 7 */
X line(0, 4000, 4000, 2000); /* octant 8 */
X
X line(0, 0, 4000, 4000); /* and a 45-degree diagonal */
X line(0, 4000, 4000, 0); /* and a minus 45-degree diagonal */
X
X closepl();
X}
END__of_the__FILE
if test `wc -c < ./test/test2.c` -ne 962
then
echo "\tWAIT A MINUTE ... Expecting file size of 962 bytes"
echo "\t but got a file size of `wc -c < ./test/test2.c` bytes"
echo "\tWARNING ......... Suggest you check file contents."
fi
else
echo "will not over write ./test/test2.c"
fi
echo "Finished archive 1 of 1"
# if you want to concatenate archives, remove anything after this line
exit