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

Marco Cecchetti marco.cecchetti at collabora.com
Fri Jul 1 09:42:33 UTC 2016


 filter/source/svg/svgwriter.cxx |  115 +++++++++++++++++++++++++++-------------
 filter/source/svg/svgwriter.hxx |   93 ++++++++++++++++++++++----------
 2 files changed, 144 insertions(+), 64 deletions(-)

New commits:
commit 0f95f4f99cf09b597cb9d7b575aed7ba776919dd
Author: Marco Cecchetti <marco.cecchetti at collabora.com>
Date:   Fri Jun 17 16:22:47 2016 +0200

    svg filter - rewritten context handling
    
    Change-Id: I9c18f6ca641de2957cbbf8fd57035f5aa2e5c294
    Reviewed-on: https://gerrit.libreoffice.org/26831
    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 fc874c1..7328886 100644
--- a/filter/source/svg/svgwriter.cxx
+++ b/filter/source/svg/svgwriter.cxx
@@ -94,9 +94,54 @@ static const char aOOOAttrNumberingType[] = NSPREFIX "numbering-type";
 static sal_Char const XML_UNO_NAME_NRULE_NUMBERINGTYPE[] = "NumberingType";
 static sal_Char const XML_UNO_NAME_NRULE_BULLET_CHAR[] = "BulletChar";
 
-SVGAttributeWriter::SVGAttributeWriter( SVGExport& rExport, SVGFontExport& rFontExport )
+
+PushFlags SVGContextHandler::getLastUsedFlags() const
+{
+    if (maStateStack.empty())
+        return PushFlags::NONE;
+
+    const PartialState& rPartialState = maStateStack.top();
+    return rPartialState.meFlags;
+}
+
+SVGState& SVGContextHandler::getCurrentState()
+{
+    return maCurrentState;
+}
+
+void SVGContextHandler::pushState( PushFlags eFlags )
+{
+    PartialState aPartialState;
+    aPartialState.meFlags = eFlags;
+
+    if (eFlags & PushFlags::FONT)
+    {
+        aPartialState.setFont( maCurrentState.aFont );
+    }
+
+    maStateStack.push( std::move(aPartialState) );
+}
+
+void SVGContextHandler::popState()
+{
+    if (maStateStack.empty())
+        return;
+
+    const PartialState& rPartialState = maStateStack.top();
+    PushFlags eFlags = rPartialState.meFlags;
+
+    if (eFlags & PushFlags::FONT)
+    {
+        maCurrentState.aFont = rPartialState.getFont( vcl::Font() );
+    }
+
+    maStateStack.pop();
+}
+
+SVGAttributeWriter::SVGAttributeWriter( SVGExport& rExport, SVGFontExport& rFontExport, SVGState& rCurState )
     : mrExport( rExport )
     , mrFontExport( rFontExport )
+    , mrCurrentState( rCurState )
     , mpElemFont( nullptr )
 {
 }
@@ -292,12 +337,14 @@ void SVGAttributeWriter::AddGradientDef( const Rectangle& rObjRect, const Gradie
 
 void SVGAttributeWriter::SetFontAttr( const vcl::Font& rFont )
 {
-    if( rFont != maCurFont )
+    vcl::Font& rCurFont = mrCurrentState.aFont;
+
+    if( rFont != rCurFont )
     {
         OUString  aFontStyle, aTextDecoration;
         sal_Int32        nFontWeight;
 
-        maCurFont = rFont;
+        rCurFont = rFont;
 
         // Font Family
         setFontFamily();
@@ -384,23 +431,25 @@ void SVGAttributeWriter::endFontSettings()
 
 void SVGAttributeWriter::setFontFamily()
 {
+    vcl::Font& rCurFont = mrCurrentState.aFont;
+
     if( mrExport.IsUsePositionedCharacters() )
     {
-        mrExport.AddAttribute( XML_NAMESPACE_NONE, aXMLAttrFontFamily, mrFontExport.GetMappedFontName( maCurFont.GetFamilyName() ) );
+        mrExport.AddAttribute( XML_NAMESPACE_NONE, aXMLAttrFontFamily, mrFontExport.GetMappedFontName( rCurFont.GetFamilyName() ) );
     }
     else
     {
         sal_Int32       nNextTokenPos( 0 );
-        const OUString& rsFontName = maCurFont.GetFamilyName();
+        const OUString& rsFontName = rCurFont.GetFamilyName();
         OUString sFontFamily( rsFontName.getToken( 0, ';', nNextTokenPos ) );
-        FontPitch ePitch = maCurFont.GetPitch();
+        FontPitch ePitch = rCurFont.GetPitch();
         if( ePitch == PITCH_FIXED )
         {
             sFontFamily += ", monospace";
         }
         else
         {
-            FontFamily eFamily = maCurFont.GetFamilyType();
+            FontFamily eFamily = rCurFont.GetFamilyType();
             if( eFamily == FAMILY_ROMAN )
                 sFontFamily += ", serif";
             else if( eFamily == FAMILY_SWISS )
@@ -410,10 +459,9 @@ void SVGAttributeWriter::setFontFamily()
     }
 }
 
-
-SVGTextWriter::SVGTextWriter( SVGExport& rExport )
+SVGTextWriter::SVGTextWriter( SVGExport& rExport,  SVGAttributeWriter& rAttributeWriter  )
 : mrExport( rExport ),
-  mpContext( nullptr ),
+  mrAttributeWriter( rAttributeWriter ),
   mpVDev( nullptr ),
   mbIsTextShapeStarted( false ),
   mrTextShape(),
@@ -1361,7 +1409,7 @@ void SVGTextWriter::implWriteBulletChars()
                             "," + OUString::number( rInfo.aPos.Y() ) + ")";
                 mrExport.AddAttribute( XML_NAMESPACE_NONE, "transform", sPosition );
 
-                mpContext->AddPaintAttr( COL_TRANSPARENT, rInfo.aColor );
+                mrAttributeWriter.AddPaintAttr( COL_TRANSPARENT, rInfo.aColor );
 
                 SvXMLElementExport aPositioningElem( mrExport, XML_NAMESPACE_NONE, aXMLElemG, true, true );
 
@@ -1664,9 +1712,8 @@ void SVGTextWriter::implWriteTextPortion( const Point& rPos,
     }
 
     addFontAttributes( /* isTexTContainer: */ false );
-    assert(mpContext); //invalid context object
 
-    mpContext->AddPaintAttr( COL_TRANSPARENT, aTextColor );
+    mrAttributeWriter.AddPaintAttr( COL_TRANSPARENT, aTextColor );
 
     // <a> tag for link should be the innermost tag, inside <tspan>
     if( !mbIsPlaceholderShape && mbIsURLField && !msUrl.isEmpty() )
@@ -1696,9 +1743,10 @@ SVGActionWriter::SVGActionWriter( SVGExport& rExport, SVGFontExport& rFontExport
     mnCurMaskId( 1 ),
     mnCurPatternId( 1 ),
     mrExport( rExport ),
-    mrFontExport( rFontExport ),
-    mpContext( nullptr ),
-    maTextWriter( rExport ),
+    maContextHandler(),
+    mrCurrentState( maContextHandler.getCurrentState() ),
+    maAttributeWriter( rExport, rFontExport, mrCurrentState ),
+    maTextWriter( rExport, maAttributeWriter ),
     mbClipAttrChanged( false ),
     mbIsPlaceholderShape( false )
 {
@@ -1711,7 +1759,6 @@ SVGActionWriter::SVGActionWriter( SVGExport& rExport, SVGFontExport& rFontExport
 
 SVGActionWriter::~SVGActionWriter()
 {
-    DBG_ASSERT( !mpContext, "Not all contexts are closed" );
     mpVDev.disposeAndClear();
 }
 
@@ -1997,7 +2044,7 @@ void SVGActionWriter::ImplWriteShape( const SVGShapeDescriptor& rShape )
     const bool  bLineOnly = ( rShape.maShapeFillColor == Color( COL_TRANSPARENT ) ) && ( !rShape.mapShapeGradient.get() );
     Rectangle   aBoundRect( aPolyPoly.GetBoundRect() );
 
-    mpContext->AddPaintAttr( rShape.maShapeLineColor, rShape.maShapeFillColor, &aBoundRect, rShape.mapShapeGradient.get() );
+    maAttributeWriter.AddPaintAttr( rShape.maShapeLineColor, rShape.maShapeFillColor, &aBoundRect, rShape.mapShapeGradient.get() );
 
     if( !rShape.maId.isEmpty() )
         mrExport.AddAttribute( XML_NAMESPACE_NONE, aXMLAttrId, rShape.maId );
@@ -2500,7 +2547,7 @@ void SVGActionWriter::ImplWriteText( const Point& rPos, const OUString& rText,
     }
 
 
-    mpContext->AddPaintAttr( COL_TRANSPARENT, aTextColor );
+    maAttributeWriter.AddPaintAttr( COL_TRANSPARENT, aTextColor );
 
     // for each line of text there should be at least one group element
     SvXMLElementExport aSVGGElem( mrExport, XML_NAMESPACE_NONE, aXMLElemG, true, false );
@@ -2768,7 +2815,7 @@ void SVGActionWriter::ImplWriteActions( const GDIMetaFile& rMtf,
                 {
                     const MetaPixelAction* pA = static_cast<const MetaPixelAction*>(pAction);
 
-                    mpContext->AddPaintAttr( pA->GetColor(), pA->GetColor() );
+                    maAttributeWriter.AddPaintAttr( pA->GetColor(), pA->GetColor() );
                     ImplWriteLine( pA->GetPoint(), pA->GetPoint(), &pA->GetColor() );
                 }
             }
@@ -2780,7 +2827,7 @@ void SVGActionWriter::ImplWriteActions( const GDIMetaFile& rMtf,
                 {
                     const MetaPointAction* pA = static_cast<const MetaPointAction*>(pAction);
 
-                    mpContext->AddPaintAttr( mpVDev->GetLineColor(), mpVDev->GetLineColor() );
+                    maAttributeWriter.AddPaintAttr( mpVDev->GetLineColor(), mpVDev->GetLineColor() );
                     ImplWriteLine( pA->GetPoint(), pA->GetPoint() );
                 }
             }
@@ -2792,7 +2839,7 @@ void SVGActionWriter::ImplWriteActions( const GDIMetaFile& rMtf,
                 {
                     const MetaLineAction* pA = static_cast<const MetaLineAction*>(pAction);
 
-                    mpContext->AddPaintAttr( mpVDev->GetLineColor(), mpVDev->GetLineColor() );
+                    maAttributeWriter.AddPaintAttr( mpVDev->GetLineColor(), mpVDev->GetLineColor() );
                     ImplWriteLine( pA->GetStartPoint(), pA->GetEndPoint() );
                 }
             }
@@ -2802,7 +2849,7 @@ void SVGActionWriter::ImplWriteActions( const GDIMetaFile& rMtf,
             {
                 if( nWriteFlags & SVGWRITER_WRITE_FILL )
                 {
-                    mpContext->AddPaintAttr( mpVDev->GetLineColor(), mpVDev->GetFillColor() );
+                    maAttributeWriter.AddPaintAttr( mpVDev->GetLineColor(), mpVDev->GetFillColor() );
                     ImplWriteRect( static_cast<const MetaRectAction*>(pAction)->GetRect() );
                 }
             }
@@ -2814,7 +2861,7 @@ void SVGActionWriter::ImplWriteActions( const GDIMetaFile& rMtf,
                 {
                     const MetaRoundRectAction* pA = static_cast<const MetaRoundRectAction*>(pAction);
 
-                    mpContext->AddPaintAttr( mpVDev->GetLineColor(), mpVDev->GetFillColor() );
+                    maAttributeWriter.AddPaintAttr( mpVDev->GetLineColor(), mpVDev->GetFillColor() );
                     ImplWriteRect( pA->GetRect(), pA->GetHorzRound(), pA->GetVertRound() );
                 }
             }
@@ -2827,7 +2874,7 @@ void SVGActionWriter::ImplWriteActions( const GDIMetaFile& rMtf,
                     const MetaEllipseAction*    pA = static_cast<const MetaEllipseAction*>(pAction);
                     const Rectangle&            rRect = pA->GetRect();
 
-                    mpContext->AddPaintAttr( mpVDev->GetLineColor(), mpVDev->GetFillColor() );
+                    maAttributeWriter.AddPaintAttr( mpVDev->GetLineColor(), mpVDev->GetFillColor() );
                     ImplWriteEllipse( rRect.Center(), rRect.GetWidth() >> 1, rRect.GetHeight() >> 1 );
                 }
             }
@@ -2873,7 +2920,7 @@ void SVGActionWriter::ImplWriteActions( const GDIMetaFile& rMtf,
 
                     if( aPoly.GetSize() )
                     {
-                        mpContext->AddPaintAttr( mpVDev->GetLineColor(), mpVDev->GetFillColor() );
+                        maAttributeWriter.AddPaintAttr( mpVDev->GetLineColor(), mpVDev->GetFillColor() );
                         ImplWritePolyPolygon( aPoly, false );
                     }
                 }
@@ -2889,7 +2936,7 @@ void SVGActionWriter::ImplWriteActions( const GDIMetaFile& rMtf,
 
                     if( rPoly.GetSize() )
                     {
-                        mpContext->AddPaintAttr( mpVDev->GetLineColor(), Color( COL_TRANSPARENT ) );
+                        maAttributeWriter.AddPaintAttr( mpVDev->GetLineColor(), Color( COL_TRANSPARENT ) );
                         ImplAddLineAttr( pA->GetLineInfo() );
                         ImplWritePolyPolygon( rPoly, true );
                     }
@@ -2906,7 +2953,7 @@ void SVGActionWriter::ImplWriteActions( const GDIMetaFile& rMtf,
 
                     if( rPolyPoly.Count() )
                     {
-                        mpContext->AddPaintAttr( mpVDev->GetLineColor(), mpVDev->GetFillColor() );
+                        maAttributeWriter.AddPaintAttr( mpVDev->GetLineColor(), mpVDev->GetFillColor() );
                         ImplWritePolyPolygon( rPolyPoly, false );
                     }
                 }
@@ -2960,7 +3007,7 @@ void SVGActionWriter::ImplWriteActions( const GDIMetaFile& rMtf,
                         aNewLineColor.SetTransparency( sal::static_int_cast<sal_uInt8>( FRound( pA->GetTransparence() * 2.55 ) ) );
                         aNewFillColor.SetTransparency( sal::static_int_cast<sal_uInt8>( FRound( pA->GetTransparence() * 2.55 ) ) );
 
-                        mpContext->AddPaintAttr( aNewLineColor, aNewFillColor );
+                        maAttributeWriter.AddPaintAttr( aNewLineColor, aNewFillColor );
                         ImplWritePolyPolygon( rPolyPoly, false );
                     }
                 }
@@ -3478,7 +3525,7 @@ void SVGActionWriter::ImplWriteActions( const GDIMetaFile& rMtf,
                         if( mrExport.IsUsePositionedCharacters() )
                         {
                             vcl::Font aFont = ImplSetCorrectFontHeight();
-                            mpContext->SetFontAttr( aFont );
+                            maAttributeWriter.SetFontAttr( aFont );
                             ImplWriteText( pA->GetPoint(), aText, nullptr, 0 );
                         }
                         else
@@ -3501,7 +3548,7 @@ void SVGActionWriter::ImplWriteActions( const GDIMetaFile& rMtf,
                         if( mrExport.IsUsePositionedCharacters() )
                         {
                             vcl::Font aFont = ImplSetCorrectFontHeight();
-                            mpContext->SetFontAttr( aFont );
+                            maAttributeWriter.SetFontAttr( aFont );
                             ImplWriteText( pA->GetRect().TopLeft(), pA->GetText(), nullptr, 0 );
                         }
                         maTextWriter.writeTextPortion( pA->GetRect().TopLeft(), pA->GetText() );
@@ -3523,7 +3570,7 @@ void SVGActionWriter::ImplWriteActions( const GDIMetaFile& rMtf,
                         if( mrExport.IsUsePositionedCharacters() )
                         {
                             vcl::Font aFont = ImplSetCorrectFontHeight();
-                            mpContext->SetFontAttr( aFont );
+                            maAttributeWriter.SetFontAttr( aFont );
                             ImplWriteText( pA->GetPoint(), aText, pA->GetDXArray(), 0 );
                         }
                         else
@@ -3548,7 +3595,7 @@ void SVGActionWriter::ImplWriteActions( const GDIMetaFile& rMtf,
                         if( mrExport.IsUsePositionedCharacters() )
                         {
                             vcl::Font aFont = ImplSetCorrectFontHeight();
-                            mpContext->SetFontAttr( aFont );
+                            maAttributeWriter.SetFontAttr( aFont );
                             ImplWriteText( pA->GetPoint(), aText, nullptr, pA->GetWidth() );
                         }
                         else
@@ -3642,7 +3689,6 @@ void SVGActionWriter::WriteMetaFile( const Point& rPos100thmm,
     aMapMode.SetOrigin( aOffset += aMapMode.GetOrigin() );
 
     mpVDev->SetMapMode( aMapMode );
-    ImplAcquireContext();
 
     mapCurShape.reset();
 
@@ -3656,7 +3702,6 @@ void SVGActionWriter::WriteMetaFile( const Point& rPos100thmm,
         mapCurShape.reset();
     }
 
-    ImplReleaseContext();
     mpVDev->Pop();
 }
 
diff --git a/filter/source/svg/svgwriter.hxx b/filter/source/svg/svgwriter.hxx
index 76c2df0..5c3b757 100644
--- a/filter/source/svg/svgwriter.hxx
+++ b/filter/source/svg/svgwriter.hxx
@@ -57,9 +57,11 @@
 #include <com/sun/star/style/NumberingType.hpp>
 #include <com/sun/star/svg/XSVGWriter.hpp>
 
+#include <memory>
 #include <stack>
 #include <unordered_map>
 
+
 using namespace ::com::sun::star::uno;
 using namespace ::com::sun::star::container;
 using namespace ::com::sun::star::lang;
@@ -75,6 +77,59 @@ using namespace ::com::sun::star::xml::sax;
 #define SVGWRITER_WRITE_TEXT        0x00000002
 #define SVGWRITER_NO_SHAPE_COMMENTS 0x01000000
 
+
+struct SVGState
+{
+    vcl::Font                               aFont;
+//  Color                                   aLineColor;
+//  Color                                   aFillColor;
+//  basegfx::B2DLineJoin                    aLineJoin;
+//  com::sun::star::drawing::LineCap        aLineCap;
+};
+// - PartialState -
+
+struct PartialState
+{
+    PushFlags                           meFlags;
+    ::std::unique_ptr<vcl::Font>        mupFont;
+
+    const vcl::Font&        getFont( const vcl::Font& rDefaultFont ) const
+                                { return mupFont ? *mupFont : rDefaultFont; }
+
+    void                    setFont( const vcl::Font& rFont )
+                                { mupFont.reset( new vcl::Font(rFont) ); }
+
+    PartialState()
+        : meFlags( PushFlags::NONE )
+    {}
+
+    PartialState(PartialState&& aPartialState)
+        : meFlags( aPartialState.meFlags )
+        , mupFont( std::move( aPartialState.mupFont ) )
+    {
+        aPartialState.meFlags = PushFlags::NONE;
+    }
+};
+
+
+// - SVGContextHandler -
+
+class SVGContextHandler
+{
+private:
+    ::std::stack<PartialState> maStateStack;
+    SVGState maCurrentState;
+
+public:
+    PushFlags getLastUsedFlags() const;
+    SVGState& getCurrentState();
+    void pushState( PushFlags eFlags );
+    void popState();
+};
+
+
+// - SVGAttributeWriter -
+
 class SVGActionWriter;
 class SVGExport;
 class SVGFontExport;
@@ -84,16 +139,17 @@ class SVGAttributeWriter
 {
 private:
 
-    vcl::Font                               maCurFont;
     SVGExport&                              mrExport;
     SVGFontExport&                          mrFontExport;
+    SVGState&                               mrCurrentState;
     SvXMLElementExport*                     mpElemFont;
-    static double            ImplRound( double fVal );
 
 
+    static double           ImplRound( double fVal );
+
 public:
 
-                            SVGAttributeWriter( SVGExport& rExport, SVGFontExport& rFontExport );
+                            SVGAttributeWriter( SVGExport& rExport, SVGFontExport& rFontExport, SVGState& rCurState );
     virtual                 ~SVGAttributeWriter();
 
     void                    AddColorAttr( const char* pColorAttrName, const char* pColorOpacityAttrName, const Color& rColor );
@@ -154,7 +210,7 @@ class SVGTextWriter
 
   private:
     SVGExport&                                  mrExport;
-    SVGAttributeWriter*                         mpContext;
+    SVGAttributeWriter&                         mrAttributeWriter;
     VclPtr<VirtualDevice>                       mpVDev;
     bool                                        mbIsTextShapeStarted;
     Reference<XText>                            mrTextShape;
@@ -187,7 +243,7 @@ class SVGTextWriter
     vcl::Font                                   maParentFont;
 
   public:
-    explicit SVGTextWriter( SVGExport& rExport );
+    explicit SVGTextWriter( SVGExport& rExport, SVGAttributeWriter& rAttributeWriter );
     virtual ~SVGTextWriter();
 
     sal_Int32 setTextPosition( const GDIMetaFile& rMtf, sal_uLong& nCurAction );
@@ -222,11 +278,6 @@ class SVGTextWriter
         mpTargetMapMode = &rTargetMapMode;
     }
 
-    void setContext( SVGAttributeWriter* pContext )
-    {
-        mpContext = pContext;
-    }
-
     void setTextShape( const Reference<XText>& rxText,
                        const GDIMetaFile* pTextEmbeddedBitmapMtf )
     {
@@ -257,11 +308,11 @@ private:
     sal_Int32                                   mnCurGradientId;
     sal_Int32                                   mnCurMaskId;
     sal_Int32                                   mnCurPatternId;
-    ::std::stack< SVGAttributeWriter* >         maContextStack;
     ::std::unique_ptr< SVGShapeDescriptor >     mapCurShape;
     SVGExport&                                  mrExport;
-    SVGFontExport&                              mrFontExport;
-    SVGAttributeWriter*                         mpContext;
+    SVGContextHandler                           maContextHandler;
+    SVGState&                                   mrCurrentState;
+    SVGAttributeWriter                          maAttributeWriter;
     SVGTextWriter                               maTextWriter;
     VclPtr<VirtualDevice>                       mpVDev;
     MapMode                                     maTargetMapMode;
@@ -269,22 +320,6 @@ private:
     bool                                        mbIsPlaceholderShape;
 
 
-    void                    ImplAcquireContext()
-    {
-        maContextStack.push( mpContext = new SVGAttributeWriter( mrExport, mrFontExport ) );
-        maTextWriter.setContext( mpContext );
-    }
-    void                    ImplReleaseContext()
-    {
-        if (!maContextStack.empty())
-        {
-            delete maContextStack.top();
-            maContextStack.pop();
-        }
-        mpContext = (maContextStack.empty() ? nullptr : maContextStack.top());
-        maTextWriter.setContext( mpContext );
-    }
-
     long                    ImplMap( sal_Int32 nVal ) const;
     Point&                  ImplMap( const Point& rPt, Point& rDstPt ) const;
     Size&                   ImplMap( const Size& rSz, Size& rDstSz ) const;


More information about the Libreoffice-commits mailing list