X-Git-Url: https://codewiz.org/gitweb?a=blobdiff_plain;f=mware%2Fgfx.c;h=2a4d8ef95af168ab340cc92e2d0f7c42055c14b9;hb=edce74d23db44bb7857440e8144484dc73c22ee9;hp=9d1e6d3aee589c5a7498ea06023438fdfbbb7884;hpb=277b540c0764dd376dcf583acdc97a2b2fd3d8e6;p=bertos.git diff --git a/mware/gfx.c b/mware/gfx.c index 9d1e6d3a..2a4d8ef9 100755 --- a/mware/gfx.c +++ b/mware/gfx.c @@ -1,7 +1,7 @@ /*! * \file * @@ -16,8 +16,20 @@ /*#* *#* $Log$ - *#* Revision 1.5 2004/08/25 14:12:09 rasky - *#* Aggiornato il comment block dei log RCS + *#* Revision 1.11 2004/12/08 08:06:16 bernie + *#* Remove done todo. + *#* + *#* Revision 1.10 2004/11/01 15:14:07 bernie + *#* Update to current coding conventions. + *#* + *#* Revision 1.9 2004/10/21 10:58:33 bernie + *#* Add a TODO item. + *#* + *#* Revision 1.8 2004/09/20 03:29:22 bernie + *#* Relax assertion. + *#* + *#* Revision 1.7 2004/09/14 21:01:08 bernie + *#* Rename rectangle drawing functions; Unify filled/cleared implementations. *#* *#* Revision 1.4 2004/08/24 16:53:10 bernie *#* Use new-style config macros. @@ -27,45 +39,53 @@ *#* *#* Revision 1.2 2004/06/03 11:27:09 bernie *#* Add dual-license information. - *#* *#*/ #include "gfx.h" -#include "config.h" -#include +#include "config.h" /* CONFIG_GFX_CLIPPING */ +#include +#include /* CPU_HARVARD */ +#include /* SWAP() */ #include /*! - * Plot a point in bitmap. + * Plot a point in bitmap \a bm. + * * \note bm is evaluated twice */ #define BM_PLOT(bm, x, y) \ ( *((bm)->raster + ((y) / 8) * (bm)->width + (x)) |= 1 << ((y) % 8) ) /*! - * Clear a point in bitmap. + * Clear a point in bitmap \a bm. + * * \note bm is evaluated twice */ #define BM_CLEAR(bm, x, y) \ ( *((bm)->raster + ((y) / 8) * (bm)->width + (x)) &= ~(1 << ((y) % 8)) ) -/*! Swap a with b */ -#define SWAP(a, b) \ +/*! + * Set a point in bitmap \a bm to the specified color. + * + * \note bm is evaluated twice + * \note This macro is somewhat slower than BM_PLOT and BM_CLEAR. + * \see BM_PLOT BM_CLEAR + */ +#define BM_DRAWPIXEL(bm, x, y, fg_pen) \ do { \ - (void)(&a == &b); /* type check */ \ - typeof(a) tmp; \ - tmp = (a); \ - (a) = (b); \ - (b) = tmp; \ + uint8_t *p = (bm)->raster + ((y) / 8) * (bm)->width + (x); \ + uint8_t mask = 1 << ((y) % 8); \ + *p = (*p & ~mask) | ((fg_pen) ? mask : 0); \ } while (0) - /*! * Initialize a Bitmap structure with the provided parameters. + * + * \note The pen position is reset to the origin. */ -void gfx_InitBitmap(Bitmap *bm, uint8_t *raster, coord_t w, coord_t h) +void gfx_bitmapInit(Bitmap *bm, uint8_t *raster, coord_t w, coord_t h) { bm->raster = raster; bm->width = w; @@ -76,25 +96,39 @@ void gfx_InitBitmap(Bitmap *bm, uint8_t *raster, coord_t w, coord_t h) /*! - * Clear the whole bitmap surface to all zeros + * Clear the whole bitmap surface to the background color. + * + * \note This function does \b not update the current pen position */ -void gfx_ClearBitmap(Bitmap *bm) +void gfx_bitmapClear(Bitmap *bm) { memset(bm->raster, 0, (bm->width * bm->height) / 8); } +#if CPU_HARVARD /*! * Copy a raster picture located in program memory in the bitmap. * The size of the raster to copy *must* be the same of the raster bitmap. + * + * \note This function does \b not update the current pen position */ -void gfx_blitBitmap_P(Bitmap *bm, const prog_uchar *raster) +void gfx_blit_P(Bitmap *bm, const prog_uchar *raster) { - memcpy_P(bm->raster, raster, bm->height/8 * bm->width); + memcpy_P(bm->raster, raster, (bm->height / 8) * bm->width); } +#endif /* CPU_HARVARD */ -void gfx_DrawLine(Bitmap *bm, coord_t x1, coord_t y1, coord_t x2, coord_t y2) +/*! + * Draw a line on the bitmap \a bm using the specified start and end + * coordinates. + * + * \note This function does \b not update the current pen position. + * + * \todo Optimize for vertical and horiziontal lines. + */ +void gfx_line(Bitmap *bm, coord_t x1, coord_t y1, coord_t x2, coord_t y2) { int x, y, e, len, adx, ady, signx, signy; @@ -230,25 +264,56 @@ void gfx_DrawLine(Bitmap *bm, coord_t x1, coord_t y1, coord_t x2, coord_t y2) } -void gfx_MoveTo(Bitmap *bm, coord_t x, coord_t y) +/*! + * Move the current pen position to the specified coordinates. + */ +void gfx_moveTo(Bitmap *bm, coord_t x, coord_t y) { bm->penX = x; bm->penY = y; } +/*! + * Draw a line from the current pen position to the new coordinates. + * + * \note This function moves the current pen position to the + * new coordinates. + */ +void gfx_lineTo(Bitmap *bm, coord_t x, coord_t y) +{ + gfx_line(bm, bm->penX, bm->penY, x, y); + gfx_moveTo(bm, x, y); +} + -void gfx_LineTo(Bitmap *bm, coord_t x, coord_t y) +/*! + * Draw an the outline of an hollow rectangle. + * + * \note The bottom-right border of the rectangle is not drawn. + * \note This function does \b not update the current pen position + */ +void gfx_rectDraw(Bitmap *bm, coord_t x1, coord_t y1, coord_t x2, coord_t y2) { - gfx_DrawLine(bm, bm->penX, bm->penY, x, y); - gfx_MoveTo(bm, x, y); + /* Sort coords (needed for correct bottom-right semantics) */ + if (x1 > x2) SWAP(x1, x2); + if (y1 > y2) SWAP(y1, y2); + + /* Draw rectangle */ + gfx_line(bm, x1, y1, x2-1, y1); + gfx_line(bm, x2-1, y1, x2-1, y2-1); + gfx_line(bm, x2-1, y2-1, x1, y2-1); + gfx_line(bm, x1, y2-1, x1, y1); } /*! - * Draw a filled rectangle. + * Fill a rectangular area with \a color. + * * \note The bottom-right border of the rectangle is not drawn. + * + * \note This function does \b not update the current pen position */ -void gfx_FillRect(Bitmap *bm, coord_t x1, coord_t y1, coord_t x2, coord_t y2) +void gfx_rectFillC(Bitmap *bm, coord_t x1, coord_t y1, coord_t x2, coord_t y2, uint8_t color) { coord_t x, y; @@ -266,71 +331,62 @@ void gfx_FillRect(Bitmap *bm, coord_t x1, coord_t y1, coord_t x2, coord_t y2) if (y1 > bm->width) y1 = bm->width; if (y2 > bm->width) y2 = bm->width; - /* Draw rectangle */ - for (x = x1; x < x2; x++) - for (y = y1; y < y2; y++) - BM_PLOT(bm, x, y); + /* + * Draw rectangle + * NOTE: Code paths are duplicated for efficiency + */ + if (color) /* fill */ + { + for (x = x1; x < x2; x++) + for (y = y1; y < y2; y++) + BM_PLOT(bm, x, y); + } + else /* clear */ + { + for (x = x1; x < x2; x++) + for (y = y1; y < y2; y++) + BM_CLEAR(bm, x, y); + } } /*! - * Draw an empty rectangle. + * Draw a filled rectangle. + * * \note The bottom-right border of the rectangle is not drawn. + * + * \note This function does \b not update the current pen position */ -void gfx_DrawRect(Bitmap *bm, coord_t x1, coord_t y1, coord_t x2, coord_t y2) +void gfx_rectFill(Bitmap *bm, coord_t x1, coord_t y1, coord_t x2, coord_t y2) { - /* Sort coords */ - if (x1 > x2) SWAP(x1, x2); - if (y1 > y2) SWAP(y1, y2); - - /* Draw rectangle */ - gfx_DrawLine(bm, x1, y1, x2-1, y1); - gfx_DrawLine(bm, x2-1, y1, x2-1, y2-1); - gfx_DrawLine(bm, x2-1, y2-1, x1, y2-1); - gfx_DrawLine(bm, x1, y2-1, x1, y1); + gfx_rectFillC(bm, x1, y1, x2, y2, 0xFF); } /*! * Clear a rectangular area. + * * \note The bottom-right border of the rectangle is not drawn. + * + * \note This function does \b not update the current pen position */ -void gfx_ClearRect(Bitmap *bm, coord_t x1, coord_t y1, coord_t x2, coord_t y2) +void gfx_rectClear(Bitmap *bm, coord_t x1, coord_t y1, coord_t x2, coord_t y2) { - coord_t x, y; - - /* Sort coords */ - if (x1 > x2) SWAP(x1, x2); - if (y1 > y2) SWAP(y1, y2); - - /* Clip rect to bitmap bounds */ - if (x1 < 0) x1 = 0; - if (x2 < 0) x2 = 0; - if (x1 > bm->width) x1 = bm->width; - if (x2 > bm->width) x2 = bm->width; - if (y1 < 0) y1 = 0; - if (y2 < 0) y2 = 0; - if (y1 > bm->width) y1 = bm->width; - if (y2 > bm->width) y2 = bm->width; - - /* Draw rectangle */ - for (x = x1; x < x2; x++) - for (y = y1; y < y2; y++) - BM_CLEAR(bm, x, y); + gfx_rectFillC(bm, x1, y1, x2, y2, 0x00); } /*! - * Imposta un rettangolo di clipping per il disegno nella bitmap + * Imposta un rettangolo di clipping per il disegno nella bitmap. */ -void gfx_SetClipRect(Bitmap *bm, coord_t minx, coord_t miny, coord_t maxx, coord_t maxy) +void gfx_setClipRect(Bitmap *bm, coord_t minx, coord_t miny, coord_t maxx, coord_t maxy) { ASSERT(minx < maxx); ASSERT(miny < maxy); ASSERT(miny >= 0); ASSERT(minx >= 0); - ASSERT(maxx < bm->width); - ASSERT(maxy < bm->height); + ASSERT(maxx <= bm->width); + ASSERT(maxy <= bm->height); bm->cr.xmin = minx; bm->cr.ymin = miny; @@ -348,15 +404,15 @@ void gfx_SetClipRect(Bitmap *bm, coord_t minx, coord_t miny, coord_t maxx, coord * Imposta gli estremi del sistema di coordinate cartesiane rispetto * al rettangolo di clipping della bitmap. */ -void gfx_SetViewRect(Bitmap *bm, vcoord_t x1, vcoord_t y1, vcoord_t x2, vcoord_t y2) +void gfx_setViewRect(Bitmap *bm, vcoord_t x1, vcoord_t y1, vcoord_t x2, vcoord_t y2) { ASSERT(x1 != x2); ASSERT(y1 != y2); bm->orgX = x1; bm->orgY = y1; - bm->scaleX = (vcoord_t)(bm->cr.xmax - bm->cr.xmin) / (vcoord_t)(x2 - x1); /* +1 */ - bm->scaleY = (vcoord_t)(bm->cr.ymax - bm->cr.ymin) / (vcoord_t)(y2 - y1); /* +1 */ + bm->scaleX = (vcoord_t)(bm->cr.xmax - bm->cr.xmin - 1) / (vcoord_t)(x2 - x1); + bm->scaleY = (vcoord_t)(bm->cr.ymax - bm->cr.ymin - 1) / (vcoord_t)(y2 - y1); /* DB(kprintf("orgX = %f, orgY = %f, scaleX = %f, scaleY = %f\n", bm->orgX, bm->orgY, bm->scaleX, bm->scaleY);) @@ -368,7 +424,7 @@ void gfx_SetViewRect(Bitmap *bm, vcoord_t x1, vcoord_t y1, vcoord_t x2, vcoord_t * Transform a coordinate from the current reference system to a * pixel offset within the bitmap. */ -coord_t gfx_TransformX(Bitmap *bm, vcoord_t x) +coord_t gfx_transformX(Bitmap *bm, vcoord_t x) { return bm->cr.xmin + (coord_t)((x - bm->orgX) * bm->scaleX); } @@ -377,19 +433,19 @@ coord_t gfx_TransformX(Bitmap *bm, vcoord_t x) * Transform a coordinate from the current reference system to a * pixel offset within the bitmap. */ -coord_t gfx_TransformY(Bitmap *bm, vcoord_t y) +coord_t gfx_transformY(Bitmap *bm, vcoord_t y) { return bm->cr.ymin + (coord_t)((y - bm->orgY) * bm->scaleY); } /*! - * Draw a line from (x1;y1) to (x2;y2) + * Draw a line from (x1;y1) to (x2;y2). */ -void gfx_VDrawLine(Bitmap *bm, vcoord_t x1, vcoord_t y1, vcoord_t x2, vcoord_t y2) +void gfx_vline(Bitmap *bm, vcoord_t x1, vcoord_t y1, vcoord_t x2, vcoord_t y2) { - gfx_DrawLine(bm, - gfx_TransformX(bm, x1), gfx_TransformY(bm, y1), - gfx_TransformY(bm, x2), gfx_TransformY(bm, y2)); + gfx_line(bm, + gfx_transformX(bm, x1), gfx_transformY(bm, y1), + gfx_transformY(bm, x2), gfx_transformY(bm, y2)); } #endif /* CONFIG_GFX_VCOORDS */