add Outputable instance for OccIfaceEq
[ghc-hetmet.git] / utils / hp2ps / Axes.c
1 #include "Main.h"
2 #include <stdio.h>
3 #include <string.h>
4 #include "Curves.h"
5 #include "Defines.h"
6 #include "Dimensions.h"
7 #include "HpFile.h"
8 #include "Utilities.h"
9
10 /* own stuff */
11 #include "Axes.h"
12
13 typedef enum {MEGABYTE, KILOBYTE, BYTE} mkb; 
14
15 static void XAxis PROTO((void)); /* forward */
16 static void YAxis PROTO((void)); /* forward */
17
18 static void XAxisMark PROTO((floatish, floatish));      /* forward */
19 static void YAxisMark PROTO((floatish, floatish, mkb)); /* forward */
20
21 static floatish Round PROTO((floatish)); /* forward */
22
23 void
24 Axes()
25 {
26     XAxis();
27     YAxis();
28 }
29
30 static void
31 XAxisMark(x, num)
32   floatish x; floatish num;
33 {
34     /* calibration mark */
35     fprintf(psfp, "%f %f moveto\n", xpage(x), ypage(0.0));
36     fprintf(psfp, "0 -4 rlineto\n");
37     fprintf(psfp, "stroke\n");
38
39     /* number */
40     fprintf(psfp, "HE%d setfont\n", NORMAL_FONT);
41     fprintf(psfp, "(%.1f)\n", num);
42     fprintf(psfp, "dup stringwidth pop\n");
43     fprintf(psfp, "2 div\n");
44     fprintf(psfp, "%f exch sub\n", xpage(x));
45     fprintf(psfp, "%f moveto\n", borderspace);
46     fprintf(psfp, "show\n");
47 }
48
49
50 #define N_X_MARKS        7
51 #define XFUDGE          15      
52
53 extern floatish xrange;
54 extern char *sampleunitstring;
55
56 static void
57 XAxis()
58 {
59     floatish increment, i; 
60     floatish t, x;
61     floatish legendlen;
62  
63     /* draw the x axis line */
64     fprintf(psfp, "%f %f moveto\n", xpage(0.0), ypage(0.0));
65     fprintf(psfp, "%f 0 rlineto\n", graphwidth);
66     fprintf(psfp, "%f setlinewidth\n", borderthick);
67     fprintf(psfp, "stroke\n"); 
68
69     /* draw x axis legend */
70     fprintf(psfp, "HE%d setfont\n", NORMAL_FONT);
71     fprintf(psfp, "(%s)\n", sampleunitstring);
72     fprintf(psfp, "dup stringwidth pop\n");
73     fprintf(psfp, "%f\n", xpage(0.0) + graphwidth);
74     fprintf(psfp, "exch sub\n");
75     fprintf(psfp, "%f moveto\n", borderspace);
76     fprintf(psfp, "show\n");
77
78
79     /* draw x axis scaling */
80
81     increment = Round(xrange / (floatish) N_X_MARKS);
82
83     t = graphwidth / xrange;
84     legendlen = StringSize(sampleunitstring) + (floatish) XFUDGE;
85  
86     for (i = samplemap[0]; i < samplemap[nsamples - 1]; i += increment) {
87         x = (i - samplemap[0]) * t;  
88  
89         if (x < (graphwidth - legendlen)) { 
90             XAxisMark(x,i);
91         } 
92     } 
93 }
94
95 static void
96 YAxisMark(y, num, unit)
97   floatish y; floatish num; mkb unit;
98 {
99     /* calibration mark */
100     fprintf(psfp, "%f %f moveto\n", xpage(0.0), ypage(y));
101     fprintf(psfp, "-4 0 rlineto\n");
102     fprintf(psfp, "stroke\n");
103  
104     /* number */
105     fprintf(psfp, "HE%d setfont\n", NORMAL_FONT);
106
107     switch (unit) {
108     case MEGABYTE :
109         fprintf(psfp, "(");
110         CommaPrint(psfp, (intish) (num / 1e6 + 0.5));
111         fprintf(psfp, "M)\n");
112         break;
113     case KILOBYTE :
114         fprintf(psfp, "(");
115         CommaPrint(psfp, (intish) (num / 1e3 + 0.5));
116         fprintf(psfp, "k)\n");
117         break;
118     case BYTE:
119         fprintf(psfp, "(");
120         CommaPrint(psfp, (intish) (num + 0.5));
121         fprintf(psfp, ")\n");
122         break;
123     }
124
125     fprintf(psfp, "dup stringwidth\n");
126     fprintf(psfp, "2 div\n");
127     fprintf(psfp, "%f exch sub\n", ypage(y));
128
129     fprintf(psfp, "exch\n");
130     fprintf(psfp, "%f exch sub\n", graphx0 - borderspace);
131
132     fprintf(psfp, "exch\n");
133     fprintf(psfp, "moveto\n");
134     fprintf(psfp, "show\n");
135 }
136
137 #define N_Y_MARKS        7      
138 #define YFUDGE          15 
139
140 extern floatish yrange;
141 extern char *valueunitstring;
142
143 static void
144 YAxis()
145 {
146     floatish increment, i;
147     floatish t, y;
148     floatish legendlen;
149     mkb unit;
150
151     /* draw the y axis line */
152     fprintf(psfp, "%f %f moveto\n", xpage(0.0), ypage(0.0));
153     fprintf(psfp, "0 %f rlineto\n", graphheight);
154     fprintf(psfp, "%f setlinewidth\n", borderthick);
155     fprintf(psfp, "stroke\n");
156
157     /* draw y axis legend */
158     fprintf(psfp, "gsave\n");
159     fprintf(psfp, "HE%d setfont\n", NORMAL_FONT);
160     fprintf(psfp, "(%s)\n", valueunitstring);
161     fprintf(psfp, "dup stringwidth pop\n");
162     fprintf(psfp, "%f\n", ypage(0.0) + graphheight);
163     fprintf(psfp, "exch sub\n");
164     fprintf(psfp, "%f exch\n", xpage(0.0) - borderspace);
165     fprintf(psfp, "translate\n");
166     fprintf(psfp, "90 rotate\n");
167     fprintf(psfp, "0 0 moveto\n");
168     fprintf(psfp, "show\n");
169     fprintf(psfp, "grestore\n");
170
171     /* draw y axis scaling */
172     increment = max( yrange / (floatish) N_Y_MARKS, 1.0);
173     increment = Round(increment);
174
175     if (increment >= 1e6) {
176         unit = MEGABYTE;
177     } else if (increment >= 1e3) {
178         unit = KILOBYTE;
179     } else {
180         unit = BYTE;
181     }   
182
183     t = graphheight / yrange; 
184     legendlen = StringSize(valueunitstring) + (floatish) YFUDGE; 
185
186     for (i = 0.0; i <= yrange; i += increment) {
187         y = i * t;
188
189         if (y < (graphheight - legendlen)) {
190             YAxisMark(y, i, unit);
191         }
192     } 
193 }
194
195
196 /*
197  *      Find a "nice round" value to use on the axis.
198  */
199
200 static floatish OneTwoFive PROTO((floatish)); /* forward */
201
202 static floatish
203 Round(y)
204   floatish y;
205 {
206     int i;
207
208     if (y > 10.0) {
209         for (i = 0; y > 10.0; y /= 10.0, i++) ;
210         y = OneTwoFive(y);
211         for ( ; i > 0; y = y * 10.0, i--) ;
212
213     } else if (y < 1.0) {
214         for (i = 0; y < 1.0; y *= 10.0, i++) ;
215         y = OneTwoFive(y);
216         for ( ; i > 0; y = y / 10.0, i--) ;
217  
218     } else {
219         y = OneTwoFive(y);
220     }
221
222     return (y);
223 }
224
225
226 /*
227  * OneTwoFive() -- Runciman's 1,2,5 scaling rule. Argument  1.0 <= y <= 10.0.
228  */
229
230 static floatish
231 OneTwoFive(y)
232   floatish y;
233 {
234     if (y > 4.0) {
235         return (5.0);
236     } else if (y > 1.0) {
237         return (2.0);
238     } else {
239         return (1.0);
240     }   
241 }