nss: upgrade to release 3.73
[LibreOffice.git] / vcl / qa / cppunit / outdev.cxx
blob5081082afc0bcb3f3197fc294df8e3a0b34d4212
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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/.
8 */
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>
19 #include <bufferdevice.hxx>
20 #include <window.h>
22 #include <basegfx/matrix/b2dhommatrix.hxx>
24 class VclOutdevTest : public test::BootstrapFixture
26 public:
27 VclOutdevTest()
28 : BootstrapFixture(true, false)
32 void testVirtualDevice();
33 void testUseAfterDispose();
34 void testPrinterBackgroundColor();
35 void testWindowBackgroundColor();
36 void testGetReadableFontColorPrinter();
37 void testGetReadableFontColorWindow();
38 void testDrawTransformedBitmapEx();
39 void testDrawTransformedBitmapExFlip();
40 void testRTL();
41 void testRTLGuard();
43 CPPUNIT_TEST_SUITE(VclOutdevTest);
45 CPPUNIT_TEST(testVirtualDevice);
46 CPPUNIT_TEST(testUseAfterDispose);
47 CPPUNIT_TEST(testPrinterBackgroundColor);
48 CPPUNIT_TEST(testWindowBackgroundColor);
49 CPPUNIT_TEST(testGetReadableFontColorPrinter);
50 CPPUNIT_TEST(testGetReadableFontColorWindow);
51 CPPUNIT_TEST(testDrawTransformedBitmapEx);
52 CPPUNIT_TEST(testDrawTransformedBitmapExFlip);
53 CPPUNIT_TEST(testRTL);
54 CPPUNIT_TEST(testRTLGuard);
55 CPPUNIT_TEST_SUITE_END();
58 void VclOutdevTest::testGetReadableFontColorPrinter()
60 ScopedVclPtrInstance<Printer> pPrinter;
61 CPPUNIT_ASSERT_EQUAL(pPrinter->GetReadableFontColor(COL_WHITE, COL_WHITE), COL_BLACK);
64 void VclOutdevTest::testGetReadableFontColorWindow()
66 ScopedVclPtrInstance<vcl::Window> pWindow(nullptr, WB_APP | WB_STDWORK);
67 CPPUNIT_ASSERT_EQUAL(pWindow->GetReadableFontColor(COL_WHITE, COL_BLACK), COL_WHITE);
68 CPPUNIT_ASSERT_EQUAL(pWindow->GetReadableFontColor(COL_WHITE, COL_WHITE), COL_BLACK);
69 CPPUNIT_ASSERT_EQUAL(pWindow->GetReadableFontColor(COL_BLACK, COL_BLACK), COL_WHITE);
72 void VclOutdevTest::testPrinterBackgroundColor()
74 ScopedVclPtrInstance<Printer> pPrinter;
75 CPPUNIT_ASSERT_EQUAL(pPrinter->GetBackgroundColor(), COL_WHITE);
78 void VclOutdevTest::testWindowBackgroundColor()
80 ScopedVclPtrInstance<vcl::Window> pWindow(nullptr, WB_APP | WB_STDWORK);
81 pWindow->SetBackground(Wallpaper(COL_WHITE));
82 CPPUNIT_ASSERT_EQUAL(pWindow->GetBackgroundColor(), COL_WHITE);
85 void VclOutdevTest::testVirtualDevice()
87 // TODO: This unit test is not executed for macOS unless bitmap scaling is implemented
88 #ifndef MACOSX
89 ScopedVclPtrInstance<VirtualDevice> pVDev;
90 pVDev->SetOutputSizePixel(Size(32, 32));
91 pVDev->SetBackground(Wallpaper(COL_WHITE));
93 CPPUNIT_ASSERT_EQUAL(pVDev->GetBackgroundColor(), COL_WHITE);
95 pVDev->Erase();
96 pVDev->DrawPixel(Point(1, 2), COL_BLUE);
97 pVDev->DrawPixel(Point(31, 30), COL_RED);
99 Size aSize = pVDev->GetOutputSizePixel();
100 CPPUNIT_ASSERT_EQUAL(Size(32, 32), aSize);
102 Bitmap aBmp = pVDev->GetBitmap(Point(), aSize);
104 #if 0
105 OUString rFileName("/tmp/foo-unx.png");
106 try {
107 vcl::PNGWriter aWriter( aBmp );
108 SvFileStream sOutput( rFileName, StreamMode::WRITE );
109 aWriter.Write( sOutput );
110 sOutput.Close();
111 } catch (...) {
112 SAL_WARN("vcl", "Error writing png to " << rFileName);
114 #endif
116 CPPUNIT_ASSERT_EQUAL(COL_WHITE, pVDev->GetPixel(Point(0, 0)));
117 #if !defined _WIN32 //TODO: various failures on Windows tinderboxes
118 CPPUNIT_ASSERT_EQUAL(COL_BLUE, pVDev->GetPixel(Point(1, 2)));
119 CPPUNIT_ASSERT_EQUAL(COL_RED, pVDev->GetPixel(Point(31, 30)));
120 #endif
121 CPPUNIT_ASSERT_EQUAL(COL_WHITE, pVDev->GetPixel(Point(30, 31)));
123 // Gotcha: y and x swap for BitmapReadAccess: deep joy.
124 Bitmap::ScopedReadAccess pAcc(aBmp);
125 CPPUNIT_ASSERT_EQUAL(COL_WHITE, static_cast<Color>(pAcc->GetPixel(0, 0)));
126 #if !defined _WIN32 //TODO: various failures on Windows tinderboxes
127 CPPUNIT_ASSERT_EQUAL(COL_BLUE, static_cast<Color>(pAcc->GetPixel(2, 1)));
128 CPPUNIT_ASSERT_EQUAL(COL_RED, static_cast<Color>(pAcc->GetPixel(30, 31)));
129 #endif
130 CPPUNIT_ASSERT_EQUAL(COL_WHITE, static_cast<Color>(pAcc->GetPixel(31, 30)));
132 #if 0
133 VclPtr<vcl::Window> pWin = VclPtr<WorkWindow>::Create( (vcl::Window *)nullptr );
134 CPPUNIT_ASSERT( pWin );
135 OutputDevice *pOutDev = pWin.get();
136 #endif
137 #endif
140 void VclOutdevTest::testUseAfterDispose()
142 // Create a virtual device, enable map mode then dispose it.
143 ScopedVclPtrInstance<VirtualDevice> pVDev;
145 pVDev->EnableMapMode();
147 pVDev->disposeOnce();
149 // Make sure that these don't crash after dispose.
150 pVDev->GetInverseViewTransformation();
152 pVDev->GetViewTransformation();
155 void VclOutdevTest::testDrawTransformedBitmapEx()
157 // Create a virtual device, and connect a metafile to it.
158 // Also create a 16x16 bitmap.
159 ScopedVclPtrInstance<VirtualDevice> pVDev;
160 Bitmap aBitmap(Size(16, 16), 24);
162 // Fill the top left quarter with black.
163 BitmapScopedWriteAccess pWriteAccess(aBitmap);
164 pWriteAccess->Erase(COL_WHITE);
165 for (int i = 0; i < 8; ++i)
167 for (int j = 0; j < 8; ++j)
169 pWriteAccess->SetPixel(j, i, COL_BLACK);
173 BitmapEx aBitmapEx(aBitmap);
174 basegfx::B2DHomMatrix aMatrix;
175 aMatrix.scale(8, 8);
176 // Rotate 90 degrees clockwise, so the black part goes to the top right.
177 aMatrix.rotate(M_PI / 2);
178 GDIMetaFile aMtf;
179 aMtf.Record(pVDev.get());
181 // Draw the rotated bitmap on the vdev.
182 pVDev->DrawTransformedBitmapEx(aMatrix, aBitmapEx);
183 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), aMtf.GetActionSize());
184 MetaAction* pAction = aMtf.GetAction(0);
185 CPPUNIT_ASSERT_EQUAL(MetaActionType::BMPEXSCALE, pAction->GetType());
186 auto pBitmapAction = static_cast<MetaBmpExScaleAction*>(pAction);
187 const BitmapEx& rBitmapEx = pBitmapAction->GetBitmapEx();
188 Size aTransformedSize = rBitmapEx.GetSizePixel();
189 // Without the accompanying fix in place, this test would have failed with:
190 // - Expected: 16x16
191 // - Actual : 8x8
192 // I.e. the bitmap before scaling was already scaled down, just because it was rotated.
193 CPPUNIT_ASSERT_EQUAL(Size(16, 16), aTransformedSize);
195 aBitmap = rBitmapEx.GetBitmap();
196 Bitmap::ScopedReadAccess pAccess(aBitmap);
197 for (int i = 0; i < 16; ++i)
199 for (int j = 0; j < 16; ++j)
201 BitmapColor aColor = pAccess->GetPixel(j, i);
202 Color aExpected = i >= 8 && j < 8 ? COL_BLACK : COL_WHITE;
203 std::stringstream ss;
204 ss << "Color is expected to be ";
205 ss << ((aExpected == COL_WHITE) ? "white" : "black");
206 ss << ", is " << aColor.AsRGBHexString();
207 ss << " (row " << j << ", col " << i << ")";
208 // Without the accompanying fix in place, this test would have failed with:
209 // - Expected: c[00000000]
210 // - Actual : c[ffffff00]
211 // - Color is expected to be black, is ffffff (row 0, col 8)
212 // i.e. the top right quarter of the image was not fully black, there was a white first
213 // row.
214 CPPUNIT_ASSERT_EQUAL_MESSAGE(ss.str(), aExpected, Color(aColor));
219 void VclOutdevTest::testDrawTransformedBitmapExFlip()
221 // Create a virtual device, and connect a metafile to it.
222 // Also create a 16x16 bitmap.
223 ScopedVclPtrInstance<VirtualDevice> pVDev;
224 Bitmap aBitmap(Size(16, 16), 24);
226 // Fill the top left quarter with black.
227 BitmapScopedWriteAccess pWriteAccess(aBitmap);
228 pWriteAccess->Erase(COL_WHITE);
229 for (int i = 0; i < 8; ++i)
231 for (int j = 0; j < 8; ++j)
233 pWriteAccess->SetPixel(j, i, COL_BLACK);
237 BitmapEx aBitmapEx(aBitmap);
238 basegfx::B2DHomMatrix aMatrix;
239 // Negative y scale: bitmap should be upside down, so the black part goes to the bottom left.
240 aMatrix.scale(8, -8);
241 // Rotate 90 degrees clockwise, so the black part goes back to the top left.
242 aMatrix.rotate(M_PI / 2);
243 GDIMetaFile aMtf;
244 aMtf.Record(pVDev.get());
246 // Draw the scaled and rotated bitmap on the vdev.
247 pVDev->DrawTransformedBitmapEx(aMatrix, aBitmapEx);
248 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), aMtf.GetActionSize());
249 MetaAction* pAction = aMtf.GetAction(0);
250 CPPUNIT_ASSERT_EQUAL(MetaActionType::BMPEXSCALE, pAction->GetType());
251 auto pBitmapAction = static_cast<MetaBmpExScaleAction*>(pAction);
252 const BitmapEx& rBitmapEx = pBitmapAction->GetBitmapEx();
254 aBitmap = rBitmapEx.GetBitmap();
255 Bitmap::ScopedReadAccess pAccess(aBitmap);
256 int nX = 8 * 0.25;
257 int nY = 8 * 0.25;
258 BitmapColor aColor = pAccess->GetPixel(nY, nX);
259 std::stringstream ss;
260 ss << "Color is expected to be black, is " << aColor.AsRGBHexString();
261 ss << " (row " << nY << ", col " << nX << ")";
262 // Without the accompanying fix in place, this test would have failed with:
263 // - Expected: c[00000000]
264 // - Actual : c[ffffff00]
265 // - Color is expected to be black, is ffffff (row 2, col 2)
266 // i.e. the top left quarter of the image was not black, due to a missing flip.
267 CPPUNIT_ASSERT_EQUAL_MESSAGE(ss.str(), COL_BLACK, Color(aColor));
270 void VclOutdevTest::testRTL()
272 ScopedVclPtrInstance<vcl::Window> pWindow(nullptr, WB_APP | WB_STDWORK);
273 pWindow->EnableRTL();
274 vcl::RenderContext& rRenderContext = *pWindow;
275 vcl::BufferDevice pBuffer(pWindow, rRenderContext);
277 // Without the accompanying fix in place, this test would have failed, because the RTL status
278 // from pWindow was not propagated to pBuffer.
279 CPPUNIT_ASSERT(pBuffer->IsRTLEnabled());
282 void VclOutdevTest::testRTLGuard()
284 ScopedVclPtrInstance<vcl::Window> pWindow(nullptr, WB_APP | WB_STDWORK);
285 pWindow->EnableRTL();
286 pWindow->RequestDoubleBuffering(true);
287 ImplFrameData* pFrameData = pWindow->ImplGetWindowImpl()->mpFrameData;
288 vcl::PaintBufferGuard aGuard(pFrameData, pWindow);
289 // Without the accompanying fix in place, this test would have failed, because the RTL status
290 // from pWindow was not propagated to aGuard.
291 CPPUNIT_ASSERT(aGuard.GetRenderContext()->IsRTLEnabled());
294 CPPUNIT_TEST_SUITE_REGISTRATION(VclOutdevTest);
296 CPPUNIT_PLUGIN_IMPLEMENT();
298 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */