diff glib/ps.c @ 0:5242703e91d3 tip

Initial checkin for AIM92 aimR8.2 (last updated May 1997).
author tomwalters
date Fri, 20 May 2011 15:19:45 +0100
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/glib/ps.c	Fri May 20 15:19:45 2011 +0100
@@ -0,0 +1,810 @@
+/*
+  Copyright (c) Applied Psychology Unit, Medical Research Council. 1988, 1989
+  ===========================================================================
+  Permission to use, copy, modify, and distribute this software without fee 
+  is hereby granted for research purposes, provided that this copyright 
+  notice appears in all copies and in all supporting documentation, and that 
+  the software is not redistributed for any fee (except for a nominal shipping 
+  charge). Anyone wanting to incorporate all or part of this software in a
+  commercial product must obtain a license from the Medical Research Council.
+  The MRC makes no representations about the suitability of this 
+  software for any purpose.  It is provided "as is" without express or implied 
+  warranty.
+
+  THE MRC DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 
+  ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE
+  A.P.U. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY 
+  DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 
+  AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 
+  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+
+/*
+  ps.c
+  ====
+  primitive PostScript interface ala windows.h interface.
+  Copyright (c), 1989  The Medical Research Council, Applied Psychology Unit.
+  Author  : John Holdsworth   22nd March, 1989.
+            Michael Akeroyd   Summer 1994.
+
+  Edited  : Roy P 27-11-92: commented out two if statements with this->hidden
+            in them to force hiddenline.
+            Also added '(void)' at start of line after second of the lines
+	    commented out to make it symmetric with similar lines.
+
+          : MAA. Summer 1994. rebuild. Notes:
+          (1) don't print windows bigger than 800 pixels wide; they aren't scaled 
+              properly. 
+          (2) all windows get drawn in the centre of the page.
+          (3) because of the 'fill's in drawing the data, the tick-marks can
+              get blanked out. To avoid this, the whole frame+marks are drawn
+              twice, at the begining (to get the coorect clipppath) and at the 
+              end
+          : MAA. Autumn 1994. rebuilt to avoid note (3).
+
+*/
+
+
+#include <stdio.h>
+#if defined(THINK_C) || defined(NeXT)
+#include <stdlib.h>
+#else
+#include <malloc.h>
+#endif
+#include "windows.h"
+#include "grey.h"
+#include "options.h"   /* MAA: 23-4-1994: required for isON() */
+#include "string.h"    /* MAA: Summer 1994: required for atof() */
+#ifndef NeXT
+/* extern int fprintf() ;       */      /* mha 8/4/97:  sgi stops here */
+#endif
+
+static char *sccs_id = "@(#)ps.c	1.31     J. Holdsworth (MRC-APU)  7/7/93  Revised MAA 1994" ;
+
+
+/* resolution parameters for line width */
+#define POINTS_PER_INCH 72     /* standard definition of "points" */
+#define PIXELS_PER_INCH 300    /* laserwriterII */
+#define PIXELS_PER_POINT ( ( double ) PIXELS_PER_INCH / POINTS_PER_INCH )
+
+
+/* limitation on graphics path lengths */
+#define MAX_PATH 350 
+
+
+typedef struct {
+ windowEntries *entries ; /* pointers to method routines below */
+ char *xptr ;             /* general pointer to postscript device */
+ int (*sender)(), (*closer)() ;       /* function to transmit postscript */
+ int (*storer)(), (*recaller)(), (*reader)(), (*writer)(), (*pauser)() ; /* functions which may be used */
+ int x, y, width, height, pixels, hidden, page ; /* window paramaters */
+ enum { False, True } drawn, showpage ; /* if drawn and if clear not used and
+			                 window can be included in document */
+ struct _lookup *lookup ; /* state structure for dithering routines in grey.c*/
+ } *psWindowObject ;
+ 
+static windowsClass psClass ;
+
+
+
+/* MAA: lots of new options */
+extern *rotateaxesstr;
+extern char *xstartstr, *ystartstr, *xendstr, *yendstr;
+extern char *xnewtitlestr, *ynewtitlestr;
+extern char *portraitstr, *landscapestr;
+extern char *fontnamestr, *fontsizestr, *titlesizestr;
+extern char *xticksstr, *yticksstr, *outsidestr;
+extern char *axistopstr, *axisbottomstr, *axisleftstr, *axisrightstr;
+extern char *xmajorticksstr, *xminorticksstr;
+extern char *ymajorticksstr, *yminorticksstr;
+extern char *axislinewidthstr, *figurelinewidthstr; 
+extern char *boxstr;
+static double temp_xmin;
+static double temp_xmax;
+static double temp_ymin;
+static double temp_ymax;
+
+
+/*-----------------------------------------------------------------------*/
+
+
+WindowObject newPostScriptWindow( xptr, default_x, default_y, default_width, default_height, pixels, sender, closer, storer, recaller, reader, writer, pauser, pshidden )
+     char *xptr ;
+     int default_x, default_y, default_width, default_height, pixels ;
+     int (*sender)(), (*closer)() ;
+     int (*storer)(), (*recaller)(), (*reader)(), (*writer)(), (*pauser)() ;
+     int pshidden;            /* =0 if off, =1 if on */
+{
+  psWindowObject this = ( psWindowObject ) malloc( sizeof ( *this ) ) ;
+  char psfontstr[30];
+  char **ptr ;
+
+  if( psClass.super == (windowsClass *) 0 )
+    (void) initPostScriptClass( &psClass ) ;
+  this->entries = &psClass.entries ;
+  this->xptr     = xptr ;
+  this->sender   = sender ;
+  this->storer   = storer ;
+  this->recaller = recaller ;
+  this->reader   = reader ;
+  this->writer   = writer ;
+  this->pauser   = pauser ;
+  this->closer   = closer ;
+  this->x       = default_x ;
+  this->y       = default_y ;
+  this->width   = default_width ;
+  this->height  = default_height ;
+  this->hidden  = pshidden ;
+  this->pixels  = abs( pixels ) ;
+  this->lookup  = 0 ;
+  this->drawn   = False ;
+
+  (void) this->sender( this->xptr, "%%!PS-Adobe-2.0 EPSF-1.2\n");
+  (void) this->sender( this->xptr, "%%%%Title: Windows postscript file\n");
+  (void) this->sender( this->xptr, "%%%%Creator: %s\n", sccs_id);
+  (void) this->sender( this->xptr, "%%%%BoundingBox: %d %d %d %d\n", this->x, this->y, this->x+this->width, this->y+this->height);
+  (void) this->sender( this->xptr, "%%%%Pages: (atend)\n", this->y);
+/*  (void) this->sender( this->xptr, "%%%%DocumentFonts: Times-Roman\n");*/
+  (void) this->sender( this->xptr, "%%%%EndComments\n") ;
+  
+  if ( this->hidden == 0 ) {
+    (void) this->sender( this->xptr, "\n%%/fill workaround: no hidden lines. MAA. 22-1-1993\n" );
+    (void) this->sender( this->xptr, "/fill {} def\n\n" );}
+  else ;
+
+  /* Fonts. The only allowed ones are Times-Roman, Helvetica and Courier,
+   * because they are the only three you get in the Adobe Red Book, and
+   * so are presumably the onyl three you get in all printers.*/
+  if      (!strcmp(fontnamestr, "Times")) {strcpy(psfontstr, "Times-Roman");}
+  else if (!strcmp(fontnamestr, "times")) {strcpy(psfontstr, "Times-Roman");}
+  else if (!strcmp(fontnamestr, "Roman")) {strcpy(psfontstr, "Times-Roman");}
+  else if (!strcmp(fontnamestr, "roman")) {strcpy(psfontstr, "Times-Roman");}
+  else if (!strcmp(fontnamestr, "times-roman")) {strcpy(psfontstr, "Times-Roman");}
+  else if (!strcmp(fontnamestr, "Times-Roman")) {strcpy(psfontstr, "Times-Roman");}
+  else if (!strcmp(fontnamestr, "timesroman")) {strcpy(psfontstr, "Times-Roman");}
+  else if (!strcmp(fontnamestr, "RimesRoman")) {strcpy(psfontstr, "Times-Roman");}
+  else if (!strcmp(fontnamestr, "TimesBold")) {strcpy(psfontstr, "Times-Bold");}
+  else if (!strcmp(fontnamestr, "timesbold")) {strcpy(psfontstr, "Times-Bold");}
+  else if (!strcmp(fontnamestr, "timesbold")) {strcpy(psfontstr, "Times-Bold");}
+  else if (!strcmp(fontnamestr, "times-bold")) {strcpy(psfontstr, "Times-Bold");}
+  else if (!strcmp(fontnamestr, "Times-Bold")) {strcpy(psfontstr, "Times-Bold");}
+						
+  else if (!strcmp(fontnamestr, "Helvetica")) {strcpy(psfontstr, "Helvetica");}
+  else if (!strcmp(fontnamestr, "helvetica")) {strcpy(psfontstr, "Helvetica");}
+  else if (!strcmp(fontnamestr, "Hel")) {strcpy(psfontstr, "Helvetica");}
+  else if (!strcmp(fontnamestr, "hel")) {strcpy(psfontstr, "Helvetica");}
+  else if (!strcmp(fontnamestr, "HelveticaBold")) {strcpy(psfontstr, "Helvetica-Bold");}
+  else if (!strcmp(fontnamestr, "Helveticabold")) {strcpy(psfontstr, "Helvetica-Bold");}
+  else if (!strcmp(fontnamestr, "helveticabold")) {strcpy(psfontstr, "Helvetica-Bold");}
+  else if (!strcmp(fontnamestr, "Helvetica-Bold")) {strcpy(psfontstr, "Helvetica-Bold");}
+  else if (!strcmp(fontnamestr, "helvetica-bold")) {strcpy(psfontstr, "Helvetica-Bold");}
+  else if (!strcmp(fontnamestr, "helbold")) {strcpy(psfontstr, "Helvetica-Bold");}
+  else if (!strcmp(fontnamestr, "HelBold")) {strcpy(psfontstr, "Helvetica-Bold");}
+
+  else if (!strcmp(fontnamestr, "Courier")) {strcpy(psfontstr, "Courier");}
+  else if (!strcmp(fontnamestr, "courier")) {strcpy(psfontstr, "Courier");}
+  else if (!strcmp(fontnamestr, "Cou")) {strcpy(psfontstr, "Courier");}
+  else if (!strcmp(fontnamestr, "cou")) {strcpy(psfontstr, "Courier");}
+  else if (!strcmp(fontnamestr, "Courier-Bold")) {strcpy(psfontstr, "Courier-Bold");}
+  else if (!strcmp(fontnamestr, "courier-bold")) {strcpy(psfontstr, "Courier-Bold");}
+  else if (!strcmp(fontnamestr, "courierbold")) {strcpy(psfontstr, "Courier-Bold");}
+  else if (!strcmp(fontnamestr, "CourierBold")) {strcpy(psfontstr, "Courier-Bold");}
+  else if (!strcmp(fontnamestr, "CouBold")) {strcpy(psfontstr, "Courier-Bold");}
+  else if (!strcmp(fontnamestr, "coubold")) {strcpy(psfontstr, "Courier-Bold");}
+  
+  else {
+    fprintf(stderr, "WARNING: Unknown font %s. (allowed time, helvetica or courier.)\n", fontnamestr);
+    fprintf(stderr, "WARNING: Stopping here; no Postscript generated\n");
+    exit(-1);}
+
+
+  /* copy postscript code for axes into output file */
+  (void) this->sender( this->xptr, "%%! simple postscript axes\n");
+  (void) this->sender( this->xptr, "%% v1.10 John Holdsworth (5/31/91).\n");
+  (void) this->sender( this->xptr, "%% Revised M Akeroyd (Summer, Autumn 1994)\n");
+  (void) this->sender( this->xptr, "\n");
+  (void) this->sender( this->xptr, "  /midprint { %% str x y midprint -\n");
+  (void) this->sender( this->xptr, "    moveto\n");
+  (void) this->sender( this->xptr, "    dup\n");
+  (void) this->sender( this->xptr, "    stringwidth pop 2 div neg 0 rmoveto\n");
+  (void) this->sender( this->xptr, "    show\n");
+  (void) this->sender( this->xptr, "  } def\n");
+  (void) this->sender( this->xptr, "\n");
+  (void) this->sender( this->xptr, "  /leftprint { %% str x y leftprint -\n");
+  (void) this->sender( this->xptr, "    moveto\n");
+  (void) this->sender( this->xptr, "    dup\n");   
+  (void) this->sender( this->xptr, "    stringwidth pop neg fontsize 0.4 mul neg rmoveto\n");
+  (void) this->sender( this->xptr, "    show\n");  
+  (void) this->sender( this->xptr, "  } def\n");
+  (void) this->sender( this->xptr, "\n");
+  (void) this->sender( this->xptr, "  /ticks { %% min max <float> <float> ticker -\n");
+  (void) this->sender( this->xptr, "    /ticker  exch def %% procedure to draw ticks\n");
+  (void) this->sender( this->xptr, "    /fmax exch cvr def %% relative spacing of max ticks (0.5x, etc)\n");
+  (void) this->sender( this->xptr, "    /fmin exch cvr def %% relative spacing of min ticks (0.5x, etc)\n");
+  (void) this->sender( this->xptr, "    /max exch cvr def %% axis maximum\n");
+  (void) this->sender( this->xptr, "    /min exch cvr def %% axis minimum\n");
+  (void) this->sender( this->xptr, "    /maxsubticks 50 def\n");
+  (void) this->sender( this->xptr, "    max min ne {\n");
+  (void) this->sender( this->xptr, "	%% calculate order of magnitude\n");
+  (void) this->sender( this->xptr, "	/delta max min sub log ceiling 1 sub 10 exch exp def\n");
+  (void) this->sender( this->xptr, "	%% do ticks\n");
+  (void) this->sender( this->xptr, "	min delta div ceiling delta mul\n");
+  (void) this->sender( this->xptr, "	delta fmax mul\n");
+  (void) this->sender( this->xptr, "	max delta div floor   delta mul\n");
+  (void) this->sender( this->xptr, "	{\n");
+  (void) this->sender( this->xptr, "		min sub max min sub div 1.333333 exch ticker\n");
+  (void) this->sender( this->xptr, "	}\n");
+  (void) this->sender( this->xptr, "	for\n");
+  (void) this->sender( this->xptr, "	%% do sub ticks (but only if fmin != 0)\n");
+  (void) this->sender( this->xptr, "	fmin 0 ne {");
+  (void) this->sender( this->xptr, "      max min sub delta div dup\n");
+  (void) this->sender( this->xptr, "	  10 mul maxsubticks lt {.1} {5 mul maxsubticks lt {.2} {.5} ifelse } ifelse\n");
+  (void) this->sender( this->xptr, "	  delta mul /delta exch def\n");
+  (void) this->sender( this->xptr, "	  min delta div ceiling delta mul\n");
+  (void) this->sender( this->xptr, "	  delta fmin mul \n");
+  (void) this->sender( this->xptr, "	  max delta div floor   delta mul\n");
+  (void) this->sender( this->xptr, "	  {\n");
+  /* MAA: This used to be 0.25; I've changed it (0.25 * 1.33), so its in real points.*/
+  (void) this->sender( this->xptr, "		  min sub max min sub div 0.666666 exch ticker\n");
+  (void) this->sender( this->xptr, "	  }\n");
+  (void) this->sender( this->xptr, "	  for\n");
+  (void) this->sender( this->xptr, "      } if\n");
+  (void) this->sender( this->xptr, "    } if\n");
+  (void) this->sender( this->xptr, "  } def\n");
+  (void) this->sender( this->xptr, "\n");
+  (void) this->sender( this->xptr, "/Axes { %% title xmin xmax xtitle ymin ymax ytitle Axes -\n");
+  (void) this->sender( this->xptr, "/AxesDict 50 dict def\n");
+  (void) this->sender( this->xptr, "AxesDict begin\n");
+  (void) this->sender( this->xptr, "  /ytitle exch def\n");
+  (void) this->sender( this->xptr, "  /ymax   exch def\n");
+  (void) this->sender( this->xptr, "  /ymin   exch def\n");
+  (void) this->sender( this->xptr, "  /xtitle exch def\n");
+  (void) this->sender( this->xptr, "  /xmax   exch def\n");
+  (void) this->sender( this->xptr, "  /xmin   exch def\n");
+  (void) this->sender( this->xptr, "  /title  exch def\n");
+  (void) this->sender( this->xptr, "  newpath clippath pathbbox /height exch def\n");
+  (void) this->sender( this->xptr, "			    /width  exch def\n");
+  (void) this->sender( this->xptr, "			    pop pop\n");
+  (void) this->sender( this->xptr, "  /tagsize  0.05 height mul neg def\n");
+  if (isOFF(xticksstr))
+    (void) this->sender( this->xptr, "  /xtagsize tagsize 1.33 mul def\n");
+  else
+    (void) this->sender( this->xptr, "  /xtagsize %s neg 1.33 mul def\n", xticksstr);
+  if (isOFF(yticksstr))
+    (void) this->sender( this->xptr, "  /ytagsize tagsize 1.33 mul def\n");
+  else
+    (void) this->sender( this->xptr, "  /ytagsize %s neg 1.33 mul def\n", yticksstr);
+  if (isOFF(fontsizestr))
+    (void) this->sender( this->xptr, "  /fontsize 0.05 height mul def\n");
+  else {
+    /* note 1.333 multiplier: required to get rid of the 0.75 later on */
+    (void) this->sender( this->xptr, "  /fontsize %s 1.333 mul def\n", fontsizestr);}
+  (void) this->sender( this->xptr, "  /space    0.10 height mul def\n");
+  (void) this->sender( this->xptr, "  /%s findfont fontsize scalefont setfont\n", psfontstr);
+  /* MAA: What do these 0.75/0.75 do? Quite a lot: they seem to be a screen -> paper multiplu constant*/
+  (void) this->sender( this->xptr, "  width 0.20 mul  0.15 height mul  translate  0.75 0.75 scale\n");
+  (void) this->sender( this->xptr, "  gsave\n");
+  (void) this->sender( this->xptr, "  gsave\n");
+  (void) this->sender( this->xptr, "  %s setlinewidth\n", axislinewidthstr);
+  /* MAA: I do  not knwo why this (2,2) translation is here, but it seems to get in the way */
+  /*  (void) this->sender( this->xptr, "  currentlinewidth 2 div neg dup translate\n");*/
+  (void) this->sender( this->xptr, "  newpath\n");
+  if (isOFF(titlesizestr))
+    (void) this->sender( this->xptr, "  title  width 2 div    height  tagsize  1.75 mul sub midprint\n");
+  else {
+    (void) this->sender( this->xptr, "  gsave\n");
+    /* note 1.333 multiplier: required to get rid of the 0.75 later on */
+    (void) this->sender( this->xptr, "  /%s findfont %s 1.333 mul scalefont  setfont\n", psfontstr, titlesizestr);
+    (void) this->sender( this->xptr, "  title  width 2 div    height  tagsize  1.75 mul sub midprint\n");}
+  if (isON(axisbottomstr)){
+    (void) this->sender( this->xptr, "  xmin   0              xtagsize fontsize sub midprint\n");
+    (void) this->sender( this->xptr, "  xmax   width          xtagsize fontsize sub midprint\n");
+    (void) this->sender( this->xptr, "  xmin cvr 0 lt  \n");
+    (void) this->sender( this->xptr, "    {xmax cvr 0 ge \n");
+    (void) this->sender( this->xptr, "       {(0) width xmin cvr neg xmin cvr neg xmax cvr add div mul xtagsize 1.0 mul fontsize sub midprint \n");
+    (void) this->sender( this->xptr, "        /xtitleconstant 2.0 def} \n");
+    (void) this->sender( this->xptr, "       {/xtitleconstant 1.0 def} \n");
+    (void) this->sender( this->xptr, "       ifelse}\n");
+    (void) this->sender( this->xptr, "    {/xtitleconstant 1.0 def} \n");
+    (void) this->sender( this->xptr, "    ifelse\n");
+    (void) this->sender( this->xptr, "  xtitle width 2 div    xtagsize xtitleconstant mul fontsize sub midprint\n");
+  }
+  if (isON(axisleftstr)) {
+    (void) this->sender( this->xptr, "  ymin   ytagsize  2.0 mul  0                    leftprint\n");
+    (void) this->sender( this->xptr, "  ymax   ytagsize  2.0 mul  height               leftprint\n");
+    (void) this->sender( this->xptr, "  ymin cvr 0 lt { \n");
+    (void) this->sender( this->xptr, "    ymax cvr 0 ge {\n");
+    (void) this->sender( this->xptr, "       (0) ytagsize  2.0 mul  height ymin cvr neg ymin cvr neg ymax cvr add div mul leftprint} \n");
+    (void) this->sender( this->xptr, "       if}\n");
+    (void) this->sender( this->xptr, "    if\n");}
+  (void) this->sender( this->xptr, "  90 rotate\n");
+  (void) this->sender( this->xptr, "  ytitle height 2 div   space   1.75 mul             midprint\n");
+  (void) this->sender( this->xptr, "  grestore\n"); 
+  (void) this->sender( this->xptr, "  grestore\n");
+  (void) this->sender( this->xptr, "end } def\n");
+  
+  
+  
+  /* MAA: New procedure AxesBox, which draws the box ... This is actually a revised workaround
+   * for the 'borderframe' problem. */
+  (void) this->sender( this->xptr, "\n\n" ) ;  
+  (void) this->sender( this->xptr, "/AxesBox { %% xmin xmax ymin ymax AxesBox -\n");
+  (void) this->sender( this->xptr, "/AxesBoxDict 50 dict def\n");
+  (void) this->sender( this->xptr, "AxesBoxDict begin\n");
+  (void) this->sender( this->xptr, "  /ymax   exch def\n");
+  (void) this->sender( this->xptr, "  /ymin   exch def\n");
+  (void) this->sender( this->xptr, "  /xmax   exch def\n");
+  (void) this->sender( this->xptr, "  /xmin   exch def\n");
+  (void) this->sender( this->xptr, "  newpath clippath pathbbox /height exch def\n");
+  (void) this->sender( this->xptr, "			    /width  exch def\n");
+  (void) this->sender( this->xptr, "			    pop pop\n");
+  (void) this->sender( this->xptr, "  /tagsize  0.05 height mul neg def\n");
+  if (isOFF(xticksstr))
+    (void) this->sender( this->xptr, "  /xtagsize tagsize def\n");
+  else
+    (void) this->sender( this->xptr, "  /xtagsize %s neg def\n", xticksstr);
+  if (isOFF(yticksstr))
+    (void) this->sender( this->xptr, "  /ytagsize tagsize def\n");
+  else
+    (void) this->sender( this->xptr, "  /ytagsize %s neg def\n", yticksstr);
+  (void) this->sender( this->xptr, "  /space    0.10 height mul def\n");
+  (void) this->sender( this->xptr, "  width 0.20 mul  0.15 height mul  translate  0.75 0.75 scale\n");
+  (void) this->sender( this->xptr, "  gsave\n");
+  (void) this->sender( this->xptr, "  %s setlinewidth\n", axislinewidthstr);
+  (void) this->sender( this->xptr, "  newpath\n");
+  if (isON(outsidestr)){
+    (void) this->sender( this->xptr, "  /toptagsize xtagsize neg def\n");
+    (void) this->sender( this->xptr, "  /bottomtagsize xtagsize def\n");
+    (void) this->sender( this->xptr, "  /lefttagsize ytagsize def\n");
+    (void) this->sender( this->xptr, "  /righttagsize ytagsize neg def\n");}
+  else{
+    (void) this->sender( this->xptr, "  /toptagsize xtagsize def\n");
+    (void) this->sender( this->xptr, "  /bottomtagsize xtagsize neg def\n");
+    (void) this->sender( this->xptr, "  /lefttagsize ytagsize neg def\n");
+    (void) this->sender( this->xptr, "  /righttagsize ytagsize def\n");}
+  if (isON(axisbottomstr)){
+    (void) this->sender( this->xptr, "  0     bottomtagsize  moveto  0     0  lineto stroke\n");
+    (void) this->sender( this->xptr, "  width bottomtagsize  moveto  width 0  lineto stroke\n");}
+  if (isON(axistopstr)){
+    (void) this->sender( this->xptr, "  0     height moveto 0   toptagsize rmoveto  0      height lineto stroke\n");
+    (void) this->sender( this->xptr, "  width height moveto 0   toptagsize rmoveto  width  height lineto stroke\n");}
+  if (isON(axisleftstr)){
+    (void) this->sender( this->xptr, "  0     0      moveto lefttagsize  0 rmoveto  0      0      lineto stroke\n");
+    (void) this->sender( this->xptr, "  0     height moveto lefttagsize  0 rmoveto  0      height lineto stroke\n");}
+  if (isON(axisrightstr)){
+    (void) this->sender( this->xptr, "  width 0      moveto righttagsize 0 rmoveto  width  0      lineto stroke\n");
+    (void) this->sender( this->xptr, "  width height moveto righttagsize 0 rmoveto  width  height lineto stroke\n");}
+  if (isON(axisbottomstr))
+    (void) this->sender( this->xptr, "  xmin xmax %s %s {width  mul      0 moveto bottomtagsize mul 0 exch rlineto stroke} ticks\n", xminorticksstr, xmajorticksstr);
+  if (isON(axistopstr))
+    (void) this->sender( this->xptr, "  xmin xmax %s %s {width  mul height moveto toptagsize mul 0 exch rlineto stroke} ticks\n", xminorticksstr, xmajorticksstr);
+  if (isON(axisleftstr))
+    (void) this->sender( this->xptr, "  ymin ymax %s %s {height mul     0 exch moveto lefttagsize  mul 0      rlineto stroke} ticks\n", yminorticksstr, ymajorticksstr);
+  if (isON(axisrightstr))
+    (void) this->sender( this->xptr, "  ymin ymax %s %s {height mul width exch moveto righttagsize mul 0      rlineto stroke} ticks\n", yminorticksstr, ymajorticksstr);
+  (void) this->sender( this->xptr, "  grestore\n");
+  (void) this->sender( this->xptr, "  newpath 0 0 moveto width 0 lineto width height lineto 0 height lineto closepath stroke clip\n");
+  (void) this->sender( this->xptr, "end } def\n");
+  (void) this->sender( this->xptr, "\ngsave\n\n" ) ;
+
+  /* rotate for landscape mode */ 
+  if( this->width > this->height ) {
+    (void) this->sender( this->xptr, "%% shift orgin and rotate for landscape mode\n" ) ;
+    (void) this->sender( this->xptr, "newpath clippath pathbbox pop exch translate pop 90 rotate %% notstand\n" ) ; }    
+  (void) this->sender( this->xptr, "%% center image on page\n" ) ;
+  (void) this->sender( this->xptr, "newpath clippath pathbbox exch %d sub 2 div exch %d sub 2 div translate pop pop %%notstand\n", this->width, this->height ) ;
+  
+  /* set clippath - used by axis routine */
+  (void) this->sender( this->xptr, "newpath 0 0 moveto %d 0 rlineto 0 %d rlineto %d neg 0 rlineto closepath clip\n", this->width, this->height, this->width ) ;
+/*  (void) this->sender( this->xptr, "%f setlinewidth\n/l { lineto } def\n", this->pixels / PIXELS_PER_POINT ) ;*/
+  (void) this->sender( this->xptr, "%s setlinewidth\n/l { lineto } def\n", figurelinewidthstr) ;
+
+  (void) this->sender( this->xptr, "1 setlinecap\n/pt {moveto 0 0 rlineto stroke} def\n" ) ;
+  (void) this->sender( this->xptr, "106 45 { dup mul exch\n dup mul add 1.0\n exch sub } setscreen\n" ) ;
+  
+  this->page = 1 ;
+  (void) this->sender( this->xptr, "%%%%EndProlog\n%%%%Page %d %d\ngsave\n", this->page, this->page ) ;
+  this->showpage = False ;
+  return ( ( WindowObject ) this ) ;
+}
+
+
+
+/*---------------------------------------------------------------*/
+
+
+
+WindowObject newFILEWindow( fp, default_x, default_y, default_width, default_height, pixels, pshidden)
+     FILE *fp ;
+     int default_x, default_y, default_width, default_height, pixels ;
+     int pshidden;
+{
+  extern int fflush() ;
+  
+  return ( newPostScriptWindow( fp, default_x, default_y, default_width, default_height, pixels, fprintf, (int (*)())0, (int (*)())0, (int (*)())0, (int (*)())0, (int (*)())0, fflush, pshidden )) ;
+}
+
+
+
+WindowObject newPSWindow( name, default_x, default_y, default_width, default_height, pixels, pshidden )
+     char *name ;
+     int default_x, default_y, default_width, default_height, pixels ;
+     int pshidden ;
+{
+  extern int fclose() ;
+  FILE *fp = stdout ;
+  
+  if( name != ( char * ) 0 && name[0] != '\000' )
+    if( ( fp = fopen( name, "w" ) ) == ( FILE * ) 0 ) {
+      (void) fprintf( stderr, "Could not open file \"%s\" for output\n", name ) ;
+      exit( 1 ) ;}
+  
+  return ( newPostScriptWindow( fp, default_x, default_y, default_width, default_height, pixels, fprintf, fclose, (int (*)())0, (int (*)())0, (int (*)())0, (int (*)())0, (int (*)()) 0  , pshidden )  ) ;
+}
+
+
+
+static short ps__x( this )
+     psWindowObject this ;
+{
+  return( this->x ) ;
+}
+
+
+static short ps__y( this )
+     psWindowObject this ;
+{
+  return( this->y ) ;
+}
+
+
+static short ps__width( this )
+     psWindowObject this ;
+{
+  return( this->width ) ;
+}
+
+
+static short ps__height( this )
+     psWindowObject this ;
+{
+  return( this->height ) ;
+}
+
+
+static void ps__draw( this, xs, ys, points )
+     psWindowObject this ;
+     short xs[], ys[] ;
+     int points ;
+{
+  int path, point ;
+  
+  (void) this->sender( this->xptr, "newpath\n" ) ;
+  if( points > 0 )
+    for( point=1 ; point < points ; point+=path ) {
+      (void) this->sender( this->xptr, "%d %d moveto\n", xs[point-1], ys[point-1] ) ;
+      for( path=0 ; point+path < points && path < MAX_PATH ; path++ )
+	(void) this->sender( this->xptr, "%d %d l\n", xs[point+path], ys[point+path] ) ;
+      if( this->hidden && xs[point+path] == xs[point-1] &&
+	 ys[point+path] == ys[point-1] )  /*Roy 27-11-92 */
+	(void) this->sender( this->xptr, "gsave 1 setgray fill grestore\n" ) ;
+      (void) this->sender( this->xptr, "stroke\n" ) ;}
+  else {
+    (void) this->sender( this->xptr, "gsave currentlinewidth 10. mul setlinewidth\n" ) ;
+    for( point=1 ; point < abs(points) ; point++ )
+      (void) this->sender( this->xptr, "%d %d pt\n", xs[point], ys[point] ) ;
+    (void) this->sender( this->xptr, "grestore\n" ) ;}
+  
+  this->drawn = True ;
+  return ;
+}
+
+
+
+static void ps__clear( this )
+psWindowObject this ;
+{
+  if( this->drawn ) {
+    ++this->page ;
+    (void) this->sender( this->xptr, "grestore\n") ;
+    (void) this->sender( this->xptr, "%s setlinewidth\n", axislinewidthstr) ;
+    if (isON(boxstr))
+      (void) this->sender( this->xptr, "(%g)  (%g) (%g)  (%g) AxesBox\n", temp_xmin, temp_xmax, temp_ymin, temp_ymax) ;
+    (void) this->sender( this->xptr, "showpage\ngrestore\n%%%%Page: %d %d\ngsave\n", this->page, this->page ) ; }
+  (void) this->sender( this->xptr, "gsave clippath 1 setgray fill grestore\n" ) ;
+  this->showpage = True ;
+  return ;
+}
+
+
+
+static void ps__close( this )
+     psWindowObject this ;
+{
+  (void) this->sender( this->xptr, "grestore\n") ;
+  (void) this->sender( this->xptr, "%s setlinewidth\n", axislinewidthstr) ;
+  if (isON(boxstr))
+    (void) this->sender( this->xptr, "(%g)  (%g) (%g)  (%g) AxesBox\n", temp_xmin, temp_xmax, temp_ymin, temp_ymax) ;
+  if( this->showpage )  
+    (void) this->sender( this->xptr, "showpage %% notstand\n" ) ;
+  else
+    this->page = 0 ;
+  (void) this->sender( this->xptr, "grestore\n%%%%Trailer\ngrestore\n%%%%Pages: %d\n", this->page ) ;
+  if( this->closer != 0 )
+    this->closer( this ) ;
+  free( (char *) this ) ;
+  return ;
+}
+
+
+
+static int ps__store( this )
+     psWindowObject this ;
+{
+  if( this->storer != 0 )
+    return ( this->storer( this->xptr ) ) ;
+  else
+    (void) fprintf( stderr, "Invalid call to restore postscript image from memory!!" ) ;
+  return 0 ;
+}
+
+
+
+static void ps__recall( this, which )
+     psWindowObject this ;
+int which ;
+{
+  if( this->recaller != 0 )
+    this->recaller( this->xptr, which ) ;
+  else
+    (void) fprintf( stderr, "Invalid call to store postscript image in memory!!" ) ;
+  return ;
+}
+
+
+
+static char *cmap( npixels )
+     int *npixels ;
+{
+#ifdef NeXT
+  static char ps_grey_scale[] = "04bf" ;
+#else
+  static char ps_grey_scale[] = "0123456789abcdef" ;
+#endif
+  
+  *npixels = sizeof ( ps_grey_scale ) - 1 ;
+  return ( ps_grey_scale ) ;
+}
+
+
+
+static void ps__fill( this, col, input, black, white, match, length, row_flag )
+     psWindowObject this ;
+     int col ;
+     short *input;
+     int black, white ;
+     int *match, length ;
+     int row_flag ;
+{
+  int chans, chan, y, blacky ;
+  
+  if( this->lookup == 0 ) {
+    this->lookup = makeLookup( cmap, black, white, length ) ;
+    (void) this->sender( this->xptr, "/picstr %d string def\n", length ) ;}
+  if( col == 1 ) {
+    if( row_flag )
+      (void) this->sender( this->xptr, "%d %d 4\n[1 0 0 -1 0 %d]\n", this->width, this->height, this->height ) ;
+    else
+      (void) this->sender( this->xptr, "%d %d 4\n[0 1 -1 0 %d 0]\n", this->height, this->width, this->height ) ;
+        (void) this->sender( this->xptr, "{currentfile\npicstr readhexstring pop}\nimage\n" ) ;}
+  
+  (void) this->sender( this->xptr, "%s\n", Lookup( col, this->lookup, input, match, length ) ) ;
+  this->drawn = True ;
+  return ;
+}
+
+
+
+static void ps__fillRow( this, row, input, black, white, match, width )
+     psWindowObject this ;
+     int row ;
+     short *input ;
+     int black, white ;
+     int *match, width ;
+{
+  ps__fill( this, row, input, black, white, match, width, 1 ) ;
+  return ;
+}
+
+
+
+static void ps__fillCol( this, col, input, black, white, match, height )
+     psWindowObject this ;
+     int col ;
+     short *input ;
+     int black, white ;
+     int *match, height ;
+{
+  ps__fill( this, col, input, black, white, match, height, 0 ) ;
+  return ;
+}
+
+
+
+static void ps__function( this, ys, segment, skip, offset, yspan, start, points )
+     psWindowObject this ;
+     short *ys ;
+     int segment, skip ;
+     double offset, yspan ;
+     int start, points ;
+{
+  int stop = start + abs( segment ) ;
+  int point, path = MAX_PATH, count, miny ;
+  short *yptr = ys ;
+  
+  for( point = start ; point < stop-1 ; point += path-1 ) {
+    if( path > stop - point ) 
+      path = stop - point ;
+    /* too-wide windows: something to do with Width( this) / (points -1.): 
+     * next line.  No fix attempted. MAA, 22-1-1993. 
+    */		
+    this->sender( this->xptr, "newpath 0 0 moveto %d 0 rlineto 0 %d rlineto %d neg 0 rlineto closepath clip\n", this->width, this->height, this->width ) ;
+    this->sender( this->xptr, "matrix currentmatrix [0 %g %g 0 0 %g] concat newpath %d %d moveto\n",
+		 Height( this ) / yspan, Width( this ) / ( points - 1. ), offset, miny = yptr[0], point ) ;
+    this->sender( this->xptr, "%s setlinewidth\n", figurelinewidthstr) ;
+
+#if defined(NeXT)
+    this->sender( this->xptr, "[\n" ) ;
+    for( count=1 ; count < path ; count++ ) {
+      yptr += skip ;
+      (void) this->sender( this->xptr, "%d\n", yptr[0]-yptr[-skip] ) ;
+      if( miny > yptr[0] )
+	miny = yptr[0] ;}
+    this->sender( this->xptr, "] {1 rlineto} forall\n" ) ;
+
+#else
+    this->sender( this->xptr, "/r {1 rlineto} bind def\n" ) ;
+    for( count=1 ; count < path ; count++ ) {
+      yptr += skip ;
+      (void) this->sender( this->xptr, "%d r\n", yptr[0]-yptr[-skip] ) ;
+      if( miny > yptr[0] )
+	miny = yptr[0] ;}
+#endif
+
+    if( this->hidden ) /* roy 27-11-92 */
+      this->sender( this->xptr, "gsave %d 0 rlineto 0 -%d rlineto closepath 1 setgray fill grestore\n", miny-yptr[0], path-1 ) ;
+    (void) this->sender( this->xptr, "setmatrix stroke\n" ) ;}
+  return ;
+}
+
+
+
+static int ps__read( this, fp, which )
+     psWindowObject this ;
+     FILE *fp ;
+     int which ;
+{
+  if( this->reader != 0 )
+    this->reader( this->xptr, fp, which ) ;
+  else
+    (void) fprintf( stderr, "Invalid call to read postscript image from file!!" ) ;
+  return ;
+}
+
+
+
+static void ps__write( this, fp )
+     psWindowObject this ;
+     FILE *fp ;
+{
+  if( this->writer != 0 )
+    this->writer( this->xptr, fp ) ;
+  else
+    (void) fprintf( stderr, "Invalid call to write postscript image to file!!" ) ;
+  return ;
+}
+
+
+
+static char ps__pause( this )
+     psWindowObject this ;
+{
+  if( this->pauser != (int (*)()) 0 )
+    return this->pauser( this->xptr ) ;
+  return '\000' ;
+}
+
+
+static void ps__axes( this, title, xmin, xmax, xtitle, ymin, ymax, ytitle )
+     psWindowObject this ;
+     char *title ;
+     double xmin, xmax ;
+     char *xtitle ;
+     double ymin, ymax ;
+     char *ytitle ;
+{
+  if (strcmp(xstartstr, "")) xmin = atoi(xstartstr);
+  if (strcmp(xendstr, ""))   xmax = atoi(xendstr);
+  if (strcmp(ystartstr, "")) ymin = atoi(ystartstr);
+  if (strcmp(yendstr, ""))   ymax = atoi(yendstr);
+  if (!strcmp(xnewtitlestr, "")) xnewtitlestr=xtitle;
+  if (!strcmp(ynewtitlestr, "")) ynewtitlestr=ytitle;  
+
+  temp_xmin = (double) xmin;
+  temp_xmax = (double) xmax;
+  temp_ymin = (double) ymin;
+  temp_ymax = (double) ymax;
+
+  if ( isOFF (rotateaxesstr) )
+    (void) this->sender( this->xptr, "(%s)   (%g)  (%g)  (%s)    (%g)  (%g)  (%s) Axes\n", title, xmin, xmax, xnewtitlestr, ymin, ymax, ynewtitlestr ) ;
+  else
+    (void) this->sender( this->xptr, "(%s)   (%g)  (%g)  (%s)    (%g)  (%g)  (%s) Axes\n", title, ymin, ymax, ytitle, (xmax * -1), (xmin * -1), xtitle ) ;
+  this->drawn = True ;
+  return ;
+}
+
+
+
+static void ps__marker( this, label, p, points )
+     psWindowObject this ;
+     char *label ;
+     int p, points ;
+{
+  short pos = ( this->entries->width( this ) * p + points / 2 ) / points ;
+  
+  (void) this->sender( this->xptr, "newpath %d %d moveto %d %d rlineto stroke\n", pos, 0, 0, this->entries->height( this ) ) ;
+  
+  this->drawn = True ;
+  return ;
+}
+
+static int ps__special( this, code, data )
+     psWindowObject this ;
+     int code ;
+     char *data ;
+{
+  this->drawn = True ;
+  switch( code ) {
+  case 1 :
+    (void) this->sender( this->xptr, "%s\n", data ) ;
+    return 1 ;
+  }
+  return 0 ;
+}
+
+
+
+windowsClass *initPostScriptClass( class )
+     windowsClass *class ;
+{
+  class->super    = &psClass ;
+  class->entries.x        = ps__x ;
+  class->entries.y        = ps__y ;
+  class->entries.width    = ps__width ;
+  class->entries.height   = ps__height ;
+  class->entries.draw     = ps__draw ;
+  class->entries.clear    = ps__clear ;
+  class->entries.close    = ps__close ;
+  class->entries.store    = ps__store ;
+  class->entries.recall   = ps__recall ;
+  class->entries.fillRow  = ps__fillRow ;
+  class->entries.fillCol  = ps__fillCol ;
+  class->entries.function = ps__function ;
+  class->entries.read     = ps__read ;
+  class->entries.write    = ps__write ;
+  class->entries.pause    = ps__pause ;
+  class->entries.axes     = ps__axes ;
+  class->entries.marker   = ps__marker ;
+  class->entries.special  = ps__special ;
+  
+  if( psClass.super == (windowsClass *) 0 )
+    (void) initPostScriptClass( &psClass ) ;
+  return ( &psClass ) ;
+}
+
+
+
+/* The End */
+/*----------------------------------------------------------------------*/
+
+