1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 #include <test/bootstrapfixture.hxx>
12 #include <vcl/print.hxx>
13 #include <vcl/virdev.hxx>
14 #include <vcl/window.hxx>
15 #include <vcl/bitmapaccess.hxx>
16 #include <vcl/gdimtf.hxx>
17 #include <vcl/metaact.hxx>
18 #include <bitmapwriteaccess.hxx>
20 #include <basegfx/matrix/b2dhommatrix.hxx>
22 class VclOutdevTest
: public test::BootstrapFixture
25 VclOutdevTest() : BootstrapFixture(true, false) {}
27 void testVirtualDevice();
28 void testUseAfterDispose();
29 void testPrinterBackgroundColor();
30 void testWindowBackgroundColor();
31 void testGetReadableFontColorPrinter();
32 void testGetReadableFontColorWindow();
33 void testDrawTransformedBitmapEx();
35 CPPUNIT_TEST_SUITE(VclOutdevTest
);
36 CPPUNIT_TEST(testVirtualDevice
);
37 CPPUNIT_TEST(testUseAfterDispose
);
38 CPPUNIT_TEST(testPrinterBackgroundColor
);
39 CPPUNIT_TEST(testWindowBackgroundColor
);
40 CPPUNIT_TEST(testGetReadableFontColorPrinter
);
41 CPPUNIT_TEST(testGetReadableFontColorWindow
);
42 CPPUNIT_TEST(testDrawTransformedBitmapEx
);
43 CPPUNIT_TEST_SUITE_END();
46 void VclOutdevTest::testGetReadableFontColorPrinter()
48 ScopedVclPtrInstance
<Printer
> pPrinter
;
49 CPPUNIT_ASSERT_EQUAL(pPrinter
->GetReadableFontColor(COL_WHITE
, COL_WHITE
), COL_BLACK
);
52 void VclOutdevTest::testGetReadableFontColorWindow()
54 ScopedVclPtrInstance
<vcl::Window
> pWindow(nullptr, WB_APP
| WB_STDWORK
);
55 CPPUNIT_ASSERT_EQUAL(pWindow
->GetReadableFontColor(COL_WHITE
, COL_BLACK
), COL_WHITE
);
56 CPPUNIT_ASSERT_EQUAL(pWindow
->GetReadableFontColor(COL_WHITE
, COL_WHITE
), COL_BLACK
);
57 CPPUNIT_ASSERT_EQUAL(pWindow
->GetReadableFontColor(COL_BLACK
, COL_BLACK
), COL_WHITE
);
60 void VclOutdevTest::testPrinterBackgroundColor()
62 ScopedVclPtrInstance
<Printer
> pPrinter
;
63 CPPUNIT_ASSERT_EQUAL(pPrinter
->GetBackgroundColor(), COL_WHITE
);
66 void VclOutdevTest::testWindowBackgroundColor()
68 ScopedVclPtrInstance
<vcl::Window
> pWindow(nullptr, WB_APP
| WB_STDWORK
);
69 pWindow
->SetBackground(Wallpaper(COL_WHITE
));
70 CPPUNIT_ASSERT_EQUAL(pWindow
->GetBackgroundColor(), COL_WHITE
);
73 void VclOutdevTest::testVirtualDevice()
75 ScopedVclPtrInstance
< VirtualDevice
> pVDev
;
76 pVDev
->SetOutputSizePixel(Size(32,32));
77 pVDev
->SetBackground(Wallpaper(COL_WHITE
));
79 CPPUNIT_ASSERT_EQUAL(pVDev
->GetBackgroundColor(), COL_WHITE
);
82 pVDev
->DrawPixel(Point(1,2),COL_BLUE
);
83 pVDev
->DrawPixel(Point(31,30),COL_RED
);
85 Size aSize
= pVDev
->GetOutputSizePixel();
86 CPPUNIT_ASSERT_EQUAL(Size(32,32), aSize
);
88 Bitmap aBmp
= pVDev
->GetBitmap(Point(),aSize
);
91 OUString
rFileName("/tmp/foo-unx.png");
93 vcl::PNGWriter
aWriter( aBmp
);
94 SvFileStream
sOutput( rFileName
, StreamMode::WRITE
);
95 aWriter
.Write( sOutput
);
98 SAL_WARN("vcl", "Error writing png to " << rFileName
);
102 CPPUNIT_ASSERT_EQUAL(COL_WHITE
, pVDev
->GetPixel(Point(0,0)));
103 #if defined LINUX //TODO: various failures on Mac and Windows tinderboxes
104 CPPUNIT_ASSERT_EQUAL(COL_BLUE
, pVDev
->GetPixel(Point(1,2)));
105 CPPUNIT_ASSERT_EQUAL(COL_RED
, pVDev
->GetPixel(Point(31,30)));
107 CPPUNIT_ASSERT_EQUAL(COL_WHITE
, pVDev
->GetPixel(Point(30,31)));
109 // Gotcha: y and x swap for BitmapReadAccess: deep joy.
110 Bitmap::ScopedReadAccess
pAcc(aBmp
);
111 CPPUNIT_ASSERT_EQUAL(COL_WHITE
, static_cast<Color
>(pAcc
->GetPixel(0,0)));
112 #if defined LINUX //TODO: various failures on Mac and Windows tinderboxes
113 CPPUNIT_ASSERT_EQUAL(COL_BLUE
, static_cast<Color
>(pAcc
->GetPixel(2,1)));
114 CPPUNIT_ASSERT_EQUAL(COL_RED
, static_cast<Color
>(pAcc
->GetPixel(30,31)));
116 CPPUNIT_ASSERT_EQUAL(COL_WHITE
, static_cast<Color
>(pAcc
->GetPixel(31,30)));
119 VclPtr
<vcl::Window
> pWin
= VclPtr
<WorkWindow
>::Create( (vcl::Window
*)nullptr );
120 CPPUNIT_ASSERT( pWin
);
121 OutputDevice
*pOutDev
= pWin
.get();
125 void VclOutdevTest::testUseAfterDispose()
127 // Create a virtual device, enable map mode then dispose it.
128 ScopedVclPtrInstance
<VirtualDevice
> pVDev
;
130 pVDev
->EnableMapMode();
132 pVDev
->disposeOnce();
134 // Make sure that these don't crash after dispose.
135 pVDev
->GetInverseViewTransformation();
137 pVDev
->GetViewTransformation();
140 void VclOutdevTest::testDrawTransformedBitmapEx()
142 // Create a virtual device, and connect a metafile to it.
143 // Also create a 16x16 bitmap.
144 ScopedVclPtrInstance
<VirtualDevice
> pVDev
;
145 Bitmap
aBitmap(Size(16, 16), 24);
147 // Fill the top left quarter with black.
148 BitmapScopedWriteAccess
pWriteAccess(aBitmap
);
149 pWriteAccess
->Erase(COL_WHITE
);
150 for (int i
= 0; i
< 8; ++i
)
152 for (int j
= 0; j
< 8; ++j
)
154 pWriteAccess
->SetPixel(j
, i
, COL_BLACK
);
158 BitmapEx
aBitmapEx(aBitmap
);
159 basegfx::B2DHomMatrix aMatrix
;
161 // Rotate 90 degrees clockwise, so the black part goes to the top right.
162 aMatrix
.rotate(M_PI
/ 2);
164 aMtf
.Record(pVDev
.get());
166 // Draw the rotated bitmap on the vdev.
167 pVDev
->DrawTransformedBitmapEx(aMatrix
, aBitmapEx
);
168 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), aMtf
.GetActionSize());
169 MetaAction
* pAction
= aMtf
.GetAction(0);
170 CPPUNIT_ASSERT_EQUAL(MetaActionType::BMPEXSCALE
, pAction
->GetType());
171 auto pBitmapAction
= static_cast<MetaBmpExScaleAction
*>(pAction
);
172 const BitmapEx
& rBitmapEx
= pBitmapAction
->GetBitmapEx();
173 Size aTransformedSize
= rBitmapEx
.GetSizePixel();
174 // Without the accompanying fix in place, this test would have failed with:
177 // I.e. the bitmap before scaling was already scaled down, just because it was rotated.
178 CPPUNIT_ASSERT_EQUAL(Size(16, 16), aTransformedSize
);
180 aBitmap
= rBitmapEx
.GetBitmap();
181 Bitmap::ScopedReadAccess
pAccess(aBitmap
);
182 for (int i
= 0; i
< 16; ++i
)
184 for (int j
= 0; j
< 16; ++j
)
186 BitmapColor aColor
= pAccess
->GetPixel(j
, i
);
187 Color aExpected
= i
>= 8 && j
< 8 ? COL_BLACK
: COL_WHITE
;
188 std::stringstream ss
;
189 ss
<< "Color is expected to be ";
190 ss
<< ((aExpected
== COL_WHITE
) ? "white" : "black");
191 ss
<< ", is " << aColor
.AsRGBHexString();
192 ss
<< " (row " << j
<< ", col " << i
<< ")";
193 // Without the accompanying fix in place, this test would have failed with:
194 // - Expected: c[00000000]
195 // - Actual : c[ffffff00]
196 // - Color is expected to be black, is ffffff (row 0, col 8)
197 // i.e. the top right quarter of the image was not fully black, there was a white first
199 CPPUNIT_ASSERT_EQUAL_MESSAGE(ss
.str(), aExpected
, Color(aColor
));
204 CPPUNIT_TEST_SUITE_REGISTRATION(VclOutdevTest
);
206 CPPUNIT_PLUGIN_IMPLEMENT();
208 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */