From acf1c6ada3ddc03888be6545568f7511d63b6ce3 Mon Sep 17 00:00:00 2001 From: Michael Pfeiffer Date: Sun, 12 Aug 2007 09:00:17 +0000 Subject: [PATCH] * test archiving / unarchiving * compare recorded / restored picture to direct drawing into bitmap * renamed Test Vertical Line -> Test Diagonal Line git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21898 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../interface/flatten_picture/PictureTest.cpp | 273 ++++++++++++------ .../interface/flatten_picture/PictureTest.h | 34 ++- .../flatten_picture/PictureTestCases.cpp | 4 +- .../flatten_picture/PictureTestWindow.cpp | 106 +++++-- .../flatten_picture/PictureTestWindow.h | 6 + .../flatten_picture/TestResultItem.cpp | 12 +- .../flatten_picture/TestResultItem.h | 2 + 7 files changed, 313 insertions(+), 124 deletions(-) diff --git a/src/tests/kits/interface/flatten_picture/PictureTest.cpp b/src/tests/kits/interface/flatten_picture/PictureTest.cpp index 78fd372c25..ebc9006937 100644 --- a/src/tests/kits/interface/flatten_picture/PictureTest.cpp +++ b/src/tests/kits/interface/flatten_picture/PictureTest.cpp @@ -28,36 +28,132 @@ public: AutoDelete(T *object) : fObject(object) { } ~AutoDelete() { delete fObject; fObject = NULL; } - void Release() { fObject = NULL; } + T* Release() { T* object = fObject; fObject = NULL; return object; } private: T *fObject; }; +class OffscreenBitmap { +public: + OffscreenBitmap(BRect frame, color_space colorSpace); + virtual ~OffscreenBitmap(); + status_t InitCheck() const { return fStatus; } + + BView *View(); + BBitmap *Copy(); -PictureTest::PictureTest() - : fColorSpace(B_RGBA32) - , fOriginalBitmap(NULL) - , fArchivedBitmap(NULL) +private: + BRect fFrame; + color_space fColorSpace; + status_t fStatus; + + BBitmap *fBitmap; + BView *fView; +}; + +OffscreenBitmap::OffscreenBitmap(BRect frame, color_space colorSpace) + : fFrame(frame) + , fColorSpace(colorSpace) + , fStatus(B_ERROR) + , fBitmap(NULL) + , fView(NULL) { + BBitmap *bitmap = new BBitmap(frame, fColorSpace, true); + AutoDelete _bitmap(bitmap); + if (bitmap == NULL || bitmap->IsValid() == false || bitmap->InitCheck() != B_OK) + return; + + BView *view = new BView(frame, "offscreen", B_FOLLOW_ALL, B_WILL_DRAW); + AutoDelete _view(view); + if (view == NULL) + return; + + bitmap->Lock(); + bitmap->AddChild(view); + // bitmap is locked during the life time of this object + + fBitmap = _bitmap.Release(); + fView = _view.Release(); + fStatus = B_OK; +} + +OffscreenBitmap::~OffscreenBitmap() +{ + if (fStatus != B_OK) + return; + + fView->RemoveSelf(); + fBitmap->Unlock(); + delete fView; + fView = NULL; + + delete fBitmap; + fBitmap = NULL; + + fStatus = B_ERROR; +} + +BView * +OffscreenBitmap::View() +{ + return fView; } BBitmap* -PictureTest::GetOriginalBitmap(bool detach) +OffscreenBitmap::Copy() { - BBitmap* bitmap = fOriginalBitmap; + // the result bitmap that does not accept views + // to save resources in the application server + BBitmap *copy = new BBitmap(fFrame, fColorSpace, false); + AutoDelete _copy(copy); + if (copy == NULL || copy->IsValid() == false || copy->InitCheck() != B_OK) + return NULL; + + fView->Sync(); + fBitmap->Unlock(); + + memcpy(copy->Bits(), fBitmap->Bits(), fBitmap->BitsLength()); + + fBitmap->Lock(); + + return _copy.Release(); +} + +PictureTest::PictureTest() + : fColorSpace(B_RGBA32) + , fDirectBitmap(NULL) + , fBitmapFromPicture(NULL) + , fBitmapFromRestoredPicture(NULL) +{ +} + + +BBitmap* +PictureTest::DirectBitmap(bool detach) +{ + BBitmap* bitmap = fDirectBitmap; if (detach) - fOriginalBitmap = NULL; + fDirectBitmap = NULL; + return bitmap; +} + +BBitmap* +PictureTest::BitmapFromPicture(bool detach) +{ + BBitmap* bitmap = fBitmapFromPicture; + if (detach) + fBitmapFromPicture = NULL; return bitmap; } BBitmap* -PictureTest::GetArchivedBitmap(bool detach) +PictureTest::BitmapFromRestoredPicture(bool detach) { - BBitmap* bitmap = fArchivedBitmap; + BBitmap* bitmap = fBitmapFromRestoredPicture; if (detach) - fArchivedBitmap = NULL; + fBitmapFromRestoredPicture = NULL; return bitmap; } @@ -70,10 +166,10 @@ PictureTest::~PictureTest() void PictureTest::CleanUp() { - delete fOriginalBitmap; - fOriginalBitmap = NULL; - delete fArchivedBitmap; - fArchivedBitmap = NULL; + delete fBitmapFromPicture; + fBitmapFromPicture = NULL; + delete fBitmapFromRestoredPicture; + fBitmapFromRestoredPicture = NULL; fErrorMessage = ""; } @@ -82,6 +178,9 @@ PictureTest::Test(draw_func* func, BRect frame) { CleanUp(); + fDirectBitmap = CreateBitmap(func, frame); + TEST_AND_RETURN(fDirectBitmap == NULL, "Could not create direct draw bitmap!", false); + BPicture *picture = RecordPicture(func, frame); AutoDelete _picture(picture); TEST_AND_RETURN(picture == NULL, "Picture could not be recorded!", false); @@ -90,57 +189,79 @@ PictureTest::Test(draw_func* func, BRect frame) AutoDelete _archivedPicture(archivedPicture); TEST_AND_RETURN(picture == NULL, "Picture could not be flattened and unflattened!", false); - fOriginalBitmap = CreateBitmap(picture, frame); - TEST_AND_RETURN(fOriginalBitmap == NULL, "Could not create bitmap from original picture!", false); + fBitmapFromPicture = CreateBitmap(picture, frame); + TEST_AND_RETURN(fBitmapFromPicture == NULL, "Could not create bitmap from original picture!", false); - fArchivedBitmap = CreateBitmap(archivedPicture, frame); - TEST_AND_RETURN(fArchivedBitmap == NULL, "Could not create bitmap from archived picture!", false); + fBitmapFromRestoredPicture = CreateBitmap(archivedPicture, frame); + TEST_AND_RETURN(fBitmapFromRestoredPicture == NULL, "Could not create bitmap from archived picture!", false); - bool result = IsSame(fOriginalBitmap, fArchivedBitmap); - TEST_AND_RETURN(result == false, "Bitmaps differ!", false); - return result; + TEST_AND_RETURN(!IsSame(fDirectBitmap, fBitmapFromPicture), "Bitmap from picture differs from direct drawing bitmap", false); + TEST_AND_RETURN(!IsSame(fDirectBitmap, fBitmapFromRestoredPicture), "Bitmap from picture differs from direct drawing bitmap", false); + return true; } +BBitmap * +PictureTest::CreateBitmap(draw_func* func, BRect frame) +{ + OffscreenBitmap bitmap(frame, fColorSpace); + if (bitmap.InitCheck() != B_OK) + return NULL; + func(bitmap.View(), frame); + return bitmap.Copy(); +} + BPicture * PictureTest::RecordPicture(draw_func* func, BRect frame) { - // create view for recording to picture - BBitmap *bitmap = new BBitmap(frame, fColorSpace, true); - AutoDelete _bitmap(bitmap); - if (bitmap == NULL || bitmap->IsValid() == false || bitmap->InitCheck() != B_OK) + OffscreenBitmap bitmap(frame, fColorSpace); + if (bitmap.InitCheck() != B_OK) return NULL; - - BView *view = new BView(frame, "offscreen", B_FOLLOW_ALL, B_WILL_DRAW); - AutoDelete _view(view); - if (view == NULL) - return NULL; - - bitmap->Lock(); - bitmap->AddChild(view); - - // R5 clears the bitmap! However Haiku does not, so clear it for now. - view->PushState(); - view->SetHighColor(255, 255, 255); - view->FillRect(frame); - view->PopState(); - + + BView *view = bitmap.View(); // record BPicture *picture = new BPicture(); view->BeginPicture(picture); func(view, frame); - picture = view->EndPicture(); - - // destroy view - view->Sync(); - view->RemoveSelf(); - bitmap->Unlock(); + picture = view->EndPicture(); return picture; } +BBitmap * +PictureTest::CreateBitmap(BPicture *picture, BRect frame) +{ + OffscreenBitmap bitmap(frame, fColorSpace); + if (bitmap.InitCheck() != B_OK) + return NULL; + + BView *view = bitmap.View(); + view->DrawPicture(picture); + view->Sync(); + + return bitmap.Copy(); +} + + +bool +PictureTest::IsSame(BBitmap *bitmap1, BBitmap *bitmap2) +{ + if (bitmap1->ColorSpace() != bitmap2->ColorSpace()) + return false; + + if (bitmap1->BitsLength() != bitmap2->BitsLength()) + return false; + + return memcmp(bitmap1->Bits(), bitmap2->Bits(), bitmap1->BitsLength()) == 0; +} + + +FlattenPictureTest::FlattenPictureTest() +{ +} + BPicture * -PictureTest::SaveAndRestore(BPicture *picture) +FlattenPictureTest::SaveAndRestore(BPicture *picture) { BMallocIO *data = new BMallocIO(); AutoDelete _data(data); @@ -158,50 +279,20 @@ PictureTest::SaveAndRestore(BPicture *picture) return archivedPicture; } -BBitmap * -PictureTest::CreateBitmap(BPicture *picture, BRect frame) +ArchivePictureTest::ArchivePictureTest() { - // create bitmap that accepts a view - BBitmap *bitmap = new BBitmap(frame, fColorSpace, true); - AutoDelete _bitmap(bitmap); - if (bitmap == NULL || bitmap->IsValid() == false || bitmap->InitCheck() != B_OK) - return NULL; - - BView *view = new BView(frame, "offscreen", B_FOLLOW_ALL, B_WILL_DRAW); - AutoDelete _view(view); - if (view == NULL) - return NULL; - - // the result bitmap that does not accept views - // to save resources in the application server - BBitmap *result = new BBitmap(frame, fColorSpace, false); - if (result == NULL || result->IsValid() == false || result->InitCheck() != B_OK) - return NULL; - - bitmap->Lock(); - bitmap->AddChild(view); - - view->DrawPicture(picture); - view->Sync(); - - // destroy view - view->RemoveSelf(); - bitmap->Unlock(); - - memcpy(result->Bits(), bitmap->Bits(), bitmap->BitsLength()); - - return result; } - -bool -PictureTest::IsSame(BBitmap *bitmap1, BBitmap *bitmap2) +BPicture * +ArchivePictureTest::SaveAndRestore(BPicture *picture) { - if (bitmap1->ColorSpace() != bitmap2->ColorSpace()) - return false; - - if (bitmap1->BitsLength() != bitmap2->BitsLength()) - return false; - - return memcmp(bitmap1->Bits(), bitmap2->Bits(), bitmap1->BitsLength()) == 0; -} + BMessage archive; + if (picture->Archive(&archive) != B_OK) + return NULL; + + BPicture *archivedPicture = new BPicture(&archive); + if (archivedPicture == NULL) + return NULL; + + return archivedPicture; +} \ No newline at end of file diff --git a/src/tests/kits/interface/flatten_picture/PictureTest.h b/src/tests/kits/interface/flatten_picture/PictureTest.h index ce20f5b7e7..844e3b7361 100644 --- a/src/tests/kits/interface/flatten_picture/PictureTest.h +++ b/src/tests/kits/interface/flatten_picture/PictureTest.h @@ -26,29 +26,49 @@ public: const char *ErrorMessage() const { return fErrorMessage.String(); } - BBitmap *GetOriginalBitmap(bool detach = false); - BBitmap *GetArchivedBitmap(bool detach = false); + BBitmap *DirectBitmap(bool detach = false); + BBitmap *BitmapFromPicture(bool detach = false); + BBitmap *BitmapFromRestoredPicture(bool detach = false); + +protected: + virtual BPicture *SaveAndRestore(BPicture *picture) = 0; private: void CleanUp(); BPicture *RecordPicture(draw_func* func, BRect frame); - - BPicture *SaveAndRestore(BPicture *picture); - + + BBitmap *CreateBitmap(draw_func* func, BRect frame); BBitmap *CreateBitmap(BPicture *picture, BRect frame); bool IsSame(BBitmap *bitmap1, BBitmap *bitmap2); color_space fColorSpace; - BBitmap *fOriginalBitmap; - BBitmap *fArchivedBitmap; + BBitmap *fDirectBitmap; + BBitmap *fBitmapFromPicture; + BBitmap *fBitmapFromRestoredPicture; BString fErrorMessage; }; +class FlattenPictureTest : public PictureTest +{ +public: + FlattenPictureTest(); +protected: + BPicture *SaveAndRestore(BPicture *picture); +}; + +class ArchivePictureTest : public PictureTest +{ +public: + ArchivePictureTest(); + +protected: + BPicture *SaveAndRestore(BPicture *picture); +}; #endif diff --git a/src/tests/kits/interface/flatten_picture/PictureTestCases.cpp b/src/tests/kits/interface/flatten_picture/PictureTestCases.cpp index 12dc72d403..e372a556c4 100644 --- a/src/tests/kits/interface/flatten_picture/PictureTestCases.cpp +++ b/src/tests/kits/interface/flatten_picture/PictureTestCases.cpp @@ -46,7 +46,7 @@ void testStrokeRect(BView *view, BRect frame) } } -void testVerticalLine(BView *view, BRect frame) +void testDiagonalLine(BView *view, BRect frame) { view->StrokeLine(BPoint(frame.left, frame.top), BPoint(frame.right, frame.bottom)); } @@ -112,7 +112,7 @@ void testBitmap(BView *view, BRect frame) { TestCase gTestCases[] = { { "Test Empty Picture", testEmptyPicture }, - { "Test Vertical Line", testVerticalLine }, + { "Test Diagonal Line", testDiagonalLine }, { "Test Stroke Rect", testStrokeRect }, { "Test Draw String", testDrawString }, { "Test Fill Red", testFillRed }, diff --git a/src/tests/kits/interface/flatten_picture/PictureTestWindow.cpp b/src/tests/kits/interface/flatten_picture/PictureTestWindow.cpp index 13793c4db4..b4bc09d12a 100644 --- a/src/tests/kits/interface/flatten_picture/PictureTestWindow.cpp +++ b/src/tests/kits/interface/flatten_picture/PictureTestWindow.cpp @@ -22,7 +22,9 @@ #include "TestResultItem.h" PictureTestWindow::PictureTestWindow() - : Inherited(BRect(100,100,500,300), "Picture Tests", B_DOCUMENT_WINDOW, 0) + : Inherited(BRect(10, 30, 630, 470), "Bitmap Drawing Tests", B_DOCUMENT_WINDOW, 0) + , fFailedTests(0) + , fNumberOfTests(0) { BuildGUI(); } @@ -62,11 +64,13 @@ void PictureTestWindow::BuildGUI() BRect b = Bounds(); b.top = mb->Bounds().bottom + 1; - BStringView *header = new BStringView(b, "header", "Picture, Unflattened Picture, Test Name, Error Message", B_FOLLOW_LEFT | B_FOLLOW_RIGHT | B_FOLLOW_TOP); - header->ResizeToPreferred(); - backdrop->AddChild(header); - b.top = header->Frame().bottom + 1; - + fHeader = new BStringView(b, "header", + "X", B_FOLLOW_LEFT | B_FOLLOW_RIGHT | B_FOLLOW_TOP); + float width, height; + fHeader->GetPreferredSize(&width, &height); + fHeader->ResizeTo(b.Width(), height); + backdrop->AddChild(fHeader); + b.top = fHeader->Frame().bottom + 1; b.right -= B_V_SCROLL_BAR_WIDTH; b.bottom -= B_H_SCROLL_BAR_HEIGHT; @@ -74,6 +78,16 @@ void PictureTestWindow::BuildGUI() B_FOLLOW_ALL_SIDES, B_WILL_DRAW | B_FRAME_EVENTS | B_FULL_UPDATE_ON_RESIZE); backdrop->AddChild(new BScrollView("scroll_results", fListView, B_FOLLOW_ALL_SIDES, 0, true, true)); + + UpdateHeader(); +} + +void +PictureTestWindow::UpdateHeader() +{ + BString text("Direct Drawing, Picture Drawing, Restored Picture Drawing, Test Name, Error Message"); + text << " (failures = " << fFailedTests << ", tests =" << fNumberOfTests << ")"; + fHeader->SetText(text.String()); } void @@ -89,6 +103,27 @@ PictureTestWindow::MessageReceived(BMessage *msg) { void PictureTestWindow::RunTests() +{ + for (int testIndex = 0; testIndex < 2; testIndex ++) { + BString text; + switch (testIndex) + { + case 0: + text = "Flatten Picture Test"; + break; + case 1: + text = "Archive Picture Test"; + break; + default: + text = "Unknown test method!"; + } + fListView->AddItem(new BStringItem(text.String())); + RunTests(testIndex); + } +} + +void +PictureTestWindow::RunTests(int32 testIndex) { color_space colorSpaces[] = { B_RGBA32, @@ -97,7 +132,7 @@ PictureTestWindow::RunTests() B_RGB16, B_RGB15 }; - BRect frame(0, 0, 100, 30); + for (uint32 csIndex = 0; csIndex < sizeof(colorSpaces)/sizeof(color_space); csIndex ++) { color_space colorSpace = colorSpaces[csIndex]; const char *csText; @@ -126,19 +161,46 @@ PictureTestWindow::RunTests() text += csText; fListView->AddItem(new BStringItem(text.String())); - for (int i = 0; gTestCases[i].name != NULL; i ++) { - TestCase *testCase = &gTestCases[i]; - PictureTest test; - test.SetColorSpace(colorSpace); - bool ok = test.Test(testCase->func, frame); - - TestResultItem *item = new TestResultItem(testCase->name, frame); - item->SetOk(ok); - item->SetErrorMessage(test.ErrorMessage()); - item->SetOriginalBitmap(test.GetOriginalBitmap(true)); - item->SetArchivedBitmap(test.GetArchivedBitmap(true)); - - fListView->AddItem(item); - } + RunTests(testIndex, colorSpace); } -} \ No newline at end of file +} + +void +PictureTestWindow::RunTests(int32 testIndex, color_space colorSpace) +{ + BRect frame(0, 0, 100, 30); + for (int i = 0; gTestCases[i].name != NULL; i ++) { + TestCase *testCase = &gTestCases[i]; + PictureTest *test; + switch (testIndex) { + case 0: + test = new FlattenPictureTest(); + break; + case 1: + test = new ArchivePictureTest(); + break; + default: + continue; + } + + test->SetColorSpace(colorSpace); + bool ok = test->Test(testCase->func, frame); + + TestResultItem *item = new TestResultItem(testCase->name, frame); + item->SetOk(ok); + item->SetErrorMessage(test->ErrorMessage()); + item->SetDirectBitmap(test->DirectBitmap(true)); + item->SetOriginalBitmap(test->BitmapFromPicture(true)); + item->SetArchivedBitmap(test->BitmapFromRestoredPicture(true)); + + delete test; + + fListView->AddItem(item); + + fNumberOfTests ++; + if (!ok) + fFailedTests ++; + + UpdateHeader(); + } +} diff --git a/src/tests/kits/interface/flatten_picture/PictureTestWindow.h b/src/tests/kits/interface/flatten_picture/PictureTestWindow.h index 89937bfdb7..45056c5492 100644 --- a/src/tests/kits/interface/flatten_picture/PictureTestWindow.h +++ b/src/tests/kits/interface/flatten_picture/PictureTestWindow.h @@ -28,10 +28,16 @@ private: }; void BuildGUI(); + void UpdateHeader(); void RunTests(); + void RunTests(int32 testIndex); + void RunTests(int32 testIndex, color_space colorSpace); BListView *fListView; + BStringView *fHeader; + int32 fFailedTests; + int32 fNumberOfTests; }; #endif diff --git a/src/tests/kits/interface/flatten_picture/TestResultItem.cpp b/src/tests/kits/interface/flatten_picture/TestResultItem.cpp index beda9d29cc..05374e6985 100644 --- a/src/tests/kits/interface/flatten_picture/TestResultItem.cpp +++ b/src/tests/kits/interface/flatten_picture/TestResultItem.cpp @@ -14,6 +14,7 @@ TestResultItem::TestResultItem(const char* name, BRect bitmapSize) : fName(name) , fBitmapSize(bitmapSize) , fOk(true) + , fDirectBitmap(NULL) , fOriginalBitmap(NULL) , fArchivedBitmap(NULL) { @@ -21,6 +22,8 @@ TestResultItem::TestResultItem(const char* name, BRect bitmapSize) TestResultItem::~TestResultItem() { + delete fDirectBitmap; + fDirectBitmap = NULL; delete fOriginalBitmap; fOriginalBitmap = NULL; delete fArchivedBitmap; @@ -55,6 +58,11 @@ TestResultItem::DrawItem(BView *owner, BRect itemRect, bool drawEverthing) owner->PopState(); owner->MovePenTo(itemRect.left+1, itemRect.top+1); + if (fDirectBitmap != NULL) { + owner->DrawBitmap(fDirectBitmap); + } + owner->MovePenBy(fBitmapSize.Width() + distance, 0); + if (fOriginalBitmap != NULL) { owner->DrawBitmap(fOriginalBitmap); } @@ -95,8 +103,8 @@ TestResultItem::Update(BView *owner, const BFont *font) width += distance; width += font->StringWidth(fErrorMessage.String()); - width += 2 * distance; - width += 2 * fBitmapSize.Width(); + width += 3 * distance; + width += 3 * fBitmapSize.Width(); height = fBitmapSize.Height(); diff --git a/src/tests/kits/interface/flatten_picture/TestResultItem.h b/src/tests/kits/interface/flatten_picture/TestResultItem.h index 28dacedf7c..1da029323d 100644 --- a/src/tests/kits/interface/flatten_picture/TestResultItem.h +++ b/src/tests/kits/interface/flatten_picture/TestResultItem.h @@ -25,6 +25,7 @@ public: void SetOk(bool ok) { fOk = ok; } void SetErrorMessage(const char *errorMessage) { fErrorMessage = errorMessage; } + void SetDirectBitmap(BBitmap *directBitmap) { fDirectBitmap = directBitmap; } void SetOriginalBitmap(BBitmap *originalBitmap) { fOriginalBitmap = originalBitmap; } void SetArchivedBitmap(BBitmap *archivedBitmap) { fArchivedBitmap = archivedBitmap; } @@ -33,6 +34,7 @@ private: BRect fBitmapSize; bool fOk; BString fErrorMessage; + BBitmap *fDirectBitmap; BBitmap *fOriginalBitmap; BBitmap *fArchivedBitmap; };