Documentation fixes.
[bertos.git] / gfx / bitmap.c
1 /*!
2  * \file
3  * <!--
4  * Copyright 2003, 2004, 2005, 2006 Develer S.r.l. (http://www.develer.com/)
5  * Copyright 1999 Bernardo Innocenti <bernie@develer.com>
6  * This file is part of DevLib - See README.devlib for information.
7  * -->
8  *
9  * \version $Id$
10  *
11  * \author Bernardo Innocenti <bernie@develer.com>
12  * \author Stefano Fedrigo <aleph@develer.com>
13  *
14  * \brief Bitmap manipulation routines.
15  */
16
17 /*#*
18  *#* $Log$
19  *#* Revision 1.6  2006/02/23 11:17:16  bernie
20  *#* Documentation fixes.
21  *#*
22  *#* Revision 1.5  2006/02/15 09:10:15  bernie
23  *#* Implement prop fonts; Fix algo styles.
24  *#*
25  *#* Revision 1.4  2006/02/10 12:32:33  bernie
26  *#* Add multiple font support in bitmaps; gfx_blitRaster(): New function.
27  *#*
28  *#* Revision 1.3  2006/01/26 00:36:48  bernie
29  *#* Const correctness for some new functions.
30  *#*
31  *#* Revision 1.2  2006/01/24 21:55:43  aleph
32  *#* gfx_blit_P(): use RASTER_SIZE() to calculate raster size
33  *#*
34  *#* Revision 1.1  2006/01/24 02:17:49  bernie
35  *#* Split out gfx.c into bitmap.c and line.c.
36  *#*
37  *#*/
38
39 #include "gfx.h"
40 #include "gfx_p.h"
41
42 #include <cfg/debug.h>  /* ASSERT() */
43 #include <cfg/cpu.h>    /* CPU_HARVARD */
44 #include <cfg/macros.h> /* MIN() */
45 #include <appconfig.h>  /* CONFIG_GFX_CLIPPING */
46
47 #include <string.h>     /* memset() */
48
49 #if CONFIG_GFX_TEXT
50 #include <gfx/font.h>   /* default_font */
51 #endif
52
53
54 /*!
55  * Initialize a Bitmap structure with the provided parameters.
56  *
57  * \note The pen position is reset to the origin.
58  */
59 void gfx_bitmapInit(Bitmap *bm, uint8_t *raster, coord_t w, coord_t h)
60 {
61         bm->raster = raster;
62         bm->width = w;
63         bm->height = h;
64         #if (CONFIG_BITMAP_FMT == BITMAP_FMT_PLANAR_H_MSB)
65                 bm->stride = (w + 7) / 8;
66         #elif CONFIG_BITMAP_FMT == BITMAP_FMT_PLANAR_V_LSB
67                 bm->stride = w;
68         #else
69                 #error Unknown value of CONFIG_BITMAP_FMT
70         #endif /* CONFIG_BITMAP_FMT */
71         bm->penX = 0;
72         bm->penY = 0;
73
74 #if CONFIG_GFX_TEXT
75         gfx_setFont(bm, &default_font);
76 #endif
77
78 #if CONFIG_GFX_CLIPPING
79         bm->cr.xmin = 0;
80         bm->cr.ymin = 0;
81         bm->cr.xmax = w;
82         bm->cr.ymax = h;
83 #endif /* CONFIG_GFX_CLIPPING */
84 }
85
86
87 /*!
88  * Clear the whole bitmap surface to the background color.
89  *
90  * \note This function does \b not update the current pen position.
91  */
92 void gfx_bitmapClear(Bitmap *bm)
93 {
94         memset(bm->raster, 0, RASTER_SIZE(bm->width, bm->height));
95 }
96
97
98 #if CPU_HARVARD
99
100 #include <avr/pgmspace.h> /* FIXME: memcpy_P() */
101
102 /*!
103  * Copy a raster picture located in program memory in the bitmap.
104  * The size of the raster to copy *must* be the same of the raster bitmap.
105  *
106  * \note This function does \b not update the current pen position
107  */
108 void gfx_blit_P(Bitmap *bm, const pgm_uint8_t *raster)
109 {
110         memcpy_P(bm->raster, raster, RASTER_SIZE(bm->width, bm->height));
111 }
112 #endif /* CPU_HARVARD */
113
114 /**
115  * Copy a rectangular area of a bitmap on another bitmap.
116  *
117  * Blitting is a common copy operation involving two bitmaps.
118  * A rectangular area of the source bitmap is copied bit-wise
119  * to a different position in the destination bitmap.
120  *
121  * \note Using the same bitmap for \a src and \a dst is unsupported.
122  *
123  * \param dst  Bitmap where the operation writes.
124  * \param rect The (xmin;ymin) coordinates provide the top/left offset
125  *             for drawing in the destination bitmap.  If the source
126  *             bitmap is larger than the rectangle, drawing is clipped.
127  * \param src  Bitmap containing the source pixels.
128  * \param srcx Starting X offset in the source bitmap.
129  * \param srcy Starting Y offset in the source bitmap.
130  */
131 void gfx_blit(Bitmap *dst, const Rect *rect, const Bitmap *src, coord_t srcx, coord_t srcy)
132 {
133         coord_t dxmin, dymin, dxmax, dymax;
134         coord_t dx, dy, sx, sy;
135
136         /*
137          * Clip coordinates inside dst->cr and src->width/height.
138          */
139         dxmin = rect->xmin;
140         if (dxmin < dst->cr.xmin)
141         {
142                 srcx += dst->cr.xmin - dxmin;
143                 dxmin = dst->cr.xmin;
144         }
145         dymin = rect->ymin;
146         if (dymin < dst->cr.ymin)
147         {
148                 srcy += dst->cr.ymin - dymin;
149                 dymin = dst->cr.ymin;
150         }
151         dxmax = MIN(MIN(rect->xmax, rect->xmin + src->width), dst->cr.xmax);
152         dymax = MIN(MIN(rect->ymax, rect->ymin + src->height), dst->cr.ymax);
153
154         /* TODO: make it not as dog slow as this */
155         for (dx = dxmin, sx = srcx; dx < dxmax; ++dx, ++sx)
156                 for (dy = dymin, sy = srcy; dy < dymax; ++dy, ++sy)
157                         BM_DRAWPIXEL(dst, dx, dy, BM_READPIXEL(src, sx, sy));
158 }
159
160
161 void gfx_blitRaster(Bitmap *dst, coord_t dxmin, coord_t dymin, const uint8_t *raster, coord_t w, coord_t h, coord_t stride)
162 {
163         coord_t dxmax, dymax;
164         coord_t sxmin = 0, symin = 0;
165         coord_t dx, dy, sx, sy;
166
167         /*
168          * Clip coordinates inside dst->cr.
169          */
170         if (dxmin < dst->cr.xmin)
171         {
172                 sxmin += dst->cr.xmin - dxmin;
173                 dxmin = dst->cr.xmin;
174         }
175         if (dymin < dst->cr.ymin)
176         {
177                 symin += dst->cr.ymin - dymin;
178                 dymin = dst->cr.ymin;
179         }
180         dxmax = MIN(dxmin + w, dst->cr.xmax);
181         dymax = MIN(dymin + h, dst->cr.ymax);
182
183         /* TODO: make it not as dog slow as this */
184         for (dx = dxmin, sx = sxmin; dx < dxmax; ++dx, ++sx)
185                 for (dy = dymin, sy = symin; dy < dymax; ++dy, ++sy)
186                         BM_DRAWPIXEL(dst, dx, dy, RAST_READPIXEL(raster, sx, sy, stride));
187 }
188
189
190 /*!
191  * Set the bitmap clipping rectangle to the specified coordinates.
192  *
193  * All drawing performed on the bitmap will be clipped inside this
194  * rectangle.
195  *
196  * \note Following the convention used in all other operations, the
197  *       top-left pixels of the rectangle are included, while the
198  *       bottom-right pixels are considered outside the clipping region.
199  */
200 void gfx_setClipRect(Bitmap *bm, coord_t minx, coord_t miny, coord_t maxx, coord_t maxy)
201 {
202         ASSERT(minx < maxx);
203         ASSERT(miny < maxy);
204         ASSERT(miny >= 0);
205         ASSERT(minx >= 0);
206         ASSERT(maxx <= bm->width);
207         ASSERT(maxy <= bm->height);
208
209         bm->cr.xmin = minx;
210         bm->cr.ymin = miny;
211         bm->cr.xmax = maxx;
212         bm->cr.ymax = maxy;
213
214 /*      kprintf("cr.xmin = %d, cr.ymin = %d, cr.xmax = %d, cr.ymax = %d\n",
215                 bm->cr.xMin, bm->cr.ymin, bm->cr.xmax, bm->cr.ymax);
216 */
217 }
218