Merge da SC: prima versione veramente funzionante
[bertos.git] / mware / charts.c
1 /*!
2  * \file
3  * <!--
4  * Copyright 2004 Develer S.r.l. (http://www.develer.com/)
5  * Copyright 1999, 2000, 2001, 2003 Bernardo Innocenti <bernie@develer.com>
6  * This file is part of DevLib - See devlib/README for information.
7  * -->
8  *
9  * \brief Simple charts on top of mware/gfx routines (implementation).
10  *
11  * Sample usage:
12  *
13  * \code
14  *      bm = chart_init(0, ymax, N_POINTS_CURVE, ymin);
15  *
16  *      chart_drawCurve(bm, curve_y, curve_points + 1);
17  *      gfx_setViewRect(bm, xmin, ymax, xmax, ymin);
18  *      chart_drawDots(bm, samples_x, samples_y, samples_cnt);
19  *
20  *      print_bitmap(bm);
21  * \endcode
22  *
23  * \version $Id$
24  * \author Bernardo Innocenti <bernie@develer.com>
25  */
26
27 /*
28  * $Log$
29  * Revision 1.1  2004/08/04 03:16:30  bernie
30  * Import simple chart drawing code.
31  *
32  */
33
34 #include "charts.h"
35 #include <mware/gfx.h>
36
37
38 static Bitmap ChartBitmap;
39
40 /*!
41  * Raster buffer to draw into.
42  *
43  * Bits in the bitmap bytes have vertical orientation,
44  * as required by the printer driver.
45  */
46 DECLARE_WALL(wall_before_raster, WALL_SIZE)
47 static uint8_t ChartRaster[BM_WIDTH * ((BM_HEIGHT + 7) / 8)];
48 DECLARE_WALL(wall_after_raster, WALL_SIZE)
49
50
51 Bitmap *chart_init(vcoord_t xmin, vcoord_t ymin, vcoord_t xmax, vcoord_t ymax)
52 {
53         /* Initialize anti-corruption walls */
54         INIT_WALL(wall_before_raster, WALL_SIZE);
55         INIT_WALL(wall_after_raster, WALL_SIZE);
56
57         gfx_InitBitMap(&ChartBitmap, ChartRaster, BM_WIDTH, BM_HEIGHT);
58         gfx_ClearBitMap(&ChartBitmap);
59         gfx_DrawAxis(&ChartBitmap);
60
61         gfx_SetClipRect(&ChartBitmap, CHART_BORDERLEFT, CHART_BORDERTOP,
62                 BM_WIDTH - CHART_BORDERRIGHT - 1, BM_HEIGHT - CHART_BORDERBOTTOM - 1);
63
64         gfx_SetViewRect(&ChartBitmap, xmin, ymin, xmax, ymax);
65
66         CHECK_WALL(wall_before_raster, WALL_SIZE);
67         CHECK_WALL(wall_after_raster, WALL_SIZE);
68
69         return &ChartBitmap;
70 }
71
72
73 /*!
74  * Draw the chart axes
75  */
76 void chart_drawAxis(Bitmap *bm)
77 {
78         /* Draw axis */
79         gfx_MoveTo(bm, CHART_BORDERLEFT, 4);
80         gfx_LineTo(bm, CHART_BORDERLEFT, CHART_BORDERTOP + CHART_HEIGHT - 1);
81         gfx_LineTo(bm, CHART_BORDERLEFT + CHART_WIDTH - 5, CHART_BORDERTOP + CHART_HEIGHT - 1);
82
83         /* Draw up arrow */
84         gfx_MoveTo(bm, CHART_BORDERLEFT - 2, 3);
85         gfx_LineTo(bm, CHART_BORDERLEFT + 2, 3);
86         gfx_LineTo(bm, CHART_BORDERLEFT, 0);
87         gfx_LineTo(bm, CHART_BORDERLEFT - 2, 3);
88
89         /* Draw right arrow */
90         gfx_MoveTo(bm, CHART_BORDERLEFT + CHART_WIDTH - 4, CHART_BORDERTOP + CHART_HEIGHT - 3);
91         gfx_LineTo(bm, CHART_BORDERLEFT + CHART_WIDTH - 4, CHART_BORDERTOP + CHART_HEIGHT + 1);
92         gfx_LineTo(bm, CHART_BORDERLEFT + CHART_WIDTH - 1, CHART_BORDERTOP + CHART_HEIGHT - 1);
93         gfx_LineTo(bm, CHART_BORDERLEFT + CHART_WIDTH - 4, CHART_BORDERTOP + CHART_HEIGHT - 3);
94
95         CHECK_WALL(wall_before_raster, WALL_SIZE);
96         CHECK_WALL(wall_after_raster, WALL_SIZE);
97 }
98
99
100 /*!
101  * Draw a set of \a curve_cnt connected segments, whose Y coordinates
102  * are identified by the \a curve_y array and X-coordinates are
103  * are evenly spaced by one virtual unit.
104  */
105 void chart_drawCurve(Bitmap *bm, const vcoord_t *curve_y, int curve_cnt)
106 {
107         int i;
108
109         gfx_MoveTo(bm, gfx_TransformX(bm, 0), gfx_TransformY(bm, curve_y[0]));
110
111         for (i = 1; i < curve_cnt; i++)
112                 gfx_LineTo(bm, gfx_TransformX(bm, i), gfx_TransformY(bm, curve_y[i]));
113
114         CHECK_WALL(wall_before_raster, WALL_SIZE);
115         CHECK_WALL(wall_after_raster, WALL_SIZE);
116 }
117
118
119 /*!
120  * Disegna dei dot in corrispondenza delle coppie (dotsx[i];dotsy[i])
121  * Se dotsx e' NULL, i punti vengono disegnati ad intervalli regolari.
122  */
123 void chart_drawDots(BitMap *bm, const vcoord_t *dotsx, const vcoord_t *dotsy, int cnt)
124 {
125         int i;
126         coord_t x, y;
127
128         for (i = 0; i < cnt; i++)
129         {
130                 if (dotsx)
131                         x = gfx_TransformX(bm, dotsx[i]);
132                 else
133                         x = gfx_TransformX(bm, i);
134
135                 y = gfx_TransformY(bm, dotsy[i]);
136
137                 gfx_DrawRect(bm, x - 1, y - 1, x + 1, y + 1);
138
139                 /* Disegna ticks sull'asse X */
140                 gfx_DrawLine(bm, x, BM_HEIGHT - 1, x, CHART_HEIGHT - 1);
141         }
142
143         CHECK_WALL(wall_before_raster, WALL_SIZE);
144         CHECK_WALL(wall_after_raster, WALL_SIZE);
145 }
146