From 0581480cfec831197846c0449f838768412e2e03 Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Mon, 13 Mar 2006 16:48:44 +0000 Subject: [PATCH] * Fixed ServerBitmap::ImportBits() to use the correct width/height * Extended ConvertBits() to properly handle negative offsets and overlapping lines * Implemented blitting the software cursor to the bitmap returned from ReadBitmap() Note: In the future we will have to directly use the final graphics buffer for ReadBitmap() if we want DirectWindow output too (R5 includes it). I don't know how R5 handles the hardware cursor though. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@16766 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/kits/interface/ColorConversion.cpp | 25 ++++++++++++++-- src/servers/app/ServerBitmap.cpp | 4 +-- src/servers/app/drawing/DrawingEngine.cpp | 36 +++++++++++++++++++++-- 3 files changed, 58 insertions(+), 7 deletions(-) diff --git a/src/kits/interface/ColorConversion.cpp b/src/kits/interface/ColorConversion.cpp index b0d416edeb..944afb9cc0 100644 --- a/src/kits/interface/ColorConversion.cpp +++ b/src/kits/interface/ColorConversion.cpp @@ -641,9 +641,30 @@ ConvertBits(const srcByte *srcBits, dstByte *dstBits, int32 srcBitsLength, // Advance the buffers to reach their offsets int32 srcOffsetX = (int32)srcOffset.x; int32 dstOffsetX = (int32)dstOffset.x; - (char *)srcBits += ((int32)srcOffset.y * srcBitsPerRow + srcOffsetX + int32 srcOffsetY = (int32)srcOffset.y; + int32 dstOffsetY = (int32)dstOffset.y; + if (srcOffsetX < 0) { + dstOffsetX -= srcOffsetX; + srcOffsetX = 0; + } + if (srcOffsetY < 0) { + dstOffsetY -= srcOffsetY; + height += srcOffsetY; + srcOffsetY = 0; + } + if (dstOffsetX < 0) { + srcOffsetX -= dstOffsetX; + dstOffsetX = 0; + } + if (dstOffsetY < 0) { + srcOffsetY -= dstOffsetY; + height += dstOffsetY; + dstOffsetY = 0; + } + + (char *)srcBits += (srcOffsetY * srcBitsPerRow + srcOffsetX * srcBitsPerPixel) >> 3; - (char *)dstBits += ((int32)dstOffset.y * dstBitsPerRow + dstOffsetX + (char *)dstBits += (dstOffsetY * dstBitsPerRow + dstOffsetX * dstBitsPerPixel) >> 3; // Ensure that the width fits diff --git a/src/servers/app/ServerBitmap.cpp b/src/servers/app/ServerBitmap.cpp index 89e8d9f109..9faa450767 100644 --- a/src/servers/app/ServerBitmap.cpp +++ b/src/servers/app/ServerBitmap.cpp @@ -266,8 +266,8 @@ ServerBitmap::ImportBits(const void *bits, int32 bitsLength, int32 bytesPerRow, return B_BAD_VALUE; return BPrivate::ConvertBits(bits, fBuffer, bitsLength, BitsLength(), - bytesPerRow, fBytesPerRow, colorSpace, fSpace, from, to, fWidth, - fHeight); + bytesPerRow, fBytesPerRow, colorSpace, fSpace, from, to, width, + height); } diff --git a/src/servers/app/drawing/DrawingEngine.cpp b/src/servers/app/drawing/DrawingEngine.cpp index 5b2d3d8b1e..2003d562ed 100644 --- a/src/servers/app/drawing/DrawingEngine.cpp +++ b/src/servers/app/drawing/DrawingEngine.cpp @@ -8,6 +8,7 @@ #include "DrawingEngine.h" +#include #include #include #include @@ -17,6 +18,7 @@ #include "Painter.h" #include "PNGDump.h" #include "ServerBitmap.h" +#include "ServerCursor.h" #include "RenderingBuffer.h" #include "frame_buffer_support.h" @@ -1150,11 +1152,39 @@ DrawingEngine::ReadBitmap(ServerBitmap *bitmap, bool drawCursor, BRect bounds) status_t result = bitmap->ImportBits(buffer->Bits(), buffer->BitsLength(), buffer->BytesPerRow(), buffer->ColorSpace(), - bounds.LeftTop(), BPoint(0, 0), bounds.IntegerWidth(), - bounds.IntegerHeight()); + bounds.LeftTop(), BPoint(0, 0), bounds.IntegerWidth() + 1, + bounds.IntegerHeight() + 1); if (drawCursor) { - // ToDo: blend the cursor + ServerCursor *cursor = fGraphicsCard->Cursor(); + int32 cursorWidth = cursor->Bounds().IntegerWidth(); + int32 cursorHeight = cursor->Bounds().IntegerHeight(); + + BPoint cursorPosition = fGraphicsCard->GetCursorPosition(); + cursorPosition -= bounds.LeftTop() + cursor->GetHotSpot(); + + BBitmap cursorArea(BRect(0, 0, cursorWidth, cursorHeight), + B_BITMAP_NO_SERVER_LINK, B_RGBA32); + cursorArea.ImportBits(bitmap->Bits(), bitmap->BitsLength(), + bitmap->BytesPerRow(), bitmap->ColorSpace(), cursorPosition, + BPoint(0, 0), cursorWidth, cursorHeight); + + uint8 *bits = (uint8 *)cursorArea.Bits(); + uint8 *cursorBits = (uint8 *)cursor->Bits(); + for (int32 i = 0; i < cursorHeight; i++) { + for (int32 j = 0; j < cursorWidth; j++) { + uint8 alpha = 255 - cursorBits[3]; + bits[0] = ((bits[0] * alpha) >> 8) + cursorBits[0]; + bits[1] = ((bits[1] * alpha) >> 8) + cursorBits[1]; + bits[2] = ((bits[2] * alpha) >> 8) + cursorBits[2]; + cursorBits += 4; + bits += 4; + } + } + + bitmap->ImportBits(cursorArea.Bits(), cursorArea.BitsLength(), + cursorArea.BytesPerRow(), cursorArea.ColorSpace(), + BPoint(0, 0), cursorPosition, cursorWidth, cursorHeight); } fGraphicsCard->ShowSoftwareCursor();