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