diff --git a/src/servers/app/drawing/Painter/bitmap_painter/BitmapPainter.cpp b/src/servers/app/drawing/Painter/bitmap_painter/BitmapPainter.cpp index a56635630d..813f291e90 100644 --- a/src/servers/app/drawing/Painter/bitmap_painter/BitmapPainter.cpp +++ b/src/servers/app/drawing/Painter/bitmap_painter/BitmapPainter.cpp @@ -82,19 +82,22 @@ Painter::BitmapPainter::Draw(const BRect& sourceRect, if (!_HasScale() && !_HasAffineTransform() && !_HasAlphaMask()) { if (fColorSpace == B_CMAP8) { if (fPainter->fDrawingMode == B_OP_COPY) { - DrawBitmapNoScale::Draw(fPainter->fInternal, - fBitmap, 1, fOffset, fDestinationRect); + DrawBitmapNoScale drawNoScale; + drawNoScale.Draw(fPainter->fInternal, fBitmap, 1, fOffset, + fDestinationRect); return; } if (fPainter->fDrawingMode == B_OP_OVER) { - DrawBitmapNoScale::Draw(fPainter->fInternal, - fBitmap, 1, fOffset, fDestinationRect); + DrawBitmapNoScale drawNoScale; + drawNoScale.Draw(fPainter->fInternal, fBitmap, 1, fOffset, + fDestinationRect); return; } } else if (fColorSpace == B_RGB32) { if (fPainter->fDrawingMode == B_OP_OVER) { - DrawBitmapNoScale::Draw(fPainter->fInternal, - fBitmap, 4, fOffset, fDestinationRect); + DrawBitmapNoScale drawNoScale; + drawNoScale.Draw(fPainter->fInternal, fBitmap, 4, fOffset, + fDestinationRect); return; } } @@ -106,16 +109,27 @@ Painter::BitmapPainter::Draw(const BRect& sourceRect, // optimized version if there is no scale if (!_HasScale() && !_HasAffineTransform() && !_HasAlphaMask()) { if (fPainter->fDrawingMode == B_OP_COPY) { - DrawBitmapNoScale::Draw(fPainter->fInternal, - fBitmap, 4, fOffset, fDestinationRect); + DrawBitmapNoScale drawNoScale; + drawNoScale.Draw(fPainter->fInternal, fBitmap, 4, fOffset, + fDestinationRect); return; } if (fPainter->fDrawingMode == B_OP_OVER || (fPainter->fDrawingMode == B_OP_ALPHA && fPainter->fAlphaSrcMode == B_PIXEL_ALPHA && fPainter->fAlphaFncMode == B_ALPHA_OVERLAY)) { - DrawBitmapNoScale::Draw(fPainter->fInternal, - fBitmap, 4, fOffset, fDestinationRect); + DrawBitmapNoScale drawNoScale; + drawNoScale.Draw(fPainter->fInternal, fBitmap, 4, fOffset, + fDestinationRect); + return; + } + } + + if (!_HasScale() && !_HasAffineTransform() && _HasAlphaMask()) { + if (fPainter->fDrawingMode == B_OP_COPY) { + DrawBitmapNoScale drawNoScale; + drawNoScale.Draw(fPainter->fInternal, fBitmap, 4, fOffset, + fDestinationRect); return; } } diff --git a/src/servers/app/drawing/Painter/bitmap_painter/DrawBitmapNoScale.h b/src/servers/app/drawing/Painter/bitmap_painter/DrawBitmapNoScale.h index 61be834b4f..d42371552d 100644 --- a/src/servers/app/drawing/Painter/bitmap_painter/DrawBitmapNoScale.h +++ b/src/servers/app/drawing/Painter/bitmap_painter/DrawBitmapNoScale.h @@ -9,12 +9,14 @@ #define DRAW_BITMAP_NO_SCALE_H #include "IntPoint.h" +#include "IntRect.h" #include "Painter.h" template struct DrawBitmapNoScale { - static void +public: + void Draw(PainterAggInterface& aggInterface, agg::rendering_buffer& bitmap, uint32 bytesPerSourcePixel, IntPoint offset, BRect destinationRect) { @@ -49,25 +51,28 @@ struct DrawBitmapNoScale { } #endif - const rgb_color* colorMap = SystemPalette(); + fColorMap = SystemPalette(); + fAlphaMask = aggInterface.fClippedAlphaMask; renderer_base& baseRenderer = aggInterface.fBaseRenderer; // copy rects, iterate over clipping boxes baseRenderer.first_clip_box(); do { - int32 x1 = max_c(baseRenderer.xmin(), left); - int32 x2 = min_c(baseRenderer.xmax(), right); - if (x1 <= x2) { - int32 y1 = max_c(baseRenderer.ymin(), top); - int32 y2 = min_c(baseRenderer.ymax(), bottom); - if (y1 <= y2) { - uint8* dstHandle = dst + y1 * dstBPR + x1 * 4; - const uint8* srcHandle = src + (y1 - offset.y) * srcBPR - + (x1 - offset.x) * bytesPerSourcePixel; + fRect.left = max_c(baseRenderer.xmin(), left); + fRect.right = min_c(baseRenderer.xmax(), right); + if (fRect.left <= fRect.right) { + fRect.top = max_c(baseRenderer.ymin(), top); + fRect.bottom = min_c(baseRenderer.ymax(), bottom); + if (fRect.top <= fRect.bottom) { + uint8* dstHandle = dst + fRect.top * dstBPR + + fRect.left * 4; + const uint8* srcHandle = src + + (fRect.top - offset.y) * srcBPR + + (fRect.left - offset.x) * bytesPerSourcePixel; - for (; y1 <= y2; y1++) { - BlendType::BlendRow(dstHandle, srcHandle, - x2 - x1 + 1, colorMap); + for (; fRect.top <= fRect.bottom; fRect.top++) { + static_cast(this)->BlendRow(dstHandle, + srcHandle, fRect.right - fRect.left + 1); dstHandle += dstBPR; srcHandle += srcBPR; @@ -76,18 +81,22 @@ struct DrawBitmapNoScale { } } while (baseRenderer.next_clip_box()); } + +protected: + IntRect fRect; + const rgb_color* fColorMap; + const agg::clipped_alpha_mask* fAlphaMask; }; struct CMap8Copy : public DrawBitmapNoScale { - static void BlendRow(uint8* dst, const uint8* src, int32 numPixels, - const rgb_color* colorMap) + void BlendRow(uint8* dst, const uint8* src, int32 numPixels) { uint32* d = (uint32*)dst; const uint8* s = src; while (numPixels--) { - const rgb_color c = colorMap[*s++]; + const rgb_color c = fColorMap[*s++]; *d++ = (c.alpha << 24) | (c.red << 16) | (c.green << 8) | (c.blue); } } @@ -96,13 +105,12 @@ struct CMap8Copy : public DrawBitmapNoScale struct CMap8Over : public DrawBitmapNoScale { - static void BlendRow(uint8* dst, const uint8* src, int32 numPixels, - const rgb_color* colorMap) + void BlendRow(uint8* dst, const uint8* src, int32 numPixels) { uint32* d = (uint32*)dst; const uint8* s = src; while (numPixels--) { - const rgb_color c = colorMap[*s++]; + const rgb_color c = fColorMap[*s++]; if (c.alpha) *d = (c.alpha << 24) | (c.red << 16) | (c.green << 8) | (c.blue); @@ -114,8 +122,7 @@ struct CMap8Over : public DrawBitmapNoScale struct Bgr32Copy : public DrawBitmapNoScale { - static void BlendRow(uint8* dst, const uint8* src, int32 numPixels, - const rgb_color*) + void BlendRow(uint8* dst, const uint8* src, int32 numPixels) { memcpy(dst, src, numPixels * 4); } @@ -124,8 +131,7 @@ struct Bgr32Copy : public DrawBitmapNoScale struct Bgr32Over : public DrawBitmapNoScale { - static void BlendRow(uint8* dst, const uint8* src, int32 numPixels, - const rgb_color*) + void BlendRow(uint8* dst, const uint8* src, int32 numPixels) { uint32* d = (uint32*)dst; uint32* s = (uint32*)src; @@ -141,8 +147,7 @@ struct Bgr32Over : public DrawBitmapNoScale struct Bgr32Alpha : public DrawBitmapNoScale { - static void BlendRow(uint8* dst, const uint8* src, int32 numPixels, - const rgb_color*) + void BlendRow(uint8* dst, const uint8* src, int32 numPixels) { uint32* d = (uint32*)dst; int32 bytes = numPixels * 4; @@ -166,4 +171,26 @@ struct Bgr32Alpha : public DrawBitmapNoScale }; +struct Bgr32CopyMasked : public DrawBitmapNoScale +{ + void BlendRow(uint8* dst, const uint8* src, int32 numPixels) + { + uint8 covers[numPixels]; + fAlphaMask->get_hspan(fRect.left, fRect.top, covers, numPixels); + + uint32* destination = (uint32*)dst; + uint32* source = (uint32*)src; + uint8* mask = (uint8*)&covers[0]; + + while (numPixels--) { + if (*mask != 0) + *destination = *source; + destination++; + source++; + mask++; + } + } +}; + + #endif // DRAW_BITMAP_NO_SCALE_H