LibreOffice Module writerfilter (master) 1
GraphicImport.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 <string.h>
21
22#include <com/sun/star/awt/Size.hpp>
23#include <com/sun/star/container/XNamed.hpp>
24#include <com/sun/star/drawing/ColorMode.hpp>
25#include <com/sun/star/drawing/PointSequenceSequence.hpp>
26#include <com/sun/star/drawing/XShape.hpp>
27#include <com/sun/star/drawing/LineStyle.hpp>
28#include <com/sun/star/graphic/XGraphic.hpp>
29#include <com/sun/star/graphic/GraphicProvider.hpp>
30#include <com/sun/star/graphic/XGraphicProvider.hpp>
31#include <com/sun/star/io/BufferSizeExceededException.hpp>
32#include <com/sun/star/io/XInputStream.hpp>
33#include <com/sun/star/lang/XMultiServiceFactory.hpp>
34#include <com/sun/star/lang/XServiceInfo.hpp>
35#include <com/sun/star/table/BorderLine2.hpp>
36#include <com/sun/star/text/GraphicCrop.hpp>
37#include <com/sun/star/text/HoriOrientation.hpp>
38#include <com/sun/star/text/RelOrientation.hpp>
39#include <com/sun/star/text/TextContentAnchorType.hpp>
40#include <com/sun/star/text/VertOrientation.hpp>
41#include <com/sun/star/text/WrapTextMode.hpp>
42#include <com/sun/star/text/XTextContent.hpp>
43#include <com/sun/star/uno/XComponentContext.hpp>
44#include <com/sun/star/table/ShadowFormat.hpp>
45
46#include <svx/svditer.hxx>
47#include <svx/svdobj.hxx>
48#include <svx/svdogrp.hxx>
49#include <svx/svdtrans.hxx>
50#include <svx/unoapi.hxx>
52#include <rtl/ustrbuf.hxx>
53#include <sal/log.hxx>
54#include <rtl/math.hxx>
57#include <comphelper/string.hxx>
60
62
63#include "DomainMapper.hxx"
65#include <ooxml/resourceids.hxx>
66
67#include "ConversionHelper.hxx"
68#include "GraphicHelpers.hxx"
69#include "GraphicImport.hxx"
70#include "PropertyMap.hxx"
71#include "TagLogger.hxx"
73#include "util.hxx"
74
76#include <algorithm>
85#include <utility>
86
87using namespace css;
88
89namespace
90{
91bool isTopGroupObj(const uno::Reference<drawing::XShape>& xShape)
92{
94 if (!pObject)
95 return false;
96
97 if (pObject->getParentSdrObjectFromSdrObject())
98 return false;
99
100 return pObject->IsGroupObject();
101}
102}
103
104namespace writerfilter::dmapper
105{
106
107namespace {
108
109class XInputStreamHelper : public cppu::WeakImplHelper<io::XInputStream>
110{
112 const sal_Int32 m_nLength;
113 sal_Int32 m_nPosition;
114public:
115 XInputStreamHelper(const sal_uInt8* buf, size_t len);
116
117 virtual ::sal_Int32 SAL_CALL readBytes( uno::Sequence< ::sal_Int8 >& aData, ::sal_Int32 nBytesToRead ) override;
118 virtual ::sal_Int32 SAL_CALL readSomeBytes( uno::Sequence< ::sal_Int8 >& aData, ::sal_Int32 nMaxBytesToRead ) override;
119 virtual void SAL_CALL skipBytes( ::sal_Int32 nBytesToSkip ) override;
120 virtual ::sal_Int32 SAL_CALL available( ) override;
121 virtual void SAL_CALL closeInput( ) override;
122};
123
124}
125
126XInputStreamHelper::XInputStreamHelper(const sal_uInt8* buf, size_t len) :
127 m_pBuffer( buf ),
128 m_nLength( len ),
129 m_nPosition( 0 )
130{
131}
132
133sal_Int32 XInputStreamHelper::readBytes( uno::Sequence<sal_Int8>& aData, sal_Int32 nBytesToRead )
134{
135 return readSomeBytes( aData, nBytesToRead );
136}
137
138sal_Int32 XInputStreamHelper::readSomeBytes( uno::Sequence<sal_Int8>& aData, sal_Int32 nMaxBytesToRead )
139{
140 sal_Int32 nRet = 0;
141 if( nMaxBytesToRead > 0 )
142 {
143 if( nMaxBytesToRead > m_nLength - m_nPosition )
144 nRet = m_nLength - m_nPosition;
145 else
146 nRet = nMaxBytesToRead;
147 aData.realloc( nRet );
148 sal_Int8* pData = aData.getArray();
149 if( nRet )
150 {
151 memcpy( pData, m_pBuffer + m_nPosition, nRet );
152 m_nPosition += nRet;
153 }
154 }
155 return nRet;
156}
157
158
159void XInputStreamHelper::skipBytes( sal_Int32 nBytesToSkip )
160{
161 if( nBytesToSkip < 0 || m_nPosition + nBytesToSkip > m_nLength)
162 throw io::BufferSizeExceededException();
163 m_nPosition += nBytesToSkip;
164}
165
166
167sal_Int32 XInputStreamHelper::available( )
168{
169 return m_nLength - m_nPosition;
170}
171
172
173void XInputStreamHelper::closeInput( )
174{
175}
176
177namespace {
178
179struct GraphicBorderLine
180{
181 sal_Int32 nLineWidth;
183
184 GraphicBorderLine() :
185 nLineWidth(0)
186 ,bHasShadow(false)
187 {}
188
189 bool isEmpty() const
190 {
191 return nLineWidth == 0 && !bHasShadow;
192 }
193
194};
195
196}
197
199{
200private:
201 sal_Int32 m_nXSize;
203 sal_Int32 m_nYSize;
205
206public:
209
211 sal_Int32 m_nTopPosition;
212
214 sal_Int32 m_zOrder;
215
216 sal_Int16 m_nHoriOrient;
218 bool m_bPageToggle = false;
219 sal_Int16 m_nVertOrient;
221 text::WrapTextMode m_nWrap;
224 bool m_bAllowOverlap = true;
230
231 sal_Int32 m_nLeftMargin;
232 sal_Int32 m_nLeftMarginOrig = 0;
233 sal_Int32 m_nRightMargin;
234 sal_Int32 m_nTopMargin;
236
240 sal_Int32 m_nShadowColor;
242
243 sal_Int32 m_nContrast;
244 sal_Int32 m_nBrightness;
245
246 static constexpr sal_Int32 nFillColor = 0xffffffff;
247
248 drawing::ColorMode m_eColorMode;
249
250 GraphicBorderLine m_aBorders[4];
251
253
257 bool m_bDecorative = false;
258
260
261 OUString m_sName;
263 OUString m_title;
265 std::pair<OUString, OUString>& m_rPositionOffsets;
266 std::pair<OUString, OUString>& m_rAligns;
267 std::queue<OUString>& m_rPositivePercentages;
268 OUString m_sAnchorId;
270 std::optional<sal_Int32> m_oEffectExtentLeft;
271 std::optional<sal_Int32> m_oEffectExtentTop;
272 std::optional<sal_Int32> m_oEffectExtentRight;
273 std::optional<sal_Int32> m_oEffectExtentBottom;
274
276 std::pair<OUString, OUString>& rPositionOffsets,
277 std::pair<OUString, OUString>& rAligns,
278 std::queue<OUString>& rPositivePercentages)
279 : m_nXSize(0)
280 ,m_bXSizeValid(false)
281 ,m_nYSize(0)
282 ,m_bYSizeValid(false)
283 ,m_rGraphicImportType(rImportType)
284 ,m_rDomainMapper( rDMapper )
285 ,m_nLeftPosition(0)
286 ,m_nTopPosition(0)
287 ,m_bUseSimplePos(false)
288 ,m_zOrder(-1)
289 ,m_nHoriOrient( text::HoriOrientation::NONE )
290 ,m_nHoriRelation( text::RelOrientation::FRAME )
291 ,m_nVertOrient( text::VertOrientation::NONE )
292 ,m_nVertRelation( text::RelOrientation::FRAME )
293 ,m_nWrap(text::WrapTextMode_NONE)
294 ,m_bLayoutInCell(true)
295 ,m_bCompatForcedLayoutInCell(false)
296 ,m_bOpaque( !rDMapper.IsInHeaderFooter() )
297 ,m_bBehindDoc(false)
298 ,m_bContour(false)
299 ,m_bContourOutside(true)
300 ,m_nLeftMargin(319)
301 ,m_nRightMargin(319)
302 ,m_nTopMargin(0)
303 ,m_nBottomMargin(0)
304 ,m_bShadow(false)
305 ,m_nShadowXDistance(0)
306 ,m_nShadowYDistance(0)
307 ,m_nShadowColor(0)
308 ,m_nShadowTransparence(0)
309 ,m_nContrast(0)
310 ,m_nBrightness(0)
311 ,m_eColorMode( drawing::ColorMode_STANDARD )
312 ,m_bIsGraphic(false)
313 ,m_bSizeProtected(false)
314 ,m_bPositionProtected(false)
315 ,m_bHidden(false)
316 ,m_nShapeOptionType(0)
317 ,m_rPositionOffsets(rPositionOffsets)
318 ,m_rAligns(rAligns)
319 ,m_rPositivePercentages(rPositivePercentages)
320 {
321 }
322
323 void setXSize(sal_Int32 _nXSize)
324 {
325 m_nXSize = _nXSize;
326 m_bXSizeValid = true;
327 }
328
329 sal_uInt32 getXSize() const
330 {
331 return m_nXSize;
332 }
333
334 bool isXSizeValid() const
335 {
336 return m_bXSizeValid;
337 }
338
339 void setYSize(sal_Int32 _nYSize)
340 {
341 m_nYSize = _nYSize;
342 m_bYSizeValid = true;
343 }
344
345 sal_uInt32 getYSize() const
346 {
347 return m_nYSize;
348 }
349
350 bool isYSizeValid() const
351 {
352 return m_bYSizeValid;
353 }
354
355 void applyMargins(const uno::Reference< beans::XPropertySet >& xGraphicObjectProperties) const
356 {
357 xGraphicObjectProperties->setPropertyValue(getPropertyName( PROP_LEFT_MARGIN ), uno::Any(m_nLeftMargin));
358 xGraphicObjectProperties->setPropertyValue(getPropertyName( PROP_RIGHT_MARGIN ), uno::Any(m_nRightMargin));
359 xGraphicObjectProperties->setPropertyValue(getPropertyName( PROP_TOP_MARGIN ), uno::Any(m_nTopMargin));
360 xGraphicObjectProperties->setPropertyValue(getPropertyName( PROP_BOTTOM_MARGIN ), uno::Any(m_nBottomMargin));
361 }
362
363 void applyPosition(const uno::Reference< beans::XPropertySet >& xGraphicObjectProperties) const
364 {
365 xGraphicObjectProperties->setPropertyValue(getPropertyName( PROP_HORI_ORIENT ),
366 uno::Any(m_nHoriOrient));
367 xGraphicObjectProperties->setPropertyValue(getPropertyName( PROP_VERT_ORIENT ),
368 uno::Any(m_nVertOrient));
369 }
370
371 void applyRelativePosition(const uno::Reference< beans::XPropertySet >& xGraphicObjectProperties, bool bRelativeOnly = false) const
372 {
373 if (!bRelativeOnly)
374 xGraphicObjectProperties->setPropertyValue(getPropertyName( PROP_HORI_ORIENT_POSITION),
375 uno::Any(m_nLeftPosition));
376 xGraphicObjectProperties->setPropertyValue(getPropertyName( PROP_HORI_ORIENT_RELATION ),
377 uno::Any(m_nHoriRelation));
378 xGraphicObjectProperties->setPropertyValue(getPropertyName(PROP_PAGE_TOGGLE),
379 uno::Any(m_bPageToggle));
380 if (!bRelativeOnly)
381 xGraphicObjectProperties->setPropertyValue(getPropertyName( PROP_VERT_ORIENT_POSITION),
382 uno::Any(m_nTopPosition));
383 xGraphicObjectProperties->setPropertyValue(getPropertyName( PROP_VERT_ORIENT_RELATION ),
384 uno::Any(m_nVertRelation));
385 }
386
387 void applyZOrder(uno::Reference<beans::XPropertySet> const & xGraphicObjectProperties) const
388 {
389 sal_Int32 nZOrder = m_zOrder;
390 if (m_rGraphicImportType == GraphicImportType::IMPORT_AS_DETECTED_INLINE
391 && !m_rDomainMapper.IsInShape())
392 {
393 nZOrder = 0;
394 }
395 if (nZOrder >= 0)
396 {
397 // tdf#120760 Send objects with behinddoc=true to the back.
398 if (m_bBehindDoc && m_rDomainMapper.IsInHeaderFooter())
399 nZOrder -= SAL_MAX_INT32;
400 GraphicZOrderHelper* pZOrderHelper = m_rDomainMapper.graphicZOrderHelper();
401 bool const bOldStyle(m_rGraphicImportType == GraphicImportType::IMPORT_AS_DETECTED_INLINE);
402 xGraphicObjectProperties->setPropertyValue(getPropertyName(PROP_Z_ORDER),
403 uno::Any(pZOrderHelper->findZOrder(nZOrder, bOldStyle)));
404 pZOrderHelper->addItem(xGraphicObjectProperties, nZOrder);
405 }
406 }
407
408 void applyName(uno::Reference<beans::XPropertySet> const & xGraphicObjectProperties) const
409 {
410 try
411 {
412 if (!m_sName.isEmpty())
413 {
414 uno::Reference<container::XNamed> const xNamed(xGraphicObjectProperties, uno::UNO_QUERY_THROW);
415 xNamed->setName(m_sName);
416 }
417 // else: name is automatically generated by SwDoc::MakeFlySection_()
418
419 xGraphicObjectProperties->setPropertyValue(getPropertyName( PROP_DESCRIPTION ),
420 uno::Any( m_sAlternativeText ));
421 xGraphicObjectProperties->setPropertyValue(getPropertyName( PROP_TITLE ),
422 uno::Any( m_title ));
423 }
424 catch( const uno::Exception& )
425 {
426 TOOLS_WARN_EXCEPTION("writerfilter", "failed");
427 }
428 }
429
430 void applyHyperlink(uno::Reference<beans::XPropertySet> const & xShapeProps, bool bIsShape)
431 {
432 // Graphic objects have a different hyperlink prop than shapes
433 auto aHyperlinkProp = bIsShape ? PROP_HYPERLINK : PROP_HYPER_LINK_U_R_L;
434 if (!m_sHyperlinkURL.isEmpty())
435 {
436 xShapeProps->setPropertyValue(
437 getPropertyName(aHyperlinkProp), uno::Any(m_sHyperlinkURL));
438 }
439 }
440
443 {
444 comphelper::SequenceAsHashMap aEffectExtent;
445 if (m_oEffectExtentLeft)
446 aEffectExtent["l"] <<= *m_oEffectExtentLeft;
447 if (m_oEffectExtentTop)
448 aEffectExtent["t"] <<= *m_oEffectExtentTop;
449 if (m_oEffectExtentRight)
450 aEffectExtent["r"] <<= *m_oEffectExtentRight;
451 if (m_oEffectExtentBottom)
452 aEffectExtent["b"] <<= *m_oEffectExtentBottom;
453 if (!aEffectExtent.empty())
454 m_aInteropGrabBag["CT_EffectExtent"] <<= aEffectExtent.getAsConstPropertyValueList();
455 return m_aInteropGrabBag;
456 }
457};
458
459GraphicImport::GraphicImport(uno::Reference<uno::XComponentContext> xComponentContext,
461 DomainMapper& rDMapper,
462 GraphicImportType & rImportType,
463 std::pair<OUString, OUString>& rPositionOffsets,
464 std::pair<OUString, OUString>& rAligns,
465 std::queue<OUString>& rPositivePercentages)
466: LoggedProperties("GraphicImport")
467, LoggedTable("GraphicImport")
468, LoggedStream("GraphicImport")
469, m_pImpl(new GraphicImport_Impl(rImportType, rDMapper, rPositionOffsets, rAligns, rPositivePercentages))
470, m_xComponentContext(std::move(xComponentContext))
471, m_xTextFactory(std::move(xTextFactory))
472{
473}
474
476{
477}
478
479com::sun::star::awt::Point GraphicImport::GetGraphicObjectPosition() const
480{
481 return (com::sun::star::awt::Point(m_pImpl->m_nLeftPosition, m_pImpl->m_nTopPosition));
482}
483
485{
486 return m_pImpl->m_bLayoutInCell;
487}
488
490{
491 switch (nVal)
492 {
493 case NS_ooxml::LN_Value_wordprocessingDrawing_ST_WrapText_bothSides: // 90920;
494 m_pImpl->m_nWrap = text::WrapTextMode_PARALLEL;
495 break;
496 case NS_ooxml::LN_Value_wordprocessingDrawing_ST_WrapText_left: // 90921;
497 m_pImpl->m_nWrap = text::WrapTextMode_LEFT;
498 break;
499 case NS_ooxml::LN_Value_wordprocessingDrawing_ST_WrapText_right: // 90922;
500 m_pImpl->m_nWrap = text::WrapTextMode_RIGHT;
501 break;
502 case NS_ooxml::LN_Value_wordprocessingDrawing_ST_WrapText_largest: // 90923;
503 m_pImpl->m_nWrap = text::WrapTextMode_DYNAMIC;
504 break;
505 default:;
506 }
507}
508
509void GraphicImport::putPropertyToFrameGrabBag( const OUString& sPropertyName, const uno::Any& aPropertyValue )
510{
511 beans::PropertyValue aProperty;
512 aProperty.Name = sPropertyName;
513 aProperty.Value = aPropertyValue;
514
515 if (!m_xShape.is())
516 return;
517
518 uno::Reference< beans::XPropertySet > xSet(m_xShape, uno::UNO_QUERY_THROW);
519
520 uno::Reference< beans::XPropertySetInfo > xSetInfo(xSet->getPropertySetInfo());
521 if (!xSetInfo.is())
522 return;
523
524 OUString aGrabBagPropName;
525 uno::Reference<lang::XServiceInfo> xServiceInfo(m_xShape, uno::UNO_QUERY_THROW);
526 if (xServiceInfo->supportsService("com.sun.star.text.TextFrame"))
527 aGrabBagPropName = "FrameInteropGrabBag";
528 else
529 aGrabBagPropName = "InteropGrabBag";
530
531 if (xSetInfo->hasPropertyByName(aGrabBagPropName))
532 {
533 //Add pProperty to the end of the Sequence for aGrabBagPropName
535 xSet->getPropertyValue(aGrabBagPropName) >>= aTmp;
536 std::vector<beans::PropertyValue> aGrabBag(comphelper::sequenceToContainer<std::vector<beans::PropertyValue> >(aTmp));
537 aGrabBag.push_back(aProperty);
538
539 xSet->setPropertyValue(aGrabBagPropName, uno::Any(comphelper::containerToSequence(aGrabBag)));
540 }
541}
542
543static bool lcl_bHasGroupSlantedChild(const SdrObject* pObj)
544{
545 // Returns true, if a child object differs more than 0.02deg from horizontal or vertical.
546 // Because lines sometimes are imported as customshapes, a horizontal or vertical line
547 // might not have exactly 0, 90, 180, or 270 degree as rotate angle.
548 if (!pObj)
549 return false;
550 if (!pObj->IsGroupObject())
551 return false;
552 SdrObjList* pSubList = pObj->GetSubList();
553 if (!pSubList)
554 return false;
555 SdrObjListIter aIterator(pSubList, SdrIterMode::DeepNoGroups);
556 while (aIterator.IsMore())
557 {
558 const SdrObject* pSubObj = aIterator.Next();
559 const Degree100 nRotateAngle = NormAngle36000(pSubObj->GetRotateAngle());
560 const sal_uInt16 nRot = nRotateAngle.get();
561 if ((3 < nRot && nRot < 8997) || (9003 < nRot && nRot < 17997)
562 || (18003 < nRot && nRot < 26997) || (27003 < nRot && nRot < 35997))
563 return true;
564 }
565 return false;
566}
567
569{
570 // Word versions older than 14 do not swap width and height (see lcl_doMSOWidthHeightSwap)
571 // and therefore generate different effectExtent. We correct them here.
572 sal_Int16 nAngleDeg = (nMSOAngle / 60000) % 180;
573 if (nAngleDeg < 45 || nAngleDeg >= 135)
574 return;
575
576 sal_Int32 nDiff = o3tl::convert(
577 (double(m_pImpl->getXSize()) - double(m_pImpl->getYSize())) / 2.0,
579 if (m_pImpl->m_oEffectExtentLeft)
580 *m_pImpl->m_oEffectExtentLeft += nDiff;
581 if (m_pImpl->m_oEffectExtentRight)
582 *m_pImpl->m_oEffectExtentRight += nDiff;
583 if (m_pImpl->m_oEffectExtentTop)
584 *m_pImpl->m_oEffectExtentTop -= nDiff;
585 if (m_pImpl->m_oEffectExtentBottom)
586 *m_pImpl->m_oEffectExtentBottom -= nDiff;
587}
588
589static void lcl_doMSOWidthHeightSwap(awt::Point& rLeftTop, awt::Size& rSize,
590 const sal_Int32 nMSOAngle)
591{
592 if (nMSOAngle == 0)
593 return;
594 // convert nMSOAngle to degree in [0°,180°[
595 sal_Int16 nAngleDeg = (nMSOAngle / 60000) % 180;
596 if (nAngleDeg >= 45 && nAngleDeg < 135)
597 {
598 // keep center of rectangle given in rLeftTop and rSize
599 sal_Int32 aTemp = rSize.Width - rSize.Height;
600 rLeftTop.X += aTemp / 2;
601 rLeftTop.Y -= aTemp / 2;
602 std::swap(rSize.Width, rSize.Height);
603 }
604 return;
605}
606
607void GraphicImport::lcl_expandRectangleByEffectExtent(awt::Point& rLeftTop, awt::Size& rSize)
608{
609 sal_Int32 nEffectExtent = (m_pImpl->m_oEffectExtentLeft)
610 ? oox::drawingml::convertEmuToHmm(*m_pImpl->m_oEffectExtentLeft)
611 : 0;
612 rLeftTop.X -= nEffectExtent;
613 rSize.Width += nEffectExtent;
614 nEffectExtent = (m_pImpl->m_oEffectExtentRight)
615 ? oox::drawingml::convertEmuToHmm(*m_pImpl->m_oEffectExtentRight)
616 : 0;
617 rSize.Width += nEffectExtent;
618 nEffectExtent = (m_pImpl->m_oEffectExtentTop)
619 ? oox::drawingml::convertEmuToHmm(*m_pImpl->m_oEffectExtentTop)
620 : 0;
621 rLeftTop.Y -= nEffectExtent;
622 rSize.Height += nEffectExtent;
623 nEffectExtent = (m_pImpl->m_oEffectExtentBottom)
624 ? oox::drawingml::convertEmuToHmm(*m_pImpl->m_oEffectExtentBottom)
625 : 0;
626 rSize.Height += nEffectExtent;
627}
628
630{
631 sal_Int32 nIntValue = rValue.getInt();
632 switch( nName )
633 {
634 case NS_ooxml::LN_OfficeArtExtension_Decorative_val:
635 m_pImpl->m_bDecorative = true;
636 break;
637 case NS_ooxml::LN_CT_Hyperlink_URL://90682;
638 m_pImpl->m_sHyperlinkURL = rValue.getString();
639 break;
640 case NS_ooxml::LN_blip: //the binary graphic data in a shape
641 {
643 if( pProperties )
644 {
645 pProperties->resolve(*this);
646 }
647 }
648 break;
649 case NS_ooxml::LN_payload :
650 {
652 if( pPictureData )
653 pPictureData->resolve(*this);
654 }
655 break;
656
657 //border properties
658 case NS_ooxml::LN_CT_Border_sz:
659 m_pImpl->m_aBorders[BORDER_TOP].nLineWidth = nIntValue;
660 break;
661 case NS_ooxml::LN_CT_Border_val:
662 //graphic borders don't support different line types
663 break;
664 case NS_ooxml::LN_CT_Border_space:
665 break;
666 case NS_ooxml::LN_CT_Border_shadow:
667 m_pImpl->m_aBorders[BORDER_TOP].bHasShadow = nIntValue != 0;
668 break;
669 case NS_ooxml::LN_CT_Border_frame:
670 break;
671 case NS_ooxml::LN_CT_PositiveSize2D_cx:
672 case NS_ooxml::LN_CT_PositiveSize2D_cy:
673 {
674 sal_Int32 nDim = oox::drawingml::convertEmuToHmm(nIntValue);
675 // drawingML equivalent of oox::vml::ShapeType::getAbsRectangle():
676 // make sure a shape isn't hidden implicitly just because it has
677 // zero height or width.
678 if (nDim == 0)
679 nDim = 1;
680
681 if( nName == NS_ooxml::LN_CT_PositiveSize2D_cx )
682 m_pImpl->setXSize(nDim);
683 else
684 m_pImpl->setYSize(nDim);
685 }
686 break;
687 case NS_ooxml::LN_CT_EffectExtent_l:
688 m_pImpl->m_oEffectExtentLeft = nIntValue;
689 break;
690 case NS_ooxml::LN_CT_EffectExtent_t:
691 m_pImpl->m_oEffectExtentTop = nIntValue;
692 break;
693 case NS_ooxml::LN_CT_EffectExtent_r:
694 m_pImpl->m_oEffectExtentRight = nIntValue;
695 break;
696 case NS_ooxml::LN_CT_EffectExtent_b:
697 m_pImpl->m_oEffectExtentBottom = nIntValue;
698 break;
699 case NS_ooxml::LN_CT_NonVisualDrawingProps_id:// 90650;
700 //id of the object - ignored
701 break;
702 case NS_ooxml::LN_CT_NonVisualDrawingProps_name:// 90651;
703 //name of the object
704 m_pImpl->m_sName = rValue.getString();
705 break;
706 case NS_ooxml::LN_CT_NonVisualDrawingProps_descr:// 90652;
707 //alternative text
708 m_pImpl->m_sAlternativeText = rValue.getString();
709 break;
710 case NS_ooxml::LN_CT_NonVisualDrawingProps_title:
711 //alternative text
712 m_pImpl->m_title = rValue.getString();
713 break;
714 case NS_ooxml::LN_CT_NonVisualDrawingProps_hidden:
715 m_pImpl->m_bHidden = (nIntValue == 1);
716 break;
717 case NS_ooxml::LN_CT_GraphicalObjectFrameLocking_noChangeAspect://90644;
718 //disallow aspect ratio change - ignored
719 break;
720 case NS_ooxml::LN_CT_GraphicalObjectFrameLocking_noMove:// 90645;
721 m_pImpl->m_bPositionProtected = true;
722 break;
723 case NS_ooxml::LN_CT_GraphicalObjectFrameLocking_noResize: // 90646;
724 m_pImpl->m_bSizeProtected = true;
725 break;
726 case NS_ooxml::LN_CT_Anchor_distT: // 90983;
727 case NS_ooxml::LN_CT_Anchor_distB: // 90984;
728 case NS_ooxml::LN_CT_Anchor_distL: // 90985;
729 case NS_ooxml::LN_CT_Anchor_distR: // 90986;
730 {
731 m_pImpl->m_nShapeOptionType = nName;
732 ProcessShapeOptions(rValue);
733 }
734 break;
735 case NS_ooxml::LN_CT_Anchor_simplePos_attr: // 90987;
736 m_pImpl->m_bUseSimplePos = nIntValue > 0;
737 break;
738 case NS_ooxml::LN_CT_Anchor_relativeHeight: // 90988;
739 m_pImpl->m_zOrder = nIntValue;
740 break;
741 case NS_ooxml::LN_CT_Anchor_behindDoc: // 90989; - in background
742 if (nIntValue > 0)
743 {
744 m_pImpl->m_bOpaque = false;
745 m_pImpl->m_bBehindDoc = true;
746 }
747 break;
748 case NS_ooxml::LN_CT_Anchor_locked: // 90990; - ignored
749 break;
750 case NS_ooxml::LN_CT_Anchor_layoutInCell: // 90991; - ignored
751 // Starting in MSO 2013, anchors are ALWAYS considered to be laid out in table cell.
752 m_pImpl->m_bCompatForcedLayoutInCell = !nIntValue
753 && m_pImpl->m_rDomainMapper.GetSettingsTable()->GetWordCompatibilityMode() > 14
754 && m_pImpl->m_rDomainMapper.IsInTable();
755 m_pImpl->m_bLayoutInCell = m_pImpl->m_bCompatForcedLayoutInCell || nIntValue;
756 break;
757 case NS_ooxml::LN_CT_Anchor_hidden: // 90992; - ignored
758 break;
759 case NS_ooxml::LN_CT_Anchor_allowOverlap:
760 m_pImpl->m_bAllowOverlap = nIntValue != 0;
761 break;
762 case NS_ooxml::LN_CT_Anchor_wp14_anchorId:
763 case NS_ooxml::LN_CT_Inline_wp14_anchorId:
764 {
765 OUStringBuffer aBuffer = OUString::number(nIntValue, 16);
766 OUStringBuffer aString;
767 comphelper::string::padToLength(aString, 8 - aBuffer.getLength(), '0');
768 aString.append(aBuffer.getStr());
769 m_pImpl->m_sAnchorId = aString.makeStringAndClear().toAsciiUpperCase();
770 }
771 break;
772 case NS_ooxml::LN_CT_Point2D_x: // 90405;
773 m_pImpl->m_nLeftPosition = ConversionHelper::convertTwipToMM100(nIntValue);
774 m_pImpl->m_nHoriRelation = text::RelOrientation::PAGE_FRAME;
775 m_pImpl->m_nHoriOrient = text::HoriOrientation::NONE;
776 break;
777 case NS_ooxml::LN_CT_Point2D_y: // 90406;
778 m_pImpl->m_nTopPosition = ConversionHelper::convertTwipToMM100(nIntValue);
779 m_pImpl->m_nVertRelation = text::RelOrientation::PAGE_FRAME;
780 m_pImpl->m_nVertOrient = text::VertOrientation::NONE;
781 break;
782 case NS_ooxml::LN_CT_WrapTight_wrapText: // 90934;
783 m_pImpl->m_bContour = true;
784 m_pImpl->m_bContourOutside = true;
785
786 handleWrapTextValue(rValue.getInt());
787
788 break;
789 case NS_ooxml::LN_CT_WrapThrough_wrapText:
790 m_pImpl->m_bContour = true;
791 m_pImpl->m_bContourOutside = false;
792
793 handleWrapTextValue(rValue.getInt());
794
795 break;
796 case NS_ooxml::LN_CT_WrapSquare_wrapText: //90928;
797 handleWrapTextValue(rValue.getInt());
798 break;
799 case NS_ooxml::LN_shape:
800 {
802 rValue.getAny( ) >>= xShape;
803 if ( xShape.is( ) )
804 {
805 // Is it a graphic image
806 bool bUseShape = true;
807 try
808 {
810 ( xShape, uno::UNO_QUERY_THROW );
811
813 xShapeProps->getPropertyValue("Graphic") >>= xGraphic;
814
815 sal_Int32 nRotation = 0;
816 xShapeProps->getPropertyValue("RotateAngle") >>= nRotation;
817
818 css::beans::PropertyValues aGrabBag;
819 xShapeProps->getPropertyValue("InteropGrabBag") >>= aGrabBag;
820 // if the shape contains effects in the grab bag, we should not transform it
821 // in a XTextContent so those effects can be preserved
822 bool bContainsEffects = std::any_of(std::cbegin(aGrabBag), std::cend(aGrabBag), [](const auto& rProp) {
823 return rProp.Name == "EffectProperties"
824 || rProp.Name == "3DEffectProperties"
825 || rProp.Name == "ArtisticEffectProperties";
826 });
827
828 xShapeProps->getPropertyValue("Shadow") >>= m_pImpl->m_bShadow;
829 if (m_pImpl->m_bShadow)
830 {
831 xShapeProps->getPropertyValue("ShadowXDistance") >>= m_pImpl->m_nShadowXDistance;
832 xShapeProps->getPropertyValue("ShadowYDistance") >>= m_pImpl->m_nShadowYDistance;
833 xShapeProps->getPropertyValue("ShadowColor") >>= m_pImpl->m_nShadowColor;
834 xShapeProps->getPropertyValue("ShadowTransparence") >>= m_pImpl->m_nShadowTransparence;
835 }
836
837 xShapeProps->getPropertyValue("GraphicColorMode") >>= m_pImpl->m_eColorMode;
838 xShapeProps->getPropertyValue("AdjustLuminance") >>= m_pImpl->m_nBrightness;
839 xShapeProps->getPropertyValue("AdjustContrast") >>= m_pImpl->m_nContrast;
840
841 // fdo#70457: transform XShape into a SwXTextGraphicObject only if there's no rotation
842 if ( nRotation == 0 && !bContainsEffects )
843 m_xGraphicObject = createGraphicObject( xGraphic, xShapeProps );
844
845 bUseShape = !m_xGraphicObject.is( );
846
847 if ( !bUseShape )
848 {
849 // Define the object size
851 uno::UNO_QUERY );
852 awt::Size aSize = xShape->getSize( );
853 xGraphProps->setPropertyValue("Height",
854 uno::Any( aSize.Height ) );
855 xGraphProps->setPropertyValue("Width",
856 uno::Any( aSize.Width ) );
857
858 text::GraphicCrop aGraphicCrop( 0, 0, 0, 0 );
859 uno::Reference< beans::XPropertySet > xSourceGraphProps( xShape, uno::UNO_QUERY );
860 uno::Any aAny = xSourceGraphProps->getPropertyValue("GraphicCrop");
861 if(aAny >>= aGraphicCrop) {
862 xGraphProps->setPropertyValue("GraphicCrop",
863 uno::Any( aGraphicCrop ) );
864 }
865
866 // We need to drop the shape here somehow
867 uno::Reference< lang::XComponent > xShapeComponent( xShape, uno::UNO_QUERY );
868 xShapeComponent->dispose( );
869 }
870 }
871 catch( const beans::UnknownPropertyException & )
872 {
873 // It isn't a graphic image
874 }
875
876 if ( bUseShape )
877 m_xShape = xShape;
878
879 if ( m_xShape.is( ) )
880 {
882 (m_xShape, uno::UNO_QUERY_THROW);
883
884
885 xShapeProps->setPropertyValue
888 (text::TextContentAnchorType_AS_CHARACTER));
889
890 // In Word, if a shape is anchored inline, that
891 // excludes being in the background.
892 xShapeProps->setPropertyValue("Opaque", uno::Any(true));
893
894 uno::Reference<lang::XServiceInfo> xServiceInfo(m_xShape, uno::UNO_QUERY_THROW);
895
896 // TextFrames can't be rotated. But for anything else,
897 // make sure that setting size doesn't affect rotation,
898 // that would not match Word's definition of rotation.
899 bool bKeepRotation = false;
900 if (!xServiceInfo->supportsService("com.sun.star.text.TextFrame"))
901 {
902 bKeepRotation = true;
903 xShapeProps->setPropertyValue
906 (m_pImpl->m_rDomainMapper.GetCurrentTextRange()));
907 }
908
909 awt::Size aSize(m_xShape->getSize());
910
911 // One purpose of the next part is, to set the logic rectangle of the SdrObject
912 // to nXSize and nYSize from import. That doesn't work for groups or lines,
913 // because they do not have a logic rectangle and m_xShape->getSize and
914 // m_xShape->setSize would work on the snap rectangle. In case a shape is
915 // rotated, non-uniform scaling the snap rectangle will introduce shearing on
916 // the shape. In case group or line is rotated, nXSize and nYSize contain the
917 // unrotated size from oox. The rotation is already incorporated into group
918 // children and line points. We must not scale them to unrotated size. Exclude
919 // those shapes here.
920
921 // Get MSO rotation angle. GetRotateAngle from SdrObject is not suitable
922 // here, because it returns the rotate angle of the first child for groups
923 // and slope angle for lines, even if line or group had not been rotated.
924 // Import in oox has put the rotation from oox file into InteropGrabBag.
925 comphelper::SequenceAsHashMap aInteropGrabBag(xShapeProps->getPropertyValue("InteropGrabBag"));
926 sal_Int32 nOOXAngle(0);
927 aInteropGrabBag.getValue("mso-rotation-angle") >>= nOOXAngle; // 1/60000 deg
928 // tdf#143455: A diagram is imported as group, but has no valid object list
929 // and contour wrap is different to Word. As workaround diagrams are excluded
930 // here in various places.
931 const SdrObject* pDiagramCandidate(SdrObject::getSdrObjectFromXShape(m_xShape));
932 const bool bIsDiagram(nullptr != pDiagramCandidate && pDiagramCandidate->isDiagram());
933 // tdf#143476: A lockedCanvas (Word2007) is imported as group, but has not
934 // got size and position. Values from m_Impl has to be used.
935 bool bIsLockedCanvas(false);
936 aInteropGrabBag.getValue("LockedCanvas") >>= bIsLockedCanvas;
937 const bool bIsGroupOrLine = (xServiceInfo->supportsService("com.sun.star.drawing.GroupShape")
938 && !bIsDiagram && !bIsLockedCanvas)
939 || xServiceInfo->supportsService("com.sun.star.drawing.LineShape");
941 if ((bIsGroupOrLine && !lcl_bHasGroupSlantedChild(pShape) && nOOXAngle == 0)
942 || !bIsGroupOrLine)
943 {
944 if (m_pImpl->isXSizeValid())
945 aSize.Width = m_pImpl->getXSize();
946 if (m_pImpl->isYSizeValid())
947 aSize.Height = m_pImpl->getYSize();
948 }
949
950 Degree100 nRotation;
951 if (bKeepRotation)
952 {
953 // Use internal API, getPropertyValue("RotateAngle")
954 // would use GetObjectRotation(), which is not what
955 // we want.
956 if (pShape)
957 nRotation = pShape->GetRotateAngle();
958 }
959 m_xShape->setSize(aSize);
960 if (bKeepRotation)
961 {
962 xShapeProps->setPropertyValue("RotateAngle", uno::Any(nRotation.get()));
963 }
964
965 m_pImpl->m_bIsGraphic = true;
966
967 if (!m_pImpl->m_sAnchorId.isEmpty())
968 {
969 putPropertyToFrameGrabBag("AnchorId", uno::Any(m_pImpl->m_sAnchorId));
970 }
971
972 // Calculate mso unrotated rectangle and its center, needed below
973 awt::Size aImportSize(m_xShape->getSize()); // here only fallback
974 if (m_pImpl->isXSizeValid())
975 aImportSize.Width = m_pImpl->getXSize(); // Hmm
976 if (m_pImpl->isYSizeValid())
977 aImportSize.Height = m_pImpl->getYSize(); // Hmm
978 const awt::Point aImportPosition(GetGraphicObjectPosition()); // Hmm
979 double fCentrumX = aImportPosition.X + aImportSize.Width / 2.0;
980 double fCentrumY = aImportPosition.Y + aImportSize.Height / 2.0;
981
982 // In case of group and lines, transformations are incorporated in the child
983 // shapes or points respectively in LO. MSO has rotation as separate property.
984 // The position refers to the unrotated rectangle of MSO. We need to adapt it
985 // to the left-top of the transformed shape.
986 awt::Size aLOSize(m_xShape->getSize()); // LO snap rectangle size in Hmm
987 if (bIsGroupOrLine && !(m_pImpl->mpWrapPolygon))
988 {
989 // Set LO position. MSO rotation is done on shape center.
990 if(pShape && pShape->IsGroupObject())
991 {
992 tools::Rectangle aSnapRect = pShape->GetSnapRect(); // Twips
993 m_pImpl->m_nLeftPosition = ConversionHelper::convertTwipToMM100(aSnapRect.Left());
994 m_pImpl->m_nTopPosition = ConversionHelper::convertTwipToMM100(aSnapRect.Top());
995 aLOSize.Width = ConversionHelper::convertTwipToMM100(aSnapRect.getOpenWidth());
996 aLOSize.Height = ConversionHelper::convertTwipToMM100(aSnapRect.getOpenHeight());
997 }
998 else
999 {
1000 m_pImpl->m_nLeftPosition = fCentrumX - aLOSize.Width / 2.0;
1001 m_pImpl->m_nTopPosition = fCentrumY - aLOSize.Height / 2.0;
1002 }
1003 m_xShape->setPosition(GetGraphicObjectPosition());
1004 }
1005 // ToDo: Rotated shapes with position type "Alignment" (UI of Word) have
1006 // wrong position. Word aligns the unrotated logic rectangle, LO the rotated
1007 // snap rectangle.
1008
1009 // Margin correction
1010
1011 // tdf#143475: Word 2007 (vers 12) calculates effectExtent for rotated images
1012 // based on the unrotated image without width-height-swap. We correct this to
1013 // those values, which would be calculated if width-height-swap was used.
1014 if (m_pImpl->m_rDomainMapper.GetSettingsTable()->GetWordCompatibilityMode() < 14
1015 && xServiceInfo->supportsService("com.sun.star.drawing.GraphicObjectShape")
1016 && nOOXAngle != 0)
1017 {
1019 }
1020
1021 if (m_pImpl->m_rGraphicImportType == IMPORT_AS_DETECTED_INLINE)
1022 {
1023 if (nOOXAngle == 0)
1024 {
1025 // EffectExtent contains all needed additional space, including fat
1026 // stroke and shadow. Simple add it to the margins.
1027 sal_Int32 nEffectExtent = (m_pImpl->m_oEffectExtentLeft)
1028 ? oox::drawingml::convertEmuToHmm(*m_pImpl->m_oEffectExtentLeft)
1029 : 0;
1030 m_pImpl->m_nLeftMargin += nEffectExtent;
1031 nEffectExtent = (m_pImpl->m_oEffectExtentRight)
1032 ? oox::drawingml::convertEmuToHmm(*m_pImpl->m_oEffectExtentRight) : 0;
1033 m_pImpl->m_nRightMargin += nEffectExtent;
1034 nEffectExtent = (m_pImpl->m_oEffectExtentTop)
1035 ? oox::drawingml::convertEmuToHmm(*m_pImpl->m_oEffectExtentTop) : 0;
1036 m_pImpl->m_nTopMargin += nEffectExtent;
1037 nEffectExtent = (m_pImpl->m_oEffectExtentBottom)
1038 ? oox::drawingml::convertEmuToHmm(*m_pImpl->m_oEffectExtentBottom) : 0;
1039 m_pImpl->m_nBottomMargin += nEffectExtent;
1040 }
1041 else
1042 {
1043 // As of June 2021 LibreOffice uses an area, which is large enough to
1044 // contain the rotated snap rectangle. MSO uses a smaller area, so
1045 // that the rotated snap rectangle covers text.
1046 awt::Point aMSOBaseLeftTop = aImportPosition;
1047 awt::Size aMSOBaseSize = aImportSize;
1048 lcl_doMSOWidthHeightSwap(aMSOBaseLeftTop, aMSOBaseSize, nOOXAngle);
1049 lcl_expandRectangleByEffectExtent(aMSOBaseLeftTop, aMSOBaseSize);
1050
1051 // Get LO SnapRect from SdrObject if possible
1052 awt::Rectangle aLOSnapRect;
1053 // For case we have no SdrObject, initialize with values from m_pImpl
1054 aLOSnapRect.X = m_pImpl->m_nLeftPosition;
1055 aLOSnapRect.Y = m_pImpl->m_nTopPosition;
1056 aLOSnapRect.Width = aLOSize.Width;
1057 aLOSnapRect.Height = aLOSize.Height;
1058 if (pShape)
1059 {
1060 tools::Rectangle aSnapRect = pShape->GetSnapRect(); // Twip
1061 aLOSnapRect.X = ConversionHelper::convertTwipToMM100(aSnapRect.Left());
1062 aLOSnapRect.Y = ConversionHelper::convertTwipToMM100(aSnapRect.Top());
1063 aLOSnapRect.Width = ConversionHelper::convertTwipToMM100(aSnapRect.getOpenWidth());
1064 aLOSnapRect.Height = ConversionHelper::convertTwipToMM100(aSnapRect.getOpenHeight());
1065 }
1066
1067 m_pImpl->m_nLeftMargin += aLOSnapRect.X - aMSOBaseLeftTop.X;
1068 m_pImpl->m_nRightMargin += aMSOBaseLeftTop.X + aMSOBaseSize.Width
1069 - (aLOSnapRect.X + aLOSnapRect.Width);
1070 m_pImpl->m_nTopMargin += aLOSnapRect.Y - aMSOBaseLeftTop.Y;
1071 m_pImpl->m_nBottomMargin += aMSOBaseLeftTop.Y + aMSOBaseSize.Height
1072 - (aLOSnapRect.Y + aLOSnapRect.Height);
1073 // tdf#141880 LibreOffice cannot handle negative vertical margins.
1074 // Those cases are caught below at common place.
1075 }
1076 } // end IMPORT_AS_DETECTED_INLINE
1077 else if ((m_pImpl->m_nWrap == text::WrapTextMode_PARALLEL
1078 || m_pImpl->m_nWrap == text::WrapTextMode_DYNAMIC
1079 || m_pImpl->m_nWrap == text::WrapTextMode_LEFT
1080 || m_pImpl->m_nWrap == text::WrapTextMode_RIGHT
1081 || m_pImpl->m_nWrap == text::WrapTextMode_NONE)
1082 && !(m_pImpl->mpWrapPolygon) && !bIsDiagram)
1083 {
1084 // For wrap "Square" an area is defined around which the text wraps. MSO
1085 // describes the area by a base rectangle and effectExtent. LO uses the
1086 // shape bounding box and margins. We adapt the margins to get the same
1087 // area as MSO.
1088 awt::Point aMSOBaseLeftTop = aImportPosition;
1089 awt::Size aMSOBaseSize = aImportSize;
1090 lcl_doMSOWidthHeightSwap(aMSOBaseLeftTop, aMSOBaseSize, nOOXAngle);
1091 lcl_expandRectangleByEffectExtent(aMSOBaseLeftTop, aMSOBaseSize);
1092
1093 // Get LO bound rectangle from SdrObject if possible
1094 awt::Rectangle aLOBoundRect;
1095 // For case we have no SdrObject, initialize with values from m_pImpl
1096 aLOBoundRect.X = m_pImpl->m_nLeftPosition;
1097 aLOBoundRect.Y = m_pImpl->m_nTopPosition;
1098 aLOBoundRect.Width = aLOSize.Width;
1099 aLOBoundRect.Height = aLOSize.Height;
1100 if (pShape)
1101 {
1102 tools::Rectangle aBoundRect = pShape->GetCurrentBoundRect(); // Twip
1103 aLOBoundRect.X = ConversionHelper::convertTwipToMM100(aBoundRect.Left());
1104 aLOBoundRect.Y = ConversionHelper::convertTwipToMM100(aBoundRect.Top());
1105 aLOBoundRect.Width = ConversionHelper::convertTwipToMM100(aBoundRect.getOpenWidth());
1106 aLOBoundRect.Height = ConversionHelper::convertTwipToMM100(aBoundRect.getOpenHeight());
1107 }
1108
1109 m_pImpl->m_nLeftMargin += aLOBoundRect.X - aMSOBaseLeftTop.X;
1110 m_pImpl->m_nRightMargin += aMSOBaseLeftTop.X + aMSOBaseSize.Width
1111 - (aLOBoundRect.X + aLOBoundRect.Width);
1112 m_pImpl->m_nTopMargin += aLOBoundRect.Y - aMSOBaseLeftTop.Y;
1113 m_pImpl->m_nBottomMargin += aMSOBaseLeftTop.Y + aMSOBaseSize.Height
1114 - (aLOBoundRect.Y + aLOBoundRect.Height);
1115 }
1116 else if (m_pImpl->mpWrapPolygon && !bIsDiagram)
1117 {
1118 // Word uses a wrap polygon, LibreOffice has no explicit wrap polygon
1119 // but creates the wrap contour based on the shape geometry, without
1120 // stroke width and shadow, but with rotation and flip. The concepts
1121 // are not compatible. We approximate Word's rendering by setting
1122 // wrap margins.
1123
1124 // Build a range from the wrap polygon from Word.
1125 const drawing::PointSequenceSequence aWrapPolygon
1126 = m_pImpl->mpWrapPolygon->getPointSequenceSequence();
1127 basegfx::B2DPolyPolygon aB2DWrapPolyPolygon
1129 aWrapPolygon);
1130 // Wrap polygon values are relative to 0..21600|0..21600.
1131 // Scale to shape size (in Hmm).
1133 aImportSize.Width / 21600.0, aImportSize.Height / 21600.0);
1134 aB2DWrapPolyPolygon.transform(aMatrix);
1135
1136 // Shape geometry will be rotated, rotate wrap polygon too.
1137 if (nOOXAngle != 0)
1138 {
1140 aImportSize.Width / 2.0, aImportSize.Height / 2.0,
1141 basegfx::deg2rad<60000>(nOOXAngle));
1142 aB2DWrapPolyPolygon.transform(aMatrix);
1143 }
1144 basegfx::B2DRange aB2DWrapRange = aB2DWrapPolyPolygon.getB2DRange();
1145
1146 // Build a range from shape geometry
1147 basegfx::B2DRange aShapeRange;
1148 if (pShape)
1149 {
1150 basegfx::B2DPolyPolygon aShapePolygon = pShape->TakeXorPoly(); // Twips
1154 aShapePolygon.transform(aMatrix);
1155 // Wrap polygon treats left/top of shape as origin, shift shape polygon accordingly
1157 -aImportPosition.X, -aImportPosition.Y);
1158 aShapePolygon.transform(aMatrix);
1159 aShapeRange = aShapePolygon.getB2DRange();
1160 }
1161 else // can this happen?
1162 {
1163 aShapeRange
1164 = basegfx::B2DRange(0, 0, aImportSize.Width, aImportSize.Height);
1165 if (nOOXAngle != 0)
1166 {
1168 basegfx::deg2rad<60000>(nOOXAngle));
1169 aShapeRange.transform(aMatrix);
1170 }
1171 }
1172
1173 // Add difference between shape and wrap range to margin and remember
1174 // difference in Twips for export.
1175 comphelper::SequenceAsHashMap aAnchorDistDiff;
1176
1177 const double fTopDiff = aShapeRange.getMinY() - aB2DWrapRange.getMinY();
1178 m_pImpl->m_nTopMargin += basegfx::fround(fTopDiff);
1179 aAnchorDistDiff["distTDiff"] <<= basegfx::fround(
1181
1182 const double fBottomDiff = aB2DWrapRange.getMaxY() - aShapeRange.getMaxY();
1183 m_pImpl->m_nBottomMargin += basegfx::fround(fBottomDiff);
1184 aAnchorDistDiff["distBDiff"] <<= basegfx::fround(
1186
1187 const double fLeftDiff = aShapeRange.getMinX() - aB2DWrapRange.getMinX();
1188 m_pImpl->m_nLeftMargin += basegfx::fround(fLeftDiff);
1189 aAnchorDistDiff["distLDiff"] <<= basegfx::fround(
1191
1192 const double fRightDiff = aB2DWrapRange.getMaxX() - aShapeRange.getMaxX();
1193 m_pImpl->m_nRightMargin += basegfx::fround(fRightDiff);
1194 aAnchorDistDiff["distRDiff"] <<= basegfx::fround(
1196
1197 m_pImpl->m_aInteropGrabBag["AnchorDistDiff"]
1198 <<= aAnchorDistDiff.getAsConstPropertyValueList();
1199
1200 // FixMe: tdf#141880. LibreOffice cannot handle negative horizontal margin in contour wrap
1201 if (m_pImpl->m_nLeftMargin < 0)
1202 m_pImpl->m_nLeftMargin = 0;
1203 if (m_pImpl->m_nRightMargin < 0)
1204 m_pImpl->m_nRightMargin = 0;
1205 }
1206 else if (!bIsDiagram) // text::WrapTextMode_THROUGH
1207 {
1208 // Word writes and evaluates the effectExtent in case of position
1209 // type 'Alignment' (UI). We move these values to margin to approximate
1210 // Word's rendering.
1211 if (m_pImpl->m_oEffectExtentLeft)
1212 {
1213 m_pImpl->m_nLeftMargin
1214 += oox::drawingml::convertEmuToHmm(*m_pImpl->m_oEffectExtentLeft);
1215 }
1216 if (m_pImpl->m_oEffectExtentTop)
1217 {
1218 m_pImpl->m_nTopMargin
1219 += oox::drawingml::convertEmuToHmm(*m_pImpl->m_oEffectExtentTop);
1220 }
1221 if (m_pImpl->m_oEffectExtentRight)
1222 {
1223 m_pImpl->m_nRightMargin
1224 += oox::drawingml::convertEmuToHmm(*m_pImpl->m_oEffectExtentRight);
1225 }
1226 if (m_pImpl->m_oEffectExtentBottom)
1227 {
1228 m_pImpl->m_nBottomMargin
1229 += oox::drawingml::convertEmuToHmm(*m_pImpl->m_oEffectExtentBottom);
1230 }
1231 }
1232
1233 // FixMe: tdf#141880 LibreOffice cannot handle negative vertical margins
1234 // although they are allowed in ODF.
1235 if (m_pImpl->m_nTopMargin < 0)
1236 m_pImpl->m_nTopMargin = 0;
1237 if (m_pImpl->m_nBottomMargin < 0)
1238 m_pImpl->m_nBottomMargin = 0;
1239 }
1240
1241 if (bUseShape && m_pImpl->m_rGraphicImportType == IMPORT_AS_DETECTED_ANCHOR)
1242 {
1243 // If we are here, this is a drawingML shape. For those, only dmapper (and not oox) knows the anchoring infos (just like for Writer pictures).
1244 // But they aren't Writer pictures, either (which are already handled above).
1245 uno::Reference< beans::XPropertySet > xShapeProps(m_xShape, uno::UNO_QUERY_THROW);
1246
1247 if (m_pImpl->m_nWrap == text::WrapTextMode_THROUGH && m_pImpl->m_nHoriRelation == text::RelOrientation::FRAME)
1248 {
1249 // text::RelOrientation::FRAME is OOXML's "column", which behaves as if
1250 // layout-in-cell would be always off.
1251 m_pImpl->m_bLayoutInCell = false;
1252 }
1253
1254 // Anchored: Word only supports at-char in that case.
1255 text::TextContentAnchorType eAnchorType = text::TextContentAnchorType_AT_CHARACTER;
1256
1257 if (m_pImpl->m_bHidden)
1258 {
1259 xShapeProps->setPropertyValue("Visible", uno::Any(false));
1260 xShapeProps->setPropertyValue("Printable", uno::Any(false));
1261 }
1262
1263 // Avoid setting AnchorType for TextBoxes till SwTextBoxHelper::syncProperty() doesn't handle transition.
1264 bool bTextBox = false;
1265 xShapeProps->getPropertyValue("TextBox") >>= bTextBox;
1266
1267 // The positioning change caused by LayoutInCell doesn't sync well
1268 // in the text / frame duo. So the compatibility fix only correctly
1269 // positions the frame and not the text currently.
1270 // tdf#135943: Instead of half-fixing and making a complete mess,
1271 // just avoid until layout's repositioning is sync'd to the text frame.
1272 if (m_pImpl->m_bLayoutInCell && bTextBox)
1273 m_pImpl->m_bLayoutInCell = !m_pImpl->m_bCompatForcedLayoutInCell;
1274
1275 xShapeProps->setPropertyValue("AnchorType", uno::Any(eAnchorType));
1276
1277 if (m_pImpl->m_nVertRelation == text::RelOrientation::TEXT_LINE)
1278 {
1279 // Word's "line" is "below the bottom of the line", our TEXT_LINE is
1280 // "towards top, from the bottom of the line", so invert the vertical
1281 // position.
1282 awt::Point aPoint = xShape->getPosition();
1283 aPoint.Y *= -1;
1284 xShape->setPosition(aPoint);
1285 }
1286
1287 if (m_pImpl->m_bLayoutInCell && bTextBox && m_pImpl->m_rDomainMapper.IsInTable()
1288 && m_pImpl->m_nHoriRelation == text::RelOrientation::PAGE_FRAME)
1289 m_pImpl->m_nHoriRelation = text::RelOrientation::FRAME;
1290 if(m_pImpl->m_rDomainMapper.IsInTable())
1291 xShapeProps->setPropertyValue(getPropertyName(PROP_FOLLOW_TEXT_FLOW),
1292 uno::Any(m_pImpl->m_bLayoutInCell));
1293 //only the position orientation is handled in applyPosition()
1294 m_pImpl->applyPosition(xShapeProps);
1295
1296 uno::Reference<lang::XServiceInfo> xServiceInfo(m_xShape, uno::UNO_QUERY_THROW);
1297 if (xServiceInfo->supportsService("com.sun.star.drawing.GroupShape") ||
1298 xServiceInfo->supportsService("com.sun.star.drawing.GraphicObjectShape"))
1299 {
1300 // You would expect that position and rotation are
1301 // independent, but they are not. Till we are not
1302 // there yet to handle all scaling, translation and
1303 // rotation with a single transformation matrix,
1304 // make sure there is no graphic rotation set when we set
1305 // the position.
1306 sal_Int32 nRotation = 0;
1307 if (xServiceInfo->supportsService("com.sun.star.drawing.GraphicObjectShape"))
1308 {
1309 xShapeProps->getPropertyValue("RotateAngle") >>= nRotation;
1310 }
1311 if (nRotation)
1312 xShapeProps->setPropertyValue("RotateAngle", uno::Any(sal_Int32(0)));
1313
1314 // Position of the groupshape should be set after children have been added.
1315 // Long-term we should get rid of positioning group
1316 // shapes, though. Do it for top-level ones with
1317 // absolute page position as a start.
1318 // fdo#80555: also set position for graphic shapes here
1319 if (!isTopGroupObj(m_xShape)
1320 || m_pImpl->m_nHoriRelation != text::RelOrientation::PAGE_FRAME
1321 || m_pImpl->m_nVertRelation != text::RelOrientation::PAGE_FRAME)
1322 m_xShape->setPosition(
1323 awt::Point(m_pImpl->m_nLeftPosition, m_pImpl->m_nTopPosition));
1324
1325 if (nRotation)
1326 xShapeProps->setPropertyValue("RotateAngle", uno::Any(nRotation));
1327 }
1328
1329
1330 m_pImpl->applyRelativePosition(xShapeProps, /*bRelativeOnly=*/true);
1331
1332 xShapeProps->setPropertyValue("SurroundContour", uno::Any(m_pImpl->m_bContour));
1333 xShapeProps->setPropertyValue("ContourOutside", uno::Any(m_pImpl->m_bContourOutside));
1334 m_pImpl->applyMargins(xShapeProps);
1335 xShapeProps->setPropertyValue("Opaque", uno::Any(m_pImpl->m_bOpaque));
1336 xShapeProps->setPropertyValue("Surround", uno::Any(static_cast<sal_Int32>(m_pImpl->m_nWrap)));
1337 m_pImpl->applyZOrder(xShapeProps);
1338 m_pImpl->applyName(xShapeProps);
1339 m_pImpl->applyHyperlink(xShapeProps, bUseShape);
1340 xShapeProps->setPropertyValue("AllowOverlap",
1341 uno::Any(m_pImpl->m_bAllowOverlap));
1342
1343 // Get the grab-bag set by oox, merge with our one and then put it back.
1344 comphelper::SequenceAsHashMap aInteropGrabBag(xShapeProps->getPropertyValue("InteropGrabBag"));
1345 aInteropGrabBag.update(m_pImpl->getInteropGrabBag());
1346 xShapeProps->setPropertyValue("InteropGrabBag", uno::Any(aInteropGrabBag.getAsConstPropertyValueList()));
1347 }
1348 else if (bUseShape && m_pImpl->m_rGraphicImportType == IMPORT_AS_DETECTED_INLINE)
1349 {
1350 uno::Reference< beans::XPropertySet > xShapeProps(m_xShape, uno::UNO_QUERY_THROW);
1351 m_pImpl->applyMargins(xShapeProps);
1352 m_pImpl->applyZOrder(xShapeProps);
1353 m_pImpl->applyName(xShapeProps);
1354 comphelper::SequenceAsHashMap aInteropGrabBag(xShapeProps->getPropertyValue("InteropGrabBag"));
1355 aInteropGrabBag.update(m_pImpl->getInteropGrabBag());
1356 xShapeProps->setPropertyValue("InteropGrabBag", uno::Any(aInteropGrabBag.getAsConstPropertyValueList()));
1357 }
1358 }
1359 }
1360 break;
1361 case NS_ooxml::LN_CT_Inline_distT:
1362 m_pImpl->m_nTopMargin = 0;
1363 break;
1364 case NS_ooxml::LN_CT_Inline_distB:
1365 m_pImpl->m_nBottomMargin = 0;
1366 break;
1367 case NS_ooxml::LN_CT_Inline_distL:
1368 m_pImpl->m_nLeftMargin = 0;
1369 break;
1370 case NS_ooxml::LN_CT_Inline_distR:
1371 m_pImpl->m_nRightMargin = 0;
1372 break;
1373 case NS_ooxml::LN_CT_GraphicalObjectData_uri:
1374 rValue.getString();
1375 //TODO: does it need to be handled?
1376 break;
1377 case NS_ooxml::LN_CT_SizeRelH_relativeFrom:
1378 {
1379 switch (nIntValue)
1380 {
1381 case NS_ooxml::LN_ST_SizeRelFromH_margin:
1382 if (m_xShape.is())
1383 {
1384 uno::Reference<beans::XPropertySet> xPropertySet(m_xShape, uno::UNO_QUERY);
1385 xPropertySet->setPropertyValue("RelativeWidthRelation", uno::Any(text::RelOrientation::FRAME));
1386 }
1387 break;
1388 case NS_ooxml::LN_ST_SizeRelFromH_leftMargin:
1389 case NS_ooxml::LN_ST_SizeRelFromH_outsideMargin:
1390 if (m_xShape.is())
1391 {
1392 // Here we handle the relative size of the width of some shape.
1393 // The size of the shape's width is going to be relative to the size of the left margin.
1394 // E.g.: (left margin = 8 && relative size = 150%) -> width of some shape = 12.
1395 uno::Reference<beans::XPropertySet> xPropertySet(m_xShape, uno::UNO_QUERY);
1396 xPropertySet->setPropertyValue("RelativeWidthRelation", uno::Any(text::RelOrientation::PAGE_LEFT));
1397 }
1398 break;
1399 case NS_ooxml::LN_ST_SizeRelFromH_rightMargin:
1400 case NS_ooxml::LN_ST_SizeRelFromH_insideMargin:
1401 if (m_xShape.is())
1402 {
1403 // Same as the left margin above.
1404 uno::Reference<beans::XPropertySet> xPropertySet(m_xShape, uno::UNO_QUERY);
1405 xPropertySet->setPropertyValue("RelativeWidthRelation", uno::Any(text::RelOrientation::PAGE_RIGHT));
1406 }
1407 break;
1408 case NS_ooxml::LN_ST_SizeRelFromH_page:
1409 if (m_xShape.is())
1410 {
1411 uno::Reference<beans::XPropertySet> xPropertySet(m_xShape, uno::UNO_QUERY);
1412 xPropertySet->setPropertyValue("RelativeWidthRelation", uno::Any(text::RelOrientation::PAGE_FRAME));
1413 }
1414 break;
1415 default:
1416 SAL_WARN("writerfilter", "GraphicImport::lcl_attribute: unhandled NS_ooxml::LN_CT_SizeRelH_relativeFrom value: " << nIntValue);
1417 break;
1418 }
1419 }
1420 break;
1421 case NS_ooxml::LN_CT_SizeRelV_relativeFrom:
1422 {
1423 switch (nIntValue)
1424 {
1425 case NS_ooxml::LN_ST_SizeRelFromV_margin:
1426 if (m_xShape.is())
1427 {
1428 uno::Reference<beans::XPropertySet> xPropertySet(m_xShape, uno::UNO_QUERY);
1429 xPropertySet->setPropertyValue("RelativeHeightRelation", uno::Any(text::RelOrientation::FRAME));
1430 }
1431 break;
1432 case NS_ooxml::LN_ST_SizeRelFromV_page:
1433 if (m_xShape.is())
1434 {
1435 uno::Reference<beans::XPropertySet> xPropertySet(m_xShape, uno::UNO_QUERY);
1436 xPropertySet->setPropertyValue("RelativeHeightRelation", uno::Any(text::RelOrientation::PAGE_FRAME));
1437 }
1438 break;
1439 case NS_ooxml::LN_ST_SizeRelFromV_topMargin:
1440 if (m_xShape.is())
1441 {
1442 uno::Reference<beans::XPropertySet> xPropertySet(m_xShape, uno::UNO_QUERY);
1443 xPropertySet->setPropertyValue("RelativeHeightRelation", uno::Any(text::RelOrientation::PAGE_PRINT_AREA));
1444 }
1445 break;
1446 case NS_ooxml::LN_ST_SizeRelFromV_bottomMargin:
1447 if (m_xShape.is())
1448 {
1449 uno::Reference<beans::XPropertySet> xPropertySet(m_xShape, uno::UNO_QUERY);
1450 xPropertySet->setPropertyValue("RelativeHeightRelation", uno::Any(text::RelOrientation::PAGE_PRINT_AREA_BOTTOM));
1451 }
1452 break;
1453 default:
1454 SAL_WARN("writerfilter", "GraphicImport::lcl_attribute: unhandled NS_ooxml::LN_CT_SizeRelV_relativeFrom value: " << nIntValue);
1455 break;
1456 }
1457 }
1458 break;
1459 default:
1460#ifdef DBG_UTIL
1461 TagLogger::getInstance().element("unhandled");
1462#endif
1463 break;
1464 }
1465}
1466
1468{
1470
1471 if (m_xGraphicObject.is())
1472 xResult = m_xGraphicObject;
1473 else if (m_xShape.is())
1474 {
1475 xResult.set(m_xShape, uno::UNO_QUERY_THROW);
1476 }
1477
1478 return xResult;
1479}
1480
1481
1483{
1484 sal_Int32 nIntValue = rValue.getInt();
1485 switch( m_pImpl->m_nShapeOptionType )
1486 {
1487 case NS_ooxml::LN_CT_Anchor_distL:
1488 m_pImpl->m_nLeftMargin = nIntValue / 360;
1489 m_pImpl->m_nLeftMarginOrig = m_pImpl->m_nLeftMargin;
1490 break;
1491 case NS_ooxml::LN_CT_Anchor_distT:
1492 //todo: changes have to be applied depending on the orientation, see SwWW8ImplReader::AdjustULWrapForWordMargins()
1493 m_pImpl->m_nTopMargin = nIntValue / 360;
1494 break;
1495 case NS_ooxml::LN_CT_Anchor_distR:
1496 //todo: changes have to be applied depending on the orientation, see SwWW8ImplReader::AdjustLRWrapForWordMargins()
1497 m_pImpl->m_nRightMargin = nIntValue / 360;
1498 break;
1499 case NS_ooxml::LN_CT_Anchor_distB:
1500 //todo: changes have to be applied depending on the orientation, see SwWW8ImplReader::AdjustULWrapForWordMargins()
1501 m_pImpl->m_nBottomMargin = nIntValue / 360;
1502 break;
1503 default:
1504 OSL_FAIL( "shape option unsupported?");
1505 }
1506}
1507
1508
1510{
1511 sal_uInt32 nSprmId = rSprm.getId();
1512
1513 switch(nSprmId)
1514 {
1515 case NS_ooxml::LN_CT_Inline_extent: // 90911;
1516 case NS_ooxml::LN_CT_Inline_effectExtent: // 90912;
1517 case NS_ooxml::LN_CT_Inline_docPr: // 90913;
1518 case NS_ooxml::LN_CT_Inline_cNvGraphicFramePr: // 90914;
1519 case NS_ooxml::LN_CT_NonVisualGraphicFrameProperties_graphicFrameLocks:// 90657
1520 case NS_ooxml::LN_CT_Inline_a_graphic:// 90915
1521 case NS_ooxml::LN_CT_Anchor_simplePos_elem: // 90975;
1522 case NS_ooxml::LN_CT_Anchor_extent: // 90978;
1523 case NS_ooxml::LN_CT_Anchor_effectExtent: // 90979;
1524 case NS_ooxml::LN_EG_WrapType_wrapSquare: // 90945;
1525 case NS_ooxml::LN_EG_WrapType_wrapTight: // 90946;
1526 case NS_ooxml::LN_EG_WrapType_wrapThrough:
1527 case NS_ooxml::LN_CT_Anchor_docPr: // 90980;
1528 case NS_ooxml::LN_CT_NonVisualDrawingProps_extLst:
1529 case NS_ooxml::LN_CT_Anchor_cNvGraphicFramePr: // 90981;
1530 case NS_ooxml::LN_CT_Anchor_a_graphic: // 90982;
1531 case NS_ooxml::LN_CT_WrapPath_start: // 90924;
1532 case NS_ooxml::LN_CT_WrapPath_lineTo: // 90925;
1533 case NS_ooxml::LN_graphic_graphic:
1534 case NS_ooxml::LN_pic_pic:
1535 case NS_ooxml::LN_dgm_relIds:
1536 case NS_ooxml::LN_lc_lockedCanvas:
1537 case NS_ooxml::LN_c_chart:
1538 case NS_ooxml::LN_wps_wsp:
1539 case NS_ooxml::LN_wpg_wgp:
1540 case NS_ooxml::LN_sizeRelH_sizeRelH:
1541 case NS_ooxml::LN_sizeRelV_sizeRelV:
1542 case NS_ooxml::LN_hlinkClick_hlinkClick:
1543 {
1545 if( pProperties )
1546 {
1547 pProperties->resolve(*this);
1548 }
1549
1550 // We'll map these to PARALLEL, save the original wrap type.
1551 if (nSprmId == NS_ooxml::LN_EG_WrapType_wrapTight)
1552 m_pImpl->m_aInteropGrabBag["EG_WrapType"] <<= OUString("wrapTight");
1553 else if (nSprmId == NS_ooxml::LN_EG_WrapType_wrapThrough)
1554 m_pImpl->m_aInteropGrabBag["EG_WrapType"] <<= OUString("wrapThrough");
1555
1556 switch (nSprmId)
1557 {
1558 case NS_ooxml::LN_EG_WrapType_wrapSquare:
1559 case NS_ooxml::LN_EG_WrapType_wrapThrough:
1560 case NS_ooxml::LN_EG_WrapType_wrapTight:
1561 {
1562 // tdf#137850: Word >= 2013 seems to ignore bBehindDoc except for wrapNone, but older versions honour it.
1563 if (m_pImpl->m_bBehindDoc && m_pImpl->m_rDomainMapper.GetSettingsTable()->GetWordCompatibilityMode() > 14)
1564 m_pImpl->m_bOpaque = true;
1565 }
1566 break;
1567 }
1568
1569 }
1570 break;
1571 case NS_ooxml::LN_CT_WrapTight_wrapPolygon:
1572 case NS_ooxml::LN_CT_WrapThrough_wrapPolygon:
1573 {
1574 WrapPolygonHandler aHandler;
1575
1576 resolveSprmProps(aHandler, rSprm);
1577
1578 m_pImpl->mpWrapPolygon = aHandler.getPolygon();
1579
1580 // Save the wrap path in case we can't handle it natively: drawinglayer shapes, TextFrames.
1581 m_pImpl->m_aInteropGrabBag["CT_WrapPath"] <<= m_pImpl->mpWrapPolygon->getPointSequenceSequence();
1582 }
1583 break;
1584 case NS_ooxml::LN_CT_Anchor_positionH: // 90976;
1585 {
1586 // Use a special handler for the positioning
1587 auto pHandler = std::make_shared<PositionHandler>( m_pImpl->m_rPositionOffsets, m_pImpl->m_rAligns );
1589 if( pProperties )
1590 {
1591 pProperties->resolve( *pHandler );
1592 if( !m_pImpl->m_bUseSimplePos )
1593 {
1594 m_pImpl->m_nHoriRelation = pHandler->relation();
1595 m_pImpl->m_bPageToggle = pHandler->GetPageToggle();
1596 m_pImpl->m_nHoriOrient = pHandler->orientation();
1597 m_pImpl->m_nLeftPosition = pHandler->position();
1598
1599 // Left adjustments: if horizontally aligned to left of margin, then remove the
1600 // left wrapping.
1601 if (m_pImpl->m_nHoriOrient == text::HoriOrientation::LEFT)
1602 {
1603 if (m_pImpl->m_nHoriRelation == text::RelOrientation::PAGE_PRINT_AREA)
1604 {
1605 m_pImpl->m_nLeftMargin = 0;
1606 }
1607 }
1608 }
1609 }
1610 }
1611 break;
1612 case NS_ooxml::LN_CT_Anchor_positionV: // 90977;
1613 {
1614 // Use a special handler for the positioning
1615 auto pHandler = std::make_shared<PositionHandler>( m_pImpl->m_rPositionOffsets, m_pImpl->m_rAligns);
1617 if( pProperties )
1618 {
1619 pProperties->resolve( *pHandler );
1620 if( !m_pImpl->m_bUseSimplePos )
1621 {
1622 m_pImpl->m_nVertRelation = pHandler->relation();
1623 m_pImpl->m_nVertOrient = pHandler->orientation();
1624 m_pImpl->m_nTopPosition = pHandler->position();
1625 }
1626 }
1627 }
1628 break;
1629 case NS_ooxml::LN_CT_SizeRelH_pctWidth:
1630 case NS_ooxml::LN_CT_SizeRelV_pctHeight:
1631 if (m_pImpl->m_rPositivePercentages.empty())
1632 break;
1633
1634 if (m_xShape.is())
1635 {
1636 sal_Int16 nPositivePercentage = rtl::math::round(m_pImpl->m_rPositivePercentages.front().toDouble() / oox::drawingml::PER_PERCENT);
1637
1638 if (nPositivePercentage)
1639 {
1640 uno::Reference<beans::XPropertySet> xPropertySet(m_xShape, uno::UNO_QUERY);
1641 OUString aProperty = nSprmId == NS_ooxml::LN_CT_SizeRelH_pctWidth ? OUString("RelativeWidth") : OUString("RelativeHeight");
1642
1643 sal_Int32 nTextPreRotateAngle = 0;
1644 uno::Any aAny;
1645 if (xPropertySet->getPropertySetInfo()->hasPropertyByName(
1646 "CustomShapeGeometry"))
1647 {
1648 aAny = xPropertySet->getPropertyValue("CustomShapeGeometry");
1649 }
1650 comphelper::SequenceAsHashMap aCustomShapeGeometry(aAny);
1651 auto it = aCustomShapeGeometry.find("TextPreRotateAngle");
1652 if (it != aCustomShapeGeometry.end())
1653 {
1654 nTextPreRotateAngle = it->second.get<sal_Int32>();
1655 }
1656 if (nTextPreRotateAngle == 0)
1657 {
1658 xPropertySet->setPropertyValue(aProperty,
1659 uno::Any(nPositivePercentage));
1660 }
1661 }
1662 }
1663
1664 // Make sure the token is consumed even if xShape is an empty
1665 // reference.
1666 m_pImpl->m_rPositivePercentages.pop();
1667 break;
1668 case NS_ooxml::LN_EG_WrapType_wrapNone: // 90944; - doesn't contain attributes
1669 //depending on the behindDoc attribute text wraps through behind or in front of the object
1670 m_pImpl->m_nWrap = text::WrapTextMode_THROUGH;
1671
1672 // Wrap though means the margins defined earlier should not be
1673 // respected.
1674 m_pImpl->m_nLeftMargin = 0;
1675 m_pImpl->m_nTopMargin = 0;
1676 m_pImpl->m_nRightMargin = 0;
1677 m_pImpl->m_nBottomMargin = 0;
1678 break;
1679 case NS_ooxml::LN_EG_WrapType_wrapTopAndBottom: // 90948;
1680 // tdf#137850: Word >= 2013 seems to ignore bBehindDoc except for wrapNone, but older versions honour it.
1681 if (m_pImpl->m_bBehindDoc && m_pImpl->m_rDomainMapper.GetSettingsTable()->GetWordCompatibilityMode() > 14)
1682 m_pImpl->m_bOpaque = true;
1683 m_pImpl->m_nWrap = text::WrapTextMode_NONE;
1684 break;
1685 case NS_ooxml::LN_CT_GraphicalObject_graphicData:// 90660;
1686 {
1687 m_pImpl->m_bIsGraphic = true;
1688
1690 if( pProperties )
1691 pProperties->resolve(*this);
1692 }
1693 break;
1694 case NS_ooxml::LN_CT_NonVisualDrawingProps_a_hlinkClick: // 90689;
1695 {
1697 if( pProperties )
1698 pProperties->resolve( *this );
1699 }
1700 break;
1701 default:
1702 SAL_WARN("writerfilter", "GraphicImport::lcl_sprm: unhandled token: " << nSprmId);
1703 break;
1704 }
1705}
1706
1707void GraphicImport::lcl_entry(writerfilter::Reference<Properties>::Pointer_t /*ref*/)
1708{
1709}
1710
1711uno::Reference<text::XTextContent> GraphicImport::createGraphicObject(uno::Reference<graphic::XGraphic> const & rxGraphic,
1712 uno::Reference<beans::XPropertySet> const & xShapeProps)
1713{
1715 try
1716 {
1717 if (rxGraphic.is())
1718 {
1719 uno::Reference< beans::XPropertySet > xGraphicObjectProperties(
1720 m_xTextFactory->createInstance("com.sun.star.text.TextGraphicObject"),
1721 uno::UNO_QUERY_THROW);
1722 xGraphicObjectProperties->setPropertyValue(getPropertyName(PROP_GRAPHIC), uno::Any(rxGraphic));
1723 xGraphicObjectProperties->setPropertyValue(getPropertyName(PROP_ANCHOR_TYPE),
1724 uno::Any( m_pImpl->m_rGraphicImportType == IMPORT_AS_DETECTED_ANCHOR ?
1725 text::TextContentAnchorType_AT_CHARACTER :
1726 text::TextContentAnchorType_AS_CHARACTER ));
1727 xGraphicObject.set( xGraphicObjectProperties, uno::UNO_QUERY_THROW );
1728
1729 //shapes have only one border
1730 table::BorderLine2 aBorderLine;
1731 GraphicBorderLine& rBorderLine = m_pImpl->m_aBorders[0];
1732 if (rBorderLine.isEmpty() && xShapeProps.is() && xShapeProps->getPropertyValue("LineStyle").get<drawing::LineStyle>() != drawing::LineStyle_NONE)
1733 {
1734 // In case we got no border tokens and we have the
1735 // original shape, then use its line properties as the
1736 // border.
1737 aBorderLine.Color = xShapeProps->getPropertyValue("LineColor").get<sal_Int32>();
1738 aBorderLine.LineWidth = xShapeProps->getPropertyValue("LineWidth").get<sal_Int32>();
1739 }
1740 else
1741 {
1742 aBorderLine.Color = 0;
1743 aBorderLine.InnerLineWidth = 0;
1744 aBorderLine.OuterLineWidth = static_cast<sal_Int16>(rBorderLine.nLineWidth);
1745 aBorderLine.LineDistance = 0;
1746 }
1747 PropertyIds const aBorderProps[] =
1748 {
1753 };
1754
1755 for(PropertyIds const & rBorderProp : aBorderProps)
1756 xGraphicObjectProperties->setPropertyValue(getPropertyName(rBorderProp), uno::Any(aBorderLine));
1757
1758 // setting graphic object shadow properties
1759 if (m_pImpl->m_bShadow)
1760 {
1761 // Shadow width is approximated by average of X and Y
1762 table::ShadowFormat aShadow;
1763 sal_uInt32 nShadowColor = m_pImpl->m_nShadowColor & 0x00FFFFFF; // The shadow color we get is RGB only.
1764 sal_Int32 nShadowWidth = (abs(m_pImpl->m_nShadowXDistance)
1765 + abs(m_pImpl->m_nShadowYDistance)) / 2;
1766
1767 aShadow.ShadowWidth = nShadowWidth;
1768 sal_uInt8 nShadowTransparence = float(m_pImpl->m_nShadowTransparence) * 2.55;
1769 nShadowColor |= (nShadowTransparence << 24); // Add transparence to the color.
1770 aShadow.Color = nShadowColor;
1771 // Distances -ve for top and right, +ve for bottom and left
1772 if (m_pImpl->m_nShadowXDistance > 0)
1773 {
1774 if (m_pImpl->m_nShadowYDistance > 0)
1775 aShadow.Location = table::ShadowLocation_BOTTOM_RIGHT;
1776 else
1777 aShadow.Location = table::ShadowLocation_TOP_RIGHT;
1778 }
1779 else
1780 {
1781 if (m_pImpl->m_nShadowYDistance > 0)
1782 aShadow.Location = table::ShadowLocation_BOTTOM_LEFT;
1783 else
1784 aShadow.Location = table::ShadowLocation_TOP_LEFT;
1785 }
1786
1787 xGraphicObjectProperties->setPropertyValue(getPropertyName(PROP_SHADOW_FORMAT), uno::Any(aShadow));
1788 }
1789
1790 // setting properties for all types
1791 if( m_pImpl->m_bPositionProtected )
1792 xGraphicObjectProperties->setPropertyValue(getPropertyName( PROP_POSITION_PROTECTED ),
1793 uno::Any(true));
1794 if( m_pImpl->m_bSizeProtected )
1795 xGraphicObjectProperties->setPropertyValue(getPropertyName( PROP_SIZE_PROTECTED ),
1796 uno::Any(true));
1797
1798 xGraphicObjectProperties->setPropertyValue(getPropertyName(PROP_DECORATIVE), uno::Any(m_pImpl->m_bDecorative));
1799 sal_Int32 nWidth = - m_pImpl->m_nLeftPosition;
1800 if (m_pImpl->m_rGraphicImportType == IMPORT_AS_DETECTED_ANCHOR)
1801 {
1802 //adjust margins
1803 if( (m_pImpl->m_nHoriOrient == text::HoriOrientation::LEFT &&
1804 (m_pImpl->m_nHoriRelation == text::RelOrientation::PAGE_PRINT_AREA ||
1805 m_pImpl->m_nHoriRelation == text::RelOrientation::FRAME) ) ||
1806 (m_pImpl->m_nHoriOrient == text::HoriOrientation::INSIDE &&
1807 m_pImpl->m_nHoriRelation == text::RelOrientation::PAGE_PRINT_AREA ))
1808 m_pImpl->m_nLeftMargin = 0;
1809 if((m_pImpl->m_nHoriOrient == text::HoriOrientation::RIGHT &&
1810 (m_pImpl->m_nHoriRelation == text::RelOrientation::PAGE_PRINT_AREA ||
1811 m_pImpl->m_nHoriRelation == text::RelOrientation::FRAME) ) ||
1812 (m_pImpl->m_nHoriOrient == text::HoriOrientation::INSIDE &&
1813 m_pImpl->m_nHoriRelation == text::RelOrientation::PAGE_PRINT_AREA ))
1814 m_pImpl->m_nRightMargin = 0;
1815 // adjust top/bottom margins
1816 if( m_pImpl->m_nVertOrient == text::VertOrientation::TOP &&
1817 ( m_pImpl->m_nVertRelation == text::RelOrientation::PAGE_PRINT_AREA ||
1818 m_pImpl->m_nVertRelation == text::RelOrientation::PAGE_FRAME))
1819 m_pImpl->m_nTopMargin = 0;
1820 if( m_pImpl->m_nVertOrient == text::VertOrientation::BOTTOM &&
1821 ( m_pImpl->m_nVertRelation == text::RelOrientation::PAGE_PRINT_AREA ||
1822 m_pImpl->m_nVertRelation == text::RelOrientation::PAGE_FRAME))
1823 m_pImpl->m_nBottomMargin = 0;
1824 if( m_pImpl->m_nVertOrient == text::VertOrientation::BOTTOM &&
1825 m_pImpl->m_nVertRelation == text::RelOrientation::PAGE_PRINT_AREA )
1826 m_pImpl->m_nBottomMargin = 0;
1827 //adjust alignment
1828 if( m_pImpl->m_nHoriOrient == text::HoriOrientation::INSIDE &&
1829 m_pImpl->m_nHoriRelation == text::RelOrientation::PAGE_FRAME )
1830 {
1831 // convert 'left to page' to 'from left -<width> to page text area'
1832 m_pImpl->m_nHoriOrient = text::HoriOrientation::NONE;
1833 m_pImpl->m_nHoriRelation = text::RelOrientation::PAGE_PRINT_AREA;
1834 m_pImpl->m_nLeftPosition = - nWidth;
1835 }
1836 else if( m_pImpl->m_nHoriOrient == text::HoriOrientation::OUTSIDE &&
1837 m_pImpl->m_nHoriRelation == text::RelOrientation::PAGE_FRAME )
1838 {
1839 // convert 'right to page' to 'from left 0 to right page border'
1840 m_pImpl->m_nHoriOrient = text::HoriOrientation::NONE;
1841 m_pImpl->m_nHoriRelation = text::RelOrientation::PAGE_RIGHT;
1842 m_pImpl->m_nLeftPosition = 0;
1843 }
1844
1845 m_pImpl->applyPosition(xGraphicObjectProperties);
1846 m_pImpl->applyRelativePosition(xGraphicObjectProperties);
1847 if( !m_pImpl->m_bOpaque )
1848 {
1849 xGraphicObjectProperties->setPropertyValue(getPropertyName( PROP_OPAQUE ), uno::Any(m_pImpl->m_bOpaque));
1850 }
1851 xGraphicObjectProperties->setPropertyValue(getPropertyName( PROP_SURROUND ),
1852 uno::Any(static_cast<sal_Int32>(m_pImpl->m_nWrap)));
1853 if( m_pImpl->m_rDomainMapper.IsInTable())
1854 xGraphicObjectProperties->setPropertyValue(getPropertyName( PROP_FOLLOW_TEXT_FLOW ),
1855 uno::Any(m_pImpl->m_bLayoutInCell));
1856
1857 xGraphicObjectProperties->setPropertyValue(getPropertyName(PROP_ALLOW_OVERLAP),
1858 uno::Any(m_pImpl->m_bAllowOverlap));
1859
1860 xGraphicObjectProperties->setPropertyValue(getPropertyName( PROP_SURROUND_CONTOUR ),
1861 uno::Any(m_pImpl->m_bContour));
1862 xGraphicObjectProperties->setPropertyValue(getPropertyName( PROP_CONTOUR_OUTSIDE ),
1863 uno::Any(m_pImpl->m_bContourOutside));
1864 m_pImpl->applyMargins(xGraphicObjectProperties);
1865 }
1866
1867 xGraphicObjectProperties->setPropertyValue(getPropertyName( PROP_ADJUST_CONTRAST ),
1868 uno::Any(static_cast<sal_Int16>(m_pImpl->m_nContrast)));
1869 xGraphicObjectProperties->setPropertyValue(getPropertyName( PROP_ADJUST_LUMINANCE ),
1870 uno::Any(static_cast<sal_Int16>(m_pImpl->m_nBrightness)));
1871 if(m_pImpl->m_eColorMode != drawing::ColorMode_STANDARD)
1872 {
1873 xGraphicObjectProperties->setPropertyValue(getPropertyName( PROP_GRAPHIC_COLOR_MODE ),
1874 uno::Any(m_pImpl->m_eColorMode));
1875 }
1876
1877 xGraphicObjectProperties->setPropertyValue(getPropertyName( PROP_BACK_COLOR ),
1878 uno::Any( GraphicImport_Impl::nFillColor ));
1879 m_pImpl->applyZOrder(xGraphicObjectProperties);
1880
1881 //there seems to be no way to detect the original size via _real_ API
1882 uno::Reference< beans::XPropertySet > xGraphicProperties(rxGraphic, uno::UNO_QUERY_THROW);
1883
1884 if (m_pImpl->mpWrapPolygon)
1885 {
1886 uno::Any aContourPolyPolygon;
1887 awt::Size aGraphicSize;
1888 WrapPolygon::Pointer_t pCorrected;
1889 xGraphicProperties->getPropertyValue(getPropertyName(PROP_SIZE100th_M_M)) >>= aGraphicSize;
1890 if (aGraphicSize.Width && aGraphicSize.Height)
1891 {
1892 pCorrected = m_pImpl->mpWrapPolygon->correctWordWrapPolygon(aGraphicSize);
1893 }
1894 else
1895 {
1896 xGraphicProperties->getPropertyValue(getPropertyName(PROP_SIZE_PIXEL)) >>= aGraphicSize;
1897 if (aGraphicSize.Width && aGraphicSize.Height)
1898 {
1899 pCorrected = m_pImpl->mpWrapPolygon->correctWordWrapPolygonPixel(aGraphicSize);
1900 }
1901 }
1902
1903 text::GraphicCrop aGraphicCrop;
1904 xShapeProps->getPropertyValue("GraphicCrop") >>= aGraphicCrop;
1905 if (aGraphicCrop.Top != 0 || aGraphicCrop.Bottom != 0 || aGraphicCrop.Left != 0
1906 || aGraphicCrop.Right != 0)
1907 {
1908 // Word's wrap polygon deals with a canvas which has the size of the already
1909 // cropped graphic, correct our polygon to have the same render result.
1910 pCorrected = pCorrected->correctCrop(aGraphicSize, aGraphicCrop);
1911 }
1912
1913 if (pCorrected)
1914 {
1915 aContourPolyPolygon <<= pCorrected->getPointSequenceSequence();
1916 xGraphicObjectProperties->setPropertyValue(getPropertyName(PROP_CONTOUR_POLY_POLYGON),
1917 aContourPolyPolygon);
1918 // We should bring it to front, even if wp:anchor's behindDoc="1",
1919 // because otherwise paragraph background (if set) overlaps the graphic
1920 // TODO: if paragraph's background becomes bottommost, then remove this hack
1921 xGraphicObjectProperties->setPropertyValue("Opaque", uno::Any(true));
1922 }
1923 }
1924
1925
1926 if (m_pImpl->m_rGraphicImportType == IMPORT_AS_DETECTED_INLINE
1927 || m_pImpl->m_rGraphicImportType == IMPORT_AS_DETECTED_ANCHOR)
1928 {
1929 if( m_pImpl->getXSize() && m_pImpl->getYSize() )
1930 xGraphicObjectProperties->setPropertyValue(getPropertyName(PROP_SIZE),
1931 uno::Any( awt::Size( m_pImpl->getXSize(), m_pImpl->getYSize() )));
1932 m_pImpl->applyMargins(xGraphicObjectProperties);
1933 m_pImpl->applyName(xGraphicObjectProperties);
1934 m_pImpl->applyHyperlink(xGraphicObjectProperties, false);
1935 }
1936
1937 // Handle horizontal flip.
1938 bool bMirrored = false;
1939 xShapeProps->getPropertyValue("IsMirrored") >>= bMirrored;
1940 if (bMirrored)
1941 {
1942 xGraphicObjectProperties->setPropertyValue("HoriMirroredOnEvenPages",
1943 uno::Any(true));
1944 xGraphicObjectProperties->setPropertyValue("HoriMirroredOnOddPages",
1945 uno::Any(true));
1946 }
1947 }
1948 }
1949 catch( const uno::Exception& )
1950 {
1951 TOOLS_WARN_EXCEPTION("writerfilter", "");
1952 }
1953 return xGraphicObject;
1954}
1955
1956
1957void GraphicImport::data(const sal_uInt8* buf, size_t len)
1958{
1959 uno::Reference< io::XInputStream > xIStream = new XInputStreamHelper( buf, len );
1960 beans::PropertyValues aMediaProperties{ comphelper::makePropertyValue(
1961 getPropertyName(PROP_INPUT_STREAM), xIStream) };
1962
1964 uno::Reference<graphic::XGraphicProvider> xGraphicProvider(graphic::GraphicProvider::create(m_xComponentContext));
1965 uno::Reference<graphic::XGraphic> xGraphic = xGraphicProvider->queryGraphic(aMediaProperties);
1966 m_xGraphicObject = createGraphicObject(xGraphic, xPropertySet);
1967}
1968
1969
1970void GraphicImport::lcl_startSectionGroup()
1971{
1972}
1973
1974
1975void GraphicImport::lcl_endSectionGroup()
1976{
1977}
1978
1979
1980void GraphicImport::lcl_startParagraphGroup()
1981{
1982}
1983
1984
1985void GraphicImport::lcl_endParagraphGroup()
1986{
1987}
1988
1989
1990void GraphicImport::lcl_startCharacterGroup()
1991{
1992}
1993
1994
1995void GraphicImport::lcl_endCharacterGroup()
1996{
1997}
1998
1999
2000void GraphicImport::lcl_text(const sal_uInt8 * /*_data*/, size_t /*len*/)
2001{
2002}
2003
2004
2005void GraphicImport::lcl_utext(const sal_uInt8 * /*_data*/, size_t /*len*/)
2006{
2007}
2008
2009
2010void GraphicImport::lcl_props(writerfilter::Reference<Properties>::Pointer_t /*ref*/)
2011{
2012}
2013
2014
2015void GraphicImport::lcl_table(Id /*name*/, writerfilter::Reference<Table>::Pointer_t /*ref*/)
2016{
2017}
2018
2019
2020void GraphicImport::lcl_substream(Id /*name*/, ::writerfilter::Reference<Stream>::Pointer_t /*ref*/)
2021{
2022}
2023
2024void GraphicImport::lcl_startShape(uno::Reference<drawing::XShape> const&)
2025{
2026}
2027
2028void GraphicImport::lcl_endShape( )
2029{
2030}
2031
2032bool GraphicImport::IsGraphic() const
2033{
2034 return m_pImpl->m_bIsGraphic;
2035}
2036
2037sal_Int32 GraphicImport::GetLeftMarginOrig() const
2038{
2039 return m_pImpl->m_nLeftMarginOrig;
2040}
2041
2042}
2043
2044/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const sal_uInt8 * m_pBuffer
const sal_Int32 m_nLength
sal_Int32 nLineWidth
bool bHasShadow
sal_Int32 m_nPosition
::std::unique_ptr< XmlIdRegistry_Impl > m_pImpl
SdrObject * Next()
bool IsMore() const
static SdrObject * getSdrObjectFromXShape(const css::uno::Reference< css::uno::XInterface > &xInt)
virtual Degree100 GetRotateAngle() const
virtual basegfx::B2DPolyPolygon TakeXorPoly() const
bool isDiagram() const
virtual SdrObjList * GetSubList() const
virtual const tools::Rectangle & GetCurrentBoundRect() const
virtual const tools::Rectangle & GetSnapRect() const
bool IsGroupObject() const
void transform(const basegfx::B2DHomMatrix &rMatrix)
B2DRange getB2DRange() const
BASEGFX_DLLPUBLIC void transform(const B2DHomMatrix &rMatrix)
TYPE getMaxX() const
TYPE getMinX() const
TYPE getMinY() const
TYPE getMaxY() const
iterator find(const OUString &rKey)
css::uno::Any getValue(const OUString &sKey) const
css::uno::Sequence< css::beans::PropertyValue > getAsConstPropertyValueList() const
void update(const SequenceAsHashMap &rSource)
constexpr tools::Long Top() const
tools::Long getOpenHeight() const
tools::Long getOpenWidth() const
constexpr tools::Long Left() const
virtual void resolve(T &rHandler)=0
Resolves the reference.
An SPRM: Section, Paragraph and Run Modifier.
virtual sal_uInt32 getId() const =0
Returns id of the SPRM.
virtual writerfilter::Reference< Properties >::Pointer_t getProps()=0
Returns reference to properties contained in the SPRM.
static TagLogger & getInstance()
Definition: TagLogger.cxx:95
void element(const std::string &name)
Definition: TagLogger.cxx:102
virtual writerfilter::Reference< Properties >::Pointer_t getProperties()=0
Returns properties of this value.
virtual writerfilter::Reference< BinaryObj >::Pointer_t getBinary()=0
Returns binary object of this value.
virtual int getInt() const =0
Returns integer representation of the value.
virtual OUString getString() const =0
Returns string representation of the value.
virtual css::uno::Any getAny() const =0
Returns representation of the value as uno::Any.
GraphicZOrderHelper * graphicZOrderHelper()
std::pair< OUString, OUString > & m_rAligns
comphelper::SequenceAsHashMap const & getInteropGrabBag()
Getter for m_aInteropGrabBag, but also merges in the values from other members if they are set.
void applyRelativePosition(const uno::Reference< beans::XPropertySet > &xGraphicObjectProperties, bool bRelativeOnly=false) const
void applyZOrder(uno::Reference< beans::XPropertySet > const &xGraphicObjectProperties) const
std::queue< OUString > & m_rPositivePercentages
GraphicImport_Impl(GraphicImportType &rImportType, DomainMapper &rDMapper, std::pair< OUString, OUString > &rPositionOffsets, std::pair< OUString, OUString > &rAligns, std::queue< OUString > &rPositivePercentages)
std::pair< OUString, OUString > & m_rPositionOffsets
void applyPosition(const uno::Reference< beans::XPropertySet > &xGraphicObjectProperties) const
std::optional< sal_Int32 > m_oEffectExtentBottom
std::optional< sal_Int32 > m_oEffectExtentTop
void applyName(uno::Reference< beans::XPropertySet > const &xGraphicObjectProperties) const
std::optional< sal_Int32 > m_oEffectExtentLeft
std::optional< sal_Int32 > m_oEffectExtentRight
comphelper::SequenceAsHashMap m_aInteropGrabBag
void applyHyperlink(uno::Reference< beans::XPropertySet > const &xShapeProps, bool bIsShape)
void applyMargins(const uno::Reference< beans::XPropertySet > &xGraphicObjectProperties) const
std::unique_ptr< GraphicImport_Impl > m_pImpl
virtual void lcl_attribute(Id Name, Value &val) override
css::uno::Reference< css::text::XTextContent > m_xGraphicObject
css::uno::Reference< css::text::XTextContent > GetGraphicObject()
void putPropertyToFrameGrabBag(const OUString &sPropertyName, const css::uno::Any &aPropertyValue)
void handleWrapTextValue(sal_uInt32 nVal)
void lcl_expandRectangleByEffectExtent(css::awt::Point &rLeftTop, css::awt::Size &rSize)
void ProcessShapeOptions(Value const &val)
css::uno::Reference< css::drawing::XShape > m_xShape
void lcl_correctWord2007EffectExtent(const sal_Int32 nMSOAngle)
css::uno::Reference< css::text::XTextContent > createGraphicObject(css::uno::Reference< css::graphic::XGraphic > const &rxGraphic, css::uno::Reference< css::beans::XPropertySet > const &xShapeProps)
com::sun::star::awt::Point GetGraphicObjectPosition() const
virtual void lcl_sprm(Sprm &sprm) override
sal_Int32 findZOrder(sal_Int32 relativeHeight, bool bOldStyle=false)
void addItem(css::uno::Reference< css::beans::XPropertySet > const &props, sal_Int32 relativeHeight)
const WrapPolygon::Pointer_t & getPolygon() const
#define TOOLS_WARN_EXCEPTION(area, stream)
OUString m_sName
Reference< XComponentContext > const m_xComponentContext
EmbeddedObjectRef * pObject
#define SAL_WARN(area, stream)
std::unique_ptr< sal_Int32[]> pData
def text(shape, orig_st)
constexpr OUStringLiteral aData
NONE
B2DHomMatrix createRotateAroundPoint(double fPointX, double fPointY, double fRadiant)
B2DHomMatrix createScaleB2DHomMatrix(double fScaleX, double fScaleY)
B2DPolyPolygon UnoPointSequenceSequenceToB2DPolyPolygon(const css::drawing::PointSequenceSequence &rPointSequenceSequenceSource)
B2DHomMatrix createTranslateB2DHomMatrix(double fTranslateX, double fTranslateY)
B2DHomMatrix createRotateB2DHomMatrix(double fRadiant)
B2IRange fround(const B2DRange &rRange)
OStringBuffer & padToLength(OStringBuffer &rBuffer, sal_Int32 nLength, char cFill='\0')
DstType sequenceToContainer(const css::uno::Sequence< SrcType > &i_Sequence)
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
css::beans::PropertyValue makePropertyValue(const OUString &rName, T &&rValue)
constexpr Point convert(const Point &rPoint, o3tl::Length eFrom, o3tl::Length eTo)
sal_Int32 convertEmuToHmm(sal_Int64 nValue)
const sal_Int32 PER_PERCENT
static bool lcl_bHasGroupSlantedChild(const SdrObject *pObj)
OUString getPropertyName(PropertyIds eId)
static void lcl_doMSOWidthHeightSwap(awt::Point &rLeftTop, awt::Size &rSize, const sal_Int32 nMSOAngle)
void resolveSprmProps(Properties &rHandler, Sprm &rSprm)
Definition: util.cxx:62
SwNodeOffset abs(const SwNodeOffset &a)
sal_uInt32 Id
UNDERLYING_TYPE get() const
SVXCORE_DLLPUBLIC Degree100 NormAngle36000(Degree100 a)
unsigned char sal_uInt8
#define SAL_MAX_INT32
signed char sal_Int8
std::unique_ptr< char[]> aBuffer