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

Armin Le Grand alg at apache.org
Thu Aug 7 12:35:20 PDT 2014


 basegfx/source/polygon/b2dpolygonclipper.cxx               |   73 +++++++++++++
 drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx |   65 +----------
 2 files changed, 84 insertions(+), 54 deletions(-)

New commits:
commit 5554be7f4cddcfeb450bfe41d0b588c8e8f6de76
Author: Armin Le Grand <alg at apache.org>
Date:   Wed Aug 6 10:42:28 2014 +0000

    Related: #i125349# refined to exclude possible recursive calls
    
    (cherry picked from commit a02eb39b84d130e5923f72edb2abb3b21adf6fff)
    
    Change-Id: Id068928f77a6efed44da9b83ecbf547302826591

diff --git a/basegfx/source/polygon/b2dpolygonclipper.cxx b/basegfx/source/polygon/b2dpolygonclipper.cxx
index e73c388..c9f1587 100644
--- a/basegfx/source/polygon/b2dpolygonclipper.cxx
+++ b/basegfx/source/polygon/b2dpolygonclipper.cxx
@@ -341,71 +341,6 @@ namespace basegfx
 
             if(rCandidate.count() && rClip.count())
             {
-                // #125349# detect if both given PolyPolygons are indeed ranges
-                bool bBothRectangle(false);
-
-                if(basegfx::tools::isRectangle(rCandidate))
-                {
-                    if(basegfx::tools::isRectangle(rClip))
-                    {
-                        // both are ranges
-                        bBothRectangle = true;
-                    }
-                    else
-                    {
-                        // rCandidate is rectangle -> clip rClip on rRectangle, use the much
-                        // cheaper and numerically more stable clipping against a range
-                        // This simplification (exchanging content and clip) is valid
-                        // since we do a logical AND operation
-                        return clipPolyPolygonOnRange(rClip, rCandidate.getB2DRange(), bInside, bStroke);
-                    }
-                }
-                else if(basegfx::tools::isRectangle(rClip))
-                {
-                    if(basegfx::tools::isRectangle(rCandidate))
-                    {
-                        // both are ranges
-                        bBothRectangle = true;
-                    }
-                    else
-                    {
-                        // rClip is rectangle -> clip rCandidate on rRectangle, use the much
-                        // cheaper and numerically more stable clipping against a range
-                        return clipPolyPolygonOnRange(rCandidate, rClip.getB2DRange(), bInside, bStroke);
-                    }
-                }
-
-                if(bBothRectangle)
-                {
-                    // both are rectangle
-                    if(rCandidate.getB2DRange().equal(rClip.getB2DRange()))
-                    {
-                        // if both are equal -> no change
-                        return rCandidate;
-                    }
-                    else
-                    {
-                        // not equal -> create new intersection from both ranges,
-                        // but much cheaper based on the ranges
-                        basegfx::B2DRange aIntersectionRange(rCandidate.getB2DRange());
-
-                        aIntersectionRange.intersect(rClip.getB2DRange());
-
-                        if(aIntersectionRange.isEmpty())
-                        {
-                            // no common IntersectionRange -> the clip will be empty
-                            return B2DPolyPolygon();
-                        }
-                        else
-                        {
-                            // use common aIntersectionRange as result, convert
-                            // to expected PolyPolygon form
-                            return basegfx::B2DPolyPolygon(
-                                basegfx::tools::createPolygonFromRect(aIntersectionRange));
-                        }
-                    }
-                }
-
                 // one or both are no rectangle - go the hard way and clip PolyPolygon
                 // against PolyPolygon...
                 if(bStroke)
@@ -476,6 +411,77 @@ namespace basegfx
                 }
                 else
                 {
+                    // check for simplification with ranges if !bStroke (handling as stroke is more simple),
+                    // but also only when bInside, else the simplification may lead to recursive calls (see
+                    // calls to clipPolyPolygonOnPolyPolygon in clipPolyPolygonOnRange and clipPolygonOnRange)
+                    if(bInside)
+                    {
+                        // #i125349# detect if both given PolyPolygons are indeed ranges
+                        bool bBothRectangle(false);
+
+                        if(basegfx::tools::isRectangle(rCandidate))
+                        {
+                            if(basegfx::tools::isRectangle(rClip))
+                            {
+                                // both are ranges
+                                bBothRectangle = true;
+                            }
+                            else
+                            {
+                                // rCandidate is rectangle -> clip rClip on rRectangle, use the much
+                                // cheaper and numerically more stable clipping against a range
+                                // This simplification (exchanging content and clip) is valid
+                                // since we do a logical AND operation
+                                return clipPolyPolygonOnRange(rClip, rCandidate.getB2DRange(), bInside, bStroke);
+                            }
+                        }
+                        else if(basegfx::tools::isRectangle(rClip))
+                        {
+                            if(basegfx::tools::isRectangle(rCandidate))
+                            {
+                                // both are ranges
+                                bBothRectangle = true;
+                            }
+                            else
+                            {
+                                // rClip is rectangle -> clip rCandidate on rRectangle, use the much
+                                // cheaper and numerically more stable clipping against a range
+                                return clipPolyPolygonOnRange(rCandidate, rClip.getB2DRange(), bInside, bStroke);
+                            }
+                        }
+
+                        if(bBothRectangle)
+                        {
+                            // both are rectangle
+                            if(rCandidate.getB2DRange().equal(rClip.getB2DRange()))
+                            {
+                                // if both are equal -> no change
+                                return rCandidate;
+                            }
+                            else
+                            {
+                                // not equal -> create new intersection from both ranges,
+                                // but much cheaper based on the ranges
+                                basegfx::B2DRange aIntersectionRange(rCandidate.getB2DRange());
+
+                                aIntersectionRange.intersect(rClip.getB2DRange());
+
+                                if(aIntersectionRange.isEmpty())
+                                {
+                                    // no common IntersectionRange -> the clip will be empty
+                                    return B2DPolyPolygon();
+                                }
+                                else
+                                {
+                                    // use common aIntersectionRange as result, convert
+                                    // to expected PolyPolygon form
+                                    return basegfx::B2DPolyPolygon(
+                                        basegfx::tools::createPolygonFromRect(aIntersectionRange));
+                                }
+                            }
+                        }
+                    }
+
                     // area clipping
                     B2DPolyPolygon aMergePolyPolygonA(rClip);
 
commit 1ca06ce59b7d3cea873d2dc109a2acaec0a80759
Author: Armin Le Grand <alg at apache.org>
Date:   Tue Aug 5 16:11:21 2014 +0000

    Related: #i125349# moved clip enhancements to base clipping functionality
    
    (cherry picked from commit 7c5e9b9b3c5c899d63bf171ee1c9050db860337e)
    
    Change-Id: I570e92c78196895bef329eb308eeb68ffc5e23d3

diff --git a/basegfx/source/polygon/b2dpolygonclipper.cxx b/basegfx/source/polygon/b2dpolygonclipper.cxx
index b8d4a04..e73c388 100644
--- a/basegfx/source/polygon/b2dpolygonclipper.cxx
+++ b/basegfx/source/polygon/b2dpolygonclipper.cxx
@@ -341,6 +341,73 @@ namespace basegfx
 
             if(rCandidate.count() && rClip.count())
             {
+                // #125349# detect if both given PolyPolygons are indeed ranges
+                bool bBothRectangle(false);
+
+                if(basegfx::tools::isRectangle(rCandidate))
+                {
+                    if(basegfx::tools::isRectangle(rClip))
+                    {
+                        // both are ranges
+                        bBothRectangle = true;
+                    }
+                    else
+                    {
+                        // rCandidate is rectangle -> clip rClip on rRectangle, use the much
+                        // cheaper and numerically more stable clipping against a range
+                        // This simplification (exchanging content and clip) is valid
+                        // since we do a logical AND operation
+                        return clipPolyPolygonOnRange(rClip, rCandidate.getB2DRange(), bInside, bStroke);
+                    }
+                }
+                else if(basegfx::tools::isRectangle(rClip))
+                {
+                    if(basegfx::tools::isRectangle(rCandidate))
+                    {
+                        // both are ranges
+                        bBothRectangle = true;
+                    }
+                    else
+                    {
+                        // rClip is rectangle -> clip rCandidate on rRectangle, use the much
+                        // cheaper and numerically more stable clipping against a range
+                        return clipPolyPolygonOnRange(rCandidate, rClip.getB2DRange(), bInside, bStroke);
+                    }
+                }
+
+                if(bBothRectangle)
+                {
+                    // both are rectangle
+                    if(rCandidate.getB2DRange().equal(rClip.getB2DRange()))
+                    {
+                        // if both are equal -> no change
+                        return rCandidate;
+                    }
+                    else
+                    {
+                        // not equal -> create new intersection from both ranges,
+                        // but much cheaper based on the ranges
+                        basegfx::B2DRange aIntersectionRange(rCandidate.getB2DRange());
+
+                        aIntersectionRange.intersect(rClip.getB2DRange());
+
+                        if(aIntersectionRange.isEmpty())
+                        {
+                            // no common IntersectionRange -> the clip will be empty
+                            return B2DPolyPolygon();
+                        }
+                        else
+                        {
+                            // use common aIntersectionRange as result, convert
+                            // to expected PolyPolygon form
+                            return basegfx::B2DPolyPolygon(
+                                basegfx::tools::createPolygonFromRect(aIntersectionRange));
+                        }
+                    }
+                }
+
+                // one or both are no rectangle - go the hard way and clip PolyPolygon
+                // against PolyPolygon...
                 if(bStroke)
                 {
                     // line clipping, create line snippets by first adding all cut points and
diff --git a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
index e592f9c..d6e1e7a 100644
--- a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
@@ -1765,52 +1765,17 @@ namespace drawinglayer
 
                             if(maClipPolyPolygon.count())
                             {
-                                // due to the cost of PolyPolygon clipping and numerical reasons try first if the current
-                                // and the new ClipRegion are ranges. If yes, processing can be simplified
-                                if(basegfx::tools::isRectangle(aMask)
-                                    && basegfx::tools::isRectangle(maClipPolyPolygon))
-                                {
-                                    // both ClipPolygons are rectangles
-                                    if(aMask.getB2DRange().equal(maClipPolyPolygon.getB2DRange()))
-                                    {
-                                        // equal -> no change in ClipRegion needed, leave
-                                        // maClipPolyPolygon unchanged
-                                    }
-                                    else
-                                    {
-                                        // not equal -> create new ClipRegion from the two ranges
-                                        basegfx::B2DRange aClipRange(aMask.getB2DRange());
-
-                                        aClipRange.intersect(maClipPolyPolygon.getB2DRange());
-
-                                        if(aClipRange.isEmpty())
-                                        {
-                                            // no common ClipRegion -> set empty ClipRegion, no content to show
-                                            maClipPolyPolygon.clear();
-                                        }
-                                        else
-                                        {
-                                            // use common ClipRegion as new ClipRegion
-                                            maClipPolyPolygon = basegfx::B2DPolyPolygon(
-                                                basegfx::tools::createPolygonFromRect(aClipRange));
-                                        }
-                                    }
-                                }
-                                else
-                                {
-                                    // The current ClipRegion or the new one is not a rectangle;
-                                    // there is already a clip polygon set; build clipped union of
-                                    // current mask polygon and new one
-                                    maClipPolyPolygon = basegfx::tools::clipPolyPolygonOnPolyPolygon(
-                                        aMask,
-                                        maClipPolyPolygon,
-                                        true, // #i106516# we want the inside of aMask, not the outside
-                                        false);
-                                }
+                                // there is already a clip polygon set; build clipped union of
+                                // current mask polygon and new one
+                                maClipPolyPolygon = basegfx::tools::clipPolyPolygonOnPolyPolygon(
+                                    aMask,
+                                    maClipPolyPolygon,
+                                    true, // #i106516# we want the inside of aMask, not the outside
+                                    false);
                             }
                             else
                             {
-                                // use new mask directly as ClipRegion
+                                // use mask directly
                                 maClipPolyPolygon = aMask;
                             }
 
@@ -1819,13 +1784,8 @@ namespace drawinglayer
                                 // set VCL clip region; subdivide before conversion to tools polygon. Subdivision necessary (!)
                                 // Removed subdivision and fixed in Region::ImplPolyPolyRegionToBandRegionFunc() in VCL where
                                 // the ClipRegion is built from the Polygon. A AdaptiveSubdivide on the source polygon was missing there
-                                const bool bNewClipRegion(maClipPolyPolygon != aLastClipPolyPolygon);
-
-                                if(bNewClipRegion)
-                                {
-                                    mpOutputDevice->Push(PUSH_CLIPREGION);
-                                    mpOutputDevice->SetClipRegion(Region(maClipPolyPolygon));
-                                }
+                                mpOutputDevice->Push(PUSH_CLIPREGION);
+                                mpOutputDevice->SetClipRegion(Region(maClipPolyPolygon));
 
                                 // recursively paint content
                                 // #i121267# Only need to process sub-content when clip polygon is *not* empty.
@@ -1833,10 +1793,7 @@ namespace drawinglayer
                                 process(rMaskCandidate.getChildren());
 
                                 // restore VCL clip region
-                                if(bNewClipRegion)
-                                {
-                                    mpOutputDevice->Pop();
-                                }
+                                mpOutputDevice->Pop();
                             }
 
                             // restore to rescued clip polygon


More information about the Libreoffice-commits mailing list