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