xref: /core/oox/source/drawingml/shape.cxx (revision 54e35fee)
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 <oox/drawingml/shape.hxx>
21 #include <drawingml/customshapeproperties.hxx>
22 #include <oox/drawingml/theme.hxx>
23 #include <drawingml/fillproperties.hxx>
24 #include <drawingml/graphicproperties.hxx>
25 #include <drawingml/lineproperties.hxx>
26 #include <drawingml/presetgeometrynames.hxx>
27 #include <drawingml/shape3dproperties.hxx>
28 #include "effectproperties.hxx"
29 #include <oox/drawingml/shapepropertymap.hxx>
30 #include <drawingml/textbody.hxx>
31 #include <drawingml/textparagraph.hxx>
32 #include <drawingml/ThemeOverrideFragmentHandler.hxx>
33 #include <drawingml/table/tableproperties.hxx>
34 #include <oox/drawingml/chart/chartconverter.hxx>
35 #include <drawingml/chart/chartspacefragment.hxx>
36 #include <drawingml/chart/chartspacemodel.hxx>
37 #include <o3tl/safeint.hxx>
38 #include <oox/ppt/pptimport.hxx>
39 #include <oox/vml/vmldrawing.hxx>
40 #include <oox/vml/vmlshape.hxx>
41 #include <oox/vml/vmlshapecontainer.hxx>
42 #include <oox/core/xmlfilterbase.hxx>
43 #include <oox/helper/graphichelper.hxx>
44 #include <oox/helper/propertyset.hxx>
45 #include <oox/helper/modelobjecthelper.hxx>
46 #include <oox/mathml/importutils.hxx>
47 #include <oox/mathml/import.hxx>
48 #include <oox/token/properties.hxx>
49 #include "diagram/datamodel.hxx"
50 
51 #include <comphelper/classids.hxx>
52 #include <comphelper/propertysequence.hxx>
53 #include <comphelper/propertyvalue.hxx>
54 #include <comphelper/sequence.hxx>
55 #include <tools/diagnose_ex.h>
56 #include <tools/gen.hxx>
57 #include <tools/globname.hxx>
58 #include <tools/mapunit.hxx>
59 #include <editeng/unoprnms.hxx>
60 #include <com/sun/star/awt/Size.hpp>
61 #include <com/sun/star/awt/XBitmap.hpp>
62 #include <com/sun/star/awt/FontWeight.hpp>
63 #include <com/sun/star/graphic/XGraphic.hpp>
64 #include <com/sun/star/container/XNamed.hpp>
65 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
66 #include <com/sun/star/xml/dom/XDocument.hpp>
67 #include <com/sun/star/xml/sax/XFastSAXSerializable.hpp>
68 #include <com/sun/star/drawing/FillStyle.hpp>
69 #include <com/sun/star/drawing/HomogenMatrix3.hpp>
70 #include <com/sun/star/drawing/TextVerticalAdjust.hpp>
71 #include <com/sun/star/drawing/GraphicExportFilter.hpp>
72 #include <com/sun/star/drawing/XShapes.hpp>
73 #include <com/sun/star/drawing/EnhancedCustomShapeAdjustmentValue.hpp>
74 #include <com/sun/star/drawing/EnhancedCustomShapeTextPathMode.hpp>
75 #include <com/sun/star/embed/XEmbeddedObject.hpp>
76 #include <com/sun/star/text/XText.hpp>
77 #include <com/sun/star/table/BorderLine2.hpp>
78 #include <com/sun/star/table/ShadowFormat.hpp>
79 #include <com/sun/star/chart2/XChartDocument.hpp>
80 #include <com/sun/star/style/ParagraphAdjust.hpp>
81 #include <com/sun/star/io/XOutputStream.hpp>
82 
83 #include <basegfx/point/b2dpoint.hxx>
84 #include <basegfx/polygon/b2dpolygon.hxx>
85 #include <basegfx/matrix/b2dhommatrix.hxx>
86 #include <com/sun/star/document/XActionLockable.hpp>
87 #include <com/sun/star/chart2/data/XDataReceiver.hpp>
88 #include <svx/svdtrans.hxx>
89 #include <tools/stream.hxx>
90 #include <unotools/streamwrap.hxx>
91 #include <unotools/fltrcfg.hxx>
92 #include <vcl/graph.hxx>
93 #include <vcl/graphicfilter.hxx>
94 #include <vcl/svapp.hxx>
95 #include <vcl/wmfexternal.hxx>
96 #include <sal/log.hxx>
97 #include <svx/unoapi.hxx>
98 #include <svx/unoshape.hxx>
99 #include <svx/sdtaitm.hxx>
100 
101 using namespace ::oox::core;
102 using namespace ::com::sun::star;
103 using namespace ::com::sun::star::uno;
104 using namespace ::com::sun::star::beans;
105 using namespace ::com::sun::star::frame;
106 using namespace ::com::sun::star::text;
107 using namespace ::com::sun::star::drawing;
108 using namespace ::com::sun::star::style;
109 
110 namespace oox::drawingml {
111 
112 Shape::Shape( const char* pServiceName, bool bDefaultHeight )
113 : mpLinePropertiesPtr( std::make_shared<LineProperties>() )
114 , mpShapeRefLinePropPtr( std::make_shared<LineProperties>() )
115 , mpFillPropertiesPtr( std::make_shared<FillProperties>() )
116 , mpShapeRefFillPropPtr( std::make_shared<FillProperties>() )
117 , mpGraphicPropertiesPtr( std::make_shared<GraphicProperties>() )
118 , mpCustomShapePropertiesPtr( std::make_shared<CustomShapeProperties>() )
119 , mp3DPropertiesPtr( std::make_shared<Shape3DProperties>() )
120 , mpEffectPropertiesPtr( std::make_shared<EffectProperties>() )
121 , mpShapeRefEffectPropPtr( std::make_shared<EffectProperties>() )
122 , mpMasterTextListStyle( std::make_shared<TextListStyle>() )
123 , mnSubType( 0 )
124 , meFrameType( FRAMETYPE_GENERIC )
125 , mnRotation( 0 )
126 , mnDiagramRotation( 0 )
127 , mbFlipH( false )
128 , mbFlipV( false )
129 , mbHidden( false )
130 , mbHiddenMasterShape( false )
131 , mbLocked( false )
132 , mbLockedCanvas( false )
133 , mbWps( false )
134 , mbTextBox( false )
135 , mbHasLinkedTxbx( false )
136 , maDiagramDoms( 0 )
137 {
138     if ( pServiceName )
139         msServiceName = OUString::createFromAscii( pServiceName );
140     setDefaults(bDefaultHeight);
141 }
142 
143 Shape::Shape( const ShapePtr& pSourceShape )
144 : maChildren()
145 , mpTextBody(pSourceShape->mpTextBody)
146 , mpLinePropertiesPtr( pSourceShape->mpLinePropertiesPtr )
147 , mpShapeRefLinePropPtr( pSourceShape->mpShapeRefLinePropPtr )
148 , mpFillPropertiesPtr( pSourceShape->mpFillPropertiesPtr )
149 , mpShapeRefFillPropPtr( pSourceShape->mpShapeRefFillPropPtr )
150 , mpGraphicPropertiesPtr( pSourceShape->mpGraphicPropertiesPtr )
151 , mpCustomShapePropertiesPtr( pSourceShape->mpCustomShapePropertiesPtr )
152 , mpTablePropertiesPtr( pSourceShape->mpTablePropertiesPtr )
153 , mp3DPropertiesPtr( pSourceShape->mp3DPropertiesPtr )
154 , mpEffectPropertiesPtr (pSourceShape->mpEffectPropertiesPtr)
155 , mpShapeRefEffectPropPtr(pSourceShape->mpShapeRefEffectPropPtr)
156 , maShapeProperties( pSourceShape->maShapeProperties )
157 , mpMasterTextListStyle( pSourceShape->mpMasterTextListStyle )
158 , mxShape()
159 , msServiceName( pSourceShape->msServiceName )
160 , msName( pSourceShape->msName )
161 , msInternalName( pSourceShape->msInternalName )
162 , msId( pSourceShape->msId )
163 , mnSubType( pSourceShape->mnSubType )
164 , moSubTypeIndex( pSourceShape->moSubTypeIndex )
165 , maShapeStyleRefs( pSourceShape->maShapeStyleRefs )
166 , maSize( pSourceShape->maSize )
167 , maPosition( pSourceShape->maPosition )
168 , meFrameType( pSourceShape->meFrameType )
169 , mnRotation( pSourceShape->mnRotation )
170 , mnDiagramRotation( pSourceShape->mnDiagramRotation )
171 , mbFlipH( pSourceShape->mbFlipH )
172 , mbFlipV( pSourceShape->mbFlipV )
173 , mbHidden( pSourceShape->mbHidden )
174 , mbHiddenMasterShape( pSourceShape->mbHiddenMasterShape )
175 , mbLocked( pSourceShape->mbLocked )
176 , mbLockedCanvas( pSourceShape->mbLockedCanvas )
177 , mbWps( pSourceShape->mbWps )
178 , mbTextBox( pSourceShape->mbTextBox )
179 , maLinkedTxbxAttr()
180 , mbHasLinkedTxbx(false)
181 , maDiagramDoms( pSourceShape->maDiagramDoms )
182 , mnZOrder(pSourceShape->mnZOrder)
183 , mnZOrderOff(pSourceShape->mnZOrderOff)
184 , mnDataNodeType(pSourceShape->mnDataNodeType)
185 , mfAspectRatio(pSourceShape->mfAspectRatio)
186 , mbUseBgFill(pSourceShape->mbUseBgFill)
187 {}
188 
189 Shape::~Shape()
190 {
191 }
192 
193 table::TablePropertiesPtr const & Shape::getTableProperties()
194 {
195     if ( !mpTablePropertiesPtr )
196         mpTablePropertiesPtr = std::make_shared<table::TableProperties>();
197     return mpTablePropertiesPtr;
198 }
199 
200 void Shape::setDefaults(bool bHeight)
201 {
202     maDefaultShapeProperties.setProperty(PROP_TextAutoGrowHeight, false);
203     maDefaultShapeProperties.setProperty(PROP_TextWordWrap, true);
204     maDefaultShapeProperties.setProperty(PROP_TextLeftDistance, static_cast< sal_Int32 >( 250 ));
205     maDefaultShapeProperties.setProperty(PROP_TextUpperDistance, static_cast< sal_Int32 >( 125 ));
206     maDefaultShapeProperties.setProperty(PROP_TextRightDistance, static_cast< sal_Int32 >( 250 ));
207     maDefaultShapeProperties.setProperty(PROP_TextLowerDistance, static_cast< sal_Int32 >( 125 ));
208     if (bHeight)
209         maDefaultShapeProperties.setProperty(PROP_CharHeight, static_cast< float >( 18.0 ));
210     maDefaultShapeProperties.setProperty(PROP_TextVerticalAdjust, TextVerticalAdjust_TOP);
211     maDefaultShapeProperties.setProperty(PROP_ParaAdjust, static_cast< sal_Int16 >( ParagraphAdjust_CENTER ));
212 }
213 
214 ::oox::vml::OleObjectInfo& Shape::setOleObjectType()
215 {
216     OSL_ENSURE( meFrameType == FRAMETYPE_GENERIC, "Shape::setOleObjectType - multiple frame types" );
217     meFrameType = FRAMETYPE_OLEOBJECT;
218     mxOleObjectInfo = std::make_shared<::oox::vml::OleObjectInfo>( true );
219     return *mxOleObjectInfo;
220 }
221 
222 ChartShapeInfo& Shape::setChartType( bool bEmbedShapes )
223 {
224     OSL_ENSURE( meFrameType == FRAMETYPE_GENERIC, "Shape::setChartType - multiple frame types" );
225     meFrameType = FRAMETYPE_CHART;
226     if (mbWps)
227         msServiceName = "com.sun.star.drawing.temporaryForXMLImportOLE2Shape";
228     else
229         msServiceName = "com.sun.star.drawing.OLE2Shape";
230     mxChartShapeInfo = std::make_shared<ChartShapeInfo>( bEmbedShapes );
231     return *mxChartShapeInfo;
232 }
233 
234 void Shape::setDiagramType()
235 {
236     OSL_ENSURE( meFrameType == FRAMETYPE_GENERIC, "Shape::setDiagramType - multiple frame types" );
237     meFrameType = FRAMETYPE_DIAGRAM;
238     msServiceName = "com.sun.star.drawing.GroupShape";
239     mnSubType = 0;
240 }
241 
242 void Shape::setTableType()
243 {
244     OSL_ENSURE( meFrameType == FRAMETYPE_GENERIC, "Shape::setTableType - multiple frame types" );
245     meFrameType = FRAMETYPE_TABLE;
246     msServiceName = "com.sun.star.drawing.TableShape";
247     mnSubType = 0;
248 }
249 
250 void Shape::setServiceName( const char* pServiceName )
251 {
252     if ( pServiceName )
253         msServiceName = OUString::createFromAscii( pServiceName );
254 }
255 
256 const ShapeStyleRef* Shape::getShapeStyleRef( sal_Int32 nRefType ) const
257 {
258     ShapeStyleRefMap::const_iterator aIt = maShapeStyleRefs.find( nRefType );
259     return (aIt == maShapeStyleRefs.end()) ? nullptr : &aIt->second;
260 }
261 
262 void Shape::addShape(
263         ::oox::core::XmlFilterBase& rFilterBase,
264         const Theme* pTheme,
265         const Reference< XShapes >& rxShapes,
266         const basegfx::B2DHomMatrix& aTransformation,
267         FillProperties& rShapeOrParentShapeFillProps,
268         ShapeIdMap* pShapeMap,
269         bool bInGroup )
270 {
271     SAL_INFO("oox.drawingml", "Shape::addShape: id='" << msId << "'");
272 
273     try
274     {
275         OUString sServiceName( msServiceName );
276         if( !sServiceName.isEmpty() )
277         {
278             basegfx::B2DHomMatrix aMatrix( aTransformation );
279             Reference< XShape > xShape( createAndInsert( rFilterBase, sServiceName, pTheme, rxShapes, false, false, aMatrix, rShapeOrParentShapeFillProps, bInGroup ) );
280 
281             if( pShapeMap && !msId.isEmpty() )
282             {
283                 (*pShapeMap)[ msId ] = shared_from_this();
284             }
285 
286             // if this is a group shape, we have to add also each child shape
287             Reference< XShapes > xShapes( xShape, UNO_QUERY );
288             if ( xShapes.is() )
289                 addChildren( rFilterBase, *this, pTheme, xShapes, pShapeMap, aMatrix );
290 
291             if( meFrameType == FRAMETYPE_DIAGRAM )
292             {
293                 keepDiagramCompatibilityInfo();
294                 if( !SvtFilterOptions::Get().IsSmartArt2Shape() )
295                     convertSmartArtToMetafile( rFilterBase );
296             }
297         }
298     }
299     catch( const Exception& )
300     {
301         TOOLS_WARN_EXCEPTION( "oox.drawingml", "Shape::addShape" );
302     }
303 }
304 
305 void Shape::setLockedCanvas(bool bLockedCanvas)
306 {
307     mbLockedCanvas = bLockedCanvas;
308 }
309 
310 void Shape::setWps(bool bWps)
311 {
312     mbWps = bWps;
313 }
314 
315 void Shape::setTextBox(bool bTextBox)
316 {
317     mbTextBox = bTextBox;
318 }
319 
320 void Shape::applyShapeReference( const Shape& rReferencedShape, bool bUseText )
321 {
322     SAL_INFO("oox.drawingml", "Shape::applyShapeReference: apply '" << rReferencedShape.msId << "' to '" << msId << "'");
323 
324     if ( rReferencedShape.mpTextBody && bUseText )
325         mpTextBody = std::make_shared<TextBody>( *rReferencedShape.mpTextBody );
326     else
327         mpTextBody.reset();
328     maShapeProperties = rReferencedShape.maShapeProperties;
329     mpShapeRefLinePropPtr = std::make_shared<LineProperties>( rReferencedShape.getActualLineProperties(nullptr) );
330     mpShapeRefFillPropPtr = std::make_shared<FillProperties>( rReferencedShape.getActualFillProperties(nullptr, nullptr) );
331     mpCustomShapePropertiesPtr = std::make_shared<CustomShapeProperties>( *rReferencedShape.mpCustomShapePropertiesPtr );
332     mpTablePropertiesPtr = rReferencedShape.mpTablePropertiesPtr ? std::make_shared<table::TableProperties>( *rReferencedShape.mpTablePropertiesPtr ) : nullptr;
333     mpShapeRefEffectPropPtr = std::make_shared<EffectProperties>( rReferencedShape.getActualEffectProperties(nullptr) );
334     mpMasterTextListStyle = std::make_shared<TextListStyle>( *rReferencedShape.mpMasterTextListStyle );
335     maSize = rReferencedShape.maSize;
336     maPosition = rReferencedShape.maPosition;
337     mnRotation = rReferencedShape.mnRotation;
338     mbFlipH = rReferencedShape.mbFlipH;
339     mbFlipV = rReferencedShape.mbFlipV;
340     mbHidden = rReferencedShape.mbHidden;
341     mbLocked = rReferencedShape.mbLocked;
342 }
343 
344 namespace {
345 
346 struct ActionLockGuard
347 {
348     explicit ActionLockGuard(Reference<drawing::XShape> const& xShape)
349         : m_xLockable(xShape, UNO_QUERY)
350     {
351         if (m_xLockable.is()) {
352             m_xLockable->addActionLock();
353         }
354     }
355     ~ActionLockGuard()
356     {
357         if (m_xLockable.is()) {
358             m_xLockable->removeActionLock();
359         }
360     }
361 private:
362     Reference<document::XActionLockable> m_xLockable;
363 };
364 
365 }
366 
367 // for group shapes, the following method is also adding each child
368 void Shape::addChildren(
369         XmlFilterBase& rFilterBase,
370         Shape& rMaster,
371         const Theme* pTheme,
372         const Reference< XShapes >& rxShapes,
373         ShapeIdMap* pShapeMap,
374         const basegfx::B2DHomMatrix& aTransformation )
375 {
376     basegfx::B2DHomMatrix aChildTransformation;
377 
378     aChildTransformation.translate(-maChPosition.X, -maChPosition.Y);
379     aChildTransformation.scale(1/(maChSize.Width ? maChSize.Width : 1.0), 1/(maChSize.Height ? maChSize.Height : 1.0));
380 
381     // Child position and size is typically non-zero, but it's allowed to have
382     // it like that, and in that case Word ignores the parent transformation
383     // (excluding translate component).
384     if (!mbWps || maChPosition.X || maChPosition.Y || maChSize.Width || maChSize.Height)
385     {
386         aChildTransformation *= aTransformation;
387     }
388     else
389     {
390         basegfx::B2DVector aScale, aTranslate;
391         double fRotate, fShearX;
392         aTransformation.decompose(aScale, aTranslate, fRotate, fShearX);
393         aChildTransformation.translate(aTranslate.getX(), aTranslate.getY());
394     }
395 
396     SAL_INFO("oox.drawingml", "Shape::addChildren: parent matrix:\n"
397              << aChildTransformation.get(0, 0) << " "
398              << aChildTransformation.get(0, 1) << " "
399              << aChildTransformation.get(0, 2) << "\n"
400              << aChildTransformation.get(1, 0) << " "
401              << aChildTransformation.get(1, 1) << " "
402              << aChildTransformation.get(1, 2) << "\n"
403              << aChildTransformation.get(2, 0) << " "
404              << aChildTransformation.get(2, 1) << " "
405              << aChildTransformation.get(2, 2));
406 
407     for (auto const& child : rMaster.maChildren)
408     {
409         child->setMasterTextListStyle( mpMasterTextListStyle );
410         child->addShape( rFilterBase, pTheme, rxShapes, aChildTransformation, getFillProperties(), pShapeMap, true );
411     }
412 }
413 
414 static void lcl_resetPropertyValue( std::vector<beans::PropertyValue>& rPropVec, const OUString& rName )
415 {
416     auto aIterator = std::find_if( rPropVec.begin(), rPropVec.end(),
417         [rName]( const beans::PropertyValue& rValue ) { return rValue.Name == rName; } );
418 
419     if (aIterator != rPropVec.end())
420         rPropVec.erase( aIterator );
421 }
422 
423 static void lcl_setPropertyValue( std::vector<beans::PropertyValue>& rPropVec,
424                            const OUString& rName,
425                            const beans::PropertyValue& rPropertyValue )
426 {
427     lcl_resetPropertyValue( rPropVec, rName );
428 
429     rPropVec.push_back( rPropertyValue );
430 }
431 
432 static SdrTextHorzAdjust lcl_convertAdjust( ParagraphAdjust eAdjust )
433 {
434     if (eAdjust == ParagraphAdjust_LEFT)
435         return SDRTEXTHORZADJUST_LEFT;
436     else if (eAdjust == ParagraphAdjust_RIGHT)
437         return SDRTEXTHORZADJUST_RIGHT;
438     else if (eAdjust == ParagraphAdjust_CENTER)
439         return SDRTEXTHORZADJUST_CENTER;
440     return SDRTEXTHORZADJUST_LEFT;
441 }
442 
443 static void lcl_createPresetShape(const uno::Reference<drawing::XShape>& xShape,
444                                          const OUString& rClass, const OUString& rPresetType,
445                                          const CustomShapePropertiesPtr& pCustomShapePropertiesPtr,
446                                          const TextBodyPtr& pTextBody,
447                                          const GraphicHelper& rGraphicHelper)
448 {
449     if (!xShape.is() || !pCustomShapePropertiesPtr || !pTextBody)
450         return;
451 
452     uno::Reference<drawing::XEnhancedCustomShapeDefaulter> xDefaulter( xShape,
453                                                                        uno::UNO_QUERY );
454 
455     if (!xDefaulter.is() || rClass.isEmpty())
456         return;
457 
458     Reference<XPropertySet> xSet( xShape, UNO_QUERY );
459     if (!xSet.is())
460         return;
461 
462     // The DrawingML shapes from the presetTextWarpDefinitions are mapped to the definitions
463     // in svx/../EnhancedCustomShapeGeometry.cxx, which are used for WordArt shapes from
464     // binary MS Office. Therefore all adjustment values need to be adapted.
465     auto aAdjGdList = pCustomShapePropertiesPtr->getAdjustmentGuideList();
466     Sequence<drawing::EnhancedCustomShapeAdjustmentValue> aAdjustment(
467         !aAdjGdList.empty() ? aAdjGdList.size() : 1 );
468 
469     int nIndex = 0;
470     for (const auto& aEntry : aAdjGdList)
471     {
472         double fValue = aEntry.maFormula.toDouble();
473         // then: polar-handle, else: XY-handle
474         // There exist only 8 polar-handles at all in presetTextWarp.
475         if ((rClass == "fontwork-arch-down-curve")
476             || (rClass == "fontwork-arch-down-pour" && aEntry.maName == "adj1")
477             || (rClass == "fontwork-arch-up-curve")
478             || (rClass == "fontwork-arch-up-pour" && aEntry.maName == "adj1")
479             || (rClass == "fontwork-open-circle-curve")
480             || (rClass == "fontwork-open-circle-pour" && aEntry.maName == "adj1")
481             || (rClass == "fontwork-circle-curve")
482             || (rClass == "fontwork-circle-pour" && aEntry.maName == "adj1"))
483         {
484             // DrawingML has 1/60000 degree unit, but WordArt simple degree. Range [0..360[
485             // or range ]-180..180] doesn't matter, because only cos(angle) and
486             // sin(angle) are used.
487             fValue = NormAngle360(fValue / 60000.0);
488         }
489         else
490         {
491             // DrawingML writes adjustment guides as relative value with 100% = 100000,
492             // but WordArt definitions use values absolute in viewBox 0 0 21600 21600,
493             // so scale with 21600/100000 = 0.216, with two exceptions:
494             // X-handles of waves describe increase/decrease relative to horizontal center.
495             // The gdRefR of pour-shapes is not relative to viewBox but to radius.
496             if ((rClass == "mso-spt158" && aEntry.maName == "adj2") // textDoubleWave1
497                 || (rClass == "fontwork-wave" && aEntry.maName == "adj2") // textWave1
498                 || (rClass == "mso-spt157" && aEntry.maName == "adj2") // textWave2
499                 || (rClass == "mso-spt159" && aEntry.maName == "adj2")) // textWave4
500             {
501                 fValue = (fValue + 50000.0) * 0.216;
502             }
503             else if ( (rClass == "fontwork-arch-down-pour" && aEntry.maName == "adj2")
504                     || (rClass == "fontwork-arch-up-pour" && aEntry.maName == "adj2")
505                     || (rClass == "fontwork-open-circle-pour" && aEntry.maName == "adj2")
506                     || (rClass == "fontwork-circle-pour" && aEntry.maName == "adj2"))
507                 {
508                     fValue *= 0.108;
509                 }
510             else
511             {
512                 fValue *= 0.216;
513             }
514         }
515 
516         aAdjustment[nIndex].Value <<= fValue;
517         aAdjustment[nIndex++].State = css::beans::PropertyState_DIRECT_VALUE;
518     }
519 
520     // Set properties
521     xSet->setPropertyValue( UNO_NAME_TEXT_AUTOGROWHEIGHT, uno::makeAny( false ) );
522     xSet->setPropertyValue( UNO_NAME_TEXT_AUTOGROWWIDTH, uno::makeAny( false ) );
523     xSet->setPropertyValue( UNO_NAME_FILLSTYLE, uno::makeAny( drawing::FillStyle_SOLID ) );
524 
525     // ToDo: Old binary WordArt does not allow different styles for different paragraphs, so it
526     // was not necessary to examine all paragraphs. Solution for DrawingML is needed.
527     // Currently different alignment of paragraphs are lost, for example.
528     const TextParagraphVector& rParagraphs = pTextBody->getParagraphs();
529     if (!rParagraphs.empty() && !rParagraphs[0]->getRuns().empty())
530     {
531         std::shared_ptr<TextParagraph> pParagraph = rParagraphs[0];
532         std::shared_ptr<TextRun> pRun = pParagraph->getRuns()[0];
533         TextCharacterProperties& pProperties = pRun->getTextCharacterProperties();
534 
535         if (pProperties.moBold.has() && pProperties.moBold.get())
536         {
537             xSet->setPropertyValue( UNO_NAME_CHAR_WEIGHT, uno::makeAny( css::awt::FontWeight::BOLD ) );
538         }
539         if (pProperties.moItalic.has() && pProperties.moItalic.get())
540         {
541             xSet->setPropertyValue( UNO_NAME_CHAR_POSTURE, uno::makeAny( css::awt::FontSlant::FontSlant_ITALIC ) );
542         }
543         if (pProperties.moHeight.has())
544         {
545             sal_Int32 nHeight = pProperties.moHeight.get() / 100;
546             xSet->setPropertyValue( UNO_NAME_CHAR_HEIGHT, uno::makeAny( nHeight ) );
547         }
548         if (pProperties.maFillProperties.maFillColor.isUsed())
549         {
550             const sal_Int32 aFillColor = static_cast<sal_Int32>(
551                 pProperties.maFillProperties.maFillColor.getColor( rGraphicHelper ).GetRGBColor() );
552             xSet->setPropertyValue( UNO_NAME_FILLCOLOR, uno::makeAny( aFillColor ) );
553         }
554         else
555         {
556             // Set default color
557             xSet->setPropertyValue( UNO_NAME_FILLCOLOR, uno::makeAny( COL_BLACK ) );
558         }
559         {
560             ParagraphAdjust eAdjust = ParagraphAdjust_LEFT;
561             if (pParagraph->getProperties().getParaAdjust())
562                 eAdjust = *pParagraph->getProperties().getParaAdjust();
563             xSet->setPropertyValue( "ParaAdjust", uno::makeAny( eAdjust ) );
564             SvxShape* pShape = comphelper::getUnoTunnelImplementation<SvxShape>( xShape );
565             assert(pShape);
566             SdrTextHorzAdjust eHorzAdjust = lcl_convertAdjust( eAdjust );
567             pShape->GetSdrObject()->SetMergedItem( SdrTextHorzAdjustItem( eHorzAdjust ) );
568         }
569     }
570 
571     // Apply vertical adjustment for text on arc
572     // ToDo: The property is currently not evaluated.
573     SvxShape* pShape = comphelper::getUnoTunnelImplementation<SvxShape>(xShape);
574     assert(pShape);
575     if (rClass == "fontwork-arch-up-curve")
576         pShape->GetSdrObject()->SetMergedItem( SdrTextVertAdjustItem( SdrTextVertAdjust::SDRTEXTVERTADJUST_BOTTOM ) );
577     else if (rClass == "fontwork-arch-down-curve")
578         pShape->GetSdrObject()->SetMergedItem( SdrTextVertAdjustItem( SdrTextVertAdjust::SDRTEXTVERTADJUST_TOP ) );
579 
580     // Apply preset shape
581     xDefaulter->createCustomShapeDefaults( rClass );
582 
583     auto aGeomPropSeq = xSet->getPropertyValue( "CustomShapeGeometry" )
584                             .get<uno::Sequence<beans::PropertyValue>>();
585     auto aGeomPropVec
586         = comphelper::sequenceToContainer<std::vector<beans::PropertyValue>>(
587             aGeomPropSeq );
588 
589     // Reset old properties
590     const OUString sTextPath( "TextPath" );
591     const OUString sAdjustmentValues( "AdjustmentValues" );
592     const OUString sPresetTextWarp( "PresetTextWarp" );
593 
594     lcl_resetPropertyValue( aGeomPropVec, "CoordinateSize" );
595     lcl_resetPropertyValue( aGeomPropVec, "Equations" );
596     lcl_resetPropertyValue( aGeomPropVec, "Path" );
597     lcl_resetPropertyValue( aGeomPropVec, sAdjustmentValues);
598 
599     bool bFromWordArt(false);
600     pTextBody->getTextProperties().maPropertyMap.getProperty(PROP_FromWordArt) >>= bFromWordArt;
601 
602     bool bScaleX(false);
603     if (!bFromWordArt
604         && (rPresetType == "textArchDown" || rPresetType == "textArchUp"
605             || rPresetType == "textCircle" || rPresetType == "textButton"))
606     {
607         bScaleX = true;
608     }
609 
610     // Apply geometry properties
611     uno::Sequence<beans::PropertyValue> aPropertyValues(
612         comphelper::InitPropertySequence(
613             { { sTextPath, uno::makeAny( true ) },
614                 { "TextPathMode",
615                 uno::Any( drawing::EnhancedCustomShapeTextPathMode_PATH ) },
616                 { "ScaleX", uno::Any(bScaleX) } } ) );
617 
618     lcl_setPropertyValue( aGeomPropVec, sTextPath,
619         comphelper::makePropertyValue( sTextPath, aPropertyValues ) );
620 
621     lcl_setPropertyValue( aGeomPropVec, sPresetTextWarp,
622         comphelper::makePropertyValue( sPresetTextWarp, rPresetType ) );
623 
624     if (!aAdjGdList.empty())
625     {
626         lcl_setPropertyValue( aGeomPropVec, sAdjustmentValues,
627             comphelper::makePropertyValue( sAdjustmentValues, aAdjustment ) );
628     }
629 
630     xSet->setPropertyValue(
631         "CustomShapeGeometry",
632         uno::makeAny(comphelper::containerToSequence(aGeomPropVec)));
633 }
634 
635 Reference< XShape > const & Shape::createAndInsert(
636         ::oox::core::XmlFilterBase& rFilterBase,
637         const OUString& rServiceName,
638         const Theme* pTheme,
639         const css::uno::Reference< css::drawing::XShapes >& rxShapes,
640         bool bClearText,
641         bool bDoNotInsertEmptyTextBody,
642         basegfx::B2DHomMatrix& aParentTransformation,
643         FillProperties& rShapeOrParentShapeFillProps,
644         bool bInGroup )
645 {
646     bool bIsEmbMedia = false;
647     SAL_INFO("oox.drawingml", "Shape::createAndInsert: id='" << msId << "' service='" << rServiceName << "'");
648 
649     formulaimport::XmlStreamBuilder * pMathXml(nullptr);
650     if (mpTextBody)
651     {
652         for (auto const& it : mpTextBody->getParagraphs())
653         {
654             if (it->HasMathXml())
655             {
656                 if (!mpTextBody->isEmpty() || pMathXml != nullptr)
657                 {
658                     SAL_WARN("oox.drawingml", "losing a Math object...");
659                 }
660                 else
661                 {
662                     pMathXml = &it->GetMathXml();
663                 }
664             }
665         }
666     }
667 
668     // tdf#90403 PowerPoint ignores a:ext cx and cy values of p:xfrm, and uses real table width and height
669     if ( mpTablePropertiesPtr && rServiceName == "com.sun.star.drawing.TableShape" )
670     {
671         maSize.Width = 0;
672         for (auto const& elem : mpTablePropertiesPtr->getTableGrid())
673         {
674             maSize.Width = o3tl::saturating_add(maSize.Width, static_cast<sal_Int32>(elem));
675         }
676         maSize.Height = 0;
677         for (auto const& elem : mpTablePropertiesPtr->getTableRows())
678         {
679             maSize.Height = o3tl::saturating_add(maSize.Height, elem.getHeight());
680         }
681     }
682 
683     awt::Rectangle aShapeRectHmm( maPosition.X / EMU_PER_HMM, maPosition.Y / EMU_PER_HMM, maSize.Width / EMU_PER_HMM, maSize.Height / EMU_PER_HMM );
684 
685     OUString aServiceName;
686     if (pMathXml)
687     {
688         // convert this shape to OLE
689         aServiceName = "com.sun.star.drawing.OLE2Shape";
690         msServiceName = aServiceName;
691         meFrameType = FRAMETYPE_GENERIC; // not OLEOBJECT, no stream in package
692         mnSubType = 0;
693     }
694     else if (rServiceName == "com.sun.star.drawing.GraphicObjectShape" &&
695         mpGraphicPropertiesPtr && !mpGraphicPropertiesPtr->m_sMediaPackageURL.isEmpty())
696     {
697         aServiceName = finalizeServiceName( rFilterBase, "com.sun.star.presentation.MediaShape", aShapeRectHmm );
698         bIsEmbMedia = true;
699     }
700     else
701     {
702         aServiceName = finalizeServiceName( rFilterBase, rServiceName, aShapeRectHmm );
703     }
704     // Use custom shape instead of GraphicObjectShape if the image is cropped to
705     // shape. Except rectangle, which does not require further cropping
706     bool bIsCroppedGraphic = (aServiceName == "com.sun.star.drawing.GraphicObjectShape" && mpCustomShapePropertiesPtr->getShapePresetType() >= 0
707             && mpCustomShapePropertiesPtr->getShapePresetType() != XML_Rect && mpCustomShapePropertiesPtr->getShapePresetType() != XML_rect);
708     bool bIsCustomShape = ( aServiceName == "com.sun.star.drawing.CustomShape" ||
709                             aServiceName == "com.sun.star.drawing.ConnectorShape" ||
710                             bIsCroppedGraphic);
711     if(bIsCroppedGraphic)
712     {
713         aServiceName = "com.sun.star.drawing.CustomShape";
714         mpGraphicPropertiesPtr->mbIsCustomShape = true;
715     }
716     bool bUseRotationTransform = ( !mbWps ||
717             aServiceName == "com.sun.star.drawing.LineShape" ||
718             aServiceName == "com.sun.star.drawing.GroupShape" ||
719             mbFlipH ||
720             mbFlipV );
721 
722     basegfx::B2DHomMatrix aTransformation;
723 
724     if (bUseRotationTransform && mnDiagramRotation != 0)
725     {
726         // rotate diagram's shape around object's center before sizing
727         aTransformation.translate(-0.5, -0.5);
728         aTransformation.rotate(basegfx::deg2rad(mnDiagramRotation / 60000.0));
729         aTransformation.translate(0.5, 0.5);
730     }
731 
732     if( maSize.Width != 1 || maSize.Height != 1)
733     {
734         // take care there are no zeros used by error
735         aTransformation.scale(
736             maSize.Width ? maSize.Width : 1.0,
737             maSize.Height ? maSize.Height : 1.0 );
738     }
739 
740     bool bNoTranslation = !aParentTransformation.isIdentity();
741     if( mbFlipH || mbFlipV || mnRotation != 0 || bNoTranslation )
742     {
743         // calculate object's center
744         basegfx::B2DPoint aCenter(0.5, 0.5);
745         aCenter *= aTransformation;
746 
747         // center object at origin
748         aTransformation.translate( -aCenter.getX(), -aCenter.getY() );
749 
750         if( !bIsCustomShape && ( mbFlipH || mbFlipV ) )
751         {
752             // mirror around object's center
753             aTransformation.scale( mbFlipH ? -1.0 : 1.0, mbFlipV ? -1.0 : 1.0 );
754         }
755 
756         if( bUseRotationTransform )
757         {
758             // OOXML flips shapes before rotating them.
759             if( bIsCustomShape )
760             {
761                 basegfx::B2DVector aScale, aTranslate;
762                 double fRotate, fShearX;
763                 aParentTransformation.decompose(aScale, aTranslate, fRotate, fShearX);
764                 // A negative scale means that the shape needs to be flipped
765                 if(aScale.getX() < 0)
766                 {
767                     mbFlipH = !mbFlipH;
768                     aTransformation.scale(-1, 1);
769                 }
770                 if(aScale.getY() < 0)
771                 {
772                     mbFlipV = !mbFlipV;
773                     aTransformation.scale(1, -1);
774                 }
775             }
776             // rotate around object's center
777             aTransformation.rotate(basegfx::deg2rad(static_cast<double>(mnRotation) / 60000.0));
778         }
779 
780         // move object back from center
781         aTransformation.translate( aCenter.getX(), aCenter.getY() );
782     }
783 
784     if( maPosition.X != 0 || maPosition.Y != 0)
785     {
786         // if global position is used, add it to transformation
787         if (mbWps && !bInGroup)
788             aTransformation.translate( maPosition.X * EMU_PER_HMM, maPosition.Y * EMU_PER_HMM);
789         else
790             aTransformation.translate( maPosition.X, maPosition.Y );
791     }
792 
793     aTransformation = aParentTransformation*aTransformation;
794     aParentTransformation = aTransformation;
795     aTransformation.scale(1/double(EMU_PER_HMM), 1/double(EMU_PER_HMM));
796 
797     if( bIsCustomShape && mbFlipH != mbFlipV )
798     {
799         basegfx::B2DVector aScale, aTranslate;
800         double fRotate, fShearX;
801         aTransformation.decompose(aScale, aTranslate, fRotate, fShearX);
802 
803         if(fRotate != 0)
804         {
805             // calculate object's center
806             basegfx::B2DPoint aCenter(0.5, 0.5);
807             aCenter *= aTransformation;
808             aTransformation.translate( -aCenter.getX(), -aCenter.getY() );
809             // OOXML flips shapes before rotating them, so the rotation needs to be inverted
810             aTransformation.rotate( fRotate * -2.0 );
811             aTransformation.translate( aCenter.getX(), aCenter.getY() );
812         }
813     }
814 
815     // special for lineshape
816     if ( aServiceName == "com.sun.star.drawing.LineShape" )
817     {
818         ::basegfx::B2DPolygon aPoly;
819         aPoly.insert( 0, ::basegfx::B2DPoint( 0, 0 ) );
820         aPoly.insert( 1, ::basegfx::B2DPoint( maSize.Width ? 1 : 0, maSize.Height ? 1 : 0 ) );
821         aPoly.transform( aTransformation );
822 
823         // now creating the corresponding PolyPolygon
824         sal_Int32 i, nNumPoints = aPoly.count();
825         uno::Sequence< awt::Point > aPointSequence( nNumPoints );
826         awt::Point* pPoints = aPointSequence.getArray();
827         uno::Reference<lang::XServiceInfo> xModelInfo(rFilterBase.getModel(), uno::UNO_QUERY);
828         bool bIsWriter = xModelInfo->supportsService("com.sun.star.text.TextDocument");
829         for( i = 0; i < nNumPoints; ++i )
830         {
831             const basegfx::B2DPoint aPoint( aPoly.getB2DPoint( i ) );
832 
833             // tdf#106792 Not needed anymore due to the change in SdrPathObj::NbcResize:
834             // tdf#96674: Guard against zero width or height.
835 
836             if (bIsWriter && bNoTranslation)
837                 // Writer's draw page is in twips, and these points get passed
838                 // to core without any unit conversion when Writer
839                 // postprocesses only the group shape itself.
840                 pPoints[i] = awt::Point(static_cast<sal_Int32>(convertMm100ToTwip(aPoint.getX())), static_cast<sal_Int32>(convertMm100ToTwip(aPoint.getY())));
841             else
842                 pPoints[i] = awt::Point(static_cast<sal_Int32>(aPoint.getX()), static_cast<sal_Int32>(aPoint.getY()));
843         }
844         uno::Sequence< uno::Sequence< awt::Point > > aPolyPolySequence( 1 );
845         aPolyPolySequence.getArray()[ 0 ] = aPointSequence;
846 
847         maShapeProperties.setProperty(PROP_PolyPolygon, aPolyPolySequence);
848     }
849     else if ( aServiceName == "com.sun.star.drawing.ConnectorShape" )
850     {
851         ::basegfx::B2DPolygon aPoly;
852         aPoly.insert( 0, ::basegfx::B2DPoint( 0, 0 ) );
853         aPoly.insert( 1, ::basegfx::B2DPoint( maSize.Width ? 1 : 0, maSize.Height ? 1 : 0 ) );
854         aPoly.transform( aTransformation );
855 
856         basegfx::B2DPoint aStartPosition( aPoly.getB2DPoint( 0 ) );
857         basegfx::B2DPoint aEndPosition( aPoly.getB2DPoint( 1 ) );
858         awt::Point aAWTStartPosition( static_cast< sal_Int32 >( aStartPosition.getX() ), static_cast< sal_Int32 >( aStartPosition.getY() ) );
859         awt::Point aAWTEndPosition( static_cast< sal_Int32 >( aEndPosition.getX() ), static_cast< sal_Int32 >( aEndPosition.getY() ) );
860 
861         maShapeProperties.setProperty(PROP_StartPosition, aAWTStartPosition);
862         maShapeProperties.setProperty(PROP_EndPosition, aAWTEndPosition);
863     }
864     else
865     {
866         // now set transformation for this object
867         HomogenMatrix3 aMatrix;
868 
869         aMatrix.Line1.Column1 = aTransformation.get(0,0);
870         aMatrix.Line1.Column2 = aTransformation.get(0,1);
871         aMatrix.Line1.Column3 = aTransformation.get(0,2);
872 
873         aMatrix.Line2.Column1 = aTransformation.get(1,0);
874         aMatrix.Line2.Column2 = aTransformation.get(1,1);
875         aMatrix.Line2.Column3 = aTransformation.get(1,2);
876 
877         aMatrix.Line3.Column1 = aTransformation.get(2,0);
878         aMatrix.Line3.Column2 = aTransformation.get(2,1);
879         aMatrix.Line3.Column3 = aTransformation.get(2,2);
880 
881         maShapeProperties.setProperty(PROP_Transformation, aMatrix);
882     }
883 
884     Reference< lang::XMultiServiceFactory > xServiceFact( rFilterBase.getModel(), UNO_QUERY_THROW );
885     if ( !mxShape.is() )
886         mxShape.set( xServiceFact->createInstance( aServiceName ), UNO_QUERY_THROW );
887 
888     Reference< XPropertySet > xSet( mxShape, UNO_QUERY );
889     if (xSet.is())
890     {
891         if( !msName.isEmpty() )
892         {
893             Reference< container::XNamed > xNamed( mxShape, UNO_QUERY );
894             if( xNamed.is() )
895                 xNamed->setName( msName );
896         }
897         if( !msDescription.isEmpty() )
898         {
899             xSet->setPropertyValue( "Description", Any( msDescription ) );
900         }
901         if (aServiceName != "com.sun.star.text.TextFrame")
902             rxShapes->add( mxShape );
903 
904         if ( mbHidden || mbHiddenMasterShape )
905         {
906             SAL_INFO("oox.drawingml", "Shape::createAndInsert: invisible shape with id='" << msId << "'");
907             xSet->setPropertyValue( "Visible", Any( false ) );
908             // In Excel hidden means not printed, let's use visibility for now until that's handled separately
909             xSet->setPropertyValue( "Printable", Any( false ) );
910         }
911 
912         if (mbLocked)
913         {
914             xSet->setPropertyValue("MoveProtect", Any(true));
915             xSet->setPropertyValue("SizeProtect", Any(true));
916         }
917 
918         ActionLockGuard const alg(mxShape);
919 
920         // sj: removing default text of placeholder objects such as SlideNumberShape or HeaderShape
921         if ( bClearText )
922         {
923             uno::Reference< text::XText > xText( mxShape, uno::UNO_QUERY );
924             if ( xText.is() )
925             {
926                 xText->setString( "" );
927             }
928         }
929 
930         if (pMathXml)
931         {
932             // the "EmbeddedObject" property is read-only, so we have to create
933             // the shape first, and it can be read only after the shape is
934             // inserted into the document, so delay the actual import until here
935             SvGlobalName name(SO3_SM_CLASSID);
936             xSet->setPropertyValue("CLSID", uno::makeAny(name.GetHexName()));
937             uno::Reference<embed::XEmbeddedObject> const xObj(
938                 xSet->getPropertyValue("EmbeddedObject"), uno::UNO_QUERY);
939             if (xObj.is())
940             {
941                 uno::Reference<uno::XInterface> const xMathModel(xObj->getComponent());
942                 oox::FormulaImportBase *const pMagic(
943                         dynamic_cast<oox::FormulaImportBase*>(xMathModel.get()));
944                 assert(pMagic);
945                 pMagic->readFormulaOoxml(*pMathXml);
946             }
947         }
948 
949         const GraphicHelper& rGraphicHelper = rFilterBase.getGraphicHelper();
950 
951         ::Color nLinePhClr(0xffffffff);
952         ::Color nFillPhClr(0xffffffff);
953         // TODO: use ph color when applying effect properties
954         //sal_Int32 nEffectPhClr = -1;
955 
956         if( pTheme )
957         {
958             if( const ShapeStyleRef* pLineRef = getShapeStyleRef( XML_lnRef ) )
959             {
960                 LineProperties aLineProperties;
961                 aLineProperties.maLineFill.moFillType = XML_noFill;
962                 if( const LineProperties* pLineProps = pTheme->getLineStyle( pLineRef->mnThemedIdx ) )
963                     aLineProperties.assignUsed( *pLineProps );
964                 nLinePhClr = pLineRef->maPhClr.getColor( rGraphicHelper );
965 
966                 // Store style-related properties to InteropGrabBag to be able to export them back
967                 uno::Sequence<beans::PropertyValue> aProperties = comphelper::InitPropertySequence(
968                 {
969                     {"SchemeClr", uno::makeAny(pLineRef->maPhClr.getSchemeName())},
970                     {"Idx", uno::makeAny(pLineRef->mnThemedIdx)},
971                     {"Color", uno::makeAny(nLinePhClr)},
972                     {"LineStyle", uno::makeAny(aLineProperties.getLineStyle())},
973                     {"LineCap", uno::makeAny(aLineProperties.getLineCap())},
974                     {"LineJoint", uno::makeAny(aLineProperties.getLineJoint())},
975                     {"LineWidth", uno::makeAny(aLineProperties.getLineWidth())},
976                     {"Transformations", uno::makeAny(pLineRef->maPhClr.getTransformations())}
977                 });
978                 putPropertyToGrabBag( "StyleLnRef", Any( aProperties ) );
979             }
980             if( const ShapeStyleRef* pFillRef = getShapeStyleRef( XML_fillRef ) )
981             {
982                 if (!mbUseBgFill)
983                 {
984                     nFillPhClr = pFillRef->maPhClr.getColor(rGraphicHelper);
985                 }
986 
987                 OUString sColorScheme = pFillRef->maPhClr.getSchemeName();
988                 if( !sColorScheme.isEmpty() )
989                 {
990                     uno::Sequence<beans::PropertyValue> aProperties = comphelper::InitPropertySequence(
991                     {
992                         {"SchemeClr", uno::makeAny(sColorScheme)},
993                         {"Idx", uno::makeAny(pFillRef->mnThemedIdx)},
994                         {"Color", uno::makeAny(nFillPhClr)},
995                         {"Transformations", uno::makeAny(pFillRef->maPhClr.getTransformations())}
996                     });
997 
998                     putPropertyToGrabBag( "StyleFillRef", Any( aProperties ) );
999                 }
1000             }
1001             if( const ShapeStyleRef* pEffectRef = getShapeStyleRef( XML_effectRef ) )
1002             {
1003                 // TODO: use ph color when applying effect properties
1004                 // nEffectPhClr = pEffectRef->maPhClr.getColor( rGraphicHelper );
1005 
1006                 // Store style-related properties to InteropGrabBag to be able to export them back
1007                 uno::Sequence<beans::PropertyValue> aProperties = comphelper::InitPropertySequence(
1008                 {
1009                     {"SchemeClr", uno::makeAny(pEffectRef->maPhClr.getSchemeName())},
1010                     {"Idx", uno::makeAny(pEffectRef->mnThemedIdx)},
1011                     {"Transformations", uno::makeAny(pEffectRef->maPhClr.getTransformations())}
1012                 });
1013                 putPropertyToGrabBag( "StyleEffectRef", Any( aProperties ) );
1014             }
1015         }
1016         ShapePropertyMap aShapeProps( rFilterBase.getModelObjectHelper() );
1017 
1018         // add properties from textbody to shape properties
1019         if( mpTextBody )
1020         {
1021             mpTextBody->getTextProperties().pushRotationAdjustments();
1022             aShapeProps.assignUsed( mpTextBody->getTextProperties().maPropertyMap );
1023             // Push char properties as well - specifically useful when this is a placeholder
1024             if( mpMasterTextListStyle &&  mpMasterTextListStyle->getListStyle()[0]->getTextCharacterProperties().moHeight.has() )
1025                 aShapeProps.setProperty(PROP_CharHeight, GetFontHeight( mpMasterTextListStyle->getListStyle()[0]->getTextCharacterProperties().moHeight.get() ));
1026         }
1027 
1028         // applying properties
1029         aShapeProps.assignUsed( getShapeProperties() );
1030         aShapeProps.assignUsed( maDefaultShapeProperties );
1031         if ( bIsEmbMedia || aServiceName == "com.sun.star.drawing.GraphicObjectShape" || aServiceName == "com.sun.star.drawing.OLE2Shape" || bIsCustomShape )
1032             mpGraphicPropertiesPtr->pushToPropMap( aShapeProps, rGraphicHelper );
1033         if ( mpTablePropertiesPtr && aServiceName == "com.sun.star.drawing.TableShape" )
1034             mpTablePropertiesPtr->pushToPropSet( rFilterBase, xSet, mpMasterTextListStyle );
1035 
1036         FillProperties aFillProperties = getActualFillProperties(pTheme, &rShapeOrParentShapeFillProps);
1037         if (getFillProperties().moFillType.has() && getFillProperties().moFillType.get() == XML_grpFill)
1038             getFillProperties().assignUsed(aFillProperties);
1039         if(!bIsCroppedGraphic)
1040             aFillProperties.pushToPropMap( aShapeProps, rGraphicHelper, mnRotation, nFillPhClr, mbFlipH, mbFlipV );
1041         LineProperties aLineProperties = getActualLineProperties(pTheme);
1042         aLineProperties.pushToPropMap( aShapeProps, rGraphicHelper, nLinePhClr );
1043         EffectProperties aEffectProperties = getActualEffectProperties(pTheme);
1044         // TODO: use ph color when applying effect properties
1045         aEffectProperties.pushToPropMap( aShapeProps, rGraphicHelper );
1046 
1047         // applying autogrowheight property before setting shape size, because
1048         // the shape size might be changed if currently autogrowheight is true
1049         // we must also check that the PropertySet supports the property.
1050         Reference< XPropertySetInfo > xSetInfo( xSet->getPropertySetInfo() );
1051         const OUString& rPropName = PropertyMap::getPropertyName( PROP_TextAutoGrowHeight );
1052         if( xSetInfo.is() && xSetInfo->hasPropertyByName( rPropName ) )
1053             if( aShapeProps.hasProperty( PROP_TextAutoGrowHeight ) )
1054                 xSet->setPropertyValue( rPropName, Any( false ) );
1055 
1056         // do not set properties at a group shape (this causes
1057         // assertions from svx) ...
1058         if( aServiceName != "com.sun.star.drawing.GroupShape" )
1059         {
1060             if (aServiceName == "com.sun.star.text.TextFrame")
1061             {
1062                 if (mpCustomShapePropertiesPtr && mpCustomShapePropertiesPtr->getShapeTypeOverride())
1063                 {
1064                     uno::Reference<beans::XPropertySet> propertySet (mxShape, uno::UNO_QUERY);
1065                     uno::Sequence<beans::PropertyValue> aGrabBag;
1066                     propertySet->getPropertyValue("FrameInteropGrabBag") >>= aGrabBag;
1067                     sal_Int32 length = aGrabBag.getLength();
1068                     aGrabBag.realloc( length+1);
1069                     aGrabBag[length].Name = "mso-orig-shape-type";
1070                     uno::Sequence< sal_Int8 > const & aNameSeq =
1071                         mpCustomShapePropertiesPtr->getShapePresetTypeName();
1072                     OUString sShapePresetTypeName(reinterpret_cast< const char* >(
1073                         aNameSeq.getConstArray()), aNameSeq.getLength(), RTL_TEXTENCODING_UTF8);
1074                     aGrabBag[length].Value <<= sShapePresetTypeName;
1075                     propertySet->setPropertyValue("FrameInteropGrabBag",uno::makeAny(aGrabBag));
1076                 }
1077                 //If the text box has links then save the link information so that
1078                 //it can be accessed in DomainMapper_Impl.cxx while chaining the text frames.
1079                 if (isLinkedTxbx())
1080                 {
1081                     uno::Reference<beans::XPropertySet> propertySet (mxShape, uno::UNO_QUERY);
1082                     uno::Sequence<beans::PropertyValue> aGrabBag;
1083                     propertySet->getPropertyValue("FrameInteropGrabBag") >>= aGrabBag;
1084                     sal_Int32 length = aGrabBag.getLength();
1085                     aGrabBag.realloc( length + 3 );
1086                     aGrabBag[length].Name = "TxbxHasLink";
1087                     aGrabBag[length].Value <<= isLinkedTxbx();
1088                     aGrabBag[length + 1 ].Name = "Txbx-Id";
1089                     aGrabBag[length + 1 ].Value <<= getLinkedTxbxAttributes().id;
1090                     aGrabBag[length + 2 ].Name = "Txbx-Seq";
1091                     aGrabBag[length + 2 ].Value <<= getLinkedTxbxAttributes().seq;
1092                     propertySet->setPropertyValue("FrameInteropGrabBag",uno::makeAny(aGrabBag));
1093                 }
1094 
1095                 // TextFrames have BackColor, not FillColor
1096                 if (aShapeProps.hasProperty(PROP_FillColor))
1097                 {
1098                     aShapeProps.setAnyProperty(PROP_BackColor, aShapeProps.getProperty(PROP_FillColor));
1099                     aShapeProps.erase(PROP_FillColor);
1100                 }
1101                 // TextFrames have BackColorTransparency, not FillTransparence
1102                 if (aShapeProps.hasProperty(PROP_FillTransparence))
1103                 {
1104                     aShapeProps.setAnyProperty(PROP_BackColorTransparency, aShapeProps.getProperty(PROP_FillTransparence));
1105                     aShapeProps.erase(PROP_FillTransparence);
1106                 }
1107                 // TextFrames have BackGraphic, not FillBitmap
1108                 if (aShapeProps.hasProperty(PROP_FillBitmap))
1109                 {
1110                     aShapeProps.setAnyProperty(PROP_BackGraphic, aShapeProps.getProperty(PROP_FillBitmap));
1111                     aShapeProps.erase(PROP_FillBitmap);
1112                 }
1113                 if (aShapeProps.hasProperty(PROP_FillBitmapName))
1114                 {
1115                     uno::Any aAny = aShapeProps.getProperty(PROP_FillBitmapName);
1116                     OUString aFillBitmapName = aAny.get<OUString>();
1117                     uno::Reference<awt::XBitmap> xBitmap = rFilterBase.getModelObjectHelper().getFillBitmap(aFillBitmapName);
1118                     uno::Reference<graphic::XGraphic> xGraphic(xBitmap, uno::UNO_QUERY);
1119                     aShapeProps.setProperty(PROP_BackGraphic, xGraphic);
1120                     // aShapeProps.erase(PROP_FillBitmapName);  // Maybe, leave the name as well
1121                 }
1122                 // And no LineColor property; individual borders can have colors
1123                 if (aShapeProps.hasProperty(PROP_LineColor))
1124                 {
1125                     uno::Reference<beans::XPropertySet> xPropertySet(mxShape, uno::UNO_QUERY);
1126                     static const sal_Int32 aBorders[] =
1127                     {
1128                         PROP_TopBorder, PROP_LeftBorder, PROP_BottomBorder, PROP_RightBorder
1129                     };
1130                     for (sal_Int32 nBorder : aBorders)
1131                     {
1132                         css::table::BorderLine2 aBorderLine = xPropertySet->getPropertyValue(PropertyMap::getPropertyName(nBorder)).get<css::table::BorderLine2>();
1133                         aBorderLine.Color = aShapeProps.getProperty(PROP_LineColor).get<sal_Int32>();
1134                         if (aLineProperties.moLineWidth.has())
1135                             aBorderLine.LineWidth = convertEmuToHmm(aLineProperties.moLineWidth.get());
1136                         aShapeProps.setProperty(nBorder, aBorderLine);
1137                     }
1138                     aShapeProps.erase(PROP_LineColor);
1139                 }
1140                 if(mnRotation)
1141                 {
1142                     uno::Reference<beans::XPropertySet> xPropertySet(mxShape, uno::UNO_QUERY);
1143                     const OUString aGrabBagPropName = "FrameInteropGrabBag";
1144                     uno::Sequence<beans::PropertyValue> aGrabBag;
1145                     xPropertySet->getPropertyValue(aGrabBagPropName) >>= aGrabBag;
1146                     beans::PropertyValue aPair;
1147                     aPair.Name = "mso-rotation-angle";
1148                     aPair.Value <<= mnRotation;
1149                     if (aGrabBag.hasElements())
1150                     {
1151                         sal_Int32 nLength = aGrabBag.getLength();
1152                         aGrabBag.realloc(nLength + 1);
1153                         aGrabBag[nLength] = aPair;
1154                     }
1155                     else
1156                     {
1157                         aGrabBag.realloc(1);
1158                         aGrabBag[0] = aPair;
1159                     }
1160                     xPropertySet->setPropertyValue(aGrabBagPropName, uno::makeAny(aGrabBag));
1161                 }
1162                 // TextFrames have ShadowFormat, not individual shadow properties.
1163                 std::optional<sal_Int32> oShadowDistance;
1164                 if (aShapeProps.hasProperty(PROP_ShadowXDistance))
1165                 {
1166                     oShadowDistance = aShapeProps.getProperty(PROP_ShadowXDistance).get<sal_Int32>();
1167                     aShapeProps.erase(PROP_ShadowXDistance);
1168                 }
1169                 if (aShapeProps.hasProperty(PROP_ShadowYDistance))
1170                 {
1171                     // There is a single 'dist' attribute, so no need to count the avg of x and y.
1172                     aShapeProps.erase(PROP_ShadowYDistance);
1173                 }
1174                 std::optional<sal_Int32> oShadowColor;
1175                 if (aShapeProps.hasProperty(PROP_ShadowColor))
1176                 {
1177                     oShadowColor = aShapeProps.getProperty(PROP_ShadowColor).get<sal_Int32>();
1178                     aShapeProps.erase(PROP_ShadowColor);
1179                 }
1180                 if (aShapeProps.hasProperty(PROP_Shadow))
1181                     aShapeProps.erase(PROP_Shadow);
1182 
1183                 if (oShadowDistance || oShadowColor || aEffectProperties.maShadow.moShadowDir.has())
1184                 {
1185                     css::table::ShadowFormat aFormat;
1186                     if (oShadowColor)
1187                         aFormat.Color = *oShadowColor;
1188                     if (aEffectProperties.maShadow.moShadowDir.has())
1189                     {
1190                         css::table::ShadowLocation nLocation = css::table::ShadowLocation_NONE;
1191                         switch (aEffectProperties.maShadow.moShadowDir.get())
1192                         {
1193                         case 13500000:
1194                             nLocation = css::table::ShadowLocation_TOP_LEFT;
1195                             break;
1196                         case 18900000:
1197                             nLocation = css::table::ShadowLocation_TOP_RIGHT;
1198                             break;
1199                         case 8100000:
1200                             nLocation = css::table::ShadowLocation_BOTTOM_LEFT;
1201                             break;
1202                         case 2700000:
1203                             nLocation = css::table::ShadowLocation_BOTTOM_RIGHT;
1204                             break;
1205                         }
1206                         aFormat.Location = nLocation;
1207                     }
1208                     aFormat.ShadowWidth = *oShadowDistance;
1209                     aShapeProps.setProperty(PROP_ShadowFormat, aFormat);
1210                 }
1211 
1212             }
1213             else if (mbTextBox)
1214             {
1215                 aShapeProps.setProperty(PROP_TextBox, true);
1216             }
1217 
1218             if (aServiceName != "com.sun.star.text.TextFrame" && isLinkedTxbx())
1219             {
1220                 uno::Reference<beans::XPropertySet> propertySet (mxShape, uno::UNO_QUERY);
1221                 uno::Sequence<beans::PropertyValue> aGrabBag;
1222                 propertySet->getPropertyValue("InteropGrabBag") >>= aGrabBag;
1223                 sal_Int32 length = aGrabBag.getLength();
1224                 aGrabBag.realloc( length + 3 );
1225                 aGrabBag[length].Name = "TxbxHasLink";
1226                 aGrabBag[length].Value <<= isLinkedTxbx();
1227                 aGrabBag[length + 1 ].Name = "Txbx-Id";
1228                 aGrabBag[length + 1 ].Value <<= getLinkedTxbxAttributes().id;
1229                 aGrabBag[length + 2 ].Name = "Txbx-Seq";
1230                 aGrabBag[length + 2 ].Value <<= getLinkedTxbxAttributes().seq;
1231                 propertySet->setPropertyValue("InteropGrabBag",uno::makeAny(aGrabBag));
1232             }
1233 
1234             PropertySet( xSet ).setProperties( aShapeProps );
1235             if (mbLockedCanvas)
1236             {
1237                 putPropertyToGrabBag( "LockedCanvas", Any( true ) );
1238                 if (aServiceName == "com.sun.star.drawing.LineShape")
1239                 {
1240                     // It seems the position and size for lines inside a locked canvas is absolute.
1241                     mxShape->setPosition(awt::Point(aShapeRectHmm.X, aShapeRectHmm.Y));
1242                     mxShape->setSize(awt::Size(aShapeRectHmm.Width, aShapeRectHmm.Height));
1243                 }
1244             }
1245 
1246             // Store original fill and line colors of the shape and the theme color name to InteropGrabBag
1247             std::vector<beans::PropertyValue> aProperties;
1248             aProperties.push_back(comphelper::makePropertyValue("EmuLineWidth", aLineProperties.moLineWidth.get(0)));
1249             aProperties.push_back(comphelper::makePropertyValue("OriginalSolidFillClr", aShapeProps.getProperty(PROP_FillColor)));
1250             aProperties.push_back(comphelper::makePropertyValue("OriginalLnSolidFillClr", aShapeProps.getProperty(PROP_LineColor)));
1251             OUString sColorFillScheme = aFillProperties.maFillColor.getSchemeName();
1252             if( !aFillProperties.maFillColor.isPlaceHolder() && !sColorFillScheme.isEmpty() )
1253             {
1254                 aProperties.push_back(comphelper::makePropertyValue("SpPrSolidFillSchemeClr", sColorFillScheme));
1255                 aProperties.push_back(comphelper::makePropertyValue("SpPrSolidFillSchemeClrTransformations", aFillProperties.maFillColor.getTransformations()));
1256             }
1257             OUString sLnColorFillScheme = aLineProperties.maLineFill.maFillColor.getSchemeName();
1258             if( !aLineProperties.maLineFill.maFillColor.isPlaceHolder() && !sLnColorFillScheme.isEmpty() )
1259             {
1260                 aProperties.push_back(comphelper::makePropertyValue("SpPrLnSolidFillSchemeClr", sLnColorFillScheme));
1261                 aProperties.push_back(comphelper::makePropertyValue("SpPrLnSolidFillSchemeClrTransformations", aLineProperties.maLineFill.maFillColor.getTransformations()));
1262             }
1263             putPropertiesToGrabBag(comphelper::containerToSequence(aProperties));
1264 
1265             // Store original gradient fill of the shape to InteropGrabBag
1266             // LibreOffice doesn't support all the kinds of gradient so we save its complete definition
1267             if( aShapeProps.hasProperty( PROP_FillGradient ) )
1268             {
1269                 std::vector<beans::PropertyValue> aGradientStops;
1270                 size_t i = 0;
1271                 for( const auto& [rPos, rColor] : aFillProperties.maGradientProps.maGradientStops )
1272                 { // for each stop in the gradient definition:
1273 
1274                     // save position
1275                     std::vector<beans::PropertyValue> aGradientStop;
1276                     aGradientStop.push_back(comphelper::makePropertyValue("Pos", rPos));
1277 
1278                     OUString sStopColorScheme = rColor.getSchemeName();
1279                     if( sStopColorScheme.isEmpty() )
1280                     {
1281                         // save RGB color
1282                         aGradientStop.push_back(comphelper::makePropertyValue("RgbClr", rColor.getColor(rGraphicHelper, nFillPhClr)));
1283                         // in the case of a RGB color, transformations are already applied to
1284                         // the color with the exception of alpha transformations. We only need
1285                         // to keep the transparency value to calculate the alpha value later.
1286                         if( rColor.hasTransparency() )
1287                             aGradientStop.push_back(comphelper::makePropertyValue("Transparency", rColor.getTransparency()));
1288                     }
1289                     else
1290                     {
1291                         // save color with scheme name
1292                         aGradientStop.push_back(comphelper::makePropertyValue("SchemeClr", sStopColorScheme));
1293                         // save all color transformations
1294                         aGradientStop.push_back(comphelper::makePropertyValue("Transformations", rColor.getTransformations()));
1295                     }
1296 
1297                     aGradientStops.push_back(comphelper::makePropertyValue(OUString::number(i), comphelper::containerToSequence(aGradientStop)));
1298                     ++i;
1299                 }
1300                 // If getFillProperties.moFillType is unused that means gradient is defined by a theme
1301                 // which is already saved into StyleFillRef property, so no need to save the explicit values too
1302                 if( getFillProperties().moFillType.has() )
1303                     putPropertyToGrabBag( "GradFillDefinition", uno::Any(comphelper::containerToSequence(aGradientStops)));
1304                 putPropertyToGrabBag( "OriginalGradFill", aShapeProps.getProperty(PROP_FillGradient) );
1305             }
1306 
1307             // store unsupported effect attributes in the grab bag
1308             if (!aEffectProperties.m_Effects.empty())
1309             {
1310                 std::vector<beans::PropertyValue> aEffects;
1311                 sal_uInt32 i = 0;
1312                 for (auto const& it : aEffectProperties.m_Effects)
1313                 {
1314                     PropertyValue aEffect = it->getEffect();
1315                     if( !aEffect.Name.isEmpty() )
1316                     {
1317                         std::vector<beans::PropertyValue> aEffectsGrabBag;
1318                         aEffectsGrabBag.push_back(comphelper::makePropertyValue("Attribs", aEffect.Value));
1319 
1320                         Color& aColor( it->moColor );
1321                         OUString sColorScheme = aColor.getSchemeName();
1322                         if( sColorScheme.isEmpty() )
1323                         {
1324                             // RGB color and transparency value
1325                             aEffectsGrabBag.push_back(comphelper::makePropertyValue("RgbClr", aColor.getColor(rGraphicHelper, nFillPhClr)));
1326                             aEffectsGrabBag.push_back(comphelper::makePropertyValue("RgbClrTransparency", aColor.getTransparency()));
1327                         }
1328                         else
1329                         {
1330                             // scheme color with name and transformations
1331                             aEffectsGrabBag.push_back(comphelper::makePropertyValue("SchemeClr", sColorScheme));
1332                             aEffectsGrabBag.push_back(comphelper::makePropertyValue("SchemeClrTransformations", aColor.getTransformations()));
1333                         }
1334                         aEffects.push_back(comphelper::makePropertyValue(aEffect.Name, comphelper::containerToSequence(aEffectsGrabBag)));
1335                         ++i;
1336                     }
1337                 }
1338                 putPropertyToGrabBag("EffectProperties", uno::Any(comphelper::containerToSequence(aEffects)));
1339             }
1340 
1341             // add 3D effects if any
1342             Sequence< PropertyValue > aCamera3DEffects = get3DProperties().getCameraAttributes();
1343             Sequence< PropertyValue > aLightRig3DEffects = get3DProperties().getLightRigAttributes();
1344             Sequence< PropertyValue > aShape3DEffects = get3DProperties().getShape3DAttributes( rGraphicHelper, nFillPhClr );
1345             if( aCamera3DEffects.hasElements() || aLightRig3DEffects.hasElements() || aShape3DEffects.hasElements() )
1346             {
1347                 uno::Sequence<beans::PropertyValue> a3DEffectsGrabBag = comphelper::InitPropertySequence(
1348                 {
1349                     {"Camera", uno::makeAny(aCamera3DEffects)},
1350                     {"LightRig", uno::makeAny(aLightRig3DEffects)},
1351                     {"Shape3D", uno::makeAny(aShape3DEffects)}
1352                 });
1353                 putPropertyToGrabBag( "3DEffectProperties", Any( a3DEffectsGrabBag ) );
1354             }
1355 
1356             // store bitmap artistic effects in the grab bag
1357             if( !mpGraphicPropertiesPtr->maBlipProps.maEffect.isEmpty() )
1358                 putPropertyToGrabBag( "ArtisticEffectProperties",
1359                                       Any( mpGraphicPropertiesPtr->maBlipProps.maEffect.getEffect() ) );
1360         }
1361 
1362         else if( mbLockedCanvas )
1363         {
1364             //If we have aServiceName as "com.sun.star.drawing.GroupShape" and lockedCanvas
1365             putPropertyToGrabBag( "LockedCanvas", Any( true ) );
1366         }
1367 
1368         // These can have a custom geometry, so position should be set here,
1369         // after creation but before custom shape handling, using the position
1370         // we got from the caller.
1371         if (mbWps && aServiceName == "com.sun.star.drawing.LineShape")
1372             mxShape->setPosition(maPosition);
1373 
1374         if( bIsCustomShape )
1375         {
1376             if ( mbFlipH )
1377                 mpCustomShapePropertiesPtr->setMirroredX( true );
1378             if ( mbFlipV )
1379                 mpCustomShapePropertiesPtr->setMirroredY( true );
1380             if( getTextBody() )
1381             {
1382                 sal_Int32 nTextCameraZRotation = static_cast< sal_Int32 >( get3DProperties().maCameraRotation.mnRevolution.get() );
1383                 mpCustomShapePropertiesPtr->setTextCameraZRotateAngle( nTextCameraZRotation / 60000 );
1384 
1385                 sal_Int32 nTextRotateAngle = static_cast< sal_Int32 >( getTextBody()->getTextProperties().moRotation.get( 0 ) );
1386 
1387                 nTextRotateAngle -= mnDiagramRotation;
1388                 /* OOX measures text rotation clockwise in 1/60000th degrees,
1389                    relative to the containing shape. setTextRotateAngle wants
1390                    degrees anticlockwise. */
1391                 mpCustomShapePropertiesPtr->setTextRotateAngle( -1 * nTextRotateAngle / 60000 );
1392             }
1393 
1394             // Note that the script oox/source/drawingml/customshapes/generatePresetsData.pl looks
1395             // for these ==cscode== and ==csdata== markers, so don't "clean up" these SAL_INFOs
1396             SAL_INFO("oox.cscode", "==cscode== shape name: '" << msName << "'");
1397             SAL_INFO("oox.csdata", "==csdata== shape name: '" << msName << "'");
1398             mpCustomShapePropertiesPtr->pushToPropSet( xSet, mxShape, maSize );
1399 
1400             if (mpTextBody)
1401             {
1402                 bool bIsPresetShape = !mpTextBody->getTextProperties().msPrst.isEmpty();
1403                 if (bIsPresetShape)
1404                 {
1405                     OUString sClass;
1406                     const OUString sPresetType = mpTextBody->getTextProperties().msPrst;
1407                     sClass = PresetGeometryTypeNames::GetFontworkType( sPresetType );
1408 
1409                     lcl_createPresetShape( mxShape, sClass, sPresetType, mpCustomShapePropertiesPtr, mpTextBody, rGraphicHelper );
1410                 }
1411             }
1412         }
1413         else if( getTextBody() )
1414             getTextBody()->getTextProperties().pushVertSimulation();
1415 
1416         PropertySet aPropertySet(mxShape);
1417         if ( !bUseRotationTransform && mnRotation != 0 )
1418         {
1419             // use the same logic for rotation from VML exporter (SimpleShape::implConvertAndInsert at vmlshape.cxx)
1420             aPropertySet.setAnyProperty( PROP_RotateAngle, makeAny( sal_Int32( NormAngle36000( mnRotation / -600 ) ) ) );
1421             aPropertySet.setAnyProperty( PROP_HoriOrientPosition, makeAny( maPosition.X ) );
1422             aPropertySet.setAnyProperty( PROP_VertOrientPosition, makeAny( maPosition.Y ) );
1423         }
1424 
1425         // in some cases, we don't have any text body.
1426         if( getTextBody() && ( !bDoNotInsertEmptyTextBody || !mpTextBody->isEmpty() ) )
1427         {
1428             Reference < XText > xText( mxShape, UNO_QUERY );
1429             if ( xText.is() )   // not every shape is supporting an XText interface (e.g. GroupShape)
1430             {
1431                 TextCharacterProperties aCharStyleProperties;
1432                 if( const ShapeStyleRef* pFontRef = getShapeStyleRef( XML_fontRef ) )
1433                 {
1434                     if( pFontRef->mnThemedIdx != 0 )
1435                     {
1436                         if( pTheme )
1437                             if( const TextCharacterProperties* pCharProps = pTheme->getFontStyle( pFontRef->mnThemedIdx ) )
1438                                 aCharStyleProperties.assignUsed( *pCharProps );
1439                         SAL_INFO("oox.drawingml", "Shape::createAndInsert: use font color");
1440                         if ( pFontRef->maPhClr.isUsed() )
1441                         {
1442                             aCharStyleProperties.maFillProperties.maFillColor = pFontRef->maPhClr;
1443                             aCharStyleProperties.maFillProperties.moFillType.set(XML_solidFill);
1444                         }
1445                     }
1446                 }
1447                 xText->setString("");
1448                 Reference < XTextCursor > xAt = xText->createTextCursor();
1449                 getTextBody()->insertAt( rFilterBase, xText, xAt, aCharStyleProperties, mpMasterTextListStyle );
1450             }
1451         }
1452         else if (mbTextBox)
1453         {
1454             // No drawingML text, but WPS text is expected: save the theme
1455             // character color on the shape, then.
1456             if(const ShapeStyleRef* pFontRef = getShapeStyleRef(XML_fontRef))
1457             {
1458                 ::Color nCharColor = pFontRef->maPhClr.getColor(rGraphicHelper);
1459                 aPropertySet.setAnyProperty(PROP_CharColor, uno::makeAny(nCharColor));
1460             }
1461         }
1462 
1463         // Set glow effect properties
1464         if ( aEffectProperties.maGlow.moGlowRad.has() )
1465         {
1466             uno::Reference<beans::XPropertySet> propertySet (mxShape, uno::UNO_QUERY);
1467             propertySet->setPropertyValue("GlowEffectRadius", makeAny(convertEmuToHmm(aEffectProperties.maGlow.moGlowRad.get())));
1468             propertySet->setPropertyValue("GlowEffectColor", makeAny(aEffectProperties.maGlow.moGlowColor.getColor(rGraphicHelper)));
1469             propertySet->setPropertyValue("GlowEffectTransparency", makeAny(aEffectProperties.maGlow.moGlowColor.getTransparency()));
1470         }
1471 
1472         // Set soft edge effect properties
1473         if (aEffectProperties.maSoftEdge.moRad.has())
1474         {
1475             uno::Reference<beans::XPropertySet> propertySet(mxShape, uno::UNO_QUERY);
1476             propertySet->setPropertyValue(
1477                 "SoftEdgeRadius", makeAny(convertEmuToHmm(aEffectProperties.maSoftEdge.moRad.get())));
1478         }
1479     }
1480 
1481     if( mxShape.is() )
1482         finalizeXShape( rFilterBase, rxShapes );
1483 
1484     return mxShape;
1485 }
1486 
1487 void Shape::keepDiagramDrawing(XmlFilterBase& rFilterBase, const OUString& rFragmentPath)
1488 {
1489     uno::Sequence<uno::Any> diagramDrawing(2);
1490     // drawingValue[0] => dom, drawingValue[1] => Sequence of associated relationships
1491 
1492     sal_Int32 length = maDiagramDoms.getLength();
1493     maDiagramDoms.realloc(length + 1);
1494 
1495     diagramDrawing[0] <<= rFilterBase.importFragment(rFragmentPath);
1496     diagramDrawing[1] <<= resolveRelationshipsOfTypeFromOfficeDoc(rFilterBase, rFragmentPath, "image");
1497 
1498     beans::PropertyValue* pValue = maDiagramDoms.getArray();
1499     pValue[length].Name = "OOXDrawing";
1500     pValue[length].Value <<= diagramDrawing;
1501 }
1502 
1503 void Shape::keepDiagramCompatibilityInfo()
1504 {
1505     try
1506     {
1507         if( !maDiagramDoms.hasElements() )
1508             return;
1509 
1510         Reference < XPropertySet > xSet( mxShape, UNO_QUERY_THROW );
1511         Reference < XPropertySetInfo > xSetInfo( xSet->getPropertySetInfo() );
1512         if ( !xSetInfo.is() )
1513             return;
1514 
1515         if (mpDiagramData)
1516         {
1517             if (SdrObject* pObj = GetSdrObjectFromXShape(mxShape))
1518                 pObj->SetDiagramData(mpDiagramData);
1519         }
1520 
1521         const OUString aGrabBagPropName = UNO_NAME_MISC_OBJ_INTEROPGRABBAG;
1522         if( !xSetInfo->hasPropertyByName( aGrabBagPropName ) )
1523             return;
1524 
1525         Sequence < PropertyValue > aGrabBag;
1526         xSet->getPropertyValue( aGrabBagPropName ) >>= aGrabBag;
1527 
1528         // We keep the previous items, if present
1529         if ( aGrabBag.hasElements() )
1530             xSet->setPropertyValue( aGrabBagPropName, Any( comphelper::concatSequences(aGrabBag, maDiagramDoms) ) );
1531         else
1532             xSet->setPropertyValue( aGrabBagPropName, Any( maDiagramDoms ) );
1533     }
1534     catch( const Exception& )
1535     {
1536         TOOLS_WARN_EXCEPTION( "oox.drawingml", "Shape::keepDiagramCompatibilityInfo" );
1537     }
1538 }
1539 
1540 void Shape::convertSmartArtToMetafile(XmlFilterBase const & rFilterBase)
1541 {
1542     try
1543     {
1544         Reference<XPropertySet> xSet(mxShape, UNO_QUERY_THROW);
1545 
1546         xSet->setPropertyValue("MoveProtect", Any(true));
1547         xSet->setPropertyValue("SizeProtect", Any(true));
1548 
1549         // Replace existing shapes with a new Graphic Object rendered
1550         // from them
1551         Reference<XShape> xShape(renderDiagramToGraphic(rFilterBase));
1552         Reference<XShapes> xShapes(mxShape, UNO_QUERY_THROW);
1553         while (xShapes->hasElements())
1554             xShapes->remove(Reference<XShape>(xShapes->getByIndex(0), UNO_QUERY_THROW));
1555         xShapes->add(xShape);
1556     }
1557     catch (const Exception&)
1558     {
1559         TOOLS_WARN_EXCEPTION("oox.drawingml", "Shape::convertSmartArtToMetafile");
1560     }
1561 }
1562 
1563 Reference < XShape > Shape::renderDiagramToGraphic( XmlFilterBase const & rFilterBase )
1564 {
1565     Reference< XShape > xShape;
1566 
1567     try
1568     {
1569         if( !maDiagramDoms.hasElements() )
1570             return xShape;
1571 
1572         // Stream in which to place the rendered shape
1573         SvMemoryStream aTempStream;
1574         Reference < io::XStream > xStream( new utl::OStreamWrapper( aTempStream ) );
1575         Reference < io::XOutputStream > xOutputStream( xStream->getOutputStream() );
1576 
1577         // Size of the rendering
1578         awt::Size aActualSize = mxShape->getSize();
1579         Size aResolution(Application::GetDefaultDevice()->LogicToPixel(Size(100, 100), MapMode(MapUnit::MapCM)));
1580         double fPixelsPer100thmm = static_cast < double > ( aResolution.Width() ) / 100000.0;
1581         awt::Size aSize( static_cast < sal_Int32 > ( ( fPixelsPer100thmm * aActualSize.Width ) + 0.5 ),
1582                          static_cast < sal_Int32 > ( ( fPixelsPer100thmm * aActualSize.Height ) + 0.5 ) );
1583 
1584         Sequence< PropertyValue > aFilterData( 4 );
1585         aFilterData[ 0 ].Name = "PixelWidth";
1586         aFilterData[ 0 ].Value <<= aSize.Width;
1587         aFilterData[ 1 ].Name = "PixelHeight";
1588         aFilterData[ 1 ].Value <<= aSize.Height;
1589         aFilterData[ 2 ].Name = "LogicalWidth";
1590         aFilterData[ 2 ].Value <<= aActualSize.Width;
1591         aFilterData[ 3 ].Name = "LogicalHeight";
1592         aFilterData[ 3 ].Value <<= aActualSize.Height;
1593 
1594         Sequence < PropertyValue > aDescriptor( 3 );
1595         aDescriptor[ 0 ].Name = "OutputStream";
1596         aDescriptor[ 0 ].Value <<= xOutputStream;
1597         aDescriptor[ 1 ].Name = "FilterName";
1598         aDescriptor[ 1 ].Value <<= OUString("SVM"); // Rendering format
1599         aDescriptor[ 2 ].Name = "FilterData";
1600         aDescriptor[ 2 ].Value <<= aFilterData;
1601 
1602         Reference < lang::XComponent > xSourceDoc( mxShape, UNO_QUERY_THROW );
1603         Reference < XGraphicExportFilter > xGraphicExporter = GraphicExportFilter::create( rFilterBase.getComponentContext() );
1604         xGraphicExporter->setSourceDocument( xSourceDoc );
1605         xGraphicExporter->filter( aDescriptor );
1606 
1607         aTempStream.Seek( STREAM_SEEK_TO_BEGIN );
1608 
1609         Graphic aGraphic;
1610         GraphicFilter aFilter( false );
1611         if ( aFilter.ImportGraphic( aGraphic, "", aTempStream, GRFILTER_FORMAT_NOTFOUND, nullptr, GraphicFilterImportFlags::NONE, static_cast < Sequence < PropertyValue >* > ( nullptr ) ) != ERRCODE_NONE )
1612         {
1613             SAL_WARN( "oox.drawingml", "Shape::renderDiagramToGraphic: Unable to import rendered stream into graphic object" );
1614             return xShape;
1615         }
1616 
1617         Reference < graphic::XGraphic > xGraphic( aGraphic.GetXGraphic() );
1618         Reference < lang::XMultiServiceFactory > xServiceFact( rFilterBase.getModel(), UNO_QUERY_THROW );
1619         xShape.set( xServiceFact->createInstance( "com.sun.star.drawing.GraphicObjectShape" ), UNO_QUERY_THROW );
1620         Reference < XPropertySet > xPropSet( xShape, UNO_QUERY_THROW );
1621         xPropSet->setPropertyValue(  "Graphic", Any( xGraphic ) );
1622         xPropSet->setPropertyValue(  "MoveProtect", Any( true ) );
1623         xPropSet->setPropertyValue(  "SizeProtect", Any( true ) );
1624         xPropSet->setPropertyValue(  "Name", Any( OUString( "RenderedShapes" ) ) );
1625     }
1626     catch( const Exception& )
1627     {
1628         TOOLS_WARN_EXCEPTION( "oox.drawingml", "Shape::renderDiagramToGraphic" );
1629     }
1630 
1631     return xShape;
1632 }
1633 
1634 void Shape::setTextBody(const TextBodyPtr & pTextBody)
1635 {
1636     mpTextBody = pTextBody;
1637 }
1638 
1639 void Shape::setMasterTextListStyle( const TextListStylePtr& pMasterTextListStyle )
1640 {
1641     SAL_INFO("oox.drawingml", "Shape::setMasterTextListStyle: Set master text list style to shape id='" << msId << "'");
1642 
1643     mpMasterTextListStyle = pMasterTextListStyle;
1644 }
1645 
1646 OUString Shape::finalizeServiceName( XmlFilterBase& rFilter, const OUString& rServiceName, const awt::Rectangle& rShapeRect )
1647 {
1648     OUString aServiceName = rServiceName;
1649     switch( meFrameType )
1650     {
1651         case FRAMETYPE_OLEOBJECT:
1652         {
1653             awt::Size aOleSize( rShapeRect.Width, rShapeRect.Height );
1654             if( rFilter.getOleObjectHelper().importOleObject( maShapeProperties, *mxOleObjectInfo, aOleSize ) )
1655                 aServiceName = "com.sun.star.drawing.OLE2Shape";
1656 
1657             // get the path to the representation graphic
1658             OUString aGraphicPath;
1659             if( !mxOleObjectInfo->maShapeId.isEmpty() )
1660                 if( ::oox::vml::Drawing* pVmlDrawing = rFilter.getVmlDrawing() )
1661                     if( const ::oox::vml::ShapeBase* pVmlShape = pVmlDrawing->getShapes().getShapeById( mxOleObjectInfo->maShapeId ) )
1662                         aGraphicPath = pVmlShape->getGraphicPath();
1663 
1664             // import and store the graphic
1665             if( !aGraphicPath.isEmpty() )
1666             {
1667                 // Transfer shape's width and height to graphicsfilter (can be used by WMF/EMF)
1668                 WmfExternal aExtHeader;
1669                 aExtHeader.mapMode = 8; // MM_ANISOTROPIC
1670                 aExtHeader.xExt = rShapeRect.Width;
1671                 aExtHeader.yExt = rShapeRect.Height;
1672 
1673                 Reference< graphic::XGraphic > xGraphic = rFilter.getGraphicHelper().importEmbeddedGraphic( aGraphicPath, &aExtHeader );
1674                 if( xGraphic.is() )
1675                     maShapeProperties.setProperty(PROP_Graphic, xGraphic);
1676             }
1677         }
1678         break;
1679 
1680         default:;
1681     }
1682     return aServiceName;
1683 }
1684 
1685 void Shape::finalizeXShape( XmlFilterBase& rFilter, const Reference< XShapes >& rxShapes )
1686 {
1687     switch( meFrameType )
1688     {
1689         case FRAMETYPE_CHART:
1690         {
1691             OSL_ENSURE( !mxChartShapeInfo->maFragmentPath.isEmpty(), "Shape::finalizeXShape - missing chart fragment" );
1692             if( mxShape.is() && !mxChartShapeInfo->maFragmentPath.isEmpty() ) try
1693             {
1694                 // set the chart2 OLE class ID at the OLE shape
1695                 PropertySet aShapeProp( mxShape );
1696                 aShapeProp.setProperty( PROP_CLSID, OUString( "12dcae26-281f-416f-a234-c3086127382e" ) );
1697 
1698                 // get the XModel interface of the embedded object from the OLE shape
1699                 Reference< frame::XModel > xDocModel;
1700                 aShapeProp.getProperty( xDocModel, PROP_Model );
1701                 Reference< chart2::XChartDocument > xChartDoc( xDocModel, UNO_QUERY_THROW );
1702 
1703                 // load the chart data from the XML fragment
1704                 bool bMSO2007Doc = rFilter.isMSO2007Document();
1705                 chart::ChartSpaceModel aModel(bMSO2007Doc);
1706                 chart::ChartSpaceFragment *pChartSpaceFragment = new chart::ChartSpaceFragment(
1707                         rFilter, mxChartShapeInfo->maFragmentPath, aModel );
1708                 const OUString aThemeOverrideFragmentPath( pChartSpaceFragment->
1709                         getFragmentPathFromFirstTypeFromOfficeDoc("themeOverride") );
1710                 rFilter.importFragment( pChartSpaceFragment );
1711                 ::oox::ppt::PowerPointImport *pPowerPointImport =
1712                     dynamic_cast< ::oox::ppt::PowerPointImport* >(&rFilter);
1713                 if (!aThemeOverrideFragmentPath.isEmpty() && pPowerPointImport)
1714                 {
1715                     uno::Reference< xml::sax::XFastSAXSerializable > xDoc(
1716                             rFilter.importFragment(aThemeOverrideFragmentPath), uno::UNO_QUERY_THROW);
1717                     ThemePtr pTheme = pPowerPointImport->getActualSlidePersist()->getTheme();
1718                     rFilter.importFragment(new ThemeOverrideFragmentHandler(
1719                                 rFilter, aThemeOverrideFragmentPath, *pTheme), xDoc);
1720                     pPowerPointImport->getActualSlidePersist()->setTheme(pTheme);
1721                 }
1722 
1723                 // convert imported chart model to chart document
1724                 Reference< drawing::XShapes > xExternalPage;
1725                 if( !mxChartShapeInfo->mbEmbedShapes )
1726                     xExternalPage = rxShapes;
1727                 if( rFilter.getChartConverter() )
1728                 {
1729                     rFilter.getChartConverter()->convertFromModel( rFilter, aModel, xChartDoc, xExternalPage, mxShape->getPosition(), mxShape->getSize() );
1730                     if( !xChartDoc->hasInternalDataProvider() )
1731                     {
1732                         Reference< chart2::data::XDataReceiver > xDataRec( xChartDoc, UNO_QUERY );
1733                         Reference< chart2::data::XDataSource > xData = xDataRec->getUsedData();
1734                         if( !xData->getDataSequences().hasElements() || !xData->getDataSequences()[0]->getValues().is() ||
1735                                 !xData->getDataSequences()[0]->getValues()->getData().hasElements() )
1736                         {
1737                             rFilter.useInternalChartDataTable( true );
1738                             rFilter.getChartConverter()->convertFromModel( rFilter, aModel, xChartDoc, xExternalPage, mxShape->getPosition(), mxShape->getSize() );
1739                             rFilter.useInternalChartDataTable( false );
1740                         }
1741                     }
1742 
1743                 }
1744             }
1745             catch( Exception& )
1746             {
1747             }
1748         }
1749         break;
1750 
1751         default:;
1752     }
1753 }
1754 
1755 void Shape::putPropertyToGrabBag( const OUString& sPropertyName, const Any& aPropertyValue )
1756 {
1757     PropertyValue aNewProperty;
1758     aNewProperty.Name = sPropertyName;
1759     aNewProperty.Value = aPropertyValue;
1760     putPropertyToGrabBag( aNewProperty );
1761 }
1762 
1763 void Shape::putPropertyToGrabBag( const PropertyValue& pProperty )
1764 {
1765     Reference< XPropertySet > xSet( mxShape, UNO_QUERY );
1766     Reference< XPropertySetInfo > xSetInfo( xSet->getPropertySetInfo() );
1767     const OUString aGrabBagPropName = UNO_NAME_MISC_OBJ_INTEROPGRABBAG;
1768     if( mxShape.is() && xSet.is() && xSetInfo.is() && xSetInfo->hasPropertyByName( aGrabBagPropName ) )
1769     {
1770         Sequence< PropertyValue > aGrabBag;
1771         xSet->getPropertyValue( aGrabBagPropName ) >>= aGrabBag;
1772 
1773         sal_Int32 length = aGrabBag.getLength();
1774         aGrabBag.realloc( length + 1 );
1775         aGrabBag[length] = pProperty;
1776 
1777         xSet->setPropertyValue( aGrabBagPropName, Any( aGrabBag ) );
1778     }
1779 }
1780 
1781 void Shape::putPropertiesToGrabBag( const Sequence< PropertyValue >& aProperties )
1782 {
1783     Reference< XPropertySet > xSet( mxShape, UNO_QUERY );
1784     Reference< XPropertySetInfo > xSetInfo( xSet->getPropertySetInfo() );
1785     const OUString aGrabBagPropName = UNO_NAME_MISC_OBJ_INTEROPGRABBAG;
1786     if( !(mxShape.is() && xSet.is() && xSetInfo.is() && xSetInfo->hasPropertyByName( aGrabBagPropName )) )
1787         return;
1788 
1789     // get existing grab bag
1790     Sequence< PropertyValue > aGrabBag;
1791     xSet->getPropertyValue( aGrabBagPropName ) >>= aGrabBag;
1792 
1793     std::vector<PropertyValue> aVec;
1794     aVec.reserve(aProperties.getLength());
1795 
1796     // put the new items
1797     std::transform(aProperties.begin(), aProperties.end(), std::back_inserter(aVec),
1798         [](const PropertyValue& rProp) {
1799             PropertyValue aProp;
1800             aProp.Name = rProp.Name;
1801             aProp.Value = rProp.Value;
1802             return aProp;
1803         });
1804 
1805     // put it back to the shape
1806     xSet->setPropertyValue( aGrabBagPropName, Any( comphelper::concatSequences(aGrabBag, aVec) ) );
1807 }
1808 
1809 FillProperties Shape::getActualFillProperties(const Theme* pTheme, const FillProperties* pParentShapeFillProps) const
1810 {
1811     FillProperties aFillProperties;
1812     aFillProperties.moFillType = XML_noFill;
1813 
1814     // Reference shape properties
1815     aFillProperties.assignUsed( *mpShapeRefFillPropPtr );
1816 
1817     // Theme
1818     if( pTheme != nullptr )
1819     {
1820         if( const ShapeStyleRef* pFillRef = getShapeStyleRef( XML_fillRef ) )
1821         {
1822             if( const FillProperties* pFillProps = pTheme->getFillStyle( pFillRef->mnThemedIdx ) )
1823                 aFillProperties.assignUsed( *pFillProps );
1824         }
1825     }
1826 
1827     // Properties specified directly for this shape
1828     aFillProperties.assignUsed(getFillProperties());
1829 
1830     // Parent shape's properties
1831     if ( pParentShapeFillProps != nullptr)
1832         if( getFillProperties().moFillType.has() && getFillProperties().moFillType.get() == XML_grpFill )
1833             aFillProperties.assignUsed( *pParentShapeFillProps );
1834 
1835     return aFillProperties;
1836 }
1837 
1838 LineProperties Shape::getActualLineProperties(const Theme* pTheme) const
1839 {
1840     LineProperties aLineProperties;
1841     aLineProperties.maLineFill.moFillType = XML_noFill;
1842 
1843     // Reference shape properties
1844     aLineProperties.assignUsed( *mpShapeRefLinePropPtr );
1845 
1846     // Theme
1847     if( pTheme != nullptr )
1848     {
1849         if( const ShapeStyleRef* pLineRef = getShapeStyleRef( XML_lnRef ) )
1850         {
1851             if( const LineProperties* pLineProps = pTheme->getLineStyle( pLineRef->mnThemedIdx ) )
1852                 aLineProperties.assignUsed( *pLineProps );
1853         }
1854     }
1855 
1856     // Properties specified directly for this shape
1857     aLineProperties.assignUsed( getLineProperties() );
1858 
1859     return aLineProperties;
1860 }
1861 
1862 EffectProperties Shape::getActualEffectProperties(const Theme* pTheme) const
1863 {
1864     EffectProperties aEffectProperties;
1865 
1866     // Reference shape properties
1867     aEffectProperties.assignUsed( *mpShapeRefEffectPropPtr );
1868 
1869     // Theme
1870     if( pTheme != nullptr )
1871     {
1872         if( const ShapeStyleRef* pEffectRef = getShapeStyleRef( XML_effectRef ) )
1873         {
1874             if( const EffectProperties* pEffectProps = pTheme->getEffectStyle( pEffectRef->mnThemedIdx ) )
1875                 aEffectProperties.assignUsed( *pEffectProps );
1876         }
1877     }
1878 
1879     // Properties specified directly for this shape
1880     aEffectProperties.assignUsed ( getEffectProperties() );
1881 
1882     return aEffectProperties;
1883 }
1884 
1885 uno::Sequence< uno::Sequence< uno::Any > >  Shape::resolveRelationshipsOfTypeFromOfficeDoc(core::XmlFilterBase& rFilter, const OUString& sFragment, const OUString& sType )
1886 {
1887     uno::Sequence< uno::Sequence< uno::Any > > xRelListTemp;
1888     sal_Int32 counter = 0;
1889 
1890     core::RelationsRef xRels = rFilter.importRelations( sFragment );
1891     if ( xRels )
1892     {
1893         core::RelationsRef xImageRels = xRels->getRelationsFromTypeFromOfficeDoc( sType );
1894         if ( xImageRels )
1895         {
1896             xRelListTemp.realloc( xImageRels->size() );
1897             for (auto const& imageRel : *xImageRels)
1898             {
1899                 uno::Sequence< uno::Any > diagramRelTuple (3);
1900                 // [0] => RID, [1] => InputStream [2] => extension
1901                 OUString sRelId = imageRel.second.maId;
1902 
1903                 diagramRelTuple[0] <<= sRelId;
1904                 OUString sTarget = xImageRels->getFragmentPathFromRelId( sRelId );
1905 
1906                 uno::Reference< io::XInputStream > xImageInputStrm( rFilter.openInputStream( sTarget ), uno::UNO_SET_THROW );
1907                 StreamDataSequence dataSeq;
1908                 if ( rFilter.importBinaryData( dataSeq, sTarget ) )
1909                 {
1910                     diagramRelTuple[1] <<= dataSeq;
1911                 }
1912 
1913                 diagramRelTuple[2] <<= sTarget.copy( sTarget.lastIndexOf(".") );
1914 
1915                 xRelListTemp[counter] = diagramRelTuple;
1916                 ++counter;
1917             }
1918             xRelListTemp.realloc(counter);
1919 
1920         }
1921     }
1922     return xRelListTemp;
1923 }
1924 
1925 void Shape::cloneFillProperties()
1926 {
1927     auto pFillProperties = std::make_shared<FillProperties>();
1928     pFillProperties->assignUsed(*mpFillPropertiesPtr);
1929     mpFillPropertiesPtr = pFillProperties;
1930 }
1931 }
1932 
1933 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
1934