Mercurial > hg > aim92
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 */ +/*----------------------------------------------------------------------*/ + +