From 940b4d1848e8c70ab7642901a68594e8016caffc Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 27 Apr 2024 18:51:28 +0200 Subject: Adding upstream version 1:7.0.4. Signed-off-by: Daniel Baumann --- vcl/qa/cppunit/outdev.cxx | 291 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 291 insertions(+) create mode 100644 vcl/qa/cppunit/outdev.cxx (limited to 'vcl/qa/cppunit/outdev.cxx') diff --git a/vcl/qa/cppunit/outdev.cxx b/vcl/qa/cppunit/outdev.cxx new file mode 100644 index 000000000..e99a35f67 --- /dev/null +++ b/vcl/qa/cppunit/outdev.cxx @@ -0,0 +1,291 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +class VclOutdevTest : public test::BootstrapFixture +{ +public: + VclOutdevTest() : BootstrapFixture(true, false) {} + + void testVirtualDevice(); + void testUseAfterDispose(); + void testPrinterBackgroundColor(); + void testWindowBackgroundColor(); + void testGetReadableFontColorPrinter(); + void testGetReadableFontColorWindow(); + void testDrawTransformedBitmapEx(); + void testDrawTransformedBitmapExFlip(); + void testRTL(); + void testRTLGuard(); + + CPPUNIT_TEST_SUITE(VclOutdevTest); + CPPUNIT_TEST(testVirtualDevice); + CPPUNIT_TEST(testUseAfterDispose); + CPPUNIT_TEST(testPrinterBackgroundColor); + CPPUNIT_TEST(testWindowBackgroundColor); + CPPUNIT_TEST(testGetReadableFontColorPrinter); + CPPUNIT_TEST(testGetReadableFontColorWindow); + CPPUNIT_TEST(testDrawTransformedBitmapEx); + CPPUNIT_TEST(testDrawTransformedBitmapExFlip); + CPPUNIT_TEST(testRTL); + CPPUNIT_TEST(testRTLGuard); + CPPUNIT_TEST_SUITE_END(); +}; + +void VclOutdevTest::testGetReadableFontColorPrinter() +{ + ScopedVclPtrInstance pPrinter; + CPPUNIT_ASSERT_EQUAL(pPrinter->GetReadableFontColor(COL_WHITE, COL_WHITE), COL_BLACK); +} + +void VclOutdevTest::testGetReadableFontColorWindow() +{ + ScopedVclPtrInstance pWindow(nullptr, WB_APP | WB_STDWORK); + CPPUNIT_ASSERT_EQUAL(pWindow->GetReadableFontColor(COL_WHITE, COL_BLACK), COL_WHITE); + CPPUNIT_ASSERT_EQUAL(pWindow->GetReadableFontColor(COL_WHITE, COL_WHITE), COL_BLACK); + CPPUNIT_ASSERT_EQUAL(pWindow->GetReadableFontColor(COL_BLACK, COL_BLACK), COL_WHITE); +} + +void VclOutdevTest::testPrinterBackgroundColor() +{ + ScopedVclPtrInstance pPrinter; + CPPUNIT_ASSERT_EQUAL(pPrinter->GetBackgroundColor(), COL_WHITE); +} + +void VclOutdevTest::testWindowBackgroundColor() +{ + ScopedVclPtrInstance pWindow(nullptr, WB_APP | WB_STDWORK); + pWindow->SetBackground(Wallpaper(COL_WHITE)); + CPPUNIT_ASSERT_EQUAL(pWindow->GetBackgroundColor(), COL_WHITE); +} + +void VclOutdevTest::testVirtualDevice() +{ + ScopedVclPtrInstance< VirtualDevice > pVDev; + pVDev->SetOutputSizePixel(Size(32,32)); + pVDev->SetBackground(Wallpaper(COL_WHITE)); + + CPPUNIT_ASSERT_EQUAL(pVDev->GetBackgroundColor(), COL_WHITE); + + pVDev->Erase(); + pVDev->DrawPixel(Point(1,2),COL_BLUE); + pVDev->DrawPixel(Point(31,30),COL_RED); + + Size aSize = pVDev->GetOutputSizePixel(); + CPPUNIT_ASSERT_EQUAL(Size(32,32), aSize); + + Bitmap aBmp = pVDev->GetBitmap(Point(),aSize); + +#if 0 + OUString rFileName("/tmp/foo-unx.png"); + try { + vcl::PNGWriter aWriter( aBmp ); + SvFileStream sOutput( rFileName, StreamMode::WRITE ); + aWriter.Write( sOutput ); + sOutput.Close(); + } catch (...) { + SAL_WARN("vcl", "Error writing png to " << rFileName); + } +#endif + + CPPUNIT_ASSERT_EQUAL(COL_WHITE, pVDev->GetPixel(Point(0,0))); +#if !defined _WIN32 //TODO: various failures on Windows tinderboxes + CPPUNIT_ASSERT_EQUAL(COL_BLUE, pVDev->GetPixel(Point(1,2))); + CPPUNIT_ASSERT_EQUAL(COL_RED, pVDev->GetPixel(Point(31,30))); +#endif + CPPUNIT_ASSERT_EQUAL(COL_WHITE, pVDev->GetPixel(Point(30,31))); + + // Gotcha: y and x swap for BitmapReadAccess: deep joy. + Bitmap::ScopedReadAccess pAcc(aBmp); + CPPUNIT_ASSERT_EQUAL(COL_WHITE, static_cast(pAcc->GetPixel(0,0))); +#if !defined _WIN32 //TODO: various failures on Windows tinderboxes + CPPUNIT_ASSERT_EQUAL(COL_BLUE, static_cast(pAcc->GetPixel(2,1))); + CPPUNIT_ASSERT_EQUAL(COL_RED, static_cast(pAcc->GetPixel(30,31))); +#endif + CPPUNIT_ASSERT_EQUAL(COL_WHITE, static_cast(pAcc->GetPixel(31,30))); + +#if 0 + VclPtr pWin = VclPtr::Create( (vcl::Window *)nullptr ); + CPPUNIT_ASSERT( pWin ); + OutputDevice *pOutDev = pWin.get(); +#endif +} + +void VclOutdevTest::testUseAfterDispose() +{ + // Create a virtual device, enable map mode then dispose it. + ScopedVclPtrInstance pVDev; + + pVDev->EnableMapMode(); + + pVDev->disposeOnce(); + + // Make sure that these don't crash after dispose. + pVDev->GetInverseViewTransformation(); + + pVDev->GetViewTransformation(); +} + +void VclOutdevTest::testDrawTransformedBitmapEx() +{ + // Create a virtual device, and connect a metafile to it. + // Also create a 16x16 bitmap. + ScopedVclPtrInstance pVDev; + Bitmap aBitmap(Size(16, 16), 24); + { + // Fill the top left quarter with black. + BitmapScopedWriteAccess pWriteAccess(aBitmap); + pWriteAccess->Erase(COL_WHITE); + for (int i = 0; i < 8; ++i) + { + for (int j = 0; j < 8; ++j) + { + pWriteAccess->SetPixel(j, i, COL_BLACK); + } + } + } + BitmapEx aBitmapEx(aBitmap); + basegfx::B2DHomMatrix aMatrix; + aMatrix.scale(8, 8); + // Rotate 90 degrees clockwise, so the black part goes to the top right. + aMatrix.rotate(M_PI / 2); + GDIMetaFile aMtf; + aMtf.Record(pVDev.get()); + + // Draw the rotated bitmap on the vdev. + pVDev->DrawTransformedBitmapEx(aMatrix, aBitmapEx); + CPPUNIT_ASSERT_EQUAL(static_cast(1), aMtf.GetActionSize()); + MetaAction* pAction = aMtf.GetAction(0); + CPPUNIT_ASSERT_EQUAL(MetaActionType::BMPEXSCALE, pAction->GetType()); + auto pBitmapAction = static_cast(pAction); + const BitmapEx& rBitmapEx = pBitmapAction->GetBitmapEx(); + Size aTransformedSize = rBitmapEx.GetSizePixel(); + // Without the accompanying fix in place, this test would have failed with: + // - Expected: 16x16 + // - Actual : 8x8 + // I.e. the bitmap before scaling was already scaled down, just because it was rotated. + CPPUNIT_ASSERT_EQUAL(Size(16, 16), aTransformedSize); + + aBitmap = rBitmapEx.GetBitmap(); + Bitmap::ScopedReadAccess pAccess(aBitmap); + for (int i = 0; i < 16; ++i) + { + for (int j = 0; j < 16; ++j) + { + BitmapColor aColor = pAccess->GetPixel(j, i); + Color aExpected = i >= 8 && j < 8 ? COL_BLACK : COL_WHITE; + std::stringstream ss; + ss << "Color is expected to be "; + ss << ((aExpected == COL_WHITE) ? "white" : "black"); + ss << ", is " << aColor.AsRGBHexString(); + ss << " (row " << j << ", col " << i << ")"; + // Without the accompanying fix in place, this test would have failed with: + // - Expected: c[00000000] + // - Actual : c[ffffff00] + // - Color is expected to be black, is ffffff (row 0, col 8) + // i.e. the top right quarter of the image was not fully black, there was a white first + // row. + CPPUNIT_ASSERT_EQUAL_MESSAGE(ss.str(), aExpected, Color(aColor)); + } + } +} + +void VclOutdevTest::testDrawTransformedBitmapExFlip() +{ + // Create a virtual device, and connect a metafile to it. + // Also create a 16x16 bitmap. + ScopedVclPtrInstance pVDev; + Bitmap aBitmap(Size(16, 16), 24); + { + // Fill the top left quarter with black. + BitmapScopedWriteAccess pWriteAccess(aBitmap); + pWriteAccess->Erase(COL_WHITE); + for (int i = 0; i < 8; ++i) + { + for (int j = 0; j < 8; ++j) + { + pWriteAccess->SetPixel(j, i, COL_BLACK); + } + } + } + BitmapEx aBitmapEx(aBitmap); + basegfx::B2DHomMatrix aMatrix; + // Negative y scale: bitmap should be upside down, so the black part goes to the bottom left. + aMatrix.scale(8, -8); + // Rotate 90 degrees clockwise, so the black part goes back to the top left. + aMatrix.rotate(M_PI / 2); + GDIMetaFile aMtf; + aMtf.Record(pVDev.get()); + + // Draw the scaled and rotated bitmap on the vdev. + pVDev->DrawTransformedBitmapEx(aMatrix, aBitmapEx); + CPPUNIT_ASSERT_EQUAL(static_cast(1), aMtf.GetActionSize()); + MetaAction* pAction = aMtf.GetAction(0); + CPPUNIT_ASSERT_EQUAL(MetaActionType::BMPEXSCALE, pAction->GetType()); + auto pBitmapAction = static_cast(pAction); + const BitmapEx& rBitmapEx = pBitmapAction->GetBitmapEx(); + + aBitmap = rBitmapEx.GetBitmap(); + Bitmap::ScopedReadAccess pAccess(aBitmap); + int nX = 8 * 0.25; + int nY = 8 * 0.25; + BitmapColor aColor = pAccess->GetPixel(nY, nX); + std::stringstream ss; + ss << "Color is expected to be black, is " << aColor.AsRGBHexString(); + ss << " (row " << nY << ", col " << nX << ")"; + // Without the accompanying fix in place, this test would have failed with: + // - Expected: c[00000000] + // - Actual : c[ffffff00] + // - Color is expected to be black, is ffffff (row 2, col 2) + // i.e. the top left quarter of the image was not black, due to a missing flip. + CPPUNIT_ASSERT_EQUAL_MESSAGE(ss.str(), COL_BLACK, Color(aColor)); +} + +void VclOutdevTest::testRTL() +{ + ScopedVclPtrInstance pWindow(nullptr, WB_APP | WB_STDWORK); + pWindow->EnableRTL(); + vcl::RenderContext& rRenderContext = *pWindow; + vcl::BufferDevice pBuffer(pWindow, rRenderContext); + + // Without the accompanying fix in place, this test would have failed, because the RTL status + // from pWindow was not propagated to pBuffer. + CPPUNIT_ASSERT(pBuffer->IsRTLEnabled()); +} + +void VclOutdevTest::testRTLGuard() +{ + ScopedVclPtrInstance pWindow(nullptr, WB_APP | WB_STDWORK); + pWindow->EnableRTL(); + pWindow->RequestDoubleBuffering(true); + ImplFrameData* pFrameData = pWindow->ImplGetWindowImpl()->mpFrameData; + vcl::PaintBufferGuard aGuard(pFrameData, pWindow); + // Without the accompanying fix in place, this test would have failed, because the RTL status + // from pWindow was not propagated to aGuard. + CPPUNIT_ASSERT(aGuard.GetRenderContext()->IsRTLEnabled()); +} + +CPPUNIT_TEST_SUITE_REGISTRATION(VclOutdevTest); + +CPPUNIT_PLUGIN_IMPLEMENT(); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ -- cgit v1.2.3