summaryrefslogtreecommitdiff
path: root/svgio
diff options
context:
space:
mode:
authorArmin Le Grand <alg@apache.org>2014-03-28 10:42:39 +0000
committerCaolán McNamara <caolanm@redhat.com>2014-03-28 14:20:35 +0000
commit0072d0315171b34fe696cdd584a72d498b4b54dd (patch)
tree699e0fb6afc2a4133886e3d5190b5d2b21190bb1 /svgio
parent355b31fe347479f63906e41300042ec5cb38837c (diff)
Resolves: #i124313# At SVG import, try to optimize used ClipRegions
(cherry picked from commit 6dc64444a42997bb4e1ab38f52e4978719e0275a) Change-Id: I42ec8b0cbfd9367bc98510bfbd1818543ac4b5be
Diffstat (limited to 'svgio')
-rw-r--r--svgio/source/svgreader/svgclippathnode.cxx78
1 files changed, 69 insertions, 9 deletions
diff --git a/svgio/source/svgreader/svgclippathnode.cxx b/svgio/source/svgreader/svgclippathnode.cxx
index 829a0a3014ad..85a4071d47b9 100644
--- a/svgio/source/svgreader/svgclippathnode.cxx
+++ b/svgio/source/svgreader/svgclippathnode.cxx
@@ -24,6 +24,7 @@
#include <drawinglayer/geometry/viewinformation2d.hxx>
#include <drawinglayer/processor2d/contourextractor2d.hxx>
#include <basegfx/polygon/b2dpolypolygoncutter.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
@@ -174,16 +175,75 @@ namespace svgio
aContentRange.getMinimum()));
}
- // redefine target. Use MaskPrimitive2D with created clip
- // geometry. Using the automatically set mbIsClipPathContent at
- // SvgStyleAttributes the clip definition is without fill, stroke,
- // and strokeWidth and forced to black
- const drawinglayer::primitive2d::Primitive2DReference xEmbedTransparence(
- new drawinglayer::primitive2d::MaskPrimitive2D(
- aClipPolyPolygon,
- rContent));
+ // #i124313# try to avoid creating an embedding to a MaskPrimitive2D if
+ // possible; MaskPrimitive2D processing is potentially expensive
+ bool bCreateEmbedding(true);
+ bool bAddContent(true);
- rContent = drawinglayer::primitive2d::Primitive2DSequence(&xEmbedTransparence, 1);
+ if(basegfx::tools::isRectangle(aClipPolyPolygon))
+ {
+ // ClipRegion is a rectangle, thus it is not expensive to tell
+ // if the content is completely inside or outside of it; get ranges
+ const basegfx::B2DRange aClipRange(aClipPolyPolygon.getB2DRange());
+ const basegfx::B2DRange aContentRange(
+ drawinglayer::primitive2d::getB2DRangeFromPrimitive2DSequence(
+ rContent,
+ aViewInformation2D));
+
+ if(aClipRange.isInside(aContentRange))
+ {
+ // completely contained, no need to clip at all, so no need for embedding
+ bCreateEmbedding = false;
+ }
+ else if(aClipRange.overlaps(aContentRange))
+ {
+ // overlap; embedding needed. ClipRegion can be minimized by using
+ // the intersection of the ClipRange and the ContentRange. Minimizing
+ // the ClipRegion potentially enhances further processing since
+ // usually clip operations are expensive.
+ basegfx::B2DRange aCommonRange(aContentRange);
+
+ aCommonRange.intersect(aClipRange);
+ aClipPolyPolygon = basegfx::B2DPolyPolygon(basegfx::tools::createPolygonFromRect(aCommonRange));
+ }
+ else
+ {
+ // not inside and no overlap -> completely outside
+ // no need for embedding, no need for content at all
+ bCreateEmbedding = false;
+ bAddContent = false;
+ }
+ }
+ else
+ {
+ // ClipRegion is not a simple rectangle, it would be possible but expensive to
+ // tell if the content needs clipping or not. It is also dependent of
+ // the content's decomposition. To do this, a processor would be needed that
+ // is capable if processing the given sequence of primitives and decide
+ // if all is inside or all is outside. Such a ClipProcessor could be written,
+ // but for now just create the embedding
+ }
+
+ if(bCreateEmbedding)
+ {
+ // redefine target. Use MaskPrimitive2D with created clip
+ // geometry. Using the automatically set mbIsClipPathContent at
+ // SvgStyleAttributes the clip definition is without fill, stroke,
+ // and strokeWidth and forced to black
+ const drawinglayer::primitive2d::Primitive2DReference xEmbedTransparence(
+ new drawinglayer::primitive2d::MaskPrimitive2D(
+ aClipPolyPolygon,
+ rContent));
+
+ rContent = drawinglayer::primitive2d::Primitive2DSequence(&xEmbedTransparence, 1);
+ }
+ else
+ {
+ if(!bAddContent)
+ {
+ rContent.realloc(0);
+ }
+ }
}
else
{