19e0fc027SAndrew Rist /**************************************************************
2cdf0e10cSrcweir *
39e0fc027SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
49e0fc027SAndrew Rist * or more contributor license agreements. See the NOTICE file
59e0fc027SAndrew Rist * distributed with this work for additional information
69e0fc027SAndrew Rist * regarding copyright ownership. The ASF licenses this file
79e0fc027SAndrew Rist * to you under the Apache License, Version 2.0 (the
89e0fc027SAndrew Rist * "License"); you may not use this file except in compliance
99e0fc027SAndrew Rist * with the License. You may obtain a copy of the License at
109e0fc027SAndrew Rist *
119e0fc027SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
129e0fc027SAndrew Rist *
139e0fc027SAndrew Rist * Unless required by applicable law or agreed to in writing,
149e0fc027SAndrew Rist * software distributed under the License is distributed on an
159e0fc027SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
169e0fc027SAndrew Rist * KIND, either express or implied. See the License for the
179e0fc027SAndrew Rist * specific language governing permissions and limitations
189e0fc027SAndrew Rist * under the License.
199e0fc027SAndrew Rist *
209e0fc027SAndrew Rist *************************************************************/
219e0fc027SAndrew Rist
229e0fc027SAndrew Rist
23cdf0e10cSrcweir
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_filter.hxx"
26cdf0e10cSrcweir
27cdf0e10cSrcweir #define ITEMID_FIELD 0
28cdf0e10cSrcweir
29cdf0e10cSrcweir #include "svgwriter.hxx"
30cdf0e10cSrcweir #include "svgfontexport.hxx"
31cdf0e10cSrcweir #include "svgfilter.hxx"
32cdf0e10cSrcweir #include "impsvgdialog.hxx"
33cdf0e10cSrcweir
34*33f678ddSArmin Le Grand #include <com/sun/star/graphic/XPrimitiveFactory2D.hpp>
35*33f678ddSArmin Le Grand
36cdf0e10cSrcweir #include <svx/unopage.hxx>
37cdf0e10cSrcweir #include <svx/unoshape.hxx>
38cdf0e10cSrcweir #include <svx/svdpage.hxx>
39cdf0e10cSrcweir #include <svx/svdoutl.hxx>
40cdf0e10cSrcweir #include <editeng/outliner.hxx>
41cdf0e10cSrcweir #include <editeng/flditem.hxx>
42cdf0e10cSrcweir #include <editeng/numitem.hxx>
43cdf0e10cSrcweir
44*33f678ddSArmin Le Grand using namespace ::com::sun::star::graphic;
45*33f678ddSArmin Le Grand using namespace ::com::sun::star::geometry;
46cdf0e10cSrcweir using ::rtl::OUString;
47cdf0e10cSrcweir
48cdf0e10cSrcweir // -------------
49cdf0e10cSrcweir // - SVGExport -
50cdf0e10cSrcweir // -------------
51cdf0e10cSrcweir
SVGExport(const::com::sun::star::uno::Reference<::com::sun::star::lang::XMultiServiceFactory> xServiceFactory,const Reference<XDocumentHandler> & rxHandler,const Sequence<PropertyValue> & rFilterData)52cdf0e10cSrcweir SVGExport::SVGExport(
53cdf0e10cSrcweir const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceFactory,
54cdf0e10cSrcweir const Reference< XDocumentHandler >& rxHandler,
55bac862b1SArmin Le Grand const Sequence< PropertyValue >& rFilterData )
56bac862b1SArmin Le Grand : SvXMLExport( xServiceFactory, MAP_100TH_MM )
57bac862b1SArmin Le Grand , mbTinyProfile ( sal_True )
58bac862b1SArmin Le Grand , mbTSpans ( sal_True )
59bac862b1SArmin Le Grand , mbEmbedFonts ( sal_False )
60bac862b1SArmin Le Grand , mbNativeTextDecoration( sal_True )
61bac862b1SArmin Le Grand , mbOpacity ( sal_True )
62bac862b1SArmin Le Grand , mbGradient ( sal_True )
63cdf0e10cSrcweir {
64bac862b1SArmin Le Grand for ( sal_Int32 i = 0, nCount = rFilterData.getLength(); i < nCount; i++ )
65bac862b1SArmin Le Grand {
66bac862b1SArmin Le Grand if ( rFilterData[ i ].Name == B2UCONST( SVG_PROP_TINYPROFILE ) )
67bac862b1SArmin Le Grand rFilterData[ i ].Value >>= mbTinyProfile;
68bac862b1SArmin Le Grand else if ( rFilterData[ i ].Name == B2UCONST( "TSpans" ) )
69bac862b1SArmin Le Grand rFilterData[ i ].Value >>= mbTSpans;
70bac862b1SArmin Le Grand else if ( rFilterData[ i ].Name == B2UCONST( SVG_PROP_EMBEDFONTS ) )
71bac862b1SArmin Le Grand rFilterData[ i ].Value >>= mbEmbedFonts;
72bac862b1SArmin Le Grand else if ( rFilterData[ i ].Name == B2UCONST( SVG_PROP_NATIVEDECORATION ) )
73bac862b1SArmin Le Grand rFilterData[ i ].Value >>= mbNativeTextDecoration;
74bac862b1SArmin Le Grand else if ( rFilterData[ i ].Name == B2UCONST( "GlyphPlacement" ) )
75bac862b1SArmin Le Grand rFilterData[ i ].Value >>= maGlyphPlacement;
76bac862b1SArmin Le Grand else if ( rFilterData[ i ].Name == B2UCONST( SVG_PROP_OPACITY ) )
77bac862b1SArmin Le Grand rFilterData[ i ].Value >>= mbOpacity;
78bac862b1SArmin Le Grand else if ( rFilterData[ i ].Name == B2UCONST( SVG_PROP_GRADIENT ) )
79bac862b1SArmin Le Grand rFilterData[ i ].Value >>= mbGradient;
80bac862b1SArmin Le Grand }
81bac862b1SArmin Le Grand if ( mbTinyProfile )
82bac862b1SArmin Le Grand mbNativeTextDecoration = sal_False;
83bac862b1SArmin Le Grand else
84bac862b1SArmin Le Grand {
85bac862b1SArmin Le Grand mbTSpans = sal_False;
86bac862b1SArmin Le Grand mbOpacity = sal_True;
87bac862b1SArmin Le Grand mbGradient = sal_True;
88bac862b1SArmin Le Grand }
89bac862b1SArmin Le Grand SetDocHandler( rxHandler );
90cdf0e10cSrcweir GetDocHandler()->startDocument();
91cdf0e10cSrcweir }
92cdf0e10cSrcweir
93cdf0e10cSrcweir // -----------------------------------------------------------------------------
94cdf0e10cSrcweir
~SVGExport()95cdf0e10cSrcweir SVGExport::~SVGExport()
96cdf0e10cSrcweir {
97cdf0e10cSrcweir GetDocHandler()->endDocument();
98cdf0e10cSrcweir }
99cdf0e10cSrcweir
100cdf0e10cSrcweir // -----------------------------------------------------------------------------
101cdf0e10cSrcweir
pushClip(const::basegfx::B2DPolyPolygon & rPolyPoly)102cdf0e10cSrcweir void SVGExport::pushClip( const ::basegfx::B2DPolyPolygon& rPolyPoly )
103cdf0e10cSrcweir {
104cdf0e10cSrcweir maClipList.push_front( ::basegfx::tools::correctOrientations( rPolyPoly ) );
105cdf0e10cSrcweir }
106cdf0e10cSrcweir
107cdf0e10cSrcweir // -----------------------------------------------------------------------------
108cdf0e10cSrcweir
popClip()109cdf0e10cSrcweir void SVGExport::popClip()
110cdf0e10cSrcweir {
111cdf0e10cSrcweir if( !maClipList.empty() )
112cdf0e10cSrcweir maClipList.pop_front();
113cdf0e10cSrcweir }
114cdf0e10cSrcweir
115cdf0e10cSrcweir // -----------------------------------------------------------------------------
116cdf0e10cSrcweir
hasClip() const117cdf0e10cSrcweir sal_Bool SVGExport::hasClip() const
118cdf0e10cSrcweir {
119cdf0e10cSrcweir return( !maClipList.empty() );
120cdf0e10cSrcweir }
121cdf0e10cSrcweir
122cdf0e10cSrcweir // -----------------------------------------------------------------------------
123cdf0e10cSrcweir
getCurClip() const124cdf0e10cSrcweir const ::basegfx::B2DPolyPolygon* SVGExport::getCurClip() const
125cdf0e10cSrcweir {
126cdf0e10cSrcweir return( maClipList.empty() ? NULL : &( *maClipList.begin() ) );
127cdf0e10cSrcweir }
128cdf0e10cSrcweir
129cdf0e10cSrcweir // ------------------------
130cdf0e10cSrcweir // - ObjectRepresentation -
131cdf0e10cSrcweir // ------------------------
132cdf0e10cSrcweir
ObjectRepresentation()133cdf0e10cSrcweir ObjectRepresentation::ObjectRepresentation() :
134cdf0e10cSrcweir mpMtf( NULL )
135cdf0e10cSrcweir {
136cdf0e10cSrcweir }
137cdf0e10cSrcweir
138cdf0e10cSrcweir // -----------------------------------------------------------------------------
139cdf0e10cSrcweir
ObjectRepresentation(const Reference<XInterface> & rxObject,const GDIMetaFile & rMtf)140cdf0e10cSrcweir ObjectRepresentation::ObjectRepresentation( const Reference< XInterface >& rxObject,
141cdf0e10cSrcweir const GDIMetaFile& rMtf ) :
142cdf0e10cSrcweir mxObject( rxObject ),
143cdf0e10cSrcweir mpMtf( new GDIMetaFile( rMtf ) )
144cdf0e10cSrcweir {
145cdf0e10cSrcweir }
146cdf0e10cSrcweir
147cdf0e10cSrcweir // -----------------------------------------------------------------------------
148cdf0e10cSrcweir
ObjectRepresentation(const ObjectRepresentation & rPresentation)149cdf0e10cSrcweir ObjectRepresentation::ObjectRepresentation( const ObjectRepresentation& rPresentation ) :
150cdf0e10cSrcweir mxObject( rPresentation.mxObject ),
151cdf0e10cSrcweir mpMtf( rPresentation.mpMtf ? new GDIMetaFile( *rPresentation.mpMtf ) : NULL )
152cdf0e10cSrcweir {
153cdf0e10cSrcweir }
154cdf0e10cSrcweir
155cdf0e10cSrcweir // -----------------------------------------------------------------------------
156cdf0e10cSrcweir
~ObjectRepresentation()157cdf0e10cSrcweir ObjectRepresentation::~ObjectRepresentation()
158cdf0e10cSrcweir {
159cdf0e10cSrcweir delete mpMtf;
160cdf0e10cSrcweir }
161cdf0e10cSrcweir
162cdf0e10cSrcweir // -----------------------------------------------------------------------------
163cdf0e10cSrcweir
operator =(const ObjectRepresentation & rPresentation)164cdf0e10cSrcweir ObjectRepresentation& ObjectRepresentation::operator=( const ObjectRepresentation& rPresentation )
165cdf0e10cSrcweir {
166cdf0e10cSrcweir mxObject = rPresentation.mxObject;
167cdf0e10cSrcweir delete mpMtf, ( mpMtf = rPresentation.mpMtf ? new GDIMetaFile( *rPresentation.mpMtf ) : NULL );
168cdf0e10cSrcweir
169cdf0e10cSrcweir return *this;
170cdf0e10cSrcweir }
171cdf0e10cSrcweir
172cdf0e10cSrcweir // -----------------------------------------------------------------------------
173cdf0e10cSrcweir
operator ==(const ObjectRepresentation & rPresentation) const174cdf0e10cSrcweir sal_Bool ObjectRepresentation::operator==( const ObjectRepresentation& rPresentation ) const
175cdf0e10cSrcweir {
176cdf0e10cSrcweir return( ( mxObject == rPresentation.mxObject ) &&
177cdf0e10cSrcweir ( *mpMtf == *rPresentation.mpMtf ) );
178cdf0e10cSrcweir }
179cdf0e10cSrcweir
180cdf0e10cSrcweir // -------------
181cdf0e10cSrcweir // - SVGFilter -
182cdf0e10cSrcweir // -------------
183cdf0e10cSrcweir
implExport(const Sequence<PropertyValue> & rDescriptor)184cdf0e10cSrcweir sal_Bool SVGFilter::implExport( const Sequence< PropertyValue >& rDescriptor )
185cdf0e10cSrcweir throw (RuntimeException)
186cdf0e10cSrcweir {
187cdf0e10cSrcweir Reference< XMultiServiceFactory > xServiceFactory( ::comphelper::getProcessServiceFactory() ) ;
188cdf0e10cSrcweir Reference< XOutputStream > xOStm;
189cdf0e10cSrcweir SvStream* pOStm = NULL;
190cdf0e10cSrcweir sal_Int32 nLength = rDescriptor.getLength();
191cdf0e10cSrcweir sal_Int32 nPageToExport = SVG_EXPORT_ALLPAGES;
192cdf0e10cSrcweir const PropertyValue* pValue = rDescriptor.getConstArray();
193cdf0e10cSrcweir sal_Bool bRet = sal_False;
194cdf0e10cSrcweir
195cdf0e10cSrcweir mnMasterSlideId = mnSlideId = mnDrawingGroupId = mnDrawingId = 0;
196cdf0e10cSrcweir maFilterData.realloc( 0 );
197cdf0e10cSrcweir
198cdf0e10cSrcweir for ( sal_Int32 i = 0 ; i < nLength; ++i)
199cdf0e10cSrcweir {
200cdf0e10cSrcweir if( pValue[ i ].Name.equalsAscii( "OutputStream" ) )
201cdf0e10cSrcweir pValue[ i ].Value >>= xOStm;
202cdf0e10cSrcweir else if( pValue[ i ].Name.equalsAscii( "FileName" ) )
203cdf0e10cSrcweir {
204cdf0e10cSrcweir ::rtl::OUString aFileName;
205cdf0e10cSrcweir
206cdf0e10cSrcweir pValue[ i ].Value >>= aFileName;
207cdf0e10cSrcweir pOStm = ::utl::UcbStreamHelper::CreateStream( aFileName, STREAM_WRITE | STREAM_TRUNC );
208cdf0e10cSrcweir
209cdf0e10cSrcweir if( pOStm )
210cdf0e10cSrcweir xOStm = Reference< XOutputStream >( new ::utl::OOutputStreamWrapper ( *pOStm ) );
211cdf0e10cSrcweir }
212cdf0e10cSrcweir else if( pValue[ i ].Name.equalsAscii( "PagePos" ) )
213cdf0e10cSrcweir {
214cdf0e10cSrcweir pValue[ i ].Value >>= nPageToExport;
215cdf0e10cSrcweir }
216cdf0e10cSrcweir else if( pValue[ i ].Name.equalsAscii( "FilterData" ) )
217cdf0e10cSrcweir {
218cdf0e10cSrcweir pValue[ i ].Value >>= maFilterData;
219cdf0e10cSrcweir }
220*33f678ddSArmin Le Grand else if( pValue[ i ].Name.equalsAscii( "ShapeSelection" ) )
221*33f678ddSArmin Le Grand {
222*33f678ddSArmin Le Grand // #124608# read selection if given
223*33f678ddSArmin Le Grand pValue[ i ].Value >>= maShapeSelection;
224*33f678ddSArmin Le Grand }
225cdf0e10cSrcweir }
226cdf0e10cSrcweir
227cdf0e10cSrcweir // if no filter data is given use stored/prepared ones
228cdf0e10cSrcweir if( !maFilterData.getLength() )
229cdf0e10cSrcweir {
230cdf0e10cSrcweir #ifdef _SVG_USE_CONFIG
231cdf0e10cSrcweir FilterConfigItem aCfgItem( String( RTL_CONSTASCII_USTRINGPARAM( SVG_EXPORTFILTER_CONFIGPATH ) ) );
232cdf0e10cSrcweir
233cdf0e10cSrcweir aCfgItem.ReadBool( String( RTL_CONSTASCII_USTRINGPARAM( SVG_PROP_TINYPROFILE ) ), sal_True );
234cdf0e10cSrcweir aCfgItem.ReadBool( String( RTL_CONSTASCII_USTRINGPARAM( SVG_PROP_EMBEDFONTS ) ), sal_True );
235cdf0e10cSrcweir aCfgItem.ReadBool( String( RTL_CONSTASCII_USTRINGPARAM( SVG_PROP_NATIVEDECORATION ) ), sal_False );
236cdf0e10cSrcweir aCfgItem.ReadString( String( RTL_CONSTASCII_USTRINGPARAM( SVG_PROP_NATIVEDECORATION ) ), B2UCONST( "xlist" ) );
237cdf0e10cSrcweir aCfgItem.ReadString( String( RTL_CONSTASCII_USTRINGPARAM( SVG_PROP_OPACITY ) ), sal_True );
238cdf0e10cSrcweir aCfgItem.ReadString( String( RTL_CONSTASCII_USTRINGPARAM( SVG_PROP_GRADIENT ) ), sal_True );
239cdf0e10cSrcweir
240cdf0e10cSrcweir maFilterData = aCfgItem.GetFilterData();
241cdf0e10cSrcweir #else
242cdf0e10cSrcweir maFilterData.realloc( 6 );
243cdf0e10cSrcweir
244cdf0e10cSrcweir maFilterData[ 0 ].Name = B2UCONST( SVG_PROP_TINYPROFILE );
245cdf0e10cSrcweir maFilterData[ 0 ].Value <<= (sal_Bool) sal_True;
246cdf0e10cSrcweir
247cdf0e10cSrcweir // font embedding
248cdf0e10cSrcweir const char* pSVGDisableFontEmbedding = getenv( "SVG_DISABLE_FONT_EMBEDDING" );
249cdf0e10cSrcweir
250cdf0e10cSrcweir maFilterData[ 1 ].Name = B2UCONST( SVG_PROP_EMBEDFONTS );
251cdf0e10cSrcweir maFilterData[ 1 ].Value <<= (sal_Bool) ( pSVGDisableFontEmbedding ? sal_False : sal_True );
252cdf0e10cSrcweir
253cdf0e10cSrcweir // Native decoration
254cdf0e10cSrcweir maFilterData[ 2 ].Name = B2UCONST( SVG_PROP_NATIVEDECORATION );
255cdf0e10cSrcweir maFilterData[ 2 ].Value <<= (sal_Bool) sal_False;
256cdf0e10cSrcweir
257cdf0e10cSrcweir // glyph placement
258cdf0e10cSrcweir const char* pSVGGlyphPlacement = getenv( "SVG_GLYPH_PLACEMENT" );
259cdf0e10cSrcweir
260cdf0e10cSrcweir maFilterData[ 3 ].Name = B2UCONST( SVG_PROP_GLYPHPLACEMENT );
261cdf0e10cSrcweir
262cdf0e10cSrcweir if( pSVGGlyphPlacement )
263cdf0e10cSrcweir maFilterData[ 3 ].Value <<= ::rtl::OUString::createFromAscii( pSVGGlyphPlacement );
264cdf0e10cSrcweir else
265cdf0e10cSrcweir maFilterData[ 3 ].Value <<= B2UCONST( "xlist" );
266cdf0e10cSrcweir
267cdf0e10cSrcweir // Tiny Opacity
268cdf0e10cSrcweir maFilterData[ 4 ].Name = B2UCONST( SVG_PROP_OPACITY );
269cdf0e10cSrcweir maFilterData[ 4 ].Value <<= (sal_Bool) sal_True;
270cdf0e10cSrcweir
271cdf0e10cSrcweir // Tiny Gradient
272cdf0e10cSrcweir maFilterData[ 5 ].Name = B2UCONST( SVG_PROP_GRADIENT );
273cdf0e10cSrcweir maFilterData[ 5 ].Value <<= (sal_Bool) sal_False;
274cdf0e10cSrcweir #endif
275cdf0e10cSrcweir }
276cdf0e10cSrcweir
277cdf0e10cSrcweir if( xOStm.is() && xServiceFactory.is() )
278cdf0e10cSrcweir {
279cdf0e10cSrcweir Reference< XMasterPagesSupplier > xMasterPagesSupplier( mxSrcDoc, UNO_QUERY );
280cdf0e10cSrcweir Reference< XDrawPagesSupplier > xDrawPagesSupplier( mxSrcDoc, UNO_QUERY );
281cdf0e10cSrcweir
282cdf0e10cSrcweir if( xMasterPagesSupplier.is() && xDrawPagesSupplier.is() )
283cdf0e10cSrcweir {
284cdf0e10cSrcweir Reference< XDrawPages > xMasterPages( xMasterPagesSupplier->getMasterPages(), UNO_QUERY );
285cdf0e10cSrcweir Reference< XDrawPages > xDrawPages( xDrawPagesSupplier->getDrawPages(), UNO_QUERY );
286cdf0e10cSrcweir
287cdf0e10cSrcweir if( xMasterPages.is() && xMasterPages->getCount() && xDrawPages.is() && xDrawPages->getCount() )
288cdf0e10cSrcweir {
289cdf0e10cSrcweir Reference< XDocumentHandler > xDocHandler( implCreateExportDocumentHandler( xOStm ) );
290cdf0e10cSrcweir
291cdf0e10cSrcweir if( xDocHandler.is() )
292cdf0e10cSrcweir {
293cdf0e10cSrcweir mbPresentation = Reference< XPresentationSupplier >( mxSrcDoc, UNO_QUERY ).is();
294cdf0e10cSrcweir mpObjects = new ObjectMap;
295cdf0e10cSrcweir
296cdf0e10cSrcweir // #110680#
297cdf0e10cSrcweir // mpSVGExport = new SVGExport( xDocHandler );
298cdf0e10cSrcweir mpSVGExport = new SVGExport( xServiceFactory, xDocHandler, maFilterData );
299cdf0e10cSrcweir
300cdf0e10cSrcweir if( nPageToExport < 0 || nPageToExport >= xDrawPages->getCount() )
301cdf0e10cSrcweir nPageToExport = SVG_EXPORT_ALLPAGES;
302cdf0e10cSrcweir
303cdf0e10cSrcweir try
304cdf0e10cSrcweir {
305cdf0e10cSrcweir const sal_Int32 nDefaultPage = ( ( SVG_EXPORT_ALLPAGES == nPageToExport ) ? 0 : nPageToExport );
306cdf0e10cSrcweir
307cdf0e10cSrcweir xDrawPages->getByIndex( nDefaultPage ) >>= mxDefaultPage;
308cdf0e10cSrcweir
309cdf0e10cSrcweir if( mxDefaultPage.is() )
310cdf0e10cSrcweir {
311cdf0e10cSrcweir SvxDrawPage* pSvxDrawPage = SvxDrawPage::getImplementation( mxDefaultPage );
312cdf0e10cSrcweir
313cdf0e10cSrcweir if( pSvxDrawPage )
314cdf0e10cSrcweir {
315cdf0e10cSrcweir mpDefaultSdrPage = pSvxDrawPage->GetSdrPage();
316cdf0e10cSrcweir mpSdrModel = mpDefaultSdrPage->GetModel();
317cdf0e10cSrcweir
318cdf0e10cSrcweir if( mpSdrModel )
319cdf0e10cSrcweir {
320cdf0e10cSrcweir SdrOutliner& rOutl = mpSdrModel->GetDrawOutliner(NULL);
321cdf0e10cSrcweir
322cdf0e10cSrcweir maOldFieldHdl = rOutl.GetCalcFieldValueHdl();
323cdf0e10cSrcweir rOutl.SetCalcFieldValueHdl( LINK( this, SVGFilter, CalcFieldHdl) );
324cdf0e10cSrcweir }
325cdf0e10cSrcweir }
326cdf0e10cSrcweir
327cdf0e10cSrcweir if( implCreateObjects( xMasterPages, xDrawPages, nPageToExport ) )
328cdf0e10cSrcweir {
329cdf0e10cSrcweir ObjectMap::const_iterator aIter( mpObjects->begin() );
330cdf0e10cSrcweir ::std::vector< ObjectRepresentation > aObjects( mpObjects->size() );
331cdf0e10cSrcweir sal_uInt32 nPos = 0;
332cdf0e10cSrcweir
333cdf0e10cSrcweir while( aIter != mpObjects->end() )
334cdf0e10cSrcweir {
335cdf0e10cSrcweir aObjects[ nPos++ ] = (*aIter).second;
336cdf0e10cSrcweir ++aIter;
337cdf0e10cSrcweir }
338cdf0e10cSrcweir
339cdf0e10cSrcweir mpSVGFontExport = new SVGFontExport( *mpSVGExport, aObjects );
340cdf0e10cSrcweir mpSVGWriter = new SVGActionWriter( *mpSVGExport, *mpSVGFontExport );
341cdf0e10cSrcweir
342cdf0e10cSrcweir bRet = implExportDocument( xMasterPages, xDrawPages, nPageToExport );
343cdf0e10cSrcweir }
344cdf0e10cSrcweir }
345cdf0e10cSrcweir }
346cdf0e10cSrcweir catch( ... )
347cdf0e10cSrcweir {
348cdf0e10cSrcweir delete mpSVGDoc, mpSVGDoc = NULL;
349cdf0e10cSrcweir DBG_ERROR( "Exception caught" );
350cdf0e10cSrcweir }
351cdf0e10cSrcweir
352cdf0e10cSrcweir if( mpSdrModel )
353cdf0e10cSrcweir mpSdrModel->GetDrawOutliner( NULL ).SetCalcFieldValueHdl( maOldFieldHdl );
354cdf0e10cSrcweir
355cdf0e10cSrcweir delete mpSVGWriter, mpSVGWriter = NULL;
356cdf0e10cSrcweir delete mpSVGExport, mpSVGExport = NULL;
357cdf0e10cSrcweir delete mpSVGFontExport, mpSVGFontExport = NULL;
358cdf0e10cSrcweir delete mpObjects, mpObjects = NULL;
359cdf0e10cSrcweir mbPresentation = sal_False;
360cdf0e10cSrcweir }
361cdf0e10cSrcweir }
362cdf0e10cSrcweir }
363cdf0e10cSrcweir }
364cdf0e10cSrcweir
365cdf0e10cSrcweir delete pOStm;
366cdf0e10cSrcweir
367cdf0e10cSrcweir return bRet;
368cdf0e10cSrcweir }
369cdf0e10cSrcweir
370cdf0e10cSrcweir // -----------------------------------------------------------------------------
371cdf0e10cSrcweir
implCreateExportDocumentHandler(const Reference<XOutputStream> & rxOStm)372cdf0e10cSrcweir Reference< XDocumentHandler > SVGFilter::implCreateExportDocumentHandler( const Reference< XOutputStream >& rxOStm )
373cdf0e10cSrcweir {
374cdf0e10cSrcweir Reference< XMultiServiceFactory > xMgr( ::comphelper::getProcessServiceFactory() );
375cdf0e10cSrcweir Reference< XDocumentHandler > xSaxWriter;
376cdf0e10cSrcweir
377cdf0e10cSrcweir if( xMgr.is() && rxOStm.is() )
378cdf0e10cSrcweir {
379cdf0e10cSrcweir xSaxWriter = Reference< XDocumentHandler >( xMgr->createInstance( B2UCONST( "com.sun.star.xml.sax.Writer" ) ), UNO_QUERY );
380cdf0e10cSrcweir
381cdf0e10cSrcweir if( xSaxWriter.is() )
382cdf0e10cSrcweir {
383cdf0e10cSrcweir Reference< XActiveDataSource > xActiveDataSource( xSaxWriter, UNO_QUERY );
384cdf0e10cSrcweir
385cdf0e10cSrcweir if( xActiveDataSource.is() )
386cdf0e10cSrcweir xActiveDataSource->setOutputStream( rxOStm );
387cdf0e10cSrcweir else
388cdf0e10cSrcweir xSaxWriter = NULL;
389cdf0e10cSrcweir }
390cdf0e10cSrcweir }
391cdf0e10cSrcweir
392cdf0e10cSrcweir return xSaxWriter;
393cdf0e10cSrcweir }
394cdf0e10cSrcweir
395cdf0e10cSrcweir // -----------------------------------------------------------------------------
396cdf0e10cSrcweir
implExportDocument(const Reference<XDrawPages> & rxMasterPages,const Reference<XDrawPages> & rxDrawPages,sal_Int32 nPageToExport)397cdf0e10cSrcweir sal_Bool SVGFilter::implExportDocument( const Reference< XDrawPages >& rxMasterPages,
398cdf0e10cSrcweir const Reference< XDrawPages >& rxDrawPages,
399cdf0e10cSrcweir sal_Int32 nPageToExport )
400cdf0e10cSrcweir {
401cdf0e10cSrcweir DBG_ASSERT( rxMasterPages.is() && rxDrawPages.is(),
402cdf0e10cSrcweir "SVGFilter::implExportDocument: invalid parameter" );
403cdf0e10cSrcweir
404cdf0e10cSrcweir OUString aAttr;
405*33f678ddSArmin Le Grand sal_Int32 nDocX = 0, nDocY = 0; // #124608#
406cdf0e10cSrcweir sal_Int32 nDocWidth = 0, nDocHeight = 0;
407cdf0e10cSrcweir sal_Int32 nVisible = -1, nVisibleMaster = -1;
408cdf0e10cSrcweir sal_Bool bRet = sal_False;
409cdf0e10cSrcweir const sal_Bool bSinglePage = ( rxDrawPages->getCount() == 1 ) || ( SVG_EXPORT_ALLPAGES != nPageToExport );
410cdf0e10cSrcweir const sal_Int32 nFirstPage = ( ( SVG_EXPORT_ALLPAGES == nPageToExport ) ? 0 : nPageToExport );
411cdf0e10cSrcweir sal_Int32 nCurPage = nFirstPage, nLastPage = ( bSinglePage ? nFirstPage : ( rxDrawPages->getCount() - 1 ) );
412cdf0e10cSrcweir
413cdf0e10cSrcweir const Reference< XPropertySet > xDefaultPagePropertySet( mxDefaultPage, UNO_QUERY );
414cdf0e10cSrcweir const Reference< XExtendedDocumentHandler > xExtDocHandler( mpSVGExport->GetDocHandler(), UNO_QUERY );
415*33f678ddSArmin Le Grand
416*33f678ddSArmin Le Grand // #124608#
417*33f678ddSArmin Le Grand mbExportSelection = maShapeSelection.is() && maShapeSelection->getCount();
418*33f678ddSArmin Le Grand
419*33f678ddSArmin Le Grand if(xDefaultPagePropertySet.is())
420*33f678ddSArmin Le Grand {
421*33f678ddSArmin Le Grand xDefaultPagePropertySet->getPropertyValue(B2UCONST("Width")) >>= nDocWidth;
422*33f678ddSArmin Le Grand xDefaultPagePropertySet->getPropertyValue(B2UCONST("Height")) >>= nDocHeight;
423*33f678ddSArmin Le Grand }
424*33f678ddSArmin Le Grand
425*33f678ddSArmin Le Grand if(mbExportSelection)
426*33f678ddSArmin Le Grand {
427*33f678ddSArmin Le Grand // #124608# create BoundRange and set nDocX, nDocY, nDocWidth and nDocHeight
428*33f678ddSArmin Le Grand basegfx::B2DRange aShapeRange;
429*33f678ddSArmin Le Grand
430*33f678ddSArmin Le Grand Reference< XPrimitiveFactory2D > xPrimitiveFactory(
431*33f678ddSArmin Le Grand mxMSF->createInstance(
432*33f678ddSArmin Le Grand String(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.graphic.PrimitiveFactory2D"))),
433*33f678ddSArmin Le Grand UNO_QUERY);
434*33f678ddSArmin Le Grand
435*33f678ddSArmin Le Grand // use XPrimitiveFactory2D and go the way over getting the primitives; this
436*33f678ddSArmin Le Grand // will give better precision (doubles) and be based on the true object
437*33f678ddSArmin Le Grand // geometry. If needed aViewInformation may be expanded to carry a view
438*33f678ddSArmin Le Grand // resolution for which to prepare the geometry.
439*33f678ddSArmin Le Grand if(xPrimitiveFactory.is())
440*33f678ddSArmin Le Grand {
441*33f678ddSArmin Le Grand Reference< XShape > xShapeCandidate;
442*33f678ddSArmin Le Grand const Sequence< PropertyValue > aViewInformation;
443*33f678ddSArmin Le Grand const Sequence< PropertyValue > aParams;
444*33f678ddSArmin Le Grand
445*33f678ddSArmin Le Grand for(sal_Int32 a(0); a < maShapeSelection->getCount(); a++)
446*33f678ddSArmin Le Grand {
447*33f678ddSArmin Le Grand if((maShapeSelection->getByIndex(a) >>= xShapeCandidate) && xShapeCandidate.is())
448*33f678ddSArmin Le Grand {
449*33f678ddSArmin Le Grand const Sequence< Reference< XPrimitive2D > > aPrimitiveSequence(
450*33f678ddSArmin Le Grand xPrimitiveFactory->createPrimitivesFromXShape( xShapeCandidate, aParams ));
451*33f678ddSArmin Le Grand const sal_Int32 nCount(aPrimitiveSequence.getLength());
452*33f678ddSArmin Le Grand
453*33f678ddSArmin Le Grand for(sal_Int32 nIndex = 0; nIndex < nCount; nIndex++)
454*33f678ddSArmin Le Grand {
455*33f678ddSArmin Le Grand const RealRectangle2D aRect(aPrimitiveSequence[nIndex]->getRange(aViewInformation));
456*33f678ddSArmin Le Grand
457*33f678ddSArmin Le Grand aShapeRange.expand(basegfx::B2DTuple(aRect.X1, aRect.Y1));
458*33f678ddSArmin Le Grand aShapeRange.expand(basegfx::B2DTuple(aRect.X2, aRect.Y2));
459*33f678ddSArmin Le Grand }
460*33f678ddSArmin Le Grand }
461*33f678ddSArmin Le Grand }
462*33f678ddSArmin Le Grand }
463*33f678ddSArmin Le Grand
464*33f678ddSArmin Le Grand if(!aShapeRange.isEmpty())
465*33f678ddSArmin Le Grand {
466*33f678ddSArmin Le Grand nDocX = basegfx::fround(aShapeRange.getMinX());
467*33f678ddSArmin Le Grand nDocY = basegfx::fround(aShapeRange.getMinY());
468*33f678ddSArmin Le Grand nDocWidth = basegfx::fround(aShapeRange.getWidth());
469*33f678ddSArmin Le Grand nDocHeight = basegfx::fround(aShapeRange.getHeight());
470*33f678ddSArmin Le Grand }
471*33f678ddSArmin Le Grand }
472cdf0e10cSrcweir
473cdf0e10cSrcweir if( xExtDocHandler.is() && !mpSVGExport->IsUseTinyProfile() )
474cdf0e10cSrcweir {
475cdf0e10cSrcweir xExtDocHandler->unknown( SVG_DTD_STRING );
476cdf0e10cSrcweir }
477cdf0e10cSrcweir
478cdf0e10cSrcweir mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "version", B2UCONST( "1.2" ) );
479cdf0e10cSrcweir
480cdf0e10cSrcweir if( mpSVGExport->IsUseTinyProfile() )
481cdf0e10cSrcweir mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "baseProfile", B2UCONST( "tiny" ) );
482cdf0e10cSrcweir
483cdf0e10cSrcweir #ifdef _SVG_WRITE_EXTENTS
484cdf0e10cSrcweir aAttr = OUString::valueOf( nDocWidth * 0.01 );
485cdf0e10cSrcweir aAttr += B2UCONST( "mm" );
486cdf0e10cSrcweir mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "width", aAttr );
487cdf0e10cSrcweir
488cdf0e10cSrcweir aAttr = OUString::valueOf( nDocHeight * 0.01 );
489cdf0e10cSrcweir aAttr += B2UCONST( "mm" );
490cdf0e10cSrcweir mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "height", aAttr );
491cdf0e10cSrcweir #endif
492cdf0e10cSrcweir
493*33f678ddSArmin Le Grand // #124608# set viewBox explicitely to the exported content
494*33f678ddSArmin Le Grand if(mbExportSelection)
495*33f678ddSArmin Le Grand {
496*33f678ddSArmin Le Grand aAttr = OUString::valueOf( nDocX );
497*33f678ddSArmin Le Grand aAttr += B2UCONST( " " );
498*33f678ddSArmin Le Grand aAttr += OUString::valueOf( nDocY );
499*33f678ddSArmin Le Grand aAttr += B2UCONST( " " );
500*33f678ddSArmin Le Grand }
501*33f678ddSArmin Le Grand else
502*33f678ddSArmin Le Grand {
503*33f678ddSArmin Le Grand aAttr = B2UCONST( "0 0 " );
504*33f678ddSArmin Le Grand }
505*33f678ddSArmin Le Grand
506cdf0e10cSrcweir aAttr += OUString::valueOf( nDocWidth );
507cdf0e10cSrcweir aAttr += B2UCONST( " " );
508cdf0e10cSrcweir aAttr += OUString::valueOf( nDocHeight );
509*33f678ddSArmin Le Grand mpSVGExport->SetViewBox( Rectangle( Point(nDocX, nDocY), Size( nDocWidth, nDocHeight ) ) );
510cdf0e10cSrcweir mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "viewBox", aAttr );
511cdf0e10cSrcweir mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "preserveAspectRatio", B2UCONST( "xMidYMid" ) );
512cdf0e10cSrcweir mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "fill-rule", B2UCONST( "evenodd" ) );
513cdf0e10cSrcweir
514cdf0e10cSrcweir // standard line width is based on 1 pixel on a 90 DPI device (0.28222mmm)
515cdf0e10cSrcweir mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "stroke-width", OUString::valueOf( 28.222 ) );
516cdf0e10cSrcweir mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "stroke-linejoin", B2UCONST( "round" ) );
517cdf0e10cSrcweir
518cdf0e10cSrcweir if( !bSinglePage )
519cdf0e10cSrcweir {
520cdf0e10cSrcweir mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "xmlns:ooo", B2UCONST( "http://xml.openoffice.org/svg/export" ) );
521cdf0e10cSrcweir mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "onclick", B2UCONST( "onClick(evt)" ) );
522cdf0e10cSrcweir mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "onkeypress", B2UCONST( "onKeyPress(evt)" ) );
523cdf0e10cSrcweir }
524cdf0e10cSrcweir
525cdf0e10cSrcweir mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "xmlns", B2UCONST( "http://www.w3.org/2000/svg" ) );
526cdf0e10cSrcweir mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "xmlns:xlink", B2UCONST( "http://www.w3.org/1999/xlink" ) );
527cdf0e10cSrcweir
528cdf0e10cSrcweir mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "xml:space", B2UCONST( "preserve" ) );
529cdf0e10cSrcweir
530cdf0e10cSrcweir mpSVGDoc = new SvXMLElementExport( *mpSVGExport, XML_NAMESPACE_NONE, "svg", sal_True, sal_True );
531cdf0e10cSrcweir
532cdf0e10cSrcweir while( ( nCurPage <= nLastPage ) && ( -1 == nVisible ) )
533cdf0e10cSrcweir {
534cdf0e10cSrcweir Reference< XDrawPage > xDrawPage;
535cdf0e10cSrcweir
536cdf0e10cSrcweir rxDrawPages->getByIndex( nCurPage ) >>= xDrawPage;
537cdf0e10cSrcweir
538cdf0e10cSrcweir if( xDrawPage.is() )
539cdf0e10cSrcweir {
540cdf0e10cSrcweir Reference< XPropertySet > xPropSet( xDrawPage, UNO_QUERY );
541cdf0e10cSrcweir
542cdf0e10cSrcweir if( xPropSet.is() )
543cdf0e10cSrcweir {
544cdf0e10cSrcweir sal_Bool bVisible = sal_False;
545cdf0e10cSrcweir
546cdf0e10cSrcweir if( !mbPresentation || bSinglePage ||
547cdf0e10cSrcweir ( ( xPropSet->getPropertyValue( B2UCONST( "Visible" ) ) >>= bVisible ) && bVisible ) )
548cdf0e10cSrcweir {
549cdf0e10cSrcweir Reference< XMasterPageTarget > xMasterTarget( xDrawPage, UNO_QUERY );
550cdf0e10cSrcweir
551cdf0e10cSrcweir if( xMasterTarget.is() )
552cdf0e10cSrcweir {
553cdf0e10cSrcweir Reference< XDrawPage > xMasterPage( xMasterTarget->getMasterPage() );
554cdf0e10cSrcweir
555cdf0e10cSrcweir nVisible = nCurPage;
556cdf0e10cSrcweir
557cdf0e10cSrcweir for( sal_Int32 nMaster = 0, nMasterCount = rxMasterPages->getCount();
558cdf0e10cSrcweir ( nMaster < nMasterCount ) && ( -1 == nVisibleMaster );
559cdf0e10cSrcweir ++nMaster )
560cdf0e10cSrcweir {
561cdf0e10cSrcweir Reference< XDrawPage > xMasterTestPage;
562cdf0e10cSrcweir
563cdf0e10cSrcweir rxMasterPages->getByIndex( nMaster ) >>= xMasterTestPage;
564cdf0e10cSrcweir
565cdf0e10cSrcweir if( xMasterTestPage == xMasterPage )
566cdf0e10cSrcweir nVisibleMaster = nMaster;
567cdf0e10cSrcweir }
568cdf0e10cSrcweir }
569cdf0e10cSrcweir }
570cdf0e10cSrcweir }
571cdf0e10cSrcweir }
572cdf0e10cSrcweir
573cdf0e10cSrcweir ++nCurPage;
574cdf0e10cSrcweir }
575cdf0e10cSrcweir
576cdf0e10cSrcweir if( mpSVGExport->IsEmbedFonts() )
577cdf0e10cSrcweir {
578cdf0e10cSrcweir mpSVGFontExport->EmbedFonts();
579cdf0e10cSrcweir }
580cdf0e10cSrcweir
581cdf0e10cSrcweir if( -1 != nVisible )
582cdf0e10cSrcweir {
583*33f678ddSArmin Le Grand if(bSinglePage)
584*33f678ddSArmin Le Grand {
585*33f678ddSArmin Le Grand if(mbExportSelection)
586*33f678ddSArmin Le Grand {
587*33f678ddSArmin Le Grand // #124608# export a given object selection, so no MasterPage export at all
588*33f678ddSArmin Le Grand }
589*33f678ddSArmin Le Grand else
590*33f678ddSArmin Le Grand {
591*33f678ddSArmin Le Grand implExportPages(rxMasterPages,nVisibleMaster,nVisibleMaster,nVisibleMaster,sal_True);
592*33f678ddSArmin Le Grand }
593*33f678ddSArmin Le Grand }
594*33f678ddSArmin Le Grand else
595*33f678ddSArmin Le Grand {
596cdf0e10cSrcweir implGenerateMetaData( rxMasterPages, rxDrawPages );
597cdf0e10cSrcweir implGenerateScript( rxMasterPages, rxDrawPages );
598cdf0e10cSrcweir implExportPages( rxMasterPages, 0, rxMasterPages->getCount() - 1, nVisibleMaster, sal_True );
599cdf0e10cSrcweir }
600cdf0e10cSrcweir
601cdf0e10cSrcweir implExportPages( rxDrawPages, nFirstPage, nLastPage, nVisible, sal_False );
602cdf0e10cSrcweir
603cdf0e10cSrcweir delete mpSVGDoc, mpSVGDoc = NULL;
604cdf0e10cSrcweir bRet = sal_True;
605cdf0e10cSrcweir }
606cdf0e10cSrcweir
607cdf0e10cSrcweir return bRet;
608cdf0e10cSrcweir }
609cdf0e10cSrcweir
610cdf0e10cSrcweir // -----------------------------------------------------------------------------
611cdf0e10cSrcweir
implGenerateMetaData(const Reference<XDrawPages> &,const Reference<XDrawPages> & rxDrawPages)612cdf0e10cSrcweir sal_Bool SVGFilter::implGenerateMetaData( const Reference< XDrawPages >& /* rxMasterPages */,
613cdf0e10cSrcweir const Reference< XDrawPages >& rxDrawPages )
614cdf0e10cSrcweir {
615cdf0e10cSrcweir sal_Bool bRet = sal_False;
616cdf0e10cSrcweir
617cdf0e10cSrcweir if( rxDrawPages->getCount() )
618cdf0e10cSrcweir {
619cdf0e10cSrcweir mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "id", B2UCONST( "meta_slides" ) );
620cdf0e10cSrcweir mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "numberOfSlides", OUString::valueOf( rxDrawPages->getCount() ) );
621cdf0e10cSrcweir
622cdf0e10cSrcweir {
623cdf0e10cSrcweir SvXMLElementExport aExp( *mpSVGExport, XML_NAMESPACE_NONE, "ooo:slidesInfo", sal_True, sal_True );
624cdf0e10cSrcweir const OUString aId( B2UCONST( "meta_slide" ) );
625cdf0e10cSrcweir
626cdf0e10cSrcweir for( sal_Int32 i = 0, nCount = rxDrawPages->getCount(); i < nCount; ++i )
627cdf0e10cSrcweir {
628cdf0e10cSrcweir OUString aSlideId( aId );
629cdf0e10cSrcweir Reference< XDrawPage > xDrawPage( rxDrawPages->getByIndex( i ), UNO_QUERY );
630cdf0e10cSrcweir Reference< XMasterPageTarget > xMasterPageTarget( xDrawPage, UNO_QUERY );
631cdf0e10cSrcweir Reference< XDrawPage > xMasterPage( xMasterPageTarget->getMasterPage(), UNO_QUERY );
632cdf0e10cSrcweir sal_Bool bMasterVisible = sal_True;
633cdf0e10cSrcweir OUString aMasterVisibility;
634cdf0e10cSrcweir
635cdf0e10cSrcweir aSlideId += OUString::valueOf( i );
636cdf0e10cSrcweir
637cdf0e10cSrcweir if( mbPresentation )
638cdf0e10cSrcweir {
639cdf0e10cSrcweir Reference< XPropertySet > xPropSet( xDrawPage, UNO_QUERY );
640cdf0e10cSrcweir
641cdf0e10cSrcweir if( xPropSet.is() )
642cdf0e10cSrcweir xPropSet->getPropertyValue( B2UCONST( "Background" ) ) >>= bMasterVisible;
643cdf0e10cSrcweir }
644cdf0e10cSrcweir
645cdf0e10cSrcweir if( bMasterVisible )
646cdf0e10cSrcweir aMasterVisibility = B2UCONST( "visible" );
647cdf0e10cSrcweir else
648cdf0e10cSrcweir aMasterVisibility = B2UCONST( "hidden" );
649cdf0e10cSrcweir
650cdf0e10cSrcweir mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "id", aSlideId );
651cdf0e10cSrcweir mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "slide", implGetValidIDFromInterface( xDrawPage ) );
652cdf0e10cSrcweir mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "master", implGetValidIDFromInterface( xMasterPage ) );
653cdf0e10cSrcweir mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "master-visibility", aMasterVisibility );
654cdf0e10cSrcweir
655cdf0e10cSrcweir {
656cdf0e10cSrcweir SvXMLElementExport aExp2( *mpSVGExport, XML_NAMESPACE_NONE, "ooo:slideInfo", sal_True, sal_True );
657cdf0e10cSrcweir }
658cdf0e10cSrcweir }
659cdf0e10cSrcweir }
660cdf0e10cSrcweir
661cdf0e10cSrcweir
662cdf0e10cSrcweir bRet =sal_True;
663cdf0e10cSrcweir }
664cdf0e10cSrcweir
665cdf0e10cSrcweir return bRet;
666cdf0e10cSrcweir }
667cdf0e10cSrcweir
668cdf0e10cSrcweir // -----------------------------------------------------------------------------
669cdf0e10cSrcweir
implGenerateScript(const Reference<XDrawPages> &,const Reference<XDrawPages> &)670cdf0e10cSrcweir sal_Bool SVGFilter::implGenerateScript( const Reference< XDrawPages >& /* rxMasterPages */,
671cdf0e10cSrcweir const Reference< XDrawPages >& /* rxDrawPages */ )
672cdf0e10cSrcweir {
673cdf0e10cSrcweir mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "type", B2UCONST( "text/ecmascript" ) );
674cdf0e10cSrcweir
675cdf0e10cSrcweir {
676cdf0e10cSrcweir SvXMLElementExport aExp( *mpSVGExport, XML_NAMESPACE_NONE, "script", sal_True, sal_True );
677cdf0e10cSrcweir Reference< XExtendedDocumentHandler > xExtDocHandler( mpSVGExport->GetDocHandler(), UNO_QUERY );
678cdf0e10cSrcweir
679cdf0e10cSrcweir if( xExtDocHandler.is() )
680cdf0e10cSrcweir {
681cdf0e10cSrcweir xExtDocHandler->unknown( OUString::createFromAscii( aSVGScript1 ) );
682cdf0e10cSrcweir xExtDocHandler->unknown( OUString::createFromAscii( aSVGScript2 ) );
683cdf0e10cSrcweir }
684cdf0e10cSrcweir }
685cdf0e10cSrcweir
686cdf0e10cSrcweir return sal_True;
687cdf0e10cSrcweir }
688cdf0e10cSrcweir
689cdf0e10cSrcweir // -----------------------------------------------------------------------------
690cdf0e10cSrcweir
implExportPages(const Reference<XDrawPages> & rxPages,sal_Int32 nFirstPage,sal_Int32 nLastPage,sal_Int32 nVisiblePage,sal_Bool bMaster)691cdf0e10cSrcweir sal_Bool SVGFilter::implExportPages( const Reference< XDrawPages >& rxPages,
692cdf0e10cSrcweir sal_Int32 nFirstPage, sal_Int32 nLastPage,
693cdf0e10cSrcweir sal_Int32 nVisiblePage, sal_Bool bMaster )
694cdf0e10cSrcweir {
695cdf0e10cSrcweir DBG_ASSERT( nFirstPage <= nLastPage,
696cdf0e10cSrcweir "SVGFilter::implExportPages: nFirstPage > nLastPage" );
697cdf0e10cSrcweir
698cdf0e10cSrcweir sal_Bool bRet = sal_False;
699cdf0e10cSrcweir
700cdf0e10cSrcweir for( sal_Int32 i = nFirstPage; i <= nLastPage; ++i )
701cdf0e10cSrcweir {
702cdf0e10cSrcweir Reference< XDrawPage > xDrawPage;
703cdf0e10cSrcweir
704cdf0e10cSrcweir rxPages->getByIndex( i ) >>= xDrawPage;
705cdf0e10cSrcweir
706cdf0e10cSrcweir if( xDrawPage.is() )
707cdf0e10cSrcweir {
708*33f678ddSArmin Le Grand Reference< XShapes > xShapes;
709*33f678ddSArmin Le Grand
710*33f678ddSArmin Le Grand if(mbExportSelection)
711*33f678ddSArmin Le Grand {
712*33f678ddSArmin Le Grand // #124608# export a given object selection
713*33f678ddSArmin Le Grand xShapes = maShapeSelection;
714*33f678ddSArmin Le Grand }
715*33f678ddSArmin Le Grand else
716*33f678ddSArmin Le Grand {
717*33f678ddSArmin Le Grand xShapes = Reference< XShapes >( xDrawPage, UNO_QUERY );
718*33f678ddSArmin Le Grand }
719cdf0e10cSrcweir
720cdf0e10cSrcweir if( xShapes.is() )
721cdf0e10cSrcweir {
722cdf0e10cSrcweir OUString aVisibility, aId, aSlideName( implGetValidIDFromInterface( xShapes, sal_True ) );
723cdf0e10cSrcweir
724cdf0e10cSrcweir // add visibility attribute
725cdf0e10cSrcweir if( i == nVisiblePage )
726cdf0e10cSrcweir aVisibility = B2UCONST( "visible" );
727cdf0e10cSrcweir else
728cdf0e10cSrcweir aVisibility = B2UCONST( "hidden" );
729cdf0e10cSrcweir
730cdf0e10cSrcweir mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "visibility", aVisibility );
731cdf0e10cSrcweir
732cdf0e10cSrcweir // add id attribute
733cdf0e10cSrcweir if( bMaster )
734cdf0e10cSrcweir aId = ( B2UCONST( "MasterSlide_" ) ) += ::rtl::OUString::valueOf( ++mnMasterSlideId );
735cdf0e10cSrcweir else
736cdf0e10cSrcweir aId = ( B2UCONST( "Slide_" ) ) += ::rtl::OUString::valueOf( ++mnSlideId );
737cdf0e10cSrcweir
738cdf0e10cSrcweir if( aSlideName.getLength() )
7390a21cc8cSArmin Le Grand ( aId += B2UCONST( "_" ) ) += aSlideName;
740cdf0e10cSrcweir
741cdf0e10cSrcweir mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "id", aId );
742cdf0e10cSrcweir
743cdf0e10cSrcweir {
744cdf0e10cSrcweir SvXMLElementExport aExp( *mpSVGExport, XML_NAMESPACE_NONE, "g", sal_True, sal_True );
745cdf0e10cSrcweir const Point aNullPt;
746cdf0e10cSrcweir
747cdf0e10cSrcweir if( mpObjects->find( xDrawPage ) != mpObjects->end() )
748cdf0e10cSrcweir {
749cdf0e10cSrcweir Reference< XExtendedDocumentHandler > xExtDocHandler( mpSVGExport->GetDocHandler(), UNO_QUERY );
750cdf0e10cSrcweir
751cdf0e10cSrcweir if( xExtDocHandler.is() )
752cdf0e10cSrcweir {
753cdf0e10cSrcweir SvXMLElementExport aExp2( *mpSVGExport, XML_NAMESPACE_NONE, "desc", sal_True, sal_True );
754cdf0e10cSrcweir OUString aDesc;
755cdf0e10cSrcweir
756cdf0e10cSrcweir if( bMaster )
757cdf0e10cSrcweir aDesc = B2UCONST( "Master slide" );
758cdf0e10cSrcweir else
759cdf0e10cSrcweir aDesc = B2UCONST( "Slide" );
760cdf0e10cSrcweir
761cdf0e10cSrcweir xExtDocHandler->unknown( aDesc );
762cdf0e10cSrcweir }
763cdf0e10cSrcweir }
764cdf0e10cSrcweir
765cdf0e10cSrcweir if( bMaster )
766cdf0e10cSrcweir {
767cdf0e10cSrcweir const GDIMetaFile& rMtf = (*mpObjects)[ xDrawPage ].GetRepresentation();
768cdf0e10cSrcweir mpSVGWriter->WriteMetaFile( aNullPt, rMtf.GetPrefSize(), rMtf, SVGWRITER_WRITE_FILL );
769cdf0e10cSrcweir }
770cdf0e10cSrcweir
771cdf0e10cSrcweir bRet = implExportShapes( xShapes ) || bRet;
772cdf0e10cSrcweir }
773cdf0e10cSrcweir }
774cdf0e10cSrcweir }
775cdf0e10cSrcweir }
776cdf0e10cSrcweir
777cdf0e10cSrcweir return bRet;
778cdf0e10cSrcweir }
779cdf0e10cSrcweir
780cdf0e10cSrcweir // -----------------------------------------------------------------------------
781cdf0e10cSrcweir
implExportShapes(const Reference<XShapes> & rxShapes)782cdf0e10cSrcweir sal_Bool SVGFilter::implExportShapes( const Reference< XShapes >& rxShapes )
783cdf0e10cSrcweir {
784cdf0e10cSrcweir Reference< XShape > xShape;
785cdf0e10cSrcweir sal_Bool bRet = sal_False;
786cdf0e10cSrcweir
787cdf0e10cSrcweir for( sal_Int32 i = 0, nCount = rxShapes->getCount(); i < nCount; ++i )
788cdf0e10cSrcweir {
789cdf0e10cSrcweir if( ( rxShapes->getByIndex( i ) >>= xShape ) && xShape.is() )
790cdf0e10cSrcweir bRet = implExportShape( xShape ) || bRet;
791cdf0e10cSrcweir
792cdf0e10cSrcweir xShape = NULL;
793cdf0e10cSrcweir }
794cdf0e10cSrcweir
795cdf0e10cSrcweir return bRet;
796cdf0e10cSrcweir }
797cdf0e10cSrcweir
798cdf0e10cSrcweir // -----------------------------------------------------------------------------
799cdf0e10cSrcweir
implExportShape(const Reference<XShape> & rxShape)800cdf0e10cSrcweir sal_Bool SVGFilter::implExportShape( const Reference< XShape >& rxShape )
801cdf0e10cSrcweir {
802cdf0e10cSrcweir Reference< XPropertySet > xShapePropSet( rxShape, UNO_QUERY );
803cdf0e10cSrcweir sal_Bool bRet = sal_False;
804cdf0e10cSrcweir
805cdf0e10cSrcweir if( xShapePropSet.is() )
806cdf0e10cSrcweir {
807cdf0e10cSrcweir const ::rtl::OUString aShapeType( rxShape->getShapeType() );
808cdf0e10cSrcweir sal_Bool bHideObj = sal_False;
809cdf0e10cSrcweir
810cdf0e10cSrcweir if( mbPresentation )
811cdf0e10cSrcweir {
812cdf0e10cSrcweir xShapePropSet->getPropertyValue( B2UCONST( "IsEmptyPresentationObject" ) ) >>= bHideObj;
813cdf0e10cSrcweir
814cdf0e10cSrcweir if( !bHideObj )
815cdf0e10cSrcweir {
816cdf0e10cSrcweir const Reference< XPropertySet > xDefaultPagePropertySet( mxDefaultPage, UNO_QUERY );
817cdf0e10cSrcweir Reference< XPropertySetInfo > xPagePropSetInfo( xDefaultPagePropertySet->getPropertySetInfo() );
818cdf0e10cSrcweir
819cdf0e10cSrcweir if( xPagePropSetInfo.is() )
820cdf0e10cSrcweir {
821cdf0e10cSrcweir const ::rtl::OUString aHeaderString( B2UCONST( "IsHeaderVisible" ) );
822cdf0e10cSrcweir const ::rtl::OUString aFooterString( B2UCONST( "IsFooterVisible" ) );
823cdf0e10cSrcweir const ::rtl::OUString aDateTimeString( B2UCONST( "IsDateTimeVisible" ) );
824cdf0e10cSrcweir const ::rtl::OUString aPageNumberString( B2UCONST( "IsPageNumberVisible" ) );
825cdf0e10cSrcweir
826cdf0e10cSrcweir Any aProperty;
827cdf0e10cSrcweir sal_Bool bValue = sal_False;
828cdf0e10cSrcweir
829cdf0e10cSrcweir if( ( aShapeType.lastIndexOf( B2UCONST( "presentation.HeaderShape" ) ) != -1 ) &&
830cdf0e10cSrcweir xPagePropSetInfo->hasPropertyByName( aHeaderString ) &&
831cdf0e10cSrcweir ( ( aProperty = xDefaultPagePropertySet->getPropertyValue( aHeaderString ) ) >>= bValue ) &&
832cdf0e10cSrcweir !bValue )
833cdf0e10cSrcweir {
834cdf0e10cSrcweir bHideObj = sal_True;
835cdf0e10cSrcweir }
836cdf0e10cSrcweir else if( ( aShapeType.lastIndexOf( B2UCONST( "presentation.FooterShape" ) ) != -1 ) &&
837cdf0e10cSrcweir xPagePropSetInfo->hasPropertyByName( aFooterString ) &&
838cdf0e10cSrcweir ( ( aProperty = xDefaultPagePropertySet->getPropertyValue( aFooterString ) ) >>= bValue ) &&
839cdf0e10cSrcweir !bValue )
840cdf0e10cSrcweir {
841cdf0e10cSrcweir bHideObj = sal_True;
842cdf0e10cSrcweir }
843cdf0e10cSrcweir else if( ( aShapeType.lastIndexOf( B2UCONST( "presentation.DateTimeShape" ) ) != -1 ) &&
844cdf0e10cSrcweir xPagePropSetInfo->hasPropertyByName( aDateTimeString ) &&
845cdf0e10cSrcweir ( ( aProperty = xDefaultPagePropertySet->getPropertyValue( aDateTimeString ) ) >>= bValue ) &&
846cdf0e10cSrcweir !bValue )
847cdf0e10cSrcweir {
848cdf0e10cSrcweir bHideObj = sal_True;
849cdf0e10cSrcweir }
850cdf0e10cSrcweir else if( ( aShapeType.lastIndexOf( B2UCONST( "presentation.SlideNumberShape" ) ) != -1 ) &&
851cdf0e10cSrcweir xPagePropSetInfo->hasPropertyByName( aPageNumberString ) &&
852cdf0e10cSrcweir ( ( aProperty = xDefaultPagePropertySet->getPropertyValue( aPageNumberString ) ) >>= bValue ) &&
853cdf0e10cSrcweir !bValue )
854cdf0e10cSrcweir {
855cdf0e10cSrcweir bHideObj = sal_True;
856cdf0e10cSrcweir }
857cdf0e10cSrcweir }
858cdf0e10cSrcweir }
859cdf0e10cSrcweir }
860cdf0e10cSrcweir
861cdf0e10cSrcweir if( !bHideObj )
862cdf0e10cSrcweir {
863cdf0e10cSrcweir if( aShapeType.lastIndexOf( B2UCONST( "drawing.GroupShape" ) ) != -1 )
864cdf0e10cSrcweir {
865cdf0e10cSrcweir Reference< XShapes > xShapes( rxShape, UNO_QUERY );
866cdf0e10cSrcweir
867cdf0e10cSrcweir if( xShapes.is() )
868cdf0e10cSrcweir {
869cdf0e10cSrcweir OUString aId( B2UCONST( "DrawingGroup_" ) );
870cdf0e10cSrcweir OUString aObjName( implGetValidIDFromInterface( rxShape, sal_True ) ), aObjDesc;
871cdf0e10cSrcweir
872cdf0e10cSrcweir aId += ::rtl::OUString::valueOf( ++mnDrawingGroupId );
873cdf0e10cSrcweir
874cdf0e10cSrcweir if( aObjName.getLength() )
8750a21cc8cSArmin Le Grand ( aId += B2UCONST( "_" ) ) += aObjName;
876cdf0e10cSrcweir
877cdf0e10cSrcweir mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "id", aId );
878cdf0e10cSrcweir
879cdf0e10cSrcweir {
880cdf0e10cSrcweir SvXMLElementExport aExp( *mpSVGExport, XML_NAMESPACE_NONE, "g", sal_True, sal_True );
881cdf0e10cSrcweir bRet = implExportShapes( xShapes );
882cdf0e10cSrcweir }
883cdf0e10cSrcweir }
884cdf0e10cSrcweir }
885cdf0e10cSrcweir
886cdf0e10cSrcweir if( !bRet && mpObjects->find( rxShape ) != mpObjects->end() )
887cdf0e10cSrcweir {
888cdf0e10cSrcweir Reference< XText > xText( rxShape, UNO_QUERY );
889cdf0e10cSrcweir ::com::sun::star::awt::Rectangle aBoundRect;
890cdf0e10cSrcweir const GDIMetaFile& rMtf = (*mpObjects)[ rxShape ].GetRepresentation();
891cdf0e10cSrcweir
892cdf0e10cSrcweir xShapePropSet->getPropertyValue( B2UCONST( "BoundRect" ) ) >>= aBoundRect;
893cdf0e10cSrcweir
894cdf0e10cSrcweir const Point aTopLeft( aBoundRect.X, aBoundRect.Y );
895cdf0e10cSrcweir const Size aSize( aBoundRect.Width, aBoundRect.Height );
896cdf0e10cSrcweir
897cdf0e10cSrcweir if( rMtf.GetActionCount() )
898cdf0e10cSrcweir {
899cdf0e10cSrcweir OUString aId( B2UCONST( "Drawing_" ) );
900cdf0e10cSrcweir OUString aObjName( implGetValidIDFromInterface( rxShape, sal_True ) ), aObjDesc;
901cdf0e10cSrcweir
902cdf0e10cSrcweir aId += ::rtl::OUString::valueOf( ++mnDrawingId );
903cdf0e10cSrcweir
904cdf0e10cSrcweir if( aObjName.getLength() )
9050a21cc8cSArmin Le Grand ( aId += B2UCONST( "_" ) ) += aObjName;
906cdf0e10cSrcweir
907cdf0e10cSrcweir {
908cdf0e10cSrcweir if( ( aShapeType.lastIndexOf( B2UCONST( "drawing.OLE2Shape" ) ) != -1 ) ||
909cdf0e10cSrcweir ( aShapeType.lastIndexOf( B2UCONST( "drawing.GraphicObjectShape" ) ) != -1 ) )
910cdf0e10cSrcweir {
911cdf0e10cSrcweir mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "id", aId );
912cdf0e10cSrcweir
913cdf0e10cSrcweir {
914cdf0e10cSrcweir SvXMLElementExport aExp( *mpSVGExport, XML_NAMESPACE_NONE, "g", sal_True, sal_True );
915cdf0e10cSrcweir mpSVGWriter->WriteMetaFile( aTopLeft, aSize, rMtf, SVGWRITER_WRITE_FILL | SVGWRITER_WRITE_TEXT );
916cdf0e10cSrcweir }
917cdf0e10cSrcweir }
918cdf0e10cSrcweir else
919cdf0e10cSrcweir {
920cdf0e10cSrcweir if( implHasText( rMtf ) )
921cdf0e10cSrcweir {
922cdf0e10cSrcweir mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "id", aId );
923cdf0e10cSrcweir
924cdf0e10cSrcweir {
925cdf0e10cSrcweir SvXMLElementExport aExp( *mpSVGExport, XML_NAMESPACE_NONE, "g", sal_True, sal_True );
926cdf0e10cSrcweir mpSVGWriter->WriteMetaFile( aTopLeft, aSize, rMtf, SVGWRITER_WRITE_FILL );
927cdf0e10cSrcweir mpSVGWriter->WriteMetaFile( aTopLeft, aSize, rMtf, SVGWRITER_WRITE_TEXT );
928cdf0e10cSrcweir }
929cdf0e10cSrcweir }
930cdf0e10cSrcweir else
931cdf0e10cSrcweir {
932cdf0e10cSrcweir SvXMLElementExport aExp( *mpSVGExport, XML_NAMESPACE_NONE, "g", sal_True, sal_True );
933cdf0e10cSrcweir mpSVGWriter->WriteMetaFile( aTopLeft, aSize, rMtf, SVGWRITER_WRITE_FILL | SVGWRITER_WRITE_TEXT, &aId );
934cdf0e10cSrcweir }
935cdf0e10cSrcweir }
936cdf0e10cSrcweir }
937cdf0e10cSrcweir }
938cdf0e10cSrcweir
939cdf0e10cSrcweir bRet = sal_True;
940cdf0e10cSrcweir }
941cdf0e10cSrcweir }
942cdf0e10cSrcweir }
943cdf0e10cSrcweir
944cdf0e10cSrcweir return bRet;
945cdf0e10cSrcweir }
946cdf0e10cSrcweir
947cdf0e10cSrcweir // -----------------------------------------------------------------------------
948cdf0e10cSrcweir
implCreateObjects(const Reference<XDrawPages> & rxMasterPages,const Reference<XDrawPages> & rxDrawPages,sal_Int32 nPageToExport)949cdf0e10cSrcweir sal_Bool SVGFilter::implCreateObjects( const Reference< XDrawPages >& rxMasterPages,
950cdf0e10cSrcweir const Reference< XDrawPages >& rxDrawPages,
951cdf0e10cSrcweir sal_Int32 nPageToExport )
952cdf0e10cSrcweir {
953cdf0e10cSrcweir if( SVG_EXPORT_ALLPAGES == nPageToExport )
954cdf0e10cSrcweir {
955*33f678ddSArmin Le Grand // export the whole document
956cdf0e10cSrcweir sal_Int32 i, nCount;
957cdf0e10cSrcweir
958cdf0e10cSrcweir for( i = 0, nCount = rxMasterPages->getCount(); i < nCount; ++i )
959cdf0e10cSrcweir {
960cdf0e10cSrcweir Reference< XDrawPage > xMasterPage;
961cdf0e10cSrcweir
962cdf0e10cSrcweir rxMasterPages->getByIndex( i ) >>= xMasterPage;
963cdf0e10cSrcweir
964cdf0e10cSrcweir if( xMasterPage.is() )
965cdf0e10cSrcweir {
966cdf0e10cSrcweir Reference< XShapes > xShapes( xMasterPage, UNO_QUERY );
967cdf0e10cSrcweir
968cdf0e10cSrcweir implCreateObjectsFromBackground( xMasterPage );
969cdf0e10cSrcweir
970cdf0e10cSrcweir if( xShapes.is() )
971cdf0e10cSrcweir implCreateObjectsFromShapes( xShapes );
972cdf0e10cSrcweir }
973cdf0e10cSrcweir }
974cdf0e10cSrcweir
975cdf0e10cSrcweir for( i = 0, nCount = rxDrawPages->getCount(); i < nCount; ++i )
976cdf0e10cSrcweir {
977cdf0e10cSrcweir Reference< XDrawPage > xDrawPage;
978cdf0e10cSrcweir
979cdf0e10cSrcweir rxDrawPages->getByIndex( i ) >>= xDrawPage;
980cdf0e10cSrcweir
981cdf0e10cSrcweir if( xDrawPage.is() )
982cdf0e10cSrcweir {
983cdf0e10cSrcweir Reference< XShapes > xShapes( xDrawPage, UNO_QUERY );
984cdf0e10cSrcweir
985cdf0e10cSrcweir if( xShapes.is() )
986cdf0e10cSrcweir implCreateObjectsFromShapes( xShapes );
987cdf0e10cSrcweir }
988cdf0e10cSrcweir }
989cdf0e10cSrcweir }
990cdf0e10cSrcweir else
991cdf0e10cSrcweir {
992cdf0e10cSrcweir DBG_ASSERT( nPageToExport >= 0 && nPageToExport < rxDrawPages->getCount(),
993cdf0e10cSrcweir "SVGFilter::implCreateObjects: invalid page number to export" );
994cdf0e10cSrcweir
995*33f678ddSArmin Le Grand if(mbExportSelection)
996*33f678ddSArmin Le Grand {
997*33f678ddSArmin Le Grand // #124608# export a given object selection
998*33f678ddSArmin Le Grand implCreateObjectsFromShapes(maShapeSelection);
999*33f678ddSArmin Le Grand }
1000*33f678ddSArmin Le Grand else
1001*33f678ddSArmin Le Grand {
1002*33f678ddSArmin Le Grand // export a given xDrawPage
1003*33f678ddSArmin Le Grand Reference< XDrawPage > xDrawPage;
1004cdf0e10cSrcweir
1005*33f678ddSArmin Le Grand rxDrawPages->getByIndex(nPageToExport) >>= xDrawPage;
1006cdf0e10cSrcweir
1007*33f678ddSArmin Le Grand if(xDrawPage.is())
1008*33f678ddSArmin Le Grand {
1009*33f678ddSArmin Le Grand Reference< XMasterPageTarget > xMasterTarget(xDrawPage,UNO_QUERY);
1010cdf0e10cSrcweir
1011*33f678ddSArmin Le Grand if(xMasterTarget.is())
1012cdf0e10cSrcweir {
1013*33f678ddSArmin Le Grand Reference< XDrawPage > xMasterPage(xMasterTarget->getMasterPage());
1014cdf0e10cSrcweir
1015*33f678ddSArmin Le Grand if(xMasterPage.is())
1016*33f678ddSArmin Le Grand {
1017*33f678ddSArmin Le Grand Reference< XShapes > xShapes(xMasterPage,UNO_QUERY);
1018cdf0e10cSrcweir
1019*33f678ddSArmin Le Grand implCreateObjectsFromBackground(xMasterPage);
1020*33f678ddSArmin Le Grand
1021*33f678ddSArmin Le Grand if(xShapes.is())
1022*33f678ddSArmin Le Grand implCreateObjectsFromShapes(xShapes);
1023*33f678ddSArmin Le Grand }
1024cdf0e10cSrcweir }
1025cdf0e10cSrcweir
1026*33f678ddSArmin Le Grand Reference< XShapes > xShapes(xDrawPage,UNO_QUERY);
1027*33f678ddSArmin Le Grand
1028*33f678ddSArmin Le Grand if(xShapes.is())
1029*33f678ddSArmin Le Grand implCreateObjectsFromShapes(xShapes);
1030*33f678ddSArmin Le Grand }
1031*33f678ddSArmin Le Grand }
1032cdf0e10cSrcweir }
1033cdf0e10cSrcweir
1034cdf0e10cSrcweir return sal_True;
1035cdf0e10cSrcweir }
1036cdf0e10cSrcweir
1037cdf0e10cSrcweir // -----------------------------------------------------------------------------
1038cdf0e10cSrcweir
implCreateObjectsFromShapes(const Reference<XShapes> & rxShapes)1039cdf0e10cSrcweir sal_Bool SVGFilter::implCreateObjectsFromShapes( const Reference< XShapes >& rxShapes )
1040cdf0e10cSrcweir {
1041cdf0e10cSrcweir Reference< XShape > xShape;
1042cdf0e10cSrcweir sal_Bool bRet = sal_False;
1043cdf0e10cSrcweir
1044cdf0e10cSrcweir for( sal_Int32 i = 0, nCount = rxShapes->getCount(); i < nCount; ++i )
1045cdf0e10cSrcweir {
1046cdf0e10cSrcweir if( ( rxShapes->getByIndex( i ) >>= xShape ) && xShape.is() )
1047cdf0e10cSrcweir bRet = implCreateObjectsFromShape( xShape ) || bRet;
1048cdf0e10cSrcweir
1049cdf0e10cSrcweir xShape = NULL;
1050cdf0e10cSrcweir }
1051cdf0e10cSrcweir
1052cdf0e10cSrcweir return bRet;
1053cdf0e10cSrcweir }
1054cdf0e10cSrcweir
1055cdf0e10cSrcweir // -----------------------------------------------------------------------------
1056cdf0e10cSrcweir
implCreateObjectsFromShape(const Reference<XShape> & rxShape)1057cdf0e10cSrcweir sal_Bool SVGFilter::implCreateObjectsFromShape( const Reference< XShape >& rxShape )
1058cdf0e10cSrcweir {
1059cdf0e10cSrcweir sal_Bool bRet = sal_False;
1060cdf0e10cSrcweir
1061cdf0e10cSrcweir if( rxShape->getShapeType().lastIndexOf( B2UCONST( "drawing.GroupShape" ) ) != -1 )
1062cdf0e10cSrcweir {
1063cdf0e10cSrcweir Reference< XShapes > xShapes( rxShape, UNO_QUERY );
1064cdf0e10cSrcweir
1065cdf0e10cSrcweir if( xShapes.is() )
1066cdf0e10cSrcweir bRet = implCreateObjectsFromShapes( xShapes );
1067cdf0e10cSrcweir }
1068cdf0e10cSrcweir else
1069cdf0e10cSrcweir {
1070cdf0e10cSrcweir SdrObject* pObj = GetSdrObjectFromXShape( rxShape );
1071cdf0e10cSrcweir
1072cdf0e10cSrcweir if( pObj )
1073cdf0e10cSrcweir {
1074cdf0e10cSrcweir Graphic aGraphic( SdrExchangeView::GetObjGraphic( pObj->GetModel(), pObj ) );
1075cdf0e10cSrcweir
1076cdf0e10cSrcweir if( aGraphic.GetType() != GRAPHIC_NONE )
1077cdf0e10cSrcweir {
1078cdf0e10cSrcweir if( aGraphic.GetType() == GRAPHIC_BITMAP )
1079cdf0e10cSrcweir {
1080cdf0e10cSrcweir GDIMetaFile aMtf;
1081cdf0e10cSrcweir const Point aNullPt;
1082cdf0e10cSrcweir const Size aSize( pObj->GetCurrentBoundRect().GetSize() );
1083cdf0e10cSrcweir
1084cdf0e10cSrcweir aMtf.AddAction( new MetaBmpExScaleAction( aNullPt, aSize, aGraphic.GetBitmapEx() ) );
1085cdf0e10cSrcweir aMtf.SetPrefSize( aSize );
1086cdf0e10cSrcweir aMtf.SetPrefMapMode( MAP_100TH_MM );
1087cdf0e10cSrcweir
1088cdf0e10cSrcweir (*mpObjects)[ rxShape ] = ObjectRepresentation( rxShape, aMtf );
1089cdf0e10cSrcweir }
1090cdf0e10cSrcweir else
1091cdf0e10cSrcweir (*mpObjects)[ rxShape ] = ObjectRepresentation( rxShape, aGraphic.GetGDIMetaFile() );
1092cdf0e10cSrcweir
1093cdf0e10cSrcweir bRet = sal_True;
1094cdf0e10cSrcweir }
1095cdf0e10cSrcweir }
1096cdf0e10cSrcweir }
1097cdf0e10cSrcweir
1098cdf0e10cSrcweir return bRet;
1099cdf0e10cSrcweir }
1100cdf0e10cSrcweir
1101cdf0e10cSrcweir // -----------------------------------------------------------------------------
1102cdf0e10cSrcweir
implCreateObjectsFromBackground(const Reference<XDrawPage> & rxMasterPage)1103cdf0e10cSrcweir sal_Bool SVGFilter::implCreateObjectsFromBackground( const Reference< XDrawPage >& rxMasterPage )
1104cdf0e10cSrcweir {
1105cdf0e10cSrcweir Reference< XExporter > xExporter( mxMSF->createInstance( B2UCONST( "com.sun.star.drawing.GraphicExportFilter" ) ), UNO_QUERY );
1106cdf0e10cSrcweir sal_Bool bRet = sal_False;
1107cdf0e10cSrcweir
1108cdf0e10cSrcweir if( xExporter.is() )
1109cdf0e10cSrcweir {
1110cdf0e10cSrcweir GDIMetaFile aMtf;
1111cdf0e10cSrcweir Reference< XFilter > xFilter( xExporter, UNO_QUERY );
1112cdf0e10cSrcweir
1113cdf0e10cSrcweir utl::TempFile aFile;
1114cdf0e10cSrcweir aFile.EnableKillingFile();
1115cdf0e10cSrcweir
1116cdf0e10cSrcweir Sequence< PropertyValue > aDescriptor( 3 );
1117cdf0e10cSrcweir aDescriptor[0].Name = B2UCONST( "FilterName" );
1118cdf0e10cSrcweir aDescriptor[0].Value <<= B2UCONST( "SVM" );
1119cdf0e10cSrcweir aDescriptor[1].Name = B2UCONST( "URL" );
1120cdf0e10cSrcweir aDescriptor[1].Value <<= OUString( aFile.GetURL() );
1121cdf0e10cSrcweir aDescriptor[2].Name = B2UCONST( "ExportOnlyBackground" );
1122cdf0e10cSrcweir aDescriptor[2].Value <<= (sal_Bool) sal_True;
1123cdf0e10cSrcweir
1124cdf0e10cSrcweir xExporter->setSourceDocument( Reference< XComponent >( rxMasterPage, UNO_QUERY ) );
1125cdf0e10cSrcweir xFilter->filter( aDescriptor );
1126cdf0e10cSrcweir aMtf.Read( *aFile.GetStream( STREAM_READ ) );
1127cdf0e10cSrcweir
1128cdf0e10cSrcweir (*mpObjects)[ rxMasterPage ] = ObjectRepresentation( rxMasterPage, aMtf );
1129cdf0e10cSrcweir
1130cdf0e10cSrcweir bRet = sal_True;
1131cdf0e10cSrcweir }
1132cdf0e10cSrcweir
1133cdf0e10cSrcweir return bRet;
1134cdf0e10cSrcweir }
1135cdf0e10cSrcweir
1136cdf0e10cSrcweir // -----------------------------------------------------------------------------
1137cdf0e10cSrcweir
implGetDescriptionFromShape(const Reference<XShape> & rxShape)1138cdf0e10cSrcweir OUString SVGFilter::implGetDescriptionFromShape( const Reference< XShape >& rxShape )
1139cdf0e10cSrcweir {
1140cdf0e10cSrcweir OUString aRet;
1141cdf0e10cSrcweir const OUString aShapeType( rxShape->getShapeType() );
1142cdf0e10cSrcweir
1143cdf0e10cSrcweir if( aShapeType.lastIndexOf( B2UCONST( "drawing.GroupShape" ) ) != -1 )
1144cdf0e10cSrcweir aRet = B2UCONST( "Group" );
1145cdf0e10cSrcweir else if( aShapeType.lastIndexOf( B2UCONST( "drawing.GraphicObjectShape" ) ) != -1 )
1146cdf0e10cSrcweir aRet = B2UCONST( "Graphic" );
1147cdf0e10cSrcweir else if( aShapeType.lastIndexOf( B2UCONST( "drawing.OLE2Shape" ) ) != -1 )
1148cdf0e10cSrcweir aRet = B2UCONST( "OLE2" );
1149cdf0e10cSrcweir else if( aShapeType.lastIndexOf( B2UCONST( "presentation.HeaderShape" ) ) != -1 )
1150cdf0e10cSrcweir aRet = B2UCONST( "Header" );
1151cdf0e10cSrcweir else if( aShapeType.lastIndexOf( B2UCONST( "presentation.FooterShape" ) ) != -1 )
1152cdf0e10cSrcweir aRet = B2UCONST( "Footer" );
1153cdf0e10cSrcweir else if( aShapeType.lastIndexOf( B2UCONST( "presentation.DateTimeShape" ) ) != -1 )
1154cdf0e10cSrcweir aRet = B2UCONST( "Date/Time" );
1155cdf0e10cSrcweir else if( aShapeType.lastIndexOf( B2UCONST( "presentation.SlideNumberShape" ) ) != -1 )
1156cdf0e10cSrcweir aRet = B2UCONST( "Slide Number" );
1157cdf0e10cSrcweir else
1158cdf0e10cSrcweir aRet = B2UCONST( "Drawing" );
1159cdf0e10cSrcweir
1160cdf0e10cSrcweir return aRet;
1161cdf0e10cSrcweir }
1162cdf0e10cSrcweir
1163cdf0e10cSrcweir // -----------------------------------------------------------------------------
1164cdf0e10cSrcweir
implGetValidIDFromInterface(const Reference<XInterface> & rxIf,sal_Bool bUnique)1165cdf0e10cSrcweir OUString SVGFilter::implGetValidIDFromInterface( const Reference< XInterface >& rxIf, sal_Bool bUnique )
1166cdf0e10cSrcweir {
1167cdf0e10cSrcweir Reference< XNamed > xNamed( rxIf, UNO_QUERY );
1168cdf0e10cSrcweir OUString aRet;
1169cdf0e10cSrcweir
1170cdf0e10cSrcweir if( xNamed.is() )
1171cdf0e10cSrcweir {
1172cdf0e10cSrcweir aRet = xNamed->getName().replace( ' ', '_' ).
1173cdf0e10cSrcweir replace( ':', '_' ).
1174cdf0e10cSrcweir replace( ',', '_' ).
1175cdf0e10cSrcweir replace( ';', '_' ).
1176cdf0e10cSrcweir replace( '&', '_' ).
1177cdf0e10cSrcweir replace( '!', '_' ).
1178cdf0e10cSrcweir replace( '|', '_' );
1179cdf0e10cSrcweir }
1180cdf0e10cSrcweir
1181cdf0e10cSrcweir if( ( aRet.getLength() > 0 ) && bUnique )
1182cdf0e10cSrcweir {
1183cdf0e10cSrcweir while( ::std::find( maUniqueIdVector.begin(), maUniqueIdVector.end(), aRet ) != maUniqueIdVector.end() )
1184cdf0e10cSrcweir {
1185cdf0e10cSrcweir aRet += B2UCONST( "_" );
1186cdf0e10cSrcweir }
1187cdf0e10cSrcweir
1188cdf0e10cSrcweir maUniqueIdVector.push_back( aRet );
1189cdf0e10cSrcweir }
1190cdf0e10cSrcweir
1191cdf0e10cSrcweir return aRet;
1192cdf0e10cSrcweir }
1193cdf0e10cSrcweir
1194cdf0e10cSrcweir // -----------------------------------------------------------------------------
1195cdf0e10cSrcweir
implHasText(const GDIMetaFile & rMtf) const1196cdf0e10cSrcweir sal_Bool SVGFilter::implHasText( const GDIMetaFile& rMtf ) const
1197cdf0e10cSrcweir {
1198cdf0e10cSrcweir sal_Bool bRet = sal_False;
1199cdf0e10cSrcweir
1200cdf0e10cSrcweir for( sal_uInt32 nCurAction = 0, nCount = rMtf.GetActionCount(); ( nCurAction < nCount ) && !bRet; ++nCurAction )
1201cdf0e10cSrcweir {
1202cdf0e10cSrcweir switch( rMtf.GetAction( nCurAction )->GetType() )
1203cdf0e10cSrcweir {
1204cdf0e10cSrcweir case( META_TEXT_ACTION ):
1205cdf0e10cSrcweir case( META_TEXTRECT_ACTION ):
1206cdf0e10cSrcweir case( META_TEXTARRAY_ACTION ):
1207cdf0e10cSrcweir case( META_STRETCHTEXT_ACTION ):
1208cdf0e10cSrcweir {
1209cdf0e10cSrcweir bRet = sal_True;
1210cdf0e10cSrcweir }
1211cdf0e10cSrcweir break;
1212cdf0e10cSrcweir
1213cdf0e10cSrcweir default:
1214cdf0e10cSrcweir break;
1215cdf0e10cSrcweir }
1216cdf0e10cSrcweir }
1217cdf0e10cSrcweir
1218cdf0e10cSrcweir return bRet;
1219cdf0e10cSrcweir }
1220cdf0e10cSrcweir
1221cdf0e10cSrcweir // -----------------------------------------------------------------------------
1222cdf0e10cSrcweir
IMPL_LINK(SVGFilter,CalcFieldHdl,EditFieldInfo *,pInfo)1223cdf0e10cSrcweir IMPL_LINK( SVGFilter, CalcFieldHdl, EditFieldInfo*, pInfo )
1224cdf0e10cSrcweir {
1225cdf0e10cSrcweir OUString aRepresentation;
1226cdf0e10cSrcweir sal_Bool bFieldProcessed = sal_False;
1227cdf0e10cSrcweir
1228cdf0e10cSrcweir if( pInfo )
1229cdf0e10cSrcweir {
1230cdf0e10cSrcweir const ::rtl::OUString aHeaderText( B2UCONST( "HeaderText" ) );
1231cdf0e10cSrcweir const ::rtl::OUString aFooterText( B2UCONST( "FooterText" ) );
1232cdf0e10cSrcweir const ::rtl::OUString aDateTimeText( B2UCONST( "DateTimeText" ) );
1233cdf0e10cSrcweir const ::rtl::OUString aPageNumberText( B2UCONST( "Number" ) );
1234cdf0e10cSrcweir
1235cdf0e10cSrcweir const Reference< XPropertySet > xDefaultPagePropertySet( mxDefaultPage, UNO_QUERY );
1236cdf0e10cSrcweir Reference< XPropertySetInfo > xDefaultPagePropSetInfo( xDefaultPagePropertySet->getPropertySetInfo() );
1237cdf0e10cSrcweir
1238cdf0e10cSrcweir if( xDefaultPagePropSetInfo.is() )
1239cdf0e10cSrcweir {
1240cdf0e10cSrcweir const SvxFieldData* pField = pInfo->GetField().GetField();
1241cdf0e10cSrcweir Any aProperty;
1242cdf0e10cSrcweir
1243cdf0e10cSrcweir if( pField->ISA( SvxHeaderField ) &&
1244cdf0e10cSrcweir xDefaultPagePropSetInfo->hasPropertyByName( aHeaderText ) )
1245cdf0e10cSrcweir {
1246cdf0e10cSrcweir xDefaultPagePropertySet->getPropertyValue( aHeaderText ) >>= aRepresentation;
1247cdf0e10cSrcweir bFieldProcessed = sal_True;
1248cdf0e10cSrcweir }
1249cdf0e10cSrcweir else if( pField->ISA( SvxFooterField ) &&
1250cdf0e10cSrcweir xDefaultPagePropSetInfo->hasPropertyByName( aFooterText ) )
1251cdf0e10cSrcweir {
1252cdf0e10cSrcweir xDefaultPagePropertySet->getPropertyValue( aFooterText ) >>= aRepresentation;
1253cdf0e10cSrcweir bFieldProcessed = sal_True;
1254cdf0e10cSrcweir }
1255cdf0e10cSrcweir else if( pField->ISA( SvxDateTimeField ) &&
1256cdf0e10cSrcweir xDefaultPagePropSetInfo->hasPropertyByName( aDateTimeText ) )
1257cdf0e10cSrcweir {
1258cdf0e10cSrcweir xDefaultPagePropertySet->getPropertyValue( aDateTimeText ) >>= aRepresentation;
1259cdf0e10cSrcweir bFieldProcessed = sal_True;
1260cdf0e10cSrcweir }
1261cdf0e10cSrcweir else if( pField->ISA( SvxPageField ) &&
1262cdf0e10cSrcweir xDefaultPagePropSetInfo->hasPropertyByName( aPageNumberText ) )
1263cdf0e10cSrcweir {
1264cdf0e10cSrcweir String aPageNumValue;
1265cdf0e10cSrcweir sal_Int16 nPageNumber = 0;
1266cdf0e10cSrcweir
1267cdf0e10cSrcweir xDefaultPagePropertySet->getPropertyValue( aPageNumberText ) >>= nPageNumber;
1268cdf0e10cSrcweir
1269cdf0e10cSrcweir if( mpSdrModel )
1270cdf0e10cSrcweir {
1271cdf0e10cSrcweir sal_Bool bUpper = sal_False;
1272cdf0e10cSrcweir
1273cdf0e10cSrcweir switch( mpSdrModel->GetPageNumType() )
1274cdf0e10cSrcweir {
1275cdf0e10cSrcweir case SVX_CHARS_UPPER_LETTER:
1276cdf0e10cSrcweir aPageNumValue += (sal_Unicode)(char)( ( nPageNumber - 1 ) % 26 + 'A' );
1277cdf0e10cSrcweir break;
1278cdf0e10cSrcweir case SVX_CHARS_LOWER_LETTER:
1279cdf0e10cSrcweir aPageNumValue += (sal_Unicode)(char)( ( nPageNumber- 1 ) % 26 + 'a' );
1280cdf0e10cSrcweir break;
1281cdf0e10cSrcweir case SVX_ROMAN_UPPER:
1282cdf0e10cSrcweir bUpper = sal_True;
1283cdf0e10cSrcweir case SVX_ROMAN_LOWER:
1284cdf0e10cSrcweir aPageNumValue += SvxNumberFormat::CreateRomanString( nPageNumber, bUpper );
1285cdf0e10cSrcweir break;
1286cdf0e10cSrcweir case SVX_NUMBER_NONE:
1287cdf0e10cSrcweir aPageNumValue.Erase();
1288cdf0e10cSrcweir aPageNumValue += sal_Unicode(' ');
1289cdf0e10cSrcweir break;
1290cdf0e10cSrcweir default : break;
1291cdf0e10cSrcweir }
1292cdf0e10cSrcweir }
1293cdf0e10cSrcweir
1294cdf0e10cSrcweir if( !aPageNumValue.Len() )
1295cdf0e10cSrcweir aPageNumValue += String::CreateFromInt32( nPageNumber );
1296cdf0e10cSrcweir
1297cdf0e10cSrcweir aRepresentation = aPageNumValue;
1298cdf0e10cSrcweir bFieldProcessed = sal_True;
1299cdf0e10cSrcweir }
1300cdf0e10cSrcweir }
1301cdf0e10cSrcweir
1302cdf0e10cSrcweir pInfo->SetRepresentation( aRepresentation );
1303cdf0e10cSrcweir }
1304cdf0e10cSrcweir
1305cdf0e10cSrcweir return( bFieldProcessed ? 0 : maOldFieldHdl.Call( pInfo ) );
1306cdf0e10cSrcweir }
1307cb0a2370SArmin Le Grand
1308cb0a2370SArmin Le Grand // -----------------------------------------------------------------------------
1309cb0a2370SArmin Le Grand
writeMtf(const GDIMetaFile & rMtf)1310cb0a2370SArmin Le Grand void SVGExport::writeMtf( const GDIMetaFile& rMtf )
1311cb0a2370SArmin Le Grand {
1312cb0a2370SArmin Le Grand const Size aSize( OutputDevice::LogicToLogic( rMtf.GetPrefSize(), rMtf.GetPrefMapMode(), MAP_MM ) );
1313cb0a2370SArmin Le Grand rtl::OUString aAttr;
1314cb0a2370SArmin Le Grand REF( NMSP_SAX::XExtendedDocumentHandler ) xExtDocHandler( GetDocHandler(), NMSP_UNO::UNO_QUERY );
1315cb0a2370SArmin Le Grand
1316cb0a2370SArmin Le Grand if( xExtDocHandler.is() )
1317cb0a2370SArmin Le Grand xExtDocHandler->unknown( SVG_DTD_STRING );
1318cb0a2370SArmin Le Grand
1319cb0a2370SArmin Le Grand aAttr = rtl::OUString::valueOf( aSize.Width() );
1320cb0a2370SArmin Le Grand aAttr += B2UCONST( "mm" );
1321cb0a2370SArmin Le Grand AddAttribute( XML_NAMESPACE_NONE, "width", aAttr );
1322cb0a2370SArmin Le Grand
1323cb0a2370SArmin Le Grand aAttr = rtl::OUString::valueOf( aSize.Height() );
1324cb0a2370SArmin Le Grand aAttr += B2UCONST( "mm" );
1325cb0a2370SArmin Le Grand AddAttribute( XML_NAMESPACE_NONE, "height", aAttr );
1326cb0a2370SArmin Le Grand
1327cb0a2370SArmin Le Grand aAttr = B2UCONST( "0 0 " );
1328cb0a2370SArmin Le Grand aAttr += rtl::OUString::valueOf( aSize.Width() * 100L );
1329cb0a2370SArmin Le Grand aAttr += B2UCONST( " " );
1330cb0a2370SArmin Le Grand aAttr += rtl::OUString::valueOf( aSize.Height() * 100L );
1331cb0a2370SArmin Le Grand AddAttribute( XML_NAMESPACE_NONE, "viewBox", aAttr );
1332bac862b1SArmin Le Grand SetViewBox( Rectangle( Point(), Size( aSize.Width() * 100, aSize.Height() * 100 ) ) );
1333bac862b1SArmin Le Grand
1334bac862b1SArmin Le Grand // standard line width is based on 1 pixel on a 90 DPI device (0.28222mmm)
1335bac862b1SArmin Le Grand AddAttribute( XML_NAMESPACE_NONE, "stroke-width", OUString::valueOf( 28.222 ) );
1336bac862b1SArmin Le Grand AddAttribute( XML_NAMESPACE_NONE, "stroke-linejoin", B2UCONST( "round" ) );
1337cb0a2370SArmin Le Grand
1338bac862b1SArmin Le Grand AddAttribute( XML_NAMESPACE_NONE, "xml:space", B2UCONST( "preserve" ) );
1339cb0a2370SArmin Le Grand {
1340cb0a2370SArmin Le Grand SvXMLElementExport aSVG( *this, XML_NAMESPACE_NONE, "svg", sal_True, sal_True );
1341cb0a2370SArmin Le Grand
1342cb0a2370SArmin Le Grand std::vector< ObjectRepresentation > aObjects;
1343cb0a2370SArmin Le Grand
1344cb0a2370SArmin Le Grand aObjects.push_back( ObjectRepresentation( Reference< XInterface >(), rMtf ) );
1345cb0a2370SArmin Le Grand SVGFontExport aSVGFontExport( *this, aObjects );
1346cb0a2370SArmin Le Grand
1347cb0a2370SArmin Le Grand Point aPoint100thmm( OutputDevice::LogicToLogic( rMtf.GetPrefMapMode().GetOrigin(), rMtf.GetPrefMapMode(), MAP_100TH_MM ) );
1348cb0a2370SArmin Le Grand Size aSize100thmm( OutputDevice::LogicToLogic( rMtf.GetPrefSize(), rMtf.GetPrefMapMode(), MAP_100TH_MM ) );
1349cb0a2370SArmin Le Grand
1350cb0a2370SArmin Le Grand SVGActionWriter aWriter( *this, aSVGFontExport );
1351cb0a2370SArmin Le Grand aWriter.WriteMetaFile( aPoint100thmm, aSize100thmm, rMtf,
1352cb0a2370SArmin Le Grand SVGWRITER_WRITE_FILL | SVGWRITER_WRITE_TEXT, NULL );
1353cb0a2370SArmin Le Grand }
1354cb0a2370SArmin Le Grand }
1355