TITLE pprSubr.c - portable plotting routines

DESCRIPTION
	These routines support simple 2-D plotting in a "window".  The
	window can be either an actual display window, a PostScript
	printer page, or an EPS file for Encapsulated PostScript.

QUICK REFERENCE
PPR_AREA *pArea;     pointer to a plot area
 PPR_WIN *pWin;      pointer to a plot "window"

    void  pprAnnotX(       pArea,   offset,   dataL,    dataR,   nDiv,
                                      drawLine, xLabel, xAnnot, angle   )
    void  pprAnnotY(       pArea,   offset,   dataB,    dataT,   nDiv,
                                      drawLine, yLabel, yAnnot, angle   )
    void  pprAnnotYMark(   pArea,   offset,   markNum                   )
    void  pprAreaClose(    pArea                                        )
    void  pprAreaErase(    pArea    fracL,    fracB,    fracR,   fracT  )
PPR_AREA *pprAreaOpen(     pWin,    fracL,    fracB,    fracR,   fracT,
                                    dataL,    dataB,    dataR,   dataT,
                                              nXint,    nYint,   charHt )
PPR_AREA *pprAreaOpenDflt( pWin,    fracL,    fracB,    fracR,   fracT,
                                    dataL,    dataB,    dataR,   dataT  )
    void  pprAreaRescale(  pArea,   dataL,    dataB,    dataR,   dataT  )
    long  pprAreaSetAttr(  pArea,   code,     attrVal,  pAttr           )
     code: PPR_ATTR_{CLIP,COLORNUM,BG,FG,KEYNUM,LINE_THICK,NOCLIP,PATT_ARRAY}
    void  pprAutoEnds(     dbl1,    dbl2,    >pNewDbl1, >pNewDbl2       )
    void  pprAutoInterval( dbl1,    dbl2,    >pNint                     )
    void  pprAutoRangeD(   dblAry,  nPts,    >minDbl,  >maxDbl          )
    void  pprAutoRangeF(   fltAry,  nPts,    >minDbl,  >maxDbl          )
    void  pprAutoRangeL(   lngAry,  nPts,    >minDbl,  >maxDbl          )
    void  pprAutoRangeS(   shtAry,  nPts,    >minDbl,  >maxDbl          )
    void  pprChar(         pArea,   xDbl, yDbl, char, charHt, angle     )
  double  pprCos_deg(      angle                                        )
    void  pprCvtDblToTxt( >text,    width,    dblVal,   nSigDigits      )
    void  pprGrid(         pArea                                        )
    void  pprGridErase(    pArea                                        )
    void  pprGridLabel(    pArea,   xLabel, xAnnot, yLabel, yAnnot, angle)
    void  pprLineD(        pArea,   xDblAry,  yDblAry,  nPts            )
    void  pprLineF(        pArea,   xFltAry,  yFltAry,  nPts            )
    void  pprLineL(        pArea,   xLngAry,  yLngAry,  nPts            )
    void  pprLineS(        pArea,   xShtAry,  yShtAry,  nPts            )
    void  pprLineSegD(     pArea,   xDbl1,    yDbl1,    xDbl2,  yDbl2   )
    void  pprLineSegL(     pArea,   xLng1,    yLng1,    xLng2,  yLng2   )
    void  pprMarkD(        pArea,   xDbl1,    yDbl1,    markNum         )
    void  pprMarkL(        pArea,   xLng1,    yLng1,    markNum         )
    void  pprMoveD(        pArea,   xDbl1,    yDbl1,    penDown         )
    void  pprPerim(        pArea                                        )
    void  pprPerimErase(   pArea                                        )
    void  pprPerimLabel(   pArea,   xLabel, xAnnot, yLabel, yAnnot, angle)
    void  pprPointD(       pArea,   xDbl1,    yDbl1                     )
    void  pprPointL(       pArea,   xLng1,    yLng1                     )
  double  pprSin_deg(      angle                                        )
    void  pprText(         pArea,   xDbl, yDbl, text, just, charHt, angle)
				just: PPR_TXT_{CEN,RJ,LJ}
    void  pprWinClose(     pWin                                         )
    void  pprWinErase(     pWin                                         )
    void  pprWinInfo(      pWin,   >pXpos,   >pYpos,   >pXwid,   >pYht  )
     int  pprWinIsMono(    pWin                                         )
    long  pprWinLoop(      pWin,    drawFn,   pDrawArg                  )
              void  drawFn(pWin, pDrawArg)
 PPR_WIN *pprWinOpen(      winType, dispName, winTitle, xPos, yPos, xWid,yHt)
                              winType: PPR_WIN_{SCREEN,POSTSCRIPT,EPS}
 PPR_WIN *pprWinOpenUW(    pFrame,  pCanvas,  NULL,     NULL            )
 PPR_WIN *pprWinOpenUW(    ppDisp,  pWindow,  pGC,      NULL            )
    void  pprWinReplot(    pWin,    drawFn,   pDrawArg                  )
    long  pprWinSetAttr(   pWin,    code,     pAttr                     )
              code: PPR_ATTR_{COLORNUM,GC,KEYNUM,LINE_THICK,PATT_ARRAY}
  
DESCRIPTION (continued)
	Plotting is done within "plot areas" which are defined within
	the window.  Plot areas can be as large as the window, and they
	can overlap, if desired.  Clipping service is optional, since
	plot areas are often calibrated for the "normal" range of data,
	and it is useful to see what's happening if the data are outside
	the normal range.

	One non-intuitive aspect of the term "plot area" is that the
	usual case ALWAYS plots outside the plot area.  Generally, this
	happens when annotations and labels are added to a grid.  The
	plot area itself only specified where the edges of the grid were
	to be drawn.  Because of this, determining the size and placement
	of a plot area must take into account the necessary margins for
	text.  (pprAreaOpenDflt automatically takes care of margins.)

	Most plotting is done using "data coordinates", which are the
	actual data values.  In some cases, coordinates or distances are
	specified in terms of a fraction of the window height (see, for
	example, pprAreaOpen or pprText).

	Also provided in this package are some routines for interacting
	with the "window".  In many cases, this means that a plotting
	program can totally avoid any knowledge of, or dependence on, a
	particular windowing environment.  This makes easily available
	the capability for producing hard copies of plots on a PostScript
	printer.

	Many routines in this package require that values be
	represented with type 'double'.  In some cases, however, other
	data types are directly supported, so that the caller doesn't
	need to alter the way data are stored.

BUGS
o	Only linear axes are presently supported
o	There is presently no mechanism to allow a calling program to
	do other work while a plot is on the screen.  It would be nice
	for a program to be able to periodically check with this package
	to see if resize or expose events need to be serviced.
o	The SunView version of this package won't run properly with
	programs which use the SunOs LightWeight Process library.
o	The SunView version of this package doesn't handle color.

EXAMPLE
	The following program plots the first 80 points of a parabola.  The
	size and position of the plot window can be freely changed; the
	window can be covered and exposed, iconified and de-iconified, etc.
	When a `click right' is done in the plot window, the window is
	closed.  A PostScript file named "testPS" is produced; the size of
	the plot in this file is about the same as it was when the plot
	window was closed.  (The plot window can be closed using the `quit'
	item on the window's title bar menu (but not under X!!).)

	The program is compiled and linked for SunView with the following
	command.  (It will be necessary to find where pprPlot.o and
	pprPlotDefs.h are located and possibly `fix up' the command.)

           cc plotTest.c pprPlot.o -lsuntool -lsunwindow -lpixrect -lm

	The program is compiled and linked for X with the following
	command.  (It will be necessary to find where pprPlot.o and
	pprPlotDefs.h are located and possibly `fix up' the command.)

           cc plotTest.c pprPlot.o -lX11 -lm

	(As of Feb 6, 1991, plotTest.c is available on the AT-division
	open network in ~gta/ar/plotTest.c.  It should be copied into
	the user's working directory before using it.)

	(As of Feb 6, 1991, pprPlot is available on the AT-division
	open network in ~gta.  Until access to this software has been
	formalized, use the following for Sun3/SunView:
	  cc plotTest.c -I/home/obiwan/gtacs/h /home/obiwan/gtacs/ar/pprPlotS.o
           				-lsuntool -lsunwindow -lpixrect -lm
	(For Sun3/X, use the following:
	  cc plotTest.c -I/home/obiwan/gtacs/h /home/obiwan/gtacs/ar/pprPlotX.o
					-lX11 -lm
	(For Sun4 builds, use "/ar/ar4/" in place of "/ar/" in the above
	commands.)

  #include <stdio.h>
  #include <pprPlotDefs.h>

  #define NPTS 80
----------------------------------------------------------------------------
   define a structure for holding the data.  This is needed because the
   replot routine (which does the actual plotting) is only given a pointer
   to the information it needs.
----------------------------------------------------------------------------
  typedef struct {
      int     nPts;
      float   x[NPTS];
      float   y[NPTS];
      double  xMin;
      double  xMax;
      double  yMin;
      double  yMax;
  } MY_DATA;

  void replot();

  main()
  {
      int     i;
      int     x=0,y=0,width=0,height=0;
      PPR_WIN	*pWin;
      MY_DATA	myData;
      long	stat;

----------------------------------------------------------------------------
   generate the data in the structure.  Once it's generated, figure out
   the range of values and put the range into the structure using
   pprAutoRangeF.  This specific routine was chosen because the data
   is in "float" arrays.  Different forms of data would result in choosing
   a different routine.

   The routine pprAutoEnds is available to "round" the endpoints of the
   axes to "nicer" values.  Depending on the application, it will be
   attractive to use this following the pprAutoRange call.
----------------------------------------------------------------------------
      myData.nPts = NPTS;
      for (i=0; i<NPTS; i++) {
          myData.x[i] = (float)i;
          myData.y[i] = (float)(i*i);
      }
      pprAutoRangeF(myData.x, NPTS, &myData.xMin, &myData.xMax);
      pprAutoRangeF(myData.y, NPTS, &myData.yMin, &myData.yMax);

----------------------------------------------------------------------------
   Now, do the actual plotting, in a roundabout way.  First, an actual
   window on the screen is created with the pprWinOpen call.  The
   size and position of the window are determined by the values
   (initialized above) of x, y, width, and height.

   After opening the window, pprWinLoop is called to accomplish the
   actual plotting.  This routine calls the replot() routine whenever it
   is necessary to replot the data.  This will happen immediately after
   pprWinLoop is called, and also any time the plot window is resized
   or re-exposed after being fully or partially covered.  pprWinLoop
   doesn't return until a "click right" (or a window menu quit) is done.

   After pprWinLoop returns, pprWinInfo is called to get the most
   recent size and position of the window.  If this program were going
   to put up another plot, this information would allow being polite
   and having the window for the new plot cover the same part of the
   screen.  In this example program, the only use being made of the
   information is to control the size of the PostScript plot.

   Finally, the plot window is closed using pprWinClose.  It's important
   not to skip this step.
----------------------------------------------------------------------------
      pWin = pprWinOpen(PPR_WIN_SCREEN, NULL, "test title",
                                                  x, y, width, height);
      if (pWin == NULL) abort();
      stat = pprWinLoop(pWin, replot, &myData);
      if (stat != 0) abort();
      pprWinInfo(pWin, &x, &y, &width, &height);
      pprWinClose(pWin);

----------------------------------------------------------------------------
   Produce a file containing a PostScript version of the plot.  Because
   of the information obtained by pprWinInfo, this will be about the
   same size as the plot last appeared on the screen.
----------------------------------------------------------------------------
      pWin = pprWinOpen(PPR_WIN_POSTSCRIPT, "testPS", NULL, x,y,width,height);
      if (pWin == NULL) abort();
      stat = pprWinLoop(pWin, replot, &myData);
      if (stat != 0) abort();
      pprWinClose(pWin);

      return;
  }

----------------------------------------------------------------------------
	D R A W   F U N C T I O N
----------------------------------------------------------------------------

  void replot(pWin, pMyData)
  PPR_WIN	*pWin;
  MY_DATA	*pMyData;
  {
      double  xlo=0., ylo=0., xhi=.95, yhi=.95;
      double  charHt, charHtX;
      PPR_AREA *pArea;
      int     i;

----------------------------------------------------------------------------
   First, figure out how big to make the characters for axis labels and
   annotations.  The character size will be used to specify the left and
   bottom margins for the actual area used for plotting.

   The pprAreaOpen call establishes a plot area that will be used for
   the actual plotting.  A left margin of 12 lines and a bottom margin
   of 6 lines are specified.  The top margin is .05 of the window height,
   and the right margin is .05 of the window width.

   A perimeter with tick marks is drawn, and annotations and labels are
   applied, with the pprPerimLabel call.

   The actual plotting of data is done with pprLineF.  This specific
   routine was chosen because the data is in "float" arrays.  Different
   forms of data would result in choosing a different routine.

   Finally, the plot area is closed with pprAreaClose.  It's important
   not to skip this step.
----------------------------------------------------------------------------
      charHt = PprDfltCharHt(ylo, yhi);
      charHtX = pprYFracToXFrac(pWin, charHt);
      pArea = pprAreaOpen(pWin, xlo+12.*charHtX, ylo+6.*charHt, xhi, yhi,
              pMyData->xMin, pMyData->yMin, pMyData->xMax, pMyData->yMax,
              5, 5, charHt);
      pprPerimLabel(pArea, "x label", NULL, "y label", NULL, 0.);

      pprLineF(pArea, pMyData->x, pMyData->y, pMyData->nPts);

      pprAreaClose(pArea);

      return;
  }


NAME	pprAnnotX - annotate an X axis, perhaps drawing a line and tick marks

DESCRIPTION
	Annotate an X axis, placing annotations at the major tick intervals.

	If desired, an axis line is also drawn, with tick marks at the
	major intervals.  The tick marks are drawn using the "generic"
	line attributes for the plot window.  The axis line is drawn with
	the line attributes of the plot area; this allows using a dashed
	line pattern or color to associate an axis with a data line.

	The annotations and label are drawn using the default character
	height for the plot area, in the color, if any, for the plot area.

	An array of text strings can be supplied for annotating the tick
	intervals.  This is useful if the desired annotations are text.
	If an annotation array isn't supplied, then numeric annotations
	are generated.

	To allow multiple calibrations for an axis, this routine accepts
	an `offset' argument.  If this argument is greater than 0, then
	the annotation and labeling activity occurs that many lines (in
	the default character height for the plot area) below the axis
	which was established by pprAreaOpen.

	An alternate entry point, pprAnnotX_wc, is available to use the
	plot window's color for the annotation.

RETURNS
	void

BUGS
o	only linear axes are handled
o	doesn't presently support offset processing

NOTES
1.	Uses a space below the axis of 5 character heights.

SEE ALSO
	pprAnnotY, pprGrid, pprPerim, pprAreaOpen, pprAreaSetAttr

SYNOPSIS

void
pprAnnotX(pArea, offset, xLeft, xRight, xNint, drawLine, xLabel, xAnnot, angle)
PPR_AREA *pArea;	/* IO pointer to plotter area */
int	offset;		/* I offset as number of lines below yBot to annotate */
double	xLeft;		/* I x data value at left end of axis */
double	xRight;		/* I x data value at right end of axis */
int	xNint;		/* I number of major intervals for axis */
int	drawLine;	/* I 1 says to draw a line and tick marks */
char	*xLabel;	/* I label for x axis, or NULL; oriented horizontal */
char	**xAnnot;	/* I pointer to array of x annotations, or NULL */
double	angle;		/* I orientation angle for annotation text; 0. or 90. */

NAME	pprAnnotY - annotate a Y axis, perhaps drawing line and tick marks

DESCRIPTION
	Annotate a Y axis, placing annotations at the major tick intervals.

	If desired, an axis line is also drawn, with tick marks at the
	major intervals.  The tick marks are drawn using the "generic"
	line attributes for the plot window.  The axis line is drawn with
	the line attributes of the plot area; this allows using a dashed
	line pattern or color to associate an axis with a data line.

	The annotations and label are drawn using the default character
	height for the plot area, in the color, if any, for the plot area.

	An array of text strings can be supplied for annotating the tick
	intervals.  This is useful if the desired annotations are text.
	If an annotation array isn't supplied, then numeric annotations
	are generated.

	To allow multiple calibrations for an axis, this routine accepts
	an `offset' argument.  If this argument is greater than 0, then
	the annotation and labeling activity occurs that many lines (in
	the default character height for the plot area) to the left of
	the axis which was established by pprAreaOpen.

	An alternate entry point, pprAnnotY_wc, is available to use the
	plot window's color for the annotation.

RETURNS
	void

BUGS
o	only linear axes are handled

NOTES
1.	Uses a space to the left of the axis of 12 character heights if
	annotations are horizontal, and a space of 5 character heights
	if they are vertical.

SEE ALSO
	pprAnnotX, pprGrid, pprPerim, pprAreaOpen, pprAreaSetAttr

SYNOPSIS

void
pprAnnotY(pArea, offset, yBot, yTop, yNint, drawLine, yLabel, yAnnot, angle)
PPR_AREA *pArea;	/* IO pointer to plotter area */
int	offset;		/* I number of lines to left of axis for annotation */
double	yBot;		/* I y data value at bottom end of axis */
double	yTop;		/* I y data value at top end of axis */
int	yNint;		/* I number of major intervals for axis */
int	drawLine;	/* I 1 says to draw a line and tick marks */
char	*yLabel;	/* I label for y axis, or NULL; oriented vertical */
char	**yAnnot;	/* I pointer to array of y annotations, or NULL */
double	angle;		/* I orientation angle for annotation text; 0. or 90. */

NAME	pprAnnotYMark - add plot marks to a Y axis annotation

DESCRIPTION
	Draw two plot marks at the foot of the Y axis annotation, to allow
	associating the axis with a particular set of data.

RETURNS
	void

BUGS
o	only linear axes are handled

SEE ALSO
	pprMark, pprAnnotY

EXAMPLE

SYNOPSIS

void
pprAnnotYMark(pArea, offset, markNum)
PPR_AREA *pArea;	/* I pointer to plot area structure */
int	offset;		/* I number of lines to left of axis for annotation */
int	markNum;	/* I mark number */

NAME	pprArc - draw an arc

DESCRIPTION
	Draw an arc.  The arc is specified by a radius and two angles.  The
	angles, in degrees, specify the angle at which the arc starts and
	the angle at which it ends.  An angle increment specifies both the
	direction of the arc and the size of the chords which approximate
	the arc.  Angles are measured counter-clockwise from the positive
	X axis.

	The radius of the arc is treated as representing data values in the
	plot area.  If both the X and Y axes of the plot area have the
	same data scaling, then circular arcs will be produced (assuming
	a square plot area).  If the X scaling is not the same as the Y
	scaling, then elliptical arcs will be produced.

	The arc is drawn using the color, dashed line, and other attributes
	of the plot area.  Alternate entry points are:

		pprArcD_ac	uses the area color, but ignores other
				attributes

RETURNS
	void

SEE ALSO

SYNOPSIS

void
pprArcD(pArea, xDbl, yDbl, radDbl, angle1, angle2, angleIncr)
PPR_AREA *pArea;	/* I pointer to plot area structure */
double	xDbl;		/* I x data coordinate for center of arc */
double	yDbl;		/* I y data coordinate for center of arc */
double	radDbl;
double	angle1;		/* I angle to start arc */
double	angle2;		/* I angle to stop arc */
double	angleIncr;	/* I size of steps in drawing arc */

NAME	pprAreaClose - close a plot area

DESCRIPTION
	Frees the memory associated with a plot area pointer and does other
	cleanup operations.  This routine should be called prior to calling
	pprWinClose.

RETURNS
	void

SYNOPSIS

void
pprAreaClose(pArea)
PPR_AREA *pArea;	/* I pointer to plot area structure */

NAME	pprAreaErase - erase an area within a plot window

DESCRIPTION
	Erases an area within a plot window.

RETURNS
	void

SEE ALSO
	pprWinErase, pprGridErase, pprPerimErase

NOTES
1.	Another mode of calling pprAreaErase, in which the arguments are
	pixel offsets from the data area boundaries, can be invoked by
	having one or more of the arguments be greater than 1. or less
	than 0.

EXAMPLES
1.	Erase within a data area, preserving the perimeter line.

		pprAreaErase(pArea, 1., 1., -1., -1.);

SYNOPSIS

void
pprAreaErase(pArea, wfracXleft, wfracYbot, wfracXright, wfracYtop)
PPR_AREA *pArea;	/* I pointer to plot area structure */
double	wfracXleft;	/* I x window fraction of left edge of area */
double	wfracYbot;	/* I y window fraction of bottom edge of area */
double	wfracXright;	/* I x window fraction of right edge of area */
double	wfracYtop;	/* I y window fraction of top edge of area */

NAME	pprAreaOpen - initialize a plot area

DESCRIPTION
	Initialize a plot area within the plot window.  This initialization
	must be done before calling any of the routines which do actual
	plotting.

	This routine establishes a rectangular "data area" within the plot
	window.  It is within the data area that data will be plotted.
	The size and position of the data area are specified in terms
	of fractions of the window size; they are expressed as
	"coordinates" of the lower left and upper right corners of the
	area.  The data area specified in the call to pprAreaOpen does
	NOT include space for axis annotations and labels.  (pprAreaOpenDflt
	can be used to automatically get the necessary margins.)

	This routine must also be told the data values at the two corners
	of the data area in order to determine scaling.

	In addition to establishing scaling, this routine accepts information
	about how many major divisions there are for each axis and what
	default character height is to be used for displaying text within
	the plot area (see pprText for more information).  If any of these
	parameters is specified as zero, this routine chooses an appropriate
	value.

	The default line attributes for the plot are copied from those of
	the plot window.  pprAreaSetAttr can be used to change them.  Under
	X11, a gc is created for the plot area with the foreground and
	background being copied from the gc for the plot window;
	pprAreaSetAttr can be used to change the foreground and background.

	When plotting is complete for a plot area, pprAreaClose should
	be called.

RETURNS
	pointer to plot area, or
	NULL

BUGS
o	only linear calibration is handled

SEE ALSO
	pprWinOpen, pprAreaOpenDflt, pprAreaSetAttr
	pprAutoEnds, pprAutoInterval, pprAutoRange
	pprText

EXAMPLE
1.	Set up an area which occupies the full width of the window, but
	which uses the middle third vertically.  The range for x values
	is 0 to 100; for y, the range is -10 to 10.  Both the x and y
	axes are to be divided into 5 intervals.

	Allow space below and to the left of the actual area for plotting
	for pprPerim to place labels and annotations.  The required
	size of "margins" depends on the size of characters used, so a
	default size is determined (and put into effect as part of the
	pprAreaOpen call).

	PPR_AREA *pArea;
	double	charHt, charHtX;

	charHt = PprDfltCharHt(.33, .67);
	charHtX = pprYFracToXFrac(pWin, charHt);
	pArea = pprAreaOpen(pWin, 0.+12.*charHtX, .33+6*charHt, 1., .67,
			0., -10., 100., 10., 5, 5, charHt);
	...
	pprAreaClose(pArea);

SYNOPSIS

PPR_AREA *
pprAreaOpen(pWin, wfracXleft, wfracYbot, wfracXright, wfracYtop,
			    xLeft, yBot, xRight, yTop, xNint, yNint, charHt)
PPR_WIN *pWin;		/* I pointer to plot window structure */
double	wfracXleft;	/* I x window fraction of left edge of data area */
double	wfracYbot;	/* I y window fraction of bottom edge of data area */
double	wfracXright;	/* I x window fraction of right edge of data area */
double	wfracYtop;	/* I y window fraction of top edge of data area */
double	xLeft;		/* I x data value at left side of data area */
double	yBot;		/* I y data value at bottom side of data area */
double	xRight;		/* I x data value at right side of data area */
double	yTop;		/* I y data value at top side of data area */
int	xNint;		/* I x axis number of intervals; if <=0, a default
				value is provided */
int	yNint;		/* I y axis number of intervals; if <=0, a default
				value is provided */
double	charHt;		/* I value to use as default for character size, as
				a fraction of window height; if <= 0.,
				a default value is provided */

NAME	pprAreaOpenDflt - initialize a plot area using defaults

DESCRIPTION
	Initialize a plot area within the plot window.  This initialization
	must be done before calling any of the routines which do actual
	plotting.

	This routine is a variant on pprAreaOpen.  It performs the functions
	of that routine, but uses some defaults rather than making the
	caller determine specific values.  In particular, this routine:

	o   sets a default character height

	o   determines the number of major divisions for each axis

	o   establishes, inside the plot area specified, margins which
	    will be adequate for annotating and labeling the axes.

	See the description for pprAreaOpen for additional details.

	When plotting is complete for a plot area, pprAreaClose should
	be called.

RETURNS
	pointer to plot area, or
	NULL

BUGS
o	only linear calibration is handled

SEE ALSO
	pprWinOpen, pprAreaOpen, pprAreaSetAttr
	pprAutoEnds, pprAutoInterval, pprAutoRange
	pprText

SYNOPSIS

PPR_AREA *
pprAreaOpenDflt(pWin, wfracXleft, wfracYbot, wfracXright, wfracYtop,
			    xLeft, yBot, xRight, yTop)
PPR_WIN *pWin;		/* I pointer to plot window structure */
double	wfracXleft;	/* I x window fraction of left edge of plot area */
double	wfracYbot;	/* I y window fraction of bottom edge of plot area */
double	wfracXright;	/* I x window fraction of right edge of plot area */
double	wfracYtop;	/* I y window fraction of top edge of plot area */
double	xLeft;		/* I x data value at left side of data area */
double	yBot;		/* I y data value at bottom side of data area */
double	xRight;		/* I x data value at right side of data area */
double	yTop;		/* I y data value at top side of data area */

NAME	pprAreaRescale - change scaling for existing plot area

DESCRIPTION
	Changes the scaling for a plot area using new data values at the
	edges of the data area.  The actual size and position of the
	data area within the plot window aren't changed.

	No re-drawing is done by this routine.  Typically, the caller will
	erase the appropriate area, draw the grid or perimeter, set the
	area for clipping, and, finally, replot the data.

	Default character height for the plot area is altered proportionally
	to the rescaling of the plot area.

RETURNS
	void

SEE ALSO
	pprAreaSetAttr, pprAreaErase

SYNOPSIS

void 
pprAreaRescale(pArea, xLeft, yBot, xRight, yTop)
PPR_AREA *pArea;	/* I pointer to plot area structure */
double	xLeft;		/* I x data value at left side of data area */
double	yBot;		/* I y data value at bottom side of data area */
double	xRight;		/* I x data value at right side of data area */
double	yTop;		/* I y data value at top side of data area */

NAME	pprAreaSetAttr - set attributes for a plot area

DESCRIPTION
	Set individual attributes for a plot area.  In most cases, the
	attributes affect the drawing of lines in the plot area.

	To use this routine, an attribute code and a corresponding value
	are supplied.  The form of the value argument depends on the code.

    o PPR_ATTR_CLIP sets the plot area so that line segments which lie
	outside the data area won't be drawn, but will terminate at their
	intersection with the edge of the data area.  Clipping can be
	disabled by setting the PPR_ATTR_NOCLIP attribute; the default when
	a plot area is created is no clipping.

	    pprAreaSetAttr(pArea, PPR_ATTR_CLIP, 0, NULL);
	    pprAreaSetAttr(pArea, PPR_ATTR_NOCLIP, 0, NULL);

    o PPR_ATTR_COLORNUM selects a color for use in drawing lines in a plot
	area.  For monochrome screens, no action is taken.  There are
	PPR_NCOLORS colors provided, numbered starting with 1.  A colorNum
	of 0 selects black.

	    int		colorNum;
	    colorNum = 4;
	    pprAreaSetAttr(pArea, PPR_ATTR_COLORNUM, colorNum, NULL);

    o PPR_ATTR_BG installs a caller-supplied background pixel value in
	the gc for the plot area.  (For use only with X11.  Under X11,
	pprAreaOpen initially set the gc for the plot area to have the
	same foreground and background colors as the gc for the plot window.)

	    pprAreaSetAttr(pArea, PPR_ATTR_BG, 0, &bg);

    o PPR_ATTR_FG installs a caller-supplied foreground pixel value in
	the gc for the plot area.  (For use only with X11.  Under X11,
	pprAreaOpen initially set the gc for the plot area to have the
	same foreground and background colors as the gc for the plot window.)

	    pprAreaSetAttr(pArea, PPR_ATTR_FG, 0, &fg);

    o PPR_ATTR_KEYNUM selects a legend key for identifying lines drawn
	in a plot area, and thus distinguishing them from the lines drawn
	by a different plot area.  This is primarily useful for overlapping
	plot areas, where several sets of data are drawn on the same axis.
	The key number, which is expected to be in the range 0 to PPR_NKEYS,
	inclusive, selects either a dashed line pattern or a color,
	depending on the nature of the device on which the plot window
	resides.  There are PPR_NKEYS unique patterns and colors; a key
	number of 0 resets to a "plain", solid line.

	Use of the PPR_ATTR_KEYNUM option provides a way to restart a
	dashed line pattern at its beginning.

	    int		keyNum;
	    keyNum = 4;
	    pprAreaSetAttr(pArea, PPR_ATTR_KEYNUM, keyNum, NULL);

    o PPR_ATTR_LINE_THICK sets the line thickness for the plot area.  The
	thickness is the integer number of thousandths of plot window height.
	The thickness is used for data drawing operations.  A thickness of
	0. results in pixel-thick lines.  As an example, a thickness of 10
	represents 10/1000 (or .01) of the window height.

	    int		thick;
	    thick = 3;			.003 of window height
	    pprAreaSetAttr(pArea, PPR_ATTR_LINE_THICK, thick, NULL);

    o PPR_ATTR_PATT_ARRAY installs a caller-supplied dashed line pattern
	array.  This is an array of type short.  The first element
	contains a number of pixels with `pen down'; the second has a
	number of pixels with `pen up'; the third with `pen down'; etc.
	Following the last element must be an element with a value of 0  .
	(pprAreaSetAttr stores only a pointer to the array, so the caller
	must preserve the array until pprAreaClose is called or until
	pprAreaSetAttr is called to `de-install' the pattern array.)  An
	array pointer of NULL resets the plot area back to normal drawing.

	    short	pattern[]={16,4,2,4,0};
	    pprAreaSetAttr(pArea, PPR_ATTR_PATT_ARRAY, 0, pattern);


	Some pprXxx routines don't use the attributes from the plot
	area, but instead use the `generic' attributes from the
	plot window structure.  The pprLineSegx_wc and pprMovex_wc
	routines provide an explicit mechanism for using the plot window
	attributes.

RETURNS
	0, or
	-1 if an error is encountered

BUGS
o	color is supported only for X
o	when color is used, ALL output for the plot area is colored; it's
	not clear yet whether this is a bug or a feature.
o	line thickness doesn't operate consistently under SunView

SEE ALSO
	pprAreaOpen

SYNOPSIS

long
pprAreaSetAttr(pArea, code, arg, pArg)
PPR_AREA *pArea;	/* IO pointer to plotter area */
PPR_ATTR_CODE code;	/* I attribute code: one of PPR_ATTR_xxx */
int	arg;		/* I attribute value, or 0 */
void	*pArg;		/* I pointer to attribute, or NULL */

NAME	pprAutoEnds - choose `clean' endpoint valuess for an axis

DESCRIPTION
	For a specific numeric range, this routine calculates a possibly
	altered numeric range which will produce more tasteful axis
	calibration.

RETURNS
	void

BUGS
o	this routine should probably focus some attention on choice of
	number of intervals for an axis; presently, the new endpoints
	chosen by this routine may be difficult to use for choosing
	interval size
o	uses exp10(), which doesn't exist in VxWorks
o	only linear calibration is handled

SEE ALSO
	pprAutoInterval, pprAutoRange, pprAreaOpen

SYNOPSIS

void
pprAutoEnds(left, right, pLeftNew, pRightNew)
double	left;		/* I leftmost value */
double	right;		/* I rightmost value */
double	*pLeftNew;	/* O new leftmost value */
double	*pRightNew;	/* O new rightmost value */

NAME	pprAutoInterval - figure out good interval size for an axis

DESCRIPTION
	Determine a "good" interval size for an axis, so that axis
	annotation will be tasteful.

RETURNS
	void

BUGS
o	this routine always chooses to divide an axis into 5 intervals
o	only linear calibration is handled

SEE ALSO
	pprAutoEnds, pprAutoRange, pprAreaOpen

SYNOPSIS

void
pprAutoInterval(val1, val2, pNint)
double	val1;		/* I value at one end of axis */
double	val2;		/* I value at other end of axis */
int	*pNint;		/* O number of intervals */

NAME	pprAutoRange - find minimum and maximum values for an array

DESCRIPTION
	Finds the minimum and maximum values in an array of values.

	Four different routines are available, depending on the type of
	the input array.  Each returns the min and max as a double:

	void pprAutoRangeD(doubleArray, nPoints, doubleMin, doubleMax)
	void pprAutoRangeF(floatArray, nPoints, doubleMin, doubleMax)
	void pprAutoRangeL(longArray, nPoints, doubleMin, doubleMax)
	void pprAutoRangeS(shortArray, nPoints, doubleMin, doubleMax)

RETURNS
	void

SEE ALSO
	pprAutoEnds, pprAutoInterval, pprAreaOpen


NAME	pprCos_deg - get the cosine of an angle in degrees

DESCRIPTION
	Get the cosine of an angle in degrees.  A table lookup technique
	is used.  The angle argument is truncated to the next lower 1/4
	degree prior to lookup.

RETURNS
	cosine

SYNOPSIS

double
pprCos_deg(angle)
double	angle;		/* I angle, in degrees */

NAME	pprChar - plot a character

DESCRIPTION
	Plots a single text character at a location.  The center of the
	character is placed at the specified x,y position.

	The character height specification is in terms of a fraction of the
	height of the window.  This results in automatic scaling of
	character sizes as the window size changes.  If a height of zero
	is specified in the call, then the default height for the plot
	area is used.  (The default height was established by pprAreaOpen.)

	A macro is available which returns the default character height
	used by this plot package.  The value returned is proportional to
	the height of the plot area.  This value can be used to generate
	"big" and "small" character sizes.

		PprDfltCharHt(lowYfrac, highYfrac)

		lowYfrac is the vertical fraction of the window at which
			the bottom edge of the plot area lies
		highYfrac is the vertical fraction of the window at which
			the top edge of the plot area lies

RETURNS
	void

BUGS
o	technique used works only with linear axes
o	ASCII character codes are assumed
o	no checks are made for illegal characters

SEE ALSO
	pprText, pprAreaOpen, pprLine, pprPoint

SYNOPSIS

void
pprChar(pArea, x, y, chr, height, angle)
PPR_AREA *pArea;	/* IO pointer to plot area structure */
double	x;		/* I x data coordinate of character */
double	y;		/* I y data coordinate of character */
char	chr;		/* I character to plot */
double	height;		/* I height of character, as a fraction of
				the height of the window; a value of
				zero results in using a default height */
double	angle;		/* I orientation angle of character, ccw degrees */

NAME	pprCvtDblToTxt - format a double for printing

DESCRIPTION
	Formats a double for printing.  This routine is dedicated to
	getting as large a range of values as possible into a particular
	field width.

	This routine doesn't attempt to handle extremely small values.
	It assumes that the field is large enough to handle the smallest
	significant value to be encountered.

RETURNS
	void

BUGS
o	extremely small values aren't handled well

NOTES
1.	If the value can't be represented at all in the field, the sign
	followed by *'s appears.
2.	In extreme cases, only the magnitude of the value will appear, as
	En or Enn.  For negative values, a - will precede the E.
3.	When appropriate, the value is rounded to the nearest integer
	for formatting.

SYNOPSIS

void
pprCvtDblToTxt(text, width, value, sigDig)
char	*text;		/* O text representation of value */
int	width;		/* I max width of text string (not counting '\0') */
double	value;		/* I value to print */
int	sigDig;		/* I max # of dec places to print */

NAME	pprGrid - draw a grid

DESCRIPTION
	Draw a perimeter and grid lines.  The number of intervals
	specified in the plot area structure is used for placing
	the grid lines.

	The color attributes for the plot window are used for drawing;
	dashed line and line thickness are ignored.

RETURNS
	void

BUGS
o	only linear axes are handled

SEE ALSO
	pprGridLabel, pprGridErase, pprPerim, pprAnnotX, pprAnnotY, pprAreaOpen

SYNOPSIS

void
pprGrid(pArea)
PPR_AREA *pArea;	/* IO pointer to plotter area */

NAME	pprGridErase - erase within a grid

DESCRIPTION
	Erases the screen inside the grid for the plot area.  (Actually,
	the entire data area is erased and then the grid is redrawn.)

RETURNS
	void

SEE ALSO
	pprPerimErase, pprAreaErase, pprWinErase

SYNOPSIS

void
pprGridErase(pArea)
PPR_AREA *pArea;	/* IO pointer to plotter area */

NAME	pprGridLabel - draw and label a grid

DESCRIPTION
	Draw a perimeter and grid lines.  The number of intervals
	specified in the plot area structure is used for placing
	the grid lines.

	Axis labels and annotations are drawn using the information from
	the plot area, as specified in the pprAreaOpen call.

RETURNS
	void

BUGS
o	only linear axes are handled

SEE ALSO
	pprGrid, pprPerim, pprAnnotX, pprAnnotY, pprAreaOpen

SYNOPSIS

void
pprGridLabel(pArea, xLabel, xAnnot, yLabel, yAnnot, angle)
PPR_AREA *pArea;	/* IO pointer to plotter area */
char	*xLabel;	/* I label for x axis, or NULL */
char	**xAnnot;	/* I pointer to array of x annotations, or NULL */
char	*yLabel;	/* I label for y axis, or NULL */
char	**yAnnot;	/* I pointer to array of y annotations, or NULL */
double	angle;		/* I angle for y annotations; 0. or 90. */

NAME	pprLine - plot a line using x and y data value vectors

DESCRIPTION
	Draw a line along the path specified by two value arrays.

	Several entry points are available to accomodate various
	types of data:

		pprLineF(pArea, x, y, npts)	x and y are float[]
		pprLineD(pArea, x, y, npts)	x and y are double[]
		pprLineS(pArea, x, y, npts)	x and y are short[]
		pprLineL(pArea, x, y, npts)	x and y are long[]

RETURNS
	void

BUGS
o	only linear calibration is handled

SEE ALSO
	pprLineSeg, pprMove, pprPoint, pprText

SYNOPSIS

void
pprLineF(pArea, x, y, npts)
PPR_AREA *pArea;	/* IO pointer to plot area structure */
float	*x;		/* I x array of data values */
float	*y;		/* I y array of data values */
int	npts;		/* I number of points to plot */

NAME	pprLineSeg - plot a line segment between a pair of points

DESCRIPTION
	Move to the first point and then draw a line to the second, using
	the line attributes of the plot area.  If the attributes indicate a
	dashed line, the current dashed line pattern will be used.

	Two entry points are available:

		pprLineSegD(pArea, x1, y1, x2, y2)	x and y are double
		pprLineSegL(pArea, x1, y1, x2, y2)	x and y are long

	For drawing ignoring the dashed line, line thickness, and other plot
	area attributes, but using the area color attribute, two alternate
	entry points are available:

		pprLineSegD_ac(pArea, x1, y1, x2, y2)	x and y are double
		pprLineSegL_ac(pArea, x1, y1, x2, y2)	x and y are long

RETURNS
	void

BUGS
o	only linear calibration is handled

SEE ALSO
	pprLine, pprMove, pprPoint, pprText

SYNOPSIS

void
pprLineSegD(pArea, x1, y1, x2, y2)
PPR_AREA *pArea;	/* IO pointer to plot area structure */
double	x1;		/* I first x point */
double	y1;		/* I first y point */
double	x2;		/* I second x point */
double	y2;		/* I second y point */

NAME	pprMarkD - draw a plotting mark

DESCRIPTION
	Draw a plotting mark at the specified point.  The color attribute
	(if any) of the plot area is used in drawing the mark.  Line
	thickness and dashed line pattern attributes are ignored.

	Two entry points are available:

		pprMarkD(pArea, x, y, markNum)	x and y are double
		pprMarkL(pArea, x, y, markNum)	x and y are long

RETURNS
	void

BUGS
o	only linear calibration is handled

SEE ALSO
	pprLine, pprLineSeg, pprPoint, pprText

SYNOPSIS

void
pprMarkD(pArea, x, y, markNum)
PPR_AREA *pArea;	/* I pointer to plot area structure */
double	x;		/* I x data coordinate */
double	y;		/* I y data coordinate */
int	markNum;	/* I mark number--0 to PPR_NMARKS-1, inclusive */

NAME	pprMoveD - move the pen, possibly drawing a line

DESCRIPTION
	Move the "pen" to the specified point.  If the "pen" is "down"
	a line will be drawn.  The line attributes of the plot area are
	used in drawing the line.  If the attributes indicate a dashed
	line, the current dashed line pattern will be used.

	The "clipping" attribute for the plot area is honored only by
	pprMoveD; pprMoveD_ac and pprMoveD_wc never clip lines at the
	data area edges.

	Two alternate entry points are available for drawing plain lines,
	ignoring all attributes except color.  One uses the color for the
	plot area (pprMoveD_ac); the other uses the plot window color
	(pprMoveD_wc).

		pprMoveD_ac(pArea, x, y, pen)	x and y are double
		pprMoveD_wc(pArea, x, y, pen)	x and y are double

RETURNS
	void

BUGS
o	only linear calibration is handled

SEE ALSO
	pprLine, pprLineSeg, pprText

SYNOPSIS

void
pprMoveD(pArea, x, y, pen)
PPR_AREA *pArea;	/* IO pointer to plot area structure */
double	x;		/* I x data coordinate of new point */
double	y;		/* I y data coordinate of new point */
int	pen;		/* I pen indicator--non-zero draws a line */

NAME	pprPerim - draw a perimeter

DESCRIPTION
	Draw a perimeter with tick marks.  The number of intervals
	specified in the plot area structure is used for placing
	the tick marks.

	The color attributes for the plot window are used for drawing;
	dashed line and line thickness are ignored.

RETURNS
	void

BUGS
o	only linear axes are handled

SEE ALSO
	pprPerimLabel, pprPerimErase, pprGrid, pprAnnotX, pprAnnotY, pprAreaOpen

SYNOPSIS

void
pprPerim(pArea)
PPR_AREA *pArea;	/* IO pointer to plotter area */

NAME	pprPerimErase - erase within a perimeter

DESCRIPTION
	Erases the screen inside the perimeter for the plot area.  (Actually,
	the perimeter and tick marks are erased as well, since plot marks
	may have been drawn on (and thus lie partly outside of) the perimeter
	itself.  The perimeter and tick marks are then redrawn.)

RETURNS
	void

SEE ALSO
	pprGridErase, pprAreaErase, pprWinErase

SYNOPSIS

void
pprPerimErase(pArea)
PPR_AREA *pArea;	/* IO pointer to plotter area */

NAME	pprPerimLabel - draw and label a perimeter

DESCRIPTION
	Draw a perimeter with tick marks.  The number of intervals
	specified in the plot area structure is used for placing
	the tick marks.

	Axis labels and annotations are drawn using the information from
	the plot area, as specified in the pprAreaOpen call.

RETURNS
	void

BUGS
o	only linear axes are handled

SEE ALSO
	pprPerim, pprGrid, pprAnnotX, pprAnnotY, pprAreaOpen

SYNOPSIS

void
pprPerimLabel(pArea, xLabel, xAnnot, yLabel, yAnnot, angle)
PPR_AREA *pArea;	/* IO pointer to plotter area */
char	*xLabel;	/* I label for x axis, or NULL */
char	**xAnnot;	/* I pointer to array of x annotations, or NULL */
char	*yLabel;	/* I label for y axis, or NULL */
char	**yAnnot;	/* I pointer to array of y annotations, or NULL */
double	angle;		/* I angle for y annotations; 0. or 90. */

NAME	pprPoint - plot a point at a coordinate

DESCRIPTION
	Plot a pixel sized point using the line thickness and color
	attributes of the plot area.

	Two entry points are available:

		pprPointD(pArea, x, y)	x and y are double
		pprPointL(pArea, x, y)	x and y are long

RETURNS
	void

BUGS
o	only linear calibration is handled

SEE ALSO
	pprMark, pprAreaOpen, pprAreaSetAttr, pprLine, pprMove, pprText

SYNOPSIS

void
pprPointD(pArea, x, y)
PPR_AREA *pArea;	/* IO pointer to plot area structure */
double	x;		/* I x data coordinate */
double	y;		/* I y data coordinate */

NAME	pprSin_deg - get the sine of an angle in degrees

DESCRIPTION
	Get the sine of an angle in degrees.  A table lookup technique
	is used.  The angle argument is truncated to the next lower 1/4
	degree prior to lookup.

RETURNS
	sine

SYNOPSIS

double
pprSin_deg(angle)
double	angle;		/* I angle, in degrees */

NAME	pprText - plot a text string

DESCRIPTION
	Plots a text string at a location.  The character "half height" is
	placed at the specified x,y position; the 'justification' option
	selects whether the left end, center, or right end of the text is
	placed at the x,y coordinate.

	The character height specification is in terms of a fraction of the
	height of the window.  This results in automatic scaling of
	character sizes as the window size changes.  If a height of zero
	is specified in the call, then the default height for the plot
	area is used.  (The default height was established by pprAreaOpen.)

	A macro is available which returns the default character height
	used by this plot package.  The value returned is proportional to
	the height of the plot area.  This value can be used to generate
	"big" and "small" character sizes with simple multiplication of
	the default height by a "scale factor".

		PprDfltCharHt(lowYfrac, highYfrac)

		lowYfrac is the vertical fraction of the window at which
			the bottom edge of the plot area lies
		highYfrac is the vertical fraction of the window at which
			the top edge of the plot area lies

	It is also often useful to know what horizontal fraction of the
	window width corresponds to a vertical fraction of the height.  The
	following routine returns the horizontal fraction:

		pprYFracToXFrac(pWin, yFrac)

	An alternate entry point, pprText_wc, is available to use the
	plot window's color for drawing the text.

RETURNS
	void

BUGS
o	technique used works only with linear axes
o	ASCII character codes are assumed
o	no checks are made for illegal characters
o	positioning and sizing are somewhat different for the various
	window types

SEE ALSO
	pprChar, pprAreaOpen, pprLine, pprPoint, pprCvtDblToTxt

SYNOPSIS

void
pprText(pArea, x, y, text, just, height, angle)
PPR_AREA *pArea;	/* IO pointer to plot area structure */
double	x;		/* I x data coordinate of text */
double	y;		/* I y data coordinate of text */
char	*text;		/* I text to plot */
PPR_TXT_JUST just;	/* I text justification selector: one of
				PPR_TXT_CEN, PPR_TXT_RJ, or PPR_TXT_LJ */
double	height;		/* I height of text characters, as a fraction of
				the height of the window; a value of
				zero results in using a default height */
double	angle;		/* I orientation angle of text string, ccw degrees */

NAME	pprWinClose - close a plot window

DESCRIPTION
	Free the memory associated with a plot window structure and do other
	cleanup activities.

	This routine should be called when plotting is complete for a plot
	window.  Any plot areas not previously closed are automatically
	closed by this routine.

	No further references to the plot window may be made.

RETURNS
	void

SEE ALSO
	pprAreaClose, pprWinInfo, pprWinOpen

SYNOPSIS

void
pprWinClose(pWin)
PPR_WIN	*pWin;	/* IO pointer to plot window structure */

NAME	pprWinErase - erase a plot window

DESCRIPTION
	Erase the contents of the entire plot window.

RETURNS
	void

SEE ALSO
	pprGridErase, pprPerimErase, pprAreaErase

SYNOPSIS

void
pprWinErase(pWin)
PPR_WIN	*pWin;	/* IO pointer to plot window structure */

NAME	pprWinInfo - get some information about the plot window

DESCRIPTION
	Get the size of the plot window and its position on the screen.

RETURNS
	void

NOTES
1.	The information returned is window system dependent.  To avoid
	portability problems, this information should be used only in
	calls to pprWinXxx routines.

SYNOPSIS

void
pprWinInfo(pWin, pXpos, pYpos, pXwid, pYht)
PPR_WIN	*pWin;	/* I pointer to plot window structure */
int	*pXpos; /* O pointer to place to store window x coord., in pixels */
int	*pYpos; /* O pointer to place to store window y coord., in pixels */
int	*pXwid;	/* O pointer to place to store window width, in pixels */
int	*pYht;	/* O pointer to place to store window height, in pixels */

NAME	pprWinIsMono - test to see if plot window is monochrome

DESCRIPTION

RETURNS
	1	if plot window is monochrome or gray scale
	0	if plot window is color

SYNOPSIS

int
pprWinIsMono(pWin)
PPR_WIN	*pWin;		/* I pointer to plot window structure */

NAME	pprWinLoop - loop until "quit" event received in window

DESCRIPTION
	Handles the interactions with the windowing system.  The specific
	actions depend on the plot window type:

	PPR_WIN_SCREEN
	o   creates a window on the screen
	o   when the window actually appears, calls the caller's draw function
	o   for all subsequent resize and expose events, calls the caller's
	    draw function
	o   when the right mouse button is clicked, closes the window and
	    returns to the caller.  The current position and size of the
	    window are stored (and can be retrieved with pprWinInfo).

	PPR_WIN_POSTSCRIPT
	o   calls the caller's draw function

	PPR_WIN_EPS
	o   calls the caller's draw function

	The idea when using pprWinLoop is that a program
	will do some preliminary setup for the data to be plotted.
	Then the program must turn control over to the plot "window
	manager" using pprWinLoop, which will call the caller's
	actual plot routine.

	When pprWinLoop exits back to the calling program, that program
	can call pprWinInfo in order to "remember" the plot window
	size and position.

RETURNS
	0, or
	-1 if an error is encountered

BUGS
o	doesn't furnish information to the draw function which would allow
	a partial redraw
o	terminology is confusing and inconsistent: "draw" function, redraw,
	replot, repaint, etc.

SEE ALSO
	pprWinOpen, pprWinInfo

NOTES
1.	Even though there aren't any "events" associated with plotting on
	a PostScript printer, this routine must be called even when using
	PPR_WIN_POSTSCRIPT and PPR_WIN_EPS, since this routine invokes the
	caller's "draw" function.

EXAMPLE
	See pprWinOpen for an example of a replot function.
j

SYNOPSIS

long
pprWinLoop(pWin, drawFun, pDrawArg)
PPR_WIN	*pWin;	/* IO pointer to plot window structure */
void	(*drawFun)();/* I pointer to function to draw the plot */
void	*pDrawArg;/* I pointer to pass to drawFun */

NAME	pprWinOpen - initialize a plotting "window" structure

DESCRIPTION
	Initialize a plot window structure.  This is the structure which
	keeps track of the information needed to interact with the
	device on which the "window" resides.  The possible types of
	windows are:

	o   PPR_WIN_SCREEN  selects a window on a visual display.  This
	    will be a SunView or X window, depending on the version of
	    the plotting used in linking the program.  The pprWinOpen
	    call actually creates a window, with the root window as the
	    parent.  The window thus created can be moved, resized, etc.
	    according to the capabilities of the window manager of the
	    windowing system being used.  (To initialize a plotting
	    window structure in a window which already exists, use
	    pprWinOpenUW.)

	    for SunView,
		`winDispName' is ignored and should be NULL
		`winTitle' appears on the window's title bar and icon
		`xPos' and `yPos' are pixel offsets from the upper left
			corner of the root window.  If values of 0 are
			supplied, then the window will be positioned at
			100,100.
		`xWid' and `yHt' are the width and height of the window,
			in pixels.  If values of 0 are supplied, then
			a size of 512,512 will be used.

	    for X,
	    	`winDispName' specifies the X display name on which the
			plot window is to appear.  If NULL, then the
			DISPLAY environment variable will be used.
		`winTitle' appears on the window's title bar and icon
		`xPos' and `yPos' are pixel offsets from the upper left
			corner of the root window.  If values of 0 are
			supplied, then the window will be positioned at
			100,100.
		`xWid' and `yHt' are the width and height of the window,
			in pixels.  If values of 0 are supplied, then
			a size of 512,512 will be used.

	o   PPR_WIN_POSTSCRIPT  selects a "window" on a PostScript
	    printer.

		`winDispName' is the name of a file to receive PostScript
			output.  This is the file which will eventually
			be sent to a PostScript printer to get a hard
			copy of the plot.  If the file exists when
			pprWinOpen is called, its contents are erased
			before writing begins.
		`winTitle' is ignored and should be NULL
		`xPos' and `yPos' are ignored
		`xWid' and `yHt' are the width and height of the window,
			in pixels.  If values of 0 are supplied, then
			a size of 512,512 will be used.  If the size is
			larger than the page, then the plot will be scaled
			to fit.  If necessary, the plot will be printed in
			landscape mode, rather than the default of portrait
			mode.

	o   PPR_WIN_EPS  selects a "window" in an Encapsulated PostScript
	    file.  EPS files are intended to be included into documents
	    prepared by word processing programs such as Interleaf and
	    TeX.  EPS files will not print directly on a PostScript printer.
	    The description of the arguments for PPR_WIN_POSTSCRIPT applies,
	    except that scaling and rotation aren't done.

	The pprXxx routines can be used for several different styles of
	usage:

	o   a complete set of data is available prior to calling any of
	    the plotting routines.  In this case, grids can be drawn and
	    data can be plotted at the same time.

	    For this style of usage, the typical usage will be:
		pprWinOpen		to "open" a plot window
		pprWinLoop		to map the plot window to the screen
					and call the caller's replot function
					when the window is exposed, resized,
					etc.
		pprWinClose		to "close" a plot window

	o   no data (or only part of the data) is available prior to calling
	    any of the plotting routines.  In this case, at least some of
	    the data must be plotted at a later time than when the grids
	    are drawn.  The pprXxx routines don't automatically support
	    this style of usage fully, but they do provide some tools which
	    make it relatively easy to implement.  See pprWinOpenUW for
	    more details.

	Under all circumstances, the calling program is expected to call
	pprWinClose when plotting is complete for the plot window.

RETURNS
	pointer to window structure, or
	NULL if an error is encountered

SEE ALSO
	pprWinOpenUW, pprWinClose, pprWinInfo, pprWinLoop

EXAMPLES
1.	Plot an existing set of data, where the data is stored in `dataStruct'.

	PPR_WIN	*pWindow;
	  .
	pWindow = pprWinOpen(PPR_WIN_SCREEN, NULL, "test", 0, 0, 0, 0);
	if (pWindow == NULL)
	    abort();
	if (pprWinLoop(pWindow, replot, &dataStruct) != 0)
	    abort();
	pprWinClose(pWindow);

SYNOPSIS

PPR_WIN *
pprWinOpen(winType, winDispName, winTitle, xPos, yPos, xWid, yHt)
PPR_WIN_TY winType;	/* I type of plot window: PPR_WIN_xxx */
char	*winDispName;	/* I name of "display" or file for window */
char	*winTitle;	/* I title for window title bar and icon */
int	xPos;		/* I x position for window; 0 for default */
int	yPos;		/* I y position for window; 0 for default */
int	xWid;		/* I width of window; 0 for default */
int	yHt;		/* I height of window; 0 for default */

NAME	pprWinOpenUW - open a plot "window" to an existing User Window

DESCRIPTION
	Initialize a plot window structure.  This is the structure which
	keeps track of the information needed to interact with the
	device on which the "window" resides.

	This routine is for use when the caller already has a window in
	the windowing system.  It is for use exclusively for PPR_WIN_SCREEN
	plot window type.  The form of the call to this routine is heavily
	dependent on the windowing system being used.  This routine provides
	the basis for obtaining `asynchronous' plotting.  (It can also be
	used for `batched' plotting, in which all data is available prior
	to the first plotting call.)

	Under all circumstances, the calling program is expected to call
	pprWinClose when plotting is complete for the plot window.

RETURNS
	pointer to window structure, or
	NULL if an error is encountered

SEE ALSO
	pprWinOpenUW, pprWinClose, pprWinInfo, pprWinLoop

EXAMPLES
1.	for X

	PPR_WIN *pWin;
	Display *pDisp;
	Window	plotWindow;
	GC	plotGC;

	pWin = pprWinOpenUW(&pDisp, &plotWindow, &plotGC, NULL);
	...
	pprWinReplot(pWin, drawFn, drawArg);
	...
	pprWinClose(pWin);


2.	for SunView

	PPR_WIN	*pWin;
	Frame	plotFrame;
	Canvas	plotCanvas;

	pWin = pprWinOpenUW(&plotFrame, &plotCanvas, NULL, NULL);
	...
	pprWinReplot(pWin, drawFn, drawArg);
	...
	pprWinClose(pWin);

3.	for XView

	PPR_WIN	*pWin;
	Display	*pDisp;
	Window	plotWindow;
	GC	plotGC;

	pDisp = (Display *)xv_get(frame, XV_DISPLAY);
	window = (Window)xv_get(canvas_paint_window(canvas), XV_XID);
	plotGC = DefaultGC(pDisp, DefaultScreen(pDisp));

	pWin = pprWinOpenUW(&pDisp, &plotWindow, &plotGC, NULL);
	...
	pprWinReplot(pWin, drawFn, drawArg);
	...
	pprWinClose(pWin);

SYNOPSIS

PPR_WIN *
pprWinOpenUW(pArg1, pArg2, pArg3, pArg4)
void	*pArg1;
void	*pArg2;
void	*pArg3;
void	*pArg4;

NAME	pprWinReplot - redraw a plot in a user owned window

DESCRIPTION
	Calls the "replot" function to repaint the plot window.  This
	routine is intended to be used with "user owned" plot windows
	which have been opened with pprWinOpenUW.

	Prior to calling the replot function, this routine determines
	the size of the actual window and rescales the existing plot
	areas.

RETURNS
	void

SEE ALSO
	pprWinOpenUW

SYNOPSIS

void
pprWinReplot(pWin, pFunc, pArg)
PPR_WIN	*pWin;
void	(*pFunc)();
void	*pArg;

NAME	pprYFracToXFrac - convert a Y fraction to an X fraction

DESCRIPTION
	Converts a value which is a fraction of window height into a value
	which is a fraction of window width, so that the two values will
	represent the same physical size, in pixels.

	This routine is useful for laying out a plot area, especially when
	a grid with annotations and labels is to be used.  The choice of
	"data area" size (i.e., the size of the grid) depends on the size
	of the characters which will be used for the annotations and
	labels.

RETURNS
	void

SEE ALSO
	pprText

EXAMPLE
	A plot area is use the full width and the vertical 1/3 of the window.
	x values range from 0 to 100, while y is from -10 to 10.  The x
	axis is to be divided into 10 divisions, the y into 4.  Use
	the default character size for annotations and labels.  Also,
	use the default window position and size.

	PPR_WIN	*pWin;
	PPR_AREA *pArea;
	float	charHt;		height as a fraction of window height
	float	charWid;	width as a fraction of window width

	charHt = PprDfltCharHt(.33, .67);
	charWid = pprYFracToXFrac(pWin, charHt);
	pArea = pprAreaOpen(pWin, 12.*charWid, .33+6.*charHt, 1., .67,
			0., -10., 100., 10, 4, charHt);

SYNOPSIS

double
pprYFracToXFrac(pWin, yFrac)
PPR_WIN	*pWin;	/* I pointer to plot window structure */
double	yFrac;	/* I fraction of window height */
