app_server: add alpha masked mode to DrawBitmapNoScale
* Add another mode to DrawBitmapNoScale for drawing bitmaps using B_OP_COPY with alpha masks. It behaves like the definition for ClipToPicture from the BeBook: pixels with alpha = 0 are ignored, pixels with any alpha > 0 are copied. Before, this fell back to the slower generic AGG-pipeline-based version. * Some light refactoring
This commit is contained in:
@@ -82,19 +82,22 @@ Painter::BitmapPainter::Draw(const BRect& sourceRect,
|
|||||||
if (!_HasScale() && !_HasAffineTransform() && !_HasAlphaMask()) {
|
if (!_HasScale() && !_HasAffineTransform() && !_HasAlphaMask()) {
|
||||||
if (fColorSpace == B_CMAP8) {
|
if (fColorSpace == B_CMAP8) {
|
||||||
if (fPainter->fDrawingMode == B_OP_COPY) {
|
if (fPainter->fDrawingMode == B_OP_COPY) {
|
||||||
DrawBitmapNoScale<CMap8Copy>::Draw(fPainter->fInternal,
|
DrawBitmapNoScale<CMap8Copy> drawNoScale;
|
||||||
fBitmap, 1, fOffset, fDestinationRect);
|
drawNoScale.Draw(fPainter->fInternal, fBitmap, 1, fOffset,
|
||||||
|
fDestinationRect);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (fPainter->fDrawingMode == B_OP_OVER) {
|
if (fPainter->fDrawingMode == B_OP_OVER) {
|
||||||
DrawBitmapNoScale<CMap8Over>::Draw(fPainter->fInternal,
|
DrawBitmapNoScale<CMap8Over> drawNoScale;
|
||||||
fBitmap, 1, fOffset, fDestinationRect);
|
drawNoScale.Draw(fPainter->fInternal, fBitmap, 1, fOffset,
|
||||||
|
fDestinationRect);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else if (fColorSpace == B_RGB32) {
|
} else if (fColorSpace == B_RGB32) {
|
||||||
if (fPainter->fDrawingMode == B_OP_OVER) {
|
if (fPainter->fDrawingMode == B_OP_OVER) {
|
||||||
DrawBitmapNoScale<Bgr32Over>::Draw(fPainter->fInternal,
|
DrawBitmapNoScale<Bgr32Over> drawNoScale;
|
||||||
fBitmap, 4, fOffset, fDestinationRect);
|
drawNoScale.Draw(fPainter->fInternal, fBitmap, 4, fOffset,
|
||||||
|
fDestinationRect);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -106,16 +109,27 @@ Painter::BitmapPainter::Draw(const BRect& sourceRect,
|
|||||||
// optimized version if there is no scale
|
// optimized version if there is no scale
|
||||||
if (!_HasScale() && !_HasAffineTransform() && !_HasAlphaMask()) {
|
if (!_HasScale() && !_HasAffineTransform() && !_HasAlphaMask()) {
|
||||||
if (fPainter->fDrawingMode == B_OP_COPY) {
|
if (fPainter->fDrawingMode == B_OP_COPY) {
|
||||||
DrawBitmapNoScale<Bgr32Copy>::Draw(fPainter->fInternal,
|
DrawBitmapNoScale<Bgr32Copy> drawNoScale;
|
||||||
fBitmap, 4, fOffset, fDestinationRect);
|
drawNoScale.Draw(fPainter->fInternal, fBitmap, 4, fOffset,
|
||||||
|
fDestinationRect);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (fPainter->fDrawingMode == B_OP_OVER
|
if (fPainter->fDrawingMode == B_OP_OVER
|
||||||
|| (fPainter->fDrawingMode == B_OP_ALPHA
|
|| (fPainter->fDrawingMode == B_OP_ALPHA
|
||||||
&& fPainter->fAlphaSrcMode == B_PIXEL_ALPHA
|
&& fPainter->fAlphaSrcMode == B_PIXEL_ALPHA
|
||||||
&& fPainter->fAlphaFncMode == B_ALPHA_OVERLAY)) {
|
&& fPainter->fAlphaFncMode == B_ALPHA_OVERLAY)) {
|
||||||
DrawBitmapNoScale<Bgr32Alpha>::Draw(fPainter->fInternal,
|
DrawBitmapNoScale<Bgr32Alpha> drawNoScale;
|
||||||
fBitmap, 4, fOffset, fDestinationRect);
|
drawNoScale.Draw(fPainter->fInternal, fBitmap, 4, fOffset,
|
||||||
|
fDestinationRect);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_HasScale() && !_HasAffineTransform() && _HasAlphaMask()) {
|
||||||
|
if (fPainter->fDrawingMode == B_OP_COPY) {
|
||||||
|
DrawBitmapNoScale<Bgr32CopyMasked> drawNoScale;
|
||||||
|
drawNoScale.Draw(fPainter->fInternal, fBitmap, 4, fOffset,
|
||||||
|
fDestinationRect);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,12 +9,14 @@
|
|||||||
#define DRAW_BITMAP_NO_SCALE_H
|
#define DRAW_BITMAP_NO_SCALE_H
|
||||||
|
|
||||||
#include "IntPoint.h"
|
#include "IntPoint.h"
|
||||||
|
#include "IntRect.h"
|
||||||
#include "Painter.h"
|
#include "Painter.h"
|
||||||
|
|
||||||
|
|
||||||
template<class BlendType>
|
template<class BlendType>
|
||||||
struct DrawBitmapNoScale {
|
struct DrawBitmapNoScale {
|
||||||
static void
|
public:
|
||||||
|
void
|
||||||
Draw(PainterAggInterface& aggInterface, agg::rendering_buffer& bitmap,
|
Draw(PainterAggInterface& aggInterface, agg::rendering_buffer& bitmap,
|
||||||
uint32 bytesPerSourcePixel, IntPoint offset, BRect destinationRect)
|
uint32 bytesPerSourcePixel, IntPoint offset, BRect destinationRect)
|
||||||
{
|
{
|
||||||
@@ -49,25 +51,28 @@ struct DrawBitmapNoScale {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const rgb_color* colorMap = SystemPalette();
|
fColorMap = SystemPalette();
|
||||||
|
fAlphaMask = aggInterface.fClippedAlphaMask;
|
||||||
renderer_base& baseRenderer = aggInterface.fBaseRenderer;
|
renderer_base& baseRenderer = aggInterface.fBaseRenderer;
|
||||||
|
|
||||||
// copy rects, iterate over clipping boxes
|
// copy rects, iterate over clipping boxes
|
||||||
baseRenderer.first_clip_box();
|
baseRenderer.first_clip_box();
|
||||||
do {
|
do {
|
||||||
int32 x1 = max_c(baseRenderer.xmin(), left);
|
fRect.left = max_c(baseRenderer.xmin(), left);
|
||||||
int32 x2 = min_c(baseRenderer.xmax(), right);
|
fRect.right = min_c(baseRenderer.xmax(), right);
|
||||||
if (x1 <= x2) {
|
if (fRect.left <= fRect.right) {
|
||||||
int32 y1 = max_c(baseRenderer.ymin(), top);
|
fRect.top = max_c(baseRenderer.ymin(), top);
|
||||||
int32 y2 = min_c(baseRenderer.ymax(), bottom);
|
fRect.bottom = min_c(baseRenderer.ymax(), bottom);
|
||||||
if (y1 <= y2) {
|
if (fRect.top <= fRect.bottom) {
|
||||||
uint8* dstHandle = dst + y1 * dstBPR + x1 * 4;
|
uint8* dstHandle = dst + fRect.top * dstBPR
|
||||||
const uint8* srcHandle = src + (y1 - offset.y) * srcBPR
|
+ fRect.left * 4;
|
||||||
+ (x1 - offset.x) * bytesPerSourcePixel;
|
const uint8* srcHandle = src
|
||||||
|
+ (fRect.top - offset.y) * srcBPR
|
||||||
|
+ (fRect.left - offset.x) * bytesPerSourcePixel;
|
||||||
|
|
||||||
for (; y1 <= y2; y1++) {
|
for (; fRect.top <= fRect.bottom; fRect.top++) {
|
||||||
BlendType::BlendRow(dstHandle, srcHandle,
|
static_cast<BlendType*>(this)->BlendRow(dstHandle,
|
||||||
x2 - x1 + 1, colorMap);
|
srcHandle, fRect.right - fRect.left + 1);
|
||||||
|
|
||||||
dstHandle += dstBPR;
|
dstHandle += dstBPR;
|
||||||
srcHandle += srcBPR;
|
srcHandle += srcBPR;
|
||||||
@@ -76,18 +81,22 @@ struct DrawBitmapNoScale {
|
|||||||
}
|
}
|
||||||
} while (baseRenderer.next_clip_box());
|
} while (baseRenderer.next_clip_box());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
IntRect fRect;
|
||||||
|
const rgb_color* fColorMap;
|
||||||
|
const agg::clipped_alpha_mask* fAlphaMask;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct CMap8Copy : public DrawBitmapNoScale<CMap8Copy>
|
struct CMap8Copy : public DrawBitmapNoScale<CMap8Copy>
|
||||||
{
|
{
|
||||||
static void BlendRow(uint8* dst, const uint8* src, int32 numPixels,
|
void BlendRow(uint8* dst, const uint8* src, int32 numPixels)
|
||||||
const rgb_color* colorMap)
|
|
||||||
{
|
{
|
||||||
uint32* d = (uint32*)dst;
|
uint32* d = (uint32*)dst;
|
||||||
const uint8* s = src;
|
const uint8* s = src;
|
||||||
while (numPixels--) {
|
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);
|
*d++ = (c.alpha << 24) | (c.red << 16) | (c.green << 8) | (c.blue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -96,13 +105,12 @@ struct CMap8Copy : public DrawBitmapNoScale<CMap8Copy>
|
|||||||
|
|
||||||
struct CMap8Over : public DrawBitmapNoScale<CMap8Over>
|
struct CMap8Over : public DrawBitmapNoScale<CMap8Over>
|
||||||
{
|
{
|
||||||
static void BlendRow(uint8* dst, const uint8* src, int32 numPixels,
|
void BlendRow(uint8* dst, const uint8* src, int32 numPixels)
|
||||||
const rgb_color* colorMap)
|
|
||||||
{
|
{
|
||||||
uint32* d = (uint32*)dst;
|
uint32* d = (uint32*)dst;
|
||||||
const uint8* s = src;
|
const uint8* s = src;
|
||||||
while (numPixels--) {
|
while (numPixels--) {
|
||||||
const rgb_color c = colorMap[*s++];
|
const rgb_color c = fColorMap[*s++];
|
||||||
if (c.alpha)
|
if (c.alpha)
|
||||||
*d = (c.alpha << 24) | (c.red << 16)
|
*d = (c.alpha << 24) | (c.red << 16)
|
||||||
| (c.green << 8) | (c.blue);
|
| (c.green << 8) | (c.blue);
|
||||||
@@ -114,8 +122,7 @@ struct CMap8Over : public DrawBitmapNoScale<CMap8Over>
|
|||||||
|
|
||||||
struct Bgr32Copy : public DrawBitmapNoScale<Bgr32Copy>
|
struct Bgr32Copy : public DrawBitmapNoScale<Bgr32Copy>
|
||||||
{
|
{
|
||||||
static void BlendRow(uint8* dst, const uint8* src, int32 numPixels,
|
void BlendRow(uint8* dst, const uint8* src, int32 numPixels)
|
||||||
const rgb_color*)
|
|
||||||
{
|
{
|
||||||
memcpy(dst, src, numPixels * 4);
|
memcpy(dst, src, numPixels * 4);
|
||||||
}
|
}
|
||||||
@@ -124,8 +131,7 @@ struct Bgr32Copy : public DrawBitmapNoScale<Bgr32Copy>
|
|||||||
|
|
||||||
struct Bgr32Over : public DrawBitmapNoScale<Bgr32Over>
|
struct Bgr32Over : public DrawBitmapNoScale<Bgr32Over>
|
||||||
{
|
{
|
||||||
static void BlendRow(uint8* dst, const uint8* src, int32 numPixels,
|
void BlendRow(uint8* dst, const uint8* src, int32 numPixels)
|
||||||
const rgb_color*)
|
|
||||||
{
|
{
|
||||||
uint32* d = (uint32*)dst;
|
uint32* d = (uint32*)dst;
|
||||||
uint32* s = (uint32*)src;
|
uint32* s = (uint32*)src;
|
||||||
@@ -141,8 +147,7 @@ struct Bgr32Over : public DrawBitmapNoScale<Bgr32Over>
|
|||||||
|
|
||||||
struct Bgr32Alpha : public DrawBitmapNoScale<Bgr32Alpha>
|
struct Bgr32Alpha : public DrawBitmapNoScale<Bgr32Alpha>
|
||||||
{
|
{
|
||||||
static void BlendRow(uint8* dst, const uint8* src, int32 numPixels,
|
void BlendRow(uint8* dst, const uint8* src, int32 numPixels)
|
||||||
const rgb_color*)
|
|
||||||
{
|
{
|
||||||
uint32* d = (uint32*)dst;
|
uint32* d = (uint32*)dst;
|
||||||
int32 bytes = numPixels * 4;
|
int32 bytes = numPixels * 4;
|
||||||
@@ -166,4 +171,26 @@ struct Bgr32Alpha : public DrawBitmapNoScale<Bgr32Alpha>
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct Bgr32CopyMasked : public DrawBitmapNoScale<Bgr32CopyMasked>
|
||||||
|
{
|
||||||
|
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
|
#endif // DRAW_BITMAP_NO_SCALE_H
|
||||||
|
|||||||
Reference in New Issue
Block a user