From 3e6052ce1b9a24f82358e574de32919fa2b6499f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=C5=BE=20Vajngerl?= Date: Mon, 22 Aug 2016 18:10:02 +0900 Subject: [PATCH] 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 --- Repository.mk | 1 + include/tools/gen.hxx | 8 + vcl/Executable_visualbackendtest.mk | 58 ++ vcl/Library_vcl.mk | 10 + vcl/Module_vcl.mk | 1 + vcl/backendtest/VisualBackendTest.cxx | 582 ++++++++++++++++++ vcl/backendtest/outputdevice/bitmap.cxx | 154 +++++ vcl/backendtest/outputdevice/common.cxx | 328 ++++++++++ vcl/backendtest/outputdevice/gradient.cxx | 43 ++ vcl/backendtest/outputdevice/line.cxx | 114 ++++ vcl/backendtest/outputdevice/outputdevice.cxx | 75 +++ vcl/backendtest/outputdevice/pixel.cxx | 57 ++ vcl/backendtest/outputdevice/polygon.cxx | 151 +++++ vcl/backendtest/outputdevice/polyline.cxx | 140 +++++ vcl/backendtest/outputdevice/polypolygon.cxx | 68 ++ vcl/backendtest/outputdevice/rectangle.cxx | 54 ++ vcl/inc/test/outputdevice.hxx | 172 ++++++ 17 files changed, 2016 insertions(+) create mode 100644 vcl/Executable_visualbackendtest.mk create mode 100644 vcl/backendtest/VisualBackendTest.cxx create mode 100644 vcl/backendtest/outputdevice/bitmap.cxx create mode 100644 vcl/backendtest/outputdevice/common.cxx create mode 100644 vcl/backendtest/outputdevice/gradient.cxx create mode 100644 vcl/backendtest/outputdevice/line.cxx create mode 100644 vcl/backendtest/outputdevice/outputdevice.cxx create mode 100644 vcl/backendtest/outputdevice/pixel.cxx create mode 100644 vcl/backendtest/outputdevice/polygon.cxx create mode 100644 vcl/backendtest/outputdevice/polyline.cxx create mode 100644 vcl/backendtest/outputdevice/polypolygon.cxx create mode 100644 vcl/backendtest/outputdevice/rectangle.cxx create mode 100644 vcl/inc/test/outputdevice.hxx diff --git a/Repository.mk b/Repository.mk index 157fdd4031b4..03573fb27e32 100644 --- a/Repository.mk +++ b/Repository.mk @@ -74,6 +74,7 @@ $(eval $(call gb_Helper_register_executables,NONE, \ vcldemo \ tiledrendering \ mtfdemo \ + visualbackendtest \ $(if $(and $(ENABLE_GTK3), $(filter LINUX %BSD SOLARIS,$(OS))), gtktiledviewer) \ )) diff --git a/include/tools/gen.hxx b/include/tools/gen.hxx index cf8383f0ccbb..987dd4398bc3 100644 --- a/include/tools/gen.hxx +++ b/include/tools/gen.hxx @@ -379,6 +379,7 @@ public: * Expands the rectangle in all directions by the input value. */ inline void expand(long nExpandBy); + inline void shrink(long nShrinkBy); private: long nLeft; @@ -620,6 +621,13 @@ inline void Rectangle::expand(long nExpandBy) nBottom += nExpandBy; } +inline void Rectangle::shrink(long nShrinkBy) +{ + nLeft += nShrinkBy; + nTop += nShrinkBy; + nRight -= nShrinkBy; + nBottom -= nShrinkBy; +} template< typename charT, typename traits > inline std::basic_ostream & operator <<( diff --git a/vcl/Executable_visualbackendtest.mk b/vcl/Executable_visualbackendtest.mk new file mode 100644 index 000000000000..abf8cbe1429b --- /dev/null +++ b/vcl/Executable_visualbackendtest.mk @@ -0,0 +1,58 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- +# +# +# 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/. +# + +$(eval $(call gb_Executable_Executable,visualbackendtest)) + +$(eval $(call gb_Executable_use_api,visualbackendtest,\ + offapi \ + udkapi \ +)) + +$(eval $(call gb_Executable_use_external,visualbackendtest,boost_headers)) + +$(eval $(call gb_Executable_set_include,visualbackendtest,\ + $$(INCLUDE) \ + -I$(SRCDIR)/vcl/inc \ +)) + +$(eval $(call gb_Executable_use_libraries,visualbackendtest,\ + basegfx \ + comphelper \ + cppu \ + cppuhelper \ + tl \ + sal \ + salhelper \ + vcl \ +)) + +$(eval $(call gb_Executable_add_exception_objects,visualbackendtest,\ + vcl/backendtest/VisualBackendTest \ +)) + +$(eval $(call gb_Executable_use_static_libraries,visualbackendtest,\ + vclmain \ +)) + +ifeq ($(OS),LINUX) +$(eval $(call gb_Executable_add_libs,visualbackendtest,\ + -lm \ + -ldl \ + -lpthread \ + -lGL \ + -lX11 \ +)) + +$(eval $(call gb_Executable_use_static_libraries,visualbackendtest,\ + glxtest \ +)) +endif + +# vim: set noet sw=4 ts=4: diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk index b79087d85517..19a6f5285932 100644 --- a/vcl/Library_vcl.mk +++ b/vcl/Library_vcl.mk @@ -399,6 +399,16 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\ vcl/source/uitest/uitest \ vcl/source/uitest/uno/uiobject_uno \ vcl/source/uitest/uno/uitest_uno \ + vcl/backendtest/outputdevice/bitmap \ + vcl/backendtest/outputdevice/common \ + vcl/backendtest/outputdevice/gradient \ + vcl/backendtest/outputdevice/line \ + vcl/backendtest/outputdevice/outputdevice \ + vcl/backendtest/outputdevice/pixel \ + vcl/backendtest/outputdevice/polygon \ + vcl/backendtest/outputdevice/polypolygon \ + vcl/backendtest/outputdevice/polyline \ + vcl/backendtest/outputdevice/rectangle \ )) $(eval $(call gb_Library_add_cobjects,vcl,\ diff --git a/vcl/Module_vcl.mk b/vcl/Module_vcl.mk index ad08e5988a7b..19f9f7667cf7 100644 --- a/vcl/Module_vcl.mk +++ b/vcl/Module_vcl.mk @@ -35,6 +35,7 @@ $(eval $(call gb_Module_add_targets,vcl,\ $(if $(ENABLE_HEADLESS),, \ Executable_vcldemo \ Executable_icontest \ + Executable_visualbackendtest \ Executable_mtfdemo ))) \ $(if $(filter-out ANDROID IOS WNT,$(OS)), \ Executable_svdemo \ 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 +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include +#include + +#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 mTimePoints; + unsigned char mnNumberOfTests; + unsigned char mnTest; + bool mbAnimate; + ScopedVclPtr mpVDev; + +public: + VisualBackendTestWindow() + : WorkWindow(NULL, WB_APP | WB_STDWORK) + , mnNumberOfTests(6) + , mnTest(10 * mnNumberOfTests) + , mbAnimate(mnTest % mnNumberOfTests == mnNumberOfTests - 1) + , mpVDev(VclPtr::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 setupRegions(int nPartitionsX, int nPartitionsY, int nWidth, int nHeight) + { + std::vector 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 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 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 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 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(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 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 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 xMSF; + + void Init() override + { + try + { + uno::Reference xComponentContext = ::cppu::defaultBootstrap_InitialComponentContext(); + xMSF = uno::Reference(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 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 + +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 aExpected + { + constBackgroundColor, constBackgroundColor, + COL_YELLOW, constFillColor, COL_YELLOW, constFillColor, constFillColor + }; + return checkRectangles(rBitmap, aExpected); +} + +TestResult OutputDeviceTestBitmap::checkTransformedBitmap(Bitmap& rBitmap) +{ + std::vector 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 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::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 aExpected + { + constBackgroundColor, constBackgroundColor, constLineColor, + constBackgroundColor, constBackgroundColor, constLineColor, constBackgroundColor + }; + return checkRectangles(aBitmap, aExpected); +} + +TestResult OutputDeviceTestCommon::checkFilledRectangle(Bitmap& aBitmap) +{ + std::vector aExpected + { + constBackgroundColor, constBackgroundColor, + constFillColor, constFillColor, constFillColor, constFillColor, constFillColor + }; + return checkRectangles(aBitmap, aExpected); +} + +TestResult OutputDeviceTestCommon::checkRectangles(Bitmap& aBitmap, std::vector& 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 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 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: */ diff --git a/vcl/inc/test/outputdevice.hxx b/vcl/inc/test/outputdevice.hxx new file mode 100644 index 000000000000..cc90b000b10d --- /dev/null +++ b/vcl/inc/test/outputdevice.hxx @@ -0,0 +1,172 @@ +/* -*- 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/. + * + */ + +#ifndef INCLUDED_VCL_OUTDEVTESTS_HXX +#define INCLUDED_VCL_OUTDEVTESTS_HXX + +#include +#include + +namespace vcl { +namespace test { + +/** Rendering test result. + * + * Test either "Passed", "Failed" or "PassedWithQuirks" which means + * the test passed but at least one rendering quirk was detected. + */ +enum class TestResult +{ + Failed, + PassedWithQuirks, + Passed +}; + +/** Common subclass for output device rendering tests. + */ +class VCL_DLLPUBLIC OutputDeviceTestCommon +{ +protected: + + ScopedVclPtr mpVirtualDevice; + Rectangle maVDRectangle; + + static const Color constBackgroundColor; + static const Color constLineColor; + static const Color constFillColor; + +public: + OutputDeviceTestCommon(); + + void initialSetup(long nWidth, long nHeight, Color aColor); + + static TestResult checkRectangle(Bitmap& rBitmap); + static TestResult checkFilledRectangle(Bitmap& rBitmap); + static TestResult checkLines(Bitmap& rBitmap); + static TestResult checkAALines(Bitmap& rBitmap); + static TestResult checkDiamond(Bitmap& rBitmap); + + static TestResult checkRectangles(Bitmap& rBitmap, std::vector& aExpectedColors); + + static void createDiamondPoints(Rectangle rRect, int nOffset, + Point& rPoint1, Point& rPoint2, + Point& rPoint3, Point& rPoint4); + + static void createHorizontalVerticalDiagonalLinePoints(Rectangle rRect, + Point& rHorizontalLinePoint1, Point& rHorizontalLinePoint2, + Point& rVerticalLinePoint1, Point& rVerticalLinePoint2, + Point& rDiagonalLinePoint1, Point& rDiagonalLinePoint2); + // tools + static Rectangle alignToCenter(Rectangle aRect1, Rectangle aRect2); + +}; + +class VCL_DLLPUBLIC OutputDeviceTestBitmap : public OutputDeviceTestCommon +{ +public: + OutputDeviceTestBitmap() = default; + + Bitmap setupDrawTransformedBitmap(); + Bitmap setupDrawBitmap(); + Bitmap setupDrawBitmapExWithAlpha(); + Bitmap setupDrawMask(); + + static TestResult checkBitmap(Bitmap& rBitmap); + static TestResult checkTransformedBitmap(Bitmap& rBitmap); + static TestResult checkBitmapExWithAlpha(Bitmap& rBitmap); + static TestResult checkMask(Bitmap& rBitmap); +}; + +class VCL_DLLPUBLIC OutputDeviceTestAnotherOutDev : public OutputDeviceTestCommon +{ +public: + OutputDeviceTestAnotherOutDev() = default; + + Bitmap setupDrawOutDev(); + Bitmap setupXOR(); + + static TestResult checkDrawOutDev(Bitmap& rBitmap); + static TestResult checkXOR(Bitmap& rBitmap); +}; + +class VCL_DLLPUBLIC OutputDeviceTestPixel : public OutputDeviceTestCommon +{ +public: + OutputDeviceTestPixel() = default; + + Bitmap setupRectangle(); +}; + +class VCL_DLLPUBLIC OutputDeviceTestLine : public OutputDeviceTestCommon +{ +public: + OutputDeviceTestLine() = default; + + Bitmap setupRectangle(); + Bitmap setupDiamond(); + Bitmap setupLines(); + Bitmap setupAALines(); +}; + +class VCL_DLLPUBLIC OutputDeviceTestPolyLine : public OutputDeviceTestCommon +{ +public: + OutputDeviceTestPolyLine() = default; + + Bitmap setupRectangle(); + Bitmap setupDiamond(); + Bitmap setupLines(); + Bitmap setupAALines(); +}; + +class VCL_DLLPUBLIC OutputDeviceTestRect : public OutputDeviceTestCommon +{ +public: + OutputDeviceTestRect() = default; + + Bitmap setupFilledRectangle(); + Bitmap setupRectangle(); +}; + +class VCL_DLLPUBLIC OutputDeviceTestPolygon : public OutputDeviceTestCommon +{ +public: + OutputDeviceTestPolygon() = default; + + Bitmap setupFilledRectangle(); + Bitmap setupRectangle(); + Bitmap setupDiamond(); + Bitmap setupLines(); + Bitmap setupAALines(); +}; + +class VCL_DLLPUBLIC OutputDeviceTestPolyPolygon : public OutputDeviceTestCommon +{ +public: + OutputDeviceTestPolyPolygon() = default; + + Bitmap setupFilledRectangle(); + Bitmap setupRectangle(); +}; + +class VCL_DLLPUBLIC OutputDeviceTestGradient : public OutputDeviceTestCommon +{ +public: + OutputDeviceTestGradient() = default; + + Bitmap setupLinearGradient(); + Bitmap setupRadialGradient(); +}; + +}} // end namespace vcl::test + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */