1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
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>
46 #include <svx/svdobj.hxx>
47 #include <svx/unoapi.hxx>
48 #include <cppuhelper/implbase.hxx>
49 #include <rtl/ustrbuf.hxx>
50 #include <sal/log.hxx>
51 #include <rtl/math.hxx>
52 #include <comphelper/string.hxx>
53 #include <comphelper/sequenceashashmap.hxx>
54 #include <comphelper/sequence.hxx>
56 #include <oox/drawingml/drawingmltypes.hxx>
58 #include "DomainMapper.hxx"
59 #include <dmapper/GraphicZOrderHelper.hxx>
60 #include <ooxml/resourceids.hxx>
62 #include "ConversionHelper.hxx"
63 #include "GraphicHelpers.hxx"
64 #include "GraphicImport.hxx"
65 #include "PropertyMap.hxx"
66 #include "WrapPolygonHandler.hxx"
73 bool isTopGroupObj(const uno::Reference
<drawing::XShape
>& xShape
)
75 SdrObject
* pObject
= GetSdrObjectFromXShape(xShape
);
79 if (pObject
->getParentSdrObjectFromSdrObject())
82 return pObject
->IsGroupObject();
86 namespace writerfilter
{
91 class XInputStreamHelper
: public cppu::WeakImplHelper
<io::XInputStream
>
93 const sal_uInt8
* m_pBuffer
;
94 const sal_Int32 m_nLength
;
95 sal_Int32 m_nPosition
;
97 XInputStreamHelper(const sal_uInt8
* buf
, size_t len
);
99 virtual ::sal_Int32 SAL_CALL
readBytes( uno::Sequence
< ::sal_Int8
>& aData
, ::sal_Int32 nBytesToRead
) override
;
100 virtual ::sal_Int32 SAL_CALL
readSomeBytes( uno::Sequence
< ::sal_Int8
>& aData
, ::sal_Int32 nMaxBytesToRead
) override
;
101 virtual void SAL_CALL
skipBytes( ::sal_Int32 nBytesToSkip
) override
;
102 virtual ::sal_Int32 SAL_CALL
available( ) override
;
103 virtual void SAL_CALL
closeInput( ) override
;
106 XInputStreamHelper::XInputStreamHelper(const sal_uInt8
* buf
, size_t len
) :
113 sal_Int32
XInputStreamHelper::readBytes( uno::Sequence
<sal_Int8
>& aData
, sal_Int32 nBytesToRead
)
115 return readSomeBytes( aData
, nBytesToRead
);
118 sal_Int32
XInputStreamHelper::readSomeBytes( uno::Sequence
<sal_Int8
>& aData
, sal_Int32 nMaxBytesToRead
)
121 if( nMaxBytesToRead
> 0 )
123 if( nMaxBytesToRead
> m_nLength
- m_nPosition
)
124 nRet
= m_nLength
- m_nPosition
;
126 nRet
= nMaxBytesToRead
;
127 aData
.realloc( nRet
);
128 sal_Int8
* pData
= aData
.getArray();
131 memcpy( pData
, m_pBuffer
+ m_nPosition
, nRet
);
139 void XInputStreamHelper::skipBytes( sal_Int32 nBytesToSkip
)
141 if( nBytesToSkip
< 0 || m_nPosition
+ nBytesToSkip
> m_nLength
)
142 throw io::BufferSizeExceededException();
143 m_nPosition
+= nBytesToSkip
;
147 sal_Int32
XInputStreamHelper::available( )
149 return m_nLength
- m_nPosition
;
153 void XInputStreamHelper::closeInput( )
158 struct GraphicBorderLine
160 sal_Int32 nLineWidth
;
163 GraphicBorderLine() :
170 return nLineWidth
== 0 && !bHasShadow
;
175 class GraphicImport_Impl
184 GraphicImportType
const eGraphicImportType
;
185 DomainMapper
& rDomainMapper
;
187 sal_Int32 nLeftPosition
;
188 sal_Int32 nTopPosition
;
193 sal_Int16 nHoriOrient
;
194 sal_Int16 nHoriRelation
;
195 sal_Int16 nVertOrient
;
196 sal_Int16 nVertRelation
;
197 text::WrapTextMode nWrap
;
201 bool bContourOutside
;
202 WrapPolygon::Pointer_t mpWrapPolygon
;
204 sal_Int32 nLeftMargin
;
205 sal_Int32 nLeftMarginOrig
= 0;
206 sal_Int32 nRightMargin
;
207 sal_Int32 nTopMargin
;
208 sal_Int32 nBottomMargin
;
211 sal_Int32 nShadowXDistance
;
212 sal_Int32 nShadowYDistance
;
213 sal_Int32 nShadowColor
;
214 sal_Int32 nShadowTransparence
;
217 sal_Int32 nBrightness
;
219 static constexpr sal_Int32 nFillColor
= 0xffffffff;
221 drawing::ColorMode eColorMode
;
223 GraphicBorderLine aBorders
[4];
228 bool bPositionProtected
;
230 sal_Int32 nShapeOptionType
;
233 OUString sAlternativeText
;
235 OUString sHyperlinkURL
;
236 std::pair
<OUString
, OUString
>& m_rPositionOffsets
;
237 std::pair
<OUString
, OUString
>& m_rAligns
;
238 std::queue
<OUString
>& m_rPositivePercentages
;
240 comphelper::SequenceAsHashMap m_aInteropGrabBag
;
241 boost::optional
<sal_Int32
> m_oEffectExtentLeft
;
242 boost::optional
<sal_Int32
> m_oEffectExtentTop
;
243 boost::optional
<sal_Int32
> m_oEffectExtentRight
;
244 boost::optional
<sal_Int32
> m_oEffectExtentBottom
;
246 GraphicImport_Impl(GraphicImportType eImportType
, DomainMapper
& rDMapper
, std::pair
<OUString
, OUString
>& rPositionOffsets
, std::pair
<OUString
, OUString
>& rAligns
, std::queue
<OUString
>& rPositivePercentages
) :
251 ,eGraphicImportType( eImportType
)
252 ,rDomainMapper( rDMapper
)
255 ,bUseSimplePos(false)
257 ,nHoriOrient( text::HoriOrientation::NONE
)
258 ,nHoriRelation( text::RelOrientation::FRAME
)
259 ,nVertOrient( text::VertOrientation::NONE
)
260 ,nVertRelation( text::RelOrientation::FRAME
)
261 ,nWrap(text::WrapTextMode_NONE
)
262 ,bLayoutInCell(false)
263 ,bOpaque( !rDMapper
.IsInHeaderFooter() )
265 ,bContourOutside(true)
274 ,nShadowTransparence(0)
277 ,eColorMode( drawing::ColorMode_STANDARD
)
279 ,bSizeProtected(false)
280 ,bPositionProtected(false)
282 ,m_rPositionOffsets(rPositionOffsets
)
284 ,m_rPositivePercentages(rPositivePercentages
)
287 void setXSize(sal_Int32 _nXSize
)
293 sal_uInt32
getXSize() const
298 bool isXSizeValid() const
303 void setYSize(sal_Int32 _nYSize
)
309 sal_uInt32
getYSize() const
314 bool isYSizeValis () const
319 void applyMargins(const uno::Reference
< beans::XPropertySet
>& xGraphicObjectProperties
) const
321 xGraphicObjectProperties
->setPropertyValue(getPropertyName( PROP_LEFT_MARGIN
), uno::makeAny(nLeftMargin
));
322 xGraphicObjectProperties
->setPropertyValue(getPropertyName( PROP_RIGHT_MARGIN
), uno::makeAny(nRightMargin
));
323 xGraphicObjectProperties
->setPropertyValue(getPropertyName( PROP_TOP_MARGIN
), uno::makeAny(nTopMargin
));
324 xGraphicObjectProperties
->setPropertyValue(getPropertyName( PROP_BOTTOM_MARGIN
), uno::makeAny(nBottomMargin
));
327 void applyPosition(const uno::Reference
< beans::XPropertySet
>& xGraphicObjectProperties
) const
329 xGraphicObjectProperties
->setPropertyValue(getPropertyName( PROP_HORI_ORIENT
),
330 uno::makeAny(nHoriOrient
));
331 xGraphicObjectProperties
->setPropertyValue(getPropertyName( PROP_VERT_ORIENT
),
332 uno::makeAny(nVertOrient
));
335 void applyRelativePosition(const uno::Reference
< beans::XPropertySet
>& xGraphicObjectProperties
, bool bRelativeOnly
= false) const
338 xGraphicObjectProperties
->setPropertyValue(getPropertyName( PROP_HORI_ORIENT_POSITION
),
339 uno::makeAny(nLeftPosition
));
340 xGraphicObjectProperties
->setPropertyValue(getPropertyName( PROP_HORI_ORIENT_RELATION
),
341 uno::makeAny(nHoriRelation
));
342 xGraphicObjectProperties
->setPropertyValue(getPropertyName( PROP_PAGE_TOGGLE
),
343 uno::makeAny(false));
345 xGraphicObjectProperties
->setPropertyValue(getPropertyName( PROP_VERT_ORIENT_POSITION
),
346 uno::makeAny(nTopPosition
));
347 xGraphicObjectProperties
->setPropertyValue(getPropertyName( PROP_VERT_ORIENT_RELATION
),
348 uno::makeAny(nVertRelation
));
351 void applyZOrder(uno::Reference
<beans::XPropertySet
> const & xGraphicObjectProperties
) const
355 GraphicZOrderHelper
* pZOrderHelper
= rDomainMapper
.graphicZOrderHelper();
356 xGraphicObjectProperties
->setPropertyValue(getPropertyName(PROP_Z_ORDER
), uno::makeAny(pZOrderHelper
->findZOrder(zOrder
)));
357 pZOrderHelper
->addItem(xGraphicObjectProperties
, zOrder
);
361 void applyName(uno::Reference
<beans::XPropertySet
> const & xGraphicObjectProperties
) const
365 // Ask the graphic naming helper to find out the name for this
366 // object: It's around till the end of the import, so it remembers
367 // what's the first free name.
368 uno::Reference
< container::XNamed
> xNamed( xGraphicObjectProperties
, uno::UNO_QUERY_THROW
);
369 xNamed
->setName(rDomainMapper
.GetGraphicNamingHelper().NameGraphic(sName
));
371 if ( sHyperlinkURL
.getLength() > 0 )
372 xGraphicObjectProperties
->setPropertyValue(getPropertyName( PROP_HYPER_LINK_U_R_L
),
373 uno::makeAny ( sHyperlinkURL
));
374 xGraphicObjectProperties
->setPropertyValue(getPropertyName( PROP_DESCRIPTION
),
375 uno::makeAny( sAlternativeText
));
376 xGraphicObjectProperties
->setPropertyValue(getPropertyName( PROP_TITLE
),
377 uno::makeAny( title
));
379 catch( const uno::Exception
& e
)
381 SAL_WARN("writerfilter", "failed. Message :" << e
);
385 /// Getter for m_aInteropGrabBag, but also merges in the values from other members if they are set.
386 comphelper::SequenceAsHashMap
const & getInteropGrabBag()
388 comphelper::SequenceAsHashMap aEffectExtent
;
389 if (m_oEffectExtentLeft
)
390 aEffectExtent
["l"] <<= *m_oEffectExtentLeft
;
391 if (m_oEffectExtentTop
)
392 aEffectExtent
["t"] <<= *m_oEffectExtentTop
;
393 if (m_oEffectExtentRight
)
394 aEffectExtent
["r"] <<= *m_oEffectExtentRight
;
395 if (m_oEffectExtentBottom
)
396 aEffectExtent
["b"] <<= *m_oEffectExtentBottom
;
397 if (!aEffectExtent
.empty())
398 m_aInteropGrabBag
["CT_EffectExtent"] <<= aEffectExtent
.getAsConstPropertyValueList();
399 return m_aInteropGrabBag
;
403 #if !HAVE_CPP_INLINE_VARIABLES
404 constexpr sal_Int32
GraphicImport_Impl::nFillColor
;
407 GraphicImport::GraphicImport(uno::Reference
<uno::XComponentContext
> const& xComponentContext
,
408 uno::Reference
<lang::XMultiServiceFactory
> const& xTextFactory
,
409 DomainMapper
& rDMapper
,
410 GraphicImportType eImportType
,
411 std::pair
<OUString
, OUString
>& rPositionOffsets
,
412 std::pair
<OUString
, OUString
>& rAligns
,
413 std::queue
<OUString
>& rPositivePercentages
)
414 : LoggedProperties("GraphicImport")
415 , LoggedTable("GraphicImport")
416 , LoggedStream("GraphicImport")
417 , m_pImpl(new GraphicImport_Impl(eImportType
, rDMapper
, rPositionOffsets
, rAligns
, rPositivePercentages
))
418 , m_xComponentContext(xComponentContext
)
419 , m_xTextFactory(xTextFactory
)
423 GraphicImport::~GraphicImport()
427 void GraphicImport::handleWrapTextValue(sal_uInt32 nVal
)
431 case NS_ooxml::LN_Value_wordprocessingDrawing_ST_WrapText_bothSides
: // 90920;
432 m_pImpl
->nWrap
= text::WrapTextMode_PARALLEL
;
434 case NS_ooxml::LN_Value_wordprocessingDrawing_ST_WrapText_left
: // 90921;
435 m_pImpl
->nWrap
= text::WrapTextMode_LEFT
;
437 case NS_ooxml::LN_Value_wordprocessingDrawing_ST_WrapText_right
: // 90922;
438 m_pImpl
->nWrap
= text::WrapTextMode_RIGHT
;
440 case NS_ooxml::LN_Value_wordprocessingDrawing_ST_WrapText_largest
: // 90923;
441 m_pImpl
->nWrap
= text::WrapTextMode_DYNAMIC
;
447 void GraphicImport::putPropertyToFrameGrabBag( const OUString
& sPropertyName
, const uno::Any
& aPropertyValue
)
449 beans::PropertyValue aProperty
;
450 aProperty
.Name
= sPropertyName
;
451 aProperty
.Value
= aPropertyValue
;
456 uno::Reference
< beans::XPropertySet
> xSet(m_xShape
, uno::UNO_QUERY_THROW
);
458 uno::Reference
< beans::XPropertySetInfo
> xSetInfo(xSet
->getPropertySetInfo());
462 OUString aGrabBagPropName
;
463 uno::Reference
<lang::XServiceInfo
> xServiceInfo(m_xShape
, uno::UNO_QUERY_THROW
);
464 if (xServiceInfo
->supportsService("com.sun.star.text.TextFrame"))
465 aGrabBagPropName
= "FrameInteropGrabBag";
467 aGrabBagPropName
= "InteropGrabBag";
469 if (xSetInfo
->hasPropertyByName(aGrabBagPropName
))
471 //Add pProperty to the end of the Sequence for aGrabBagPropName
472 uno::Sequence
<beans::PropertyValue
> aTmp
;
473 xSet
->getPropertyValue(aGrabBagPropName
) >>= aTmp
;
474 std::vector
<beans::PropertyValue
> aGrabBag(comphelper::sequenceToContainer
<std::vector
<beans::PropertyValue
> >(aTmp
));
475 aGrabBag
.push_back(aProperty
);
477 xSet
->setPropertyValue(aGrabBagPropName
, uno::makeAny(comphelper::containerToSequence(aGrabBag
)));
481 void GraphicImport::lcl_attribute(Id nName
, Value
& rValue
)
483 sal_Int32 nIntValue
= rValue
.getInt();
486 case NS_ooxml::LN_CT_Hyperlink_URL
://90682;
487 m_pImpl
->sHyperlinkURL
= rValue
.getString();
489 case NS_ooxml::LN_blip
: //the binary graphic data in a shape
491 writerfilter::Reference
<Properties
>::Pointer_t pProperties
= rValue
.getProperties();
492 if( pProperties
.get())
494 pProperties
->resolve(*this);
498 case NS_ooxml::LN_payload
:
500 writerfilter::Reference
<BinaryObj
>::Pointer_t pPictureData
= rValue
.getBinary();
501 if( pPictureData
.get())
502 pPictureData
->resolve(*this);
507 case NS_ooxml::LN_CT_Border_sz
:
508 m_pImpl
->aBorders
[BORDER_TOP
].nLineWidth
= nIntValue
;
510 case NS_ooxml::LN_CT_Border_val
:
511 //graphic borders don't support different line types
513 case NS_ooxml::LN_CT_Border_space
:
515 case NS_ooxml::LN_CT_Border_shadow
:
516 m_pImpl
->aBorders
[BORDER_TOP
].bHasShadow
= nIntValue
!= 0;
518 case NS_ooxml::LN_CT_Border_frame
:
520 case NS_ooxml::LN_CT_PositiveSize2D_cx
:
521 case NS_ooxml::LN_CT_PositiveSize2D_cy
:
523 sal_Int32 nDim
= oox::drawingml::convertEmuToHmm(nIntValue
);
524 // drawingML equivalent of oox::vml::ShapeType::getAbsRectangle():
525 // make sure a shape isn't hidden implicitly just because it has
526 // zero height or width.
530 if( nName
== NS_ooxml::LN_CT_PositiveSize2D_cx
)
531 m_pImpl
->setXSize(nDim
);
533 m_pImpl
->setYSize(nDim
);
536 case NS_ooxml::LN_CT_EffectExtent_l
:
537 m_pImpl
->m_oEffectExtentLeft
= nIntValue
;
539 case NS_ooxml::LN_CT_EffectExtent_t
:
540 m_pImpl
->m_oEffectExtentTop
= nIntValue
;
542 case NS_ooxml::LN_CT_EffectExtent_r
:
543 m_pImpl
->m_oEffectExtentRight
= nIntValue
;
545 case NS_ooxml::LN_CT_EffectExtent_b
:
546 m_pImpl
->m_oEffectExtentBottom
= nIntValue
;
548 case NS_ooxml::LN_CT_NonVisualDrawingProps_id
:// 90650;
549 //id of the object - ignored
551 case NS_ooxml::LN_CT_NonVisualDrawingProps_name
:// 90651;
553 m_pImpl
->sName
= rValue
.getString();
555 case NS_ooxml::LN_CT_NonVisualDrawingProps_descr
:// 90652;
557 m_pImpl
->sAlternativeText
= rValue
.getString();
559 case NS_ooxml::LN_CT_NonVisualDrawingProps_title
:
561 m_pImpl
->title
= rValue
.getString();
563 case NS_ooxml::LN_CT_GraphicalObjectFrameLocking_noChangeAspect
://90644;
564 //disallow aspect ratio change - ignored
566 case NS_ooxml::LN_CT_GraphicalObjectFrameLocking_noMove
:// 90645;
567 m_pImpl
->bPositionProtected
= true;
569 case NS_ooxml::LN_CT_GraphicalObjectFrameLocking_noResize
: // 90646;
570 m_pImpl
->bSizeProtected
= true;
572 case NS_ooxml::LN_CT_Anchor_distT
: // 90983;
573 case NS_ooxml::LN_CT_Anchor_distB
: // 90984;
574 case NS_ooxml::LN_CT_Anchor_distL
: // 90985;
575 case NS_ooxml::LN_CT_Anchor_distR
: // 90986;
577 m_pImpl
->nShapeOptionType
= nName
;
578 ProcessShapeOptions(rValue
);
581 case NS_ooxml::LN_CT_Anchor_simplePos_attr
: // 90987;
582 m_pImpl
->bUseSimplePos
= nIntValue
> 0;
584 case NS_ooxml::LN_CT_Anchor_relativeHeight
: // 90988;
585 m_pImpl
->zOrder
= nIntValue
;
587 case NS_ooxml::LN_CT_Anchor_behindDoc
: // 90989; - in background
589 m_pImpl
->bOpaque
= false;
591 case NS_ooxml::LN_CT_Anchor_locked
: // 90990; - ignored
593 case NS_ooxml::LN_CT_Anchor_layoutInCell
: // 90991; - ignored
594 m_pImpl
->bLayoutInCell
= nIntValue
!= 0;
596 case NS_ooxml::LN_CT_Anchor_hidden
: // 90992; - ignored
598 case NS_ooxml::LN_CT_Anchor_allowOverlap
: // 90993;
599 //enable overlapping - ignored
601 case NS_ooxml::LN_CT_Anchor_wp14_anchorId
:
602 case NS_ooxml::LN_CT_Inline_wp14_anchorId
:
604 OUStringBuffer aBuffer
= OUString::number(nIntValue
, 16);
605 OUStringBuffer aString
;
606 comphelper::string::padToLength(aString
, 8 - aBuffer
.getLength(), '0');
607 aString
.append(aBuffer
.getStr());
608 m_pImpl
->sAnchorId
= aString
.makeStringAndClear().toAsciiUpperCase();
611 case NS_ooxml::LN_CT_Point2D_x
: // 90405;
612 m_pImpl
->nLeftPosition
= ConversionHelper::convertTwipToMM100(nIntValue
);
613 m_pImpl
->nHoriRelation
= text::RelOrientation::PAGE_FRAME
;
614 m_pImpl
->nHoriOrient
= text::HoriOrientation::NONE
;
616 case NS_ooxml::LN_CT_Point2D_y
: // 90406;
617 m_pImpl
->nTopPosition
= ConversionHelper::convertTwipToMM100(nIntValue
);
618 m_pImpl
->nVertRelation
= text::RelOrientation::PAGE_FRAME
;
619 m_pImpl
->nVertOrient
= text::VertOrientation::NONE
;
621 case NS_ooxml::LN_CT_WrapTight_wrapText
: // 90934;
622 m_pImpl
->bContour
= true;
623 m_pImpl
->bContourOutside
= true;
625 handleWrapTextValue(rValue
.getInt());
628 case NS_ooxml::LN_CT_WrapThrough_wrapText
:
629 m_pImpl
->bContour
= true;
630 m_pImpl
->bContourOutside
= false;
632 handleWrapTextValue(rValue
.getInt());
635 case NS_ooxml::LN_CT_WrapSquare_wrapText
: //90928;
636 handleWrapTextValue(rValue
.getInt());
638 case NS_ooxml::LN_shape
:
640 uno::Reference
< drawing::XShape
> xShape
;
641 rValue
.getAny( ) >>= xShape
;
645 // Is it a graphic image
646 bool bUseShape
= true;
649 uno::Reference
< beans::XPropertySet
> xShapeProps
650 ( xShape
, uno::UNO_QUERY_THROW
);
652 uno::Reference
<graphic::XGraphic
> xGraphic
;
653 xShapeProps
->getPropertyValue("Graphic") >>= xGraphic
;
655 sal_Int32 nRotation
= 0;
656 xShapeProps
->getPropertyValue("RotateAngle") >>= nRotation
;
658 css::beans::PropertyValues aGrabBag
;
659 bool bContainsEffects
= false;
660 xShapeProps
->getPropertyValue("InteropGrabBag") >>= aGrabBag
;
661 for( sal_Int32 i
= 0; i
< aGrabBag
.getLength(); ++i
)
663 // if the shape contains effects in the grab bag, we should not transform it
664 // in a XTextContent so those effects can be preserved
665 if( aGrabBag
[i
].Name
== "EffectProperties" || aGrabBag
[i
].Name
== "3DEffectProperties" ||
666 aGrabBag
[i
].Name
== "ArtisticEffectProperties" )
667 bContainsEffects
= true;
670 xShapeProps
->getPropertyValue("Shadow") >>= m_pImpl
->bShadow
;
671 if (m_pImpl
->bShadow
)
673 xShapeProps
->getPropertyValue("ShadowXDistance") >>= m_pImpl
->nShadowXDistance
;
674 xShapeProps
->getPropertyValue("ShadowYDistance") >>= m_pImpl
->nShadowYDistance
;
675 xShapeProps
->getPropertyValue("ShadowColor") >>= m_pImpl
->nShadowColor
;
676 xShapeProps
->getPropertyValue("ShadowTransparence") >>= m_pImpl
->nShadowTransparence
;
679 xShapeProps
->getPropertyValue("GraphicColorMode") >>= m_pImpl
->eColorMode
;
680 xShapeProps
->getPropertyValue("AdjustLuminance") >>= m_pImpl
->nBrightness
;
681 xShapeProps
->getPropertyValue("AdjustContrast") >>= m_pImpl
->nContrast
;
683 // fdo#70457: transform XShape into a SwXTextGraphicObject only if there's no rotation
684 if ( nRotation
== 0 && !bContainsEffects
)
685 m_xGraphicObject
= createGraphicObject( xGraphic
, xShapeProps
);
687 bUseShape
= !m_xGraphicObject
.is( );
691 // Define the object size
692 uno::Reference
< beans::XPropertySet
> xGraphProps( m_xGraphicObject
,
694 awt::Size aSize
= xShape
->getSize( );
695 xGraphProps
->setPropertyValue("Height",
696 uno::makeAny( aSize
.Height
) );
697 xGraphProps
->setPropertyValue("Width",
698 uno::makeAny( aSize
.Width
) );
700 text::GraphicCrop
aGraphicCrop( 0, 0, 0, 0 );
701 uno::Reference
< beans::XPropertySet
> xSourceGraphProps( xShape
, uno::UNO_QUERY
);
702 uno::Any aAny
= xSourceGraphProps
->getPropertyValue("GraphicCrop");
703 if(aAny
>>= aGraphicCrop
) {
704 xGraphProps
->setPropertyValue("GraphicCrop",
705 uno::makeAny( aGraphicCrop
) );
708 // We need to drop the shape here somehow
709 uno::Reference
< lang::XComponent
> xShapeComponent( xShape
, uno::UNO_QUERY
);
710 xShapeComponent
->dispose( );
713 catch( const beans::UnknownPropertyException
& )
715 // It isn't a graphic image
722 if ( m_xShape
.is( ) )
724 uno::Reference
< beans::XPropertySet
> xShapeProps
725 (m_xShape
, uno::UNO_QUERY_THROW
);
728 xShapeProps
->setPropertyValue
729 (getPropertyName(PROP_ANCHOR_TYPE
),
731 (text::TextContentAnchorType_AS_CHARACTER
));
733 // In Word, if a shape is anchored inline, that
734 // excludes being in the background.
735 xShapeProps
->setPropertyValue("Opaque", uno::makeAny(true));
737 uno::Reference
<lang::XServiceInfo
> xServiceInfo(m_xShape
, uno::UNO_QUERY_THROW
);
739 // TextFrames can't be rotated. But for anything else,
740 // make sure that setting size doesn't affect rotation,
741 // that would not match Word's definition of rotation.
742 bool bKeepRotation
= false;
743 if (!xServiceInfo
->supportsService("com.sun.star.text.TextFrame"))
745 bKeepRotation
= true;
746 xShapeProps
->setPropertyValue
747 (getPropertyName(PROP_TEXT_RANGE
),
749 (m_pImpl
->rDomainMapper
.GetCurrentTextRange()));
752 awt::Size
aSize(m_xShape
->getSize());
754 if (m_pImpl
->isXSizeValid())
755 aSize
.Width
= m_pImpl
->getXSize();
756 if (m_pImpl
->isYSizeValis())
757 aSize
.Height
= m_pImpl
->getYSize();
759 sal_Int32 nRotation
= 0;
762 // Use internal API, getPropertyValue(RotateAngle)
763 // would use GetObjectRotation(), which is not what
765 if (SdrObject
* pShape
= GetSdrObjectFromXShape(m_xShape
))
766 nRotation
= pShape
->GetRotateAngle();
768 m_xShape
->setSize(aSize
);
771 xShapeProps
->setPropertyValue("RotateAngle", uno::makeAny(nRotation
));
774 // Include effect extent in the margin to bring Writer layout closer
775 // to Word. But do this for non-rotated shapes only, where effect
776 // extents map to increased margins as-is.
777 if (m_pImpl
->m_oEffectExtentLeft
)
779 m_pImpl
->nLeftMargin
+= oox::drawingml::convertEmuToHmm(
780 *m_pImpl
->m_oEffectExtentLeft
);
782 if (m_pImpl
->m_oEffectExtentTop
)
784 m_pImpl
->nTopMargin
+= oox::drawingml::convertEmuToHmm(
785 *m_pImpl
->m_oEffectExtentTop
);
787 if (m_pImpl
->m_oEffectExtentRight
)
789 m_pImpl
->nRightMargin
+= oox::drawingml::convertEmuToHmm(
790 *m_pImpl
->m_oEffectExtentRight
);
792 if (m_pImpl
->m_oEffectExtentBottom
)
794 m_pImpl
->nBottomMargin
+= oox::drawingml::convertEmuToHmm(
795 *m_pImpl
->m_oEffectExtentBottom
);
800 m_pImpl
->bIsGraphic
= true;
802 if (!m_pImpl
->sAnchorId
.isEmpty())
804 putPropertyToFrameGrabBag("AnchorId", uno::makeAny(m_pImpl
->sAnchorId
));
808 if (bUseShape
&& m_pImpl
->eGraphicImportType
== IMPORT_AS_DETECTED_ANCHOR
)
810 // 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).
811 // But they aren't Writer pictures, either (which are already handled above).
812 uno::Reference
< beans::XPropertySet
> xShapeProps(m_xShape
, uno::UNO_QUERY_THROW
);
814 // This needs to be AT_PARAGRAPH by default and not AT_CHARACTER, otherwise shape will move when the user inserts a new paragraph.
815 text::TextContentAnchorType eAnchorType
= text::TextContentAnchorType_AT_PARAGRAPH
;
817 // Avoid setting AnchorType for TextBoxes till SwTextBoxHelper::syncProperty() doesn't handle transition.
818 bool bTextBox
= false;
819 xShapeProps
->getPropertyValue("TextBox") >>= bTextBox
;
820 if (m_pImpl
->nVertRelation
== text::RelOrientation::TEXT_LINE
&& !bTextBox
)
821 eAnchorType
= text::TextContentAnchorType_AT_CHARACTER
;
823 xShapeProps
->setPropertyValue("AnchorType", uno::makeAny(eAnchorType
));
825 //only the position orientation is handled in applyPosition()
826 m_pImpl
->applyPosition(xShapeProps
);
828 uno::Reference
<lang::XServiceInfo
> xServiceInfo(m_xShape
, uno::UNO_QUERY_THROW
);
829 if (xServiceInfo
->supportsService("com.sun.star.drawing.GroupShape") ||
830 xServiceInfo
->supportsService("com.sun.star.drawing.GraphicObjectShape"))
832 // You would expect that position and rotation are
833 // independent, but they are not. Till we are not
834 // there yet to handle all scaling, translation and
835 // rotation with a single transformation matrix,
836 // make sure there is no rotation set when we set
838 sal_Int32 nRotation
= 0;
839 xShapeProps
->getPropertyValue("RotateAngle") >>= nRotation
;
841 xShapeProps
->setPropertyValue("RotateAngle", uno::makeAny(sal_Int32(0)));
843 // Position of the groupshape should be set after children have been added.
844 // Long-term we should get rid of positioning group
845 // shapes, though. Do it for top-level ones with
846 // absolute page position as a start.
847 // fdo#80555: also set position for graphic shapes here
848 if (!isTopGroupObj(m_xShape
)
849 || m_pImpl
->nHoriRelation
!= text::RelOrientation::PAGE_FRAME
850 || m_pImpl
->nVertRelation
!= text::RelOrientation::PAGE_FRAME
)
851 m_xShape
->setPosition(
852 awt::Point(m_pImpl
->nLeftPosition
, m_pImpl
->nTopPosition
));
855 xShapeProps
->setPropertyValue("RotateAngle", uno::makeAny(nRotation
));
857 m_pImpl
->applyRelativePosition(xShapeProps
, /*bRelativeOnly=*/true);
859 xShapeProps
->setPropertyValue("SurroundContour", uno::makeAny(m_pImpl
->bContour
));
860 m_pImpl
->applyMargins(xShapeProps
);
861 xShapeProps
->setPropertyValue("Opaque", uno::makeAny(m_pImpl
->bOpaque
));
862 xShapeProps
->setPropertyValue("Surround", uno::makeAny(static_cast<sal_Int32
>(m_pImpl
->nWrap
)));
863 m_pImpl
->applyZOrder(xShapeProps
);
864 m_pImpl
->applyName(xShapeProps
);
866 // Get the grab-bag set by oox, merge with our one and then put it back.
867 comphelper::SequenceAsHashMap
aInteropGrabBag(xShapeProps
->getPropertyValue("InteropGrabBag"));
868 aInteropGrabBag
.update(m_pImpl
->getInteropGrabBag());
869 xShapeProps
->setPropertyValue("InteropGrabBag", uno::makeAny(aInteropGrabBag
.getAsConstPropertyValueList()));
871 else if (bUseShape
&& m_pImpl
->eGraphicImportType
== IMPORT_AS_DETECTED_INLINE
)
873 uno::Reference
< beans::XPropertySet
> xShapeProps(m_xShape
, uno::UNO_QUERY_THROW
);
874 comphelper::SequenceAsHashMap
aInteropGrabBag(xShapeProps
->getPropertyValue("InteropGrabBag"));
875 aInteropGrabBag
.update(m_pImpl
->getInteropGrabBag());
876 xShapeProps
->setPropertyValue("InteropGrabBag", uno::makeAny(aInteropGrabBag
.getAsConstPropertyValueList()));
881 case NS_ooxml::LN_CT_Inline_distT
:
882 m_pImpl
->nTopMargin
= 0;
884 case NS_ooxml::LN_CT_Inline_distB
:
885 m_pImpl
->nBottomMargin
= 0;
887 case NS_ooxml::LN_CT_Inline_distL
:
888 m_pImpl
->nLeftMargin
= 0;
890 case NS_ooxml::LN_CT_Inline_distR
:
891 m_pImpl
->nRightMargin
= 0;
893 case NS_ooxml::LN_CT_GraphicalObjectData_uri
:
895 //TODO: does it need to be handled?
897 case NS_ooxml::LN_CT_SizeRelH_relativeFrom
:
901 case NS_ooxml::LN_ST_SizeRelFromH_margin
:
904 uno::Reference
<beans::XPropertySet
> xPropertySet(m_xShape
, uno::UNO_QUERY
);
905 xPropertySet
->setPropertyValue("RelativeWidthRelation", uno::makeAny(text::RelOrientation::FRAME
));
908 case NS_ooxml::LN_ST_SizeRelFromH_page
:
911 uno::Reference
<beans::XPropertySet
> xPropertySet(m_xShape
, uno::UNO_QUERY
);
912 xPropertySet
->setPropertyValue("RelativeWidthRelation", uno::makeAny(text::RelOrientation::PAGE_FRAME
));
916 SAL_WARN("writerfilter", "GraphicImport::lcl_attribute: unhandled NS_ooxml::LN_CT_SizeRelH_relativeFrom value: " << nIntValue
);
921 case NS_ooxml::LN_CT_SizeRelV_relativeFrom
:
925 case NS_ooxml::LN_ST_SizeRelFromV_margin
:
928 uno::Reference
<beans::XPropertySet
> xPropertySet(m_xShape
, uno::UNO_QUERY
);
929 xPropertySet
->setPropertyValue("RelativeHeightRelation", uno::makeAny(text::RelOrientation::FRAME
));
932 case NS_ooxml::LN_ST_SizeRelFromV_page
:
935 uno::Reference
<beans::XPropertySet
> xPropertySet(m_xShape
, uno::UNO_QUERY
);
936 xPropertySet
->setPropertyValue("RelativeHeightRelation", uno::makeAny(text::RelOrientation::PAGE_FRAME
));
940 SAL_WARN("writerfilter", "GraphicImport::lcl_attribute: unhandled NS_ooxml::LN_CT_SizeRelV_relativeFrom value: " << nIntValue
);
946 #ifdef DEBUG_WRITERFILTER
947 TagLogger::getInstance().element("unhandled");
953 uno::Reference
<text::XTextContent
> GraphicImport::GetGraphicObject()
955 uno::Reference
<text::XTextContent
> xResult
;
957 if (m_xGraphicObject
.is())
958 xResult
= m_xGraphicObject
;
959 else if (m_xShape
.is())
961 xResult
.set(m_xShape
, uno::UNO_QUERY_THROW
);
968 void GraphicImport::ProcessShapeOptions(Value
const & rValue
)
970 sal_Int32 nIntValue
= rValue
.getInt();
971 switch( m_pImpl
->nShapeOptionType
)
973 case NS_ooxml::LN_CT_Anchor_distL
:
974 m_pImpl
->nLeftMargin
= nIntValue
/ 360;
975 m_pImpl
->nLeftMarginOrig
= m_pImpl
->nLeftMargin
;
977 case NS_ooxml::LN_CT_Anchor_distT
:
978 //todo: changes have to be applied depending on the orientation, see SwWW8ImplReader::AdjustULWrapForWordMargins()
979 m_pImpl
->nTopMargin
= nIntValue
/ 360;
981 case NS_ooxml::LN_CT_Anchor_distR
:
982 //todo: changes have to be applied depending on the orientation, see SwWW8ImplReader::AdjustLRWrapForWordMargins()
983 m_pImpl
->nRightMargin
= nIntValue
/ 360;
985 case NS_ooxml::LN_CT_Anchor_distB
:
986 //todo: changes have to be applied depending on the orientation, see SwWW8ImplReader::AdjustULWrapForWordMargins()
987 m_pImpl
->nBottomMargin
= nIntValue
/ 360;
990 OSL_FAIL( "shape option unsupported?");
995 void GraphicImport::lcl_sprm(Sprm
& rSprm
)
997 sal_uInt32 nSprmId
= rSprm
.getId();
998 Value::Pointer_t pValue
= rSprm
.getValue();
1002 case NS_ooxml::LN_CT_Inline_extent
: // 90911;
1003 case NS_ooxml::LN_CT_Inline_effectExtent
: // 90912;
1004 case NS_ooxml::LN_CT_Inline_docPr
: // 90913;
1005 case NS_ooxml::LN_CT_Inline_cNvGraphicFramePr
: // 90914;
1006 case NS_ooxml::LN_CT_NonVisualGraphicFrameProperties_graphicFrameLocks
:// 90657
1007 case NS_ooxml::LN_CT_Inline_a_graphic
:// 90915
1008 case NS_ooxml::LN_CT_Anchor_simplePos_elem
: // 90975;
1009 case NS_ooxml::LN_CT_Anchor_extent
: // 90978;
1010 case NS_ooxml::LN_CT_Anchor_effectExtent
: // 90979;
1011 case NS_ooxml::LN_EG_WrapType_wrapSquare
: // 90945;
1012 case NS_ooxml::LN_EG_WrapType_wrapTight
: // 90946;
1013 case NS_ooxml::LN_EG_WrapType_wrapThrough
:
1014 case NS_ooxml::LN_CT_Anchor_docPr
: // 90980;
1015 case NS_ooxml::LN_CT_Anchor_cNvGraphicFramePr
: // 90981;
1016 case NS_ooxml::LN_CT_Anchor_a_graphic
: // 90982;
1017 case NS_ooxml::LN_CT_WrapPath_start
: // 90924;
1018 case NS_ooxml::LN_CT_WrapPath_lineTo
: // 90925;
1019 case NS_ooxml::LN_graphic_graphic
:
1020 case NS_ooxml::LN_pic_pic
:
1021 case NS_ooxml::LN_dgm_relIds
:
1022 case NS_ooxml::LN_lc_lockedCanvas
:
1023 case NS_ooxml::LN_c_chart
:
1024 case NS_ooxml::LN_wps_wsp
:
1025 case NS_ooxml::LN_wpg_wgp
:
1026 case NS_ooxml::LN_sizeRelH_sizeRelH
:
1027 case NS_ooxml::LN_sizeRelV_sizeRelV
:
1028 case NS_ooxml::LN_hlinkClick_hlinkClick
:
1030 writerfilter::Reference
<Properties
>::Pointer_t pProperties
= rSprm
.getProps();
1031 if( pProperties
.get())
1033 pProperties
->resolve(*this);
1036 // We'll map these to PARALLEL, save the original wrap type.
1037 if (nSprmId
== NS_ooxml::LN_EG_WrapType_wrapTight
)
1038 m_pImpl
->m_aInteropGrabBag
["EG_WrapType"] <<= OUString("wrapTight");
1039 else if (nSprmId
== NS_ooxml::LN_EG_WrapType_wrapThrough
)
1040 m_pImpl
->m_aInteropGrabBag
["EG_WrapType"] <<= OUString("wrapThrough");
1043 case NS_ooxml::LN_CT_WrapTight_wrapPolygon
:
1044 case NS_ooxml::LN_CT_WrapThrough_wrapPolygon
:
1046 WrapPolygonHandler aHandler
;
1048 resolveSprmProps(aHandler
, rSprm
);
1050 m_pImpl
->mpWrapPolygon
= aHandler
.getPolygon();
1052 // Save the wrap path in case we can't handle it natively: drawinglayer shapes, TextFrames.
1053 m_pImpl
->m_aInteropGrabBag
["CT_WrapPath"] <<= m_pImpl
->mpWrapPolygon
->getPointSequenceSequence();
1056 case NS_ooxml::LN_CT_Anchor_positionH
: // 90976;
1058 // Use a special handler for the positioning
1059 std::shared_ptr
<PositionHandler
> pHandler( new PositionHandler( m_pImpl
->m_rPositionOffsets
, m_pImpl
->m_rAligns
));
1060 writerfilter::Reference
<Properties
>::Pointer_t pProperties
= rSprm
.getProps();
1061 if( pProperties
.get( ) )
1063 pProperties
->resolve( *pHandler
);
1064 if( !m_pImpl
->bUseSimplePos
)
1066 m_pImpl
->nHoriRelation
= pHandler
->relation();
1067 m_pImpl
->nHoriOrient
= pHandler
->orientation();
1068 m_pImpl
->nLeftPosition
= pHandler
->position();
1070 // Left adjustments: if horizontally aligned to left of margin, then remove the
1072 if (m_pImpl
->nHoriOrient
== text::HoriOrientation::LEFT
)
1074 if (m_pImpl
->nHoriRelation
== text::RelOrientation::PAGE_PRINT_AREA
)
1076 m_pImpl
->nLeftMargin
= 0;
1083 case NS_ooxml::LN_CT_Anchor_positionV
: // 90977;
1085 // Use a special handler for the positioning
1086 std::shared_ptr
<PositionHandler
> pHandler( new PositionHandler( m_pImpl
->m_rPositionOffsets
, m_pImpl
->m_rAligns
));
1087 writerfilter::Reference
<Properties
>::Pointer_t pProperties
= rSprm
.getProps();
1088 if( pProperties
.get( ) )
1090 pProperties
->resolve( *pHandler
);
1091 if( !m_pImpl
->bUseSimplePos
)
1093 m_pImpl
->nVertRelation
= pHandler
->relation();
1094 m_pImpl
->nVertOrient
= pHandler
->orientation();
1095 m_pImpl
->nTopPosition
= pHandler
->position();
1100 case NS_ooxml::LN_CT_SizeRelH_pctWidth
:
1101 case NS_ooxml::LN_CT_SizeRelV_pctHeight
:
1102 if (m_pImpl
->m_rPositivePercentages
.empty())
1107 sal_Int16 nPositivePercentage
= rtl::math::round(m_pImpl
->m_rPositivePercentages
.front().toDouble() / oox::drawingml::PER_PERCENT
);
1109 if (nPositivePercentage
)
1111 uno::Reference
<beans::XPropertySet
> xPropertySet(m_xShape
, uno::UNO_QUERY
);
1112 OUString aProperty
= nSprmId
== NS_ooxml::LN_CT_SizeRelH_pctWidth
? OUString("RelativeWidth") : OUString("RelativeHeight");
1113 xPropertySet
->setPropertyValue(aProperty
, uno::makeAny(nPositivePercentage
));
1117 // Make sure the token is consumed even if xShape is an empty
1119 m_pImpl
->m_rPositivePercentages
.pop();
1121 case NS_ooxml::LN_EG_WrapType_wrapNone
: // 90944; - doesn't contain attributes
1122 //depending on the behindDoc attribute text wraps through behind or in front of the object
1123 m_pImpl
->nWrap
= text::WrapTextMode_THROUGH
;
1125 // Wrap though means the margins defined earlier should not be
1127 m_pImpl
->nLeftMargin
= 0;
1128 m_pImpl
->nTopMargin
= 0;
1129 m_pImpl
->nRightMargin
= 0;
1130 m_pImpl
->nBottomMargin
= 0;
1132 case NS_ooxml::LN_EG_WrapType_wrapTopAndBottom
: // 90948;
1133 m_pImpl
->nWrap
= text::WrapTextMode_NONE
;
1135 case NS_ooxml::LN_CT_GraphicalObject_graphicData
:// 90660;
1137 m_pImpl
->bIsGraphic
= true;
1139 writerfilter::Reference
<Properties
>::Pointer_t pProperties
= rSprm
.getProps();
1140 if( pProperties
.get())
1141 pProperties
->resolve(*this);
1144 case NS_ooxml::LN_CT_NonVisualDrawingProps_a_hlinkClick
: // 90689;
1146 writerfilter::Reference
<Properties
>::Pointer_t pProperties
= rSprm
.getProps();
1147 if( pProperties
.get( ) )
1148 pProperties
->resolve( *this );
1152 SAL_WARN("writerfilter", "GraphicImport::lcl_sprm: unhandled token: " << nSprmId
);
1157 void GraphicImport::lcl_entry(int /*pos*/, writerfilter::Reference
<Properties
>::Pointer_t
/*ref*/)
1161 uno::Reference
<text::XTextContent
> GraphicImport::createGraphicObject(uno::Reference
<graphic::XGraphic
> const & rxGraphic
,
1162 uno::Reference
<beans::XPropertySet
> const & xShapeProps
)
1164 uno::Reference
<text::XTextContent
> xGraphicObject
;
1169 uno::Reference
< beans::XPropertySet
> xGraphicObjectProperties(
1170 m_xTextFactory
->createInstance("com.sun.star.text.TextGraphicObject"),
1171 uno::UNO_QUERY_THROW
);
1172 xGraphicObjectProperties
->setPropertyValue(getPropertyName(PROP_GRAPHIC
), uno::makeAny(rxGraphic
));
1173 xGraphicObjectProperties
->setPropertyValue(getPropertyName(PROP_ANCHOR_TYPE
),
1174 uno::makeAny( m_pImpl
->eGraphicImportType
== IMPORT_AS_DETECTED_ANCHOR
?
1175 text::TextContentAnchorType_AT_CHARACTER
:
1176 text::TextContentAnchorType_AS_CHARACTER
));
1177 xGraphicObject
.set( xGraphicObjectProperties
, uno::UNO_QUERY_THROW
);
1179 //shapes have only one border
1180 table::BorderLine2 aBorderLine
;
1181 GraphicBorderLine
& rBorderLine
= m_pImpl
->aBorders
[0];
1182 if (rBorderLine
.isEmpty() && xShapeProps
.is() && xShapeProps
->getPropertyValue("LineStyle").get
<drawing::LineStyle
>() != drawing::LineStyle_NONE
)
1184 // In case we got no border tokens and we have the
1185 // original shape, then use its line properties as the
1187 aBorderLine
.Color
= xShapeProps
->getPropertyValue("LineColor").get
<sal_Int32
>();
1188 aBorderLine
.LineWidth
= xShapeProps
->getPropertyValue("LineWidth").get
<sal_Int32
>();
1192 aBorderLine
.Color
= 0;
1193 aBorderLine
.InnerLineWidth
= 0;
1194 aBorderLine
.OuterLineWidth
= static_cast<sal_Int16
>(rBorderLine
.nLineWidth
);
1195 aBorderLine
.LineDistance
= 0;
1197 PropertyIds
const aBorderProps
[] =
1205 for(PropertyIds
const & rBorderProp
: aBorderProps
)
1206 xGraphicObjectProperties
->setPropertyValue(getPropertyName(rBorderProp
), uno::makeAny(aBorderLine
));
1208 // setting graphic object shadow properties
1209 if (m_pImpl
->bShadow
)
1211 // Shadow width is approximated by average of X and Y
1212 table::ShadowFormat aShadow
;
1213 sal_uInt32 nShadowColor
= m_pImpl
->nShadowColor
& 0x00FFFFFF; // The shadow color we get is RGB only.
1214 sal_Int32 nShadowWidth
= (abs(m_pImpl
->nShadowXDistance
)
1215 + abs(m_pImpl
->nShadowYDistance
)) / 2;
1217 aShadow
.ShadowWidth
= nShadowWidth
;
1218 sal_uInt8 nShadowTransparence
= float(m_pImpl
->nShadowTransparence
) * 2.55;
1219 nShadowColor
|= (nShadowTransparence
<< 24); // Add transparence to the color.
1220 aShadow
.Color
= nShadowColor
;
1221 // Distances -ve for top and right, +ve for bottom and left
1222 if (m_pImpl
->nShadowXDistance
> 0)
1224 if (m_pImpl
->nShadowYDistance
> 0)
1225 aShadow
.Location
= table::ShadowLocation_BOTTOM_RIGHT
;
1227 aShadow
.Location
= table::ShadowLocation_TOP_RIGHT
;
1231 if (m_pImpl
->nShadowYDistance
> 0)
1232 aShadow
.Location
= table::ShadowLocation_BOTTOM_LEFT
;
1234 aShadow
.Location
= table::ShadowLocation_TOP_LEFT
;
1237 xGraphicObjectProperties
->setPropertyValue(getPropertyName(PROP_SHADOW_FORMAT
), uno::makeAny(aShadow
));
1240 // setting properties for all types
1241 if( m_pImpl
->bPositionProtected
)
1242 xGraphicObjectProperties
->setPropertyValue(getPropertyName( PROP_POSITION_PROTECTED
),
1243 uno::makeAny(true));
1244 if( m_pImpl
->bSizeProtected
)
1245 xGraphicObjectProperties
->setPropertyValue(getPropertyName( PROP_SIZE_PROTECTED
),
1246 uno::makeAny(true));
1248 sal_Int32 nWidth
= - m_pImpl
->nLeftPosition
;
1249 if (m_pImpl
->eGraphicImportType
== IMPORT_AS_DETECTED_ANCHOR
)
1252 if( (m_pImpl
->nHoriOrient
== text::HoriOrientation::LEFT
&&
1253 (m_pImpl
->nHoriRelation
== text::RelOrientation::PAGE_PRINT_AREA
||
1254 m_pImpl
->nHoriRelation
== text::RelOrientation::FRAME
) ) ||
1255 (m_pImpl
->nHoriOrient
== text::HoriOrientation::INSIDE
&&
1256 m_pImpl
->nHoriRelation
== text::RelOrientation::PAGE_PRINT_AREA
))
1257 m_pImpl
->nLeftMargin
= 0;
1258 if((m_pImpl
->nHoriOrient
== text::HoriOrientation::RIGHT
&&
1259 (m_pImpl
->nHoriRelation
== text::RelOrientation::PAGE_PRINT_AREA
||
1260 m_pImpl
->nHoriRelation
== text::RelOrientation::FRAME
) ) ||
1261 (m_pImpl
->nHoriOrient
== text::HoriOrientation::INSIDE
&&
1262 m_pImpl
->nHoriRelation
== text::RelOrientation::PAGE_PRINT_AREA
))
1263 m_pImpl
->nRightMargin
= 0;
1264 // adjust top/bottom margins
1265 if( m_pImpl
->nVertOrient
== text::VertOrientation::TOP
&&
1266 ( m_pImpl
->nVertRelation
== text::RelOrientation::PAGE_PRINT_AREA
||
1267 m_pImpl
->nVertRelation
== text::RelOrientation::PAGE_FRAME
))
1268 m_pImpl
->nTopMargin
= 0;
1269 if( m_pImpl
->nVertOrient
== text::VertOrientation::BOTTOM
&&
1270 ( m_pImpl
->nVertRelation
== text::RelOrientation::PAGE_PRINT_AREA
||
1271 m_pImpl
->nVertRelation
== text::RelOrientation::PAGE_FRAME
))
1272 m_pImpl
->nBottomMargin
= 0;
1273 if( m_pImpl
->nVertOrient
== text::VertOrientation::BOTTOM
&&
1274 m_pImpl
->nVertRelation
== text::RelOrientation::PAGE_PRINT_AREA
)
1275 m_pImpl
->nBottomMargin
= 0;
1277 if( m_pImpl
->nHoriOrient
== text::HoriOrientation::INSIDE
&&
1278 m_pImpl
->nHoriRelation
== text::RelOrientation::PAGE_FRAME
)
1280 // convert 'left to page' to 'from left -<width> to page text area'
1281 m_pImpl
->nHoriOrient
= text::HoriOrientation::NONE
;
1282 m_pImpl
->nHoriRelation
= text::RelOrientation::PAGE_PRINT_AREA
;
1283 m_pImpl
->nLeftPosition
= - nWidth
;
1285 else if( m_pImpl
->nHoriOrient
== text::HoriOrientation::OUTSIDE
&&
1286 m_pImpl
->nHoriRelation
== text::RelOrientation::PAGE_FRAME
)
1288 // convert 'right to page' to 'from left 0 to right page border'
1289 m_pImpl
->nHoriOrient
= text::HoriOrientation::NONE
;
1290 m_pImpl
->nHoriRelation
= text::RelOrientation::PAGE_RIGHT
;
1291 m_pImpl
->nLeftPosition
= 0;
1294 m_pImpl
->applyPosition(xGraphicObjectProperties
);
1295 m_pImpl
->applyRelativePosition(xGraphicObjectProperties
);
1296 if( !m_pImpl
->bOpaque
)
1298 xGraphicObjectProperties
->setPropertyValue(getPropertyName( PROP_OPAQUE
), uno::makeAny(m_pImpl
->bOpaque
));
1300 xGraphicObjectProperties
->setPropertyValue(getPropertyName( PROP_SURROUND
),
1301 uno::makeAny(static_cast<sal_Int32
>(m_pImpl
->nWrap
)));
1302 if( m_pImpl
->rDomainMapper
.IsInTable() && m_pImpl
->bLayoutInCell
&& m_pImpl
->nWrap
!= text::WrapTextMode_THROUGH
)
1303 xGraphicObjectProperties
->setPropertyValue(getPropertyName( PROP_FOLLOW_TEXT_FLOW
),
1304 uno::makeAny(true));
1305 if( m_pImpl
->rDomainMapper
.IsInTable() && m_pImpl
->bLayoutInCell
)
1307 xGraphicObjectProperties
->setPropertyValue(getPropertyName( PROP_LAYOUT_IN_CELL
),
1308 uno::makeAny(true));
1311 xGraphicObjectProperties
->setPropertyValue(getPropertyName( PROP_SURROUND_CONTOUR
),
1312 uno::makeAny(m_pImpl
->bContour
));
1313 xGraphicObjectProperties
->setPropertyValue(getPropertyName( PROP_CONTOUR_OUTSIDE
),
1314 uno::makeAny(m_pImpl
->bContourOutside
));
1315 m_pImpl
->applyMargins(xGraphicObjectProperties
);
1318 if( m_pImpl
->eColorMode
== drawing::ColorMode_WATERMARK
&&
1319 m_pImpl
->nContrast
== -70 &&
1320 m_pImpl
->nBrightness
== 70 )
1322 // watermark filter is already applied at this point, so reset Contrast and Brightness
1323 m_pImpl
->nContrast
= 0;
1324 m_pImpl
->nBrightness
= 0;
1327 xGraphicObjectProperties
->setPropertyValue(getPropertyName( PROP_ADJUST_CONTRAST
),
1328 uno::makeAny(static_cast<sal_Int16
>(m_pImpl
->nContrast
)));
1329 xGraphicObjectProperties
->setPropertyValue(getPropertyName( PROP_ADJUST_LUMINANCE
),
1330 uno::makeAny(static_cast<sal_Int16
>(m_pImpl
->nBrightness
)));
1331 if(m_pImpl
->eColorMode
!= drawing::ColorMode_STANDARD
)
1333 xGraphicObjectProperties
->setPropertyValue(getPropertyName( PROP_GRAPHIC_COLOR_MODE
),
1334 uno::makeAny(m_pImpl
->eColorMode
));
1337 xGraphicObjectProperties
->setPropertyValue(getPropertyName( PROP_BACK_COLOR
),
1338 uno::makeAny( GraphicImport_Impl::nFillColor
));
1340 m_pImpl
->applyZOrder(xGraphicObjectProperties
);
1342 //there seems to be no way to detect the original size via _real_ API
1343 uno::Reference
< beans::XPropertySet
> xGraphicProperties(rxGraphic
, uno::UNO_QUERY_THROW
);
1345 if (m_pImpl
->mpWrapPolygon
.get() != nullptr)
1347 uno::Any aContourPolyPolygon
;
1348 awt::Size aGraphicSize
;
1349 WrapPolygon::Pointer_t pCorrected
;
1350 xGraphicProperties
->getPropertyValue(getPropertyName(PROP_SIZE100th_M_M
)) >>= aGraphicSize
;
1351 if (aGraphicSize
.Width
&& aGraphicSize
.Height
)
1353 pCorrected
= m_pImpl
->mpWrapPolygon
->correctWordWrapPolygon(aGraphicSize
);
1357 xGraphicProperties
->getPropertyValue(getPropertyName(PROP_SIZE_PIXEL
)) >>= aGraphicSize
;
1358 if (aGraphicSize
.Width
&& aGraphicSize
.Height
)
1360 pCorrected
= m_pImpl
->mpWrapPolygon
->correctWordWrapPolygonPixel(aGraphicSize
);
1365 aContourPolyPolygon
<<= pCorrected
->getPointSequenceSequence();
1366 xGraphicObjectProperties
->setPropertyValue(getPropertyName(PROP_CONTOUR_POLY_POLYGON
),
1367 aContourPolyPolygon
);
1368 // We should bring it to front, even if wp:anchor's behindDoc="1",
1369 // because otherwise paragraph background (if set) overlaps the graphic
1370 // TODO: if paragraph's background becomes bottommost, then remove this hack
1371 xGraphicObjectProperties
->setPropertyValue("Opaque", uno::makeAny(true));
1376 if(m_pImpl
->eGraphicImportType
== IMPORT_AS_DETECTED_INLINE
|| m_pImpl
->eGraphicImportType
== IMPORT_AS_DETECTED_ANCHOR
)
1378 if( m_pImpl
->getXSize() && m_pImpl
->getYSize() )
1379 xGraphicObjectProperties
->setPropertyValue(getPropertyName(PROP_SIZE
),
1380 uno::makeAny( awt::Size( m_pImpl
->getXSize(), m_pImpl
->getYSize() )));
1381 m_pImpl
->applyMargins(xGraphicObjectProperties
);
1382 m_pImpl
->applyName(xGraphicObjectProperties
);
1385 // Handle horizontal flip.
1386 bool bMirrored
= false;
1387 xShapeProps
->getPropertyValue("IsMirrored") >>= bMirrored
;
1390 xGraphicObjectProperties
->setPropertyValue("HoriMirroredOnEvenPages",
1391 uno::makeAny(true));
1392 xGraphicObjectProperties
->setPropertyValue("HoriMirroredOnOddPages",
1393 uno::makeAny(true));
1397 catch( const uno::Exception
& e
)
1399 SAL_WARN("writerfilter", "failed. Message :" << e
);
1401 return xGraphicObject
;
1405 void GraphicImport::data(const sal_uInt8
* buf
, size_t len
, writerfilter::Reference
<Properties
>::Pointer_t
/*ref*/)
1407 beans::PropertyValues
aMediaProperties( 1 );
1408 aMediaProperties
[0].Name
= getPropertyName(PROP_INPUT_STREAM
);
1410 uno::Reference
< io::XInputStream
> xIStream
= new XInputStreamHelper( buf
, len
);
1411 aMediaProperties
[0].Value
<<= xIStream
;
1413 uno::Reference
<beans::XPropertySet
> xPropertySet
;
1414 uno::Reference
<graphic::XGraphicProvider
> xGraphicProvider(graphic::GraphicProvider::create(m_xComponentContext
));
1415 uno::Reference
<graphic::XGraphic
> xGraphic
= xGraphicProvider
->queryGraphic(aMediaProperties
);
1416 m_xGraphicObject
= createGraphicObject(xGraphic
, xPropertySet
);
1420 void GraphicImport::lcl_startSectionGroup()
1425 void GraphicImport::lcl_endSectionGroup()
1430 void GraphicImport::lcl_startParagraphGroup()
1435 void GraphicImport::lcl_endParagraphGroup()
1440 void GraphicImport::lcl_startCharacterGroup()
1445 void GraphicImport::lcl_endCharacterGroup()
1450 void GraphicImport::lcl_text(const sal_uInt8
* /*_data*/, size_t /*len*/)
1455 void GraphicImport::lcl_utext(const sal_uInt8
* /*_data*/, size_t /*len*/)
1460 void GraphicImport::lcl_props(writerfilter::Reference
<Properties
>::Pointer_t
/*ref*/)
1465 void GraphicImport::lcl_table(Id
/*name*/, writerfilter::Reference
<Table
>::Pointer_t
/*ref*/)
1470 void GraphicImport::lcl_substream(Id
/*name*/, ::writerfilter::Reference
<Stream
>::Pointer_t
/*ref*/)
1474 void GraphicImport::lcl_info(const std::string
& /*info*/)
1478 void GraphicImport::lcl_startShape(uno::Reference
<drawing::XShape
> const&)
1482 void GraphicImport::lcl_endShape( )
1486 bool GraphicImport::IsGraphic() const
1488 return m_pImpl
->bIsGraphic
;
1491 sal_Int32
GraphicImport::GetLeftMarginOrig() const
1493 return m_pImpl
->nLeftMarginOrig
;
1499 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */