From e89985cc317a80cfcfaa320944c0d015c0fc93f6 Mon Sep 17 00:00:00 2001 From: Adrien Destugues Date: Sun, 10 Feb 2019 10:26:31 +0100 Subject: [PATCH] Fix drawing of B_GRAY1 bitmaps. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Colors were reversed - Padding was not handled properly because of a roundeing error Add a test that shows the issue (behavior confirmed against BeOS) Change-Id: I4c6e954fb6bdab92ad4e0e96897e78b26eb4727b Reviewed-on: https://review.haiku-os.org/c/1025 Reviewed-by: Stephan Aßmus --- src/kits/interface/ColorConversion.cpp | 8 +- src/tests/kits/interface/Jamfile | 26 +++--- .../kits/interface/bbitmap/DrawBitmapTest.cpp | 90 +++++++++++++++++++ 3 files changed, 110 insertions(+), 14 deletions(-) create mode 100644 src/tests/kits/interface/bbitmap/DrawBitmapTest.cpp diff --git a/src/kits/interface/ColorConversion.cpp b/src/kits/interface/ColorConversion.cpp index 75dd298578..0f46f2ef47 100644 --- a/src/kits/interface/ColorConversion.cpp +++ b/src/kits/interface/ColorConversion.cpp @@ -546,7 +546,9 @@ uint32 ReadGray1(const uint8 **source, int32 index) { int32 shift = 7 - (index % 8); - uint32 result = ((**source >> shift) & 0x01) ? 0xff : 0x00; + // In B_GRAY1, a set bit means black (highcolor), a clear bit means white + // (low/view color). So we map them to 00 and 0xFF, respectively. + uint32 result = ((**source >> shift) & 0x01) ? 0x00 : 0xFF; if (shift == 0) (*source)++; return result; @@ -656,8 +658,8 @@ ConvertBits(const srcByte *srcBits, dstByte *dstBits, int32 srcBitsLength, return B_OK; } - int32 srcLinePad = (srcBitsPerRow - width * srcBitsPerPixel) >> 3; - int32 dstLinePad = (dstBitsPerRow - width * dstBitsPerPixel) >> 3; + int32 srcLinePad = (srcBitsPerRow - width * srcBitsPerPixel + 7) >> 3; + int32 dstLinePad = (dstBitsPerRow - width * dstBitsPerPixel + 7) >> 3; uint32 result; uint32 source; diff --git a/src/tests/kits/interface/Jamfile b/src/tests/kits/interface/Jamfile index 29a6c45b53..b82efa4e1c 100644 --- a/src/tests/kits/interface/Jamfile +++ b/src/tests/kits/interface/Jamfile @@ -67,17 +67,6 @@ ObjectDefines : BCheckBox=HCheckBox ; -SimpleTest ScrollViewTest_r5 : - ScrollViewTest.cpp - : be [ TargetLibsupc++ ] - ; - -SimpleTest ScrollViewTest : - ScrollViewTest.cpp - ScrollView.cpp - : be [ TargetLibsupc++ ] - ; - SimpleTest AlertTest : SimpleAlertTest.cpp : be [ TargetLibsupc++ ] @@ -101,6 +90,10 @@ SimpleTest ControlLookTest : : be [ TargetLibsupc++ ] ; +SimpleTest DrawBitmapTest : + DrawBitmapTest.cpp + : be ; + SimpleTest ListViewTest : ListViewTest.cpp : be [ TargetLibsupc++ ] @@ -111,6 +104,17 @@ SimpleTest ScreenTest : : be ; +SimpleTest ScrollViewTest_r5 : + ScrollViewTest.cpp + : be [ TargetLibsupc++ ] + ; + +SimpleTest ScrollViewTest : + ScrollViewTest.cpp + ScrollView.cpp + : be [ TargetLibsupc++ ] + ; + SimpleTest StatusBarTest : StatusBarTest.cpp : be [ TargetLibsupc++ ] diff --git a/src/tests/kits/interface/bbitmap/DrawBitmapTest.cpp b/src/tests/kits/interface/bbitmap/DrawBitmapTest.cpp new file mode 100644 index 0000000000..e395aa38ae --- /dev/null +++ b/src/tests/kits/interface/bbitmap/DrawBitmapTest.cpp @@ -0,0 +1,90 @@ +/* + * Copyright 2019, Adrien Destugues + * Distributed under terms of the MIT license. + */ + + +#include +#include +#include +#include + +#include + + +class BitmapView: public BView +{ + public: + BitmapView(BBitmap* bitmap) + : BView(bitmap->Bounds(), "test view", B_FOLLOW_LEFT_TOP, B_WILL_DRAW) + , fBitmap(bitmap) + { + } + + ~BitmapView() + { + delete fBitmap; + } + + void Draw(BRect updateRect) + { + DrawBitmap(fBitmap); + } + + private: + BBitmap* fBitmap; +}; + + +int +main(void) +{ + BApplication app("application/Haiku-BitmapTest"); + + BWindow* window = new BWindow(BRect(10, 10, 100, 100), + "Bitmap drawing test", B_DOCUMENT_WINDOW, B_QUIT_ON_WINDOW_CLOSE); + window->Show(); + + BBitmap* bitmap = new BBitmap(BRect(0, 0, 24, 24), B_GRAY1); + + // Bitmap is 25 pixels wide, which rounds up to 4 pixels + // The last byte only has one bit used, and 7 bits of padding + assert(bitmap->BytesPerRow() == 4); + + // This was extracted from letter_a.pbm and should look mostly like a + // black "A" letter on a white background (confirmed BeOS behavior) + const unsigned char data[] = { + 0, 0, 0, 0, + 0, 8, 0, 0, + 0, 0x1c, 0, 0, + 0, 0x3e, 0, 0, + 0, 0x7e, 0, 0, + 0, 0xFF, 0, 0, + 0, 0xE7, 0, 0, + 0, 0xC3, 0, 0, + 1, 0xC3, 0x80, 0, + 1, 0x81, 0x80, 0, + 3, 0x81, 0xC0, 0, + 3, 0xFF, 0xC0, 0, + 7, 0xFF, 0xE0, 0, + 7, 0xFF, 0xE0, 0, + 7, 0x81, 0xE0, 0, + 0x0F, 0, 0x0F, 0, + 0x0F, 0, 0x0F, 0, + 0x1F, 0, 0xF8, 0, + 0x1E, 0, 0x78, 0, + 0x1C, 0, 0x38, 0, + 0x3C, 0, 0x3C, 0, + 0x3C, 0, 0x3C, 0, + 0x38, 0, 0x0E, 0, + 0x78, 0, 0x0F, 0, + 0, 0, 0, 0 + }; + bitmap->SetBits(data, sizeof(data), 0, B_GRAY1); + + BView* view = new BitmapView(bitmap); + window->AddChild(view); + + app.Run(); + return 0; +}