summaryrefslogtreecommitdiff
path: root/vcl/backendtest
diff options
context:
space:
mode:
authorLuboš Luňák <l.lunak@collabora.com>2021-04-21 20:16:29 +0200
committerLuboš Luňák <l.lunak@collabora.com>2021-04-24 17:31:52 +0200
commit38ed3b8064e76c0a6de077cb535cdb573737b26a (patch)
treecc5a93003206b3dae6d04c49af1e41e35ed1d401 /vcl/backendtest
parent3926984e85700cabedf215633e18809e6d926cb6 (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.cxx72
-rw-r--r--vcl/backendtest/outputdevice/common.cxx94
-rw-r--r--vcl/backendtest/outputdevice/line.cxx51
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: */