include/vcl/test/GraphicsRenderTests.hxx | 4 vcl/backendtest/GraphicsRenderTests.cxx | 86 ++++++++++++++++++ vcl/backendtest/outputdevice/common.cxx | 138 ++++++++++++++++++++++++++++++ vcl/backendtest/outputdevice/polygon.cxx | 24 +++++ vcl/backendtest/outputdevice/polyline.cxx | 27 +++++ vcl/inc/test/outputdevice.hxx | 7 + vcl/qa/cppunit/BackendTest.cxx | 46 ++++++++++ 7 files changed, 332 insertions(+)
New commits: commit 3c2cf76892890051e27e0e0798b7a06fc3acccd8 Author: homeboy445 <[email protected]> AuthorDate: Thu Jul 1 17:47:48 2021 +0530 Commit: Tomaž Vajngerl <[email protected]> CommitDate: Sat Aug 7 01:10:51 2021 +0200 backendtest: drop like shape test for polygon / polyline Add a test for drawing a drop like shape using polygon and polyline drawing code-paths. Change-Id: Ifee7b978009d66af01ccbfc92b36d1423084ed48 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/118278 Tested-by: Tomaž Vajngerl <[email protected]> Reviewed-by: Tomaž Vajngerl <[email protected]> diff --git a/include/vcl/test/GraphicsRenderTests.hxx b/include/vcl/test/GraphicsRenderTests.hxx index dd39cc16d815..b8307b97ab25 100644 --- a/include/vcl/test/GraphicsRenderTests.hxx +++ b/include/vcl/test/GraphicsRenderTests.hxx @@ -75,8 +75,12 @@ class VCL_PLUGIN_PUBLIC GraphicsRenderTests void testDrawInvertWithRectangle(); void testDrawInvertN50WithRectangle(); void testDrawInvertTrackFrameWithRectangle(); + void testDrawDropShapeWithPolyline(); + void testDrawDropShapeAAWithPolyline(); void testDrawBezierWithPolylineB2D(); void testDrawBezierAAWithPolylineB2D(); + void testDrawDropShapeWithPolygon(); + void testDrawDropShapeAAWithPolygon(); void testDrawBitmap(); void testDrawTransformedBitmap(); void testDrawBitmapExWithAlpha(); diff --git a/vcl/backendtest/GraphicsRenderTests.cxx b/vcl/backendtest/GraphicsRenderTests.cxx index cd19d4255902..eae05149840b 100644 --- a/vcl/backendtest/GraphicsRenderTests.cxx +++ b/vcl/backendtest/GraphicsRenderTests.cxx @@ -636,6 +636,47 @@ void GraphicsRenderTests::testDrawInvertTrackFrameWithRectangle() } } +void GraphicsRenderTests::testDrawDropShapeWithPolyline() +{ + vcl::test::OutputDeviceTestPolyLine aOutDevTest; + Bitmap aBitmap = aOutDevTest.setupDropShape(); + OUString atestName = "testDrawDropShapeWithPolyline"; + if (!SHOULD_ASSERT) + { + appendTestResult(atestName, "SKIPPED"); + return; + } + vcl::test::TestResult eResult = vcl::test::OutputDeviceTestCommon::checkDropShape(aBitmap); + appendTestResult(atestName, returnTestStatus(eResult), + (m_aStoreResultantBitmap ? aBitmap : Bitmap())); + if (m_aStoreResultantBitmap) + { + BitmapEx aBitmapEx(aBitmap); + exportBitmapExToImage(m_aUserInstallPath + atestName + ".png", aBitmapEx); + } +} + +void GraphicsRenderTests::testDrawDropShapeAAWithPolyline() +{ + vcl::test::OutputDeviceTestPolyLine aOutDevTest; + Bitmap aBitmap = aOutDevTest.setupAADropShape(); + OUString atestName = "testDrawDropShapeAAWithPolyline"; + if (!SHOULD_ASSERT) + { + appendTestResult(atestName, "SKIPPED"); + return; + } + vcl::test::TestResult eResult + = vcl::test::OutputDeviceTestCommon::checkDropShape(aBitmap, true); + appendTestResult(atestName, returnTestStatus(eResult), + (m_aStoreResultantBitmap ? aBitmap : Bitmap())); + if (m_aStoreResultantBitmap) + { + BitmapEx aBitmapEx(aBitmap); + exportBitmapExToImage(m_aUserInstallPath + atestName + ".png", aBitmapEx); + } +} + void GraphicsRenderTests::testDrawBezierWithPolylineB2D() { vcl::test::OutputDeviceTestPolyLineB2D aOutDevTest; @@ -676,6 +717,47 @@ void GraphicsRenderTests::testDrawBezierAAWithPolylineB2D() } } +void GraphicsRenderTests::testDrawDropShapeWithPolygon() +{ + vcl::test::OutputDeviceTestPolygon aOutDevTest; + Bitmap aBitmap = aOutDevTest.setupDropShape(); + OUString atestName = "testDrawDropShapeWithPolygon"; + if (!SHOULD_ASSERT) + { + appendTestResult(atestName, "SKIPPED"); + return; + } + vcl::test::TestResult eResult = vcl::test::OutputDeviceTestCommon::checkDropShape(aBitmap); + appendTestResult(atestName, returnTestStatus(eResult), + (m_aStoreResultantBitmap ? aBitmap : Bitmap())); + if (m_aStoreResultantBitmap) + { + BitmapEx aBitmapEx(aBitmap); + exportBitmapExToImage(m_aUserInstallPath + atestName + ".png", aBitmapEx); + } +} + +void GraphicsRenderTests::testDrawDropShapeAAWithPolygon() +{ + vcl::test::OutputDeviceTestPolygon aOutDevTest; + Bitmap aBitmap = aOutDevTest.setupAADropShape(); + OUString atestName = "testDrawDropShapeAAWithPolygon"; + if (!SHOULD_ASSERT) + { + appendTestResult(atestName, "SKIPPED"); + return; + } + vcl::test::TestResult eResult + = vcl::test::OutputDeviceTestCommon::checkDropShape(aBitmap, true); + appendTestResult(atestName, returnTestStatus(eResult), + (m_aStoreResultantBitmap ? aBitmap : Bitmap())); + if (m_aStoreResultantBitmap) + { + BitmapEx aBitmapEx(aBitmap); + exportBitmapExToImage(m_aUserInstallPath + atestName + ".png", aBitmapEx); + } +} + void GraphicsRenderTests::testDrawBitmap() { vcl::test::OutputDeviceTestBitmap aOutDevTest; @@ -1280,6 +1362,10 @@ void GraphicsRenderTests::runALLTests() testLineCapRound(); testLineCapSquare(); testLineCapButt(); + testDrawDropShapeWithPolyline(); + testDrawDropShapeAAWithPolyline(); + testDrawDropShapeWithPolygon(); + testDrawDropShapeAAWithPolygon(); } void GraphicsRenderTests::appendTestResult(OUString aTestName, OUString aTestStatus, diff --git a/vcl/backendtest/outputdevice/common.cxx b/vcl/backendtest/outputdevice/common.cxx index 40d20ea3568d..1675d5947d56 100644 --- a/vcl/backendtest/outputdevice/common.cxx +++ b/vcl/backendtest/outputdevice/common.cxx @@ -86,6 +86,50 @@ void checkValue(BitmapScopedWriteAccess& pAccess, int x, int y, Color aExpected, } } +char returnDominantColor(Color aColor) +{ + int aRed = aColor.GetRed(); + int aGreen = aColor.GetGreen(); + int aBlue = aColor.GetBlue(); + if (aRed > aGreen && aRed > aBlue) + return 'R'; + + if (aGreen > aRed && aGreen > aBlue) + return 'G'; + + if(aBlue > aRed && aBlue > aGreen) + return 'B'; + + return 'X'; //No Dominant Color. +} + +void checkValueAA(BitmapScopedWriteAccess& pAccess, int x, int y, Color aExpected, + int& nNumberOfQuirks, int& nNumberOfErrors, int nColorDeltaThresh = 64) +{ + const bool bColorize = false; + Color aColor = pAccess->GetPixel(y, x); + bool aColorResult = returnDominantColor(aExpected) == returnDominantColor(aColor); + int nColorDelta = deltaColor(aColor, aExpected); + + if (nColorDelta <= nColorDeltaThresh && aColorResult) + { + if (bColorize) + pAccess->SetPixel(y, x, COL_LIGHTGREEN); + } + else if (aColorResult) + { + nNumberOfQuirks++; + if (bColorize) + pAccess->SetPixel(y, x, COL_YELLOW); + } + else + { + nNumberOfErrors++; + if (bColorize) + pAccess->SetPixel(y, x, COL_LIGHTRED); + } +} + // Return all colors in the rectangle and their count. std::map<Color, int> collectColors(Bitmap& bitmap, const tools::Rectangle& rectangle) { @@ -492,6 +536,100 @@ void OutputDeviceTestCommon::createDiamondPoints(tools::Rectangle rRect, int nOf rPoint4 = Point(midPointX - nOffset, midPointY ); } +tools::Polygon OutputDeviceTestCommon::createDropShapePolygon() +{ + tools::Polygon aPolygon(15); + + aPolygon.SetPoint(Point(10, 2), 0); + aPolygon.SetFlags(0, PolyFlags::Normal); + aPolygon.SetPoint(Point(14, 2), 1); + aPolygon.SetFlags(1, PolyFlags::Control); + aPolygon.SetPoint(Point(18, 6), 2); + aPolygon.SetFlags(2, PolyFlags::Control); + aPolygon.SetPoint(Point(18, 10), 3); + + aPolygon.SetFlags(3, PolyFlags::Normal); + aPolygon.SetPoint(Point(18, 10), 4); + aPolygon.SetFlags(4, PolyFlags::Normal); + aPolygon.SetPoint(Point(18, 14), 5); + aPolygon.SetFlags(5, PolyFlags::Control); + aPolygon.SetPoint(Point(14, 18), 6); + aPolygon.SetFlags(6, PolyFlags::Control); + aPolygon.SetPoint(Point(10, 18), 7); + aPolygon.SetFlags(7, PolyFlags::Normal); + + aPolygon.SetPoint(Point(10, 18), 8); + aPolygon.SetFlags(8, PolyFlags::Normal); + aPolygon.SetPoint(Point(6, 18), 9); + aPolygon.SetFlags(9, PolyFlags::Control); + aPolygon.SetPoint(Point(2, 14), 10); + aPolygon.SetFlags(10, PolyFlags::Control); + aPolygon.SetPoint(Point(2, 10), 11); + aPolygon.SetFlags(11, PolyFlags::Normal); + + aPolygon.SetPoint(Point(2, 10), 12); + aPolygon.SetFlags(12, PolyFlags::Normal); + aPolygon.SetPoint(Point(2, 2), 13); + aPolygon.SetFlags(13, PolyFlags::Normal); + aPolygon.SetPoint(Point(10, 2), 14); + aPolygon.SetFlags(14, PolyFlags::Normal); + + aPolygon.Optimize(PolyOptimizeFlags::CLOSE); + + return aPolygon; +} + +TestResult OutputDeviceTestCommon::checkDropShape(Bitmap& rBitmap, bool aEnableAA) +{ + BitmapScopedWriteAccess pAccess(rBitmap); + + TestResult aResult = TestResult::Passed; + int nNumberOfQuirks = 0; + int nNumberOfErrors = 0; + + std::map<std::pair<int, int>, bool> SetPixels + = { { { 2, 2 }, true }, { { 3, 2 }, true }, { { 4, 2 }, true }, { { 5, 2 }, true }, + { { 6, 2 }, true }, { { 7, 2 }, true }, { { 8, 2 }, true }, { { 9, 2 }, true }, + { { 10, 2 }, true }, { { 11, 2 }, true }, { { 12, 2 }, true }, { { 2, 3 }, true }, + { { 13, 3 }, true }, { { 14, 3 }, true }, { { 2, 4 }, true }, { { 15, 4 }, true }, + { { 2, 5 }, true }, { { 16, 5 }, true }, { { 2, 6 }, true }, { { 17, 6 }, true }, + { { 2, 7 }, true }, { { 17, 7 }, true }, { { 2, 8 }, true }, { { 18, 8 }, true }, + { { 2, 9 }, true }, { { 18, 9 }, true }, { { 2, 10 }, true }, { { 18, 10 }, true }, + { { 2, 11 }, true }, { { 18, 11 }, true }, { { 2, 12 }, true }, { { 18, 12 }, true }, + { { 3, 13 }, true }, { { 17, 13 }, true }, { { 3, 14 }, true }, { { 17, 14 }, true }, + { { 4, 15 }, true }, { { 16, 15 }, true }, { { 5, 16 }, true }, { { 15, 16 }, true }, + { { 6, 17 }, true }, { { 7, 17 }, true }, { { 13, 17 }, true }, { { 14, 17 }, true }, + { { 8, 18 }, true }, { { 9, 18 }, true }, { { 10, 18 }, true }, { { 11, 18 }, true }, + { { 12, 18 }, true } }; + + for (tools::Long x = 0; x < pAccess->Width(); x++) + { + for (tools::Long y = 0; y < pAccess->Height(); y++) + { + if (SetPixels[{ x, y }]) + { + if (aEnableAA) + checkValueAA(pAccess, y, x, constLineColor, nNumberOfQuirks, nNumberOfErrors); + else + checkValue(pAccess, y, x, constLineColor, nNumberOfQuirks, nNumberOfErrors, + true); + } + else + { + if (!aEnableAA) + checkValue(pAccess, y, x, constBackgroundColor, nNumberOfQuirks, nNumberOfErrors, + true); + } + } + } + + if (nNumberOfQuirks > 0) + aResult = TestResult::PassedWithQuirks; + if (nNumberOfErrors > 0) + aResult = TestResult::Failed; + return aResult; +} + void OutputDeviceTestCommon::createHorizontalVerticalDiagonalLinePoints(tools::Rectangle rRect, Point& rHorizontalLinePoint1, Point& rHorizontalLinePoint2, Point& rVerticalLinePoint1, Point& rVerticalLinePoint2, diff --git a/vcl/backendtest/outputdevice/polygon.cxx b/vcl/backendtest/outputdevice/polygon.cxx index e5eb16e0c220..b3a918f29ff7 100644 --- a/vcl/backendtest/outputdevice/polygon.cxx +++ b/vcl/backendtest/outputdevice/polygon.cxx @@ -152,6 +152,30 @@ Bitmap OutputDeviceTestPolygon::setupAALines() return mpVirtualDevice->GetBitmap(maVDRectangle.TopLeft(), maVDRectangle.GetSize()); } +Bitmap OutputDeviceTestPolygon::setupDropShape() +{ + initialSetup(21, 21, constBackgroundColor); + + mpVirtualDevice->SetLineColor(constLineColor); + mpVirtualDevice->SetFillColor(); + + mpVirtualDevice->DrawPolygon(OutputDeviceTestCommon::createDropShapePolygon()); + + return mpVirtualDevice->GetBitmap(maVDRectangle.TopLeft(), maVDRectangle.GetSize()); +} + +Bitmap OutputDeviceTestPolygon::setupAADropShape() +{ + initialSetup(21, 21, constBackgroundColor,true); + + mpVirtualDevice->SetLineColor(constLineColor); + mpVirtualDevice->SetFillColor(); + + mpVirtualDevice->DrawPolygon(OutputDeviceTestCommon::createDropShapePolygon()); + + 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 index 438cccf09810..db82d4f0a9d1 100644 --- a/vcl/backendtest/outputdevice/polyline.cxx +++ b/vcl/backendtest/outputdevice/polyline.cxx @@ -10,6 +10,9 @@ #include <test/outputdevice.hxx> +#include <cmath> +#include <vector> + namespace vcl::test { namespace @@ -134,6 +137,30 @@ Bitmap OutputDeviceTestPolyLine::setupAALines() return mpVirtualDevice->GetBitmap(maVDRectangle.TopLeft(), maVDRectangle.GetSize()); } +Bitmap OutputDeviceTestPolyLine::setupDropShape() +{ + initialSetup(21, 21, constBackgroundColor); + + mpVirtualDevice->SetLineColor(constLineColor); + mpVirtualDevice->SetFillColor(); + + mpVirtualDevice->DrawPolyLine(OutputDeviceTestCommon::createDropShapePolygon()); + + return mpVirtualDevice->GetBitmap(maVDRectangle.TopLeft(), maVDRectangle.GetSize()); +} + +Bitmap OutputDeviceTestPolyLine::setupAADropShape() +{ + initialSetup(21, 21, constBackgroundColor,true); + + mpVirtualDevice->SetLineColor(constLineColor); + mpVirtualDevice->SetFillColor(); + + mpVirtualDevice->DrawPolyLine(OutputDeviceTestCommon::createDropShapePolygon()); + + 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 index a13183d8112e..d3dec05c5ebf 100644 --- a/vcl/inc/test/outputdevice.hxx +++ b/vcl/inc/test/outputdevice.hxx @@ -67,6 +67,8 @@ public: Point& rPoint1, Point& rPoint2, Point& rPoint3, Point& rPoint4); + static tools::Polygon createDropShapePolygon(); + static void createHorizontalVerticalDiagonalLinePoints(tools::Rectangle rRect, Point& rHorizontalLinePoint1, Point& rHorizontalLinePoint2, Point& rVerticalLinePoint1, Point& rVerticalLinePoint2, @@ -84,6 +86,7 @@ public: static TestResult checkLineJoinRound(Bitmap& rBitmap) { return checkLineJoin(rBitmap, basegfx::B2DLineJoin::Round); } static TestResult checkLineJoinMiter(Bitmap& rBitmap) { return checkLineJoin(rBitmap, basegfx::B2DLineJoin::Miter); } static TestResult checkLineJoinNone(Bitmap& rBitmap) { return checkLineJoin(rBitmap, basegfx::B2DLineJoin::NONE); } + static TestResult checkDropShape(Bitmap& rBitmap, bool aEnableAA = false); private: static TestResult checkLineCap(Bitmap& rBitmap, css::drawing::LineCap lineCap); static TestResult checkLineJoin(Bitmap& rBitmap, basegfx::B2DLineJoin lineJoin); @@ -161,6 +164,8 @@ public: Bitmap setupDiamond(); Bitmap setupLines(); Bitmap setupAALines(); + Bitmap setupDropShape(); + Bitmap setupAADropShape(); }; class VCL_DLLPUBLIC OutputDeviceTestPolyLineB2D : public OutputDeviceTestCommon @@ -196,6 +201,8 @@ public: Bitmap setupDiamond(); Bitmap setupLines(); Bitmap setupAALines(); + Bitmap setupDropShape(); + Bitmap setupAADropShape(); }; class VCL_DLLPUBLIC OutputDeviceTestPolyPolygon : public OutputDeviceTestCommon diff --git a/vcl/qa/cppunit/BackendTest.cxx b/vcl/qa/cppunit/BackendTest.cxx index e9aeaad8f588..4f6dde7ad6a4 100644 --- a/vcl/qa/cppunit/BackendTest.cxx +++ b/vcl/qa/cppunit/BackendTest.cxx @@ -862,6 +862,46 @@ public: CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed); } + void testDrawDropShapeWithPolyline() + { + vcl::test::OutputDeviceTestPolyLine aOutDevTest; + Bitmap aBitmap = aOutDevTest.setupDropShape(); + auto eResult = vcl::test::OutputDeviceTestCommon::checkDropShape(aBitmap); + exportImage("15-01_drop_shape_test-polyline.png", aBitmap); + if (SHOULD_ASSERT) + CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed); + } + + void testDrawDropShapeAAWithPolyline() + { + vcl::test::OutputDeviceTestPolyLine aOutDevTest; + Bitmap aBitmap = aOutDevTest.setupAADropShape(); + auto eResult = vcl::test::OutputDeviceTestCommon::checkDropShape(aBitmap, true); + exportImage("15-02_drop_shape_AA_test-polyline.png", aBitmap); + if (SHOULD_ASSERT) + CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed); + } + + void testDrawDropShapeWithPolygon() + { + vcl::test::OutputDeviceTestPolygon aOutDevTest; + Bitmap aBitmap = aOutDevTest.setupDropShape(); + auto eResult = vcl::test::OutputDeviceTestCommon::checkDropShape(aBitmap); + exportImage("16-01_drop_shape_test-polygon.png", aBitmap); + if (SHOULD_ASSERT) + CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed); + } + + void testDrawDropShapeAAWithPolygon() + { + vcl::test::OutputDeviceTestPolygon aOutDevTest; + Bitmap aBitmap = aOutDevTest.setupAADropShape(); + auto eResult = vcl::test::OutputDeviceTestCommon::checkDropShape(aBitmap, true); + exportImage("16-02_drop_shape_AA_test-polygon.png", aBitmap); + if (SHOULD_ASSERT) + CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed); + } + // Test SalGraphics::blendBitmap() and blendAlphaBitmap() calls. void testDrawBlendExtended() { @@ -1081,6 +1121,12 @@ public: CPPUNIT_TEST(testDrawBezierWithPolylineB2D); CPPUNIT_TEST(testDrawBezierAAWithPolylineB2D); + CPPUNIT_TEST(testDrawDropShapeWithPolyline); + CPPUNIT_TEST(testDrawDropShapeAAWithPolyline); + + CPPUNIT_TEST(testDrawDropShapeWithPolygon); + CPPUNIT_TEST(testDrawDropShapeAAWithPolygon); + CPPUNIT_TEST(testDrawBitmap); CPPUNIT_TEST(testDrawTransformedBitmap); CPPUNIT_TEST(testDrawBitmapExWithAlpha);
