[comp.sources.unix] v14i022: Device-independant graphics system, with drivers

rsalz@bbn.com (Rich Salz) (04/06/88)

Submitted-by: Joe Dellinger <joe@hanauma.STANFORD.EDU>
Posting-number: Volume 14, Issue 22
Archive-name: vplot/part17

#! /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 17 (of 24)."
# Wrapped by rsalz@fig.bbn.com on Fri Mar 25 11:47:28 1988
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'Vplot_Kernel/Documentation/vplottext.mn' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Vplot_Kernel/Documentation/vplottext.mn'\"
else
echo shar: Extracting \"'Vplot_Kernel/Documentation/vplottext.mn'\" \(15800 characters\)
sed "s/^X//" >'Vplot_Kernel/Documentation/vplottext.mn' <<'END_OF_FILE'
X.TH vplot_text 9 "7 April 1987"
X.SH NAME
vplot text \- A guide to using the new Hershey fonts in vplot
X
X.SH DESCRIPTION
Vplot fonts are mixtures of vectors and filled areas which simulate typeset
fonts on graphics devices.  Since they are not raster, they can be arbitrarily
scaled, stretched, skewed, and rotated, and can be plotted on any device.
X
There are 17 fonts.  Font 0 is just the regular old PEN font we've been using all
along.  The default font is device and installation dependent, or can be set
from the command line (see options below).
Here is a complete list of fonts and their number:
X
X.br
X0 pen
X.br
X1 roman simplex
X.br
X2 roman duplex
X.br
X3 roman complex
X.br
X4 roman triplex
X.br
X5 italic complex
X.br
X6 italic triplex
X.br
X7 script simplex
X.br
X8 script complex
X.br
X9 greek simplex
X.br
X10 greek complex
X.br
X11 Cyrillic complex
X.br
X12 German style gothic triplex
X.br
X13 Greek style gothic triplex
X.br
X14 Italian style gothic triplex
X.br
X15 mathematics
X.br
X16 miscellaneous
X.br
X
Font 0 was designed by Rob Clayton at Stanford.  Fonts 1 through 16 are debugged
versions of the `Hershey' fonts available from mod.sources.  In order to
have permission to use these fonts, I must now display this message:
X
X.br
X	- The Hershey Fonts were originally created by Dr.
X.br
X		A. V. Hershey while working at the U. S.
X.br
X		National Bureau of Standards.
X
X.SH INTERFACE
This section describes the control sequences which are accessible to any user
of
X.B vplot
text, via whatever program.
X
Vplot text recognizes `\\' as a special character used to signal the start of
an escape sequence.  There are two sorts of escape sequences, those that take an
argument and those that do not.
X
Here is a complete list of escape sequences that do not take an argument:
X.br
X\\>	Advance one interletter space
X.br
X\\<	Back up one interletter space
X.br
X\\^	Raise one half of a capital letter height
X.br
X\\_	Lower one half of a capital letter height
X.br
X\\g	Continue processing text, but don't actually print it (`ghostify it').
This is useful if you want to leave space to go back and add something by hand.
X.br
X\\G	Start printing text again
X.br
X\\n	Newline
X.br
X\\h	Backspace (control-h also works) back up over the last character
X.br
X\\-	Does nothing; used to prevent a group of characters from being formed
into a ligature.
X.br
X\\\\	Print a backslash
X.br
X
The following take an integer argument immediately after, with a
X.B required space
after the integer to delineate the end.  This space is not printed.
X
X.br
X\\s	Size change.  Change to this percent of the size set in the text vplot
call.  \\s100  restores the default height.
X.br
X\\f	Add this to current fatness.  Goes out of effect when text printing is
finished.
X.br
X\\F	Switch to this font number.  (-1 restores the default font).
X.br
X\\k	Move by this many space widths to the right.
X.br
X\\r	Move up this many character heights (the height of a standard capital
letter, such as `A').
X.br
X\\v	Print this ASCII character number in the current font, stripping it
of any special meaning.
This and ligatures are the only way that glyphs numbered
greater than 255 are available.
X.br
X\\c	Switch to this color.  -1 restores the current drawing color.
Vplot's current drawing color is not changed by changing the color inside text.
X.br
X\\m	Save current position in this number register.
X.br
X\\M	Restore position saved in this number register.
X.br
X
X.SH EXAMPLES
Since programs such as `graph' do not interpret text themselves, but
rely on vplot to do it, the above control sequences may simply be used wherever
any graphics text is used.  For example, instead of specifying as an option to
graph label=`beta', you can specify label=`\\F9 b' and actually get the Greek
letter beta from the Greek Simplex font.
X
X	Here are some more examples:
X
X	To get an integral sign:
X.br
X	\\F15 \\v168 
X.br
X	Translation: Switch to font 15 (math symbols), print character #168 (integral
sign).
X
X	To get `X squared plus Y squared':
X.br
X	X\\^2\\_ + Y\\^2
X.br
X	Translation: Print X, go up half, print 2, go back down half, print +,
print Y, go up half, print 2.
X
X	As an advanced example, to get `A sub b sup beta':
X.br
X	A\\m1 \\_b\\M1 \\^\\F9 b
X.br
X	Translation: Do A, save this spot, go down half, do b, restore the
saved spot, go up half, switch to font 9 (Greek Simplex) do beta.  (Notice
the use of marks to stack characters on top of each other.)
X
X	Warning: \\ is a special character in C.  To get a backslash, you
have to use \\\\.
X
X.SH GENERIC PEN OPTIONS
X
X.TP
X.B txfont=font_number
Txfont specifies the default text font.
The default is device and installation
dependent.  Generally, screen devices will default to the `pen' font since it is
by far the fastest to draw, and hardcopy devices will default to either
roman simplex
or roman complex since these are the closest to looking like standard typeset
text.  Out-of-range font
numbers (starting at 100) may be used in a device-dependent fashion
to access hardware fonts on devices that have them. Devices that don't have
hardware fonts will use the font number modulo 100.
Fonts 0-99 are guaranteed device-independent.
X
X.TP
X.B txprec=0
Txprec specifies the default text precision (a GKS term).
Possible values are character (0), string (1), and stroke (2).
For vector fonts, the text precision parameter is ignored except that
ligatures are only enabled at precision 2.  The precision parameter
may be significant if device-dependent hardware fonts are used,
however.  The default precision is device and installation dependent.
X
X.TP
X.B txovly=0
Txovly sets the default text overlay mode.
This controls whether or not to clear out an area behind the
text before writing it, and whether or not to put a box around it.
Overlay modes 1 and 3 draw a box, and modes 2 and 3 shade the inside of
the box with the background color.  The default text overlay mode is 0
X(do nothing).
All text overlay modes may not be supported on all devices.
X(Some devices cannot shade to background color, for example.)
X
The default font, default precision, and default text overlay mode may all be
reset by the appropriate vplot command.
X
X.TP
X.B fontN=file_name
The binary format vplot font file for font number N is located in file_name.
If the font number is not one normally defined on the system, file_name
defaults to fontN, where again N is the font number. If the device does
not have hardware fonts, the font number modulo 100 will be used
for all internal purposes (so fonts 201 and 101 must be the same,
for example). The N in the above option will still be the
original font number, however. Fonts that are included
at compile time are hardwired and cannot be changed.
X
X.SH LIGATURES
Fonts may specify that certain combinations of adjacent glyphs be combined into
a single new glyph whenever they occur.  For example, `ffi' in font 3 (it's
a ligature in troff, too).  This
takes place automatically at precision 2.
The only fonts which currently contain
ligatures are the Roman Complex, Italic Complex, and Cyrillic Complex fonts.
X(Ligatures may be used in fonts for foreign languages to good effect to
automatically de-transliterate English approximations.  For example, `sh' in
the Cyrillic font automatically comes out as a single Shah character.
X`KHrushchev', for example, contains only 6 glyphs: KH-r-u-shch-e-v.
The K and H here are both
capitalized since they are both part of the first character.  The `Tests'
directory contains the example TEST_Cyrillic which shows how to generate
every letter in the Cyrillic alphabet.)
X
X.SH TEXT JUSTIFICATION
Text justification is set by the appropriate command in vplot, and follows
the GKS standard.
Since this text routine allows character size and active font to
be changed within a single text string, the GKS standard is extended so that
X`TOP' and `BOTTOM' alignments align on the highest top and the lowest
bottom of the characters used.  (Note that this makes the alignment font and
size dependent, but not dependent on the actual characters used.)
The `CAP' and `HALF' alignments are determined
by those for the default font.
X
All sizes of all fonts are aligned together by their baselines.
X
Horizontal alignment is based according to the beginning and ending horizontal
positions.  You can use marks to make the ending position be anywhere in the
string you wish.
X
A `SYMBOL' justification mode has also been added to those defined by GKS.
Each glyph has a `hot
spot' defined, which is where the glyph is to be centered if it is used as
a symbol.  The last printable character in a string is the character centered on
as the symbol.  To center on a character in the middle
of the string as a symbol, mark the spot with the \\m command immediately after that
character and then restore that location at the end of the string with the
X\\M command.  That character
is now the `last character' as far as all centering is concerned.
Size changes and horizontal
shifts are taken into account
in the symbol justification mode, but shifts up and down are not.
X
Vplot polymarkers are drawn by setting the SYMBOL text justification mode,
setting the correct font,
creating a special single-character string, and
then calling the text routine to draw the symbol.
X
X.SH DIAGNOSTICS
Nonexistent glyphs are rendered as a special `error' glyph.  Which glyph is
used for this is installation dependent, and is set by defines in
gentext.c.  As distributed, it is glyph 30 in font 0, which is a `?' inside
a diamond.  (I stole this idea from the Imagen laser printer.)  An error message
will be produced the first time that a nonexistent glyph is referenced.
X(Only the first time so that you don't get overwhelmed with error messages
if you're trying to use a font that doesn't exist on that system.)
Attempts to use nonexistent fonts produce
an error message and font 0 (or whatever other font has been
designated as the error font in gentext.c) is used instead.
X
Various other non-fatal errors can occur and all
give self-explanatory error messages.
X
X.SH COPYRIGHT
The Vplot source code is copyrighted. Please read the copyright notice you
will find in the Vplot manual page.
X
X.SH FONT FILES
Font files used by the vplot text subroutine `gentext' are kept in
X.../vplot/filters/include/vplotfonts/*.  There are two forms for each font,
an `include' form and a `binary' form.  The include form is compiled in
as an #include file into gentext.  This is more efficient, but makes the
executable code considerably longer and slows down compilation.
The binary form is loaded on the fly as
needed at runtime.  Which method is used for which font is system dependent
and is determined by the file .../vplot/include/font_definitions.h.
X
X.SH ASSOCIATED PROGRAMS
The subroutine
X.B gentext.c
is the device-independent generic subroutine that vplot uses to draw
vector fonts.
Gentext.c is constructed in such a way that it could easily be fit into a GKS
package.  While Vplot itself thinks in terms of `text orientation' and
X`text size', gentext thinks in terms of `character up vectors' and
X`character path vectors'.  Squashed, slanted, etc, text can be produced
by having these two vectors not be perpendicular or not the same length.
X(This can only happen when using vplot when xscale does not equal yscale.)
X
The program
X.B makefont.c
takes a `vplot font' and encodes it into the forms required by gentext.
The format of a `vplot font' is designed such that it can be read into the
program `plas'
and then piped into a vplot filter.  IE, the command
X.br
plas < cyrilc.vplot_font | ?pen xcenter=0 ycenter=0 scale=50 pause=1
X.br
will display each glyph in the cyrillic font, one per second.
X
The exact format of a `vplot font' file is given in comments at the beginning of
makefont.c, and the file pen.vplot_font serves as an example.
Since vplot_fonts are just open-format vplot files, it is very easy to create your
own special purpose glyphs, markers, or fonts and add these to the system.
X
The program
X.B hertovplot.c
converts `Hershey' font data as distributed by mod.sources
X(mod.sources is a UNIX network `news' group for distributing
useful UNIX software.)
into vplot fonts.
Its use is described in comments at the beginning of the program.
The program
X.B hertogrid.c
draws all the glyphs in a Hershey glyph file on a grid, labeling each glyph
with its number.  (The Hershey glyph files have to be organized into reasonable
fonts by hand! The organization of my fonts mostly follows those provided by
Mr. Hurt, but I have added in a few things he missed
and reordered the non-English
fonts to make more sense.  I have stolen bits of Mr. Hurt's code to write
hertovplot.c and hertogrid.c.)
X
X.SH FONT INSTALLATION
To install all the fonts, you must first obtain the Hershey fonts for
yourself
as distributed by mod.sources (if you don't know how to get stuff
from them, then how did you get this file that you're reading now?).
Follow the instructions to create the
four `.oc' files, and copy these into the .../vplot/Hershey directory.
Do not copy the `.hmp' files.
Follow the instructions you will find in the file .../vplot/Hershey/README
to make all the required `vplot_font's.
X(Note that pen.vplot_font is not part of the Hershey font distribution.
This font was created by Rob Clayton around 1980, and slightly modified
by Joe Dellinger in 1986.)
Once you have done this,
go into the .../vplot/filters/include/vplotfonts directory, and
do `make'.  This will create the required `.include' and `.bin'
fonts.
X
X.SH SEE ALSO
pen(9) vplot(9) libvplot(9)
X
X.SH AUTHOR
Joe Dellinger
X(joe@hanauma.stanford.edu, convex!convexw!hanauma!joe, decvax!hanauma!joe)
You may ask me for advice if you wish to help do any of the things in
the wish list below.
X
X.SH BUGS
The letter `J' in the Roman Triplex font in the Hershey font distribution
has mangled width information.  The vplot font for this font has to be edited by
hand to correct this mistake.
X
Gentext.c does not yet support all the required GKS features.  However, as all
the internal calculations are done in a way consistent with the GKS model
modifying the code to support these is a very straightforward job which I
leave to someone else.
X
Somebody should make sure that all the `hot spots' defined for characters
are reasonable.  (The `hot spot' is the point that is aligned on when
symbol alignment mode is used.)
X(The ones installed now are the defaults chosen by
makefont.c.)  Somebody should create a special `polymarker' font.
Currently several of the more esoteric symbols called by the vplot
polymarker command are not very well centered (notably triangles).
X
Somebody should write an interactive program to create new glyphs with.
X
Somebody should turn some of the better Hershey vector fonts into filled-area
fonts.  (Unfortunately, Mr. Hershey didn't see fit to order his vectors in such
a way as to make this easy.) The only thing lacking is the font itself,
because vplot itself already supports arbitrary mixtures of filled-areas
and vectors in fonts.  Currently there are just a few glyphs containing
filled areas in font 0, as examples showing how to do it.
X
Dr. Geller (the first tenured American professor at a Japanese university,
and a former Stanford Earth Sciences professor)
should have his students create a katakana and a hirigana font.
Ligatures can be used to pair the appropriate consonant-vowel pairs.
There are also quite a few Kanji glyphs available as well, from which a Kanji
font could be constructed.
A ligature could be constructed to turn each English word into its Kanji
equivalent! (The number of glyphs in a font is not limited to 256! That's
why I did things that way.)
X
Somebody should extend the way ligatures are read from vplot font files,
so that you can just give the
ASCII character itself instead of the glyph number
if one exists.  Since I only had a few ligatures I didn't want to bother with
this.
END_OF_FILE
if test 15800 -ne `wc -c <'Vplot_Kernel/Documentation/vplottext.mn'`; then
    echo shar: \"'Vplot_Kernel/Documentation/vplottext.mn'\" unpacked with wrong size!
fi
# end of 'Vplot_Kernel/Documentation/vplottext.mn'
fi
if test -f 'Vplot_Kernel/filters/genlib/polyfix.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Vplot_Kernel/filters/genlib/polyfix.c'\"
else
echo shar: Extracting \"'Vplot_Kernel/filters/genlib/polyfix.c'\" \(15037 characters\)
sed "s/^X//" >'Vplot_Kernel/filters/genlib/polyfix.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/genlib/polyfix.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 * Joe Dellinger Feb 29, 1988
X *	Changed POLYS to 5000 so it will compile on RT's.
X *	Somebody should change the whole thing into linked lists!
X */
X
X#include <stdio.h>
X#include "../include/err.h"
X#include "../include/extern.h"
X#include "../include/params.h"
X#define EMPTY -100
X#define NOLINK -10
X#define ENDOFLIST -1
X#define UNCLAIMED 0
X#define CLAIMED 1
X#define INTERIOR 0
X#define POLYS   5000	/* Memory alloted for polygon */
X#define MAXPOL  500	/* Maximum number of polygons made */
X
X/*
X * This routine breaks up the clipped polygon generated by "polygon" into
X * multiple polygons as needed, using the Thorson-Dellinger method!
X *
X *	Note 1:
X *	The output of "polygon" is a clipped polygon with different parts
X *	joined by lines around the edge of the window. (This is unsightly.)
X *	This routine seems to do a reasonably efficient job of fixing this.
X *	(It's a pretty hard problem!)
X *
X *	Note 2:
X *	This always (I hope) works for non-crossed polygons. Crossed polygons
X *	will sometimes be turned into two overlapping polygons,
X *	which can cause interior voids to be shaded. Some terminals,
X *	like the color tektronix, can be sent multiple polygons
X *	and told that they are to be shaded as one. If this is the
X *	case, the routine should always (I think) work, even for crossed
X *	polygons. To fix this problem, you would have to laboriously
X *	look for intersections of "disjoint" polygons. A new point would
X *	then be added at the intersection, and the two polygons joined
X *	into one through that point. The required routines are pretty much
X *	already in this program, but it seems that the large amount of
X *	time to check for this obscure case is not worth it. There seems
X *	to be no obvious way around this.
X *
X *		--- Joe Dellinger, May 7, 1984.
X *
X *	Looking back on this I realize that I still had a lot to learn
X *	about C coding when I wrote this; some kind soul should go back
X *	and update this to use pointers and allocated linked-lists.
X *	I don't feel like doing this myself; the thing works perfectly
X *	for us even if the code itself is a mess!
X *
X *		--- Joe Dellinger, May 3, 1987.
X */
X
static int      poly[POLYS][5];
X/*
X * Doubly linked list that will contain the vertices of our polygons. 0-X 1-Y
X * 2-forward link 3-backward link 4-which edge? 1-bottom 2-left 4-top 8-right 
X */
static int      pols[MAXPOL];	/* Point to the start of each polygon */
static int      polsc[MAXPOL];	/* Cycle length */
static int      npols;	/* How many polygons we have */
X
static int      pedge[POLYS];	/* Edge points of the polygon */
static int      nedge, nedge2;	/* number of edge points */
X
static int      point, endlist;
X
int             bottom, left;
X
X
int             Allgone;/* Communicate to polygon whether we ever got
X			 * anything */
X
polyfix (x, y, first)	/* Read in the data for polystart */
X    int             x, y, *first;
X{
static int      oldx, oldy;
X
X    if (*first == 1)
X    {
X	*first = 0;
X	point = 1;
X	Allgone = 0;		/* All the points aren't gone! */
X	oldx = x + 1;
X	oldy = y + 1;		/* Won't match */
X    }
X    /*
X     * Put the point x,y into the list as number point, Unless it is *
X     * superfluous 
X     */
X    if ((x == oldx) && (y == oldy))
X	return;			/* ignore repeated points */
X    poly[point][0] = x;		/* X of vertex */
X    poly[point][1] = y;		/* Y of vertex */
X    oldx = x;
X    oldy = y;
X    point++;
X    if (point >= POLYS)
X	ERR (FATAL, name, "Not enough memory for polygon!");
X}
X
polystart ()		/* Start working on the polygons */
X{
int             i, j, k, l, ii;
int             firstpoint, flag, double_check;
int             temp1, temp2, temp;
extern int      smart_clip;
X
X    endlist = point;		/* Last element in use */
X    /* initialize array */
X    for (i = 0; i <= point; i++)
X    {
X	poly[i][4] = INTERIOR;
X	poly[i][2] = i + 1;
X	poly[i][3] = i - 1;
X    }
X    poly[0][0] = poly[0][1] = EMPTY;
X    poly[point][0] = poly[point][1] = EMPTY;
X
X    /* fix links of free list and last point */
X    poly[0][3] = NOLINK;
X    poly[0][2] = point;
X    poly[point][2] = ENDOFLIST;
X    poly[point][3] = 0;		/* point to start of free list */
X
X    poly[point - 1][2] = 1;	/* point to start of polygon */
X    poly[1][3] = point - 1;
X
X    /* Now we have our polygon stored as a circular double-linked list! */
X
X    if (smart_clip)
X	goto skip_it;		/* smart device can handle it from here */
X
X
X    /* Identify all edge points */
X
X    /*
X     * They are identified 2 ways; each point contains the information
X     * itself, and there is an array which points to all edge points. This is
X     * to avoid searching through the entire polygon. 
X     */
X
X    nedge = 0;
X    i = firstpoint = 1;		/* Since we are just starting, we know the
X				 * polygon MUST start here */
X    do
X    {
X	if (poly[i][4] = edge (poly[i][0], poly[i][1]))	/* NOT an == */
X	{
X	    /* It's on an edge */
X	    nedge++;
X	    pedge[nedge] = i;
X	}
X	i = poly[i][2];
X    }
X    while (firstpoint != i);
X
X    nedge2 = nedge;
X
X    /*
X     * Look at each edge segment. See if any edge points occur inside
X     * segments joining two other edge points. (Got that?) 
X     */
X
X    for (ii = 1; ii <= nedge2; ii++)
X    {
X	i = pedge[ii];
X	if (k = (poly[i][4] & poly[poly[i][2]][4]))
X	{
X	    /* We have an edge link. That is, it connects to edge vertices. */
X	    /* See if any other edge points lie inbetween these two. */
X	    for (j = 1; j <= nedge; j++)
X	    {
X		if (k & poly[pedge[j]][4])
X		{
X		    /* This point is on the correct edge */
X
X		    l = ((k & (8 + 2)) > 0);
X
X		    /* l = 0 if top or bottom, 1 if left or right */
X
X		    if (poly[i][l] > poly[poly[i][2]][l])
X		    {
X			if ((poly[pedge[j]][l] > poly[poly[i][2]][l])
X			    && (poly[pedge[j]][l] < poly[i][l]))
X			    /* Got one! */
X			    /* insert it into the list */
X			{
X			    nedge2++;
X			    insert (i, poly[pedge[j]][0],
X				    poly[pedge[j]][1],
X				    poly[pedge[j]][4]);
X			    pedge[nedge2] = poly[i][2];
X			}
X		    }
X		    else
X		    {
X			if ((poly[pedge[j]][l] < poly[poly[i][2]][l])
X			    && (poly[pedge[j]][l] > poly[i][l]))
X			    /* Got one! */
X			    /* insert it into the list */
X			{
X			    nedge2++;
X			    insert (i, poly[pedge[j]][0],
X				    poly[pedge[j]][1],
X				    poly[pedge[j]][4]);
X			    pedge[nedge2] = poly[i][2];
X			}
X		    }
X		}
X		/*
X		 * Whether you found one or not, continue on. If we did
X		 * insert one, IT is now the next point and our interval has
X		 * gotten shorter. Some sort of sorting would be more
X		 * effecient, but it doesn't seem worth the extra complexity
X		 * at this time of night. It would involve a lot of special
X		 * cases, whereas doing it this way doesn't. 
X		 */
X	    }
X	}
X    }
X
X    nedge = nedge2;		/* Keep track of all the new edge points we
X				 * just created */
X
X    /*
X     * We have now inserted all the required points. Look for links that
X     * connect the same two positions. (But different vertices... That is,
X     * vertices which are not consecutive but have the same location!) 
X     */
X    /* Be careful that the link is not of zero length! */
X    /*
X     * Despite everything, it still seems to occasionally miss a spot. So as
X     * an easy fix make it go through the search until it doesn't find
X     * anything. In the overwhelming majority of cases, the first pass will
X     * have done the job. 
X     */
X    double_check = 1;
X    while (double_check == 1)
X    {
X	double_check = 0;
X
X	for (j = 1; j <= nedge; j++)	/* Loop through all edge points */
X	{
X	    flag = 1;
X	    while (flag == 1)
X	    {
X		flag = 0;
X		if ((poly[pedge[j]][4] & poly[poly[pedge[j]][2]][4])
X		    && ((poly[pedge[j]][0] != poly[poly[pedge[j]][2]][0])
X		      || (poly[pedge[j]][1] != poly[poly[pedge[j]][2]][1])))
X		{
X		    /*
X		     * This edge point's succesor is a point on the same
X		     * edge, And the link is not of zero length 
X		     */
X		    for (k = j; k <= nedge; k++)	/* Loop through edge
X							 * points */
X		    {
X			/* Look for a vertex that is at the same position */
X			if ((poly[pedge[j]][0] == poly[pedge[k]][0])
X			    && (poly[pedge[j]][1] == poly[pedge[k]][1]))
X			{
X			    /*
X			     * OK, it is in the same position. See if either
X			     * its succesor or predecessor is the same as the
X			     * other end of the link. 
X			     */
X			    if ((poly[poly[pedge[j]][2]][0] ==
X				 poly[poly[pedge[k]][3]][0])
X				&& (poly[poly[pedge[j]][2]][1] ==
X				    poly[poly[pedge[k]][3]][1]))
X			    {
X				/*
X				 * links go in opposite directions. (The easy
X				 * case) Break the links and instead link
X				 * points at the same location. Delete
X				 * duplicated point. 
X				 */
X				/*
X				 * pedge[j] and pedge[k] are at the same
X				 * spot, as are pedge[j]'s succesor and
X				 * pedge[k]'s predecessor. 
X				 */
X				temp1 = poly[pedge[j]][2];
X				/* remember pedge[j]'s succesor */
X				poly[pedge[j]][2] = pedge[k];
X				/* pedge[j]'s succesor is now pedge[k] */
X				temp2 = poly[pedge[k]][3];
X				/* remember pedge[k]'s predecessor */
X				poly[pedge[k]][3] = pedge[j];
X				/*
X				 * pedge[j] and pedge[k] are now linked. Link
X				 * temp1 and temp2 
X				 */
X				poly[temp1][3] = temp2;
X				poly[temp2][2] = temp1;
X				/*
X				 * Done. We have just split one polygon into
X				 * two! 
X				 */
X				/* Clean up by removing the repeated vertices */
X				delete (pedge[k]);
X				pedge[k] = 0;
X				/*
X				 * Point this to a place we know is marked as
X				 * an interior point. Always fails checks to
X				 * see if it is on the edge we want. 
X				 */
X				delete (temp2);
X				flag = 1;
X				double_check = 1;
X			    }
X			    else
X			    {
X				if ((j != k) &&
X				    (poly[poly[pedge[j]][2]][0] ==
X				     poly[poly[pedge[k]][2]][0])
X				    && (poly[poly[pedge[j]][2]][1] ==
X					poly[poly[pedge[k]][2]][1]))
X				{
X				    /*
X				     * the hard case. Both links go the same
X				     * direction. Do as before, but Reverse
X				     * the direction of one of the two
X				     * pieces. 
X				     */
X				    temp1 = poly[pedge[j]][2];
X				    temp2 = poly[pedge[k]][2];
X				    i = temp1;
X				    do
X				    {	/* Reverse one piece first */
X					temp = poly[i][2];
X					poly[i][2] = poly[i][3];
X					poly[i][3] = temp;
X					i = temp;
X				    }
X				    while ((temp2 != i) && (temp1 != i));
X				    poly[temp1][2] = temp2;
X				    poly[temp2][3] = temp1;
X				    if (i == temp2)
X				    {
X					poly[pedge[j]][2] = pedge[k];
X					poly[pedge[k]][3] = pedge[j];
X					/*
X					 * We have not created a new polygon,
X					 * merely re-ordered one! 
X					 */
X				    }
X				    else
X				    {
X					poly[pedge[j]][3] = pedge[k];
X					poly[pedge[k]][2] = pedge[j];
X					/*
X					 * We have merged two polygons back
X					 * into one! 
X					 */
X				    }
X				    /* clean up */
X				    delete (pedge[k]);
X				    pedge[k] = 0;
X				    delete (temp2);
X				    flag = 1;
X				    double_check = 1;
X				}
X			    }
X			}
X			if (flag == 1)
X			    break;
X			/*
X			 * We've just altered the point we're at! So better
X			 * stop this loop. 
X			 */
X		    }		/* End of search loop */
X		}
X	    }
X	}
X    }
X
X    /*
X     * Our polygon has been fragmented into multiple smaller polygons as
X     * necessary! Output the resulting polygons 
X     */
X
skip_it:
X    scan ();
X
X    for (i = 1; i <= npols; i++)
X    {
X	dev.startpoly (polsc[i]);
X	j = pols[i];
X	do
X	{
X	    dev.midpoly (poly[j][0], poly[j][1]);
X	    j = poly[j][2];
X	}
X	while (j != pols[i]);
X	dev.endpoly (i == npols);
X    }
X}
X
insert (where, x, y, z)
X    int             where, x, y, z;
X{
int             temp;
X
X    /* insert the given vertex between the element where and its forward link */
X
X    /* remove an element from the free list */
X    temp = poly[0][2];		/* free element */
X    if (temp == endlist)
X    {
X	/* Need to make our list one longer. */
X	endlist++;
X	if (endlist >= POLYS)
X	    ERR (FATAL, name, "Ran out of memory on the polygon!");
X	poly[endlist][3] = temp;
X	poly[endlist][2] = ENDOFLIST;
X	poly[temp][2] = endlist;
X    }
X    /* OK, Now you can remove it, it isn't at the end anymore. */
X    poly[0][2] = poly[temp][2];
X    poly[poly[temp][2]][3] = 0;
X
X    poly[temp][0] = x;		/* Put vertex in for element */
X    poly[temp][1] = y;
X    poly[temp][4] = z;
X
X    /* update links */
X
X    poly[temp][2] = poly[where][2];
X    poly[where][2] = temp;
X
X    poly[temp][3] = poly[poly[temp][2]][3];
X    poly[poly[temp][2]][3] = temp;
X}
X
delete (where)
X    int             where;
X{
int             temp;
X
X    /* Get rid of element number where; put it on the free list */
X    /* This must work even if element where points to itself! */
X    poly[where][0] = poly[where][1] = EMPTY;
X    poly[where][4] = INTERIOR;
X    temp = poly[where][3];
X    poly[where][3] = 0;
X    poly[temp][2] = poly[where][2];
X    poly[where][2] = poly[0][2];
X    poly[0][2] = where;
X    poly[poly[where][2]][3] = where;
X    poly[poly[temp][2]][3] = temp;
X}
X
X/*
X * See how many polygons we have, and where they start.
X * Put this information in pols.
X */
scan ()
X{
int             polyon[POLYS];	/* Array to remember whom this point belongs
X				 * to */
int             joe;
int             cycle;
int             firstpoint;
int             where;
X
X    for (joe = 1; joe < endlist; joe++)
X    {
X	if (poly[joe][0] == EMPTY)
X	{
X	    polyon[joe] = EMPTY;
X	}
X	else
X	{
X	    polyon[joe] = UNCLAIMED;
X	}
X    }
X
X    npols = 0;
X    for (joe = 1; joe < endlist; joe++)
X    {
X	if (polyon[joe] == UNCLAIMED)
X	{
X	    /* Found the start of a polygon */
X	    firstpoint = joe;
X	    polyon[firstpoint] = CLAIMED;
X	    cycle = 1;
X	    where = poly[firstpoint][2];
X	    while (firstpoint != where)
X	    {
X		cycle++;
X		polyon[where] = CLAIMED;
X		where = poly[where][2];
X		if (where == NOLINK)
X		    ERR (FATAL, name, "Oh, No! Polygon list damaged! (This shouldn't be able to happen.)");
X	    }
X	    if (cycle < 3)
X	    {			/* Not really a polygon, remove it */
X		where = poly[firstpoint][2];
X		while (firstpoint != where)
X		{
X		    delete (where);
X		    where = poly[firstpoint][2];
X		}
X		delete (firstpoint);
X	    }
X	    else
X	    {
X		/* We found another polygon */
X		npols++;
X		if (npols > MAXPOL)
X		    ERR (FATAL, name, "Too many polygons!");
X		pols[npols] = firstpoint;
X		polsc[npols] = cycle;
X	    }
X	}
X    }
X}
X /*
X  * Now pols is a list of indexes to the beginnings of each of the  Polygons.
X  * npols gives how many there are. 
X  */
X
int
edge (x, y)		/* Find out which edges this point is on */
X    int             x, y;
X{
X    bottom = left = 0;
X    if (x == xwmin)
X	left = 2;
X    if (y == ywmin)
X	bottom = 1;
X    if (x == xwmax)
X	left = 8;
X    if (y == ywmax)
X	bottom = 4;
X    return (bottom + left);
X}
END_OF_FILE
if test 15037 -ne `wc -c <'Vplot_Kernel/filters/genlib/polyfix.c'`; then
    echo shar: \"'Vplot_Kernel/filters/genlib/polyfix.c'\" unpacked with wrong size!
fi
# end of 'Vplot_Kernel/filters/genlib/polyfix.c'
fi
if test -f 'Vplot_Kernel/util/Ta2vplot.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Vplot_Kernel/util/Ta2vplot.c'\"
else
echo shar: Extracting \"'Vplot_Kernel/util/Ta2vplot.c'\" \(15559 characters\)
sed "s/^X//" >'Vplot_Kernel/util/Ta2vplot.c' <<'END_OF_FILE'
X/*
X * Ta2vplot - reads in a Taplot/Movie format file and outputs a vplot raster
X * file. 
X *
X * <moviefile.h  Ta2vplot xll=1. yll=1. xur=5. yur=5. nreserve=8 orient=1 invert=y
X * title=, label1=, label2=, titlefat=, titlesz= labelfat= labelsz= d1num=0.
X * o1num= d2num=0. o2num= grid=y frame=y polarity=1 coltab=y labelrot=0
X * axiscol=7 color=I backcol=red,green,blue hurry=y > vplotfile.H 
X *
X * esize:
X * 
X * If esize=1, then the input file is in "Taplot" format. Default is color=I.
X *
X * If esize=3, then the input file is assumed to contain RGB 3-byte triples.
X * The color number that corresponds to the "closest available color"
X * to that defined by the triple is used. Default is color=332.
X * Using Movie color schemes is slow. (BEWARE "color" set to the wrong
X * value by your history file!!!)
X *
X * Positioning the plot: 
X *
X * xll,yll are the coordinates of the lower left corner of the plot. xur,yur are
X * the coordinates of the upper right corner. orient=0,1,2,3 to start plot in
X * upper left, upper right, lower right, or lower left. invert=y 'flips' output
X * image to agree with movie display. 
X *
X * Annotation: 
X *
X * title,label1, and label2 are strings for axis labelling. titlefat and titlesz
X * are the fatness and size of the title. labelfat and labelsz are the fatness
X * and size of the axis labels. labelrot = 1 rotates label1 180 degrees o1num
X * and d1num are the starting value and increment for labelling the n1 axis.
X * o2num and d2num are the starting value and increment for labelling the n2
X * axis. grid=y places a grid line for each label. frame=y draws a frame around
X * the plot. axiscol determines the frame, label and title colors d1num = 0
X * turns off the labelling. d1num and d2num MUST be specified. negative fatness
X * turns off the title or labels. NOTE: labelling works properly only for
X * invert=y orient=1 at this time! 
X *
X * polarity=-1 flips the raster values black to white and white to black 
X *
X * If coltab=n, no color table definition is prepended to the vplot file. nreserve
X * is the number of colors for the plotting device that you want to be left
X * "free", ie not used in the raster color table. This prevents Ta2vplot from
X * overwriting vplot type colors with the grey scale used to display movie
X * files. 
X *
X * color= one of {I,i,F,R,W,G} just like in Movie, and also RGB, where
X * each of R,G, and B is the number of bits to allot to that primary.
X *
X * backcol=red,green,blue sets the background color. Each of {red,green,blue} are
X * between 0. and 1. 
X *
X * movish=n (if y, halves the color table like movie does) 
X *
X * The resulting vplot file can be displayed using any vplot pen filter.
X * Various device-dependent corrections are automatically made by vplot
X * to compensate for the peculiarities of each display device. Some of
X * these corrections can be controlled by the user. See "man pen" for
X * more details.
X *
X * Keywords: vplot plot movie raster hardcopy rgb color
X */
X/*
X * EDIT HISTORY:
X * Author Steve Cole, March 1987
X * Joe Dellinger, Dec 1987 fixed "color value too large" bug.
X * Steve Cole, Dec 1987, changed putch call for movish to avoid problem
X *     on suns.
X * Joe Dellinger, Jan 1988, fixed some bugs involving color mapping,
X *	and added capability for RGB triples.
X * Joe Dellinger Feb 25 1988, vp_style after vp_erase
X */
X#ifndef SOURCE
X#define SOURCE "/usr/src/sepsrc/Ta2vplot.c"
X#endif
X#include <sep.main>
X#include <stdio.h>
X#include <strings.h>
X#include <vplot.h>
X
X#define SQUARE(A) ((A)*(A))
X
int             cintensityp[9] =
X{
X 0, 128, 255, 0, 128, 255, 0, 128, 255
X};
int             cintensityn[9] =
X{
X 255, 128, 0, 255, 128, 0, 255, 128, 0
X};
int             cflag[9] =
X{
X 255, 255, 0, 0, 255, 0, 0, 255, 255
X};
int             cbi[9] =
X{
X 255, 0, 0, 0, 0, 0, 0, 0, 255
X};
int             csurf[9] =
X{
X 0, 0, 255, 0, 0, 255, 0, 200, 255
X};
int             cgsi[9] =
X{
X 0, 255, 255, 0, 255, 0, 0, 255, 0
X};
int            *cola;
X
MAIN ()
X{
int             n1, n2, n3, i3, i4, incr, ii, jj, kk, esize;
int             labelsz, titlesz, labelfat, titlefat;
int             labelrot, axiscol, sign;
float           d1, o1, d2, o2, d3, o3;
float           pos1, pos2;
float           xx, yy;
char            string[80];
float           d1num, d2num;
float           o1num, o2num;
int             grid, frame;
char            label1[80], label2[80], title[160];
int             offset, xpix, ypix, bit, blast, orient, invert;
float           xll, yll, xur, yur, ppi;
int             nreserve;
int             polarity, coltab;
unsigned char  *data;
char            color[10];
extern float    rd_color (), gr_color (), bl_color ();
float           backcol[3];
float           back = 0;
int             movish;
int             map[256];
int             smap[256];
float           red[256], green[256], blue[256];
float           red_lev, green_lev, blue_lev, error, error_win;
int             ired_lev, igreen_lev, iblue_lev;
int             win, redbit, greenbit, bluebit;
int             redbit2, greenbit2, bluebit2;
int             redoff, greenoff, blueoff;
X
X    if (!fetch ("n1", "d", &n1))
X	err ("n1 not given\n");
X    if (!fetch ("n2", "d", &n2))
X	err ("n2 not given\n");
X    if (!fetch ("n3", "d", &n3))
X	n3 = 1;
X    if (!fetch ("esize", "d", &esize))
X	err ("esize not given\n");
X
X    if (esize != 1 && esize != 3)
X	err ("esize must be 1 or 3\n");
X
X    coltab = 1;
X    fetch ("coltab", "1", &coltab);
X    if (!coltab && esize == 3)
X	err ("esize must be 1 if coltab=no\n");
X
X    if (esize == 1)
X	strcpy (color, "I");
X    else
X	strcpy (color, "332");
X    fetch ("color", "s", color);
X
X    if (!getch ("xll", "f", &xll))
X	xll = 1.;
X    if (!getch ("yll", "f", &yll))
X	yll = 1.;
X    if (!getch ("xur", "f", &xur))
X	xur = 5.;
X    if (!getch ("yur", "f", &yur))
X	yur = 5.;
X    if (!getch ("orient", "d", &orient))
X	orient = 1;
X    if (!getch ("nreserve", "d", &nreserve))
X	nreserve = 8;
X    if (!getch ("invert", "1", &invert))
X	invert = 1;
X    if (!getch ("movish", "1", &movish))
X	movish = 0;
X
X    putch_ ("movish", "d", &movish);
X
X    puthead ("\tn1=-1\n");
X
X    /* Polarity stuff */
X    polarity = 1;
X    fetch ("polarity", "d", &polarity);
X    putch ("polarity", "d", &polarity);
X
X    /* Axis and labelling parameters */
X    strcpy (label1, "");
X    strcpy (label2, "");
X    strcpy (title, "");
X    fetch ("label1", "s", label1);
X    fetch ("label2", "s", label2);
X    fetch ("title", "s", title);
X    o1 = 0.;
X    o2 = 0.;
X    d1 = 1.;
X    d2 = 1.;
X    fetch ("o1", "f", &o1);
X    fetch ("o2", "f", &o2);
X    fetch ("d1", "f", &d1);
X    fetch ("d2", "f", &d2);
X    d1num = 0.;
X    d2num = 0.;
X    o1num = o1;
X    o2num = o2;
X    fetch ("d1num", "f", &d1num);
X    fetch ("d2num", "f", &d2num);
X    fetch ("o1num", "f", &o1num);
X    fetch ("o2num", "f", &o2num);
X    labelsz = 5;
X    titlesz = 5;
X    labelfat = 1;
X    titlefat = 1;
X    fetch ("labelsz", "d", &labelsz);
X    fetch ("titlesz", "d", &titlesz);
X    fetch ("labelfat", "d", &labelfat);
X    fetch ("titlefat", "d", &titlefat);
X    labelrot = 0;
X    axiscol = 7;
X    fetch ("labelrot", "1", &labelrot);
X    fetch ("axiscol", "d", &axiscol);
X    sign = -1;
X    if (labelrot)
X	sign = 1;
X
X    frame = 1;
X    grid = 1;
X    fetch ("frame", "1", &frame);
X    fetch ("grid", "1", &grid);
X
X    if (fetch ("backcol", "f", backcol))
X    {
X	back = 1;
X    }
X    blast = 1;
X    fetch ("hurry", "1", &blast);
X
X    hclose ();
X
X    data = (unsigned char *) alloc (n1 * n2 * esize);
X
X    vp_erase ();
X    vp_style (STANDARD);
X    vp_color (axiscol);
X
X    if (coltab)
X    {
X
X	if (color[0] >= '0' && color[0] <= '9')
X	{
X	    redbit = color[0] - '0';
X	    greenbit = color[1] - '0';
X	    bluebit = color[2] - '0';
X	    if (redbit + greenbit + bluebit != 8)
X		err ("You must use exactly 8 bits!\n");
X
X	    redoff = 0;
X	    greenoff = redbit;
X	    blueoff = redbit + greenbit;
X
X	    for (i3 = 0; i3 < 256; i3++)
X	    {
X		ii = ~(~0 << redbit);
X		if (ii > 0)
X		    red[i3] = (float) ((i3 >> redoff) & ii) / (float) (ii);
X		else
X		    red[i3] = 0.;
X
X		ii = ~(~0 << greenbit);
X		if (ii > 0)
X		    green[i3] = (float) ((i3 >> greenoff) & ii) / (float) (ii);
X		else
X		    green[i3] = 0.;
X
X		ii = ~(~0 << bluebit);
X		if (ii > 0)
X		    blue[i3] = (float) ((i3 >> blueoff) & ii) / (float) (ii);
X		else
X		    blue[i3] = 0.;
X	    }
X
X	    for (i3 = 256; i3 < 512; i3++)
X	    {
X		jj = i3 - 256;
X
X		if (movish)
X		    jj = 2 * (int) (jj / 2);
X		vp_coltab (i3, red[jj], green[jj], blue[jj]);
X	    }
X
X	    for (jj = 0; jj < 256; jj++)
X	    {
X		ii = 0;
X		greenbit2 = greenbit;
X		bluebit2 = bluebit;
X		redbit2 = redbit;
X		kk = 0;
X		while (kk < 8)
X		{
X		    greenbit2--;
X		    if (greenbit2 >= 0)
X		    {
X			if (jj & (1 << (greenbit2 + greenoff)))
X			    ii |= 1 << kk;
X			kk++;
X		    }
X
X		    redbit2--;
X		    if (redbit2 >= 0)
X		    {
X			if (jj & (1 << (redbit2 + redoff)))
X			    ii |= 1 << kk;
X			kk++;
X		    }
X
X		    bluebit2--;
X		    if (bluebit2 >= 0)
X		    {
X			if (jj & (1 << (bluebit2 + blueoff)))
X			    ii |= 1 << kk;
X			kk++;
X		    }
X		}
X		map[ii] = jj;
X	    }
X
X	    for (i3 = nreserve; i3 < 256; i3++)
X	    {
X		jj = i3 - nreserve;
X
X		vp_coltab (i3, red[map[jj]],
X			   green[map[jj]],
X			   blue[map[jj]]);
X	    }
X	}
X	else
X	{
X	    switch (*color)
X	    {
X	    case 'i':
X		cola = cintensityn;
X		break;
X	    case 'F':
X		cola = cflag;
X		break;
X	    case 'R':
X		cola = cbi;
X		break;
X	    case 'W':
X		cola = csurf;
X		break;
X	    case 'G':
X		cola = cgsi;
X		break;
X	    case 'I':
X	    default:
X		cola = cintensityp;
X		break;
X	    }
X
X	    /*
X	     * set up a perfect grey scale in colors 256-511. the offset in
X	     * vp_raster maps the pixels into that range. no device actually
X	     * has such colors, so vplot looks at those colors the device
X	     * does have (0 through some n) and picks out the one closest to
X	     * the desired grey. thus by setting up black, white, 50% grey,
X	     * 75% grey, 25% grey, ... in 0-255, we'll get the best grey
X	     * scale for the device. 
X	     *
X	     * note: we leave colors 0 through nreserve-1 alone, since they are
X	     * already defined for the device. 
X	     *
X	     */
X	    for (i3 = 0; i3 < 256; i3++)
X	    {
X		red[i3] = rd_color ((float) i3);
X		green[i3] = gr_color ((float) i3);
X		blue[i3] = bl_color ((float) i3);
X	    }
X
X	    for (i3 = 256; i3 < 512; i3++)
X	    {
X		jj = i3 - 256;
X
X		if (movish)
X		    jj = 2 * (int) (jj / 2);
X		vp_coltab (i3, red[jj], green[jj], blue[jj]);
X	    }
X
X	    /*
X	     * set the lower grey scale, which will give us the best grey
X	     * scale possible for the device. 
X	     *
X	     * we assume that the device already has colors white and black set. 
X	     */
X
X	    i3 = 0;
X	    smap[i3] = 0;
X	    i3++;
X	    if (nreserve == 0)
X	    {
X		smap[i3] = 255;
X		i3++;
X	    }
X	    for (incr = 2; incr < 512; incr *= 2)
X	    {
X		for (i4 = 1; i4 < incr; i4 += 2)
X		{
X		    jj = i4 * 256 / incr;
X		    smap[i3] = jj;
X		    i3++;
X		    if (i3 == 256)
X			break;
X		}
X	    }
X
X	    for (i3 = nreserve; i3 < 256; i3++)
X	    {
X		jj = i3 - nreserve;
X
X		vp_coltab (i3, red[smap[jj]],
X			   green[smap[jj]],
X			   blue[smap[jj]]);
X	    }
X
X	}
X	if (back)
X	    vp_coltab (0, backcol[0], backcol[1], backcol[2]);
X    }
X    /* Set the coordinate transformation */
X    vp_orig (xll, yur);
X    vp_uorig (o2, o1);
X    vp_scale ((xur - xll) / (d2 * n2), (yll - yur) / (d1 * n1));
X
X
X    /*
X     * Do the plots 
X     */
X
X    for (i3 = 0; i3 < n3; i3++)
X    {
X	if (i3 != 0)
X	{
X	    vp_erase ();
X	    vp_style (STANDARD);
X	    vp_color (axiscol);
X	}
X	reed (infd, data, n1 * n2 * esize);
X	if (polarity < 0)
X	    for (ii = 0; ii < n1 * n2 * esize; ii++)
X	    {
X		data[ii] = (unsigned char) 255 - data[ii];
X	    }
X/*
X * If esize=3, then map the RGB triples onto the closest available
X * color.
X */
X	if (esize == 3)
X	{
X	    if (color[0] >= '0' && color[0] <= '9')
X	    {
X		for (ii = 0; ii < n1 * n2; ii++)
X		{
X		    ired_lev = data[esize * ii];
X		    igreen_lev = data[esize * ii + 1];
X		    iblue_lev = data[esize * ii + 2];
X
X		    win = 0;
X		    win |= ((ired_lev >> (8 - redbit)) & ~(~0 << redbit)) << redoff;
X		    win |= ((igreen_lev >> (8 - greenbit)) & ~(~0 << greenbit)) << greenoff;
X		    win |= ((iblue_lev >> (8 - bluebit)) & ~(~0 << bluebit)) << blueoff;
X		    data[ii] = win;
X		}
X	    }
X	    else
X	    {
X		for (ii = 0; ii < n1 * n2; ii++)
X		{
X		    red_lev = data[esize * ii] / 255.;
X		    green_lev = data[esize * ii + 1] / 255.;
X		    blue_lev = data[esize * ii + 2] / 255.;
X		    error_win = 8.;
X		    for (jj = 0; jj < 256; jj++)
X		    {
X			error = 2. * SQUARE (red_lev - red[jj]) + 4. * SQUARE (green_lev - green[jj]) + SQUARE (blue_lev - blue[jj]);
X			if (error < error_win)
X			{
X			    error_win = error;
X			    win = jj;
X			    if (error == 0.)
X				break;
X			}
X		    }
X		    data[ii] = win;
X		}
X	    }
X	}
X
X	/*
X	 * Only offset the colors if we have defined a color table.
X	 * Otherwise, leave them alone. 
X	 */
X	if (coltab)
X	    offset = 256;
X	else
X	    offset = 0;
X
X	xpix = n1;
X	ypix = n2;
X	bit = 0;
X	ppi = 0;
X	vp_raster (data, blast, bit, offset, xpix, ypix, xll, yll, ppi, &xur, &yur, orient, invert);
X
X	vp_fat (1);
X	if (frame)
X	{
X	    vp_move (xll, yll);
X	    vp_draw (xll, yur);
X	    vp_draw (xur, yur);
X	    vp_draw (xur, yll);
X	    vp_draw (xll, yll);
X	}
X	if (grid)
X	{
X	    if (d2num > 0)
X	    {
X		for (pos2 = o2num; pos2 <= o2 + n2 * d2; pos2 += d2num)
X		{
X		    vp_umove (pos2, o1);
X		    vp_udraw (pos2, o1 + n1 * d1);
X		}
X	    }
X	    if (d1num > 0)
X	    {
X		for (pos1 = o1num; pos1 <= o1 + n1 * d1; pos1 += d1num)
X		{
X		    vp_umove (o2, pos1);
X		    vp_udraw (o2 + n2 * d2, pos1);
X		}
X	    }
X	}
X	if (d2num > 0)
X	{
X	    vp_fat (labelfat);
X	    vp_tjust (TH_CENTER, TV_BASE);
X	    for (pos2 = o2num; pos2 <= o2 + n2 * d2; pos2 += d2num)
X	    {
X		vp_umove (pos2, o1);
X		vp_where (&xx, &yy);
X		yy += .07;
X		vp_draw (xx, yy);
X		yy += .03;
X		sprintf (string, "%g", pos2);
X		vp_text (xx, yy, labelsz, 0, string);
X	    }
X	}
X	if (d1num > 0)
X	{
X	    vp_fat (labelfat);
X	    vp_tjust (TH_CENTER, TV_TOP);
X	    for (pos1 = o1num; pos1 <= o1 + n1 * d1; pos1 += d1num)
X	    {
X		vp_umove (o2, pos1);
X		vp_where (&xx, &yy);
X		xx -= .07;
X		vp_draw (xx, yy);
X		xx -= .03;
X		sprintf (string, "%g", pos1);
X		vp_text (xx, yy, labelsz, -90, string);
X	    }
X	}
X	vp_move ((xll + xur) / 2., yur);
X	vp_where (&xx, &yy);
X	yy += .07;
X	yy += .03;
X	yy += labelsz / TXPERIN;
X	yy += .15;
X	vp_fat (labelfat);
X	vp_tjust (TH_CENTER, TV_BASE);
X	vp_text (xx, yy, labelsz, 0, label2);
X
X	yy += labelsz / TXPERIN;
X	yy += .15;
X	vp_fat (titlefat);
X	vp_tjust (TH_CENTER, TV_BOTTOM);
X	vp_text (xx, yy, titlesz, 0, title);
X
X	vp_move (xll, (yll + yur) / 2.);
X	vp_where (&xx, &yy);
X	xx -= .07;
X	xx -= .03;
X	xx -= labelsz / TXPERIN;
X	xx -= .15;
X	vp_fat (labelfat);
X	if (labelrot)
X	    vp_tjust (TH_CENTER, TV_BOTTOM);
X	else
X	    vp_tjust (TH_CENTER, TV_TOP);
X	vp_text (xx, yy, labelsz, sign * 90, label1);
X    }
X}
X
float
rd_color (x)
X    float           x;
X{
X    if (x < 128)
X	return (((128. - x) * (float) cola[0] / 128.) + (x * (float) cola[1] / 128.)) / 255.;
X    else
X	return (((255. - x) * (float) cola[1] / 127.) + ((x - 128.) * (float) cola[2] / 127.)) / 255.;
X}
X
float
gr_color (x)
X    float           x;
X{
X    if (x < 128)
X	return (((128. - x) * (float) cola[3] / 128.) + (x * (float) cola[4] / 128.)) / 255.;
X    else
X	return (((255. - x) * (float) cola[4] / 127.) + ((x - 128.) * (float) cola[5] / 127.)) / 255.;
X}
X
float
bl_color (x)
X    float           x;
X{
X    if (x < 128)
X	return (((128. - x) * (float) cola[6] / 128.) + (x * (float) cola[7] / 128.)) / 255.;
X    else
X	return (((255. - x) * (float) cola[7] / 127.) + ((x - 128.) * (float) cola[8] / 127.)) / 255.;
X}
END_OF_FILE
if test 15559 -ne `wc -c <'Vplot_Kernel/util/Ta2vplot.c'`; then
    echo shar: \"'Vplot_Kernel/util/Ta2vplot.c'\" unpacked with wrong size!
fi
# end of 'Vplot_Kernel/util/Ta2vplot.c'
fi
echo shar: End of archive 17 \(of 24\).
cp /dev/null ark17isdone
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.