LibreOffice Module oox (master) 1
shape.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <config_wasm_strip.h>
21
30#include "effectproperties.hxx"
39#include <o3tl/safeint.hxx>
41#include <oox/ppt/pptimport.hxx>
43#include <oox/vml/vmlshape.hxx>
50#include <oox/mathml/import.hxx>
51#include <oox/token/properties.hxx>
52#include "diagram/datamodel.hxx"
54
60#include <tools/gen.hxx>
61#include <tools/globname.hxx>
62#include <tools/mapunit.hxx>
63#include <editeng/unoprnms.hxx>
64#include <com/sun/star/awt/FontSlant.hpp>
65#include <com/sun/star/awt/Size.hpp>
66#include <com/sun/star/awt/XBitmap.hpp>
67#include <com/sun/star/awt/FontWeight.hpp>
68#include <com/sun/star/graphic/XGraphic.hpp>
69#include <com/sun/star/container/XNamed.hpp>
70#include <com/sun/star/lang/XMultiServiceFactory.hpp>
71#include <com/sun/star/xml/dom/XDocument.hpp>
72#include <com/sun/star/xml/sax/XFastSAXSerializable.hpp>
73#include <com/sun/star/drawing/FillStyle.hpp>
74#include <com/sun/star/drawing/HomogenMatrix3.hpp>
75#include <com/sun/star/drawing/TextVerticalAdjust.hpp>
76#include <com/sun/star/drawing/GraphicExportFilter.hpp>
77#include <com/sun/star/drawing/XShapes.hpp>
78#include <com/sun/star/drawing/EnhancedCustomShapeAdjustmentValue.hpp>
79#include <com/sun/star/drawing/XEnhancedCustomShapeDefaulter.hpp>
80#include <com/sun/star/drawing/EnhancedCustomShapeTextPathMode.hpp>
81#include <com/sun/star/drawing/ConnectorType.hpp>
82#include <com/sun/star/embed/XEmbeddedObject.hpp>
83#include <com/sun/star/text/XText.hpp>
84#include <com/sun/star/table/BorderLine2.hpp>
85#include <com/sun/star/table/ShadowFormat.hpp>
86#include <com/sun/star/chart2/XChartDocument.hpp>
87#include <com/sun/star/style/ParagraphAdjust.hpp>
88#include <com/sun/star/io/XOutputStream.hpp>
89#include <com/sun/star/lang/Locale.hpp>
90#include <com/sun/star/i18n/ScriptType.hpp>
91
95#include <com/sun/star/document/XActionLockable.hpp>
96#include <com/sun/star/chart2/data/XDataReceiver.hpp>
97#include <com/sun/star/text/GraphicCrop.hpp>
98#include <svx/svdobj.hxx>
99#include <svx/svdotable.hxx>
100#include <svx/svdtrans.hxx>
101#include <tools/stream.hxx>
103#include <unotools/fltrcfg.hxx>
105#include <vcl/graph.hxx>
106#include <vcl/graphicfilter.hxx>
107#include <vcl/svapp.hxx>
108#include <vcl/wmfexternal.hxx>
109#include <sal/log.hxx>
110#include <svx/sdtaitm.hxx>
114
115using namespace ::oox::core;
116using namespace ::com::sun::star;
117using namespace ::com::sun::star::uno;
118using namespace ::com::sun::star::beans;
119using namespace ::com::sun::star::frame;
120using namespace ::com::sun::star::text;
121using namespace ::com::sun::star::drawing;
122using namespace ::com::sun::star::style;
123
124namespace oox::drawingml {
125
126Shape::Shape( const char* pServiceName, bool bDefaultHeight )
127: mpLinePropertiesPtr( std::make_shared<LineProperties>() )
128, mpShapeRefLinePropPtr( std::make_shared<LineProperties>() )
129, mpFillPropertiesPtr( std::make_shared<FillProperties>() )
130, mpShapeRefFillPropPtr( std::make_shared<FillProperties>() )
131, mpGraphicPropertiesPtr( std::make_shared<GraphicProperties>() )
132, mpCustomShapePropertiesPtr( std::make_shared<CustomShapeProperties>() )
133, mp3DPropertiesPtr( std::make_shared<Shape3DProperties>() )
134, mpEffectPropertiesPtr( std::make_shared<EffectProperties>() )
135, mpShapeRefEffectPropPtr( std::make_shared<EffectProperties>() )
136, mpMasterTextListStyle( std::make_shared<TextListStyle>() )
137, mnSubType( 0 )
138, meFrameType( FRAMETYPE_GENERIC )
139, mnRotation( 0 )
140, mnDiagramRotation( 0 )
141, mbFlipH( false )
142, mbFlipV( false )
143, mbHidden( false )
144, mbHiddenMasterShape( false )
145, mbLocked( false )
146, mbWPGChild(false)
147, mbLockedCanvas( false )
148, mbWps( false )
149, mbTextBox( false )
150, mbHasLinkedTxbx( false )
151, maDiagramDoms( 0 )
152, mpDiagramHelper( nullptr )
153{
154 if ( pServiceName )
155 msServiceName = OUString::createFromAscii( pServiceName );
156 setDefaults(bDefaultHeight);
157}
158
159Shape::Shape( const ShapePtr& pSourceShape )
160: mpTextBody(pSourceShape->mpTextBody)
161, mpLinePropertiesPtr( pSourceShape->mpLinePropertiesPtr )
162, mpShapeRefLinePropPtr( pSourceShape->mpShapeRefLinePropPtr )
163, mpFillPropertiesPtr( pSourceShape->mpFillPropertiesPtr )
164, mpShapeRefFillPropPtr( pSourceShape->mpShapeRefFillPropPtr )
165, mpGraphicPropertiesPtr( pSourceShape->mpGraphicPropertiesPtr )
166, mpCustomShapePropertiesPtr( pSourceShape->mpCustomShapePropertiesPtr )
167, mpTablePropertiesPtr( pSourceShape->mpTablePropertiesPtr )
168, mp3DPropertiesPtr( pSourceShape->mp3DPropertiesPtr )
169, mpEffectPropertiesPtr (pSourceShape->mpEffectPropertiesPtr)
170, mpShapeRefEffectPropPtr(pSourceShape->mpShapeRefEffectPropPtr)
171, maShapeProperties( pSourceShape->maShapeProperties )
172, mpMasterTextListStyle( pSourceShape->mpMasterTextListStyle )
173, msServiceName( pSourceShape->msServiceName )
174, msName( pSourceShape->msName )
175, msInternalName( pSourceShape->msInternalName )
176, msId( pSourceShape->msId )
177, mnSubType( pSourceShape->mnSubType )
178, moSubTypeIndex( pSourceShape->moSubTypeIndex )
179, maShapeStyleRefs( pSourceShape->maShapeStyleRefs )
180, maSize( pSourceShape->maSize )
181, maPosition( pSourceShape->maPosition )
182, meFrameType( pSourceShape->meFrameType )
183, mnRotation( pSourceShape->mnRotation )
184, mnDiagramRotation( pSourceShape->mnDiagramRotation )
185, mbFlipH( pSourceShape->mbFlipH )
186, mbFlipV( pSourceShape->mbFlipV )
187, mbHidden( pSourceShape->mbHidden )
188, mbHiddenMasterShape( pSourceShape->mbHiddenMasterShape )
189, mbLocked( pSourceShape->mbLocked )
190, mbWPGChild( pSourceShape->mbWPGChild )
191, mbLockedCanvas( pSourceShape->mbLockedCanvas )
192, mbWps( pSourceShape->mbWps )
193, mbTextBox( pSourceShape->mbTextBox )
194, mbHasLinkedTxbx(false)
195, maDiagramDoms( pSourceShape->maDiagramDoms )
196, mnZOrder(pSourceShape->mnZOrder)
197, mnZOrderOff(pSourceShape->mnZOrderOff)
198, mnDataNodeType(pSourceShape->mnDataNodeType)
199, mfAspectRatio(pSourceShape->mfAspectRatio)
200, mpDiagramHelper( nullptr )
201, msDiagramDataModelID(pSourceShape->msDiagramDataModelID)
202{}
203
205{
206 // DiagramHelper should not be set here anymore, see
207 // propagateDiagramHelper below (maybe assert..?)
208 delete mpDiagramHelper;
209}
210
212 const std::shared_ptr< Diagram >& rDiagramPtr,
213 const std::shared_ptr<::oox::drawingml::Theme>& rTheme)
214{
215 // Prepare Diagram data collecting for this Shape
216 if( nullptr == mpDiagramHelper && FRAMETYPE_DIAGRAM == meFrameType )
217 {
219 rDiagramPtr,
220 rTheme,
221 getSize());
222 }
223}
224
226{
227 // Propagate collected Diagram data to data holder
228 if (FRAMETYPE_DIAGRAM == meFrameType && nullptr != mpDiagramHelper)
229 {
231
232 if(pAnchorObj)
233 {
234 static_cast<AdvancedDiagramHelper*>(mpDiagramHelper)->doAnchor(*pAnchorObj, *this);
235 mpDiagramHelper = nullptr;
236 }
237 }
238
239 // If propagation failed, delete/cleanup here. Since the DiagramHelper
240 // holds a Diagram and that this Shape it is necessary - the destructor
241 // will not be called and will be too late
242 if (nullptr != mpDiagramHelper)
243 {
244 delete mpDiagramHelper;
245 mpDiagramHelper = nullptr;
246 }
247}
248
250{
251 if(!mpDiagramHelper)
252 {
253 return;
254 }
255
256 if(!pTarget)
257 {
258 // no migrate target, but cleanup helper
259 delete mpDiagramHelper;
260 mpDiagramHelper = nullptr;
261 return;
262 }
263
264 if(pTarget->mpDiagramHelper)
265 {
266 // this should no happen, but if there is already a helper, clean it up
267 delete pTarget->mpDiagramHelper;
268 pTarget->mpDiagramHelper = nullptr;
269 }
270
271 // exchange and reset to nullptr
272 pTarget->mpDiagramHelper = mpDiagramHelper;
273 mpDiagramHelper = nullptr;
274}
275
277{
279 mpTablePropertiesPtr = std::make_shared<table::TableProperties>();
281}
282
283void Shape::setDefaults(bool bHeight)
284{
287 maDefaultShapeProperties.setProperty(PROP_TextLeftDistance, static_cast< sal_Int32 >( 250 ));
288 maDefaultShapeProperties.setProperty(PROP_TextUpperDistance, static_cast< sal_Int32 >( 125 ));
289 maDefaultShapeProperties.setProperty(PROP_TextRightDistance, static_cast< sal_Int32 >( 250 ));
290 maDefaultShapeProperties.setProperty(PROP_TextLowerDistance, static_cast< sal_Int32 >( 125 ));
291 if (bHeight)
292 maDefaultShapeProperties.setProperty(PROP_CharHeight, static_cast< float >( 18.0 ));
295 static_cast<sal_Int16>(ParagraphAdjust_LEFT));
296}
297
299{
300 OSL_ENSURE( meFrameType == FRAMETYPE_GENERIC, "Shape::setOleObjectType - multiple frame types" );
302 mxOleObjectInfo = std::make_shared<::oox::vml::OleObjectInfo>( true );
303 return *mxOleObjectInfo;
304}
305
307{
308 OSL_ENSURE( meFrameType == FRAMETYPE_GENERIC, "Shape::setChartType - multiple frame types" );
310 if (mbWps)
311 msServiceName = "com.sun.star.drawing.temporaryForXMLImportOLE2Shape";
312 else
313 msServiceName = "com.sun.star.drawing.OLE2Shape";
314 mxChartShapeInfo = std::make_shared<ChartShapeInfo>( bEmbedShapes );
315 return *mxChartShapeInfo;
316}
317
319{
320 OSL_ENSURE( meFrameType == FRAMETYPE_GENERIC, "Shape::setDiagramType - multiple frame types" );
322 msServiceName = "com.sun.star.drawing.GroupShape";
323 mnSubType = 0;
324}
325
327{
328 OSL_ENSURE( meFrameType == FRAMETYPE_GENERIC, "Shape::setTableType - multiple frame types" );
330 msServiceName = "com.sun.star.drawing.TableShape";
331 mnSubType = 0;
332}
333
334void Shape::setServiceName( const char* pServiceName )
335{
336 if ( pServiceName )
337 msServiceName = OUString::createFromAscii( pServiceName );
338}
339
340const ShapeStyleRef* Shape::getShapeStyleRef( sal_Int32 nRefType ) const
341{
342 ShapeStyleRefMap::const_iterator aIt = maShapeStyleRefs.find( nRefType );
343 return (aIt == maShapeStyleRefs.end()) ? nullptr : &aIt->second;
344}
345
347 ::oox::core::XmlFilterBase& rFilterBase,
348 const Theme* pTheme,
349 const Reference< XShapes >& rxShapes,
350 const basegfx::B2DHomMatrix& aTransformation,
351 const FillProperties& rShapeOrParentShapeFillProps,
352 ShapeIdMap* pShapeMap,
353 oox::drawingml::ShapePtr pParentGroupShape)
354{
355 SAL_INFO("oox.drawingml", "Shape::addShape: id='" << msId << "'");
356
357 try
358 {
359 OUString sServiceName( msServiceName );
360 if( !sServiceName.isEmpty() )
361 {
362 basegfx::B2DHomMatrix aMatrix( aTransformation );
363 Reference< XShape > xShape( createAndInsert( rFilterBase, sServiceName, pTheme, rxShapes, false, false, aMatrix, rShapeOrParentShapeFillProps, pParentGroupShape) );
364
365 if( pShapeMap && !msId.isEmpty() )
366 {
367 (*pShapeMap)[ msId ] = shared_from_this();
368 }
369
370 // if this is a group shape, we have to add also each child shape
371 Reference< XShapes > xShapes( xShape, UNO_QUERY );
372 if ( xShapes.is() )
373 addChildren( rFilterBase, *this, pTheme, xShapes, pShapeMap, aMatrix );
374
375 if (isWPGChild() && xShape)
376 {
377 // This is a wps shape and it is the child of the WPG, now copy the
378 // the text body properties to the xshape.
379 Reference<XPropertySet> xChildWPSProperties(xShape, uno::UNO_QUERY);
380
381 if (getTextBody() && xChildWPSProperties)
382 {
383 xChildWPSProperties->setPropertyValue(
385 uno::Any(getTextBody()->getTextProperties().meVA));
386
387 xChildWPSProperties->setPropertyValue(
389 uno::Any(getTextBody()->getTextProperties().moInsets[0].has_value()
390 ? *getTextBody()->getTextProperties().moInsets[0]
391 : 0));
392 xChildWPSProperties->setPropertyValue(
394 uno::Any(getTextBody()->getTextProperties().moInsets[1].has_value()
395 ? *getTextBody()->getTextProperties().moInsets[1]
396 : 0));
397 xChildWPSProperties->setPropertyValue(
399 uno::Any(getTextBody()->getTextProperties().moInsets[2].has_value()
400 ? *getTextBody()->getTextProperties().moInsets[2]
401 : 0));
402 xChildWPSProperties->setPropertyValue(
404 uno::Any(getTextBody()->getTextProperties().moInsets[3].has_value()
405 ? *getTextBody()->getTextProperties().moInsets[3]
406 : 0));
407 }
408 }
409
411 {
413
414 // set DiagramHelper at SdrObjGroup
416
417 // Check if this is the PPTX import, so far converting SmartArt to a non-editable
418 // metafile is only implemented for DOCX.
419 bool bPowerPoint = dynamic_cast<oox::ppt::PowerPointImport*>(&rFilterBase) != nullptr;
420
421 if (!SvtFilterOptions::Get().IsSmartArt2Shape() && !bPowerPoint)
422 convertSmartArtToMetafile( rFilterBase );
423 }
424
425 NamedShapePairs* pNamedShapePairs = rFilterBase.getDiagramFontHeights();
426 if (xShape.is() && pNamedShapePairs)
427 {
428 auto itPairs = pNamedShapePairs->find(getInternalName());
429 if (itPairs != pNamedShapePairs->end())
430 {
431 auto it = itPairs->second.find(shared_from_this());
432 if (it != itPairs->second.end())
433 {
434 // Our drawingml::Shape is in the list of an internal name, remember the now
435 // inserted XShape.
436 it->second = xShape;
437 }
438 }
439 }
440 }
441 }
442 catch( const Exception& )
443 {
444 TOOLS_WARN_EXCEPTION( "oox.drawingml", "Shape::addShape" );
445 }
446}
447
448void Shape::setLockedCanvas(bool bLockedCanvas)
449{
450 mbLockedCanvas = bLockedCanvas;
451}
452
453void Shape::setWPGChild(bool bWPG)
454{
455 mbWPGChild = bWPG;
456}
457
458void Shape::setWps(bool bWps)
459{
460 mbWps = bWps;
461}
462
463void Shape::setTextBox(bool bTextBox)
464{
465 mbTextBox = bTextBox;
466}
467
468void Shape::applyShapeReference( const Shape& rReferencedShape, bool bUseText )
469{
470 SAL_INFO("oox.drawingml", "Shape::applyShapeReference: apply '" << rReferencedShape.msId << "' to '" << msId << "'");
471
472 if ( rReferencedShape.mpTextBody && bUseText )
473 mpTextBody = std::make_shared<TextBody>( *rReferencedShape.mpTextBody );
474 else
475 mpTextBody.reset();
476 maShapeProperties = rReferencedShape.maShapeProperties;
477 mpShapeRefLinePropPtr = std::make_shared<LineProperties>( rReferencedShape.getActualLineProperties(nullptr) );
478 mpShapeRefFillPropPtr = std::make_shared<FillProperties>( rReferencedShape.getActualFillProperties(nullptr, nullptr) );
479 mpCustomShapePropertiesPtr = std::make_shared<CustomShapeProperties>( *rReferencedShape.mpCustomShapePropertiesPtr );
480 mpTablePropertiesPtr = rReferencedShape.mpTablePropertiesPtr ? std::make_shared<table::TableProperties>( *rReferencedShape.mpTablePropertiesPtr ) : nullptr;
481 mpShapeRefEffectPropPtr = std::make_shared<EffectProperties>( rReferencedShape.getActualEffectProperties(nullptr) );
482 mpMasterTextListStyle = std::make_shared<TextListStyle>( *rReferencedShape.mpMasterTextListStyle );
483 maSize = rReferencedShape.maSize;
484 maPosition = rReferencedShape.maPosition;
485 mnRotation = rReferencedShape.mnRotation;
486 mbFlipH = rReferencedShape.mbFlipH;
487 mbFlipV = rReferencedShape.mbFlipV;
488 mbHidden = rReferencedShape.mbHidden;
489 mbLocked = rReferencedShape.mbLocked;
490}
491
492namespace {
493
494struct ActionLockGuard
495{
496 explicit ActionLockGuard(Reference<drawing::XShape> const& xShape)
497 : m_xLockable(xShape, UNO_QUERY)
498 {
499 if (m_xLockable.is()) {
500 m_xLockable->addActionLock();
501 }
502 }
503 ~ActionLockGuard()
504 {
505 if (m_xLockable.is()) {
506 m_xLockable->removeActionLock();
507 }
508 }
509private:
510 Reference<document::XActionLockable> m_xLockable;
511};
512
513}
514
515// for group shapes, the following method is also adding each child
517 XmlFilterBase& rFilterBase,
518 Shape& rMaster,
519 const Theme* pTheme,
520 const Reference< XShapes >& rxShapes,
521 ShapeIdMap* pShapeMap,
522 const basegfx::B2DHomMatrix& aTransformation )
523{
524 for (auto const& child : rMaster.maChildren)
525 {
526 child->setMasterTextListStyle( mpMasterTextListStyle );
527 child->addShape( rFilterBase, pTheme, rxShapes, aTransformation, getFillProperties(), pShapeMap, rMaster.shared_from_this());
528 }
529}
530
531static void lcl_resetPropertyValue( std::vector<beans::PropertyValue>& rPropVec, const OUString& rName )
532{
533 auto aIterator = std::find_if( rPropVec.begin(), rPropVec.end(),
534 [rName]( const beans::PropertyValue& rValue ) { return rValue.Name == rName; } );
535
536 if (aIterator != rPropVec.end())
537 rPropVec.erase( aIterator );
538}
539
540static void lcl_setPropertyValue( std::vector<beans::PropertyValue>& rPropVec,
541 const OUString& rName,
542 const beans::PropertyValue& rPropertyValue )
543{
544 lcl_resetPropertyValue( rPropVec, rName );
545
546 rPropVec.push_back( rPropertyValue );
547}
548
549static SdrTextHorzAdjust lcl_convertAdjust( ParagraphAdjust eAdjust )
550{
551 if (eAdjust == ParagraphAdjust_LEFT)
553 else if (eAdjust == ParagraphAdjust_RIGHT)
555 else if (eAdjust == ParagraphAdjust_CENTER)
558}
559
560static void
561lcl_putCustomShapeIntoTextPathMode(const uno::Reference<drawing::XShape>& xShape,
562 const CustomShapePropertiesPtr& pCustomShapePropertiesPtr,
563 const TextBodyPtr& pTextBody)
564{
565 if (!xShape.is() || !pCustomShapePropertiesPtr || !pTextBody)
566 return;
567
568 uno::Reference<drawing::XEnhancedCustomShapeDefaulter> xDefaulter(xShape, uno::UNO_QUERY);
569 if (!xDefaulter.is())
570 return;
571
572 Reference<XPropertySet> xSet(xShape, UNO_QUERY);
573 if (!xSet.is())
574 return;
575
576 const OUString sMSPresetType = pTextBody->getTextProperties().msPrst;
577 const OUString sFontworkType = PresetGeometryTypeNames::GetFontworkType(sMSPresetType);
578
579 // The DrawingML shapes from the presetTextWarpDefinitions are mapped to the definitions
580 // in svx/../EnhancedCustomShapeGeometry.cxx, which are used for WordArt shapes from
581 // binary MS Office. Therefore all adjustment values need to be adapted.
582 auto aAdjGdList = pCustomShapePropertiesPtr->getAdjustmentGuideList();
584 !aAdjGdList.empty() ? aAdjGdList.size() : 1);
585 auto pAdjustment = aAdjustment.getArray();
586 int nIndex = 0;
587 for (const auto& aEntry : aAdjGdList)
588 {
589 double fValue = aEntry.maFormula.toDouble();
590 // then: polar-handle, else: XY-handle
591 // There exist only 8 polar-handles at all in presetTextWarp.
592 if ((sFontworkType == "fontwork-arch-down-curve")
593 || (sFontworkType == "fontwork-arch-down-pour" && aEntry.maName == "adj1")
594 || (sFontworkType == "fontwork-arch-up-curve")
595 || (sFontworkType == "fontwork-arch-up-pour" && aEntry.maName == "adj1")
596 || (sFontworkType == "fontwork-open-circle-curve")
597 || (sFontworkType == "fontwork-open-circle-pour" && aEntry.maName == "adj1")
598 || (sFontworkType == "fontwork-circle-curve")
599 || (sFontworkType == "fontwork-circle-pour" && aEntry.maName == "adj1"))
600 {
601 // DrawingML has 1/60000 degree unit, but WordArt simple degree. Range [0..360[
602 // or range ]-180..180] doesn't matter, because only cos(angle) and
603 // sin(angle) are used.
604 fValue = NormAngle360(fValue / 60000.0);
605 }
606 else
607 {
608 // DrawingML writes adjustment guides as relative value with 100% = 100000,
609 // but WordArt definitions use values absolute in viewBox 0 0 21600 21600,
610 // so scale with 21600/100000 = 0.216, with two exceptions:
611 // X-handles of waves describe increase/decrease relative to horizontal center.
612 // The gdRefR of pour-shapes is not relative to viewBox but to radius.
613 if ((sFontworkType == "mso-spt158" && aEntry.maName == "adj2") // textDoubleWave1
614 || (sFontworkType == "fontwork-wave" && aEntry.maName == "adj2") // textWave1
615 || (sFontworkType == "mso-spt157" && aEntry.maName == "adj2") // textWave2
616 || (sFontworkType == "mso-spt159" && aEntry.maName == "adj2")) // textWave4
617 {
618 fValue = (fValue + 50000.0) * 0.216;
619 }
620 else if ((sFontworkType == "fontwork-arch-down-pour" && aEntry.maName == "adj2")
621 || (sFontworkType == "fontwork-arch-up-pour" && aEntry.maName == "adj2")
622 || (sFontworkType == "fontwork-open-circle-pour" && aEntry.maName == "adj2")
623 || (sFontworkType == "fontwork-circle-pour" && aEntry.maName == "adj2"))
624 {
625 fValue *= 0.108;
626 }
627 else
628 {
629 fValue *= 0.216;
630 }
631 }
632
633 pAdjustment[nIndex].Value <<= fValue;
634 pAdjustment[nIndex++].State = css::beans::PropertyState_DIRECT_VALUE;
635 }
636
637 // Set attributes in CustomShapeGeometry
638 xDefaulter->createCustomShapeDefaults(sFontworkType);
639
640 auto aGeomPropSeq
641 = xSet->getPropertyValue("CustomShapeGeometry").get<uno::Sequence<beans::PropertyValue>>();
642 auto aGeomPropVec
643 = comphelper::sequenceToContainer<std::vector<beans::PropertyValue>>(aGeomPropSeq);
644
645 // Reset old properties
646 static const OUStringLiteral sTextPath(u"TextPath");
647 static const OUStringLiteral sAdjustmentValues(u"AdjustmentValues");
648 static const OUStringLiteral sPresetTextWarp(u"PresetTextWarp");
649
650 lcl_resetPropertyValue(aGeomPropVec, "CoordinateSize");
651 lcl_resetPropertyValue(aGeomPropVec, "Equations");
652 lcl_resetPropertyValue(aGeomPropVec, "Path");
653 lcl_resetPropertyValue(aGeomPropVec, sAdjustmentValues);
654
655 bool bFromWordArt(false);
656 pTextBody->getTextProperties().maPropertyMap.getProperty(PROP_FromWordArt) >>= bFromWordArt;
657
658 bool bScaleX(false);
659 if (!bFromWordArt
660 && (sMSPresetType == "textArchDown" || sMSPresetType == "textArchUp"
661 || sMSPresetType == "textCircle" || sMSPresetType == "textButton"))
662 {
663 bScaleX = true;
664 }
665
666 // Apply new properties
667 uno::Sequence<beans::PropertyValue> aPropertyValues(comphelper::InitPropertySequence(
668 { { sTextPath, uno::Any(true) },
669 { "TextPathMode", uno::Any(drawing::EnhancedCustomShapeTextPathMode_PATH) },
670 { "ScaleX", uno::Any(bScaleX) } }));
671
672 lcl_setPropertyValue(aGeomPropVec, sTextPath,
674
675 lcl_setPropertyValue(aGeomPropVec, sPresetTextWarp,
676 comphelper::makePropertyValue(sPresetTextWarp, sMSPresetType));
677
678 if (!aAdjGdList.empty())
679 {
680 lcl_setPropertyValue(aGeomPropVec, sAdjustmentValues,
681 comphelper::makePropertyValue(sAdjustmentValues, aAdjustment));
682 }
683
684 xSet->setPropertyValue("CustomShapeGeometry",
686}
687
688// LO does not interpret properties in styles belonging to the text content of a FontWork shape,
689// but only those in the shape style. This method copies properties from the text content styles to
690// the shape style.
691static void lcl_copyCharPropsToShape(const uno::Reference<drawing::XShape>& xShape,
692 const TextBodyPtr& pTextBody,
693 const ::oox::core::XmlFilterBase& rFilter)
694{
695 if (!xShape.is() || !pTextBody)
696 return;
697
698 Reference<XPropertySet> xSet(xShape, UNO_QUERY);
699 if (!xSet.is())
700 return;
701
702 // Content stretches or scales to given width and height, thus disable autogrow.
703 xSet->setPropertyValue(UNO_NAME_TEXT_AUTOGROWHEIGHT, uno::Any(false));
704 xSet->setPropertyValue(UNO_NAME_TEXT_AUTOGROWWIDTH, uno::Any(false));
705
706 // LibreOffice is not able (as of Nov 2022) to use different styles for the paragraphs or
707 // characters in FontWork, since that was not allowed in old binary WordArt. We use the
708 // properties of the first non empty paragraph for now.
709 const TextParagraphVector& rParagraphs = pTextBody->getParagraphs();
710 auto aParaIt = std::find_if_not(rParagraphs.cbegin(), rParagraphs.cend(),
711 [](const std::shared_ptr<TextParagraph> pParagraph) {
712 return pParagraph->getRuns().empty();
713 });
714 if (aParaIt != rParagraphs.cend())
715 {
716 std::shared_ptr<TextParagraph> pParagraph = *aParaIt;
717 const TextRunVector& rRuns = pParagraph->getRuns();
718 auto aRunIt = std::find_if_not(
719 rRuns.cbegin(), rRuns.cend(),
720 [](const std::shared_ptr<TextRun> pRun) { return pRun->getText().isEmpty(); });
721 if (aRunIt != rRuns.cend())
722 {
723 std::shared_ptr<TextRun> pRun = *aRunIt;
724 TextCharacterProperties& rCharProps = pRun->getTextCharacterProperties();
725
726 // set language
727 if (rCharProps.moLang.has_value() && !rCharProps.moLang.value().isEmpty())
728 {
729 LanguageTag aTag(rCharProps.moLang.value());
730 css::lang::Locale aLocale(aTag.getLocale(false));
732 {
733 case css::i18n::ScriptType::LATIN:
734 xSet->setPropertyValue(u"CharLocale", uno::Any(aLocale));
735 break;
736 case css::i18n::ScriptType::ASIAN:
737 xSet->setPropertyValue(u"CharLocaleAsian", uno::Any(aLocale));
738 break;
739 case css::i18n::ScriptType::COMPLEX:
740 xSet->setPropertyValue(u"CharLocaleComplex", uno::Any(aLocale));
741 break;
742 default:;
743 }
744 }
745
746 // Font Weight, Posture, Height
747 if (rCharProps.moBold.has_value() && rCharProps.moBold.value())
748 {
749 xSet->setPropertyValue(UNO_NAME_CHAR_WEIGHT, uno::Any(css::awt::FontWeight::BOLD));
750 }
751 if (rCharProps.moItalic.has_value() && rCharProps.moItalic.value())
752 {
753 xSet->setPropertyValue(UNO_NAME_CHAR_POSTURE,
754 uno::Any(css::awt::FontSlant::FontSlant_ITALIC));
755 }
756 if (rCharProps.moHeight.has_value())
757 {
758 sal_Int32 nHeight = rCharProps.moHeight.value() / 100;
759 xSet->setPropertyValue(UNO_NAME_CHAR_HEIGHT, uno::Any(nHeight));
760 }
761
762 // Put theme fonts into shape properties
763 OUString sFontName;
764 sal_Int16 nFontPitch = 0;
765 sal_Int16 nFontFamily = 0;
766 bool bRet(false);
767 if (const Theme* pTheme = rFilter.getCurrentTheme())
768 {
769 // minor Latin
770 if (const TextFont* pFont = pTheme->resolveFont(u"+mn-lt"))
771 {
772 bRet = pFont->getFontData(sFontName, nFontPitch, nFontFamily, rFilter);
773 if (bRet)
774 {
775 xSet->setPropertyValue(u"CharFontName", uno::Any(sFontName));
776 xSet->setPropertyValue(u"CharFontPitch", uno::Any(nFontPitch));
777 xSet->setPropertyValue(u"CharFontFamily", uno::Any(nFontFamily));
778 }
779 }
780 // minor Asian
781 if (const TextFont* pFont = pTheme->resolveFont(u"+mn-ea"))
782 {
783 bRet = pFont->getFontData(sFontName, nFontPitch, nFontFamily, rFilter);
784 if (bRet)
785 {
786 xSet->setPropertyValue(u"CharFontNameAsian", uno::Any(sFontName));
787 xSet->setPropertyValue(u"CharFontPitchAsian", uno::Any(nFontPitch));
788 xSet->setPropertyValue(u"CharFontFamilyAsian", uno::Any(nFontFamily));
789 }
790 }
791 // minor Complex
792 if (const TextFont* pFont = pTheme->resolveFont(u"+mn-cs"))
793 {
794 bRet = pFont->getFontData(sFontName, nFontPitch, nFontFamily, rFilter);
795 if (bRet)
796 {
797 xSet->setPropertyValue(u"CharFontNameComplex", uno::Any(sFontName));
798 xSet->setPropertyValue(u"CharFontPitchComplex", uno::Any(nFontPitch));
799 xSet->setPropertyValue(u"CharFontFamilyComplex", uno::Any(nFontFamily));
800 }
801 }
802 }
803
804 // Replace theme fonts with formatting at run if any. ToDo: Inspect paragraph too?
805 // Latin
806 bRet = rCharProps.maLatinFont.getFontData(sFontName, nFontPitch, nFontFamily, rFilter);
807 if (!bRet)
808 // In case there is no direct font, try to look it up as a theme reference.
809 bRet = rCharProps.maLatinThemeFont.getFontData(sFontName, nFontPitch, nFontFamily,
810 rFilter);
811
812 if (bRet)
813 {
814 xSet->setPropertyValue(u"CharFontName", uno::Any(sFontName));
815 xSet->setPropertyValue(u"CharFontPitch", uno::Any(nFontPitch));
816 xSet->setPropertyValue(u"CharFontFamily", uno::Any(nFontFamily));
817 }
818 // Asian
819 bRet = rCharProps.maAsianFont.getFontData(sFontName, nFontPitch, nFontFamily, rFilter);
820 if (!bRet)
821 // In case there is no direct font, try to look it up as a theme reference.
822 bRet = rCharProps.maAsianThemeFont.getFontData(sFontName, nFontPitch, nFontFamily,
823 rFilter);
824 if (bRet)
825 {
826 xSet->setPropertyValue(u"CharFontNameAsian", uno::Any(sFontName));
827 xSet->setPropertyValue(u"CharFontPitchAsian", uno::Any(nFontPitch));
828 xSet->setPropertyValue(u"CharFontFamilyAsian", uno::Any(nFontFamily));
829 }
830 // Complex
831 bRet
832 = rCharProps.maComplexFont.getFontData(sFontName, nFontPitch, nFontFamily, rFilter);
833 if (!bRet)
834 // In case there is no direct font, try to look it up as a theme reference.
835 bRet = rCharProps.maComplexThemeFont.getFontData(sFontName, nFontPitch, nFontFamily,
836 rFilter);
837 if (bRet)
838 {
839 xSet->setPropertyValue(u"CharFontNameComplex", uno::Any(sFontName));
840 xSet->setPropertyValue(u"CharFontPitchComplex", uno::Any(nFontPitch));
841 xSet->setPropertyValue(u"CharFontFamilyComplex", uno::Any(nFontFamily));
842 }
843
844 // LO uses shape fill, MS Office character fill. Currently only this solid fill workaround
845 // is implemented.
846 // ToDo: Consider other fill styles
847 // ToDo: Consider Color Theme
848 xSet->setPropertyValue(UNO_NAME_FILLSTYLE, uno::Any(drawing::FillStyle_SOLID));
849 sal_Int32 aFillColor(COL_BLACK); //default
850 if (rCharProps.maFillProperties.maFillColor.isUsed())
851 {
852 aFillColor = static_cast<sal_Int32>(
853 rCharProps.maFillProperties.maFillColor.getColor(rFilter.getGraphicHelper())
854 .GetRGBColor());
855 }
856 xSet->setPropertyValue(UNO_NAME_FILLCOLOR, uno::Any(aFillColor));
857
858 // ToDo: copy character outline to shape stroke.
859 }
860
861 // LO does not evaluate paragraph alignment in text path mode. Use text area anchor instead.
862 {
863 ParagraphAdjust eAdjust = ParagraphAdjust_LEFT;
864 if (pParagraph->getProperties().getParaAdjust())
865 eAdjust = *pParagraph->getProperties().getParaAdjust();
866 xSet->setPropertyValue("ParaAdjust", uno::Any(eAdjust));
868 assert(pShape);
869 SdrTextHorzAdjust eHorzAdjust = lcl_convertAdjust(eAdjust);
870 pShape->SetMergedItem(SdrTextHorzAdjustItem(eHorzAdjust));
871 }
872 }
873
874 // Vertical adjustment is only meaningful for OOXML WordArt shapes of 'Follow Path' kinds. We set
875 // it so, that text position is approximately same as in MS Office.
876 const OUString sMSPresetType = pTextBody->getTextProperties().msPrst;
877 const OUString sFontworkType = PresetGeometryTypeNames::GetFontworkType(sMSPresetType);
879 assert(pShape);
880 if (sFontworkType == "fontwork-arch-up-curve" || sFontworkType == "fontwork-circle-curve")
881 pShape->SetMergedItem(SdrTextVertAdjustItem(SdrTextVertAdjust::SDRTEXTVERTADJUST_BOTTOM));
882 else if (sFontworkType == "fontwork-arch-down-curve")
883 pShape->SetMergedItem(SdrTextVertAdjustItem(SdrTextVertAdjust::SDRTEXTVERTADJUST_TOP));
884 else
885 pShape->SetMergedItem(SdrTextVertAdjustItem(SdrTextVertAdjust::SDRTEXTVERTADJUST_CENTER));
886}
887
888// Some helper methods for createAndInsert
889namespace
890{
891// mirrors aTransformation at its center axis
892// only valid if neither rotation or shear included
893void lcl_mirrorAtCenter(basegfx::B2DHomMatrix& aTransformation, bool bFlipH, bool bFlipV)
894{
895 if (!bFlipH && !bFlipV)
896 return;
897 basegfx::B2DPoint aCenter(0.5, 0.5);
898 aCenter *= aTransformation;
899 aTransformation.translate(-aCenter);
900 aTransformation.scale(bFlipH ? -1.0 : 1.0, bFlipV ? -1.0 : 1.0);
901 aTransformation.translate(aCenter);
902 return;
903}
904
905// only valid if neither rotation or shear included
906void lcl_doSpecialMSOWidthHeightToggle(basegfx::B2DHomMatrix& aTransformation)
907{
908 // The values are directly set at the matrix without any matrix multiplication.
909 // That way it is valid for lines too. Those have zero width or height.
910 const double fSx(aTransformation.get(0, 0));
911 const double fSy(aTransformation.get(1, 1));
912 const double fTx(aTransformation.get(0, 2));
913 const double fTy(aTransformation.get(1, 2));
914 aTransformation.set(0, 0, fSy);
915 aTransformation.set(1, 1, fSx);
916 aTransformation.set(0, 2, fTx + 0.5 * (fSx - fSy));
917 aTransformation.set(1, 2, fTy + 0.5 * (fSy - fSx));
918 return;
919}
920
921void lcl_RotateAtCenter(basegfx::B2DHomMatrix& aTransformation,sal_Int32 nMSORotationAngle)
922{
923 if (nMSORotationAngle == 0)
924 return;
925 double fRad = basegfx::deg2rad<60000>(nMSORotationAngle);
926 basegfx::B2DPoint aCenter(0.5, 0.5);
927 aCenter *= aTransformation;
928 aTransformation.translate(-aCenter);
929 aTransformation.rotate(fRad);
930 aTransformation.translate(aCenter);
931 return;
932}
933}
934
936 ::oox::core::XmlFilterBase& rFilterBase,
937 const OUString& rServiceName,
938 const Theme* pTheme,
939 const css::uno::Reference< css::drawing::XShapes >& rxShapes,
940 bool bClearText,
941 bool bDoNotInsertEmptyTextBody,
942 basegfx::B2DHomMatrix& aParentTransformation,
943 const FillProperties& rShapeOrParentShapeFillProps,
944 oox::drawingml::ShapePtr pParentGroupShape)
945{
946 bool bIsEmbMedia = false;
947 SAL_INFO("oox.drawingml", "Shape::createAndInsert: id='" << msId << "' service='" << rServiceName << "'");
948
949 formulaimport::XmlStreamBuilder * pMathXml(nullptr);
950 if (mpTextBody)
951 {
952 for (auto const& it : mpTextBody->getParagraphs())
953 {
954 if (it->HasMathXml())
955 {
956 if (!mpTextBody->isEmpty() || pMathXml != nullptr)
957 {
958 SAL_WARN("oox.drawingml", "losing a Math object...");
959 }
960 else
961 {
962 pMathXml = &it->GetMathXml();
963 }
964 }
965 }
966 }
967
968 // tdf#90403 PowerPoint ignores a:ext cx and cy values of p:xfrm, and uses real table width and height
969 if ( mpTablePropertiesPtr && rServiceName == "com.sun.star.drawing.TableShape" )
970 {
971 maSize.Width = 0;
972 for (auto const& elem : mpTablePropertiesPtr->getTableGrid())
973 {
974 maSize.Width = o3tl::saturating_add(maSize.Width, static_cast<sal_Int32>(elem));
975 }
976 maSize.Height = 0;
977 for (auto const& elem : mpTablePropertiesPtr->getTableRows())
978 {
979 // WARN: If some rows can't fit the content, this is not the final height
980 maSize.Height = o3tl::saturating_add(maSize.Height, elem.getHeight());
981 }
982 }
983
984 awt::Rectangle aShapeRectHmm(
989
990 OUString aServiceName;
991 if (pMathXml)
992 {
993 // convert this shape to OLE
994 aServiceName = "com.sun.star.drawing.OLE2Shape";
995 msServiceName = aServiceName;
996 meFrameType = FRAMETYPE_GENERIC; // not OLEOBJECT, no stream in package
997 mnSubType = 0;
998 }
999 else if (rServiceName == "com.sun.star.drawing.GraphicObjectShape" &&
1000 mpGraphicPropertiesPtr && !mpGraphicPropertiesPtr->m_sMediaPackageURL.isEmpty())
1001 {
1002 aServiceName = finalizeServiceName( rFilterBase, "com.sun.star.presentation.MediaShape", aShapeRectHmm );
1003 bIsEmbMedia = true;
1004 }
1005 else
1006 {
1007 aServiceName = finalizeServiceName( rFilterBase, rServiceName, aShapeRectHmm );
1008 }
1009 // Use custom shape instead of GraphicObjectShape if the image is cropped to
1010 // shape. Except rectangle, which does not require further cropping
1011 bool bIsCroppedGraphic = (aServiceName == "com.sun.star.drawing.GraphicObjectShape" &&
1012 !mpCustomShapePropertiesPtr->representsDefaultShape());
1013
1014 bool bIsCustomShape = (aServiceName == "com.sun.star.drawing.CustomShape" || bIsCroppedGraphic);
1015 bool bIsConnectorShape = (aServiceName == "com.sun.star.drawing.ConnectorShape");
1016 if(bIsCroppedGraphic)
1017 {
1018 aServiceName = "com.sun.star.drawing.CustomShape";
1019 mpGraphicPropertiesPtr->mbIsCustomShape = true;
1020 }
1021 bool bUseRotationTransform = ( !mbWps ||
1022 aServiceName == "com.sun.star.drawing.LineShape" ||
1023 aServiceName == "com.sun.star.drawing.GroupShape" ||
1024 mbFlipH ||
1025 mbFlipV );
1026
1027 basegfx::B2DHomMatrix aTransformation; // will be cumulative transformation of this object
1028
1029 // Special for SmartArt import. Rotate diagram's shape around object's center before sizing.
1030 if (bUseRotationTransform && mnDiagramRotation != 0)
1031 {
1032 aTransformation.translate(-0.5, -0.5);
1033 aTransformation.rotate(basegfx::deg2rad<60000>(mnDiagramRotation));
1034 aTransformation.translate(0.5, 0.5);
1035 }
1036
1037 // Build object matrix from shape size and position; corresponds to MSO ext and off
1038 // Only LineShape and ConnectorShape may have zero width or height.
1039 if (aServiceName == "com.sun.star.drawing.LineShape"
1040 || aServiceName == "com.sun.star.drawing.ConnectorShape")
1041 aTransformation.scale(maSize.Width, maSize.Height);
1042 else
1043 {
1044 aTransformation.scale(maSize.Width ? maSize.Width : 1.0,
1045 maSize.Height ? maSize.Height : 1.0);
1046 }
1047
1048 // Evaluate object flip. Other shapes than custom shapes have no attribute for flip but use
1049 // negative scale. Flip in MSO is at object center.
1050 if (!bIsCustomShape && (mbFlipH || mbFlipV))
1051 lcl_mirrorAtCenter(aTransformation, mbFlipH, mbFlipV);
1052
1053 // Evaluate parent flip.
1054 // A CustomShape has mirror not as negative scale, but as attributes.
1055 basegfx::B2DVector aParentScale(1.0, 1.0);
1056 basegfx::B2DVector aParentTranslate(0.0, 0.0);
1057 double fParentRotate(0.0);
1058 double fParentShearX(0.0);
1059 if (pParentGroupShape)
1060 {
1061 aParentTransformation.decompose(aParentScale, aParentTranslate, fParentRotate, fParentShearX);
1062 if (bIsCustomShape)
1063 {
1064 lcl_mirrorAtCenter(aTransformation, aParentScale.getX() < 0, aParentScale.getY() < 0);
1065 if(aParentScale.getX() < 0)
1066 mbFlipH = !mbFlipH;
1067 if(aParentScale.getY() < 0)
1068 mbFlipV = !mbFlipV;
1069 }
1070 }
1071
1072 if (maPosition.X != 0 || maPosition.Y != 0)
1073 {
1074 // if global position is used, add it to transformation
1075 if (mbWps && pParentGroupShape == nullptr)
1076 aTransformation.translate(
1079 else
1080 aTransformation.translate(maPosition.X, maPosition.Y);
1081 }
1082
1083 // Apply further parent transformations. First scale object then rotate. Other way round would
1084 // introduce shearing.
1085
1086 // The attributes chExt and chOff of the group in oox file contain the values on which the size
1087 // and position of the child is based on. If they differ from the actual size of the group as
1088 // given in its ext and off attributes, the child has to be transformed according the new values.
1089 if (pParentGroupShape)
1090 {
1091 // ToDo: A diagram in a group might need special handling because it cannot flip and only
1092 // resize uniformly. But currently it is imported with zero size, see tdf#139575. That needs
1093 // to be fixed beforehand.
1094
1095 // Scaling is done from left/top edges of the group. So these need to become coordinate axes.
1096 aTransformation.translate(-pParentGroupShape->maChPosition.X,
1097 -pParentGroupShape->maChPosition.Y);
1098
1099 // oox allows zero or missing attribute chExt. In that case the scaling factor is 1.
1100 // Transform2DContext::onCreateContext has set maChSize to maSize for groups in oox file in
1101 // such cases. For own made groups (e.g. diagrams) that is missing.
1102 // The factors cumulate on the way through the parent groups, so we do not use maSize of the
1103 // direct parent group but the cumulated value from aParentScale.
1104 double fFactorX = 1.0;
1105 double fFactorY = 1.0;
1106 if (pParentGroupShape->maChSize.Width != 0)
1107 fFactorX = aParentScale.getX() / pParentGroupShape->maChSize.Width;
1108 if (pParentGroupShape->maChSize.Height != 0)
1109 fFactorY = aParentScale.getY() / pParentGroupShape->maChSize.Height;
1110 if (fFactorX != 1 || fFactorY != 1)
1111 {
1112 // It depends on the object rotation angle whether scaling is applied to switched
1113 // width and height. MSO acts strange in that case (as of May 2021).
1114 const sal_Int32 nDeg(mnRotation / 60000);
1115 const bool bNeedsMSOWidthHeightToggle
1116 = (nDeg >= 45 && nDeg < 135) || (nDeg >= 225 && nDeg < 315);
1117 if (bNeedsMSOWidthHeightToggle)
1118 lcl_doSpecialMSOWidthHeightToggle(aTransformation);
1119
1120 aTransformation.scale(fFactorX, fFactorY);
1121
1122 if (bNeedsMSOWidthHeightToggle)
1123 {
1124 lcl_doSpecialMSOWidthHeightToggle(aTransformation);
1125 // In case of flip the special case needs an additional 180deg rotation.
1126 if ((aParentScale.getX() < 0) != (aParentScale.getY() < 0))
1127 lcl_RotateAtCenter(aTransformation, 10800000);
1128 }
1129 }
1130 }
1131
1132 // Apply object rotation at current object center
1133 // The flip contained in aParentScale will affect orientation of object rotation angle.
1134 sal_Int16 nOrientation = ((aParentScale.getX() < 0) != (aParentScale.getY() < 0)) ? -1 : 1;
1135 // ToDo: Not sure about the restrictions given by bUseRotationTransform.
1136 // Since LibreOffice doesn't have 3D camera options for 2D shapes, rotate the shape opposite of
1137 // the camera Z axis rotation, in order to produce the same visual result from MSO
1138 const sal_Int32 nCameraRotation = get3DProperties().maCameraRotation.mnRevolution.value_or(0);
1139 if (bUseRotationTransform && (mnRotation != 0 || nCameraRotation != 0))
1140 lcl_RotateAtCenter(aTransformation, nOrientation * (mnRotation - nCameraRotation));
1141
1142 if (fParentRotate != 0.0)
1143 aTransformation.rotate(fParentRotate);
1144 if (!aParentTranslate.equalZero())
1145 aTransformation.translate(aParentTranslate);
1146
1147 aParentTransformation = aTransformation;
1148
1149 constexpr double fEmuToMm100 = o3tl::convert(1.0, o3tl::Length::emu, o3tl::Length::mm100);
1150 aTransformation.scale(fEmuToMm100, fEmuToMm100);
1151
1152 // OOXML flips shapes before rotating them, so the rotation needs to be inverted
1153 if( bIsCustomShape && mbFlipH != mbFlipV )
1154 {
1155 basegfx::B2DVector aScale, aTranslate;
1156 double fRotate, fShearX;
1157 aTransformation.decompose(aScale, aTranslate, fRotate, fShearX);
1158
1159 if(fRotate != 0)
1160 {
1161 basegfx::B2DPoint aCenter(0.5, 0.5);
1162 aCenter *= aTransformation;
1163 aTransformation.translate( -aCenter.getX(), -aCenter.getY() );
1164 aTransformation.rotate( fRotate * -2.0 );
1165 aTransformation.translate( aCenter.getX(), aCenter.getY() );
1166 }
1167 }
1168
1169 // special for lineshape
1170 if ( aServiceName == "com.sun.star.drawing.LineShape" )
1171 {
1173 aPoly.insert( 0, ::basegfx::B2DPoint( 0, 0 ) );
1174 aPoly.insert( 1, ::basegfx::B2DPoint( maSize.Width ? 1 : 0, maSize.Height ? 1 : 0 ) );
1175 aPoly.transform( aTransformation );
1176
1177 // now creating the corresponding PolyPolygon
1178 sal_Int32 i, nNumPoints = aPoly.count();
1179 uno::Sequence< awt::Point > aPointSequence( nNumPoints );
1180 awt::Point* pPoints = aPointSequence.getArray();
1181 for( i = 0; i < nNumPoints; ++i )
1182 {
1183 basegfx::B2DPoint aPoint( aPoly.getB2DPoint( i ) );
1184
1185 // Guard against zero width or height.
1186 if (i)
1187 {
1188 const basegfx::B2DPoint& rPreviousPoint = aPoly.getB2DPoint(i - 1);
1189 if (aPoint.getX() - rPreviousPoint.getX() == 0)
1190 aPoint.setX(aPoint.getX() + 1);
1191 if (aPoint.getY() - rPreviousPoint.getY() == 0)
1192 aPoint.setY(aPoint.getY() + 1);
1193 }
1194
1195 pPoints[i] = awt::Point(static_cast<sal_Int32>(aPoint.getX()), static_cast<sal_Int32>(aPoint.getY()));
1196 }
1197 uno::Sequence< uno::Sequence< awt::Point > > aPolyPolySequence( 1 );
1198 aPolyPolySequence.getArray()[ 0 ] = aPointSequence;
1199
1200 maShapeProperties.setProperty(PROP_PolyPolygon, aPolyPolySequence);
1201 }
1202 else if ( aServiceName == "com.sun.star.drawing.ConnectorShape" )
1203 {
1205 aPoly.insert( 0, ::basegfx::B2DPoint( 0, 0 ) );
1206 aPoly.insert( 1, ::basegfx::B2DPoint( maSize.Width ? 1 : 0, maSize.Height ? 1 : 0 ) );
1207 aPoly.transform( aTransformation );
1208
1209 basegfx::B2DPoint aStartPosition( aPoly.getB2DPoint( 0 ) );
1210 basegfx::B2DPoint aEndPosition( aPoly.getB2DPoint( 1 ) );
1211 awt::Point aAWTStartPosition( static_cast< sal_Int32 >( aStartPosition.getX() ), static_cast< sal_Int32 >( aStartPosition.getY() ) );
1212 awt::Point aAWTEndPosition( static_cast< sal_Int32 >( aEndPosition.getX() ), static_cast< sal_Int32 >( aEndPosition.getY() ) );
1213
1214 maShapeProperties.setProperty(PROP_StartPosition, aAWTStartPosition);
1215 maShapeProperties.setProperty(PROP_EndPosition, aAWTEndPosition);
1216 }
1217 else
1218 {
1219 // now set transformation for this object
1220 HomogenMatrix3 aMatrix;
1221
1222 aMatrix.Line1.Column1 = aTransformation.get(0,0);
1223 aMatrix.Line1.Column2 = aTransformation.get(0,1);
1224 aMatrix.Line1.Column3 = aTransformation.get(0,2);
1225
1226 aMatrix.Line2.Column1 = aTransformation.get(1,0);
1227 aMatrix.Line2.Column2 = aTransformation.get(1,1);
1228 aMatrix.Line2.Column3 = aTransformation.get(1,2);
1229
1230 aMatrix.Line3.Column1 = aTransformation.get(2,0);
1231 aMatrix.Line3.Column2 = aTransformation.get(2,1);
1232 aMatrix.Line3.Column3 = aTransformation.get(2,2);
1233
1234 maShapeProperties.setProperty(PROP_Transformation, aMatrix);
1235 }
1236
1237 Reference< lang::XMultiServiceFactory > xServiceFact( rFilterBase.getModel(), UNO_QUERY_THROW );
1238 if ( !mxShape.is() )
1239 {
1240 mxShape.set( xServiceFact->createInstance( aServiceName ), UNO_QUERY_THROW );
1241 }
1242
1243 Reference< XPropertySet > xSet( mxShape, UNO_QUERY );
1244 if (xSet.is())
1245 {
1246 if( !msName.isEmpty() )
1247 {
1248 Reference< container::XNamed > xNamed( mxShape, UNO_QUERY );
1249 if( xNamed.is() )
1250 xNamed->setName( msName );
1251 }
1252 if( !msDescription.isEmpty() )
1253 {
1254 xSet->setPropertyValue( "Description", Any( msDescription ) );
1255 }
1256 if (aServiceName != "com.sun.star.text.TextFrame")
1257 rxShapes->add( mxShape );
1258
1260 {
1261 SAL_INFO("oox.drawingml", "Shape::createAndInsert: invisible shape with id='" << msId << "'");
1262 xSet->setPropertyValue( "Visible", Any( false ) );
1263 // In Excel hidden means not printed, let's use visibility for now until that's handled separately
1264 xSet->setPropertyValue( "Printable", Any( false ) );
1265 }
1266
1267 if (mbLocked)
1268 {
1269 xSet->setPropertyValue("MoveProtect", Any(true));
1270 xSet->setPropertyValue("SizeProtect", Any(true));
1271 }
1272
1273 ActionLockGuard const alg(mxShape);
1274
1275 // sj: removing default text of placeholder objects such as SlideNumberShape or HeaderShape
1276 if ( bClearText )
1277 {
1278 uno::Reference< text::XText > xText( mxShape, uno::UNO_QUERY );
1279 if ( xText.is() )
1280 {
1281 xText->setString( "" );
1282 }
1283 }
1284
1285 if (pMathXml)
1286 {
1287 // the "EmbeddedObject" property is read-only, so we have to create
1288 // the shape first, and it can be read only after the shape is
1289 // inserted into the document, so delay the actual import until here
1291 xSet->setPropertyValue("CLSID", uno::Any(name.GetHexName()));
1292 uno::Reference<embed::XEmbeddedObject> const xObj(
1293 xSet->getPropertyValue("EmbeddedObject"), uno::UNO_QUERY);
1294 if (xObj.is())
1295 {
1296 uno::Reference<uno::XInterface> const xMathModel(xObj->getComponent());
1297 oox::FormulaImportBase *const pMagic(
1298 dynamic_cast<oox::FormulaImportBase*>(xMathModel.get()));
1299 assert(pMagic);
1300 pMagic->readFormulaOoxml(*pMathXml);
1301 }
1302 }
1303
1304 const GraphicHelper& rGraphicHelper = rFilterBase.getGraphicHelper();
1305
1306 ::Color nLinePhClr(ColorTransparency, 0xffffffff);
1307 ::Color nFillPhClr(ColorTransparency, 0xffffffff);
1308 sal_Int16 nFillPhClrTheme = -1;
1309 // TODO: use ph color when applying effect properties
1310 //sal_Int32 nEffectPhClr = -1;
1311
1312 // dmapper needs the original rotation angle for calculating square wrap. This angle is not
1313 // available as property there, so store it in InteropGrabBag.
1314 putPropertyToGrabBag("mso-rotation-angle", Any(mnRotation));
1315
1316 if( pTheme )
1317 {
1318 if( const ShapeStyleRef* pLineRef = getShapeStyleRef( XML_lnRef ) )
1319 {
1320 LineProperties aLineProperties;
1321 aLineProperties.maLineFill.moFillType = XML_noFill;
1322 if( const LineProperties* pLineProps = pTheme->getLineStyle( pLineRef->mnThemedIdx ) )
1323 aLineProperties.assignUsed( *pLineProps );
1324 nLinePhClr = pLineRef->maPhClr.getColor( rGraphicHelper );
1325
1326 // Store style-related properties to InteropGrabBag to be able to export them back
1327 uno::Sequence<beans::PropertyValue> aProperties = comphelper::InitPropertySequence(
1328 {
1329 {"SchemeClr", uno::Any(pLineRef->maPhClr.getSchemeColorName())},
1330 {"Idx", uno::Any(pLineRef->mnThemedIdx)},
1331 {"Color", uno::Any(nLinePhClr)},
1332 {"LineStyle", uno::Any(aLineProperties.getLineStyle())},
1333 {"LineCap", uno::Any(aLineProperties.getLineCap())},
1334 {"LineJoint", uno::Any(aLineProperties.getLineJoint())},
1335 {"LineWidth", uno::Any(aLineProperties.getLineWidth())},
1336 {"Transformations", uno::Any(pLineRef->maPhClr.getTransformations())}
1337 });
1338 putPropertyToGrabBag( "StyleLnRef", Any( aProperties ) );
1339 }
1340 if( const ShapeStyleRef* pFillRef = getShapeStyleRef( XML_fillRef ) )
1341 {
1342 if (!getFillProperties().moUseBgFill.value_or(false))
1343 {
1344 nFillPhClr = pFillRef->maPhClr.getColor(rGraphicHelper);
1345 nFillPhClrTheme = pFillRef->maPhClr.getSchemeColorIndex();
1346 }
1347
1348 OUString sColorScheme = pFillRef->maPhClr.getSchemeColorName();
1349 if( !sColorScheme.isEmpty() )
1350 {
1351 uno::Sequence<beans::PropertyValue> aProperties = comphelper::InitPropertySequence(
1352 {
1353 {"SchemeClr", uno::Any(sColorScheme)},
1354 {"Idx", uno::Any(pFillRef->mnThemedIdx)},
1355 {"Color", uno::Any(nFillPhClr)},
1356 {"Transformations", uno::Any(pFillRef->maPhClr.getTransformations())}
1357 });
1358
1359 putPropertyToGrabBag( "StyleFillRef", Any( aProperties ) );
1360 }
1361 }
1362 if( const ShapeStyleRef* pEffectRef = getShapeStyleRef( XML_effectRef ) )
1363 {
1364 // TODO: use ph color when applying effect properties
1365 // nEffectPhClr = pEffectRef->maPhClr.getColor( rGraphicHelper );
1366
1367 // Store style-related properties to InteropGrabBag to be able to export them back
1368 uno::Sequence<beans::PropertyValue> aProperties = comphelper::InitPropertySequence(
1369 {
1370 {"SchemeClr", uno::Any(pEffectRef->maPhClr.getSchemeColorName())},
1371 {"Idx", uno::Any(pEffectRef->mnThemedIdx)},
1372 {"Transformations", uno::Any(pEffectRef->maPhClr.getTransformations())}
1373 });
1374 putPropertyToGrabBag( "StyleEffectRef", Any( aProperties ) );
1375 }
1376 }
1377 ShapePropertyMap aShapeProps( rFilterBase.getModelObjectHelper() );
1378
1379 // add properties from textbody to shape properties
1380 if( mpTextBody )
1381 {
1382 mpTextBody->getTextProperties().pushTextDistances(Size(aShapeRectHmm.Width, aShapeRectHmm.Height));
1383 aShapeProps.assignUsed( mpTextBody->getTextProperties().maPropertyMap );
1384 // Push char properties as well - specifically useful when this is a placeholder
1385 if( mpMasterTextListStyle && mpMasterTextListStyle->getListStyle()[0].getTextCharacterProperties().moHeight.has_value() )
1386 aShapeProps.setProperty(PROP_CharHeight, GetFontHeight( mpMasterTextListStyle->getListStyle()[0].getTextCharacterProperties().moHeight.value() ));
1387 }
1388
1389 // applying properties
1390 aShapeProps.assignUsed( getShapeProperties() );
1391 aShapeProps.assignUsed( maDefaultShapeProperties );
1392 if(mnRotation != 0 && bIsCustomShape)
1393 aShapeProps.setProperty( PROP_RotateAngle, sal_Int32( NormAngle36000( Degree100(mnRotation / -600) ) ));
1394 if( bIsEmbMedia ||
1395 bIsCustomShape ||
1396 aServiceName == "com.sun.star.drawing.GraphicObjectShape" ||
1397 aServiceName == "com.sun.star.drawing.OLE2Shape")
1398 {
1399 mpGraphicPropertiesPtr->pushToPropMap( aShapeProps, rGraphicHelper, mbFlipH, mbFlipV );
1400 }
1401 if ( mpTablePropertiesPtr && aServiceName == "com.sun.star.drawing.TableShape" )
1402 {
1403 mpTablePropertiesPtr->pushToPropSet( rFilterBase, xSet, mpMasterTextListStyle );
1404 if ( auto* pTableShape = dynamic_cast<sdr::table::SdrTableObj*>(SdrObject::getSdrObjectFromXShape(mxShape)) )
1405 {
1406 // Disable layouting until table height is expanded to fit the content
1407 pTableShape->SetSkipChangeLayout(true);
1408 }
1409 }
1410
1411 FillProperties aFillProperties = getActualFillProperties(pTheme, &rShapeOrParentShapeFillProps);
1412 if (getFillProperties().moFillType.has_value() && getFillProperties().moFillType.value() == XML_grpFill)
1413 getFillProperties().assignUsed(aFillProperties);
1414 if(!bIsCroppedGraphic)
1415 aFillProperties.pushToPropMap( aShapeProps, rGraphicHelper, mnRotation, nFillPhClr, nFillPhClrTheme, mbFlipH, mbFlipV, bIsCustomShape );
1416 LineProperties aLineProperties = getActualLineProperties(pTheme);
1417 aLineProperties.pushToPropMap( aShapeProps, rGraphicHelper, nLinePhClr );
1418 EffectProperties aEffectProperties = getActualEffectProperties(pTheme);
1419 // TODO: use ph color when applying effect properties
1420 aEffectProperties.pushToPropMap( aShapeProps, rGraphicHelper );
1421
1422 // applying autogrowheight property before setting shape size, because
1423 // the shape size might be changed if currently autogrowheight is true
1424 // we must also check that the PropertySet supports the property.
1425 Reference< XPropertySetInfo > xSetInfo( xSet->getPropertySetInfo() );
1426 const OUString& rPropName = PropertyMap::getPropertyName( PROP_TextAutoGrowHeight );
1427 if( xSetInfo.is() && xSetInfo->hasPropertyByName( rPropName ) )
1428 if( aShapeProps.hasProperty( PROP_TextAutoGrowHeight ) )
1429 xSet->setPropertyValue( rPropName, Any( false ) );
1430
1431 // do not set properties at a group shape (this causes
1432 // assertions from svx) ...
1433 if( aServiceName != "com.sun.star.drawing.GroupShape" )
1434 {
1435 if (aServiceName == "com.sun.star.text.TextFrame")
1436 {
1437 if (mpCustomShapePropertiesPtr && mpCustomShapePropertiesPtr->getShapeTypeOverride())
1438 {
1439 uno::Reference<beans::XPropertySet> propertySet (mxShape, uno::UNO_QUERY);
1440 uno::Sequence<beans::PropertyValue> aGrabBag;
1441 propertySet->getPropertyValue("FrameInteropGrabBag") >>= aGrabBag;
1442 sal_Int32 length = aGrabBag.getLength();
1443 aGrabBag.realloc( length+1);
1444 auto pGrabBag = aGrabBag.getArray();
1445 pGrabBag[length].Name = "mso-orig-shape-type";
1446 uno::Sequence< sal_Int8 > const & aNameSeq =
1447 mpCustomShapePropertiesPtr->getShapePresetTypeName();
1448 OUString sShapePresetTypeName(reinterpret_cast< const char* >(
1449 aNameSeq.getConstArray()), aNameSeq.getLength(), RTL_TEXTENCODING_UTF8);
1450 pGrabBag[length].Value <<= sShapePresetTypeName;
1451 propertySet->setPropertyValue("FrameInteropGrabBag",uno::Any(aGrabBag));
1452 }
1453 //If the text box has links then save the link information so that
1454 //it can be accessed in DomainMapper_Impl.cxx while chaining the text frames.
1455 if (isLinkedTxbx())
1456 {
1457 uno::Reference<beans::XPropertySet> propertySet (mxShape, uno::UNO_QUERY);
1458 uno::Sequence<beans::PropertyValue> aGrabBag;
1459 propertySet->getPropertyValue("FrameInteropGrabBag") >>= aGrabBag;
1460 sal_Int32 length = aGrabBag.getLength();
1461 aGrabBag.realloc( length + 3 );
1462 auto pGrabBag = aGrabBag.getArray();
1463 pGrabBag[length].Name = "TxbxHasLink";
1464 pGrabBag[length].Value <<= isLinkedTxbx();
1465 pGrabBag[length + 1 ].Name = "Txbx-Id";
1466 pGrabBag[length + 1 ].Value <<= getLinkedTxbxAttributes().id;
1467 pGrabBag[length + 2 ].Name = "Txbx-Seq";
1468 pGrabBag[length + 2 ].Value <<= getLinkedTxbxAttributes().seq;
1469 propertySet->setPropertyValue("FrameInteropGrabBag",uno::Any(aGrabBag));
1470 }
1471
1472 // TextFrames have BackColor, not FillColor
1473 if (aShapeProps.hasProperty(PROP_FillColor))
1474 {
1475 aShapeProps.setAnyProperty(PROP_BackColor, aShapeProps.getProperty(PROP_FillColor));
1476 aShapeProps.erase(PROP_FillColor);
1477 }
1478 // TextFrames have BackColorTransparency, not FillTransparence
1479 if (aShapeProps.hasProperty(PROP_FillTransparence))
1480 {
1482 aShapeProps.erase(PROP_FillTransparence);
1483 }
1484 // TextFrames have BackGraphic, not FillBitmap
1485 if (aShapeProps.hasProperty(PROP_FillBitmap))
1486 {
1487 aShapeProps.setAnyProperty(PROP_BackGraphic, aShapeProps.getProperty(PROP_FillBitmap));
1488 aShapeProps.erase(PROP_FillBitmap);
1489 }
1490 if (aShapeProps.hasProperty(PROP_FillBitmapName))
1491 {
1492 uno::Any aAny = aShapeProps.getProperty(PROP_FillBitmapName);
1493 OUString aFillBitmapName = aAny.get<OUString>();
1494 uno::Reference<awt::XBitmap> xBitmap = rFilterBase.getModelObjectHelper().getFillBitmap(aFillBitmapName);
1495 uno::Reference<graphic::XGraphic> xGraphic(xBitmap, uno::UNO_QUERY);
1496 aShapeProps.setProperty(PROP_BackGraphic, xGraphic);
1497 // aShapeProps.erase(PROP_FillBitmapName); // Maybe, leave the name as well
1498 }
1499 // And no LineColor property; individual borders can have colors
1500 if (aShapeProps.hasProperty(PROP_LineColor))
1501 {
1502 uno::Reference<beans::XPropertySet> xPropertySet(mxShape, uno::UNO_QUERY);
1503 static const sal_Int32 aBorders[] =
1504 {
1506 };
1507 for (sal_Int32 nBorder : aBorders)
1508 {
1509 css::table::BorderLine2 aBorderLine = xPropertySet->getPropertyValue(PropertyMap::getPropertyName(nBorder)).get<css::table::BorderLine2>();
1510 aBorderLine.Color = aShapeProps.getProperty(PROP_LineColor).get<sal_Int32>();
1511 if (aLineProperties.moLineWidth.has_value())
1512 aBorderLine.LineWidth = convertEmuToHmm(aLineProperties.moLineWidth.value());
1513 aShapeProps.setProperty(nBorder, aBorderLine);
1514 }
1515 aShapeProps.erase(PROP_LineColor);
1516 }
1517 if(mnRotation)
1518 {
1519 uno::Reference<beans::XPropertySet> xPropertySet(mxShape, uno::UNO_QUERY);
1520 static const OUStringLiteral aGrabBagPropName = u"FrameInteropGrabBag";
1521 uno::Sequence<beans::PropertyValue> aGrabBag;
1522 xPropertySet->getPropertyValue(aGrabBagPropName) >>= aGrabBag;
1523 beans::PropertyValue aPair(comphelper::makePropertyValue("mso-rotation-angle",
1524 mnRotation));
1525 if (aGrabBag.hasElements())
1526 {
1527 sal_Int32 nLength = aGrabBag.getLength();
1528 aGrabBag.realloc(nLength + 1);
1529 aGrabBag.getArray()[nLength] = aPair;
1530 }
1531 else
1532 {
1533 aGrabBag = { aPair };
1534 }
1535 xPropertySet->setPropertyValue(aGrabBagPropName, uno::Any(aGrabBag));
1536 }
1537 // TextFrames have ShadowFormat, not individual shadow properties.
1538 std::optional<sal_Int32> oShadowDistance;
1539 if (aShapeProps.hasProperty(PROP_ShadowXDistance))
1540 {
1541 oShadowDistance = aShapeProps.getProperty(PROP_ShadowXDistance).get<sal_Int32>();
1542 aShapeProps.erase(PROP_ShadowXDistance);
1543 }
1544 if (aShapeProps.hasProperty(PROP_ShadowYDistance))
1545 {
1546 // There is a single 'dist' attribute, so no need to count the avg of x and y.
1547 aShapeProps.erase(PROP_ShadowYDistance);
1548 }
1549 std::optional<sal_Int32> oShadowColor;
1550 if (aShapeProps.hasProperty(PROP_ShadowColor))
1551 {
1552 oShadowColor = aShapeProps.getProperty(PROP_ShadowColor).get<sal_Int32>();
1553 aShapeProps.erase(PROP_ShadowColor);
1554 }
1555 if (aShapeProps.hasProperty(PROP_Shadow))
1556 aShapeProps.erase(PROP_Shadow);
1557
1558 if (oShadowDistance || oShadowColor || aEffectProperties.maShadow.moShadowDir.has_value())
1559 {
1560 css::table::ShadowFormat aFormat;
1561 if (oShadowColor)
1562 aFormat.Color = *oShadowColor;
1563 if (aEffectProperties.maShadow.moShadowDir.has_value())
1564 {
1565 css::table::ShadowLocation nLocation = css::table::ShadowLocation_NONE;
1566 switch (aEffectProperties.maShadow.moShadowDir.value())
1567 {
1568 case 13500000:
1569 nLocation = css::table::ShadowLocation_TOP_LEFT;
1570 break;
1571 case 18900000:
1572 nLocation = css::table::ShadowLocation_TOP_RIGHT;
1573 break;
1574 case 8100000:
1575 nLocation = css::table::ShadowLocation_BOTTOM_LEFT;
1576 break;
1577 case 2700000:
1578 nLocation = css::table::ShadowLocation_BOTTOM_RIGHT;
1579 break;
1580 }
1581 aFormat.Location = nLocation;
1582 }
1583 aFormat.ShadowWidth = *oShadowDistance;
1584 aShapeProps.setProperty(PROP_ShadowFormat, aFormat);
1585 }
1586
1587 }
1588 else if (mbTextBox)
1589 {
1590 // This introduces a TextBox in a shape in Writer. ToDo: Can we restrict it to cases
1591 // where the TextBox edit engine is really needed? tdf#82627
1592 aShapeProps.setProperty(PROP_TextBox, true);
1593 }
1594
1595 if (aServiceName != "com.sun.star.text.TextFrame" && isLinkedTxbx())
1596 {
1597 uno::Reference<beans::XPropertySet> propertySet (mxShape, uno::UNO_QUERY);
1598 uno::Sequence<beans::PropertyValue> aGrabBag;
1599 propertySet->getPropertyValue("InteropGrabBag") >>= aGrabBag;
1600 sal_Int32 length = aGrabBag.getLength();
1601 aGrabBag.realloc( length + 3 );
1602 auto pGrabBag = aGrabBag.getArray();
1603 pGrabBag[length].Name = "TxbxHasLink";
1604 pGrabBag[length].Value <<= isLinkedTxbx();
1605 pGrabBag[length + 1 ].Name = "Txbx-Id";
1606 pGrabBag[length + 1 ].Value <<= getLinkedTxbxAttributes().id;
1607 pGrabBag[length + 2 ].Name = "Txbx-Seq";
1608 pGrabBag[length + 2 ].Value <<= getLinkedTxbxAttributes().seq;
1609 propertySet->setPropertyValue("InteropGrabBag",uno::Any(aGrabBag));
1610 }
1611
1612 // If the shape is a picture placeholder.
1613 if (aServiceName == "com.sun.star.presentation.GraphicObjectShape" && !bClearText)
1614 {
1615 // Placeholder text should be in center of the shape.
1616 aShapeProps.setProperty(PROP_TextContourFrame, false);
1617
1618 /* Placeholder icon should be at the center of the parent shape.
1619 * We use negative graphic crop property because of that we don't
1620 * have padding support.
1621 */
1622 uno::Reference<beans::XPropertySet> xGraphic(xSet->getPropertyValue("Graphic"), uno::UNO_QUERY);
1623 if (xGraphic.is())
1624 {
1625 awt::Size aBitmapSize;
1626 xGraphic->getPropertyValue("Size100thMM") >>= aBitmapSize;
1627 sal_Int32 nXMargin = (aShapeRectHmm.Width - aBitmapSize.Width) / 2;
1628 sal_Int32 nYMargin = (aShapeRectHmm.Height - aBitmapSize.Height) / 2;
1629 if (nXMargin > 0 && nYMargin > 0)
1630 {
1631 text::GraphicCrop aGraphicCrop;
1632 aGraphicCrop.Top = nYMargin * -1;
1633 aGraphicCrop.Bottom = nYMargin * -1;
1634 aGraphicCrop.Left = nXMargin * -1;
1635 aGraphicCrop.Right = nXMargin * -1;
1636 aShapeProps.setProperty(PROP_GraphicCrop, aGraphicCrop);
1637 }
1638 }
1639 }
1640
1641 PropertySet( xSet ).setProperties( aShapeProps );
1642
1643 if (mpTablePropertiesPtr && aServiceName == "com.sun.star.drawing.TableShape")
1644 {
1645 // Powerpoint exports desired row heights (i.e. what user attempted to set it as, not how it appears visually)
1646 // Expand table height if there are rows that can't fit the content
1647 if (auto* pTableShape = dynamic_cast<sdr::table::SdrTableObj*>(SdrObject::getSdrObjectFromXShape(mxShape)))
1648 {
1649 tools::Rectangle aArea{};
1650 pTableShape->LayoutTableHeight(aArea, /*bFit=*/false);
1651 sal_Int32 nCorrectedHeight = aArea.GetHeight();
1652 const auto& aShapeSize = mxShape->getSize();
1653 if( nCorrectedHeight > aShapeSize.Height )
1654 mxShape->setSize( {aShapeSize.Width, nCorrectedHeight} );
1655 pTableShape->SetSkipChangeLayout(false);
1656 }
1657 }
1658
1659 if (mbLockedCanvas)
1660 {
1661 putPropertyToGrabBag( "LockedCanvas", Any( true ) );
1662 if (aServiceName == "com.sun.star.drawing.LineShape")
1663 {
1664 // It seems the position and size for lines inside a locked canvas is absolute.
1665 mxShape->setPosition(awt::Point(aShapeRectHmm.X, aShapeRectHmm.Y));
1666 mxShape->setSize(awt::Size(aShapeRectHmm.Width, aShapeRectHmm.Height));
1667 }
1668 }
1669
1670 // Store original fill and line colors of the shape and the theme color name to InteropGrabBag
1671 std::vector<beans::PropertyValue> aProperties
1672 {
1673 comphelper::makePropertyValue("EmuLineWidth", aLineProperties.moLineWidth.value_or(0)),
1674 comphelper::makePropertyValue("OriginalSolidFillClr", aShapeProps.getProperty(PROP_FillColor)),
1675 comphelper::makePropertyValue("OriginalLnSolidFillClr", aShapeProps.getProperty(PROP_LineColor))
1676 };
1677 OUString sColorFillScheme = aFillProperties.maFillColor.getSchemeColorName();
1678 if( !aFillProperties.maFillColor.isPlaceHolder() && !sColorFillScheme.isEmpty() )
1679 {
1680 aProperties.push_back(comphelper::makePropertyValue("SpPrSolidFillSchemeClr", sColorFillScheme));
1681 aProperties.push_back(comphelper::makePropertyValue("SpPrSolidFillSchemeClrTransformations", aFillProperties.maFillColor.getTransformations()));
1682 }
1683 OUString sLnColorFillScheme = aLineProperties.maLineFill.maFillColor.getSchemeColorName();
1684 if( !aLineProperties.maLineFill.maFillColor.isPlaceHolder() && !sLnColorFillScheme.isEmpty() )
1685 {
1686 aProperties.push_back(comphelper::makePropertyValue("SpPrLnSolidFillSchemeClr", sLnColorFillScheme));
1687 auto aResolvedSchemeClr = aLineProperties.maLineFill.maFillColor;
1688 aResolvedSchemeClr.clearTransformations();
1689 aProperties.push_back(comphelper::makePropertyValue("SpPrLnSolidFillResolvedSchemeClr", aResolvedSchemeClr.getColor(rGraphicHelper, nFillPhClr)));
1690 aProperties.push_back(comphelper::makePropertyValue("SpPrLnSolidFillSchemeClrTransformations", aLineProperties.maLineFill.maFillColor.getTransformations()));
1691 }
1693
1694 // Store original gradient fill of the shape to InteropGrabBag
1695 // LibreOffice doesn't support all the kinds of gradient so we save its complete definition
1696 if( aShapeProps.hasProperty( PROP_FillGradient ) )
1697 {
1698 std::vector<beans::PropertyValue> aGradientStops;
1699 size_t i = 0;
1700 for( const auto& [rPos, rColor] : aFillProperties.maGradientProps.maGradientStops )
1701 { // for each stop in the gradient definition:
1702
1703 // save position
1704 std::vector<beans::PropertyValue> aGradientStop
1705 {
1707 };
1708
1709 OUString sStopColorScheme = rColor.getSchemeColorName();
1710 if( sStopColorScheme.isEmpty() )
1711 {
1712 // save RGB color
1713 aGradientStop.push_back(comphelper::makePropertyValue("RgbClr", rColor.getColor(rGraphicHelper, nFillPhClr)));
1714 // in the case of a RGB color, transformations are already applied to
1715 // the color with the exception of alpha transformations. We only need
1716 // to keep the transparency value to calculate the alpha value later.
1717 if( rColor.hasTransparency() )
1718 aGradientStop.push_back(comphelper::makePropertyValue("Transparency", rColor.getTransparency()));
1719 }
1720 else
1721 {
1722 // save color with scheme name
1723 aGradientStop.push_back(comphelper::makePropertyValue("SchemeClr", sStopColorScheme));
1724 // save all color transformations
1725 aGradientStop.push_back(comphelper::makePropertyValue("Transformations", rColor.getTransformations()));
1726 }
1727
1728 aGradientStops.push_back(comphelper::makePropertyValue(OUString::number(i), comphelper::containerToSequence(aGradientStop)));
1729 ++i;
1730 }
1731 // If getFillProperties.moFillType is unused that means gradient is defined by a theme
1732 // which is already saved into StyleFillRef property, so no need to save the explicit values too
1733 if( getFillProperties().moFillType.has_value() )
1734 putPropertyToGrabBag( "GradFillDefinition", uno::Any(comphelper::containerToSequence(aGradientStops)));
1735 putPropertyToGrabBag( "OriginalGradFill", aShapeProps.getProperty(PROP_FillGradient) );
1736 }
1737
1738 // store unsupported effect attributes in the grab bag
1739 if (!aEffectProperties.m_Effects.empty())
1740 {
1741 std::vector<beans::PropertyValue> aEffects;
1742 for (auto const& it : aEffectProperties.m_Effects)
1743 {
1744 PropertyValue aEffect = it->getEffect();
1745 if( !aEffect.Name.isEmpty() )
1746 {
1747 std::vector<beans::PropertyValue> aEffectsGrabBag
1748 {
1749 comphelper::makePropertyValue("Attribs", aEffect.Value)
1750 };
1751
1752 Color& aColor( it->moColor );
1753 OUString sColorScheme = aColor.getSchemeColorName();
1754 if( sColorScheme.isEmpty() )
1755 {
1756 // RGB color and transparency value
1757 aEffectsGrabBag.push_back(comphelper::makePropertyValue("RgbClr", aColor.getColor(rGraphicHelper, nFillPhClr)));
1758 aEffectsGrabBag.push_back(comphelper::makePropertyValue("RgbClrTransparency", aColor.getTransparency()));
1759 }
1760 else
1761 {
1762 // scheme color with name and transformations
1763 aEffectsGrabBag.push_back(comphelper::makePropertyValue("SchemeClr", sColorScheme));
1764 aEffectsGrabBag.push_back(comphelper::makePropertyValue("SchemeClrTransformations", aColor.getTransformations()));
1765 }
1766 aEffects.push_back(comphelper::makePropertyValue(aEffect.Name, comphelper::containerToSequence(aEffectsGrabBag)));
1767 }
1768 }
1769 putPropertyToGrabBag("EffectProperties", uno::Any(comphelper::containerToSequence(aEffects)));
1770 }
1771
1772 // add 3D effects if any
1775 Sequence< PropertyValue > aShape3DEffects = get3DProperties().getShape3DAttributes( rGraphicHelper, nFillPhClr );
1776 if( aCamera3DEffects.hasElements() || aLightRig3DEffects.hasElements() || aShape3DEffects.hasElements() )
1777 {
1778 uno::Sequence<beans::PropertyValue> a3DEffectsGrabBag = comphelper::InitPropertySequence(
1779 {
1780 {"Camera", uno::Any(aCamera3DEffects)},
1781 {"LightRig", uno::Any(aLightRig3DEffects)},
1782 {"Shape3D", uno::Any(aShape3DEffects)}
1783 });
1784 putPropertyToGrabBag( "3DEffectProperties", Any( a3DEffectsGrabBag ) );
1785 }
1786
1787 if( bIsCustomShape && getTextBody())
1788 {
1789
1790 Sequence< PropertyValue > aTextCamera3DEffects = getTextBody()->get3DProperties().getCameraAttributes();
1791 Sequence< PropertyValue > aTextLightRig3DEffects = getTextBody()->get3DProperties().getLightRigAttributes();
1792 Sequence< PropertyValue > aTextShape3DEffects = getTextBody()->get3DProperties().getShape3DAttributes( rGraphicHelper, nFillPhClr );
1793 if( aTextCamera3DEffects.hasElements() || aTextLightRig3DEffects.hasElements() || aTextShape3DEffects.hasElements() )
1794 {
1795 uno::Sequence<beans::PropertyValue> aText3DEffectsGrabBag = comphelper::InitPropertySequence(
1796 {
1797 {"Camera", uno::Any(aTextCamera3DEffects)},
1798 {"LightRig", uno::Any(aTextLightRig3DEffects)},
1799 {"Shape3D", uno::Any(aTextShape3DEffects)}
1800 });
1801 putPropertyToGrabBag( "Text3DEffectProperties", Any( aText3DEffectsGrabBag ) );
1802 }
1803 }
1804
1805 // store bitmap artistic effects in the grab bag
1806 if( !mpGraphicPropertiesPtr->maBlipProps.maEffect.isEmpty() )
1807 putPropertyToGrabBag( "ArtisticEffectProperties",
1808 Any( mpGraphicPropertiesPtr->maBlipProps.maEffect.getEffect() ) );
1809 }
1810
1811 else if( mbLockedCanvas )
1812 {
1813 //If we have aServiceName as "com.sun.star.drawing.GroupShape" and lockedCanvas
1814 putPropertyToGrabBag( "LockedCanvas", Any( true ) );
1815 }
1816
1817 // These can have a custom geometry, so position should be set here,
1818 // after creation but before custom shape handling, using the position
1819 // we got from the caller.
1820 if (mbWps && aServiceName == "com.sun.star.drawing.LineShape" && !pParentGroupShape)
1821 mxShape->setPosition(maPosition);
1822
1823 if (bIsConnectorShape)
1824 {
1825 OUString sConnectorShapePresetTypeName(
1826 reinterpret_cast<const char*>(
1827 mpCustomShapePropertiesPtr->getShapePresetTypeName().getConstArray()),
1828 mpCustomShapePropertiesPtr->getShapePresetTypeName().getLength(),
1829 RTL_TEXTENCODING_UTF8);
1830 msConnectorName = sConnectorShapePresetTypeName;
1831
1832 sal_Int32 nType = mpCustomShapePropertiesPtr->getShapePresetType();
1833 switch (nType)
1834 {
1835 case XML_line:
1836 case XML_straightConnector1:
1837 xSet->setPropertyValue("EdgeKind", Any(ConnectorType_LINE));
1838 break;
1839 case XML_bentConnector2:
1840 case XML_bentConnector3:
1841 case XML_bentConnector4:
1842 case XML_bentConnector5:
1843 xSet->setPropertyValue("EdgeKind", Any(ConnectorType_STANDARD));
1844 break;
1845 case XML_curvedConnector2:
1846 case XML_curvedConnector3:
1847 case XML_curvedConnector4:
1848 case XML_curvedConnector5:
1849 xSet->setPropertyValue("EdgeKind", Any(ConnectorType_CURVE));
1850 break;
1851 default:
1852 break;
1853 }
1854 }
1855
1856 if( bIsCustomShape )
1857 {
1858 if ( mbFlipH )
1859 mpCustomShapePropertiesPtr->setMirroredX( true );
1860 if ( mbFlipV )
1861 mpCustomShapePropertiesPtr->setMirroredY( true );
1862 if( getTextBody() )
1863 {
1864 sal_Int32 nTextCameraZRotation = getTextBody()->get3DProperties().maCameraRotation.mnRevolution.value_or(0);
1865 mpCustomShapePropertiesPtr->setTextCameraZRotateAngle( nTextCameraZRotation / 60000 );
1866
1867 // TextPreRotateAngle. Text rotates inside the text area. Might be used for diagram layout 'upr' and 'grav'.
1868 sal_Int32 nTextPreRotateAngle = static_cast< sal_Int32 >( getTextBody()->getTextProperties().moTextPreRotation.value_or( 0 ) );
1869
1870 nTextPreRotateAngle -= mnDiagramRotation; // Use of mnDiagramRotation is unclear. It seems to be always 0 here.
1871
1872 // TextRotateAngle. The text area rotates.
1873 sal_Int32 nTextAreaRotateAngle = getTextBody()->getTextProperties().moTextAreaRotation.value_or(0);
1874 if (getTextBody()->getTextProperties().moUpright)
1875 {
1876 // When upright is set, any text area transformation and shape rotation is ignored
1877 // in MS Office. To simulate this behaviour, we rotate the text area into the
1878 // opposite direction of the shape rotation by as much as the shape was rotated
1879 // and so compensate the shape rotation, which is added in rendering.
1880 nTextAreaRotateAngle = -mnRotation;
1881 // If 45° <= shape rotation < 135° or 225° <= shape rotation < 315°,
1882 // then MS Office adds an additional 90° rotation to the text area.
1883 const sal_Int32 nDeg(mnRotation / 60000);
1884 if ((nDeg >= 45 && nDeg < 135) || (nDeg >= 225 && nDeg < 315))
1885 {
1886 nTextAreaRotateAngle += 5400000;
1887 nTextPreRotateAngle -= 5400000; // compensate the additional text area rotation
1888 }
1889 putPropertyToGrabBag("Upright", Any(true));
1890 }
1891 /* OOX measures text rotation clockwise in 1/60000th degrees,
1892 relative to the containing shape. set*Angle wants degrees counter-clockwise. */
1893 mpCustomShapePropertiesPtr->setTextPreRotateAngle(-nTextPreRotateAngle / 60000);
1894 if (nTextAreaRotateAngle != 0)
1895 mpCustomShapePropertiesPtr->setTextAreaRotateAngle(-nTextAreaRotateAngle / 60000);
1896
1897 auto sHorzOverflow = getTextBody()->getTextProperties().msHorzOverflow;
1898 if (!sHorzOverflow.isEmpty())
1899 putPropertyToGrabBag("horzOverflow", uno::Any(getTextBody()->getTextProperties().msHorzOverflow));
1900 auto nVertOverflow = getTextBody()->getTextProperties().msVertOverflow;
1901 if (!nVertOverflow.isEmpty())
1902 putPropertyToGrabBag("vertOverflow", uno::Any(getTextBody()->getTextProperties().msVertOverflow));
1903 }
1904
1905 // Note that the script oox/source/drawingml/customshapes/generatePresetsData.pl looks
1906 // for these ==cscode== and ==csdata== markers, so don't "clean up" these SAL_INFOs
1907 SAL_INFO("oox.cscode", "==cscode== shape name: '" << msName << "'");
1908 SAL_INFO("oox.csdata", "==csdata== shape name: '" << msName << "'");
1909
1910 mpCustomShapePropertiesPtr->pushToPropSet(xSet, maSize);
1911
1912 // Consider WordArt
1913 if (mpTextBody && !mpTextBody->getTextProperties().msPrst.isEmpty()
1914 && mpTextBody->getTextProperties().msPrst != u"textNoShape")
1915 {
1917 }
1918 }
1919 else if( getTextBody() )
1920 getTextBody()->getTextProperties().pushVertSimulation();
1921
1922 // tdf#133037: a bit hackish: force Shape to rotate in the opposite direction the camera would rotate
1923 PropertySet aPropertySet(mxShape);
1924 if ( !bUseRotationTransform && (mnRotation != 0 || nCameraRotation != 0) )
1925 {
1926 // use the same logic for rotation from VML exporter (SimpleShape::implConvertAndInsert at vmlshape.cxx)
1927 Degree100 nAngle = NormAngle36000( Degree100((mnRotation - nCameraRotation) / -600) );
1928 aPropertySet.setAnyProperty( PROP_RotateAngle, Any( sal_Int32( nAngle.get() ) ) );
1931 }
1932
1933 // in some cases, we don't have any text body.
1934 if( mpTextBody && ( !bDoNotInsertEmptyTextBody || !mpTextBody->isEmpty() ) )
1935 {
1936 Reference < XText > xText( mxShape, UNO_QUERY );
1937 if ( xText.is() ) // not every shape is supporting an XText interface (e.g. GroupShape)
1938 {
1939 TextCharacterProperties aCharStyleProperties;
1940 if( const ShapeStyleRef* pFontRef = getShapeStyleRef( XML_fontRef ) )
1941 {
1942 if( pFontRef->mnThemedIdx != 0 )
1943 {
1944 if( pTheme )
1945 if( const TextCharacterProperties* pCharProps = pTheme->getFontStyle( pFontRef->mnThemedIdx ) )
1946 aCharStyleProperties.assignUsed( *pCharProps );
1947 SAL_INFO("oox.drawingml", "Shape::createAndInsert: use font color");
1948 if ( pFontRef->maPhClr.isUsed() )
1949 {
1950 aCharStyleProperties.maFillProperties.maFillColor = pFontRef->maPhClr;
1951 aCharStyleProperties.maFillProperties.moFillType = XML_solidFill;
1952 }
1953 }
1954 }
1955 xText->setString("");
1956 Reference < XTextCursor > xAt = xText->createTextCursor();
1957 getTextBody()->insertAt( rFilterBase, xText, xAt, aCharStyleProperties, mpMasterTextListStyle );
1958
1959 const TextParagraphVector& rParagraphs = getTextBody()->getParagraphs();
1960 if (!rParagraphs.empty())
1961 {
1962 const std::shared_ptr<TextParagraph>& pParagraph = rParagraphs[0];
1963 if (pParagraph->getProperties().getParaAdjust())
1964 {
1965 style::ParagraphAdjust eAdjust = *pParagraph->getProperties().getParaAdjust();
1966 if (eAdjust == style::ParagraphAdjust_CENTER)
1967 {
1968 // If the first paragraph is centered, then set the para adjustment of
1969 // the shape itself to centered as well.
1970 aPropertySet.setAnyProperty(PROP_ParaAdjust, uno::Any(eAdjust));
1971 }
1972 }
1973
1974 // tdf#144092 For empty textboxes push character styles &
1975 // endParaRPr into the Shape's properties
1976 if (rParagraphs.size() == 1 && pParagraph->getRuns().empty())
1977 {
1978 TextCharacterProperties aTextCharacterProps{ pParagraph->getCharacterStyle(
1979 aCharStyleProperties, *mpMasterTextListStyle,
1980 getTextBody()->getTextListStyle()) };
1981 aTextCharacterProps.assignUsed(pParagraph->getEndProperties());
1982 aTextCharacterProps.pushToPropSet(aPropertySet, rFilterBase);
1983 }
1984 }
1985
1986 // MS Office has e.g. fill and stroke of WordArt in the character properties,
1987 // LibreOffice uses shape properties.
1988 if (!mpTextBody->getTextProperties().msPrst.isEmpty()
1989 && mpTextBody->getTextProperties().msPrst != u"textNoShape")
1990 {
1992 }
1993 }
1994 }
1995 else if (mbTextBox)
1996 {
1997 // No drawingML text, but WPS text is expected: save the theme
1998 // character color on the shape, then.
1999 if(const ShapeStyleRef* pFontRef = getShapeStyleRef(XML_fontRef))
2000 {
2001 ::Color nCharColor = pFontRef->maPhClr.getColor(rGraphicHelper);
2002 aPropertySet.setAnyProperty(PROP_CharColor, uno::Any(nCharColor));
2003 }
2004 }
2005
2006 // Set glow effect properties
2007 if ( aEffectProperties.maGlow.moGlowRad.has_value() )
2008 {
2009 uno::Reference<beans::XPropertySet> propertySet (mxShape, uno::UNO_QUERY);
2010 propertySet->setPropertyValue("GlowEffectRadius", Any(convertEmuToHmm(aEffectProperties.maGlow.moGlowRad.value())));
2011 propertySet->setPropertyValue("GlowEffectColor", Any(aEffectProperties.maGlow.moGlowColor.getColor(rGraphicHelper)));
2012 propertySet->setPropertyValue("GlowEffectTransparency", Any(aEffectProperties.maGlow.moGlowColor.getTransparency()));
2013 }
2014
2015 // Set soft edge effect properties
2016 if (aEffectProperties.maSoftEdge.moRad.has_value())
2017 {
2018 uno::Reference<beans::XPropertySet> propertySet(mxShape, uno::UNO_QUERY);
2019 propertySet->setPropertyValue(
2020 "SoftEdgeRadius", Any(convertEmuToHmm(aEffectProperties.maSoftEdge.moRad.value())));
2021 }
2022
2023 // Set the stroke and fill-color properties of the OLE shape
2024 if (aServiceName == "com.sun.star.drawing.OLE2Shape" && mxOleObjectInfo
2025 && !mxOleObjectInfo->maShapeId.isEmpty())
2026 if (::oox::vml::Drawing* pVmlDrawing = rFilterBase.getVmlDrawing())
2027 if (const ::oox::vml::ShapeBase* pVmlShape
2028 = pVmlDrawing->getShapes().getShapeById(mxOleObjectInfo->maShapeId))
2029 {
2030 // Apply stroke props from the type model of the related VML shape.
2031 ShapePropertyMap aPropMap(rFilterBase.getModelObjectHelper());
2032 pVmlShape->getTypeModel().maStrokeModel.pushToPropMap(
2033 aPropMap, rFilterBase.getGraphicHelper());
2034 // And, fill-color properties as well...
2035 pVmlShape->getTypeModel().maFillModel.pushToPropMap(
2036 aPropMap, rFilterBase.getGraphicHelper());
2037 PropertySet(xSet).setProperties(aPropMap);
2038 }
2039 }
2040
2041 if (mxShape.is())
2042 {
2043 finalizeXShape( rFilterBase, rxShapes );
2044
2045 if (mpTextBody)
2046 {
2047 // tdf#151518. The method readjustTextDistances is fix for tdf#148321, but conflicts with
2048 // text position in some of the SmartArt types in Writer. So exclude Writer here.
2049 OUString sDocumentService;
2051 if (sDocumentService != u"com.sun.star.text.TextDocument")
2052 mpTextBody->getTextProperties().readjustTextDistances(mxShape);
2053 }
2054 }
2055 return mxShape;
2056}
2057
2058void Shape::keepDiagramDrawing(XmlFilterBase& rFilterBase, const OUString& rFragmentPath)
2059{
2060
2061 sal_Int32 length = maDiagramDoms.getLength();
2062 maDiagramDoms.realloc(length + 1);
2063
2064 // drawingValue[0] => dom, drawingValue[1] => Sequence of associated relationships
2065 uno::Sequence<uno::Any> diagramDrawing{
2066 uno::Any(rFilterBase.importFragment(rFragmentPath)),
2067 uno::Any(resolveRelationshipsOfTypeFromOfficeDoc(rFilterBase, rFragmentPath, u"image"))
2068 };
2069
2070 beans::PropertyValue* pValue = maDiagramDoms.getArray();
2071 pValue[length].Name = "OOXDrawing";
2072 pValue[length].Value <<= diagramDrawing;
2073}
2074
2076{
2077 try
2078 {
2079 if( !maDiagramDoms.hasElements() )
2080 return;
2081
2082 Reference < XPropertySet > xSet( mxShape, UNO_QUERY_THROW );
2083 Reference < XPropertySetInfo > xSetInfo( xSet->getPropertySetInfo() );
2084 if ( !xSetInfo.is() )
2085 return;
2086
2087 const OUString aGrabBagPropName = UNO_NAME_MISC_OBJ_INTEROPGRABBAG;
2088 if( !xSetInfo->hasPropertyByName( aGrabBagPropName ) )
2089 return;
2090
2092 xSet->getPropertyValue( aGrabBagPropName ) >>= aGrabBag;
2093
2094 // We keep the previous items, if present
2095 if ( aGrabBag.hasElements() )
2096 xSet->setPropertyValue( aGrabBagPropName, Any( comphelper::concatSequences(aGrabBag, maDiagramDoms) ) );
2097 else
2098 xSet->setPropertyValue( aGrabBagPropName, Any( maDiagramDoms ) );
2099 }
2100 catch( const Exception& )
2101 {
2102 TOOLS_WARN_EXCEPTION( "oox.drawingml", "Shape::keepDiagramCompatibilityInfo" );
2103 }
2104}
2105
2107{
2108 try
2109 {
2110 Reference<XPropertySet> xSet(mxShape, UNO_QUERY_THROW);
2111
2112 xSet->setPropertyValue("MoveProtect", Any(true));
2113 xSet->setPropertyValue("SizeProtect", Any(true));
2114
2115 // Replace existing shapes with a new Graphic Object rendered
2116 // from them
2117 Reference<XShape> xShape(renderDiagramToGraphic(rFilterBase));
2118 Reference<XShapes> xShapes(mxShape, UNO_QUERY_THROW);
2119 tools::Rectangle aBackgroundRect
2121 Reference<XShape>(xShapes->getByIndex(0), UNO_QUERY_THROW))
2122 ->GetLogicRect();
2123 while (xShapes->hasElements())
2124 xShapes->remove(Reference<XShape>(xShapes->getByIndex(0), UNO_QUERY_THROW));
2125 xShapes->add(xShape);
2127 Reference<XShape>(xShapes->getByIndex(0), UNO_QUERY_THROW))
2128 ->NbcSetLogicRect(aBackgroundRect);
2129 }
2130 catch (const Exception&)
2131 {
2132 TOOLS_WARN_EXCEPTION("oox.drawingml", "Shape::convertSmartArtToMetafile");
2133 }
2134}
2135
2137{
2138 Reference< XShape > xShape;
2139
2140 try
2141 {
2142 if( !maDiagramDoms.hasElements() )
2143 return xShape;
2144
2145 // Stream in which to place the rendered shape
2146 SvMemoryStream aTempStream;
2148 Reference < io::XOutputStream > xOutputStream( xStream->getOutputStream() );
2149
2150 // Size of the rendering
2151 awt::Size aActualSize = mxShape->getSize();
2152 Size aResolution(Application::GetDefaultDevice()->LogicToPixel(Size(100, 100), MapMode(MapUnit::MapCM)));
2153 double fPixelsPer100thmm = static_cast < double > ( aResolution.Width() ) / 100000.0;
2154 awt::Size aSize( static_cast < sal_Int32 > ( ( fPixelsPer100thmm * aActualSize.Width ) + 0.5 ),
2155 static_cast < sal_Int32 > ( ( fPixelsPer100thmm * aActualSize.Height ) + 0.5 ) );
2156
2157 Sequence< PropertyValue > aFilterData{
2158 comphelper::makePropertyValue("PixelWidth", aSize.Width),
2159 comphelper::makePropertyValue("PixelHeight", aSize.Height),
2160 comphelper::makePropertyValue("LogicalWidth", aActualSize.Width),
2161 comphelper::makePropertyValue("LogicalHeight", aActualSize.Height)
2162 };
2163
2164 Sequence < PropertyValue > aDescriptor{
2165 comphelper::makePropertyValue("OutputStream", xOutputStream),
2166 comphelper::makePropertyValue("FilterName", OUString("SVM")), // Rendering format
2167 comphelper::makePropertyValue("FilterData", aFilterData)
2168 };
2169
2170 Reference < lang::XComponent > xSourceDoc( mxShape, UNO_QUERY_THROW );
2171 Reference < XGraphicExportFilter > xGraphicExporter = GraphicExportFilter::create( rFilterBase.getComponentContext() );
2172 xGraphicExporter->setSourceDocument( xSourceDoc );
2173 xGraphicExporter->filter( aDescriptor );
2174
2175 aTempStream.Seek( STREAM_SEEK_TO_BEGIN );
2176
2177 Graphic aGraphic;
2178 GraphicFilter aFilter( false );
2179 if ( aFilter.ImportGraphic( aGraphic, u"", aTempStream, GRFILTER_FORMAT_NOTFOUND, nullptr, GraphicFilterImportFlags::NONE ) != ERRCODE_NONE )
2180 {
2181 SAL_WARN( "oox.drawingml", "Shape::renderDiagramToGraphic: Unable to import rendered stream into graphic object" );
2182 return xShape;
2183 }
2184
2185 Reference < graphic::XGraphic > xGraphic( aGraphic.GetXGraphic() );
2186 Reference < lang::XMultiServiceFactory > xServiceFact( rFilterBase.getModel(), UNO_QUERY_THROW );
2187 xShape.set( xServiceFact->createInstance( "com.sun.star.drawing.GraphicObjectShape" ), UNO_QUERY_THROW );
2188 Reference < XPropertySet > xPropSet( xShape, UNO_QUERY_THROW );
2189 xPropSet->setPropertyValue( "Graphic", Any( xGraphic ) );
2190 xPropSet->setPropertyValue( "MoveProtect", Any( true ) );
2191 xPropSet->setPropertyValue( "SizeProtect", Any( true ) );
2192 xPropSet->setPropertyValue( "Name", Any( OUString( "RenderedShapes" ) ) );
2193 }
2194 catch( const Exception& )
2195 {
2196 TOOLS_WARN_EXCEPTION( "oox.drawingml", "Shape::renderDiagramToGraphic" );
2197 }
2198
2199 return xShape;
2200}
2201
2202void Shape::setTextBody(const TextBodyPtr & pTextBody)
2203{
2204 mpTextBody = pTextBody;
2205}
2206
2207void Shape::setMasterTextListStyle( const TextListStylePtr& pMasterTextListStyle )
2208{
2209 SAL_INFO("oox.drawingml", "Shape::setMasterTextListStyle: Set master text list style to shape id='" << msId << "'");
2210
2211 mpMasterTextListStyle = pMasterTextListStyle;
2212}
2213
2214OUString Shape::finalizeServiceName( XmlFilterBase& rFilter, const OUString& rServiceName, const awt::Rectangle& rShapeRect )
2215{
2216 OUString aServiceName = rServiceName;
2217 switch( meFrameType )
2218 {
2220 {
2221 awt::Size aOleSize( rShapeRect.Width, rShapeRect.Height );
2223 aServiceName = "com.sun.star.drawing.OLE2Shape";
2224
2225 // get the path to the representation graphic
2226 OUString aGraphicPath;
2227 if( !mxOleObjectInfo->maShapeId.isEmpty() )
2228 if( ::oox::vml::Drawing* pVmlDrawing = rFilter.getVmlDrawing() )
2229 if( const ::oox::vml::ShapeBase* pVmlShape = pVmlDrawing->getShapes().getShapeById( mxOleObjectInfo->maShapeId ) )
2230 aGraphicPath = pVmlShape->getGraphicPath();
2231
2232 // import and store the graphic
2233 if( !aGraphicPath.isEmpty() )
2234 {
2235 // Transfer shape's width and height to graphicsfilter (can be used by WMF/EMF)
2236 WmfExternal aExtHeader;
2237 aExtHeader.mapMode = 8; // MM_ANISOTROPIC
2238 aExtHeader.xExt = rShapeRect.Width;
2239 aExtHeader.yExt = rShapeRect.Height;
2240
2241 Reference< graphic::XGraphic > xGraphic = rFilter.getGraphicHelper().importEmbeddedGraphic( aGraphicPath, &aExtHeader );
2242 if( xGraphic.is() )
2243 maShapeProperties.setProperty(PROP_Graphic, xGraphic);
2244 }
2245 }
2246 break;
2247
2248 default:;
2249 }
2250 return aServiceName;
2251}
2252
2253void Shape::finalizeXShape( XmlFilterBase& rFilter, const Reference< XShapes >& rxShapes )
2254{
2255 switch( meFrameType )
2256 {
2257 case FRAMETYPE_CHART:
2258 {
2259 OSL_ENSURE( !mxChartShapeInfo->maFragmentPath.isEmpty(), "Shape::finalizeXShape - missing chart fragment" );
2260 if( mxShape.is() && !mxChartShapeInfo->maFragmentPath.isEmpty() ) try
2261 {
2262 // set the chart2 OLE class ID at the OLE shape
2263 PropertySet aShapeProp( mxShape );
2264 aShapeProp.setProperty( PROP_CLSID, OUString( "12dcae26-281f-416f-a234-c3086127382e" ) );
2265
2266 // get the XModel interface of the embedded object from the OLE shape
2268 aShapeProp.getProperty( xDocModel, PROP_Model );
2269 Reference< chart2::XChartDocument > xChartDoc( xDocModel, UNO_QUERY_THROW );
2270
2271 // load the chart data from the XML fragment
2272#if ENABLE_WASM_STRIP_CHART
2273 (void) rFilter;
2274 (void) rxShapes;
2275#else
2276 // WASM_CHART change
2277 // TODO: Instead of using convertFromModel an alternative may be
2278 // added to convert not to Chart/OLE SdrObejct, but to GraphicObject
2279 // with the Chart visualization. There should be a preview available
2280 // in the imported chart data
2281 bool bMSO2007Doc = rFilter.isMSO2007Document();
2282 chart::ChartSpaceModel aModel(bMSO2007Doc);
2284 rFilter, mxChartShapeInfo->maFragmentPath, aModel );
2285 const OUString aThemeOverrideFragmentPath( pChartSpaceFragment->
2286 getFragmentPathFromFirstTypeFromOfficeDoc(u"themeOverride") );
2287 rFilter.importFragment( pChartSpaceFragment );
2288 ::oox::ppt::PowerPointImport *pPowerPointImport =
2289 dynamic_cast< ::oox::ppt::PowerPointImport* >(&rFilter);
2290
2291 // The original theme.
2292 ThemePtr pTheme;
2293
2294 if (!aThemeOverrideFragmentPath.isEmpty() && pPowerPointImport)
2295 {
2296 // Handle theme override.
2297 uno::Reference< xml::sax::XFastSAXSerializable > xDoc(
2298 rFilter.importFragment(aThemeOverrideFragmentPath), uno::UNO_QUERY_THROW);
2299 pTheme = pPowerPointImport->getActualSlidePersist()->getTheme();
2300 auto pThemeOverride = std::make_shared<Theme>(*pTheme);
2301 rFilter.importFragment(
2302 new ThemeOverrideFragmentHandler(rFilter, aThemeOverrideFragmentPath,
2303 *pThemeOverride),
2304 xDoc);
2305 pPowerPointImport->getActualSlidePersist()->setTheme(pThemeOverride);
2306 }
2307
2308 // convert imported chart model to chart document
2309 Reference< drawing::XShapes > xExternalPage;
2310 if( !mxChartShapeInfo->mbEmbedShapes )
2311 xExternalPage = rxShapes;
2312 if( rFilter.getChartConverter() )
2313 {
2314 rFilter.getChartConverter()->convertFromModel( rFilter, aModel, xChartDoc, xExternalPage, mxShape->getPosition(), mxShape->getSize() );
2315 if( !xChartDoc->hasInternalDataProvider() )
2316 {
2317 Reference< chart2::data::XDataReceiver > xDataRec( xChartDoc, UNO_QUERY );
2318 Reference< chart2::data::XDataSource > xData = xDataRec->getUsedData();
2319 if( !xData->getDataSequences().hasElements() || !xData->getDataSequences()[0]->getValues().is() ||
2320 !xData->getDataSequences()[0]->getValues()->getData().hasElements() )
2321 {
2322 rFilter.useInternalChartDataTable( true );
2323 rFilter.getChartConverter()->convertFromModel( rFilter, aModel, xChartDoc, xExternalPage, mxShape->getPosition(), mxShape->getSize() );
2324 rFilter.useInternalChartDataTable( false );
2325 }
2326 }
2327
2328 }
2329
2330 if (!aThemeOverrideFragmentPath.isEmpty() && pPowerPointImport)
2331 {
2332 // Restore the original theme.
2333 pPowerPointImport->getActualSlidePersist()->setTheme(pTheme);
2334 }
2335#endif
2336 }
2337 catch( Exception& )
2338 {
2339 }
2340 }
2341 break;
2342
2343 default:;
2344 }
2345}
2346
2347void Shape::putPropertyToGrabBag( const OUString& sPropertyName, const Any& aPropertyValue )
2348{
2349 PropertyValue aNewProperty;
2350 aNewProperty.Name = sPropertyName;
2351 aNewProperty.Value = aPropertyValue;
2352 putPropertyToGrabBag( aNewProperty );
2353}
2354
2355void Shape::putPropertyToGrabBag( const PropertyValue& pProperty )
2356{
2357 Reference< XPropertySet > xSet( mxShape, UNO_QUERY );
2358 Reference< XPropertySetInfo > xSetInfo( xSet->getPropertySetInfo() );
2359 const OUString aGrabBagPropName = UNO_NAME_MISC_OBJ_INTEROPGRABBAG;
2360 if( mxShape.is() && xSet.is() && xSetInfo.is() && xSetInfo->hasPropertyByName( aGrabBagPropName ) )
2361 {
2362 Sequence< PropertyValue > aGrabBag;
2363 xSet->getPropertyValue( aGrabBagPropName ) >>= aGrabBag;
2364
2365 sal_Int32 length = aGrabBag.getLength();
2366 aGrabBag.realloc( length + 1 );
2367 aGrabBag.getArray()[length] = pProperty;
2368
2369 xSet->setPropertyValue( aGrabBagPropName, Any( aGrabBag ) );
2370 }
2371}
2372
2374{
2375 Reference< XPropertySet > xSet( mxShape, UNO_QUERY );
2376 Reference< XPropertySetInfo > xSetInfo( xSet->getPropertySetInfo() );
2377 const OUString aGrabBagPropName = UNO_NAME_MISC_OBJ_INTEROPGRABBAG;
2378 if( !(mxShape.is() && xSet.is() && xSetInfo.is() && xSetInfo->hasPropertyByName( aGrabBagPropName )) )
2379 return;
2380
2381 // get existing grab bag
2383 xSet->getPropertyValue( aGrabBagPropName ) >>= aGrabBag;
2384
2385 std::vector<PropertyValue> aVec;
2386 aVec.reserve(aProperties.getLength());
2387
2388 // put the new items
2389 std::transform(aProperties.begin(), aProperties.end(), std::back_inserter(aVec),
2390 [](const PropertyValue& rProp) {
2391 PropertyValue aProp;
2392 aProp.Name = rProp.Name;
2393 aProp.Value = rProp.Value;
2394 return aProp;
2395 });
2396
2397 // put it back to the shape
2398 xSet->setPropertyValue( aGrabBagPropName, Any( comphelper::concatSequences(aGrabBag, aVec) ) );
2399}
2400
2401FillProperties Shape::getActualFillProperties(const Theme* pTheme, const FillProperties* pParentShapeFillProps) const
2402{
2403 FillProperties aFillProperties;
2404 aFillProperties.moFillType = XML_noFill;
2405
2406 // Reference shape properties
2407 aFillProperties.assignUsed( *mpShapeRefFillPropPtr );
2408
2409 // Theme
2410 if( pTheme != nullptr )
2411 {
2412 if( const ShapeStyleRef* pFillRef = getShapeStyleRef( XML_fillRef ) )
2413 {
2414 if( const FillProperties* pFillProps = pTheme->getFillStyle( pFillRef->mnThemedIdx ) )
2415 aFillProperties.assignUsed( *pFillProps );
2416 }
2417 }
2418
2419 // Properties specified directly for this shape
2420 aFillProperties.assignUsed(getFillProperties());
2421
2422 // Parent shape's properties
2423 if ( pParentShapeFillProps != nullptr)
2424 if( getFillProperties().moFillType.has_value() && getFillProperties().moFillType.value() == XML_grpFill )
2425 aFillProperties.assignUsed( *pParentShapeFillProps );
2426
2427 return aFillProperties;
2428}
2429
2431{
2432 LineProperties aLineProperties;
2433 aLineProperties.maLineFill.moFillType = XML_noFill;
2434
2435 // Reference shape properties
2436 aLineProperties.assignUsed( *mpShapeRefLinePropPtr );
2437
2438 // Theme
2439 if( pTheme != nullptr )
2440 {
2441 if( const ShapeStyleRef* pLineRef = getShapeStyleRef( XML_lnRef ) )
2442 {
2443 if( const LineProperties* pLineProps = pTheme->getLineStyle( pLineRef->mnThemedIdx ) )
2444 aLineProperties.assignUsed( *pLineProps );
2445 }
2446 }
2447
2448 // Properties specified directly for this shape
2449 aLineProperties.assignUsed( getLineProperties() );
2450
2451 return aLineProperties;
2452}
2453
2455{
2456 EffectProperties aEffectProperties;
2457
2458 // Reference shape properties
2459 aEffectProperties.assignUsed( *mpShapeRefEffectPropPtr );
2460
2461 // Theme
2462 if( pTheme != nullptr )
2463 {
2464 if( const ShapeStyleRef* pEffectRef = getShapeStyleRef( XML_effectRef ) )
2465 {
2466 if( const EffectProperties* pEffectProps = pTheme->getEffectStyle( pEffectRef->mnThemedIdx ) )
2467 aEffectProperties.assignUsed( *pEffectProps );
2468 }
2469 }
2470
2471 // Properties specified directly for this shape
2472 aEffectProperties.assignUsed ( getEffectProperties() );
2473
2474 return aEffectProperties;
2475}
2476
2477uno::Sequence< uno::Sequence< uno::Any > > Shape::resolveRelationshipsOfTypeFromOfficeDoc(core::XmlFilterBase& rFilter, const OUString& sFragment, std::u16string_view sType )
2478{
2479 uno::Sequence< uno::Sequence< uno::Any > > xRelListTemp;
2480 sal_Int32 counter = 0;
2481
2482 core::RelationsRef xRels = rFilter.importRelations( sFragment );
2483 if ( xRels )
2484 {
2485 core::RelationsRef xImageRels = xRels->getRelationsFromTypeFromOfficeDoc( sType );
2486 if ( xImageRels )
2487 {
2488 xRelListTemp.realloc( xImageRels->size() );
2489 auto pxRelListTemp = xRelListTemp.getArray();
2490 for (auto const& imageRel : *xImageRels)
2491 {
2492 uno::Sequence< uno::Any > diagramRelTuple (3);
2493 auto pdiagramRelTuple = diagramRelTuple.getArray();
2494 // [0] => RID, [1] => InputStream [2] => extension
2495 OUString sRelId = imageRel.second.maId;
2496
2497 pdiagramRelTuple[0] <<= sRelId;
2498 OUString sTarget = xImageRels->getFragmentPathFromRelId( sRelId );
2499
2500 uno::Reference< io::XInputStream > xImageInputStrm( rFilter.openInputStream( sTarget ), uno::UNO_SET_THROW );
2501 StreamDataSequence dataSeq;
2502 if ( rFilter.importBinaryData( dataSeq, sTarget ) )
2503 {
2504 pdiagramRelTuple[1] <<= dataSeq;
2505 }
2506
2507 pdiagramRelTuple[2] <<= sTarget.copy( sTarget.lastIndexOf(".") );
2508
2509 pxRelListTemp[counter] = diagramRelTuple;
2510 ++counter;
2511 }
2512 xRelListTemp.realloc(counter);
2513
2514 }
2515 }
2516 return xRelListTemp;
2517}
2518
2520{
2521 auto pFillProperties = std::make_shared<FillProperties>();
2522 pFillProperties->assignUsed(*mpFillPropertiesPtr);
2523 mpFillPropertiesPtr = pFillProperties;
2524}
2525}
2526
2527/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
OptionalString sType
geometry::RealPoint2D maPosition
PropertyValueVector_t aPropertyValues
PropertiesInfo aProperties
Reference< XInputStream > xStream
constexpr OUStringLiteral sServiceName
constexpr OUStringLiteral sDocumentService
static OutputDevice * GetDefaultDevice()
ErrCode ImportGraphic(Graphic &rGraphic, const INetURLObject &rPath, sal_uInt16 nFormat=GRFILTER_FORMAT_DONTKNOW, sal_uInt16 *pDeterminedFormat=nullptr, GraphicFilterImportFlags nImportFlags=GraphicFilterImportFlags::NONE)
css::uno::Reference< css::graphic::XGraphic > GetXGraphic() const
LanguageType getLanguageType(bool bResolveSystem=true) const
const css::lang::Locale & getLocale(bool bResolveSystem=true) const
static sal_Int16 getScriptType(LanguageType nLang)
static SdrObject * getSdrObjectFromXShape(const css::uno::Reference< css::uno::XInterface > &xInt)
virtual void NbcSetLogicRect(const tools::Rectangle &rRect)
void SetMergedItem(const SfxPoolItem &rItem)
virtual const tools::Rectangle & GetLogicRect() const
constexpr tools::Long Width() const
sal_uInt64 Seek(sal_uInt64 nPos)
static SvtFilterOptions & Get()
bool IsSmartArt2Shape() const
bool decompose(B2DTuple &rScale, B2DTuple &rTranslate, double &rRotate, double &rShearX) const
void set(sal_uInt16 nRow, sal_uInt16 nColumn, double fValue)
void rotate(double fRadiant)
void translate(double fX, double fY)
double get(sal_uInt16 nRow, sal_uInt16 nColumn) const
void scale(double fX, double fY)
void insert(sal_uInt32 nIndex, const basegfx::B2DPoint &rPoint, sal_uInt32 nCount=1)
basegfx::B2DPoint const & getB2DPoint(sal_uInt32 nIndex) const
void transform(const basegfx::B2DHomMatrix &rMatrix)
sal_uInt32 count() const
bool equalZero() const
TYPE getX() const
void setY(TYPE fY)
TYPE getY() const
void setX(TYPE fX)
#define SO3_SM_CLASSID
Provides helper functions for colors, device measurement conversion, graphics, and graphic objects ha...
css::uno::Reference< css::graphic::XGraphic > importEmbeddedGraphic(const OUString &rStreamName, const WmfExternal *pExtHeader=nullptr) const
Imports a graphic from the storage stream with the passed path and name.
css::uno::Reference< css::awt::XBitmap > getFillBitmap(OUString const &rGraphicName)
void assignUsed(const PropertyMap &rPropMap)
Inserts all properties contained in the passed property map.
void erase(sal_Int32 nPropId)
css::uno::Any getProperty(sal_Int32 nPropId)
bool hasProperty(sal_Int32 nPropId) const
Returns true, if the map contains a property with the passed identifier.
static const OUString & getPropertyName(sal_Int32 nPropId)
Returns the name of the passed property identifier.
bool setProperty(sal_Int32 nPropId, Type &&rValue)
Sets the specified property to the passed value.
Definition: propertymap.hxx:72
A wrapper for a UNO property set.
Definition: propertyset.hxx:58
void setProperties(const css::uno::Sequence< OUString > &rPropNames, const css::uno::Sequence< css::uno::Any > &rValues)
Puts the passed properties into the property set.
bool setAnyProperty(sal_Int32 nPropId, const css::uno::Any &rValue)
Puts the passed any into the property set.
Definition: propertyset.cxx:70
bool importBinaryData(StreamDataSequence &orDataSeq, const OUString &rStreamName)
Imports the raw binary data from the specified stream.
Definition: filterbase.cxx:382
utl::MediaDescriptor & getMediaDescriptor() const
Returns the media descriptor.
Definition: filterbase.cxx:240
const css::uno::Reference< css::frame::XModel > & getModel() const
Returns the document model (always existing).
Definition: filterbase.cxx:220
css::uno::Reference< css::io::XInputStream > openInputStream(const OUString &rStreamName) const
Opens and returns the specified input stream from the base storage.
Definition: filterbase.cxx:327
::oox::ole::OleObjectHelper & getOleObjectHelper() const
Returns a helper for the handling of OLE objects.
Definition: filterbase.cxx:368
GraphicHelper & getGraphicHelper() const
Returns a helper for the handling of graphics and graphic objects.
Definition: filterbase.cxx:346
ModelObjectHelper & getModelObjectHelper() const
Returns a helper with containers for various named drawing objects for the imported document.
Definition: filterbase.cxx:353
const css::uno::Reference< css::uno::XComponentContext > & getComponentContext() const
Returns the component context passed in the filter constructor (always existing).
Definition: filterbase.cxx:215
virtual ::oox::vml::Drawing * getVmlDrawing()=0
Has to be implemented by each filter to return the collection of VML shapes.
RelationsRef importRelations(const OUString &rFragmentPath)
Imports the relations fragment associated with the specified fragment.
NamedShapePairs * getDiagramFontHeights()
virtual ::oox::drawingml::chart::ChartConverter * getChartConverter()=0
Has to be implemented by each filter, returns a filter-specific chart converter object,...
bool importFragment(const rtl::Reference< FragmentHandler > &rxHandler)
Imports a fragment using the passed fragment handler, which contains the full path to the fragment st...
virtual void useInternalChartDataTable(bool)
Helper to switch chart data table - specifically for xlsx imports.
bool isPlaceHolder() const
Returns true, if the color is a placeholder color in theme style lists.
Definition: color.hxx:89
const OUString & getSchemeColorName() const
Returns the scheme name from the a:schemeClr element for interoperability purposes.
Definition: color.hxx:100
sal_Int16 getTransparency() const
Returns the transparency of the color (0 = opaque, 100 = full transparent).
Definition: color.cxx:708
void clearTransformations()
Removes all color transformations.
Definition: color.cxx:362
bool isUsed() const
Returns true, if the color is initialized.
Definition: color.hxx:87
const css::uno::Sequence< css::beans::PropertyValue > & getTransformations() const
Returns the unaltered list of transformations for interoperability purposes.
Definition: color.hxx:107
::Color getColor(const GraphicHelper &rGraphicHelper, ::Color nPhClr=API_RGB_TRANSPARENT) const
Returns the final RGB color value.
Definition: color.cxx:531
bool setProperty(ShapeProperty ePropId, const Type &rValue)
Sets the specified shape property to the passed value.
bool setAnyProperty(ShapeProperty ePropId, const css::uno::Any &rValue)
Sets the specified shape property to the passed value.
bool mbLockedCanvas
Is this shape part of a locked canvas?
Definition: shape.hxx:386
ChartShapeInfo & setChartType(bool bEmbedShapes)
Definition: shape.cxx:306
void setTextBox(bool bTextBox)
Definition: shape.cxx:463
FrameType meFrameType
Type for graphic frame shapes.
Definition: shape.hxx:366
const OUString & getInternalName() const
Definition: shape.hxx:172
FillProperties getActualFillProperties(const Theme *pTheme, const FillProperties *pParentShapeFillProps) const
Definition: shape.cxx:2401
void putPropertyToGrabBag(const OUString &sPropertyName, const css::uno::Any &aPropertyValue)
void setServiceName(const char *pServiceName)
Definition: shape.cxx:334
const ShapeStyleRef * getShapeStyleRef(sal_Int32 nRefType) const
Definition: shape.cxx:340
svx::diagram::IDiagramHelper * mpDiagramHelper
Definition: shape.hxx:414
PropertyMap maShapeProperties
Definition: shape.hxx:344
PropertyMap & getShapeProperties()
Definition: shape.hxx:126
LinePropertiesPtr mpShapeRefLinePropPtr
Definition: shape.hxx:335
void keepDiagramDrawing(::oox::core::XmlFilterBase &rFilterBase, const OUString &rFragmentPath)
Definition: shape.cxx:2058
css::uno::Sequence< css::beans::PropertyValue > maDiagramDoms
Definition: shape.hxx:392
void applyShapeReference(const Shape &rReferencedShape, bool bUseText=true)
Definition: shape.cxx:468
void putPropertiesToGrabBag(const css::uno::Sequence< css::beans::PropertyValue > &aProperties)
Definition: shape.cxx:2373
void propagateDiagramHelper()
Definition: shape.cxx:225
LineProperties & getLineProperties()
Definition: shape.hxx:128
css::uno::Reference< css::drawing::XShape > renderDiagramToGraphic(::oox::core::XmlFilterBase const &rFilterBase)
Definition: shape.cxx:2136
PropertyMap maDefaultShapeProperties
Definition: shape.hxx:345
const css::awt::Size & getSize() const
Definition: shape.hxx:158
css::uno::Sequence< css::uno::Sequence< css::uno::Any > > resolveRelationshipsOfTypeFromOfficeDoc(core::XmlFilterBase &rFilter, const OUString &sFragment, std::u16string_view sType)
Definition: shape.cxx:2477
OUString msDescription
Definition: shape.hxx:355
GraphicPropertiesPtr mpGraphicPropertiesPtr
Definition: shape.hxx:338
void cloneFillProperties()
Changes reference semantics to value semantics for fill properties.
Definition: shape.cxx:2519
void setWPGChild(bool bWPG)
Definition: shape.cxx:453
OUString finalizeServiceName(::oox::core::XmlFilterBase &rFilter, const OUString &rServiceName, const css::awt::Rectangle &rShapeRect)
Definition: shape.cxx:2214
bool mbTextBox
This shape has a textbox.
Definition: shape.hxx:388
ShapeStyleRefMap maShapeStyleRefs
Definition: shape.hxx:359
EffectProperties & getEffectProperties() const
Definition: shape.hxx:149
void setMasterTextListStyle(const TextListStylePtr &pMasterTextListStyle)
Definition: shape.cxx:2207
bool isWPGChild() const
Definition: shape.hxx:225
const LinkedTxbxAttr & getLinkedTxbxAttributes() const
Definition: shape.hxx:236
Shape3DProperties & get3DProperties()
Definition: shape.hxx:144
void convertSmartArtToMetafile(::oox::core::XmlFilterBase const &rFilterBase)
Definition: shape.cxx:2106
void setLockedCanvas(bool bLockedCanvas)
Definition: shape.cxx:448
FillPropertiesPtr mpShapeRefFillPropPtr
Definition: shape.hxx:337
EffectProperties getActualEffectProperties(const Theme *pTheme) const
Definition: shape.cxx:2454
@ FRAMETYPE_GENERIC
Generic shape, no special type.
Definition: shape.hxx:275
@ FRAMETYPE_TABLE
A table embedded in a shape.
Definition: shape.hxx:279
@ FRAMETYPE_OLEOBJECT
OLE object embedded in a shape.
Definition: shape.hxx:276
@ FRAMETYPE_CHART
Chart embedded in a shape.
Definition: shape.hxx:277
@ FRAMETYPE_DIAGRAM
Complex diagram drawing shape.
Definition: shape.hxx:278
Shape(const char *pServiceType=nullptr, bool bDefaultHeight=true)
Definition: shape.cxx:126
void addChildren(::oox::core::XmlFilterBase &rFilterBase, Shape &rMaster, const Theme *pTheme, const css::uno::Reference< css::drawing::XShapes > &rxShapes, ShapeIdMap *pShapeMap, const basegfx::B2DHomMatrix &aTransformation)
Definition: shape.cxx:516
ChartShapeInfoRef mxChartShapeInfo
Additional data for chart shapes.
Definition: shape.hxx:374
css::awt::Point maPosition
Definition: shape.hxx:362
void setWps(bool bWps)
Definition: shape.cxx:458
TextListStylePtr mpMasterTextListStyle
Definition: shape.hxx:346
table::TablePropertiesPtr mpTablePropertiesPtr
Definition: shape.hxx:340
virtual ~Shape()
Definition: shape.cxx:204
table::TablePropertiesPtr const & getTableProperties()
Definition: shape.cxx:276
void keepDiagramCompatibilityInfo()
Definition: shape.cxx:2075
FillPropertiesPtr mpFillPropertiesPtr
Definition: shape.hxx:336
CustomShapePropertiesPtr mpCustomShapePropertiesPtr
Definition: shape.hxx:339
OleObjectInfoRef mxOleObjectInfo
Additional data for OLE objects.
Definition: shape.hxx:373
FillProperties & getFillProperties()
Definition: shape.hxx:131
css::awt::Size maSize
Definition: shape.hxx:361
void prepareDiagramHelper(const std::shared_ptr< Diagram > &rDiagramPtr, const std::shared_ptr<::oox::drawingml::Theme > &rTheme)
Definition: shape.cxx:211
void setDefaults(bool bHeight)
Definition: shape.cxx:283
bool mbWps
Is this a wps shape?
Definition: shape.hxx:387
OUString msConnectorName
Definition: shape.hxx:350
virtual void finalizeXShape(::oox::core::XmlFilterBase &rFilter, const css::uno::Reference< css::drawing::XShapes > &rxShapes)
void migrateDiagramHelperToNewShape(const ShapePtr &pTarget)
Definition: shape.cxx:249
sal_Int32 mnSubType
Definition: shape.hxx:356
std::vector< ShapePtr > maChildren
Definition: shape.hxx:329
EffectPropertiesPtr mpShapeRefEffectPropPtr
Definition: shape.hxx:343
const TextBodyPtr & getTextBody() const
Definition: shape.hxx:193
TextBodyPtr mpTextBody
Definition: shape.hxx:333
bool isLinkedTxbx() const
Definition: shape.hxx:237
css::uno::Reference< css::drawing::XShape > const & createAndInsert(::oox::core::XmlFilterBase &rFilterBase, const OUString &rServiceName, const Theme *pTheme, const css::uno::Reference< css::drawing::XShapes > &rxShapes, bool bClearText, bool bDoNotInsertEmptyTextBody, basegfx::B2DHomMatrix &aTransformation, const FillProperties &rShapeOrParentShapeFillProps, oox::drawingml::ShapePtr pParentGroupShape=nullptr)
Definition: shape.cxx:935
void addShape(::oox::core::XmlFilterBase &rFilterBase, const Theme *pTheme, const css::uno::Reference< css::drawing::XShapes > &rxShapes, const basegfx::B2DHomMatrix &aTransformation, const FillProperties &rShapeOrParentShapeFillProps, ShapeIdMap *pShapeMap=nullptr, oox::drawingml::ShapePtr pParentGroupShape=nullptr)
Definition: shape.cxx:346
sal_Int32 mnDiagramRotation
Definition: shape.hxx:377
::oox::vml::OleObjectInfo & setOleObjectType()
Definition: shape.cxx:298
css::uno::Reference< css::drawing::XShape > mxShape
Definition: shape.hxx:347
sal_Int32 mnRotation
Definition: shape.hxx:376
void setTextBody(const TextBodyPtr &pTextBody)
Definition: shape.cxx:2202
OUString msServiceName
Definition: shape.hxx:351
LineProperties getActualLineProperties(const Theme *pTheme) const
Definition: shape.cxx:2430
carries a CT_TextFont
Definition: textfont.hxx:33
bool getFontData(OUString &rFontName, sal_Int16 &rnFontPitch, sal_Int16 &rnFontFamily, const ::oox::core::XmlFilterBase &rFilter) const
Returns the font name, pitch, and family; tries to resolve theme placeholder names,...
Definition: textfont.cxx:78
const EffectProperties * getEffectStyle(sal_Int32 nIndex) const
Definition: theme.cxx:55
const FillProperties * getFillStyle(sal_Int32 nIndex) const
Returns the fill properties of the passed one-based themed style index.
Definition: theme.cxx:43
const LineProperties * getLineStyle(sal_Int32 nIndex) const
Returns the line properties of the passed one-based themed style index.
Definition: theme.cxx:50
const TextCharacterProperties * getFontStyle(sal_Int32 nSchemeType) const
Returns theme font properties by scheme type (major/minor).
Definition: theme.cxx:60
void convertFromModel(::oox::core::XmlFilterBase &rFilter, ChartSpaceModel &rChartModel, const css::uno::Reference< css::chart2::XChartDocument > &rxChartDoc, const css::uno::Reference< css::drawing::XShapes > &rxExternalPage, const css::awt::Point &rChartPos, const css::awt::Size &rChartSize)
Converts the passed OOXML chart model to the passed chart2 document.
Handler for a chart fragment (c:chartSpace root element).
This class is used for creating XmlStream.
bool importOleObject(PropertyMap &rPropMap, const OleObjectInfo &rOleObject, const css::awt::Size &rObjSize)
const SlidePersistPtr & getActualSlidePersist() const
Definition: pptimport.hxx:68
Represents the collection of VML shapes for a complete draw page.
Definition: vmldrawing.hxx:94
constexpr tools::Long GetHeight() const
static constexpr OUStringLiteral PROP_DOCUMENTSERVICE
ColorTransparency
constexpr ::Color COL_BLACK(0x00, 0x00, 0x00)
#define TOOLS_WARN_EXCEPTION(area, stream)
::basegfx::B2IVector maSize
float u
#define ERRCODE_NONE
#define GRFILTER_FORMAT_NOTFOUND
T NormAngle360(T angle)
const char * name
sal_Int32 nIndex
OUString msName
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
OUString GetFontworkType(std::u16string_view rMsoType)
tools::Long const nBorder
@ Exception
css::uno::Sequence< T > concatSequences(const css::uno::Sequence< T > &rS1, const Ss &... rSn)
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
css::uno::Sequence< css::beans::PropertyValue > InitPropertySequence(::std::initializer_list< ::std::pair< OUString, css::uno::Any > > vInit)
css::beans::PropertyValue makePropertyValue(const OUString &rName, T &&rValue)
std::shared_ptr< T > make_shared(Args &&... args)
constexpr Point convert(const Point &rPoint, o3tl::Length eFrom, o3tl::Length eTo)
constexpr T saturating_add(T a, T b)
std::shared_ptr< Relations > RelationsRef
Definition: relations.hxx:63
std::map< OUString, ShapePairs > NamedShapePairs
std::shared_ptr< TableProperties > TablePropertiesPtr
float GetFontHeight(sal_Int32 nHeight)
static SdrTextHorzAdjust lcl_convertAdjust(ParagraphAdjust eAdjust)
Definition: shape.cxx:549
static void lcl_setPropertyValue(std::vector< beans::PropertyValue > &rPropVec, const OUString &rName, const beans::PropertyValue &rPropertyValue)
Definition: shape.cxx:540
std::shared_ptr< Shape > ShapePtr
sal_Int32 convertEmuToHmm(sal_Int64 nValue)
Converts the passed 64-bit integer value from EMUs to 1/100 mm.
static void lcl_resetPropertyValue(std::vector< beans::PropertyValue > &rPropVec, const OUString &rName)
Definition: shape.cxx:531
static void lcl_putCustomShapeIntoTextPathMode(const uno::Reference< drawing::XShape > &xShape, const CustomShapePropertiesPtr &pCustomShapePropertiesPtr, const TextBodyPtr &pTextBody)
Definition: shape.cxx:561
std::shared_ptr< CustomShapeProperties > CustomShapePropertiesPtr
std::shared_ptr< Theme > ThemePtr
::std::map< OUString, ShapePtr > ShapeIdMap
Definition: shape.hxx:77
static void lcl_copyCharPropsToShape(const uno::Reference< drawing::XShape > &xShape, const TextBodyPtr &pTextBody, const ::oox::core::XmlFilterBase &rFilter)
Definition: shape.cxx:691
std::shared_ptr< TextListStyle > TextListStylePtr
std::shared_ptr< TextBody > TextBodyPtr
css::uno::Sequence< sal_Int8 > StreamDataSequence
QPRO_FUNC_TYPE nType
SdrTextHorzAdjust
SDRTEXTHORZADJUST_LEFT
SDRTEXTHORZADJUST_CENTER
SDRTEXTHORZADJUST_RIGHT
Reference< document::XActionLockable > m_xLockable
Definition: shape.cxx:510
#define STREAM_SEEK_TO_BEGIN
sal_uInt16 yExt
sal_uInt16 mapMode
sal_uInt16 xExt
UNDERLYING_TYPE get() const
Additional information for a chart embedded in a drawing shape.
Definition: shape.hxx:92
std::optional< sal_Int64 > moGlowRad
EffectSoftEdgeProperties maSoftEdge
std::vector< std::unique_ptr< Effect > > m_Effects
Stores all effect properties, including those not supported by core yet.
void assignUsed(const EffectProperties &rSourceProps)
Overwrites all members that are explicitly set in rSourceProps.
void pushToPropMap(PropertyMap &rPropMap, const GraphicHelper &rGraphicHelper) const
Writes the properties to the passed property map.
std::optional< sal_Int64 > moShadowDir
void pushToPropMap(ShapePropertyMap &rPropMap, const GraphicHelper &rGraphicHelper, sal_Int32 nShapeRotation=0, ::Color nPhClr=API_RGB_TRANSPARENT, sal_Int16 nPhClrTheme=-1, bool bFlipH=false, bool bFlipV=false, bool bIsCustomShape=false) const
Writes the properties to the passed property map.
GradientFillProperties maGradientProps
Whether the background is used as fill type.
void assignUsed(const FillProperties &rSourceProps)
Properties for bitmap fills.
Color maFillColor
Fill type (OOXML token).
std::optional< sal_Int32 > moFillType
css::uno::Sequence< css::beans::PropertyValue > getLightRigAttributes()
css::uno::Sequence< css::beans::PropertyValue > getShape3DAttributes(const GraphicHelper &rGraphicHelper, ::Color rPhClr)
css::uno::Sequence< css::beans::PropertyValue > getCameraAttributes()
void assignUsed(const LineProperties &rSourceProps)
Line joint type (OOXML token).
void pushToPropMap(ShapePropertyMap &rPropMap, const GraphicHelper &rGraphicHelper, ::Color nPhClr=API_RGB_TRANSPARENT) const
Writes the properties to the passed property map.
FillProperties maLineFill
End line arrow style.
sal_Int32 getLineWidth() const
Calculates the line width attribute from the internal state of the object.
std::optional< sal_Int32 > moLineWidth
User-defined line dash style.
css::drawing::LineStyle getLineStyle() const
Calculates the line style attribute from the internal state of the object.
css::drawing::LineCap getLineCap() const
Calculates the line cap attribute from the internal state of the object.
css::drawing::LineJoint getLineJoint() const
Calculates the line joint attribute from the internal state of the object.
std::optional< sal_Int32 > mnRevolution
void assignUsed(const TextCharacterProperties &rSourceProps)
Overwrites all members that are explicitly set in rSourceProps.
Contains information about an OLE object embedded in a draw page.
Definition: vmldrawing.hxx:63
SVXCORE_DLLPUBLIC Degree100 NormAngle36000(Degree100 a)
constexpr OUStringLiteral UNO_NAME_TEXT_LOWERDIST
constexpr OUStringLiteral UNO_NAME_FILLCOLOR
constexpr OUStringLiteral UNO_NAME_TEXT_UPPERDIST
constexpr OUStringLiteral UNO_NAME_CHAR_POSTURE
constexpr OUStringLiteral UNO_NAME_FILLSTYLE
constexpr OUStringLiteral UNO_NAME_TEXT_VERTADJUST
constexpr OUStringLiteral UNO_NAME_TEXT_LEFTDIST
constexpr OUStringLiteral UNO_NAME_TEXT_AUTOGROWHEIGHT
constexpr OUStringLiteral UNO_NAME_TEXT_AUTOGROWWIDTH
constexpr OUStringLiteral UNO_NAME_CHAR_HEIGHT
constexpr OUStringLiteral UNO_NAME_MISC_OBJ_INTEROPGRABBAG
constexpr OUStringLiteral UNO_NAME_TEXT_RIGHTDIST
constexpr OUStringLiteral UNO_NAME_CHAR_WEIGHT
constexpr OUStringLiteral PROP_FillTransparence
constexpr OUStringLiteral PROP_TextWordWrap
constexpr OUStringLiteral PROP_Shadow
constexpr OUStringLiteral PROP_RightBorder
constexpr OUStringLiteral PROP_RotateAngle
constexpr OUStringLiteral PROP_TextLeftDistance
constexpr OUStringLiteral PROP_ShadowXDistance
constexpr OUStringLiteral PROP_HoriOrientPosition
constexpr OUStringLiteral PROP_CharHeight
constexpr OUStringLiteral PROP_LineColor
constexpr OUStringLiteral PROP_TextUpperDistance
constexpr OUStringLiteral PROP_BackColor
constexpr OUStringLiteral PROP_FillColor
constexpr OUStringLiteral PROP_BackColorTransparency
constexpr OUStringLiteral PROP_TextContourFrame
constexpr OUStringLiteral PROP_CharColor
constexpr OUStringLiteral PROP_FillBitmapName
constexpr OUStringLiteral PROP_LeftBorder
constexpr OUStringLiteral PROP_GraphicCrop
constexpr OUStringLiteral PROP_ShadowFormat
constexpr OUStringLiteral PROP_BackGraphic
constexpr OUStringLiteral PROP_TextLowerDistance
constexpr OUStringLiteral PROP_TextAutoGrowHeight
constexpr OUStringLiteral PROP_ParaAdjust
constexpr OUStringLiteral PROP_TextRightDistance
constexpr OUStringLiteral PROP_TopBorder
constexpr OUStringLiteral PROP_TextVerticalAdjust
constexpr OUStringLiteral PROP_VertOrientPosition
constexpr OUStringLiteral PROP_ShadowColor
constexpr OUStringLiteral PROP_ShadowYDistance
constexpr OUStringLiteral PROP_BottomBorder
sal_Int32 nLength