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