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