home *** CD-ROM | disk | FTP | other *** search
- Subject: v14i029: Device-independant graphics system, with drivers
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rsalz@uunet.UU.NET
-
- 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
-