comparison 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
comparison
equal deleted inserted replaced
-1:000000000000 0:5242703e91d3
1 /*
2 Copyright (c) Applied Psychology Unit, Medical Research Council. 1988, 1989
3 ===========================================================================
4 Permission to use, copy, modify, and distribute this software without fee
5 is hereby granted for research purposes, provided that this copyright
6 notice appears in all copies and in all supporting documentation, and that
7 the software is not redistributed for any fee (except for a nominal shipping
8 charge). Anyone wanting to incorporate all or part of this software in a
9 commercial product must obtain a license from the Medical Research Council.
10 The MRC makes no representations about the suitability of this
11 software for any purpose. It is provided "as is" without express or implied
12 warranty.
13
14 THE MRC DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
15 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE
16 A.P.U. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
17 DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
18 AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 */
21
22 /*
23 ps.c
24 ====
25 primitive PostScript interface ala windows.h interface.
26 Copyright (c), 1989 The Medical Research Council, Applied Psychology Unit.
27 Author : John Holdsworth 22nd March, 1989.
28 Michael Akeroyd Summer 1994.
29
30 Edited : Roy P 27-11-92: commented out two if statements with this->hidden
31 in them to force hiddenline.
32 Also added '(void)' at start of line after second of the lines
33 commented out to make it symmetric with similar lines.
34
35 : MAA. Summer 1994. rebuild. Notes:
36 (1) don't print windows bigger than 800 pixels wide; they aren't scaled
37 properly.
38 (2) all windows get drawn in the centre of the page.
39 (3) because of the 'fill's in drawing the data, the tick-marks can
40 get blanked out. To avoid this, the whole frame+marks are drawn
41 twice, at the begining (to get the coorect clipppath) and at the
42 end
43 : MAA. Autumn 1994. rebuilt to avoid note (3).
44
45 */
46
47
48 #include <stdio.h>
49 #if defined(THINK_C) || defined(NeXT)
50 #include <stdlib.h>
51 #else
52 #include <malloc.h>
53 #endif
54 #include "windows.h"
55 #include "grey.h"
56 #include "options.h" /* MAA: 23-4-1994: required for isON() */
57 #include "string.h" /* MAA: Summer 1994: required for atof() */
58 #ifndef NeXT
59 /* extern int fprintf() ; */ /* mha 8/4/97: sgi stops here */
60 #endif
61
62 static char *sccs_id = "@(#)ps.c 1.31 J. Holdsworth (MRC-APU) 7/7/93 Revised MAA 1994" ;
63
64
65 /* resolution parameters for line width */
66 #define POINTS_PER_INCH 72 /* standard definition of "points" */
67 #define PIXELS_PER_INCH 300 /* laserwriterII */
68 #define PIXELS_PER_POINT ( ( double ) PIXELS_PER_INCH / POINTS_PER_INCH )
69
70
71 /* limitation on graphics path lengths */
72 #define MAX_PATH 350
73
74
75 typedef struct {
76 windowEntries *entries ; /* pointers to method routines below */
77 char *xptr ; /* general pointer to postscript device */
78 int (*sender)(), (*closer)() ; /* function to transmit postscript */
79 int (*storer)(), (*recaller)(), (*reader)(), (*writer)(), (*pauser)() ; /* functions which may be used */
80 int x, y, width, height, pixels, hidden, page ; /* window paramaters */
81 enum { False, True } drawn, showpage ; /* if drawn and if clear not used and
82 window can be included in document */
83 struct _lookup *lookup ; /* state structure for dithering routines in grey.c*/
84 } *psWindowObject ;
85
86 static windowsClass psClass ;
87
88
89
90 /* MAA: lots of new options */
91 extern *rotateaxesstr;
92 extern char *xstartstr, *ystartstr, *xendstr, *yendstr;
93 extern char *xnewtitlestr, *ynewtitlestr;
94 extern char *portraitstr, *landscapestr;
95 extern char *fontnamestr, *fontsizestr, *titlesizestr;
96 extern char *xticksstr, *yticksstr, *outsidestr;
97 extern char *axistopstr, *axisbottomstr, *axisleftstr, *axisrightstr;
98 extern char *xmajorticksstr, *xminorticksstr;
99 extern char *ymajorticksstr, *yminorticksstr;
100 extern char *axislinewidthstr, *figurelinewidthstr;
101 extern char *boxstr;
102 static double temp_xmin;
103 static double temp_xmax;
104 static double temp_ymin;
105 static double temp_ymax;
106
107
108 /*-----------------------------------------------------------------------*/
109
110
111 WindowObject newPostScriptWindow( xptr, default_x, default_y, default_width, default_height, pixels, sender, closer, storer, recaller, reader, writer, pauser, pshidden )
112 char *xptr ;
113 int default_x, default_y, default_width, default_height, pixels ;
114 int (*sender)(), (*closer)() ;
115 int (*storer)(), (*recaller)(), (*reader)(), (*writer)(), (*pauser)() ;
116 int pshidden; /* =0 if off, =1 if on */
117 {
118 psWindowObject this = ( psWindowObject ) malloc( sizeof ( *this ) ) ;
119 char psfontstr[30];
120 char **ptr ;
121
122 if( psClass.super == (windowsClass *) 0 )
123 (void) initPostScriptClass( &psClass ) ;
124 this->entries = &psClass.entries ;
125 this->xptr = xptr ;
126 this->sender = sender ;
127 this->storer = storer ;
128 this->recaller = recaller ;
129 this->reader = reader ;
130 this->writer = writer ;
131 this->pauser = pauser ;
132 this->closer = closer ;
133 this->x = default_x ;
134 this->y = default_y ;
135 this->width = default_width ;
136 this->height = default_height ;
137 this->hidden = pshidden ;
138 this->pixels = abs( pixels ) ;
139 this->lookup = 0 ;
140 this->drawn = False ;
141
142 (void) this->sender( this->xptr, "%%!PS-Adobe-2.0 EPSF-1.2\n");
143 (void) this->sender( this->xptr, "%%%%Title: Windows postscript file\n");
144 (void) this->sender( this->xptr, "%%%%Creator: %s\n", sccs_id);
145 (void) this->sender( this->xptr, "%%%%BoundingBox: %d %d %d %d\n", this->x, this->y, this->x+this->width, this->y+this->height);
146 (void) this->sender( this->xptr, "%%%%Pages: (atend)\n", this->y);
147 /* (void) this->sender( this->xptr, "%%%%DocumentFonts: Times-Roman\n");*/
148 (void) this->sender( this->xptr, "%%%%EndComments\n") ;
149
150 if ( this->hidden == 0 ) {
151 (void) this->sender( this->xptr, "\n%%/fill workaround: no hidden lines. MAA. 22-1-1993\n" );
152 (void) this->sender( this->xptr, "/fill {} def\n\n" );}
153 else ;
154
155 /* Fonts. The only allowed ones are Times-Roman, Helvetica and Courier,
156 * because they are the only three you get in the Adobe Red Book, and
157 * so are presumably the onyl three you get in all printers.*/
158 if (!strcmp(fontnamestr, "Times")) {strcpy(psfontstr, "Times-Roman");}
159 else if (!strcmp(fontnamestr, "times")) {strcpy(psfontstr, "Times-Roman");}
160 else if (!strcmp(fontnamestr, "Roman")) {strcpy(psfontstr, "Times-Roman");}
161 else if (!strcmp(fontnamestr, "roman")) {strcpy(psfontstr, "Times-Roman");}
162 else if (!strcmp(fontnamestr, "times-roman")) {strcpy(psfontstr, "Times-Roman");}
163 else if (!strcmp(fontnamestr, "Times-Roman")) {strcpy(psfontstr, "Times-Roman");}
164 else if (!strcmp(fontnamestr, "timesroman")) {strcpy(psfontstr, "Times-Roman");}
165 else if (!strcmp(fontnamestr, "RimesRoman")) {strcpy(psfontstr, "Times-Roman");}
166 else if (!strcmp(fontnamestr, "TimesBold")) {strcpy(psfontstr, "Times-Bold");}
167 else if (!strcmp(fontnamestr, "timesbold")) {strcpy(psfontstr, "Times-Bold");}
168 else if (!strcmp(fontnamestr, "timesbold")) {strcpy(psfontstr, "Times-Bold");}
169 else if (!strcmp(fontnamestr, "times-bold")) {strcpy(psfontstr, "Times-Bold");}
170 else if (!strcmp(fontnamestr, "Times-Bold")) {strcpy(psfontstr, "Times-Bold");}
171
172 else if (!strcmp(fontnamestr, "Helvetica")) {strcpy(psfontstr, "Helvetica");}
173 else if (!strcmp(fontnamestr, "helvetica")) {strcpy(psfontstr, "Helvetica");}
174 else if (!strcmp(fontnamestr, "Hel")) {strcpy(psfontstr, "Helvetica");}
175 else if (!strcmp(fontnamestr, "hel")) {strcpy(psfontstr, "Helvetica");}
176 else if (!strcmp(fontnamestr, "HelveticaBold")) {strcpy(psfontstr, "Helvetica-Bold");}
177 else if (!strcmp(fontnamestr, "Helveticabold")) {strcpy(psfontstr, "Helvetica-Bold");}
178 else if (!strcmp(fontnamestr, "helveticabold")) {strcpy(psfontstr, "Helvetica-Bold");}
179 else if (!strcmp(fontnamestr, "Helvetica-Bold")) {strcpy(psfontstr, "Helvetica-Bold");}
180 else if (!strcmp(fontnamestr, "helvetica-bold")) {strcpy(psfontstr, "Helvetica-Bold");}
181 else if (!strcmp(fontnamestr, "helbold")) {strcpy(psfontstr, "Helvetica-Bold");}
182 else if (!strcmp(fontnamestr, "HelBold")) {strcpy(psfontstr, "Helvetica-Bold");}
183
184 else if (!strcmp(fontnamestr, "Courier")) {strcpy(psfontstr, "Courier");}
185 else if (!strcmp(fontnamestr, "courier")) {strcpy(psfontstr, "Courier");}
186 else if (!strcmp(fontnamestr, "Cou")) {strcpy(psfontstr, "Courier");}
187 else if (!strcmp(fontnamestr, "cou")) {strcpy(psfontstr, "Courier");}
188 else if (!strcmp(fontnamestr, "Courier-Bold")) {strcpy(psfontstr, "Courier-Bold");}
189 else if (!strcmp(fontnamestr, "courier-bold")) {strcpy(psfontstr, "Courier-Bold");}
190 else if (!strcmp(fontnamestr, "courierbold")) {strcpy(psfontstr, "Courier-Bold");}
191 else if (!strcmp(fontnamestr, "CourierBold")) {strcpy(psfontstr, "Courier-Bold");}
192 else if (!strcmp(fontnamestr, "CouBold")) {strcpy(psfontstr, "Courier-Bold");}
193 else if (!strcmp(fontnamestr, "coubold")) {strcpy(psfontstr, "Courier-Bold");}
194
195 else {
196 fprintf(stderr, "WARNING: Unknown font %s. (allowed time, helvetica or courier.)\n", fontnamestr);
197 fprintf(stderr, "WARNING: Stopping here; no Postscript generated\n");
198 exit(-1);}
199
200
201 /* copy postscript code for axes into output file */
202 (void) this->sender( this->xptr, "%%! simple postscript axes\n");
203 (void) this->sender( this->xptr, "%% v1.10 John Holdsworth (5/31/91).\n");
204 (void) this->sender( this->xptr, "%% Revised M Akeroyd (Summer, Autumn 1994)\n");
205 (void) this->sender( this->xptr, "\n");
206 (void) this->sender( this->xptr, " /midprint { %% str x y midprint -\n");
207 (void) this->sender( this->xptr, " moveto\n");
208 (void) this->sender( this->xptr, " dup\n");
209 (void) this->sender( this->xptr, " stringwidth pop 2 div neg 0 rmoveto\n");
210 (void) this->sender( this->xptr, " show\n");
211 (void) this->sender( this->xptr, " } def\n");
212 (void) this->sender( this->xptr, "\n");
213 (void) this->sender( this->xptr, " /leftprint { %% str x y leftprint -\n");
214 (void) this->sender( this->xptr, " moveto\n");
215 (void) this->sender( this->xptr, " dup\n");
216 (void) this->sender( this->xptr, " stringwidth pop neg fontsize 0.4 mul neg rmoveto\n");
217 (void) this->sender( this->xptr, " show\n");
218 (void) this->sender( this->xptr, " } def\n");
219 (void) this->sender( this->xptr, "\n");
220 (void) this->sender( this->xptr, " /ticks { %% min max <float> <float> ticker -\n");
221 (void) this->sender( this->xptr, " /ticker exch def %% procedure to draw ticks\n");
222 (void) this->sender( this->xptr, " /fmax exch cvr def %% relative spacing of max ticks (0.5x, etc)\n");
223 (void) this->sender( this->xptr, " /fmin exch cvr def %% relative spacing of min ticks (0.5x, etc)\n");
224 (void) this->sender( this->xptr, " /max exch cvr def %% axis maximum\n");
225 (void) this->sender( this->xptr, " /min exch cvr def %% axis minimum\n");
226 (void) this->sender( this->xptr, " /maxsubticks 50 def\n");
227 (void) this->sender( this->xptr, " max min ne {\n");
228 (void) this->sender( this->xptr, " %% calculate order of magnitude\n");
229 (void) this->sender( this->xptr, " /delta max min sub log ceiling 1 sub 10 exch exp def\n");
230 (void) this->sender( this->xptr, " %% do ticks\n");
231 (void) this->sender( this->xptr, " min delta div ceiling delta mul\n");
232 (void) this->sender( this->xptr, " delta fmax mul\n");
233 (void) this->sender( this->xptr, " max delta div floor delta mul\n");
234 (void) this->sender( this->xptr, " {\n");
235 (void) this->sender( this->xptr, " min sub max min sub div 1.333333 exch ticker\n");
236 (void) this->sender( this->xptr, " }\n");
237 (void) this->sender( this->xptr, " for\n");
238 (void) this->sender( this->xptr, " %% do sub ticks (but only if fmin != 0)\n");
239 (void) this->sender( this->xptr, " fmin 0 ne {");
240 (void) this->sender( this->xptr, " max min sub delta div dup\n");
241 (void) this->sender( this->xptr, " 10 mul maxsubticks lt {.1} {5 mul maxsubticks lt {.2} {.5} ifelse } ifelse\n");
242 (void) this->sender( this->xptr, " delta mul /delta exch def\n");
243 (void) this->sender( this->xptr, " min delta div ceiling delta mul\n");
244 (void) this->sender( this->xptr, " delta fmin mul \n");
245 (void) this->sender( this->xptr, " max delta div floor delta mul\n");
246 (void) this->sender( this->xptr, " {\n");
247 /* MAA: This used to be 0.25; I've changed it (0.25 * 1.33), so its in real points.*/
248 (void) this->sender( this->xptr, " min sub max min sub div 0.666666 exch ticker\n");
249 (void) this->sender( this->xptr, " }\n");
250 (void) this->sender( this->xptr, " for\n");
251 (void) this->sender( this->xptr, " } if\n");
252 (void) this->sender( this->xptr, " } if\n");
253 (void) this->sender( this->xptr, " } def\n");
254 (void) this->sender( this->xptr, "\n");
255 (void) this->sender( this->xptr, "/Axes { %% title xmin xmax xtitle ymin ymax ytitle Axes -\n");
256 (void) this->sender( this->xptr, "/AxesDict 50 dict def\n");
257 (void) this->sender( this->xptr, "AxesDict begin\n");
258 (void) this->sender( this->xptr, " /ytitle exch def\n");
259 (void) this->sender( this->xptr, " /ymax exch def\n");
260 (void) this->sender( this->xptr, " /ymin exch def\n");
261 (void) this->sender( this->xptr, " /xtitle exch def\n");
262 (void) this->sender( this->xptr, " /xmax exch def\n");
263 (void) this->sender( this->xptr, " /xmin exch def\n");
264 (void) this->sender( this->xptr, " /title exch def\n");
265 (void) this->sender( this->xptr, " newpath clippath pathbbox /height exch def\n");
266 (void) this->sender( this->xptr, " /width exch def\n");
267 (void) this->sender( this->xptr, " pop pop\n");
268 (void) this->sender( this->xptr, " /tagsize 0.05 height mul neg def\n");
269 if (isOFF(xticksstr))
270 (void) this->sender( this->xptr, " /xtagsize tagsize 1.33 mul def\n");
271 else
272 (void) this->sender( this->xptr, " /xtagsize %s neg 1.33 mul def\n", xticksstr);
273 if (isOFF(yticksstr))
274 (void) this->sender( this->xptr, " /ytagsize tagsize 1.33 mul def\n");
275 else
276 (void) this->sender( this->xptr, " /ytagsize %s neg 1.33 mul def\n", yticksstr);
277 if (isOFF(fontsizestr))
278 (void) this->sender( this->xptr, " /fontsize 0.05 height mul def\n");
279 else {
280 /* note 1.333 multiplier: required to get rid of the 0.75 later on */
281 (void) this->sender( this->xptr, " /fontsize %s 1.333 mul def\n", fontsizestr);}
282 (void) this->sender( this->xptr, " /space 0.10 height mul def\n");
283 (void) this->sender( this->xptr, " /%s findfont fontsize scalefont setfont\n", psfontstr);
284 /* MAA: What do these 0.75/0.75 do? Quite a lot: they seem to be a screen -> paper multiplu constant*/
285 (void) this->sender( this->xptr, " width 0.20 mul 0.15 height mul translate 0.75 0.75 scale\n");
286 (void) this->sender( this->xptr, " gsave\n");
287 (void) this->sender( this->xptr, " gsave\n");
288 (void) this->sender( this->xptr, " %s setlinewidth\n", axislinewidthstr);
289 /* MAA: I do not knwo why this (2,2) translation is here, but it seems to get in the way */
290 /* (void) this->sender( this->xptr, " currentlinewidth 2 div neg dup translate\n");*/
291 (void) this->sender( this->xptr, " newpath\n");
292 if (isOFF(titlesizestr))
293 (void) this->sender( this->xptr, " title width 2 div height tagsize 1.75 mul sub midprint\n");
294 else {
295 (void) this->sender( this->xptr, " gsave\n");
296 /* note 1.333 multiplier: required to get rid of the 0.75 later on */
297 (void) this->sender( this->xptr, " /%s findfont %s 1.333 mul scalefont setfont\n", psfontstr, titlesizestr);
298 (void) this->sender( this->xptr, " title width 2 div height tagsize 1.75 mul sub midprint\n");}
299 if (isON(axisbottomstr)){
300 (void) this->sender( this->xptr, " xmin 0 xtagsize fontsize sub midprint\n");
301 (void) this->sender( this->xptr, " xmax width xtagsize fontsize sub midprint\n");
302 (void) this->sender( this->xptr, " xmin cvr 0 lt \n");
303 (void) this->sender( this->xptr, " {xmax cvr 0 ge \n");
304 (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");
305 (void) this->sender( this->xptr, " /xtitleconstant 2.0 def} \n");
306 (void) this->sender( this->xptr, " {/xtitleconstant 1.0 def} \n");
307 (void) this->sender( this->xptr, " ifelse}\n");
308 (void) this->sender( this->xptr, " {/xtitleconstant 1.0 def} \n");
309 (void) this->sender( this->xptr, " ifelse\n");
310 (void) this->sender( this->xptr, " xtitle width 2 div xtagsize xtitleconstant mul fontsize sub midprint\n");
311 }
312 if (isON(axisleftstr)) {
313 (void) this->sender( this->xptr, " ymin ytagsize 2.0 mul 0 leftprint\n");
314 (void) this->sender( this->xptr, " ymax ytagsize 2.0 mul height leftprint\n");
315 (void) this->sender( this->xptr, " ymin cvr 0 lt { \n");
316 (void) this->sender( this->xptr, " ymax cvr 0 ge {\n");
317 (void) this->sender( this->xptr, " (0) ytagsize 2.0 mul height ymin cvr neg ymin cvr neg ymax cvr add div mul leftprint} \n");
318 (void) this->sender( this->xptr, " if}\n");
319 (void) this->sender( this->xptr, " if\n");}
320 (void) this->sender( this->xptr, " 90 rotate\n");
321 (void) this->sender( this->xptr, " ytitle height 2 div space 1.75 mul midprint\n");
322 (void) this->sender( this->xptr, " grestore\n");
323 (void) this->sender( this->xptr, " grestore\n");
324 (void) this->sender( this->xptr, "end } def\n");
325
326
327
328 /* MAA: New procedure AxesBox, which draws the box ... This is actually a revised workaround
329 * for the 'borderframe' problem. */
330 (void) this->sender( this->xptr, "\n\n" ) ;
331 (void) this->sender( this->xptr, "/AxesBox { %% xmin xmax ymin ymax AxesBox -\n");
332 (void) this->sender( this->xptr, "/AxesBoxDict 50 dict def\n");
333 (void) this->sender( this->xptr, "AxesBoxDict begin\n");
334 (void) this->sender( this->xptr, " /ymax exch def\n");
335 (void) this->sender( this->xptr, " /ymin exch def\n");
336 (void) this->sender( this->xptr, " /xmax exch def\n");
337 (void) this->sender( this->xptr, " /xmin exch def\n");
338 (void) this->sender( this->xptr, " newpath clippath pathbbox /height exch def\n");
339 (void) this->sender( this->xptr, " /width exch def\n");
340 (void) this->sender( this->xptr, " pop pop\n");
341 (void) this->sender( this->xptr, " /tagsize 0.05 height mul neg def\n");
342 if (isOFF(xticksstr))
343 (void) this->sender( this->xptr, " /xtagsize tagsize def\n");
344 else
345 (void) this->sender( this->xptr, " /xtagsize %s neg def\n", xticksstr);
346 if (isOFF(yticksstr))
347 (void) this->sender( this->xptr, " /ytagsize tagsize def\n");
348 else
349 (void) this->sender( this->xptr, " /ytagsize %s neg def\n", yticksstr);
350 (void) this->sender( this->xptr, " /space 0.10 height mul def\n");
351 (void) this->sender( this->xptr, " width 0.20 mul 0.15 height mul translate 0.75 0.75 scale\n");
352 (void) this->sender( this->xptr, " gsave\n");
353 (void) this->sender( this->xptr, " %s setlinewidth\n", axislinewidthstr);
354 (void) this->sender( this->xptr, " newpath\n");
355 if (isON(outsidestr)){
356 (void) this->sender( this->xptr, " /toptagsize xtagsize neg def\n");
357 (void) this->sender( this->xptr, " /bottomtagsize xtagsize def\n");
358 (void) this->sender( this->xptr, " /lefttagsize ytagsize def\n");
359 (void) this->sender( this->xptr, " /righttagsize ytagsize neg def\n");}
360 else{
361 (void) this->sender( this->xptr, " /toptagsize xtagsize def\n");
362 (void) this->sender( this->xptr, " /bottomtagsize xtagsize neg def\n");
363 (void) this->sender( this->xptr, " /lefttagsize ytagsize neg def\n");
364 (void) this->sender( this->xptr, " /righttagsize ytagsize def\n");}
365 if (isON(axisbottomstr)){
366 (void) this->sender( this->xptr, " 0 bottomtagsize moveto 0 0 lineto stroke\n");
367 (void) this->sender( this->xptr, " width bottomtagsize moveto width 0 lineto stroke\n");}
368 if (isON(axistopstr)){
369 (void) this->sender( this->xptr, " 0 height moveto 0 toptagsize rmoveto 0 height lineto stroke\n");
370 (void) this->sender( this->xptr, " width height moveto 0 toptagsize rmoveto width height lineto stroke\n");}
371 if (isON(axisleftstr)){
372 (void) this->sender( this->xptr, " 0 0 moveto lefttagsize 0 rmoveto 0 0 lineto stroke\n");
373 (void) this->sender( this->xptr, " 0 height moveto lefttagsize 0 rmoveto 0 height lineto stroke\n");}
374 if (isON(axisrightstr)){
375 (void) this->sender( this->xptr, " width 0 moveto righttagsize 0 rmoveto width 0 lineto stroke\n");
376 (void) this->sender( this->xptr, " width height moveto righttagsize 0 rmoveto width height lineto stroke\n");}
377 if (isON(axisbottomstr))
378 (void) this->sender( this->xptr, " xmin xmax %s %s {width mul 0 moveto bottomtagsize mul 0 exch rlineto stroke} ticks\n", xminorticksstr, xmajorticksstr);
379 if (isON(axistopstr))
380 (void) this->sender( this->xptr, " xmin xmax %s %s {width mul height moveto toptagsize mul 0 exch rlineto stroke} ticks\n", xminorticksstr, xmajorticksstr);
381 if (isON(axisleftstr))
382 (void) this->sender( this->xptr, " ymin ymax %s %s {height mul 0 exch moveto lefttagsize mul 0 rlineto stroke} ticks\n", yminorticksstr, ymajorticksstr);
383 if (isON(axisrightstr))
384 (void) this->sender( this->xptr, " ymin ymax %s %s {height mul width exch moveto righttagsize mul 0 rlineto stroke} ticks\n", yminorticksstr, ymajorticksstr);
385 (void) this->sender( this->xptr, " grestore\n");
386 (void) this->sender( this->xptr, " newpath 0 0 moveto width 0 lineto width height lineto 0 height lineto closepath stroke clip\n");
387 (void) this->sender( this->xptr, "end } def\n");
388 (void) this->sender( this->xptr, "\ngsave\n\n" ) ;
389
390 /* rotate for landscape mode */
391 if( this->width > this->height ) {
392 (void) this->sender( this->xptr, "%% shift orgin and rotate for landscape mode\n" ) ;
393 (void) this->sender( this->xptr, "newpath clippath pathbbox pop exch translate pop 90 rotate %% notstand\n" ) ; }
394 (void) this->sender( this->xptr, "%% center image on page\n" ) ;
395 (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 ) ;
396
397 /* set clippath - used by axis routine */
398 (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 ) ;
399 /* (void) this->sender( this->xptr, "%f setlinewidth\n/l { lineto } def\n", this->pixels / PIXELS_PER_POINT ) ;*/
400 (void) this->sender( this->xptr, "%s setlinewidth\n/l { lineto } def\n", figurelinewidthstr) ;
401
402 (void) this->sender( this->xptr, "1 setlinecap\n/pt {moveto 0 0 rlineto stroke} def\n" ) ;
403 (void) this->sender( this->xptr, "106 45 { dup mul exch\n dup mul add 1.0\n exch sub } setscreen\n" ) ;
404
405 this->page = 1 ;
406 (void) this->sender( this->xptr, "%%%%EndProlog\n%%%%Page %d %d\ngsave\n", this->page, this->page ) ;
407 this->showpage = False ;
408 return ( ( WindowObject ) this ) ;
409 }
410
411
412
413 /*---------------------------------------------------------------*/
414
415
416
417 WindowObject newFILEWindow( fp, default_x, default_y, default_width, default_height, pixels, pshidden)
418 FILE *fp ;
419 int default_x, default_y, default_width, default_height, pixels ;
420 int pshidden;
421 {
422 extern int fflush() ;
423
424 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 )) ;
425 }
426
427
428
429 WindowObject newPSWindow( name, default_x, default_y, default_width, default_height, pixels, pshidden )
430 char *name ;
431 int default_x, default_y, default_width, default_height, pixels ;
432 int pshidden ;
433 {
434 extern int fclose() ;
435 FILE *fp = stdout ;
436
437 if( name != ( char * ) 0 && name[0] != '\000' )
438 if( ( fp = fopen( name, "w" ) ) == ( FILE * ) 0 ) {
439 (void) fprintf( stderr, "Could not open file \"%s\" for output\n", name ) ;
440 exit( 1 ) ;}
441
442 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 ) ) ;
443 }
444
445
446
447 static short ps__x( this )
448 psWindowObject this ;
449 {
450 return( this->x ) ;
451 }
452
453
454 static short ps__y( this )
455 psWindowObject this ;
456 {
457 return( this->y ) ;
458 }
459
460
461 static short ps__width( this )
462 psWindowObject this ;
463 {
464 return( this->width ) ;
465 }
466
467
468 static short ps__height( this )
469 psWindowObject this ;
470 {
471 return( this->height ) ;
472 }
473
474
475 static void ps__draw( this, xs, ys, points )
476 psWindowObject this ;
477 short xs[], ys[] ;
478 int points ;
479 {
480 int path, point ;
481
482 (void) this->sender( this->xptr, "newpath\n" ) ;
483 if( points > 0 )
484 for( point=1 ; point < points ; point+=path ) {
485 (void) this->sender( this->xptr, "%d %d moveto\n", xs[point-1], ys[point-1] ) ;
486 for( path=0 ; point+path < points && path < MAX_PATH ; path++ )
487 (void) this->sender( this->xptr, "%d %d l\n", xs[point+path], ys[point+path] ) ;
488 if( this->hidden && xs[point+path] == xs[point-1] &&
489 ys[point+path] == ys[point-1] ) /*Roy 27-11-92 */
490 (void) this->sender( this->xptr, "gsave 1 setgray fill grestore\n" ) ;
491 (void) this->sender( this->xptr, "stroke\n" ) ;}
492 else {
493 (void) this->sender( this->xptr, "gsave currentlinewidth 10. mul setlinewidth\n" ) ;
494 for( point=1 ; point < abs(points) ; point++ )
495 (void) this->sender( this->xptr, "%d %d pt\n", xs[point], ys[point] ) ;
496 (void) this->sender( this->xptr, "grestore\n" ) ;}
497
498 this->drawn = True ;
499 return ;
500 }
501
502
503
504 static void ps__clear( this )
505 psWindowObject this ;
506 {
507 if( this->drawn ) {
508 ++this->page ;
509 (void) this->sender( this->xptr, "grestore\n") ;
510 (void) this->sender( this->xptr, "%s setlinewidth\n", axislinewidthstr) ;
511 if (isON(boxstr))
512 (void) this->sender( this->xptr, "(%g) (%g) (%g) (%g) AxesBox\n", temp_xmin, temp_xmax, temp_ymin, temp_ymax) ;
513 (void) this->sender( this->xptr, "showpage\ngrestore\n%%%%Page: %d %d\ngsave\n", this->page, this->page ) ; }
514 (void) this->sender( this->xptr, "gsave clippath 1 setgray fill grestore\n" ) ;
515 this->showpage = True ;
516 return ;
517 }
518
519
520
521 static void ps__close( this )
522 psWindowObject this ;
523 {
524 (void) this->sender( this->xptr, "grestore\n") ;
525 (void) this->sender( this->xptr, "%s setlinewidth\n", axislinewidthstr) ;
526 if (isON(boxstr))
527 (void) this->sender( this->xptr, "(%g) (%g) (%g) (%g) AxesBox\n", temp_xmin, temp_xmax, temp_ymin, temp_ymax) ;
528 if( this->showpage )
529 (void) this->sender( this->xptr, "showpage %% notstand\n" ) ;
530 else
531 this->page = 0 ;
532 (void) this->sender( this->xptr, "grestore\n%%%%Trailer\ngrestore\n%%%%Pages: %d\n", this->page ) ;
533 if( this->closer != 0 )
534 this->closer( this ) ;
535 free( (char *) this ) ;
536 return ;
537 }
538
539
540
541 static int ps__store( this )
542 psWindowObject this ;
543 {
544 if( this->storer != 0 )
545 return ( this->storer( this->xptr ) ) ;
546 else
547 (void) fprintf( stderr, "Invalid call to restore postscript image from memory!!" ) ;
548 return 0 ;
549 }
550
551
552
553 static void ps__recall( this, which )
554 psWindowObject this ;
555 int which ;
556 {
557 if( this->recaller != 0 )
558 this->recaller( this->xptr, which ) ;
559 else
560 (void) fprintf( stderr, "Invalid call to store postscript image in memory!!" ) ;
561 return ;
562 }
563
564
565
566 static char *cmap( npixels )
567 int *npixels ;
568 {
569 #ifdef NeXT
570 static char ps_grey_scale[] = "04bf" ;
571 #else
572 static char ps_grey_scale[] = "0123456789abcdef" ;
573 #endif
574
575 *npixels = sizeof ( ps_grey_scale ) - 1 ;
576 return ( ps_grey_scale ) ;
577 }
578
579
580
581 static void ps__fill( this, col, input, black, white, match, length, row_flag )
582 psWindowObject this ;
583 int col ;
584 short *input;
585 int black, white ;
586 int *match, length ;
587 int row_flag ;
588 {
589 int chans, chan, y, blacky ;
590
591 if( this->lookup == 0 ) {
592 this->lookup = makeLookup( cmap, black, white, length ) ;
593 (void) this->sender( this->xptr, "/picstr %d string def\n", length ) ;}
594 if( col == 1 ) {
595 if( row_flag )
596 (void) this->sender( this->xptr, "%d %d 4\n[1 0 0 -1 0 %d]\n", this->width, this->height, this->height ) ;
597 else
598 (void) this->sender( this->xptr, "%d %d 4\n[0 1 -1 0 %d 0]\n", this->height, this->width, this->height ) ;
599 (void) this->sender( this->xptr, "{currentfile\npicstr readhexstring pop}\nimage\n" ) ;}
600
601 (void) this->sender( this->xptr, "%s\n", Lookup( col, this->lookup, input, match, length ) ) ;
602 this->drawn = True ;
603 return ;
604 }
605
606
607
608 static void ps__fillRow( this, row, input, black, white, match, width )
609 psWindowObject this ;
610 int row ;
611 short *input ;
612 int black, white ;
613 int *match, width ;
614 {
615 ps__fill( this, row, input, black, white, match, width, 1 ) ;
616 return ;
617 }
618
619
620
621 static void ps__fillCol( this, col, input, black, white, match, height )
622 psWindowObject this ;
623 int col ;
624 short *input ;
625 int black, white ;
626 int *match, height ;
627 {
628 ps__fill( this, col, input, black, white, match, height, 0 ) ;
629 return ;
630 }
631
632
633
634 static void ps__function( this, ys, segment, skip, offset, yspan, start, points )
635 psWindowObject this ;
636 short *ys ;
637 int segment, skip ;
638 double offset, yspan ;
639 int start, points ;
640 {
641 int stop = start + abs( segment ) ;
642 int point, path = MAX_PATH, count, miny ;
643 short *yptr = ys ;
644
645 for( point = start ; point < stop-1 ; point += path-1 ) {
646 if( path > stop - point )
647 path = stop - point ;
648 /* too-wide windows: something to do with Width( this) / (points -1.):
649 * next line. No fix attempted. MAA, 22-1-1993.
650 */
651 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 ) ;
652 this->sender( this->xptr, "matrix currentmatrix [0 %g %g 0 0 %g] concat newpath %d %d moveto\n",
653 Height( this ) / yspan, Width( this ) / ( points - 1. ), offset, miny = yptr[0], point ) ;
654 this->sender( this->xptr, "%s setlinewidth\n", figurelinewidthstr) ;
655
656 #if defined(NeXT)
657 this->sender( this->xptr, "[\n" ) ;
658 for( count=1 ; count < path ; count++ ) {
659 yptr += skip ;
660 (void) this->sender( this->xptr, "%d\n", yptr[0]-yptr[-skip] ) ;
661 if( miny > yptr[0] )
662 miny = yptr[0] ;}
663 this->sender( this->xptr, "] {1 rlineto} forall\n" ) ;
664
665 #else
666 this->sender( this->xptr, "/r {1 rlineto} bind def\n" ) ;
667 for( count=1 ; count < path ; count++ ) {
668 yptr += skip ;
669 (void) this->sender( this->xptr, "%d r\n", yptr[0]-yptr[-skip] ) ;
670 if( miny > yptr[0] )
671 miny = yptr[0] ;}
672 #endif
673
674 if( this->hidden ) /* roy 27-11-92 */
675 this->sender( this->xptr, "gsave %d 0 rlineto 0 -%d rlineto closepath 1 setgray fill grestore\n", miny-yptr[0], path-1 ) ;
676 (void) this->sender( this->xptr, "setmatrix stroke\n" ) ;}
677 return ;
678 }
679
680
681
682 static int ps__read( this, fp, which )
683 psWindowObject this ;
684 FILE *fp ;
685 int which ;
686 {
687 if( this->reader != 0 )
688 this->reader( this->xptr, fp, which ) ;
689 else
690 (void) fprintf( stderr, "Invalid call to read postscript image from file!!" ) ;
691 return ;
692 }
693
694
695
696 static void ps__write( this, fp )
697 psWindowObject this ;
698 FILE *fp ;
699 {
700 if( this->writer != 0 )
701 this->writer( this->xptr, fp ) ;
702 else
703 (void) fprintf( stderr, "Invalid call to write postscript image to file!!" ) ;
704 return ;
705 }
706
707
708
709 static char ps__pause( this )
710 psWindowObject this ;
711 {
712 if( this->pauser != (int (*)()) 0 )
713 return this->pauser( this->xptr ) ;
714 return '\000' ;
715 }
716
717
718 static void ps__axes( this, title, xmin, xmax, xtitle, ymin, ymax, ytitle )
719 psWindowObject this ;
720 char *title ;
721 double xmin, xmax ;
722 char *xtitle ;
723 double ymin, ymax ;
724 char *ytitle ;
725 {
726 if (strcmp(xstartstr, "")) xmin = atoi(xstartstr);
727 if (strcmp(xendstr, "")) xmax = atoi(xendstr);
728 if (strcmp(ystartstr, "")) ymin = atoi(ystartstr);
729 if (strcmp(yendstr, "")) ymax = atoi(yendstr);
730 if (!strcmp(xnewtitlestr, "")) xnewtitlestr=xtitle;
731 if (!strcmp(ynewtitlestr, "")) ynewtitlestr=ytitle;
732
733 temp_xmin = (double) xmin;
734 temp_xmax = (double) xmax;
735 temp_ymin = (double) ymin;
736 temp_ymax = (double) ymax;
737
738 if ( isOFF (rotateaxesstr) )
739 (void) this->sender( this->xptr, "(%s) (%g) (%g) (%s) (%g) (%g) (%s) Axes\n", title, xmin, xmax, xnewtitlestr, ymin, ymax, ynewtitlestr ) ;
740 else
741 (void) this->sender( this->xptr, "(%s) (%g) (%g) (%s) (%g) (%g) (%s) Axes\n", title, ymin, ymax, ytitle, (xmax * -1), (xmin * -1), xtitle ) ;
742 this->drawn = True ;
743 return ;
744 }
745
746
747
748 static void ps__marker( this, label, p, points )
749 psWindowObject this ;
750 char *label ;
751 int p, points ;
752 {
753 short pos = ( this->entries->width( this ) * p + points / 2 ) / points ;
754
755 (void) this->sender( this->xptr, "newpath %d %d moveto %d %d rlineto stroke\n", pos, 0, 0, this->entries->height( this ) ) ;
756
757 this->drawn = True ;
758 return ;
759 }
760
761 static int ps__special( this, code, data )
762 psWindowObject this ;
763 int code ;
764 char *data ;
765 {
766 this->drawn = True ;
767 switch( code ) {
768 case 1 :
769 (void) this->sender( this->xptr, "%s\n", data ) ;
770 return 1 ;
771 }
772 return 0 ;
773 }
774
775
776
777 windowsClass *initPostScriptClass( class )
778 windowsClass *class ;
779 {
780 class->super = &psClass ;
781 class->entries.x = ps__x ;
782 class->entries.y = ps__y ;
783 class->entries.width = ps__width ;
784 class->entries.height = ps__height ;
785 class->entries.draw = ps__draw ;
786 class->entries.clear = ps__clear ;
787 class->entries.close = ps__close ;
788 class->entries.store = ps__store ;
789 class->entries.recall = ps__recall ;
790 class->entries.fillRow = ps__fillRow ;
791 class->entries.fillCol = ps__fillCol ;
792 class->entries.function = ps__function ;
793 class->entries.read = ps__read ;
794 class->entries.write = ps__write ;
795 class->entries.pause = ps__pause ;
796 class->entries.axes = ps__axes ;
797 class->entries.marker = ps__marker ;
798 class->entries.special = ps__special ;
799
800 if( psClass.super == (windowsClass *) 0 )
801 (void) initPostScriptClass( &psClass ) ;
802 return ( &psClass ) ;
803 }
804
805
806
807 /* The End */
808 /*----------------------------------------------------------------------*/
809
810