fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / oox / source / drawingml / shape.cxx
blobd7247bee3cee4bcb8b668829abe81bba84650a22
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include "oox/drawingml/shape.hxx"
21 #include "drawingml/customshapeproperties.hxx"
22 #include "oox/drawingml/theme.hxx"
23 #include "oox/drawingml/fillproperties.hxx"
24 #include "drawingml/graphicproperties.hxx"
25 #include <drawingml/scene3dcontext.hxx>
26 #include "oox/drawingml/lineproperties.hxx"
27 #include "effectproperties.hxx"
28 #include "oox/drawingml/shapepropertymap.hxx"
29 #include "drawingml/textbody.hxx"
30 #include <drawingml/ThemeOverrideFragmentHandler.hxx>
31 #include "drawingml/table/tableproperties.hxx"
32 #include "oox/drawingml/chart/chartconverter.hxx"
33 #include "drawingml/chart/chartspacefragment.hxx"
34 #include "drawingml/chart/chartspacemodel.hxx"
35 #include "oox/ppt/pptimport.hxx"
36 #include "oox/vml/vmldrawing.hxx"
37 #include "oox/vml/vmlshape.hxx"
38 #include "oox/vml/vmlshapecontainer.hxx"
39 #include "oox/core/xmlfilterbase.hxx"
40 #include "oox/helper/graphichelper.hxx"
41 #include "oox/helper/propertyset.hxx"
42 #include "oox/helper/modelobjecthelper.hxx"
44 #include <tools/gen.hxx>
45 #include <tools/mapunit.hxx>
46 #include <editeng/unoprnms.hxx>
47 #include <com/sun/star/awt/Size.hpp>
48 #include <com/sun/star/graphic/XGraphic.hpp>
49 #include <com/sun/star/container/XNamed.hpp>
50 #include <com/sun/star/container/XNameContainer.hpp>
51 #include <com/sun/star/beans/XMultiPropertySet.hpp>
52 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
53 #include <com/sun/star/xml/AttributeData.hpp>
54 #include <com/sun/star/xml/sax/XFastSAXSerializable.hpp>
55 #include <com/sun/star/drawing/HomogenMatrix3.hpp>
56 #include <com/sun/star/drawing/TextVerticalAdjust.hpp>
57 #include <com/sun/star/drawing/GraphicExportFilter.hpp>
58 #include <com/sun/star/text/XText.hpp>
59 #include <com/sun/star/table/BorderLine2.hpp>
60 #include <com/sun/star/table/ShadowFormat.hpp>
61 #include <com/sun/star/chart2/XChartDocument.hpp>
62 #include <com/sun/star/style/ParagraphAdjust.hpp>
63 #include <com/sun/star/io/XOutputStream.hpp>
65 #include <basegfx/point/b2dpoint.hxx>
66 #include <basegfx/polygon/b2dpolygon.hxx>
67 #include <basegfx/matrix/b2dhommatrix.hxx>
68 #include <com/sun/star/document/XActionLockable.hpp>
69 #include <com/sun/star/chart2/data/XDataReceiver.hpp>
70 #include <svl/outstrm.hxx>
71 #include <svx/svdtrans.hxx>
72 #include <unotools/streamwrap.hxx>
73 #include <unotools/fltrcfg.hxx>
74 #include <vcl/graph.hxx>
75 #include <vcl/graphicfilter.hxx>
76 #include <vcl/svapp.hxx>
78 #include <vcl/wmf.hxx>
80 using namespace ::oox::core;
81 using namespace ::com::sun::star;
82 using namespace ::com::sun::star::uno;
83 using namespace ::com::sun::star::beans;
84 using namespace ::com::sun::star::frame;
85 using namespace ::com::sun::star::text;
86 using namespace ::com::sun::star::drawing;
87 using namespace ::com::sun::star::style;
89 namespace oox { namespace drawingml {
91 #define PUT_PROP( aProperties, nPos, sPropName, aPropValue ) \
92 aProperties[nPos].Name = sPropName; \
93 aProperties[nPos].Value = Any( aPropValue );
95 Shape::Shape( const sal_Char* pServiceName, bool bDefaultHeight )
96 : mbIsChild( false )
97 , mpLinePropertiesPtr( new LineProperties )
98 , mpShapeRefLinePropPtr( new LineProperties )
99 , mpFillPropertiesPtr( new FillProperties )
100 , mpShapeRefFillPropPtr( new FillProperties )
101 , mpGraphicPropertiesPtr( new GraphicProperties )
102 , mpCustomShapePropertiesPtr( new CustomShapeProperties )
103 , mp3DPropertiesPtr( new Shape3DProperties )
104 , mpEffectPropertiesPtr( new EffectProperties )
105 , mpShapeRefEffectPropPtr( new EffectProperties )
106 , mpMasterTextListStyle( new TextListStyle )
107 , mnSubType( 0 )
108 , meFrameType( FRAMETYPE_GENERIC )
109 , mnRotation( 0 )
110 , mbFlipH( false )
111 , mbFlipV( false )
112 , mbHidden( false )
113 , mbHiddenMasterShape( false )
114 , mbLockedCanvas( false )
115 , mbWps( false )
116 , mbTextBox( false )
117 , mbHasLinkedTxbx( false )
118 , maDiagramDoms( 0 )
120 if ( pServiceName )
121 msServiceName = OUString::createFromAscii( pServiceName );
122 setDefaults(bDefaultHeight);
125 Shape::Shape( const ShapePtr& pSourceShape )
126 : maChildren()
127 , mbIsChild( pSourceShape->mbIsChild )
128 , mpTextBody(pSourceShape->mpTextBody)
129 , mpLinePropertiesPtr( pSourceShape->mpLinePropertiesPtr )
130 , mpShapeRefLinePropPtr( pSourceShape->mpShapeRefLinePropPtr )
131 , mpFillPropertiesPtr( pSourceShape->mpFillPropertiesPtr )
132 , mpShapeRefFillPropPtr( pSourceShape->mpShapeRefFillPropPtr )
133 , mpGraphicPropertiesPtr( pSourceShape->mpGraphicPropertiesPtr )
134 , mpCustomShapePropertiesPtr( pSourceShape->mpCustomShapePropertiesPtr )
135 , mpTablePropertiesPtr( pSourceShape->mpTablePropertiesPtr )
136 , mp3DPropertiesPtr( pSourceShape->mp3DPropertiesPtr )
137 , mpEffectPropertiesPtr (pSourceShape->mpEffectPropertiesPtr)
138 , mpShapeRefEffectPropPtr(pSourceShape->mpShapeRefEffectPropPtr)
139 , maShapeProperties( pSourceShape->maShapeProperties )
140 , mpMasterTextListStyle( pSourceShape->mpMasterTextListStyle )
141 , mxShape()
142 , msServiceName( pSourceShape->msServiceName )
143 , msName( pSourceShape->msName )
144 , msId( pSourceShape->msId )
145 , mnSubType( pSourceShape->mnSubType )
146 , moSubTypeIndex( pSourceShape->moSubTypeIndex )
147 , maShapeStyleRefs( pSourceShape->maShapeStyleRefs )
148 , maSize( pSourceShape->maSize )
149 , maPosition( pSourceShape->maPosition )
150 , meFrameType( pSourceShape->meFrameType )
151 , mnRotation( pSourceShape->mnRotation )
152 , mbFlipH( pSourceShape->mbFlipH )
153 , mbFlipV( pSourceShape->mbFlipV )
154 , mbHidden( pSourceShape->mbHidden )
155 , mbHiddenMasterShape( pSourceShape->mbHiddenMasterShape )
156 , mbLockedCanvas( pSourceShape->mbLockedCanvas )
157 , mbWps( pSourceShape->mbWps )
158 , mbTextBox( pSourceShape->mbTextBox )
159 , maLinkedTxbxAttr()
160 , mbHasLinkedTxbx(false)
161 , maDiagramDoms( pSourceShape->maDiagramDoms )
164 Shape::~Shape()
168 table::TablePropertiesPtr Shape::getTableProperties()
170 if ( !mpTablePropertiesPtr.get() )
171 mpTablePropertiesPtr.reset( new table::TableProperties() );
172 return mpTablePropertiesPtr;
175 void Shape::setDefaults(bool bHeight)
177 maDefaultShapeProperties.setProperty(PROP_TextAutoGrowHeight, false);
178 maDefaultShapeProperties.setProperty(PROP_TextWordWrap, true);
179 maDefaultShapeProperties.setProperty(PROP_TextLeftDistance, static_cast< sal_Int32 >( 250 ));
180 maDefaultShapeProperties.setProperty(PROP_TextUpperDistance, static_cast< sal_Int32 >( 125 ));
181 maDefaultShapeProperties.setProperty(PROP_TextRightDistance, static_cast< sal_Int32 >( 250 ));
182 maDefaultShapeProperties.setProperty(PROP_TextLowerDistance, static_cast< sal_Int32 >( 125 ));
183 if (bHeight)
184 maDefaultShapeProperties.setProperty(PROP_CharHeight, static_cast< float >( 18.0 ));
185 maDefaultShapeProperties.setProperty(PROP_TextVerticalAdjust, TextVerticalAdjust_TOP);
186 maDefaultShapeProperties.setProperty(PROP_ParaAdjust, static_cast< sal_Int16 >( ParagraphAdjust_LEFT )); // check for RTL?
189 ::oox::vml::OleObjectInfo& Shape::setOleObjectType()
191 OSL_ENSURE( meFrameType == FRAMETYPE_GENERIC, "Shape::setOleObjectType - multiple frame types" );
192 meFrameType = FRAMETYPE_OLEOBJECT;
193 mxOleObjectInfo.reset( new ::oox::vml::OleObjectInfo( true ) );
194 return *mxOleObjectInfo;
197 ChartShapeInfo& Shape::setChartType( bool bEmbedShapes )
199 OSL_ENSURE( meFrameType == FRAMETYPE_GENERIC, "Shape::setChartType - multiple frame types" );
200 meFrameType = FRAMETYPE_CHART;
201 msServiceName = "com.sun.star.drawing.OLE2Shape";
202 mxChartShapeInfo.reset( new ChartShapeInfo( bEmbedShapes ) );
203 return *mxChartShapeInfo;
206 void Shape::setDiagramType()
208 OSL_ENSURE( meFrameType == FRAMETYPE_GENERIC, "Shape::setDiagramType - multiple frame types" );
209 meFrameType = FRAMETYPE_DIAGRAM;
210 msServiceName = "com.sun.star.drawing.GroupShape";
211 mnSubType = 0;
214 void Shape::setTableType()
216 OSL_ENSURE( meFrameType == FRAMETYPE_GENERIC, "Shape::setTableType - multiple frame types" );
217 meFrameType = FRAMETYPE_TABLE;
218 msServiceName = "com.sun.star.drawing.TableShape";
219 mnSubType = 0;
222 void Shape::setServiceName( const sal_Char* pServiceName )
224 if ( pServiceName )
225 msServiceName = OUString::createFromAscii( pServiceName );
228 const ShapeStyleRef* Shape::getShapeStyleRef( sal_Int32 nRefType ) const
230 ShapeStyleRefMap::const_iterator aIt = maShapeStyleRefs.find( nRefType );
231 return (aIt == maShapeStyleRefs.end()) ? 0 : &aIt->second;
234 void Shape::addShape(
235 ::oox::core::XmlFilterBase& rFilterBase,
236 const Theme* pTheme,
237 const Reference< XShapes >& rxShapes,
238 const basegfx::B2DHomMatrix& aTransformation,
239 FillProperties& rShapeOrParentShapeFillProps,
240 const awt::Rectangle* pShapeRect,
241 ShapeIdMap* pShapeMap )
243 SAL_INFO("oox.drawingml", OSL_THIS_FUNC << " id: " << msId);
247 OUString sServiceName( msServiceName );
248 if( !sServiceName.isEmpty() )
250 basegfx::B2DHomMatrix aMatrix( aTransformation );
251 Reference< XShape > xShape( createAndInsert( rFilterBase, sServiceName, pTheme, rxShapes, pShapeRect, false, false, aMatrix, rShapeOrParentShapeFillProps ) );
253 if( pShapeMap && !msId.isEmpty() )
255 (*pShapeMap)[ msId ] = shared_from_this();
258 // if this is a group shape, we have to add also each child shape
259 Reference< XShapes > xShapes( xShape, UNO_QUERY );
260 if ( xShapes.is() )
261 addChildren( rFilterBase, *this, pTheme, xShapes, pShapeRect ? *pShapeRect : awt::Rectangle( maPosition.X, maPosition.Y, maSize.Width, maSize.Height ), pShapeMap, aMatrix );
263 if( meFrameType == FRAMETYPE_DIAGRAM )
265 if( !SvtFilterOptions::Get().IsSmartArt2Shape() )
266 keepDiagramCompatibilityInfo( rFilterBase );
270 catch( const Exception& e )
272 SAL_WARN( "oox.drawingml", OSL_THIS_FUNC << "Exception: " << e.Message );
276 void Shape::setLockedCanvas(bool bLockedCanvas)
278 mbLockedCanvas = bLockedCanvas;
281 void Shape::setWps(bool bWps)
283 mbWps = bWps;
286 void Shape::setTextBox(bool bTextBox)
288 mbTextBox = bTextBox;
291 void Shape::applyShapeReference( const Shape& rReferencedShape, bool bUseText )
293 SAL_INFO("oox", OSL_THIS_FUNC << "apply shape reference: " << rReferencedShape.msId << " to shape id: " << msId);
295 if ( rReferencedShape.mpTextBody.get() && bUseText )
296 mpTextBody = TextBodyPtr( new TextBody( *rReferencedShape.mpTextBody.get() ) );
297 else
298 mpTextBody.reset();
299 maShapeProperties = rReferencedShape.maShapeProperties;
300 mpShapeRefLinePropPtr = LinePropertiesPtr( new LineProperties( *rReferencedShape.mpLinePropertiesPtr.get() ) );
301 mpShapeRefFillPropPtr = FillPropertiesPtr( new FillProperties( *rReferencedShape.mpFillPropertiesPtr.get() ) );
302 mpCustomShapePropertiesPtr = CustomShapePropertiesPtr( new CustomShapeProperties( *rReferencedShape.mpCustomShapePropertiesPtr.get() ) );
303 mpTablePropertiesPtr = table::TablePropertiesPtr( rReferencedShape.mpTablePropertiesPtr.get() ? new table::TableProperties( *rReferencedShape.mpTablePropertiesPtr.get() ) : NULL );
304 mpShapeRefEffectPropPtr = EffectPropertiesPtr( new EffectProperties( *rReferencedShape.mpEffectPropertiesPtr.get() ) );
305 mpMasterTextListStyle = TextListStylePtr( new TextListStyle( *rReferencedShape.mpMasterTextListStyle.get() ) );
306 maShapeStyleRefs = rReferencedShape.maShapeStyleRefs;
307 maSize = rReferencedShape.maSize;
308 maPosition = rReferencedShape.maPosition;
309 mnRotation = rReferencedShape.mnRotation;
310 mbFlipH = rReferencedShape.mbFlipH;
311 mbFlipV = rReferencedShape.mbFlipV;
312 mbHidden = rReferencedShape.mbHidden;
315 void Shape::addChildren( ::oox::core::XmlFilterBase& rFilterBase,
316 const Theme* pTheme,
317 const Reference< XShapes >& rxShapes,
318 basegfx::B2DHomMatrix& aTransformation,
319 const awt::Rectangle* pShapeRect,
320 ShapeIdMap* pShapeMap )
322 addChildren(rFilterBase, *this, pTheme, rxShapes,
323 pShapeRect ?
324 *pShapeRect :
325 awt::Rectangle( maPosition.X, maPosition.Y, maSize.Width, maSize.Height ),
326 pShapeMap, aTransformation);
329 struct ActionLockGuard
331 explicit ActionLockGuard(Reference<drawing::XShape> const& xShape)
332 : m_xLockable(xShape, UNO_QUERY)
334 if (m_xLockable.is()) {
335 m_xLockable->addActionLock();
338 ~ActionLockGuard()
340 if (m_xLockable.is()) {
341 m_xLockable->removeActionLock();
344 private:
345 Reference<document::XActionLockable> m_xLockable;
348 // for group shapes, the following method is also adding each child
349 void Shape::addChildren(
350 XmlFilterBase& rFilterBase,
351 Shape& rMaster,
352 const Theme* pTheme,
353 const Reference< XShapes >& rxShapes,
354 const awt::Rectangle&,
355 ShapeIdMap* pShapeMap,
356 const basegfx::B2DHomMatrix& aTransformation )
358 basegfx::B2DHomMatrix aChildTransformation;
360 aChildTransformation.translate(-maChPosition.X, -maChPosition.Y);
361 aChildTransformation.scale(1/(maChSize.Width ? maChSize.Width : 1.0), 1/(maChSize.Height ? maChSize.Height : 1.0));
363 // Child position and size is typically non-zero, but it's allowed to have
364 // it like that, and in that case Word ignores the parent transformation
365 // (excluding translate component).
366 if (!mbWps || maChPosition.X || maChPosition.Y || maChSize.Width || maChSize.Height)
368 aChildTransformation *= aTransformation;
370 else
372 basegfx::B2DVector aScale, aTranslate;
373 double fRotate, fShearX;
374 aTransformation.decompose(aScale, aTranslate, fRotate, fShearX);
375 aChildTransformation.translate(aTranslate.getX(), aTranslate.getY());
378 SAL_INFO("oox.drawingml", OSL_THIS_FUNC << "parent matrix:\n"
379 << aChildTransformation.get(0, 0) << " "
380 << aChildTransformation.get(0, 1) << " "
381 << aChildTransformation.get(0, 2) << "\n"
382 << aChildTransformation.get(1, 0) << " "
383 << aChildTransformation.get(1, 1) << " "
384 << aChildTransformation.get(1, 2) << "\n"
385 << aChildTransformation.get(2, 0) << " "
386 << aChildTransformation.get(2, 1) << " "
387 << aChildTransformation.get(2, 2));
389 std::vector< ShapePtr >::iterator aIter( rMaster.maChildren.begin() );
390 while( aIter != rMaster.maChildren.end() ) {
391 (*aIter)->setMasterTextListStyle( mpMasterTextListStyle );
392 (*aIter++)->addShape( rFilterBase, pTheme, rxShapes, aChildTransformation, getFillProperties(), NULL, pShapeMap );
396 Reference< XShape > Shape::createAndInsert(
397 ::oox::core::XmlFilterBase& rFilterBase,
398 const OUString& rServiceName,
399 const Theme* pTheme,
400 const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes,
401 const awt::Rectangle* /* pShapeRect */,
402 bool bClearText,
403 bool bDoNotInsertEmptyTextBody,
404 basegfx::B2DHomMatrix& aParentTransformation,
405 FillProperties& rShapeOrParentShapeFillProps )
407 bool bIsEmbMedia = false;
408 SAL_INFO("oox.drawingml", OSL_THIS_FUNC << " id: " << msId);
410 // tdf#90403 PowerPoint ignores a:ext cx and cy values of p:xfrm, and uses real table width and height
411 if ( mpTablePropertiesPtr.get() && rServiceName == "com.sun.star.drawing.TableShape" )
413 maSize.Width = 0;
414 for( std::vector< sal_Int32 >::const_iterator aTableColIter(mpTablePropertiesPtr->getTableGrid().begin());
415 aTableColIter != mpTablePropertiesPtr->getTableGrid().end(); ++aTableColIter )
417 maSize.Width += *aTableColIter;
419 maSize.Height = 0;
420 for( std::vector< ::oox::drawingml::table::TableRow >::const_iterator aTableRowIter(mpTablePropertiesPtr->getTableRows().begin());
421 aTableRowIter != mpTablePropertiesPtr->getTableRows().end(); ++aTableRowIter )
423 maSize.Height += (*aTableRowIter).getHeight();
427 awt::Rectangle aShapeRectHmm( maPosition.X / EMU_PER_HMM, maPosition.Y / EMU_PER_HMM, maSize.Width / EMU_PER_HMM, maSize.Height / EMU_PER_HMM );
429 OUString aServiceName;
430 if( rServiceName == "com.sun.star.drawing.GraphicObjectShape" &&
431 mpGraphicPropertiesPtr && !mpGraphicPropertiesPtr->m_sMediaPackageURL.isEmpty())
433 aServiceName = finalizeServiceName( rFilterBase, "com.sun.star.presentation.MediaShape", aShapeRectHmm );
434 bIsEmbMedia = true;
436 else
438 aServiceName = finalizeServiceName( rFilterBase, rServiceName, aShapeRectHmm );
440 bool bIsCustomShape = ( aServiceName == "com.sun.star.drawing.CustomShape" ||
441 aServiceName == "com.sun.star.drawing.ConnectorShape" );
442 bool bUseRotationTransform = ( !mbWps ||
443 aServiceName == "com.sun.star.drawing.LineShape" ||
444 aServiceName == "com.sun.star.drawing.GroupShape" ||
445 mbFlipH ||
446 mbFlipV );
448 basegfx::B2DHomMatrix aTransformation;
450 if( maSize.Width != 1 || maSize.Height != 1)
452 // take care there are no zeros used by error
453 aTransformation.scale(
454 maSize.Width ? maSize.Width : 1.0,
455 maSize.Height ? maSize.Height : 1.0 );
458 if( mbFlipH || mbFlipV || mnRotation != 0)
460 // calculate object's center
461 basegfx::B2DPoint aCenter(0.5, 0.5);
462 aCenter *= aTransformation;
464 // center object at origin
465 aTransformation.translate( -aCenter.getX(), -aCenter.getY() );
467 if( !bIsCustomShape && ( mbFlipH || mbFlipV ) )
469 // mirror around object's center
470 aTransformation.scale( mbFlipH ? -1.0 : 1.0, mbFlipV ? -1.0 : 1.0 );
473 if( bUseRotationTransform && mnRotation != 0 )
475 // rotate around object's center
476 aTransformation.rotate( F_PI180 * ( (double)mnRotation / 60000.0 ) );
479 // move object back from center
480 aTransformation.translate( aCenter.getX(), aCenter.getY() );
483 bool bInGroup = !aParentTransformation.isIdentity();
484 if( maPosition.X != 0 || maPosition.Y != 0)
486 // if global position is used, add it to transformation
487 if (mbWps && !bInGroup)
488 aTransformation.translate( maPosition.X * EMU_PER_HMM, maPosition.Y * EMU_PER_HMM);
489 else
490 aTransformation.translate( maPosition.X, maPosition.Y );
493 aTransformation = aParentTransformation*aTransformation;
494 aParentTransformation = aTransformation;
495 aTransformation.scale(1/double(EMU_PER_HMM), 1/double(EMU_PER_HMM));
497 // special for lineshape
498 if ( aServiceName == "com.sun.star.drawing.LineShape" )
500 ::basegfx::B2DPolygon aPoly;
501 aPoly.insert( 0, ::basegfx::B2DPoint( 0, 0 ) );
502 aPoly.insert( 1, ::basegfx::B2DPoint( maSize.Width ? 1 : 0, maSize.Height ? 1 : 0 ) );
503 aPoly.transform( aTransformation );
505 // now creating the corresponding PolyPolygon
506 sal_Int32 i, nNumPoints = aPoly.count();
507 uno::Sequence< awt::Point > aPointSequence( nNumPoints );
508 awt::Point* pPoints = aPointSequence.getArray();
509 uno::Reference<lang::XServiceInfo> xModelInfo(rFilterBase.getModel(), uno::UNO_QUERY);
510 bool bIsWriter = xModelInfo->supportsService("com.sun.star.text.TextDocument");
511 for( i = 0; i < nNumPoints; ++i )
513 const ::basegfx::B2DPoint aPoint( aPoly.getB2DPoint( i ) );
514 if (bIsWriter && bInGroup)
515 // Writer's draw page is in twips, and these points get passed
516 // to core without any unit conversion when Writer
517 // postprocesses only the group shape itself.
518 pPoints[i] = awt::Point(static_cast<sal_Int32>(convertMm100ToTwip(aPoint.getX())), static_cast<sal_Int32>(convertMm100ToTwip(aPoint.getY())));
519 else
520 pPoints[i] = awt::Point(static_cast<sal_Int32>(aPoint.getX()), static_cast<sal_Int32>(aPoint.getY()));
522 uno::Sequence< uno::Sequence< awt::Point > > aPolyPolySequence( 1 );
523 aPolyPolySequence.getArray()[ 0 ] = aPointSequence;
525 maShapeProperties.setProperty(PROP_PolyPolygon, aPolyPolySequence);
527 else if ( aServiceName == "com.sun.star.drawing.ConnectorShape" )
529 ::basegfx::B2DPolygon aPoly;
530 aPoly.insert( 0, ::basegfx::B2DPoint( 0, 0 ) );
531 aPoly.insert( 1, ::basegfx::B2DPoint( maSize.Width ? 1 : 0, maSize.Height ? 1 : 0 ) );
532 aPoly.transform( aTransformation );
534 basegfx::B2DPoint aStartPosition( aPoly.getB2DPoint( 0 ) );
535 basegfx::B2DPoint aEndPosition( aPoly.getB2DPoint( 1 ) );
536 awt::Point aAWTStartPosition( static_cast< sal_Int32 >( aStartPosition.getX() ), static_cast< sal_Int32 >( aStartPosition.getY() ) );
537 awt::Point aAWTEndPosition( static_cast< sal_Int32 >( aEndPosition.getX() ), static_cast< sal_Int32 >( aEndPosition.getY() ) );
539 maShapeProperties.setProperty(PROP_StartPosition, aAWTStartPosition);
540 maShapeProperties.setProperty(PROP_EndPosition, aAWTEndPosition);
542 else
544 // now set transformation for this object
545 HomogenMatrix3 aMatrix;
547 aMatrix.Line1.Column1 = aTransformation.get(0,0);
548 aMatrix.Line1.Column2 = aTransformation.get(0,1);
549 aMatrix.Line1.Column3 = aTransformation.get(0,2);
551 aMatrix.Line2.Column1 = aTransformation.get(1,0);
552 aMatrix.Line2.Column2 = aTransformation.get(1,1);
553 aMatrix.Line2.Column3 = aTransformation.get(1,2);
555 aMatrix.Line3.Column1 = aTransformation.get(2,0);
556 aMatrix.Line3.Column2 = aTransformation.get(2,1);
557 aMatrix.Line3.Column3 = aTransformation.get(2,2);
559 maShapeProperties.setProperty(PROP_Transformation, aMatrix);
562 Reference< lang::XMultiServiceFactory > xServiceFact( rFilterBase.getModel(), UNO_QUERY_THROW );
563 if ( !mxShape.is() )
564 mxShape = Reference< drawing::XShape >( xServiceFact->createInstance( aServiceName ), UNO_QUERY_THROW );
566 Reference< XPropertySet > xSet( mxShape, UNO_QUERY );
567 if( mxShape.is() && xSet.is() )
569 if( !msName.isEmpty() )
571 Reference< container::XNamed > xNamed( mxShape, UNO_QUERY );
572 if( xNamed.is() )
573 xNamed->setName( msName );
575 if (aServiceName != "com.sun.star.text.TextFrame")
576 rxShapes->add( mxShape );
578 if ( mbHidden || mbHiddenMasterShape )
580 SAL_INFO("oox.drawingml", OSL_THIS_FUNC << "invisible shape with id: " << msId);
581 const OUString sVisible( "Visible" );
582 xSet->setPropertyValue( sVisible, Any( sal_False ) );
585 ActionLockGuard const alg(mxShape);
587 // sj: removing default text of placeholder objects such as SlideNumberShape or HeaderShape
588 if ( bClearText )
590 uno::Reference< text::XText > xText( mxShape, uno::UNO_QUERY );
591 if ( xText.is() )
593 OUString aEmpty;
594 xText->setString( aEmpty );
598 const GraphicHelper& rGraphicHelper = rFilterBase.getGraphicHelper();
600 LineProperties aLineProperties;
601 aLineProperties.maLineFill.moFillType = XML_noFill;
602 sal_Int32 nLinePhClr = -1;
603 FillProperties aFillProperties;
604 aFillProperties.moFillType = XML_noFill;
605 sal_Int32 nFillPhClr = -1;
606 EffectProperties aEffectProperties;
607 // TODO: use ph color when applying effect properties
608 //sal_Int32 nEffectPhClr = -1;
610 // First apply reference shape's properties (shape on the master slide)
611 aFillProperties.assignUsed( *mpShapeRefFillPropPtr );
612 aLineProperties.assignUsed( *mpShapeRefLinePropPtr );
613 aEffectProperties.assignUsed( *mpShapeRefEffectPropPtr );
615 if( pTheme )
617 if( const ShapeStyleRef* pLineRef = getShapeStyleRef( XML_lnRef ) )
619 if( const LineProperties* pLineProps = pTheme->getLineStyle( pLineRef->mnThemedIdx ) )
620 aLineProperties.assignUsed( *pLineProps );
621 nLinePhClr = pLineRef->maPhClr.getColor( rGraphicHelper );
623 // Store style-related properties to InteropGrabBag to be able to export them back
624 Sequence< PropertyValue > aProperties( 7 );
625 PUT_PROP( aProperties, 0, "SchemeClr", pLineRef->maPhClr.getSchemeName() );
626 PUT_PROP( aProperties, 1, "Idx", pLineRef->mnThemedIdx );
627 PUT_PROP( aProperties, 2, "Color", nLinePhClr );
628 PUT_PROP( aProperties, 3, "LineStyle", aLineProperties.getLineStyle() );
629 PUT_PROP( aProperties, 4, "LineJoint", aLineProperties.getLineJoint() );
630 PUT_PROP( aProperties, 5, "LineWidth", aLineProperties.getLineWidth() );
631 PUT_PROP( aProperties, 6, "Transformations", pLineRef->maPhClr.getTransformations() );
632 putPropertyToGrabBag( "StyleLnRef", Any( aProperties ) );
634 if( const ShapeStyleRef* pFillRef = getShapeStyleRef( XML_fillRef ) )
636 if( const FillProperties* pFillProps = pTheme->getFillStyle( pFillRef->mnThemedIdx ) )
637 aFillProperties.assignUsed( *pFillProps );
638 nFillPhClr = pFillRef->maPhClr.getColor( rGraphicHelper );
640 OUString sColorScheme = pFillRef->maPhClr.getSchemeName();
641 if( !sColorScheme.isEmpty() )
643 Sequence< PropertyValue > aProperties(4);
644 PUT_PROP( aProperties, 0, "SchemeClr", sColorScheme );
645 PUT_PROP( aProperties, 1, "Idx", pFillRef->mnThemedIdx );
646 PUT_PROP( aProperties, 2, "Color", nFillPhClr );
647 PUT_PROP( aProperties, 3, "Transformations", pFillRef->maPhClr.getTransformations() );
649 putPropertyToGrabBag( "StyleFillRef", Any( aProperties ) );
652 if( const ShapeStyleRef* pEffectRef = getShapeStyleRef( XML_effectRef ) )
654 if( const EffectProperties* pEffectProps = pTheme->getEffectStyle( pEffectRef->mnThemedIdx ) )
655 aEffectProperties.assignUsed( *pEffectProps );
656 // TODO: use ph color when applying effect properties
657 // nEffectPhClr = pEffectRef->maPhClr.getColor( rGraphicHelper );
659 // Store style-related properties to InteropGrabBag to be able to export them back
660 Sequence< PropertyValue > aProperties( 3 );
661 PUT_PROP( aProperties, 0, "SchemeClr", pEffectRef->maPhClr.getSchemeName() );
662 PUT_PROP( aProperties, 1, "Idx", pEffectRef->mnThemedIdx );
663 PUT_PROP( aProperties, 2, "Transformations", pEffectRef->maPhClr.getTransformations() );
664 putPropertyToGrabBag( "StyleEffectRef", Any( aProperties ) );
668 aLineProperties.assignUsed( getLineProperties() );
670 // group fill inherits from parent
671 if ( getFillProperties().moFillType.has() && getFillProperties().moFillType.get() == XML_grpFill )
672 getFillProperties().assignUsed( rShapeOrParentShapeFillProps );
673 aFillProperties.assignUsed( getFillProperties() );
674 aEffectProperties.assignUsed ( getEffectProperties() );
676 ShapePropertyMap aShapeProps( rFilterBase.getModelObjectHelper() );
678 // add properties from textbody to shape properties
679 if( mpTextBody.get() )
681 mpTextBody->getTextProperties().pushRotationAdjustments();
682 aShapeProps.assignUsed( mpTextBody->getTextProperties().maPropertyMap );
683 // Push char properties as well - specifically useful when this is a placeholder
684 if( mpMasterTextListStyle && mpMasterTextListStyle->getListStyle()[0]->getTextCharacterProperties().moHeight.has() )
685 aShapeProps.setProperty(PROP_CharHeight, GetFontHeight( mpMasterTextListStyle->getListStyle()[0]->getTextCharacterProperties().moHeight.get() ));
688 // applying properties
689 aShapeProps.assignUsed( getShapeProperties() );
690 aShapeProps.assignUsed( maDefaultShapeProperties );
691 if ( bIsEmbMedia || aServiceName == "com.sun.star.drawing.GraphicObjectShape" || aServiceName == "com.sun.star.drawing.OLE2Shape" )
692 mpGraphicPropertiesPtr->pushToPropMap( aShapeProps, rGraphicHelper );
693 if ( mpTablePropertiesPtr.get() && aServiceName == "com.sun.star.drawing.TableShape" )
694 mpTablePropertiesPtr->pushToPropSet( rFilterBase, xSet, mpMasterTextListStyle );
695 aFillProperties.pushToPropMap( aShapeProps, rGraphicHelper, mnRotation, nFillPhClr, mbFlipH, mbFlipV );
696 aLineProperties.pushToPropMap( aShapeProps, rGraphicHelper, nLinePhClr );
697 // TODO: use ph color when applying effect properties
698 aEffectProperties.pushToPropMap( aShapeProps, rGraphicHelper );
700 // applying autogrowheight property before setting shape size, because
701 // the shape size might be changed if currently autogrowheight is true
702 // we must also check that the PropertySet supports the property.
703 Reference< XPropertySetInfo > xSetInfo( xSet->getPropertySetInfo() );
704 const OUString& rPropName = PropertyMap::getPropertyName( PROP_TextAutoGrowHeight );
705 if( xSetInfo.is() && xSetInfo->hasPropertyByName( rPropName ) )
706 if( aShapeProps.hasProperty( PROP_TextAutoGrowHeight ) )
707 xSet->setPropertyValue( rPropName, Any( false ) );
709 // do not set properties at a group shape (this causes
710 // assertions from svx) ...
711 if( aServiceName != "com.sun.star.drawing.GroupShape" )
713 if (aServiceName == "com.sun.star.text.TextFrame")
715 if (mpCustomShapePropertiesPtr && mpCustomShapePropertiesPtr->getShapeTypeOverride())
717 uno::Reference<beans::XPropertySet> propertySet (mxShape, uno::UNO_QUERY);
718 uno::Sequence<beans::PropertyValue> aGrabBag;
719 propertySet->getPropertyValue("FrameInteropGrabBag") >>= aGrabBag;
720 sal_Int32 length = aGrabBag.getLength();
721 aGrabBag.realloc( length+1);
722 aGrabBag[length].Name = "mso-orig-shape-type";
723 const uno::Sequence< sal_Int8 > aNameSeq =
724 mpCustomShapePropertiesPtr->getShapePresetTypeName();
725 OUString sShapePresetTypeName(reinterpret_cast< const char* >(
726 aNameSeq.getConstArray()), aNameSeq.getLength(), RTL_TEXTENCODING_UTF8);
727 aGrabBag[length].Value = uno::makeAny(sShapePresetTypeName);
728 propertySet->setPropertyValue("FrameInteropGrabBag",uno::makeAny(aGrabBag));
730 //If the text box has links then save the link information so that
731 //it can be accessed in DomainMapper_Impl.cxx while chaining the text frames.
732 if (this->isLinkedTxbx())
734 uno::Reference<beans::XPropertySet> propertySet (mxShape, uno::UNO_QUERY);
735 uno::Sequence<beans::PropertyValue> aGrabBag;
736 propertySet->getPropertyValue("FrameInteropGrabBag") >>= aGrabBag;
737 sal_Int32 length = aGrabBag.getLength();
738 aGrabBag.realloc( length + 3 );
739 aGrabBag[length].Name = "TxbxHasLink";
740 aGrabBag[length].Value = uno::makeAny(this->isLinkedTxbx());
741 aGrabBag[length + 1 ].Name = "Txbx-Id";
742 aGrabBag[length + 1 ].Value = uno::makeAny(this->getLinkedTxbxAttributes().id);
743 aGrabBag[length + 2 ].Name = "Txbx-Seq";
744 aGrabBag[length + 2 ].Value = uno::makeAny(this->getLinkedTxbxAttributes().seq);
745 propertySet->setPropertyValue("FrameInteropGrabBag",uno::makeAny(aGrabBag));
748 // TextFrames have BackColor, not FillColor
749 if (aShapeProps.hasProperty(PROP_FillColor))
751 aShapeProps.setProperty(PROP_BackColor, aShapeProps.getProperty(PROP_FillColor));
752 aShapeProps.erase(PROP_FillColor);
754 // TextFrames have BackColorTransparency, not FillTransparence
755 if (aShapeProps.hasProperty(PROP_FillTransparence))
757 aShapeProps.setProperty(PROP_BackColorTransparency, aShapeProps.getProperty(PROP_FillTransparence));
758 aShapeProps.erase(PROP_FillTransparence);
760 // TextFrames have BackGrahicURL, not FillBitmapURL
761 if (aShapeProps.hasProperty(PROP_FillBitmapURL))
763 aShapeProps.setProperty(PROP_BackGraphicURL, aShapeProps.getProperty(PROP_FillBitmapURL));
764 aShapeProps.erase(PROP_FillBitmapURL);
766 if (aShapeProps.hasProperty(PROP_FillBitmapName))
768 uno::Any aAny = aShapeProps.getProperty(PROP_FillBitmapName);
769 aShapeProps.setProperty(PROP_BackGraphicURL, rFilterBase.getModelObjectHelper().getFillBitmapUrl( aAny.get<OUString>() ));
770 // aShapeProps.erase(PROP_FillBitmapName); // Maybe, leave the name as well
772 // And no LineColor property; individual borders can have colors
773 if (aShapeProps.hasProperty(PROP_LineColor))
775 uno::Reference<beans::XPropertySet> xPropertySet(mxShape, uno::UNO_QUERY);
776 static const sal_Int32 aBorders[] =
778 PROP_TopBorder, PROP_LeftBorder, PROP_BottomBorder, PROP_RightBorder
780 for (unsigned int i = 0; i < SAL_N_ELEMENTS(aBorders); ++i)
782 css::table::BorderLine2 aBorderLine = xPropertySet->getPropertyValue(PropertyMap::getPropertyName(aBorders[i])).get<css::table::BorderLine2>();
783 aBorderLine.Color = aShapeProps.getProperty(PROP_LineColor).get<sal_Int32>();
784 if (aLineProperties.moLineWidth.has())
785 aBorderLine.LineWidth = convertEmuToHmm(aLineProperties.moLineWidth.get());
786 aShapeProps.setProperty(aBorders[i], uno::makeAny(aBorderLine));
788 aShapeProps.erase(PROP_LineColor);
790 if(mnRotation)
792 uno::Reference<beans::XPropertySet> xPropertySet(mxShape, uno::UNO_QUERY);
793 const OUString aGrabBagPropName = "FrameInteropGrabBag";
794 uno::Sequence<beans::PropertyValue> aGrabBag;
795 xPropertySet->getPropertyValue(aGrabBagPropName) >>= aGrabBag;
796 beans::PropertyValue aPair;
797 aPair.Name = "mso-rotation-angle";
798 aPair.Value = uno::makeAny(mnRotation);
799 if (aGrabBag.hasElements())
801 sal_Int32 nLength = aGrabBag.getLength();
802 aGrabBag.realloc(nLength + 1);
803 aGrabBag[nLength] = aPair;
805 else
807 aGrabBag.realloc(1);
808 aGrabBag[0] = aPair;
810 xPropertySet->setPropertyValue(aGrabBagPropName, uno::makeAny(aGrabBag));
812 // TextFrames have ShadowFormat, not individual shadow properties.
813 boost::optional<sal_Int32> oShadowDistance;
814 if (aShapeProps.hasProperty(PROP_ShadowXDistance))
816 oShadowDistance = aShapeProps.getProperty(PROP_ShadowXDistance).get<sal_Int32>();
817 aShapeProps.erase(PROP_ShadowXDistance);
819 if (aShapeProps.hasProperty(PROP_ShadowYDistance))
821 // There is a single 'dist' attribute, so no need to count the avg of x and y.
822 aShapeProps.erase(PROP_ShadowYDistance);
824 boost::optional<sal_Int32> oShadowColor;
825 if (aShapeProps.hasProperty(PROP_ShadowColor))
827 oShadowColor = aShapeProps.getProperty(PROP_ShadowColor).get<sal_Int32>();
828 aShapeProps.erase(PROP_ShadowColor);
830 if (aShapeProps.hasProperty(PROP_Shadow))
831 aShapeProps.erase(PROP_Shadow);
833 if (oShadowDistance || oShadowColor || aEffectProperties.maShadow.moShadowDir.has())
835 css::table::ShadowFormat aFormat;
836 if (oShadowColor)
837 aFormat.Color = *oShadowColor;
838 if (aEffectProperties.maShadow.moShadowDir.has())
840 css::table::ShadowLocation nLocation = css::table::ShadowLocation_NONE;
841 switch (aEffectProperties.maShadow.moShadowDir.get())
843 case 13500000:
844 nLocation = css::table::ShadowLocation_TOP_LEFT;
845 break;
846 case 18900000:
847 nLocation = css::table::ShadowLocation_TOP_RIGHT;
848 break;
849 case 8100000:
850 nLocation = css::table::ShadowLocation_BOTTOM_LEFT;
851 break;
852 case 2700000:
853 nLocation = css::table::ShadowLocation_BOTTOM_RIGHT;
854 break;
856 aFormat.Location = nLocation;
858 aFormat.ShadowWidth = *oShadowDistance;
859 aShapeProps.setProperty(PROP_ShadowFormat, uno::makeAny(aFormat));
862 else if (mbTextBox)
864 aShapeProps.setProperty(PROP_TextBox, uno::makeAny(true));
867 if (aServiceName != "com.sun.star.text.TextFrame" && isLinkedTxbx())
869 uno::Reference<beans::XPropertySet> propertySet (mxShape, uno::UNO_QUERY);
870 uno::Sequence<beans::PropertyValue> aGrabBag;
871 propertySet->getPropertyValue("InteropGrabBag") >>= aGrabBag;
872 sal_Int32 length = aGrabBag.getLength();
873 aGrabBag.realloc( length + 3 );
874 aGrabBag[length].Name = "TxbxHasLink";
875 aGrabBag[length].Value = uno::makeAny(this->isLinkedTxbx());
876 aGrabBag[length + 1 ].Name = "Txbx-Id";
877 aGrabBag[length + 1 ].Value = uno::makeAny(this->getLinkedTxbxAttributes().id);
878 aGrabBag[length + 2 ].Name = "Txbx-Seq";
879 aGrabBag[length + 2 ].Value = uno::makeAny(this->getLinkedTxbxAttributes().seq);
880 propertySet->setPropertyValue("InteropGrabBag",uno::makeAny(aGrabBag));
883 PropertySet( xSet ).setProperties( aShapeProps );
884 if (mbLockedCanvas)
886 putPropertyToGrabBag( "LockedCanvas", Any( true ) );
887 if (aServiceName == "com.sun.star.drawing.LineShape")
889 // It seems the position and size for lines inside a locked canvas is absolute.
890 mxShape->setPosition(awt::Point(aShapeRectHmm.X, aShapeRectHmm.Y));
891 mxShape->setSize(awt::Size(aShapeRectHmm.Width, aShapeRectHmm.Height));
895 // Store original fill and line colors of the shape and the theme color name to InteropGrabBag
896 Sequence< PropertyValue > aProperties( 6 ); //allocate the maximum possible number of slots
897 sal_Int32 nSize = 2;
898 PUT_PROP( aProperties, 0, "OriginalSolidFillClr", aShapeProps.getProperty(PROP_FillColor) );
899 PUT_PROP( aProperties, 1, "OriginalLnSolidFillClr", aShapeProps.getProperty(PROP_LineColor) );
900 OUString sColorFillScheme = aFillProperties.maFillColor.getSchemeName();
901 if( !aFillProperties.maFillColor.isPlaceHolder() && !sColorFillScheme.isEmpty() )
903 PUT_PROP( aProperties, nSize, "SpPrSolidFillSchemeClr", sColorFillScheme );
904 nSize++;
905 PUT_PROP( aProperties, nSize, "SpPrSolidFillSchemeClrTransformations",
906 aFillProperties.maFillColor.getTransformations() );
907 nSize++;
909 OUString sLnColorFillScheme = aLineProperties.maLineFill.maFillColor.getSchemeName();
910 if( !aLineProperties.maLineFill.maFillColor.isPlaceHolder() && !sLnColorFillScheme.isEmpty() )
912 PUT_PROP( aProperties, nSize, "SpPrLnSolidFillSchemeClr", sLnColorFillScheme );
913 nSize++;
914 PUT_PROP( aProperties, nSize, "SpPrLnSolidFillSchemeClrTransformations",
915 aLineProperties.maLineFill.maFillColor.getTransformations() );
916 nSize++;
918 aProperties.realloc( nSize ); //shrink the Sequence if we didn't use all the slots
919 putPropertiesToGrabBag( aProperties );
921 // Store original gradient fill of the shape to InteropGrabBag
922 // LibreOffice doesn't support all the kinds of gradient so we save its complete definition
923 if( aShapeProps.hasProperty( PROP_FillGradient ) )
925 Sequence< PropertyValue > aGradientStops( aFillProperties.maGradientProps.maGradientStops.size() );
926 ::std::map< double, Color >::iterator aIt = aFillProperties.maGradientProps.maGradientStops.begin();
927 for( sal_uInt32 i = 0; i < aFillProperties.maGradientProps.maGradientStops.size(); ++i )
928 { // for each stop in the gradient definition:
930 // save position
931 Sequence< PropertyValue > aGradientStop( 3 );
932 PUT_PROP( aGradientStop, 0, "Pos", aIt->first );
934 OUString sStopColorScheme = aIt->second.getSchemeName();
935 if( sStopColorScheme.isEmpty() )
937 // save RGB color
938 PUT_PROP( aGradientStop, 1, "RgbClr", aIt->second.getColor( rGraphicHelper, nFillPhClr ) );
939 // in the case of a RGB color, transformations are already applied to
940 // the color with the exception of alpha transformations. We only need
941 // to keep the transparency value to calculate the alpha value later.
942 if( aIt->second.hasTransparency() )
944 PUT_PROP( aGradientStop, 2, "Transparency", aIt->second.getTransparency() );
947 else
949 // save color with scheme name
950 PUT_PROP( aGradientStop, 1, "SchemeClr", sStopColorScheme );
951 // save all color transformations
952 PUT_PROP( aGradientStop, 2, "Transformations", aIt->second.getTransformations() );
955 PUT_PROP( aGradientStops, i, OUString::number( i ), aGradientStop );
956 ++aIt;
958 // If getFillProperties.moFillType is unused that means gradient is defined by a theme
959 // which is already saved into StyleFillRef property, so no need to save the explicit values too
960 if( getFillProperties().moFillType.has() )
961 putPropertyToGrabBag( "GradFillDefinition", Any( aGradientStops ) );
962 putPropertyToGrabBag( "OriginalGradFill", aShapeProps.getProperty(PROP_FillGradient) );
965 // store unsupported effect attributes in the grab bag
966 if( aEffectProperties.maEffects.size() > 0 )
968 Sequence< PropertyValue > aEffects( aEffectProperties.maEffects.size() );
969 sal_uInt32 i = 0;
970 for( boost::ptr_vector< Effect >::iterator it = aEffectProperties.maEffects.begin();
971 it != aEffectProperties.maEffects.end(); ++it )
973 PropertyValue aEffect = it->getEffect();
974 if( !aEffect.Name.isEmpty() )
976 Sequence< PropertyValue > aEffectsGrabBag( 3 );
977 PUT_PROP( aEffectsGrabBag, 0, "Attribs", aEffect.Value );
979 Color& aColor( it->moColor );
980 OUString sColorScheme = aColor.getSchemeName();
981 if( sColorScheme.isEmpty() )
983 // RGB color and transparency value
984 PUT_PROP( aEffectsGrabBag, 1, "RgbClr",
985 aColor.getColor( rGraphicHelper, nFillPhClr ) );
986 PUT_PROP( aEffectsGrabBag, 2, "RgbClrTransparency",
987 aColor.getTransparency() );
989 else
991 // scheme color with name and transformations
992 PUT_PROP( aEffectsGrabBag, 1, "SchemeClr", sColorScheme );
993 PUT_PROP( aEffectsGrabBag, 2, "SchemeClrTransformations",
994 aColor.getTransformations() );
996 PUT_PROP( aEffects, i, aEffect.Name, aEffectsGrabBag );
997 ++i;
1000 putPropertyToGrabBag( "EffectProperties", Any( aEffects ) );
1003 // add 3D effects if any
1004 Sequence< PropertyValue > aCamera3DEffects = get3DProperties().getCameraAttributes();
1005 Sequence< PropertyValue > aLightRig3DEffects = get3DProperties().getLightRigAttributes();
1006 Sequence< PropertyValue > aShape3DEffects = get3DProperties().getShape3DAttributes( rGraphicHelper, nFillPhClr );
1007 if( aCamera3DEffects.getLength() > 0 || aLightRig3DEffects.getLength() > 0 || aShape3DEffects.getLength() > 0 )
1009 Sequence< PropertyValue > a3DEffectsGrabBag( 3 );
1010 PUT_PROP( a3DEffectsGrabBag, 0, "Camera", Any( aCamera3DEffects ) );
1011 PUT_PROP( a3DEffectsGrabBag, 1, "LightRig", Any( aLightRig3DEffects ) );
1012 PUT_PROP( a3DEffectsGrabBag, 2, "Shape3D", Any( aShape3DEffects ) );
1013 putPropertyToGrabBag( "3DEffectProperties", Any( a3DEffectsGrabBag ) );
1016 // store bitmap artistic effects in the grab bag
1017 if( !mpGraphicPropertiesPtr->maBlipProps.maEffect.isEmpty() )
1018 putPropertyToGrabBag( "ArtisticEffectProperties",
1019 Any( mpGraphicPropertiesPtr->maBlipProps.maEffect.getEffect() ) );
1022 else if( mbLockedCanvas )
1024 //If we have aServiceName as "com.sun.star.drawing.GroupShape" and lockedCanvas
1025 putPropertyToGrabBag( "LockedCanvas", Any( true ) );
1028 // These can have a custom geometry, so position should be set here,
1029 // after creation but before custom shape handling, using the position
1030 // we got from the caller.
1031 if (mbWps && aServiceName == "com.sun.star.drawing.LineShape")
1032 mxShape->setPosition(maPosition);
1034 if( bIsCustomShape )
1036 if ( mbFlipH )
1037 mpCustomShapePropertiesPtr->setMirroredX( true );
1038 if ( mbFlipV )
1039 mpCustomShapePropertiesPtr->setMirroredY( true );
1040 if( getTextBody() )
1042 sal_Int32 nTextRotateAngle = static_cast< sal_Int32 >( getTextBody()->getTextProperties().moRotation.get( 0 ) );
1043 /* OOX measures text rotation clockwise in 1/60000th degrees,
1044 relative to the containing shape. setTextRotateAngle wants
1045 degrees anticlockwise. */
1046 mpCustomShapePropertiesPtr->setTextRotateAngle( -1 * nTextRotateAngle / 60000 );
1049 SAL_INFO("oox.cscode", "==cscode== shape name: '" << msName << "'");
1050 SAL_INFO("oox.csdata", "==csdata== shape name: '" << msName << "'");
1051 mpCustomShapePropertiesPtr->pushToPropSet( rFilterBase, xSet, mxShape, maSize );
1053 else if( getTextBody() )
1054 getTextBody()->getTextProperties().pushVertSimulation();
1056 PropertySet aPropertySet(mxShape);
1057 if ( !bUseRotationTransform && mnRotation != 0 )
1059 // use the same logic for rotation from VML exporter (SimpleShape::implConvertAndInsert at vmlshape.cxx)
1060 aPropertySet.setAnyProperty( PROP_RotateAngle, makeAny( sal_Int32( NormAngle360( mnRotation / -600 ) ) ) );
1061 aPropertySet.setAnyProperty( PROP_HoriOrientPosition, makeAny( maPosition.X ) );
1062 aPropertySet.setAnyProperty( PROP_VertOrientPosition, makeAny( maPosition.Y ) );
1065 // in some cases, we don't have any text body.
1066 if( getTextBody() && ( !bDoNotInsertEmptyTextBody || !mpTextBody->isEmpty() ) )
1068 Reference < XText > xText( mxShape, UNO_QUERY );
1069 if ( xText.is() ) // not every shape is supporting an XText interface (e.g. GroupShape)
1071 TextCharacterProperties aCharStyleProperties;
1072 if( const ShapeStyleRef* pFontRef = getShapeStyleRef( XML_fontRef ) )
1074 if( pFontRef->mnThemedIdx != 0 )
1076 if( pTheme )
1077 if( const TextCharacterProperties* pCharProps = pTheme->getFontStyle( pFontRef->mnThemedIdx ) )
1078 aCharStyleProperties.assignUsed( *pCharProps );
1079 SAL_INFO("oox.drawingml", OSL_THIS_FUNC << "use font color");
1080 aCharStyleProperties.maCharColor.assignIfUsed( pFontRef->maPhClr );
1084 Reference < XTextCursor > xAt = xText->createTextCursor();
1085 getTextBody()->insertAt( rFilterBase, xText, xAt, aCharStyleProperties, mpMasterTextListStyle );
1088 else if (mbTextBox)
1090 // No drawingML text, but WPS text is expected: save the theme
1091 // character color on the shape, then.
1092 if(const ShapeStyleRef* pFontRef = getShapeStyleRef(XML_fontRef))
1094 sal_Int32 nCharColor = pFontRef->maPhClr.getColor(rGraphicHelper);
1095 aPropertySet.setAnyProperty(PROP_CharColor, uno::makeAny(nCharColor));
1100 if( mxShape.is() )
1101 finalizeXShape( rFilterBase, rxShapes );
1103 return mxShape;
1106 void Shape::keepDiagramCompatibilityInfo( XmlFilterBase& rFilterBase )
1110 if( !maDiagramDoms.hasElements() )
1111 return;
1113 Reference < XPropertySet > xSet( mxShape, UNO_QUERY_THROW );
1114 Reference < XPropertySetInfo > xSetInfo( xSet->getPropertySetInfo() );
1115 if ( !xSetInfo.is() )
1116 return;
1118 const OUString aGrabBagPropName = UNO_NAME_MISC_OBJ_INTEROPGRABBAG;
1119 if( !xSetInfo->hasPropertyByName( aGrabBagPropName ) )
1120 return;
1122 Sequence < PropertyValue > aGrabBag;
1123 xSet->getPropertyValue( aGrabBagPropName ) >>= aGrabBag;
1125 // We keep the previous items, if present
1126 if ( aGrabBag.hasElements() )
1128 sal_Int32 length = aGrabBag.getLength();
1129 aGrabBag.realloc( length+maDiagramDoms.getLength() );
1131 for( sal_Int32 i = 0; i < maDiagramDoms.getLength(); ++i )
1132 aGrabBag[length+i] = maDiagramDoms[i];
1134 xSet->setPropertyValue( aGrabBagPropName, Any( aGrabBag ) );
1135 } else
1136 xSet->setPropertyValue( aGrabBagPropName, Any( maDiagramDoms ) );
1138 xSet->setPropertyValue( OUString( "MoveProtect" ), Any( sal_True ) );
1139 xSet->setPropertyValue( OUString( "SizeProtect" ), Any( sal_True ) );
1141 // Replace existing shapes with a new Graphic Object rendered
1142 // from them
1143 Reference < XShape > xShape( renderDiagramToGraphic( rFilterBase ) );
1144 Reference < XShapes > xShapes( mxShape, UNO_QUERY_THROW );
1145 while( xShapes->hasElements() )
1146 xShapes->remove( Reference < XShape > ( xShapes->getByIndex( 0 ), UNO_QUERY_THROW ) );
1147 xShapes->add( xShape );
1149 catch( const Exception& e )
1151 SAL_WARN( "oox.drawingml", OSL_THIS_FUNC << "Exception: " << e.Message );
1155 Reference < XShape > Shape::renderDiagramToGraphic( XmlFilterBase& rFilterBase )
1157 Reference< XShape > xShape;
1161 if( !maDiagramDoms.hasElements() )
1162 return xShape;
1164 // Stream in which to place the rendered shape
1165 SvMemoryStream mpTempStream;
1166 Reference < io::XStream > xStream( new utl::OStreamWrapper( mpTempStream ) );
1167 Reference < io::XOutputStream > xOutputStream( xStream->getOutputStream() );
1169 // Rendering format
1170 OUString sFormat( "SVM" );
1172 // Size of the rendering
1173 awt::Size aActualSize = mxShape->getSize();
1174 Size aResolution( Application::GetDefaultDevice()->LogicToPixel( Size( 100, 100 ), MAP_CM ) );
1175 double fPixelsPer100thmm = static_cast < double > ( aResolution.Width() ) / 100000.0;
1176 awt::Size aSize = awt::Size( static_cast < sal_Int32 > ( ( fPixelsPer100thmm * aActualSize.Width ) + 0.5 ),
1177 static_cast < sal_Int32 > ( ( fPixelsPer100thmm * aActualSize.Height ) + 0.5 ) );
1179 Sequence< PropertyValue > aFilterData( 4 );
1180 aFilterData[ 0 ].Name = "PixelWidth";
1181 aFilterData[ 0 ].Value <<= aSize.Width;
1182 aFilterData[ 1 ].Name = "PixelHeight";
1183 aFilterData[ 1 ].Value <<= aSize.Height;
1184 aFilterData[ 2 ].Name = "LogicalWidth";
1185 aFilterData[ 2 ].Value <<= aActualSize.Width;
1186 aFilterData[ 3 ].Name = "LogicalHeight";
1187 aFilterData[ 3 ].Value <<= aActualSize.Height;
1189 Sequence < PropertyValue > aDescriptor( 3 );
1190 aDescriptor[ 0 ].Name = "OutputStream";
1191 aDescriptor[ 0 ].Value <<= xOutputStream;
1192 aDescriptor[ 1 ].Name = "FilterName";
1193 aDescriptor[ 1 ].Value <<= sFormat;
1194 aDescriptor[ 2 ].Name = "FilterData";
1195 aDescriptor[ 2 ].Value <<= aFilterData;
1197 Reference < lang::XComponent > xSourceDoc( mxShape, UNO_QUERY_THROW );
1198 Reference < XGraphicExportFilter > xGraphicExporter = GraphicExportFilter::create( rFilterBase.getComponentContext() );
1199 xGraphicExporter->setSourceDocument( xSourceDoc );
1200 xGraphicExporter->filter( aDescriptor );
1202 mpTempStream.Seek( STREAM_SEEK_TO_BEGIN );
1204 Graphic aGraphic;
1205 GraphicFilter aFilter( false );
1206 if ( aFilter.ImportGraphic( aGraphic, "", mpTempStream, GRFILTER_FORMAT_NOTFOUND, NULL, GraphicFilterImportFlags::NONE, static_cast < Sequence < PropertyValue >* > ( NULL ), NULL ) != GRFILTER_OK )
1208 SAL_WARN( "oox.drawingml", OSL_THIS_FUNC
1209 << "Unable to import rendered stream into graphic object" );
1210 return xShape;
1213 Reference < graphic::XGraphic > xGraphic( aGraphic.GetXGraphic() );
1214 Reference < lang::XMultiServiceFactory > xServiceFact( rFilterBase.getModel(), UNO_QUERY_THROW );
1215 xShape = Reference < XShape > ( xServiceFact->createInstance( OUString( "com.sun.star.drawing.GraphicObjectShape" ) ), UNO_QUERY_THROW );
1216 Reference < XPropertySet > xPropSet( xShape, UNO_QUERY_THROW );
1217 xPropSet->setPropertyValue( OUString( "Graphic" ), Any( xGraphic ) );
1218 xPropSet->setPropertyValue( OUString( "MoveProtect" ), Any( sal_True ) );
1219 xPropSet->setPropertyValue( OUString( "SizeProtect" ), Any( sal_True ) );
1220 xPropSet->setPropertyValue( OUString( "Name" ), Any( OUString( "RenderedShapes" ) ) );
1222 catch( const Exception& e )
1224 SAL_WARN( "oox.drawingml", OSL_THIS_FUNC << "Exception: " << e.Message );
1227 return xShape;
1230 void Shape::setTextBody(const TextBodyPtr & pTextBody)
1232 mpTextBody = pTextBody;
1235 void Shape::setMasterTextListStyle( const TextListStylePtr& pMasterTextListStyle )
1237 SAL_INFO("oox.drawingml", OSL_THIS_FUNC << "set master text list style to shape id: " << msId);
1239 mpMasterTextListStyle = pMasterTextListStyle;
1242 OUString Shape::finalizeServiceName( XmlFilterBase& rFilter, const OUString& rServiceName, const awt::Rectangle& rShapeRect )
1244 OUString aServiceName = rServiceName;
1245 switch( meFrameType )
1247 case FRAMETYPE_OLEOBJECT:
1249 awt::Size aOleSize( rShapeRect.Width, rShapeRect.Height );
1250 if( rFilter.getOleObjectHelper().importOleObject( maShapeProperties, *mxOleObjectInfo, aOleSize ) )
1251 aServiceName = "com.sun.star.drawing.OLE2Shape";
1253 // get the path to the representation graphic
1254 OUString aGraphicPath;
1255 if( !mxOleObjectInfo->maShapeId.isEmpty() )
1256 if( ::oox::vml::Drawing* pVmlDrawing = rFilter.getVmlDrawing() )
1257 if( const ::oox::vml::ShapeBase* pVmlShape = pVmlDrawing->getShapes().getShapeById( mxOleObjectInfo->maShapeId, true ) )
1258 aGraphicPath = pVmlShape->getGraphicPath();
1260 // import and store the graphic
1261 if( !aGraphicPath.isEmpty() )
1263 // Transfer shape's width and heightto graphicsfilter (can be used by WMF/EMF)
1264 WMF_EXTERNALHEADER aExtHeader;
1265 aExtHeader.mapMode = 8; // MM_ANISOTROPIC
1266 aExtHeader.xExt = rShapeRect.Width;
1267 aExtHeader.yExt = rShapeRect.Height;
1269 Reference< graphic::XGraphic > xGraphic = rFilter.getGraphicHelper().importEmbeddedGraphic( aGraphicPath, &aExtHeader );
1270 if( xGraphic.is() )
1271 maShapeProperties.setProperty(PROP_Graphic, xGraphic);
1274 break;
1276 default:;
1278 return aServiceName;
1281 void Shape::finalizeXShape( XmlFilterBase& rFilter, const Reference< XShapes >& rxShapes )
1283 switch( meFrameType )
1285 case FRAMETYPE_CHART:
1287 OSL_ENSURE( !mxChartShapeInfo->maFragmentPath.isEmpty(), "Shape::finalizeXShape - missing chart fragment" );
1288 if( mxShape.is() && !mxChartShapeInfo->maFragmentPath.isEmpty() ) try
1290 // set the chart2 OLE class ID at the OLE shape
1291 PropertySet aShapeProp( mxShape );
1292 aShapeProp.setProperty( PROP_CLSID, OUString( "12dcae26-281f-416f-a234-c3086127382e" ) );
1294 // get the XModel interface of the embedded object from the OLE shape
1295 Reference< frame::XModel > xDocModel;
1296 aShapeProp.getProperty( xDocModel, PROP_Model );
1297 Reference< chart2::XChartDocument > xChartDoc( xDocModel, UNO_QUERY_THROW );
1299 // load the chart data from the XML fragment
1300 bool bMSO2007Doc = rFilter.isMSO2007Document();
1301 chart::ChartSpaceModel aModel(bMSO2007Doc);
1302 chart::ChartSpaceFragment *pChartSpaceFragment = new chart::ChartSpaceFragment(
1303 rFilter, mxChartShapeInfo->maFragmentPath, aModel );
1304 const OUString aThemeOverrideFragmentPath( pChartSpaceFragment->
1305 getFragmentPathFromFirstTypeFromOfficeDoc("themeOverride") );
1306 rFilter.importFragment( pChartSpaceFragment );
1307 ::oox::ppt::PowerPointImport *pPowerPointImport =
1308 dynamic_cast< ::oox::ppt::PowerPointImport* >(&rFilter);
1309 if (!aThemeOverrideFragmentPath.isEmpty() && pPowerPointImport)
1311 uno::Reference< xml::sax::XFastSAXSerializable > xDoc(
1312 rFilter.importFragment(aThemeOverrideFragmentPath), uno::UNO_QUERY_THROW);
1313 ThemePtr pTheme = pPowerPointImport->getActualSlidePersist()->getTheme();
1314 rFilter.importFragment(new ThemeOverrideFragmentHandler(
1315 rFilter, aThemeOverrideFragmentPath, *pTheme), xDoc);
1316 pPowerPointImport->getActualSlidePersist()->setTheme(pTheme);
1319 // convert imported chart model to chart document
1320 Reference< drawing::XShapes > xExternalPage;
1321 if( !mxChartShapeInfo->mbEmbedShapes )
1322 xExternalPage = rxShapes;
1323 if( rFilter.getChartConverter() )
1325 rFilter.getChartConverter()->convertFromModel( rFilter, aModel, xChartDoc, xExternalPage, mxShape->getPosition(), mxShape->getSize() );
1326 if( !xChartDoc->hasInternalDataProvider() )
1328 Reference< chart2::data::XDataReceiver > xDataRec( xChartDoc, UNO_QUERY );
1329 Reference< chart2::data::XDataSource > xData( xDataRec->getUsedData(), UNO_QUERY );
1330 if( xData->getDataSequences().getLength() <= 0 || !xData->getDataSequences()[0]->getValues().is() ||
1331 xData->getDataSequences()[0]->getValues()->getData().getLength() <= 0 )
1333 rFilter.useInternalChartDataTable( true );
1334 rFilter.getChartConverter()->convertFromModel( rFilter, aModel, xChartDoc, xExternalPage, mxShape->getPosition(), mxShape->getSize() );
1335 rFilter.useInternalChartDataTable( false );
1341 catch( Exception& )
1345 break;
1347 default:;
1351 void Shape::putPropertyToGrabBag( const OUString& sPropertyName, const Any& aPropertyValue )
1353 PropertyValue pNewProperty;
1354 pNewProperty.Name = sPropertyName;
1355 pNewProperty.Value = aPropertyValue;
1356 putPropertyToGrabBag( pNewProperty );
1359 void Shape::putPropertyToGrabBag( const PropertyValue& pProperty )
1361 Reference< XPropertySet > xSet( mxShape, UNO_QUERY );
1362 Reference< XPropertySetInfo > xSetInfo( xSet->getPropertySetInfo() );
1363 const OUString& aGrabBagPropName = OUString( UNO_NAME_MISC_OBJ_INTEROPGRABBAG );
1364 if( mxShape.is() && xSet.is() && xSetInfo.is() && xSetInfo->hasPropertyByName( aGrabBagPropName ) )
1366 Sequence< PropertyValue > aGrabBag;
1367 xSet->getPropertyValue( aGrabBagPropName ) >>= aGrabBag;
1369 sal_Int32 length = aGrabBag.getLength();
1370 aGrabBag.realloc( length + 1 );
1371 aGrabBag[length] = pProperty;
1373 xSet->setPropertyValue( aGrabBagPropName, Any( aGrabBag ) );
1377 void Shape::putPropertiesToGrabBag( const Sequence< PropertyValue >& aProperties )
1379 Reference< XPropertySet > xSet( mxShape, UNO_QUERY );
1380 Reference< XPropertySetInfo > xSetInfo( xSet->getPropertySetInfo() );
1381 const OUString& aGrabBagPropName = OUString( UNO_NAME_MISC_OBJ_INTEROPGRABBAG );
1382 if( mxShape.is() && xSet.is() && xSetInfo.is() && xSetInfo->hasPropertyByName( aGrabBagPropName ) )
1384 // get existing grab bag
1385 Sequence< PropertyValue > aGrabBag;
1386 xSet->getPropertyValue( aGrabBagPropName ) >>= aGrabBag;
1387 sal_Int32 length = aGrabBag.getLength();
1389 // update grab bag size to contain the new items
1390 aGrabBag.realloc( length + aProperties.getLength() );
1392 // put the new items
1393 for( sal_Int32 i=0; i < aProperties.getLength(); ++i )
1395 aGrabBag[length + i].Name = aProperties[i].Name;
1396 aGrabBag[length + i].Value = aProperties[i].Value;
1399 // put it back to the shape
1400 xSet->setPropertyValue( aGrabBagPropName, Any( aGrabBag ) );
1404 uno::Sequence< uno::Sequence< uno::Any > > Shape::resolveRelationshipsOfTypeFromOfficeDoc(core::XmlFilterBase& rFilter, const OUString& sFragment, const OUString& sType )
1406 uno::Sequence< uno::Sequence< uno::Any > > xRelListTemp;
1407 sal_Int32 counter = 0;
1409 core::RelationsRef xRels = rFilter.importRelations( sFragment );
1410 if ( xRels )
1412 core::RelationsRef xImageRels = xRels->getRelationsFromTypeFromOfficeDoc( sType );
1413 if ( xImageRels )
1415 xRelListTemp.realloc( xImageRels->size() );
1416 for( ::std::map< OUString, core::Relation >::const_iterator aIt = xImageRels->begin(), aEnd = xImageRels->end(); aIt != aEnd; ++aIt )
1418 uno::Sequence< uno::Any > diagramRelTuple (3);
1419 // [0] => RID, [1] => InputStream [2] => extension
1420 OUString sRelId = aIt->second.maId;
1422 diagramRelTuple[0] = uno::makeAny ( sRelId );
1423 OUString sTarget = xImageRels->getFragmentPathFromRelId( sRelId );
1425 uno::Reference< io::XInputStream > xImageInputStrm( rFilter.openInputStream( sTarget ), uno::UNO_SET_THROW );
1426 StreamDataSequence dataSeq;
1427 if ( rFilter.importBinaryData( dataSeq, sTarget ) )
1429 diagramRelTuple[1] = uno::makeAny( dataSeq );
1432 diagramRelTuple[2] = uno::makeAny( sTarget.copy( sTarget.lastIndexOf(".") ) );
1434 xRelListTemp[counter] = diagramRelTuple;
1435 ++counter;
1437 xRelListTemp.realloc(counter);
1441 return xRelListTemp;
1446 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */