cui/uiconfig/ui/graphictestdlg.ui                |    2 
 include/vcl/test/GraphicsRenderTests.hxx         |    2 
 vcl/backendtest/GraphicsRenderTests.cxx          |   44 +++++++++++
 vcl/backendtest/outputdevice/common.cxx          |   48 ++++++++++++
 vcl/backendtest/outputdevice/polypolygon.cxx     |   87 +++++++++++++++++++++++
 vcl/backendtest/outputdevice/polypolygon_b2d.cxx |   77 ++++++++++++++++++++
 vcl/inc/test/outputdevice.hxx                    |    4 +
 vcl/qa/cppunit/BackendTest.cxx                   |   12 +++
 8 files changed, 275 insertions(+), 1 deletion(-)

New commits:
commit dbca6679aa40f65a67264f416d20d1434f6a926d
Author:     homeboy445 <akshitsa...@gmail.com>
AuthorDate: Sat Jul 17 17:46:10 2021 +0530
Commit:     Tomaž Vajngerl <qui...@gmail.com>
CommitDate: Thu Aug 26 07:07:46 2021 +0200

    backendtest: Intersecting Rectangles Drawing test
    
    This test intends to test the even-odd filling rule by
    testing if the intersecting rectangles have been filled
    accordingly to the rule or not.
    
    Change-Id: I0fb7f115a25476cc38e8bec5cd02737aea3c0316
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/119098
    Tested-by: Jenkins
    Reviewed-by: Tomaž Vajngerl <qui...@gmail.com>

diff --git a/cui/uiconfig/ui/graphictestdlg.ui 
b/cui/uiconfig/ui/graphictestdlg.ui
index 2e1252a2bf94..903d092ccf22 100644
--- a/cui/uiconfig/ui/graphictestdlg.ui
+++ b/cui/uiconfig/ui/graphictestdlg.ui
@@ -7,7 +7,7 @@
     <property name="title" translatable="yes" 
context="graphictestdlg|GraphicTestsDialog">Run Graphics Tests</property>
     <property name="resizable">False</property>
     <property name="modal">True</property>
-    <property name="default-width">500</property>
+    <property name="default-width">550</property>
     <property name="default-height">550</property>
     <property name="type-hint">dialog</property>
     <child internal-child="vbox">
diff --git a/include/vcl/test/GraphicsRenderTests.hxx 
b/include/vcl/test/GraphicsRenderTests.hxx
index 8599cb5893fc..dee521438edc 100644
--- a/include/vcl/test/GraphicsRenderTests.hxx
+++ b/include/vcl/test/GraphicsRenderTests.hxx
@@ -118,6 +118,8 @@ class VCL_PLUGIN_PUBLIC GraphicsRenderTests
     void testClosedBezierWithPolygon();
     void testFilledAsymmetricalDropShape();
     void testTextDrawing();
+    void testEvenOddRuleInIntersectingRectsWithPolyPolygon();
+    void testEvenOddRuleInIntersectingRectsWithPolyPolygonB2D();
     static OUString returnTestStatus(vcl::test::TestResult const result);
     void runALLTests();
     void appendTestResult(OUString aTestName, OUString aTestStatus, Bitmap 
aTestBitmap = Bitmap());
diff --git a/vcl/backendtest/GraphicsRenderTests.cxx 
b/vcl/backendtest/GraphicsRenderTests.cxx
index 1b98dead0264..263d37cf6d3f 100644
--- a/vcl/backendtest/GraphicsRenderTests.cxx
+++ b/vcl/backendtest/GraphicsRenderTests.cxx
@@ -1503,6 +1503,48 @@ void GraphicsRenderTests::testTextDrawing()
     }
 }
 
+void GraphicsRenderTests::testEvenOddRuleInIntersectingRectsWithPolyPolygon()
+{
+    vcl::test::OutputDeviceTestPolyPolygon aOutDevTest;
+    Bitmap aBitmap = aOutDevTest.setupIntersectingRectangles();
+    OUString aTestName = "testEvenOddRuleInIntersectingRectsWithPolyPolygon";
+    if (!SHOULD_ASSERT)
+    {
+        appendTestResult(aTestName, "SKIPPED");
+        return;
+    }
+    vcl::test::TestResult eResult
+        = 
vcl::test::OutputDeviceTestLine::checkEvenOddRuleInIntersectingRecs(aBitmap);
+    appendTestResult(aTestName, returnTestStatus(eResult),
+                     (m_aStoreResultantBitmap ? aBitmap : Bitmap()));
+    if (m_aStoreResultantBitmap)
+    {
+        BitmapEx aBitmapEx(aBitmap);
+        exportBitmapExToImage(m_aUserInstallPath + aTestName + ".png", 
aBitmapEx);
+    }
+}
+
+void 
GraphicsRenderTests::testEvenOddRuleInIntersectingRectsWithPolyPolygonB2D()
+{
+    vcl::test::OutputDeviceTestPolyPolygonB2D aOutDevTest;
+    Bitmap aBitmap = aOutDevTest.setupIntersectingRectangles();
+    OUString aTestName = 
"testEvenOddRuleInIntersectingRectsWithPolyPolygonB2D";
+    if (!SHOULD_ASSERT)
+    {
+        appendTestResult(aTestName, "SKIPPED");
+        return;
+    }
+    vcl::test::TestResult eResult
+        = 
vcl::test::OutputDeviceTestLine::checkEvenOddRuleInIntersectingRecs(aBitmap);
+    appendTestResult(aTestName, returnTestStatus(eResult),
+                     (m_aStoreResultantBitmap ? aBitmap : Bitmap()));
+    if (m_aStoreResultantBitmap)
+    {
+        BitmapEx aBitmapEx(aBitmap);
+        exportBitmapExToImage(m_aUserInstallPath + aTestName + ".png", 
aBitmapEx);
+    }
+}
+
 void GraphicsRenderTests::runALLTests()
 {
     testDrawRectWithRectangle();
@@ -1575,6 +1617,8 @@ void GraphicsRenderTests::runALLTests()
     testClosedBezierWithPolygon();
     testFilledAsymmetricalDropShape();
     testTextDrawing();
+    testEvenOddRuleInIntersectingRectsWithPolyPolygon();
+    testEvenOddRuleInIntersectingRectsWithPolyPolygonB2D();
 }
 
 void GraphicsRenderTests::appendTestResult(OUString aTestName, OUString 
aTestStatus,
diff --git a/vcl/backendtest/outputdevice/common.cxx 
b/vcl/backendtest/outputdevice/common.cxx
index b548571e22bb..2aa7de78a294 100644
--- a/vcl/backendtest/outputdevice/common.cxx
+++ b/vcl/backendtest/outputdevice/common.cxx
@@ -968,6 +968,54 @@ TestResult 
OutputDeviceTestCommon::checkTextLocation(Bitmap& rBitmap)
     return aResult;
 }
 
+TestResult OutputDeviceTestCommon::checkIntersectingRecs(Bitmap& rBitmap, int 
aLayerNumber,
+                                                         Color aExpected)
+{
+    BitmapScopedWriteAccess pAccess(rBitmap);
+
+    TestResult aResult = TestResult::Passed;
+    int nNumberOfQuirks = 0;
+    int nNumberOfErrors = 0;
+
+    for (int x = 4; x <= 19; ++x)
+    {
+        checkValue(pAccess, x, aLayerNumber, aExpected, nNumberOfQuirks, 
nNumberOfErrors, true);
+    }
+
+    if (nNumberOfQuirks > 0)
+        aResult = TestResult::PassedWithQuirks;
+    if (nNumberOfErrors > 0)
+        aResult = TestResult::Failed;
+    return aResult;
+}
+
+TestResult OutputDeviceTestCommon::checkEvenOddRuleInIntersectingRecs(Bitmap& 
rBitmap)
+{
+    /*
+    The even-odd rule would be tested via the below pattern as layers both of 
the
+    constFillColor & constBackgroundColor appears in an even-odd fashion.
+     */
+    std::vector<Color> aExpectedColors
+        = { constBackgroundColor, constBackgroundColor, constLineColor,       
constFillColor,
+            constFillColor,       constLineColor,       constBackgroundColor, 
constBackgroundColor,
+            constLineColor,       constFillColor,       constFillColor,       
constLineColor,
+            constBackgroundColor, constBackgroundColor, constLineColor,       
constFillColor,
+            constFillColor,       constLineColor,       constBackgroundColor, 
constBackgroundColor,
+            constLineColor,       constFillColor,       constLineColor };
+
+    TestResult aReturnValue = TestResult::Passed;
+    for (size_t i = 0; i < aExpectedColors.size(); i++)
+    {
+        TestResult eResult = checkIntersectingRecs(rBitmap, i, 
aExpectedColors[i]);
+
+        if (eResult == TestResult::Failed)
+            aReturnValue = TestResult::Failed;
+        if (eResult == TestResult::PassedWithQuirks && aReturnValue != 
TestResult::Failed)
+            aReturnValue = TestResult::PassedWithQuirks;
+    }
+    return aReturnValue;
+}
+
 // Check 'count' pixels from (x,y) in (addX,addY) direction, the color values 
must not decrease.
 static bool checkGradient(BitmapScopedWriteAccess& pAccess, int x, int y, int 
count, int addX, int addY)
 {
diff --git a/vcl/backendtest/outputdevice/polypolygon.cxx 
b/vcl/backendtest/outputdevice/polypolygon.cxx
index 9151bd28ff3f..642e0ce8fc61 100644
--- a/vcl/backendtest/outputdevice/polypolygon.cxx
+++ b/vcl/backendtest/outputdevice/polypolygon.cxx
@@ -65,6 +65,93 @@ Bitmap 
OutputDeviceTestPolyPolygon::setupFilledRectangle(bool useLineColor)
     return mpVirtualDevice->GetBitmap(maVDRectangle.TopLeft(), 
maVDRectangle.GetSize());
 }
 
+Bitmap OutputDeviceTestPolyPolygon::setupIntersectingRectangles()
+{
+    initialSetup(24, 24, constBackgroundColor);
+
+    mpVirtualDevice->SetLineColor(constLineColor);
+    mpVirtualDevice->SetFillColor(constFillColor);
+
+    tools::PolyPolygon aPolyPolygon(4);
+
+    int nOffset = 2, nFix = 1;
+    tools::Polygon aPolygon1(4), aPolygon2(4), aPolygon3(4), aPolygon4(4);
+
+    /*
+        The intersection between different rectangles has been
+        acheived by stacking them on top of each other and decreasing and
+        increasing the top and bottom offset accordingly to the rectangle
+        keeping the left and the right offset intact which in turn coalesced
+        them to each other helping in acheiving multiple intersecting 
rectangles.
+        The desired color fill pattern is then achieved by setting the fill
+        color which in turn would fill the shape with the provided color
+        in accordance to the even-odd filling rule.
+    */
+
+    //Rect - 1
+    aPolygon1.SetPoint(
+        Point(maVDRectangle.Left() + nOffset + nFix, maVDRectangle.Top() + 
(nOffset - 1) + nFix),
+        0);
+    aPolygon1.SetPoint(Point(maVDRectangle.Right() - (nOffset + 2) + nFix,
+                             maVDRectangle.Top() + (nOffset - 1) + nFix),
+                       1);
+    aPolygon1.SetPoint(Point(maVDRectangle.Right() - (nOffset + 2) + nFix,
+                             maVDRectangle.Bottom() - (nOffset + 8) + nFix),
+                       2);
+    aPolygon1.SetPoint(
+        Point(maVDRectangle.Left() + nOffset + nFix, maVDRectangle.Bottom() - 
(nOffset + 8) + nFix),
+        3);
+    aPolyPolygon.Insert(aPolygon1);
+
+    //Rect - 2
+    aPolygon2.SetPoint(
+        Point(maVDRectangle.Left() + nOffset + nFix, maVDRectangle.Top() + 
(nOffset + 2) + nFix),
+        0);
+    aPolygon2.SetPoint(Point(maVDRectangle.Right() - (nOffset + 2) + nFix,
+                             maVDRectangle.Top() + (nOffset + 2) + nFix),
+                       1);
+    aPolygon2.SetPoint(Point(maVDRectangle.Right() - (nOffset + 2) + nFix,
+                             maVDRectangle.Bottom() - (nOffset + 5) + nFix),
+                       2);
+    aPolygon2.SetPoint(
+        Point(maVDRectangle.Left() + nOffset + nFix, maVDRectangle.Bottom() - 
(nOffset + 5) + nFix),
+        3);
+    aPolyPolygon.Insert(aPolygon2);
+
+    //Rect - 3
+    aPolygon3.SetPoint(
+        Point(maVDRectangle.Left() + nOffset + nFix, maVDRectangle.Top() + 
(nOffset + 5) + nFix),
+        0);
+    aPolygon3.SetPoint(Point(maVDRectangle.Right() - (nOffset + 2) + nFix,
+                             maVDRectangle.Top() + (nOffset + 5) + nFix),
+                       1);
+    aPolygon3.SetPoint(Point(maVDRectangle.Right() - (nOffset + 2) + nFix,
+                             maVDRectangle.Bottom() - (nOffset + 2) + nFix),
+                       2);
+    aPolygon3.SetPoint(
+        Point(maVDRectangle.Left() + nOffset + nFix, maVDRectangle.Bottom() - 
(nOffset + 2) + nFix),
+        3);
+    aPolyPolygon.Insert(aPolygon3);
+
+    //Rect - 4
+    aPolygon4.SetPoint(
+        Point(maVDRectangle.Left() + nOffset + nFix, maVDRectangle.Top() + 
(nOffset + 8) + nFix),
+        0);
+    aPolygon4.SetPoint(Point(maVDRectangle.Right() - (nOffset + 2) + nFix,
+                             maVDRectangle.Top() + (nOffset + 8) + nFix),
+                       1);
+    aPolygon4.SetPoint(Point(maVDRectangle.Right() - (nOffset + 2) + nFix,
+                             maVDRectangle.Bottom() - nOffset + nFix),
+                       2);
+    aPolygon4.SetPoint(
+        Point(maVDRectangle.Left() + nOffset + nFix, maVDRectangle.Bottom() - 
nOffset + nFix), 3);
+    aPolyPolygon.Insert(aPolygon4);
+
+    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/polypolygon_b2d.cxx 
b/vcl/backendtest/outputdevice/polypolygon_b2d.cxx
index 737cfae195f2..ef8ee6f0390e 100644
--- a/vcl/backendtest/outputdevice/polypolygon_b2d.cxx
+++ b/vcl/backendtest/outputdevice/polypolygon_b2d.cxx
@@ -65,6 +65,83 @@ Bitmap 
OutputDeviceTestPolyPolygonB2D::setupFilledRectangle(bool useLineColor)
 
     return mpVirtualDevice->GetBitmap(maVDRectangle.TopLeft(), 
maVDRectangle.GetSize());
 }
+
+Bitmap OutputDeviceTestPolyPolygonB2D::setupIntersectingRectangles()
+{
+    initialSetup(24, 24, constBackgroundColor);
+
+    mpVirtualDevice->SetLineColor(constLineColor);
+    mpVirtualDevice->SetFillColor(constFillColor);
+
+    basegfx::B2DPolyPolygon aPolyPolygon;
+
+    int nOffset = 2, nFix = 1;
+    basegfx::B2DPolygon aPolygon1, aPolygon2, aPolygon3, aPolygon4;
+
+    /*
+        The intersection between different rectangles has been
+        acheived by stacking them on top of each other and decreasing and
+        increasing the top and bottom offset accordingly to the rectangle
+        keeping the left and the right offset intact which in turn coalesced
+        them to each other helping in acheiving multiple intersecting 
rectangles.
+        The desired color fill pattern is then achieved by setting the fill
+        color which in turn would fill the shape with the provided color
+        in accordance to the even-odd filling rule.
+    */
+
+    //Rect - 1
+    aPolygon1.append(basegfx::B2DPoint(maVDRectangle.Left() + nOffset + nFix,
+                                       maVDRectangle.Top() + (nOffset - 1) + 
nFix));
+    aPolygon1.append(basegfx::B2DPoint(maVDRectangle.Right() - (nOffset + 2) + 
nFix,
+                                       maVDRectangle.Top() + (nOffset - 1) + 
nFix));
+    aPolygon1.append(basegfx::B2DPoint(maVDRectangle.Right() - (nOffset + 2) + 
nFix,
+                                       maVDRectangle.Bottom() - (nOffset + 8) 
+ nFix));
+    aPolygon1.append(basegfx::B2DPoint(maVDRectangle.Left() + nOffset + nFix,
+                                       maVDRectangle.Bottom() - (nOffset + 8) 
+ nFix));
+    aPolygon1.setClosed(true);
+    aPolyPolygon.append(aPolygon1);
+
+    //Rect - 2
+    aPolygon2.append(basegfx::B2DPoint(maVDRectangle.Left() + nOffset + nFix,
+                                       maVDRectangle.Top() + (nOffset + 2) + 
nFix));
+    aPolygon2.append(basegfx::B2DPoint(maVDRectangle.Right() - (nOffset + 2) + 
nFix,
+                                       maVDRectangle.Top() + (nOffset + 2) + 
nFix));
+    aPolygon2.append(basegfx::B2DPoint(maVDRectangle.Right() - (nOffset + 2) + 
nFix,
+                                       maVDRectangle.Bottom() - (nOffset + 5) 
+ nFix));
+    aPolygon2.append(basegfx::B2DPoint(maVDRectangle.Left() + nOffset + nFix,
+                                       maVDRectangle.Bottom() - (nOffset + 5) 
+ nFix));
+    aPolygon2.setClosed(true);
+    aPolyPolygon.append(aPolygon2);
+
+    //Rect - 3
+    aPolygon3.append(basegfx::B2DPoint(maVDRectangle.Left() + nOffset + nFix,
+                                       maVDRectangle.Top() + (nOffset + 5) + 
nFix));
+    aPolygon3.append(basegfx::B2DPoint(maVDRectangle.Right() - (nOffset + 2) + 
nFix,
+                                       maVDRectangle.Top() + (nOffset + 5) + 
nFix));
+    aPolygon3.append(basegfx::B2DPoint(maVDRectangle.Right() - (nOffset + 2) + 
nFix,
+                                       maVDRectangle.Bottom() - (nOffset + 2) 
+ nFix));
+    aPolygon3.append(basegfx::B2DPoint(maVDRectangle.Left() + nOffset + nFix,
+                                       maVDRectangle.Bottom() - (nOffset + 2) 
+ nFix));
+    aPolygon3.setClosed(true);
+    aPolyPolygon.append(aPolygon3);
+
+    //Rect - 4
+    aPolygon4.append(basegfx::B2DPoint(maVDRectangle.Left() + nOffset + nFix,
+                                       maVDRectangle.Top() + (nOffset + 8) + 
nFix));
+    aPolygon4.append(basegfx::B2DPoint(maVDRectangle.Right() - (nOffset + 2) + 
nFix,
+                                       maVDRectangle.Top() + (nOffset + 8) + 
nFix));
+    aPolygon4.append(basegfx::B2DPoint(maVDRectangle.Right() - (nOffset + 2) + 
nFix,
+                                       maVDRectangle.Bottom() - nOffset + 
nFix));
+    aPolygon4.append(basegfx::B2DPoint(maVDRectangle.Left() + nOffset + nFix,
+                                       maVDRectangle.Bottom() - nOffset + 
nFix));
+    aPolygon4.setClosed(true);
+    aPolyPolygon.append(aPolygon4);
+
+    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/inc/test/outputdevice.hxx b/vcl/inc/test/outputdevice.hxx
index df10da2bbe51..b72206d76cd1 100644
--- a/vcl/inc/test/outputdevice.hxx
+++ b/vcl/inc/test/outputdevice.hxx
@@ -93,6 +93,8 @@ public:
     static TestResult checkClosedBezier(Bitmap& rBitmap);
     static TestResult checkFilledAsymmetricalDropShape(Bitmap& rBitmap);
     static TestResult checkTextLocation(Bitmap& rBitmap);
+    static TestResult checkEvenOddRuleInIntersectingRecs(Bitmap &rBitmap);
+    static TestResult checkIntersectingRecs(Bitmap& rBitmap,int aLayerNumber, 
Color aExpectedColor);
 private:
     static TestResult checkLineCap(Bitmap& rBitmap, css::drawing::LineCap 
lineCap);
     static TestResult checkLineJoin(Bitmap& rBitmap, basegfx::B2DLineJoin 
lineJoin);
@@ -224,6 +226,7 @@ public:
 
     Bitmap setupRectangle(bool bEnableAA);
     Bitmap setupFilledRectangle(bool useLineColor);
+    Bitmap setupIntersectingRectangles();
 };
 
 class VCL_DLLPUBLIC OutputDeviceTestPolyPolygonB2D : public 
OutputDeviceTestCommon
@@ -233,6 +236,7 @@ public:
 
     Bitmap setupRectangle(bool bEnableAA);
     Bitmap setupFilledRectangle(bool useLineColor);
+    Bitmap setupIntersectingRectangles();
 };
 
 class VCL_DLLPUBLIC OutputDeviceTestGradient : public OutputDeviceTestCommon
diff --git a/vcl/qa/cppunit/BackendTest.cxx b/vcl/qa/cppunit/BackendTest.cxx
index 0146d1dabd50..7bef9b2479d7 100644
--- a/vcl/qa/cppunit/BackendTest.cxx
+++ b/vcl/qa/cppunit/BackendTest.cxx
@@ -1121,6 +1121,17 @@ public:
             CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed);
     }
 
+    void testEvenOddRuleInIntersectionRectangles()
+    {
+        vcl::test::OutputDeviceTestPolyPolygon aOutDevTest;
+        Bitmap aBitmap = aOutDevTest.setupIntersectingRectangles();
+        auto eResult
+            = 
vcl::test::OutputDeviceTestCommon::checkEvenOddRuleInIntersectingRecs(aBitmap);
+        exportImage("18-01_test_Even-Odd-rule_intersecting_Recs.png", aBitmap);
+        if (SHOULD_ASSERT)
+            CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed);
+    }
+
     void testTdf124848()
     {
 // TODO: This unit test is not executed for macOS unless bitmap scaling is 
implemented
@@ -1281,6 +1292,7 @@ public:
     CPPUNIT_TEST(testDrawAlphaBitmapMirrored);
 
     CPPUNIT_TEST(testDrawingText);
+    CPPUNIT_TEST(testEvenOddRuleInIntersectionRectangles);
 
     CPPUNIT_TEST(testTdf124848);
     CPPUNIT_TEST(testTdf136171);

Reply via email to