Kaydet (Commit) 7c5e9b9b authored tarafından Armin Le Grand's avatar Armin Le Grand

i125349 moved clip enhancements to base clipping functionality

üst 6b426a17
...@@ -417,6 +417,73 @@ namespace basegfx ...@@ -417,6 +417,73 @@ namespace basegfx
if(rCandidate.count() && rClip.count()) 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) if(bStroke)
{ {
// line clipping, create line snippets by first adding all cut points and // line clipping, create line snippets by first adding all cut points and
......
...@@ -1744,52 +1744,17 @@ namespace drawinglayer ...@@ -1744,52 +1744,17 @@ namespace drawinglayer
if(maClipPolyPolygon.count()) if(maClipPolyPolygon.count())
{ {
// due to the cost of PolyPolygon clipping and numerical reasons try first if the current // there is already a clip polygon set; build clipped union of
// and the new ClipRegion are ranges. If yes, processing can be simplified // current mask polygon and new one
if(basegfx::tools::isRectangle(aMask) maClipPolyPolygon = basegfx::tools::clipPolyPolygonOnPolyPolygon(
&& basegfx::tools::isRectangle(maClipPolyPolygon)) aMask,
{ maClipPolyPolygon,
// both ClipPolygons are rectangles true, // #i106516# we want the inside of aMask, not the outside
if(aMask.getB2DRange().equal(maClipPolyPolygon.getB2DRange())) false);
{
// 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);
}
} }
else else
{ {
// use new mask directly as ClipRegion // use mask directly
maClipPolyPolygon = aMask; maClipPolyPolygon = aMask;
} }
...@@ -1798,13 +1763,8 @@ namespace drawinglayer ...@@ -1798,13 +1763,8 @@ namespace drawinglayer
// set VCL clip region; subdivide before conversion to tools polygon. Subdivision necessary (!) // set VCL clip region; subdivide before conversion to tools polygon. Subdivision necessary (!)
// Removed subdivision and fixed in Region::ImplPolyPolyRegionToBandRegionFunc() in VCL where // 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 // the ClipRegion is built from the Polygon. A AdaptiveSubdivide on the source polygon was missing there
const bool bNewClipRegion(maClipPolyPolygon != aLastClipPolyPolygon); mpOutputDevice->Push(PUSH_CLIPREGION);
mpOutputDevice->SetClipRegion(Region(maClipPolyPolygon));
if(bNewClipRegion)
{
mpOutputDevice->Push(PUSH_CLIPREGION);
mpOutputDevice->SetClipRegion(Region(maClipPolyPolygon));
}
// recursively paint content // recursively paint content
// #121267# Only need to process sub-content when clip polygon is *not* empty. // #121267# Only need to process sub-content when clip polygon is *not* empty.
...@@ -1812,10 +1772,7 @@ namespace drawinglayer ...@@ -1812,10 +1772,7 @@ namespace drawinglayer
process(rMaskCandidate.getChildren()); process(rMaskCandidate.getChildren());
// restore VCL clip region // restore VCL clip region
if(bNewClipRegion) mpOutputDevice->Pop();
{
mpOutputDevice->Pop();
}
} }
// restore to rescued clip polygon // restore to rescued clip polygon
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment