summaryrefslogtreecommitdiff
path: root/extensions/source/svg
diff options
context:
space:
mode:
Diffstat (limited to 'extensions/source/svg')
-rw-r--r--extensions/source/svg/makefile.mk67
-rw-r--r--extensions/source/svg/svgaction.cxx1458
-rw-r--r--extensions/source/svg/svgaction.hxx164
-rw-r--r--extensions/source/svg/svgcom.hxx82
-rw-r--r--extensions/source/svg/svgprinter.cxx328
-rw-r--r--extensions/source/svg/svgprinter.hxx67
-rw-r--r--extensions/source/svg/svguno.cxx128
-rw-r--r--extensions/source/svg/svgwriter.cxx175
-rw-r--r--extensions/source/svg/svgwriter.hxx60
9 files changed, 2529 insertions, 0 deletions
diff --git a/extensions/source/svg/makefile.mk b/extensions/source/svg/makefile.mk
new file mode 100644
index 000000000000..c46aede54920
--- /dev/null
+++ b/extensions/source/svg/makefile.mk
@@ -0,0 +1,67 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+PRJNAME=extensions
+TARGET=svg
+
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings ----------------------------------
+
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Files -------------------------------------
+
+SLOFILES= $(SLO)$/svgprinter.obj \
+ $(SLO)$/svguno.obj \
+ $(SLO)$/svgwriter.obj \
+ $(SLO)$/svgaction.obj
+
+# --- Library -----------------------------------
+
+SHL1TARGET=$(TARGET)$(DLLPOSTFIX)
+SHL1IMPLIB=i$(SHL1TARGET)
+
+SHL1VERSIONMAP=$(SOLARENV)/src/component.map
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+DEF1NAME=$(SHL1TARGET)
+
+SHL1STDLIBS=\
+ $(XMLOFFLIB) \
+ $(VCLLIB) \
+ $(TOOLSLIB) \
+ $(CPPUHELPERLIB) \
+ $(CPPULIB) \
+ $(SALLIB)
+
+SHL1LIBS= $(SLB)$/$(TARGET).lib
+
+# --- Targets ----------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/extensions/source/svg/svgaction.cxx b/extensions/source/svg/svgaction.cxx
new file mode 100644
index 000000000000..dc2c47ecb937
--- /dev/null
+++ b/extensions/source/svg/svgaction.cxx
@@ -0,0 +1,1458 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_extensions.hxx"
+
+#include "svgaction.hxx"
+#include <vcl/virdev.hxx>
+#include <vcl/cvtgrf.hxx>
+#include <vcl/metric.hxx>
+
+#undef _SVG_USE_NATIVE_TEXTDECORATION
+#undef _SVG_USE_TSPANS
+
+// -----------
+// - statics -
+// -----------
+
+static const char aXMLElemSVG[] = "svg";
+static const char aXMLElemG[] = "g";
+static const char aXMLElemDefs[] = "defs";
+static const char aXMLElemClipPath[] = "clipPath";
+static const char aXMLElemLine[] = "line";
+static const char aXMLElemRect[] = "rect";
+static const char aXMLElemEllipse[] = "ellipse";
+static const char aXMLElemPath[] = "path";
+static const char aXMLElemPolygon[] = "polygon";
+static const char aXMLElemPolyLine[] = "polyline";
+static const char aXMLElemText[] = "text";
+static const char aXMLElemTSpan[] = "tspan";
+static const char aXMLElemImage[] = "image";
+
+static const char aXMLAttrTransform[] = "transform";
+static const char aXMLAttrStyle[] = "style";
+static const char aXMLAttrId[] = "id";
+
+static const char aXMLAttrD[] = "d";
+static const char aXMLAttrX[] = "x";
+static const char aXMLAttrY[] = "y";
+static const char aXMLAttrX1[] = "x1";
+static const char aXMLAttrY1[] = "y1";
+static const char aXMLAttrX2[] = "x2";
+static const char aXMLAttrY2[] = "y2";
+static const char aXMLAttrCX[] = "cx";
+static const char aXMLAttrCY[] = "cy";
+static const char aXMLAttrRX[] = "rx";
+static const char aXMLAttrRY[] = "ry";
+static const char aXMLAttrWidth[] = "width";
+static const char aXMLAttrHeight[] = "height";
+static const char aXMLAttrPoints[] = "points";
+static const char aXMLAttrXLinkHRef[] = "xlink:href";
+
+static const sal_Unicode pBase64[] =
+{
+ //0 1 2 3 4 5 6 7
+ 'A','B','C','D','E','F','G','H', // 0
+ 'I','J','K','L','M','N','O','P', // 1
+ 'Q','R','S','T','U','V','W','X', // 2
+ 'Y','Z','a','b','c','d','e','f', // 3
+ 'g','h','i','j','k','l','m','n', // 4
+ 'o','p','q','r','s','t','u','v', // 5
+ 'w','x','y','z','0','1','2','3', // 6
+ '4','5','6','7','8','9','+','/' // 7
+};
+
+// --------------
+// - FastString -
+// --------------
+
+FastString::FastString( sal_uInt32 nInitLen, sal_uInt32 nIncrement ) :
+ mpBuffer( new sal_Unicode[ nInitLen * sizeof( sal_Unicode ) ] ),
+ mnBufLen( nInitLen ),
+ mnCurLen( 0 ),
+ mnBufInc( nIncrement ),
+ mnPartPos( 0 )
+{
+ DBG_ASSERT( nInitLen, "invalid initial length" );
+ DBG_ASSERT( nIncrement, "invalid increment" );
+}
+
+// -----------------------------------------------------------------------------
+
+FastString::FastString( sal_Char* pBufferForBase64Encoding, sal_uInt32 nBufLen ) :
+ mnBufInc( 2048 ),
+ mnPartPos( 0 )
+{
+ DBG_ASSERT( pBufferForBase64Encoding && nBufLen, "invalid arguments" );
+
+ const sal_uInt32 nQuadCount = nBufLen / 3;
+ const sal_uInt32 nRest = nBufLen % 3;
+
+ if( nQuadCount || nRest )
+ {
+ mnBufLen = mnCurLen = ( ( nQuadCount + ( nRest ? 1 : 0 ) ) << 2 );
+ mpBuffer = new sal_Unicode[ mnBufLen * sizeof( sal_Unicode ) ];
+
+ sal_Char* pTmpSrc = pBufferForBase64Encoding;
+ sal_Unicode* pTmpDst = mpBuffer;
+
+ for( sal_uInt32 i = 0; i < nQuadCount; i++ )
+ {
+ const sal_Int32 nA = *pTmpSrc++;
+ const sal_Int32 nB = *pTmpSrc++;
+ const sal_Int32 nC = *pTmpSrc++;
+
+ *pTmpDst++ = pBase64[ ( nA >> 2 ) & 0x3f ];
+ *pTmpDst++ = pBase64[ ( ( nA << 4 ) & 0x30 ) + ( ( nB >> 4 ) & 0xf ) ];
+ *pTmpDst++ = pBase64[ ( ( nB << 2 ) & 0x3c ) + ( ( nC >> 6 ) & 0x3 ) ];
+ *pTmpDst++ = pBase64[ nC & 0x3f ];
+ }
+
+ if( 1 == nRest )
+ {
+ const sal_Int32 nA = *pTmpSrc;
+
+ *pTmpDst++ = pBase64[ ( nA >> 2 ) & 0x3f ];
+ *pTmpDst++ = pBase64[ ( nA << 4 ) & 0x30 ];
+ *pTmpDst++ = '=';
+ *pTmpDst = '=';
+ }
+ else if( 2 == nRest )
+ {
+ const sal_Int32 nA = *pTmpSrc++;
+ const sal_Int32 nB = *pTmpSrc;
+
+ *pTmpDst++ = pBase64[ ( nA >> 2 ) & 0x3f ];
+ *pTmpDst++ = pBase64[ ( ( nA << 4 ) & 0x30 ) + ( ( nB >> 4 ) & 0xf ) ];
+ *pTmpDst++ = pBase64[ ( nB << 2 ) & 0x3c ];
+ *pTmpDst = '=';
+ }
+ }
+ else
+ {
+ mpBuffer = new sal_Unicode[ ( mnBufLen = 1 ) * sizeof( sal_Unicode ) ];
+ mnCurLen = 0;
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+FastString::~FastString()
+{
+ delete[] mpBuffer;
+}
+
+// -----------------------------------------------------------------------------
+
+FastString& FastString::operator+=( const NMSP_RTL::OUString& rStr )
+{
+ if( rStr.getLength() )
+ {
+ if( ( mnCurLen + rStr.getLength() ) > mnBufLen )
+ {
+ const sal_uInt32 nNewBufLen = ( mnBufLen + ( ( ( mnCurLen + rStr.getLength() ) - mnBufLen ) / mnBufInc + 1 ) * mnBufInc );
+ sal_Unicode* pNewBuffer = new sal_Unicode[ nNewBufLen * sizeof( sal_Unicode ) ];
+
+ memcpy( pNewBuffer, mpBuffer, mnBufLen * sizeof( sal_Unicode ) );
+ delete[] mpBuffer;
+ mpBuffer = pNewBuffer;
+ mnBufLen = nNewBufLen;
+ }
+
+ memcpy( mpBuffer + mnCurLen, rStr.getStr(), rStr.getLength() * sizeof( sal_Unicode ) );
+ mnCurLen += rStr.getLength();
+
+ if( maString.getLength() )
+ maString = NMSP_RTL::OUString();
+ }
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------------
+
+const NMSP_RTL::OUString& FastString::GetString() const
+{
+ if( !maString.getLength() && mnCurLen )
+ ( (FastString*) this )->maString = NMSP_RTL::OUString( mpBuffer, mnCurLen );
+
+ return maString;
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool FastString::GetFirstPartString( const sal_uInt32 nPartLen, NMSP_RTL::OUString& rPartString )
+{
+ const sal_uInt32 nLength = Min( mnCurLen, nPartLen );
+
+ mnPartPos = 0;
+
+ if( nLength )
+ {
+ rPartString = NMSP_RTL::OUString( mpBuffer, nLength );
+ mnPartPos = nLength;
+ }
+
+ return( rPartString.getLength() > 0 );
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool FastString::GetNextPartString( const sal_uInt32 nPartLen, NMSP_RTL::OUString& rPartString )
+{
+ if( mnPartPos < mnCurLen )
+ {
+ const sal_uInt32 nLength = Min( mnCurLen - mnPartPos, nPartLen );
+ rPartString = NMSP_RTL::OUString( mpBuffer + mnPartPos, nLength );
+ mnPartPos += nLength;
+ }
+ else
+ rPartString = NMSP_RTL::OUString();
+
+ return( rPartString.getLength() > 0 );
+}
+
+// ----------------------
+// - SVGAttributeWriter -
+// ----------------------
+
+SVGAttributeWriter::SVGAttributeWriter( SVGActionWriter& rParent, SvXMLExport& rExport ) :
+ mrParent( rParent ),
+ mrExport( rExport ),
+ mpElemFont( NULL ),
+ mpElemPaint( NULL )
+{
+}
+
+// -----------------------------------------------------------------------------
+
+SVGAttributeWriter::~SVGAttributeWriter()
+{
+ delete mpElemPaint;
+ delete mpElemFont;
+}
+
+// -----------------------------------------------------------------------------
+
+NMSP_RTL::OUString SVGAttributeWriter::GetFontStyle( const Font& rFont )
+{
+ FastString aStyle;
+
+ // font family
+ aStyle += B2UCONST( "font-family:" );
+ aStyle += NMSP_RTL::OUString( rFont.GetName().GetToken( 0, ';' ) );
+
+ // font size
+ aStyle += B2UCONST( ";" );
+ aStyle += B2UCONST( "font-size:" );
+ aStyle += mrParent.GetValueString( mrParent.ImplMap( Size( 0, rFont.GetHeight() ) ).Height(), mrParent.HasDoublePoints() );
+
+ // font style
+ if( rFont.GetItalic() != ITALIC_NONE )
+ {
+ aStyle += B2UCONST( ";" );
+ aStyle += B2UCONST( "font-style:" );
+
+ if( rFont.GetItalic() == ITALIC_OBLIQUE )
+ aStyle += B2UCONST( "oblique" );
+ else
+ aStyle += B2UCONST( "italic" );
+ }
+
+ // font weight
+ sal_Int32 nFontWeight;
+
+ switch( rFont.GetWeight() )
+ {
+ case WEIGHT_THIN: nFontWeight = 100; break;
+ case WEIGHT_ULTRALIGHT: nFontWeight = 200; break;
+ case WEIGHT_LIGHT: nFontWeight = 300; break;
+ case WEIGHT_SEMILIGHT: nFontWeight = 400; break;
+ case WEIGHT_NORMAL: nFontWeight = 400; break;
+ case WEIGHT_MEDIUM: nFontWeight = 500; break;
+ case WEIGHT_SEMIBOLD: nFontWeight = 600; break;
+ case WEIGHT_BOLD: nFontWeight = 700; break;
+ case WEIGHT_ULTRABOLD: nFontWeight = 800; break;
+ case WEIGHT_BLACK: nFontWeight = 900; break;
+ default: nFontWeight = 400; break;
+ }
+
+ aStyle += B2UCONST( ";" );
+ aStyle += B2UCONST( "font-weight:" );
+ aStyle += NMSP_RTL::OUString::valueOf( nFontWeight );
+
+ // !!!
+ // font-variant
+ // font-stretch
+ // font-size-adjust
+
+#ifdef _SVG_USE_NATIVE_TEXTDECORATION
+
+ if( rFont.GetUnderline() != UNDERLINE_NONE || rFont.GetStrikeout() != STRIKEOUT_NONE )
+ {
+ aStyle += B2UCONST( ";" );
+ aStyle += B2UCONST( "text-decoration:" );
+
+ if( rFont.GetUnderline() != UNDERLINE_NONE )
+ aStyle += B2UCONST( " underline" );
+
+ if( rFont.GetStrikeout() != STRIKEOUT_NONE )
+ aStyle += B2UCONST( " line-through" );
+ }
+
+#endif // _SVG_USE_NATIVE_TEXTDECORATION
+
+ return aStyle.GetString();
+}
+
+// -----------------------------------------------------------------------------
+
+NMSP_RTL::OUString SVGAttributeWriter::GetPaintStyle( const Color& rLineColor, const Color& rFillColor )
+{
+ FastString aStyle;
+
+ // line color
+ aStyle += B2UCONST( "stroke:" );
+
+ if( rLineColor.GetTransparency() == 255 )
+ aStyle += B2UCONST( "none" );
+ else
+ {
+ // line color value in rgb
+ aStyle += B2UCONST( "rgb(" );
+ aStyle += NMSP_RTL::OUString::valueOf( (sal_Int32) rLineColor.GetRed() );
+ aStyle += B2UCONST( "," );
+ aStyle += NMSP_RTL::OUString::valueOf( (sal_Int32) rLineColor.GetGreen() );
+ aStyle += B2UCONST( "," );
+ aStyle += NMSP_RTL::OUString::valueOf( (sal_Int32) rLineColor.GetBlue() );
+ aStyle += B2UCONST( ")" );
+
+ // line color opacity in percent if neccessary
+ if( rLineColor.GetTransparency() )
+ {
+ aStyle += B2UCONST( ";" );
+ aStyle += B2UCONST( "stroke-opacity:" );
+ aStyle += NMSP_RTL::OUString::valueOf( (sal_Int32) ( ( 255 - (double) rLineColor.GetTransparency() ) / 2.55 ) );
+ aStyle += B2UCONST( "%" );
+ }
+ }
+
+ // fill color
+ aStyle += B2UCONST( ";" );
+ aStyle += B2UCONST( "fill:" );
+
+ if( rFillColor.GetTransparency() == 255 )
+ aStyle += B2UCONST( "none" );
+ else
+ {
+ // fill color value in rgb
+ aStyle += B2UCONST( "rgb(" );
+ aStyle += NMSP_RTL::OUString::valueOf( (sal_Int32) rFillColor.GetRed() );
+ aStyle += B2UCONST( "," );
+ aStyle += NMSP_RTL::OUString::valueOf( (sal_Int32) rFillColor.GetGreen() );
+ aStyle += B2UCONST( "," );
+ aStyle += NMSP_RTL::OUString::valueOf( (sal_Int32) rFillColor.GetBlue() );
+ aStyle += B2UCONST( ")" );
+
+ // fill color opacity in percent if neccessary
+ if( rFillColor.GetTransparency() )
+ {
+ aStyle += B2UCONST( ";" );
+ aStyle += B2UCONST( "fill-opacity:" );
+ aStyle += NMSP_RTL::OUString::valueOf( (sal_Int32) ( ( 255 - (double) rFillColor.GetTransparency() ) / 2.55 ) );
+ aStyle += B2UCONST( "%" );
+ }
+ }
+
+ return aStyle.GetString();
+}
+
+// -----------------------------------------------------------------------------
+
+void SVGAttributeWriter::SetFontAttr( const Font& rFont )
+{
+ if( !mpElemFont || ( rFont != maCurFont ) )
+ {
+ delete mpElemPaint, mpElemPaint = NULL;
+ delete mpElemFont;
+ mrExport.AddAttribute( XML_NAMESPACE_NONE, aXMLAttrStyle, GetFontStyle( maCurFont = rFont ) );
+ mpElemFont = new SvXMLElementExport( mrExport, XML_NAMESPACE_NONE, aXMLElemG, TRUE, TRUE );
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void SVGAttributeWriter::SetPaintAttr( const Color& rLineColor, const Color& rFillColor )
+{
+ if( !mpElemPaint || ( rLineColor != maCurLineColor ) || ( rFillColor != maCurFillColor ) )
+ {
+ delete mpElemPaint;
+ mrExport.AddAttribute( XML_NAMESPACE_NONE, aXMLAttrStyle, GetPaintStyle( maCurLineColor = rLineColor, maCurFillColor = rFillColor ) );
+ mpElemPaint = new SvXMLElementExport( mrExport, XML_NAMESPACE_NONE, aXMLElemG, TRUE, TRUE );
+ }
+}
+
+// -------------------
+// - SVGActionWriter -
+// -------------------
+
+SVGActionWriter::SVGActionWriter( SvXMLExport& rExport, const GDIMetaFile& rMtf,
+ VirtualDevice* pParentVDev, sal_Bool bWriteDoublePoints ) :
+ mrExport( rExport ),
+ mrMtf( rMtf ),
+ mpContext( NULL ),
+ mnCurClipId( 1 ),
+ mbClipAttrChanged( sal_False ),
+ mbDoublePoints( bWriteDoublePoints )
+{
+ if( pParentVDev )
+ {
+ mpVDev = pParentVDev;
+ mbDestroyVDev = sal_False;
+ maTargetMapMode = mpVDev->GetMapMode();
+ }
+ else
+ {
+ mpVDev = new VirtualDevice;
+ mpVDev->EnableOutput( sal_False );
+ mbDestroyVDev = sal_True;
+ maTargetMapMode = MAP_100TH_MM;
+ }
+
+ mpVDev->Push();
+ mpVDev->SetMapMode( mrMtf.GetPrefMapMode() );
+ ImplWriteActions( mrMtf );
+ mpVDev->Pop();
+}
+
+// -----------------------------------------------------------------------------
+
+SVGActionWriter::~SVGActionWriter()
+{
+ DBG_ASSERT( !mpContext, "Not all contexts are closed" );
+
+ if( mbDestroyVDev )
+ delete mpVDev;
+}
+
+// -----------------------------------------------------------------------------
+
+long SVGActionWriter::ImplMap( sal_Int32 nVal ) const
+{
+ return ImplMap( Size( nVal, nVal ) ).Width();
+}
+
+// -----------------------------------------------------------------------------
+
+Point SVGActionWriter::ImplMap( const Point& rPt ) const
+{
+ return mpVDev->LogicToLogic( rPt, mpVDev->GetMapMode(), maTargetMapMode );
+}
+
+// -----------------------------------------------------------------------------
+
+Size SVGActionWriter::ImplMap( const Size& rSz ) const
+{
+ return mpVDev->LogicToLogic( rSz, mpVDev->GetMapMode(), maTargetMapMode );
+}
+
+// -----------------------------------------------------------------------------
+
+NMSP_RTL::OUString SVGActionWriter::GetValueString( sal_Int32 nVal, sal_Bool bDoublePoints )
+{
+ if( !bDoublePoints )
+ return NMSP_RTL::OUString::valueOf( nVal );
+ else
+ {
+ const double fPoints = nVal * 72.0 / 2540.0;
+ const sal_Int32 nInt = (sal_Int32) fPoints;
+
+ return( ( NMSP_RTL::OUString::valueOf( nInt ) +=
+ NMSP_RTL::OUString::valueOf( (sal_Unicode) '.' ) ) +=
+ NMSP_RTL::OUString::valueOf( labs( (sal_Int32) ( ( fPoints - nInt ) * 100.0 ) ) ) );
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void SVGActionWriter::ImplWriteLine( const Point& rPt1, const Point& rPt2, const Color* pLineColor,
+ const NMSP_RTL::OUString* pStyle )
+{
+ const Point aPt1( ImplMap( rPt1 ) );
+ const Point aPt2( ImplMap( rPt2 ) );
+
+ mrExport.AddAttribute( XML_NAMESPACE_NONE, aXMLAttrX1, GetValueString( aPt1.X(), mbDoublePoints ) );
+ mrExport.AddAttribute( XML_NAMESPACE_NONE, aXMLAttrY1, GetValueString( aPt1.Y(), mbDoublePoints ) );
+ mrExport.AddAttribute( XML_NAMESPACE_NONE, aXMLAttrX2, GetValueString( aPt2.X(), mbDoublePoints ) );
+ mrExport.AddAttribute( XML_NAMESPACE_NONE, aXMLAttrY2, GetValueString( aPt2.Y(), mbDoublePoints ) );
+
+ // add additional style if requested
+ if( pStyle )
+ mrExport.AddAttribute( XML_NAMESPACE_NONE, aXMLAttrStyle, *pStyle );
+
+ if( pLineColor )
+ {
+ // !!! mrExport.AddAttribute( XML_NAMESPACE_NONE, ... )
+ DBG_ERROR( "SVGActionWriter::ImplWriteLine: Line color not implemented" );
+ }
+
+ {
+ SvXMLElementExport aElem( mrExport, XML_NAMESPACE_NONE, aXMLElemLine, TRUE, TRUE );
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void SVGActionWriter::ImplWriteRect( const Rectangle& rRect, long nRadX, long nRadY,
+ const NMSP_RTL::OUString* pStyle )
+{
+ const Rectangle aRect( ImplMap( rRect ) );
+
+ mrExport.AddAttribute( XML_NAMESPACE_NONE, aXMLAttrX, GetValueString( aRect.Left(), mbDoublePoints ) );
+ mrExport.AddAttribute( XML_NAMESPACE_NONE, aXMLAttrY, GetValueString( aRect.Top(), mbDoublePoints ) );
+ mrExport.AddAttribute( XML_NAMESPACE_NONE, aXMLAttrWidth, GetValueString( aRect.GetWidth(), mbDoublePoints ) );
+ mrExport.AddAttribute( XML_NAMESPACE_NONE, aXMLAttrHeight, GetValueString( aRect.GetHeight(), mbDoublePoints ) );
+
+ if( nRadX )
+ mrExport.AddAttribute( XML_NAMESPACE_NONE, aXMLAttrRX, GetValueString( ImplMap( nRadX ), mbDoublePoints ) );
+
+ if( nRadY )
+ mrExport.AddAttribute( XML_NAMESPACE_NONE, aXMLAttrRY, GetValueString( ImplMap( nRadY ), mbDoublePoints ) );
+
+ // add additional style if requested
+ if( pStyle )
+ mrExport.AddAttribute( XML_NAMESPACE_NONE, aXMLAttrStyle, *pStyle );
+
+ {
+ SvXMLElementExport aElem( mrExport, XML_NAMESPACE_NONE, aXMLElemRect, TRUE, TRUE );
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void SVGActionWriter::ImplWriteEllipse( const Point& rCenter, long nRadX, long nRadY,
+ const NMSP_RTL::OUString* pStyle )
+{
+ const Point aCenter( ImplMap( rCenter ) );
+
+ mrExport.AddAttribute( XML_NAMESPACE_NONE, aXMLAttrCX, GetValueString( aCenter.X(), mbDoublePoints ) );
+ mrExport.AddAttribute( XML_NAMESPACE_NONE, aXMLAttrCY, GetValueString( aCenter.Y(), mbDoublePoints ) );
+ mrExport.AddAttribute( XML_NAMESPACE_NONE, aXMLAttrRX, GetValueString( ImplMap( nRadX ), mbDoublePoints ) );
+ mrExport.AddAttribute( XML_NAMESPACE_NONE, aXMLAttrRY, GetValueString( ImplMap( nRadY ), mbDoublePoints ) );
+
+ // add additional style if requested
+ if( pStyle )
+ mrExport.AddAttribute( XML_NAMESPACE_NONE, aXMLAttrStyle, *pStyle );
+
+ {
+ SvXMLElementExport aElem( mrExport, XML_NAMESPACE_NONE, aXMLElemEllipse, TRUE, TRUE );
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void SVGActionWriter::ImplWritePolygon( const Polygon& rPoly, sal_Bool bLineOnly,
+ const NMSP_RTL::OUString* pStyle )
+{
+ if( rPoly.GetSize() )
+ {
+ if( rPoly.HasFlags() )
+ ImplWritePolyPolygon( rPoly, bLineOnly, pStyle );
+ else
+ {
+ FastString aStyle;
+ FastString aPoints;
+ USHORT i = 0, nSize = rPoly.GetSize();
+ const NMSP_RTL::OUString aBlank( B2UCONST( " " ) );
+
+ // points
+ while( i < nSize )
+ {
+ const Point aPolyPoint( ImplMap( rPoly[ i ] ) );
+
+ aPoints += GetValueString( aPolyPoint.X(), mbDoublePoints );
+ aPoints += B2UCONST( "," );
+ aPoints += GetValueString( aPolyPoint.Y(), mbDoublePoints );
+
+ if( ++i < nSize )
+ aPoints += aBlank;
+ }
+
+ // style
+ if( bLineOnly )
+ {
+ aStyle += B2UCONST( "fill:none" );
+
+ if( pStyle )
+ {
+ aStyle += B2UCONST( ";" );
+ aStyle += *pStyle;
+ }
+ }
+ else if( pStyle )
+ aStyle += *pStyle;
+
+ // add point attribute
+ mrExport.AddAttribute( XML_NAMESPACE_NONE, aXMLAttrPoints, aPoints.GetString() );
+
+ // add style attribute
+ if( aStyle.GetLength() )
+ mrExport.AddAttribute( XML_NAMESPACE_NONE, aXMLAttrStyle, aStyle.GetString() );
+
+ {
+ // write polyline/polygon element
+ SvXMLElementExport aElem( mrExport, XML_NAMESPACE_NONE, bLineOnly ? aXMLElemPolyLine : aXMLElemPolygon, TRUE, TRUE );
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void SVGActionWriter::ImplWritePolyPolygon( const PolyPolygon& rPolyPoly, sal_Bool bLineOnly,
+ const NMSP_RTL::OUString* pStyle )
+{
+ if( rPolyPoly.Count() )
+ {
+ if( ( rPolyPoly.Count() == 1 ) && ( rPolyPoly[ 0 ].HasFlags() == sal_False ) )
+ ImplWritePolygon( rPolyPoly[ 0 ], bLineOnly, pStyle );
+ else
+ {
+ FastString aStyle;
+ FastString aPathData;
+ const NMSP_RTL::OUString aBlank( B2UCONST( " " ) );
+ const NMSP_RTL::OUString aComma( B2UCONST( "," ) );
+ Point aPolyPoint;
+
+ for( long i = 0, nCount = rPolyPoly.Count(); i < nCount; i++ )
+ {
+ const Polygon& rPoly = rPolyPoly[ (USHORT) i ];
+ USHORT n = 1, nSize = rPoly.GetSize();
+
+ if( nSize > 1 )
+ {
+ aPathData += B2UCONST( "M " );
+ aPathData += GetValueString( ( aPolyPoint = ImplMap( rPoly[ 0 ] ) ).X(), mbDoublePoints );
+ aPathData += aComma;
+ aPathData += GetValueString( aPolyPoint.Y(), mbDoublePoints );
+ sal_Char nCurrentMode = 0;
+
+ while( n < nSize )
+ {
+ aPathData += aBlank;
+ if ( ( rPoly.GetFlags( n ) == POLY_CONTROL ) && ( ( n + 2 ) < nSize ) )
+ {
+ if ( nCurrentMode != 'C' )
+ {
+ nCurrentMode = 'C';
+ aPathData += B2UCONST( "C " );
+ }
+ for ( int j = 0; j < 3; j++ )
+ {
+ if ( j )
+ aPathData += aBlank;
+ aPathData += GetValueString( ( aPolyPoint = ImplMap( rPoly[ n++ ] ) ).X(), mbDoublePoints );
+ aPathData += aComma;
+ aPathData += GetValueString( aPolyPoint.Y(), mbDoublePoints );
+ }
+ }
+ else
+ {
+ if ( nCurrentMode != 'L' )
+ {
+ nCurrentMode = 'L';
+ aPathData += B2UCONST( "L " );
+ }
+ aPathData += GetValueString( ( aPolyPoint = ImplMap( rPoly[ n++ ] ) ).X(), mbDoublePoints );
+ aPathData += aComma;
+ aPathData += GetValueString( aPolyPoint.Y(), mbDoublePoints );
+ }
+ }
+ aPathData += B2UCONST( " Z" );
+
+ if( i < ( nCount - 1 ) )
+ aPathData += aBlank;
+ }
+ }
+ if( bLineOnly )
+ {
+ aStyle += B2UCONST( "fill:none" );
+ if( pStyle )
+ aStyle += B2UCONST( ";" );
+ }
+ if( pStyle )
+ aStyle += *pStyle;
+
+ // add style attribute
+ if( aStyle.GetLength() )
+ mrExport.AddAttribute( XML_NAMESPACE_NONE, aXMLAttrStyle, aStyle.GetString() );
+
+ // add path data attribute
+ mrExport.AddAttribute( XML_NAMESPACE_NONE, aXMLAttrD, aPathData.GetString() );
+ {
+ // write polyline/polygon element
+ SvXMLElementExport aElem( mrExport, XML_NAMESPACE_NONE, aXMLElemPath, TRUE, TRUE );
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void SVGActionWriter::ImplWriteGradientEx( const PolyPolygon& rPolyPoly, const Gradient& rGradient,
+ const NMSP_RTL::OUString* pStyle )
+{
+ if( rPolyPoly.Count() )
+ {
+ SvXMLElementExport aElemG( mrExport, XML_NAMESPACE_NONE, aXMLElemG, TRUE, TRUE );
+ FastString aClipId;
+ FastString aClipStyle;
+
+ aClipId += B2UCONST( "clip" );
+ aClipId += NMSP_RTL::OUString::valueOf( ImplGetNextClipId() );
+
+ {
+ SvXMLElementExport aElemDefs( mrExport, XML_NAMESPACE_NONE, aXMLElemDefs, TRUE, TRUE );
+
+ mrExport.AddAttribute( XML_NAMESPACE_NONE, aXMLAttrId, aClipId.GetString() );
+
+ {
+ SvXMLElementExport aElemClipPath( mrExport, XML_NAMESPACE_NONE, aXMLElemClipPath, TRUE, TRUE );
+ ImplWritePolyPolygon( rPolyPoly, sal_False );
+ }
+ }
+
+ // create new context with clippath set
+ aClipStyle += B2UCONST( "clip-path:URL(#" );
+ aClipStyle += aClipId.GetString();
+ aClipStyle += B2UCONST( ")" );
+
+ mrExport.AddAttribute( XML_NAMESPACE_NONE, aXMLAttrStyle, aClipStyle.GetString() );
+
+ {
+ GDIMetaFile aTmpMtf;
+ SvXMLElementExport aElemG2( mrExport, XML_NAMESPACE_NONE, aXMLElemG, TRUE, TRUE );
+
+ mpVDev->AddGradientActions( rPolyPoly.GetBoundRect(), rGradient, aTmpMtf );
+ ImplWriteActions( aTmpMtf, pStyle );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void SVGActionWriter::ImplWriteText( const Point& rPos, const String& rText,
+ const sal_Int32* pDXArray, long nWidth,
+ const NMSP_RTL::OUString* pStyle )
+{
+ String aText( rText ); aText.EraseLeadingChars( ' ' );
+ UINT32 nLen = aText.Len(), i;
+
+ if( nLen )
+ {
+ Size aNormSize;
+ sal_Int32* pOwnArray;
+ sal_Int32* pDX;
+
+ // get text sizes
+ if( pDXArray )
+ {
+ pOwnArray = NULL;
+ aNormSize = Size( mpVDev->GetTextWidth( aText ), 0 );
+ pDX = const_cast< sal_Int32* >( pDXArray );
+ }
+ else
+ {
+ pOwnArray = new sal_Int32[ nLen ];
+ aNormSize = Size( mpVDev->GetTextArray( aText, pOwnArray ), 0 );
+ pDX = pOwnArray;
+ }
+
+ if( nLen > 1 )
+ {
+ aNormSize.Width() = pDX[ nLen - 2 ] + mpVDev->GetTextWidth( aText.GetChar( (USHORT) nLen - 1 ) );
+
+ if( nWidth && aNormSize.Width() && ( nWidth != aNormSize.Width() ) )
+ {
+ const double fFactor = (double) nWidth / aNormSize.Width();
+
+ for( i = 0; i < ( nLen - 1 ); i++ )
+ pDX[ i ] = FRound( pDX[ i ] * fFactor );
+ }
+ }
+
+ FastString aStyle;
+ const Font& rFont = mpVDev->GetFont();
+ const FontMetric aMetric( mpVDev->GetFontMetric() );
+ Point aBaseLinePos( rPos );
+ SvXMLElementExport* pTransform = NULL;
+
+ // leading whitespaces erased? => adjust position
+ if( nLen < rText.Len() )
+ {
+ aBaseLinePos.X() += mpVDev->GetTextWidth( ' ' ) * ( rText.Len() - nLen );
+ }
+
+ // always adjust text position to match baseline alignment
+ switch( rFont.GetAlign() )
+ {
+ case( ALIGN_TOP ):
+ aBaseLinePos.Y() += aMetric.GetAscent();
+ break;
+
+ case( ALIGN_BOTTOM ):
+ aBaseLinePos.Y() -= aMetric.GetDescent();
+ break;
+
+ default:
+ break;
+ }
+
+ // get mapped text position
+ const Point aPt( ImplMap( aBaseLinePos ) );
+
+ // if text is rotated, set transform at new g element
+ if( rFont.GetOrientation() )
+ {
+ String aTransform;
+
+ aTransform = NMSP_RTL::OUString::createFromAscii( "translate" );
+ aTransform += '(';
+ aTransform += String( GetValueString( aPt.X(), mbDoublePoints ) );
+ aTransform += ',';
+ aTransform += String( GetValueString( aPt.Y(), mbDoublePoints ) );
+ aTransform += ')';
+
+ aTransform += String( NMSP_RTL::OUString::createFromAscii( " rotate" ) );
+ aTransform += '(';
+ aTransform += String( NMSP_RTL::OUString::valueOf( rFont.GetOrientation() * -0.1 ) );
+ aTransform += ')';
+
+ aTransform += String( NMSP_RTL::OUString::createFromAscii( " translate" ) );
+ aTransform += '(';
+ aTransform += String( GetValueString( -aPt.X(), mbDoublePoints ) );
+ aTransform += ',';
+ aTransform += String( GetValueString( -aPt.Y(), mbDoublePoints ) );
+ aTransform += ')';
+
+ mrExport.AddAttribute( XML_NAMESPACE_NONE, aXMLAttrTransform, aTransform );
+ pTransform = new SvXMLElementExport( mrExport, XML_NAMESPACE_NONE, aXMLElemG, TRUE, TRUE );
+ }
+
+ // add additional style if requested
+ if( pStyle && pStyle->getLength() )
+ mrExport.AddAttribute( XML_NAMESPACE_NONE, aXMLAttrStyle, *pStyle );
+
+ // write text element
+#ifdef _SVG_USE_TSPANS
+ if( pDXArray )
+ {
+ SvXMLElementExport aElem( mrExport, XML_NAMESPACE_NONE, aXMLElemText, TRUE, TRUE );
+ FastString aTSpanX;
+ const NMSP_RTL::OUString aSpace( ' ' );
+ long i, nX, nCount;
+
+ aTSpanX += GetValueString( aPt.X(), mbDoublePoints );
+ aTSpanX += aSpace;
+
+ for( i = 0, nX = aPt.X(), nCount = ( nLen - 1 ); i < nCount; )
+ {
+ aTSpanX += GetValueString( aPt.X() + pDX[ i++ ], mbDoublePoints );
+ aTSpanX += aSpace;
+ }
+
+ mrExport.AddAttribute( XML_NAMESPACE_NONE, aXMLAttrX, aTSpanX.GetString() );
+ mrExport.AddAttribute( XML_NAMESPACE_NONE, aXMLAttrY, GetValueString( aPt.Y(), mbDoublePoints ) );
+
+ {
+ try
+ {
+ try
+ {
+ SvXMLElementExport aElem( mrExport, XML_NAMESPACE_NONE, aXMLElemTSpan, TRUE, TRUE );
+ mrExport.GetDocHandler()->characters( NMSP_RTL::OUString( UniString( aText ) ) );
+ }
+ catch( ::com::sun::star::xml::sax::SAXException& )
+ {
+ // string seems to contain invalid characters
+ }
+ }
+ }
+ }
+ else
+#endif
+ {
+ mrExport.AddAttribute( XML_NAMESPACE_NONE, aXMLAttrX, GetValueString( aPt.X(), mbDoublePoints ) );
+ mrExport.AddAttribute( XML_NAMESPACE_NONE, aXMLAttrY, GetValueString( aPt.Y(), mbDoublePoints ) );
+
+ try
+ {
+ SvXMLElementExport aElem( mrExport, XML_NAMESPACE_NONE, aXMLElemText, TRUE, TRUE );
+ mrExport.GetDocHandler()->characters( NMSP_RTL::OUString( UniString( aText ) ) );
+ }
+ catch( ::com::sun::star::xml::sax::SAXException& )
+ {
+ // string seems to contain invalid characters
+ }
+ }
+
+#ifndef _SVG_USE_NATIVE_TEXTDECORATION
+
+ // write strikeout if neccessary
+ if( ( rFont.GetStrikeout() != STRIKEOUT_NONE ) || ( rFont.GetUnderline() != UNDERLINE_NONE ) )
+ {
+ Polygon aPoly( 4 );
+ const long nLineHeight = Max( (long) FRound( aMetric.GetLineHeight() * 0.05 ), (long) 1 );
+
+ if( rFont.GetStrikeout() )
+ {
+ const long nYLinePos = aBaseLinePos.Y() - FRound( aMetric.GetAscent() * 0.26 );
+
+ aPoly[ 0 ].X() = aBaseLinePos.X(); aPoly[ 0 ].Y() = nYLinePos - ( nLineHeight >> 1 );
+ aPoly[ 1 ].X() = aBaseLinePos.X() + aNormSize.Width() - 1; aPoly[ 1 ].Y() = aPoly[ 0 ].Y();
+ aPoly[ 2 ].X() = aPoly[ 1 ].X(); aPoly[ 2 ].Y() = aPoly[ 0 ].Y() + nLineHeight - 1;
+ aPoly[ 3 ].X() = aPoly[ 0 ].X(); aPoly[ 3 ].Y() = aPoly[ 2 ].Y();
+
+ ImplWritePolygon( aPoly, FALSE );
+ }
+
+ if( rFont.GetUnderline() )
+ {
+ const long nYLinePos = aBaseLinePos.Y() + ( nLineHeight << 1 );
+
+ aPoly[ 0 ].X() = aBaseLinePos.X(); aPoly[ 0 ].Y() = nYLinePos - ( nLineHeight >> 1 );
+ aPoly[ 1 ].X() = aBaseLinePos.X() + aNormSize.Width() - 1; aPoly[ 1 ].Y() = aPoly[ 0 ].Y();
+ aPoly[ 2 ].X() = aPoly[ 1 ].X(); aPoly[ 2 ].Y() = aPoly[ 0 ].Y() + nLineHeight - 1;
+ aPoly[ 3 ].X() = aPoly[ 0 ].X(); aPoly[ 3 ].Y() = aPoly[ 2 ].Y();
+
+ ImplWritePolygon( aPoly, FALSE );
+ }
+ }
+
+#endif // _SVG_USE_NATIVE_TEXTDECORATION
+
+ delete[] pOwnArray;
+ delete pTransform;
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void SVGActionWriter::ImplWriteBmp( const BitmapEx& rBmpEx,
+ const Point& rPt, const Size& rSz,
+ const Point& rSrcPt, const Size& rSrcSz,
+ const NMSP_RTL::OUString* /*pStyle*/ )
+{
+ if( !!rBmpEx )
+ {
+ BitmapEx aBmpEx( rBmpEx );
+ Point aPoint = Point();
+ const Rectangle aBmpRect( aPoint, rBmpEx.GetSizePixel() );
+ const Rectangle aSrcRect( rSrcPt, rSrcSz );
+
+ if( aSrcRect != aBmpRect )
+ aBmpEx.Crop( aSrcRect );
+
+ if( !!aBmpEx )
+ {
+ SvMemoryStream aOStm( 65535, 65535 );
+
+ if( GraphicConverter::Export( aOStm, rBmpEx, CVT_PNG ) == ERRCODE_NONE )
+ {
+ const Point aPt( ImplMap( rPt ) );
+ const Size aSz( ImplMap( rSz ) );
+ FastString aImageData( (sal_Char*) aOStm.GetData(), aOStm.Tell() );
+ REF( NMSP_SAX::XExtendedDocumentHandler ) xExtDocHandler( mrExport.GetDocHandler(), NMSP_UNO::UNO_QUERY );
+
+ if( xExtDocHandler.is() )
+ {
+ static const sal_uInt32 nPartLen = 64;
+ const NMSP_RTL::OUString aSpace( ' ' );
+ const NMSP_RTL::OUString aLineFeed( NMSP_RTL::OUString::valueOf( (sal_Unicode) 0x0a ) );
+ NMSP_RTL::OUString aString;
+ NMSP_RTL::OUString aImageString;
+
+ aString = aLineFeed;
+ aString += B2UCONST( "<" );
+ aString += NMSP_RTL::OUString::createFromAscii( aXMLElemImage );
+ aString += aSpace;
+
+ aString += NMSP_RTL::OUString::createFromAscii( aXMLAttrX );
+ aString += B2UCONST( "=\"" );
+ aString += GetValueString( aPt.X(), mbDoublePoints );
+ aString += B2UCONST( "\" " );
+
+ aString += NMSP_RTL::OUString::createFromAscii( aXMLAttrY );
+ aString += B2UCONST( "=\"" );
+ aString += GetValueString( aPt.Y(), mbDoublePoints );
+ aString += B2UCONST( "\" " );
+
+ aString += NMSP_RTL::OUString::createFromAscii( aXMLAttrWidth );
+ aString += B2UCONST( "=\"" );
+ aString += GetValueString( aSz.Width(), mbDoublePoints );
+ aString += B2UCONST( "\" " );
+
+ aString += NMSP_RTL::OUString::createFromAscii( aXMLAttrHeight );
+ aString += B2UCONST( "=\"" );
+ aString += GetValueString( aSz.Height(), mbDoublePoints );
+ aString += B2UCONST( "\" " );
+
+ aString += NMSP_RTL::OUString::createFromAscii( aXMLAttrXLinkHRef );
+ aString += B2UCONST( "=\"data:image/png;base64," );
+
+ if( aImageData.GetFirstPartString( nPartLen, aImageString ) )
+ {
+ xExtDocHandler->unknown( aString += aImageString );
+
+ while( aImageData.GetNextPartString( nPartLen, aImageString ) )
+ {
+ xExtDocHandler->unknown( aLineFeed );
+ xExtDocHandler->unknown( aImageString );
+ }
+ }
+
+ xExtDocHandler->unknown( B2UCONST( "\"/>" ) );
+ }
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void SVGActionWriter::ImplWriteActions( const GDIMetaFile& rMtf, const NMSP_RTL::OUString* pStyle )
+{
+ ImplAcquireContext();
+
+ for( ULONG i = 0, nCount = rMtf.GetActionCount(); i < nCount; i++ )
+ {
+ const MetaAction* pAction = rMtf.GetAction( i );
+ const USHORT nType = pAction->GetType();
+
+ switch( nType )
+ {
+ case( META_PIXEL_ACTION ):
+ {
+ const MetaPixelAction* pA = (const MetaPixelAction*) pAction;
+
+ mpContext->SetPaintAttr( pA->GetColor(), pA->GetColor() );
+ ImplWriteLine( pA->GetPoint(), pA->GetPoint(), &pA->GetColor(), pStyle );
+ }
+ break;
+
+ case( META_POINT_ACTION ):
+ {
+ const MetaPointAction* pA = (const MetaPointAction*) pAction;
+
+ mpContext->SetPaintAttr( mpVDev->GetLineColor(), mpVDev->GetLineColor() );
+ ImplWriteLine( pA->GetPoint(), pA->GetPoint(), NULL, pStyle );
+ }
+ break;
+
+ case( META_LINE_ACTION ):
+ {
+ const MetaLineAction* pA = (const MetaLineAction*) pAction;
+
+ mpContext->SetPaintAttr( mpVDev->GetLineColor(), mpVDev->GetLineColor() );
+ ImplWriteLine( pA->GetStartPoint(), pA->GetEndPoint(), NULL, pStyle );
+ }
+ break;
+
+ case( META_RECT_ACTION ):
+ {
+ mpContext->SetPaintAttr( mpVDev->GetLineColor(), mpVDev->GetFillColor() );
+ ImplWriteRect( ( (const MetaRectAction*) pAction )->GetRect(), 0, 0, pStyle );
+ }
+ break;
+
+ case( META_ROUNDRECT_ACTION ):
+ {
+ const MetaRoundRectAction* pA = (const MetaRoundRectAction*) pAction;
+
+ mpContext->SetPaintAttr( mpVDev->GetLineColor(), mpVDev->GetFillColor() );
+ ImplWriteRect( pA->GetRect(), pA->GetHorzRound(), pA->GetVertRound(), pStyle );
+ }
+ break;
+
+ case( META_ELLIPSE_ACTION ):
+ {
+ const MetaEllipseAction* pA = (const MetaEllipseAction*) pAction;
+ const Rectangle& rRect = pA->GetRect();
+
+ mpContext->SetPaintAttr( mpVDev->GetLineColor(), mpVDev->GetFillColor() );
+ ImplWriteEllipse( rRect.Center(), rRect.GetWidth() >> 1, rRect.GetHeight() >> 1, pStyle );
+ }
+ break;
+
+ case( META_ARC_ACTION ):
+ case( META_PIE_ACTION ):
+ case( META_CHORD_ACTION ):
+ case( META_POLYGON_ACTION ):
+ {
+ Polygon aPoly;
+
+ switch( nType )
+ {
+ case( META_ARC_ACTION ):
+ {
+ const MetaArcAction* pA = (const MetaArcAction*) pAction;
+ aPoly = Polygon( pA->GetRect(), pA->GetStartPoint(), pA->GetEndPoint(), POLY_ARC );
+ }
+ break;
+
+ case( META_PIE_ACTION ):
+ {
+ const MetaPieAction* pA = (const MetaPieAction*) pAction;
+ aPoly = Polygon( pA->GetRect(), pA->GetStartPoint(), pA->GetEndPoint(), POLY_PIE );
+ }
+ break;
+
+ case( META_CHORD_ACTION ):
+ {
+ const MetaChordAction* pA = (const MetaChordAction*) pAction;
+ aPoly = Polygon( pA->GetRect(), pA->GetStartPoint(), pA->GetEndPoint(), POLY_CHORD );
+ }
+ break;
+
+ case( META_POLYGON_ACTION ):
+ aPoly = ( (const MetaPolygonAction*) pAction )->GetPolygon();
+ break;
+ }
+
+ if( aPoly.GetSize() )
+ {
+ mpContext->SetPaintAttr( mpVDev->GetLineColor(), mpVDev->GetFillColor() );
+ ImplWritePolygon( aPoly, sal_False, pStyle );
+ }
+ }
+ break;
+
+ case( META_POLYLINE_ACTION ):
+ {
+ const MetaPolyLineAction* pA = (const MetaPolyLineAction*) pAction;
+ const Polygon& rPoly = pA->GetPolygon();
+
+ if( rPoly.GetSize() )
+ {
+ mpContext->SetPaintAttr( mpVDev->GetLineColor(), mpVDev->GetFillColor() );
+ ImplWritePolygon( rPoly, sal_True, pStyle );
+ }
+ }
+ break;
+
+ case( META_POLYPOLYGON_ACTION ):
+ {
+ const MetaPolyPolygonAction* pA = (const MetaPolyPolygonAction*) pAction;
+ const PolyPolygon& rPolyPoly = pA->GetPolyPolygon();
+
+ if( rPolyPoly.Count() )
+ {
+ mpContext->SetPaintAttr( mpVDev->GetLineColor(), mpVDev->GetFillColor() );
+ ImplWritePolyPolygon( rPolyPoly, sal_False, pStyle );
+ }
+ }
+ break;
+
+ case( META_GRADIENT_ACTION ):
+ {
+ const MetaGradientAction* pA = (const MetaGradientAction*) pAction;
+ GDIMetaFile aTmpMtf;
+
+ mpVDev->AddGradientActions( pA->GetRect(), pA->GetGradient(), aTmpMtf );
+ ImplWriteActions( aTmpMtf, pStyle );
+ }
+ break;
+
+ case( META_GRADIENTEX_ACTION ):
+ {
+ const MetaGradientExAction* pA = (const MetaGradientExAction*) pAction;
+ ImplWriteGradientEx( pA->GetPolyPolygon(), pA->GetGradient(), pStyle );
+ }
+ break;
+
+ case META_HATCH_ACTION:
+ {
+ const MetaHatchAction* pA = (const MetaHatchAction*) pAction;
+ GDIMetaFile aTmpMtf;
+
+ mpVDev->AddHatchActions( pA->GetPolyPolygon(), pA->GetHatch(), aTmpMtf );
+ ImplWriteActions( aTmpMtf, pStyle );
+ }
+ break;
+
+ case( META_TRANSPARENT_ACTION ):
+ {
+ const MetaTransparentAction* pA = (const MetaTransparentAction*) pAction;
+ const PolyPolygon& rPolyPoly = pA->GetPolyPolygon();
+
+ if( rPolyPoly.Count() )
+ {
+ mpContext->SetPaintAttr( mpVDev->GetLineColor(), mpVDev->GetFillColor() );
+ ImplWritePolyPolygon( rPolyPoly, sal_False, pStyle );
+ }
+ }
+ break;
+
+ case( META_FLOATTRANSPARENT_ACTION ):
+ {
+ const MetaFloatTransparentAction* pA = (const MetaFloatTransparentAction*) pAction;
+ GDIMetaFile aTmpMtf( pA->GetGDIMetaFile() );
+ Point aSrcPt( aTmpMtf.GetPrefMapMode().GetOrigin() );
+ const Size aSrcSize( aTmpMtf.GetPrefSize() );
+ const Point aDestPt( pA->GetPoint() );
+ const Size aDestSize( pA->GetSize() );
+ const double fScaleX = aSrcSize.Width() ? (double) aDestSize.Width() / aSrcSize.Width() : 1.0;
+ const double fScaleY = aSrcSize.Height() ? (double) aDestSize.Height() / aSrcSize.Height() : 1.0;
+ long nMoveX, nMoveY;
+
+ if( fScaleX != 1.0 || fScaleY != 1.0 )
+ {
+ aTmpMtf.Scale( fScaleX, fScaleY );
+ aSrcPt.X() = FRound( aSrcPt.X() * fScaleX ), aSrcPt.Y() = FRound( aSrcPt.Y() * fScaleY );
+ }
+
+ nMoveX = aDestPt.X() - aSrcPt.X(), nMoveY = aDestPt.Y() - aSrcPt.Y();
+
+ if( nMoveX || nMoveY )
+ aTmpMtf.Move( nMoveX, nMoveY );
+
+ mpVDev->Push();
+ ImplWriteActions( aTmpMtf, pStyle );
+ mpVDev->Pop();
+ }
+ break;
+
+ case( META_EPS_ACTION ):
+ {
+ const MetaEPSAction* pA = (const MetaEPSAction*) pAction;
+ const GDIMetaFile aGDIMetaFile( pA->GetSubstitute() );
+ sal_Bool bFound = sal_False;
+
+ for( ULONG j = 0, nCount2 = aGDIMetaFile.GetActionCount(); ( j < nCount2 ) && !bFound; j++ )
+ {
+ const MetaAction* pSubstAct = aGDIMetaFile.GetAction( j );
+
+ if( pSubstAct->GetType() == META_BMPSCALE_ACTION )
+ {
+ bFound = sal_True;
+ const MetaBmpScaleAction* pBmpScaleAction = (const MetaBmpScaleAction*) pSubstAct;
+ mpContext->SetPaintAttr( mpVDev->GetLineColor(), mpVDev->GetFillColor() );
+ ImplWriteBmp( pBmpScaleAction->GetBitmap(),
+ pA->GetPoint(), pA->GetSize(),
+ Point(), pBmpScaleAction->GetBitmap().GetSizePixel(), pStyle );
+ }
+ }
+ }
+ break;
+
+ case( META_COMMENT_ACTION ):
+ {
+ const MetaCommentAction* pA = (const MetaCommentAction*) pAction;
+ String aSkipComment;
+
+ if( pA->GetComment().CompareIgnoreCaseToAscii( "XGRAD_SEQ_BEGIN" ) == COMPARE_EQUAL )
+ {
+ const MetaGradientExAction* pGradAction = NULL;
+ sal_Bool bDone = sal_False;
+
+ while( !bDone && ( ++i < nCount ) )
+ {
+ pAction = rMtf.GetAction( i );
+
+ if( pAction->GetType() == META_GRADIENTEX_ACTION )
+ pGradAction = (const MetaGradientExAction*) pAction;
+ else if( ( pAction->GetType() == META_COMMENT_ACTION ) &&
+ ( ( (const MetaCommentAction*) pAction )->GetComment().CompareIgnoreCaseToAscii( "XGRAD_SEQ_END" ) == COMPARE_EQUAL ) )
+ {
+ bDone = sal_True;
+ }
+ }
+
+ if( pGradAction )
+ ImplWriteGradientEx( pGradAction->GetPolyPolygon(), pGradAction->GetGradient(), pStyle );
+ }
+ }
+ break;
+
+ case( META_BMP_ACTION ):
+ {
+ const MetaBmpAction* pA = (const MetaBmpAction*) pAction;
+
+ mpContext->SetPaintAttr( mpVDev->GetLineColor(), mpVDev->GetFillColor() );
+ ImplWriteBmp( pA->GetBitmap(),
+ pA->GetPoint(), mpVDev->PixelToLogic( pA->GetBitmap().GetSizePixel() ),
+ Point(), pA->GetBitmap().GetSizePixel(), pStyle );
+ }
+ break;
+
+ case( META_BMPSCALE_ACTION ):
+ {
+ const MetaBmpScaleAction* pA = (const MetaBmpScaleAction*) pAction;
+
+ mpContext->SetPaintAttr( mpVDev->GetLineColor(), mpVDev->GetFillColor() );
+ ImplWriteBmp( pA->GetBitmap(),
+ pA->GetPoint(), pA->GetSize(),
+ Point(), pA->GetBitmap().GetSizePixel(), pStyle );
+ }
+ break;
+
+ case( META_BMPSCALEPART_ACTION ):
+ {
+ const MetaBmpScalePartAction* pA = (const MetaBmpScalePartAction*) pAction;
+
+ mpContext->SetPaintAttr( mpVDev->GetLineColor(), mpVDev->GetFillColor() );
+ ImplWriteBmp( pA->GetBitmap(),
+ pA->GetDestPoint(), pA->GetDestSize(),
+ pA->GetSrcPoint(), pA->GetSrcSize(), pStyle );
+ }
+ break;
+
+ case( META_BMPEX_ACTION ):
+ {
+ const MetaBmpExAction* pA = (const MetaBmpExAction*) pAction;
+
+ mpContext->SetPaintAttr( mpVDev->GetLineColor(), mpVDev->GetFillColor() );
+ ImplWriteBmp( pA->GetBitmapEx(),
+ pA->GetPoint(), mpVDev->PixelToLogic( pA->GetBitmapEx().GetSizePixel() ),
+ Point(), pA->GetBitmapEx().GetSizePixel(), pStyle );
+ }
+ break;
+
+ case( META_BMPEXSCALE_ACTION ):
+ {
+ const MetaBmpExScaleAction* pA = (const MetaBmpExScaleAction*) pAction;
+
+ mpContext->SetPaintAttr( mpVDev->GetLineColor(), mpVDev->GetFillColor() );
+ ImplWriteBmp( pA->GetBitmapEx(),
+ pA->GetPoint(), pA->GetSize(),
+ Point(), pA->GetBitmapEx().GetSizePixel(), pStyle );
+ }
+ break;
+
+ case( META_BMPEXSCALEPART_ACTION ):
+ {
+ const MetaBmpExScalePartAction* pA = (const MetaBmpExScalePartAction*) pAction;
+
+ mpContext->SetPaintAttr( mpVDev->GetLineColor(), mpVDev->GetFillColor() );
+ ImplWriteBmp( pA->GetBitmapEx(),
+ pA->GetDestPoint(), pA->GetDestSize(),
+ pA->GetSrcPoint(), pA->GetSrcSize(), pStyle );
+ }
+ break;
+
+ case( META_TEXT_ACTION ):
+ {
+ const MetaTextAction* pA = (const MetaTextAction*) pAction;
+
+ mpContext->SetFontAttr( mpVDev->GetFont() );
+ mpContext->SetPaintAttr( COL_TRANSPARENT, mpVDev->GetFont().GetColor() );
+ ImplWriteText( pA->GetPoint(), String( pA->GetText(), pA->GetIndex(), pA->GetLen() ), NULL, 0, pStyle );
+ }
+ break;
+
+ case( META_TEXTRECT_ACTION ):
+ {
+ const MetaTextRectAction* pA = (const MetaTextRectAction*) pAction;
+
+ mpContext->SetFontAttr( mpVDev->GetFont() );
+ mpContext->SetPaintAttr( COL_TRANSPARENT, mpVDev->GetFont().GetColor() );
+ ImplWriteText( pA->GetRect().TopLeft(), pA->GetText(), NULL, 0, pStyle );
+ }
+ break;
+
+ case( META_TEXTARRAY_ACTION ):
+ {
+ const MetaTextArrayAction* pA = (const MetaTextArrayAction*) pAction;
+ const Point aPos( ImplMap( pA->GetPoint() ) );
+
+ mpContext->SetFontAttr( mpVDev->GetFont() );
+ mpContext->SetPaintAttr( COL_TRANSPARENT, mpVDev->GetFont().GetColor() );
+ ImplWriteText( pA->GetPoint(), String( pA->GetText(), pA->GetIndex(), pA->GetLen() ), pA->GetDXArray(), 0, pStyle );
+ }
+ break;
+
+ case( META_STRETCHTEXT_ACTION ):
+ {
+ const MetaStretchTextAction* pA = (const MetaStretchTextAction*) pAction;
+
+ mpContext->SetFontAttr( mpVDev->GetFont() );
+ mpContext->SetPaintAttr( COL_TRANSPARENT, mpVDev->GetFont().GetColor() );
+ ImplWriteText( pA->GetPoint(), String( pA->GetText(), pA->GetIndex(), pA->GetLen() ), NULL, pA->GetWidth(), pStyle );
+ }
+ break;
+
+ case( META_CLIPREGION_ACTION ):
+ case( META_ISECTRECTCLIPREGION_ACTION ):
+ case( META_ISECTREGIONCLIPREGION_ACTION ):
+ case( META_MOVECLIPREGION_ACTION ):
+ {
+ ( (MetaAction*) pAction )->Execute( mpVDev );
+ mbClipAttrChanged = sal_True;
+ }
+ break;
+
+ case( META_REFPOINT_ACTION ):
+ case( META_MAPMODE_ACTION ):
+ case( META_LINECOLOR_ACTION ):
+ case( META_FILLCOLOR_ACTION ):
+ case( META_TEXTLINECOLOR_ACTION ):
+ case( META_TEXTFILLCOLOR_ACTION ):
+ case( META_TEXTCOLOR_ACTION ):
+ case( META_TEXTALIGN_ACTION ):
+ case( META_FONT_ACTION ):
+ case( META_PUSH_ACTION ):
+ case( META_POP_ACTION ):
+ {
+ ( (MetaAction*) pAction )->Execute( mpVDev );
+ }
+ break;
+
+ case( META_RASTEROP_ACTION ):
+ case( META_MASK_ACTION ):
+ case( META_MASKSCALE_ACTION ):
+ case( META_MASKSCALEPART_ACTION ):
+ case( META_WALLPAPER_ACTION ):
+ case( META_TEXTLINE_ACTION ):
+ case( META_LAYOUTMODE_ACTION ):
+ {
+ // !!! >>> we don't want to support these actions
+ }
+ break;
+
+#ifdef DBG_UTIL
+ default :
+ ByteString aDbgOut( "SVGActionWriter::ImplWriteActions: unsupported MetaAction #" );
+ aDbgOut.Append( ByteString::CreateFromInt32( nType ) );
+ DBG_ERROR( aDbgOut.GetBuffer() );
+ break;
+#endif
+ }
+ }
+
+ ImplReleaseContext();
+}
diff --git a/extensions/source/svg/svgaction.hxx b/extensions/source/svg/svgaction.hxx
new file mode 100644
index 000000000000..8e7bececb87d
--- /dev/null
+++ b/extensions/source/svg/svgaction.hxx
@@ -0,0 +1,164 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SVGACTION_HXX
+#define _SVGACTION_HXX
+
+#include "svgcom.hxx"
+
+// --------------
+// - FastString -
+// --------------
+
+class FastString
+{
+private:
+
+ NMSP_RTL::OUString maString;
+ sal_Unicode* mpBuffer;
+ sal_uInt32 mnBufLen;
+ sal_uInt32 mnCurLen;
+ sal_uInt32 mnBufInc;
+ sal_uInt32 mnPartPos;
+
+public:
+
+ FastString( sal_uInt32 nInitLen = 2048, sal_uInt32 nIncrement = 2048 );
+ FastString( sal_Char* pBufferForBase64Encoding, sal_uInt32 nBufLen );
+ ~FastString();
+
+ FastString& operator+=( const NMSP_RTL::OUString& rStr );
+
+ const NMSP_RTL::OUString& GetString() const;
+ sal_Bool GetFirstPartString( const sal_uInt32 nPartLen, NMSP_RTL::OUString& rPartString );
+ sal_Bool GetNextPartString( const sal_uInt32 nPartLen, NMSP_RTL::OUString& rPartString );
+
+ sal_uInt32 GetLength() const { return mnCurLen; }
+ void Clear() { mnCurLen = 0, maString = NMSP_RTL::OUString(); }
+};
+
+// ----------------------
+// - SVGAttributeWriter -
+// ----------------------
+
+class SVGActionWriter;
+
+class SVGAttributeWriter
+{
+private:
+
+ Font maCurFont;
+ Color maCurLineColor;
+ Color maCurFillColor;
+ SVGActionWriter& mrParent;
+ SvXMLExport& mrExport;
+ SvXMLElementExport* mpElemFont;
+ SvXMLElementExport* mpElemPaint;
+
+ SVGAttributeWriter();
+
+public:
+
+ SVGAttributeWriter( SVGActionWriter& rParent, SvXMLExport& rExport );
+ virtual ~SVGAttributeWriter();
+
+ NMSP_RTL::OUString GetFontStyle( const Font& rFont );
+ NMSP_RTL::OUString GetPaintStyle( const Color& rLineColor, const Color& rFillColor );
+
+ void SetFontAttr( const Font& rFont );
+ void SetPaintAttr( const Color& rLineColor, const Color& rFillColor );
+};
+
+// -------------------
+// - SVGActionWriter -
+// -------------------
+
+class SVGAttributeWriter;
+class SvXMLExport;
+class GDIMetaFile;
+
+class SVGActionWriter
+{
+ friend class SVGAttributeWriter;
+
+private:
+
+ Stack maContextStack;
+ SvXMLExport& mrExport;
+ const GDIMetaFile& mrMtf;
+ SVGAttributeWriter* mpContext;
+ VirtualDevice* mpVDev;
+ MapMode maTargetMapMode;
+ sal_Int32 mnCurClipId;
+ sal_Bool mbDestroyVDev;
+ sal_Bool mbPaintAttrChanged;
+ sal_Bool mbFontAttrChanged;
+ sal_Bool mbClipAttrChanged;
+ sal_Bool mbDoublePoints;
+
+ SVGAttributeWriter* ImplAcquireContext() { maContextStack.Push( mpContext = new SVGAttributeWriter( *this, mrExport ) ); return mpContext; }
+ void ImplReleaseContext() { delete (SVGAttributeWriter*) maContextStack.Pop(); mpContext = (SVGAttributeWriter*) maContextStack.Top(); }
+
+ long ImplMap( sal_Int32 nVal ) const;
+ Point ImplMap( const Point& rPt ) const;
+ Size ImplMap( const Size& rSz ) const;
+ inline Rectangle ImplMap( const Rectangle& rRect ) const { return Rectangle( ImplMap( rRect.TopLeft() ), ImplMap( rRect.GetSize() ) ); }
+
+ void ImplWriteLine( const Point& rPt1, const Point& rPt2, const Color* pLineColor = NULL, const NMSP_RTL::OUString* pStyle = NULL );
+ void ImplWriteRect( const Rectangle& rRect, long nRadX = 0, long nRadY = 0, const NMSP_RTL::OUString* pStyle = NULL );
+ void ImplWriteEllipse( const Point& rCenter, long nRadX, long nRadY, const NMSP_RTL::OUString* pStyle = NULL );
+ void ImplWritePolygon( const Polygon& rPoly, sal_Bool bLineOnly, const NMSP_RTL::OUString* pStyle = NULL );
+ void ImplWritePolyPolygon( const PolyPolygon& rPolyPoly, sal_Bool bLineOnly, const NMSP_RTL::OUString* pStyle = NULL );
+ void ImplWriteGradientEx( const PolyPolygon& rPolyPoly, const Gradient& rGradient, const NMSP_RTL::OUString* pStyle = NULL );
+ void ImplWriteText( const Point& rPos, const String& rText, const sal_Int32* pDXArray, long nWidth, const NMSP_RTL::OUString* pStyle = NULL );
+ void ImplWriteBmp( const BitmapEx& rBmpEx, const Point& rPt, const Size& rSz, const Point& rSrcPt, const Size& rSrcSz, const NMSP_RTL::OUString* pStyle = NULL );
+
+ void ImplCheckFontAttributes();
+ void ImplCheckPaintAttributes();
+
+ void ImplWriteActions( const GDIMetaFile& rMtf, const NMSP_RTL::OUString* pStyle = NULL );
+
+ sal_Int32 ImplGetNextClipId() { return mnCurClipId++; }
+
+ SVGActionWriter();
+
+public:
+
+ static NMSP_RTL::OUString GetValueString( sal_Int32 nVal, sal_Bool bDoublePoints );
+
+public:
+
+ SVGActionWriter( SvXMLExport& rExport, const GDIMetaFile& rMtf,
+ VirtualDevice* pParentVDev = NULL,
+ sal_Bool bWriteDoublePoints = sal_False );
+ virtual ~SVGActionWriter();
+
+ const VirtualDevice& GetVDev() const { return *mpVDev; }
+ BOOL HasDoublePoints() const { return mbDoublePoints; }
+};
+
+#endif
diff --git a/extensions/source/svg/svgcom.hxx b/extensions/source/svg/svgcom.hxx
new file mode 100644
index 000000000000..3e593ff3ccf6
--- /dev/null
+++ b/extensions/source/svg/svgcom.hxx
@@ -0,0 +1,82 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SVGCOM_HXX
+#define _SVGCOM_HXX
+
+#include <cppuhelper/weak.hxx>
+#ifndef __RTL_USTRING_HXX_
+#include <rtl/ustring.hxx>
+#endif
+#include <tools/debug.hxx>
+#include <tools/stream.hxx>
+#include <tools/string.hxx>
+#include <tools/urlobj.hxx>
+#include <tools/stack.hxx>
+#ifndef _SALBTYPE_HXX
+#include <vcl/salbtype.hxx>
+#endif
+#ifndef _GDIMTF_HXX
+#include <vcl/gdimtf.hxx>
+#endif
+#ifndef _METAACT_HXX
+#include <vcl/metaact.hxx>
+#endif
+
+#include <com/sun/star/uno/Reference.h>
+#include <com/sun/star/uno/RuntimeException.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/registry/XRegistryKey.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <com/sun/star/xml/sax/XDocumentHandler.hpp>
+#include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
+#include <com/sun/star/svg/XSVGWriter.hpp>
+#include <com/sun/star/svg/XSVGPrinter.hpp>
+#include <xmloff/xmlexp.hxx>
+#include <xmloff/nmspmap.hxx>
+
+// -----------------------------------------------------------------------------
+
+#define NMSP_CPPU cppu
+#define NMSP_RTL rtl
+#define NMSP_UNO com::sun::star::uno
+#define NMSP_LANG com::sun::star::lang
+#define NMSP_SAX com::sun::star::xml::sax
+#define NMSP_SVG com::sun::star::svg
+#define NMSP_REGISTRY com::sun::star::registry
+
+
+#define REF( _def_Obj ) NMSP_UNO::Reference< _def_Obj >
+#define SEQ( _def_Obj ) NMSP_UNO::Sequence< _def_Obj >
+#define ANY NMSP_UNO::Any
+#define B2UCONST( _def_pChar ) (NMSP_RTL::OUString(RTL_CONSTASCII_USTRINGPARAM(_def_pChar )))
+#define SVG_DTD_STRING B2UCONST( "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">" )
+
+#endif // _SYNCCOM_HXX
diff --git a/extensions/source/svg/svgprinter.cxx b/extensions/source/svg/svgprinter.cxx
new file mode 100644
index 000000000000..c7605a8af16d
--- /dev/null
+++ b/extensions/source/svg/svgprinter.cxx
@@ -0,0 +1,328 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_extensions.hxx"
+
+#define _RMPRINTER_EXT
+
+#include "svgprinter.hxx"
+#include "svgaction.hxx"
+#include <uno/mapping.hxx>
+#include <vcl/print.hxx>
+#include <vcl/virdev.hxx>
+
+static const char aXMLElemSVG[] = "svg";
+static const char aXMLElemMetaSVG[] = "staroffice:svgElementMeta";
+static const char aXMLElemDesc[] = "desc";
+static const char aXMLElemMeta[] = "metadata";
+static const char aXMLElemRect[] = "rect";
+
+static const char aXMLAttrMetaSVGOuter[] = "isOuterElement";
+static const char aXMLAttrMetaSVGPage[] = "isPageElement";
+static const char aXMLAttrViewBox[] = "viewBox";
+static const char aXMLAttrX[] = "x";
+static const char aXMLAttrY[] = "y";
+static const char aXMLAttrWidth[] = "width";
+static const char aXMLAttrHeight[] = "height";
+
+// ----------------
+// - SVGMtfExport -
+// ----------------
+
+class SVGPrinterExport : public SvXMLExport
+{
+private:
+
+ Printer maPrinter;
+ VirtualDevice* mpVDev;
+ SvXMLElementExport* mpOuterElement;
+ sal_uInt32 mnPage;
+
+ SVGPrinterExport();
+
+ SvXMLElementExport* ImplCreateSVGElement( const JobSetup& rSetup, Size& rOutputSize );
+ void ImplWriteMetaAttr( sal_Bool bOuter, sal_Bool bPage );
+
+protected:
+
+ virtual void _ExportMeta() {}
+ virtual void _ExportStyles( BOOL /*bUsed*/ ) {}
+ virtual void _ExportAutoStyles() {}
+ virtual void _ExportContent() {}
+ virtual void _ExportMasterStyles() {}
+ virtual sal_uInt32 exportDoc( enum ::xmloff::token::XMLTokenEnum eClass = ::xmloff::token::XML_TOKEN_INVALID ) { (void)eClass; return 0; }
+
+public:
+
+ // #110680#
+ SVGPrinterExport(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceFactory,
+ const REF( NMSP_SAX::XDocumentHandler )& rxHandler,
+ const JobSetup& rSetup,
+ const NMSP_RTL::OUString& rJobName,
+ sal_uInt32 nCopies,
+ sal_Bool bCollate );
+
+ virtual ~SVGPrinterExport();
+
+ virtual void writePage( const JobSetup& rJobSetup, const GDIMetaFile& rMtf );
+};
+
+// -----------------------------------------------------------------------------
+
+// #110680#
+SVGPrinterExport::SVGPrinterExport(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceFactory,
+ const REF( NMSP_SAX::XDocumentHandler )& rxHandler,
+ const JobSetup& rSetup,
+ const NMSP_RTL::OUString& rJobName,
+ sal_uInt32 /*nCopies*/,
+ sal_Bool /*bCollate*/ )
+: SvXMLExport( xServiceFactory, NMSP_RTL::OUString(), rxHandler ),
+ mpVDev( NULL ),
+ mnPage( 0 )
+{
+ maPrinter.SetJobSetup( rSetup );
+
+ GetDocHandler()->startDocument();
+
+ REF( NMSP_SAX::XExtendedDocumentHandler ) xExtDocHandler( GetDocHandler(), NMSP_UNO::UNO_QUERY );
+
+ if( xExtDocHandler.is() )
+ {
+ NMSP_RTL::OUString aString;
+ const NMSP_RTL::OUString aLineFeed( NMSP_RTL::OUString::valueOf( (sal_Unicode) 0x0a ) );
+
+ // intro
+ xExtDocHandler->unknown( ( aString = SVG_DTD_STRING ) += aLineFeed );
+ xExtDocHandler->unknown( ( aString = B2UCONST( "<!ELEMENT metadata (#PCDATA | staroffice:svgElementMeta)*> " ) += aLineFeed ) );
+ xExtDocHandler->unknown( ( aString = B2UCONST( "<!ELEMENT staroffice:svgElementMeta ANY> " ) += aLineFeed ) );
+ xExtDocHandler->unknown( ( aString = B2UCONST( "<!ATTLIST staroffice:svgElementMeta " ) += aLineFeed ) );
+
+ // ATTLIST
+ xExtDocHandler->unknown( ( aString = B2UCONST( "isOuterElement (true | false) \"false\" " ) += aLineFeed ) );
+ xExtDocHandler->unknown( ( aString = B2UCONST( "isPageElement (true | false) \"true\"" ) += aLineFeed ) );
+
+ // end of intro
+ xExtDocHandler->unknown( ( aString = B2UCONST( ">" ) += aLineFeed ) );
+ xExtDocHandler->unknown( ( aString = B2UCONST( "]>" ) ) );
+ }
+
+ // create outer element
+ Size aOutputSize;
+
+ mpOuterElement = ImplCreateSVGElement( rSetup, aOutputSize );
+
+ // write description
+ SvXMLElementExport* pDescElem = new SvXMLElementExport( *this, XML_NAMESPACE_NONE, aXMLElemDesc, TRUE, TRUE );
+ NMSP_RTL::OUString aDesc( B2UCONST( "document name: " ) );
+
+ GetDocHandler()->characters( aDesc += rJobName );
+ delete pDescElem;
+
+ // write meta attributes
+ ImplWriteMetaAttr( TRUE, FALSE );
+}
+
+// -----------------------------------------------------------------------------
+
+SVGPrinterExport::~SVGPrinterExport()
+{
+ delete mpOuterElement;
+ GetDocHandler()->endDocument();
+ delete mpVDev;
+}
+
+// -----------------------------------------------------------------------------
+
+SvXMLElementExport* SVGPrinterExport::ImplCreateSVGElement( const JobSetup& rSetup, Size& rOutputSize )
+{
+ NMSP_RTL::OUString aAttr;
+
+ delete mpVDev;
+ mpVDev = new VirtualDevice;
+ mpVDev->EnableOutput( FALSE );
+ mpVDev->SetMapMode( MAP_100TH_MM );
+ maPrinter.SetJobSetup( rSetup );
+
+ rOutputSize = maPrinter.PixelToLogic( maPrinter.GetOutputSizePixel(), mpVDev->GetMapMode() );
+
+ aAttr = SVGActionWriter::GetValueString( rOutputSize.Width(), sal_True );
+ AddAttribute( XML_NAMESPACE_NONE, aXMLAttrWidth, aAttr );
+
+ aAttr = SVGActionWriter::GetValueString( rOutputSize.Height(), sal_True );
+ AddAttribute( XML_NAMESPACE_NONE, aXMLAttrHeight, aAttr );
+
+ aAttr = B2UCONST( "0.0 0.0 " );
+ aAttr += SVGActionWriter::GetValueString( rOutputSize.Width(), sal_True );
+ aAttr += B2UCONST( " " );
+ aAttr += SVGActionWriter::GetValueString( rOutputSize.Height(), sal_True );
+ AddAttribute( XML_NAMESPACE_NONE, aXMLAttrViewBox, aAttr );
+
+ return( new SvXMLElementExport( *this, XML_NAMESPACE_NONE, aXMLElemSVG, TRUE, TRUE ) );
+}
+
+// -----------------------------------------------------------------------------
+
+void SVGPrinterExport::ImplWriteMetaAttr( sal_Bool bOuter, sal_Bool bPage )
+{
+ SvXMLElementExport aMetaData( *this, XML_NAMESPACE_NONE, aXMLElemMeta, TRUE, TRUE );
+ NMSP_RTL::OUString aAttr;
+
+ aAttr = bOuter ? B2UCONST( "true" ) : B2UCONST( "false" );
+ AddAttribute( XML_NAMESPACE_NONE, aXMLAttrMetaSVGOuter, aAttr );
+
+ aAttr = bPage ? B2UCONST( "true" ) : B2UCONST( "false" );
+ AddAttribute( XML_NAMESPACE_NONE, aXMLAttrMetaSVGPage, aAttr );
+
+ {
+ delete( new SvXMLElementExport( *this, XML_NAMESPACE_NONE, aXMLElemMetaSVG, TRUE, TRUE ) );
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void SVGPrinterExport::writePage( const JobSetup& rSetup, const GDIMetaFile& rMtf )
+{
+ Size aOutputSize;
+ NMSP_RTL::OUString aAttr;
+ SvXMLElementExport* pPageElem = ImplCreateSVGElement( rSetup, aOutputSize );
+
+ // write description
+ SvXMLElementExport* pDescElem = new SvXMLElementExport( *this, XML_NAMESPACE_NONE, aXMLElemDesc, TRUE, TRUE );
+ NMSP_RTL::OUString aDesc( B2UCONST( "page: " ) );
+
+ GetDocHandler()->characters( aDesc += NMSP_RTL::OUString::valueOf( (sal_Int32) ++mnPage ) );
+ delete pDescElem;
+
+ // write meta attributes
+ ImplWriteMetaAttr( FALSE, TRUE );
+
+ // write dummy rect element
+ aAttr = B2UCONST( "0.0" );
+ AddAttribute( XML_NAMESPACE_NONE, aXMLAttrX, aAttr );
+ AddAttribute( XML_NAMESPACE_NONE, aXMLAttrY, aAttr );
+
+ aAttr = SVGActionWriter::GetValueString( aOutputSize.Width(), sal_True );
+ AddAttribute( XML_NAMESPACE_NONE, aXMLAttrWidth, aAttr );
+
+ aAttr = SVGActionWriter::GetValueString( aOutputSize.Height(), sal_True );
+ AddAttribute( XML_NAMESPACE_NONE, aXMLAttrHeight, aAttr );
+
+ delete( new SvXMLElementExport( *this, XML_NAMESPACE_NONE, aXMLElemRect, TRUE, TRUE ) );
+ delete( new SVGActionWriter( *this, rMtf, mpVDev, TRUE ) );
+
+ delete pPageElem;
+}
+
+// --------------
+// - SVGPrinter -
+// --------------
+
+SVGPrinter::SVGPrinter( const REF( NMSP_LANG::XMultiServiceFactory )& rxMgr ) :
+ mxFact( rxMgr ),
+ mpWriter( NULL )
+{
+}
+
+// -----------------------------------------------------------------------------
+
+SVGPrinter::~SVGPrinter()
+{
+ delete mpWriter;
+}
+
+// -----------------------------------------------------------------------------
+
+
+ANY SAL_CALL SVGPrinter::queryInterface( const NMSP_UNO::Type & rType ) throw( NMSP_UNO::RuntimeException )
+{
+ const ANY aRet( NMSP_CPPU::queryInterface( rType, static_cast< NMSP_SVG::XSVGPrinter* >( this ) ) );
+
+ return( aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType ) );
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL SVGPrinter::acquire() throw()
+{
+ OWeakObject::acquire();
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL SVGPrinter::release() throw()
+{
+ OWeakObject::release();
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool SAL_CALL SVGPrinter::startJob( const REF( NMSP_SAX::XDocumentHandler )& rxHandler,
+ const SEQ( sal_Int8 )& rJobSetupSeq,
+ const NMSP_RTL::OUString& rJobName,
+ sal_uInt32 nCopies, sal_Bool bCollate ) throw( NMSP_UNO::RuntimeException )
+{
+ const sal_Bool bRet = ( mpWriter == NULL );
+
+ if( bRet )
+ {
+ SvMemoryStream aMemStm( (char*) rJobSetupSeq.getConstArray(), rJobSetupSeq.getLength(), STREAM_READ );
+ JobSetup aJobSetup;
+
+ aMemStm.SetCompressMode( COMPRESSMODE_FULL );
+ aMemStm >> aJobSetup;
+
+ const REF( NMSP_SAX::XDocumentHandler ) xDocumentHandler( rxHandler );
+
+ // #110680#
+ // mpWriter = new SVGPrinterExport( xDocumentHandler, aJobSetup, rJobName, nCopies, bCollate );
+ mpWriter = new SVGPrinterExport( mxFact, xDocumentHandler, aJobSetup, rJobName, nCopies, bCollate );
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL SVGPrinter::printPage( const SEQ( sal_Int8 )& rPrintPage ) throw( NMSP_UNO::RuntimeException )
+{
+ SvMemoryStream aMemStm( (char*) rPrintPage.getConstArray(), rPrintPage.getLength(), STREAM_READ );
+ PrinterPage aPage;
+
+ aMemStm.SetCompressMode( COMPRESSMODE_FULL );
+ aMemStm >> aPage;
+ mpWriter->writePage( aPage.GetJobSetup(), *aPage.GetGDIMetaFile() );
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL SVGPrinter::endJob() throw( NMSP_UNO::RuntimeException )
+{
+ delete mpWriter, mpWriter = NULL;
+}
diff --git a/extensions/source/svg/svgprinter.hxx b/extensions/source/svg/svgprinter.hxx
new file mode 100644
index 000000000000..743a86bc7a50
--- /dev/null
+++ b/extensions/source/svg/svgprinter.hxx
@@ -0,0 +1,67 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SVGPRINTER_HXX
+#define _SVGPRINTER_HXX
+
+#include "svgcom.hxx"
+
+// -------------
+// - SVGWriter -
+// -------------
+
+class SVGPrinterExport;
+
+class SVGPrinter : public NMSP_CPPU::OWeakObject, NMSP_SVG::XSVGPrinter
+{
+private:
+
+ REF( NMSP_LANG::XMultiServiceFactory ) mxFact;
+ SVGPrinterExport* mpWriter;
+
+ SVGPrinter();
+
+public:
+
+ SVGPrinter( const REF( NMSP_LANG::XMultiServiceFactory )& rxMgr );
+ virtual ~SVGPrinter();
+
+ // XInterface
+ virtual ANY SAL_CALL queryInterface( const NMSP_UNO::Type & rType ) throw( NMSP_UNO::RuntimeException );
+ virtual void SAL_CALL acquire() throw();
+ virtual void SAL_CALL release() throw();
+
+ // XSVGPrinter
+ virtual sal_Bool SAL_CALL startJob( const REF( NMSP_SAX::XDocumentHandler )& rxHandler,
+ const SEQ( sal_Int8 )& rJobSetup,
+ const NMSP_RTL::OUString& rJobName,
+ sal_uInt32 nCopies, sal_Bool bCollate ) throw( NMSP_UNO::RuntimeException );
+ virtual void SAL_CALL printPage( const SEQ( sal_Int8 )& rPrintPage ) throw( NMSP_UNO::RuntimeException );
+ virtual void SAL_CALL endJob() throw( NMSP_UNO::RuntimeException );
+};
+
+#endif
diff --git a/extensions/source/svg/svguno.cxx b/extensions/source/svg/svguno.cxx
new file mode 100644
index 000000000000..cb76e80d9319
--- /dev/null
+++ b/extensions/source/svg/svguno.cxx
@@ -0,0 +1,128 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_extensions.hxx"
+
+#include "svgcom.hxx"
+#include "svgwriter.hxx"
+#include "svgprinter.hxx"
+
+#include <cppuhelper/factory.hxx>
+#include <uno/mapping.hxx>
+
+// -------------------
+// - factory methods -
+// -------------------
+
+static REF( NMSP_UNO::XInterface ) SAL_CALL create_SVGWriter( const REF( NMSP_LANG::XMultiServiceFactory )& rxFact )
+{
+ return REF( NMSP_UNO::XInterface )( *new SVGWriter( rxFact ) );
+}
+
+// -----------------------------------------------------------------------------
+
+static REF( NMSP_UNO::XInterface ) SAL_CALL create_SVGPrinter( const REF( NMSP_LANG::XMultiServiceFactory )& rxFact )
+{
+ return REF( NMSP_UNO::XInterface )( *new SVGPrinter( rxFact ) );
+}
+
+// ------------------------------------------
+// - component_getImplementationEnvironment -
+// ------------------------------------------
+
+extern "C" void SAL_CALL component_getImplementationEnvironment( const sal_Char ** ppEnvTypeName, uno_Environment ** /*ppEnv*/ )
+{
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+
+// -----------------------
+// - component_writeInfo -
+// -----------------------
+
+extern "C" sal_Bool SAL_CALL component_writeInfo( void* /*pServiceManager*/, void* pRegistryKey )
+{
+ sal_Bool bRet = sal_False;
+
+ if( pRegistryKey )
+ {
+ try
+ {
+ REF( NMSP_REGISTRY::XRegistryKey ) xNewKey1(
+ static_cast< NMSP_REGISTRY::XRegistryKey* >( pRegistryKey )->createKey(
+ B2UCONST( "/com.sun.star.comp.extensions.SVGWriter/UNO/SERVICES/com.sun.star.svg.SVGWriter" ) ) );
+ REF( NMSP_REGISTRY::XRegistryKey ) xNewKey2(
+ static_cast< NMSP_REGISTRY::XRegistryKey* >( pRegistryKey )->createKey(
+ B2UCONST( "/com.sun.star.comp.extensions.SVGPrinter/UNO/SERVICES/com.sun.star.svg.SVGPrinter" ) ) );
+
+ bRet = sal_True;
+ }
+ catch( NMSP_REGISTRY::InvalidRegistryException& )
+ {
+ OSL_ENSURE( sal_False, "### InvalidRegistryException!" );
+ }
+ }
+
+ return bRet;
+}
+
+// ------------------------
+// - component_getFactory -
+// ------------------------
+
+extern "C" void* SAL_CALL component_getFactory( const sal_Char* pImplName, void* pServiceManager, void* /*pRegistryKey*/ )
+{
+ REF( NMSP_LANG::XSingleServiceFactory ) xFactory;
+ void* pRet = 0;
+
+ if( rtl_str_compare( pImplName, "com.sun.star.comp.extensions.SVGWriter" ) == 0 )
+ {
+ const NMSP_RTL::OUString aServiceName( B2UCONST( "com.sun.star.svg.SVGWriter" ) );
+
+ xFactory = REF( NMSP_LANG::XSingleServiceFactory )( NMSP_CPPU::createSingleFactory(
+ reinterpret_cast< NMSP_LANG::XMultiServiceFactory* >( pServiceManager ),
+ B2UCONST( "com.sun.star.comp.extensions.SVGWriter" ),
+ create_SVGWriter, SEQ( NMSP_RTL::OUString )( &aServiceName, 1 ) ) );
+ }
+ else if( rtl_str_compare( pImplName, "com.sun.star.comp.extensions.SVGPrinter" ) == 0 )
+ {
+ const NMSP_RTL::OUString aServiceName( B2UCONST( "com.sun.star.svg.SVGPrinter" ) );
+
+ xFactory = REF( NMSP_LANG::XSingleServiceFactory )( NMSP_CPPU::createSingleFactory(
+ reinterpret_cast< NMSP_LANG::XMultiServiceFactory* >( pServiceManager ),
+ B2UCONST( "com.sun.star.comp.extensions.SVGPrinter" ),
+ create_SVGPrinter, SEQ( NMSP_RTL::OUString )( &aServiceName, 1 ) ) );
+ }
+
+ if( xFactory.is() )
+ {
+ xFactory->acquire();
+ pRet = xFactory.get();
+ }
+
+ return pRet;
+}
diff --git a/extensions/source/svg/svgwriter.cxx b/extensions/source/svg/svgwriter.cxx
new file mode 100644
index 000000000000..0a2ae22242ff
--- /dev/null
+++ b/extensions/source/svg/svgwriter.cxx
@@ -0,0 +1,175 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_extensions.hxx"
+
+#include "svgwriter.hxx"
+#include "svgaction.hxx"
+#include <uno/mapping.hxx>
+
+// ----------------
+// - SVGMtfExport -
+// ----------------
+
+class SVGMtfExport : public SvXMLExport
+{
+private:
+
+ SVGMtfExport();
+
+protected:
+
+ virtual void _ExportMeta() {}
+ virtual void _ExportStyles( BOOL /*bUsed*/ ) {}
+ virtual void _ExportAutoStyles() {}
+ virtual void _ExportContent() {}
+ virtual void _ExportMasterStyles() {}
+ virtual sal_uInt32 exportDoc( enum ::xmloff::token::XMLTokenEnum /*eClass*/ ) { return 0; }
+
+public:
+
+ // #110680#
+ SVGMtfExport(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceFactory,
+ const REF( NMSP_SAX::XDocumentHandler )& rxHandler );
+
+ virtual ~SVGMtfExport();
+
+ virtual void writeMtf( const GDIMetaFile& rMtf );
+};
+
+// -----------------------------------------------------------------------------
+
+// #110680#
+SVGMtfExport::SVGMtfExport(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceFactory,
+ const REF( NMSP_SAX::XDocumentHandler )& rxHandler )
+: SvXMLExport( xServiceFactory, NMSP_RTL::OUString(), rxHandler )
+{
+ GetDocHandler()->startDocument();
+}
+
+// -----------------------------------------------------------------------------
+
+SVGMtfExport::~SVGMtfExport()
+{
+ GetDocHandler()->endDocument();
+}
+
+// -----------------------------------------------------------------------------
+
+void SVGMtfExport::writeMtf( const GDIMetaFile& rMtf )
+{
+ const Size aSize( OutputDevice::LogicToLogic( rMtf.GetPrefSize(), rMtf.GetPrefMapMode(), MAP_MM ) );
+ NMSP_RTL::OUString aAttr;
+ REF( NMSP_SAX::XExtendedDocumentHandler ) xExtDocHandler( GetDocHandler(), NMSP_UNO::UNO_QUERY );
+
+ if( xExtDocHandler.is() )
+ xExtDocHandler->unknown( SVG_DTD_STRING );
+
+ aAttr = NMSP_RTL::OUString::valueOf( aSize.Width() );
+ aAttr += B2UCONST( "mm" );
+ AddAttribute( XML_NAMESPACE_NONE, "width", aAttr );
+
+ aAttr = NMSP_RTL::OUString::valueOf( aSize.Height() );
+ aAttr += B2UCONST( "mm" );
+ AddAttribute( XML_NAMESPACE_NONE, "height", aAttr );
+
+ aAttr = B2UCONST( "0 0 " );
+ aAttr += NMSP_RTL::OUString::valueOf( aSize.Width() * 100L );
+ aAttr += B2UCONST( " " );
+ aAttr += NMSP_RTL::OUString::valueOf( aSize.Height() * 100L );
+ AddAttribute( XML_NAMESPACE_NONE, "viewBox", aAttr );
+
+ {
+ SvXMLElementExport aSVG( *this, XML_NAMESPACE_NONE, "svg", TRUE, TRUE );
+ SVGActionWriter* pWriter = new SVGActionWriter( *this, rMtf );
+
+ delete pWriter;
+ }
+}
+
+// -------------
+// - SVGWriter -
+// -------------
+
+SVGWriter::SVGWriter( const REF( NMSP_LANG::XMultiServiceFactory )& rxMgr ) :
+ mxFact( rxMgr )
+{
+}
+
+// -----------------------------------------------------------------------------
+
+SVGWriter::~SVGWriter()
+{
+}
+
+// -----------------------------------------------------------------------------
+
+
+ANY SAL_CALL SVGWriter::queryInterface( const NMSP_UNO::Type & rType ) throw( NMSP_UNO::RuntimeException )
+{
+ const ANY aRet( NMSP_CPPU::queryInterface( rType, static_cast< NMSP_SVG::XSVGWriter* >( this ) ) );
+
+ return( aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType ) );
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL SVGWriter::acquire() throw()
+{
+ OWeakObject::acquire();
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL SVGWriter::release() throw()
+{
+ OWeakObject::release();
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL SVGWriter::write( const REF( NMSP_SAX::XDocumentHandler )& rxDocHandler,
+ const SEQ( sal_Int8 )& rMtfSeq ) throw( NMSP_UNO::RuntimeException )
+{
+ SvMemoryStream aMemStm( (char*) rMtfSeq.getConstArray(), rMtfSeq.getLength(), STREAM_READ );
+ GDIMetaFile aMtf;
+
+ aMemStm.SetCompressMode( COMPRESSMODE_FULL );
+ aMemStm >> aMtf;
+
+ const REF( NMSP_SAX::XDocumentHandler ) xDocumentHandler( rxDocHandler );
+
+ // #110680#
+ // SVGMtfExport* pWriter = new SVGMtfExport( xDocumentHandler );
+ SVGMtfExport* pWriter = new SVGMtfExport( mxFact, xDocumentHandler );
+
+ pWriter->writeMtf( aMtf );
+ delete pWriter;
+}
diff --git a/extensions/source/svg/svgwriter.hxx b/extensions/source/svg/svgwriter.hxx
new file mode 100644
index 000000000000..dc1ea932ebe3
--- /dev/null
+++ b/extensions/source/svg/svgwriter.hxx
@@ -0,0 +1,60 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SVGWRITER_HXX
+#define _SVGWRITER_HXX
+
+#include "svgcom.hxx"
+
+// -------------
+// - SVGWriter -
+// -------------
+
+class SVGWriter : public NMSP_CPPU::OWeakObject, NMSP_SVG::XSVGWriter
+{
+private:
+
+ REF( NMSP_LANG::XMultiServiceFactory ) mxFact;
+
+ SVGWriter();
+
+public:
+
+ SVGWriter( const REF( NMSP_LANG::XMultiServiceFactory )& rxMgr );
+ virtual ~SVGWriter();
+
+ // XInterface
+ virtual ANY SAL_CALL queryInterface( const NMSP_UNO::Type & rType ) throw( NMSP_UNO::RuntimeException );
+ virtual void SAL_CALL acquire() throw();
+ virtual void SAL_CALL release() throw();
+
+ // XSVGWriter
+ virtual void SAL_CALL write( const REF( NMSP_SAX::XDocumentHandler )& rxDocHandler,
+ const SEQ( sal_Int8 )& rMtfSeq ) throw( NMSP_UNO::RuntimeException );
+};
+
+#endif