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:
@@ -1266,6 +1266,31 @@ copy_bitmap_row_bgr32_alpha(uint8* dst, const uint8* src, int32 numPixels,
|
|||||||
memcpy(dst, buffer, bytes);
|
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
|
// _DrawBitmap
|
||||||
void
|
void
|
||||||
Painter::_DrawBitmap(agg::rendering_buffer& srcBuffer, color_space format,
|
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,
|
if (format != B_RGB32 || fDrawingMode != B_OP_OVER) {
|
||||||
xScale, yScale, viewRect);
|
_DrawBitmapGeneric32(srcBuffer, xOffset, yOffset,
|
||||||
break;
|
xScale, yScale, viewRect);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// otherwise fall through to get B_OP_OVER handling for B_RGB32
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
if (format == B_CMAP8 && xScale == 1.0 && yScale == 1.0) {
|
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.height() * srcBuffer.stride(),
|
||||||
srcBuffer.stride(),
|
srcBuffer.stride(),
|
||||||
0, format);
|
0, format);
|
||||||
|
|
||||||
if (err >= B_OK) {
|
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;
|
agg::rendering_buffer convertedBuffer;
|
||||||
convertedBuffer.attach((uint8*)temp.Bits(),
|
convertedBuffer.attach((uint8*)temp.Bits(),
|
||||||
(uint32)actualBitmapRect.IntegerWidth() + 1,
|
(uint32)actualBitmapRect.IntegerWidth() + 1,
|
||||||
|
|||||||
@@ -214,6 +214,13 @@ class Painter {
|
|||||||
BPoint pt3,
|
BPoint pt3,
|
||||||
bool fill) const;
|
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,
|
void _DrawBitmap( agg::rendering_buffer& srcBuffer,
|
||||||
color_space format,
|
color_space format,
|
||||||
BRect actualBitmapRect,
|
BRect actualBitmapRect,
|
||||||
|
|||||||
Reference in New Issue
Block a user