rsalz@bbn.com (Rich Salz) (04/07/88)
Submitted-by: Joe Dellinger <joe@hanauma.STANFORD.EDU> Posting-number: Volume 14, Issue 29 Archive-name: vplot/part24 #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 24 (of 24)." # Wrapped by rsalz@fig.bbn.com on Fri Mar 25 11:47:38 1988 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'Vplot_Kernel/filters/dovplot.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Vplot_Kernel/filters/dovplot.c'\" else echo shar: Extracting \"'Vplot_Kernel/filters/dovplot.c'\" \(51559 characters\) sed "s/^X//" >'Vplot_Kernel/filters/dovplot.c' <<'END_OF_FILE' X/* X * Copyright 1987 the Board of Trustees of the Leland Stanford Junior X * University. Official permission to use this software is included in X * the documentation. It authorizes you to use this file for any X * non-commercial purpose, provided that this copyright notice is not X * removed and that any modifications made to this file are commented X * and dated in the style of my example below. X */ X X/* X * X * source file: ./filters/dovplot.c X * X * Joe Dellinger (SEP), June 11 1987 X * Inserted this sample edit history entry. X * Please log any further modifications made to this file: X */ X/* X * Joe Dellinger Oct 18 1987 X * Made text fatness scale with txscale and scale for GKS compatibility X * Joe Dellinger Nov 9 1987 X * Changed "\n" to CRLF in MESG_TEXT calls, since newlines are X * no longer mapped into Carriage-return linefeeds automatically. X * (This was due to Stew's turning off of output translation.) X * Joe Dellinger Dec 9 1987 X * Made the "bad color level" error message more verbose. X * Joe Dellinger Dec 19 1987 X * Call dev.attributes(NEW_DASH,...) when the dash pattern has X * been changed, call dev.attributes(NEW_PAT,...) when a new raster X * pattern has been loaded, call dev.attributes(NEW_FONT,...) X * when the txfont, txprec, or txovly has been changed, X * dev.attributes(NEW_OVERLAY,...) when the overlay mode has X * been changed, dev.attributes(NEW_ALIGN) when the text X * alignment mode has been changed, dev.attributes(NEW_FAT) when X * the fatness has been changed. Call dev.message(MESG_MESSAGE) X * when a message is generated via the VP_MESSAGE vplot command. X * Joe Dellinger Dec 20 1987 X * It's up to the device to turn around and call gentext if X * txfont < NUMGENFONT. X * Joe Dellinger Jan 8 1988 X * Added reset_parameters() to frontend and dovplot. X * Turn off ALL polygon shading if shade=NO, even that generated X * by raster, text, etc. X * Joe Dellinger Jan 10 1988 X * Don't blindly scale up fatmult each time dovplot thinks it's X * being called for the first time. X * Joe Dellinger Jan 14 1988 X * The text alignment should also be reset between plots. X * Joe Dellinger Jan 20 1988 X * Added VP_BEGIN_GROUP and VP_END_GROUP. Fixed nplots bug. X * Joe Dellinger Jan 22 1988 X * Added xdim_orig and ydim_orig to pat.h. X * Joe Dellinger Jan 26 1988 X * Fixed EOF bug in getvpstring(). Changed rule for mapping X * colors to grey levels to match how B+W TV's do it. X * Joe Dellinger Feb 10 1988 X * Weight color mismatches to tally with grey mapping method. X * Joe Dellinger Feb 12 1988 X * Make sure that VP_WINDOW commands that specify an inverted X * clipping rectangle cause everything to be clipped away. X * Joe Dellinger Feb 16 1988 X * Make number of arguments passed to dev.attributes and dev.raster X * constant to head off future catastrophe from Sun IV's. X * Joe Dellinger Feb 22 1988 X * Created INT_PAUSE to be separate from INT_GET_STRING. X * Joe Dellinger Feb 24 1988 X * Txfont, txprec, txovly, style, dash line style also reset X * on erases. X * Only the erase command is handled specially at the start X * of the file. This was causing initial setstyle commands X * to be left out of their groups! X * Joe Dellinger Feb 26 1988 X * Allow vpattributes(END_GROUP,...) to signal dovplot whether it X * should exit or not after the call. X * Joe Dellinger Feb 28 1988 X * Fatness behaves like a geometric attribute. X * Can't use the *= operator on the Sun! X * if integer i = 10, then i *= .5 sets i to ZERO. X * I wish Sun would get their act together. X * This explains several mysterious bugs on the Suns. X */ X X/* X * process a vplot file or stream X * Keywords: vplot pen generic X */ X X#include <stdio.h> X#include <math.h> X#include <ctype.h> X#include <strings.h> X X#include <vplot.h> X X#include "./include/params.h" /* for machine dependencies */ X#include "./include/enum.h" X#include "./include/err.h" X#include "./include/attrcom.h" X#include "./include/intcom.h" X#include "./include/mesgcom.h" X#include "./include/erasecom.h" X#include "./include/closestat.h" X#include "./include/getxy.h" X#include "./include/pat.h" X#include "./include/vertex.h" X#include "./include/extern.h" X#include "./include/round.h" X X#define COLOR_MAP(A) color_set[A][MAP]; X#define GREY_MAP(A) color_set[A][_GREY]; X X/* X * Banished to an include file so that "indent" can't get its hands on it X */ X#include "./include/readraster.h" X extern int wantras, smart_raster; extern int allowecho; extern int brake; extern FILE *controltty; extern int cur_color; extern int pat_color; extern int epause; extern int erase; extern int ever_called; extern int fatbase; extern int ifat; extern int first_time; extern int framewindows; extern int next_color; extern int ipat; extern int nplots; extern int overlay; extern struct pat pat[]; extern FILE *pltout, *pltin, *temp; extern char group_name[]; extern int group_number; extern char *txbuffer; extern int txbuflen; extern struct vertex *vxbuffer; extern int vxbuflen; extern int window; extern int xwmax, xwmin, ywmax, ywmin; extern int xWmax, xWmin, yWmax, yWmin; int xwmin_last, xwmax_last, ywmin_last, ywmax_last; extern int xnew, ynew; extern int xold, yold; extern int xorigin, yorigin; extern float scale; extern float xscale; extern float yscale; extern int default_style; extern int default_txfont, default_txprec, default_txovly; extern int default_overlay; extern int color_set[MAX_COL + 1][_NUM_PRIM]; extern int greycorr (); extern int num_col_8; extern int xret, yret; extern int add_a_cor (); extern char interact[]; extern float dashsum; extern float dashpos; extern float dashes[]; extern struct txalign txalign; X char *malloc (); char *calloc (); char *realloc (); long int ftell (); extern void dithline (); extern void wlimit (); X int need_devcolor = NO; X dovplot () X{ int i, j, k, c; int key, size, npts; int nmul; int nx, ny, nx_orig, ny_orig; int orient, ras_orient; register int *ptr; int nx_mult, ny_mult; int nx_temp, ny_temp; int *tempbuf, *ptemp; FILE *fopen (); int new_style; int starterase = 0; int col_tab_no, red, green, blue, grey, dist, min_dist, best_col; int hacol[NHATCH * 2], hafat[NHATCH * 2], haoff[NHATCH * 2], hasiz[NHATCH * 2], numhatch; float angle, xrasmult, yrasmult; int xpix, ypix, num_pat, num_byte; int yrast, lastrast; int xvr_min, xvr_max, yvr_min, yvr_max; int xr_min, xr_max, yr_min, yr_max; int xvru_min, xvru_max, yvru_min, yvru_max; int xru_min, yru_max; int xxx[4], yyy[4]; int pos, ii, jj, kk, num_rep, ras_offset, dither_it; unsigned char *rasterline, *rasterline2, *outraster, *outraster2; unsigned char ibyte; int xnewer, ynewer; int xtext0, xtext1, xtext2, ytext0, ytext1, ytext2; int type; int *marker_vec, *mvec; int savefat; float savefatmult; char string[MAXFLEN + 1]; X X /* X * Check to make sure we really got anything before we claim we've made a X * plot. X */ X if ((c = getc (pltin)) == EOF) X return; X ungetc ((char) c, pltin); X X while (((c = getc (pltin)) == VP_ERASE) || ((c == VP_BREAK) && brake)) X { X /* X * This is a baby version of the main switch that takes up most of X * this file. X */ X switch (c) X { X case VP_ERASE: X case VP_BREAK: X starterase = 1; X break; X } X } X X /* X * Files that consist only of erase characters and nothing else are X * ignored. X */ X if (c == EOF) X return; X ungetc ((char) c, pltin); X X if (first_time) X { X dev.reset (); X/* X * Device is now officially open for orders. X */ X if (dev_xmax <= dev_xmin || X dev_ymax <= dev_ymin || X pixels_per_inch == 0. || X aspect_ratio == 0. || X num_col == -1) X ERR (FATAL, name, "Critical variables left unset by device!"); X X/* X * Set maximum clipping window for dev.attributes(SET_WINDOW) X */ X xwmax_last = dev_xmax; X xwmin_last = dev_xmin; X ywmax_last = dev_ymax; X ywmin_last = dev_ymin; X X/* X * Set up color maps X */ X init_colors (); X X ever_called = 1; X } X else X { X dev.close (CLOSE_FLUSH); X if (epause > 0) X { X sleep ((unsigned) epause); X } X else X if (epause < 0) X { X dev.close (CLOSE_FLUSH); X message (MESG_ERASE); X message (MESG_ON); X message (MESG_HOME); X message (MESG_READY); X message (MESG_HIGHLIGHT_ON); X message (MESG_TEXT, "Type Return to Continue... "); X message (MESG_DONE); X dev.interact (INT_PAUSE, controltty, string); X message (MESG_HIGHLIGHT_OFF); X if (!allowecho) X { X message (MESG_READY); X message (MESG_TEXT, CRLF); X } X message (MESG_DONE); X message (MESG_OFF); X message (MESG_ERASE); X } X /* X * Inquire point back from device X */ X if (interact[0] != '\0') X { X getapoint (); X } X } X X /* X * Erase the screen to background color X */ X if (((erase & FORCE_INITIAL) && (first_time || (erase & DO_LITERALS))) X || (starterase && (erase & DO_LITERALS))) X { X if (first_time) X dev.erase (ERASE_START); X else X { X dev.erase (ERASE_MIDDLE); X nplots++; X } X dev.close (CLOSE_FLUSH); X } X X first_time = NO; X X/* X * Reset fatness, cur_color, etc. X */ X new_style = default_style; X setstyle (new_style); X reset (); X X/* X * Make SURE the color is what it's supposed to be, just to be safe. X */ X dev.attributes (SET_COLOR, cur_color, 0, 0, 0); X need_devcolor = NO; X X message (MESG_OFF); X dev.close (CLOSE_FLUSH); X X/* X * Start a group that will contain this frame (always group 0). X */ X ii = ftell (pltin); X sprintf (group_name, "%s.%d", pltname, nplots); X dev.attributes (BEGIN_GROUP, group_number, ii, 0, 0); X group_number++; X X if (framewindows) X outline_window (); X X/* X * Finally, here's the main loop that does the actual processing of vplot. X * Notice that some tricky commands (VP_DRAW, VP_SET_COLOR_TABLE) look ahead X * at the next command to try to anticipate often-occuring situations, X * so things get a little complicated here. X */ X while ((c = getc (pltin)) != EOF) X { X switch (c) /* command list */ X { X case VP_SETSTYLE: /* set the style */ X c = getc (pltin); X if ((c == 'r') || (c == 'R') || (c == 'm') || (c == 'M')) X new_style = ROTATED; X else X if ((c == 'o') || (c == 'O')) X new_style = OLD; X else X if ((c == 'a') || (c == 'A')) X new_style = ABSOLUTE; X else X new_style = STANDARD; X setstyle (new_style); X X if (framewindows) X outline_window (); X X break; X case VP_MOVE: /* move */ X /* X * Reset position in dash pattern. X */ X dashpos = 0.; X X GETXY (xold, yold); X break; X case VP_DRAW: /* draw */ X GETXY (xnew, ynew); X update_color (); X while ((c = getc (pltin)) == VP_DRAW) X { X GETXY (xnewer, ynewer); X /* X * Is it the same point? X */ X if (xnewer == xnew && ynewer == ynew) X continue; X /* X * Is it colinear and horizontal or vertical? X */ X if ((ynewer == ynew && ynew == yold && X ((xnewer > xnew) == (xnew > xold))) || X (xnewer == xnew && xnew == xold && X ((ynewer > ynew) == (ynew > yold)))) X { X ynew = ynewer; X xnew = xnewer; X continue; X } X dev.vector (xold, yold, xnew, ynew, fat, dashon); X xold = xnew; X yold = ynew; X xnew = xnewer; X ynew = ynewer; X } X dev.vector (xold, yold, xnew, ynew, fat, dashon); X xold = xnew; X yold = ynew; X if (c == EOF) X goto End_of_file; X ungetc ((char) c, pltin); X break; X case VP_PLINE: /* polyline */ X /* X * Reset position in dash pattern. X */ X dashpos = 0.; X X npts = geth (pltin); X if (npts == 0) X break; X GETXY (xold, yold); X npts--; X if (npts == 0) X break; X GETXY (xnew, ynew); X npts--; X update_color (); X while (npts > 0) X { X GETXY (xnewer, ynewer); X npts--; X /* X * Is it the same point? X */ X if (xnewer == xnew && ynewer == ynew) X continue; X /* X * Is it colinear and horizontal or vertical? X */ X if ((ynewer == ynew && ynew == yold && X ((xnewer > xnew) == (xnew > xold))) || X (xnewer == xnew && xnew == xold && X ((ynewer > ynew) == (ynew > yold)))) X { X ynew = ynewer; X xnew = xnewer; X continue; X } X dev.vector (xold, yold, xnew, ynew, fat, dashon); X xold = xnew; X yold = ynew; X xnew = xnewer; X ynew = ynewer; X } X dev.vector (xold, yold, xnew, ynew, fat, dashon); X xold = xnew; X yold = ynew; X break; X case VP_PMARK: /* polymarker */ X npts = geth (pltin);/* how many markers ? */ X type = geth (pltin);/* what symbol? (any positive integer) */ X size = geth (pltin);/* How big? */ X size = size * mkscale * vdevscale * RPERIN / TXPERIN; X X if (npts == 0) X break; X /* allocate space for the points */ X marker_vec = (int *) malloc ((unsigned) (npts * 2 * sizeof (int))); X mvec = marker_vec; X if (mvec == NULL) X ERR (FATAL, name, "Can't malloc memory for markers!"); X X /* read the locations, and transform them to device coordinates */ X for (ii = 0; ii < npts; ii++) X { X GETXY (xnewer, ynewer); X *mvec = xnewer; X ++mvec; X *mvec = ynewer; X ++mvec; X } X update_color (); X /* call the device routine to display the markers */ X dev.marker (npts, type, size, marker_vec); X /* release the storage used for the points */ X free ((char *) marker_vec); X break; X case VP_ORIGIN: /* set origin */ X xorigin = geth (pltin); X yorigin = geth (pltin); X break; X case VP_BEGIN_GROUP: X ii = ftell (pltin) - 1; X getvpstring (); X strncpy (group_name, txbuffer, MAXFLEN); X dev.attributes (BEGIN_GROUP, group_number, ii, 0, 0); X group_number++; X break; X case VP_END_GROUP: X group_number--; X if (group_number < 1) X { X ERR (WARN, name, X "group invalidly nested"); X group_number = 1; X } X else X { X ii = dev.attributes (END_GROUP, group_number, 0, 0, 0); X if (ii == DOVPLOT_EXIT) X { X dev.close (CLOSE_FLUSH); X return; X } X if (ii != DOVPLOT_CONT) X ERR (WARN, name, "dev.attributes(END_GROUP,...) returned junk."); X } X break; X case VP_GTEXT: /* GKS-like text */ X xtext0 = 0; X ytext0 = 0; X vptodevxy (xtext0, ytext0, &xtext0, &ytext0); X GETXY (xtext1, ytext1); X GETXY (xtext2, ytext2); X g_text: X xtext1 -= xtext0; X xtext2 -= xtext0; X ytext1 -= ytext0; X ytext2 -= ytext0; X X savefat = fat; X savefatmult = fatmult; X fatmult *= txscale; X if (ifat >= 0) X { X fat = fatmult * (float) (ifat + fatbase); X } X else X { X fat = -1; X } X update_color (); X getvpstring (); X/* X * Fonts less than NUMGENFONT reserved for gentext fonts: X * up to the device to enforce that rule, though. X */ X dev.text (txbuffer, X (float) xtext1 / TEXTVECSCALE, X (float) ytext1 / TEXTVECSCALE, X (float) xtext2 / TEXTVECSCALE, X (float) ytext2 / TEXTVECSCALE); X fat = savefat; X fatmult = savefatmult; X break; X case VP_TEXT: /* text */ X size = geth (pltin); X size = size * txscale * (float) RPERIN / (float) TXPERIN; X orient = (int) geth (pltin); X new_text: X xtext0 = 0; X ytext0 = 0; X /* Character path direction */ X xtext1 = X ROUND (TEXTVECSCALE * size * cos (orient * 3.14159 / 180.)); X ytext1 = X ROUND (TEXTVECSCALE * size * sin (orient * 3.14159 / 180.)); X /* Character up vector direction */ X orient += 90; X xtext2 = X ROUND (TEXTVECSCALE * size * cos (orient * 3.14159 / 180.)); X ytext2 = X ROUND (TEXTVECSCALE * size * sin (orient * 3.14159 / 180.)); X vptodevxy (xtext0, ytext0, &xtext0, &ytext0); X vptodevxy (xtext1, ytext1, &xtext1, &ytext1); X vptodevxy (xtext2, ytext2, &xtext2, &ytext2); X goto g_text; X break; X case VP_OLDTEXT: /* archaic format text */ X if ((key = geth (pltin)) < 0) X ERR (FATAL, name, "invalid text key"); X size = (key & 037); X size = size * txscale * (float) RPERIN / (float) TXPERIN; X orient = (int) (((key & 0140) >> 5) * 90); X goto new_text; X break; X case VP_OLDAREA: /* polygon */ X npts = geth (pltin); X afat = geth (pltin); X if (afat >= 0) X { X afat = fatmult * (fatbase + afat); X } X nx_temp = geth (pltin); X ny_temp = geth (pltin); X X/* X * If a monochrome device, then fill with dot pattern. X * If a color device, fill with solid color. X */ X nx = nx_temp * patternmult; X if (nx_temp == 1 || (nx_temp > 0 && nx == 0)) X nx = 1; X ny = ny_temp * patternmult; X if (ny_temp == 1 || (ny_temp > 0 && ny == 0)) X ny = 1; X X nx_orig = nx; X ny_orig = ny; X X if (!mono) X { X if (nx_temp == 0 || ny_temp == 0) X { X nx = 0; X ny = 0; X } X else X { X nx = 1; X ny = 1; X } X } X /* X * Create a temporary pattern X */ X ipat = 0; X if (nx * ny > 0) X { X if ((ptr = (int *) calloc ((unsigned) nx * ny, sizeof (int))) == NULL) X ERR (FATAL, name, "cannot alloc memory to load pattern"); X pat[ipat] .patbits = ptr; X ptr[(nx * ny) - 1] = cur_color; X } X else X pat[ipat] .patbits = NULL; X X pat[ipat] .xdim = nx; X pat[ipat] .ydim = ny; X pat[ipat] .xdim_orig = nx_orig; X pat[ipat] .ydim_orig = ny_orig; X npts = getpolygon (npts); X update_color (); X if (afat >= 0) X vecoutline (vxbuffer); X if (npts > 2 && shade && nx > 0 && ny > 0) X dev.area (npts, vxbuffer); X if (nx * ny > 0) X free ((char *) ptr); X break; X case VP_AREA: /* polygon fill */ X npts = geth (pltin); X ipat = pat_color; X X if (pat[ipat] .patbits == NULL && shade) X { X /* X * Create a default pattern (solid fill with this color) If X * you don't like this default for a particular device, ie, a X * black and white one, then the device itself can set up X * defaults for colors 0 through 7 in dev.open X */ X nx = 1; X ny = 1; X X if ((ptr = (int *) calloc ((unsigned) nx * ny, sizeof (int))) == NULL) X ERR (FATAL, name, "cannot alloc memory to load pattern"); X pat[ipat] .patbits = ptr; X ptr[(nx * ny) - 1] = cur_color; X pat[ipat] .xdim = nx; X pat[ipat] .ydim = ny; X pat[ipat] .xdim_orig = nx; X pat[ipat] .ydim_orig = ny; X } X X npts = getpolygon (npts); X X if (!shade) X { X /* At least draw the boundary to show where it is */ X afat = 0; X update_color (); X vecoutline (vxbuffer); X } X else X { X /* See whether raster or hatch area */ X if (pat[ipat] .xdim >= 0) X { X /* raster */ X if (npts > 2 && pat[ipat] .ydim > 0 && pat[ipat] .xdim > 0) X { X update_color (); X dev.area (npts, vxbuffer); X } X } X else X { X /* hatch */ X numhatch = -pat[ipat] .xdim; X angle = 3.14159 * pat[ipat] .ydim / 180.; X ptr = pat[ipat] .patbits; X for (i = 0; i < numhatch * 2; i++) X { X hafat[i] = (*ptr++); X hacol[i] = (*ptr++); X haoff[i] = (*ptr++); X hasiz[i] = (*ptr++); X } X if (npts > 2) X { X /* X * Hatch patterns don't rotate. The polygon does, the X * fill pattern doesn't. X */ X genhatch (npts, numhatch, angle, hafat, hacol, haoff, hasiz, vxbuffer); X } X } X } X break; X case VP_FAT: /* fat */ X /* X * negative fat always means to not draw the line at all. X */ X ifat = geth (pltin); X if (ifat >= 0) X { X fat = fatmult * (float) (ifat + fatbase); X } X else X { X fat = -1; X } X dev.attributes (NEW_FAT, fat, 0, 0, 0); X break; X case VP_COLOR: /* change color */ X pat_color = geth (pltin); X if (pat_color > MAX_COL || pat_color < 0) X { X ERR (WARN, name, "bad color number %d (max %d, min 0)", X pat_color, MAX_COL); X pat_color = DEFAULT_COLOR; X } X next_color = COLOR_MAP (pat_color); X if (next_color != cur_color) X { X cur_color = next_color; X need_devcolor = YES; X } X /* X * Pattern zero reserved for the OLD_AREA command, so increment X * the rest by one to make room. X */ X pat_color++; X break; X case VP_SET_COLOR_TABLE: /* set color table entry */ X /* X * The logic here is a bit tricky. Basically, it goes like this: X * If the device actually has a settable color of that number, X * then reset the device's color as asked. Otherwise, take the X * closest color that we have and map to that. Color 0 is the X * background color, and is special. Merely "close" colors are X * not mapped to Color 0... it has to be exact. Even devices with X * NO settable colors are still sent colors 0 through 7, and X * these colors are then always left set to their original X * defaults. In this way you can handle terminals like the GIGI X * which have colors but not SETTABLE colors. Also remember that X * the device itself will THEN have to permute colors 0 through 7 X * on top of all this to correspond with Vplot's definitions! X */ X col_tab_no = geth (pltin); X if (col_tab_no > MAX_COL || col_tab_no < 0) X { X ERR (FATAL, name, "Bad color table value %d (%d max)", X col_tab_no, MAX_COL); X } X red = geth (pltin); X green = geth (pltin); X blue = geth (pltin); X if (red > MAX_GUN || green > MAX_GUN || blue > MAX_GUN X || red < 0 || green < 0 || blue < 0) X { X ERR (FATAL, name, X "Bad color level in color %d (%d,%d,%d), %d max", X col_tab_no, red, green, blue, MAX_GUN); X } X if (col_tab_no < num_col) X { X dev.attributes (SET_COLOR_TABLE, col_tab_no, red, green, blue); X color_set[col_tab_no][STATUS] = SET; X } X else X if (col_tab_no > 7) X { X color_set[col_tab_no][STATUS] = MAPPED; X } X else X { X if (col_tab_no > 0) X { X color_set[col_tab_no][STATUS] = MAP_SET; X /* X * Means that we need to map these but they are still set X * to the original colors and can't be changed. Color 0 X * is always background, and any other color exactly the X * same color as color 0 "wants to be", even if color 0 X * actually can't be and hasn't been reset, is mapped to X * color zero if it can't be set. X */ X } X } X /* X * Save the color that this color table number wants to be X */ X color_set[col_tab_no][_RED] = red; X color_set[col_tab_no][_GREEN] = green; X color_set[col_tab_no][_BLUE] = blue; X /* X * grey level is "Black and White TV style" mapped from color, X * with corrections added by the subroutine greycorr. X */ X grey = (blue * 1 + red * 2 + green * 4 + 6) / 7; X color_set[col_tab_no][_GREY] = greycorr (grey); X /* X * If the next command is also a set color table command, we can X * postpone doing this and kill 2 (or more) birds with one stone. X */ X c = getc (pltin); X if (c == EOF) X goto End_of_file; X ungetc ((char) c, pltin); X if (c != VP_SET_COLOR_TABLE) X { X if (mono) X { X for (ii = 1; ii <= MAX_COL; ii++) X { X if (color_set[ii][_RED] == color_set[0][_RED] && X color_set[ii][_GREEN] == color_set[0][_GREEN] && X color_set[ii][_BLUE] == color_set[0][_BLUE]) X { X color_set[ii][MAP] = 0; X } X else X { X color_set[ii][MAP] = 7; X } X } X } X else X { X /* X * For all color table entries that aren't set, (because X * we ran out of colors, for example) find the best color X * that IS set and use that instead. X */ X for (ii = num_col; ii <= MAX_COL; ii++) X { X if (color_set[ii][STATUS] & MAPPED) X { X min_dist = MAX_GUN * MAX_GUN * 8; X for (i = num_col_8 - 1; i >= 0; i--) X { X /* X * Colors 1 through 7 are guaranteed SET, So X * we always get an answer. Color zero is X * background and special. To map to it you X * have to hit its color exactly, and no X * other color matched exactly first. X */ X if (color_set[i][STATUS] & SET) X { X if (color_set[i][STATUS] == SET) X { X k = color_set[i][_RED] - color_set[ii][_RED]; X dist = 2 * k * k; X k = color_set[i][_GREEN] - color_set[ii][_GREEN]; X dist += 4 * k * k; X k = color_set[i][_BLUE] - color_set[ii][_BLUE]; X dist += k * k; X } X else X { X k = MAX_GUN * ((i & 2) / 2) - color_set[ii][_RED]; X dist = 2 * k * k; X k = MAX_GUN * ((i & 4) / 4) - color_set[ii][_GREEN]; X dist += 4 * k * k; X k = MAX_GUN * ((i & 1) / 1) - color_set[ii][_BLUE]; X dist += k * k; X } X if (dist < min_dist && (i != 0 || dist == 0)) X { X min_dist = dist; X best_col = i; X if (dist == 0) X { X /* X * Might as well look no further X */ X break; X } X } X } X } X color_set[ii][MAP] = best_col; X } X } X } X } X break; X case VP_PURGE: /* purge pltout buffers */ X dev.close (CLOSE_FLUSH); X break; X case VP_BREAK: /* break */ X case VP_ERASE: /* erase */ X dev.close (CLOSE_FLUSH); X X if ((c == VP_ERASE) || brake) X { X group_number--; X if (group_number != 0) X { X ERR (WARN, name, X "group contains erase"); X group_number = 0; X } X else X { X ii = dev.attributes (END_GROUP, group_number, 0, 0, 0); X if (ii == DOVPLOT_EXIT) X return; X if (ii != DOVPLOT_CONT) X ERR (WARN, name, "dev.attributes(END_GROUP,...) returned junk."); X } X } X X if (epause < 0) X { X message (MESG_ERASE); X message (MESG_ON); X message (MESG_HOME); X message (MESG_READY); X message (MESG_HIGHLIGHT_ON); X message (MESG_TEXT, "Type Return to Continue... "); X message (MESG_DONE); X dev.interact (INT_PAUSE, controltty, string); X message (MESG_HIGHLIGHT_OFF); X if (!allowecho) X { X message (MESG_READY); X message (MESG_TEXT, CRLF); X } X message (MESG_DONE); X message (MESG_OFF); X message (MESG_ERASE); X } X else X { X if (epause > 0) X sleep ((unsigned) epause); X } X /* X * Inquire point back from device X */ X if (interact[0] != '\0') X { X getapoint (); X } X X if (erase & DO_LITERALS) X if ((c == VP_ERASE) || brake) X { X dev.erase (ERASE_MIDDLE); X nplots++; X } X else X { X dev.erase (ERASE_BREAK); X nplots++; X } X X new_style = default_style; X setstyle (new_style); X reset (); X X if ((c == VP_ERASE) || brake) X { X ii = ftell (pltin); X sprintf (group_name, "%s.%d", pltname, nplots); X dev.attributes (BEGIN_GROUP, group_number, ii, 0, 0); X group_number++; X } X X if (framewindows) X outline_window (); X X break; X case VP_WINDOW: /* window */ X if (window) X { X xwmin = geth (pltin); X ywmin = geth (pltin); X xwmax = geth (pltin); X ywmax = geth (pltin); X X if (xwmin > xwmax || ywmin > ywmax) X { X/* X * vptodevw will always return a window that is the "right way around", X * even if the original window was inverted. So produce an inside-out X * window which will clip everything away to nothing. X */ X X xwmin = xWmax + 1; X xwmax = xWmin - 1; X ywmin = yWmax + 1; X ywmax = yWmin - 1; X } X else X { X X vptodevw (xwmin, ywmin, xwmax, ywmax, &xwmin, &ywmin, &xwmax, &ywmax); X X wlimit (xWmin, xWmax, &xwmin, &xwmax); X wlimit (yWmin, yWmax, &ywmin, &ywmax); X } X } X else X { X geth (pltin); X geth (pltin); X geth (pltin); X geth (pltin); X } X reset_windows (); X if (framewindows) X outline_window (); X break; X case VP_NOOP: /* no op */ X break; X case VP_TXALIGN: /* set text alignment */ X /* X * These are made available to the device text routine X */ X txalign.hor = geth (pltin); X txalign.ver = geth (pltin); X dev.attributes (NEW_ALIGN, txalign.hor, txalign.ver, 0, 0); X break; X case VP_TXFONTPREC: /* set text font */ X /* X * These are made available to the device text routine X */ X ii = geth (pltin); X if (ii >= 0) X txfont = ii; X else X ii = -1; X X jj = geth (pltin); X if (jj >= 0) X txprec = jj; X else X jj = -1; X X kk = geth (pltin); X if (kk >= 0) X txovly = kk; X else X kk = -1; X X /* X * Another way for the device to keep track of changes. X */ X dev.attributes (NEW_FONT, ii, jj, kk, 0); X break; X case VP_OVERLAY: /* change overlay mode */ X /* X * This is made available to the device dependent subroutines X */ X overlay = geth (pltin); X dev.attributes (NEW_OVERLAY, overlay, 0, 0, 0); X break; X case VP_PATLOAD: /* load a pattern */ X nmul = geth (pltin); X ny = geth (pltin); X X /* See whether Raster or Hatch */ X if (ny >= 0) X { X /* Raster */ X /* nmul gives pixels_per_inch pattern is designed for */ X ny_mult = ny * (pixels_per_inch / nmul) * patternmult / aspect_ratio; X if (ny_mult == 0 && ny > 0) X ny_mult = 1; X nx = geth (pltin); X nx_mult = nx * (pixels_per_inch / nmul) * patternmult; X if (nx_mult == 0 && nx > 0) X nx_mult = 1; X X ipat = geth (pltin) + 1; X if (ipat > NPAT || ipat < 1) X ERR (FATAL, name, "bad pattern number %d (max %d, min 1)", ipat, NPAT); X /* X * Free up pattern that may already be there X */ X if (pat[ipat] .patbits != NULL) X { X free ((char *) pat[ipat] .patbits); X } X X if (nx_mult * ny_mult > 0) X { X if ((ptr = (int *) malloc ((unsigned) (nx_mult * ny_mult * sizeof (int)))) == NULL) X ERR (FATAL, name, "cannot alloc memory to load pattern"); X pat[ipat] .patbits = ptr; X } X else X { X if ((ptr = (int *) malloc ((unsigned) (1 * sizeof (int)))) == NULL) X ERR (FATAL, name, "cannot alloc memory to load dummy pattern"); X pat[ipat] .patbits = ptr; X ptr[0] = 0; X } X X if (nx * ny > 0) X { X if ((tempbuf = (int *) malloc ((unsigned) (nx * ny * sizeof (int)))) == NULL) X ERR (FATAL, name, X "cannot alloc memory to load pattern's temporary buffer"); X } X else X tempbuf = NULL; X X /* X * read in pattern X */ X ptemp = tempbuf; X for (j = 0; j < nx * ny; j++) X { X k = geth (pltin); X if (k > MAX_COL || k < 0) X { X ERR (WARN, name, "bad color number in pattern %d (max %d, min 0)", X k, MAX_COL); X k = DEFAULT_COLOR; X } X *ptemp++ = COLOR_MAP (k); X } X X /* X * copy into patbits, with "stretching" X */ X for (i = 0; i < ny_mult; i++) X { X ny_temp = i * ny / ny_mult; X for (j = 0; j < nx_mult; j++) X { X nx_temp = j * nx / nx_mult; X ptr[j + nx_mult * i] = tempbuf[nx_temp + nx * ny_temp]; X } X } X /* X * set dimensions of pattern X */ X pat[ipat] .xdim = nx_mult; X pat[ipat] .ydim = ny_mult; X pat[ipat] .xdim_orig = nx_mult; X pat[ipat] .ydim_orig = ny_mult; X X if (tempbuf != NULL) X free ((char *) tempbuf); X X dev.attributes (NEW_PAT, ipat, 0, 0, 0); X } X else X { X /* Hatch Pattern */ X /* nmul gives angle, ny is merely a flag */ X nx = geth (pltin); X if (nx <= 0 || nx * 2 > NHATCH) X ERR (FATAL, name, "bad numhatch %d (max %d/2, min 1)", nx, NHATCH); X ipat = geth (pltin) + 1; X if (ipat > NPAT || ipat < 1) X ERR (FATAL, name, "bad pattern number %d (max %d, min 1)", ipat, NPAT); X /* X * Free up pattern that may already be there X */ X if (pat[ipat] .patbits != NULL) X { X free ((char *) pat[ipat] .patbits); X } X if ((ptr = (int *) malloc ((unsigned) (nx * 4 * 2 * sizeof (int)))) == NULL) X ERR (FATAL, name, "cannot alloc memory to load pattern"); X pat[ipat] .patbits = ptr; X X for (i = 0; i < nx * 2; i++) X { X hafat[i] = geth (pltin); X if (hafat[i] >= 0) X { X hafat[i] = fatmult * (fatbase + hafat[i]); X } X k = geth (pltin); X if (k > MAX_COL || k < 0) X { X ERR (WARN, name, "bad color number in hatch %d (max %d, min 0)", X k, MAX_COL); X k = DEFAULT_COLOR; X } X hacol[i] = COLOR_MAP (k); X haoff[i] = geth (pltin) * patternmult * pixels_per_inch / RPERIN; X hasiz[i] = geth (pltin); X } X /* X * Find the smallest hatch interval. 1/2 that, and then force X * everything to be a multiple of that. If this were not X * done, then hatch intervals that originally differed by X * some simple fraction might end up slightly off, causing X * very unsightly beats. X */ X /* X * Upper quantization limit of 1/10 inch X */ X k = (RPERIN / 10) * 2; X for (i = 0; i < nx * 2; i++) X { X if (hasiz[i] > 0 && hasiz[i] < k) X k = hasiz[i]; X } X j = k * (patternmult * pixels_per_inch / RPERIN) / 2.; X if (j < 1) X j = 1; X for (i = 0; i < nx * 2; i++) X { X hasiz[i] = ((int) ((hasiz[i] * 2) / k)) * j; X } X /* X * The above algorithm also means that you can't have a hatch X * pattern come out on any device with a repetition rate of X * faster than once per two pixels. X */ X X for (i = 0; i < nx * 2; i++) X { X/* X * Make sure haoff < hasiz X */ X if (haoff[i] >= hasiz[i]) X haoff[i] = 0; X *ptr++ = hafat[i]; X *ptr++ = hacol[i]; X *ptr++ = haoff[i]; X *ptr++ = hasiz[i]; X } X /* X * set numhatch and angle... dimensions are 2 * numhatch by 4 X * . pat[ipat].xdim negative is a flag that this is a hatch X * pattern, not raster, and so must be treated differently. X */ X /* X * numhatch, with neg as flag for hatch numhatch = 0 is OK, X * because that means don't fill, same as nx = 0. X */ X pat[ipat] .xdim = -nx; X pat[ipat] .ydim = nmul; /* angle */ X } X break; X case VP_BIT_RASTER: /* bit raster data */ X case VP_BYTE_RASTER: /* byte raster data */ X ras_orient = geth (pltin); X if (rotate % 90 != 0) X { X if (wantras) X { X ERR (WARN, name, "Raster only possible in 4 principal orientations"); X wantras = NO; X } X } X else X { X ras_orient += rotate / 90; X if (ras_orient >= 0) X ras_orient = ras_orient % 4; X else X ras_orient = ((ras_orient % 4) + 4) % 4; X } X X /* X * They're on their honor to not go out of bounds. This check is X * just for things that HAVE to go out of bounds. X */ X ras_offset = geth (pltin); X X if (ras_offset + 0 > MAX_COL || ras_offset + 255 < 0) X { X ERR (FATAL, name, "Absurd raster offset %d", ras_offset); X } X X xvr_min = geth (pltin); X yvr_min = geth (pltin); X xvr_max = geth (pltin); X yvr_max = geth (pltin); X vptodevw (xvr_min, yvr_min, xvr_max, yvr_max, X &xvr_min, &yvr_min, &xvr_max, &yvr_max); X xvru_min = xvr_min; X yvru_min = yvr_min; X xvru_max = xvr_max; X yvru_max = yvr_max; X X xpix = geth (pltin); X ypix = geth (pltin); X X switch (ras_orient) X { X case 0: X xrasmult = (float) xpix / (float) (xvr_max - xvr_min); X yrasmult = (float) ypix / (float) (yvr_max - yvr_min); X xvr_max--; X yvr_max--; X break; X case 1: X yrasmult = (float) ypix / (float) (xvr_max - xvr_min); X xrasmult = (float) xpix / (float) (yvr_max - yvr_min); X xvr_max--; X yvr_min++; X break; X case 2: X xrasmult = (float) xpix / (float) (xvr_max - xvr_min); X yrasmult = (float) ypix / (float) (yvr_max - yvr_min); X xvr_min++; X yvr_min++; X break; X case 3: X yrasmult = (float) ypix / (float) (xvr_max - xvr_min); X xrasmult = (float) xpix / (float) (yvr_max - yvr_min); X xvr_min++; X yvr_max--; X break; X } X X if (wantras && smart_raster) X { X rasterline = (unsigned char *) malloc ((unsigned) ((xpix + 7 + 2) * sizeof (unsigned char))); X rasterline2 = (unsigned char *) malloc ((unsigned) ((xpix + 7 + 2) * sizeof (unsigned char))); X if (rasterline == NULL || rasterline2 == NULL) X ERR (FATAL, name, "cannot alloc memory to load raster line"); X X outraster = (unsigned char *) malloc ((unsigned) (xpix * ypix) * sizeof (unsigned char)); X if (outraster == NULL) X ERR (FATAL, name, "cannot alloc memory to load raster image"); X X/* X * See whether we want to dither or not. X * Dither if monochrome device and dithering has been asked for. X * It's up to the device to decide whether to actually do this. X */ X dither_it = dither && mono; X X /* X * Read in the Raster data for "Smart" devices, ie, those X * which can stretch (and dither) their own raster. X */ X num_rep = 0; X for (yrast = 0; yrast < ypix; yrast++) X { X /* X * Read in the next raster line, if we have a new one X */ X if (num_rep <= 0) X { X num_rep = geth (pltin); X if (num_rep <= 0) X ERR (FATAL, name, "Bad Raster line multiplier"); X pos = 0; X new_pat:num_pat = geth (pltin); X num_byte = geth (pltin); X if (num_pat <= 0 || num_byte <= 0 || X pos + num_pat * num_byte > xpix) X ERR (FATAL, name, "Raster line not length promised"); X X if (num_pat > 1) X { X if (dither_it) X { X READ_RASTER ( X rasterline2[j] = GREY_MAP (ras_offset + (int) fgetc (pltin)), X rasterline2[j + jj] = GREY_MAP (ras_offset * ((ibyte & (001 << (7 - j))) != 0)) X ); X } X else X { X READ_RASTER ( X rasterline2[j] = COLOR_MAP (ras_offset + (int) fgetc (pltin)), X rasterline2[j + jj] = COLOR_MAP (ras_offset * ((ibyte & (001 << (7 - j))) != 0)) X ); X } X for (j = 0; j < num_pat; j++) X { X for (k = 0; k < num_byte; k++) X { X rasterline[pos] = rasterline2[k]; X pos++; X } X } X } X else X { X if (dither_it) X { X READ_RASTER ( X rasterline[pos + j] = GREY_MAP (ras_offset + (int) fgetc (pltin)), X rasterline[pos + j + jj] = GREY_MAP (ras_offset * ((ibyte & (001 << (7 - j))) != 0)) X ); X } X else X { X READ_RASTER ( X rasterline[pos + j] = COLOR_MAP (ras_offset + (int) fgetc (pltin)), X rasterline[pos + j + jj] = COLOR_MAP (ras_offset * ((ibyte & (001 << (7 - j))) != 0)) X ); X } X pos += num_byte; X } X X if (pos < xpix) X goto new_pat; X if (pos != xpix) X ERR (FATAL, name, "Raster line not length promised"); X } X num_rep--; X for (ii = 0; ii < xpix; ii++) X { X outraster[ii + yrast * xpix] = rasterline[ii]; X } X } X X /* Smart form */ X dev.raster (xpix, ypix, xvr_min, yvr_min, xvr_max, yvr_max, X outraster, ras_orient, dither_it); X X free ((char *) rasterline); X free ((char *) rasterline2); X free ((char *) outraster); X } X else X { X wlimit (xwmin, xwmax, &xvr_min, &xvr_max); X wlimit (ywmin, ywmax, &yvr_min, &yvr_max); X X switch (ras_orient) X { X case 0: X xvr_max++; X yvr_max++; X xr_max = xvr_max - xvru_min; X xr_min = xvr_min - xvru_min; X yr_max = yvr_max - yvru_min; X yr_min = yvr_min - yvru_min; X yru_max = yvru_max - yvru_min; X break; X case 1: X xvr_max++; X yvr_min--; X xr_max = yvru_max - yvr_min; X xr_min = yvru_max - yvr_max; X yr_max = xvr_max - xvru_min; X yr_min = xvr_min - xvru_min; X yru_max = xvru_max - xvru_min; X break; X case 2: X xvr_min--; X yvr_min--; X xr_max = xvru_max - xvr_min; X xr_min = xvru_max - xvr_max; X yr_max = yvru_max - yvr_min; X yr_min = yvru_max - yvr_max; X yru_max = yvru_max - yvru_min; X break; X case 3: X xvr_min--; X yvr_max++; X xr_max = yvr_max - yvru_min; X xr_min = yvr_min - yvru_min; X yr_max = xvru_max - xvr_min; X yr_min = xvru_max - xvr_max; X yru_max = xvru_max - xvru_min; X break; X } X xru_min = 0; X X if (yr_max < yr_min || xr_max < xr_min || !wantras) X { X /* X * We need to read through all the raster stuff, even if X * we never use it. X */ X yr_max = yr_min; X xr_max = xr_min; X } X X rasterline = (unsigned char *) malloc ((unsigned) ((xpix + 7 + 2) * sizeof (unsigned char))); X rasterline2 = (unsigned char *) malloc ((unsigned) ((xpix + 7 + 2) * sizeof (unsigned char))); X if (rasterline == NULL || rasterline2 == NULL) X ERR (FATAL, name, "cannot alloc memory to load raster line"); X X/* X * See whether we need to dither or not. X * Dither if monochrome device and dithering has been asked for, X * Except if it is black-and-white bit raster already anyway. X * For some reason putting "GREY_MAP" directly in the if makes a X * syntax error. I think it is a compiler bug. X */ X dither_it = dither && mono; X if (dither_it && c == VP_BIT_RASTER) X { X j = GREY_MAP (0 * ras_offset); X k = GREY_MAP (1 * ras_offset); X if ((j == 0 || j == 255) && (k == 0 || k == 255)) X dither_it = NO; X } X X if (xr_max > xr_min) X { X outraster2 = (unsigned char *) malloc ((unsigned) ((xr_max - xr_min) * sizeof (char))); X if (dither_it) X { X outraster = (unsigned char *) malloc ((unsigned) ((xr_max - xr_min) * sizeof (char))); X } X else X { X outraster = outraster2; X } X if (outraster2 == NULL || outraster == NULL) X ERR (FATAL, name, "cannot alloc memory to load raster line"); X } X else X { X outraster2 = NULL; X outraster = NULL; X } X X /* X * Read in the Raster data X */ X lastrast = -1; X num_rep = 0; X for (i = yr_max - 1; i >= yr_min - 1; i--) X { X yrast = (yru_max - 1 - i) * yrasmult; X if (i == yr_min - 1) X { X /* X * Assure that the last bit of unused raster, if any, X * is read. This last time through the loop is a X * "dummy". X */ X yrast = ypix - 1; X } X X for (ii = 0; ii < (yrast - lastrast); ii++) X { X /* X * Read in the next raster line, if we have a new one X */ X if (num_rep <= 0) X { X num_rep = geth (pltin); X if (num_rep <= 0) X ERR (FATAL, name, "Bad Raster line multiplier"); X pos = 0; X new_pat2:num_pat = geth (pltin); X num_byte = geth (pltin); X if (num_pat <= 0 || num_byte <= 0 || X pos + num_pat * num_byte > xpix) X ERR (FATAL, name, "Raster line not length promised"); X X/* X * Only bother with it if we're actually going to use it X */ X if (ii + num_rep >= yrast - lastrast X && xr_max > xr_min && i >= yr_min) X { X if (num_pat > 1) X { X if (dither_it) X { X READ_RASTER ( X rasterline2[j] = GREY_MAP (ras_offset + (int) fgetc (pltin)), X rasterline2[j + jj] = GREY_MAP (ras_offset * ((ibyte & (001 << (7 - j))) != 0)) X ); X } X else X { X READ_RASTER ( X rasterline2[j] = COLOR_MAP (ras_offset + (int) fgetc (pltin)), X rasterline2[j + jj] = COLOR_MAP (ras_offset * ((ibyte & (001 << (7 - j))) != 0)) X ); X } X for (j = 0; j < num_pat; j++) X { X for (k = 0; k < num_byte; k++) X { X rasterline[pos] = rasterline2[k]; X pos++; X } X } X } X else X { X if (dither_it) X { X READ_RASTER ( X rasterline[pos + j] = GREY_MAP (ras_offset + (int) fgetc (pltin)), X rasterline[pos + j + jj] = GREY_MAP (ras_offset * ((ibyte & (001 << (7 - j))) != 0)) X ); X } X else X { X READ_RASTER ( X rasterline[pos + j] = COLOR_MAP (ras_offset + (int) fgetc (pltin)), X rasterline[pos + j + jj] = COLOR_MAP (ras_offset * ((ibyte & (001 << (7 - j))) != 0)) X ); X } X pos += num_byte; X } X } X else X { X/* X * We're just going to turn right around and read another one, X * So throw this away! X */ X if (c == VP_BYTE_RASTER) X { X for (j = 0; j < num_byte; j++) X { X fgetc (pltin); X } X } X else X { X for (j = 0; j < num_byte; j += 8) X { X fgetc (pltin); X } X } X pos += num_pat * num_byte; X } X if (pos < xpix) X goto new_pat2; X if (pos != xpix) X ERR (FATAL, name, "Raster line not length promised"); X X if (wantras && xr_max > xr_min && i >= yr_min) X { X for (j = xr_min; j < xr_max; j++) X { X outraster2[j - xr_min] = X rasterline[(int) ((j - xru_min) * xrasmult)]; X } X } X } X num_rep--; X } X lastrast = yrast; X X if (xr_max > xr_min && i >= yr_min) X { X if (dither_it) X { X dithline (outraster2, outraster, xr_max - xr_min, yr_max - 1 - i, dither); X } X /* Dumb forms */ X switch (ras_orient) X { X case 0: X dev.raster (yr_max - 1 - i, yr_max - yr_min, X xvr_min, i + yvru_min, X xr_max - xr_min, ras_orient, outraster, X 0, 0); X break; X case 1: X dev.raster (yr_max - 1 - i, yr_max - yr_min, X xvru_min + i, yvr_max, X xr_max - xr_min, ras_orient, outraster, X 0, 0); X break; X case 2: X dev.raster (yr_max - 1 - i, yr_max - yr_min, X xvr_max, yvru_max - i, X xr_max - xr_min, ras_orient, outraster, X 0, 0); X break; X case 3: X dev.raster (yr_max - 1 - i, yr_max - yr_min, X xvru_max - i, yvr_min, X xr_max - xr_min, ras_orient, outraster, X 0, 0); X break; X } X } X } X free ((char *) rasterline); X free ((char *) rasterline2); X if (outraster2 != NULL) X { X free ((char *) outraster2); X if (dither_it) X free ((char *) outraster); X } X if (!wantras) X { X xxx[0] = xvru_min; X yyy[0] = yvru_min; X xxx[1] = xvru_min; X yyy[1] = yvru_max; X xxx[2] = xvru_max; X yyy[2] = yvru_max; X xxx[3] = xvru_max; X yyy[3] = yvru_min; X drawpolygon (4, xxx, yyy); X } X } X break; X case VP_MESSAGE: /* Text message */ X getvpstring (); X message (MESG_READY); X message (MESG_MESSAGE); X message (MESG_TEXT, txbuffer); X message (MESG_TEXT, CRLF); X message (MESG_DONE); X break; X case VP_SETDASH: X npts = geth (pltin); X if (npts > MAXDASH) X { X ERR (FATAL, name, "Too complicated a dash line pattern."); X } X dashon = npts; X k = 0; X dashsum = 0.; X for (ii = 0; ii < npts * 2; ii++) X { X dashes[ii] = dashscale * (float) geth (pltin) / RPERIN; X if (dashes[ii] < 0.) X ERR (FATAL, name, "Negative dash distance."); X X if (dashes[ii] != 0.) X k = 1; X X dashsum += dashes[ii]; X } X if (!k) X dashon = NO; X dev.attributes (NEW_DASH, dashon, 0, 0, 0); X break; X default: /* error */ X ERR (FATAL, name, X "invalid VPLOT command decimal %d character %c", X (int) c, (char) c); X break; X } X } End_of_file: X/* X * End of main while loop. Either fall out here or jump here when you hit X * the end of the file somewhere. X */ X X dev.close (CLOSE_FLUSH); /* force last vector out */ X X/* X * End the group for this frame X */ X group_number--; X if (group_number != 0) X { X ERR (WARN, name, X "group left unclosed at end of file"); X group_number = 0; X } X else X { X ii = dev.attributes (END_GROUP, group_number, 0, 0, 0); X if (ii == DOVPLOT_EXIT) X return; X if (ii != DOVPLOT_CONT) X ERR (WARN, name, "dev.attributes(END_GROUP,...) returned junk."); X } X X/* X * Exit of dovplot X */ X return; X} X X/* X * reset variables that can be affected by vplot commands when X * processing multiple plots, and don't stay set across pages X */ reset () X{ int ii, jj, kk; X X xwmin = xWmin; /* plot window parameters defaulted */ X xwmax = xWmax; /* to maximum size */ X ywmin = yWmin; X ywmax = yWmax; X X reset_windows (); X X fat = fatmult * (float) (fatbase); X dev.attributes (NEW_FAT, fat, 0, 0, 0); X X if (cur_color != DEFAULT_COLOR) X { X need_devcolor = YES; X cur_color = DEFAULT_COLOR; X } X X txalign.hor = TH_NORMAL; X txalign.ver = TV_NORMAL; X dev.attributes (NEW_ALIGN, txalign.hor, txalign.ver, 0, 0); X X ii = -1; X jj = -1; X kk = -1; X if (txfont != default_txfont) X { X txfont = default_txfont; X ii = txfont; X } X if (txprec != default_txprec) X { X txprec = default_txprec; X jj = txprec; X } X if (txovly != default_txovly) X { X txovly = default_txovly; X kk = txovly; X } X dev.attributes (NEW_FONT, ii, jj, kk, 0); X X dashon = NO; X dev.attributes (NEW_DASH, dashon, 0, 0, 0); X X overlay = default_overlay; X dev.attributes (NEW_OVERLAY, overlay, 0, 0, 0); X} X reset_windows () X{ extern int xwmax_last, ywmax_last, xwmin_last, ywmin_last; X X if (xwmax != xwmax_last || ywmax != ywmax_last X || xwmin != xwmin_last || ywmin != ywmin_last) X dev.attributes (SET_WINDOW, xwmin, ywmin, xwmax, ywmax); X X xwmin_last = xwmin; X ywmin_last = ywmin; X xwmax_last = xwmax; X ywmax_last = ywmax; X} X outline_window () X{ X if (need_devcolor == YES || cur_color != DEFAULT_COLOR) X { X dev.attributes (SET_COLOR, DEFAULT_COLOR, 0, 0, 0); X need_devcolor = NO; X } X dev.vector (xwmin, ywmin, xwmax, ywmin, 0, 0); X dev.vector (xwmax, ywmin, xwmax, ywmax, 0, 0); X dev.vector (xwmax, ywmax, xwmin, ywmax, 0, 0); X dev.vector (xwmin, ywmax, xwmin, ywmin, 0, 0); X if (cur_color != DEFAULT_COLOR) X { X dev.attributes (SET_COLOR, cur_color, 0, 0, 0); X need_devcolor = NO; X } X} X getvpstring () X{ char *txptr; int ii; X X txptr = txbuffer; X X while (1) X { X ii = getc (pltin); X X if (ii == EOF) X { X ERR (FATAL, name, X "Unexpected EOF encountered in Text string"); X } X X *txptr = ii; X txptr++; X X if (ii == 0) X { X break; X } X X if ((txptr - txbuffer) == txbuflen) X { X txbuffer = realloc (txbuffer, (unsigned) (txbuflen + TXBUFLEN)); X txptr = txbuffer + txbuflen; X txbuflen += TXBUFLEN; X } X } X return; X} X drawpolygon (npts, x, y) X int npts, *x, *y; X{ int i, j; struct vertex *vertex; static int point; X X j = 0; X if (npts > (vxbuflen - 1)) X { X free ((char *) vxbuffer); X vxbuffer = X (struct vertex *) malloc ((unsigned) ((npts + 1) * sizeof (struct vertex))); X } X vertex = vxbuffer; X xnew = x[j]; X ynew = y[j]; X j++; X vertex->x = xnew; X vertex->y = ynew; X vertex->next = vertex + 1; X vertex++; X i = npts - 1; X while (i--) X { X vertex->x = x[j]; X vertex->y = y[j]; X j++; X if ((vertex->x != xnew) || (vertex->y != ynew)) X { X xnew = vertex->x; X ynew = vertex->y; X vertex->next = vertex + 1; X vertex->last = vertex - 1; X vertex++; X continue; X } X npts--; X } X vertex--; X vxbuffer->last = vertex; X vertex->next = vxbuffer; X X ipat = 0; X point = cur_color; X pat[ipat] .patbits = &point; X pat[ipat] .xdim = 1; X pat[ipat] .ydim = 1; X pat[ipat] .xdim_orig = 1; X pat[ipat] .ydim_orig = 1; X update_color (); X if (npts > 2) X { X if (shade) X dev.area (npts, vxbuffer); X else X vecoutline (vxbuffer); X } X} X getpolygon (npts) X int npts; X{ int i; struct vertex *vertex; X X if (npts > (vxbuflen - 1)) X { X free ((char *) vxbuffer); X vxbuffer = X (struct vertex *) malloc ((unsigned) ((npts + 1) * sizeof (struct vertex))); X } X vertex = vxbuffer; X GETXY (xnew, ynew); X vertex->x = xnew; X vertex->y = ynew; X vertex->next = vertex + 1; X vertex++; X i = npts - 1; X while (i--) X { X GETXY (vertex->x, vertex->y); X if ((vertex->x != xnew) || (vertex->y != ynew)) X { X xnew = vertex->x; X ynew = vertex->y; X vertex->next = vertex + 1; X vertex->last = vertex - 1; X vertex++; X continue; X } X npts--; X } X vertex--; X vxbuffer->last = vertex; X vertex->next = vxbuffer; X return (npts); X} X update_color () X{ X if (need_devcolor) X { X dev.attributes (SET_COLOR, cur_color, 0, 0, 0); X need_devcolor = NO; X } X} X getapoint () X{ X while (1) X { X xret = dev_xmax + 1; X yret = dev_ymax + 1; X if ((int) dev.getpoint (controltty, &xret, &yret) || X (xret > dev_xmax - 5 && yret > dev_ymax - 5)) X break; X devtovpxy (xret, yret, &xret, &yret); X add_a_cor (interact, xret, yret); X } X} END_OF_FILE if test 51559 -ne `wc -c <'Vplot_Kernel/filters/dovplot.c'`; then echo shar: \"'Vplot_Kernel/filters/dovplot.c'\" unpacked with wrong size! fi # end of 'Vplot_Kernel/filters/dovplot.c' fi echo shar: End of archive 24 \(of 24\). cp /dev/null ark24isdone MISSING="" for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 24 archives. rm -f ark[1-9]isdone ark[1-9][0-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 -- Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.