summaryrefslogtreecommitdiff
path: root/filter/source
diff options
context:
space:
mode:
authorMarco Cecchetti <marco.cecchetti@collabora.com>2016-06-17 16:22:47 +0200
committerMarco Cecchetti <mrcekets@gmail.com>2016-07-01 09:41:58 +0000
commit0f95f4f99cf09b597cb9d7b575aed7ba776919dd (patch)
treece6ef1c479dcfb27ee923d53e640a6b443a25a65 /filter/source
parent1085035078ac1546238be5de2ec47f70a8caffb1 (diff)
svg filter - rewritten context handling
Change-Id: I9c18f6ca641de2957cbbf8fd57035f5aa2e5c294 Reviewed-on: https://gerrit.libreoffice.org/26831 Reviewed-by: Marco Cecchetti <mrcekets@gmail.com> Tested-by: Marco Cecchetti <mrcekets@gmail.com>
Diffstat (limited to 'filter/source')
-rw-r--r--filter/source/svg/svgwriter.cxx115
-rw-r--r--filter/source/svg/svgwriter.hxx93
2 files changed, 144 insertions, 64 deletions
diff --git a/filter/source/svg/svgwriter.cxx b/filter/source/svg/svgwriter.cxx
index fc874c1b7835..7328886a4584 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 76c2df0b1592..5c3b75772ba9 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;