1 /*****************************************************************************
2  *
3  *  Elmer, A Finite Element Software for Multiphysical Problems
4  *
5  *  Copyright 1st April 1995 - , CSC - IT Center for Science Ltd., Finland
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library (in file ../LGPL-2.1); if not, write
19  * to the Free Software Foundation, Inc., 51 Franklin Street,
20  * Fifth Floor, Boston, MA  02110-1301  USA
21  *
22  *****************************************************************************/
23 
24 /*******************************************************************************
25  *
26  *     Postscript driver of the MATC graphics.
27  *
28  *******************************************************************************
29  *
30  *                     Author:       Juha Ruokolainen
31  *
32  *                    Address: CSC - IT Center for Science Ltd.
33  *                                Keilaranta 14, P.O. BOX 405
34  *                                  02101 Espoo, Finland
35  *                                  Tel. +358 0 457 2723
36  *                                Telefax: +358 0 457 2302
37  *                              EMail: Juha.Ruokolainen@csc.fi
38  *
39  *                       Date: 30 May 1996
40  *
41  *                Modified by:
42  *
43  *       Date of modification:
44  *
45  ******************************************************************************/
46 
47 /*
48  * $Id: dri_ps.c,v 1.2 2005/05/27 12:26:19 vierinen Exp $
49  *
50  * $Log: dri_ps.c,v $
51  * Revision 1.2  2005/05/27 12:26:19  vierinen
52  * changed header install location
53  *
54  * Revision 1.1.1.1  2005/04/14 13:29:14  vierinen
55  * initial matc automake package
56  *
57  * Revision 1.2  1998/08/01 12:34:32  jpr
58  *
59  * Added Id, started Log.
60  *
61  *
62  */
63 
64 #include "elmer/matc.h"
65 
66 #define GRA_PS_FILE "matc.ps"
67 
68 #define GRA_PS_MAXC 16
69 static unsigned char gra_ps_rgb[GRA_PS_MAXC][3] =
70 {
71   { 255, 255, 255 },
72   { 0,   0,     0 },
73   { 0,   83,  255 },
74   { 0,   166, 255 },
75   { 0,   255, 255 },
76   { 0,   83,  0   },
77   { 0,   166, 0   },
78   { 0,   255, 0   },
79   { 255, 255, 0   },
80   { 255, 166, 0   },
81   { 255, 83,  0   },
82   { 255, 0,   0   },
83   { 255, 0,   255 },
84   { 255, 83,  255 },
85   { 255, 166, 255 },
86   { 0,   0,   0   }
87 };
88 
89 static double sh = -1,
90               fs = -1,
91               pip180 = 3.14158/180.0;
92 #pragma omp threadprivate (gra_ps_rgb, sh, fs, pip180)
93 
gra_ps_open(dev)94 void gra_ps_open(dev) int dev;
95 {
96   int i;
97 
98   if (gra_state.out_fp == NULL)
99   {
100     if ((gra_state.out_fp = fopen(GRA_PS_FILE, "w")) == NULL)
101     {
102       gra_state.driver = GRA_DRV_NULL;
103       error("gra: open: Can't open output file...\n");
104     }
105   }
106 
107   fprintf(gra_state.out_fp, "%%!PS-Adobe-1.0\n");
108   fprintf(gra_state.out_fp, "/m { moveto } def\n");
109   fprintf(gra_state.out_fp, "/l { lineto } def\n");
110   fprintf(gra_state.out_fp, "/d { stroke } def\n");
111   fprintf(gra_state.out_fp, "/t { show } def\n");
112   fprintf(gra_state.out_fp, "/c { setrgbcolor } def\n");
113   fprintf(gra_state.out_fp, "/p { eofill } def\n");
114   fprintf(gra_state.out_fp, "/f { findfont } def\n");
115   fprintf(gra_state.out_fp, "/h { scalefont } def\n");
116   fprintf(gra_state.out_fp, "/x { setfont } def\n");
117   fprintf(gra_state.out_fp, "/w { setlinewidth } def\n");
118   fprintf(gra_state.out_fp, "/s { gsave } def\n");
119   fprintf(gra_state.out_fp, "/r { grestore } def\n");
120   fprintf(gra_state.out_fp, "/a { rotate } def\n");
121   fprintf(gra_state.out_fp,
122     "gsave clippath pathbbox 2 copy lt { exch } if 0.9 mul dup scale 0.07 dup translate\n");
123   fprintf(gra_state.out_fp, "%g w\n", 0.001);
124 
125   for(i = 0; i < GRA_PS_MAXC; i++)
126   {
127     gra_ps_defcolor(i, gra_ps_rgb[i][0]/255.0,
128                        gra_ps_rgb[i][1]/255.0,
129                        gra_ps_rgb[i][2]/255.0);
130   }
131   fprintf(gra_state.out_fp, "newpath\n");
132   fprintf(gra_state.out_fp, "c1\n");
133 
134   sh = -1;
135 }
136 
gra_ps_close()137 void gra_ps_close()
138 {
139   fprintf(gra_state.out_fp, "showpage grestore\n");
140   gra_close_sys();
141 }
142 
gra_ps_clear()143 void gra_ps_clear()
144 {
145   /* fprintf(gra_state.out_fp, "showpage\n"); */
146 
147   gra_state.cur_point.x =
148   gra_state.cur_point.y = 0;
149 }
150 
gra_ps_flush()151 void gra_ps_flush()
152 {
153 }
154 
gra_ps_reset()155 void gra_ps_reset()
156 {
157 }
158 
gra_ps_defcolor(index,r,g,b)159 void gra_ps_defcolor(index, r, g, b) int index; double r, g, b;
160 {
161   fprintf(gra_state.out_fp, "/c%d {%.3g %.3g %.3g c} def\n", index, r, g, b);
162   if (gra_state.cur_color == index)
163   {
164     fprintf(gra_state.out_fp, "c%d\n", index);
165   }
166 }
167 
gra_ps_color(index)168 void gra_ps_color(index) int index;
169 {
170   if (gra_state.cur_color != index)
171   {
172     fprintf(gra_state.out_fp, "c%d\n", index);
173     gra_state.cur_color = index;
174   }
175 }
176 
gra_ps_polyline(n,p)177 void gra_ps_polyline(n, p) int n; Point *p;
178 {
179   double *xn,*yn,zn, vx, vy;
180   int i, np, nn, ni;
181 
182   if (n > 1)
183   {
184     xn = (double *)ALLOCMEM(n*sizeof(double));
185     yn = (double *)ALLOCMEM(n*sizeof(double));
186 
187     for(i = 1; i < n; i++)
188     {
189       gra_mtrans(p[i].x,p[i].y,p[i].z,&xn[i],&yn[i],&zn);
190     }
191 
192     gra_state.cur_point.x = xn[n];
193     gra_state.cur_point.y = yn[n];
194 
195     nn = n;
196     ni = 0;
197     while(nn > 1)
198     {
199       gra_mtrans(p[ni].x,p[ni].y,p[ni].z,&xn[ni],&yn[ni],&zn);
200       if (clip_line(&nn,&xn[ni],&yn[ni]) > 1)
201       {
202         gra_window_to_viewport(xn[ni],yn[ni],zn,&vx,&vy);
203         fprintf(gra_state.out_fp,"%.3g %.3g m\n", vx, vy);
204         for(np=0,i=1; i < nn; i++)
205         {
206           gra_window_to_viewport(xn[i+ni],yn[i+ni],zn,&vx,&vy);
207           if (np++ > 32 && i != n-1)
208           {
209             fprintf(gra_state.out_fp,
210                     "%.3g %.3g l %.3g %.3g m\n", vx, vy, vx, vy);
211             np = 0;
212           }
213           else
214             fprintf(gra_state.out_fp,"%.3g %.3g l\n", vx, vy);
215         }
216         fprintf(gra_state.out_fp,"d\n");
217         ni += nn - 1;
218       }
219       else
220         ni++;
221       nn  = n - ni;
222     }
223 
224     FREEMEM(yn);
225     FREEMEM(xn);
226   }
227 }
228 
gra_ps_draw(p)229 void gra_ps_draw(p) Point *p;
230 {
231   double vx,vy,xn[2],yn[2],zn;
232   int n = 2;
233 
234   xn[0] = gra_state.cur_point.x;
235   yn[0] = gra_state.cur_point.y;
236 
237   gra_mtrans(p[0].x,p[0].y,p[0].z,&xn[1],&yn[1],&zn);
238 
239   gra_state.cur_point.x = xn[1];
240   gra_state.cur_point.y = yn[1];
241 
242   if (clip_line(&n, xn, yn) > 1)
243   {
244     gra_window_to_viewport(xn[0],yn[0],zn,&vx,&vy);
245     fprintf(gra_state.out_fp,"%.3g %.3g m ",vx,vy);
246 
247     gra_window_to_viewport(xn[1],yn[1],zn,&vx,&vy);
248     fprintf(gra_state.out_fp,"%.3g %.3g l d\n",vx,vy);
249   }
250 }
251 
gra_ps_move(p)252 void gra_ps_move(p) Point *p;
253 {
254   double wx,wy,wz;
255 
256   gra_mtrans(p[0].x,p[0].y,p[0].z,&wx,&wy,&wz);
257 
258   gra_state.cur_point.x = wx;
259   gra_state.cur_point.y = wy;
260 }
261 
gra_ps_polymarker(index,n,p)262 void gra_ps_polymarker(index, n, p) int index, n; Point *p;
263 {
264   double vx,vy,wx,wy,wz;
265   int *x, *y,
266       i,nm;
267 
268   if (gra_state.cur_marker != index)
269   {
270     gra_state.cur_marker = index;
271   }
272 
273   if (n > 0)
274   {
275     x = (int *)ALLOCMEM(n*sizeof(int));
276     y = (int *)ALLOCMEM(n*sizeof(int));
277 
278     for(i=nm=0; i < n; i++)
279     {
280       gra_mtrans(p[i].x,p[i].y,p[i].z,&wx,&wy,&wz);
281 
282       gra_state.cur_point.x = wx;
283       gra_state.cur_point.y = wy;
284 
285       if (wx >= CL_XMIN && wx <= CL_XMAX &&
286           wy >= CL_YMIN && wy <= CL_YMAX)
287       {
288         gra_window_to_viewport(wx,wy,wz,&vx,&vy);
289         nm++;
290       }
291     }
292 
293     FREEMEM(x);
294     FREEMEM(y);
295   }
296 }
297 
gra_ps_marker(index,p)298 void gra_ps_marker(index, p) int index; Point *p;
299 {
300   double wx,wy,wz;
301 
302   gra_mtrans(p[0].x,p[0].y,p[0].z,&wx,&wy,&wz);
303   gra_state.cur_point.x = wx;
304   gra_state.cur_point.y = wy;
305 }
306 
307 
gra_ps_areafill(n,p)308 void gra_ps_areafill(n, p) int n; Point *p;
309 {
310   double vx,vy,*xn,*yn,zn;
311   int i, nn;
312 
313   if (n > 2)
314   {
315     xn = (double *)ALLOCMEM((2*n+2)*sizeof(double));
316     yn = (double *)ALLOCMEM((2*n+2)*sizeof(double));
317 
318     for(i = 0; i < n; i++)
319     {
320       gra_mtrans(p[i].x,p[i].y,p[i].z,&xn[i],&yn[i],&zn);
321     }
322 
323     gra_state.cur_point.x = xn[0];
324     gra_state.cur_point.y = yn[0];
325 
326     nn = n;
327     clip_poly(&nn,xn,yn);
328 
329     if (nn > 2)
330     {
331       gra_window_to_viewport(xn[0],yn[0],zn,&vx,&vy);
332       fprintf(gra_state.out_fp,"%.3g %.3g m\n", vx, vy);
333 
334       for(i = 1; i < nn; i++)
335       {
336         gra_window_to_viewport(xn[i],yn[i],zn,&vx,&vy);
337         fprintf(gra_state.out_fp,"%.3g %.3g l\n", vx, vy);
338       }
339 
340       fprintf(gra_state.out_fp,"p\n");
341     }
342 
343     FREEMEM((char *)yn);
344     FREEMEM((char *)xn);
345   }
346 }
347 
gra_ps_image(w,h,d,r)348 void gra_ps_image(w, h, d, r) int w, h, d; unsigned char *r;
349 {
350   int i, j, k;
351 
352   if (d != 8)
353   {
354     error("gra: ps: driver does (currently) support only 8 bits/pixel.\n");
355     return;
356   }
357 
358   fprintf(gra_state.out_fp, "gsave\n/picstr %d string def\n", w);
359   fprintf(gra_state.out_fp, "%.3g %.3g translate %.3g %.3g scale\n",
360                          gra_state.viewport.xlow,
361                          gra_state.viewport.ylow,
362                          gra_state.viewport.xhigh-gra_state.viewport.xlow,
363                          gra_state.viewport.yhigh-gra_state.viewport.ylow);
364   fprintf(gra_state.out_fp, "%d %d %d [%d 0 0 %d 0 0]\n",w,h,d,w,h);
365   fprintf(gra_state.out_fp, "{ currentfile picstr readhexstring pop } image\n");
366   for(i = k = 0; i < h; i++)
367   {
368     for(j = 0; j < w; j++)
369     {
370       fprintf(gra_state.out_fp,"%02x", *r++);
371       k++;
372       if (k >= 40)
373       {
374         fprintf(gra_state.out_fp,"\n");
375         k = 0;
376       }
377     }
378   }
379   fprintf(gra_state.out_fp," grestore\n");
380 }
381 
gra_ps_text(h,r,str)382 void gra_ps_text(h, r, str) double h, r; char *str;
383 {
384   double wx = gra_state.cur_point.x;
385   double wy = gra_state.cur_point.y;
386   double wz =0.0;
387   double vx,vy;
388 
389   if (!(wx >= CL_XMIN && wx <= CL_XMAX &&
390         wy >= CL_YMIN && wy <= CL_YMAX ) ) return;
391 
392   gra_window_to_viewport(wx,wy,wz,&vx,&vy);
393   fprintf(gra_state.out_fp,"%.3g %.3g m\n", vx, vy );
394 
395   if ( sh != h )
396   {
397     fs = (gra_state.viewport.xhigh-gra_state.viewport.xlow) /
398            (gra_state.window.xhigh-gra_state.window.xlow);
399 
400     fs *= 1.65 * h;
401 
402     sh = h;
403     fprintf(gra_state.out_fp,"/Times-Roman f %g h x\n", fs);
404   }
405 
406   if ( r != 0.0 )
407       fprintf(gra_state.out_fp,"s %.3g a (%s) t r\n", r, str );
408   else
409       fprintf(gra_state.out_fp, "(%s) t\n", str );
410 
411   gra_state.cur_point.x += cos(r*pip180)*fs*strlen(str);
412   gra_state.cur_point.y += sin(r*pip180)*fs*strlen(str);
413 }
414