bitmap.c

Go to the documentation of this file.
00001 
00040 #include "gfx.h"
00041 #include "gfx_p.h"
00042 
00043 #include <cfg/debug.h>  /* ASSERT() */
00044 #include <cpu/attr.h>   /* CPU_HARVARD */
00045 #include <cfg/macros.h> /* MIN() */
00046 #include <appconfig.h>  /* CONFIG_GFX_CLIPPING */
00047 
00048 #include <string.h>     /* memset() */
00049 
00050 #if CONFIG_GFX_TEXT
00051 #include <gfx/font.h>   /* default_font */
00052 #endif
00053 
00054 
00060 void gfx_bitmapInit(Bitmap *bm, uint8_t *raster, coord_t w, coord_t h)
00061 {
00062     bm->raster = raster;
00063     bm->width = w;
00064     bm->height = h;
00065     #if (CONFIG_BITMAP_FMT == BITMAP_FMT_PLANAR_H_MSB)
00066         bm->stride = (w + 7) / 8;
00067     #elif CONFIG_BITMAP_FMT == BITMAP_FMT_PLANAR_V_LSB
00068         bm->stride = w;
00069     #else
00070         #error Unknown value of CONFIG_BITMAP_FMT
00071     #endif /* CONFIG_BITMAP_FMT */
00072     bm->penX = 0;
00073     bm->penY = 0;
00074 
00075 #if CONFIG_GFX_TEXT
00076     gfx_setFont(bm, &default_font);
00077     bm->styles = 0;
00078 #endif
00079 
00080 #if CONFIG_GFX_CLIPPING
00081     bm->cr.xmin = 0;
00082     bm->cr.ymin = 0;
00083     bm->cr.xmax = w;
00084     bm->cr.ymax = h;
00085 #endif /* CONFIG_GFX_CLIPPING */
00086 }
00087 
00088 
00095 void gfx_bitmapClear(Bitmap *bm)
00096 {
00097     memset(bm->raster, 0, RAST_SIZE(bm->width, bm->height));
00098 }
00099 
00100 
00101 #if CPU_HARVARD
00102 
00103 #include <avr/pgmspace.h> /* FIXME: memcpy_P() */
00104 
00111 void gfx_blit_P(Bitmap *bm, const pgm_uint8_t *raster)
00112 {
00113     memcpy_P(bm->raster, raster, RAST_SIZE(bm->width, bm->height));
00114 }
00115 #endif /* CPU_HARVARD */
00116 
00117 #if CONFIG_GFX_CLIPPING
00118 
00128     #define gfx_clip(dmin, dmax, smin, cmin, cmax) \
00129         do { \
00130             if ((dmin) < (cmin)) \
00131             { \
00132                 (smin) += (cmin) - (dmin); \
00133                 (dmin) = (cmin); \
00134             } \
00135             (dmax) = MIN((dmax), (cmax)); \
00136         } while(0)
00137 
00138 #else /* !CONFIG_GFX_CLIPPING */
00139 
00140     #define gfx_clip(dmin, dmax, smin, cmin, cmax) do { } while (0)
00141 
00142 #endif /* !CONFIG_GFX_CLIPPING */
00143 
00144 
00162 void gfx_blit(Bitmap *dst, const Rect *rect, const Bitmap *src, coord_t srcx, coord_t srcy)
00163 {
00164     coord_t dxmin, dymin, dxmax, dymax;
00165     coord_t dx, dy, sx, sy;
00166 
00167     /*
00168      * Pre-clip coordinates inside src->width/height.
00169      */
00170     dxmin = rect->xmin;
00171     dymin = rect->ymin;
00172     dxmax = MIN(rect->xmax, rect->xmin + src->width);
00173     dymax = MIN(rect->ymax, rect->ymin + src->height);
00174 
00175     /* Perform regular clipping */
00176     gfx_clip(dxmin, dxmax, srcx, dst->cr.xmin, dst->cr.xmax);
00177     gfx_clip(dymin, dymax, srcy, dst->cr.ymin, dst->cr.ymax);
00178 
00179     //kprintf("dxmin=%d, sxmin=%d, dxmax=%d; ", dxmin, sxmin, dxmax);
00180     //kprintf("dymin=%d, symin=%d, dymax=%d\n", dymin, symin, dymax);
00181 
00182     /* TODO: make it not as dog slow as this */
00183     for (dx = dxmin, sx = srcx; dx < dxmax; ++dx, ++sx)
00184         for (dy = dymin, sy = srcy; dy < dymax; ++dy, ++sy)
00185             BM_DRAWPIXEL(dst, dx, dy, BM_READPIXEL(src, sx, sy));
00186 }
00187 
00195 void gfx_blitRaster(Bitmap *dst, coord_t dxmin, coord_t dymin,
00196         const uint8_t *raster, coord_t w, coord_t h, coord_t stride)
00197 {
00198     coord_t dxmax = dxmin + w, dymax = dymin + h;
00199     coord_t sxmin = 0, symin = 0;
00200     coord_t dx, dy, sx, sy;
00201 
00202     /* Perform regular clipping */
00203     gfx_clip(dxmin, dxmax, sxmin, dst->cr.xmin, dst->cr.xmax);
00204     gfx_clip(dymin, dymax, symin, dst->cr.ymin, dst->cr.ymax);
00205 
00206     //kprintf("dxmin=%d, sxmin=%d, dxmax=%d; ", dxmin, sxmin, dxmax);
00207     //kprintf("dymin=%d, symin=%d, dymax=%d\n", dymin, symin, dymax);
00208 
00209     /* TODO: make it not as dog slow as this */
00210     for (dx = dxmin, sx = sxmin; dx < dxmax; ++dx, ++sx)
00211         for (dy = dymin, sy = symin; dy < dymax; ++dy, ++sy)
00212             BM_DRAWPIXEL(dst, dx, dy, RAST_READPIXEL(raster, sx, sy, stride));
00213 }
00214 
00220 void gfx_blitImage(Bitmap *dst, coord_t dxmin, coord_t dymin, const Image *image)
00221 {
00222     ASSERT(image);
00223 
00224     gfx_blitRaster(dst, dxmin, dymin,
00225             image->raster, image->width, image->height, image->stride);
00226 }
00227 
00228 
00229 #if CONFIG_GFX_CLIPPING || CONFIG_GFX_VCOORDS
00230 
00246 void gfx_setClipRect(Bitmap *bm, coord_t minx, coord_t miny, coord_t maxx, coord_t maxy)
00247 {
00248     ASSERT(minx < maxx);
00249     ASSERT(miny < maxy);
00250     ASSERT(miny >= 0);
00251     ASSERT(minx >= 0);
00252     ASSERT(maxx <= bm->width);
00253     ASSERT(maxy <= bm->height);
00254 
00255     bm->cr.xmin = minx;
00256     bm->cr.ymin = miny;
00257     bm->cr.xmax = maxx;
00258     bm->cr.ymax = maxy;
00259 
00260 //  kprintf("cr.xmin = %d, cr.ymin = %d, cr.xmax = %d, cr.ymax = %d\n",
00261 //      bm->cr.xMin, bm->cr.ymin, bm->cr.xmax, bm->cr.ymax);
00262 }
00263 
00264 #endif /* CONFIG_GFX_CLIPPING */
00265