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 <a...@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 <a...@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 _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits