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
This commit is contained in:
Michael Lotz
2008-06-14 20:52:05 +00:00
parent 50320b5500
commit 345dc29f8a
2 changed files with 75 additions and 3 deletions
+68 -3
View File
@@ -1266,6 +1266,31 @@ copy_bitmap_row_bgr32_alpha(uint8* dst, const uint8* src, int32 numPixels,
memcpy(dst, buffer, bytes);
}
template<typename sourcePixel>
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,
@@ -214,6 +214,13 @@ class Painter {
BPoint pt3,
bool fill) const;
template<typename sourcePixel>
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,