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