Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include "svgwriter.hxx"
21 : #include "svgfontexport.hxx"
22 : #include "svgfilter.hxx"
23 : #include "svgscript.hxx"
24 : #include "impsvgdialog.hxx"
25 :
26 : #include <com/sun/star/util/MeasureUnit.hpp>
27 : #include <com/sun/star/text/textfield/Type.hpp>
28 : #include <com/sun/star/xml/sax/Writer.hpp>
29 :
30 : #include <rtl/bootstrap.hxx>
31 : #include <svtools/miscopt.hxx>
32 : #include <svx/unopage.hxx>
33 : #include <svx/unoshape.hxx>
34 : #include <svx/svdpage.hxx>
35 : #include <svx/svdoutl.hxx>
36 : #include <editeng/outliner.hxx>
37 : #include <editeng/flditem.hxx>
38 : #include <editeng/numitem.hxx>
39 : #include <comphelper/processfactory.hxx>
40 : #include <i18npool/lang.h>
41 : #include <svl/zforlist.hxx>
42 : #include <xmloff/unointerfacetouniqueidentifiermapper.hxx>
43 : #include <xmloff/animationexport.hxx>
44 :
45 : #include <boost/preprocessor/repetition/repeat.hpp>
46 :
47 : using ::rtl::OUString;
48 : using namespace ::com::sun::star;
49 :
50 : // -------------------------------
51 : // - ooo elements and attributes -
52 : // -------------------------------
53 :
54 : #define NSPREFIX "ooo:"
55 :
56 : // ooo xml elements
57 : static const char aOOOElemMetaSlides[] = NSPREFIX "meta_slides";
58 : static const char aOOOElemMetaSlide[] = NSPREFIX "meta_slide";
59 : static const char aOOOElemTextField[] = NSPREFIX "text_field";
60 :
61 : // ooo xml attributes for meta_slides
62 : static const char aOOOAttrNumberOfSlides[] = NSPREFIX "number-of-slides";
63 : static const char aOOOAttrStartSlideNumber[] = NSPREFIX "start-slide-number";
64 : static const char aOOOAttrNumberingType[] = NSPREFIX "page-numbering-type";
65 :
66 : // ooo xml attributes for meta_slide
67 : static const char aOOOAttrSlide[] = NSPREFIX "slide";
68 : static const char aOOOAttrMaster[] = NSPREFIX "master";
69 : static const char aOOOAttrBackgroundVisibility[] = NSPREFIX "background-visibility";
70 : static const char aOOOAttrMasterObjectsVisibility[] = NSPREFIX "master-objects-visibility";
71 : static const char aOOOAttrPageNumberVisibility[] = NSPREFIX "page-number-visibility";
72 : static const char aOOOAttrDateTimeVisibility[] = NSPREFIX "date-time-visibility";
73 : static const char aOOOAttrFooterVisibility[] = NSPREFIX "footer-visibility";
74 : static const char aOOOAttrDateTimeField[] = NSPREFIX "date-time-field";
75 : static const char aOOOAttrFooterField[] = NSPREFIX "footer-field";
76 : static const char aOOOAttrHeaderField[] = NSPREFIX "header-field";
77 : static const char aOOOAttrHasTransition[] = NSPREFIX "has-transition";
78 : static const char aOOOAttrIdList[] = NSPREFIX "id-list";
79 :
80 : // ooo xml attributes for pages and shapes
81 : static const char aOOOAttrName[] = NSPREFIX "name";
82 :
83 : // ooo xml attributes for date_time_field
84 : static const char aOOOAttrDateTimeFormat[] = NSPREFIX "date-time-format";
85 :
86 : // ooo xml attributes for Placeholder Shapes
87 : static const char aOOOAttrTextAdjust[] = NSPREFIX "text-adjust";
88 :
89 :
90 :
91 : /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
92 : * - Text Field Class Hierarchy - *
93 : * *
94 : * This is a set of classes for exporting text field meta info. *
95 : * *
96 : * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
97 :
98 : #define TEXT_FIELD_GET_CLASS_NAME_METHOD( class_name ) \
99 : virtual ::rtl::OUString getClassName() const \
100 : { \
101 : static const char className[] = #class_name; \
102 : return B2UCONST( className ); \
103 : }
104 :
105 :
106 0 : class TextField
107 : {
108 : protected:
109 : SVGFilter::ObjectSet mMasterPageSet;
110 : public:
111 :
112 0 : TEXT_FIELD_GET_CLASS_NAME_METHOD( TextField )
113 : virtual sal_Bool equalTo( const TextField & aTextField ) const = 0;
114 : virtual void growCharSet( SVGFilter::UCharSetMapMap & aTextFieldCharSets ) const = 0;
115 0 : virtual void elementExport( SVGExport* pSVGExport ) const
116 : {
117 0 : pSVGExport->AddAttribute( XML_NAMESPACE_NONE, "class", getClassName() );
118 0 : }
119 0 : void insertMasterPage( Reference< XDrawPage> xMasterPage )
120 : {
121 0 : mMasterPageSet.insert( xMasterPage );
122 0 : }
123 0 : virtual ~TextField() {}
124 : protected:
125 0 : void implGrowCharSet( SVGFilter::UCharSetMapMap & aTextFieldCharSets, ::rtl::OUString sText, ::rtl::OUString sTextFieldId ) const
126 : {
127 0 : const sal_Unicode * ustr = sText.getStr();
128 0 : sal_Int32 nLength = sText.getLength();
129 0 : SVGFilter::ObjectSet::const_iterator aMasterPageIt = mMasterPageSet.begin();
130 0 : for( ; aMasterPageIt != mMasterPageSet.end(); ++aMasterPageIt )
131 : {
132 0 : const Reference< XInterface > & xMasterPage = *aMasterPageIt;
133 0 : for( sal_Int32 i = 0; i < nLength; ++i )
134 : {
135 0 : aTextFieldCharSets[ xMasterPage ][ sTextFieldId ].insert( ustr[i] );
136 : }
137 : }
138 0 : }
139 : };
140 :
141 0 : class FixedTextField : public TextField
142 : {
143 : public:
144 : ::rtl::OUString text;
145 :
146 0 : TEXT_FIELD_GET_CLASS_NAME_METHOD( FixedTextField )
147 0 : virtual sal_Bool equalTo( const TextField & aTextField ) const
148 : {
149 0 : if( const FixedTextField* aFixedTextField = dynamic_cast< const FixedTextField* >( &aTextField ) )
150 : {
151 0 : return ( text == aFixedTextField->text );
152 : }
153 0 : return false;
154 : }
155 0 : virtual void elementExport( SVGExport* pSVGExport ) const
156 : {
157 0 : TextField::elementExport( pSVGExport );
158 0 : SvXMLElementExport aExp( *pSVGExport, XML_NAMESPACE_NONE, "g", sal_True, sal_True );
159 0 : pSVGExport->GetDocHandler()->characters( text );
160 0 : }
161 0 : virtual ~FixedTextField() {}
162 : };
163 :
164 0 : class FixedDateTimeField : public FixedTextField
165 : {
166 : public:
167 0 : FixedDateTimeField() {}
168 0 : TEXT_FIELD_GET_CLASS_NAME_METHOD( FixedDateTimeField )
169 0 : virtual void growCharSet( SVGFilter::UCharSetMapMap & aTextFieldCharSets ) const
170 : {
171 0 : static const ::rtl::OUString sFieldId = B2UCONST( aOOOAttrDateTimeField );
172 0 : implGrowCharSet( aTextFieldCharSets, text, sFieldId );
173 0 : }
174 0 : virtual ~FixedDateTimeField() {}
175 : };
176 :
177 0 : class FooterField : public FixedTextField
178 : {
179 : public:
180 0 : FooterField() {}
181 0 : TEXT_FIELD_GET_CLASS_NAME_METHOD( FooterField )
182 0 : virtual void growCharSet( SVGFilter::UCharSetMapMap & aTextFieldCharSets ) const
183 : {
184 0 : static const ::rtl::OUString sFieldId = B2UCONST( aOOOAttrFooterField );
185 0 : implGrowCharSet( aTextFieldCharSets, text, sFieldId );
186 0 : }
187 0 : virtual ~FooterField() {}
188 : };
189 :
190 : class HeaderField : public FixedTextField
191 : {
192 : public:
193 : HeaderField() {}
194 0 : TEXT_FIELD_GET_CLASS_NAME_METHOD( HeaderField )
195 0 : virtual void growCharSet( SVGFilter::UCharSetMapMap & aTextFieldCharSets ) const
196 : {
197 0 : static const ::rtl::OUString sFieldId = B2UCONST( aOOOAttrHeaderField );
198 0 : implGrowCharSet( aTextFieldCharSets, text, sFieldId );
199 0 : }
200 0 : virtual ~HeaderField() {}
201 : };
202 :
203 0 : class VariableTextField : public TextField
204 : {
205 : public:
206 0 : TEXT_FIELD_GET_CLASS_NAME_METHOD( VariableTextField )
207 0 : virtual ~VariableTextField() {}
208 : };
209 :
210 0 : class VariableDateTimeField : public VariableTextField
211 : {
212 : public:
213 : sal_Int32 format;
214 :
215 0 : VariableDateTimeField() {}
216 0 : TEXT_FIELD_GET_CLASS_NAME_METHOD( VariableDateTimeField )
217 0 : virtual sal_Bool equalTo( const TextField & aTextField ) const
218 : {
219 0 : if( const VariableDateTimeField* aField = dynamic_cast< const VariableDateTimeField* >( &aTextField ) )
220 : {
221 0 : return ( format == aField->format );
222 : }
223 0 : return false;
224 : }
225 0 : virtual void elementExport( SVGExport* pSVGExport ) const
226 : {
227 0 : VariableTextField::elementExport( pSVGExport );
228 0 : OUString sDateFormat, sTimeFormat;
229 0 : SvxDateFormat eDateFormat = (SvxDateFormat)( format & 0x0f );
230 0 : if( eDateFormat )
231 : {
232 0 : switch( eDateFormat )
233 : {
234 : case SVXDATEFORMAT_STDSMALL: ;
235 : case SVXDATEFORMAT_A: // 13.02.96
236 0 : sDateFormat = B2UCONST( "" );
237 0 : break;
238 : case SVXDATEFORMAT_C: // 13.Feb 1996
239 0 : sDateFormat = B2UCONST( "" );
240 0 : break;
241 : case SVXDATEFORMAT_D: // 13.February 1996
242 0 : sDateFormat = B2UCONST( "" );
243 0 : break;
244 : case SVXDATEFORMAT_E: // Tue, 13.February 1996
245 0 : sDateFormat = B2UCONST( "" );
246 0 : break;
247 : case SVXDATEFORMAT_STDBIG: ;
248 : case SVXDATEFORMAT_F: // Tuesday, 13.February 1996
249 0 : sDateFormat = B2UCONST( "" );
250 0 : break;
251 : // default case
252 : case SVXDATEFORMAT_B: ; // 13.02.1996
253 : default:
254 0 : sDateFormat = B2UCONST( "" );
255 0 : break;
256 : }
257 : }
258 :
259 0 : SvxTimeFormat eTimeFormat = (SvxTimeFormat)( ( format >> 4 ) & 0x0f );
260 0 : if( eTimeFormat )
261 : {
262 0 : switch( eTimeFormat )
263 : {
264 : case SVXTIMEFORMAT_24_HMS: // 13:49:38
265 0 : sTimeFormat = B2UCONST( "" );
266 0 : break;
267 : case SVXTIMEFORMAT_AM_HM: ; // 01:49 PM
268 : case SVXTIMEFORMAT_12_HM:
269 0 : sTimeFormat = B2UCONST( "" );
270 0 : break;
271 : case SVXTIMEFORMAT_AM_HMS: ; // 01:49:38 PM
272 : case SVXTIMEFORMAT_12_HMS:
273 0 : sTimeFormat = B2UCONST( "" );
274 0 : break;
275 : // default case
276 : case SVXTIMEFORMAT_24_HM: ; // 13:49
277 : default:
278 0 : sTimeFormat = B2UCONST( "" );
279 0 : break;
280 : }
281 : }
282 :
283 0 : OUString sDateTimeFormat = sDateFormat;
284 0 : sDateTimeFormat += OUString::valueOf( sal_Unicode(' ') );
285 0 : sDateTimeFormat += sTimeFormat;
286 :
287 0 : pSVGExport->AddAttribute( XML_NAMESPACE_NONE, aOOOAttrDateTimeFormat, sDateTimeFormat );
288 0 : SvXMLElementExport aExp( *pSVGExport, XML_NAMESPACE_NONE, "g", sal_True, sal_True );
289 0 : }
290 0 : virtual void growCharSet( SVGFilter::UCharSetMapMap & aTextFieldCharSets ) const
291 : {
292 : // we use the unicode char set in an improper way: we put in the date/time fortat
293 : // in order to pass it to the CalcFieldValue method
294 0 : static const ::rtl::OUString sFieldId = B2UCONST( aOOOAttrDateTimeField ) + B2UCONST( "-variable" );
295 0 : SVGFilter::ObjectSet::const_iterator aMasterPageIt = mMasterPageSet.begin();
296 0 : for( ; aMasterPageIt != mMasterPageSet.end(); ++aMasterPageIt )
297 : {
298 0 : aTextFieldCharSets[ *aMasterPageIt ][ sFieldId ].insert( (sal_Unicode)( format ) );
299 : }
300 0 : }
301 0 : virtual ~VariableDateTimeField() {}
302 : };
303 :
304 0 : sal_Bool operator==( const TextField & aLhsTextField, const TextField & aRhsTextField )
305 : {
306 0 : return aLhsTextField.equalTo( aRhsTextField );
307 : }
308 :
309 :
310 :
311 : // -------------
312 : // - SVGExport -
313 : // -------------
314 :
315 0 : SVGExport::SVGExport(
316 : const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceFactory,
317 : const Reference< XDocumentHandler >& rxHandler,
318 : const Sequence< PropertyValue >& rFilterData )
319 : : SvXMLExport( util::MeasureUnit::MM_100TH,
320 : xServiceFactory,
321 : xmloff::token::XML_TOKEN_INVALID,
322 : EXPORT_META|EXPORT_PRETTY )
323 0 : , mrFilterData( rFilterData )
324 : {
325 0 : SetDocHandler( rxHandler );
326 0 : GetDocHandler()->startDocument();
327 0 : }
328 :
329 : // -----------------------------------------------------------------------------
330 :
331 0 : SVGExport::~SVGExport()
332 : {
333 0 : GetDocHandler()->endDocument();
334 0 : }
335 :
336 : // -----------------------------------------------------------------------------
337 :
338 0 : sal_Bool SVGExport::IsUseTinyProfile() const
339 : {
340 0 : sal_Bool bRet = sal_False;
341 :
342 0 : if( IsUsePositionedCharacters() && mrFilterData.getLength() > 0 )
343 0 : mrFilterData[ 0 ].Value >>= bRet;
344 :
345 0 : return bRet;
346 : }
347 :
348 : // -----------------------------------------------------------------------------
349 :
350 0 : sal_Bool SVGExport::IsEmbedFonts() const
351 : {
352 0 : sal_Bool bRet = sal_False;
353 :
354 0 : if( IsUsePositionedCharacters() && mrFilterData.getLength() > 1 )
355 0 : mrFilterData[ 1 ].Value >>= bRet;
356 :
357 0 : return bRet;
358 : }
359 :
360 : // -----------------------------------------------------------------------------
361 :
362 0 : sal_Bool SVGExport::IsUseNativeTextDecoration() const
363 : {
364 0 : sal_Bool bRet = !IsUseTinyProfile();
365 :
366 0 : if( bRet && ( mrFilterData.getLength() > 2 ) )
367 0 : mrFilterData[ 2 ].Value >>= bRet;
368 :
369 0 : return bRet;
370 : }
371 :
372 : // -----------------------------------------------------------------------------
373 :
374 0 : sal_Bool SVGExport::IsUseOpacity() const
375 : {
376 0 : sal_Bool bRet = !IsUseTinyProfile();
377 :
378 0 : if( !bRet && ( mrFilterData.getLength() > 4 ) )
379 0 : mrFilterData[ 4 ].Value >>= bRet;
380 :
381 0 : return bRet;
382 : }
383 :
384 : // -----------------------------------------------------------------------------
385 :
386 0 : sal_Bool SVGExport::IsUsePositionedCharacters() const
387 : {
388 0 : sal_Bool bRet = sal_False;
389 0 : if( mrFilterData.getLength() > 6 )
390 0 : mrFilterData[ 6 ].Value >>= bRet;
391 :
392 0 : return bRet;
393 : }
394 :
395 :
396 : // ------------------------
397 : // - ObjectRepresentation -
398 : // ------------------------
399 :
400 0 : ObjectRepresentation::ObjectRepresentation() :
401 0 : mpMtf( NULL )
402 : {
403 0 : }
404 :
405 : // -----------------------------------------------------------------------------
406 :
407 0 : ObjectRepresentation::ObjectRepresentation( const Reference< XInterface >& rxObject,
408 : const GDIMetaFile& rMtf ) :
409 : mxObject( rxObject ),
410 0 : mpMtf( new GDIMetaFile( rMtf ) )
411 : {
412 0 : }
413 :
414 : // -----------------------------------------------------------------------------
415 :
416 0 : ObjectRepresentation::ObjectRepresentation( const ObjectRepresentation& rPresentation ) :
417 : mxObject( rPresentation.mxObject ),
418 0 : mpMtf( rPresentation.mpMtf ? new GDIMetaFile( *rPresentation.mpMtf ) : NULL )
419 : {
420 0 : }
421 :
422 : // -----------------------------------------------------------------------------
423 :
424 0 : ObjectRepresentation::~ObjectRepresentation()
425 : {
426 0 : delete mpMtf;
427 0 : }
428 :
429 : // -----------------------------------------------------------------------------
430 :
431 0 : ObjectRepresentation& ObjectRepresentation::operator=( const ObjectRepresentation& rPresentation )
432 : {
433 : // Check for self-assignment
434 0 : if (this == &rPresentation)
435 0 : return *this;
436 0 : mxObject = rPresentation.mxObject;
437 0 : delete mpMtf, ( mpMtf = rPresentation.mpMtf ? new GDIMetaFile( *rPresentation.mpMtf ) : NULL );
438 :
439 0 : return *this;
440 : }
441 :
442 : // -----------------------------------------------------------------------------
443 :
444 0 : sal_Bool ObjectRepresentation::operator==( const ObjectRepresentation& rPresentation ) const
445 : {
446 0 : return( ( mxObject == rPresentation.mxObject ) &&
447 0 : ( *mpMtf == *rPresentation.mpMtf ) );
448 : }
449 :
450 : // -----------------------------------------------------------------------------
451 :
452 0 : sal_uLong GetBitmapChecksum( const MetaAction* pAction )
453 : {
454 0 : sal_uLong nChecksum = 0;
455 0 : const sal_uInt16 nType = pAction->GetType();
456 :
457 0 : switch( nType )
458 : {
459 : case( META_BMPSCALE_ACTION ):
460 : {
461 0 : const MetaBmpScaleAction* pA = (const MetaBmpScaleAction*) pAction;
462 0 : if( pA )
463 0 : nChecksum = pA->GetBitmap().GetChecksum();
464 : else
465 : OSL_FAIL( "GetBitmapChecksum: MetaBmpScaleAction pointer is null." );
466 : }
467 0 : break;
468 : case( META_BMPEXSCALE_ACTION ):
469 : {
470 0 : const MetaBmpExScaleAction* pA = (const MetaBmpExScaleAction*) pAction;
471 0 : if( pA )
472 0 : nChecksum = pA->GetBitmapEx().GetChecksum();
473 : else
474 : OSL_FAIL( "GetBitmapChecksum: MetaBmpExScaleAction pointer is null." );
475 : }
476 0 : break;
477 : }
478 0 : return nChecksum;
479 : }
480 : // -----------------------------------------------------------------------------
481 :
482 0 : void MetaBitmapActionGetPoint( const MetaAction* pAction, Point& rPt )
483 : {
484 0 : const sal_uInt16 nType = pAction->GetType();
485 0 : switch( nType )
486 : {
487 : case( META_BMPSCALE_ACTION ):
488 : {
489 0 : const MetaBmpScaleAction* pA = (const MetaBmpScaleAction*) pAction;
490 0 : if( pA )
491 0 : rPt = pA->GetPoint();
492 : else
493 : OSL_FAIL( "MetaBitmapActionGetPoint: MetaBmpScaleAction pointer is null." );
494 : }
495 0 : break;
496 : case( META_BMPEXSCALE_ACTION ):
497 : {
498 0 : const MetaBmpExScaleAction* pA = (const MetaBmpExScaleAction*) pAction;
499 0 : if( pA )
500 0 : rPt = pA->GetPoint();
501 : else
502 : OSL_FAIL( "MetaBitmapActionGetPoint: MetaBmpExScaleAction pointer is null." );
503 : }
504 0 : break;
505 : }
506 :
507 0 : }
508 :
509 : // -----------------------------------------------------------------------------
510 :
511 0 : size_t HashBitmap::operator()( const ObjectRepresentation& rObjRep ) const
512 : {
513 0 : const GDIMetaFile& aMtf = rObjRep.GetRepresentation();
514 0 : if( aMtf.GetActionSize() == 1 )
515 : {
516 0 : return static_cast< size_t >( GetBitmapChecksum( aMtf.GetAction( 0 ) ) );
517 : }
518 : else
519 : {
520 : OSL_FAIL( "HashBitmap: metafile should have a single action." );
521 0 : return 0;
522 : }
523 : }
524 :
525 : // -----------------------------------------------------------------------------
526 :
527 0 : bool EqualityBitmap::operator()( const ObjectRepresentation& rObjRep1,
528 : const ObjectRepresentation& rObjRep2 ) const
529 : {
530 0 : const GDIMetaFile& aMtf1 = rObjRep1.GetRepresentation();
531 0 : const GDIMetaFile& aMtf2 = rObjRep2.GetRepresentation();
532 0 : if( aMtf1.GetActionSize() == 1 && aMtf2.GetActionSize() == 1 )
533 : {
534 0 : sal_uLong nChecksum1 = GetBitmapChecksum( aMtf1.GetAction( 0 ) );
535 0 : sal_uLong nChecksum2 = GetBitmapChecksum( aMtf2.GetAction( 0 ) );
536 0 : return ( nChecksum1 == nChecksum2 );
537 : }
538 : else
539 : {
540 : OSL_FAIL( "EqualityBitmap: metafile should have a single action." );
541 0 : return false;
542 : }
543 : }
544 :
545 :
546 : // -------------
547 : // - SVGFilter -
548 : // -------------
549 :
550 0 : sal_Bool SVGFilter::implExport( const Sequence< PropertyValue >& rDescriptor )
551 : throw (RuntimeException)
552 : {
553 0 : Reference< XMultiServiceFactory > xServiceFactory( ::comphelper::getProcessServiceFactory() ) ;
554 0 : Reference< XOutputStream > xOStm;
555 0 : SvStream* pOStm = NULL;
556 0 : sal_Int32 nLength = rDescriptor.getLength();
557 0 : const PropertyValue* pValue = rDescriptor.getConstArray();
558 0 : sal_Bool bRet = sal_False;
559 :
560 0 : maFilterData.realloc( 0 );
561 :
562 0 : for ( sal_Int32 i = 0 ; i < nLength; ++i)
563 : {
564 0 : if ( pValue[ i ].Name == "OutputStream" )
565 0 : pValue[ i ].Value >>= xOStm;
566 0 : else if ( pValue[ i ].Name == "FileName" )
567 : {
568 0 : ::rtl::OUString aFileName;
569 :
570 0 : pValue[ i ].Value >>= aFileName;
571 0 : pOStm = ::utl::UcbStreamHelper::CreateStream( aFileName, STREAM_WRITE | STREAM_TRUNC );
572 :
573 0 : if( pOStm )
574 0 : xOStm = Reference< XOutputStream >( new ::utl::OOutputStreamWrapper ( *pOStm ) );
575 : }
576 0 : else if ( pValue[ i ].Name == "FilterData" )
577 : {
578 0 : pValue[ i ].Value >>= maFilterData;
579 : }
580 : }
581 :
582 : // if no filter data is given use stored/prepared ones
583 0 : if( !maFilterData.getLength() )
584 : {
585 0 : maFilterData.realloc( 6 );
586 :
587 0 : maFilterData[ 0 ].Name = B2UCONST( SVG_PROP_TINYPROFILE );
588 0 : maFilterData[ 0 ].Value <<= (sal_Bool) sal_True;
589 :
590 : // font embedding
591 0 : const char* pSVGDisableFontEmbedding = getenv( "SVG_DISABLE_FONT_EMBEDDING" );
592 : rtl::OUString aEmbedFontEnv(
593 0 : RTL_CONSTASCII_USTRINGPARAM("${SVG_DISABLE_FONT_EMBEDDING}"));
594 0 : rtl::Bootstrap::expandMacros(aEmbedFontEnv);
595 : const bool bEmbedFonts=pSVGDisableFontEmbedding ? false : (
596 0 : aEmbedFontEnv.getLength() ? false : true);
597 :
598 0 : maFilterData[ 1 ].Name = B2UCONST( SVG_PROP_EMBEDFONTS );
599 0 : maFilterData[ 1 ].Value <<= (sal_Bool) (bEmbedFonts);
600 :
601 : // Native decoration
602 0 : maFilterData[ 2 ].Name = B2UCONST( SVG_PROP_NATIVEDECORATION );
603 0 : maFilterData[ 2 ].Value <<= (sal_Bool) sal_False;
604 :
605 : // glyph placement
606 0 : const char* pSVGGlyphPlacement = getenv( "SVG_GLYPH_PLACEMENT" );
607 :
608 0 : maFilterData[ 3 ].Name = B2UCONST( SVG_PROP_GLYPHPLACEMENT );
609 :
610 0 : if( pSVGGlyphPlacement )
611 0 : maFilterData[ 3 ].Value <<= ::rtl::OUString::createFromAscii( pSVGGlyphPlacement );
612 : else
613 0 : maFilterData[ 3 ].Value <<= B2UCONST( "xlist" );
614 :
615 : // Tiny Opacity
616 0 : maFilterData[ 4 ].Name = B2UCONST( SVG_PROP_OPACITY );
617 0 : maFilterData[ 4 ].Value <<= (sal_Bool) sal_True;
618 :
619 : // Tiny Gradient
620 0 : maFilterData[ 5 ].Name = B2UCONST( SVG_PROP_GRADIENT );
621 0 : maFilterData[ 5 ].Value <<= (sal_Bool) sal_False;
622 : }
623 :
624 0 : if( xOStm.is() && xServiceFactory.is() )
625 : {
626 0 : if( mSelectedPages.hasElements() && mMasterPageTargets.hasElements() )
627 : {
628 0 : Reference< XDocumentHandler > xDocHandler( implCreateExportDocumentHandler( xOStm ), UNO_QUERY );
629 :
630 0 : if( xDocHandler.is() )
631 : {
632 0 : mbPresentation = Reference< XPresentationSupplier >( mxSrcDoc, UNO_QUERY ).is();
633 0 : mpObjects = new ObjectMap;
634 :
635 : // #110680#
636 : // mpSVGExport = new SVGExport( xDocHandler );
637 0 : mpSVGExport = new SVGExport( xServiceFactory, xDocHandler, maFilterData );
638 :
639 0 : if( mpSVGExport != NULL )
640 : {
641 : // xSVGExport is set up only to manage the life-time of the object pointed by mpSVGExport,
642 : // and in order to prevent that it is destroyed when passed to AnimationExporter.
643 0 : Reference< XInterface > xSVGExport = static_cast< ::com::sun::star::document::XFilter* >( mpSVGExport );
644 :
645 : // create an id for each draw page
646 0 : for( sal_Int32 i = 0; i < mSelectedPages.getLength(); ++i )
647 0 : implRegisterInterface( mSelectedPages[i] );
648 :
649 : // create an id for each master page
650 0 : for( sal_Int32 i = 0; i < mMasterPageTargets.getLength(); ++i )
651 0 : implRegisterInterface( mMasterPageTargets[i] );
652 :
653 : try
654 : {
655 0 : mxDefaultPage = mSelectedPages[0];
656 :
657 0 : if( mxDefaultPage.is() )
658 : {
659 0 : SvxDrawPage* pSvxDrawPage = SvxDrawPage::getImplementation( mxDefaultPage );
660 :
661 0 : if( pSvxDrawPage )
662 : {
663 0 : mpDefaultSdrPage = pSvxDrawPage->GetSdrPage();
664 0 : mpSdrModel = mpDefaultSdrPage->GetModel();
665 :
666 0 : if( mpSdrModel )
667 : {
668 0 : SdrOutliner& rOutl = mpSdrModel->GetDrawOutliner(NULL);
669 :
670 0 : maOldFieldHdl = rOutl.GetCalcFieldValueHdl();
671 0 : rOutl.SetCalcFieldValueHdl( LINK( this, SVGFilter, CalcFieldHdl) );
672 : }
673 : }
674 0 : bRet = implExportDocument();
675 : }
676 : }
677 0 : catch( ... )
678 : {
679 0 : delete mpSVGDoc, mpSVGDoc = NULL;
680 : OSL_FAIL( "Exception caught" );
681 : }
682 :
683 0 : if( mpSdrModel )
684 0 : mpSdrModel->GetDrawOutliner( NULL ).SetCalcFieldValueHdl( maOldFieldHdl );
685 :
686 0 : delete mpSVGWriter, mpSVGWriter = NULL;
687 0 : mpSVGExport = NULL; // pointed object is released by xSVGExport dtor at the end of this scope
688 0 : delete mpSVGFontExport, mpSVGFontExport = NULL;
689 0 : delete mpObjects, mpObjects = NULL;
690 0 : mbPresentation = sal_False;
691 : }
692 0 : }
693 : }
694 : }
695 :
696 0 : delete pOStm;
697 :
698 0 : return bRet;
699 : }
700 :
701 : // -----------------------------------------------------------------------------
702 :
703 0 : Reference< XWriter > SVGFilter::implCreateExportDocumentHandler( const Reference< XOutputStream >& rxOStm )
704 : {
705 0 : Reference< XWriter > xSaxWriter;
706 :
707 0 : if( rxOStm.is() )
708 : {
709 0 : xSaxWriter = Writer::create( ::comphelper::getProcessComponentContext() );
710 0 : xSaxWriter->setOutputStream( rxOStm );
711 : }
712 :
713 0 : return xSaxWriter;
714 : }
715 :
716 : // -----------------------------------------------------------------------------
717 :
718 0 : sal_Bool SVGFilter::implLookForFirstVisiblePage()
719 : {
720 0 : sal_Int32 nCurPage = 0, nLastPage = mSelectedPages.getLength() - 1;
721 :
722 0 : while( ( nCurPage <= nLastPage ) && ( -1 == mnVisiblePage ) )
723 : {
724 0 : const Reference< XDrawPage > & xDrawPage = mSelectedPages[nCurPage];
725 :
726 0 : if( xDrawPage.is() )
727 : {
728 0 : Reference< XPropertySet > xPropSet( xDrawPage, UNO_QUERY );
729 :
730 0 : if( xPropSet.is() )
731 : {
732 0 : sal_Bool bVisible = sal_False;
733 :
734 0 : if( !mbPresentation || mbSinglePage ||
735 0 : ( ( xPropSet->getPropertyValue( B2UCONST( "Visible" ) ) >>= bVisible ) && bVisible ) )
736 : {
737 0 : mnVisiblePage = nCurPage;
738 : }
739 0 : }
740 : }
741 0 : ++nCurPage;
742 : }
743 :
744 0 : return ( mnVisiblePage != -1 );
745 : }
746 :
747 : // -----------------------------------------------------------------------------
748 0 : sal_Bool SVGFilter::implExportDocument()
749 : {
750 0 : OUString aAttr;
751 0 : sal_Int32 nDocWidth = 0, nDocHeight = 0;
752 0 : sal_Bool bRet = sal_False;
753 0 : sal_Int32 nLastPage = mSelectedPages.getLength() - 1;
754 :
755 0 : SvtMiscOptions aMiscOptions;
756 0 : const bool bExperimentalMode = aMiscOptions.IsExperimentalMode();
757 :
758 0 : mbSinglePage = (nLastPage == 0) || !bExperimentalMode;
759 0 : mnVisiblePage = -1;
760 :
761 0 : const Reference< XPropertySet > xDefaultPagePropertySet( mxDefaultPage, UNO_QUERY );
762 0 : const Reference< XExtendedDocumentHandler > xExtDocHandler( mpSVGExport->GetDocHandler(), UNO_QUERY );
763 :
764 0 : if( xDefaultPagePropertySet.is() )
765 : {
766 0 : xDefaultPagePropertySet->getPropertyValue( B2UCONST( "Width" ) ) >>= nDocWidth;
767 0 : xDefaultPagePropertySet->getPropertyValue( B2UCONST( "Height" ) ) >>= nDocHeight;
768 : }
769 :
770 0 : if( xExtDocHandler.is() && !mpSVGExport->IsUseTinyProfile() )
771 : {
772 0 : xExtDocHandler->unknown( SVG_DTD_STRING );
773 : }
774 :
775 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "version", B2UCONST( "1.2" ) );
776 :
777 0 : if( mpSVGExport->IsUseTinyProfile() )
778 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "baseProfile", B2UCONST( "tiny" ) );
779 :
780 : // enabling _SVG_WRITE_EXTENTS means that the slide size is not adapted
781 : // to the size of the browser window, moreover the slide is top left aligned
782 : // instead of centered.
783 : #define _SVG_WRITE_EXTENTS
784 : #ifdef _SVG_WRITE_EXTENTS
785 0 : if( mbSinglePage )
786 : {
787 0 : aAttr = OUString::valueOf( nDocWidth * 0.01 );
788 0 : aAttr += B2UCONST( "mm" );
789 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "width", aAttr );
790 :
791 0 : aAttr = OUString::valueOf( nDocHeight * 0.01 );
792 0 : aAttr += B2UCONST( "mm" );
793 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "height", aAttr );
794 : }
795 : #endif
796 :
797 :
798 0 : aAttr = B2UCONST( "0 0 " );
799 0 : aAttr += OUString::valueOf( nDocWidth );
800 0 : aAttr += B2UCONST( " " );
801 0 : aAttr += OUString::valueOf( nDocHeight );
802 :
803 0 : msClipPathId = B2UCONST( "presentation_clip_path" );
804 0 : OUString sClipPathAttrValue = B2UCONST( "url(#" ) + msClipPathId + B2UCONST( ")" );
805 :
806 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "viewBox", aAttr );
807 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "preserveAspectRatio", B2UCONST( "xMidYMid" ) );
808 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "fill-rule", B2UCONST( "evenodd" ) );
809 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "clip-path", sClipPathAttrValue );
810 :
811 : // standard line width is based on 1 pixel on a 90 DPI device (0.28222mmm)
812 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "stroke-width", OUString::valueOf( 28.222 ) );
813 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "stroke-linejoin", B2UCONST( "round" ) );
814 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "xmlns", B2UCONST( "http://www.w3.org/2000/svg" ) );
815 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "xmlns:ooo", B2UCONST( "http://xml.openoffice.org/svg/export" ) );
816 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "xmlns:xlink", B2UCONST( "http://www.w3.org/1999/xlink" ) );
817 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "xml:space", B2UCONST( "preserve" ) );
818 :
819 0 : mpSVGDoc = new SvXMLElementExport( *mpSVGExport, XML_NAMESPACE_NONE, "svg", sal_True, sal_True );
820 :
821 : // Create a ClipPath element that will be used for cutting bitmaps and other elements that could exceed the page margins.
822 : {
823 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "class", B2UCONST( "ClipPathGroup" ) );
824 0 : SvXMLElementExport aDefsElem( *mpSVGExport, XML_NAMESPACE_NONE, "defs", sal_True, sal_True );
825 : {
826 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "id", msClipPathId );
827 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "clipPathUnits", B2UCONST( "userSpaceOnUse" ) );
828 0 : SvXMLElementExport aClipPathElem( *mpSVGExport, XML_NAMESPACE_NONE, "clipPath", sal_True, sal_True );
829 : {
830 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "x", OUString::valueOf( sal_Int32(0) ) );
831 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "y", OUString::valueOf( sal_Int32(0) ) );
832 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "width", OUString::valueOf( nDocWidth ) );
833 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "height", OUString::valueOf( nDocHeight ) );
834 0 : SvXMLElementExport aRectElem( *mpSVGExport, XML_NAMESPACE_NONE, "rect", sal_True, sal_True );
835 0 : }
836 0 : }
837 : }
838 :
839 0 : if( implLookForFirstVisiblePage() ) // OK! We found at least one visible page.
840 : {
841 0 : if( !mbSinglePage )
842 : {
843 0 : implGenerateMetaData();
844 0 : if( bExperimentalMode )
845 0 : implExportAnimations();
846 : }
847 : else
848 : {
849 0 : implGetPagePropSet( mSelectedPages[0] );
850 : }
851 :
852 : // Create the (Shape, GDIMetaFile) map
853 0 : if( implCreateObjects() )
854 : {
855 0 : ObjectMap::const_iterator aIter( mpObjects->begin() );
856 0 : ::std::vector< ObjectRepresentation > aObjects( mpObjects->size() );
857 0 : sal_uInt32 nPos = 0;
858 :
859 0 : while( aIter != mpObjects->end() )
860 : {
861 0 : aObjects[ nPos++ ] = (*aIter).second;
862 0 : ++aIter;
863 : }
864 :
865 0 : mpSVGFontExport = new SVGFontExport( *mpSVGExport, aObjects );
866 0 : mpSVGWriter = new SVGActionWriter( *mpSVGExport, *mpSVGFontExport );
867 :
868 0 : if( mpSVGExport->IsEmbedFonts() )
869 : {
870 0 : mpSVGFontExport->EmbedFonts();
871 : }
872 0 : if( !mpSVGExport->IsUsePositionedCharacters() )
873 : {
874 0 : implExportTextShapeIndex();
875 0 : implEmbedBulletGlyphs();
876 0 : implExportTextEmbeddedBitmaps();
877 : }
878 0 : implExportMasterPages( mMasterPageTargets, 0, mMasterPageTargets.getLength() - 1 );
879 0 : implExportDrawPages( mSelectedPages, 0, nLastPage );
880 :
881 0 : if( !mbSinglePage )
882 : {
883 0 : implGenerateScript();
884 : }
885 :
886 0 : delete mpSVGDoc, mpSVGDoc = NULL;
887 0 : bRet = sal_True;
888 : }
889 : }
890 :
891 0 : return bRet;
892 : }
893 :
894 :
895 : //------------------------------------------------------------------------------
896 : // Append aField to aFieldSet if it is not already present in the set
897 : // and create the field id sFieldId
898 : //
899 :
900 : template< typename TextFieldType >
901 0 : OUString implGenerateFieldId( std::vector< TextField* > & aFieldSet,
902 : const TextFieldType & aField,
903 : const OUString & sOOOElemField,
904 : Reference< XDrawPage > xMasterPage )
905 : {
906 0 : sal_Bool bFound = sal_False;
907 : sal_Int32 i;
908 0 : sal_Int32 nSize = aFieldSet.size();
909 0 : for( i = 0; i < nSize; ++i )
910 : {
911 0 : if( *(aFieldSet[i]) == aField )
912 : {
913 0 : bFound = sal_True;
914 0 : break;
915 : }
916 : }
917 0 : OUString sFieldId( sOOOElemField );
918 0 : sFieldId += OUString::valueOf( sal_Unicode('_') );
919 0 : if( !bFound )
920 : {
921 0 : aFieldSet.push_back( new TextFieldType( aField ) );
922 : }
923 0 : aFieldSet[i]->insertMasterPage( xMasterPage );
924 0 : sFieldId += OUString::valueOf( i );
925 0 : return sFieldId;
926 : }
927 :
928 : //------------------------------------------------------------------------------
929 :
930 0 : sal_Bool SVGFilter::implGenerateMetaData()
931 : {
932 0 : sal_Bool bRet = sal_False;
933 0 : sal_Int32 nCount = mSelectedPages.getLength();
934 0 : if( nCount != 0 )
935 : {
936 : // we wrap all meta presentation info into a svg:defs element
937 0 : SvXMLElementExport aDefsElem( *mpSVGExport, XML_NAMESPACE_NONE, "defs", sal_True, sal_True );
938 :
939 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "id", B2UCONST( aOOOElemMetaSlides ) );
940 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, aOOOAttrNumberOfSlides, OUString::valueOf( nCount ) );
941 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, aOOOAttrStartSlideNumber, OUString::valueOf( mnVisiblePage ) );
942 :
943 : /*
944 : * Add a (global) Page Numbering Type attribute for the document
945 : */
946 : // NOTE:
947 : // at present pSdrModel->GetPageNumType() returns always SVX_ARABIC
948 : // so the following code fragment is pretty unuseful
949 0 : sal_Int32 nPageNumberingType = SVX_ARABIC;
950 0 : SvxDrawPage* pSvxDrawPage = SvxDrawPage::getImplementation( mSelectedPages[0] );
951 0 : if( pSvxDrawPage )
952 : {
953 0 : SdrPage* pSdrPage = pSvxDrawPage->GetSdrPage();
954 0 : SdrModel* pSdrModel = pSdrPage->GetModel();
955 0 : nPageNumberingType = pSdrModel->GetPageNumType();
956 :
957 : // That is used by CalcFieldHdl method.
958 0 : mVisiblePagePropSet.nPageNumberingType = nPageNumberingType;
959 : }
960 0 : if( nPageNumberingType != SVX_NUMBER_NONE )
961 : {
962 0 : OUString sNumberingType;
963 0 : switch( nPageNumberingType )
964 : {
965 : case SVX_CHARS_UPPER_LETTER:
966 0 : sNumberingType = B2UCONST( "alpha-upper" );
967 0 : break;
968 : case SVX_CHARS_LOWER_LETTER:
969 0 : sNumberingType = B2UCONST( "alpha-lower" );
970 0 : break;
971 : case SVX_ROMAN_UPPER:
972 0 : sNumberingType = B2UCONST( "roman-upper" );
973 0 : break;
974 : case SVX_ROMAN_LOWER:
975 0 : sNumberingType = B2UCONST( "roman-lower" );
976 0 : break;
977 : // arabic numbering type is the default, so we do not append any attribute for it
978 : case SVX_ARABIC: ;
979 : // in case the numbering type is not handled we fall back on arabic numbering
980 : default: ;
981 0 : break;
982 : }
983 0 : if( !sNumberingType.isEmpty() )
984 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, aOOOAttrNumberingType, sNumberingType );
985 : }
986 :
987 :
988 : {
989 0 : SvXMLElementExport aExp( *mpSVGExport, XML_NAMESPACE_NONE, "g", sal_True, sal_True );
990 0 : const OUString aId( B2UCONST( aOOOElemMetaSlide ) );
991 0 : const OUString aElemTextFieldId( B2UCONST( aOOOElemTextField ) );
992 0 : std::vector< TextField* > aFieldSet;
993 :
994 0 : for( sal_Int32 i = 0; i < nCount; ++i )
995 : {
996 0 : const Reference< XDrawPage > & xDrawPage = mSelectedPages[i];
997 0 : Reference< XMasterPageTarget > xMasterPageTarget( xDrawPage, UNO_QUERY );
998 0 : Reference< XDrawPage > xMasterPage( xMasterPageTarget->getMasterPage(), UNO_QUERY );
999 0 : OUString aSlideId( aId );
1000 0 : aSlideId += OUString::valueOf( sal_Unicode('_') );
1001 0 : aSlideId += OUString::valueOf( i );
1002 :
1003 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "id", aSlideId );
1004 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, aOOOAttrSlide, implGetValidIDFromInterface( xDrawPage ) );
1005 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, aOOOAttrMaster, implGetValidIDFromInterface( xMasterPage ) );
1006 :
1007 :
1008 0 : if( mbPresentation )
1009 : {
1010 0 : Reference< XPropertySet > xPropSet( xDrawPage, UNO_QUERY );
1011 :
1012 0 : if( xPropSet.is() )
1013 : {
1014 0 : sal_Bool bBackgroundVisibility = sal_True; // default: visible
1015 0 : sal_Bool bBackgroundObjectsVisibility = sal_True; // default: visible
1016 0 : sal_Bool bPageNumberVisibility = sal_False; // default: hidden
1017 0 : sal_Bool bDateTimeVisibility = sal_True; // default: visible
1018 0 : sal_Bool bFooterVisibility = sal_True; // default: visible
1019 0 : sal_Bool bDateTimeFixed = sal_True; // default: fixed
1020 :
1021 0 : FixedDateTimeField aFixedDateTimeField;
1022 0 : VariableDateTimeField aVariableDateTimeField;
1023 0 : FooterField aFooterField;
1024 :
1025 0 : xPropSet->getPropertyValue( B2UCONST( "IsBackgroundVisible" ) ) >>= bBackgroundVisibility;
1026 : // in case the attribute is set to its default value it is not appended to the meta-slide element
1027 0 : if( !bBackgroundVisibility ) // visibility default value: 'visible'
1028 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, aOOOAttrBackgroundVisibility, B2UCONST( "hidden" ) );
1029 :
1030 : // Page Number, Date/Time, Footer and Header Fields are regarded as background objects.
1031 : // So bBackgroundObjectsVisibility overrides visibility of master page text fields.
1032 0 : xPropSet->getPropertyValue( B2UCONST( "IsBackgroundObjectsVisible" ) ) >>= bBackgroundObjectsVisibility;
1033 0 : if( bBackgroundObjectsVisibility ) // visibility default value: 'visible'
1034 : {
1035 : /*
1036 : * Page Number Field
1037 : */
1038 0 : xPropSet->getPropertyValue( B2UCONST( "IsPageNumberVisible" ) ) >>= bPageNumberVisibility;
1039 0 : bPageNumberVisibility = bPageNumberVisibility && ( nPageNumberingType != SVX_NUMBER_NONE );
1040 0 : if( bPageNumberVisibility ) // visibility default value: 'hidden'
1041 : {
1042 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, aOOOAttrPageNumberVisibility, B2UCONST( "visible" ) );
1043 : }
1044 : /*
1045 : * Date/Time Field
1046 : */
1047 0 : xPropSet->getPropertyValue( B2UCONST( "IsDateTimeVisible" ) ) >>= bDateTimeVisibility;
1048 0 : if( bDateTimeVisibility ) // visibility default value: 'visible'
1049 : {
1050 0 : xPropSet->getPropertyValue( B2UCONST( "IsDateTimeFixed" ) ) >>= bDateTimeFixed;
1051 0 : if( bDateTimeFixed ) // we are interested only in the field text not in the date/time format
1052 : {
1053 0 : xPropSet->getPropertyValue( B2UCONST( "DateTimeText" ) ) >>= aFixedDateTimeField.text;
1054 0 : if( !aFixedDateTimeField.text.isEmpty() )
1055 : {
1056 0 : OUString sFieldId = implGenerateFieldId( aFieldSet, aFixedDateTimeField, aElemTextFieldId, xMasterPage );
1057 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, aOOOAttrDateTimeField, sFieldId );
1058 : }
1059 : }
1060 : else // the inverse applies: we are interested only in the date/time format not in the field text
1061 : {
1062 0 : xPropSet->getPropertyValue( B2UCONST( "DateTimeFormat" ) ) >>= aVariableDateTimeField.format;
1063 0 : OUString sFieldId = implGenerateFieldId( aFieldSet, aVariableDateTimeField, aElemTextFieldId, xMasterPage );
1064 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, aOOOAttrDateTimeField, sFieldId );
1065 : }
1066 : }
1067 : else
1068 : {
1069 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, aOOOAttrDateTimeVisibility, B2UCONST( "hidden" ) );
1070 : }
1071 : /*
1072 : * Footer Field
1073 : */
1074 0 : xPropSet->getPropertyValue( B2UCONST( "IsFooterVisible" ) ) >>= bFooterVisibility;
1075 0 : if( bFooterVisibility ) // visibility default value: 'visible'
1076 : {
1077 0 : xPropSet->getPropertyValue( B2UCONST( "FooterText" ) ) >>= aFooterField.text;
1078 0 : if( !aFooterField.text.isEmpty() )
1079 : {
1080 0 : OUString sFieldId = implGenerateFieldId( aFieldSet, aFooterField, aElemTextFieldId, xMasterPage );
1081 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, aOOOAttrFooterField, sFieldId );
1082 : }
1083 : }
1084 : else
1085 : {
1086 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, aOOOAttrFooterVisibility, B2UCONST( "hidden" ) );
1087 : }
1088 : }
1089 : else
1090 : {
1091 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, aOOOAttrMasterObjectsVisibility, B2UCONST( "hidden" ) );
1092 : }
1093 :
1094 : // We look for a slide transition.
1095 : // Transition properties are exported together with animations.
1096 0 : sal_Int16 nTransitionType(0);
1097 0 : if( xPropSet->getPropertySetInfo()->hasPropertyByName( "TransitionType" ) &&
1098 0 : (xPropSet->getPropertyValue( "TransitionType" ) >>= nTransitionType) )
1099 : {
1100 0 : sal_Int16 nTransitionSubType(0);
1101 0 : if( xPropSet->getPropertyValue( B2UCONST( "TransitionSubtype" ) ) >>= nTransitionSubType )
1102 : {
1103 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, aOOOAttrHasTransition, B2UCONST( "true" ) );
1104 : }
1105 0 : }
1106 :
1107 0 : }
1108 : }
1109 :
1110 : {
1111 0 : SvXMLElementExport aExp2( *mpSVGExport, XML_NAMESPACE_NONE, "g", sal_True, sal_True );
1112 : } // when the aExp2 destructor is called the </g> tag is appended to the output file
1113 0 : }
1114 :
1115 : // export text field elements
1116 0 : if( mbPresentation )
1117 : {
1118 0 : for( sal_Int32 i = 0, nSize = aFieldSet.size(); i < nSize; ++i )
1119 : {
1120 0 : OUString sElemId = B2UCONST( aOOOElemTextField );
1121 0 : sElemId += OUString::valueOf( sal_Unicode('_') );
1122 0 : sElemId += OUString::valueOf( i );
1123 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "id", sElemId );
1124 0 : aFieldSet[i]->elementExport( mpSVGExport );
1125 0 : }
1126 0 : if( mpSVGExport->IsEmbedFonts() && mpSVGExport->IsUsePositionedCharacters() )
1127 : {
1128 0 : for( sal_Int32 i = 0, nSize = aFieldSet.size(); i < nSize; ++i )
1129 : {
1130 0 : aFieldSet[i]->growCharSet( mTextFieldCharSets );
1131 : }
1132 : }
1133 : }
1134 : // text fields are used only for generating meta info so we don't need them anymore
1135 0 : for( sal_uInt32 i = 0; i < aFieldSet.size(); ++i )
1136 : {
1137 0 : if( aFieldSet[i] != NULL )
1138 : {
1139 0 : delete aFieldSet[i];
1140 : }
1141 0 : }
1142 : }
1143 0 : bRet = sal_True;
1144 : }
1145 :
1146 0 : return bRet;
1147 : }
1148 :
1149 : // -----------------------------------------------------------------------------
1150 :
1151 0 : sal_Bool SVGFilter::implExportAnimations()
1152 : {
1153 0 : sal_Bool bRet = sal_False;
1154 :
1155 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "id", B2UCONST( "presentation-animations" ) );
1156 0 : SvXMLElementExport aDefsContainerElem( *mpSVGExport, XML_NAMESPACE_NONE, "defs", sal_True, sal_True );
1157 :
1158 0 : for( sal_Int32 i = 0; i < mSelectedPages.getLength(); ++i )
1159 : {
1160 0 : Reference< XPropertySet > xProps( mSelectedPages[i], UNO_QUERY );
1161 :
1162 0 : if( xProps.is() && xProps->getPropertySetInfo()->hasPropertyByName( "TransitionType" ) )
1163 : {
1164 0 : sal_Int16 nTransition = 0;
1165 0 : xProps->getPropertyValue( B2UCONST( "TransitionType" ) ) >>= nTransition;
1166 : // we have a slide transition ?
1167 0 : sal_Bool bHasEffects = ( nTransition != 0 );
1168 :
1169 0 : Reference< XAnimationNodeSupplier > xAnimNodeSupplier( mSelectedPages[i], UNO_QUERY );
1170 0 : if( xAnimNodeSupplier.is() )
1171 : {
1172 0 : Reference< XAnimationNode > xRootNode = xAnimNodeSupplier->getAnimationNode();
1173 0 : if( xRootNode.is() )
1174 : {
1175 0 : if( !bHasEffects )
1176 : {
1177 : // first check if there are no animations
1178 0 : Reference< XEnumerationAccess > xEnumerationAccess( xRootNode, UNO_QUERY_THROW );
1179 0 : Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY_THROW );
1180 0 : if( xEnumeration->hasMoreElements() )
1181 : {
1182 : // first child node may be an empty main sequence, check this
1183 0 : Reference< XAnimationNode > xMainNode( xEnumeration->nextElement(), UNO_QUERY_THROW );
1184 0 : Reference< XEnumerationAccess > xMainEnumerationAccess( xMainNode, UNO_QUERY_THROW );
1185 0 : Reference< XEnumeration > xMainEnumeration( xMainEnumerationAccess->createEnumeration(), UNO_QUERY_THROW );
1186 :
1187 : // only export if the main sequence is not empty or if there are additional
1188 : // trigger sequences
1189 0 : bHasEffects = xMainEnumeration->hasMoreElements() || xEnumeration->hasMoreElements();
1190 0 : }
1191 : }
1192 0 : if( bHasEffects )
1193 : {
1194 0 : OUString sId = implGetValidIDFromInterface( mSelectedPages[i] );
1195 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, aOOOAttrSlide, sId );
1196 0 : sId += B2UCONST( "-animations" );
1197 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "id", sId );
1198 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "class", B2UCONST( "Animations" ) );
1199 0 : SvXMLElementExport aDefsElem( *mpSVGExport, XML_NAMESPACE_NONE, "defs", sal_True, sal_True );
1200 :
1201 0 : UniReference< xmloff::AnimationsExporter > xAnimationsExporter;
1202 0 : xAnimationsExporter = new xmloff::AnimationsExporter( *mpSVGExport, xProps );
1203 0 : xAnimationsExporter->prepare( xRootNode );
1204 0 : xAnimationsExporter->exportAnimations( xRootNode );
1205 : }
1206 0 : }
1207 0 : }
1208 : }
1209 0 : }
1210 :
1211 0 : bRet = sal_True;
1212 0 : return bRet;
1213 : }
1214 :
1215 : // -----------------------------------------------------------------------------
1216 :
1217 0 : void SVGFilter::implExportTextShapeIndex()
1218 : {
1219 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "class", B2UCONST( "TextShapeIndex" ) );
1220 0 : SvXMLElementExport aDefsContainerElem( *mpSVGExport, XML_NAMESPACE_NONE, "defs", sal_True, sal_True );
1221 :
1222 0 : sal_Int32 nCount = mSelectedPages.getLength();
1223 0 : for( sal_Int32 i = 0; i < nCount; ++i )
1224 : {
1225 0 : const Reference< XDrawPage > & xDrawPage = mSelectedPages[i];
1226 0 : if( mTextShapeIdListMap.find( xDrawPage ) != mTextShapeIdListMap.end() )
1227 : {
1228 0 : OUString sTextShapeIdList = mTextShapeIdListMap[xDrawPage].trim();
1229 :
1230 0 : Reference< XInterface > xRef( xDrawPage, UNO_QUERY );
1231 0 : const OUString& rPageId = implGetValidIDFromInterface( xRef );
1232 0 : if( !rPageId.isEmpty() && !sTextShapeIdList.isEmpty() )
1233 : {
1234 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, aOOOAttrSlide, rPageId );
1235 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, aOOOAttrIdList, sTextShapeIdList );
1236 0 : SvXMLElementExport aGElem( *mpSVGExport, XML_NAMESPACE_NONE, "g", sal_True, sal_True );
1237 0 : }
1238 : }
1239 0 : }
1240 0 : }
1241 :
1242 : // -----------------------------------------------------------------------------
1243 :
1244 0 : void SVGFilter::implEmbedBulletGlyphs()
1245 : {
1246 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "class", B2UCONST( "EmbeddedBulletChars" ) );
1247 0 : SvXMLElementExport aDefsContainerElem( *mpSVGExport, XML_NAMESPACE_NONE, "defs", sal_True, sal_True );
1248 :
1249 0 : OUString sPathData = B2UCONST( "M 580,1141 L 1163,571 580,0 -4,571 580,1141 Z" );
1250 0 : implEmbedBulletGlyph( 57356, sPathData );
1251 0 : sPathData = B2UCONST( "M 8,1128 L 1137,1128 1137,0 8,0 8,1128 Z" );
1252 0 : implEmbedBulletGlyph( 57354, sPathData );
1253 0 : sPathData = B2UCONST( "M 174,0 L 602,739 174,1481 1456,739 174,0 Z M 1358,739 L 309,1346 659,739 1358,739 Z" );
1254 0 : implEmbedBulletGlyph( 10146, sPathData );
1255 0 : sPathData = B2UCONST( "M 2015,739 L 1276,0 717,0 1260,543 174,543 174,936 1260,936 717,1481 1274,1481 2015,739 Z" );
1256 0 : implEmbedBulletGlyph( 10132, sPathData );
1257 0 : sPathData = B2UCONST( "M 0,-2 C -7,14 -16,27 -25,37 L 356,567 C 262,823 215,952 215,954 215,979 228,992 255,992 264,992 276,990 289,987 310,991 331,999 354,1012 L 381,999 492,748 772,1049 836,1024 860,1049 C 881,1039 901,1025 922,1006 886,937 835,863 770,784 769,783 710,716 594,584 L 774,223 C 774,196 753,168 711,139 L 727,119 C 717,90 699,76 672,76 641,76 570,178 457,381 L 164,-76 C 142,-110 111,-127 72,-127 30,-127 9,-110 8,-76 1,-67 -2,-52 -2,-32 -2,-23 -1,-13 0,-2 Z" );
1258 0 : implEmbedBulletGlyph( 10007, sPathData );
1259 0 : sPathData = B2UCONST( "M 285,-33 C 182,-33 111,30 74,156 52,228 41,333 41,471 41,549 55,616 82,672 116,743 169,778 240,778 293,778 328,747 346,684 L 369,508 C 377,444 397,411 428,410 L 1163,1116 C 1174,1127 1196,1133 1229,1133 1271,1133 1292,1118 1292,1087 L 1292,965 C 1292,929 1282,901 1262,881 L 442,47 C 390,-6 338,-33 285,-33 Z" );
1260 0 : implEmbedBulletGlyph( 10004, sPathData );
1261 0 : sPathData = B2UCONST( "M 813,0 C 632,0 489,54 383,161 276,268 223,411 223,592 223,773 276,916 383,1023 489,1130 632,1184 813,1184 992,1184 1136,1130 1245,1023 1353,916 1407,772 1407,592 1407,412 1353,268 1245,161 1136,54 992,0 813,0 Z" );
1262 0 : implEmbedBulletGlyph( 9679, sPathData );
1263 0 : sPathData = B2UCONST( "M 346,457 C 273,457 209,483 155,535 101,586 74,649 74,723 74,796 101,859 155,911 209,963 273,989 346,989 419,989 480,963 531,910 582,859 608,796 608,723 608,648 583,586 532,535 482,483 420,457 346,457 Z" );
1264 0 : implEmbedBulletGlyph( 8226, sPathData );
1265 0 : sPathData = B2UCONST( "M -4,459 L 1135,459 1135,606 -4,606 -4,459 Z" );
1266 0 : implEmbedBulletGlyph( 8211, sPathData );
1267 0 : }
1268 :
1269 : // -----------------------------------------------------------------------------
1270 :
1271 0 : void SVGFilter::implEmbedBulletGlyph( sal_Unicode cBullet, const ::rtl::OUString & sPathData )
1272 : {
1273 0 : OUString sId = B2UCONST( "bullet-char-template(" );
1274 0 : sId += OUString::valueOf( (sal_Int32)cBullet );
1275 0 : sId += B2UCONST( ")" );
1276 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "id", sId );
1277 :
1278 0 : double fFactor = 1.0 / 2048;
1279 0 : OUString sFactor = OUString::valueOf( fFactor );
1280 0 : OUString sTransform = B2UCONST( "scale(" );
1281 0 : sTransform += sFactor; sTransform += B2UCONST( ",-" ); sTransform += sFactor;
1282 0 : sTransform += B2UCONST( ")" );
1283 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "transform", sTransform );
1284 :
1285 0 : SvXMLElementExport aGElem( *mpSVGExport, XML_NAMESPACE_NONE, "g", sal_True, sal_True );
1286 :
1287 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "d", sPathData );
1288 0 : SvXMLElementExport aPathElem( *mpSVGExport, XML_NAMESPACE_NONE, "path", sal_True, sal_True );
1289 :
1290 0 : }
1291 :
1292 : // -----------------------------------------------------------------------------
1293 :
1294 : /** SVGFilter::implExportTextEmbeddedBitmaps
1295 : * We export bitmaps embedded into text shapes, such as those used by list
1296 : * items with image style, only once in a specic <defs> element.
1297 : */
1298 0 : sal_Bool SVGFilter::implExportTextEmbeddedBitmaps()
1299 : {
1300 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "class", B2UCONST( "TextEmbeddedBitmaps" ) );
1301 0 : SvXMLElementExport aDefsContainerElem( *mpSVGExport, XML_NAMESPACE_NONE, "defs", sal_True, sal_True );
1302 :
1303 0 : OUString sId;
1304 :
1305 0 : MetaBitmapActionSet::const_iterator it = mEmbeddedBitmapActionSet.begin();
1306 0 : MetaBitmapActionSet::const_iterator end = mEmbeddedBitmapActionSet.end();
1307 0 : for( ; it != end; ++it)
1308 : {
1309 0 : const GDIMetaFile& aMtf = it->GetRepresentation();
1310 :
1311 0 : if( aMtf.GetActionSize() == 1 )
1312 : {
1313 0 : MetaAction* pAction = aMtf.GetAction( 0 );
1314 0 : if( pAction )
1315 : {
1316 0 : sal_uLong nId = GetBitmapChecksum( pAction );
1317 0 : sId = B2UCONST( "bitmap(" );
1318 0 : sId += OUString::valueOf( (sal_Int64)nId );
1319 0 : sId += B2UCONST( ")" );
1320 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "id", sId );
1321 :
1322 0 : const Reference< XShape >& rxShape = (const Reference< XShape >&)( it->GetObject() );
1323 0 : Reference< XPropertySet > xShapePropSet( rxShape, UNO_QUERY );
1324 0 : ::com::sun::star::awt::Rectangle aBoundRect;
1325 0 : if( xShapePropSet.is() && ( xShapePropSet->getPropertyValue( B2UCONST( "BoundRect" ) ) >>= aBoundRect ) )
1326 : {
1327 : // Origin of the coordinate device must be (0,0).
1328 0 : const Point aTopLeft;
1329 0 : const Size aSize( aBoundRect.Width, aBoundRect.Height );
1330 :
1331 0 : Point aPt;
1332 0 : MetaBitmapActionGetPoint( pAction, aPt );
1333 : // The image must be exported with x, y attribute set to 0,
1334 : // on the contrary when referenced by a <use> element,
1335 : // specifying the wanted position, they will result
1336 : // misplaced.
1337 0 : pAction->Move( -aPt.X(), -aPt.Y() );
1338 0 : mpSVGWriter->WriteMetaFile( aTopLeft, aSize, aMtf, 0xffffffff, NULL );
1339 : // We reset to the original values so that when the <use>
1340 : // element is created the x, y attributes are correct.
1341 0 : pAction->Move( aPt.X(), aPt.Y() );
1342 : }
1343 : else
1344 : {
1345 : OSL_FAIL( "implExportTextEmbeddedBitmaps: no shape bounding box." );
1346 0 : return sal_False;
1347 0 : }
1348 : }
1349 : else
1350 : {
1351 : OSL_FAIL( "implExportTextEmbeddedBitmaps: metafile should have MetaBmpExScaleAction only." );
1352 0 : return sal_False;
1353 : }
1354 : }
1355 : else
1356 : {
1357 : OSL_FAIL( "implExportTextEmbeddedBitmaps: metafile should have a single action." );
1358 0 : return sal_False;
1359 : }
1360 :
1361 : }
1362 0 : return sal_True;
1363 : }
1364 :
1365 : // -----------------------------------------------------------------------------
1366 :
1367 : #define SVGFILTER_EXPORT_SVGSCRIPT( z, n, aFragment ) \
1368 : xExtDocHandler->unknown( OUString::createFromAscii( aFragment ## n ) );
1369 :
1370 0 : sal_Bool SVGFilter::implGenerateScript()
1371 : {
1372 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "type", B2UCONST( "text/ecmascript" ) );
1373 :
1374 : {
1375 0 : SvXMLElementExport aExp( *mpSVGExport, XML_NAMESPACE_NONE, "script", sal_True, sal_True );
1376 0 : Reference< XExtendedDocumentHandler > xExtDocHandler( mpSVGExport->GetDocHandler(), UNO_QUERY );
1377 :
1378 0 : if( xExtDocHandler.is() )
1379 : {
1380 0 : BOOST_PP_REPEAT( N_SVGSCRIPT_FRAGMENTS, SVGFILTER_EXPORT_SVGSCRIPT, aSVGScript )
1381 0 : }
1382 : }
1383 :
1384 0 : return sal_True;
1385 : }
1386 :
1387 : // -----------------------------------------------------------------------------
1388 :
1389 0 : Any SVGFilter::implSafeGetPagePropSet( const OUString & sPropertyName,
1390 : const Reference< XPropertySet > & rxPropSet,
1391 : const Reference< XPropertySetInfo > & rxPropSetInfo )
1392 : {
1393 0 : Any result;
1394 0 : if( rxPropSetInfo->hasPropertyByName( sPropertyName ) )
1395 : {
1396 0 : result = rxPropSet->getPropertyValue( sPropertyName );
1397 : }
1398 0 : return result;
1399 : }
1400 :
1401 : // -----------------------------------------------------------------------------
1402 :
1403 : /* SVGFilter::implGetPagePropSet
1404 : *
1405 : * We collect info on master page elements visibility,
1406 : * and placeholder text shape content.
1407 : * This method is used when exporting a single page
1408 : * as implGenerateMetaData is not invoked.
1409 : */
1410 0 : sal_Bool SVGFilter::implGetPagePropSet( const Reference< XDrawPage > & rxPage )
1411 : {
1412 0 : sal_Bool bRet = sal_False;
1413 :
1414 0 : mVisiblePagePropSet.bIsBackgroundVisible = true;
1415 0 : mVisiblePagePropSet.bAreBackgroundObjectsVisible = true;
1416 0 : mVisiblePagePropSet.bIsPageNumberFieldVisible = false;;
1417 0 : mVisiblePagePropSet.bIsHeaderFieldVisible = false;
1418 0 : mVisiblePagePropSet.bIsFooterFieldVisible = true;
1419 0 : mVisiblePagePropSet.bIsDateTimeFieldVisible = true;
1420 0 : mVisiblePagePropSet.bIsDateTimeFieldFixed = true;
1421 0 : mVisiblePagePropSet.nDateTimeFormat = SVXDATEFORMAT_B;
1422 0 : mVisiblePagePropSet.nPageNumberingType = SVX_ARABIC;
1423 :
1424 : /* We collect info on master page elements visibility,
1425 : * and placeholder text shape content.
1426 : */
1427 0 : Any result;
1428 0 : Reference< XPropertySet > xPropSet( rxPage, UNO_QUERY );
1429 0 : if( xPropSet.is() )
1430 : {
1431 0 : Reference< XPropertySetInfo > xPropSetInfo( xPropSet->getPropertySetInfo() );
1432 0 : if( xPropSetInfo.is() )
1433 : {
1434 0 : implSafeGetPagePropSet( B2UCONST( "IsBackgroundVisible" ), xPropSet, xPropSetInfo ) >>= mVisiblePagePropSet.bIsBackgroundVisible;
1435 0 : implSafeGetPagePropSet( B2UCONST( "IsBackgroundObjectsVisible" ), xPropSet, xPropSetInfo ) >>= mVisiblePagePropSet.bAreBackgroundObjectsVisible;
1436 0 : implSafeGetPagePropSet( B2UCONST( "IsPageNumberVisible" ), xPropSet, xPropSetInfo ) >>= mVisiblePagePropSet.bIsPageNumberFieldVisible;
1437 0 : implSafeGetPagePropSet( B2UCONST( "IsHeaderVisible" ), xPropSet, xPropSetInfo ) >>= mVisiblePagePropSet.bIsHeaderFieldVisible;
1438 0 : implSafeGetPagePropSet( B2UCONST( "IsFooterVisible" ), xPropSet, xPropSetInfo ) >>= mVisiblePagePropSet.bIsFooterFieldVisible;
1439 0 : implSafeGetPagePropSet( B2UCONST( "IsDateTimeVisible" ), xPropSet, xPropSetInfo ) >>= mVisiblePagePropSet.bIsDateTimeFieldVisible;
1440 :
1441 0 : implSafeGetPagePropSet( B2UCONST( "IsDateTimeFixed" ), xPropSet, xPropSetInfo ) >>= mVisiblePagePropSet.bIsDateTimeFieldFixed;
1442 0 : implSafeGetPagePropSet( B2UCONST( "DateTimeFormat" ), xPropSet, xPropSetInfo ) >>= mVisiblePagePropSet.nDateTimeFormat;
1443 0 : implSafeGetPagePropSet( B2UCONST( "Number" ), xPropSet, xPropSetInfo ) >>= mVisiblePagePropSet.nPageNumber;
1444 0 : implSafeGetPagePropSet( B2UCONST( "DateTimeText" ), xPropSet, xPropSetInfo ) >>= mVisiblePagePropSet.sDateTimeText;
1445 0 : implSafeGetPagePropSet( B2UCONST( "FooterText" ), xPropSet, xPropSetInfo ) >>= mVisiblePagePropSet.sFooterText;
1446 0 : implSafeGetPagePropSet( B2UCONST( "HeaderText" ), xPropSet, xPropSetInfo ) >>= mVisiblePagePropSet.sHeaderText;
1447 :
1448 0 : if( mVisiblePagePropSet.bIsPageNumberFieldVisible )
1449 : {
1450 0 : SvxDrawPage* pSvxDrawPage = SvxDrawPage::getImplementation( rxPage );
1451 0 : if( pSvxDrawPage )
1452 : {
1453 0 : SdrPage* pSdrPage = pSvxDrawPage->GetSdrPage();
1454 0 : SdrModel* pSdrModel = pSdrPage->GetModel();
1455 0 : mVisiblePagePropSet.nPageNumberingType = pSdrModel->GetPageNumType();
1456 : }
1457 : }
1458 :
1459 0 : bRet = sal_True;
1460 0 : }
1461 : }
1462 :
1463 0 : return bRet;
1464 : }
1465 :
1466 :
1467 : // -----------------------------------------------------------------------------
1468 :
1469 0 : sal_Bool SVGFilter::implExportMasterPages( const SVGFilter::XDrawPageSequence & rxPages,
1470 : sal_Int32 nFirstPage, sal_Int32 nLastPage )
1471 : {
1472 : DBG_ASSERT( nFirstPage <= nLastPage,
1473 : "SVGFilter::implExportPages: nFirstPage > nLastPage" );
1474 :
1475 : // When the exported slides are more than one we wrap master page elements
1476 : // with a svg <defs> element.
1477 0 : OUString aContainerTag = (mbSinglePage) ? B2UCONST( "g" ) : B2UCONST( "defs" );
1478 0 : SvXMLElementExport aContainerElement( *mpSVGExport, XML_NAMESPACE_NONE, aContainerTag, sal_True, sal_True );
1479 :
1480 0 : sal_Bool bRet = sal_False;
1481 0 : for( sal_Int32 i = nFirstPage; i <= nLastPage; ++i )
1482 : {
1483 0 : if( rxPages[i].is() )
1484 : {
1485 0 : Reference< XShapes > xShapes( rxPages[i], UNO_QUERY );
1486 :
1487 0 : if( xShapes.is() )
1488 : {
1489 : // add id attribute
1490 0 : const OUString & sPageId = implGetValidIDFromInterface( rxPages[i] );
1491 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "id", sPageId );
1492 :
1493 0 : bRet = implExportPage( sPageId, rxPages[i], xShapes, sal_True /* is a master page */ ) || bRet;
1494 0 : }
1495 : }
1496 : }
1497 0 : return bRet;
1498 : }
1499 :
1500 : // -----------------------------------------------------------------------------
1501 :
1502 0 : sal_Bool SVGFilter::implExportDrawPages( const SVGFilter::XDrawPageSequence & rxPages,
1503 : sal_Int32 nFirstPage, sal_Int32 nLastPage )
1504 : {
1505 : DBG_ASSERT( nFirstPage <= nLastPage,
1506 : "SVGFilter::implExportPages: nFirstPage > nLastPage" );
1507 :
1508 : // We wrap all slide in a group element with class name "SlideGroup".
1509 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "class", B2UCONST( "SlideGroup" ) );
1510 0 : SvXMLElementExport aExp( *mpSVGExport, XML_NAMESPACE_NONE, "g", sal_True, sal_True );
1511 :
1512 0 : sal_Bool bRet = sal_False;
1513 0 : for( sal_Int32 i = nFirstPage; i <= nLastPage; ++i )
1514 : {
1515 0 : Reference< XShapes > xShapes( rxPages[i], UNO_QUERY );
1516 :
1517 0 : if( xShapes.is() )
1518 : {
1519 : // Insert the <g> open tag related to the svg element for
1520 : // handling a slide visibility.
1521 : // In case the exported slides are more than one the initial
1522 : // visibility of each slide is set to 'hidden'.
1523 0 : if( !mbSinglePage )
1524 : {
1525 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "visibility", B2UCONST( "hidden" ) );
1526 : }
1527 0 : SvXMLElementExport aGElement( *mpSVGExport, XML_NAMESPACE_NONE, "g", sal_True, sal_True );
1528 :
1529 : {
1530 : // add id attribute
1531 0 : const OUString & sPageId = implGetValidIDFromInterface( rxPages[i] );
1532 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "id", sPageId );
1533 :
1534 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "class", B2UCONST( "Slide" ) );
1535 :
1536 : // Adding a clip path to each exported slide , so in case
1537 : // bitmaps or other elements exceed the slide margins, they are
1538 : // trimmed, even when they are shown inside a thumbnail view.
1539 0 : OUString sClipPathAttrValue = B2UCONST( "url(#" ) + msClipPathId + B2UCONST( ")" );
1540 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "clip-path", sClipPathAttrValue );
1541 :
1542 0 : SvXMLElementExport aSlideElement( *mpSVGExport, XML_NAMESPACE_NONE, "g", sal_True, sal_True );
1543 :
1544 0 : bRet = implExportPage( sPageId, rxPages[i], xShapes, sal_False /* is not a master page */ ) || bRet;
1545 0 : }
1546 : } // append the </g> closing tag related to the svg element handling the slide visibility
1547 0 : }
1548 :
1549 0 : return bRet;
1550 : }
1551 :
1552 : // -----------------------------------------------------------------------------
1553 0 : sal_Bool SVGFilter::implExportPage( const ::rtl::OUString & sPageId,
1554 : const Reference< XDrawPage > & rxPage,
1555 : const Reference< XShapes > & xShapes,
1556 : sal_Bool bMaster )
1557 : {
1558 0 : sal_Bool bRet = sal_False;
1559 :
1560 : {
1561 0 : OUString sPageName = implGetInterfaceName( rxPage );
1562 0 : if( !(sPageName.isEmpty() || mbSinglePage ))
1563 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, aOOOAttrName, sPageName );
1564 :
1565 : {
1566 0 : Reference< XExtendedDocumentHandler > xExtDocHandler( mpSVGExport->GetDocHandler(), UNO_QUERY );
1567 :
1568 0 : if( xExtDocHandler.is() )
1569 : {
1570 0 : OUString aDesc;
1571 :
1572 0 : if( bMaster )
1573 0 : aDesc = B2UCONST( "Master_Slide" );
1574 : else
1575 0 : aDesc = B2UCONST( "Page" );
1576 :
1577 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "class", aDesc );
1578 0 : }
1579 : }
1580 :
1581 : // insert the <g> open tag related to the DrawPage/MasterPage
1582 0 : SvXMLElementExport aExp( *mpSVGExport, XML_NAMESPACE_NONE, "g", sal_True, sal_True );
1583 :
1584 : // In case the page has a background object we append it .
1585 0 : if( (mpObjects->find( rxPage ) != mpObjects->end()) )
1586 : {
1587 0 : const GDIMetaFile& rMtf = (*mpObjects)[ rxPage ].GetRepresentation();
1588 0 : if( rMtf.GetActionSize() )
1589 : {
1590 : // background id = "bg-" + page id
1591 0 : OUString sBackgroundId = B2UCONST( "bg-" );
1592 0 : sBackgroundId += sPageId;
1593 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "id", sBackgroundId );
1594 :
1595 : // At present (LibreOffice 3.4.0) the 'IsBackgroundVisible' property is not handled
1596 : // by Impress; anyway we handle this property as referring only to the visibility
1597 : // of the master page background. So if a slide has its own background object,
1598 : // the visibility of such a background object is always inherited from the visibility
1599 : // of the parent slide regardless of the value of the 'IsBackgroundVisible' property.
1600 : // This means that we need to set up the visibility attribute only for the background
1601 : // element of a master page.
1602 0 : if( mbSinglePage && bMaster )
1603 : {
1604 0 : if( !mVisiblePagePropSet.bIsBackgroundVisible )
1605 : {
1606 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "visibility", B2UCONST( "hidden" ) );
1607 : }
1608 : }
1609 :
1610 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "class", B2UCONST( "Background" ) );
1611 :
1612 : // insert the <g> open tag related to the Background
1613 0 : SvXMLElementExport aExp2( *mpSVGExport, XML_NAMESPACE_NONE, "g", sal_True, sal_True );
1614 :
1615 : // append all elements that make up the Background
1616 0 : const Point aNullPt;
1617 0 : mpSVGWriter->WriteMetaFile( aNullPt, rMtf.GetPrefSize(), rMtf, SVGWRITER_WRITE_FILL );
1618 : } // insert the </g> closing tag related to the Background
1619 : }
1620 :
1621 : // In case we are dealing with a master page we need to to group all its shapes
1622 : // into a group element, this group will make up the so named "background objects"
1623 0 : if( bMaster )
1624 : {
1625 : // background objects id = "bo-" + page id
1626 0 : OUString sBackgroundObjectsId = B2UCONST( "bo-" );
1627 0 : sBackgroundObjectsId += sPageId;
1628 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "id", sBackgroundObjectsId );
1629 0 : if( mbSinglePage )
1630 : {
1631 0 : if( !mVisiblePagePropSet.bAreBackgroundObjectsVisible )
1632 : {
1633 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "visibility", B2UCONST( "hidden" ) );
1634 : }
1635 : }
1636 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "class", B2UCONST( "BackgroundObjects" ) );
1637 :
1638 : // insert the <g> open tag related to the Background Objects
1639 0 : SvXMLElementExport aExp2( *mpSVGExport, XML_NAMESPACE_NONE, "g", sal_True, sal_True );
1640 :
1641 : // append all shapes that make up the Master Slide
1642 0 : bRet = implExportShapes( xShapes ) || bRet;
1643 : } // append the </g> closing tag related to the Background Objects
1644 : else
1645 : {
1646 : // append all shapes that make up the Slide
1647 0 : bRet = implExportShapes( xShapes ) || bRet;
1648 0 : }
1649 : } // append the </g> closing tag related to the Slide/Master_Slide
1650 :
1651 0 : return bRet;
1652 : }
1653 :
1654 :
1655 : // -----------------------------------------------------------------------------
1656 :
1657 0 : sal_Bool SVGFilter::implExportShapes( const Reference< XShapes >& rxShapes )
1658 : {
1659 0 : Reference< XShape > xShape;
1660 0 : sal_Bool bRet = sal_False;
1661 :
1662 0 : for( sal_Int32 i = 0, nCount = rxShapes->getCount(); i < nCount; ++i )
1663 : {
1664 0 : if( ( rxShapes->getByIndex( i ) >>= xShape ) && xShape.is() )
1665 0 : bRet = implExportShape( xShape ) || bRet;
1666 :
1667 0 : xShape = NULL;
1668 : }
1669 :
1670 0 : return bRet;
1671 : }
1672 :
1673 : // -----------------------------------------------------------------------------
1674 :
1675 0 : sal_Bool SVGFilter::implExportShape( const Reference< XShape >& rxShape )
1676 : {
1677 0 : Reference< XPropertySet > xShapePropSet( rxShape, UNO_QUERY );
1678 0 : sal_Bool bRet = sal_False;
1679 :
1680 0 : if( xShapePropSet.is() )
1681 : {
1682 0 : const ::rtl::OUString aShapeType( rxShape->getShapeType() );
1683 0 : sal_Bool bHideObj = sal_False;
1684 :
1685 0 : if( mbPresentation )
1686 : {
1687 0 : xShapePropSet->getPropertyValue( B2UCONST( "IsEmptyPresentationObject" ) ) >>= bHideObj;
1688 : }
1689 :
1690 0 : if( !bHideObj )
1691 : {
1692 0 : if( aShapeType.lastIndexOf( B2UCONST( "drawing.GroupShape" ) ) != -1 )
1693 : {
1694 0 : Reference< XShapes > xShapes( rxShape, UNO_QUERY );
1695 :
1696 0 : if( xShapes.is() )
1697 : {
1698 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "class", B2UCONST( "Group" ) );
1699 0 : SvXMLElementExport aExp( *mpSVGExport, XML_NAMESPACE_NONE, "g", sal_True, sal_True );
1700 :
1701 0 : bRet = implExportShapes( xShapes );
1702 0 : }
1703 : }
1704 :
1705 0 : if( !bRet && mpObjects->find( rxShape ) != mpObjects->end() )
1706 : {
1707 0 : const ::rtl::OUString* pElementId = NULL;
1708 :
1709 0 : ::com::sun::star::awt::Rectangle aBoundRect;
1710 0 : const GDIMetaFile& rMtf = (*mpObjects)[ rxShape ].GetRepresentation();
1711 :
1712 0 : xShapePropSet->getPropertyValue( B2UCONST( "BoundRect" ) ) >>= aBoundRect;
1713 :
1714 0 : const Point aTopLeft( aBoundRect.X, aBoundRect.Y );
1715 0 : const Size aSize( aBoundRect.Width, aBoundRect.Height );
1716 :
1717 0 : if( rMtf.GetActionSize() )
1718 : { // for text field shapes we set up text-adjust attributes
1719 : // and set visibility to hidden
1720 0 : OUString aShapeClass = implGetClassFromShape( rxShape );
1721 0 : if( mbPresentation )
1722 : {
1723 0 : sal_Bool bIsPageNumber = ( aShapeClass == "Slide_Number" );
1724 0 : sal_Bool bIsFooter = ( aShapeClass == "Footer" );
1725 0 : sal_Bool bIsDateTime = ( aShapeClass == "Date/Time" );
1726 0 : if( bIsPageNumber || bIsDateTime || bIsFooter )
1727 : {
1728 0 : if( !mbSinglePage )
1729 : {
1730 : // to notify to the SVGActionWriter::ImplWriteActions method
1731 : // that we are dealing with a placeholder shape
1732 0 : pElementId = &sPlaceholderTag;
1733 :
1734 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "visibility", B2UCONST( "hidden" ) );
1735 :
1736 0 : sal_uInt16 nTextAdjust = ParagraphAdjust_LEFT;
1737 0 : OUString sTextAdjust;
1738 0 : xShapePropSet->getPropertyValue( B2UCONST( "ParaAdjust" ) ) >>= nTextAdjust;
1739 :
1740 0 : switch( nTextAdjust )
1741 : {
1742 : case ParagraphAdjust_LEFT:
1743 0 : sTextAdjust = B2UCONST( "left" );
1744 0 : break;
1745 : case ParagraphAdjust_CENTER:
1746 0 : sTextAdjust = B2UCONST( "center" );
1747 0 : break;
1748 : case ParagraphAdjust_RIGHT:
1749 0 : sTextAdjust = B2UCONST( "right" );
1750 0 : break;
1751 : default:
1752 0 : break;
1753 : }
1754 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, aOOOAttrTextAdjust, sTextAdjust );
1755 : }
1756 : else // single page case
1757 : {
1758 0 : if( !mVisiblePagePropSet.bAreBackgroundObjectsVisible || (
1759 0 : ( bIsPageNumber && !mVisiblePagePropSet.bIsPageNumberFieldVisible ) ||
1760 0 : ( bIsDateTime && !mVisiblePagePropSet.bIsDateTimeFieldVisible ) ||
1761 0 : ( bIsFooter && !mVisiblePagePropSet.bIsFooterFieldVisible ) ) )
1762 : {
1763 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "visibility", B2UCONST( "hidden" ) );
1764 : }
1765 : }
1766 : }
1767 : }
1768 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "class", aShapeClass );
1769 0 : SvXMLElementExport aExp( *mpSVGExport, XML_NAMESPACE_NONE, "g", sal_True, sal_True );
1770 :
1771 0 : Reference< XExtendedDocumentHandler > xExtDocHandler( mpSVGExport->GetDocHandler(), UNO_QUERY );
1772 :
1773 0 : OUString aTitle;
1774 0 : xShapePropSet->getPropertyValue( B2UCONST( "Title" ) ) >>= aTitle;
1775 0 : if( !aTitle.isEmpty() )
1776 : {
1777 0 : SvXMLElementExport aExp2( *mpSVGExport, XML_NAMESPACE_NONE, "title", sal_True, sal_True );
1778 0 : xExtDocHandler->characters( aTitle );
1779 : }
1780 :
1781 0 : OUString aDescription;
1782 0 : xShapePropSet->getPropertyValue( B2UCONST( "Description" ) ) >>= aDescription;
1783 0 : if( !aDescription.isEmpty() )
1784 : {
1785 0 : SvXMLElementExport aExp2( *mpSVGExport, XML_NAMESPACE_NONE, "desc", sal_True, sal_True );
1786 0 : xExtDocHandler->characters( aDescription );
1787 : }
1788 :
1789 :
1790 0 : Reference< XInterface > xRef( rxShape, UNO_QUERY );
1791 0 : const OUString& rShapeId = implGetValidIDFromInterface( xRef );
1792 0 : if( !rShapeId.isEmpty() )
1793 : {
1794 0 : mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "id", rShapeId );
1795 : }
1796 :
1797 0 : const GDIMetaFile* pEmbeddedBitmapsMtf = NULL;
1798 0 : if( mEmbeddedBitmapActionMap.find( rxShape ) != mEmbeddedBitmapActionMap.end() )
1799 : {
1800 0 : pEmbeddedBitmapsMtf = &( mEmbeddedBitmapActionMap[ rxShape ].GetRepresentation() );
1801 : }
1802 :
1803 : {
1804 0 : SvXMLElementExport aExp2( *mpSVGExport, XML_NAMESPACE_NONE, "g", sal_True, sal_True );
1805 : mpSVGWriter->WriteMetaFile( aTopLeft, aSize, rMtf,
1806 : 0xffffffff,
1807 : pElementId,
1808 : &rxShape,
1809 0 : pEmbeddedBitmapsMtf );
1810 0 : }
1811 : }
1812 :
1813 0 : bRet = sal_True;
1814 : }
1815 0 : }
1816 : }
1817 :
1818 0 : return bRet;
1819 : }
1820 :
1821 : // -----------------------------------------------------------------------------
1822 :
1823 0 : sal_Bool SVGFilter::implCreateObjects()
1824 : {
1825 : sal_Int32 i, nCount;
1826 :
1827 0 : for( i = 0, nCount = mMasterPageTargets.getLength(); i < nCount; ++i )
1828 : {
1829 0 : const Reference< XDrawPage > & xMasterPage = mMasterPageTargets[i];
1830 :
1831 0 : if( xMasterPage.is() )
1832 : {
1833 0 : mCreateOjectsCurrentMasterPage = xMasterPage;
1834 0 : implCreateObjectsFromBackground( xMasterPage );
1835 :
1836 0 : Reference< XShapes > xShapes( xMasterPage, UNO_QUERY );
1837 :
1838 0 : if( xShapes.is() )
1839 0 : implCreateObjectsFromShapes( xMasterPage, xShapes );
1840 : }
1841 : }
1842 :
1843 0 : for( i = 0, nCount = mSelectedPages.getLength(); i < nCount; ++i )
1844 : {
1845 0 : const Reference< XDrawPage > & xDrawPage = mSelectedPages[i];
1846 :
1847 0 : if( xDrawPage.is() )
1848 : {
1849 : #if ENABLE_EXPORT_CUSTOM_SLIDE_BACKGROUND
1850 : // TODO complete the implementation for exporting custom background for each slide
1851 : // implementation status:
1852 : // - hatch stroke color is set to 'none' so the hatch is not visible, why ?
1853 : // - gradient look is not really awesome, too few colors are used;
1854 : // - stretched bitmap, gradient and hatch are not exported only once
1855 : // and then referenced in case more than one slide uses them.
1856 : // - tiled bitmap: an image element is exported for each tile,
1857 : // this is really too expensive!
1858 : Reference< XPropertySet > xPropSet( xDrawPage, UNO_QUERY );
1859 : Reference< XPropertySet > xBackground;
1860 : xPropSet->getPropertyValue( B2UCONST( "Background" ) ) >>= xBackground;
1861 : if( xBackground.is() )
1862 : {
1863 : drawing::FillStyle aFillStyle;
1864 : sal_Bool assigned = ( xBackground->getPropertyValue( B2UCONST( "FillStyle" ) ) >>= aFillStyle );
1865 : if( assigned && aFillStyle != drawing::FillStyle_NONE )
1866 : {
1867 : implCreateObjectsFromBackground( xDrawPage );
1868 : }
1869 : }
1870 : #endif
1871 0 : Reference< XShapes > xShapes( xDrawPage, UNO_QUERY );
1872 :
1873 0 : if( xShapes.is() )
1874 0 : implCreateObjectsFromShapes( xDrawPage, xShapes );
1875 : }
1876 : }
1877 0 : return sal_True;
1878 : }
1879 :
1880 : // -----------------------------------------------------------------------------
1881 :
1882 0 : sal_Bool SVGFilter::implCreateObjectsFromShapes( const Reference< XDrawPage > & rxPage, const Reference< XShapes >& rxShapes )
1883 : {
1884 0 : Reference< XShape > xShape;
1885 0 : sal_Bool bRet = sal_False;
1886 :
1887 0 : for( sal_Int32 i = 0, nCount = rxShapes->getCount(); i < nCount; ++i )
1888 : {
1889 0 : if( ( rxShapes->getByIndex( i ) >>= xShape ) && xShape.is() )
1890 0 : bRet = implCreateObjectsFromShape( rxPage, xShape ) || bRet;
1891 :
1892 0 : xShape = NULL;
1893 : }
1894 :
1895 0 : return bRet;
1896 : }
1897 :
1898 : // -----------------------------------------------------------------------------
1899 :
1900 0 : sal_Bool SVGFilter::implCreateObjectsFromShape( const Reference< XDrawPage > & rxPage, const Reference< XShape >& rxShape )
1901 : {
1902 0 : sal_Bool bRet = sal_False;
1903 0 : if( rxShape->getShapeType().lastIndexOf( B2UCONST( "drawing.GroupShape" ) ) != -1 )
1904 : {
1905 0 : Reference< XShapes > xShapes( rxShape, UNO_QUERY );
1906 :
1907 0 : if( xShapes.is() )
1908 0 : bRet = implCreateObjectsFromShapes( rxPage, xShapes );
1909 : }
1910 : else
1911 : {
1912 0 : SdrObject* pObj = GetSdrObjectFromXShape( rxShape );
1913 :
1914 0 : if( pObj )
1915 : {
1916 0 : Graphic aGraphic( SdrExchangeView::GetObjGraphic( pObj->GetModel(), pObj ) );
1917 :
1918 0 : if( aGraphic.GetType() != GRAPHIC_NONE )
1919 : {
1920 0 : if( aGraphic.GetType() == GRAPHIC_BITMAP )
1921 : {
1922 0 : GDIMetaFile aMtf;
1923 0 : const Point aNullPt;
1924 0 : const Size aSize( pObj->GetCurrentBoundRect().GetSize() );
1925 :
1926 0 : aMtf.AddAction( new MetaBmpExScaleAction( aNullPt, aSize, aGraphic.GetBitmapEx() ) );
1927 0 : aMtf.SetPrefSize( aSize );
1928 0 : aMtf.SetPrefMapMode( MAP_100TH_MM );
1929 :
1930 0 : (*mpObjects)[ rxShape ] = ObjectRepresentation( rxShape, aMtf );
1931 : }
1932 : else
1933 : {
1934 0 : if( aGraphic.GetGDIMetaFile().GetActionSize() )
1935 : {
1936 0 : Reference< XText > xText( rxShape, UNO_QUERY );
1937 0 : sal_Bool bIsTextShape = xText.is();
1938 :
1939 0 : if( !mpSVGExport->IsUsePositionedCharacters() && bIsTextShape )
1940 : {
1941 0 : Reference< XPropertySet > xShapePropSet( rxShape, UNO_QUERY );
1942 :
1943 0 : if( xShapePropSet.is() )
1944 : {
1945 0 : sal_Bool bHideObj = sal_False;
1946 :
1947 0 : if( mbPresentation )
1948 : {
1949 0 : xShapePropSet->getPropertyValue( B2UCONST( "IsEmptyPresentationObject" ) ) >>= bHideObj;
1950 : }
1951 :
1952 0 : if( !bHideObj )
1953 : {
1954 : // We create a map of text shape ids.
1955 0 : implRegisterInterface( rxShape );
1956 0 : Reference< XInterface > xRef( rxShape, UNO_QUERY );
1957 0 : const OUString& rShapeId = implGetValidIDFromInterface( xRef );
1958 0 : if( !rShapeId.isEmpty() )
1959 : {
1960 0 : mTextShapeIdListMap[rxPage] += rShapeId;
1961 0 : mTextShapeIdListMap[rxPage] += B2UCONST( " " );
1962 : }
1963 :
1964 : // We create a set of bitmaps embedded into text shape.
1965 0 : GDIMetaFile aMtf;
1966 0 : const Size aSize( pObj->GetCurrentBoundRect().GetSize() );
1967 : MetaAction* pAction;
1968 0 : sal_Bool bIsTextShapeStarted = sal_False;
1969 0 : const GDIMetaFile& rMtf = aGraphic.GetGDIMetaFile();
1970 0 : sal_uLong nCount = rMtf.GetActionSize();
1971 0 : for( sal_uLong nCurAction = 0; nCurAction < nCount; ++nCurAction )
1972 : {
1973 0 : pAction = rMtf.GetAction( nCurAction );
1974 0 : const sal_uInt16 nType = pAction->GetType();
1975 :
1976 0 : if( nType == META_COMMENT_ACTION )
1977 : {
1978 0 : const MetaCommentAction* pA = (const MetaCommentAction*) pAction;
1979 0 : if( ( pA->GetComment().equalsIgnoreAsciiCaseL(RTL_CONSTASCII_STRINGPARAM("XTEXT_PAINTSHAPE_BEGIN")) ) )
1980 : {
1981 0 : bIsTextShapeStarted = sal_True;
1982 : }
1983 0 : else if( ( pA->GetComment().equalsIgnoreAsciiCaseL( RTL_CONSTASCII_STRINGPARAM( "XTEXT_PAINTSHAPE_END" ) ) ) )
1984 : {
1985 0 : bIsTextShapeStarted = sal_False;
1986 : }
1987 : }
1988 0 : if( bIsTextShapeStarted && ( nType == META_BMPSCALE_ACTION || nType == META_BMPEXSCALE_ACTION ) )
1989 : {
1990 0 : GDIMetaFile aEmbeddedBitmapMtf;
1991 0 : pAction->Duplicate();
1992 0 : aEmbeddedBitmapMtf.AddAction( pAction );
1993 0 : aEmbeddedBitmapMtf.SetPrefSize( aSize );
1994 0 : aEmbeddedBitmapMtf.SetPrefMapMode( MAP_100TH_MM );
1995 0 : mEmbeddedBitmapActionSet.insert( ObjectRepresentation( rxShape, aEmbeddedBitmapMtf ) );
1996 0 : pAction->Duplicate();
1997 0 : aMtf.AddAction( pAction );
1998 : }
1999 : }
2000 0 : aMtf.SetPrefSize( aSize );
2001 0 : aMtf.SetPrefMapMode( MAP_100TH_MM );
2002 0 : mEmbeddedBitmapActionMap[ rxShape ] = ObjectRepresentation( rxShape, aMtf );
2003 : }
2004 0 : }
2005 0 : }
2006 : }
2007 0 : (*mpObjects)[ rxShape ] = ObjectRepresentation( rxShape, aGraphic.GetGDIMetaFile() );
2008 : }
2009 0 : bRet = sal_True;
2010 0 : }
2011 : }
2012 : }
2013 :
2014 0 : return bRet;
2015 : }
2016 :
2017 : // -----------------------------------------------------------------------------
2018 :
2019 0 : sal_Bool SVGFilter::implCreateObjectsFromBackground( const Reference< XDrawPage >& rxDrawPage )
2020 : {
2021 0 : Reference< XExporter > xExporter( mxContext->getServiceManager()->createInstanceWithContext( B2UCONST( "com.sun.star.drawing.GraphicExportFilter" ), mxContext ), UNO_QUERY );
2022 0 : sal_Bool bRet = sal_False;
2023 :
2024 0 : if( xExporter.is() )
2025 : {
2026 0 : GDIMetaFile aMtf;
2027 0 : Reference< XFilter > xFilter( xExporter, UNO_QUERY );
2028 :
2029 0 : utl::TempFile aFile;
2030 0 : aFile.EnableKillingFile();
2031 :
2032 0 : Sequence< PropertyValue > aDescriptor( 3 );
2033 0 : aDescriptor[0].Name = B2UCONST( "FilterName" );
2034 0 : aDescriptor[0].Value <<= B2UCONST( "SVM" );
2035 0 : aDescriptor[1].Name = B2UCONST( "URL" );
2036 0 : aDescriptor[1].Value <<= OUString( aFile.GetURL() );
2037 0 : aDescriptor[2].Name = B2UCONST( "ExportOnlyBackground" );
2038 0 : aDescriptor[2].Value <<= (sal_Bool) sal_True;
2039 :
2040 0 : xExporter->setSourceDocument( Reference< XComponent >( rxDrawPage, UNO_QUERY ) );
2041 0 : xFilter->filter( aDescriptor );
2042 0 : aMtf.Read( *aFile.GetStream( STREAM_READ ) );
2043 :
2044 0 : (*mpObjects)[ rxDrawPage ] = ObjectRepresentation( rxDrawPage, aMtf );
2045 :
2046 0 : bRet = sal_True;
2047 : }
2048 :
2049 0 : return bRet;
2050 : }
2051 :
2052 : // -----------------------------------------------------------------------------
2053 :
2054 0 : OUString SVGFilter::implGetClassFromShape( const Reference< XShape >& rxShape )
2055 : {
2056 0 : OUString aRet;
2057 0 : const OUString aShapeType( rxShape->getShapeType() );
2058 :
2059 0 : if( aShapeType.lastIndexOf( B2UCONST( "drawing.GroupShape" ) ) != -1 )
2060 0 : aRet = B2UCONST( "Group" );
2061 0 : else if( aShapeType.lastIndexOf( B2UCONST( "drawing.GraphicObjectShape" ) ) != -1 )
2062 0 : aRet = B2UCONST( "Graphic" );
2063 0 : else if( aShapeType.lastIndexOf( B2UCONST( "drawing.OLE2Shape" ) ) != -1 )
2064 0 : aRet = B2UCONST( "OLE2" );
2065 0 : else if( aShapeType.lastIndexOf( B2UCONST( "presentation.HeaderShape" ) ) != -1 )
2066 0 : aRet = B2UCONST( "Header" );
2067 0 : else if( aShapeType.lastIndexOf( B2UCONST( "presentation.FooterShape" ) ) != -1 )
2068 0 : aRet = B2UCONST( "Footer" );
2069 0 : else if( aShapeType.lastIndexOf( B2UCONST( "presentation.DateTimeShape" ) ) != -1 )
2070 0 : aRet = B2UCONST( "Date/Time" );
2071 0 : else if( aShapeType.lastIndexOf( B2UCONST( "presentation.SlideNumberShape" ) ) != -1 )
2072 0 : aRet = B2UCONST( "Slide_Number" );
2073 : else
2074 0 : aRet = aShapeType;
2075 : //aRet = B2UCONST( "Drawing" );
2076 :
2077 0 : return aRet;
2078 : }
2079 :
2080 : // -----------------------------------------------------------------------------
2081 :
2082 0 : void SVGFilter::implRegisterInterface( const Reference< XInterface >& rxIf )
2083 : {
2084 0 : if( rxIf.is() )
2085 0 : (mpSVGExport->getInterfaceToIdentifierMapper()).registerReference( rxIf );
2086 0 : }
2087 :
2088 : // -----------------------------------------------------------------------------
2089 :
2090 0 : const ::rtl::OUString & SVGFilter::implGetValidIDFromInterface( const Reference< XInterface >& rxIf )
2091 : {
2092 0 : return (mpSVGExport->getInterfaceToIdentifierMapper()).getIdentifier( rxIf );
2093 : }
2094 :
2095 : // -----------------------------------------------------------------------------
2096 :
2097 0 : OUString SVGFilter::implGetInterfaceName( const Reference< XInterface >& rxIf )
2098 : {
2099 0 : Reference< XNamed > xNamed( rxIf, UNO_QUERY );
2100 0 : OUString aRet;
2101 0 : if( xNamed.is() )
2102 : {
2103 0 : aRet = xNamed->getName().replace( ' ', '_' );
2104 : }
2105 0 : return aRet;
2106 : }
2107 :
2108 : // -----------------------------------------------------------------------------
2109 :
2110 0 : IMPL_LINK( SVGFilter, CalcFieldHdl, EditFieldInfo*, pInfo )
2111 : {
2112 0 : sal_Bool bFieldProcessed = sal_False;
2113 0 : if( pInfo && mbPresentation )
2114 : {
2115 0 : bFieldProcessed = true;
2116 0 : OUString aRepresentation = B2UCONST("");
2117 0 : if( !mbSinglePage )
2118 : {
2119 0 : if( mpSVGExport->IsEmbedFonts() && mpSVGExport->IsUsePositionedCharacters() )
2120 : {
2121 : // to notify to the SVGActionWriter::ImplWriteText method
2122 : // that we are dealing with a placeholder shape
2123 0 : aRepresentation = sPlaceholderTag;
2124 :
2125 0 : if( !mCreateOjectsCurrentMasterPage.is() )
2126 : {
2127 : OSL_FAIL( "error: !mCreateOjectsCurrentMasterPage.is()" );
2128 0 : return 0;
2129 : }
2130 0 : sal_Bool bHasCharSetMap = !( mTextFieldCharSets.find( mCreateOjectsCurrentMasterPage ) == mTextFieldCharSets.end() );
2131 :
2132 0 : static const ::rtl::OUString aHeaderId( B2UCONST( aOOOAttrHeaderField ) );
2133 0 : static const ::rtl::OUString aFooterId( B2UCONST( aOOOAttrFooterField ) );
2134 0 : static const ::rtl::OUString aDateTimeId( B2UCONST( aOOOAttrDateTimeField ) );
2135 0 : static const ::rtl::OUString aVariableDateTimeId( B2UCONST( aOOOAttrDateTimeField ) + B2UCONST( "-variable" ) );
2136 :
2137 0 : const UCharSet * pCharSet = NULL;
2138 0 : UCharSetMap * pCharSetMap = NULL;
2139 0 : if( bHasCharSetMap )
2140 : {
2141 0 : pCharSetMap = &( mTextFieldCharSets[ mCreateOjectsCurrentMasterPage ] );
2142 : }
2143 0 : const SvxFieldData* pField = pInfo->GetField().GetField();
2144 0 : if( bHasCharSetMap && ( pField->GetClassId() == text::textfield::Type::PRESENTATION_HEADER ) && ( pCharSetMap->find( aHeaderId ) != pCharSetMap->end() ) )
2145 : {
2146 0 : pCharSet = &( (*pCharSetMap)[ aHeaderId ] );
2147 : }
2148 0 : else if( bHasCharSetMap && ( pField->GetClassId() == text::textfield::Type::PRESENTATION_FOOTER ) && ( pCharSetMap->find( aFooterId ) != pCharSetMap->end() ) )
2149 : {
2150 0 : pCharSet = &( (*pCharSetMap)[ aFooterId ] );
2151 : }
2152 0 : else if( pField->GetClassId() == text::textfield::Type::PRESENTATION_DATE_TIME )
2153 : {
2154 0 : if( bHasCharSetMap && ( pCharSetMap->find( aDateTimeId ) != pCharSetMap->end() ) )
2155 : {
2156 0 : pCharSet = &( (*pCharSetMap)[ aDateTimeId ] );
2157 : }
2158 0 : if( bHasCharSetMap && ( pCharSetMap->find( aVariableDateTimeId ) != pCharSetMap->end() ) && !(*pCharSetMap)[ aVariableDateTimeId ].empty() )
2159 : {
2160 0 : SvxDateFormat eDateFormat = SVXDATEFORMAT_B, eCurDateFormat;
2161 0 : const UCharSet & aCharSet = (*pCharSetMap)[ aVariableDateTimeId ];
2162 0 : UCharSet::const_iterator aChar = aCharSet.begin();
2163 : // we look for the most verbose date format
2164 0 : for( ; aChar != aCharSet.end(); ++aChar )
2165 : {
2166 0 : eCurDateFormat = (SvxDateFormat)( (int)( *aChar ) & 0x0f );
2167 0 : switch( eDateFormat )
2168 : {
2169 : case SVXDATEFORMAT_STDSMALL: ;
2170 : case SVXDATEFORMAT_A: ; // 13.02.96
2171 : case SVXDATEFORMAT_B: // 13.02.1996
2172 0 : switch( eCurDateFormat )
2173 : {
2174 : case SVXDATEFORMAT_C: ; // 13.Feb 1996
2175 : case SVXDATEFORMAT_D: // 13.February 1996
2176 : case SVXDATEFORMAT_E: ; // Tue, 13.February 1996
2177 : case SVXDATEFORMAT_STDBIG: ;
2178 : case SVXDATEFORMAT_F: // Tuesday, 13.February 1996
2179 0 : eDateFormat = eCurDateFormat;
2180 0 : break;
2181 : default:
2182 0 : break;
2183 : }
2184 : case SVXDATEFORMAT_C: ; // 13.Feb 1996
2185 : case SVXDATEFORMAT_D: // 13.February 1996
2186 0 : switch( eCurDateFormat )
2187 : {
2188 : case SVXDATEFORMAT_E: ; // Tue, 13.February 1996
2189 : case SVXDATEFORMAT_STDBIG: ;
2190 : case SVXDATEFORMAT_F: // Tuesday, 13.February 1996
2191 0 : eDateFormat = eCurDateFormat;
2192 0 : break;
2193 : default:
2194 0 : break;
2195 : }
2196 0 : break;
2197 : default:
2198 0 : break;
2199 : }
2200 : }
2201 : // Independently of the date format, we always put all these characters by default.
2202 : // They should be enough to cover every time format.
2203 0 : aRepresentation += B2UCONST( "0123456789.:/-APM" );
2204 :
2205 0 : if( eDateFormat )
2206 : {
2207 0 : String sDate;
2208 0 : LanguageType eLang = pInfo->GetOutliner()->GetLanguage( pInfo->GetPara(), pInfo->GetPos() );
2209 0 : SvNumberFormatter * pNumberFormatter = new SvNumberFormatter( ::comphelper::getProcessServiceFactory(), LANGUAGE_SYSTEM );
2210 : // We always collect the characters obtained by using the SVXDATEFORMAT_B (as: 13.02.1996)
2211 : // so we are sure to include any unusual day|month|year separator.
2212 0 : Date aDate( 1, 1, 1996 );
2213 0 : sDate += SvxDateField::GetFormatted( aDate, SVXDATEFORMAT_B, *pNumberFormatter, eLang );
2214 0 : switch( eDateFormat )
2215 : {
2216 : case SVXDATEFORMAT_E: ; // Tue, 13.February 1996
2217 : case SVXDATEFORMAT_STDBIG: ;
2218 : case SVXDATEFORMAT_F: // Tuesday, 13.February 1996
2219 0 : for( sal_uInt16 i = 1; i <= 7; ++i ) // we get all days in a week
2220 : {
2221 0 : aDate.SetDay( i );
2222 0 : sDate += SvxDateField::GetFormatted( aDate, eDateFormat, *pNumberFormatter, eLang );
2223 : }
2224 : // No break here! We need months too!
2225 : case SVXDATEFORMAT_C: ; // 13.Feb 1996
2226 : case SVXDATEFORMAT_D: // 13.February 1996
2227 0 : for( sal_uInt16 i = 1; i <= 12; ++i ) // we get all months in a year
2228 : {
2229 0 : aDate.SetMonth( i );
2230 0 : sDate += SvxDateField::GetFormatted( aDate, eDateFormat, *pNumberFormatter, eLang );
2231 : }
2232 0 : break;
2233 : case SVXDATEFORMAT_STDSMALL: ;
2234 : case SVXDATEFORMAT_A: ; // 13.02.96
2235 : case SVXDATEFORMAT_B: ; // 13.02.1996
2236 : default:
2237 : // nothing to do here, we always collect the characters needed for these cases.
2238 0 : break;
2239 : }
2240 0 : aRepresentation += sDate;
2241 : }
2242 : }
2243 : }
2244 0 : else if( pField->GetClassId() == text::textfield::Type::PAGE )
2245 : {
2246 0 : switch( mVisiblePagePropSet.nPageNumberingType )
2247 : {
2248 : case SVX_CHARS_UPPER_LETTER:
2249 0 : aRepresentation += B2UCONST( "QWERTYUIOPASDFGHJKLZXCVBNM" );
2250 0 : break;
2251 : case SVX_CHARS_LOWER_LETTER:
2252 0 : aRepresentation += B2UCONST( "qwertyuiopasdfghjklzxcvbnm" );
2253 0 : break;
2254 : case SVX_ROMAN_UPPER:
2255 0 : aRepresentation += B2UCONST( "IVXLCDM" );
2256 0 : break;
2257 : case SVX_ROMAN_LOWER:
2258 0 : aRepresentation += B2UCONST( "ivxlcdm" );
2259 0 : break;
2260 : // arabic numbering type is the default
2261 : case SVX_ARABIC: ;
2262 : // in case the numbering type is not handled we fall back on arabic numbering
2263 : default:
2264 0 : aRepresentation += B2UCONST( "0123456789" );
2265 0 : break;
2266 : }
2267 : }
2268 : else
2269 : {
2270 0 : bFieldProcessed = sal_False;
2271 : }
2272 0 : if( bFieldProcessed )
2273 : {
2274 0 : if( pCharSet != NULL )
2275 : {
2276 0 : UCharSet::const_iterator aChar = pCharSet->begin();
2277 0 : for( ; aChar != pCharSet->end(); ++aChar )
2278 : {
2279 0 : aRepresentation += OUString::valueOf( *aChar );
2280 : }
2281 : }
2282 0 : pInfo->SetRepresentation( aRepresentation );
2283 : }
2284 : }
2285 : else
2286 : {
2287 0 : bFieldProcessed = sal_False;
2288 : }
2289 : }
2290 : else // single page case
2291 : {
2292 0 : if( mVisiblePagePropSet.bAreBackgroundObjectsVisible )
2293 : {
2294 0 : const SvxFieldData* pField = pInfo->GetField().GetField();
2295 0 : if( ( pField->GetClassId() == text::textfield::Type::PRESENTATION_HEADER ) && mVisiblePagePropSet.bIsHeaderFieldVisible )
2296 : {
2297 0 : aRepresentation += mVisiblePagePropSet.sHeaderText;
2298 : }
2299 0 : else if( ( pField->GetClassId() == text::textfield::Type::PRESENTATION_FOOTER ) && mVisiblePagePropSet.bIsFooterFieldVisible )
2300 : {
2301 0 : aRepresentation += mVisiblePagePropSet.sFooterText;
2302 : }
2303 0 : else if( ( pField->GetClassId() == text::textfield::Type::PRESENTATION_DATE_TIME ) && mVisiblePagePropSet.bIsDateTimeFieldVisible )
2304 : {
2305 : // TODO: implement the variable case
2306 0 : aRepresentation += mVisiblePagePropSet.sDateTimeText;
2307 : }
2308 0 : else if( ( pField->GetClassId() == text::textfield::Type::PAGE ) && mVisiblePagePropSet.bIsPageNumberFieldVisible )
2309 : {
2310 0 : sal_Int16 nPageNumber = mVisiblePagePropSet.nPageNumber;
2311 0 : switch( mVisiblePagePropSet.nPageNumberingType )
2312 : {
2313 : case SVX_CHARS_UPPER_LETTER:
2314 0 : aRepresentation += OUString::valueOf( (sal_Unicode)(char)( ( nPageNumber - 1 ) % 26 + 'A' ) );
2315 0 : break;
2316 : case SVX_CHARS_LOWER_LETTER:
2317 0 : aRepresentation += OUString::valueOf( (sal_Unicode)(char)( ( nPageNumber - 1 ) % 26 + 'a' ) );
2318 0 : break;
2319 : case SVX_ROMAN_UPPER:
2320 0 : aRepresentation += SvxNumberFormat::CreateRomanString( nPageNumber, true /* upper */ );
2321 0 : break;
2322 : case SVX_ROMAN_LOWER:
2323 0 : aRepresentation += SvxNumberFormat::CreateRomanString( nPageNumber, false /* lower */ );
2324 0 : break;
2325 : // arabic numbering type is the default
2326 : case SVX_ARABIC: ;
2327 : // in case the numbering type is not handled we fall back on arabic numbering
2328 : default:
2329 0 : aRepresentation += OUString::valueOf( sal_Int32(nPageNumber) );
2330 0 : break;
2331 : }
2332 : }
2333 : else
2334 : {
2335 0 : bFieldProcessed = sal_False;
2336 : }
2337 0 : if( bFieldProcessed )
2338 : {
2339 0 : pInfo->SetRepresentation( aRepresentation );
2340 : }
2341 : }
2342 :
2343 0 : }
2344 : }
2345 0 : return ( bFieldProcessed ? 0 : maOldFieldHdl.Call( pInfo ) );
2346 0 : }
2347 :
2348 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|