filter/source/svg/svgwriter.cxx | 118 +++++++++++++++++++++++++++------------- filter/source/svg/svgwriter.hxx | 97 +++++++++++++++++++++----------- 2 files changed, 143 insertions(+), 72 deletions(-)
New commits: commit b392fd706545c23bed0afc9ae5b397f76c5ab7e5 Author: Marco Cecchetti <marco.cecche...@collabora.com> Date: Fri Jun 17 16:22:47 2016 +0200 svg filter - rewritten context handling Change-Id: Ibb66ab6d339d48ad9eef90c2f6795793f0392d03 Reviewed-on: https://gerrit.libreoffice.org/26505 Reviewed-by: Marco Cecchetti <mrcek...@gmail.com> Tested-by: Marco Cecchetti <mrcek...@gmail.com> diff --git a/filter/source/svg/svgwriter.cxx b/filter/source/svg/svgwriter.cxx index 6273fe5..f2e5470 100644 --- a/filter/source/svg/svgwriter.cxx +++ b/filter/source/svg/svgwriter.cxx @@ -95,20 +95,60 @@ 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( NULL ) - , mpElemPaint( NULL ) - , maLineJoin(basegfx::B2DLINEJOIN_NONE) - , maLineCap(css::drawing::LineCap_BUTT) { } SVGAttributeWriter::~SVGAttributeWriter() { - if( mpElemPaint ) - delete mpElemPaint; if( mpElemFont ) delete mpElemFont; } @@ -292,12 +332,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(); @@ -381,23 +423,25 @@ void SVGAttributeWriter::endFontSettings() void SVGAttributeWriter::setFontFamily() { + vcl::Font& rCurFont = mrCurrentState.aFont; + if( mrExport.IsUsePositionedCharacters() ) { - mrExport.AddAttribute( XML_NAMESPACE_NONE, aXMLAttrFontFamily, mrFontExport.GetMappedFontName( maCurFont.GetName() ) ); + mrExport.AddAttribute( XML_NAMESPACE_NONE, aXMLAttrFontFamily, mrFontExport.GetMappedFontName( rCurFont.GetName() ) ); } else { sal_Int32 nNextTokenPos( 0 ); - const OUString& rsFontName = maCurFont.GetName(); + const OUString& rsFontName = rCurFont.GetName(); OUString sFontFamily( rsFontName.getToken( 0, ';', nNextTokenPos ) ); - FontPitch ePitch = maCurFont.GetPitch(); + FontPitch ePitch = rCurFont.GetPitch(); if( ePitch == PITCH_FIXED ) { sFontFamily += ", monospace"; } else { - FontFamily eFamily = maCurFont.GetFamily(); + FontFamily eFamily = rCurFont.GetFamily(); if( eFamily == FAMILY_ROMAN ) sFontFamily += ", serif"; else if( eFamily == FAMILY_SWISS ) @@ -407,9 +451,9 @@ void SVGAttributeWriter::setFontFamily() } } -SVGTextWriter::SVGTextWriter( SVGExport& rExport ) +SVGTextWriter::SVGTextWriter( SVGExport& rExport, SVGAttributeWriter& rAttributeWriter ) : mrExport( rExport ), - mpContext( NULL ), + mrAttributeWriter( rAttributeWriter ), mpVDev( NULL ), mbIsTextShapeStarted( false ), mrTextShape(), @@ -1336,7 +1380,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 ); @@ -1641,9 +1685,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 ); OUString sTextContent = rText; @@ -1675,8 +1718,10 @@ SVGActionWriter::SVGActionWriter( SVGExport& rExport, SVGFontExport& rFontExport mnCurPatternId( 1 ), mrExport( rExport ), mrFontExport( rFontExport ), - mpContext( NULL ), - maTextWriter( rExport ), + maContextHandler(), + mrCurrentState( maContextHandler.getCurrentState() ), + maAttributeWriter( rExport, rFontExport, mrCurrentState ), + maTextWriter( rExport, maAttributeWriter ), mnInnerMtfCount( 0 ), mbClipAttrChanged( false ), mbIsPlaceholderShape( false ) @@ -1689,7 +1734,6 @@ SVGActionWriter::SVGActionWriter( SVGExport& rExport, SVGFontExport& rFontExport SVGActionWriter::~SVGActionWriter() { - DBG_ASSERT( !mpContext, "Not all contexts are closed" ); mpVDev.disposeAndClear(); } @@ -1983,7 +2027,7 @@ void SVGActionWriter::ImplWriteShape( const SVGShapeDescriptor& rShape, bool bAp 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 ); @@ -2481,7 +2525,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 ); @@ -2762,7 +2806,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() ); } } @@ -2774,7 +2818,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(), NULL ); } } @@ -2786,7 +2830,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(), NULL ); } } @@ -2796,7 +2840,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(), 0, 0 ); } } @@ -2808,7 +2852,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() ); } } @@ -2821,7 +2865,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 ); } } @@ -2867,7 +2911,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 ); } } @@ -2883,7 +2927,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 ); } @@ -2900,7 +2944,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 ); } } @@ -2954,7 +2998,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 ); } } @@ -3472,7 +3516,7 @@ void SVGActionWriter::ImplWriteActions( const GDIMetaFile& rMtf, if( mrExport.IsUsePositionedCharacters() ) { vcl::Font aFont = ImplSetCorrectFontHeight(); - mpContext->SetFontAttr( aFont ); + maAttributeWriter.SetFontAttr( aFont ); ImplWriteText( pA->GetPoint(), aText, NULL, 0 ); } else @@ -3495,7 +3539,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(), NULL, 0 ); } maTextWriter.writeTextPortion( pA->GetRect().TopLeft(), pA->GetText() ); @@ -3517,7 +3561,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 @@ -3542,7 +3586,7 @@ void SVGActionWriter::ImplWriteActions( const GDIMetaFile& rMtf, if( mrExport.IsUsePositionedCharacters() ) { vcl::Font aFont = ImplSetCorrectFontHeight(); - mpContext->SetFontAttr( aFont ); + maAttributeWriter.SetFontAttr( aFont ); ImplWriteText( pA->GetPoint(), aText, NULL, pA->GetWidth() ); } else @@ -3634,7 +3678,6 @@ void SVGActionWriter::WriteMetaFile( const Point& rPos100thmm, aMapMode.SetOrigin( aOffset += aMapMode.GetOrigin() ); mpVDev->SetMapMode( aMapMode ); - ImplAcquireContext(); mapCurShape.reset(); @@ -3648,7 +3691,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 498fda4..d1384bc 100644 --- a/filter/source/svg/svgwriter.hxx +++ b/filter/source/svg/svgwriter.hxx @@ -58,9 +58,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; @@ -79,8 +81,61 @@ using namespace ::com::sun::star::xml::sax; #define SVGWRITER_NO_SHAPE_COMMENTS 0x01000000 -// - SVGAttributeWriter - +// - SVGState - + +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; @@ -90,15 +145,10 @@ class SVGAttributeWriter { private: - vcl::Font maCurFont; - Color maCurLineColor; - Color maCurFillColor; SVGExport& mrExport; SVGFontExport& mrFontExport; + SVGState& mrCurrentState; SvXMLElementExport* mpElemFont; - SvXMLElementExport* mpElemPaint; - basegfx::B2DLineJoin maLineJoin; - com::sun::star::drawing::LineCap maLineCap; SVGAttributeWriter(); @@ -107,7 +157,7 @@ private: 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 ); @@ -175,7 +225,7 @@ class SVGTextWriter private: SVGExport& mrExport; - SVGAttributeWriter* mpContext; + SVGAttributeWriter& mrAttributeWriter; VclPtr<VirtualDevice> mpVDev; bool mbIsTextShapeStarted; Reference<XText> mrTextShape; @@ -208,7 +258,7 @@ class SVGTextWriter vcl::Font maParentFont; public: - SVGTextWriter( SVGExport& rExport ); + SVGTextWriter( SVGExport& rExport, SVGAttributeWriter& rAttributeWriter ); virtual ~SVGTextWriter(); sal_Int32 setTextPosition( const GDIMetaFile& rMtf, sal_uLong& nCurAction ); @@ -244,11 +294,6 @@ class SVGTextWriter mpTargetMapMode = &rTargetMapMode; } - void setContext( SVGAttributeWriter* pContext ) - { - mpContext = pContext; - } - void setTextShape( const Reference<XText>& rxText, const GDIMetaFile* pTextEmbeddedBitmapMtf ) { @@ -293,11 +338,12 @@ 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; @@ -306,23 +352,6 @@ private: bool mbIsPlaceholderShape; - SVGAttributeWriter* ImplAcquireContext() - { - maContextStack.push( mpContext = new SVGAttributeWriter( mrExport, mrFontExport ) ); - maTextWriter.setContext( mpContext ); - return mpContext; - } - void ImplReleaseContext() - { - if (!maContextStack.empty()) - { - delete maContextStack.top(); - maContextStack.pop(); - } - mpContext = (maContextStack.empty() ? NULL : 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; _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits