[Libreoffice-commits] core.git: svgio/source

Armin Le Grand alg at apache.org
Fri Mar 28 07:21:05 PDT 2014


 svgio/source/svgreader/svgclippathnode.cxx |   78 +++++++++++++++++++++++++----
 1 file changed, 69 insertions(+), 9 deletions(-)

New commits:
commit 0072d0315171b34fe696cdd584a72d498b4b54dd
Author: Armin Le Grand <alg at apache.org>
Date:   Fri Mar 28 10:42:39 2014 +0000

    Resolves: #i124313# At SVG import, try to optimize used ClipRegions
    
    (cherry picked from commit 6dc64444a42997bb4e1ab38f52e4978719e0275a)
    
    Change-Id: I42ec8b0cbfd9367bc98510bfbd1818543ac4b5be

diff --git a/svgio/source/svgreader/svgclippathnode.cxx b/svgio/source/svgreader/svgclippathnode.cxx
index 829a0a3..85a4071 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
                 {


More information about the Libreoffice-commits mailing list