1 /* SCCS-info %W% %E% */
2
3 /*--------------------------------------------------------------------*/
4 /* */
5 /* VCG : Visualization of Compiler Graphs */
6 /* -------------------------------------- */
7 /* */
8 /* file: PSDev.c */
9 /* version: 1.00.00 */
10 /* creation: 14.4.93 */
11 /* author: G. Sander (Version 1.00.00-...) */
12 /* Universitaet des Saarlandes, 66041 Saarbruecken */
13 /* ESPRIT Project #5399 Compare */
14 /* description: PostScript Device: Print bitmap into a file in */
15 /* PostScript format */
16 /* status: in work */
17 /* */
18 /*--------------------------------------------------------------------*/
19
20
21 #ifndef lint
22 static char *id_string="$Id: PSdev.c,v 1.8 1995/02/08 11:11:14 sander Exp $";
23 #endif
24
25
26 /*
27 * Copyright (C) 1993-2005 Saarland University
28 *
29 * This program and documentation is free software; you can redistribute
30 * it under the terms of the GNU General Public License as published by
31 * the Free Software Foundation; either version 2 of the License, or
32 * (at your option) any later version.
33 *
34 * This program is distributed in the hope that it will be useful,
35 * but WITHOUT ANY WARRANTY; without even the implied warranty of
36 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
37 * GNU General Public License for more details.
38 *
39 * You should have received a copy of the GNU General Public License
40 * along with this program; if not, write to the Free Software
41 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
42 *
43 * The software is available per anonymous ftp at ftp.cs.uni-sb.de.
44 * Contact sander@cs.uni-sb.de for additional information.
45 */
46
47
48 /*
49 * $Log: PSdev.c,v $
50 * Revision 1.8 1995/02/08 11:11:14 sander
51 * Distribution version 1.3.
52 *
53 * Revision 1.7 1994/12/23 18:12:45 sander
54 * Manhatten layout added.
55 * Option interface cleared.
56 * infobox behaviour improved.
57 * First version of fisheye (carthesian).
58 * Options Noedge and nonode.
59 * Titles in the node title box are now sorted.
60 *
61 * Revision 1.6 1994/11/25 15:43:29 sander
62 * Printer interface added to allow to use VCG as a converter.
63 *
64 * Revision 1.5 1994/08/02 15:36:12 sander
65 * Bounding box for landscape format corrected.
66 *
67 * Revision 1.4 1994/06/07 14:09:59 sander
68 * Splines implemented.
69 * HP-UX, Linux, AIX, Sun-Os, IRIX compatibility tested.
70 * The tool is now ready to be distributed.
71 *
72 * Revision 1.3 1994/05/16 08:56:03 sander
73 * shape attribute (boxes, rhombs, ellipses, triangles) added.
74 *
75 * Revision 1.2 1994/05/05 08:20:30 sander
76 * Small corrections.
77 *
78 * Revision 1.1 1994/04/27 16:05:19 sander
79 * Initial revision
80 *
81 *
82 */
83
84 /************************************************************************
85 * This file allows to write the graph into a PostScript file. These
86 * routines are called, if the "export"-menu was selected.
87 *
88 * The implementation idea is a little bit ugly: We use the same
89 * drawing driver "draw.c" and "drawlib.c" and only redefine the
90 * device dependent functions. This duplication of code ensures that
91 * the speed is reasonable. All global function names must be mapped
92 * to new names, otherwise we have linking conflicts.
93 *
94 * Basically, the following function are in this file:
95 * print_all_ps prints the PostScript to a file
96 ************************************************************************/
97
98
99 /* Mapping of global names of draw.c, drawstr.c, drawlib.c
100 * =======================================================
101 */
102
103 #define INCLUDE_DRAW
104 #define POSTSCRIPT_DEVICE
105
106 #define draw_main ps_draw_main
107 #define draw_one_node ps_draw_one_node
108 #define gs_stringw ps_stringw
109 #define gs_stringh ps_stringh
110 #define gs_boxw ps_boxw
111 #define gs_boxh ps_boxh
112
113 #define gs_printstr ps_printstr
114 #define gs_calcstringsize ps_calcstringsize
115 #define gs_setto ps_setto
116 #define gs_setshrink ps_setshrink
117 #define gs_calctextboxsize ps_calctextboxsize
118 #define gs_anchornode ps_anchornode
119 #define gs_textbox ps_textbox
120 #define gs_reverttextbox ps_reverttextbox
121 #define gs_halfreverttextbox ps_halfreverttextbox
122 #define gs_stringbox ps_stringbox
123 #define gs_calcrhombsize ps_calcrhombsize
124 #define gs_rhomb ps_rhomb
125 #define gs_revertrhomb ps_revertrhomb
126 #define gs_halfrevertrhomb ps_halfrevertrhomb
127 #define gs_calctrianglesize ps_calctrianglesize
128 #define gs_triangle ps_triangle
129 #define gs_reverttriangle ps_reverttriangle
130 #define gs_halfreverttriangle ps_halfreverttriangle
131 #define gs_calcellipsesize ps_calcellipsesize
132 #define gs_ellipse ps_ellipse
133 #define gs_revertellipse ps_revertellipse
134 #define gs_halfrevertellipse ps_halfrevertellipse
135 #define gs_solidarrow ps_solidarrow
136 #define gs_dashedarrow ps_dashedarrow
137 #define gs_dottedarrow ps_dottedarrow
138 #define gs_line ps_line
139 #define gs_rectangle ps_rectangle
140 #define gs_actbackground ps_actbackground
141
142 #define mystretch ps_mystretch
143 #define myshrink ps_myshrink
144 #define myxpos ps_myxpos
145 #define myypos ps_myypos
146 #define gs_stlimit ps_stlimit
147 #define gs_shlimit ps_shlimit
148
149
150 /* Includes, Prototypes, Variables
151 * ===============================
152 * We must include globals.h before everything, otherwise we cannot
153 * define the prototypes.
154 * Even if globals.h is included in draw.c and drawlib.c again, this
155 * is correct, because of the include-security mechanism, that prevents
156 * second inclusion of a file from having ugly effects.
157 */
158
159 #include <stdio.h>
160 #include <stdlib.h>
161 #include <math.h>
162 #include "globals.h"
163
164
165 /* Prototypes
166 * ----------
167 */
168
169 static int print_ps
170 _PP((char *fname, int a,int b,int c,int d, float scale, float lm, float bm,
171 float tm, int form, int col, int numpag));
172
173 static FILE *check_and_open_file _PP((char *fname));
174
175 void ps_line
176 _PP((int fx,int fy,int tx,int ty,int c));
177 void ps_thickline
178 _PP((int fx,int fy,int tx,int ty,int t,int c));
179 static void ps_dashedthickline
180 _PP((int fx,int fy,int tx,int ty,int t,int c,int d));
181 static void ps_dottedthickline
182 _PP((int fx,int fy,int tx,int ty,int t,int c,int d));
183 static void ps_bezierspline
184 _PP((int x0,int y0,int x1,int y1,int x2,int y2,int x3,int y3,int t,int c,int m));
185 static void ps_rectangle
186 _PP((int x,int y,int w,int h,int c));
187 static void ps_fillrhomb
188 _PP((int x,int y,int w,int h,int c));
189 static void ps_filltriangle
190 _PP((int x,int y,int w,int h,int c));
191 static void ps_fillellipse
192 _PP((int x,int y,int w,int h,int c));
193 static void ps_freearrowpoint
194 _PP((int x1,int y1,int rx1,int ry1,int rx2,int ry2,int c));
195 static void ps_w_arrowpoint
196 _PP((int x,int y,int size,int c));
197 static void ps_s_arrowpoint
198 _PP((int x,int y,int size,int c));
199 static void ps_n_arrowpoint
200 _PP((int x,int y,int size,int c));
201 static void ps_e_arrowpoint
202 _PP((int x,int y,int size,int c));
203 static void ps_sw_arrowpoint
204 _PP((int x,int y,int size,int c));
205 static void ps_nw_arrowpoint
206 _PP((int x,int y,int size,int c));
207 static void ps_ne_arrowpoint
208 _PP((int x,int y,int size,int c));
209 static void ps_se_arrowpoint
210 _PP((int x,int y,int size,int c));
211
212 static void portrait_header
213 _PP((int a,int b,int c,int d,float scale,float lm, float bm));
214 static void landscape_header
215 _PP((int a,int b,int c,int d,float scale,float lm, float bm));
216
217 static void common_header _PP((void));
218
219 static void init_postscriptpage _PP((void));
220 static void calc_paper_width _PP((void));
221
222 static void ps_setcolor _PP((int c));
223
224
225
226 /* Variables
227 * ---------
228 */
229
230 static char *mfilename;
231
232 /* Flag, wether cps (2), gps (1) or bps (0)
233 */
234
235 static int bps_flag;
236 static FILE *fptr;
237
238 static int dist;
239
240 /* from X11devpb.c */
241
242 extern int act_output_type;
243 extern int act_color_type;
244 extern int act_ori_type;
245 extern int act_paper_num;
246 extern int act_paper_type;
247 extern float act_width;
248 extern float act_height;
249 extern float act_left_margin;
250 extern float act_right_margin;
251 extern float act_top_margin;
252 extern float act_bottom_margin;
253 extern int act_xdpi;
254 extern int act_ydpi;
255 extern float act_scaling;
256 extern int act_bbox;
257
258 /* Counter for the wait message */
259
260 static int wait_cntr;
261
262 static int mreg_xmin;
263 static int mreg_xmax;
264 static int mreg_ymin;
265 static int mreg_ymax;
266 static int maxxdist;
267 static int maxydist;
268 static int maxover;
269
270
271 /* Modules
272 * -------
273 * We use this ugly trick to reuse the files draw.c and drawlib.c
274 */
275
276 #include "draw.c"
277 #include "drawlib.c"
278 #include "PSdev.h"
279
280
281 /*--------------------------------------------------------------------*/
282 /* Print all nodes into a file, Entry point */
283 /*--------------------------------------------------------------------*/
284
285 /* We take the arguments that are setup in X11devpb, recalculate
286 * the measures, and output the graph.
287 */
288
289 #ifdef ANSI_C
print_all_ps(char * fname,int a,int b,int c,int d)290 void print_all_ps(char *fname, int a, int b, int c, int d)
291 #else
292 void print_all_ps(fname, a, b, c, d)
293 char *fname;
294 int a, b, c, d;
295 #endif
296 {
297 int form;
298 float scale, lm, bm, tm;
299
300 assert((act_output_type==3));
301
302
303 wait_cntr = 0;
304 if (a>c) { form = a; a = c; c = form; }
305 if (b>d) { form = b; b = d; d = form; }
306 mreg_xmin = a;
307 mreg_xmax = c;
308 mreg_ymin = b;
309 mreg_ymax = d;
310
311 switch (act_ori_type) {
312 case 1: form = 0; break;
313 case 2: form = 1; break;
314 }
315
316 scale = (float)(act_xdpi)/act_scaling;
317 lm = act_left_margin/2.54;
318 bm = act_bottom_margin/2.54;
319 tm = act_top_margin/2.54;
320
321 switch (act_color_type) {
322 case 1: print_ps(fname, a, b, c, d,scale,lm,bm,tm,form,2,act_paper_num);
323 break;
324 case 2: print_ps(fname, a, b, c, d,scale,lm,bm,tm,form,1,act_paper_num);
325 break;
326 case 3: print_ps(fname, a, b, c, d,scale,lm,bm,tm,form,0,act_paper_num);
327 break;
328 }
329 }
330
331
332
333 /*--------------------------------------------------------------------*/
334 /* Print all nodes into a file, driver */
335 /*--------------------------------------------------------------------*/
336
337 /* Print ps-file
338 * =============
339 * This is the black and white driver. No colors, no grayscales.
340 * The region (a,b)-(c,d) is printed to the file.
341 * The scaling is scale, however different as before, it gives the
342 * scaling of 1 inch. E.g. scale = 300 means we have 300 units per
343 * inch, i.e. 300 dpi.
344 * lm,bm are the left margin, bottom margin in inches.
345 *
346 * We follow the Adobe 2.0 PostScript format with Bounding Box.
347 * Note: the bounding box gives the true size of the picture in 72dpi,
348 * E.g. BoundingBox: 72 72 518 762 is a picture that is on a din A 4
349 * 1 inc far from the border.
350 * A 4 maximal: 0 0 590 834
351 * Letter maximal: 0 0 590 864
352 * form gives the format: 1 is landscape, 0 is portrait
353 * We return 1 on success.
354 */
355
356
357 #ifdef ANSI_C
print_ps(char * fname,int a,int b,int c,int d,float scale,float lm,float bm,float tm,int form,int col,int numpag)358 static int print_ps(char *fname,int a,int b,int c,int d,float scale,float lm,float bm,float tm,int form,int col,int numpag)
359 #else
360 static int print_ps(fname, a, b, c, d,scale,lm,bm,tm,form,col,numpag)
361 char *fname;
362 int a,b,c,d;
363 float scale;
364 float lm,bm,tm;
365 int form;
366 int col;
367 int numpag;
368 #endif
369 {
370 int Vs_xmin, Vs_ymin, Vs_xmax, Vs_ymax;
371 int s_stretch, s_shrink, oldcol;
372 int i, j;
373 int oldx, oldy;
374
375 mfilename = fname;
376 bps_flag = col;
377
378 if (c<=a) return(0);
379 if (d<=b) return(0);
380
381 if (act_paper_num > 1) {
382 lm = 1.0/2.54;
383 bm = 1.0/2.54;
384 tm = 1.0/2.54;
385 calc_paper_width();
386 act_bbox = 0;
387 }
388
389 fptr = check_and_open_file(fname);
390 if (fptr==NULL) return(0);
391
392 /* save old values */
393 Vs_xmin = V_xmin; Vs_ymin = V_ymin;
394 Vs_xmax = V_xmax; Vs_ymax = V_ymax;
395 s_shrink = G_shrink; s_stretch = G_stretch;
396 oldcol = colored;
397
398 /* install printout values. We leave the scaling to postscript */
399 V_xmin = a; V_ymin = b;
400 V_xmax = c; V_ymax = d;
401 G_shrink = 1; G_stretch = 1;
402
403 switch (bps_flag) {
404 case 2: colored = 1; break;
405 case 1: colored = 1; break;
406 case 0: colored = 0; break;
407 }
408
409 wait_cntr = 0;
410
411 /* Header */
412 if (form == 1) landscape_header(a, b, c, d, scale, lm, tm);
413 else portrait_header( a, b, c, d, scale, lm, bm);
414
415 oldx = mreg_xmin;
416 for (i=1; i<=numpag; i++) {
417 if (numpag!=1) {
418 a = oldx;
419 if (a>=mreg_xmax) break;
420 c = a + maxxdist + maxover;
421 oldx = a + maxxdist;
422 if (c>=mreg_xmax) {
423 oldx = mreg_xmax;
424 c = mreg_xmax;
425 }
426 oldy = mreg_ymin;
427 }
428 for (j=1; j<=numpag; j++) {
429
430 gs_wait_message('y');
431
432 if (numpag==1) {
433 a = mreg_xmin;
434 c = mreg_xmax;
435 b = mreg_ymin;
436 d = mreg_ymax;
437 }
438 else {
439 b = oldy;
440 if (b>=mreg_ymax) break;
441
442 d = b + maxydist + maxover;
443 oldy = b + maxydist;
444 if (d>=mreg_ymax) {
445 oldy = mreg_ymax;
446 d = mreg_ymax;
447 }
448 }
449 V_xmin = a;
450 V_xmax = c;
451 V_ymin = b;
452 V_ymax = d;
453 dist = V_ymax-V_ymin;
454
455 FPRINTF(fptr,"%%%%Page: %d %d\n",
456 (i-1)*numpag+j, (i-1)*numpag+j);
457 /* if (numpag>1) init_postscriptpage(); */
458 FPRINTF(fptr,"72 %3.2f div dup scale\n",scale);
459 if (numpag == 1) {
460 if (form == 1) {
461 FPRINTF(fptr,"90 rotate\n");
462 FPRINTF(fptr,"%f %f translate\n",
463 lm*scale,
464 -tm*scale
465 -(float)(d-b));
466 }
467 else {
468 FPRINTF(fptr,"%f %f translate\n",
469 lm*scale,bm*scale);
470 }
471 }
472 else {
473 if (form == 1) {
474 FPRINTF(fptr,"90 rotate\n");
475 FPRINTF(fptr,"%f %f translate\n",
476 0.39*scale,
477 -0.39*scale
478 -(float)(d-b));
479 }
480 else {
481 FPRINTF(fptr,"%f %f translate\n",
482 0.39*scale,0.39*scale);
483 }
484 }
485
486 /* draw to file */
487
488 if (colored) {
489 ps_rectangle(V_xmin, V_ymin, V_xmax-V_xmin, V_ymax-V_ymin, G_color);
490 }
491 else {
492 ps_rectangle(V_xmin, V_ymin, V_xmax-V_xmin, V_ymax-V_ymin, WHITE);
493 }
494 ps_draw_main();
495
496 FPRINTF(fptr,"showpage\n");
497 FPRINTF(fptr,"%%%%PageTrailer\n");
498 }
499 }
500 FPRINTF(fptr,"%%%%Trailer\n");
501 FPRINTF(fptr,"%%%%EOF\n");
502
503 if (fptr) fclose(fptr);
504 fptr = NULL;
505
506 /* restore old values */
507 V_xmin = Vs_xmin; V_ymin = Vs_ymin;
508 V_xmax = Vs_xmax; V_ymax = Vs_ymax;
509 G_shrink = s_shrink; G_stretch = s_stretch;
510 colored = oldcol;
511 return(1);
512 }
513
514
515
516
517
518 /* Check a file
519 * ------------
520 * Try to open a file `fname' for writing.
521 * If the file exists already, or the filename is not appropriate,
522 * it is an error.
523 * On error, we return NULL, otherwise the opend file.
524 */
525
526 #ifdef ANSI_C
check_and_open_file(char * fname)527 static FILE *check_and_open_file(char *fname)
528 #else
529 static FILE *check_and_open_file(fname)
530 char *fname;
531 #endif
532 {
533 FILE *f;
534 char *c;
535
536 c = fname;
537 while (*c) c++;
538 if (c>fname) c--;
539 #ifdef VMS
540 if (*c==']') {
541 #else
542 if (*c=='/') {
543 #endif
544 return(NULL);
545 }
546
547 /* check whether filename is useful */
548 if (!fname) return(NULL);
549 if (!*fname) return(NULL);
550
551 /* check whether file already exists */
552 f = fopen(fname,"r");
553 if (f) { fclose(f); return(NULL); }
554
555 f = fopen(fname,"w");
556 return(f);
557 }
558
559
560 /*--------------------------------------------------------------------*/
561 /* Initializing sequences for PostScript */
562 /*--------------------------------------------------------------------*/
563
564 /* Portrait format
565 * ---------------
566 */
567
568 #ifdef ANSI_C
portrait_header(int a,int b,int c,int d,float scale,float lm,float bm)569 static void portrait_header(int a,int b,int c,int d,float scale,float lm,float bm)
570 #else
571 static void portrait_header(a, b, c, d, scale, lm, bm)
572 int a, b, c, d;
573 float scale, lm, bm;
574 #endif
575 {
576 float numxunits, numyunits;
577
578 assert((c>a));
579 assert((d>b));
580
581 numxunits = (float)(c-a);
582 numyunits = (float)(d-b);
583
584 FPRINTF(fptr,"%%!PS-Adobe-2.0 EPSF-1.2\n");
585 FPRINTF(fptr,"%%%%Creator: %s (P)\n", short_banner);
586 FPRINTF(fptr,"%%%%Title: %s\n", mfilename);
587 FPRINTF(fptr,"%%%%RCS-info: $I");
588 FPRINTF(fptr,"d$\n");
589 FPRINTF(fptr,"%%%%SCCS-info: %%W");
590 FPRINTF(fptr,"%% %%E");
591 FPRINTF(fptr,"%%\n");
592 if (act_bbox) FPRINTF(fptr,"%%%%BoundingBox: ");
593 else FPRINTF(fptr,"%%%%ProposedBoundings: ");
594 FPRINTF(fptr," %d %d %d %d\n",
595 gstoint(lm*72),gstoint(bm*72),
596 gstoint(lm*72)+gstoint(72*numxunits/scale),
597 gstoint(bm*72)+gstoint(72*numyunits/scale));
598
599 FPRINTF(fptr,"%%%%EndComments\n");
600
601 common_header();
602 }
603
604
605 /* Landscape format
606 * ----------------
607 */
608
609 #ifdef ANSI_C
landscape_header(int a,int b,int c,int d,float scale,float lm,float tm)610 static void landscape_header(int a,int b,int c,int d,float scale,float lm,float tm)
611 #else
612 static void landscape_header(a, b, c, d, scale, lm, tm)
613 int a, b, c, d;
614 float scale, lm, tm;
615 #endif
616 {
617 float numxunits, numyunits;
618
619 assert((c>a));
620 assert((d>b));
621
622 numxunits = (float)(c-a);
623 numyunits = (float)(d-b);
624
625 FPRINTF(fptr,"%%!PS-Adobe-2.0 EPSF-1.2\n");
626 FPRINTF(fptr,"%%%%Creator: %s (L)\n", short_banner);
627 FPRINTF(fptr,"%%%%Title: %s\n", mfilename);
628 FPRINTF(fptr,"%%%%RCS-info: $I");
629 FPRINTF(fptr,"d$\n");
630 FPRINTF(fptr,"%%%%SCCS-info: %%W");
631 FPRINTF(fptr,"%% %%E");
632 FPRINTF(fptr,"%%\n");
633 if (act_bbox) FPRINTF(fptr,"%%%%BoundingBox: ");
634 else FPRINTF(fptr,"%%%%ProposedBoundings: ");
635 FPRINTF(fptr," %d %d %d %d\n",
636 gstoint(tm*72),gstoint(lm*72),
637 gstoint(tm*72)+gstoint(72*numyunits/scale),
638 gstoint(lm*72)+gstoint(72*numxunits/scale));
639 FPRINTF(fptr,"%%%%EndComments\n");
640
641 common_header();
642 }
643
644
645 /* Common Header for both formats
646 */
647
648 #ifdef ANSI_C
common_header(void)649 static void common_header(void)
650 #else
651 static void common_header()
652 #endif
653 {
654 FPRINTF(fptr,"1 setlinecap\n");
655 FPRINTF(fptr,"1 setlinejoin\n");
656
657 /* Position turtle without drawing */
658
659 FPRINTF(fptr,"/M /moveto load def\n");
660
661 /* Draw linw from actual point to specified point */
662
663 FPRINTF(fptr,"/D { lineto currentpoint stroke moveto } def\n");
664
665 /* Define line from actual point to specified point without drawing */
666
667 FPRINTF(fptr,"/P /lineto load def\n");
668
669 /* Text print command (currently not used) */
670
671 FPRINTF(fptr,"/S /show load def\n");
672
673 /* Set gray value color. 0 = Black */
674
675 FPRINTF(fptr,"/G /setgray load def\n");
676
677 /* Set real RGB color */
678
679 FPRINTF(fptr,"/C /setrgbcolor load def\n");
680
681 /* Set line width */
682
683 FPRINTF(fptr,"/LW /setlinewidth load def\n");
684
685 /* Define a new path (for filling) */
686
687 FPRINTF(fptr,"/NP /newpath load def\n");
688
689 /* Close a path, i.e. combine start and end point */
690
691 FPRINTF(fptr,"/CP /closepath load def\n");
692
693 /* Set Dashing mode */
694
695 FPRINTF(fptr,"/SD /setdash load def\n");
696
697 /* Default line thickness is 1 */
698
699 FPRINTF(fptr,"1 LW\n");
700 }
701
702
703 /* Initialize a page, i.e. fill the whole page with the background color
704 * ---------------------------------------------------------------------
705 */
706
707 #ifdef ANSI_C
init_postscriptpage(void)708 static void init_postscriptpage(void)
709 #else
710 static void init_postscriptpage()
711 #endif
712 {
713 int a, b, h;
714
715 switch (act_paper_type) {
716 case 1: a = 595; b = 850; break;
717 case 2: a = 525; b = 765; break;
718 case 3: a = 425; b = 595; break;
719 case 4: a = 792; b = 1224; break;
720 case 5: a = 612; b = 792; break;
721 case 6: a = 612; b = 1008; break;
722 }
723
724 if (colored) ps_setcolor(G_color);
725 else ps_setcolor(WHITE);
726
727 FPRINTF(fptr,"NP %d %d M %d %d P %d %d P %d %d P CP fill\n",
728 0, 0, 0, b, a, b, a, 0);
729 }
730
731
732
733 /* Calculate the maximal number of pixels on a page
734 * ------------------------------------------------
735 * This is used for multipage output only.
736 */
737
738 #ifdef ANSI_C
calc_paper_width(void)739 static void calc_paper_width(void)
740 #else
741 static void calc_paper_width()
742 #endif
743 {
744 float mx, my;
745
746 assert((act_paper_num>1));
747 switch (act_paper_type) {
748 case 1:
749 if (act_ori_type==1) { mx = 21.0; my = 30.0; }
750 else { mx = 30.0; my = 21.0; }
751 break;
752 case 2:
753 if (act_ori_type==1) { mx = 18.5; my = 27.0; }
754 else { mx = 27.0; my = 18.5; }
755 break;
756 case 3:
757 if (act_ori_type==1) { mx = 15.0; my = 21.0; }
758 else { mx = 21.0; my = 15.0; }
759 break;
760 case 4:
761 if (act_ori_type==1) { mx = 27.94; my = 43.18; }
762 else { mx = 43.18; my = 27.94; }
763 break;
764 case 5:
765 if (act_ori_type==1) { mx = 21.59; my = 27.94; }
766 else { mx = 27.94; my = 21.59; }
767 break;
768 case 6:
769 if (act_ori_type==1) { mx = 21.59; my = 35.56; }
770 else { mx = 35.56; my = 21.59; }
771 break;
772 }
773 mx = (mx-3.0);
774 my = (my-3.0);
775 maxxdist = (int)(mx * act_xdpi / act_scaling / 2.54);
776 maxydist = (int)(my * act_ydpi / act_scaling / 2.54);
777 maxover = (int)(1.0 * act_ydpi / act_scaling / 2.54);
778 }
779
780
781 /*--------------------------------------------------------------------*/
782 /* Device driver for pbm and ppm Files */
783 /*--------------------------------------------------------------------*/
784
785 #ifdef ANSI_C
ps_setcolor(int c)786 static void ps_setcolor(int c)
787 #else
788 static void ps_setcolor(c)
789 int c;
790 #endif
791 {
792 float col;
793
794 wait_cntr++;
795 if (wait_cntr > 40) { gs_wait_message('x'); wait_cntr = 0; }
796
797 switch(bps_flag) {
798 case 0:
799 if (c==WHITE) FPRINTF(fptr,"1.0 G ");
800 else FPRINTF(fptr,"0.0 G ");
801 break;
802 case 1:
803 col = (float)(299*redmap[c]+587*greenmap[c]+114*bluemap[c]);
804 FPRINTF(fptr,"%3.2f G ", col/1000.0/255.0);
805 break;
806 case 2:
807 FPRINTF(fptr,"%3.2f %3.2f %3.2f C ",
808 redmap[c]/255.0, greenmap[c]/255.0, bluemap[c]/255.0);
809 break;
810 }
811 }
812
813
814 /* Draw a rectangle
815 * ----------------
816 * at (x,y) with width w, height h and color c
817 */
818
819 #ifdef ANSI_C
ps_rectangle(int x,int y,int w,int h,int c)820 static void ps_rectangle(int x,int y,int w,int h,int c)
821 #else
822 static void ps_rectangle(x, y, w, h, c)
823 int x, y, w, h, c;
824 #endif
825 {
826 ps_setcolor(c);
827
828 FPRINTF(fptr,"NP %d %d M %d %d P %d %d P %d %d P CP fill\n",
829 x-V_xmin, dist - (y-V_ymin),
830 x-V_xmin+w, dist - (y-V_ymin),
831 x-V_xmin+w, dist - (y-V_ymin+h),
832 x-V_xmin, dist - (y-V_ymin+h));
833 }
834
835
836 /* Draw a rhomb
837 * ------------
838 * at (x,y) with width w, height h and color c
839 */
840
841 #ifdef ANSI_C
ps_fillrhomb(int x,int y,int w,int h,int c)842 static void ps_fillrhomb(int x,int y,int w,int h,int c)
843 #else
844 static void ps_fillrhomb(x, y, w, h, c)
845 int x, y, w, h, c;
846 #endif
847 {
848 ps_setcolor(c);
849
850 FPRINTF(fptr,"NP %d %d M %d %d P %d %d P %d %d P CP fill\n",
851 x-V_xmin, dist - (y-V_ymin+h/2),
852 x-V_xmin+w/2, dist - (y-V_ymin),
853 x-V_xmin+w, dist - (y-V_ymin+h/2),
854 x-V_xmin+w/2, dist - (y-V_ymin+h));
855 }
856
857
858 /* Draw a triangle
859 * ---------------
860 * at (x,y) with width w, height h and color c
861 */
862
863 #ifdef ANSI_C
ps_filltriangle(int x,int y,int w,int h,int c)864 static void ps_filltriangle(int x,int y,int w,int h,int c)
865 #else
866 static void ps_filltriangle(x, y, w, h, c)
867 int x, y, w, h, c;
868 #endif
869 {
870 ps_setcolor(c);
871
872 switch (G_orientation) {
873 case LEFT_TO_RIGHT:
874 FPRINTF(fptr,"NP %d %d M %d %d P %d %d P CP fill\n",
875 x-V_xmin+w , dist - (y-V_ymin),
876 x-V_xmin+w , dist - (y-V_ymin+h),
877 x-V_xmin , dist - (y-V_ymin+h/2));
878 return;
879 case RIGHT_TO_LEFT:
880 FPRINTF(fptr,"NP %d %d M %d %d P %d %d P CP fill\n",
881 x-V_xmin , dist - (y-V_ymin),
882 x-V_xmin , dist - (y-V_ymin+h),
883 x-V_xmin+w, dist - (y-V_ymin+h/2));
884 return;
885 case BOTTOM_TO_TOP:
886 FPRINTF(fptr,"NP %d %d M %d %d P %d %d P CP fill\n",
887 x-V_xmin+w/2, dist - (y-V_ymin+h),
888 x-V_xmin+w , dist - (y-V_ymin),
889 x-V_xmin , dist - (y-V_ymin));
890 return;
891 case TOP_TO_BOTTOM:
892 FPRINTF(fptr,"NP %d %d M %d %d P %d %d P CP fill\n",
893 x-V_xmin+w/2, dist - (y-V_ymin),
894 x-V_xmin+w , dist - (y-V_ymin+h),
895 x-V_xmin , dist - (y-V_ymin+h));
896 return;
897 }
898 }
899
900
901 /* Draw an ellipse
902 * ---------------
903 * at (x,y) with width w, height h and color c
904 */
905
906 #ifdef ANSI_C
ps_fillellipse(int x,int y,int w,int h,int c)907 static void ps_fillellipse(int x,int y,int w,int h,int c)
908 #else
909 static void ps_fillellipse(x, y, w, h, c)
910 int x, y, w, h, c;
911 #endif
912 {
913 int i,j;
914
915 ps_setcolor(c);
916
917 FPRINTF(fptr,"NP %d %d M\n", x+w/2-V_xmin, dist-(y+h-V_ymin));
918 for (i=0; i<=(w+1)/2; i++) {
919 j = h*h/4 - i*h/w * i*h/w;
920 if (j>=0) j = gstoint(sqrt((double)j));
921 else j = 0;
922 FPRINTF(fptr,"%d %d P\n",
923 x+w/2+i-V_xmin, dist-(y+h/2+j-V_ymin));
924 }
925 for (i=(w+1)/2; i>0; i--) {
926 j = h*h/4 - i*h/w * i*h/w;
927 if (j>=0) j = gstoint(sqrt((double)j));
928 else j = 0;
929 FPRINTF(fptr,"%d %d P\n",
930 x+w/2+i-V_xmin, dist-(y+h/2-j-V_ymin));
931 }
932 for (i=0; i<=(w+1)/2; i++) {
933 j = h*h/4 - i*h/w * i*h/w;
934 if (j>=0) j = gstoint(sqrt((double)j));
935 else j = 0;
936 FPRINTF(fptr,"%d %d P\n",
937 x+w/2-i-V_xmin, dist-(y+h/2-j-V_ymin));
938 }
939 for (i=(w+1)/2; i>0; i--) {
940 j = h*h/4 - i*h/w * i*h/w;
941 if (j>=0) j = gstoint(sqrt((double)j));
942 else j = 0;
943 FPRINTF(fptr,"%d %d P\n",
944 x+w/2-i-V_xmin, dist-(y+h/2+j-V_ymin));
945 }
946
947 FPRINTF(fptr,"CP fill\n");
948 }
949
950
951 /* Draw a line
952 * -----------
953 * from fx,fy to tx,ty with color c.
954 */
955
956 #ifdef ANSI_C
ps_line(int fx,int fy,int tx,int ty,int c)957 void ps_line(int fx,int fy,int tx,int ty,int c)
958 #else
959 void ps_line(fx, fy, tx, ty, c)
960 int fx, fy, tx, ty, c;
961 #endif
962 {
963 ps_setcolor(c);
964
965 FPRINTF(fptr,"%d %d M %d %d D\n",
966 fx-V_xmin, dist - (fy-V_ymin),
967 tx-V_xmin, dist - (ty-V_ymin));
968
969 }
970
971
972 /* Draw a solid line of thickness t
973 * --------------------------------
974 * from fx,fy to tx,ty with color c.
975 */
976
977 #ifdef ANSI_C
ps_thickline(int fx,int fy,int tx,int ty,int t,int c)978 void ps_thickline(int fx,int fy,int tx,int ty,int t,int c)
979 #else
980 void ps_thickline(fx, fy, tx, ty, t, c)
981 int fx, fy, tx, ty, t, c;
982 #endif
983 {
984 ps_setcolor(c);
985
986 FPRINTF(fptr,"%d LW ",t);
987 FPRINTF(fptr,"%d %d M %d %d D 1 LW\n",
988 fx-V_xmin, dist - (fy-V_ymin),
989 tx-V_xmin, dist - (ty-V_ymin));
990 }
991
992
993 /* Draw a dashed line of thickness t
994 * ---------------------------------
995 * from fx,fy to tx,ty with color c.
996 */
997
998 #ifdef ANSI_C
ps_dashedthickline(int fx,int fy,int tx,int ty,int t,int c,int d)999 static void ps_dashedthickline(int fx,int fy,int tx,int ty,int t,int c,int d)
1000 #else
1001 static void ps_dashedthickline(fx, fy, tx, ty, t, c, d)
1002 int fx, fy, tx, ty, t, c, d;
1003 #endif
1004 {
1005 ps_setcolor(c);
1006
1007 FPRINTF(fptr,"[ %d %d ] 0 SD %d LW ",d,d,t);
1008 FPRINTF(fptr,"%d %d M %d %d D [ 100 0 ] 0 SD 1 LW\n",
1009 fx-V_xmin, dist - (fy-V_ymin),
1010 tx-V_xmin, dist - (ty-V_ymin));
1011 }
1012
1013
1014 /* Draw a dotted line of thickness t
1015 * ---------------------------------
1016 * from fx,fy to tx,ty with color c.
1017 */
1018
1019 #ifdef ANSI_C
ps_dottedthickline(int fx,int fy,int tx,int ty,int t,int c,int d)1020 static void ps_dottedthickline(int fx,int fy,int tx,int ty,int t,int c,int d)
1021 #else
1022 static void ps_dottedthickline(fx, fy, tx, ty, t, c, d)
1023 int fx, fy, tx, ty, t, c, d;
1024 #endif
1025 {
1026 ps_setcolor(c);
1027
1028 FPRINTF(fptr,"[ 1 %d ] 0 SD %d LW ",d,t);
1029 FPRINTF(fptr,"%d %d M %d %d D [ 100 0 ] 0 SD 1 LW\n",
1030 fx-V_xmin, dist - (fy-V_ymin),
1031 tx-V_xmin, dist - (ty-V_ymin));
1032 }
1033
1034
1035 /* Draw a bezier spline of thickness t
1036 * -----------------------------------
1037 * with color c and mode m.
1038 */
1039
1040 #ifdef ANSI_C
ps_bezierspline(int x0,int y0,int x1,int y1,int x2,int y2,int x3,int y3,int t,int c,int m)1041 static void ps_bezierspline(
1042 int x0,int y0,int x1,int y1,int x2,int y2,int x3,int y3,
1043 int t,int c,int m)
1044 #else
1045 static void ps_bezierspline(x0,y0,x1,y1,x2,y2,x3,y3,t,c,m)
1046 int x0,y0,x1,y1,x2,y2,x3,y3,t,c,m;
1047 #endif
1048 {
1049 int d;
1050
1051 ps_setcolor(c);
1052
1053 switch (m) {
1054 case SOLID:
1055 FPRINTF(fptr,"%d LW ",t);
1056 break;
1057 case DOTTED:
1058 d = 15*3*G_stretch/12/G_shrink;
1059 FPRINTF(fptr,"[ 1 %d ] 0 SD %d LW ",d,t);
1060 break;
1061 case DASHED:
1062 d = 15*G_stretch/G_shrink;
1063 FPRINTF(fptr,"[ %d %d ] 0 SD %d LW ",d,d,t);
1064 break;
1065 case UNVISIBLE:
1066 return;
1067 }
1068 FPRINTF(fptr,"%d %d M %d %d ",
1069 x0-V_xmin, dist - (y0-V_ymin),
1070 x1-V_xmin, dist - (y1-V_ymin));
1071 FPRINTF(fptr,"%d %d %d %d curveto stroke\n",
1072 x2-V_xmin, dist - (y2-V_ymin),
1073 x3-V_xmin, dist - (y3-V_ymin));
1074 FPRINTF(fptr,"[ 100 0] 0 SD 1 LW\n");
1075 }
1076
1077
1078 /* Draw a free arrowhead
1079 * ---------------------
1080 * i.e. draw a triangle between (x1, y1), (rx1, ry1), (rx2, ry2)
1081 */
1082
1083
1084 #ifdef ANSI_C
ps_freearrowpoint(int x1,int y1,int rx1,int ry1,int rx2,int ry2,int c)1085 static void ps_freearrowpoint(int x1,int y1,int rx1,int ry1,int rx2,int ry2,
1086 int c)
1087 #else
1088 static void ps_freearrowpoint(x1, y1, rx1, ry1, rx2, ry2, c)
1089 int x1, y1, rx1, ry1, rx2, ry2, c;
1090 #endif
1091 {
1092 ps_setcolor(c);
1093 FPRINTF(fptr,"NP %d %d M %d %d P %d %d P CP fill\n",
1094 x1-V_xmin, dist - (y1-V_ymin),
1095 rx1-V_xmin,dist - (ry1-V_ymin),
1096 rx2-V_xmin,dist - (ry2-V_ymin));
1097 }
1098
1099
1100
1101 /* Draw an arrowhead to the north
1102 * ------------------------------
1103 * with `size' of katheses and color
1104 */
1105
1106 #ifdef ANSI_C
ps_n_arrowpoint(int x,int y,int size,int c)1107 static void ps_n_arrowpoint(int x,int y,int size,int c)
1108 #else
1109 static void ps_n_arrowpoint(x, y, size, c)
1110 int x, y, size, c;
1111 #endif
1112 {
1113 int k;
1114
1115 ps_setcolor(c);
1116
1117 k = 7*size/10 - 1;
1118
1119 FPRINTF(fptr,"NP %d %d M %d %d P %d %d P CP fill\n",
1120 x-k-V_xmin, dist - (y+k-V_ymin),
1121 x-V_xmin, dist - (y-V_ymin),
1122 x+k-V_xmin, dist - (y+k-V_ymin));
1123 }
1124
1125
1126 /* Draw an arrowhead to the south
1127 * ------------------------------
1128 * with `size' of katheses and color
1129 */
1130
1131 #ifdef ANSI_C
ps_s_arrowpoint(int x,int y,int size,int c)1132 static void ps_s_arrowpoint(int x,int y,int size,int c)
1133 #else
1134 static void ps_s_arrowpoint(x, y, size, c)
1135 int x, y, size, c;
1136 #endif
1137 {
1138 int k;
1139
1140 ps_setcolor(c);
1141
1142 k = 7*size/10 - 1;
1143
1144 FPRINTF(fptr,"NP %d %d M %d %d P %d %d P CP fill\n",
1145 x-k-V_xmin, dist - (y-k-V_ymin),
1146 x-V_xmin, dist - (y-V_ymin),
1147 x+k-V_xmin, dist - (y-k-V_ymin));
1148 }
1149
1150
1151
1152 /* Draw an arrowhead to the east
1153 * -----------------------------
1154 * with `size' of katheses and color
1155 */
1156
1157 #ifdef ANSI_C
ps_e_arrowpoint(int x,int y,int size,int c)1158 static void ps_e_arrowpoint(int x,int y,int size,int c)
1159 #else
1160 static void ps_e_arrowpoint(x, y, size, c)
1161 int x, y, size, c;
1162 #endif
1163 {
1164 int k;
1165
1166 ps_setcolor(c);
1167
1168 k = 7*size/10 - 1;
1169
1170 FPRINTF(fptr,"NP %d %d M %d %d P %d %d P CP fill\n",
1171 x-k-V_xmin, dist - (y-k-V_ymin),
1172 x-V_xmin, dist - (y-V_ymin),
1173 x-k-V_xmin, dist - (y+k-V_ymin));
1174 }
1175
1176
1177
1178 /* Draw an arrowhead to the west
1179 * -----------------------------
1180 * with `size' of katheses and color
1181 */
1182
1183 #ifdef ANSI_C
ps_w_arrowpoint(int x,int y,int size,int c)1184 static void ps_w_arrowpoint(int x,int y,int size,int c)
1185 #else
1186 static void ps_w_arrowpoint(x, y, size, c)
1187 int x, y, size, c;
1188 #endif
1189 {
1190 int k;
1191
1192 ps_setcolor(c);
1193
1194 k = 7*size/10 - 1;
1195
1196 FPRINTF(fptr,"NP %d %d M %d %d P %d %d P CP fill\n",
1197 x+k-V_xmin, dist - (y-k-V_ymin),
1198 x-V_xmin, dist - (y-V_ymin),
1199 x+k-V_xmin, dist - (y+k-V_ymin));
1200 }
1201
1202
1203 /* Draw an arrowhead to the northeast
1204 * ----------------------------------
1205 * with `size' of katheses and color
1206 */
1207
1208 #ifdef ANSI_C
ps_ne_arrowpoint(int x,int y,int size,int c)1209 static void ps_ne_arrowpoint(int x,int y,int size,int c)
1210 #else
1211 static void ps_ne_arrowpoint(x, y, size, c)
1212 int x, y, size, c;
1213 #endif
1214 {
1215 ps_setcolor(c);
1216
1217 FPRINTF(fptr,"NP %d %d M %d %d P %d %d P CP fill\n",
1218 x-size+1-V_xmin, dist - (y-V_ymin),
1219 x-V_xmin, dist - (y-V_ymin),
1220 x-V_xmin, dist - (y+size-1-V_ymin));
1221 }
1222
1223
1224 /* Draw an arrowhead to the northwest
1225 * ----------------------------------
1226 * with `size' of katheses and color
1227 */
1228
1229 #ifdef ANSI_C
ps_nw_arrowpoint(int x,int y,int size,int c)1230 static void ps_nw_arrowpoint(int x,int y,int size,int c)
1231 #else
1232 static void ps_nw_arrowpoint(x, y, size, c)
1233 int x, y, size, c;
1234 #endif
1235 {
1236 ps_setcolor(c);
1237
1238 FPRINTF(fptr,"NP %d %d M %d %d P %d %d P CP fill\n",
1239 x+size-1-V_xmin, dist - (y-V_ymin),
1240 x-V_xmin, dist - (y-V_ymin),
1241 x-V_xmin, dist - (y+size-1-V_ymin));
1242 }
1243
1244
1245 /* Draw an arrowhead to the southeast
1246 * ----------------------------------
1247 * with `size' of katheses and color
1248 */
1249
1250 #ifdef ANSI_C
ps_se_arrowpoint(int x,int y,int size,int c)1251 static void ps_se_arrowpoint(int x,int y,int size,int c)
1252 #else
1253 static void ps_se_arrowpoint(x, y, size, c)
1254 int x, y, size, c;
1255 #endif
1256 {
1257 ps_setcolor(c);
1258
1259 FPRINTF(fptr,"NP %d %d M %d %d P %d %d P CP fill\n",
1260 x-size+1-V_xmin, dist - (y-V_ymin),
1261 x-V_xmin, dist - (y-V_ymin),
1262 x-V_xmin, dist - (y-size+1-V_ymin));
1263 }
1264
1265
1266 /* Draw an arrowhead to the southwest
1267 * ----------------------------------
1268 * with `size' of katheses and color
1269 */
1270
1271 #ifdef ANSI_C
ps_sw_arrowpoint(int x,int y,int size,int c)1272 static void ps_sw_arrowpoint(int x,int y,int size,int c)
1273 #else
1274 static void ps_sw_arrowpoint(x, y, size, c)
1275 int x, y, size, c;
1276 #endif
1277 {
1278 ps_setcolor(c);
1279
1280 FPRINTF(fptr,"NP %d %d M %d %d P %d %d P CP fill\n",
1281 x+size-1-V_xmin, dist - (y-V_ymin),
1282 x-V_xmin, dist - (y-V_ymin),
1283 x-V_xmin, dist - (y-size+1-V_ymin));
1284 }
1285
1286
1287
1288 /*--------------------------------------------------------------------*/
1289
1290