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