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

Marco Cecchetti marco.cecchetti at collabora.com
Fri Jul 1 09:43:08 UTC 2016


 filter/source/svg/svgwriter.cxx |  100 ++++++++++++++++++++++++++++++++++++++--
 filter/source/svg/svgwriter.hxx |   19 +++++++
 2 files changed, 115 insertions(+), 4 deletions(-)

New commits:
commit 880c6e40f694342408681929ae5c4fe12bd63332
Author: Marco Cecchetti <marco.cecchetti at collabora.com>
Date:   Sun Jun 19 23:45:20 2016 +0200

    bccu#1307 - svg filter - added support for clip region meta action
    
    Change-Id: I90beea5e101a14f0dc9df8c7db0bb55782aba110
    Reviewed-on: https://gerrit.libreoffice.org/26832
    Reviewed-by: Marco Cecchetti <mrcekets at gmail.com>
    Tested-by: Marco Cecchetti <mrcekets at gmail.com>

diff --git a/filter/source/svg/svgwriter.cxx b/filter/source/svg/svgwriter.cxx
index 7328886..0fe1cd0 100644
--- a/filter/source/svg/svgwriter.cxx
+++ b/filter/source/svg/svgwriter.cxx
@@ -32,8 +32,11 @@
 #include <memory>
 
 
+static const char   aPrefixClipPathId[] = "clip_path_";
+
 static const char   aXMLElemG[] = "g";
 static const char   aXMLElemA[] = "a";
+static const char   aXMLElemClipPath[] = "clipPath";
 static const char   aXMLElemDefs[] = "defs";
 static const char   aXMLElemLine[] = "line";
 static const char   aXMLElemRect[] = "rect";
@@ -51,6 +54,8 @@ static const char   aXMLElemStop[] = "stop";
 static const char   aXMLAttrTransform[] = "transform";
 static const char   aXMLAttrStyle[] = "style";
 static const char   aXMLAttrId[] = "id";
+static const char   aXMLAttrClipPath[] = "clip-path";
+static const char   aXMLAttrClipPathUnits[] = "clipPathUnits";
 static const char   aXMLAttrD[] = "d";
 static const char   aXMLAttrX[] = "x";
 static const char   aXMLAttrY[] = "y";
@@ -95,7 +100,7 @@ static sal_Char const XML_UNO_NAME_NRULE_NUMBERINGTYPE[] = "NumberingType";
 static sal_Char const XML_UNO_NAME_NRULE_BULLET_CHAR[] = "BulletChar";
 
 
-PushFlags SVGContextHandler::getLastUsedFlags() const
+PushFlags SVGContextHandler::getPushFlags() const
 {
     if (maStateStack.empty())
         return PushFlags::NONE;
@@ -119,6 +124,11 @@ void SVGContextHandler::pushState( PushFlags eFlags )
         aPartialState.setFont( maCurrentState.aFont );
     }
 
+    if (eFlags & PushFlags::CLIPREGION)
+    {
+        aPartialState.mnRegionClipPathId = maCurrentState.nRegionClipPathId;
+    }
+
     maStateStack.push( std::move(aPartialState) );
 }
 
@@ -135,6 +145,11 @@ void SVGContextHandler::popState()
         maCurrentState.aFont = rPartialState.getFont( vcl::Font() );
     }
 
+    if (eFlags & PushFlags::CLIPREGION)
+    {
+        maCurrentState.nRegionClipPathId = rPartialState.mnRegionClipPathId;
+    }
+
     maStateStack.pop();
 }
 
@@ -1742,6 +1757,8 @@ SVGActionWriter::SVGActionWriter( SVGExport& rExport, SVGFontExport& rFontExport
     mnCurGradientId( 1 ),
     mnCurMaskId( 1 ),
     mnCurPatternId( 1 ),
+    mnCurClipPathId( 1 ),
+    mpCurrentClipRegionElem(),
     mrExport( rExport ),
     maContextHandler(),
     mrCurrentState( maContextHandler.getCurrentState() ),
@@ -2122,6 +2139,54 @@ void SVGActionWriter::ImplWriteShape( const SVGShapeDescriptor& rShape )
 }
 
 
+
+void SVGActionWriter::ImplCreateClipPathDef( const tools::PolyPolygon& rPolyPoly )
+{
+    OUString aClipPathId = aPrefixClipPathId + OUString::number( mnCurClipPathId++ );
+
+    SvXMLElementExport aElemDefs( mrExport, XML_NAMESPACE_NONE, aXMLElemDefs, true, true );
+
+    {
+        mrExport.AddAttribute( XML_NAMESPACE_NONE, aXMLAttrId, aClipPathId );
+        mrExport.AddAttribute( XML_NAMESPACE_NONE, aXMLAttrClipPathUnits, "userSpaceOnUse" );
+        SvXMLElementExport aElemClipPath( mrExport, XML_NAMESPACE_NONE, aXMLElemClipPath, true, true );
+
+        ImplWritePolyPolygon(rPolyPoly, false, true);
+    }
+}
+
+void SVGActionWriter::ImplStartClipRegion(sal_Int32 nClipPathId)
+{
+    assert(!mpCurrentClipRegionElem);
+
+    if (nClipPathId == 0)
+        return;
+
+    OUString aUrl = OUString("url(#") + aPrefixClipPathId + OUString::number( nClipPathId ) + ")";
+    mrExport.AddAttribute( XML_NAMESPACE_NONE, aXMLAttrClipPath, aUrl );
+    mpCurrentClipRegionElem.reset( new SvXMLElementExport( mrExport, XML_NAMESPACE_NONE, aXMLElemG, true, true ) );
+}
+
+void SVGActionWriter::ImplEndClipRegion()
+{
+    if (mpCurrentClipRegionElem)
+    {
+        mpCurrentClipRegionElem.reset();
+    }
+}
+
+void SVGActionWriter::ImplWriteClipPath( const tools::PolyPolygon& rPolyPoly )
+{
+    ImplEndClipRegion();
+
+    if( rPolyPoly.Count() == 0 )
+        return;
+
+    ImplCreateClipPathDef(rPolyPoly);
+    mrCurrentState.nRegionClipPathId = mnCurClipPathId - 1;
+    ImplStartClipRegion( mrCurrentState.nRegionClipPathId );
+}
+
 void SVGActionWriter::ImplWritePattern( const tools::PolyPolygon& rPolyPoly,
                                         const Hatch* pHatch,
                                         const Gradient* pGradient,
@@ -3613,10 +3678,40 @@ void SVGActionWriter::ImplWriteActions( const GDIMetaFile& rMtf,
             case( MetaActionType::MOVECLIPREGION ):
             {
                 const_cast<MetaAction*>(pAction)->Execute( mpVDev );
+                const vcl::Region& rClipRegion = mpVDev->GetActiveClipRegion();
+                ImplWriteClipPath( rClipRegion.GetAsPolyPolygon() );
+
                 mbClipAttrChanged = true;
             }
             break;
 
+            case( MetaActionType::PUSH ):
+            {
+                const MetaPushAction*  pA = static_cast<const MetaPushAction*>(pAction);
+                PushFlags mnFlags = pA->GetFlags();
+
+                const_cast<MetaAction*>(pAction)->Execute( mpVDev );
+
+                maContextHandler.pushState( mnFlags );
+            }
+            break;
+
+            case( MetaActionType::POP ):
+            {
+                const_cast<MetaAction*>(pAction)->Execute( mpVDev );
+
+                PushFlags mnFlags = maContextHandler.getPushFlags();
+
+                maContextHandler.popState();
+
+                if( mnFlags & PushFlags::CLIPREGION )
+                {
+                    ImplEndClipRegion();
+                    ImplStartClipRegion( mrCurrentState.nRegionClipPathId );
+                }
+            }
+            break;
+
             case( MetaActionType::REFPOINT ):
             case( MetaActionType::MAPMODE ):
             case( MetaActionType::LINECOLOR ):
@@ -3626,8 +3721,6 @@ void SVGActionWriter::ImplWriteActions( const GDIMetaFile& rMtf,
             case( MetaActionType::TEXTCOLOR ):
             case( MetaActionType::TEXTALIGN ):
             case( MetaActionType::FONT ):
-            case( MetaActionType::PUSH ):
-            case( MetaActionType::POP ):
             case( MetaActionType::LAYOUTMODE ):
             {
                 const_cast<MetaAction*>(pAction)->Execute( mpVDev );
@@ -3694,6 +3787,7 @@ void SVGActionWriter::WriteMetaFile( const Point& rPos100thmm,
 
     ImplWriteActions( rMtf, nWriteFlags, pElementId, pXShape, pTextEmbeddedBitmapMtf );
     maTextWriter.endTextParagraph();
+    ImplEndClipRegion();
 
     // draw open shape that doesn't have a border
     if( mapCurShape.get() )
diff --git a/filter/source/svg/svgwriter.hxx b/filter/source/svg/svgwriter.hxx
index 5c3b757..74cda8a 100644
--- a/filter/source/svg/svgwriter.hxx
+++ b/filter/source/svg/svgwriter.hxx
@@ -85,6 +85,12 @@ struct SVGState
 //  Color                                   aFillColor;
 //  basegfx::B2DLineJoin                    aLineJoin;
 //  com::sun::star::drawing::LineCap        aLineCap;
+    sal_Int32                               nRegionClipPathId;
+
+    SVGState()
+        : aFont()
+        , nRegionClipPathId( 0 )
+    {}
 };
 // - PartialState -
 
@@ -92,6 +98,7 @@ struct PartialState
 {
     PushFlags                           meFlags;
     ::std::unique_ptr<vcl::Font>        mupFont;
+    sal_Int32                           mnRegionClipPathId;
 
     const vcl::Font&        getFont( const vcl::Font& rDefaultFont ) const
                                 { return mupFont ? *mupFont : rDefaultFont; }
@@ -101,13 +108,17 @@ struct PartialState
 
     PartialState()
         : meFlags( PushFlags::NONE )
+        , mupFont()
+        , mnRegionClipPathId( 0 )
     {}
 
     PartialState(PartialState&& aPartialState)
         : meFlags( aPartialState.meFlags )
         , mupFont( std::move( aPartialState.mupFont ) )
+        , mnRegionClipPathId( aPartialState.mnRegionClipPathId )
     {
         aPartialState.meFlags = PushFlags::NONE;
+        aPartialState.mnRegionClipPathId = 0;
     }
 };
 
@@ -121,7 +132,7 @@ private:
     SVGState maCurrentState;
 
 public:
-    PushFlags getLastUsedFlags() const;
+    PushFlags getPushFlags() const;
     SVGState& getCurrentState();
     void pushState( PushFlags eFlags );
     void popState();
@@ -308,6 +319,8 @@ private:
     sal_Int32                                   mnCurGradientId;
     sal_Int32                                   mnCurMaskId;
     sal_Int32                                   mnCurPatternId;
+    sal_Int32                                   mnCurClipPathId;
+    ::std::unique_ptr< SvXMLElementExport >     mpCurrentClipRegionElem;
     ::std::unique_ptr< SVGShapeDescriptor >     mapCurShape;
     SVGExport&                                  mrExport;
     SVGContextHandler                           maContextHandler;
@@ -335,6 +348,10 @@ private:
     void                    ImplWritePolyPolygon( const tools::PolyPolygon& rPolyPoly, bool bLineOnly,
                                                   bool bApplyMapping = true );
     void                    ImplWriteShape( const SVGShapeDescriptor& rShape );
+    void                    ImplCreateClipPathDef( const tools::PolyPolygon& rPolyPoly );
+    void                    ImplStartClipRegion(sal_Int32 nClipPathId);
+    void                    ImplEndClipRegion();
+    void                    ImplWriteClipPath( const tools::PolyPolygon& rPolyPoly );
     void                    ImplWriteGradientEx( const tools::PolyPolygon& rPolyPoly, const Gradient& rGradient, sal_uInt32 nWriteFlags);
     void                    ImplWriteGradientLinear( const tools::PolyPolygon& rPolyPoly, const Gradient& rGradient );
     void                    ImplWriteGradientStop( const Color& rColor, double fOffset );


More information about the Libreoffice-commits mailing list