[Libreoffice-commits] core.git: basegfx/source basegfx/test drawinglayer/source include/basegfx

Miklos Vajna (via logerrit) logerrit at kemper.freedesktop.org
Thu May 9 08:48:06 UTC 2019


 basegfx/source/polygon/b2dpolypolygontools.cxx          |   18 ++++++++++++++
 basegfx/test/B2DPolygonTest.cxx                         |   20 ++++++++++++++++
 drawinglayer/source/processor2d/vclpixelprocessor2d.cxx |   10 ++++++++
 drawinglayer/source/processor2d/vclprocessor2d.cxx      |   10 ++++++++
 include/basegfx/polygon/b2dpolygontools.hxx             |    3 ++
 5 files changed, 61 insertions(+)

New commits:
commit f8b4d371eddd27594d549fb00294c01229a9bd24
Author:     Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Thu May 9 09:18:00 2019 +0200
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Thu May 9 10:46:55 2019 +0200

    drawinglayer: avoid AA for hairline polygons built from hori/vert lines only
    
    For one, it seems this was the intention already since commit
    85c70f37b56299f6fa02312c0fb73cc55af084ef (CWS-TOOLING: integrate CWS
    aw063, 2009-03-04): "suppress AntiAliasing for pure horizontal or
    vertical lines".
    
    For another, this fixes the TileCacheTests::testTileWireIDHandling()
    testcase in online.git, which assumes that the indicators at the corners
    of the Writer body frame (paragraph marks hidden / default case) can be
    painted multiple times, producing pixel-by-pixel matching results. But
    in reality AA breaks that assumption, and we know these indicators are
    never diagonal lines.
    
    Change-Id: Ib74f823165799991296b64cee58ec106dbdcedcf
    Reviewed-on: https://gerrit.libreoffice.org/72000
    Reviewed-by: Miklos Vajna <vmiklos at collabora.com>
    Tested-by: Jenkins

diff --git a/basegfx/source/polygon/b2dpolypolygontools.cxx b/basegfx/source/polygon/b2dpolypolygontools.cxx
index 062e37da9dae..d537531a4600 100644
--- a/basegfx/source/polygon/b2dpolypolygontools.cxx
+++ b/basegfx/source/polygon/b2dpolypolygontools.cxx
@@ -416,6 +416,24 @@ namespace basegfx
             return aRetval;
         }
 
+        bool containsOnlyHorizontalOrVerticalLines(const basegfx::B2DPolygon& rPolygon)
+        {
+            if (rPolygon.count() <= 1)
+                return false;
+
+            for (size_t i = 1; i < rPolygon.count(); ++i)
+            {
+                const basegfx::B2DPoint& rPrevPoint = rPolygon.getB2DPoint(i - 1);
+                const basegfx::B2DPoint& rPoint = rPolygon.getB2DPoint(i);
+                if (rPrevPoint.getX() == rPoint.getX() || rPrevPoint.getY() == rPoint.getY())
+                    continue;
+
+                return false;
+            }
+
+            return true;
+        }
+
         B2DPolyPolygon createSevenSegmentPolyPolygon(sal_Char nNumber, bool bLitSegments)
         {
             // config here
diff --git a/basegfx/test/B2DPolygonTest.cxx b/basegfx/test/B2DPolygonTest.cxx
index 9f0d1ef98dcc..316a916f931f 100644
--- a/basegfx/test/B2DPolygonTest.cxx
+++ b/basegfx/test/B2DPolygonTest.cxx
@@ -22,6 +22,7 @@
 #include <cppunit/extensions/HelperMacros.h>
 
 #include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
 #include <basegfx/point/b2dpoint.hxx>
 
 namespace basegfx
@@ -77,12 +78,31 @@ public:
         CPPUNIT_ASSERT_EQUAL_MESSAGE("#2 second polygon point wrong", B2DPoint(3, 3),
                                      aPoly.getB2DPoint(1));
     }
+
+    void testContainsOnlyHorizontalOrVerticalLines()
+    {
+        // First line is horziontal, second is vertical.
+        B2DPolygon aPoly;
+        aPoly.append(B2DPoint(0, 1));
+        aPoly.append(B2DPoint(1, 1));
+        aPoly.append(B2DPoint(1, 0));
+        CPPUNIT_ASSERT(utils::containsOnlyHorizontalOrVerticalLines(aPoly));
+
+        // First line is diagonal, second is vertical.
+        aPoly.clear();
+        aPoly.append(B2DPoint(0, 0));
+        aPoly.append(B2DPoint(1, 1));
+        aPoly.append(B2DPoint(1, 0));
+        CPPUNIT_ASSERT(!utils::containsOnlyHorizontalOrVerticalLines(aPoly));
+    }
+
     // Change the following lines only, if you add, remove or rename
     // member functions of the current class,
     // because these macros are need by auto register mechanism.
 
     CPPUNIT_TEST_SUITE(b2dpolygon);
     CPPUNIT_TEST(testBasics);
+    CPPUNIT_TEST(testContainsOnlyHorizontalOrVerticalLines);
     CPPUNIT_TEST_SUITE_END();
 }; // class b2dpolygon
 
diff --git a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
index 03012fb5d35a..db65dc3de4bb 100644
--- a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
@@ -140,6 +140,16 @@ namespace drawinglayer
             mpOutputDevice->SetLineColor(Color(aLineColor));
             //aLocalPolygon.transform(maCurrentTransformation);
 
+            if (getOptionsDrawinglayer().IsAntiAliasing() && getOptionsDrawinglayer().IsSnapHorVerLinesToDiscrete())
+            {
+                if (basegfx::utils::containsOnlyHorizontalOrVerticalLines(rLocalPolygon))
+                {
+                    // DrawPolyLineDirect() only works in AA mode, but pure horizontal or vertical
+                    // lines are better with AA off.
+                    return false;
+                }
+            }
+
             // try drawing; if it did not work, use standard fallback
             return mpOutputDevice->DrawPolyLineDirect(
                 maCurrentTransformation,
diff --git a/drawinglayer/source/processor2d/vclprocessor2d.cxx b/drawinglayer/source/processor2d/vclprocessor2d.cxx
index 361f7a5bd5a3..335e30a56ce9 100644
--- a/drawinglayer/source/processor2d/vclprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclprocessor2d.cxx
@@ -331,6 +331,7 @@ namespace drawinglayer
             basegfx::B2DPolygon aLocalPolygon(rPolygonCandidate.getB2DPolygon());
             aLocalPolygon.transform(maCurrentTransformation);
 
+            bool bDisableAA = false;
             if(bPixelBased && getOptionsDrawinglayer().IsAntiAliasing() && getOptionsDrawinglayer().IsSnapHorVerLinesToDiscrete())
             {
                 // #i98289#
@@ -339,9 +340,18 @@ namespace drawinglayer
                 // not-AntiAliased such lines look more pleasing to the eye (e.g. 2D chart content). This
                 // NEEDS to be done in discrete coordinates, so only useful for pixel based rendering.
                 aLocalPolygon = basegfx::utils::snapPointsOfHorizontalOrVerticalEdges(aLocalPolygon);
+
+                // Also disable AA, snap would leave the start/end of lines still anti-aliased when
+                // their coordinates are provided in logic units.
+                bDisableAA = basegfx::utils::containsOnlyHorizontalOrVerticalLines(aLocalPolygon);
             }
 
+            const AntialiasingFlags nOriginalAA(mpOutputDevice->GetAntialiasing());
+            if (bDisableAA && (nOriginalAA & AntialiasingFlags::EnableB2dDraw))
+                mpOutputDevice->SetAntialiasing(nOriginalAA & ~AntialiasingFlags::EnableB2dDraw);
             mpOutputDevice->DrawPolyLine(aLocalPolygon, 0.0);
+            if (bDisableAA && (nOriginalAA & AntialiasingFlags::EnableB2dDraw))
+                mpOutputDevice->SetAntialiasing(mpOutputDevice->GetAntialiasing() | AntialiasingFlags::EnableB2dDraw);
         }
 
         // direct draw of transformed BitmapEx primitive
diff --git a/include/basegfx/polygon/b2dpolygontools.hxx b/include/basegfx/polygon/b2dpolygontools.hxx
index 57b9130b4399..fbd73220ec29 100644
--- a/include/basegfx/polygon/b2dpolygontools.hxx
+++ b/include/basegfx/polygon/b2dpolygontools.hxx
@@ -445,6 +445,9 @@ namespace basegfx
         */
         BASEGFX_DLLPUBLIC B2DPolygon snapPointsOfHorizontalOrVerticalEdges(const B2DPolygon& rCandidate);
 
+        /// Determines if rPolygon lacks diagonal lines or not.
+        BASEGFX_DLLPUBLIC bool containsOnlyHorizontalOrVerticalLines(const basegfx::B2DPolygon& rPolygon);
+
         /// get the tangent with which the given point is entered seen from the previous
         /// polygon path data. Take into account all stuff like closed state, zero-length edges and others.
         BASEGFX_DLLPUBLIC B2DVector getTangentEnteringPoint(const B2DPolygon& rCandidate, sal_uInt32 nIndex);


More information about the Libreoffice-commits mailing list