summaryrefslogtreecommitdiff
path: root/vcl/backendtest
diff options
context:
space:
mode:
authorTomaž Vajngerl <tomaz.vajngerl@collabora.co.uk>2016-08-22 18:10:02 +0900
committerTomaž Vajngerl <tomaz.vajngerl@collabora.co.uk>2016-08-23 09:52:43 +0900
commit3e6052ce1b9a24f82358e574de32919fa2b6499f (patch)
tree9e81e23f724a4be0938b61d866e777399f40e794 /vcl/backendtest
parent129c0d6363e58f6d32dc9583edb6a0edd07521f9 (diff)
vcl: Adds backend tests to check for correct rendering
Collection of test that check rendering of VCL backend. This works by rendering primitives to the VirtualDevice, outputing the result to a Bitmap and checking the rendering by comparing pixels. This should warn when the primitive is drawn to a wrong position or if it is the wrong size or color. It also test some rendering tricks like XOR drawing. Currently this is not implemented as a CPPUnit test but separately, as its own executable file so we can check the results visually. The idea is also to add the tests into LO for the user to test or automatically to test the backend on first start (especially useful to test the OpenGL backend as some drivers could have unexpected behaviour). Change-Id: I2a565b9986ca68850e2752466e3cd5fc71991ba6
Diffstat (limited to 'vcl/backendtest')
-rw-r--r--vcl/backendtest/VisualBackendTest.cxx582
-rw-r--r--vcl/backendtest/outputdevice/bitmap.cxx154
-rw-r--r--vcl/backendtest/outputdevice/common.cxx328
-rw-r--r--vcl/backendtest/outputdevice/gradient.cxx43
-rw-r--r--vcl/backendtest/outputdevice/line.cxx114
-rw-r--r--vcl/backendtest/outputdevice/outputdevice.cxx75
-rw-r--r--vcl/backendtest/outputdevice/pixel.cxx57
-rw-r--r--vcl/backendtest/outputdevice/polygon.cxx151
-rw-r--r--vcl/backendtest/outputdevice/polyline.cxx140
-rw-r--r--vcl/backendtest/outputdevice/polypolygon.cxx68
-rw-r--r--vcl/backendtest/outputdevice/rectangle.cxx54
11 files changed, 1766 insertions, 0 deletions
diff --git a/vcl/backendtest/VisualBackendTest.cxx b/vcl/backendtest/VisualBackendTest.cxx
new file mode 100644
index 000000000000..7b6bc02fdd53
--- /dev/null
+++ b/vcl/backendtest/VisualBackendTest.cxx
@@ -0,0 +1,582 @@
+/* -*- 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 <math.h>
+#include <rtl/math.hxx>
+
+#include <comphelper/processfactory.hxx>
+#include <comphelper/random.hxx>
+#include <cppuhelper/bootstrap.hxx>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/registry/XSimpleRegistry.hpp>
+#include <com/sun/star/ucb/UniversalContentBroker.hpp>
+
+#include <osl/time.h>
+#include <vcl/vclmain.hxx>
+#include <vcl/layout.hxx>
+#include <salhelper/thread.hxx>
+
+#include <tools/urlobj.hxx>
+#include <tools/stream.hxx>
+#include <tools/poly.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/pngread.hxx>
+#include <vcl/wrkwin.hxx>
+#include <vcl/virdev.hxx>
+#include <vcl/graphicfilter.hxx>
+#include <vcl/button.hxx>
+#include <vcl/toolbox.hxx>
+#include <vcl/pngwrite.hxx>
+#include <vcl/floatwin.hxx>
+#include <vcl/salbtype.hxx>
+#include <vcl/bitmapaccess.hxx>
+#include <vcl/help.hxx>
+
+#include <basegfx/numeric/ftools.hxx>
+#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <vcldemo-debug.hxx>
+
+#include <rtl/math.hxx>
+
+#include <chrono>
+#include <iostream>
+
+#include "test/outputdevice.hxx"
+
+using namespace css;
+
+void drawBitmapCentered(Rectangle& rRect, Bitmap aBitmap, vcl::RenderContext& rRenderContext)
+{
+ long nWidth = rRect.GetWidth();
+ long nHeight = rRect.GetHeight();
+
+ Size aBitmapSize(aBitmap.GetSizePixel());
+
+ Point aPoint(rRect.TopLeft());
+
+ aPoint.X() += (nWidth - aBitmapSize.Width()) / 2;
+ aPoint.Y() += (nHeight - aBitmapSize.Height()) / 2;
+
+ rRenderContext.DrawBitmap(aPoint, aBitmap);
+}
+
+void drawBitmapScaledAndCentered(Rectangle& rRect, Bitmap aBitmap, vcl::RenderContext& rRenderContext, BmpScaleFlag aFlag = BmpScaleFlag::Fast)
+{
+ long nWidth = rRect.GetWidth();
+ long nHeight = rRect.GetHeight();
+
+ Size aBitmapSize(aBitmap.GetSizePixel());
+
+ double fWidthHeight = nWidth > nHeight ? nHeight : nWidth;
+ double fScale = fWidthHeight / aBitmapSize.Width();
+ aBitmap.Scale(fScale, fScale, aFlag);
+
+ drawBitmapCentered(rRect, aBitmap, rRenderContext);
+}
+
+void drawBackgroundRect(Rectangle& rRect, Color aColor, vcl::RenderContext& rRenderContext)
+{
+ rRenderContext.Push(PushFlags::LINECOLOR | PushFlags::FILLCOLOR);
+ rRenderContext.SetFillColor(aColor);
+ rRenderContext.SetLineColor(aColor);
+ rRenderContext.DrawRect(rRect);
+ rRenderContext.Pop();
+}
+
+void assertAndSetBackground(vcl::test::TestResult eResult, Rectangle& rRect, vcl::RenderContext& rRenderContext)
+{
+ if (eResult == vcl::test::TestResult::Passed)
+ drawBackgroundRect(rRect, COL_GREEN, rRenderContext);
+ else if (eResult == vcl::test::TestResult::PassedWithQuirks)
+ drawBackgroundRect(rRect, COL_YELLOW, rRenderContext);
+ else if (eResult == vcl::test::TestResult::Failed)
+ drawBackgroundRect(rRect, COL_RED, rRenderContext);
+}
+
+class VisualBackendTestWindow : public WorkWindow
+{
+private:
+ Timer maUpdateTimer;
+ std::vector<std::chrono::high_resolution_clock::time_point> mTimePoints;
+ unsigned char mnNumberOfTests;
+ unsigned char mnTest;
+ bool mbAnimate;
+ ScopedVclPtr<VirtualDevice> mpVDev;
+
+public:
+ VisualBackendTestWindow()
+ : WorkWindow(NULL, WB_APP | WB_STDWORK)
+ , mnNumberOfTests(6)
+ , mnTest(10 * mnNumberOfTests)
+ , mbAnimate(mnTest % mnNumberOfTests == mnNumberOfTests - 1)
+ , mpVDev(VclPtr<VirtualDevice>::Create())
+ {
+ maUpdateTimer.SetTimeoutHdl(LINK(this, VisualBackendTestWindow, updateHdl));
+ maUpdateTimer.SetPriority(SchedulerPriority::REPAINT);
+ if (mbAnimate)
+ {
+ maUpdateTimer.SetTimeout(1000.0);
+ maUpdateTimer.Start();
+ }
+ }
+
+ virtual ~VisualBackendTestWindow()
+ {
+ disposeOnce();
+ }
+
+ DECL_LINK_TYPED(updateHdl, Timer*, void);
+
+ virtual void dispose() override
+ {
+ WorkWindow::dispose();
+ }
+
+ virtual void KeyInput(const KeyEvent& rKEvt) override
+ {
+ sal_uInt16 nCode = rKEvt.GetKeyCode().GetCode();
+
+ if (nCode == KEY_BACKSPACE)
+ mnTest--;
+ else if(nCode == KEY_SPACE)
+ mnTest++;
+
+ if (nCode == KEY_BACKSPACE || nCode == KEY_SPACE)
+ {
+ if (mnTest % mnNumberOfTests == mnNumberOfTests - 1)
+ {
+ mbAnimate = true;
+ maUpdateTimer.Start();
+ }
+ else
+ {
+ mbAnimate = false;
+ Invalidate();
+ }
+ }
+ }
+
+ std::vector<Rectangle> setupRegions(int nPartitionsX, int nPartitionsY, int nWidth, int nHeight)
+ {
+ std::vector<Rectangle> aRegions;
+
+ for (int y = 0; y < nPartitionsY; y++)
+ {
+ for (int x = 0; x < nPartitionsX; x++)
+ {
+ long x1 = x * (nWidth / nPartitionsX);
+ long y1 = y * (nHeight / nPartitionsY);
+ long x2 = (x+1) * (nWidth / nPartitionsX);
+ long y2 = (y+1) * (nHeight / nPartitionsY);
+
+ aRegions.push_back(Rectangle(x1 + 1, y1 + 1, x2 - 2, y2 - 2));
+ }
+ }
+ return aRegions;
+ }
+
+ void testRectangles(vcl::RenderContext& rRenderContext, int nWidth, int nHeight)
+ {
+ Rectangle aRectangle;
+ size_t index = 0;
+
+ std::vector<Rectangle> aRegions = setupRegions(3, 2, nWidth, nHeight);
+
+ aRectangle = aRegions[index++];
+ {
+ vcl::test::OutputDeviceTestRect aOutDevTest;
+ Bitmap aBitmap = aOutDevTest.setupRectangle();
+ assertAndSetBackground(aOutDevTest.checkRectangle(aBitmap), aRectangle, rRenderContext);
+ drawBitmapScaledAndCentered(aRectangle, aBitmap, rRenderContext);
+ }
+
+ aRectangle = aRegions[index++];
+ {
+ vcl::test::OutputDeviceTestPixel aOutDevTest;
+ Bitmap aBitmap = aOutDevTest.setupRectangle();
+ assertAndSetBackground(aOutDevTest.checkRectangle(aBitmap), aRectangle, rRenderContext);
+ drawBitmapScaledAndCentered(aRectangle, aBitmap, rRenderContext);
+ }
+
+ aRectangle = aRegions[index++];
+ {
+ vcl::test::OutputDeviceTestLine aOutDevTest;
+ Bitmap aBitmap = aOutDevTest.setupRectangle();
+ assertAndSetBackground(aOutDevTest.checkRectangle(aBitmap), aRectangle, rRenderContext);
+ drawBitmapScaledAndCentered(aRectangle, aBitmap, rRenderContext);
+ }
+
+ aRectangle = aRegions[index++];
+ {
+ vcl::test::OutputDeviceTestPolygon aOutDevTest;
+ Bitmap aBitmap = aOutDevTest.setupRectangle();
+ assertAndSetBackground(aOutDevTest.checkRectangle(aBitmap), aRectangle, rRenderContext);
+ drawBitmapScaledAndCentered(aRectangle, aBitmap, rRenderContext);
+ }
+
+ aRectangle = aRegions[index++];
+ {
+ vcl::test::OutputDeviceTestPolyLine aOutDevTest;
+ Bitmap aBitmap = aOutDevTest.setupRectangle();
+ assertAndSetBackground(aOutDevTest.checkRectangle(aBitmap), aRectangle, rRenderContext);
+ drawBitmapScaledAndCentered(aRectangle, aBitmap, rRenderContext);
+ }
+
+ aRectangle = aRegions[index++];
+ {
+ vcl::test::OutputDeviceTestPolyPolygon aOutDevTest;
+ Bitmap aBitmap = aOutDevTest.setupRectangle();
+ assertAndSetBackground(aOutDevTest.checkRectangle(aBitmap), aRectangle, rRenderContext);
+ drawBitmapScaledAndCentered(aRectangle, aBitmap, rRenderContext);
+ }
+ }
+
+ void testFilledRectangles(vcl::RenderContext& rRenderContext, int nWidth, int nHeight)
+ {
+ Rectangle aRectangle;
+ size_t index = 0;
+
+ std::vector<Rectangle> aRegions = setupRegions(3, 2, nWidth, nHeight);
+
+ aRectangle = aRegions[index++];
+ {
+ vcl::test::OutputDeviceTestRect aOutDevTest;
+ Bitmap aBitmap = aOutDevTest.setupFilledRectangle();
+ assertAndSetBackground(aOutDevTest.checkFilledRectangle(aBitmap), aRectangle, rRenderContext);
+ drawBitmapScaledAndCentered(aRectangle, aBitmap, rRenderContext);
+ }
+
+ aRectangle = aRegions[index++];
+ {
+ vcl::test::OutputDeviceTestPolygon aOutDevTest;
+ Bitmap aBitmap = aOutDevTest.setupFilledRectangle();
+ assertAndSetBackground(aOutDevTest.checkFilledRectangle(aBitmap), aRectangle, rRenderContext);
+ drawBitmapScaledAndCentered(aRectangle, aBitmap, rRenderContext);
+ }
+
+ aRectangle = aRegions[index++];
+ {
+ vcl::test::OutputDeviceTestPolyPolygon aOutDevTest;
+ Bitmap aBitmap = aOutDevTest.setupFilledRectangle();
+ assertAndSetBackground(aOutDevTest.checkFilledRectangle(aBitmap), aRectangle, rRenderContext);
+ drawBitmapScaledAndCentered(aRectangle, aBitmap, rRenderContext);
+ }
+
+ aRectangle = aRegions[index++];
+ {
+ vcl::test::OutputDeviceTestPolygon aOutDevTest;
+ Bitmap aBitmap = aOutDevTest.setupDiamond();
+ assertAndSetBackground(aOutDevTest.checkDiamond(aBitmap), aRectangle, rRenderContext);
+ drawBitmapScaledAndCentered(aRectangle, aBitmap, rRenderContext);
+ }
+ aRectangle = aRegions[index++];
+ {
+ vcl::test::OutputDeviceTestLine aOutDevTest;
+ Bitmap aBitmap = aOutDevTest.setupDiamond();
+ assertAndSetBackground(aOutDevTest.checkDiamond(aBitmap), aRectangle, rRenderContext);
+ drawBitmapScaledAndCentered(aRectangle, aBitmap, rRenderContext);
+ }
+ aRectangle = aRegions[index++];
+ {
+ vcl::test::OutputDeviceTestPolyLine aOutDevTest;
+ Bitmap aBitmap = aOutDevTest.setupDiamond();
+ assertAndSetBackground(aOutDevTest.checkDiamond(aBitmap), aRectangle, rRenderContext);
+ drawBitmapScaledAndCentered(aRectangle, aBitmap, rRenderContext);
+ }
+ }
+
+ void testLines(vcl::RenderContext& rRenderContext, int nWidth, int nHeight)
+ {
+ Rectangle aRectangle;
+ size_t index = 0;
+
+ std::vector<Rectangle> aRegions = setupRegions(3, 2, nWidth, nHeight);
+
+ aRectangle = aRegions[index++];
+ {
+ vcl::test::OutputDeviceTestLine aOutDevTest;
+ Bitmap aBitmap = aOutDevTest.setupLines();
+ assertAndSetBackground(aOutDevTest.checkLines(aBitmap), aRectangle, rRenderContext);
+ drawBitmapScaledAndCentered(aRectangle, aBitmap, rRenderContext);
+ }
+ aRectangle = aRegions[index++];
+ {
+ vcl::test::OutputDeviceTestPolyLine aOutDevTest;
+ Bitmap aBitmap = aOutDevTest.setupLines();
+ assertAndSetBackground(aOutDevTest.checkLines(aBitmap), aRectangle, rRenderContext);
+ drawBitmapScaledAndCentered(aRectangle, aBitmap, rRenderContext);
+ }
+ aRectangle = aRegions[index++];
+ {
+ vcl::test::OutputDeviceTestPolygon aOutDevTest;
+ Bitmap aBitmap = aOutDevTest.setupLines();
+ assertAndSetBackground(aOutDevTest.checkLines(aBitmap), aRectangle, rRenderContext);
+ drawBitmapScaledAndCentered(aRectangle, aBitmap, rRenderContext);
+ }
+ aRectangle = aRegions[index++];
+ {
+ vcl::test::OutputDeviceTestLine aOutDevTest;
+ Bitmap aBitmap = aOutDevTest.setupAALines();
+ assertAndSetBackground(aOutDevTest.checkAALines(aBitmap), aRectangle, rRenderContext);
+ drawBitmapScaledAndCentered(aRectangle, aBitmap, rRenderContext);
+ }
+ aRectangle = aRegions[index++];
+ {
+ vcl::test::OutputDeviceTestPolyLine aOutDevTest;
+ Bitmap aBitmap = aOutDevTest.setupAALines();
+ assertAndSetBackground(aOutDevTest.checkAALines(aBitmap), aRectangle, rRenderContext);
+ drawBitmapScaledAndCentered(aRectangle, aBitmap, rRenderContext);
+ }
+ aRectangle = aRegions[index++];
+ {
+ vcl::test::OutputDeviceTestPolygon aOutDevTest;
+ Bitmap aBitmap = aOutDevTest.setupAALines();
+ assertAndSetBackground(aOutDevTest.checkAALines(aBitmap), aRectangle, rRenderContext);
+ drawBitmapScaledAndCentered(aRectangle, aBitmap, rRenderContext);
+ }
+ }
+
+ void testBitmaps(vcl::RenderContext& rRenderContext, int nWidth, int nHeight)
+ {
+ Rectangle aRectangle;
+ size_t index = 0;
+
+ std::vector<Rectangle> aRegions = setupRegions(2, 2, nWidth, nHeight);
+
+ aRectangle = aRegions[index++];
+ {
+ vcl::test::OutputDeviceTestBitmap aOutDevTest;
+ Bitmap aBitmap = aOutDevTest.setupDrawBitmap();
+ assertAndSetBackground(aOutDevTest.checkTransformedBitmap(aBitmap), aRectangle, rRenderContext);
+ drawBitmapScaledAndCentered(aRectangle, aBitmap, rRenderContext);
+ }
+ aRectangle = aRegions[index++];
+ {
+ vcl::test::OutputDeviceTestBitmap aOutDevTest;
+ Bitmap aBitmap = aOutDevTest.setupDrawTransformedBitmap();
+ assertAndSetBackground(aOutDevTest.checkTransformedBitmap(aBitmap), aRectangle, rRenderContext);
+ drawBitmapScaledAndCentered(aRectangle, aBitmap, rRenderContext);
+ }
+ aRectangle = aRegions[index++];
+ {
+ vcl::test::OutputDeviceTestBitmap aOutDevTest;
+ Bitmap aBitmap = aOutDevTest.setupDrawBitmapExWithAlpha();
+ assertAndSetBackground(aOutDevTest.checkBitmapExWithAlpha(aBitmap), aRectangle, rRenderContext);
+ drawBitmapScaledAndCentered(aRectangle, aBitmap, rRenderContext);
+ }
+ aRectangle = aRegions[index++];
+ {
+ vcl::test::OutputDeviceTestBitmap aOutDevTest;
+ Bitmap aBitmap = aOutDevTest.setupDrawMask();
+ assertAndSetBackground(aOutDevTest.checkMask(aBitmap), aRectangle, rRenderContext);
+ drawBitmapScaledAndCentered(aRectangle, aBitmap, rRenderContext);
+ }
+ }
+
+ virtual void Paint(vcl::RenderContext& rRenderContext, const Rectangle& /*rRect*/) override
+ {
+ if (mnTest % mnNumberOfTests == mnNumberOfTests - 1)
+ {
+ rRenderContext.SetBackground(Wallpaper(COL_GREEN));
+
+ static size_t nTimeIndex = 0;
+ static const size_t constSamplesFPS = 120;
+ double fps = 0.0;
+
+ if (mTimePoints.size() < constSamplesFPS)
+ {
+ mTimePoints.push_back(std::chrono::high_resolution_clock::now());
+ nTimeIndex++;
+ }
+ else
+ {
+ size_t current = nTimeIndex % constSamplesFPS;
+ mTimePoints[current] = std::chrono::high_resolution_clock::now();
+ size_t last = (nTimeIndex + 1) % constSamplesFPS;
+ auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(mTimePoints[current] - mTimePoints[last]).count();
+ fps = constSamplesFPS * 1000.0 / ms;
+ nTimeIndex++;
+ }
+
+ double fTime = 0.5 + std::sin(nTimeIndex / 100.0) / 2.0;
+
+ Size aSizePixel = GetSizePixel();
+
+ mpVDev->SetAntialiasing(AntialiasingFlags::EnableB2dDraw | AntialiasingFlags::PixelSnapHairline);
+ mpVDev->SetOutputSizePixel(aSizePixel);
+ mpVDev->SetBackground(Wallpaper(COL_LIGHTGRAY));
+ mpVDev->Erase();
+ mpVDev->SetFillColor(COL_LIGHTRED);
+ mpVDev->SetLineColor(COL_LIGHTBLUE);
+
+ basegfx::B2DPolyPolygon polyPolygon;
+
+ for (int b=10; b<14; b++)
+ {
+ basegfx::B2DPolygon polygon;
+ for (double a=0.0; a<360.0; a+=0.5)
+ {
+ double x = std::sin(a*M_PI / 180.0) * (b+1) * 20;
+ double y = std::cos(a*M_PI / 180.0) * (b+1) * 20;
+ polygon.append(basegfx::B2DPoint(x + 200 + 500 * fTime, y + 200 + 500 * fTime));
+ }
+ polygon.setClosed(true);
+ polyPolygon.append(polygon);
+ }
+
+ mpVDev->DrawPolyPolygon(polyPolygon);
+
+ Rectangle aGradientRect(Point(200, 200), Size(200 + fTime * 300, 200 + fTime * 300));
+ mpVDev->DrawGradient(aGradientRect, Gradient(GradientStyle_LINEAR, COL_YELLOW, COL_BLUE));
+
+ rRenderContext.DrawOutDev(Point(), mpVDev->GetOutputSizePixel(),
+ Point(), mpVDev->GetOutputSizePixel(),
+ *mpVDev.get());
+ rRenderContext.SetTextColor(COL_LIGHTRED);
+ rRenderContext.DrawText(Point(10, 10), OUString("FPS: ") + OUString::number(int(fps)));
+ return;
+ }
+
+ rRenderContext.SetBackground(Wallpaper(COL_GREEN));
+
+ Size aSize = GetOutputSizePixel();
+
+ long nWidth = aSize.Width();
+ long nHeight = aSize.Height();
+
+ Rectangle aRectangle;
+ size_t index = 0;
+
+ if (mnTest % mnNumberOfTests == 0)
+ {
+ testRectangles(rRenderContext, nWidth, nHeight);
+ }
+ else if (mnTest % mnNumberOfTests == 1)
+ {
+ testFilledRectangles(rRenderContext, nWidth, nHeight);
+ }
+ else if (mnTest % mnNumberOfTests == 2)
+ {
+ testLines(rRenderContext, nWidth, nHeight);
+ }
+ else if (mnTest % mnNumberOfTests == 3)
+ {
+ testBitmaps(rRenderContext, nWidth, nHeight);
+ }
+ else if (mnTest % mnNumberOfTests == 4)
+ {
+ std::vector<Rectangle> aRegions = setupRegions(3, 2, nWidth, nHeight);
+
+ aRectangle = aRegions[index++];
+ {
+ vcl::test::OutputDeviceTestAnotherOutDev aOutDevTest;
+ Bitmap aBitmap = aOutDevTest.setupDrawOutDev();
+ assertAndSetBackground(aOutDevTest.checkDrawOutDev(aBitmap), aRectangle, rRenderContext);
+ drawBitmapScaledAndCentered(aRectangle, aBitmap, rRenderContext);
+ }
+ aRectangle = aRegions[index++];
+ {
+ vcl::test::OutputDeviceTestAnotherOutDev aOutDevTest;
+ Bitmap aBitmap = aOutDevTest.setupXOR();
+ assertAndSetBackground(aOutDevTest.checkXOR(aBitmap), aRectangle, rRenderContext);
+ drawBitmapScaledAndCentered(aRectangle, aBitmap, rRenderContext);
+ }
+ aRectangle = aRegions[index++];
+ {
+ vcl::test::OutputDeviceTestGradient aOutDevTest;
+ Bitmap aBitmap = aOutDevTest.setupLinearGradient();
+ drawBitmapScaledAndCentered(aRectangle, aBitmap, rRenderContext);
+ }
+ aRectangle = aRegions[index++];
+ {
+ vcl::test::OutputDeviceTestGradient aOutDevTest;
+ Bitmap aBitmap = aOutDevTest.setupRadialGradient();
+ drawBitmapScaledAndCentered(aRectangle, aBitmap, rRenderContext);
+ }
+ }
+ }
+};
+
+IMPL_LINK_NOARG_TYPED(VisualBackendTestWindow, updateHdl, Timer *, void)
+{
+ if (mbAnimate)
+ {
+ maUpdateTimer.SetTimeout(1000.0 / 60.0);
+ maUpdateTimer.Start();
+ Invalidate();
+ }
+}
+
+class VisualBackendTestApp : public Application
+{
+
+public:
+ VisualBackendTestApp()
+ {}
+
+ virtual int Main() override
+ {
+ try
+ {
+ ScopedVclPtrInstance<VisualBackendTestWindow> aMainWindow;
+
+ aMainWindow->SetText("VCL Test");
+ aMainWindow->Show();
+
+ Application::Execute();
+ }
+ catch (const css::uno::Exception& rException)
+ {
+ SAL_WARN("vcl.app", "Fatal exception: " << rException.Message);
+ return 1;
+ }
+ catch (const std::exception& rException)
+ {
+ SAL_WARN("vcl.app", "Fatal exception: " << rException.what());
+ return 1;
+ }
+ return 0;
+ }
+
+protected:
+ uno::Reference<lang::XMultiServiceFactory> xMSF;
+
+ void Init() override
+ {
+ try
+ {
+ uno::Reference<uno::XComponentContext> xComponentContext = ::cppu::defaultBootstrap_InitialComponentContext();
+ xMSF = uno::Reference<lang::XMultiServiceFactory>(xComponentContext->getServiceManager(), uno::UNO_QUERY);
+
+ if (!xMSF.is())
+ Application::Abort("Bootstrap failure - no service manager");
+
+ comphelper::setProcessServiceFactory(xMSF);
+ }
+ catch (const uno::Exception &e)
+ {
+ Application::Abort("Bootstrap exception " + e.Message);
+ }
+ }
+
+ void DeInit() override
+ {
+ uno::Reference<lang::XComponent> xComponent(comphelper::getProcessComponentContext(), uno::UNO_QUERY_THROW);
+ xComponent->dispose();
+ comphelper::setProcessServiceFactory(nullptr);
+ }
+};
+
+void vclmain::createApplication()
+{
+ static VisualBackendTestApp aApplication;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/backendtest/outputdevice/bitmap.cxx b/vcl/backendtest/outputdevice/bitmap.cxx
new file mode 100644
index 000000000000..351dfa2eb802
--- /dev/null
+++ b/vcl/backendtest/outputdevice/bitmap.cxx
@@ -0,0 +1,154 @@
+/* -*- 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 "test/outputdevice.hxx"
+
+#include <basegfx/matrix/b2dhommatrix.hxx>
+
+namespace vcl {
+namespace test {
+
+Bitmap OutputDeviceTestBitmap::setupDrawTransformedBitmap()
+{
+ Size aBitmapSize(9, 9);
+ Bitmap aBitmap(aBitmapSize, 24);
+ {
+ Bitmap::ScopedWriteAccess aWriteAccess(aBitmap);
+ aWriteAccess->Erase(constFillColor);
+ aWriteAccess->SetLineColor(COL_YELLOW);
+ aWriteAccess->DrawRect(Rectangle(0, 0, 8, 8));
+ aWriteAccess->DrawRect(Rectangle(2, 2, 6, 6));
+ }
+
+ initialSetup(13, 13, constBackgroundColor);
+
+ basegfx::B2DHomMatrix aTransform;
+ aTransform.scale(aBitmapSize.Width(), aBitmapSize.Height());
+ aTransform.translate((maVDRectangle.GetWidth() / 2.0) - (aBitmapSize.Width() / 2.0),
+ (maVDRectangle.GetHeight() / 2.0) - (aBitmapSize.Height() / 2.0));
+
+ mpVirtualDevice->DrawTransformedBitmapEx(aTransform, BitmapEx(aBitmap));
+
+ return mpVirtualDevice->GetBitmap(maVDRectangle.TopLeft(), maVDRectangle.GetSize());
+}
+
+
+Bitmap OutputDeviceTestBitmap::setupDrawBitmap()
+{
+ Size aBitmapSize(9, 9);
+ Bitmap aBitmap(aBitmapSize, 24);
+ {
+ Bitmap::ScopedWriteAccess aWriteAccess(aBitmap);
+ aWriteAccess->Erase(constFillColor);
+ aWriteAccess->SetLineColor(COL_YELLOW);
+ aWriteAccess->DrawRect(Rectangle(0, 0, 8, 8));
+ aWriteAccess->DrawRect(Rectangle(2, 2, 6, 6));
+ }
+
+ initialSetup(13, 13, constBackgroundColor);
+
+ Point aPoint((maVDRectangle.GetWidth() / 2.0) - (aBitmapSize.Width() / 2.0),
+ (maVDRectangle.GetHeight() / 2.0) - (aBitmapSize.Height() / 2.0));
+
+ mpVirtualDevice->DrawBitmapEx(aPoint, BitmapEx(aBitmap));
+
+ return mpVirtualDevice->GetBitmap(maVDRectangle.TopLeft(), maVDRectangle.GetSize());
+}
+
+Bitmap OutputDeviceTestBitmap::setupDrawBitmapExWithAlpha()
+{
+ Size aBitmapSize(9, 9);
+ Bitmap aBitmap(aBitmapSize, 24);
+ {
+ Bitmap::ScopedWriteAccess aWriteAccess(aBitmap);
+ aWriteAccess->Erase(COL_WHITE);
+ aWriteAccess->SetLineColor(Color(0xFF, 0xFF, 0x00));
+ aWriteAccess->DrawRect(Rectangle(0, 0, 8, 8));
+ aWriteAccess->DrawRect(Rectangle(3, 3, 5, 5));
+ }
+
+ AlphaMask aAlpha(aBitmapSize);
+ {
+ AlphaMask::ScopedWriteAccess aWriteAccess(aAlpha);
+ aWriteAccess->Erase(COL_WHITE);
+ aWriteAccess->SetLineColor(Color(0x44, 0x44, 0x44));
+ aWriteAccess->DrawRect(Rectangle(0, 0, 8, 8));
+ aWriteAccess->DrawRect(Rectangle(3, 3, 5, 5));
+ }
+
+ initialSetup(13, 13, constBackgroundColor);
+
+ Point aPoint(alignToCenter(maVDRectangle, Rectangle(Point(), aBitmapSize)).TopLeft());
+
+ mpVirtualDevice->DrawBitmapEx(aPoint, BitmapEx(aBitmap, aAlpha));
+
+ return mpVirtualDevice->GetBitmap(maVDRectangle.TopLeft(), maVDRectangle.GetSize());
+}
+
+Bitmap OutputDeviceTestBitmap::setupDrawMask()
+{
+ Size aBitmapSize(9, 9);
+ Bitmap aBitmap(aBitmapSize, 24);
+ {
+ Bitmap::ScopedWriteAccess aWriteAccess(aBitmap);
+ aWriteAccess->Erase(COL_WHITE);
+ aWriteAccess->SetLineColor(COL_BLACK);
+ aWriteAccess->DrawRect(Rectangle(0, 0, 8, 8));
+ aWriteAccess->DrawRect(Rectangle(3, 3, 5, 5));
+ }
+
+ initialSetup(13, 13, constBackgroundColor);
+
+ mpVirtualDevice->DrawMask(Point(2, 2), aBitmap, constFillColor);
+
+ return mpVirtualDevice->GetBitmap(maVDRectangle.TopLeft(), maVDRectangle.GetSize());
+}
+
+TestResult OutputDeviceTestBitmap::checkBitmap(Bitmap& rBitmap)
+{
+ std::vector<Color> aExpected
+ {
+ constBackgroundColor, constBackgroundColor,
+ COL_YELLOW, constFillColor, COL_YELLOW, constFillColor, constFillColor
+ };
+ return checkRectangles(rBitmap, aExpected);
+}
+
+TestResult OutputDeviceTestBitmap::checkTransformedBitmap(Bitmap& rBitmap)
+{
+ std::vector<Color> aExpected
+ {
+ constBackgroundColor, constBackgroundColor,
+ COL_YELLOW, constFillColor, COL_YELLOW, constFillColor, constFillColor
+ };
+ return checkRectangles(rBitmap, aExpected);
+}
+
+TestResult OutputDeviceTestBitmap::checkBitmapExWithAlpha(Bitmap& rBitmap)
+{
+ const Color aBlendedColor(0xEE, 0xEE, 0x33);
+
+ std::vector<Color> aExpected
+ {
+ constBackgroundColor, constBackgroundColor,
+ aBlendedColor, constBackgroundColor, constBackgroundColor,
+ aBlendedColor, constBackgroundColor
+ };
+ return checkRectangles(rBitmap, aExpected);
+}
+
+TestResult OutputDeviceTestBitmap::checkMask(Bitmap& rBitmap)
+{
+ return checkRectangle(rBitmap);
+}
+
+}} // end namespace vcl::test
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/backendtest/outputdevice/common.cxx b/vcl/backendtest/outputdevice/common.cxx
new file mode 100644
index 000000000000..ae3ef5963334
--- /dev/null
+++ b/vcl/backendtest/outputdevice/common.cxx
@@ -0,0 +1,328 @@
+/* -*- 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 "test/outputdevice.hxx"
+
+namespace vcl {
+namespace test {
+
+namespace
+{
+
+int deltaColor(BitmapColor aColor1, BitmapColor aColor2)
+{
+ int deltaR = std::abs(aColor1.GetRed() - aColor2.GetRed());
+ int deltaG = std::abs(aColor1.GetGreen() - aColor2.GetGreen());
+ int deltaB = std::abs(aColor1.GetBlue() - aColor2.GetBlue());
+
+ return std::max(std::max(deltaR, deltaG), deltaB);
+}
+
+void checkValue(Bitmap::ScopedWriteAccess& pAccess, int x, int y, Color aExpected,
+ int& nNumberOfQuirks, int& nNumberOfErrors, bool bQuirkMode, int nColorDeltaThresh = 0)
+{
+ bool bColorize = false;
+ Color aColor = pAccess->GetPixel(y, x);
+ int nColorDelta = deltaColor(aColor, aExpected);
+
+ if (nColorDelta <= nColorDeltaThresh)
+ {
+ if (bColorize)
+ pAccess->SetPixel(y, x, Color(COL_LIGHTGREEN));
+ }
+ else if (bQuirkMode)
+ {
+ nNumberOfQuirks++;
+ if (bColorize)
+ pAccess->SetPixel(y, x, Color(COL_YELLOW));
+ }
+ else
+ {
+ nNumberOfErrors++;
+ if (bColorize)
+ pAccess->SetPixel(y, x, Color(COL_LIGHTRED));
+ }
+}
+
+TestResult checkRect(Bitmap& rBitmap, int aLayerNumber, Color aExpectedColor)
+{
+ Bitmap::ScopedWriteAccess pAccess(rBitmap);
+ long nHeight = pAccess->Height();
+ long nWidth = pAccess->Width();
+
+ long firstX = 0 + aLayerNumber;
+ long firstY = 0 + aLayerNumber;
+
+ long lastX = nWidth - aLayerNumber - 1;
+ long lastY = nHeight - aLayerNumber - 1;
+
+ TestResult aResult = TestResult::Passed;
+ int nNumberOfQuirks = 0;
+ int nNumberOfErrors = 0;
+
+ // check corner quirks
+ checkValue(pAccess, firstX, firstY, aExpectedColor, nNumberOfQuirks, nNumberOfErrors, true);
+ checkValue(pAccess, lastX, firstY, aExpectedColor, nNumberOfQuirks, nNumberOfErrors, true);
+ checkValue(pAccess, firstX, lastY, aExpectedColor, nNumberOfQuirks, nNumberOfErrors, true);
+ checkValue(pAccess, lastX, lastY, aExpectedColor, nNumberOfQuirks, nNumberOfErrors, true);
+
+ for (long y = firstY + 1; y <= lastY - 1; y++)
+ {
+ checkValue(pAccess, firstX, y, aExpectedColor, nNumberOfQuirks, nNumberOfErrors, false);
+ checkValue(pAccess, lastX, y, aExpectedColor, nNumberOfQuirks, nNumberOfErrors, false);
+ }
+ for (long x = firstX + 1; x <= lastX - 1; x++)
+ {
+ checkValue(pAccess, x, firstY, aExpectedColor, nNumberOfQuirks, nNumberOfErrors, false);
+ checkValue(pAccess, x, lastY, aExpectedColor, nNumberOfQuirks, nNumberOfErrors, false);
+ }
+ if (nNumberOfQuirks > 0)
+ aResult = TestResult::PassedWithQuirks;
+ if (nNumberOfErrors > 0)
+ aResult = TestResult::Failed;
+ return aResult;
+}
+
+TestResult checkHorizontalVerticalDiagonalLines(Bitmap& rBitmap, Color aExpectedColor, int nColorThresh)
+{
+ Bitmap::ScopedWriteAccess pAccess(rBitmap);
+ long nWidth = pAccess->Width();
+ long nHeight = pAccess->Height();
+
+ TestResult aResult = TestResult::Passed;
+ int nNumberOfQuirks = 0;
+ int nNumberOfErrors = 0;
+
+ // check horizontal line
+ {
+ long startX = 4;
+ long endX = nWidth - 2;
+
+ long y = 1;
+
+ checkValue(pAccess, startX, y, aExpectedColor, nNumberOfQuirks, nNumberOfErrors, true, nColorThresh);
+ checkValue(pAccess, endX, y, aExpectedColor, nNumberOfQuirks, nNumberOfErrors, true, nColorThresh);
+
+ for (int x = startX + 1; x <= endX - 1; x++)
+ {
+ checkValue(pAccess, x, y, aExpectedColor, nNumberOfQuirks, nNumberOfErrors, false, nColorThresh);
+ }
+ }
+
+ // check vertical line
+ {
+ long startY = 4;
+ long endY = nHeight - 2;
+
+ long x = 1;
+
+ checkValue(pAccess, x, startY, aExpectedColor, nNumberOfQuirks, nNumberOfErrors, true, nColorThresh);
+ checkValue(pAccess, x, endY, aExpectedColor, nNumberOfQuirks, nNumberOfErrors, true, nColorThresh);
+
+ for (int y = startY + 1; y <= endY - 1; y++)
+ {
+ checkValue(pAccess, x, y, aExpectedColor, nNumberOfQuirks, nNumberOfErrors, false, nColorThresh);
+ }
+ }
+
+ // check diagonal line
+ {
+ long startX = 1;
+ long endX = nWidth - 2;
+
+ long startY = 1;
+ long endY = nHeight - 2;
+
+ long x = startX;
+ long y = startY;
+
+ checkValue(pAccess, startX, startY, aExpectedColor, nNumberOfQuirks, nNumberOfErrors, true, nColorThresh);
+ checkValue(pAccess, endX, endY, aExpectedColor, nNumberOfQuirks, nNumberOfErrors, true, nColorThresh);
+
+ x++; y++;
+
+ while(y <= endY - 1 && x <= endX - 1)
+ {
+ checkValue(pAccess, x, y, aExpectedColor, nNumberOfQuirks, nNumberOfErrors, false, nColorThresh);
+ x++; y++;
+ }
+ }
+
+ if (nNumberOfQuirks > 0)
+ aResult = TestResult::PassedWithQuirks;
+ if (nNumberOfErrors > 0)
+ aResult = TestResult::Failed;
+ return aResult;
+}
+
+TestResult checkDiamondLine(Bitmap& rBitmap, int aLayerNumber, Color aExpectedColor)
+{
+ Bitmap::ScopedWriteAccess pAccess(rBitmap);
+ long nHeight = pAccess->Height();
+ long nWidth = pAccess->Width();
+
+ long midX = nWidth / 2;
+ long midY = nHeight / 2;
+
+ long firstX = aLayerNumber;
+ long lastX = nWidth - aLayerNumber - 1;
+
+ long firstY = aLayerNumber;
+ long lastY = nHeight - aLayerNumber - 1;
+
+ long offsetFromMid = 0;
+
+ TestResult aResult = TestResult::Passed;
+ int nNumberOfQuirks = 0;
+ int nNumberOfErrors = 0;
+
+ checkValue(pAccess, firstX, midY, aExpectedColor, nNumberOfQuirks, nNumberOfErrors, true);
+ checkValue(pAccess, lastX, midY, aExpectedColor, nNumberOfQuirks, nNumberOfErrors, true);
+ checkValue(pAccess, midX, firstY, aExpectedColor, nNumberOfQuirks, nNumberOfErrors, true);
+ checkValue(pAccess, midX, lastY, aExpectedColor, nNumberOfQuirks, nNumberOfErrors, true);
+
+ offsetFromMid = 1;
+ for (long x = firstX + 1; x <= midX - 1; x++)
+ {
+ checkValue(pAccess, x, midY - offsetFromMid, aExpectedColor, nNumberOfQuirks, nNumberOfErrors, false);
+ checkValue(pAccess, x, midY + offsetFromMid, aExpectedColor, nNumberOfQuirks, nNumberOfErrors, false);
+
+ offsetFromMid++;
+ }
+
+ offsetFromMid = midY - aLayerNumber - 1;
+
+ for (long x = midX + 1; x <= lastX - 1; x++)
+ {
+ checkValue(pAccess, x, midY - offsetFromMid, aExpectedColor, nNumberOfQuirks, nNumberOfErrors, false);
+ checkValue(pAccess, x, midY + offsetFromMid, aExpectedColor, nNumberOfQuirks, nNumberOfErrors, false);
+
+ offsetFromMid--;
+ }
+
+ if (nNumberOfQuirks > 0)
+ aResult = TestResult::PassedWithQuirks;
+ if (nNumberOfErrors > 0)
+ aResult = TestResult::Failed;
+ return aResult;
+}
+
+} // end anonymous namespace
+
+const Color OutputDeviceTestCommon::constBackgroundColor(COL_LIGHTGRAY);
+const Color OutputDeviceTestCommon::constLineColor(COL_LIGHTBLUE);
+const Color OutputDeviceTestCommon::constFillColor(COL_LIGHTBLUE);
+
+OutputDeviceTestCommon::OutputDeviceTestCommon()
+ : mpVirtualDevice(VclPtr<VirtualDevice>::Create())
+{}
+
+void OutputDeviceTestCommon::initialSetup(long nWidth, long nHeight, Color aColor)
+{
+ maVDRectangle = Rectangle(Point(), Size (nWidth, nHeight));
+ mpVirtualDevice->SetOutputSizePixel(maVDRectangle.GetSize());
+ mpVirtualDevice->SetBackground(Wallpaper(aColor));
+ mpVirtualDevice->Erase();
+}
+
+TestResult OutputDeviceTestCommon::checkLines(Bitmap& rBitmap)
+{
+ return checkHorizontalVerticalDiagonalLines(rBitmap, constLineColor, 0);
+}
+
+TestResult OutputDeviceTestCommon::checkAALines(Bitmap& rBitmap)
+{
+ return checkHorizontalVerticalDiagonalLines(rBitmap, constLineColor, 30); // 30 color values threshold delta
+}
+
+TestResult OutputDeviceTestCommon::checkRectangle(Bitmap& aBitmap)
+{
+ std::vector<Color> aExpected
+ {
+ constBackgroundColor, constBackgroundColor, constLineColor,
+ constBackgroundColor, constBackgroundColor, constLineColor, constBackgroundColor
+ };
+ return checkRectangles(aBitmap, aExpected);
+}
+
+TestResult OutputDeviceTestCommon::checkFilledRectangle(Bitmap& aBitmap)
+{
+ std::vector<Color> aExpected
+ {
+ constBackgroundColor, constBackgroundColor,
+ constFillColor, constFillColor, constFillColor, constFillColor, constFillColor
+ };
+ return checkRectangles(aBitmap, aExpected);
+}
+
+TestResult OutputDeviceTestCommon::checkRectangles(Bitmap& aBitmap, std::vector<Color>& aExpectedColors)
+{
+ TestResult aReturnValue = TestResult::Passed;
+ for (size_t i = 0; i < aExpectedColors.size(); i++)
+ {
+ switch(checkRect(aBitmap, i, aExpectedColors[i]))
+ {
+ case TestResult::Failed:
+ return TestResult::Failed;
+ case TestResult::PassedWithQuirks:
+ aReturnValue = TestResult::PassedWithQuirks;
+ break;
+ default:
+ break;
+ }
+
+ }
+ return aReturnValue;
+}
+
+Rectangle OutputDeviceTestCommon::alignToCenter(Rectangle aRect1, Rectangle aRect2)
+{
+ Point aPoint((aRect1.GetWidth() / 2.0) - (aRect2.GetWidth() / 2.0),
+ (aRect1.GetHeight() / 2.0) - (aRect2.GetHeight() / 2.0));
+
+ return Rectangle(aPoint, aRect2.GetSize());
+}
+
+TestResult OutputDeviceTestCommon::checkDiamond(Bitmap& rBitmap)
+{
+ return checkDiamondLine(rBitmap, 1, constLineColor);
+}
+
+void OutputDeviceTestCommon::createDiamondPoints(Rectangle rRect, int nOffset,
+ Point& rPoint1, Point& rPoint2,
+ Point& rPoint3, Point& rPoint4)
+{
+ long midPointX = rRect.Left() + (rRect.Right() - rRect.Left()) / 2.0;
+ long midPointY = rRect.Top() + (rRect.Bottom() - rRect.Top()) / 2.0;
+
+ rPoint1 = Point(midPointX , midPointY - nOffset);
+ rPoint2 = Point(midPointX + nOffset, midPointY );
+ rPoint3 = Point(midPointX , midPointY + nOffset);
+ rPoint4 = Point(midPointX - nOffset, midPointY );
+}
+
+void OutputDeviceTestCommon::createHorizontalVerticalDiagonalLinePoints(Rectangle rRect,
+ Point& rHorizontalLinePoint1, Point& rHorizontalLinePoint2,
+ Point& rVerticalLinePoint1, Point& rVerticalLinePoint2,
+ Point& rDiagonalLinePoint1, Point& rDiagonalLinePoint2)
+{
+ rHorizontalLinePoint1 = Point(4, 1);
+ rHorizontalLinePoint2 = Point(rRect.Right() - 1, 1);
+
+ rVerticalLinePoint1 = Point(1, 4);
+ rVerticalLinePoint2 = Point(1,rRect.Bottom() - 1);
+
+ rDiagonalLinePoint1 = Point(1, 1);
+ rDiagonalLinePoint2 = Point(rRect.Right() - 1, rRect.Bottom() - 1);
+}
+
+}} // end namespace vcl::test
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/backendtest/outputdevice/gradient.cxx b/vcl/backendtest/outputdevice/gradient.cxx
new file mode 100644
index 000000000000..f686e3270c80
--- /dev/null
+++ b/vcl/backendtest/outputdevice/gradient.cxx
@@ -0,0 +1,43 @@
+/* -*- 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 "test/outputdevice.hxx"
+
+namespace vcl {
+namespace test {
+
+Bitmap OutputDeviceTestGradient::setupLinearGradient()
+{
+ initialSetup(12, 12, constBackgroundColor);
+
+ Gradient aGradient(GradientStyle_LINEAR, Color(0xFF, 0xFF, 0xFF), Color(0x00, 0x00, 0x00));
+ aGradient.SetAngle(900);
+ Rectangle aDrawRect(maVDRectangle.Left() + 1, maVDRectangle.Top() + 1,
+ maVDRectangle.Right() - 1, maVDRectangle.Bottom() - 1);
+ mpVirtualDevice->DrawGradient(aDrawRect, aGradient);
+
+ return mpVirtualDevice->GetBitmap(maVDRectangle.TopLeft(), maVDRectangle.GetSize());
+}
+
+Bitmap OutputDeviceTestGradient::setupRadialGradient()
+{
+ initialSetup(12, 12, constBackgroundColor);
+
+ Gradient aGradient(GradientStyle_RADIAL, Color(0xFF, 0xFF, 0xFF), Color(0x00, 0x00, 0x00));
+ Rectangle aDrawRect(maVDRectangle.Left() + 1, maVDRectangle.Top() + 1,
+ maVDRectangle.Right() - 1, maVDRectangle.Bottom() - 1);
+ mpVirtualDevice->DrawGradient(aDrawRect, aGradient);
+
+ return mpVirtualDevice->GetBitmap(maVDRectangle.TopLeft(), maVDRectangle.GetSize());
+}
+
+}} // end namespace vcl::test
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/backendtest/outputdevice/line.cxx b/vcl/backendtest/outputdevice/line.cxx
new file mode 100644
index 000000000000..4cd39dbfcfe9
--- /dev/null
+++ b/vcl/backendtest/outputdevice/line.cxx
@@ -0,0 +1,114 @@
+/* -*- 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 "test/outputdevice.hxx"
+
+namespace vcl {
+namespace test {
+
+namespace
+{
+
+void drawLineOffset(OutputDevice& rDevice, Rectangle& rRect, int nOffset)
+{
+ Point aLeftTop (rRect.Left() + nOffset, rRect.Top() + nOffset);
+ Point aRightTop (rRect.Right() - nOffset, rRect.Top() + nOffset);
+ Point aLeftBottom (rRect.Left() + nOffset, rRect.Bottom() - nOffset);
+ Point aRightBottom (rRect.Right() - nOffset, rRect.Bottom() - nOffset);
+
+ rDevice.DrawLine(aLeftTop, aRightTop);
+ rDevice.DrawLine(aRightTop, aRightBottom);
+ rDevice.DrawLine(aRightBottom, aLeftBottom);
+ rDevice.DrawLine(aLeftBottom, aLeftTop);
+}
+
+} // end anonymous namespace
+
+Bitmap OutputDeviceTestLine::setupRectangle()
+{
+ initialSetup(13, 13, constBackgroundColor);
+
+ mpVirtualDevice->SetLineColor(constLineColor);
+ mpVirtualDevice->SetFillColor();
+
+ drawLineOffset(*mpVirtualDevice, maVDRectangle, 2);
+ drawLineOffset(*mpVirtualDevice, maVDRectangle, 5);
+
+ return mpVirtualDevice->GetBitmap(maVDRectangle.TopLeft(), maVDRectangle.GetSize());
+}
+
+Bitmap OutputDeviceTestLine::setupDiamond()
+{
+ initialSetup(11, 11, constBackgroundColor);
+
+ mpVirtualDevice->SetLineColor(constFillColor);
+ mpVirtualDevice->SetFillColor();
+
+ Point aPoint1, aPoint2, aPoint3, aPoint4;
+ OutputDeviceTestCommon::createDiamondPoints(maVDRectangle, 4, aPoint1, aPoint2, aPoint3, aPoint4);
+
+ mpVirtualDevice->DrawLine(aPoint1, aPoint2);
+ mpVirtualDevice->DrawLine(aPoint2, aPoint3);
+ mpVirtualDevice->DrawLine(aPoint3, aPoint4);
+ mpVirtualDevice->DrawLine(aPoint4, aPoint1);
+
+ return mpVirtualDevice->GetBitmap(maVDRectangle.TopLeft(), maVDRectangle.GetSize());
+}
+
+Bitmap OutputDeviceTestLine::setupLines()
+{
+ initialSetup(13, 13, constBackgroundColor);
+
+ mpVirtualDevice->SetLineColor(constLineColor);
+ mpVirtualDevice->SetFillColor();
+
+ Point aHorizontalLinePoint1, aHorizontalLinePoint2;
+ Point aVerticalLinePoint1, aVerticalLinePoint2;
+ Point aDiagonalLinePoint1, aDiagonalLinePoint2;
+
+ OutputDeviceTestCommon::createHorizontalVerticalDiagonalLinePoints(
+ maVDRectangle, aHorizontalLinePoint1, aHorizontalLinePoint2,
+ aVerticalLinePoint1, aVerticalLinePoint2,
+ aDiagonalLinePoint1, aDiagonalLinePoint2);
+
+ mpVirtualDevice->DrawLine(aHorizontalLinePoint1, aHorizontalLinePoint2);
+ mpVirtualDevice->DrawLine(aVerticalLinePoint1, aVerticalLinePoint2);
+ mpVirtualDevice->DrawLine(aDiagonalLinePoint1, aDiagonalLinePoint2);
+
+ return mpVirtualDevice->GetBitmap(maVDRectangle.TopLeft(), maVDRectangle.GetSize());
+}
+
+Bitmap OutputDeviceTestLine::setupAALines()
+{
+ initialSetup(13, 13, constBackgroundColor);
+
+ mpVirtualDevice->SetAntialiasing(AntialiasingFlags::EnableB2dDraw);
+ mpVirtualDevice->SetLineColor(constLineColor);
+ mpVirtualDevice->SetFillColor();
+
+ Point aHorizontalLinePoint1, aHorizontalLinePoint2;
+ Point aVerticalLinePoint1, aVerticalLinePoint2;
+ Point aDiagonalLinePoint1, aDiagonalLinePoint2;
+
+ OutputDeviceTestCommon::createHorizontalVerticalDiagonalLinePoints(
+ maVDRectangle, aHorizontalLinePoint1, aHorizontalLinePoint2,
+ aVerticalLinePoint1, aVerticalLinePoint2,
+ aDiagonalLinePoint1, aDiagonalLinePoint2);
+
+ mpVirtualDevice->DrawLine(aHorizontalLinePoint1, aHorizontalLinePoint2);
+ mpVirtualDevice->DrawLine(aVerticalLinePoint1, aVerticalLinePoint2);
+ mpVirtualDevice->DrawLine(aDiagonalLinePoint1, aDiagonalLinePoint2);
+
+ return mpVirtualDevice->GetBitmap(maVDRectangle.TopLeft(), maVDRectangle.GetSize());
+}
+
+}} // end namespace vcl::test
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/backendtest/outputdevice/outputdevice.cxx b/vcl/backendtest/outputdevice/outputdevice.cxx
new file mode 100644
index 000000000000..6bc4278b8f65
--- /dev/null
+++ b/vcl/backendtest/outputdevice/outputdevice.cxx
@@ -0,0 +1,75 @@
+/* -*- 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 "test/outputdevice.hxx"
+
+namespace vcl {
+namespace test {
+
+Bitmap OutputDeviceTestAnotherOutDev::setupDrawOutDev()
+{
+ ScopedVclPtrInstance<VirtualDevice> pSourceDev;
+ Size aSourceSize(9, 9);
+ pSourceDev->SetOutputSizePixel(aSourceSize);
+ pSourceDev->SetBackground(Wallpaper(constFillColor));
+ pSourceDev->Erase();
+
+ initialSetup(13, 13, constBackgroundColor);
+
+ mpVirtualDevice->DrawOutDev(Point(2, 2), aSourceSize, Point(), aSourceSize, *pSourceDev.get());
+
+ return mpVirtualDevice->GetBitmap(maVDRectangle.TopLeft(), maVDRectangle.GetSize());
+}
+
+Bitmap OutputDeviceTestAnotherOutDev::setupXOR()
+{
+ initialSetup(13, 13, constBackgroundColor);
+
+ Rectangle aDrawRectangle(maVDRectangle);
+ aDrawRectangle.shrink(2);
+
+ Rectangle aScissorRectangle(maVDRectangle);
+ aScissorRectangle.shrink(4);
+
+ mpVirtualDevice->SetRasterOp(ROP_XOR);
+ mpVirtualDevice->SetFillColor(constFillColor);
+ mpVirtualDevice->DrawRect(aDrawRectangle);
+
+ mpVirtualDevice->SetRasterOp(ROP_0);
+ mpVirtualDevice->SetFillColor(COL_BLACK);
+ mpVirtualDevice->DrawRect(aScissorRectangle);
+
+ mpVirtualDevice->SetRasterOp(ROP_XOR);
+ mpVirtualDevice->SetFillColor(constFillColor);
+ mpVirtualDevice->DrawRect(aDrawRectangle);
+
+ return mpVirtualDevice->GetBitmap(maVDRectangle.TopLeft(), maVDRectangle.GetSize());
+}
+
+TestResult OutputDeviceTestAnotherOutDev::checkDrawOutDev(Bitmap& rBitmap)
+{
+ return checkFilledRectangle(rBitmap);
+}
+
+TestResult OutputDeviceTestAnotherOutDev::checkXOR(Bitmap& rBitmap)
+{
+ std::vector<Color> aExpected
+ {
+ constBackgroundColor, constBackgroundColor,
+ constBackgroundColor, constBackgroundColor,
+ constFillColor, constFillColor,
+ constFillColor
+ };
+ return checkRectangles(rBitmap, aExpected);
+}
+
+}} // end namespace vcl::test
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/backendtest/outputdevice/pixel.cxx b/vcl/backendtest/outputdevice/pixel.cxx
new file mode 100644
index 000000000000..f13690e72209
--- /dev/null
+++ b/vcl/backendtest/outputdevice/pixel.cxx
@@ -0,0 +1,57 @@
+/* -*- 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 "test/outputdevice.hxx"
+
+namespace vcl {
+namespace test {
+
+namespace
+{
+
+void drawPixelOffset(OutputDevice& rDevice, Rectangle& rRect, int nOffset)
+{
+ for (long x = 0 + nOffset; x < (rRect.GetWidth() - nOffset); ++x)
+ {
+ long y1 = nOffset;
+ long y2 = rRect.GetHeight() - nOffset - 1;
+
+ rDevice.DrawPixel(Point(x, y1));
+ rDevice.DrawPixel(Point(x, y2));
+ }
+
+ for (long y = 0 + nOffset; y < (rRect.GetHeight() - nOffset); ++y)
+ {
+ long x1 = nOffset;
+ long x2 = rRect.GetWidth() - nOffset - 1;
+
+ rDevice.DrawPixel(Point(x1, y));
+ rDevice.DrawPixel(Point(x2, y));
+ }
+}
+
+} // end anonymous namespace
+
+Bitmap OutputDeviceTestPixel::setupRectangle()
+{
+ initialSetup(13, 13, constBackgroundColor);
+
+ mpVirtualDevice->SetLineColor(constLineColor);
+ mpVirtualDevice->SetFillColor();
+
+ drawPixelOffset(*mpVirtualDevice, maVDRectangle, 2);
+ drawPixelOffset(*mpVirtualDevice, maVDRectangle, 5);
+
+ return mpVirtualDevice->GetBitmap(maVDRectangle.TopLeft(), maVDRectangle.GetSize());
+}
+
+}} // end namespace vcl::test
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/backendtest/outputdevice/polygon.cxx b/vcl/backendtest/outputdevice/polygon.cxx
new file mode 100644
index 000000000000..de722c54abe9
--- /dev/null
+++ b/vcl/backendtest/outputdevice/polygon.cxx
@@ -0,0 +1,151 @@
+/* -*- 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 "test/outputdevice.hxx"
+
+namespace vcl {
+namespace test {
+
+namespace
+{
+
+void drawPolygonOffset(OutputDevice& rDevice, Rectangle& rRect, int nOffset)
+{
+ tools::Polygon aPolygon(4);
+ aPolygon.SetPoint(Point(rRect.Left() + nOffset, rRect.Top() + nOffset), 0);
+ aPolygon.SetPoint(Point(rRect.Right() - nOffset, rRect.Top() + nOffset), 1);
+ aPolygon.SetPoint(Point(rRect.Right() - nOffset, rRect.Bottom() - nOffset), 2);
+ aPolygon.SetPoint(Point(rRect.Left() + nOffset, rRect.Bottom() - nOffset), 3);
+ aPolygon.Optimize(PolyOptimizeFlags::CLOSE);
+
+ rDevice.DrawPolygon(aPolygon);
+}
+
+} // end anonymous namespace
+
+Bitmap OutputDeviceTestPolygon::setupRectangle()
+{
+ initialSetup(13, 13, constBackgroundColor);
+
+ mpVirtualDevice->SetLineColor(constLineColor);
+ mpVirtualDevice->SetFillColor();
+
+ drawPolygonOffset(*mpVirtualDevice, maVDRectangle, 2);
+ drawPolygonOffset(*mpVirtualDevice, maVDRectangle, 5);
+
+ return mpVirtualDevice->GetBitmap(maVDRectangle.TopLeft(), maVDRectangle.GetSize());
+}
+
+Bitmap OutputDeviceTestPolygon::setupFilledRectangle()
+{
+ initialSetup(13, 13, constBackgroundColor);
+
+ mpVirtualDevice->SetLineColor(constFillColor);
+ mpVirtualDevice->SetFillColor(constFillColor);
+ drawPolygonOffset(*mpVirtualDevice, maVDRectangle, 2);
+
+ return mpVirtualDevice->GetBitmap(maVDRectangle.TopLeft(), maVDRectangle.GetSize());
+}
+
+Bitmap OutputDeviceTestPolygon::setupDiamond()
+{
+ initialSetup(11, 11, constBackgroundColor);
+
+ mpVirtualDevice->SetLineColor(constLineColor);
+ mpVirtualDevice->SetFillColor();
+
+ Point aPoint1, aPoint2, aPoint3, aPoint4;
+ OutputDeviceTestCommon::createDiamondPoints(maVDRectangle, 4, aPoint1, aPoint2, aPoint3, aPoint4);
+
+ tools::Polygon aPolygon(4);
+
+ aPolygon.SetPoint(aPoint1, 0);
+ aPolygon.SetPoint(aPoint2, 1);
+ aPolygon.SetPoint(aPoint3, 2);
+ aPolygon.SetPoint(aPoint4, 3);
+ aPolygon.Optimize(PolyOptimizeFlags::CLOSE);
+
+ mpVirtualDevice->DrawPolygon(aPolygon);
+
+ return mpVirtualDevice->GetBitmap(maVDRectangle.TopLeft(), maVDRectangle.GetSize());
+}
+
+Bitmap OutputDeviceTestPolygon::setupLines()
+{
+ initialSetup(13, 13, constBackgroundColor);
+
+ mpVirtualDevice->SetLineColor(constLineColor);
+ mpVirtualDevice->SetFillColor();
+
+ Point aHorizontalLinePoint1, aHorizontalLinePoint2;
+ Point aVerticalLinePoint1, aVerticalLinePoint2;
+ Point aDiagonalLinePoint1, aDiagonalLinePoint2;
+
+ OutputDeviceTestCommon::createHorizontalVerticalDiagonalLinePoints(
+ maVDRectangle, aHorizontalLinePoint1, aHorizontalLinePoint2,
+ aVerticalLinePoint1, aVerticalLinePoint2,
+ aDiagonalLinePoint1, aDiagonalLinePoint2);
+
+ tools::Polygon aHorizontalPolygon(2);
+ aHorizontalPolygon.SetPoint(aHorizontalLinePoint1, 0);
+ aHorizontalPolygon.SetPoint(aHorizontalLinePoint2, 1);
+ mpVirtualDevice->DrawPolygon(aHorizontalPolygon);
+
+ tools::Polygon aVerticalPolygon(2);
+ aVerticalPolygon.SetPoint(aVerticalLinePoint1, 0);
+ aVerticalPolygon.SetPoint(aVerticalLinePoint2, 1);
+ mpVirtualDevice->DrawPolygon(aVerticalPolygon);
+
+ tools::Polygon aDiagonalPolygon(2);
+ aDiagonalPolygon.SetPoint(aDiagonalLinePoint1, 0);
+ aDiagonalPolygon.SetPoint(aDiagonalLinePoint2, 1);
+ mpVirtualDevice->DrawPolygon(aDiagonalPolygon);
+
+ return mpVirtualDevice->GetBitmap(maVDRectangle.TopLeft(), maVDRectangle.GetSize());
+}
+
+Bitmap OutputDeviceTestPolygon::setupAALines()
+{
+ initialSetup(13, 13, constBackgroundColor);
+
+ mpVirtualDevice->SetAntialiasing(AntialiasingFlags::EnableB2dDraw);
+ mpVirtualDevice->SetLineColor(constLineColor);
+ mpVirtualDevice->SetFillColor();
+
+ Point aHorizontalLinePoint1, aHorizontalLinePoint2;
+ Point aVerticalLinePoint1, aVerticalLinePoint2;
+ Point aDiagonalLinePoint1, aDiagonalLinePoint2;
+
+ OutputDeviceTestCommon::createHorizontalVerticalDiagonalLinePoints(
+ maVDRectangle, aHorizontalLinePoint1, aHorizontalLinePoint2,
+ aVerticalLinePoint1, aVerticalLinePoint2,
+ aDiagonalLinePoint1, aDiagonalLinePoint2);
+
+ tools::Polygon aHorizontalPolygon(2);
+ aHorizontalPolygon.SetPoint(aHorizontalLinePoint1, 0);
+ aHorizontalPolygon.SetPoint(aHorizontalLinePoint2, 1);
+ mpVirtualDevice->DrawPolygon(aHorizontalPolygon);
+
+ tools::Polygon aVerticalPolygon(2);
+ aVerticalPolygon.SetPoint(aVerticalLinePoint1, 0);
+ aVerticalPolygon.SetPoint(aVerticalLinePoint2, 1);
+ mpVirtualDevice->DrawPolygon(aVerticalPolygon);
+
+ tools::Polygon aDiagonalPolygon(2);
+ aDiagonalPolygon.SetPoint(aDiagonalLinePoint1, 0);
+ aDiagonalPolygon.SetPoint(aDiagonalLinePoint2, 1);
+ mpVirtualDevice->DrawPolygon(aDiagonalPolygon);
+
+ return mpVirtualDevice->GetBitmap(maVDRectangle.TopLeft(), maVDRectangle.GetSize());
+}
+
+}} // end namespace vcl::test
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/backendtest/outputdevice/polyline.cxx b/vcl/backendtest/outputdevice/polyline.cxx
new file mode 100644
index 000000000000..808d7274965b
--- /dev/null
+++ b/vcl/backendtest/outputdevice/polyline.cxx
@@ -0,0 +1,140 @@
+/* -*- 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 "test/outputdevice.hxx"
+
+namespace vcl {
+namespace test {
+
+namespace
+{
+
+void drawPolyLineOffset(OutputDevice& rDevice, Rectangle& rRect, int nOffset)
+{
+ tools::Polygon aPolygon(4);
+ aPolygon.SetPoint(Point(rRect.Left() + nOffset, rRect.Top() + nOffset), 0);
+ aPolygon.SetPoint(Point(rRect.Right() - nOffset, rRect.Top() + nOffset), 1);
+ aPolygon.SetPoint(Point(rRect.Right() - nOffset, rRect.Bottom() - nOffset), 2);
+ aPolygon.SetPoint(Point(rRect.Left() + nOffset, rRect.Bottom() - nOffset), 3);
+ aPolygon.Optimize(PolyOptimizeFlags::CLOSE);
+
+ rDevice.DrawPolyLine(aPolygon);
+}
+
+} // end anonymous namespace
+
+Bitmap OutputDeviceTestPolyLine::setupRectangle()
+{
+ initialSetup(13, 13, constBackgroundColor);
+
+ mpVirtualDevice->SetLineColor(constLineColor);
+ mpVirtualDevice->SetFillColor();
+
+ drawPolyLineOffset(*mpVirtualDevice, maVDRectangle, 2);
+ drawPolyLineOffset(*mpVirtualDevice, maVDRectangle, 5);
+
+ return mpVirtualDevice->GetBitmap(maVDRectangle.TopLeft(), maVDRectangle.GetSize());
+}
+
+Bitmap OutputDeviceTestPolyLine::setupDiamond()
+{
+ initialSetup(11, 11, constBackgroundColor);
+
+ mpVirtualDevice->SetLineColor(constLineColor);
+ mpVirtualDevice->SetFillColor();
+
+ Point aPoint1, aPoint2, aPoint3, aPoint4;
+ OutputDeviceTestCommon::createDiamondPoints(maVDRectangle, 4, aPoint1, aPoint2, aPoint3, aPoint4);
+
+ tools::Polygon aPolygon(4);
+
+ aPolygon.SetPoint(aPoint1, 0);
+ aPolygon.SetPoint(aPoint2, 1);
+ aPolygon.SetPoint(aPoint3, 2);
+ aPolygon.SetPoint(aPoint4, 3);
+ aPolygon.Optimize(PolyOptimizeFlags::CLOSE);
+
+ mpVirtualDevice->DrawPolyLine(aPolygon);
+
+ return mpVirtualDevice->GetBitmap(maVDRectangle.TopLeft(), maVDRectangle.GetSize());
+}
+
+Bitmap OutputDeviceTestPolyLine::setupLines()
+{
+ initialSetup(13, 13, constBackgroundColor);
+
+ mpVirtualDevice->SetLineColor(constLineColor);
+ mpVirtualDevice->SetFillColor();
+
+ Point aHorizontalLinePoint1, aHorizontalLinePoint2;
+ Point aVerticalLinePoint1, aVerticalLinePoint2;
+ Point aDiagonalLinePoint1, aDiagonalLinePoint2;
+
+ OutputDeviceTestCommon::createHorizontalVerticalDiagonalLinePoints(
+ maVDRectangle, aHorizontalLinePoint1, aHorizontalLinePoint2,
+ aVerticalLinePoint1, aVerticalLinePoint2,
+ aDiagonalLinePoint1, aDiagonalLinePoint2);
+
+ tools::Polygon aHorizontalPolygon(2);
+ aHorizontalPolygon.SetPoint(aHorizontalLinePoint1, 0);
+ aHorizontalPolygon.SetPoint(aHorizontalLinePoint2, 1);
+ mpVirtualDevice->DrawPolyLine(aHorizontalPolygon);
+
+ tools::Polygon aVerticalPolygon(2);
+ aVerticalPolygon.SetPoint(aVerticalLinePoint1, 0);
+ aVerticalPolygon.SetPoint(aVerticalLinePoint2, 1);
+ mpVirtualDevice->DrawPolyLine(aVerticalPolygon);
+
+ tools::Polygon aDiagonalPolygon(2);
+ aDiagonalPolygon.SetPoint(aDiagonalLinePoint1, 0);
+ aDiagonalPolygon.SetPoint(aDiagonalLinePoint2, 1);
+ mpVirtualDevice->DrawPolyLine(aDiagonalPolygon);
+
+ return mpVirtualDevice->GetBitmap(maVDRectangle.TopLeft(), maVDRectangle.GetSize());
+}
+
+Bitmap OutputDeviceTestPolyLine::setupAALines()
+{
+ initialSetup(13, 13, constBackgroundColor);
+
+ mpVirtualDevice->SetAntialiasing(AntialiasingFlags::EnableB2dDraw);
+ mpVirtualDevice->SetLineColor(constLineColor);
+ mpVirtualDevice->SetFillColor();
+
+ Point aHorizontalLinePoint1, aHorizontalLinePoint2;
+ Point aVerticalLinePoint1, aVerticalLinePoint2;
+ Point aDiagonalLinePoint1, aDiagonalLinePoint2;
+
+ OutputDeviceTestCommon::createHorizontalVerticalDiagonalLinePoints(
+ maVDRectangle, aHorizontalLinePoint1, aHorizontalLinePoint2,
+ aVerticalLinePoint1, aVerticalLinePoint2,
+ aDiagonalLinePoint1, aDiagonalLinePoint2);
+
+ tools::Polygon aHorizontalPolygon(2);
+ aHorizontalPolygon.SetPoint(aHorizontalLinePoint1, 0);
+ aHorizontalPolygon.SetPoint(aHorizontalLinePoint2, 1);
+ mpVirtualDevice->DrawPolyLine(aHorizontalPolygon);
+
+ tools::Polygon aVerticalPolygon(2);
+ aVerticalPolygon.SetPoint(aVerticalLinePoint1, 0);
+ aVerticalPolygon.SetPoint(aVerticalLinePoint2, 1);
+ mpVirtualDevice->DrawPolyLine(aVerticalPolygon);
+
+ tools::Polygon aDiagonalPolygon(2);
+ aDiagonalPolygon.SetPoint(aDiagonalLinePoint1, 0);
+ aDiagonalPolygon.SetPoint(aDiagonalLinePoint2, 1);
+ mpVirtualDevice->DrawPolyLine(aDiagonalPolygon);
+
+ return mpVirtualDevice->GetBitmap(maVDRectangle.TopLeft(), maVDRectangle.GetSize());
+}
+
+}} // end namespace vcl::test
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/backendtest/outputdevice/polypolygon.cxx b/vcl/backendtest/outputdevice/polypolygon.cxx
new file mode 100644
index 000000000000..a6d3a018fbfc
--- /dev/null
+++ b/vcl/backendtest/outputdevice/polypolygon.cxx
@@ -0,0 +1,68 @@
+/* -*- 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 "test/outputdevice.hxx"
+
+
+namespace vcl {
+namespace test {
+
+namespace
+{
+
+tools::Polygon createPolygonOffset(Rectangle& rRect, int nOffset)
+{
+ tools::Polygon aPolygon(4);
+ aPolygon.SetPoint(Point(rRect.Left() + nOffset, rRect.Top() + nOffset), 0);
+ aPolygon.SetPoint(Point(rRect.Right() - nOffset, rRect.Top() + nOffset), 1);
+ aPolygon.SetPoint(Point(rRect.Right() - nOffset, rRect.Bottom() - nOffset), 2);
+ aPolygon.SetPoint(Point(rRect.Left() + nOffset, rRect.Bottom() - nOffset), 3);
+ aPolygon.Optimize(PolyOptimizeFlags::CLOSE);
+ return aPolygon;
+}
+
+} // end anonymous namespace
+
+Bitmap OutputDeviceTestPolyPolygon::setupRectangle()
+{
+ initialSetup(13, 13, constBackgroundColor);
+
+ mpVirtualDevice->SetLineColor(constLineColor);
+ mpVirtualDevice->SetFillColor();
+
+ tools::PolyPolygon aPolyPolygon(2);
+ aPolyPolygon.Insert(createPolygonOffset(maVDRectangle, 2));
+ aPolyPolygon.Insert(createPolygonOffset(maVDRectangle, 5));
+
+ mpVirtualDevice->DrawPolyPolygon(aPolyPolygon);
+
+ return mpVirtualDevice->GetBitmap(maVDRectangle.TopLeft(), maVDRectangle.GetSize());
+}
+
+Bitmap OutputDeviceTestPolyPolygon::setupFilledRectangle()
+{
+ initialSetup(13, 13, constBackgroundColor);
+
+ mpVirtualDevice->SetLineColor(constFillColor);
+ mpVirtualDevice->SetFillColor(constFillColor);
+
+ tools::PolyPolygon aPolyPolygon(3);
+ aPolyPolygon.Insert(createPolygonOffset(maVDRectangle, 2));
+ aPolyPolygon.Insert(createPolygonOffset(maVDRectangle, 4));
+ aPolyPolygon.Insert(createPolygonOffset(maVDRectangle, 4));
+
+ mpVirtualDevice->DrawPolyPolygon(aPolyPolygon);
+
+ return mpVirtualDevice->GetBitmap(maVDRectangle.TopLeft(), maVDRectangle.GetSize());
+}
+
+}} // end namespace vcl::test
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/backendtest/outputdevice/rectangle.cxx b/vcl/backendtest/outputdevice/rectangle.cxx
new file mode 100644
index 000000000000..80ab3cf6f7ee
--- /dev/null
+++ b/vcl/backendtest/outputdevice/rectangle.cxx
@@ -0,0 +1,54 @@
+/* -*- 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 "test/outputdevice.hxx"
+
+namespace vcl {
+namespace test {
+
+namespace
+{
+ void drawRectOffset(OutputDevice& rDevice, Rectangle& rRect, int nOffset)
+ {
+ rDevice.DrawRect(Rectangle(rRect.Left() + nOffset, rRect.Top() + nOffset,
+ rRect.Right() - nOffset, rRect.Bottom() - nOffset));
+
+ }
+} // end anonymous namespace
+
+Bitmap OutputDeviceTestRect::setupFilledRectangle()
+{
+ initialSetup(13, 13, constBackgroundColor);
+
+ mpVirtualDevice->SetLineColor(constFillColor);
+ mpVirtualDevice->SetFillColor(constFillColor);
+
+ drawRectOffset(*mpVirtualDevice, maVDRectangle, 2);
+ drawRectOffset(*mpVirtualDevice, maVDRectangle, 5);
+
+ return mpVirtualDevice->GetBitmap(maVDRectangle.TopLeft(), maVDRectangle.GetSize());
+}
+
+Bitmap OutputDeviceTestRect::setupRectangle()
+{
+ initialSetup(13, 13, constBackgroundColor);
+
+ mpVirtualDevice->SetLineColor(constLineColor);
+ mpVirtualDevice->SetFillColor();
+
+ drawRectOffset(*mpVirtualDevice, maVDRectangle, 2);
+ drawRectOffset(*mpVirtualDevice, maVDRectangle, 5);
+
+ return mpVirtualDevice->GetBitmap(maVDRectangle.TopLeft(), maVDRectangle.GetSize());
+}
+
+}} // end namespace vcl::test
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */