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