[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