Blame


1 5cedca1b 2004-05-15 devnull #include <stdio.h>
2 5cedca1b 2004-05-15 devnull #include <stdlib.h>
3 5cedca1b 2004-05-15 devnull #include <string.h>
4 5cedca1b 2004-05-15 devnull #include <math.h>
5 5cedca1b 2004-05-15 devnull #include "grap.h"
6 5cedca1b 2004-05-15 devnull #include "y.tab.h"
7 5cedca1b 2004-05-15 devnull
8 5cedca1b 2004-05-15 devnull #define MAXTICK 200
9 5cedca1b 2004-05-15 devnull int ntick = 0;
10 5cedca1b 2004-05-15 devnull double tickval[MAXTICK]; /* tick values (one axis at a time */
11 5cedca1b 2004-05-15 devnull char *tickstr[MAXTICK]; /* and labels */
12 5cedca1b 2004-05-15 devnull
13 5cedca1b 2004-05-15 devnull int tside = 0;
14 5cedca1b 2004-05-15 devnull int tlist = 0; /* 1 => explicit values given */
15 5cedca1b 2004-05-15 devnull int toffside = 0; /* no ticks on these sides */
16 5cedca1b 2004-05-15 devnull int goffside = 0; /* no ticks on grid on these sides */
17 5cedca1b 2004-05-15 devnull int tick_dir = OUT;
18 5cedca1b 2004-05-15 devnull double ticklen = TICKLEN; /* default tick length */
19 5cedca1b 2004-05-15 devnull int autoticks = LEFT|BOT;
20 5cedca1b 2004-05-15 devnull int autodir = 0; /* set LEFT, etc. if automatic ticks go in */
21 5cedca1b 2004-05-15 devnull
22 5cedca1b 2004-05-15 devnull void savetick(double f, char *s) /* remember tick location and label */
23 5cedca1b 2004-05-15 devnull {
24 5cedca1b 2004-05-15 devnull if (ntick >= MAXTICK)
25 5cedca1b 2004-05-15 devnull ERROR "too many ticks (%d)", MAXTICK FATAL;
26 5cedca1b 2004-05-15 devnull tickval[ntick] = f;
27 5cedca1b 2004-05-15 devnull tickstr[ntick] = s;
28 5cedca1b 2004-05-15 devnull ntick++;
29 5cedca1b 2004-05-15 devnull }
30 5cedca1b 2004-05-15 devnull
31 5cedca1b 2004-05-15 devnull void dflt_tick(double f)
32 5cedca1b 2004-05-15 devnull {
33 5cedca1b 2004-05-15 devnull if (f >= 0.0)
34 5cedca1b 2004-05-15 devnull savetick(f, tostring("%g"));
35 5cedca1b 2004-05-15 devnull else
36 5cedca1b 2004-05-15 devnull savetick(f, tostring("\\%g"));
37 5cedca1b 2004-05-15 devnull }
38 5cedca1b 2004-05-15 devnull
39 5cedca1b 2004-05-15 devnull void tickside(int n) /* remember which side these ticks/gridlines go on */
40 5cedca1b 2004-05-15 devnull {
41 5cedca1b 2004-05-15 devnull tside |= n;
42 5cedca1b 2004-05-15 devnull }
43 5cedca1b 2004-05-15 devnull
44 5cedca1b 2004-05-15 devnull void tickoff(int side) /* remember explicit sides */
45 5cedca1b 2004-05-15 devnull {
46 5cedca1b 2004-05-15 devnull toffside |= side;
47 5cedca1b 2004-05-15 devnull }
48 5cedca1b 2004-05-15 devnull
49 5cedca1b 2004-05-15 devnull void gridtickoff(void) /* turn grid ticks off on the side previously specified (ugh) */
50 5cedca1b 2004-05-15 devnull {
51 5cedca1b 2004-05-15 devnull goffside = tside;
52 5cedca1b 2004-05-15 devnull }
53 5cedca1b 2004-05-15 devnull
54 5cedca1b 2004-05-15 devnull void setlist(void) /* remember that there was an explicit list */
55 5cedca1b 2004-05-15 devnull {
56 5cedca1b 2004-05-15 devnull tlist = 1;
57 5cedca1b 2004-05-15 devnull }
58 5cedca1b 2004-05-15 devnull
59 5cedca1b 2004-05-15 devnull void tickdir(int dir, double val, int explicit) /* remember in/out [expr] */
60 5cedca1b 2004-05-15 devnull {
61 5cedca1b 2004-05-15 devnull tick_dir = dir;
62 5cedca1b 2004-05-15 devnull if (explicit)
63 5cedca1b 2004-05-15 devnull ticklen = val;
64 5cedca1b 2004-05-15 devnull }
65 5cedca1b 2004-05-15 devnull
66 5cedca1b 2004-05-15 devnull void ticks(void) /* set autoticks after ticks statement */
67 5cedca1b 2004-05-15 devnull {
68 5cedca1b 2004-05-15 devnull /* was there an explicit "ticks [side] off"? */
69 5cedca1b 2004-05-15 devnull if (toffside)
70 5cedca1b 2004-05-15 devnull autoticks &= ~toffside;
71 5cedca1b 2004-05-15 devnull /* was there an explicit list? (eg "ticks at ..." or "ticks from ...") */
72 5cedca1b 2004-05-15 devnull if (tlist) {
73 5cedca1b 2004-05-15 devnull if (tside & (BOT|TOP))
74 5cedca1b 2004-05-15 devnull autoticks &= ~(BOT|TOP);
75 5cedca1b 2004-05-15 devnull if (tside & (LEFT|RIGHT))
76 5cedca1b 2004-05-15 devnull autoticks &= ~(LEFT|RIGHT);
77 5cedca1b 2004-05-15 devnull }
78 5cedca1b 2004-05-15 devnull /* was there a side without a list? (eg "ticks left in") */
79 5cedca1b 2004-05-15 devnull if (tside && !tlist) {
80 5cedca1b 2004-05-15 devnull if (tick_dir == IN)
81 5cedca1b 2004-05-15 devnull autodir |= tside;
82 5cedca1b 2004-05-15 devnull if (tside & (BOT|TOP))
83 5cedca1b 2004-05-15 devnull autoticks = (autoticks & ~(BOT|TOP)) | (tside & (BOT|TOP));
84 5cedca1b 2004-05-15 devnull if (tside & (LEFT|RIGHT))
85 5cedca1b 2004-05-15 devnull autoticks = (autoticks & ~(LEFT|RIGHT)) | (tside & (LEFT|RIGHT));
86 5cedca1b 2004-05-15 devnull }
87 5cedca1b 2004-05-15 devnull tlist = tside = toffside = goffside = 0;
88 5cedca1b 2004-05-15 devnull tick_dir = OUT;
89 5cedca1b 2004-05-15 devnull }
90 5cedca1b 2004-05-15 devnull
91 5cedca1b 2004-05-15 devnull double modfloor(double f, double t)
92 5cedca1b 2004-05-15 devnull {
93 5cedca1b 2004-05-15 devnull t = fabs(t);
94 5cedca1b 2004-05-15 devnull return floor(f/t) * t;
95 5cedca1b 2004-05-15 devnull }
96 5cedca1b 2004-05-15 devnull
97 5cedca1b 2004-05-15 devnull double modceil(double f, double t)
98 5cedca1b 2004-05-15 devnull {
99 5cedca1b 2004-05-15 devnull t = fabs(t);
100 5cedca1b 2004-05-15 devnull return ceil(f/t) * t;
101 5cedca1b 2004-05-15 devnull }
102 5cedca1b 2004-05-15 devnull
103 5cedca1b 2004-05-15 devnull double xtmin, xtmax; /* range of ticks */
104 5cedca1b 2004-05-15 devnull double ytmin, ytmax;
105 5cedca1b 2004-05-15 devnull double xquant, xmult; /* quantization & scale for auto x ticks */
106 5cedca1b 2004-05-15 devnull double yquant, ymult;
107 5cedca1b 2004-05-15 devnull double lograt = 5;
108 5cedca1b 2004-05-15 devnull
109 5cedca1b 2004-05-15 devnull void do_autoticks(Obj *p) /* make set of ticks for default coord only */
110 5cedca1b 2004-05-15 devnull {
111 5cedca1b 2004-05-15 devnull double x, xl, xu, q;
112 5cedca1b 2004-05-15 devnull
113 5cedca1b 2004-05-15 devnull if (p == NULL)
114 5cedca1b 2004-05-15 devnull return;
115 5cedca1b 2004-05-15 devnull fprintf(tfd, "Autoticks:\t# x %g..%g, y %g..%g",
116 5cedca1b 2004-05-15 devnull p->pt.x, p->pt1.x, p->pt.y, p->pt1.y);
117 5cedca1b 2004-05-15 devnull fprintf(tfd, "; xt %g,%g, yt %g,%g, xq,xm = %g,%g, yq,ym = %g,%g\n",
118 5cedca1b 2004-05-15 devnull xtmin, xtmax, ytmin, ytmax, xquant, xmult, yquant, ymult);
119 5cedca1b 2004-05-15 devnull if ((autoticks & (BOT|TOP)) && p->pt1.x >= p->pt.x) { /* make x ticks */
120 5cedca1b 2004-05-15 devnull q = xquant;
121 5cedca1b 2004-05-15 devnull xl = p->pt.x;
122 5cedca1b 2004-05-15 devnull xu = p->pt1.x;
123 5cedca1b 2004-05-15 devnull if (xl >= xu)
124 5cedca1b 2004-05-15 devnull dflt_tick(xl);
125 5cedca1b 2004-05-15 devnull else if ((p->log & XFLAG) && xu/xl >= lograt) {
126 5cedca1b 2004-05-15 devnull for (x = q; x < xu; x *= 10) {
127 5cedca1b 2004-05-15 devnull logtick(x, xl, xu);
128 5cedca1b 2004-05-15 devnull if (xu/xl <= 100) {
129 5cedca1b 2004-05-15 devnull logtick(2*x, xl, xu);
130 5cedca1b 2004-05-15 devnull logtick(5*x, xl, xu);
131 5cedca1b 2004-05-15 devnull }
132 5cedca1b 2004-05-15 devnull }
133 5cedca1b 2004-05-15 devnull } else {
134 5cedca1b 2004-05-15 devnull xl = modceil(xtmin - q/100, q);
135 5cedca1b 2004-05-15 devnull xu = modfloor(xtmax + q/100, q) + q/2;
136 5cedca1b 2004-05-15 devnull for (x = xl; x <= xu; x += q)
137 5cedca1b 2004-05-15 devnull dflt_tick(x);
138 5cedca1b 2004-05-15 devnull }
139 5cedca1b 2004-05-15 devnull tside = autoticks & (BOT|TOP);
140 5cedca1b 2004-05-15 devnull ticklist(p, 0);
141 5cedca1b 2004-05-15 devnull }
142 5cedca1b 2004-05-15 devnull if ((autoticks & (LEFT|RIGHT)) && p->pt1.y >= p->pt.y) { /* make y ticks */
143 5cedca1b 2004-05-15 devnull q = yquant;
144 5cedca1b 2004-05-15 devnull xl = p->pt.y;
145 5cedca1b 2004-05-15 devnull xu = p->pt1.y;
146 5cedca1b 2004-05-15 devnull if (xl >= xu)
147 5cedca1b 2004-05-15 devnull dflt_tick(xl);
148 5cedca1b 2004-05-15 devnull else if ((p->log & YFLAG) && xu/xl >= lograt) {
149 5cedca1b 2004-05-15 devnull for (x = q; x < xu; x *= 10) {
150 5cedca1b 2004-05-15 devnull logtick(x, xl, xu);
151 5cedca1b 2004-05-15 devnull if (xu/xl <= 100) {
152 5cedca1b 2004-05-15 devnull logtick(2*x, xl, xu);
153 5cedca1b 2004-05-15 devnull logtick(5*x, xl, xu);
154 5cedca1b 2004-05-15 devnull }
155 5cedca1b 2004-05-15 devnull }
156 5cedca1b 2004-05-15 devnull } else {
157 5cedca1b 2004-05-15 devnull xl = modceil(ytmin - q/100, q);
158 5cedca1b 2004-05-15 devnull xu = modfloor(ytmax + q/100, q) + q/2;
159 5cedca1b 2004-05-15 devnull for (x = xl; x <= xu; x += q)
160 5cedca1b 2004-05-15 devnull dflt_tick(x);
161 5cedca1b 2004-05-15 devnull }
162 5cedca1b 2004-05-15 devnull tside = autoticks & (LEFT|RIGHT);
163 5cedca1b 2004-05-15 devnull ticklist(p, 0);
164 5cedca1b 2004-05-15 devnull }
165 5cedca1b 2004-05-15 devnull }
166 5cedca1b 2004-05-15 devnull
167 5cedca1b 2004-05-15 devnull void logtick(double v, double lb, double ub)
168 5cedca1b 2004-05-15 devnull {
169 5cedca1b 2004-05-15 devnull float slop = 1.0; /* was 1.001 */
170 5cedca1b 2004-05-15 devnull
171 5cedca1b 2004-05-15 devnull if (slop * lb <= v && ub >= slop * v)
172 5cedca1b 2004-05-15 devnull dflt_tick(v);
173 5cedca1b 2004-05-15 devnull }
174 5cedca1b 2004-05-15 devnull
175 5cedca1b 2004-05-15 devnull Obj *setauto(void) /* compute new min,max, and quant & mult */
176 5cedca1b 2004-05-15 devnull {
177 5cedca1b 2004-05-15 devnull Obj *p, *q;
178 5cedca1b 2004-05-15 devnull
179 5cedca1b 2004-05-15 devnull if ((q = lookup("lograt",0)) != NULL)
180 5cedca1b 2004-05-15 devnull lograt = q->fval;
181 5cedca1b 2004-05-15 devnull for (p = objlist; p; p = p->next)
182 5cedca1b 2004-05-15 devnull if (p->type == NAME && strcmp(p->name,dflt_coord) == 0)
183 5cedca1b 2004-05-15 devnull break;
184 5cedca1b 2004-05-15 devnull if (p) {
185 5cedca1b 2004-05-15 devnull if ((p->log & XFLAG) && p->pt1.x/p->pt.x >= lograt)
186 5cedca1b 2004-05-15 devnull autolog(p, 'x');
187 5cedca1b 2004-05-15 devnull else
188 5cedca1b 2004-05-15 devnull autoside(p, 'x');
189 5cedca1b 2004-05-15 devnull if ((p->log & YFLAG) && p->pt1.y/p->pt.y >= lograt)
190 5cedca1b 2004-05-15 devnull autolog(p, 'y');
191 5cedca1b 2004-05-15 devnull else
192 5cedca1b 2004-05-15 devnull autoside(p, 'y');
193 5cedca1b 2004-05-15 devnull }
194 5cedca1b 2004-05-15 devnull return p;
195 5cedca1b 2004-05-15 devnull }
196 5cedca1b 2004-05-15 devnull
197 5cedca1b 2004-05-15 devnull void autoside(Obj *p, int side)
198 5cedca1b 2004-05-15 devnull {
199 5cedca1b 2004-05-15 devnull double r, s, d, ub, lb;
200 5cedca1b 2004-05-15 devnull
201 5cedca1b 2004-05-15 devnull if (side == 'x') {
202 5cedca1b 2004-05-15 devnull xtmin = lb = p->pt.x;
203 5cedca1b 2004-05-15 devnull xtmax = ub = p->pt1.x;
204 5cedca1b 2004-05-15 devnull } else {
205 5cedca1b 2004-05-15 devnull ytmin = lb = p->pt.y;
206 5cedca1b 2004-05-15 devnull ytmax = ub = p->pt1.y;
207 5cedca1b 2004-05-15 devnull }
208 5cedca1b 2004-05-15 devnull if (ub <= lb)
209 5cedca1b 2004-05-15 devnull return; /* cop out on little ranges */
210 5cedca1b 2004-05-15 devnull d = ub - lb;
211 5cedca1b 2004-05-15 devnull r = s = 1;
212 5cedca1b 2004-05-15 devnull while (d * s < 10)
213 5cedca1b 2004-05-15 devnull s *= 10;
214 5cedca1b 2004-05-15 devnull d *= s;
215 5cedca1b 2004-05-15 devnull while (10 * r < d)
216 5cedca1b 2004-05-15 devnull r *= 10;
217 5cedca1b 2004-05-15 devnull if (r > d/3)
218 5cedca1b 2004-05-15 devnull r /= 2;
219 5cedca1b 2004-05-15 devnull else if (r <= d/6)
220 5cedca1b 2004-05-15 devnull r *= 2;
221 5cedca1b 2004-05-15 devnull if (side == 'x') {
222 5cedca1b 2004-05-15 devnull xquant = r / s;
223 5cedca1b 2004-05-15 devnull } else {
224 5cedca1b 2004-05-15 devnull yquant = r / s;
225 5cedca1b 2004-05-15 devnull }
226 5cedca1b 2004-05-15 devnull }
227 5cedca1b 2004-05-15 devnull
228 5cedca1b 2004-05-15 devnull void autolog(Obj *p, int side)
229 5cedca1b 2004-05-15 devnull {
230 5cedca1b 2004-05-15 devnull double r, s, t, ub, lb;
231 5cedca1b 2004-05-15 devnull int flg;
232 5cedca1b 2004-05-15 devnull
233 5cedca1b 2004-05-15 devnull if (side == 'x') {
234 5cedca1b 2004-05-15 devnull xtmin = lb = p->pt.x;
235 5cedca1b 2004-05-15 devnull xtmax = ub = p->pt1.x;
236 5cedca1b 2004-05-15 devnull flg = p->coord & XFLAG;
237 5cedca1b 2004-05-15 devnull } else {
238 5cedca1b 2004-05-15 devnull ytmin = lb = p->pt.y;
239 5cedca1b 2004-05-15 devnull ytmax = ub = p->pt1.y;
240 5cedca1b 2004-05-15 devnull flg = p->coord & YFLAG;
241 5cedca1b 2004-05-15 devnull }
242 5cedca1b 2004-05-15 devnull for (s = 1; lb * s < 1; s *= 10)
243 5cedca1b 2004-05-15 devnull ;
244 5cedca1b 2004-05-15 devnull lb *= s;
245 5cedca1b 2004-05-15 devnull ub *= s;
246 5cedca1b 2004-05-15 devnull for (r = 1; 10 * r < lb; r *= 10)
247 5cedca1b 2004-05-15 devnull ;
248 5cedca1b 2004-05-15 devnull for (t = 1; t < ub; t *= 10)
249 5cedca1b 2004-05-15 devnull ;
250 5cedca1b 2004-05-15 devnull if (side == 'x')
251 5cedca1b 2004-05-15 devnull xquant = r / s;
252 5cedca1b 2004-05-15 devnull else
253 5cedca1b 2004-05-15 devnull yquant = r / s;
254 5cedca1b 2004-05-15 devnull if (flg)
255 5cedca1b 2004-05-15 devnull return;
256 5cedca1b 2004-05-15 devnull if (ub / lb < 100) {
257 5cedca1b 2004-05-15 devnull if (lb >= 5 * r)
258 5cedca1b 2004-05-15 devnull r *= 5;
259 5cedca1b 2004-05-15 devnull else if (lb >= 2 * r)
260 5cedca1b 2004-05-15 devnull r *= 2;
261 5cedca1b 2004-05-15 devnull if (ub * 5 <= t)
262 5cedca1b 2004-05-15 devnull t /= 5;
263 5cedca1b 2004-05-15 devnull else if (ub * 2 <= t)
264 5cedca1b 2004-05-15 devnull t /= 2;
265 5cedca1b 2004-05-15 devnull if (side == 'x') {
266 5cedca1b 2004-05-15 devnull xtmin = r / s;
267 5cedca1b 2004-05-15 devnull xtmax = t / s;
268 5cedca1b 2004-05-15 devnull } else {
269 5cedca1b 2004-05-15 devnull ytmin = r / s;
270 5cedca1b 2004-05-15 devnull ytmax = t / s;
271 5cedca1b 2004-05-15 devnull }
272 5cedca1b 2004-05-15 devnull }
273 5cedca1b 2004-05-15 devnull }
274 5cedca1b 2004-05-15 devnull
275 5cedca1b 2004-05-15 devnull void iterator(double from, double to, int op, double by, char *fmt) /* create an iterator */
276 5cedca1b 2004-05-15 devnull {
277 5cedca1b 2004-05-15 devnull double x;
278 5cedca1b 2004-05-15 devnull
279 5cedca1b 2004-05-15 devnull /* should validate limits, etc. */
280 5cedca1b 2004-05-15 devnull /* punt for now */
281 5cedca1b 2004-05-15 devnull
282 5cedca1b 2004-05-15 devnull dprintf("iterate from %g to %g by %g, op = %c, fmt=%s\n",
283 5cedca1b 2004-05-15 devnull from, to, by, op, fmt ? fmt : "");
284 5cedca1b 2004-05-15 devnull switch (op) {
285 5cedca1b 2004-05-15 devnull case '+':
286 5cedca1b 2004-05-15 devnull case ' ':
287 5cedca1b 2004-05-15 devnull for (x = from; x <= to + (SLOP-1) * by; x += by)
288 5cedca1b 2004-05-15 devnull if (fmt)
289 5cedca1b 2004-05-15 devnull savetick(x, tostring(fmt));
290 5cedca1b 2004-05-15 devnull else
291 5cedca1b 2004-05-15 devnull dflt_tick(x);
292 5cedca1b 2004-05-15 devnull break;
293 5cedca1b 2004-05-15 devnull case '-':
294 5cedca1b 2004-05-15 devnull for (x = from; x >= to; x -= by)
295 5cedca1b 2004-05-15 devnull if (fmt)
296 5cedca1b 2004-05-15 devnull savetick(x, tostring(fmt));
297 5cedca1b 2004-05-15 devnull else
298 5cedca1b 2004-05-15 devnull dflt_tick(x);
299 5cedca1b 2004-05-15 devnull break;
300 5cedca1b 2004-05-15 devnull case '*':
301 5cedca1b 2004-05-15 devnull for (x = from; x <= SLOP * to; x *= by)
302 5cedca1b 2004-05-15 devnull if (fmt)
303 5cedca1b 2004-05-15 devnull savetick(x, tostring(fmt));
304 5cedca1b 2004-05-15 devnull else
305 5cedca1b 2004-05-15 devnull dflt_tick(x);
306 5cedca1b 2004-05-15 devnull break;
307 5cedca1b 2004-05-15 devnull case '/':
308 5cedca1b 2004-05-15 devnull for (x = from; x >= to; x /= by)
309 5cedca1b 2004-05-15 devnull if (fmt)
310 5cedca1b 2004-05-15 devnull savetick(x, tostring(fmt));
311 5cedca1b 2004-05-15 devnull else
312 5cedca1b 2004-05-15 devnull dflt_tick(x);
313 5cedca1b 2004-05-15 devnull break;
314 5cedca1b 2004-05-15 devnull }
315 5cedca1b 2004-05-15 devnull if (fmt)
316 5cedca1b 2004-05-15 devnull free(fmt);
317 5cedca1b 2004-05-15 devnull }
318 5cedca1b 2004-05-15 devnull
319 5cedca1b 2004-05-15 devnull void ticklist(Obj *p, int explicit) /* fire out the accumulated ticks */
320 5cedca1b 2004-05-15 devnull /* 1 => list, 0 => auto */
321 5cedca1b 2004-05-15 devnull {
322 5cedca1b 2004-05-15 devnull if (p == NULL)
323 5cedca1b 2004-05-15 devnull return;
324 5cedca1b 2004-05-15 devnull fprintf(tfd, "Ticks_%s:\n\tticklen = %g\n", p->name, ticklen);
325 5cedca1b 2004-05-15 devnull print_ticks(TICKS, explicit, p, "ticklen", "");
326 5cedca1b 2004-05-15 devnull }
327 5cedca1b 2004-05-15 devnull
328 5cedca1b 2004-05-15 devnull void print_ticks(int type, int explicit, Obj *p, char *lenstr, char *descstr)
329 5cedca1b 2004-05-15 devnull {
330 5cedca1b 2004-05-15 devnull int i, logflag, inside;
331 5cedca1b 2004-05-15 devnull char buf[100];
332 5cedca1b 2004-05-15 devnull double tv;
333 5cedca1b 2004-05-15 devnull
334 5cedca1b 2004-05-15 devnull for (i = 0; i < ntick; i++) /* any ticks given explicitly? */
335 5cedca1b 2004-05-15 devnull if (tickstr[i] != NULL)
336 5cedca1b 2004-05-15 devnull break;
337 5cedca1b 2004-05-15 devnull if (i >= ntick && type == TICKS) /* no, so use values */
338 5cedca1b 2004-05-15 devnull for (i = 0; i < ntick; i++) {
339 5cedca1b 2004-05-15 devnull if (tickval[i] >= 0.0)
340 5cedca1b 2004-05-15 devnull sprintf(buf, "%g", tickval[i]);
341 5cedca1b 2004-05-15 devnull else
342 5cedca1b 2004-05-15 devnull sprintf(buf, "\\-%g", -tickval[i]);
343 5cedca1b 2004-05-15 devnull tickstr[i] = tostring(buf);
344 5cedca1b 2004-05-15 devnull }
345 5cedca1b 2004-05-15 devnull else
346 5cedca1b 2004-05-15 devnull for (i = 0; i < ntick; i++) {
347 5cedca1b 2004-05-15 devnull if (tickstr[i] != NULL) {
348 5cedca1b 2004-05-15 devnull sprintf(buf, tickstr[i], tickval[i]);
349 5cedca1b 2004-05-15 devnull free(tickstr[i]);
350 5cedca1b 2004-05-15 devnull tickstr[i] = tostring(buf);
351 5cedca1b 2004-05-15 devnull }
352 5cedca1b 2004-05-15 devnull }
353 5cedca1b 2004-05-15 devnull logflag = sidelog(p->log, tside);
354 5cedca1b 2004-05-15 devnull for (i = 0; i < ntick; i++) {
355 5cedca1b 2004-05-15 devnull tv = tickval[i];
356 5cedca1b 2004-05-15 devnull halfrange(p, tside, tv);
357 5cedca1b 2004-05-15 devnull if (logflag) {
358 5cedca1b 2004-05-15 devnull if (tv <= 0.0)
359 5cedca1b 2004-05-15 devnull ERROR "can't take log of tick value %g", tv FATAL;
360 5cedca1b 2004-05-15 devnull logit(tv);
361 5cedca1b 2004-05-15 devnull }
362 5cedca1b 2004-05-15 devnull if (type == GRID)
363 5cedca1b 2004-05-15 devnull inside = LEFT|RIGHT|TOP|BOT;
364 5cedca1b 2004-05-15 devnull else if (explicit)
365 5cedca1b 2004-05-15 devnull inside = (tick_dir == IN) ? tside : 0;
366 5cedca1b 2004-05-15 devnull else
367 5cedca1b 2004-05-15 devnull inside = autodir;
368 5cedca1b 2004-05-15 devnull if (tside & BOT)
369 5cedca1b 2004-05-15 devnull maketick(type, p->name, BOT, inside, tv, tickstr[i], lenstr, descstr);
370 5cedca1b 2004-05-15 devnull if (tside & TOP)
371 5cedca1b 2004-05-15 devnull maketick(type, p->name, TOP, inside, tv, tickstr[i], lenstr, descstr);
372 5cedca1b 2004-05-15 devnull if (tside & LEFT)
373 5cedca1b 2004-05-15 devnull maketick(type, p->name, LEFT, inside, tv, tickstr[i], lenstr, descstr);
374 5cedca1b 2004-05-15 devnull if (tside & RIGHT)
375 5cedca1b 2004-05-15 devnull maketick(type, p->name, RIGHT, inside, tv, tickstr[i], lenstr, descstr);
376 5cedca1b 2004-05-15 devnull if (tickstr[i]) {
377 5cedca1b 2004-05-15 devnull free(tickstr[i]);
378 5cedca1b 2004-05-15 devnull tickstr[i] = NULL;
379 5cedca1b 2004-05-15 devnull }
380 5cedca1b 2004-05-15 devnull }
381 5cedca1b 2004-05-15 devnull ntick = 0;
382 5cedca1b 2004-05-15 devnull }
383 5cedca1b 2004-05-15 devnull
384 5cedca1b 2004-05-15 devnull void maketick(int type, char *name, int side, int inflag, double val, char *lab, char *lenstr, char *descstr)
385 5cedca1b 2004-05-15 devnull {
386 5cedca1b 2004-05-15 devnull char *sidestr, *td;
387 5cedca1b 2004-05-15 devnull
388 5cedca1b 2004-05-15 devnull fprintf(tfd, "\tline %s ", descstr);
389 5cedca1b 2004-05-15 devnull inflag &= side;
390 5cedca1b 2004-05-15 devnull switch (side) {
391 5cedca1b 2004-05-15 devnull case BOT:
392 5cedca1b 2004-05-15 devnull case 0:
393 5cedca1b 2004-05-15 devnull td = inflag ? "up" : "down";
394 5cedca1b 2004-05-15 devnull fprintf(tfd, "%s %s from (x_%s(%g),0)", td, lenstr, name, val);
395 5cedca1b 2004-05-15 devnull break;
396 5cedca1b 2004-05-15 devnull case TOP:
397 5cedca1b 2004-05-15 devnull td = inflag ? "down" : "up";
398 5cedca1b 2004-05-15 devnull fprintf(tfd, "%s %s from (x_%s(%g),frameht)", td, lenstr, name, val);
399 5cedca1b 2004-05-15 devnull break;
400 5cedca1b 2004-05-15 devnull case LEFT:
401 5cedca1b 2004-05-15 devnull td = inflag ? "right" : "left";
402 5cedca1b 2004-05-15 devnull fprintf(tfd, "%s %s from (0,y_%s(%g))", td, lenstr, name, val);
403 5cedca1b 2004-05-15 devnull break;
404 5cedca1b 2004-05-15 devnull case RIGHT:
405 5cedca1b 2004-05-15 devnull td = inflag ? "left" : "right";
406 5cedca1b 2004-05-15 devnull fprintf(tfd, "%s %s from (framewid,y_%s(%g))", td, lenstr, name, val);
407 5cedca1b 2004-05-15 devnull break;
408 5cedca1b 2004-05-15 devnull }
409 5cedca1b 2004-05-15 devnull fprintf(tfd, "\n");
410 5cedca1b 2004-05-15 devnull if (type == GRID && (side & goffside)) /* wanted no ticks on grid */
411 5cedca1b 2004-05-15 devnull return;
412 5cedca1b 2004-05-15 devnull sidestr = tick_dir == IN ? "start" : "end";
413 5cedca1b 2004-05-15 devnull if (lab != NULL) {
414 5cedca1b 2004-05-15 devnull /* BUG: should fix size of lab here */
415 5cedca1b 2004-05-15 devnull double wid = strlen(lab)/7.5 + (tick_dir == IN ? 0 : 0.1); /* estimate width at 15 chars/inch */
416 5cedca1b 2004-05-15 devnull switch (side) {
417 5cedca1b 2004-05-15 devnull case BOT: case 0:
418 5cedca1b 2004-05-15 devnull /* can drop "box invis" with new pic */
419 5cedca1b 2004-05-15 devnull fprintf(tfd, "\tbox invis \"%s\" ht .25 wid 0 with .n at last line.%s",
420 5cedca1b 2004-05-15 devnull lab, sidestr);
421 5cedca1b 2004-05-15 devnull break;
422 5cedca1b 2004-05-15 devnull case TOP:
423 5cedca1b 2004-05-15 devnull fprintf(tfd, "\tbox invis \"%s\" ht .2 wid 0 with .s at last line.%s",
424 5cedca1b 2004-05-15 devnull lab, sidestr);
425 5cedca1b 2004-05-15 devnull break;
426 5cedca1b 2004-05-15 devnull case LEFT:
427 5cedca1b 2004-05-15 devnull fprintf(tfd, "\t\"%s \" wid %.2f rjust at last line.%s",
428 5cedca1b 2004-05-15 devnull lab, wid, sidestr);
429 5cedca1b 2004-05-15 devnull break;
430 5cedca1b 2004-05-15 devnull case RIGHT:
431 5cedca1b 2004-05-15 devnull fprintf(tfd, "\t\" %s\" wid %.2f ljust at last line.%s",
432 5cedca1b 2004-05-15 devnull lab, wid, sidestr);
433 5cedca1b 2004-05-15 devnull break;
434 5cedca1b 2004-05-15 devnull }
435 5cedca1b 2004-05-15 devnull /* BUG: works only if "down x" comes before "at wherever" */
436 5cedca1b 2004-05-15 devnull lab_adjust();
437 5cedca1b 2004-05-15 devnull fprintf(tfd, "\n");
438 5cedca1b 2004-05-15 devnull }
439 5cedca1b 2004-05-15 devnull }
440 5cedca1b 2004-05-15 devnull
441 5cedca1b 2004-05-15 devnull Attr *grid_desc = 0;
442 5cedca1b 2004-05-15 devnull
443 5cedca1b 2004-05-15 devnull void griddesc(Attr *a)
444 5cedca1b 2004-05-15 devnull {
445 5cedca1b 2004-05-15 devnull grid_desc = a;
446 5cedca1b 2004-05-15 devnull }
447 5cedca1b 2004-05-15 devnull
448 5cedca1b 2004-05-15 devnull void gridlist(Obj *p)
449 5cedca1b 2004-05-15 devnull {
450 5cedca1b 2004-05-15 devnull char *framestr;
451 5cedca1b 2004-05-15 devnull
452 5cedca1b 2004-05-15 devnull if ((tside & (BOT|TOP)) || tside == 0)
453 5cedca1b 2004-05-15 devnull framestr = "frameht";
454 5cedca1b 2004-05-15 devnull else
455 5cedca1b 2004-05-15 devnull framestr = "framewid";
456 5cedca1b 2004-05-15 devnull fprintf(tfd, "Grid_%s:\n", p->name);
457 5cedca1b 2004-05-15 devnull tick_dir = IN;
458 5cedca1b 2004-05-15 devnull print_ticks(GRID, 0, p, framestr, desc_str(grid_desc));
459 5cedca1b 2004-05-15 devnull if (grid_desc) {
460 5cedca1b 2004-05-15 devnull freeattr(grid_desc);
461 5cedca1b 2004-05-15 devnull grid_desc = 0;
462 5cedca1b 2004-05-15 devnull }
463 5cedca1b 2004-05-15 devnull }
464 5cedca1b 2004-05-15 devnull
465 5cedca1b 2004-05-15 devnull char *desc_str(Attr *a) /* convert DOT to "dotted", etc. */
466 5cedca1b 2004-05-15 devnull {
467 5cedca1b 2004-05-15 devnull static char buf[50], *p;
468 5cedca1b 2004-05-15 devnull
469 5cedca1b 2004-05-15 devnull if (a == NULL)
470 5cedca1b 2004-05-15 devnull return p = "";
471 5cedca1b 2004-05-15 devnull switch (a->type) {
472 5cedca1b 2004-05-15 devnull case DOT: p = "dotted"; break;
473 5cedca1b 2004-05-15 devnull case DASH: p = "dashed"; break;
474 5cedca1b 2004-05-15 devnull case INVIS: p = "invis"; break;
475 5cedca1b 2004-05-15 devnull default: p = "";
476 5cedca1b 2004-05-15 devnull }
477 5cedca1b 2004-05-15 devnull if (a->fval != 0.0) {
478 5cedca1b 2004-05-15 devnull sprintf(buf, "%s %g", p, a->fval);
479 5cedca1b 2004-05-15 devnull return buf;
480 5cedca1b 2004-05-15 devnull } else
481 5cedca1b 2004-05-15 devnull return p;
482 5cedca1b 2004-05-15 devnull }
483 5cedca1b 2004-05-15 devnull
484 b237df90 2004-05-16 devnull int
485 5cedca1b 2004-05-15 devnull sidelog(int logflag, int side) /* figure out whether to scale a side */
486 5cedca1b 2004-05-15 devnull {
487 5cedca1b 2004-05-15 devnull if ((logflag & XFLAG) && ((side & (BOT|TOP)) || side == 0))
488 5cedca1b 2004-05-15 devnull return 1;
489 5cedca1b 2004-05-15 devnull else if ((logflag & YFLAG) && (side & (LEFT|RIGHT)))
490 5cedca1b 2004-05-15 devnull return 1;
491 5cedca1b 2004-05-15 devnull else
492 5cedca1b 2004-05-15 devnull return 0;
493 5cedca1b 2004-05-15 devnull }