Mercurial > hg > aim92
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 |