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