bitmap.c

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