4 * Copyright (C) 1999 Bernardo Innocenti <bernie@develer.com>
5 * Copyright (C) 2003 Develer S.r.l. (http://www.develer.com/)
11 * \author Bernardo Innocenti <bernie@develer.com>
12 * \author Stefano Fedrigo <aleph@develer.com>
14 * \brief General pourpose graphics routines
19 * Revision 1.1 2004/05/23 15:43:16 bernie
20 * Import mware modules.
22 * Revision 1.6 2004/03/24 15:03:45 bernie
23 * Use explicit include paths; clean Doxygen comments
25 * Revision 1.5 2004/02/09 00:21:28 aleph
28 * Revision 1.4 2004/01/27 23:24:19 aleph
29 * Add new graphics primitives
31 * Revision 1.3 2004/01/13 00:05:23 aleph
34 * Revision 1.2 2004/01/07 23:33:01 aleph
35 * Change copyright email
37 * Revision 1.1 2004/01/07 19:05:31 aleph
38 * Add graphics routines
44 #include <drv/kdebug.h>
50 * Plot a point in bitmap.
51 * \note bm is evaluated twice
53 #define BM_PLOT(bm, x, y) \
54 ( *((bm)->raster + ((y) / 8) * (bm)->width + (x)) |= 1 << ((y) % 8) )
57 * Clear a point in bitmap.
58 * \note bm is evaluated twice
60 #define BM_CLEAR(bm, x, y) \
61 ( *((bm)->raster + ((y) / 8) * (bm)->width + (x)) &= ~(1 << ((y) % 8)) )
66 (void)(&a == &b); /* type check */ \
75 * Initialize a Bitmap structure with the provided parameters.
77 void gfx_InitBitmap(Bitmap *bm, uint8_t *raster, coord_t w, coord_t h)
88 * Clear the whole bitmap surface to all zeros
90 void gfx_ClearBitmap(Bitmap *bm)
92 memset(bm->raster, 0, (bm->width * bm->height) / 8);
97 * Copy a raster picture located in program memory in the bitmap.
98 * The size of the raster to copy *must* be the same of the raster bitmap.
100 void gfx_blitBitmap_P(Bitmap *bm, const prog_uchar *raster)
102 memcpy_P(bm->raster, raster, bm->height/8 * bm->width);
106 void gfx_DrawLine(Bitmap *bm, coord_t x1, coord_t y1, coord_t x2, coord_t y2)
108 int x, y, e, len, adx, ady, signx, signy;
111 #ifdef CONFIG_GFX_CLIPPING
116 #define XMAX (bm->width - 1)
117 #define YMAX (bm->height - 1)
122 y1 = y2 - ((x2 - XMIN) * (y2 - y1)) / (x2 - x1);
127 x1 = x2 - ((y2 - YMIN) * (x2 - x1)) / (y2 - y1);
132 y2 = y2 - ((XMIN - x1) * (y2 - y1)) / (x2 - x1);
137 x2 = x2 - ((YMIN - y1) * (x2 - x1)) / (y2 - y1);
143 y1 = ((x2 - XMAX) * (y2 - y1)) / (x2 - x1);
148 x1 = ((y2 - YMAX) * (x2 - x1)) / (y2 - y1);
153 y2 = ((XMAX - x1) * (y2 - y1)) / (x2 - x1);
158 x2 = ((YMAX - y1) * (x2 - x1)) / (y2 - y1);
167 #endif /* CONFIG_GRAPH_CLIPPING */
201 /* X-major line (octants 1/4/5/8) */
208 if ((x >= 0) && (x < bm->width) && (y >= 0) && (y < bm->height))
221 /* Y-major line (octants 2/3/6/7) */
228 if ((x >= 0) && (x < bm->width) && (y >= 0) && (y < bm->height))
242 void gfx_MoveTo(Bitmap *bm, coord_t x, coord_t y)
249 void gfx_LineTo(Bitmap *bm, coord_t x, coord_t y)
251 gfx_DrawLine(bm, bm->penX, bm->penY, x, y);
252 gfx_MoveTo(bm, x, y);
257 * Draw a filled rectangle.
258 * \note The bottom-right border of the rectangle is not drawn.
260 void gfx_FillRect(Bitmap *bm, coord_t x1, coord_t y1, coord_t x2, coord_t y2)
265 if (x1 > x2) SWAP(x1, x2);
266 if (y1 > y2) SWAP(y1, y2);
268 /* Clip rect to bitmap bounds */
271 if (x1 > bm->width) x1 = bm->width;
272 if (x2 > bm->width) x2 = bm->width;
275 if (y1 > bm->width) y1 = bm->width;
276 if (y2 > bm->width) y2 = bm->width;
279 for (x = x1; x < x2; x++)
280 for (y = y1; y < y2; y++)
286 * Draw an empty rectangle.
287 * \note The bottom-right border of the rectangle is not drawn.
289 void gfx_DrawRect(Bitmap *bm, coord_t x1, coord_t y1, coord_t x2, coord_t y2)
292 if (x1 > x2) SWAP(x1, x2);
293 if (y1 > y2) SWAP(y1, y2);
296 gfx_DrawLine(bm, x1, y1, x2-1, y1);
297 gfx_DrawLine(bm, x2-1, y1, x2-1, y2-1);
298 gfx_DrawLine(bm, x2-1, y2-1, x1, y2-1);
299 gfx_DrawLine(bm, x1, y2-1, x1, y1);
304 * Clear a rectangular area.
305 * \note The bottom-right border of the rectangle is not drawn.
307 void gfx_ClearRect(Bitmap *bm, coord_t x1, coord_t y1, coord_t x2, coord_t y2)
312 if (x1 > x2) SWAP(x1, x2);
313 if (y1 > y2) SWAP(y1, y2);
315 /* Clip rect to bitmap bounds */
318 if (x1 > bm->width) x1 = bm->width;
319 if (x2 > bm->width) x2 = bm->width;
322 if (y1 > bm->width) y1 = bm->width;
323 if (y2 > bm->width) y2 = bm->width;
326 for (x = x1; x < x2; x++)
327 for (y = y1; y < y2; y++)
333 * Imposta un rettangolo di clipping per il disegno nella bitmap
335 void gfx_SetClipRect(Bitmap *bm, coord_t minx, coord_t miny, coord_t maxx, coord_t maxy)
341 ASSERT(maxx < bm->width);
342 ASSERT(maxy < bm->height);
349 /* DB(kprintf("cr.xmin = %d, cr.ymin = %d, cr.xmax = %d, cr.ymax = %d\n",
350 bm->cr.xMin, bm->cr.ymin, bm->cr.xmax, bm->cr.ymax);)
355 #ifdef CONFIG_LCD_VCOORDS
357 * Imposta gli estremi del sistema di coordinate cartesiane rispetto
358 * al rettangolo di clipping della bitmap.
360 void gfx_SetViewRect(Bitmap *bm, vcoord_t x1, vcoord_t y1, vcoord_t x2, vcoord_t y2)
367 bm->scaleX = (vcoord_t)(bm->cr.xmax - bm->cr.xmin) / (vcoord_t)(x2 - x1); /* +1 */
368 bm->scaleY = (vcoord_t)(bm->cr.ymax - bm->cr.ymin) / (vcoord_t)(y2 - y1); /* +1 */
370 /* DB(kprintf("orgX = %f, orgY = %f, scaleX = %f, scaleY = %f\n",
371 bm->orgX, bm->orgY, bm->scaleX, bm->scaleY);)
377 * Transform a coordinate from the current reference system to a
378 * pixel offset within the bitmap.
380 coord_t gfx_TransformX(Bitmap *bm, vcoord_t x)
382 return bm->cr.xmin + (coord_t)((x - bm->orgX) * bm->scaleX);
386 * Transform a coordinate from the current reference system to a
387 * pixel offset within the bitmap.
389 coord_t gfx_TransformY(Bitmap *bm, vcoord_t y)
391 return bm->cr.ymin + (coord_t)((y - bm->orgY) * bm->scaleY);
396 * Draw a line from (x1;y1) to (x2;y2)
398 void gfx_VDrawLine(Bitmap *bm, vcoord_t x1, vcoord_t y1, vcoord_t x2, vcoord_t y2)
401 gfx_TransformX(bm, x1), gfx_TransformY(bm, y1),
402 gfx_TransformY(bm, x2), gfx_TransformY(bm, y2));
404 #endif /* CONFIG_LCD_VCOORDS */