From 345dc29f8a09aae48d13ca9f6813082c2f31554c Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Sat, 14 Jun 2008 20:52:05 +0000 Subject: [PATCH] When drawing bitmaps with B_OP_OVER with a color space that does not provide an alpha channel of itself, we have to respect B_TRANSPARENT_MAGIC_* pixels and properly make them transparent. We achive that now by just setting the alpha to 0 in our converted B_RGBA32 bitmap for each pixel where there is a B_TRANSPARENT_MAGIC_* pixel in the source. This is not really efficient, but fixes missing images for example in NetPositive. They were treated as B_RGBA32 while they in fact were B_RGB32 and happened to have all alpha bits set to 0. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25956 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/servers/app/drawing/Painter/Painter.cpp | 71 ++++++++++++++++++++- src/servers/app/drawing/Painter/Painter.h | 7 ++ 2 files changed, 75 insertions(+), 3 deletions(-) diff --git a/src/servers/app/drawing/Painter/Painter.cpp b/src/servers/app/drawing/Painter/Painter.cpp index ace264dfc8..392e8db52e 100644 --- a/src/servers/app/drawing/Painter/Painter.cpp +++ b/src/servers/app/drawing/Painter/Painter.cpp @@ -1266,6 +1266,31 @@ copy_bitmap_row_bgr32_alpha(uint8* dst, const uint8* src, int32 numPixels, memcpy(dst, buffer, bytes); } + +template +void +Painter::_TransparentMagicToAlpha(sourcePixel *buffer, uint32 width, + uint32 height, uint32 sourceBytesPerRow, sourcePixel transparentMagic, + BBitmap *output) const +{ + sourcePixel *sourceRow = buffer; + uint32 *destRow = (uint32 *)output->Bits(); + uint32 destBytesPerRow = output->BytesPerRow(); + + for (uint32 y = 0; y < height; y++) { + sourcePixel *pixel = sourceRow; + uint32 *destPixel = destRow; + for (uint32 x = 0; x < width; x++, pixel++, destPixel++) { + if (*pixel == transparentMagic) + *destPixel &= 0x00ffffff; + } + + (char *)sourceRow += sourceBytesPerRow; + (char *)destRow += destBytesPerRow; + } +} + + // _DrawBitmap void Painter::_DrawBitmap(agg::rendering_buffer& srcBuffer, color_space format, @@ -1338,9 +1363,12 @@ Painter::_DrawBitmap(agg::rendering_buffer& srcBuffer, color_space format, } } - _DrawBitmapGeneric32(srcBuffer, xOffset, yOffset, - xScale, yScale, viewRect); - break; + if (format != B_RGB32 || fDrawingMode != B_OP_OVER) { + _DrawBitmapGeneric32(srcBuffer, xOffset, yOffset, + xScale, yScale, viewRect); + break; + } + // otherwise fall through to get B_OP_OVER handling for B_RGB32 } default: { if (format == B_CMAP8 && xScale == 1.0 && yScale == 1.0) { @@ -1366,7 +1394,44 @@ Painter::_DrawBitmap(agg::rendering_buffer& srcBuffer, color_space format, srcBuffer.height() * srcBuffer.stride(), srcBuffer.stride(), 0, format); + if (err >= B_OK) { + if (fDrawingMode == B_OP_OVER) { + // the original bitmap might have had some of the + // transaparent magic colors set that we now need to + // make transparent in our RGBA32 bitmap again. + switch (format) { + case B_RGB32: + _TransparentMagicToAlpha((uint32 *)srcBuffer.buf(), + srcBuffer.width(), srcBuffer.height(), + srcBuffer.stride(), B_TRANSPARENT_MAGIC_RGBA32, + &temp); + break; + + // TODO: not sure if this applies to B_RGBA15 too. It + // should not because B_RGBA15 actually has an alpha + // channel itself and it should have been preserved + // when importing the bitmap. Maybe it applies to + // B_RGB16 though? + case B_RGB15: + _TransparentMagicToAlpha((uint16 *)srcBuffer.buf(), + srcBuffer.width(), srcBuffer.height(), + srcBuffer.stride(), B_TRANSPARENT_MAGIC_RGBA15, + &temp); + break; + + case B_CMAP8: + _TransparentMagicToAlpha((uint8 *)srcBuffer.buf(), + srcBuffer.width(), srcBuffer.height(), + srcBuffer.stride(), B_TRANSPARENT_MAGIC_CMAP8, + &temp); + break; + + default: + break; + } + } + agg::rendering_buffer convertedBuffer; convertedBuffer.attach((uint8*)temp.Bits(), (uint32)actualBitmapRect.IntegerWidth() + 1, diff --git a/src/servers/app/drawing/Painter/Painter.h b/src/servers/app/drawing/Painter/Painter.h index d91d1c4aec..d8c8469ece 100644 --- a/src/servers/app/drawing/Painter/Painter.h +++ b/src/servers/app/drawing/Painter/Painter.h @@ -214,6 +214,13 @@ class Painter { BPoint pt3, bool fill) const; + template + void _TransparentMagicToAlpha(sourcePixel *buffer, + uint32 width, uint32 height, + uint32 sourceBytesPerRow, + sourcePixel transparentMagic, + BBitmap *output) const; + void _DrawBitmap( agg::rendering_buffer& srcBuffer, color_space format, BRect actualBitmapRect,