LibreOffice Module filter (master) 1
svgexport.cxx
Go to the documentation of this file.
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
25#include <com/sun/star/awt/Rectangle.hpp>
26#include <com/sun/star/animations/XAnimationNodeSupplier.hpp>
27#include <com/sun/star/container/XEnumerationAccess.hpp>
28#include <com/sun/star/drawing/FillStyle.hpp>
29#include <com/sun/star/drawing/XMasterPageTarget.hpp>
30#include <com/sun/star/drawing/GraphicExportFilter.hpp>
31#include <com/sun/star/presentation/XPresentationSupplier.hpp>
32#include <com/sun/star/style/ParagraphAdjust.hpp>
33#include <com/sun/star/text/textfield/Type.hpp>
34#include <com/sun/star/util/MeasureUnit.hpp>
35#include <com/sun/star/xml/sax/Writer.hpp>
36#include <com/sun/star/beans/XPropertySet.hpp>
37#include <com/sun/star/drawing/ShapeCollection.hpp>
38
39#include <rtl/bootstrap.hxx>
40#include <svx/unopage.hxx>
41#include <svx/svdpage.hxx>
42#include <svx/svdoutl.hxx>
43#include <editeng/outliner.hxx>
44#include <editeng/flditem.hxx>
49#include <i18nlangtag/lang.h>
50#include <svl/numformat.hxx>
51#include <tools/debug.hxx>
52#include <tools/urlobj.hxx>
54#include <unotools/tempfile.hxx>
60#include <xmloff/xmltoken.hxx>
62#include <svx/svdograf.hxx>
63#include <svx/svdmodel.hxx>
64#include <svx/svdxcgv.hxx>
65#include <sal/log.hxx>
67#include <tools/zcodec.hxx>
68#include <rtl/crc.h>
69
70#include <memory>
71#include <string_view>
72
73using namespace css::animations;
74using namespace css::presentation;
75using namespace ::com::sun::star::graphic;
76using namespace ::com::sun::star::geometry;
77using namespace ::com::sun::star;
78using namespace ::xmloff::token;
79
80// - ooo elements and attributes -
81
82#define NSPREFIX u"ooo:"
83
84constexpr OUStringLiteral SVG_PROP_TINYPROFILE = u"TinyMode";
85constexpr OUStringLiteral SVG_PROP_DTDSTRING = u"DTDString";
86constexpr OUStringLiteral SVG_PROP_EMBEDFONTS = u"EmbedFonts";
87constexpr OUStringLiteral SVG_PROP_NATIVEDECORATION = u"UseNativeTextDecoration";
88constexpr OUStringLiteral SVG_PROP_OPACITY = u"Opacity";
89constexpr OUStringLiteral SVG_PROP_POSITIONED_CHARACTERS = u"UsePositionedCharacters";
90
91// ooo xml elements
92constexpr OUStringLiteral aOOOElemTextField = NSPREFIX "text_field";
93
94
95// ooo xml attributes for meta_slide
96constexpr OUStringLiteral aOOOAttrSlide = NSPREFIX "slide";
97constexpr OUStringLiteral aOOOAttrMaster = NSPREFIX "master";
98constexpr OUStringLiteral aOOOAttrHasCustomBackground = NSPREFIX "has-custom-background";
99constexpr OUStringLiteral aOOOAttrDisplayName = NSPREFIX "display-name";
100constexpr OUStringLiteral aOOOAttrBackgroundVisibility = NSPREFIX "background-visibility";
101constexpr OUStringLiteral aOOOAttrMasterObjectsVisibility = NSPREFIX "master-objects-visibility";
102constexpr OUStringLiteral aOOOAttrSlideDuration = NSPREFIX "slide-duration";
103constexpr OUStringLiteral aOOOAttrDateTimeField = NSPREFIX "date-time-field";
104constexpr OUStringLiteral aOOOAttrFooterField = NSPREFIX "footer-field";
105constexpr OUStringLiteral aOOOAttrHasTransition = NSPREFIX "has-transition";
106
107// ooo xml attributes for pages and shapes
108constexpr OUStringLiteral aOOOAttrName = NSPREFIX "name";
109
110constexpr OUStringLiteral constSvgNamespace = u"http://www.w3.org/2000/svg";
111
112
117namespace {
118
119class TextField
120{
121protected:
122 SVGFilter::ObjectSet mMasterPageSet;
123public:
124 TextField() = default;
125 TextField(TextField const &) = default;
126 TextField(TextField &&) = default;
127 TextField & operator =(TextField const &) = default;
128 TextField & operator =(TextField &&) = default;
129
130 virtual OUString getClassName() const
131 {
132 return "TextField";
133 }
134 virtual bool equalTo( const TextField & aTextField ) const = 0;
135 virtual void growCharSet( SVGFilter::UCharSetMapMap & aTextFieldCharSets ) const = 0;
136 virtual void elementExport( SVGExport* pSVGExport ) const
137 {
138 pSVGExport->AddAttribute( XML_NAMESPACE_NONE, "class", getClassName() );
139 }
140 void insertMasterPage( const Reference< css::drawing::XDrawPage>& xMasterPage )
141 {
142 mMasterPageSet.insert( xMasterPage );
143 }
144 virtual ~TextField() {}
145protected:
146 void implGrowCharSet( SVGFilter::UCharSetMapMap & aTextFieldCharSets, const OUString& sText, const OUString& sTextFieldId ) const
147 {
148 const sal_Unicode * ustr = sText.getStr();
149 sal_Int32 nLength = sText.getLength();
150 for (auto const& masterPage : mMasterPageSet)
151 {
152 const Reference< XInterface > & xMasterPage = masterPage;
153 for( sal_Int32 i = 0; i < nLength; ++i )
154 {
155 aTextFieldCharSets[ xMasterPage ][ sTextFieldId ].insert( ustr[i] );
156 }
157 }
158 }
159};
160
161
162class FixedTextField : public TextField
163{
164public:
165 OUString text;
166
167 virtual OUString getClassName() const override
168 {
169 return "FixedTextField";
170 }
171 virtual bool equalTo( const TextField & aTextField ) const override
172 {
173 if( const FixedTextField* aFixedTextField = dynamic_cast< const FixedTextField* >( &aTextField ) )
174 {
175 return ( text == aFixedTextField->text );
176 }
177 return false;
178 }
179 virtual void elementExport( SVGExport* pSVGExport ) const override
180 {
181 TextField::elementExport( pSVGExport );
182 SvXMLElementExport aExp( *pSVGExport, XML_NAMESPACE_NONE, "g", true, true );
183 pSVGExport->GetDocHandler()->characters( text );
184 }
185};
186
187
188class FixedDateTimeField : public FixedTextField
189{
190public:
191 FixedDateTimeField() {}
192 virtual OUString getClassName() const override
193 {
194 return "FixedDateTimeField";
195 }
196 virtual void growCharSet( SVGFilter::UCharSetMapMap & aTextFieldCharSets ) const override
197 {
198 implGrowCharSet( aTextFieldCharSets, text, aOOOAttrDateTimeField );
199 }
200};
201
202
203class FooterField : public FixedTextField
204{
205public:
206 FooterField() {}
207 virtual OUString getClassName() const override
208 {
209 return "FooterField";
210 }
211 virtual void growCharSet( SVGFilter::UCharSetMapMap & aTextFieldCharSets ) const override
212 {
213 static constexpr OUStringLiteral sFieldId = aOOOAttrFooterField;
214 implGrowCharSet( aTextFieldCharSets, text, sFieldId );
215 }
216};
217
218
219class VariableTextField : public TextField
220{
221public:
222 virtual OUString getClassName() const override
223 {
224 return "VariableTextField";
225 }
226};
227
228
229class VariableDateTimeField : public VariableTextField
230{
231public:
232 sal_Int32 format;
233
234 VariableDateTimeField()
235 : format(0)
236 {
237 }
238 virtual OUString getClassName() const override
239 {
240 return "VariableDateTimeField";
241 }
242 virtual bool equalTo( const TextField & aTextField ) const override
243 {
244 if( const VariableDateTimeField* aField = dynamic_cast< const VariableDateTimeField* >( &aTextField ) )
245 {
246 return ( format == aField->format );
247 }
248 return false;
249 }
250 virtual void elementExport( SVGExport* pSVGExport ) const override
251 {
252 VariableTextField::elementExport( pSVGExport );
253 OUString sDateFormat, sTimeFormat;
254 SvxDateFormat eDateFormat = static_cast<SvxDateFormat>( format & 0x0f );
255 if( eDateFormat != SvxDateFormat::AppDefault )
256 {
257 switch( eDateFormat )
258 {
259 case SvxDateFormat::StdSmall:
260 case SvxDateFormat::A: // 13.02.96
261 sDateFormat.clear();
262 break;
263 case SvxDateFormat::C: // 13.Feb 1996
264 sDateFormat.clear();
265 break;
266 case SvxDateFormat::D: // 13.February 1996
267 sDateFormat.clear();
268 break;
269 case SvxDateFormat::E: // Tue, 13.February 1996
270 sDateFormat.clear();
271 break;
272 case SvxDateFormat::StdBig:
273 case SvxDateFormat::F: // Tuesday, 13.February 1996
274 sDateFormat.clear();
275 break;
276 // default case
277 case SvxDateFormat::B: // 13.02.1996
278 default:
279 sDateFormat.clear();
280 break;
281 }
282 }
283
284 SvxTimeFormat eTimeFormat = static_cast<SvxTimeFormat>( ( format >> 4 ) & 0x0f );
285 if( eTimeFormat != SvxTimeFormat::AppDefault )
286 {
287 switch( eTimeFormat )
288 {
289 case SvxTimeFormat::HH24_MM_SS: // 13:49:38
290 sTimeFormat.clear();
291 break;
292 case SvxTimeFormat::HH12_MM_AMPM: // 01:49 PM
293 case SvxTimeFormat::HH12_MM:
294 sTimeFormat.clear();
295 break;
296 case SvxTimeFormat::HH12_MM_SS_AMPM: // 01:49:38 PM
297 case SvxTimeFormat::HH12_MM_SS:
298 sTimeFormat.clear();
299 break;
300 // default case
301 case SvxTimeFormat::HH24_MM: // 13:49
302 default:
303 sTimeFormat.clear();
304 break;
305 }
306 }
307
308 OUString sDateTimeFormat = sDateFormat + " " + sTimeFormat;
309
310 pSVGExport->AddAttribute( XML_NAMESPACE_NONE, NSPREFIX "date-time-format", sDateTimeFormat );
311 SvXMLElementExport aExp( *pSVGExport, XML_NAMESPACE_NONE, "g", true, true );
312 }
313 virtual void growCharSet( SVGFilter::UCharSetMapMap & aTextFieldCharSets ) const override
314 {
315 // we use the unicode char set in an improper way: we put in the date/time format
316 // in order to pass it to the CalcFieldValue method
317 static const OUString sFieldId = aOOOAttrDateTimeField + "-variable";
318 for (auto const& masterPage : mMasterPageSet)
319 {
320 aTextFieldCharSets[ masterPage ][ sFieldId ].insert( static_cast<sal_Unicode>( format ) );
321 }
322 }
323};
324
325
326bool operator==( const TextField & aLhsTextField, const TextField & aRhsTextField )
327{
328 return aLhsTextField.equalTo( aRhsTextField );
329}
330
331}
332
334 const css::uno::Reference< css::uno::XComponentContext >& rContext,
335 const Reference< XDocumentHandler >& rxHandler,
336 const Sequence< PropertyValue >& rFilterData )
337 : SvXMLExport( rContext, "",
338 util::MeasureUnit::MM_100TH,
341{
342 SetDocHandler( rxHandler );
343 GetDocHandler()->startDocument();
344
345 // initializing filter settings from filter data
346 comphelper::SequenceAsHashMap aFilterDataHashMap = rFilterData;
347
348 // TinyProfile
350
351 // DTD string
353
354 // Font Embedding
356 if(iter==aFilterDataHashMap.end())
357 {
358 OUString v;
359 mbIsEmbedFonts = !rtl::Bootstrap::get("SVG_DISABLE_FONT_EMBEDDING", v);
360 }
361 else
362 {
363 if(!(iter->second >>= mbIsEmbedFonts))
364 mbIsEmbedFonts = false;
365 }
366
367 // Native Decoration
369
370 // Tiny Opacity (supported from SVG Tiny 1.2)
372
373 // Positioned Characters (The old method)
375
376 // add namespaces
381
386
391
396}
397
399{
400 GetDocHandler()->endDocument();
401}
402
404{
405}
406
407ObjectRepresentation::ObjectRepresentation( const Reference< XInterface >& rxObject,
408 const GDIMetaFile& rMtf ) :
409 mxObject( rxObject ),
410 mxMtf( new GDIMetaFile( rMtf ) )
411{
412}
413
415 mxObject( rPresentation.mxObject ),
416 mxMtf( rPresentation.mxMtf ? new GDIMetaFile( *rPresentation.mxMtf ) : nullptr )
417{
418}
419
421{
422 // Check for self-assignment
423 if (this == &rPresentation)
424 return *this;
425
426 mxObject = rPresentation.mxObject;
427 mxMtf.reset(rPresentation.mxMtf ? new GDIMetaFile(*rPresentation.mxMtf) : nullptr);
428
429 return *this;
430}
431
432
433namespace
434{
435
436BitmapChecksum GetBitmapChecksum( const MetaAction* pAction )
437{
438 if( !pAction )
439 {
440 OSL_FAIL( "GetBitmapChecksum: passed MetaAction pointer is null." );
441 return 0;
442 }
443
444 BitmapChecksum nChecksum = 0;
445 const MetaActionType nType = pAction->GetType();
446
447 switch( nType )
448 {
449 case MetaActionType::BMPSCALE:
450 {
451 const MetaBmpScaleAction* pA = static_cast<const MetaBmpScaleAction*>(pAction);
452 // The conversion to BitmapEx is needed since a Bitmap object is
453 // converted to BitmapEx before passing it to SVGActionWriter::ImplWriteBmp
454 // where the checksum is checked for matching.
455 nChecksum = BitmapEx( pA->GetBitmap() ).GetChecksum();
456 }
457 break;
458 case MetaActionType::BMPEXSCALE:
459 {
460 const MetaBmpExScaleAction* pA = static_cast<const MetaBmpExScaleAction*>(pAction);
461 nChecksum = pA->GetBitmapEx().GetChecksum();
462 }
463 break;
464 default: break;
465 }
466 return nChecksum;
467}
468
469MetaAction* CreateMetaBitmapAction( const MetaAction* pAction, const Point& rPt, const Size& rSz )
470{
471 if( !pAction )
472 {
473 OSL_FAIL( "CreateMetaBitmapAction: passed MetaAction pointer is null." );
474 return nullptr;
475 }
476
477 MetaAction* pResAction = nullptr;
478 const MetaActionType nType = pAction->GetType();
479 switch( nType )
480 {
481 case MetaActionType::BMPSCALE:
482 {
483 const MetaBmpScaleAction* pA = static_cast<const MetaBmpScaleAction*>(pAction);
484 pResAction = new MetaBmpScaleAction( rPt, rSz, pA->GetBitmap() );
485 }
486 break;
487 case MetaActionType::BMPEXSCALE:
488 {
489 const MetaBmpExScaleAction* pA = static_cast<const MetaBmpExScaleAction*>(pAction);
490 pResAction = new MetaBmpExScaleAction( rPt, rSz, pA->GetBitmapEx() );
491 }
492 break;
493 default: break;
494 }
495 return pResAction;
496}
497
498void MetaBitmapActionGetPoint( const MetaAction* pAction, Point& rPt )
499{
500 if( !pAction )
501 {
502 OSL_FAIL( "MetaBitmapActionGetPoint: passed MetaAction pointer is null." );
503 return;
504 }
505 const MetaActionType nType = pAction->GetType();
506 switch( nType )
507 {
508 case MetaActionType::BMPSCALE:
509 {
510 const MetaBmpScaleAction* pA = static_cast<const MetaBmpScaleAction*>(pAction);
511 rPt = pA->GetPoint();
512 }
513 break;
514 case MetaActionType::BMPEXSCALE:
515 {
516 const MetaBmpExScaleAction* pA = static_cast<const MetaBmpExScaleAction*>(pAction);
517 rPt = pA->GetPoint();
518 }
519 break;
520 default: break;
521 }
522}
523
524void MetaBitmapActionGetSize( const MetaAction* pAction, Size& rSz )
525{
526 if( !pAction )
527 {
528 OSL_FAIL( "MetaBitmapActionGetSize: passed MetaAction pointer is null." );
529 return;
530 }
531 const MetaActionType nType = pAction->GetType();
532 switch( nType )
533 {
534 case MetaActionType::BMPSCALE:
535 {
536 const MetaBmpScaleAction* pA = static_cast<const MetaBmpScaleAction*>(pAction);
537 rSz = pA->GetSize();
538 }
539 break;
540 case MetaActionType::BMPEXSCALE:
541 {
542 const MetaBmpExScaleAction* pA = static_cast<const MetaBmpExScaleAction*>(pAction);
543 rSz = pA->GetSize();
544 }
545 break;
546 default: break;
547 }
548}
549
550void MetaBitmapActionGetOrigSize( const MetaAction* pAction, Size& rSz )
551{
552 if( !pAction )
553 {
554 OSL_FAIL( "MetaBitmapActionGetOrigSize: passed MetaAction pointer is null." );
555 return;
556 }
557
558 const MetaActionType nType = pAction->GetType();
559 MapMode aSourceMode( MapUnit::MapPixel );
560 MapMode aTargetMode( MapUnit::Map100thMM );
561
562 switch( nType )
563 {
564 case MetaActionType::BMPSCALE:
565 {
566 const MetaBmpScaleAction* pA = static_cast<const MetaBmpScaleAction*>(pAction);
567 const Bitmap& rBitmap = pA->GetBitmap();
568 rSz = rBitmap.GetSizePixel();
569 }
570 break;
571 case MetaActionType::BMPEXSCALE:
572 {
573 const MetaBmpExScaleAction* pA = static_cast<const MetaBmpExScaleAction*>(pAction);
574 const BitmapEx& rBitmap = pA->GetBitmapEx();
575 rSz = rBitmap.GetSizePixel();
576 }
577 break;
578 default: break;
579 }
580 rSz = OutputDevice::LogicToLogic( rSz, aSourceMode, aTargetMode );
581}
582
583OUString getPatternIdForTiledBackground( std::u16string_view sSlideId, BitmapChecksum nChecksum )
584{
585 return OUString::Concat("bg-pattern.") + sSlideId + "." + OUString::number( nChecksum );
586}
587
588OUString getIdForTiledBackground( std::u16string_view sSlideId, BitmapChecksum nChecksum )
589{
590 return OUString::Concat("bg-") + sSlideId + "." + OUString::number( nChecksum );
591}
592
593} // end anonymous namespace
594
595size_t HashBitmap::operator()( const ObjectRepresentation& rObjRep ) const
596{
597 const GDIMetaFile& aMtf = rObjRep.GetRepresentation();
598 if( aMtf.GetActionSize() == 1 )
599 {
600 return static_cast< size_t >( GetBitmapChecksum( aMtf.GetAction( 0 ) ) );
601 }
602 else
603 {
604 OSL_FAIL( "HashBitmap: metafile should have a single action." );
605 return 0;
606 }
607}
608
609
611 const ObjectRepresentation& rObjRep2 ) const
612{
613 const GDIMetaFile& aMtf1 = rObjRep1.GetRepresentation();
614 const GDIMetaFile& aMtf2 = rObjRep2.GetRepresentation();
615 if( aMtf1.GetActionSize() == 1 && aMtf2.GetActionSize() == 1 )
616 {
617 BitmapChecksum nChecksum1 = GetBitmapChecksum( aMtf1.GetAction( 0 ) );
618 BitmapChecksum nChecksum2 = GetBitmapChecksum( aMtf2.GetAction( 0 ) );
619 return ( nChecksum1 == nChecksum2 );
620 }
621 else
622 {
623 OSL_FAIL( "EqualityBitmap: metafile should have a single action." );
624 return false;
625 }
626}
627
628
629bool SVGFilter::implExport( const Sequence< PropertyValue >& rDescriptor )
630{
631 Reference< XOutputStream > xOStm;
632 std::unique_ptr<SvStream> pOStm;
633 sal_Int32 nLength = rDescriptor.getLength();
634 const PropertyValue* pValue = rDescriptor.getConstArray();
635
636 maFilterData.realloc( 0 );
637
638 for ( sal_Int32 i = 0 ; i < nLength; ++i)
639 {
640 if ( pValue[ i ].Name == "OutputStream" )
641 pValue[ i ].Value >>= xOStm;
642 else if ( pValue[ i ].Name == "FileName" )
643 {
644 OUString aFileName;
645
646 pValue[ i ].Value >>= aFileName;
647 pOStm = ::utl::UcbStreamHelper::CreateStream( aFileName, StreamMode::WRITE | StreamMode::TRUNC );
648
649 if( pOStm )
650 xOStm.set( new ::utl::OOutputStreamWrapper ( *pOStm ) );
651 }
652 else if ( pValue[ i ].Name == "FilterData" )
653 {
654 pValue[ i ].Value >>= maFilterData;
655 }
656 }
657
659 return implExportWriterOrCalc(xOStm);
660
661 return implExportImpressOrDraw(xOStm);
662}
663
664bool SVGFilter::implExportImpressOrDraw( const Reference< XOutputStream >& rxOStm)
665{
666 Reference< XComponentContext > xContext( ::comphelper::getProcessComponentContext() ) ;
667 bool bRet = false;
668 // Instead of writing to rxOStm directly, we write here in case we need
669 // to compress the output later
670 SvMemoryStream aTempStm;
671
672 if( rxOStm.is() )
673 {
674 if (!mSelectedPages.empty())
675 {
676 ::rtl::Reference< ::utl::OStreamWrapper > aTempStmWrapper = new ::utl::OStreamWrapper( aTempStm );
677 Reference< XDocumentHandler > xDocHandler = implCreateExportDocumentHandler( aTempStmWrapper );
678
679 if( xDocHandler.is() )
680 {
681 mbPresentation = Reference< XPresentationSupplier >( mxSrcDoc, UNO_QUERY ).is();
682 mpObjects = new ObjectMap;
683
684 // mpSVGExport = new SVGExport( xDocHandler );
685 mpSVGExport = new SVGExport( xContext, xDocHandler, maFilterData );
686
687 // create an id for each draw page
688 for( const auto& rPage : mSelectedPages )
689 implRegisterInterface( rPage );
690
691 // create an id for each master page
692 for(const uno::Reference<drawing::XDrawPage> & mMasterPageTarget : mMasterPageTargets)
693 implRegisterInterface( mMasterPageTarget );
694
695 SdrModel* pSdrModel(nullptr);
696
697 try
698 {
700
701 if( mxDefaultPage.is() )
702 {
703 SvxDrawPage* pSvxDrawPage = comphelper::getFromUnoTunnel<SvxDrawPage>( mxDefaultPage );
704
705 if( pSvxDrawPage )
706 {
707 mpDefaultSdrPage = pSvxDrawPage->GetSdrPage();
709 SdrOutliner& rOutl = pSdrModel->GetDrawOutliner();
710
711 maOldFieldHdl = rOutl.GetCalcFieldValueHdl();
712 maNewFieldHdl = LINK(this, SVGFilter, CalcFieldHdl);
713 rOutl.SetCalcFieldValueHdl(maNewFieldHdl);
714 }
715
716 bRet = implExportDocument();
717 }
718 }
719 catch( ... )
720 {
721 delete mpSVGDoc;
722 mpSVGDoc = nullptr;
723 SAL_WARN("filter.svg", "Exception caught");
724 }
725
726 if( nullptr != pSdrModel )
727 {
728 // fdo#62682 The maNewFieldHdl can end up getting copied
729 // into various other outliners which live past this
730 // method, so get the full list of outliners and restore
731 // the maOldFieldHdl for all that have ended up using
732 // maNewFieldHdl
733 std::vector<SdrOutliner*> aOutliners(pSdrModel->GetActiveOutliners());
734 for (auto const& outliner : aOutliners)
735 {
736 if (maNewFieldHdl == outliner->GetCalcFieldValueHdl())
737 outliner->SetCalcFieldValueHdl(maOldFieldHdl);
738 }
739 }
740
741 delete mpSVGWriter;
742 mpSVGWriter = nullptr;
743 mpSVGExport = nullptr; // pointed object is released by xSVGExport dtor at the end of this scope
744 delete mpSVGFontExport;
745 mpSVGFontExport = nullptr;
746 delete mpObjects;
747 mpObjects = nullptr;
748 mbPresentation = false;
749 }
750 }
751 }
752 if ( bRet )
753 {
754 const sal_Int8* aDataPtr = static_cast< const sal_Int8* >( aTempStm.GetData() );
755 sal_uInt32 aDataSize = aTempStm.GetSize();
756 SvMemoryStream aCompressedStm;
757 if ( mbShouldCompress )
758 {
759 sal_uInt32 nUncompressedCRC32
760 = rtl_crc32( 0, aTempStm.GetData(), aTempStm.GetSize() );
761 ZCodec aCodec;
762 aTempStm.Seek( 0 );
763 aCodec.BeginCompression( ZCODEC_DEFAULT_COMPRESSION, /*gzLib*/true );
764 // the inner modify time/filename doesn't really matter in this context because
765 // compressed graphic formats are meant to be opened as is - not to be extracted
766 aCodec.SetCompressionMetadata( "inner", 0, nUncompressedCRC32 );
767 aCodec.Compress( aTempStm, aCompressedStm );
768 sal_uInt32 nTotalIn = static_cast< sal_uInt32 >( aCodec.EndCompression() );
769 if ( aCompressedStm.GetError() || nTotalIn != aDataSize )
770 {
771 bRet = false;
772 return bRet;
773 }
774 else
775 {
776 aDataPtr = static_cast< const sal_Int8* >( aCompressedStm.GetData() );
777 aDataSize = aCompressedStm.GetSize();
778 }
779 }
780
781 Sequence< sal_Int8 > aTempSeq( aDataPtr, aDataSize );
782 rxOStm->writeBytes( aTempSeq );
783 }
784 return bRet;
785}
786
787
788bool SVGFilter::implExportWriterOrCalc( const Reference< XOutputStream >& rxOStm )
789{
790 Reference< XComponentContext > xContext( ::comphelper::getProcessComponentContext() ) ;
791 bool bRet = false;
792
793 if( rxOStm.is() )
794 {
795 Reference< XDocumentHandler > xDocHandler = implCreateExportDocumentHandler( rxOStm );
796
797 if( xDocHandler.is() )
798 {
799 mpObjects = new ObjectMap;
800
801 // mpSVGExport = new SVGExport( xDocHandler );
802 mpSVGExport = new SVGExport( xContext, xDocHandler, maFilterData );
803
804 try
805 {
807 bRet = implExportDocument();
808 }
809 catch( ... )
810 {
811 TOOLS_WARN_EXCEPTION( "filter.svg", "" );
812 delete mpSVGDoc;
813 mpSVGDoc = nullptr;
814 }
815
816 delete mpSVGWriter;
817 mpSVGWriter = nullptr;
818 mpSVGExport = nullptr; // pointed object is released by xSVGExport dtor at the end of this scope
819 delete mpSVGFontExport;
820 mpSVGFontExport = nullptr;
821 delete mpObjects;
822 mpObjects = nullptr;
823 }
824 }
825 return bRet;
826}
827
828bool SVGFilter::implExportWriterTextGraphic( const Reference< view::XSelectionSupplier >& xSelectionSupplier )
829{
830 Any selection = xSelectionSupplier->getSelection();
831 uno::Reference<lang::XServiceInfo> xSelection;
832 selection >>= xSelection;
833 if (!xSelection || !xSelection->supportsService("com.sun.star.text.TextGraphicObject"))
834 return true;
835
836 uno::Reference<beans::XPropertySet> xPropertySet(xSelection, uno::UNO_QUERY);
837
838 uno::Reference<graphic::XGraphic> xOriginalGraphic;
839 xPropertySet->getPropertyValue("Graphic") >>= xOriginalGraphic;
840 const Graphic aOriginalGraphic(xOriginalGraphic);
841
842 uno::Reference<graphic::XGraphic> xTransformedGraphic;
843 xPropertySet->getPropertyValue(
844 mbIsPreview ? OUString("GraphicPreview") : OUString("TransformedGraphic"))
845 >>= xTransformedGraphic;
846
847 if (!xTransformedGraphic.is())
848 return false;
849 const Graphic aTransformedGraphic(xTransformedGraphic);
850 bool bSameGraphic = aTransformedGraphic == aOriginalGraphic ||
851 aOriginalGraphic.GetChecksum() == aTransformedGraphic.GetChecksum();
852 const Graphic aGraphic = bSameGraphic ? aOriginalGraphic : aTransformedGraphic;
853 uno::Reference<graphic::XGraphic> xGraphic = bSameGraphic ? xOriginalGraphic : xTransformedGraphic;
854
855 // Calculate size from Graphic
856 Point aPos( OutputDevice::LogicToLogic(aGraphic.GetPrefMapMode().GetOrigin(), aGraphic.GetPrefMapMode(), MapMode(MapUnit::Map100thMM)) );
857 Size aSize( OutputDevice::LogicToLogic(aGraphic.GetPrefSize(), aGraphic.GetPrefMapMode(), MapMode(MapUnit::Map100thMM)) );
858
859 assert(mSelectedPages.size() == 1);
860 SvxDrawPage* pSvxDrawPage(comphelper::getFromUnoTunnel<SvxDrawPage>(mSelectedPages[0]));
861 if(pSvxDrawPage == nullptr || pSvxDrawPage->GetSdrPage() == nullptr)
862 return false;
863
864 SdrModel& rModel = pSvxDrawPage->GetSdrPage()->getSdrModelFromSdrPage();
865 const bool bUndoEnable = rModel.IsUndoEnabled();
866 if (bUndoEnable)
867 rModel.EnableUndo(false);
868 comphelper::ScopeGuard guard([bUndoEnable, &rModel]() {
869 // restore when leaving
870 if (bUndoEnable)
871 rModel.EnableUndo(false);
872 });
873
874 rtl::Reference<SdrGrafObj> pGraphicObj = new SdrGrafObj(rModel, aGraphic, tools::Rectangle( aPos, aSize ));
875 uno::Reference< drawing::XShape > xShape = GetXShapeForSdrObject(pGraphicObj.get());
876 uno::Reference< XPropertySet > xShapePropSet(xShape, uno::UNO_QUERY);
877 xShapePropSet->setPropertyValue("Graphic", uno::Any(xGraphic));
878
879 maShapeSelection = drawing::ShapeCollection::create(comphelper::getProcessComponentContext());
880 maShapeSelection->add(xShape);
881
882 return true;
883}
884
885
886Reference< XWriter > SVGFilter::implCreateExportDocumentHandler( const Reference< XOutputStream >& rxOStm )
887{
888 Reference< XWriter > xSaxWriter;
889
890 if( rxOStm.is() )
891 {
892 xSaxWriter = Writer::create( ::comphelper::getProcessComponentContext() );
893 xSaxWriter->setOutputStream( rxOStm );
894 }
895
896 return xSaxWriter;
897}
898
899
901{
902 sal_Int32 nCurPage = 0, nLastPage = mSelectedPages.size() - 1;
903
905 {
906 mnVisiblePage = nCurPage;
907 }
908
909 while( ( nCurPage <= nLastPage ) && ( -1 == mnVisiblePage ) )
910 {
911 const Reference< css::drawing::XDrawPage > & xDrawPage = mSelectedPages[nCurPage];
912
913 if( xDrawPage.is() )
914 {
915 Reference< XPropertySet > xPropSet( xDrawPage, UNO_QUERY );
916
917 if( xPropSet.is() )
918 {
919 bool bVisible = false;
920
921 if( ( xPropSet->getPropertyValue( "Visible" ) >>= bVisible ) && bVisible )
922 {
923 mnVisiblePage = nCurPage;
924 }
925 }
926 }
927 ++nCurPage;
928 }
929
930 return ( mnVisiblePage != -1 );
931}
932
933
935{
936 sal_Int32 nDocX = 0, nDocY = 0; // #i124608#
937 sal_Int32 nDocWidth = 0, nDocHeight = 0;
938 bool bRet = false;
939 sal_Int32 nLastPage = mSelectedPages.size() - 1;
940
941 mbSinglePage = (nLastPage == 0);
942 mnVisiblePage = -1;
943
944 const Reference< XPropertySet > xDefaultPagePropertySet( mxDefaultPage, UNO_QUERY );
945
946 // #i124608#
948
949 if (xDefaultPagePropertySet.is())
950 {
951 sal_Int32 nWidth = 0;
952 sal_Int32 nHeight = 0;
953 if (xDefaultPagePropertySet->getPropertyValue("Width") >>= nWidth)
954 nDocWidth = nWidth;
955 if (xDefaultPagePropertySet->getPropertyValue("Height") >>= nHeight)
956 nDocHeight = nHeight;
957 }
958
960 {
961 // #i124608# create BoundRange and set nDocX, nDocY, nDocWidth and nDocHeight
962 basegfx::B2DRange aShapeRange;
963
964 for(sal_Int32 a(0); a < maShapeSelection->getCount(); a++)
965 {
966 Reference< css::drawing::XShape > xShapeCandidate;
967 if((maShapeSelection->getByIndex(a) >>= xShapeCandidate) && xShapeCandidate.is())
968 {
969 Reference< XPropertySet > xShapePropSet( xShapeCandidate, UNO_QUERY );
970 css::awt::Rectangle aBoundRect;
971 if( xShapePropSet.is() && ( xShapePropSet->getPropertyValue( "BoundRect" ) >>= aBoundRect ))
972 {
973 aShapeRange.expand(basegfx::B2DTuple(aBoundRect.X, aBoundRect.Y));
974 aShapeRange.expand(basegfx::B2DTuple(aBoundRect.X + aBoundRect.Width,
975 aBoundRect.Y + aBoundRect.Height));
976 }
977 }
978 }
979
980 if(!aShapeRange.isEmpty())
981 {
982 nDocX = basegfx::fround(aShapeRange.getMinX());
983 nDocY = basegfx::fround(aShapeRange.getMinY());
984 nDocWidth = basegfx::fround(aShapeRange.getWidth());
985 nDocHeight = basegfx::fround(aShapeRange.getHeight());
986 }
987 }
988
990 implExportDocumentHeaderWriterOrCalc(nDocX, nDocY, nDocWidth, nDocHeight);
991 else
992 implExportDocumentHeaderImpressOrDraw(nDocX, nDocY, nDocWidth, nDocHeight);
993
994
995 if( implLookForFirstVisiblePage() ) // OK! We found at least one visible page.
996 {
998 {
1001 }
1002 else
1003 {
1005 }
1006
1007 // Create the (Shape, GDIMetaFile) map
1008 if( implCreateObjects() )
1009 {
1010 ::std::vector< ObjectRepresentation > aObjects( mpObjects->size() );
1011 sal_uInt32 nPos = 0;
1012
1013 for (auto const& elem : *mpObjects)
1014 {
1015 aObjects[ nPos++ ] = elem.second;
1016 }
1017
1018 mpSVGFontExport = new SVGFontExport( *mpSVGExport, std::move(aObjects) );
1020
1021 if( mpSVGExport->IsEmbedFonts() )
1022 {
1024 }
1025 if( !mpSVGExport->IsUsePositionedCharacters() )
1026 {
1033 }
1034 if( mbIsPreview )
1036
1037 // #i124608# export a given object selection, so no MasterPage export at all
1040 implExportDrawPages( mSelectedPages, 0, nLastPage );
1041
1043 {
1045 }
1046
1047 delete mpSVGDoc;
1048 mpSVGDoc = nullptr;
1049 bRet = true;
1050 }
1051 }
1052
1053 return bRet;
1054}
1055
1056void SVGFilter::implExportDocumentHeaderImpressOrDraw(sal_Int32 nDocX, sal_Int32 nDocY,
1057 sal_Int32 nDocWidth, sal_Int32 nDocHeight)
1058{
1059 const Reference< XExtendedDocumentHandler > xExtDocHandler( mpSVGExport->GetDocHandler(), UNO_QUERY );
1060 if( xExtDocHandler.is() && !mpSVGExport->IsUseTinyProfile() )
1061 {
1062 xExtDocHandler->unknown( SVG_DTD_STRING );
1063 }
1064
1065 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "version", "1.2" );
1066
1067 if( mpSVGExport->IsUseTinyProfile() )
1068 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "baseProfile", "tiny" );
1069
1070 // The following if block means that the slide size is not adapted
1071 // to the size of the browser window, moreover the slide is top left aligned
1072 // instead of centered:
1073 OUString aAttr;
1074 if( !mbPresentation )
1075 {
1076 aAttr = OUString::number( nDocWidth * 0.01 ) + "mm";
1077 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "width", aAttr );
1078
1079 aAttr = OUString::number( nDocHeight * 0.01 ) + "mm";
1080 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "height", aAttr );
1081 }
1082
1083 // #i124608# set viewBox explicitly to the exported content
1085 {
1086 aAttr = OUString::number(nDocX) + " " + OUString::number(nDocY) + " ";
1087 }
1088 else
1089 {
1090 aAttr = "0 0 ";
1091 }
1092
1093 aAttr += OUString::number(nDocWidth) + " " + OUString::number(nDocHeight);
1094
1095 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "viewBox", aAttr );
1096 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "preserveAspectRatio", "xMidYMid" );
1097 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "fill-rule", "evenodd" );
1098
1099 // standard line width is based on 1 pixel on a 90 DPI device (0.28222mmm)
1100 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "stroke-width", OUString::number( 28.222 ) );
1101 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "stroke-linejoin", "round" );
1102 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "xmlns", constSvgNamespace );
1103 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "xmlns:ooo", "http://xml.openoffice.org/svg/export" );
1104 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "xmlns:xlink", "http://www.w3.org/1999/xlink" );
1105 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "xmlns:presentation", "http://sun.com/xmlns/staroffice/presentation" );
1106 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "xmlns:smil", "http://www.w3.org/2001/SMIL20/" );
1107 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "xmlns:anim", "urn:oasis:names:tc:opendocument:xmlns:animation:1.0" );
1108 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "xmlns:svg", "urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" );
1109 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "xml:space", "preserve" );
1110
1111 mpSVGDoc = new SvXMLElementExport( *mpSVGExport, XML_NAMESPACE_NONE, "svg", true, true );
1112
1113 // Create a ClipPath element that will be used for cutting bitmaps and other elements that could exceed the page margins.
1115 return;
1116
1117 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "class", "ClipPathGroup" );
1118 SvXMLElementExport aDefsElem( *mpSVGExport, XML_NAMESPACE_NONE, "defs", true, true );
1119 {
1120 msClipPathId = "presentation_clip_path";
1121 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "id", msClipPathId );
1122 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "clipPathUnits", "userSpaceOnUse" );
1123 SvXMLElementExport aClipPathElem( *mpSVGExport, XML_NAMESPACE_NONE, "clipPath", true, true );
1124 {
1125 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "x", OUString::number( nDocX ) );
1126 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "y", OUString::number( nDocY ) );
1127 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "width", OUString::number( nDocWidth ) );
1128 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "height", OUString::number( nDocHeight ) );
1129 SvXMLElementExport aRectElem( *mpSVGExport, XML_NAMESPACE_NONE, "rect", true, true );
1130 }
1131 }
1132 // Create a ClipPath element applied to the leaving slide in order
1133 // to avoid that slide borders are visible during transition
1134 {
1135 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "id", "presentation_clip_path_shrink" );
1136 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "clipPathUnits", "userSpaceOnUse" );
1137 SvXMLElementExport aClipPathElem( *mpSVGExport, XML_NAMESPACE_NONE, "clipPath", true, true );
1138 {
1139 sal_Int32 nDocWidthExt = nDocWidth / 500;
1140 sal_Int32 nDocHeightExt = nDocHeight / 500;
1141 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "x", OUString::number( nDocX + nDocWidthExt / 2 ) );
1142 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "y", OUString::number( nDocY + nDocHeightExt / 2) );
1143 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "width", OUString::number( nDocWidth - nDocWidthExt ) );
1144 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "height", OUString::number( nDocHeight - nDocHeightExt ) );
1145 SvXMLElementExport aRectElem( *mpSVGExport, XML_NAMESPACE_NONE, "rect", true, true );
1146 }
1147 }
1148}
1149
1150void SVGFilter::implExportDocumentHeaderWriterOrCalc(sal_Int32 nDocX, sal_Int32 nDocY,
1151 sal_Int32 nDocWidth, sal_Int32 nDocHeight)
1152{
1153 OUString aAttr;
1154 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "version", "1.2" );
1155
1156 aAttr = OUString::number( nDocWidth * 0.01 ) + "mm";
1157 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "width", aAttr );
1158
1159 aAttr = OUString::number( nDocHeight * 0.01 ) + "mm";
1160 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "height", aAttr );
1161
1162 aAttr = OUString::number(nDocX) + " " + OUString::number(nDocY) + " " +
1163 OUString::number(nDocWidth) + " " + OUString::number(nDocHeight);
1164
1165 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "viewBox", aAttr );
1166 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "preserveAspectRatio", "xMidYMid" );
1167 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "fill-rule", "evenodd" );
1168
1169 // standard line width is based on 1 pixel on a 90 DPI device (0.28222mmm)
1170 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "stroke-width", OUString::number( 28.222 ) );
1171 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "stroke-linejoin", "round" );
1172 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "xmlns", constSvgNamespace );
1173 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "xmlns:ooo", "http://xml.openoffice.org/svg/export" );
1174 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "xmlns:xlink", "http://www.w3.org/1999/xlink" );
1175 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "xmlns:office", "urn:oasis:names:tc:opendocument:xmlns:office:1.0" );
1176 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "xmlns:smil", "urn:oasis:names:tc:opendocument:xmlns:smil-compatible:1.0" );
1177 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "xml:space", "preserve" );
1178
1179 mpSVGDoc = new SvXMLElementExport( *mpSVGExport, XML_NAMESPACE_NONE, "svg", true, true );
1180}
1181
1183template< typename TextFieldType >
1184static OUString implGenerateFieldId( std::vector< std::unique_ptr<TextField> > & aFieldSet,
1185 const TextFieldType & aField,
1186 std::u16string_view sOOOElemField,
1187 const Reference< css::drawing::XDrawPage >& xMasterPage )
1188{
1189 bool bFound = false;
1190 sal_Int32 i;
1191 sal_Int32 nSize = aFieldSet.size();
1192 for( i = 0; i < nSize; ++i )
1193 {
1194 if( *(aFieldSet[i]) == aField )
1195 {
1196 bFound = true;
1197 break;
1198 }
1199 }
1200 OUString sFieldId(OUString::Concat(sOOOElemField) + "_");
1201 if( !bFound )
1202 {
1203 aFieldSet.emplace_back( new TextFieldType( aField ) );
1204 }
1205 aFieldSet[i]->insertMasterPage( xMasterPage );
1206 sFieldId += OUString::number( i );
1207 return sFieldId;
1208}
1209
1210
1212{
1213 sal_Int32 nCount = mSelectedPages.size();
1214 if( nCount == 0 )
1215 return;
1216
1217 // we wrap all meta presentation info into a svg:defs element
1218 SvXMLElementExport aDefsElem( *mpSVGExport, XML_NAMESPACE_NONE, "defs", true, true );
1219
1220 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "id", NSPREFIX "meta_slides" );
1221 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, NSPREFIX "number-of-slides", OUString::number( nCount ) );
1222 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, NSPREFIX "start-slide-number", OUString::number( mnVisiblePage ) );
1223
1224 if( mpSVGExport->IsUsePositionedCharacters() )
1225 {
1226 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, NSPREFIX "use-positioned-chars", "true" );
1227 }
1228
1229 // Add a (global) Page Numbering Type attribute for the document
1230 // NOTE: at present pSdrModel->GetPageNumType() returns always css::style::NumberingType::ARABIC
1231 // so the following code fragment is pretty useless
1232 sal_Int32 nPageNumberingType = css::style::NumberingType::ARABIC;
1233 SvxDrawPage* pSvxDrawPage = comphelper::getFromUnoTunnel<SvxDrawPage>( mSelectedPages[0] );
1234 if( pSvxDrawPage )
1235 {
1236 SdrPage* pSdrPage = pSvxDrawPage->GetSdrPage();
1237 SdrModel& rSdrModel(pSdrPage->getSdrModelFromSdrPage());
1238 nPageNumberingType = rSdrModel.GetPageNumType();
1239
1240 // That is used by CalcFieldHdl method.
1241 mVisiblePagePropSet.nPageNumberingType = nPageNumberingType;
1242 }
1243 if( nPageNumberingType != css::style::NumberingType::NUMBER_NONE )
1244 {
1245 OUString sNumberingType;
1246 switch( nPageNumberingType )
1247 {
1248 case css::style::NumberingType::CHARS_UPPER_LETTER:
1249 sNumberingType = "alpha-upper";
1250 break;
1251 case css::style::NumberingType::CHARS_LOWER_LETTER:
1252 sNumberingType = "alpha-lower";
1253 break;
1254 case css::style::NumberingType::ROMAN_UPPER:
1255 sNumberingType = "roman-upper";
1256 break;
1257 case css::style::NumberingType::ROMAN_LOWER:
1258 sNumberingType = "roman-lower";
1259 break;
1260 case css::style::NumberingType::ARABIC:
1261 // arabic numbering type is the default, so we do not append any attribute for it
1262 default:
1263 // in case the numbering type is not handled we fall back on arabic numbering
1264 break;
1265 }
1266 if( !sNumberingType.isEmpty() )
1267 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, NSPREFIX "page-numbering-type", sNumberingType );
1268 }
1269
1270
1271 {
1272 SvXMLElementExport aExp( *mpSVGExport, XML_NAMESPACE_NONE, "g", true, true );
1273 const OUString aId( NSPREFIX "meta_slide" );
1274 const OUString aElemTextFieldId( aOOOElemTextField );
1275 std::vector< std::unique_ptr<TextField> > aFieldSet;
1276
1277 // dummy slide - used as leaving slide for transition on the first slide
1278 if( mbPresentation )
1279 {
1280 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "id", NSPREFIX "meta_dummy_slide" );
1281 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, aOOOAttrSlide, "dummy-slide" );
1282 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, aOOOAttrMaster, "dummy-master-page" );
1285 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, aOOOAttrHasTransition, "false" );
1286 SvXMLElementExport aMetaDummySlideElem( *mpSVGExport, XML_NAMESPACE_NONE, "g", true, true );
1287 }
1288
1289 for( sal_Int32 i = 0; i < nCount; ++i )
1290 {
1291 const Reference< css::drawing::XDrawPage > & xDrawPage = mSelectedPages[i];
1292 Reference< css::drawing::XMasterPageTarget > xMasterPageTarget( xDrawPage, UNO_QUERY );
1293 if (!xMasterPageTarget.is())
1294 continue;
1295 Reference< css::drawing::XDrawPage > xMasterPage = xMasterPageTarget->getMasterPage();
1296 OUString aSlideId(aId + "_" + OUString::number( i ));
1297
1298 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "id", aSlideId );
1301
1302
1303 if( mbPresentation )
1304 {
1305 Reference< XPropertySet > xPropSet( xDrawPage, UNO_QUERY );
1306
1307 if( xPropSet.is() )
1308 {
1309 OUString sDisplayName;
1310 if (xPropSet->getPropertyValue("LinkDisplayName") >>= sDisplayName)
1311 {
1313 }
1314
1315 bool bBackgroundVisibility = true; // default: visible
1316 bool bBackgroundObjectsVisibility = true; // default: visible
1317
1318 FixedDateTimeField aFixedDateTimeField;
1319 VariableDateTimeField aVariableDateTimeField;
1320 FooterField aFooterField;
1321
1322 // check if the slide has a custom background which overlaps the master page background
1323 Reference< XPropertySet > xBackground;
1324 xPropSet->getPropertyValue( "Background" ) >>= xBackground;
1325 if( xBackground.is() )
1326 {
1327 drawing::FillStyle aFillStyle;
1328 bool assigned = ( xBackground->getPropertyValue( "FillStyle" ) >>= aFillStyle );
1329 // has a custom background ?
1330 if( assigned && aFillStyle != drawing::FillStyle_NONE )
1332 }
1333
1334 xPropSet->getPropertyValue( "IsBackgroundVisible" ) >>= bBackgroundVisibility;
1335 // in case the attribute is set to its default value it is not appended to the meta-slide element
1336 if( !bBackgroundVisibility ) // visibility default value: 'visible'
1338
1339 // Page Number, DateTime, Footer and Header Fields are regarded as background objects.
1340 // So bBackgroundObjectsVisibility overrides visibility of master page text fields.
1341 xPropSet->getPropertyValue( "IsBackgroundObjectsVisible" ) >>= bBackgroundObjectsVisibility;
1342 if( bBackgroundObjectsVisibility ) // visibility default value: 'visible'
1343 {
1344 bool bPageNumberVisibility = false; // default: hidden
1345 bool bDateTimeVisibility = true; // default: visible
1346 bool bFooterVisibility = true; // default: visible
1347
1348 // Page Number Field
1349 xPropSet->getPropertyValue( "IsPageNumberVisible" ) >>= bPageNumberVisibility;
1350 bPageNumberVisibility = bPageNumberVisibility && ( nPageNumberingType != css::style::NumberingType::NUMBER_NONE );
1351 if( bPageNumberVisibility ) // visibility default value: 'hidden'
1352 {
1353 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, NSPREFIX "page-number-visibility", "visible" );
1354 }
1355
1356 // DateTime Field
1357 bool bDateTimeFixed = true; // default: fixed
1358 xPropSet->getPropertyValue( "IsDateTimeFixed" ) >>= bDateTimeFixed;
1359 if( bDateTimeFixed ) // we are interested only in the field text not in the date/time format
1360 {
1361 xPropSet->getPropertyValue( "DateTimeText" ) >>= aFixedDateTimeField.text;
1362 if( !aFixedDateTimeField.text.isEmpty() )
1363 {
1364 OUString sFieldId = implGenerateFieldId( aFieldSet, aFixedDateTimeField, aElemTextFieldId, xMasterPage );
1365 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, aOOOAttrDateTimeField, sFieldId );
1366 }
1367 }
1368 else // the inverse applies: we are interested only in the date/time format not in the field text
1369 {
1370 xPropSet->getPropertyValue( "DateTimeFormat" ) >>= aVariableDateTimeField.format;
1371 OUString sFieldId = implGenerateFieldId( aFieldSet, aVariableDateTimeField, aElemTextFieldId, xMasterPage );
1372 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, aOOOAttrDateTimeField, sFieldId );
1373 }
1374 xPropSet->getPropertyValue( "IsDateTimeVisible" ) >>= bDateTimeVisibility;
1375 if( !bDateTimeVisibility ) // visibility default value: 'visible'
1376 {
1377 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, NSPREFIX "date-time-visibility", "hidden" );
1378 }
1379
1380 // Footer Field
1381 xPropSet->getPropertyValue( "FooterText" ) >>= aFooterField.text;
1382 if( !aFooterField.text.isEmpty() )
1383 {
1384 OUString sFieldId = implGenerateFieldId( aFieldSet, aFooterField, aElemTextFieldId, xMasterPage );
1385 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, aOOOAttrFooterField, sFieldId );
1386 }
1387 xPropSet->getPropertyValue( "IsFooterVisible" ) >>= bFooterVisibility;
1388 if( !bFooterVisibility ) // visibility default value: 'visible'
1389 {
1390 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, NSPREFIX "footer-visibility", "hidden" );
1391 }
1392 }
1393 else
1394 {
1396 }
1397
1398 sal_Int32 nChange(0);
1399
1400 if( xPropSet->getPropertySetInfo()->hasPropertyByName( "Change" ) &&
1401 (xPropSet->getPropertyValue( "Change" ) >>= nChange ) && nChange == 1 )
1402 {
1403 double fSlideDuration(0);
1404 if( xPropSet->getPropertySetInfo()->hasPropertyByName( "HighResDuration" ) &&
1405 (xPropSet->getPropertyValue( "HighResDuration" ) >>= fSlideDuration) )
1406 {
1407 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, aOOOAttrSlideDuration, OUString::number(fSlideDuration) );
1408 }
1409 }
1410 // We look for a slide transition.
1411 // Transition properties are exported together with animations.
1412 sal_Int16 nTransitionType(0);
1413 if( xPropSet->getPropertySetInfo()->hasPropertyByName( "TransitionType" ) &&
1414 (xPropSet->getPropertyValue( "TransitionType" ) >>= nTransitionType) )
1415 {
1416 sal_Int16 nTransitionSubType(0);
1417 if( xPropSet->getPropertyValue( "TransitionSubtype" ) >>= nTransitionSubType )
1418 {
1419 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, aOOOAttrHasTransition, "true" );
1420 }
1421 }
1422
1423 }
1424 }
1425
1426 {
1427 SvXMLElementExport aExp2( *mpSVGExport, XML_NAMESPACE_NONE, "g", true, true );
1428 } // when the aExp2 destructor is called the </g> tag is appended to the output file
1429 }
1430
1431 // export text field elements
1432 if( mbPresentation )
1433 {
1434 for( sal_Int32 i = 0, nSize = aFieldSet.size(); i < nSize; ++i )
1435 {
1436 OUString sElemId = OUString::Concat(aOOOElemTextField) + "_" + OUString::number( i );
1437 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "id", sElemId );
1438 aFieldSet[i]->elementExport( mpSVGExport.get() );
1439 }
1440 if( mpSVGExport->IsEmbedFonts() && mpSVGExport->IsUsePositionedCharacters() )
1441 {
1442 for(const std::unique_ptr<TextField>& i : aFieldSet)
1443 {
1444 i->growCharSet( mTextFieldCharSets );
1445 }
1446 }
1447 }
1448
1449 // text fields are used only for generating meta info so we don't need them anymore
1450 aFieldSet.clear();
1451 }
1452}
1453
1454
1456{
1457 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "id", "presentation-animations" );
1458 SvXMLElementExport aDefsContainerElem( *mpSVGExport, XML_NAMESPACE_NONE, "defs", true, true );
1459
1460 for(const uno::Reference<drawing::XDrawPage> & mSelectedPage : mSelectedPages)
1461 {
1462 Reference< XPropertySet > xProps( mSelectedPage, UNO_QUERY );
1463
1464 if( xProps.is() && xProps->getPropertySetInfo()->hasPropertyByName( "TransitionType" ) )
1465 {
1466 sal_Int16 nTransition = 0;
1467 xProps->getPropertyValue( "TransitionType" ) >>= nTransition;
1468 // we have a slide transition ?
1469 bool bHasEffects = ( nTransition != 0 );
1470
1471 Reference< XAnimationNodeSupplier > xAnimNodeSupplier( mSelectedPage, UNO_QUERY );
1472 if( xAnimNodeSupplier.is() )
1473 {
1474 Reference< XAnimationNode > xRootNode = xAnimNodeSupplier->getAnimationNode();
1475 if( xRootNode.is() )
1476 {
1477 if( !bHasEffects )
1478 {
1479 // first check if there are no animations
1480 Reference< XEnumerationAccess > xEnumerationAccess( xRootNode, UNO_QUERY_THROW );
1481 Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_SET_THROW );
1482 if( xEnumeration->hasMoreElements() )
1483 {
1484 // first child node may be an empty main sequence, check this
1485 Reference< XAnimationNode > xMainNode( xEnumeration->nextElement(), UNO_QUERY_THROW );
1486 Reference< XEnumerationAccess > xMainEnumerationAccess( xMainNode, UNO_QUERY_THROW );
1487 Reference< XEnumeration > xMainEnumeration( xMainEnumerationAccess->createEnumeration(), UNO_SET_THROW );
1488
1489 // only export if the main sequence is not empty or if there are additional
1490 // trigger sequences
1491 bHasEffects = xMainEnumeration->hasMoreElements() || xEnumeration->hasMoreElements();
1492 }
1493 }
1494 if( bHasEffects )
1495 {
1496 OUString sId = implGetValidIDFromInterface( mSelectedPage );
1498 sId += "-animations";
1499 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "id", sId );
1500 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "class", "Animations" );
1501 SvXMLElementExport aDefsElem( *mpSVGExport, XML_NAMESPACE_NONE, "defs", true, true );
1502
1504 xAnimationsExporter->prepare( xRootNode );
1505 xAnimationsExporter->exportAnimations( xRootNode );
1506 }
1507 }
1508 }
1509 }
1510 }
1511}
1512
1513
1515{
1517 return;
1518
1519 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "class", "TextShapeIndex" );
1520 SvXMLElementExport aDefsContainerElem( *mpSVGExport, XML_NAMESPACE_NONE, "defs", true, true );
1521
1522 sal_Int32 nCount = mSelectedPages.size();
1523 for( sal_Int32 i = 0; i < nCount; ++i )
1524 {
1525 const Reference< css::drawing::XDrawPage > & xDrawPage = mSelectedPages[i];
1526 if( mTextShapeIdListMap.find( xDrawPage ) != mTextShapeIdListMap.end() )
1527 {
1528 OUString sTextShapeIdList = mTextShapeIdListMap[xDrawPage].trim();
1529
1530 const OUString& rPageId = implGetValidIDFromInterface( Reference<XInterface>(xDrawPage, UNO_QUERY) );
1531 if( !rPageId.isEmpty() && !sTextShapeIdList.isEmpty() )
1532 {
1533 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, aOOOAttrSlide, rPageId );
1534 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, NSPREFIX "id-list", sTextShapeIdList );
1535 SvXMLElementExport aGElem( *mpSVGExport, XML_NAMESPACE_NONE, "g", true, true );
1536 }
1537 }
1538 }
1539}
1540
1541
1543{
1544 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "class", "EmbeddedBulletChars" );
1545 SvXMLElementExport aDefsContainerElem( *mpSVGExport, XML_NAMESPACE_NONE, "defs", true, true );
1546
1547 OUString sPathData = "M 580,1141 L 1163,571 580,0 -4,571 580,1141 Z";
1548 implEmbedBulletGlyph( 57356, sPathData );
1549 sPathData = "M 8,1128 L 1137,1128 1137,0 8,0 8,1128 Z";
1550 implEmbedBulletGlyph( 57354, sPathData );
1551 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";
1552 implEmbedBulletGlyph( 10146, sPathData );
1553 sPathData = "M 2015,739 L 1276,0 717,0 1260,543 174,543 174,936 1260,936 717,1481 1274,1481 2015,739 Z";
1554 implEmbedBulletGlyph( 10132, sPathData );
1555 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";
1556 implEmbedBulletGlyph( 10007, sPathData );
1557 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";
1558 implEmbedBulletGlyph( 10004, sPathData );
1559 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";
1560 implEmbedBulletGlyph( 9679, sPathData );
1561 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";
1562 implEmbedBulletGlyph( 8226, sPathData );
1563 sPathData = "M -4,459 L 1135,459 1135,606 -4,606 -4,459 Z";
1564 implEmbedBulletGlyph( 8211, sPathData );
1565 sPathData = "M 173,740 C 173,903 231,1043 346,1159 462,1274 601,1332 765,1332 928,1332 1067,1274 1183,1159 1299,1043 1357,903 1357,740 1357,577 1299,437 1183,322 1067,206 928,148 765,148 601,148 462,206 346,322 231,437 173,577 173,740 Z";
1566 implEmbedBulletGlyph( 61548, sPathData );
1567}
1568
1569
1570void SVGFilter::implEmbedBulletGlyph( sal_Unicode cBullet, const OUString & sPathData )
1571{
1572 OUString sId = "bullet-char-template-" + OUString::number( static_cast<sal_Int32>(cBullet) );
1573 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "id", sId );
1574
1575 OUString sFactor = OUString::number( 1.0 / 2048 );
1576 OUString sTransform = "scale(" + sFactor + ",-" + sFactor + ")";
1577 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "transform", sTransform );
1578
1579 SvXMLElementExport aGElem( *mpSVGExport, XML_NAMESPACE_NONE, "g", true, true );
1580
1581 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "d", sPathData );
1582 SvXMLElementExport aPathElem( *mpSVGExport, XML_NAMESPACE_NONE, "path", true, true );
1583
1584 mpSVGExport->SetEmbeddedBulletGlyph(cBullet);
1585}
1586
1588{
1589 if (maBitmapActionMap.empty())
1590 return;
1591
1592 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "class", "BackgroundBitmaps" );
1593 SvXMLElementExport aDefsContainerElem( *mpSVGExport, XML_NAMESPACE_NONE, "defs", true, true );
1594
1595 OUString sId;
1596 for( const auto& rItem : maBitmapActionMap )
1597 {
1598 BitmapChecksum nChecksum = rItem.first;
1599 const GDIMetaFile& aEmbeddedBitmapMtf = *(rItem.second);
1600 MetaAction* pBitmapAction = aEmbeddedBitmapMtf.GetAction( 0 );
1601 if( pBitmapAction )
1602 {
1603 sId = "bitmap(" + OUString::number( nChecksum ) + ")";
1604 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "id", sId );
1605
1606 const Point aPos; // (0, 0)
1607 const Size aSize = aEmbeddedBitmapMtf.GetPrefSize();
1608 mpSVGWriter->WriteMetaFile( aPos, aSize, aEmbeddedBitmapMtf, 0xffffffff );
1609 }
1610 }
1611}
1612
1614{
1615 if( maPatterProps.empty() )
1616 return;
1617
1618 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "class", "BackgroundPatterns" );
1619 SvXMLElementExport aDefsContainerElem( *mpSVGExport, XML_NAMESPACE_NONE, "defs", true, true );
1620
1621 for( const auto& [ rSlideId, rData ] : maPatterProps )
1622 {
1623 auto aBitmapActionIt = maBitmapActionMap.find( rData.aBitmapChecksum );
1624 if( aBitmapActionIt != maBitmapActionMap.end() )
1625 {
1626 // pattern element attributes
1627 const OUString sPatternId = getPatternIdForTiledBackground( rSlideId, rData.aBitmapChecksum );
1628 // <pattern> <use>
1629 {
1630 // pattern element attributes
1631 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "id", sPatternId );
1632
1633 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "x", OUString::number( rData.aPos.X() ) );
1634 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "y", OUString::number( rData.aPos.Y() ) );
1635 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "width", OUString::number( rData.aSize.Width() ) );
1636 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "height", OUString::number( rData.aSize.Height() ) );
1637 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "patternUnits", "userSpaceOnUse" );
1638
1639 SvXMLElementExport aPatternElem( *mpSVGExport, XML_NAMESPACE_NONE, "pattern", true, true );
1640
1641 // use element attributes
1642 const Size& aOrigSize = aBitmapActionIt->second->GetPrefSize();
1643 OUString sTransform;
1644 Fraction aFractionX( rData.aSize.Width(), aOrigSize.Width() );
1645 Fraction aFractionY( rData.aSize.Height(), aOrigSize.Height() );
1646 double scaleX = rtl_math_round( double(aFractionX), 3, rtl_math_RoundingMode::rtl_math_RoundingMode_Corrected );
1647 double scaleY = rtl_math_round( double(aFractionY), 3, rtl_math_RoundingMode::rtl_math_RoundingMode_Corrected );
1648 if( !rtl_math_approxEqual( scaleX, 1.0 ) || !rtl_math_approxEqual( scaleY, 1.0 ) )
1649 sTransform += " scale(" + OUString::number( double(aFractionX) ) + ", " + OUString::number( double(aFractionY) ) + ")";
1650
1651 if( !sTransform.isEmpty() )
1652 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "transform", sTransform );
1653
1654 // referenced bitmap
1655 OUString sRefId = "#bitmap(" + OUString::number( rData.aBitmapChecksum ) + ")";
1656 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "xlink:href", sRefId );
1657
1658 SvXMLElementExport aUseElem( *mpSVGExport, XML_NAMESPACE_NONE, "use", true, true );
1659 } // </use> </pattern>
1660
1661 // <g> <rect>
1662 {
1663 // group
1664 const OUString sBgId = getIdForTiledBackground( rSlideId, rData.aBitmapChecksum );
1665 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "id", sBgId );
1666
1667 SvXMLElementExport aGroupElem( *mpSVGExport, XML_NAMESPACE_NONE, "g", true, true );
1668
1669 // rectangle
1670 const OUString sUrl = "url(#" + sPatternId + ")";
1671 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "x", "0" );
1672 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "y", "0" );
1673 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "width", OUString::number( rData.aSlideSize.Width() ) );
1674 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "height", OUString::number( rData.aSlideSize.Height() ) );
1675 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "stroke", "none" );
1676 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "fill", sUrl );
1677
1678 SvXMLElementExport aRectElem( *mpSVGExport, XML_NAMESPACE_NONE, "rect", true, true );
1679 } // </g> </rect>
1680 }
1681 }
1682}
1683
1689{
1690 if (mEmbeddedBitmapActionSet.empty())
1691 return;
1692
1693 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "class", "TextEmbeddedBitmaps" );
1694 SvXMLElementExport aDefsContainerElem( *mpSVGExport, XML_NAMESPACE_NONE, "defs", true, true );
1695
1696 OUString sId;
1697
1698 for (auto const& embeddedBitmapAction : mEmbeddedBitmapActionSet)
1699 {
1700 const GDIMetaFile& aMtf = embeddedBitmapAction.GetRepresentation();
1701
1702 if( aMtf.GetActionSize() == 1 )
1703 {
1704 MetaAction* pAction = aMtf.GetAction( 0 );
1705 if( pAction )
1706 {
1707 BitmapChecksum nId = GetBitmapChecksum( pAction );
1708 sId = "bitmap(" + OUString::number( nId ) + ")";
1709 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "id", sId );
1710
1711 const Reference< XInterface >& rxShape = embeddedBitmapAction.GetObject();
1712 Reference< XPropertySet > xShapePropSet( rxShape, UNO_QUERY );
1713 css::awt::Rectangle aBoundRect;
1714 if( xShapePropSet.is() && ( xShapePropSet->getPropertyValue( "BoundRect" ) >>= aBoundRect ) )
1715 {
1716 // Origin of the coordinate device must be (0,0).
1717 const Point aTopLeft;
1718 const Size aSize( aBoundRect.Width, aBoundRect.Height );
1719
1720 Point aPt;
1721 MetaBitmapActionGetPoint( pAction, aPt );
1722 // The image must be exported with x, y attribute set to 0,
1723 // on the contrary when referenced by a <use> element,
1724 // specifying the wanted position, they will result
1725 // misplaced.
1726 pAction->Move( -aPt.X(), -aPt.Y() );
1727 mpSVGWriter->WriteMetaFile( aTopLeft, aSize, aMtf, 0xffffffff );
1728 // We reset to the original values so that when the <use>
1729 // element is created the x, y attributes are correct.
1730 pAction->Move( aPt.X(), aPt.Y() );
1731 }
1732 else
1733 {
1734 OSL_FAIL( "implExportTextEmbeddedBitmaps: no shape bounding box." );
1735 return;
1736 }
1737 }
1738 else
1739 {
1740 OSL_FAIL( "implExportTextEmbeddedBitmaps: metafile should have MetaBmpExScaleAction only." );
1741 return;
1742 }
1743 }
1744 else
1745 {
1746 OSL_FAIL( "implExportTextEmbeddedBitmaps: metafile should have a single action." );
1747 return;
1748 }
1749 }
1750}
1751
1753{
1754 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "type", "text/ecmascript" );
1755
1756 {
1757 SvXMLElementExport aExp( *mpSVGExport, XML_NAMESPACE_NONE, "script", true, true );
1758 Reference< XExtendedDocumentHandler > xExtDocHandler( mpSVGExport->GetDocHandler(), UNO_QUERY );
1759
1760 if( xExtDocHandler.is() )
1761 {
1762 for (size_t i = 0; i < N_SVGSCRIPT_FRAGMENTS; ++i)
1763 {
1764 xExtDocHandler->unknown(OUString::createFromAscii(g_SVGScripts[i]));
1765 }
1766 }
1767 }
1768}
1769
1770
1771Any SVGFilter::implSafeGetPagePropSet( const OUString & sPropertyName,
1772 const Reference< XPropertySet > & rxPropSet,
1773 const Reference< XPropertySetInfo > & rxPropSetInfo )
1774{
1775 Any result;
1776 if( rxPropSetInfo->hasPropertyByName( sPropertyName ) )
1777 {
1778 result = rxPropSet->getPropertyValue( sPropertyName );
1779 }
1780 return result;
1781}
1782
1783
1787void SVGFilter::implGetPagePropSet( const Reference< css::drawing::XDrawPage > & rxPage )
1788{
1796 mVisiblePagePropSet.nDateTimeFormat = SvxDateFormat::B;
1797 mVisiblePagePropSet.nPageNumberingType = css::style::NumberingType::ARABIC;
1798
1799 // We collect info on master page elements visibility, and placeholder text shape content.
1800 Reference< XPropertySet > xPropSet( rxPage, UNO_QUERY );
1801 if( !xPropSet.is() )
1802 return;
1803
1804 Reference< XPropertySetInfo > xPropSetInfo( xPropSet->getPropertySetInfo() );
1805 if( !xPropSetInfo.is() )
1806 return;
1807
1808 implSafeGetPagePropSet( "IsBackgroundVisible", xPropSet, xPropSetInfo ) >>= mVisiblePagePropSet.bIsBackgroundVisible;
1809 implSafeGetPagePropSet( "IsBackgroundObjectsVisible", xPropSet, xPropSetInfo ) >>= mVisiblePagePropSet.bAreBackgroundObjectsVisible;
1810 implSafeGetPagePropSet( "IsPageNumberVisible", xPropSet, xPropSetInfo ) >>= mVisiblePagePropSet.bIsPageNumberFieldVisible;
1811 implSafeGetPagePropSet( "IsHeaderVisible", xPropSet, xPropSetInfo ) >>= mVisiblePagePropSet.bIsHeaderFieldVisible;
1812 implSafeGetPagePropSet( "IsFooterVisible", xPropSet, xPropSetInfo ) >>= mVisiblePagePropSet.bIsFooterFieldVisible;
1813 implSafeGetPagePropSet( "IsDateTimeVisible", xPropSet, xPropSetInfo ) >>= mVisiblePagePropSet.bIsDateTimeFieldVisible;
1814
1815 implSafeGetPagePropSet( "IsDateTimeFixed", xPropSet, xPropSetInfo ) >>= mVisiblePagePropSet.bIsDateTimeFieldFixed;
1816 sal_Int32 nTmp;
1817 if (implSafeGetPagePropSet( "DateTimeFormat", xPropSet, xPropSetInfo ) >>= nTmp)
1819
1821 {
1822 SvxDrawPage* pSvxDrawPage = comphelper::getFromUnoTunnel<SvxDrawPage>( rxPage );
1823 if( pSvxDrawPage )
1824 {
1825 SdrPage* pSdrPage = pSvxDrawPage->GetSdrPage();
1826 SdrModel& rSdrModel(pSdrPage->getSdrModelFromSdrPage());
1828 }
1829 }
1830}
1831
1832
1833bool SVGFilter::implExportMasterPages( const std::vector< Reference< css::drawing::XDrawPage > > & rxPages,
1834 sal_Int32 nFirstPage, sal_Int32 nLastPage )
1835{
1836 DBG_ASSERT( nFirstPage <= nLastPage,
1837 "SVGFilter::implExportMasterPages: nFirstPage > nLastPage" );
1838
1839 // When the exported slides are more than one we wrap master page elements
1840 // with a svg <defs> element.
1841 OUString aContainerTag = (!mbPresentation) ? OUString( "g" ) : OUString( "defs" );
1842 SvXMLElementExport aContainerElement( *mpSVGExport, XML_NAMESPACE_NONE, aContainerTag, true, true );
1843
1844 // dummy slide - used as leaving slide for transition on the first slide
1845 if( mbPresentation )
1846 {
1847 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "id", "dummy-master-page" );
1848 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, aOOOAttrName, "dummy-master-page" );
1849 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "class", "Master_Slide" );
1850 SvXMLElementExport aMasterSlideElem( *mpSVGExport, XML_NAMESPACE_NONE, "g", true, true );
1851 {
1852 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "id", "bg-dummy-master-page" );
1853 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "class", "Background" );
1854 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "visibility", "hidden" );
1855 SvXMLElementExport aBackgroundElem( *mpSVGExport, XML_NAMESPACE_NONE, "g", true, true );
1856 }
1857 {
1858 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "id", "bo-dummy-master-page" );
1859 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "class", "BackgroundObjects" );
1860 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "visibility", "hidden" );
1861 SvXMLElementExport aBackgroundObjectElem( *mpSVGExport, XML_NAMESPACE_NONE, "g", true, true );
1862 }
1863 }
1864
1865 bool bRet = false;
1866 for( sal_Int32 i = nFirstPage; i <= nLastPage; ++i )
1867 {
1868 if( rxPages[i].is() )
1869 {
1870 // add id attribute
1871 const OUString & sPageId = implGetValidIDFromInterface( rxPages[i] );
1872 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "id", sPageId );
1873
1874 bRet = implExportPage( sPageId, rxPages[i], rxPages[i], true /* is a master page */ ) || bRet;
1875 }
1876 }
1877 return bRet;
1878}
1879
1880
1881void SVGFilter::implExportDrawPages( const std::vector< Reference< css::drawing::XDrawPage > > & rxPages,
1882 sal_Int32 nFirstPage, sal_Int32 nLastPage )
1883{
1884 DBG_ASSERT( nFirstPage <= nLastPage,
1885 "SVGFilter::implExportDrawPages: nFirstPage > nLastPage" );
1886
1887 // dummy slide - used as leaving slide for transition on the first slide
1889 {
1890 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "class", "DummySlide" );
1891 SvXMLElementExport aDummySlideElement( *mpSVGExport, XML_NAMESPACE_NONE, "g", true, true );
1892 {
1893 SvXMLElementExport aGElement( *mpSVGExport, XML_NAMESPACE_NONE, "g", true, true );
1894 {
1895 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "id", "dummy-slide" );
1896 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "class", "Slide" );
1897 OUString sClipPathAttrValue = "url(#" + msClipPathId + ")";
1898 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "clip-path", sClipPathAttrValue );
1899 SvXMLElementExport aSlideElement( *mpSVGExport, XML_NAMESPACE_NONE, "g", true, true );
1900 {
1901 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, aOOOAttrName, "dummy-page" );
1902 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "class", "Page" );
1903 SvXMLElementExport aPageElement( *mpSVGExport, XML_NAMESPACE_NONE, "g", true, true );
1904 }
1905 }
1906 }
1907 }
1908
1910 {
1911 // We wrap all slide in a group element with class name "SlideGroup".
1912 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "class", "SlideGroup" );
1913 SvXMLElementExport aExp( *mpSVGExport, XML_NAMESPACE_NONE, "g", true, true );
1914
1915 for( sal_Int32 i = nFirstPage; i <= nLastPage; ++i )
1916 {
1917 Reference< css::drawing::XShapes > xShapes;
1918
1920 {
1921 // #i124608# export a given object selection
1922 xShapes = maShapeSelection;
1923 }
1924 else
1925 {
1926 xShapes = rxPages[i];
1927 }
1928
1929 if( xShapes.is() )
1930 {
1931 // Insert the <g> open tag related to the svg element for
1932 // handling a slide visibility.
1933 // In case the exported slides are more than one the initial
1934 // visibility of each slide is set to 'hidden'.
1935 if( mbPresentation )
1936 {
1937 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "visibility", "hidden" );
1938 }
1939 SvXMLElementExport aGElement( *mpSVGExport, XML_NAMESPACE_NONE, "g", true, true );
1940
1941
1942 {
1943 // Insert a further inner the <g> open tag for handling elements
1944 // inserted before or after a slide: that is used for some
1945 // when switching from the last to the first slide.
1946 const OUString & sPageId = implGetValidIDFromInterface( rxPages[i] );
1947 OUString sContainerId = "container-" + sPageId;
1948 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "id", sContainerId );
1949 SvXMLElementExport aContainerExp( *mpSVGExport, XML_NAMESPACE_NONE, "g", true, true );
1950
1951 {
1952 // add id attribute
1953 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "id", sPageId );
1954
1955 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "class", "Slide" );
1956
1957 // Adding a clip path to each exported slide , so in case
1958 // bitmaps or other elements exceed the slide margins, they are
1959 // trimmed, even when they are shown inside a thumbnail view.
1960 OUString sClipPathAttrValue = "url(#" + msClipPathId + ")";
1961 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "clip-path", sClipPathAttrValue );
1962
1963 SvXMLElementExport aSlideElement( *mpSVGExport, XML_NAMESPACE_NONE, "g", true, true );
1964
1965 implExportPage( sPageId, rxPages[i], xShapes, false /* is not a master page */ );
1966 }
1967 } // append the </g> closing tag related to inserted elements
1968 } // append the </g> closing tag related to the svg element handling the slide visibility
1969 }
1970 }
1971 else
1972 {
1973 assert(maShapeSelection.is());
1974 assert(rxPages.size() == 1);
1975
1976 const OUString & sPageId = implGetValidIDFromInterface( rxPages[0] );
1977 implExportPage( sPageId, rxPages[0], maShapeSelection, false /* is not a master page */ );
1978 }
1979}
1980
1981
1982bool SVGFilter::implExportPage( std::u16string_view sPageId,
1983 const Reference< css::drawing::XDrawPage > & rxPage,
1984 const Reference< css::drawing::XShapes > & xShapes,
1985 bool bMaster )
1986{
1987 bool bRet = false;
1988
1989 {
1990 OUString sPageName = implGetInterfaceName( rxPage );
1991 if( mbPresentation && !sPageName.isEmpty() )
1992 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, aOOOAttrName, sPageName );
1993
1994 {
1995 Reference< XExtendedDocumentHandler > xExtDocHandler( mpSVGExport->GetDocHandler(), UNO_QUERY );
1996
1997 if( xExtDocHandler.is() )
1998 {
1999 OUString aDesc;
2000
2001 if( bMaster )
2002 aDesc = "Master_Slide";
2003 else
2004 aDesc = "Page";
2005
2006 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "class", aDesc );
2007 }
2008 }
2009
2010 // insert the <g> open tag related to the DrawPage/MasterPage
2011 SvXMLElementExport aExp( *mpSVGExport, XML_NAMESPACE_NONE, "g", true, true );
2012
2013 // In case the page has a background object we append it .
2014 if( mpObjects->find( rxPage ) != mpObjects->end() )
2015 {
2016 const GDIMetaFile& rMtf = (*mpObjects)[ rxPage ].GetRepresentation();
2017 if( rMtf.GetActionSize() )
2018 {
2019 // If this is not a master page wrap the slide custom background
2020 // by a <defs> element.
2021 // Slide custom background, if any, is referenced at a different position
2022 // in order to not overlap background objects.
2023 std::unique_ptr<SvXMLElementExport> xDefsExp;
2024 if (!bMaster) // insert the <defs> open tag related to the slide background
2025 {
2026 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "class", "SlideBackground" );
2027 xDefsExp.reset( new SvXMLElementExport( *mpSVGExport, XML_NAMESPACE_NONE, "defs", true, true ) );
2028 }
2029 {
2030 // background id = "bg-" + page id
2031 OUString sBackgroundId = OUString::Concat("bg-") + sPageId;
2032 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "id", sBackgroundId );
2033
2034 // At present (LibreOffice 3.4.0) the 'IsBackgroundVisible' property is not handled
2035 // by Impress; anyway we handle this property as referring only to the visibility
2036 // of the master page background. So if a slide has its own background object,
2037 // the visibility of such a background object is always inherited from the visibility
2038 // of the parent slide regardless of the value of the 'IsBackgroundVisible' property.
2039 // This means that we need to set up the visibility attribute only for the background
2040 // element of a master page.
2041 if( !mbPresentation && bMaster )
2042 {
2044 {
2045 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "visibility", "hidden" );
2046 }
2047 }
2048
2049 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "class", "Background" );
2050
2051 // insert the <g> open tag related to the Background
2052 SvXMLElementExport aExp2( *mpSVGExport, XML_NAMESPACE_NONE, "g", true, true );
2053
2054 // append all elements that make up the Background
2055 const Point aNullPt;
2056 mpSVGWriter->WriteMetaFile( aNullPt, rMtf.GetPrefSize(), rMtf, SVGWRITER_WRITE_FILL );
2057 } // insert the </g> closing tag related to the Background
2058
2059 } // insert the </defs> closing tag related to the slide background
2060 }
2061
2062 // In case we are dealing with a master page we need to group all its shapes
2063 // into a group element, this group will make up the so named "background objects"
2064 if( bMaster )
2065 {
2066 // background objects id = "bo-" + page id
2067 OUString sBackgroundObjectsId = OUString::Concat("bo-") + sPageId;
2068 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "id", sBackgroundObjectsId );
2069 if( !mbPresentation )
2070 {
2072 {
2073 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "visibility", "hidden" );
2074 }
2075 }
2076 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "class", "BackgroundObjects" );
2077
2078 // insert the <g> open tag related to the Background Objects
2079 SvXMLElementExport aExp2( *mpSVGExport, XML_NAMESPACE_NONE, "g", true, true );
2080
2081 // append all shapes that make up the Master Slide
2082 bRet = implExportShapes( xShapes, true ) || bRet;
2083 } // append the </g> closing tag related to the Background Objects
2084 else
2085 {
2086 // append all shapes that make up the Slide
2087 bRet = implExportShapes( xShapes, false ) || bRet;
2088 }
2089 } // append the </g> closing tag related to the Slide/Master_Slide
2090
2091 return bRet;
2092}
2093
2094
2095bool SVGFilter::implExportShapes( const Reference< css::drawing::XShapes >& rxShapes, bool bMaster )
2096{
2097 Reference< css::drawing::XShape > xShape;
2098 bool bRet = false;
2099
2100 for( sal_Int32 i = 0, nCount = rxShapes->getCount(); i < nCount; ++i )
2101 {
2102 if( ( rxShapes->getByIndex( i ) >>= xShape ) && xShape.is() )
2103 bRet = implExportShape( xShape, bMaster ) || bRet;
2104
2105 xShape = nullptr;
2106 }
2107
2108 return bRet;
2109}
2110
2111
2112bool SVGFilter::implExportShape( const Reference< css::drawing::XShape >& rxShape, bool bMaster )
2113{
2114 Reference< XPropertySet > xShapePropSet( rxShape, UNO_QUERY );
2115 bool bRet = false;
2116
2117 if( xShapePropSet.is() )
2118 {
2119 const OUString aShapeType( rxShape->getShapeType() );
2120 bool bHideObj = false;
2121
2122 if( mbPresentation )
2123 {
2124 xShapePropSet->getPropertyValue( "IsEmptyPresentationObject" ) >>= bHideObj;
2125 }
2126
2127 OUString aShapeClass = implGetClassFromShape( rxShape );
2128 if( bMaster )
2129 {
2130 if( aShapeClass == "TitleText" || aShapeClass == "Outline" )
2131 bHideObj = true;
2132 }
2133
2134 if( !bHideObj )
2135 {
2136 if( aShapeType.lastIndexOf( "drawing.GroupShape" ) != -1 )
2137 {
2138 Reference< css::drawing::XShapes > xShapes( rxShape, UNO_QUERY );
2139
2140 if( xShapes.is() )
2141 {
2142 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "class", "Group" );
2143 const OUString& rShapeId = implGetValidIDFromInterface( Reference<XInterface>(rxShape, UNO_QUERY) );
2144 if( !rShapeId.isEmpty() )
2145 {
2146 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "id", rShapeId );
2147 }
2148 SvXMLElementExport aExp( *mpSVGExport, XML_NAMESPACE_NONE, "g", true, true );
2149
2150 bRet = implExportShapes( xShapes, bMaster );
2151 }
2152 }
2153
2154 if( !bRet && mpObjects->find( rxShape ) != mpObjects->end() )
2155 {
2156 css::awt::Rectangle aBoundRect;
2157 const GDIMetaFile& rMtf = (*mpObjects)[ rxShape ].GetRepresentation();
2158
2159 xShapePropSet->getPropertyValue( "BoundRect" ) >>= aBoundRect;
2160
2161 const Point aTopLeft( aBoundRect.X, aBoundRect.Y );
2162 const Size aSize( aBoundRect.Width, aBoundRect.Height );
2163
2164 if( rMtf.GetActionSize() )
2165 { // for text field shapes we set up text-adjust attributes
2166 // and set visibility to hidden
2167 OUString aElementId;
2168
2169 if( mbPresentation )
2170 {
2171 bool bIsPageNumber = ( aShapeClass == "PageNumber" );
2172 bool bIsFooter = ( aShapeClass == "Footer" );
2173 bool bIsDateTime = ( aShapeClass == "DateTime" );
2174 bool bTextField = bIsPageNumber || bIsFooter || bIsDateTime;
2175 if( bTextField )
2176 {
2177 // to notify to the SVGActionWriter::ImplWriteActions method
2178 // that we are dealing with a placeholder shape
2179 aElementId = sPlaceholderTag;
2180
2181 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "visibility", "hidden" );
2182 }
2183
2184 if( bTextField || ( aShapeClass == "TextShape" ) )
2185 {
2186 sal_uInt16 nTextAdjust = sal_uInt16(ParagraphAdjust_LEFT);
2187 OUString sTextAdjust;
2188 xShapePropSet->getPropertyValue( "ParaAdjust" ) >>= nTextAdjust;
2189
2190 switch( static_cast<ParagraphAdjust>(nTextAdjust) )
2191 {
2192 case ParagraphAdjust_LEFT:
2193 sTextAdjust = "left";
2194 break;
2195 case ParagraphAdjust_CENTER:
2196 sTextAdjust = "center";
2197 break;
2198 case ParagraphAdjust_RIGHT:
2199 sTextAdjust = "right";
2200 break;
2201 default:
2202 break;
2203 }
2204 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, NSPREFIX "text-adjust", sTextAdjust );
2205 }
2206 }
2207 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "class", aShapeClass );
2208 SvXMLElementExport aExp( *mpSVGExport, XML_NAMESPACE_NONE, "g", true, true );
2209
2210 Reference< XExtendedDocumentHandler > xExtDocHandler( mpSVGExport->GetDocHandler(), UNO_QUERY );
2211
2212 OUString aTitle;
2213 xShapePropSet->getPropertyValue( "Title" ) >>= aTitle;
2214 if( !aTitle.isEmpty() )
2215 {
2216 SvXMLElementExport aExp2( *mpSVGExport, XML_NAMESPACE_NONE, "title", true, true );
2217 xExtDocHandler->characters( aTitle );
2218 }
2219
2220 OUString aDescription;
2221 xShapePropSet->getPropertyValue( "Description" ) >>= aDescription;
2222 if( !aDescription.isEmpty() )
2223 {
2224 SvXMLElementExport aExp2( *mpSVGExport, XML_NAMESPACE_NONE, "desc", true, true );
2225 xExtDocHandler->characters( aDescription );
2226 }
2227
2228
2229 const OUString& rShapeId = implGetValidIDFromInterface( Reference<XInterface>(rxShape, UNO_QUERY) );
2230 if( !rShapeId.isEmpty() )
2231 {
2232 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "id", rShapeId );
2233 }
2234
2235 const GDIMetaFile* pEmbeddedBitmapsMtf = nullptr;
2236 if( mEmbeddedBitmapActionMap.find( rxShape ) != mEmbeddedBitmapActionMap.end() )
2237 {
2238 pEmbeddedBitmapsMtf = &( mEmbeddedBitmapActionMap[ rxShape ].GetRepresentation() );
2239 }
2240
2241 {
2242 OUString aBookmark;
2243 Reference<XPropertySetInfo> xShapePropSetInfo = xShapePropSet->getPropertySetInfo();
2244 if(xShapePropSetInfo->hasPropertyByName("Bookmark"))
2245 {
2246 xShapePropSet->getPropertyValue( "Bookmark" ) >>= aBookmark;
2247 }
2248
2249 SvXMLElementExport aExp2( *mpSVGExport, XML_NAMESPACE_NONE, "g", true, true );
2250
2251 // export the shape bounding box
2252 {
2253 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "class", "BoundingBox" );
2254 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "stroke", "none" );
2255 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "fill", "none" );
2256 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "x", OUString::number( aBoundRect.X ) );
2257 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "y", OUString::number( aBoundRect.Y ) );
2258 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "width", OUString::number( aBoundRect.Width ) );
2259 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "height", OUString::number( aBoundRect.Height ) );
2260 SvXMLElementExport aBB( *mpSVGExport, XML_NAMESPACE_NONE, "rect", true, true );
2261 }
2262
2263 if( !aBookmark.isEmpty() )
2264 {
2265 INetURLObject aINetURLObject(aBookmark);
2266 if (!aINetURLObject.HasError()
2267 && aINetURLObject.GetProtocol() != INetProtocol::Javascript)
2268 {
2269 mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "xlink:href", aBookmark);
2270 SvXMLElementExport alinkA( *mpSVGExport, XML_NAMESPACE_NONE, "a", true, true );
2271 mpSVGWriter->WriteMetaFile( aTopLeft, aSize, rMtf,
2272 0xffffffff,
2273 aElementId,
2274 &rxShape,
2275 pEmbeddedBitmapsMtf );
2276 }
2277 }
2278 else
2279 {
2280 mpSVGWriter->WriteMetaFile( aTopLeft, aSize, rMtf,
2281 0xffffffff,
2282 aElementId,
2283 &rxShape,
2284 pEmbeddedBitmapsMtf );
2285 }
2286 }
2287 }
2288
2289 bRet = true;
2290 }
2291 }
2292 }
2293
2294 return bRet;
2295}
2296
2297
2299{
2301 {
2302 // #i124608# export a given object selection
2303 if (!mSelectedPages.empty() && mSelectedPages[0].is())
2304 {
2306 return true;
2307 }
2308 return false;
2309 }
2310
2311 sal_Int32 i, nCount;
2312
2313 for( i = 0, nCount = mMasterPageTargets.size(); i < nCount; ++i )
2314 {
2315 const Reference< css::drawing::XDrawPage > & xMasterPage = mMasterPageTargets[i];
2316
2317 if( xMasterPage.is() )
2318 {
2319 mCreateOjectsCurrentMasterPage = xMasterPage;
2320 implCreateObjectsFromBackground( xMasterPage );
2321
2322 if( xMasterPage.is() )
2323 implCreateObjectsFromShapes( xMasterPage, xMasterPage );
2324 }
2325 }
2326
2327 for( i = 0, nCount = mSelectedPages.size(); i < nCount; ++i )
2328 {
2329 const Reference< css::drawing::XDrawPage > & xDrawPage = mSelectedPages[i];
2330
2331 if( xDrawPage.is() )
2332 {
2333 // TODO complete the implementation for exporting custom background for each slide
2334 // implementation status:
2335 // - hatch stroke color is set to 'none' so the hatch is not visible, why?
2336 // - gradient look is not really awesome, too few colors are used;
2337 // - gradient and hatch are not exported only once
2338 // and then referenced in case more than one slide uses them.
2339 Reference< XPropertySet > xPropSet( xDrawPage, UNO_QUERY );
2340 if( xPropSet.is() )
2341 {
2342 Reference< XPropertySet > xBackground;
2343 if (xPropSet->getPropertySetInfo()->hasPropertyByName("Background"))
2344 xPropSet->getPropertyValue( "Background" ) >>= xBackground;
2345 if( xBackground.is() )
2346 {
2347 drawing::FillStyle aFillStyle;
2348 bool assigned = ( xBackground->getPropertyValue( "FillStyle" ) >>= aFillStyle );
2349 if( assigned && aFillStyle != drawing::FillStyle_NONE )
2350 {
2352 }
2353 }
2354 }
2355 implCreateObjectsFromShapes( xDrawPage, xDrawPage );
2356 }
2357 }
2358 return true;
2359}
2360
2361
2362bool SVGFilter::implCreateObjectsFromShapes( const Reference< css::drawing::XDrawPage > & rxPage, const Reference< css::drawing::XShapes >& rxShapes )
2363{
2364 Reference< css::drawing::XShape > xShape;
2365 bool bRet = false;
2366
2367 for( sal_Int32 i = 0, nCount = rxShapes->getCount(); i < nCount; ++i )
2368 {
2369 if( ( rxShapes->getByIndex( i ) >>= xShape ) && xShape.is() )
2370 bRet = implCreateObjectsFromShape( rxPage, xShape ) || bRet;
2371
2372 xShape = nullptr;
2373 }
2374
2375 return bRet;
2376}
2377
2378
2379bool SVGFilter::implCreateObjectsFromShape( const Reference< css::drawing::XDrawPage > & rxPage, const Reference< css::drawing::XShape >& rxShape )
2380{
2381 bool bRet = false;
2382 if( rxShape->getShapeType().lastIndexOf( "drawing.GroupShape" ) != -1 )
2383 {
2384 Reference< css::drawing::XShapes > xShapes( rxShape, UNO_QUERY );
2385
2386 if( xShapes.is() )
2387 bRet = implCreateObjectsFromShapes( rxPage, xShapes );
2388 }
2389 else
2390 {
2392
2393 if( pObj )
2394 {
2395 // tdf#155479 need to signal SVG export
2396 Graphic aGraphic(SdrExchangeView::GetObjGraphic(*pObj, true));
2397
2398 // Writer graphic shapes are handled differently
2399 if( mbWriterFilter && aGraphic.GetType() == GraphicType::NONE )
2400 {
2401 if (rxShape->getShapeType() == "com.sun.star.drawing.GraphicObjectShape")
2402 {
2403 uno::Reference<beans::XPropertySet> xPropertySet(rxShape, uno::UNO_QUERY);
2404 uno::Reference<graphic::XGraphic> xGraphic;
2405 xPropertySet->getPropertyValue("Graphic") >>= xGraphic;
2406
2407 if (!xGraphic.is())
2408 return false;
2409
2410 aGraphic = Graphic(xGraphic);
2411 }
2412 }
2413
2414 if( aGraphic.GetType() != GraphicType::NONE )
2415 {
2416 if( aGraphic.GetType() == GraphicType::Bitmap )
2417 {
2418 GDIMetaFile aMtf;
2419 const Point aNullPt;
2420 const Size aSize( pObj->GetCurrentBoundRect().GetSize() );
2421
2422 aMtf.AddAction( new MetaBmpExScaleAction( aNullPt, aSize, aGraphic.GetBitmapEx() ) );
2423 aMtf.SetPrefSize( aSize );
2424 aMtf.SetPrefMapMode(MapMode(MapUnit::Map100thMM));
2425
2426 (*mpObjects)[ rxShape ] = ObjectRepresentation( rxShape, aMtf );
2427 }
2428 else
2429 {
2430 if( aGraphic.GetGDIMetaFile().GetActionSize() )
2431 {
2432 Reference< XText > xText( rxShape, UNO_QUERY );
2433 bool bIsTextShape = xText.is();
2434
2435 if( !mpSVGExport->IsUsePositionedCharacters() && bIsTextShape )
2436 {
2437 Reference< XPropertySet > xShapePropSet( rxShape, UNO_QUERY );
2438
2439 if( xShapePropSet.is() )
2440 {
2441 bool bHideObj = false;
2442
2443 if( mbPresentation )
2444 {
2445 xShapePropSet->getPropertyValue( "IsEmptyPresentationObject" ) >>= bHideObj;
2446 }
2447
2448 if( !bHideObj )
2449 {
2450 // We create a map of text shape ids.
2451 implRegisterInterface( rxShape );
2452 const OUString& rShapeId = implGetValidIDFromInterface( Reference<XInterface>(rxShape, UNO_QUERY) );
2453 if( !rShapeId.isEmpty() )
2454 {
2455 mTextShapeIdListMap[rxPage] += rShapeId;
2456 mTextShapeIdListMap[rxPage] += " ";
2457 }
2458
2459 // We create a set of bitmaps embedded into text shape.
2460 GDIMetaFile aMtf;
2461 const Size aSize( pObj->GetCurrentBoundRect().GetSize() );
2462 MetaAction* pAction;
2463 bool bIsTextShapeStarted = false;
2464 const GDIMetaFile& rMtf = aGraphic.GetGDIMetaFile();
2465 size_t nCount = rMtf.GetActionSize();
2466 for( size_t nCurAction = 0; nCurAction < nCount; ++nCurAction )
2467 {
2468 pAction = rMtf.GetAction( nCurAction );
2469 const MetaActionType nType = pAction->GetType();
2470
2471 if( nType == MetaActionType::COMMENT )
2472 {
2473 const MetaCommentAction* pA = static_cast<const MetaCommentAction*>(pAction);
2474 if( pA->GetComment().equalsIgnoreAsciiCase("XTEXT_PAINTSHAPE_BEGIN") )
2475 {
2476 bIsTextShapeStarted = true;
2477 }
2478 else if( pA->GetComment().equalsIgnoreAsciiCase( "XTEXT_PAINTSHAPE_END" ) )
2479 {
2480 bIsTextShapeStarted = false;
2481 }
2482 }
2483 if( bIsTextShapeStarted && ( nType == MetaActionType::BMPSCALE || nType == MetaActionType::BMPEXSCALE ) )
2484 {
2485 GDIMetaFile aEmbeddedBitmapMtf;
2486 aEmbeddedBitmapMtf.AddAction( pAction );
2487 aEmbeddedBitmapMtf.SetPrefSize( aSize );
2488 aEmbeddedBitmapMtf.SetPrefMapMode(MapMode(MapUnit::Map100thMM));
2489 mEmbeddedBitmapActionSet.insert( ObjectRepresentation( rxShape, aEmbeddedBitmapMtf ) );
2490 aMtf.AddAction( pAction );
2491 }
2492 }
2493 aMtf.SetPrefSize( aSize );
2494 aMtf.SetPrefMapMode(MapMode(MapUnit::Map100thMM));
2495 mEmbeddedBitmapActionMap[ rxShape ] = ObjectRepresentation( rxShape, aMtf );
2496 }
2497 }
2498 }
2499 }
2500 (*mpObjects)[ rxShape ] = ObjectRepresentation( rxShape, aGraphic.GetGDIMetaFile() );
2501 }
2502 bRet = true;
2503 }
2504 }
2505 }
2506
2507 return bRet;
2508}
2509
2510
2511void SVGFilter::implCreateObjectsFromBackground( const Reference< css::drawing::XDrawPage >& rxDrawPage )
2512{
2513 Reference< css::drawing::XGraphicExportFilter > xExporter = drawing::GraphicExportFilter::create( mxContext );
2514
2515 GDIMetaFile aMtf;
2516
2517 utl::TempFileFast aFile;
2518 SvStream* pStream = aFile.GetStream(StreamMode::READWRITE);
2519
2520 Sequence< PropertyValue > aDescriptor{
2521 comphelper::makePropertyValue("FilterName", OUString( "SVM" )),
2522 comphelper::makePropertyValue("OutputStream", uno::Reference<XOutputStream>(new utl::OOutputStreamWrapper(*pStream))),
2523 comphelper::makePropertyValue("ExportOnlyBackground", true)
2524 };
2525
2526 xExporter->setSourceDocument( Reference< XComponent >( rxDrawPage, UNO_QUERY ) );
2527 xExporter->filter( aDescriptor );
2528 pStream->Seek(0);
2529 SvmReader aReader( *pStream );
2530 aReader.Read( aMtf );
2531
2532 bool bIsBitmap = false;
2533 bool bIsTiled = false;
2534
2535 // look for background type
2536 Reference< XPropertySet > xPropSet( rxDrawPage, UNO_QUERY );
2537 if( xPropSet.is() )
2538 {
2539 Reference< XPropertySet > xBackground;
2540 xPropSet->getPropertyValue( "Background" ) >>= xBackground;
2541 if( xBackground.is() )
2542 {
2543 drawing::FillStyle aFillStyle;
2544 if( xBackground->getPropertyValue( "FillStyle" ) >>= aFillStyle )
2545 {
2546 if( aFillStyle == drawing::FillStyle::FillStyle_BITMAP )
2547 {
2548 bIsBitmap = true;
2549 xBackground->getPropertyValue( "FillBitmapTile" ) >>= bIsTiled;
2550
2551 // we do not handle tiled background with a row or column offset
2552 sal_Int32 nFillBitmapOffsetX = 0, nFillBitmapOffsetY = 0;
2553 xBackground->getPropertyValue( "FillBitmapOffsetX" ) >>= nFillBitmapOffsetX;
2554 xBackground->getPropertyValue( "FillBitmapOffsetY" ) >>= nFillBitmapOffsetY;
2555 bIsTiled = bIsTiled && ( nFillBitmapOffsetX == 0 && nFillBitmapOffsetY == 0 );
2556 }
2557 }
2558 }
2559 }
2560
2561 if( !bIsBitmap )
2562 {
2563 (*mpObjects)[ rxDrawPage ] = ObjectRepresentation( rxDrawPage, aMtf );
2564 return;
2565 }
2566
2567 GDIMetaFile aTiledMtf;
2568 bool bBitmapFound = false;
2569 MetaAction* pAction;
2570 size_t nCount = aMtf.GetActionSize();
2571 for( size_t nCurAction = 0; nCurAction < nCount; ++nCurAction )
2572 {
2573 pAction = aMtf.GetAction( nCurAction );
2574 const MetaActionType nType = pAction->GetType();
2575
2576 // collect bitmap
2577 if( nType == MetaActionType::BMPSCALE || nType == MetaActionType::BMPEXSCALE )
2578 {
2579 if( bBitmapFound )
2580 continue;
2581 bBitmapFound = true; // the subsequent bitmaps are still the same just translated
2582
2583 BitmapChecksum nChecksum = GetBitmapChecksum( pAction );
2584 if( maBitmapActionMap.find( nChecksum ) == maBitmapActionMap.end() )
2585 {
2586 Point aPos; // (0, 0)
2587 Size aSize;
2588 MetaBitmapActionGetOrigSize( pAction, aSize );
2589 MetaAction* pBitmapAction = CreateMetaBitmapAction( pAction, aPos, aSize );
2590 if( pBitmapAction )
2591 {
2592 GDIMetaFile* pEmbeddedBitmapMtf = new GDIMetaFile();
2593 pEmbeddedBitmapMtf->AddAction( pBitmapAction );
2594 pEmbeddedBitmapMtf->SetPrefSize( aSize );
2595 pEmbeddedBitmapMtf->SetPrefMapMode( MapMode(MapUnit::Map100thMM) );
2596
2597 maBitmapActionMap[ nChecksum ].reset( pEmbeddedBitmapMtf );
2598 }
2599 }
2600
2601 if( bIsTiled )
2602 {
2603 // collect data for <pattern> and <rect>
2604 const OUString & sPageId = implGetValidIDFromInterface( rxDrawPage );
2605 Point aPos;
2606 MetaBitmapActionGetPoint( pAction, aPos );
2607 Size aSize;
2608 MetaBitmapActionGetSize( pAction, aSize );
2609
2610 sal_Int32 nSlideWidth = 0, nSlideHeight = 0;
2611 xPropSet->getPropertyValue( "Width" ) >>= nSlideWidth;
2612 xPropSet->getPropertyValue( "Height" ) >>= nSlideHeight;
2613
2614 maPatterProps[ sPageId ] = { nChecksum, aPos, aSize, { nSlideWidth, nSlideHeight } };
2615
2616 // create meta comment action that is used to exporting
2617 // a <use> element which points to the group element representing the background
2618 const OUString sBgId = getIdForTiledBackground( sPageId, nChecksum );
2619 OString sComment = sTiledBackgroundTag + " " + sBgId.toUtf8();
2620 MetaCommentAction* pCommentAction = new MetaCommentAction( sComment );
2621 if( pCommentAction )
2622 aTiledMtf.AddAction( pCommentAction );
2623 }
2624 }
2625 else if( bIsTiled && nType != MetaActionType::CLIPREGION )
2626 {
2627 aTiledMtf.AddAction( pAction );
2628 }
2629 }
2630
2631 (*mpObjects)[ rxDrawPage ] = ObjectRepresentation( rxDrawPage, bIsTiled ? aTiledMtf : aMtf );
2632}
2633
2634OUString SVGFilter::implGetClassFromShape( const Reference< css::drawing::XShape >& rxShape )
2635{
2636 OUString aRet;
2637 const OUString aShapeType( rxShape->getShapeType() );
2638
2639 if( aShapeType.lastIndexOf( "drawing.GroupShape" ) != -1 )
2640 aRet = "Group";
2641 else if( aShapeType.lastIndexOf( "drawing.GraphicObjectShape" ) != -1 )
2642 aRet = "Graphic";
2643 else if( aShapeType.lastIndexOf( "drawing.OLE2Shape" ) != -1 )
2644 aRet = "OLE2";
2645 else if( aShapeType.lastIndexOf( "drawing.TextShape" ) != -1 )
2646 aRet = "TextShape";
2647 else if( aShapeType.lastIndexOf( "presentation.HeaderShape" ) != -1 )
2648 aRet = "Header";
2649 else if( aShapeType.lastIndexOf( "presentation.FooterShape" ) != -1 )
2650 aRet = "Footer";
2651 else if( aShapeType.lastIndexOf( "presentation.DateTimeShape" ) != -1 )
2652 aRet = "DateTime";
2653 else if( aShapeType.lastIndexOf( "presentation.SlideNumberShape" ) != -1 )
2654 aRet = "PageNumber";
2655 else if( aShapeType.lastIndexOf( "presentation.TitleTextShape" ) != -1 )
2656 aRet = "TitleText";
2657 else if( aShapeType.lastIndexOf( "presentation.OutlinerShape" ) != -1 )
2658 aRet = "Outline";
2659 else
2660 aRet = aShapeType;
2661
2662 return aRet;
2663}
2664
2665
2666void SVGFilter::implRegisterInterface( const Reference< XInterface >& rxIf )
2667{
2668 if( rxIf.is() )
2669 mpSVGExport->getInterfaceToIdentifierMapper().registerReference( rxIf );
2670}
2671
2672
2673const OUString & SVGFilter::implGetValidIDFromInterface( const Reference< XInterface >& rxIf )
2674{
2675 return mpSVGExport->getInterfaceToIdentifierMapper().getIdentifier( rxIf );
2676}
2677
2678
2679OUString SVGFilter::implGetInterfaceName( const Reference< XInterface >& rxIf )
2680{
2681 Reference< XNamed > xNamed( rxIf, UNO_QUERY );
2682 OUString aRet;
2683 if( xNamed.is() )
2684 {
2685 aRet = xNamed->getName().replace( ' ', '_' );
2686 }
2687 return aRet;
2688}
2689
2690
2691IMPL_LINK( SVGFilter, CalcFieldHdl, EditFieldInfo*, pInfo, void )
2692{
2693 bool bFieldProcessed = false;
2694 if( pInfo && mbPresentation )
2695 {
2696 bFieldProcessed = true;
2697 if( mpSVGExport->IsEmbedFonts() && mpSVGExport->IsUsePositionedCharacters() )
2698 {
2699 // to notify to the SVGActionWriter::ImplWriteText method
2700 // that we are dealing with a placeholder shape
2701 OUStringBuffer aRepresentation(sPlaceholderTag);
2702
2703 if( !mCreateOjectsCurrentMasterPage.is() )
2704 {
2705 OSL_FAIL( "error: !mCreateOjectsCurrentMasterPage.is()" );
2706 return;
2707 }
2708 bool bHasCharSetMap = mTextFieldCharSets.find( mCreateOjectsCurrentMasterPage ) != mTextFieldCharSets.end();
2709
2710 static constexpr OUStringLiteral aHeaderId( NSPREFIX "header-field" );
2711 static constexpr OUStringLiteral aFooterId( aOOOAttrFooterField );
2712 static constexpr OUStringLiteral aDateTimeId( aOOOAttrDateTimeField );
2713 static const OUString aVariableDateTimeId( aOOOAttrDateTimeField + "-variable" );
2714
2715 const UCharSet * pCharSet = nullptr;
2716 UCharSetMap * pCharSetMap = nullptr;
2717 if( bHasCharSetMap )
2718 {
2719 pCharSetMap = &( mTextFieldCharSets[ mCreateOjectsCurrentMasterPage ] );
2720 }
2721 const SvxFieldData* pField = pInfo->GetField().GetField();
2722 if( bHasCharSetMap && ( pField->GetClassId() == text::textfield::Type::PRESENTATION_HEADER ) && ( pCharSetMap->find( aHeaderId ) != pCharSetMap->end() ) )
2723 {
2724 pCharSet = &( (*pCharSetMap)[ aHeaderId ] );
2725 }
2726 else if( bHasCharSetMap && ( pField->GetClassId() == text::textfield::Type::PRESENTATION_FOOTER ) && ( pCharSetMap->find( aFooterId ) != pCharSetMap->end() ) )
2727 {
2728 pCharSet = &( (*pCharSetMap)[ aFooterId ] );
2729 }
2730 else if( pField->GetClassId() == text::textfield::Type::PRESENTATION_DATE_TIME )
2731 {
2732 if( bHasCharSetMap && ( pCharSetMap->find( aDateTimeId ) != pCharSetMap->end() ) )
2733 {
2734 pCharSet = &( (*pCharSetMap)[ aDateTimeId ] );
2735 }
2736 if( bHasCharSetMap && ( pCharSetMap->find( aVariableDateTimeId ) != pCharSetMap->end() ) && !(*pCharSetMap)[ aVariableDateTimeId ].empty() )
2737 {
2738 SvxDateFormat eDateFormat = SvxDateFormat::B, eCurDateFormat;
2739 const UCharSet & aCharSet = (*pCharSetMap)[ aVariableDateTimeId ];
2740 // we look for the most verbose date format
2741 for (auto const& elem : aCharSet)
2742 {
2743 eCurDateFormat = static_cast<SvxDateFormat>( static_cast<int>(elem) & 0x0f );
2744 switch( eDateFormat )
2745 {
2746 case SvxDateFormat::StdSmall:
2747 case SvxDateFormat::A: // 13.02.96
2748 case SvxDateFormat::B: // 13.02.1996
2749 switch( eCurDateFormat )
2750 {
2751 case SvxDateFormat::C: // 13.Feb 1996
2752 case SvxDateFormat::D: // 13.February 1996
2753 case SvxDateFormat::E: // Tue, 13.February 1996
2754 case SvxDateFormat::StdBig:
2755 case SvxDateFormat::F: // Tuesday, 13.February 1996
2756 eDateFormat = eCurDateFormat;
2757 break;
2758 default:
2759 break;
2760 }
2761 break;
2762 case SvxDateFormat::C: // 13.Feb 1996
2763 case SvxDateFormat::D: // 13.February 1996
2764 switch( eCurDateFormat )
2765 {
2766 case SvxDateFormat::E: // Tue, 13.February 1996
2767 case SvxDateFormat::StdBig:
2768 case SvxDateFormat::F: // Tuesday, 13.February 1996
2769 eDateFormat = eCurDateFormat;
2770 break;
2771 default:
2772 break;
2773 }
2774 break;
2775 default:
2776 break;
2777 }
2778 }
2779 // Independently of the date format, we always put all these characters by default.
2780 // They should be enough to cover every time format.
2781 aRepresentation.append( "0123456789.:/-APM" );
2782
2783 if( eDateFormat != SvxDateFormat::AppDefault )
2784 {
2785 OUStringBuffer sDate;
2786 LanguageType eLang = pInfo->GetOutliner()->GetLanguage( pInfo->GetPara(), pInfo->GetPos() );
2787 SvNumberFormatter * pNumberFormatter = new SvNumberFormatter( ::comphelper::getProcessComponentContext(), LANGUAGE_SYSTEM );
2788 // We always collect the characters obtained by using the SvxDateFormat::B (as: 13.02.1996)
2789 // so we are sure to include any unusual day|month|year separator.
2790 Date aDate( 1, 1, 1996 );
2791 sDate.append( SvxDateField::GetFormatted( aDate, SvxDateFormat::B, *pNumberFormatter, eLang ) );
2792 switch( eDateFormat )
2793 {
2794 case SvxDateFormat::E: // Tue, 13.February 1996
2795 case SvxDateFormat::StdBig:
2796 case SvxDateFormat::F: // Tuesday, 13.February 1996
2797 for( sal_uInt16 i = 1; i <= 7; ++i ) // we get all days in a week
2798 {
2799 aDate.SetDay( i );
2800 sDate.append( SvxDateField::GetFormatted( aDate, eDateFormat, *pNumberFormatter, eLang ) );
2801 }
2802 [[fallthrough]]; // We need months too!
2803 case SvxDateFormat::C: // 13.Feb 1996
2804 case SvxDateFormat::D: // 13.February 1996
2805 for( sal_uInt16 i = 1; i <= 12; ++i ) // we get all months in a year
2806 {
2807 aDate.SetMonth( i );
2808 sDate.append( SvxDateField::GetFormatted( aDate, eDateFormat, *pNumberFormatter, eLang ) );
2809 }
2810 break;
2811 // coverity[dead_error_begin] - following conditions exist to avoid compiler warning
2812 case SvxDateFormat::StdSmall:
2813 case SvxDateFormat::A: // 13.02.96
2814 case SvxDateFormat::B: // 13.02.1996
2815 default:
2816 // nothing to do here, we always collect the characters needed for these cases.
2817 break;
2818 }
2819 aRepresentation.append( sDate );
2820 }
2821 }
2822 }
2823 else if( pField->GetClassId() == text::textfield::Type::PAGE )
2824 {
2825 switch( mVisiblePagePropSet.nPageNumberingType )
2826 {
2827 case css::style::NumberingType::CHARS_UPPER_LETTER:
2828 aRepresentation.append( "QWERTYUIOPASDFGHJKLZXCVBNM" );
2829 break;
2830 case css::style::NumberingType::CHARS_LOWER_LETTER:
2831 aRepresentation.append( "qwertyuiopasdfghjklzxcvbnm" );
2832 break;
2833 case css::style::NumberingType::ROMAN_UPPER:
2834 aRepresentation.append( "IVXLCDM" );
2835 break;
2836 case css::style::NumberingType::ROMAN_LOWER:
2837 aRepresentation.append( "ivxlcdm" );
2838 break;
2839 // arabic numbering type is the default
2840 case css::style::NumberingType::ARABIC:
2841 // in case the numbering type is not handled we fall back on arabic numbering
2842 default:
2843 aRepresentation.append( "0123456789" );
2844 break;
2845 }
2846 }
2847 else
2848 {
2849 bFieldProcessed = false;
2850 }
2851 if( bFieldProcessed )
2852 {
2853 if( pCharSet != nullptr )
2854 {
2855 for (auto const& elem : *pCharSet)
2856 {
2857 aRepresentation.append(elem);
2858 }
2859 }
2860 pInfo->SetRepresentation( aRepresentation.makeStringAndClear() );
2861 }
2862 }
2863 else
2864 {
2865 bFieldProcessed = false;
2866 }
2867
2868 }
2869 if (!bFieldProcessed)
2870 maOldFieldHdl.Call( pInfo );
2871}
2872
2873
2875{
2876 const Size aSize( OutputDevice::LogicToLogic(rMtf.GetPrefSize(), rMtf.GetPrefMapMode(), MapMode(MapUnit::MapMM)) );
2877 OUString aAttr;
2878 Reference< XExtendedDocumentHandler> xExtDocHandler( GetDocHandler(), UNO_QUERY );
2879
2880 if( xExtDocHandler.is() && IsUseDTDString() )
2881 xExtDocHandler->unknown( SVG_DTD_STRING );
2882
2883 aAttr = OUString::number( aSize.Width() ) + "mm";
2884 AddAttribute( XML_NAMESPACE_NONE, "width", aAttr );
2885
2886 aAttr = OUString::number( aSize.Height() ) + "mm";
2887 AddAttribute( XML_NAMESPACE_NONE, "height", aAttr );
2888
2889 aAttr = "0 0 " + OUString::number( aSize.Width() * 100 ) + " " +
2890 OUString::number( aSize.Height() * 100 );
2891 AddAttribute( XML_NAMESPACE_NONE, "viewBox", aAttr );
2892
2893 AddAttribute( XML_NAMESPACE_NONE, "version", "1.1" );
2894
2895 if( IsUseTinyProfile() )
2896 AddAttribute( XML_NAMESPACE_NONE, "baseProfile", "tiny" );
2897
2899 // For <image xlink:href="...">.
2900 AddAttribute(XML_NAMESPACE_XMLNS, "xlink", "http://www.w3.org/1999/xlink");
2901 AddAttribute( XML_NAMESPACE_NONE, "stroke-width", OUString::number( 28.222 ) );
2902 AddAttribute( XML_NAMESPACE_NONE, "stroke-linejoin", "round" );
2903 AddAttribute( XML_NAMESPACE_NONE, "xml:space", "preserve" );
2904
2905 {
2906 SvXMLElementExport aSVG( *this, XML_NAMESPACE_NONE, "svg", true, true );
2907
2908 std::vector< ObjectRepresentation > aObjects;
2909
2910 aObjects.emplace_back( Reference< XInterface >(), rMtf );
2911 SVGFontExport aSVGFontExport( *this, std::move(aObjects) );
2912
2913 Point aPoint100thmm( OutputDevice::LogicToLogic(rMtf.GetPrefMapMode().GetOrigin(), rMtf.GetPrefMapMode(), MapMode(MapUnit::Map100thMM)) );
2914 Size aSize100thmm( OutputDevice::LogicToLogic(rMtf.GetPrefSize(), rMtf.GetPrefMapMode(), MapMode(MapUnit::Map100thMM)) );
2915
2916 SVGActionWriter aWriter( *this, aSVGFontExport );
2917 aWriter.WriteMetaFile( aPoint100thmm, aSize100thmm, rMtf,
2919 }
2920}
2921
2923{
2924 maEmbeddedBulletGlyphs.insert(cBullet);
2925}
2926
2928{
2929 auto it = maEmbeddedBulletGlyphs.find(cBullet);
2930 return it != maEmbeddedBulletGlyphs.end();
2931}
2932
2933/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
sal_uInt64 BitmapChecksum
BitmapChecksum GetChecksum() const
const Size & GetSizePixel() const
Size GetSizePixel() const
void SetMonth(sal_uInt16 nNewMonth)
void SetDay(sal_uInt16 nNewDay)
size_t GetActionSize() const
const Size & GetPrefSize() const
MetaAction * GetAction(size_t nAction) const
void AddAction(const rtl::Reference< MetaAction > &pAction)
void SetPrefMapMode(const MapMode &rMapMode)
const MapMode & GetPrefMapMode() const
void SetPrefSize(const Size &rSize)
Size GetPrefSize() const
const GDIMetaFile & GetGDIMetaFile() const
GraphicType GetType() const
BitmapChecksum GetChecksum() const
BitmapEx GetBitmapEx(const GraphicConversionParameters &rParameters=GraphicConversionParameters()) const
MapMode GetPrefMapMode() const
bool HasError() const
INetProtocol GetProtocol() const
const Point & GetOrigin() const
MetaActionType GetType() const
virtual void Move(tools::Long nHorzMove, tools::Long nVertMove)
const Size & GetSize() const
const Point & GetPoint() const
const BitmapEx & GetBitmapEx() const
const Point & GetPoint() const
const Size & GetSize() const
const Bitmap & GetBitmap() const
const OString & GetComment() const
std::unique_ptr< GDIMetaFile > mxMtf
Definition: svgfilter.hxx:105
Reference< XInterface > mxObject
Definition: svgfilter.hxx:104
const GDIMetaFile & GetRepresentation() const
Definition: svgfilter.hxx:117
ObjectRepresentation & operator=(const ObjectRepresentation &rPresentation)
Definition: svgexport.cxx:420
SAL_WARN_UNUSED_RESULT Point LogicToLogic(const Point &rPtSource, const MapMode *pMapModeSource, const MapMode *pMapModeDest) const
constexpr tools::Long Y() const
constexpr tools::Long X() const
void WriteMetaFile(const Point &rPos100thmm, const Size &rSize100thmm, const GDIMetaFile &rMtf, sal_uInt32 nWriteFlags, const OUString &aElementId="", const Reference< css::drawing::XShape > *pXShape=nullptr, const GDIMetaFile *pTextEmbeddedBitmapMtf=nullptr)
Definition: svgwriter.cxx:4077
void SetEmbeddedBitmapRefs(const MetaBitmapActionMap *pEmbeddedBitmapsMap)
Definition: svgwriter.cxx:1972
void SetPreviewMode(bool bState=true)
Definition: svgwriter.hxx:381
virtual ~SVGExport() override
Definition: svgexport.cxx:398
bool mbIsUseOpacity
Definition: svgfilter.hxx:66
std::set< sal_Unicode > maEmbeddedBulletGlyphs
Definition: svgfilter.hxx:69
void writeMtf(const GDIMetaFile &rMtf)
Definition: svgexport.cxx:2874
bool mbIsUseTinyProfile
Definition: svgfilter.hxx:63
bool IsUseTinyProfile() const
Definition: svgfilter.hxx:79
bool mbIsUseNativeTextDecoration
Definition: svgfilter.hxx:67
void SetEmbeddedBulletGlyph(sal_Unicode cBullet)
Definition: svgexport.cxx:2922
bool mbIsUsePositionedCharacters
Definition: svgfilter.hxx:68
bool mbIsUseDTDString
Definition: svgfilter.hxx:64
bool mbIsEmbedFonts
Definition: svgfilter.hxx:65
SVGExport(const css::uno::Reference< css::uno::XComponentContext > &rContext, const Reference< XDocumentHandler > &rxHandler, const Sequence< PropertyValue > &rFilterData)
Definition: svgexport.cxx:333
bool IsEmbeddedBulletGlyph(sal_Unicode cBullet) const
Definition: svgexport.cxx:2927
bool IsUseDTDString() const
Definition: svgfilter.hxx:80
bool implCreateObjects()
Definition: svgexport.cxx:2298
bool mbShouldCompress
Definition: svgfilter.hxx:213
void implGetPagePropSet(const Reference< css::drawing::XDrawPage > &rxPage)
We collect info on master page elements visibility, and placeholder text shape content.
Definition: svgexport.cxx:1787
SVGFontExport * mpSVGFontExport
Definition: svgfilter.hxx:199
MetaBitmapActionMap maBitmapActionMap
Definition: svgfilter.hxx:232
void implExportTiledBackground()
Definition: svgexport.cxx:1613
bool mbWriterFilter
Definition: svgfilter.hxx:215
bool implCreateObjectsFromShapes(const Reference< css::drawing::XDrawPage > &rxPage, const Reference< css::drawing::XShapes > &rxShapes)
Definition: svgexport.cxx:2362
UCharSetMapMap mTextFieldCharSets
Definition: svgfilter.hxx:226
bool implExportImpressOrDraw(const Reference< XOutputStream > &rxOStm)
Definition: svgexport.cxx:664
const OUString & implGetValidIDFromInterface(const Reference< XInterface > &rxIf)
Definition: svgexport.cxx:2673
void implEmbedBulletGlyphs()
Definition: svgexport.cxx:1542
void implExportBackgroundBitmaps()
Definition: svgexport.cxx:1587
void implExportTextShapeIndex()
Definition: svgexport.cxx:1514
bool mbSinglePage
Definition: svgfilter.hxx:201
Link< EditFieldInfo *, void > maOldFieldHdl
Definition: svgfilter.hxx:236
OUString msClipPathId
Definition: svgfilter.hxx:225
sal_Int32 mnVisiblePage
Definition: svgfilter.hxx:202
SVGActionWriter * mpSVGWriter
Definition: svgfilter.hxx:200
std::vector< Reference< css::drawing::XDrawPage > > mMasterPageTargets
Definition: svgfilter.hxx:234
bool implExportPage(std::u16string_view sPageId, const Reference< css::drawing::XDrawPage > &rxPage, const Reference< css::drawing::XShapes > &xShapes, bool bMaster)
Definition: svgexport.cxx:1982
void implExportDocumentHeaderImpressOrDraw(sal_Int32 nDocX, sal_Int32 nDocY, sal_Int32 nDocWidth, sal_Int32 nDocHeight)
Definition: svgexport.cxx:1056
MetaBitmapActionSet mEmbeddedBitmapActionSet
Definition: svgfilter.hxx:230
void implExportDocumentHeaderWriterOrCalc(sal_Int32 nDocX, sal_Int32 nDocY, sal_Int32 nDocWidth, sal_Int32 nDocHeight)
Definition: svgexport.cxx:1150
bool implExport(const Sequence< PropertyValue > &rDescriptor)
Definition: svgexport.cxx:629
SvXMLElementExport * mpSVGDoc
Definition: svgfilter.hxx:197
std::unordered_map< Reference< XInterface >, ObjectRepresentation > ObjectMap
Definition: svgfilter.hxx:183
bool implExportShape(const Reference< css::drawing::XShape > &rxShape, bool bMaster)
Definition: svgexport.cxx:2112
static Reference< XWriter > implCreateExportDocumentHandler(const Reference< XOutputStream > &rxOStm)
Definition: svgexport.cxx:886
void implEmbedBulletGlyph(sal_Unicode cBullet, const OUString &sPathData)
Definition: svgexport.cxx:1570
bool implExportShapes(const Reference< css::drawing::XShapes > &rxShapes, bool bMaster)
Definition: svgexport.cxx:2095
bool implExportWriterTextGraphic(const Reference< view::XSelectionSupplier > &xSelectionSupplier)
Definition: svgexport.cxx:828
ObjectMap * mpObjects
Definition: svgfilter.hxx:203
bool mbExportShapeSelection
Definition: svgfilter.hxx:208
PagePropertySet mVisiblePagePropSet
Definition: svgfilter.hxx:224
bool implCreateObjectsFromShape(const Reference< css::drawing::XDrawPage > &rxPage, const Reference< css::drawing::XShape > &rxShape)
Definition: svgexport.cxx:2379
bool mbPresentation
Definition: svgfilter.hxx:223
void implRegisterInterface(const Reference< XInterface > &rxIf)
Definition: svgexport.cxx:2666
static OUString implGetClassFromShape(const Reference< css::drawing::XShape > &rxShape)
Definition: svgexport.cxx:2634
bool implExportDocument()
Definition: svgexport.cxx:934
void implExportTextEmbeddedBitmaps()
SVGFilter::implExportTextEmbeddedBitmaps We export bitmaps embedded into text shapes,...
Definition: svgexport.cxx:1688
SdrPage * mpDefaultSdrPage
Impress / draw only members.
Definition: svgfilter.hxx:222
Reference< XInterface > mCreateOjectsCurrentMasterPage
Definition: svgfilter.hxx:227
bool implExportWriterOrCalc(const Reference< XOutputStream > &rxOStm)
Definition: svgexport.cxx:788
Reference< XComponentContext > mxContext
Generally use members.
Definition: svgfilter.hxx:196
bool mbCalcFilter
Definition: svgfilter.hxx:216
std::unordered_map< Reference< XInterface >, OUString > mTextShapeIdListMap
Definition: svgfilter.hxx:229
static Any implSafeGetPagePropSet(const OUString &sPropertyName, const Reference< XPropertySet > &rxPropSet, const Reference< XPropertySetInfo > &rxPropSetInfo)
Definition: svgexport.cxx:1771
void implCreateObjectsFromBackground(const Reference< css::drawing::XDrawPage > &rxMasterPage)
Definition: svgexport.cxx:2511
bool implLookForFirstVisiblePage()
Definition: svgexport.cxx:900
Link< EditFieldInfo *, void > maNewFieldHdl
Definition: svgfilter.hxx:237
rtl::Reference< SVGExport > mpSVGExport
Definition: svgfilter.hxx:198
Reference< css::drawing::XDrawPage > mxDefaultPage
Definition: svgfilter.hxx:210
static OUString implGetInterfaceName(const Reference< XInterface > &rxIf)
Definition: svgexport.cxx:2679
Sequence< PropertyValue > maFilterData
Definition: svgfilter.hxx:209
void implGenerateScript()
Definition: svgexport.cxx:1752
bool implExportMasterPages(const std::vector< Reference< css::drawing::XDrawPage > > &rxPages, sal_Int32 nFirstPage, sal_Int32 nLastPage)
Definition: svgexport.cxx:1833
void implExportAnimations()
Definition: svgexport.cxx:1455
std::unordered_set< Reference< XInterface > > ObjectSet
Definition: svgfilter.hxx:184
std::vector< Reference< css::drawing::XDrawPage > > mSelectedPages
Definition: svgfilter.hxx:211
ObjectMap mEmbeddedBitmapActionMap
Definition: svgfilter.hxx:231
Reference< XComponent > mxSrcDoc
Definition: svgfilter.hxx:204
std::unordered_map< Reference< XInterface >, UCharSetMap > UCharSetMapMap
Definition: svgfilter.hxx:188
PatternPropertySet maPatterProps
Definition: svgfilter.hxx:233
Reference< css::drawing::XShapes > maShapeSelection
Definition: svgfilter.hxx:207
void implExportDrawPages(const std::vector< Reference< css::drawing::XDrawPage > > &rxPages, sal_Int32 nFirstPage, sal_Int32 nLastPage)
Definition: svgexport.cxx:1881
void implGenerateMetaData()
Definition: svgexport.cxx:1211
bool mbIsPreview
Definition: svgfilter.hxx:212
static Graphic GetObjGraphic(const SdrObject &rSdrObject, bool bSVG=false)
virtual SvxNumType GetPageNumType() const
SdrOutliner & GetDrawOutliner(const SdrTextObj *pObj=nullptr) const
void EnableUndo(bool bEnable)
std::vector< SdrOutliner * > GetActiveOutliners() const
bool IsUndoEnabled() const
static SdrObject * getSdrObjectFromXShape(const css::uno::Reference< css::uno::XInterface > &xInt)
virtual const tools::Rectangle & GetCurrentBoundRect() const
SdrModel & getSdrModelFromSdrPage() const
constexpr tools::Long Height() const
constexpr tools::Long Width() const
const void * GetData()
sal_uInt64 GetSize()
sal_uInt64 Seek(sal_uInt64 nPos)
ErrCode GetError() const
void AddAttribute(sal_uInt16 nPrefix, const OUString &rName, const OUString &rValue)
SvXMLNamespaceMap & GetNamespaceMap_()
const css::uno::Reference< css::xml::sax::XDocumentHandler > & GetDocHandler() const
void SetDocHandler(const css::uno::Reference< css::xml::sax::XDocumentHandler > &rHandler)
sal_uInt16 Add(const OUString &rPrefix, const OUString &rName, sal_uInt16 nKey=XML_NAMESPACE_UNKNOWN)
SvStream & Read(GDIMetaFile &rMetaFile, ImplMetaReadData *pData=nullptr)
OUString GetFormatted(SvNumberFormatter &rFormatter, LanguageType eLanguage) const
SdrPage * GetSdrPage() const
virtual sal_Int32 GetClassId() const
void SetCompressionMetadata(const OString &sFilename, sal_uInt32 nLastModifiedTime, sal_uInt32 nInBufCRC32)
tools::Long EndCompression()
void BeginCompression(int nCompressLevel=ZCODEC_DEFAULT_COMPRESSION, bool gzLib=false)
void Compress(SvStream &rIStm, SvStream &rOStm)
TYPE getWidth() const
TYPE getMinX() const
TYPE getMinY() const
void expand(const Tuple2D< TYPE > &rTuple)
bool isEmpty() const
TYPE getHeight() const
TValueType getUnpackedValueOrDefault(const OUString &sKey, const TValueType &aDefault) const
iterator find(const OUString &rKey)
SequenceAsHashMapBase::const_iterator const_iterator
constexpr Size GetSize() const
SvStream * GetStream(StreamMode eMode)
static std::unique_ptr< SvStream > CreateStream(const OUString &rFileName, StreamMode eOpenMode, css::uno::Reference< css::awt::XWindow > xParentWin=nullptr)
int nCount
#define DBG_ASSERT(sCon, aError)
#define TOOLS_WARN_EXCEPTION(area, stream)
float v
float u
SvxTimeFormat
SvxDateFormat
OUString sDisplayName
uno_Any a
#define LANGUAGE_SYSTEM
sal_uInt16 nPos
#define SAL_WARN(area, stream)
MetaActionType
def text(shape, orig_st)
constexpr OUStringLiteral aTextField
B2IRange fround(const B2DRange &rRange)
Shape IDs per cluster in DGG atom.
Reference< XComponentContext > getProcessComponentContext()
css::beans::PropertyValue makePropertyValue(const OUString &rName, T &&rValue)
int i
Definition: gentoken.py:48
const sal_uInt16 XML_NAMESPACE_NONE
const sal_uInt16 XML_NAMESPACE_XMLNS
XML_NP_SMIL
XML_N_SVG_COMPAT
XML_NP_PRESENTATION
XML_N_ANIMATION
XML_TOKEN_INVALID
XML_N_PRESENTATION
XML_NP_ANIMATION
XML_NP_SVG
XML_N_SMIL_COMPAT
const OUString & GetXMLToken(enum XMLTokenEnum eToken)
sal_Int16 nId
QPRO_FUNC_TYPE nType
bool operator()(const ObjectRepresentation &rObjRep1, const ObjectRepresentation &rObjRep2) const
Definition: svgexport.cxx:610
size_t operator()(const ObjectRepresentation &rObjRep) const
Definition: svgexport.cxx:595
bool bIsDateTimeFieldFixed
Definition: svgfilter.hxx:129
bool bIsBackgroundVisible
Definition: svgfilter.hxx:122
bool bIsHeaderFieldVisible
Definition: svgfilter.hxx:127
SvxDateFormat nDateTimeFormat
Definition: svgfilter.hxx:130
bool bIsPageNumberFieldVisible
Definition: svgfilter.hxx:124
bool bIsDateTimeFieldVisible
Definition: svgfilter.hxx:125
bool bAreBackgroundObjectsVisible
Definition: svgfilter.hxx:123
bool bIsFooterFieldVisible
Definition: svgfilter.hxx:126
sal_Int32 nPageNumberingType
Definition: svgfilter.hxx:128
constexpr OUStringLiteral aOOOAttrName
Definition: svgexport.cxx:108
constexpr OUStringLiteral aOOOAttrFooterField
Definition: svgexport.cxx:104
constexpr OUStringLiteral SVG_PROP_NATIVEDECORATION
Definition: svgexport.cxx:87
constexpr OUStringLiteral SVG_PROP_DTDSTRING
Definition: svgexport.cxx:85
constexpr OUStringLiteral aOOOAttrHasTransition
Definition: svgexport.cxx:105
constexpr OUStringLiteral aOOOAttrMaster
Definition: svgexport.cxx:97
IMPL_LINK(SVGFilter, CalcFieldHdl, EditFieldInfo *, pInfo, void)
Definition: svgexport.cxx:2691
constexpr OUStringLiteral SVG_PROP_TINYPROFILE
Definition: svgexport.cxx:84
constexpr OUStringLiteral SVG_PROP_EMBEDFONTS
Definition: svgexport.cxx:86
constexpr OUStringLiteral aOOOAttrSlideDuration
Definition: svgexport.cxx:102
#define NSPREFIX
Definition: svgexport.cxx:82
constexpr OUStringLiteral aOOOAttrSlide
Definition: svgexport.cxx:96
constexpr OUStringLiteral aOOOAttrDisplayName
Definition: svgexport.cxx:99
constexpr OUStringLiteral aOOOAttrHasCustomBackground
Definition: svgexport.cxx:98
constexpr OUStringLiteral SVG_PROP_OPACITY
Definition: svgexport.cxx:88
static OUString implGenerateFieldId(std::vector< std::unique_ptr< TextField > > &aFieldSet, const TextFieldType &aField, std::u16string_view sOOOElemField, const Reference< css::drawing::XDrawPage > &xMasterPage)
Append aField to aFieldSet if it is not already present in the set and create the field id sFieldId.
Definition: svgexport.cxx:1184
constexpr OUStringLiteral aOOOAttrBackgroundVisibility
Definition: svgexport.cxx:100
constexpr OUStringLiteral aOOOAttrMasterObjectsVisibility
Definition: svgexport.cxx:101
constexpr OUStringLiteral aOOOElemTextField
Definition: svgexport.cxx:92
constexpr OUStringLiteral constSvgNamespace
Definition: svgexport.cxx:110
constexpr OUStringLiteral aOOOAttrDateTimeField
Definition: svgexport.cxx:103
constexpr OUStringLiteral SVG_PROP_POSITIONED_CHARACTERS
Definition: svgexport.cxx:89
constexpr OStringLiteral sTiledBackgroundTag
Definition: svgfilter.hxx:59
constexpr OUStringLiteral sPlaceholderTag
Definition: svgfilter.hxx:57
#define SVGWRITER_WRITE_FILL
Definition: svgwriter.hxx:56
#define SVGWRITER_WRITE_TEXT
Definition: svgwriter.hxx:57
constexpr OUStringLiteral SVG_DTD_STRING
Definition: svgwriter.hxx:54
bool bVisible
OUString Name
sal_uInt16 sal_Unicode
signed char sal_Int8
Any result
SVXCORE_DLLPUBLIC css::uno::Reference< css::drawing::XShape > GetXShapeForSdrObject(SdrObject *pObj) noexcept
OUString sId
bool operator==(const XclFontData &rLeft, const XclFontData &rRight)
SvXMLExportFlags
constexpr sal_uInt16 XML_NAMESPACE_SMIL
constexpr sal_uInt16 XML_NAMESPACE_ANIMATION
constexpr sal_uInt16 XML_NAMESPACE_SVG
constexpr sal_uInt16 XML_NAMESPACE_PRESENTATION
sal_Int32 nLength
#define ZCODEC_DEFAULT_COMPRESSION