/** * Copy a rectangular area of a bitmap on another bitmap. * * Blitting is a common copy operation involving two bitmaps. * A rectangular area of the source bitmap is copied bit-wise * to a different position in the destination bitmap. * * \note Using the same bitmap for \a src and \a dst is unsupported. * * \param dst Bitmap where the operation writes. * \param rect The (xmin;ymin) coordinates provide the top/left offset * for drawing in the destination bitmap. If the source * bitmap is larger than the rectangle, drawing is clipped. * \param src Bitmap containing the source pixels. * \param srcx Starting X offset in the source bitmap. * \param srcy Starting Y offset in the source bitmap. */ void gfx_blit(Bitmap *dst, const Rect *rect, const Bitmap *src, coord_t srcx, coord_t srcy) { coord_t dxmin, dymin, dxmax, dymax; coord_t dx, dy, sx, sy; /* * Pre-clip coordinates inside src->width/height. */ dxmin = rect->xmin; dymin = rect->ymin; dxmax = MIN(rect->xmax, rect->xmin + src->width); dymax = MIN(rect->ymax, rect->ymin + src->height); /* Perform regular clipping */ gfx_clip(dxmin, dxmax, srcx, dst->cr.xmin, dst->cr.xmax); gfx_clip(dymin, dymax, srcy, dst->cr.ymin, dst->cr.ymax); //kprintf("dxmin=%d, sxmin=%d, dxmax=%d; ", dxmin, sxmin, dxmax); //kprintf("dymin=%d, symin=%d, dymax=%d\n", dymin, symin, dymax); /* TODO: make it not as dog slow as this */ for (dx = dxmin, sx = srcx; dx < dxmax; ++dx, ++sx) for (dy = dymin, sy = srcy; dy < dymax; ++dy, ++sy) BM_DRAWPIXEL(dst, dx, dy, BM_READPIXEL(src, sx, sy)); }
/** * Blit a raster to a Bitmap. * * \todo Merge this function into gfx_blit() * * \see gfx_blit() */ void gfx_blitRaster(Bitmap *dst, coord_t dxmin, coord_t dymin, const uint8_t *raster, coord_t w, coord_t h, coord_t stride) { coord_t dxmax = dxmin + w, dymax = dymin + h; coord_t sxmin = 0, symin = 0; coord_t dx, dy, sx, sy; /* Perform regular clipping */ gfx_clip(dxmin, dxmax, sxmin, dst->cr.xmin, dst->cr.xmax); gfx_clip(dymin, dymax, symin, dst->cr.ymin, dst->cr.ymax); //kprintf("dxmin=%d, sxmin=%d, dxmax=%d; ", dxmin, sxmin, dxmax); //kprintf("dymin=%d, symin=%d, dymax=%d\n", dymin, symin, dymax); /* TODO: make it not as dog slow as this */ for (dx = dxmin, sx = sxmin; dx < dxmax; ++dx, ++sx) for (dy = dymin, sy = symin; dy < dymax; ++dy, ++sy) BM_DRAWPIXEL(dst, dx, dy, RAST_READPIXEL(raster, sx, sy, stride)); }
void gfx_draw_image_section(const struct image *image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, unsigned flags) { if (test_bit(flags, GFX_NO_CLIPPING)) { image_blit(image, src_x, src_y, src_w, src_h, gfx_back_buffer, dst_x, dst_y, flags & IMAGE_BLIT_MASK); } else { int cx = dst_x; int cy = dst_y; int cw = src_w; int ch = src_h; if (!gfx_clip(&cx, &cy, &cw, &ch)) return; int dx = (cx - dst_x); int dy = (cy - dst_y); image_blit(image, src_x + dx, src_y + dy, cw, ch, gfx_back_buffer, dst_x + dx, dst_y + dy, flags & IMAGE_BLIT_MASK); } }