gfio: add font selection and resize original window
[fio.git] / tickmarks.c
1 #include <stdio.h>
2 #include <math.h>
3 #include <malloc.h>
4
5 /* 
6  * adapted from Paul Heckbert's algorithm on p 657-659 of
7  * Andrew S. Glassner's book, "Graphics Gems"
8  * ISBN 0-12-286166-3
9  *
10  */
11
12 #include "tickmarks.h"
13
14 #define MAX(a, b) (((a) < (b)) ? (b) : (a))
15
16 static double nicenum(double x, int round)
17 {
18         int exp;        /* exponent of x */
19         double f;       /* fractional part of x */
20
21         exp = floor(log10(x));
22         f = x / pow(10.0, exp);
23         if (round) {
24                 if (f < 1.5)
25                         return 1.0 * pow(10.0, exp);
26                 if (f < 3.0)
27                         return 2.0 * pow(10.0, exp);
28                 if (f < 7.0)
29                         return 5.0 * pow(10.0, exp);
30                 return 10.0 * pow(10.0, exp);
31         }
32         if (f <= 1.0)
33                 return 1.0 * pow(10.0, exp);
34         if (f <= 2.0)
35                 return 2.0 * pow(10.0, exp);
36         if (f <= 5.0)
37                 return 5.0 * pow(10.0, exp);
38         return 10.0 * pow(10.0, exp);
39 }
40
41 int calc_tickmarks(double min, double max, int nticks, struct tickmark **tm)
42 {
43         char str[100];
44         int nfrac;
45         double d;       /* tick mark spacing */
46         double graphmin, graphmax;      /* graph range min and max */
47         double range, x;
48         int count, i;
49
50         /* we expect min != max */
51         range = nicenum(max - min, 0);
52         d = nicenum(range / (nticks - 1), 1);
53         graphmin = floor(min / d) * d;
54         graphmax = ceil(max / d) * d;
55         nfrac = MAX(-floor(log10(d)), 0);
56         snprintf(str, sizeof(str)-1, "%%.%df", nfrac);
57
58         count = ((graphmax + 0.5 * d) - graphmin) / d + 1;
59         *tm = malloc(sizeof(**tm) * count);
60
61         i = 0;
62         for (x = graphmin; x < graphmax + 0.5 * d; x += d) {
63                 (*tm)[i].value = x;
64                 sprintf((*tm)[i].string, str, x);
65                 i++;
66         }
67         return i;
68 }
69
70 #if 0
71
72 static void test_range(double x, double y)
73 {
74         int nticks, i;
75
76         struct tickmark *tm = NULL;
77         printf("Testing range %g - %g\n", x, y);
78         nticks = calc_tickmarks(x, y, 10, &tm);
79
80         for (i = 0; i < nticks; i++) {
81                 printf("   (%s) %g\n", tm[i].string, tm[i].value);
82         }
83         printf("\n\n");
84         free(tm);
85 }
86
87 int main(int argc, char *argv[])
88 {
89         test_range(0.0005, 0.008);      
90         test_range(0.5, 0.8);   
91         test_range(5.5, 8.8);   
92         test_range(50.5, 80.8); 
93         test_range(-20, 20.8);  
94         test_range(-30, 700.8); 
95 }
96 #endif