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