diff options
author | Luboš Luňák <l.lunak@collabora.com> | 2021-04-21 20:16:29 +0200 |
---|---|---|
committer | Luboš Luňák <l.lunak@collabora.com> | 2021-04-24 17:31:52 +0200 |
commit | 38ed3b8064e76c0a6de077cb535cdb573737b26a (patch) | |
tree | cc5a93003206b3dae6d04c49af1e41e35ed1d401 /vcl/backendtest | |
parent | 3926984e85700cabedf215633e18809e6d926cb6 (diff) |
backend tests for linecap and linejoin types
Change-Id: Id481feb25ce938b4382f970f2e1082a3594c9eca
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/114560
Tested-by: Jenkins
Reviewed-by: Luboš Luňák <l.lunak@collabora.com>
Diffstat (limited to 'vcl/backendtest')
-rw-r--r-- | vcl/backendtest/VisualBackendTest.cxx | 72 | ||||
-rw-r--r-- | vcl/backendtest/outputdevice/common.cxx | 94 | ||||
-rw-r--r-- | vcl/backendtest/outputdevice/line.cxx | 51 |
3 files changed, 212 insertions, 5 deletions
diff --git a/vcl/backendtest/VisualBackendTest.cxx b/vcl/backendtest/VisualBackendTest.cxx index 441588aa611c..55ec308fb226 100644 --- a/vcl/backendtest/VisualBackendTest.cxx +++ b/vcl/backendtest/VisualBackendTest.cxx @@ -91,7 +91,7 @@ class VisualBackendTestWindow : public WorkWindow private: Timer maUpdateTimer; std::vector<std::chrono::high_resolution_clock::time_point> mTimePoints; - static constexpr unsigned char gnNumberOfTests = 11; + static constexpr unsigned char gnNumberOfTests = 12; unsigned char mnTest; bool mbAnimate; ScopedVclPtr<VirtualDevice> mpVDev; @@ -409,6 +409,64 @@ public: } } + static void testLineTypes(vcl::RenderContext& rRenderContext, int nWidth, int nHeight) + { + tools::Rectangle aRectangle; + size_t index = 0; + + std::vector<tools::Rectangle> aRegions = setupRegions(4, 2, nWidth, nHeight); + + aRectangle = aRegions[index++]; + { + vcl::test::OutputDeviceTestLine aOutDevTest; + Bitmap aBitmap = aOutDevTest.setupLineJoinBevel(); + assertAndSetBackground(vcl::test::OutputDeviceTestLine::checkLineJoinBevel(aBitmap), aRectangle, rRenderContext); + drawBitmapScaledAndCentered(aRectangle, aBitmap, rRenderContext); + } + aRectangle = aRegions[index++]; + { + vcl::test::OutputDeviceTestLine aOutDevTest; + Bitmap aBitmap = aOutDevTest.setupLineJoinRound(); + assertAndSetBackground(vcl::test::OutputDeviceTestLine::checkLineJoinRound(aBitmap), aRectangle, rRenderContext); + drawBitmapScaledAndCentered(aRectangle, aBitmap, rRenderContext); + } + aRectangle = aRegions[index++]; + { + vcl::test::OutputDeviceTestLine aOutDevTest; + Bitmap aBitmap = aOutDevTest.setupLineJoinMiter(); + assertAndSetBackground(vcl::test::OutputDeviceTestLine::checkLineJoinMiter(aBitmap), aRectangle, rRenderContext); + drawBitmapScaledAndCentered(aRectangle, aBitmap, rRenderContext); + } + aRectangle = aRegions[index++]; + { + vcl::test::OutputDeviceTestLine aOutDevTest; + Bitmap aBitmap = aOutDevTest.setupLineJoinNone(); + assertAndSetBackground(vcl::test::OutputDeviceTestLine::checkLineJoinNone(aBitmap), aRectangle, rRenderContext); + drawBitmapScaledAndCentered(aRectangle, aBitmap, rRenderContext); + } + aRectangle = aRegions[index++]; + { + vcl::test::OutputDeviceTestLine aOutDevTest; + Bitmap aBitmap = aOutDevTest.setupLineCapRound(); + assertAndSetBackground(vcl::test::OutputDeviceTestLine::checkLineCapRound(aBitmap), aRectangle, rRenderContext); + drawBitmapScaledAndCentered(aRectangle, aBitmap, rRenderContext); + } + aRectangle = aRegions[index++]; + { + vcl::test::OutputDeviceTestLine aOutDevTest; + Bitmap aBitmap = aOutDevTest.setupLineCapSquare(); + assertAndSetBackground(vcl::test::OutputDeviceTestCommon::checkLineCapSquare(aBitmap), aRectangle, rRenderContext); + drawBitmapScaledAndCentered(aRectangle, aBitmap, rRenderContext); + } + aRectangle = aRegions[index++]; + { + vcl::test::OutputDeviceTestLine aOutDevTest; + Bitmap aBitmap = aOutDevTest.setupLineCapButt(); + assertAndSetBackground(vcl::test::OutputDeviceTestCommon::checkLineCapButt(aBitmap), aRectangle, rRenderContext); + drawBitmapScaledAndCentered(aRectangle, aBitmap, rRenderContext); + } + } + static void testBitmaps(vcl::RenderContext& rRenderContext, int nWidth, int nHeight) { tools::Rectangle aRectangle; @@ -685,22 +743,26 @@ public: } else if (mnTest % gnNumberOfTests == 5) { - testBitmaps(rRenderContext, nWidth, nHeight); + testLineTypes(rRenderContext, nWidth, nHeight); } else if (mnTest % gnNumberOfTests == 6) { - testInvert(rRenderContext, nWidth, nHeight); + testBitmaps(rRenderContext, nWidth, nHeight); } else if (mnTest % gnNumberOfTests == 7) { - testClip(rRenderContext, nWidth, nHeight); + testInvert(rRenderContext, nWidth, nHeight); } else if (mnTest % gnNumberOfTests == 8) { - testGradients(rRenderContext, nWidth, nHeight); + testClip(rRenderContext, nWidth, nHeight); } else if (mnTest % gnNumberOfTests == 9) { + testGradients(rRenderContext, nWidth, nHeight); + } + else if (mnTest % gnNumberOfTests == 10) + { std::vector<tools::Rectangle> aRegions = setupRegions(2, 1, nWidth, nHeight); size_t index = 0; diff --git a/vcl/backendtest/outputdevice/common.cxx b/vcl/backendtest/outputdevice/common.cxx index 2ccd1085ec02..40d20ea3568d 100644 --- a/vcl/backendtest/outputdevice/common.cxx +++ b/vcl/backendtest/outputdevice/common.cxx @@ -53,6 +53,12 @@ void checkValue(BitmapScopedWriteAccess& pAccess, int x, int y, Color aExpected, } } +void checkValue(BitmapScopedWriteAccess& pAccess, const Point& point, Color aExpected, + int& nNumberOfQuirks, int& nNumberOfErrors, bool bQuirkMode, int nColorDeltaThresh = 0) +{ + checkValue(pAccess, point.getX(), point.getY(), aExpected, nNumberOfQuirks, nNumberOfErrors, bQuirkMode, nColorDeltaThresh); +} + void checkValue(BitmapScopedWriteAccess& pAccess, int x, int y, Color aExpected, int& nNumberOfQuirks, int& nNumberOfErrors, int nColorDeltaThresh, int nColorDeltaThreshQuirk = 0) { @@ -715,6 +721,94 @@ TestResult OutputDeviceTestCommon::checkRadialGradientOfs(Bitmap& bitmap) return aResult; } +constexpr int CAPSHRINK = 25; +constexpr int CAPWIDTH = 20; +TestResult OutputDeviceTestCommon::checkLineCap(Bitmap& rBitmap, css::drawing::LineCap lineCap) +{ + BitmapScopedWriteAccess access(rBitmap); + tools::Rectangle rectangle( Point( 0, 0 ), Size( 101, 101 )); + rectangle.shrink(CAPSHRINK); + rectangle = tools::Rectangle( Point(rectangle.LeftCenter().getX(), rectangle.LeftCenter().getY() - CAPWIDTH / 2), + Point(rectangle.RightCenter().getX(), rectangle.RightCenter().getY() + CAPWIDTH / 2)); + rectangle.shrink(1); + TestResult aResult = TestResult::Passed; + int nNumberOfQuirks = 0; + int nNumberOfErrors = 0; + + // the line itself + checkValue(access, rectangle.TopLeft(), constLineColor, nNumberOfQuirks, nNumberOfErrors, false); + checkValue(access, rectangle.TopRight(), constLineColor, nNumberOfQuirks, nNumberOfErrors, false); + checkValue(access, rectangle.BottomLeft(), constLineColor, nNumberOfQuirks, nNumberOfErrors, false); + checkValue(access, rectangle.BottomRight(), constLineColor, nNumberOfQuirks, nNumberOfErrors, false); + + // the cap in the middle + Color color = ( lineCap == css::drawing::LineCap_BUTT ) ? constBackgroundColor : constLineColor; + checkValue(access, rectangle.LeftCenter() - Point(CAPWIDTH/2, 0), color, nNumberOfQuirks, nNumberOfErrors, false); + checkValue(access, rectangle.RightCenter() + Point(CAPWIDTH/2, 0), color, nNumberOfQuirks, nNumberOfErrors, false); + + // the cap corners + color = ( lineCap == css::drawing::LineCap_SQUARE ) ? constLineColor : constBackgroundColor; + checkValue(access, rectangle.TopLeft() - Point(CAPWIDTH/2, 0), color, nNumberOfQuirks, nNumberOfErrors, false); + checkValue(access, rectangle.TopRight() + Point(CAPWIDTH/2, 0), color, nNumberOfQuirks, nNumberOfErrors, false); + checkValue(access, rectangle.BottomLeft() - Point(CAPWIDTH/2, 0), color, nNumberOfQuirks, nNumberOfErrors, false); + checkValue(access, rectangle.BottomRight() + Point(CAPWIDTH/2, 0), color, nNumberOfQuirks, nNumberOfErrors, false); + + if (nNumberOfQuirks > 0) + checkResult(TestResult::PassedWithQuirks, aResult); + if (nNumberOfErrors > 0) + checkResult(TestResult::Failed, aResult); + return aResult; +} + +TestResult OutputDeviceTestCommon::checkLineJoin(Bitmap& rBitmap, basegfx::B2DLineJoin lineJoin) +{ + BitmapScopedWriteAccess access(rBitmap); + tools::Rectangle rectangle( Point( 0, 0 ), Size( 101, 101 )); + rectangle.shrink(CAPSHRINK); + tools::Rectangle rectangle1( Point(rectangle.TopLeft().getX(), rectangle.TopLeft().getY() - CAPWIDTH / 2), + Point(rectangle.TopRight().getX(), rectangle.TopRight().getY() + CAPWIDTH / 2)); + tools::Rectangle rectangle2( Point(rectangle.TopRight().getX() - CAPWIDTH / 2, rectangle.TopRight().getY()), + Point(rectangle.BottomRight().getX() + CAPWIDTH / 2, rectangle.BottomRight().getY())); + rectangle1.shrink(1); + rectangle2.shrink(1); + TestResult aResult = TestResult::Passed; + int nNumberOfQuirks = 0; + int nNumberOfErrors = 0; + + // the lines themselves + checkValue(access, rectangle1.TopLeft(), constLineColor, nNumberOfQuirks, nNumberOfErrors, false); + checkValue(access, rectangle1.TopRight(), constLineColor, nNumberOfQuirks, nNumberOfErrors, false); + checkValue(access, rectangle1.BottomLeft(), constLineColor, nNumberOfQuirks, nNumberOfErrors, false); + checkValue(access, rectangle1.BottomRight(), constLineColor, nNumberOfQuirks, nNumberOfErrors, false); + checkValue(access, rectangle2.TopLeft(), constLineColor, nNumberOfQuirks, nNumberOfErrors, false); + checkValue(access, rectangle2.TopRight(), constLineColor, nNumberOfQuirks, nNumberOfErrors, false); + checkValue(access, rectangle2.BottomLeft(), constLineColor, nNumberOfQuirks, nNumberOfErrors, false); + checkValue(access, rectangle2.BottomRight(), constLineColor, nNumberOfQuirks, nNumberOfErrors, false); + + // Only miter has the corner point. + Color color = ( lineJoin == basegfx::B2DLineJoin::Miter ) ? constLineColor : constBackgroundColor; + checkValue(access, rectangle2.Right(), rectangle1.Top(), color, nNumberOfQuirks, nNumberOfErrors, false); + + // Round reaches a bit past the diagonal. + Point midDiagonal = (Point( rectangle2.Right(), rectangle1.Top()) + rectangle.TopRight()) / 2; + if( lineJoin == basegfx::B2DLineJoin::Round) + color = constLineColor; + checkValue(access, midDiagonal + Point( 2, -2 ), color, nNumberOfQuirks, nNumberOfErrors, false); + // Bevel is the diagonal. + if( lineJoin == basegfx::B2DLineJoin::Bevel) + color = constLineColor; + checkValue(access, midDiagonal + Point( -1, 1 ), color, nNumberOfQuirks, nNumberOfErrors, false); + // Everything except None has at least some line join. + checkValue(access, rectangle.TopRight() + Point( 1, -1 ), color, nNumberOfQuirks, nNumberOfErrors, false); + + if (nNumberOfQuirks > 0) + checkResult(TestResult::PassedWithQuirks, aResult); + if (nNumberOfErrors > 0) + checkResult(TestResult::Failed, aResult); + return aResult; +} + + } // 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 index 73505c0ef43d..48526bde6fca 100644 --- a/vcl/backendtest/outputdevice/line.cxx +++ b/vcl/backendtest/outputdevice/line.cxx @@ -195,6 +195,57 @@ TestResult OutputDeviceTestLine::checkDashedLine(Bitmap& rBitmap) return returnValue; } +constexpr int CAPSHRINK = 25; +constexpr int CAPWIDTH = 20; +Bitmap OutputDeviceTestLine::setupLineCap( css::drawing::LineCap lineCap ) +{ + initialSetup(101, 101, constBackgroundColor); + + mpVirtualDevice->SetLineColor(constLineColor); + mpVirtualDevice->SetFillColor(); + + tools::Rectangle rectangle = maVDRectangle; + rectangle.shrink(CAPSHRINK); + + const basegfx::B2DPolygon poly{ + basegfx::B2DPoint(rectangle.LeftCenter().getX(), rectangle.LeftCenter().getY()), + basegfx::B2DPoint(rectangle.RightCenter().getX(), rectangle.RightCenter().getY())}; + + mpVirtualDevice->DrawPolyLineDirect( basegfx::B2DHomMatrix(),poly, + CAPWIDTH, 0, nullptr, basegfx::B2DLineJoin::NONE, lineCap ); + + mpVirtualDevice->SetLineColor(constFillColor); + mpVirtualDevice->DrawPolyLineDirect( basegfx::B2DHomMatrix(), poly, + 0, 0, nullptr, basegfx::B2DLineJoin::NONE ); + + return mpVirtualDevice->GetBitmap(maVDRectangle.TopLeft(), maVDRectangle.GetSize()); +} + +Bitmap OutputDeviceTestLine::setupLineJoin( basegfx::B2DLineJoin lineJoin ) +{ + initialSetup(101, 101, constBackgroundColor); + + mpVirtualDevice->SetLineColor(constLineColor); + mpVirtualDevice->SetFillColor(); + + tools::Rectangle rectangle = maVDRectangle; + rectangle.shrink(CAPSHRINK); + + const basegfx::B2DPolygon poly{ + basegfx::B2DPoint(rectangle.TopLeft().getX(), rectangle.TopLeft().getY()), + basegfx::B2DPoint(rectangle.TopRight().getX(), rectangle.TopRight().getY()), + basegfx::B2DPoint(rectangle.BottomRight().getX(), rectangle.BottomRight().getY())}; + + mpVirtualDevice->DrawPolyLineDirect( basegfx::B2DHomMatrix(), poly, + CAPWIDTH, 0, nullptr, lineJoin ); + + mpVirtualDevice->SetLineColor(constFillColor); + mpVirtualDevice->DrawPolyLineDirect( basegfx::B2DHomMatrix(), poly, + 0, 0, nullptr, lineJoin ); + + return mpVirtualDevice->GetBitmap(maVDRectangle.TopLeft(), maVDRectangle.GetSize()); +} + } // end namespace vcl::test /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |