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