update emoji autocorrect entries from po-files
[LibreOffice.git] / writerfilter / source / dmapper / GraphicImport.cxx
blob1b0644d1eabca96164966cd38c94e25ddd17b190
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <string.h>
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/XInputStream.hpp>
32 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
33 #include <com/sun/star/lang/XServiceInfo.hpp>
34 #include <com/sun/star/table/BorderLine2.hpp>
35 #include <com/sun/star/text/GraphicCrop.hpp>
36 #include <com/sun/star/text/HoriOrientation.hpp>
37 #include <com/sun/star/text/RelOrientation.hpp>
38 #include <com/sun/star/text/TextContentAnchorType.hpp>
39 #include <com/sun/star/text/VertOrientation.hpp>
40 #include <com/sun/star/text/WrapTextMode.hpp>
41 #include <com/sun/star/text/XTextContent.hpp>
42 #include <com/sun/star/uno/XComponentContext.hpp>
43 #include <com/sun/star/table/ShadowFormat.hpp>
45 #include <svx/svdobj.hxx>
46 #include <svx/unoapi.hxx>
47 #include <cppuhelper/implbase.hxx>
48 #include <rtl/ustrbuf.hxx>
49 #include <rtl/math.hxx>
50 #include <comphelper/string.hxx>
51 #include <comphelper/sequenceashashmap.hxx>
52 #include <comphelper/sequence.hxx>
54 #include <oox/drawingml/drawingmltypes.hxx>
56 #include <DomainMapper.hxx>
57 #include <dmapper/GraphicZOrderHelper.hxx>
58 #include <ooxml/resourceids.hxx>
60 #include "ConversionHelper.hxx"
61 #include "GraphicHelpers.hxx"
62 #include "GraphicImport.hxx"
63 #include "PropertyMap.hxx"
64 #include "WrapPolygonHandler.hxx"
65 #include "util.hxx"
67 namespace writerfilter {
69 namespace dmapper
71 using namespace css;
73 class XInputStreamHelper : public cppu::WeakImplHelper<io::XInputStream>
75 const sal_uInt8* m_pBuffer;
76 const sal_Int32 m_nLength;
77 sal_Int32 m_nPosition;
78 bool m_bBmp;
80 const sal_uInt8* m_pBMPHeader; //default BMP-header
81 sal_Int32 m_nHeaderLength;
82 public:
83 XInputStreamHelper(const sal_uInt8* buf, size_t len, bool bBmp);
84 virtual ~XInputStreamHelper();
86 virtual ::sal_Int32 SAL_CALL readBytes( uno::Sequence< ::sal_Int8 >& aData, ::sal_Int32 nBytesToRead ) throw (io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException, std::exception) SAL_OVERRIDE;
87 virtual ::sal_Int32 SAL_CALL readSomeBytes( uno::Sequence< ::sal_Int8 >& aData, ::sal_Int32 nMaxBytesToRead ) throw (io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException, std::exception) SAL_OVERRIDE;
88 virtual void SAL_CALL skipBytes( ::sal_Int32 nBytesToSkip ) throw (io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException, std::exception) SAL_OVERRIDE;
89 virtual ::sal_Int32 SAL_CALL available( ) throw (io::NotConnectedException, io::IOException, uno::RuntimeException, std::exception) SAL_OVERRIDE;
90 virtual void SAL_CALL closeInput( ) throw (io::NotConnectedException, io::IOException, uno::RuntimeException, std::exception) SAL_OVERRIDE;
93 XInputStreamHelper::XInputStreamHelper(const sal_uInt8* buf, size_t len, bool bBmp) :
94 m_pBuffer( buf ),
95 m_nLength( len ),
96 m_nPosition( 0 ),
97 m_bBmp( bBmp )
99 static const sal_uInt8 aHeader[] =
100 {0x42, 0x4d, 0xe6, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 };
101 m_pBMPHeader = aHeader;
102 m_nHeaderLength = m_bBmp ? sizeof( aHeader ) / sizeof(sal_uInt8) : 0;
106 XInputStreamHelper::~XInputStreamHelper()
110 sal_Int32 XInputStreamHelper::readBytes( uno::Sequence<sal_Int8>& aData, sal_Int32 nBytesToRead )
111 throw (io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException, std::exception)
113 return readSomeBytes( aData, nBytesToRead );
116 sal_Int32 XInputStreamHelper::readSomeBytes( uno::Sequence<sal_Int8>& aData, sal_Int32 nMaxBytesToRead )
117 throw (io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException, std::exception)
119 sal_Int32 nRet = 0;
120 if( nMaxBytesToRead > 0 )
122 if( nMaxBytesToRead > (m_nLength + m_nHeaderLength) - m_nPosition )
123 nRet = (m_nLength + m_nHeaderLength) - m_nPosition;
124 else
125 nRet = nMaxBytesToRead;
126 aData.realloc( nRet );
127 sal_Int8* pData = aData.getArray();
128 sal_Int32 nHeaderRead = 0;
129 if( m_nPosition < m_nHeaderLength)
131 //copy header content first
132 nHeaderRead = m_nHeaderLength - m_nPosition;
133 memcpy( pData, m_pBMPHeader + (m_nPosition ), nHeaderRead );
134 nRet -= nHeaderRead;
135 m_nPosition += nHeaderRead;
137 if( nRet )
139 memcpy( pData + nHeaderRead, m_pBuffer + (m_nPosition - m_nHeaderLength), nRet );
140 m_nPosition += nRet;
143 return nRet;
147 void XInputStreamHelper::skipBytes( sal_Int32 nBytesToSkip ) throw (io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException, std::exception)
149 if( nBytesToSkip < 0 || m_nPosition + nBytesToSkip > (m_nLength + m_nHeaderLength))
150 throw io::BufferSizeExceededException();
151 m_nPosition += nBytesToSkip;
155 sal_Int32 XInputStreamHelper::available( ) throw (io::NotConnectedException, io::IOException, uno::RuntimeException, std::exception)
157 return ( m_nLength + m_nHeaderLength ) - m_nPosition;
161 void XInputStreamHelper::closeInput( ) throw (io::NotConnectedException, io::IOException, uno::RuntimeException, std::exception)
166 struct GraphicBorderLine
168 sal_Int32 nLineWidth;
169 sal_Int32 nLineColor;
170 sal_Int32 nLineDistance;
171 bool bHasShadow;
173 GraphicBorderLine() :
174 nLineWidth(0)
175 ,nLineColor(0)
176 ,nLineDistance(0)
177 ,bHasShadow(false)
180 bool isEmpty()
182 return nLineWidth == 0 && nLineColor == 0 && !bHasShadow;
187 class GraphicImport_Impl
189 private:
190 sal_Int32 nXSize;
191 bool bXSizeValid;
192 sal_Int32 nYSize;
193 bool bYSizeValid;
195 public:
196 GraphicImportType eGraphicImportType;
197 DomainMapper& rDomainMapper;
199 sal_Int32 nHoriScaling;
200 sal_Int32 nVertScaling;
201 sal_Int32 nLeftPosition;
202 sal_Int32 nTopPosition;
203 sal_Int32 nRightPosition;
204 sal_Int32 nBottomPosition;
206 bool bUseSimplePos;
207 sal_Int32 zOrder;
209 sal_Int16 nHoriOrient;
210 sal_Int16 nHoriRelation;
211 bool bPageToggle;
212 sal_Int16 nVertOrient;
213 sal_Int16 nVertRelation;
214 sal_Int32 nWrap;
215 bool bLayoutInCell;
216 bool bOpaque;
217 bool bContour;
218 bool bContourOutside;
219 WrapPolygon::Pointer_t mpWrapPolygon;
220 bool bIgnoreWRK;
222 sal_Int32 nLeftMargin;
223 sal_Int32 nRightMargin;
224 sal_Int32 nTopMargin;
225 sal_Int32 nBottomMargin;
227 bool bShadow;
228 sal_Int32 nShadowXDistance;
229 sal_Int32 nShadowYDistance;
230 sal_Int32 nShadowColor;
231 sal_Int32 nShadowTransparence;
233 sal_Int32 nContrast;
234 sal_Int32 nBrightness;
235 double fGamma;
237 sal_Int32 nFillColor;
239 drawing::ColorMode eColorMode;
241 GraphicBorderLine aBorders[4];
242 sal_Int32 nCurrentBorderLine;
244 sal_Int32 nDffType;
245 bool bIsGraphic;
246 bool bIsBitmap;
247 bool bIsTiff;
248 sal_Int32 nBitsPerPixel;
250 bool bHoriFlip;
251 bool bVertFlip;
253 bool bSizeProtected;
254 bool bPositionProtected;
256 sal_Int32 nShapeOptionType;
258 OUString sName;
259 OUString sAlternativeText;
260 OUString title;
261 std::pair<OUString, OUString>& m_rPositionOffsets;
262 std::pair<OUString, OUString>& m_rAligns;
263 std::queue<OUString>& m_rPositivePercentages;
264 OUString sAnchorId;
265 comphelper::SequenceAsHashMap m_aInteropGrabBag;
266 boost::optional<sal_Int32> m_oEffectExtentLeft;
267 boost::optional<sal_Int32> m_oEffectExtentTop;
268 boost::optional<sal_Int32> m_oEffectExtentRight;
269 boost::optional<sal_Int32> m_oEffectExtentBottom;
271 GraphicImport_Impl(GraphicImportType eImportType, DomainMapper& rDMapper, std::pair<OUString, OUString>& rPositionOffsets, std::pair<OUString, OUString>& rAligns, std::queue<OUString>& rPositivePercentages) :
272 nXSize(0)
273 ,bXSizeValid(false)
274 ,nYSize(0)
275 ,bYSizeValid(false)
276 ,eGraphicImportType( eImportType )
277 ,rDomainMapper( rDMapper )
278 ,nHoriScaling(0)
279 ,nVertScaling(0)
280 ,nLeftPosition(0)
281 ,nTopPosition(0)
282 ,nRightPosition(0)
283 ,nBottomPosition(0)
284 ,bUseSimplePos(false)
285 ,zOrder(-1)
286 ,nHoriOrient( text::HoriOrientation::NONE )
287 ,nHoriRelation( text::RelOrientation::FRAME )
288 ,bPageToggle( false )
289 ,nVertOrient( text::VertOrientation::NONE )
290 ,nVertRelation( text::RelOrientation::FRAME )
291 ,nWrap(0)
292 ,bLayoutInCell(false)
293 ,bOpaque( true )
294 ,bContour(false)
295 ,bContourOutside(true)
296 ,bIgnoreWRK(true)
297 ,nLeftMargin(319)
298 ,nRightMargin(319)
299 ,nTopMargin(0)
300 ,nBottomMargin(0)
301 ,bShadow(false)
302 ,nShadowXDistance(0)
303 ,nShadowYDistance(0)
304 ,nShadowColor(0)
305 ,nShadowTransparence(0)
306 ,nContrast(0)
307 ,nBrightness(0)
308 ,fGamma( -1.0 )
309 ,nFillColor( 0xffffffff )
310 ,eColorMode( drawing::ColorMode_STANDARD )
311 ,nCurrentBorderLine(BORDER_TOP)
312 ,nDffType( 0 )
313 ,bIsGraphic(false)
314 ,bIsBitmap(false)
315 ,bIsTiff(false)
316 ,nBitsPerPixel(0)
317 ,bHoriFlip(false)
318 ,bVertFlip(false)
319 ,bSizeProtected(false)
320 ,bPositionProtected(false)
321 ,nShapeOptionType(0)
322 ,m_rPositionOffsets(rPositionOffsets)
323 ,m_rAligns(rAligns)
324 ,m_rPositivePercentages(rPositivePercentages)
327 void setXSize(sal_Int32 _nXSize)
329 nXSize = _nXSize;
330 bXSizeValid = true;
333 sal_uInt32 getXSize() const
335 return nXSize;
338 bool isXSizeValid() const
340 return bXSizeValid;
343 void setYSize(sal_Int32 _nYSize)
345 nYSize = _nYSize;
346 bYSizeValid = true;
349 sal_uInt32 getYSize() const
351 return nYSize;
354 bool isYSizeValis () const
356 return bYSizeValid;
359 void applyMargins(uno::Reference< beans::XPropertySet > xGraphicObjectProperties) const
361 PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
362 xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName( PROP_LEFT_MARGIN ), uno::makeAny(nLeftMargin));
363 xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName( PROP_RIGHT_MARGIN ), uno::makeAny(nRightMargin));
364 xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName( PROP_TOP_MARGIN ), uno::makeAny(nTopMargin));
365 xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName( PROP_BOTTOM_MARGIN ), uno::makeAny(nBottomMargin));
368 void applyPosition(uno::Reference< beans::XPropertySet > xGraphicObjectProperties) const
370 PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
371 xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName( PROP_HORI_ORIENT ),
372 uno::makeAny(nHoriOrient));
373 xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName( PROP_VERT_ORIENT ),
374 uno::makeAny(nVertOrient));
377 void applyRelativePosition(uno::Reference< beans::XPropertySet > xGraphicObjectProperties, bool bRelativeOnly = false) const
379 PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
380 if (!bRelativeOnly)
381 xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName( PROP_HORI_ORIENT_POSITION),
382 uno::makeAny(nLeftPosition));
383 xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName( PROP_HORI_ORIENT_RELATION ),
384 uno::makeAny(nHoriRelation));
385 xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName( PROP_PAGE_TOGGLE ),
386 uno::makeAny(bPageToggle));
387 if (!bRelativeOnly)
388 xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName( PROP_VERT_ORIENT_POSITION),
389 uno::makeAny(nTopPosition));
390 xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName( PROP_VERT_ORIENT_RELATION ),
391 uno::makeAny(nVertRelation));
394 void applyZOrder(uno::Reference<beans::XPropertySet>& xGraphicObjectProperties) const
396 PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
397 if (zOrder >= 0)
399 GraphicZOrderHelper* pZOrderHelper = rDomainMapper.graphicZOrderHelper();
400 xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName(PROP_Z_ORDER), uno::makeAny(pZOrderHelper->findZOrder(zOrder)));
401 pZOrderHelper->addItem(xGraphicObjectProperties, zOrder);
405 void applyName(uno::Reference<beans::XPropertySet>& xGraphicObjectProperties) const
407 PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
410 if( !sName.isEmpty() )
412 uno::Reference< container::XNamed > xNamed( xGraphicObjectProperties, uno::UNO_QUERY_THROW );
413 xNamed->setName( sName );
415 xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName( PROP_DESCRIPTION ),
416 uno::makeAny( sAlternativeText ));
417 xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName( PROP_TITLE ),
418 uno::makeAny( title ));
420 catch( const uno::Exception& e )
422 SAL_WARN("writerfilter", "failed. Message :" << e.Message);
426 /// Getter for m_aInteropGrabBag, but also merges in the values from other members if they are set.
427 comphelper::SequenceAsHashMap getInteropGrabBag()
429 comphelper::SequenceAsHashMap aEffectExtent;
430 if (m_oEffectExtentLeft)
431 aEffectExtent["l"] <<= *m_oEffectExtentLeft;
432 if (m_oEffectExtentTop)
433 aEffectExtent["t"] <<= *m_oEffectExtentTop;
434 if (m_oEffectExtentRight)
435 aEffectExtent["r"] <<= *m_oEffectExtentRight;
436 if (m_oEffectExtentBottom)
437 aEffectExtent["b"] <<= *m_oEffectExtentBottom;
438 if (!aEffectExtent.empty())
439 m_aInteropGrabBag["CT_EffectExtent"] <<= aEffectExtent.getAsConstPropertyValueList();
440 return m_aInteropGrabBag;
444 GraphicImport::GraphicImport(uno::Reference<uno::XComponentContext> const& xComponentContext,
445 uno::Reference<lang::XMultiServiceFactory> const& xTextFactory,
446 DomainMapper& rDMapper,
447 GraphicImportType eImportType,
448 std::pair<OUString, OUString>& rPositionOffsets,
449 std::pair<OUString, OUString>& rAligns,
450 std::queue<OUString>& rPositivePercentages)
451 : LoggedProperties("GraphicImport")
452 , LoggedTable("GraphicImport")
453 , LoggedStream("GraphicImport")
454 , m_pImpl(new GraphicImport_Impl(eImportType, rDMapper, rPositionOffsets, rAligns, rPositivePercentages))
455 , m_xComponentContext(xComponentContext)
456 , m_xTextFactory(xTextFactory)
460 GraphicImport::~GraphicImport()
464 void GraphicImport::handleWrapTextValue(sal_uInt32 nVal)
466 switch (nVal)
468 case NS_ooxml::LN_Value_wordprocessingDrawing_ST_WrapText_bothSides: // 90920;
469 m_pImpl->nWrap = text::WrapTextMode_PARALLEL;
470 break;
471 case NS_ooxml::LN_Value_wordprocessingDrawing_ST_WrapText_left: // 90921;
472 m_pImpl->nWrap = text::WrapTextMode_LEFT;
473 break;
474 case NS_ooxml::LN_Value_wordprocessingDrawing_ST_WrapText_right: // 90922;
475 m_pImpl->nWrap = text::WrapTextMode_RIGHT;
476 break;
477 case NS_ooxml::LN_Value_wordprocessingDrawing_ST_WrapText_largest: // 90923;
478 m_pImpl->nWrap = text::WrapTextMode_DYNAMIC;
479 break;
480 default:;
484 void GraphicImport::putPropertyToFrameGrabBag( const OUString& sPropertyName, const uno::Any& aPropertyValue )
486 beans::PropertyValue pProperty;
487 pProperty.Name = sPropertyName;
488 pProperty.Value = aPropertyValue;
490 if (!m_xShape.is())
491 return;
493 uno::Reference< beans::XPropertySet > xSet(m_xShape, uno::UNO_QUERY_THROW);
494 if (!xSet.is())
495 return;
497 uno::Reference< beans::XPropertySetInfo > xSetInfo(xSet->getPropertySetInfo());
498 if (!xSetInfo.is())
499 return;
501 OUString aGrabBagPropName;
502 uno::Reference<lang::XServiceInfo> xServiceInfo(m_xShape, uno::UNO_QUERY_THROW);
503 if (xServiceInfo->supportsService("com.sun.star.text.TextFrame"))
504 aGrabBagPropName = "FrameInteropGrabBag";
505 else
506 aGrabBagPropName = "InteropGrabBag";
508 if (xSetInfo->hasPropertyByName(aGrabBagPropName))
510 //Add pProperty to the end of the Sequence for aGrabBagPropName
511 uno::Sequence<beans::PropertyValue> aTmp;
512 xSet->getPropertyValue(aGrabBagPropName) >>= aTmp;
513 std::vector<beans::PropertyValue> aGrabBag(comphelper::sequenceToContainer<std::vector<beans::PropertyValue> >(aTmp));
514 aGrabBag.push_back(pProperty);
516 xSet->setPropertyValue(aGrabBagPropName, uno::makeAny(comphelper::containerToSequence(aGrabBag)));
520 void GraphicImport::lcl_attribute(Id nName, Value& rValue)
522 sal_Int32 nIntValue = rValue.getInt();
523 switch( nName )
525 case NS_ooxml::LN_blip: //the binary graphic data in a shape
527 writerfilter::Reference<Properties>::Pointer_t pProperties = rValue.getProperties();
528 if( pProperties.get())
530 pProperties->resolve(*this);
533 break;
534 case NS_ooxml::LN_payload :
536 writerfilter::Reference<BinaryObj>::Pointer_t pPictureData = rValue.getBinary();
537 if( pPictureData.get())
538 pPictureData->resolve(*this);
540 break;
542 //border properties
543 case NS_ooxml::LN_CT_Border_sz:
544 m_pImpl->aBorders[m_pImpl->nCurrentBorderLine].nLineWidth = nIntValue;
545 break;
546 case NS_ooxml::LN_CT_Border_val:
547 //graphic borders don't support different line types
548 break;
549 case NS_ooxml::LN_CT_Border_space:
550 m_pImpl->aBorders[m_pImpl->nCurrentBorderLine].nLineDistance = nIntValue;
551 break;
552 case NS_ooxml::LN_CT_Border_shadow:
553 m_pImpl->aBorders[m_pImpl->nCurrentBorderLine].bHasShadow = nIntValue != 0;
554 break;
555 case NS_ooxml::LN_CT_Border_frame:
556 break;
557 case NS_ooxml::LN_CT_PositiveSize2D_cx:
558 case NS_ooxml::LN_CT_PositiveSize2D_cy:
560 sal_Int32 nDim = oox::drawingml::convertEmuToHmm(nIntValue);
561 if( nName == NS_ooxml::LN_CT_PositiveSize2D_cx )
562 m_pImpl->setXSize(nDim);
563 else
564 m_pImpl->setYSize(nDim);
566 break;
567 case NS_ooxml::LN_CT_EffectExtent_l:
568 m_pImpl->m_oEffectExtentLeft = nIntValue;
569 m_pImpl->nLeftMargin += oox::drawingml::convertEmuToHmm(nIntValue);
570 break;
571 case NS_ooxml::LN_CT_EffectExtent_t:
572 m_pImpl->m_oEffectExtentTop = nIntValue;
573 m_pImpl->nTopMargin += oox::drawingml::convertEmuToHmm(nIntValue);
574 break;
575 case NS_ooxml::LN_CT_EffectExtent_r:
576 m_pImpl->m_oEffectExtentRight = nIntValue;
577 m_pImpl->nRightMargin += oox::drawingml::convertEmuToHmm(nIntValue);
578 break;
579 case NS_ooxml::LN_CT_EffectExtent_b:
580 m_pImpl->m_oEffectExtentBottom = nIntValue;
581 m_pImpl->nBottomMargin += oox::drawingml::convertEmuToHmm(nIntValue);
582 break;
583 case NS_ooxml::LN_CT_NonVisualDrawingProps_id:// 90650;
584 //id of the object - ignored
585 break;
586 case NS_ooxml::LN_CT_NonVisualDrawingProps_name:// 90651;
587 //name of the object
588 m_pImpl->sName = rValue.getString();
589 break;
590 case NS_ooxml::LN_CT_NonVisualDrawingProps_descr:// 90652;
591 //alternative text
592 m_pImpl->sAlternativeText = rValue.getString();
593 break;
594 case NS_ooxml::LN_CT_NonVisualDrawingProps_title:
595 //alternative text
596 m_pImpl->title = rValue.getString();
597 break;
598 case NS_ooxml::LN_CT_GraphicalObjectFrameLocking_noChangeAspect://90644;
599 //disallow aspect ratio change - ignored
600 break;
601 case NS_ooxml::LN_CT_GraphicalObjectFrameLocking_noMove:// 90645;
602 m_pImpl->bPositionProtected = true;
603 break;
604 case NS_ooxml::LN_CT_GraphicalObjectFrameLocking_noResize: // 90646;
605 m_pImpl->bSizeProtected = true;
606 break;
607 case NS_ooxml::LN_CT_Anchor_distT: // 90983;
608 case NS_ooxml::LN_CT_Anchor_distB: // 90984;
609 case NS_ooxml::LN_CT_Anchor_distL: // 90985;
610 case NS_ooxml::LN_CT_Anchor_distR: // 90986;
612 m_pImpl->nShapeOptionType = nName;
613 ProcessShapeOptions(rValue);
615 break;
616 case NS_ooxml::LN_CT_Anchor_simplePos_attr: // 90987;
617 m_pImpl->bUseSimplePos = nIntValue > 0;
618 break;
619 case NS_ooxml::LN_CT_Anchor_relativeHeight: // 90988;
620 m_pImpl->zOrder = nIntValue;
621 break;
622 case NS_ooxml::LN_CT_Anchor_behindDoc: // 90989; - in background
623 if( nIntValue > 0 )
624 m_pImpl->bOpaque = false;
625 break;
626 case NS_ooxml::LN_CT_Anchor_locked: // 90990; - ignored
627 break;
628 case NS_ooxml::LN_CT_Anchor_layoutInCell: // 90991; - ignored
629 m_pImpl->bLayoutInCell = nIntValue != 0;
630 break;
631 case NS_ooxml::LN_CT_Anchor_hidden: // 90992; - ignored
632 break;
633 case NS_ooxml::LN_CT_Anchor_allowOverlap: // 90993;
634 //enable overlapping - ignored
635 break;
636 case NS_ooxml::LN_CT_Anchor_wp14_anchorId:
637 case NS_ooxml::LN_CT_Inline_wp14_anchorId:
639 OUStringBuffer aBuffer = OUString::number(nIntValue, 16);
640 OUStringBuffer aString;
641 comphelper::string::padToLength(aString, 8 - aBuffer.getLength(), '0');
642 aString.append(aBuffer.getStr());
643 m_pImpl->sAnchorId = aString.makeStringAndClear().toAsciiUpperCase();
645 break;
646 case NS_ooxml::LN_CT_Point2D_x: // 90405;
647 m_pImpl->nLeftPosition = ConversionHelper::convertTwipToMM100(nIntValue);
648 m_pImpl->nHoriRelation = text::RelOrientation::PAGE_FRAME;
649 m_pImpl->nHoriOrient = text::HoriOrientation::NONE;
650 break;
651 case NS_ooxml::LN_CT_Point2D_y: // 90406;
652 m_pImpl->nTopPosition = ConversionHelper::convertTwipToMM100(nIntValue);
653 m_pImpl->nVertRelation = text::RelOrientation::PAGE_FRAME;
654 m_pImpl->nVertOrient = text::VertOrientation::NONE;
655 break;
656 case NS_ooxml::LN_CT_WrapTight_wrapText: // 90934;
657 m_pImpl->bContour = true;
658 m_pImpl->bContourOutside = true;
660 handleWrapTextValue(rValue.getInt());
662 break;
663 case NS_ooxml::LN_CT_WrapThrough_wrapText:
664 m_pImpl->bContour = true;
665 m_pImpl->bContourOutside = false;
667 handleWrapTextValue(rValue.getInt());
669 break;
670 case NS_ooxml::LN_CT_WrapSquare_wrapText: //90928;
671 handleWrapTextValue(rValue.getInt());
672 break;
673 case NS_ooxml::LN_shape:
675 uno::Reference< drawing::XShape> xShape;
676 rValue.getAny( ) >>= xShape;
678 if ( xShape.is( ) )
680 // Is it a graphic image
681 bool bUseShape = true;
684 uno::Reference< beans::XPropertySet > xShapeProps
685 ( xShape, uno::UNO_QUERY_THROW );
687 OUString sUrl;
688 xShapeProps->getPropertyValue("GraphicURL") >>= sUrl;
690 sal_Int32 nRotation = 0;
691 xShapeProps->getPropertyValue("RotateAngle") >>= nRotation;
693 css::beans::PropertyValues aGrabBag;
694 bool bContainsEffects = false;
695 xShapeProps->getPropertyValue("InteropGrabBag") >>= aGrabBag;
696 for( sal_Int32 i = 0; i < aGrabBag.getLength(); ++i )
698 // if the shape contains effects in the grab bag, we should not transform it
699 // in a XTextContent so those effects can be preserved
700 if( aGrabBag[i].Name == "EffectProperties" || aGrabBag[i].Name == "3DEffectProperties" ||
701 aGrabBag[i].Name == "ArtisticEffectProperties" )
702 bContainsEffects = true;
705 beans::PropertyValues aMediaProperties( 1 );
706 aMediaProperties[0].Name = "URL";
707 aMediaProperties[0].Value <<= sUrl;
709 xShapeProps->getPropertyValue("Shadow") >>= m_pImpl->bShadow;
710 if (m_pImpl->bShadow)
712 xShapeProps->getPropertyValue("ShadowXDistance") >>= m_pImpl->nShadowXDistance;
713 xShapeProps->getPropertyValue("ShadowYDistance") >>= m_pImpl->nShadowYDistance;
714 xShapeProps->getPropertyValue("ShadowColor") >>= m_pImpl->nShadowColor;
715 xShapeProps->getPropertyValue("ShadowTransparence") >>= m_pImpl->nShadowTransparence;
718 xShapeProps->getPropertyValue("GraphicColorMode") >>= m_pImpl->eColorMode;
719 xShapeProps->getPropertyValue("AdjustLuminance") >>= m_pImpl->nBrightness;
720 xShapeProps->getPropertyValue("AdjustContrast") >>= m_pImpl->nContrast;
722 // fdo#70457: transform XShape into a SwXTextGraphicObject only if there's no rotation
723 if ( nRotation == 0 && !bContainsEffects )
724 m_xGraphicObject = createGraphicObject( aMediaProperties, xShapeProps );
726 bUseShape = !m_xGraphicObject.is( );
728 if ( !bUseShape )
730 // Define the object size
731 uno::Reference< beans::XPropertySet > xGraphProps( m_xGraphicObject,
732 uno::UNO_QUERY );
733 awt::Size aSize = xShape->getSize( );
734 xGraphProps->setPropertyValue("Height",
735 uno::makeAny( aSize.Height ) );
736 xGraphProps->setPropertyValue("Width",
737 uno::makeAny( aSize.Width ) );
739 text::GraphicCrop aGraphicCrop( 0, 0, 0, 0 );
740 uno::Reference< beans::XPropertySet > xSourceGraphProps( xShape, uno::UNO_QUERY );
741 uno::Any aAny = xSourceGraphProps->getPropertyValue("GraphicCrop");
742 if(aAny >>= aGraphicCrop) {
743 xGraphProps->setPropertyValue("GraphicCrop",
744 uno::makeAny( aGraphicCrop ) );
747 // We need to drop the shape here somehow
748 uno::Reference< lang::XComponent > xShapeComponent( xShape, uno::UNO_QUERY );
749 xShapeComponent->dispose( );
752 catch( const beans::UnknownPropertyException & )
754 // It isn't a graphic image
757 if ( bUseShape )
758 m_xShape = xShape;
761 if ( m_xShape.is( ) )
763 uno::Reference< beans::XPropertySet > xShapeProps
764 (m_xShape, uno::UNO_QUERY_THROW);
767 PropertyNameSupplier& rPropNameSupplier =
768 PropertyNameSupplier::GetPropertyNameSupplier();
769 xShapeProps->setPropertyValue
770 (rPropNameSupplier.GetName(PROP_ANCHOR_TYPE),
771 uno::makeAny
772 (text::TextContentAnchorType_AS_CHARACTER));
774 // In Word, if a shape is anchored inline, that
775 // excludes being in the background.
776 xShapeProps->setPropertyValue("Opaque", uno::makeAny(true));
778 uno::Reference<lang::XServiceInfo> xServiceInfo(m_xShape, uno::UNO_QUERY_THROW);
780 // TextFrames can't be rotated. But for anything else,
781 // make sure that setting size doesn't affect rotation,
782 // that would not match Word's definition of rotation.
783 bool bKeepRotation = false;
784 if (!xServiceInfo->supportsService("com.sun.star.text.TextFrame"))
786 bKeepRotation = true;
787 xShapeProps->setPropertyValue
788 (rPropNameSupplier.GetName(PROP_TEXT_RANGE),
789 uno::makeAny
790 (m_pImpl->rDomainMapper.GetCurrentTextRange()));
793 awt::Size aSize(m_xShape->getSize());
795 if (m_pImpl->isXSizeValid())
796 aSize.Width = m_pImpl->getXSize();
797 if (m_pImpl->isYSizeValis())
798 aSize.Height = m_pImpl->getYSize();
800 sal_Int32 nRotation = 0;
801 if (bKeepRotation)
803 // Use internal API, getPropertyValue(RotateAngle)
804 // would use GetObjectRotation(), which is not what
805 // we want.
806 if (SdrObject* pShape = GetSdrObjectFromXShape(m_xShape))
807 nRotation = pShape->GetRotateAngle();
809 m_xShape->setSize(aSize);
810 if (bKeepRotation)
811 xShapeProps->setPropertyValue("RotateAngle", uno::makeAny(nRotation));
813 m_pImpl->bIsGraphic = true;
815 if (!m_pImpl->sAnchorId.isEmpty())
817 putPropertyToFrameGrabBag("AnchorId", uno::makeAny(m_pImpl->sAnchorId));
821 if (bUseShape && m_pImpl->eGraphicImportType == IMPORT_AS_DETECTED_ANCHOR)
823 // 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).
824 // But they aren't Writer pictures, either (which are already handled above).
825 uno::Reference< beans::XPropertySet > xShapeProps(m_xShape, uno::UNO_QUERY_THROW);
827 // This needs to be AT_PARAGRAPH by default and not AT_CHARACTER, otherwise shape will move when the user inserts a new paragraph.
828 text::TextContentAnchorType eAnchorType = text::TextContentAnchorType_AT_PARAGRAPH;
829 if (m_pImpl->nVertRelation == text::RelOrientation::TEXT_LINE)
830 eAnchorType = text::TextContentAnchorType_AT_CHARACTER;
831 xShapeProps->setPropertyValue("AnchorType", uno::makeAny(eAnchorType));
833 //only the position orientation is handled in applyPosition()
834 m_pImpl->applyPosition(xShapeProps);
836 uno::Reference<lang::XServiceInfo> xServiceInfo(m_xShape, uno::UNO_QUERY_THROW);
837 if (xServiceInfo->supportsService("com.sun.star.drawing.GroupShape") ||
838 xServiceInfo->supportsService("com.sun.star.drawing.GraphicObjectShape"))
840 // You would expect that position and rotation are
841 // independent, but they are not. Till we are not
842 // there yet to handle all scaling, translation and
843 // rotation with a single transformation matrix,
844 // make sure there is no rotation set when we set
845 // the position.
846 sal_Int32 nRotation = 0;
847 xShapeProps->getPropertyValue("RotateAngle") >>= nRotation;
848 if (nRotation)
849 xShapeProps->setPropertyValue("RotateAngle", uno::makeAny(sal_Int32(0)));
851 // Position of the groupshape should be set after children have been added.
852 // fdo#80555: also set position for graphic shapes here
853 m_xShape->setPosition(awt::Point(m_pImpl->nLeftPosition, m_pImpl->nTopPosition));
855 if (nRotation)
856 xShapeProps->setPropertyValue("RotateAngle", uno::makeAny(nRotation));
858 m_pImpl->applyRelativePosition(xShapeProps, /*bRelativeOnly=*/true);
860 xShapeProps->setPropertyValue("SurroundContour", uno::makeAny(m_pImpl->bContour));
861 m_pImpl->applyMargins(xShapeProps);
862 bool bOpaque = m_pImpl->bOpaque && !m_pImpl->rDomainMapper.IsInHeaderFooter();
863 xShapeProps->setPropertyValue("Opaque", uno::makeAny(bOpaque));
864 xShapeProps->setPropertyValue("Surround", uno::makeAny(m_pImpl->nWrap));
865 m_pImpl->applyZOrder(xShapeProps);
866 m_pImpl->applyName(xShapeProps);
868 // Get the grab-bag set by oox, merge with our one and then put it back.
869 comphelper::SequenceAsHashMap aInteropGrabBag(xShapeProps->getPropertyValue("InteropGrabBag"));
870 aInteropGrabBag.update(m_pImpl->getInteropGrabBag());
871 xShapeProps->setPropertyValue("InteropGrabBag", uno::makeAny(aInteropGrabBag.getAsConstPropertyValueList()));
875 break;
876 case NS_ooxml::LN_CT_Inline_distT:
877 m_pImpl->nTopMargin = 0;
878 break;
879 case NS_ooxml::LN_CT_Inline_distB:
880 m_pImpl->nBottomMargin = 0;
881 break;
882 case NS_ooxml::LN_CT_Inline_distL:
883 m_pImpl->nLeftMargin = 0;
884 break;
885 case NS_ooxml::LN_CT_Inline_distR:
886 m_pImpl->nRightMargin = 0;
887 break;
888 case NS_ooxml::LN_CT_GraphicalObjectData_uri:
889 rValue.getString();
890 //TODO: does it need to be handled?
891 break;
892 case NS_ooxml::LN_CT_SizeRelH_relativeFrom:
894 switch (nIntValue)
896 case NS_ooxml::LN_ST_SizeRelFromH_margin:
897 if (m_xShape.is())
899 uno::Reference<beans::XPropertySet> xPropertySet(m_xShape, uno::UNO_QUERY);
900 xPropertySet->setPropertyValue("RelativeWidthRelation", uno::makeAny(text::RelOrientation::FRAME));
902 break;
903 case NS_ooxml::LN_ST_SizeRelFromH_page:
904 if (m_xShape.is())
906 uno::Reference<beans::XPropertySet> xPropertySet(m_xShape, uno::UNO_QUERY);
907 xPropertySet->setPropertyValue("RelativeWidthRelation", uno::makeAny(text::RelOrientation::PAGE_FRAME));
909 break;
910 default:
911 SAL_WARN("writerfilter", "GraphicImport::lcl_attribute: unhandled NS_ooxml::LN_CT_SizeRelH_relativeFrom value: " << nIntValue);
912 break;
915 break;
916 case NS_ooxml::LN_CT_SizeRelV_relativeFrom:
918 switch (nIntValue)
920 case NS_ooxml::LN_ST_SizeRelFromV_margin:
921 if (m_xShape.is())
923 uno::Reference<beans::XPropertySet> xPropertySet(m_xShape, uno::UNO_QUERY);
924 xPropertySet->setPropertyValue("RelativeHeightRelation", uno::makeAny(text::RelOrientation::FRAME));
926 break;
927 case NS_ooxml::LN_ST_SizeRelFromV_page:
928 if (m_xShape.is())
930 uno::Reference<beans::XPropertySet> xPropertySet(m_xShape, uno::UNO_QUERY);
931 xPropertySet->setPropertyValue("RelativeHeightRelation", uno::makeAny(text::RelOrientation::PAGE_FRAME));
933 break;
934 default:
935 SAL_WARN("writerfilter", "GraphicImport::lcl_attribute: unhandled NS_ooxml::LN_CT_SizeRelV_relativeFrom value: " << nIntValue);
936 break;
939 break;
940 default:
941 #ifdef DEBUG_WRITERFILTER
942 TagLogger::getInstance().element("unhandled");
943 #endif
944 break;
948 uno::Reference<text::XTextContent> GraphicImport::GetGraphicObject()
950 uno::Reference<text::XTextContent> xResult;
952 if (m_xGraphicObject.is())
953 xResult = m_xGraphicObject;
954 else if (m_xShape.is())
956 xResult.set(m_xShape, uno::UNO_QUERY_THROW);
959 return xResult;
963 void GraphicImport::ProcessShapeOptions(Value& rValue)
965 sal_Int32 nIntValue = rValue.getInt();
966 switch( m_pImpl->nShapeOptionType )
968 case NS_ooxml::LN_CT_Anchor_distL:
969 //todo: changes have to be applied depending on the orientation, see SwWW8ImplReader::AdjustLRWrapForWordMargins()
970 m_pImpl->nLeftMargin = nIntValue / 360;
971 break;
972 case NS_ooxml::LN_CT_Anchor_distT:
973 //todo: changes have to be applied depending on the orientation, see SwWW8ImplReader::AdjustULWrapForWordMargins()
974 m_pImpl->nTopMargin = nIntValue / 360;
975 break;
976 case NS_ooxml::LN_CT_Anchor_distR:
977 //todo: changes have to be applied depending on the orientation, see SwWW8ImplReader::AdjustLRWrapForWordMargins()
978 m_pImpl->nRightMargin = nIntValue / 360;
979 break;
980 case NS_ooxml::LN_CT_Anchor_distB:
981 //todo: changes have to be applied depending on the orientation, see SwWW8ImplReader::AdjustULWrapForWordMargins()
982 m_pImpl->nBottomMargin = nIntValue / 360;
983 break;
984 default:
985 OSL_FAIL( "shape option unsupported?");
990 void GraphicImport::lcl_sprm(Sprm& rSprm)
992 sal_uInt32 nSprmId = rSprm.getId();
993 Value::Pointer_t pValue = rSprm.getValue();
995 switch(nSprmId)
997 case NS_ooxml::LN_CT_Inline_extent: // 90911;
998 case NS_ooxml::LN_CT_Inline_effectExtent: // 90912;
999 case NS_ooxml::LN_CT_Inline_docPr: // 90913;
1000 case NS_ooxml::LN_CT_Inline_cNvGraphicFramePr: // 90914;
1001 case NS_ooxml::LN_CT_NonVisualGraphicFrameProperties_graphicFrameLocks:// 90657
1002 case NS_ooxml::LN_CT_Inline_a_graphic:// 90915
1003 case NS_ooxml::LN_CT_Anchor_simplePos_elem: // 90975;
1004 case NS_ooxml::LN_CT_Anchor_extent: // 90978;
1005 case NS_ooxml::LN_CT_Anchor_effectExtent: // 90979;
1006 case NS_ooxml::LN_EG_WrapType_wrapSquare: // 90945;
1007 case NS_ooxml::LN_EG_WrapType_wrapTight: // 90946;
1008 case NS_ooxml::LN_EG_WrapType_wrapThrough:
1009 case NS_ooxml::LN_CT_Anchor_docPr: // 90980;
1010 case NS_ooxml::LN_CT_Anchor_cNvGraphicFramePr: // 90981;
1011 case NS_ooxml::LN_CT_Anchor_a_graphic: // 90982;
1012 case NS_ooxml::LN_CT_WrapPath_start: // 90924;
1013 case NS_ooxml::LN_CT_WrapPath_lineTo: // 90925;
1014 case NS_ooxml::LN_graphic_graphic:
1015 case NS_ooxml::LN_pic_pic:
1016 case NS_ooxml::LN_dgm_relIds:
1017 case NS_ooxml::LN_lc_lockedCanvas:
1018 case NS_ooxml::LN_c_chart:
1019 case NS_ooxml::LN_wps_wsp:
1020 case NS_ooxml::LN_wpg_wgp:
1021 case NS_ooxml::LN_sizeRelH_sizeRelH:
1022 case NS_ooxml::LN_sizeRelV_sizeRelV:
1023 case NS_ooxml::LN_hlinkClick_hlinkClick:
1025 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
1026 if( pProperties.get())
1028 pProperties->resolve(*this);
1031 // We'll map these to PARALLEL, save the original wrap type.
1032 if (nSprmId == NS_ooxml::LN_EG_WrapType_wrapTight)
1033 m_pImpl->m_aInteropGrabBag["EG_WrapType"] <<= OUString("wrapTight");
1034 else if (nSprmId == NS_ooxml::LN_EG_WrapType_wrapThrough)
1035 m_pImpl->m_aInteropGrabBag["EG_WrapType"] <<= OUString("wrapThrough");
1037 break;
1038 case NS_ooxml::LN_CT_WrapTight_wrapPolygon:
1039 case NS_ooxml::LN_CT_WrapThrough_wrapPolygon:
1041 WrapPolygonHandler aHandler;
1043 resolveSprmProps(aHandler, rSprm);
1045 m_pImpl->mpWrapPolygon = aHandler.getPolygon();
1047 // Save the wrap path in case we can't handle it natively: drawinglayer shapes, TextFrames.
1048 m_pImpl->m_aInteropGrabBag["CT_WrapPath"] <<= m_pImpl->mpWrapPolygon->getPointSequenceSequence();
1050 break;
1051 case NS_ooxml::LN_CT_Anchor_positionH: // 90976;
1053 // Use a special handler for the positionning
1054 PositionHandlerPtr pHandler( new PositionHandler( m_pImpl->m_rPositionOffsets, m_pImpl->m_rAligns ));
1055 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
1056 if( pProperties.get( ) )
1058 pProperties->resolve( *pHandler );
1059 if( !m_pImpl->bUseSimplePos )
1061 m_pImpl->nHoriRelation = pHandler->relation();
1062 m_pImpl->nHoriOrient = pHandler->orientation();
1063 m_pImpl->nLeftPosition = pHandler->position();
1064 if (m_pImpl->nHoriRelation == text::RelOrientation::PAGE_FRAME && m_pImpl->nHoriOrient == text::HoriOrientation::RIGHT)
1066 // If the shape is relative from page and aligned to
1067 // right, then set the relation to right and clear the
1068 // orientation, that provides the same visual result as
1069 // Word.
1070 m_pImpl->nHoriRelation = text::RelOrientation::PAGE_RIGHT;
1071 m_pImpl->nHoriOrient = text::HoriOrientation::NONE;
1076 break;
1077 case NS_ooxml::LN_CT_Anchor_positionV: // 90977;
1079 // Use a special handler for the positionning
1080 PositionHandlerPtr pHandler( new PositionHandler( m_pImpl->m_rPositionOffsets, m_pImpl->m_rAligns));
1081 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
1082 if( pProperties.get( ) )
1084 pProperties->resolve( *pHandler );
1085 if( !m_pImpl->bUseSimplePos )
1087 m_pImpl->nVertRelation = pHandler->relation();
1088 m_pImpl->nVertOrient = pHandler->orientation();
1089 m_pImpl->nTopPosition = pHandler->position();
1093 break;
1094 case NS_ooxml::LN_CT_SizeRelH_pctWidth:
1095 case NS_ooxml::LN_CT_SizeRelV_pctHeight:
1096 if (m_xShape.is() && !m_pImpl->m_rPositivePercentages.empty())
1098 sal_Int16 nPositivePercentage = rtl::math::round(m_pImpl->m_rPositivePercentages.front().toDouble() / oox::drawingml::PER_PERCENT);
1099 m_pImpl->m_rPositivePercentages.pop();
1101 if (nPositivePercentage)
1103 uno::Reference<beans::XPropertySet> xPropertySet(m_xShape, uno::UNO_QUERY);
1104 OUString aProperty = nSprmId == NS_ooxml::LN_CT_SizeRelH_pctWidth ? OUString("RelativeWidth") : OUString("RelativeHeight");
1105 xPropertySet->setPropertyValue(aProperty, uno::makeAny(nPositivePercentage));
1108 break;
1109 case NS_ooxml::LN_EG_WrapType_wrapNone: // 90944; - doesn't contain attributes
1110 //depending on the behindDoc attribute text wraps through behind or in fron of the object
1111 m_pImpl->nWrap = text::WrapTextMode_THROUGHT;
1112 break;
1113 case NS_ooxml::LN_EG_WrapType_wrapTopAndBottom: // 90948;
1114 m_pImpl->nWrap = text::WrapTextMode_NONE;
1115 break;
1116 case NS_ooxml::LN_CT_GraphicalObject_graphicData:// 90660;
1118 m_pImpl->bIsGraphic = true;
1120 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
1121 if( pProperties.get())
1122 pProperties->resolve(*this);
1124 break;
1125 default:
1126 SAL_WARN("writerfilter", "GraphicImport::lcl_sprm: unhandled token: " << nSprmId);
1127 break;
1131 void GraphicImport::lcl_entry(int /*pos*/, writerfilter::Reference<Properties>::Pointer_t /*ref*/)
1135 uno::Reference< text::XTextContent > GraphicImport::createGraphicObject( const beans::PropertyValues& aMediaProperties, const uno::Reference<beans::XPropertySet>& xShapeProps )
1137 uno::Reference< text::XTextContent > xGraphicObject;
1140 uno::Reference< graphic::XGraphicProvider > xGraphicProvider( graphic::GraphicProvider::create(m_xComponentContext) );
1141 uno::Reference< graphic::XGraphic > xGraphic = xGraphicProvider->queryGraphic( aMediaProperties );
1143 if(xGraphic.is())
1145 PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
1147 uno::Reference< beans::XPropertySet > xGraphicObjectProperties(
1148 m_xTextFactory->createInstance("com.sun.star.text.TextGraphicObject"),
1149 uno::UNO_QUERY_THROW);
1150 xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName(PROP_GRAPHIC), uno::makeAny( xGraphic ));
1151 xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName(PROP_ANCHOR_TYPE),
1152 uno::makeAny( m_pImpl->eGraphicImportType == IMPORT_AS_DETECTED_ANCHOR ?
1153 text::TextContentAnchorType_AT_CHARACTER :
1154 text::TextContentAnchorType_AS_CHARACTER ));
1155 xGraphicObject = uno::Reference< text::XTextContent >( xGraphicObjectProperties, uno::UNO_QUERY_THROW );
1157 //shapes have only one border
1158 table::BorderLine2 aBorderLine;
1159 GraphicBorderLine& rBorderLine = m_pImpl->aBorders[0];
1160 if (rBorderLine.isEmpty() && xShapeProps.is() && xShapeProps->getPropertyValue("LineStyle").get<drawing::LineStyle>() != drawing::LineStyle_NONE)
1162 // In case we got no border tokens and we have the
1163 // original shape, then use its line properties as the
1164 // border.
1165 aBorderLine.Color = xShapeProps->getPropertyValue("LineColor").get<sal_Int32>();
1166 aBorderLine.LineWidth = xShapeProps->getPropertyValue("LineWidth").get<sal_Int32>();
1168 else
1170 aBorderLine.Color = rBorderLine.nLineColor;
1171 aBorderLine.InnerLineWidth = 0;
1172 aBorderLine.OuterLineWidth = (sal_Int16)rBorderLine.nLineWidth;
1173 aBorderLine.LineDistance = 0;
1175 PropertyIds aBorderProps[4] =
1177 PROP_LEFT_BORDER,
1178 PROP_RIGHT_BORDER,
1179 PROP_TOP_BORDER,
1180 PROP_BOTTOM_BORDER
1183 for( sal_Int32 nBorder = 0; nBorder < 4; ++nBorder )
1184 xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName( aBorderProps[nBorder]), uno::makeAny(aBorderLine));
1186 // setting graphic object shadow proerties
1187 if (m_pImpl->bShadow)
1189 // Shadow width is approximated by average of X and Y
1190 table::ShadowFormat aShadow;
1191 sal_uInt32 nShadowColor = m_pImpl->nShadowColor & 0x00FFFFFF; // The shadow color we get is RGB only.
1192 sal_Int32 nShadowWidth = (abs(m_pImpl->nShadowXDistance)
1193 + abs(m_pImpl->nShadowYDistance)) / 2;
1195 aShadow.ShadowWidth = nShadowWidth;
1196 sal_uInt8 nShadowTransparence = float(m_pImpl->nShadowTransparence) * 2.55;
1197 nShadowColor |= (nShadowTransparence << 24); // Add transparence to the color.
1198 aShadow.Color = nShadowColor;
1199 // Distances -ve for top and right, +ve for bottom and left
1200 if (m_pImpl->nShadowXDistance > 0)
1202 if (m_pImpl->nShadowYDistance > 0)
1203 aShadow.Location = table::ShadowLocation_BOTTOM_RIGHT;
1204 else
1205 aShadow.Location = table::ShadowLocation_TOP_RIGHT;
1207 else
1209 if (m_pImpl->nShadowYDistance > 0)
1210 aShadow.Location = table::ShadowLocation_BOTTOM_LEFT;
1211 else
1212 aShadow.Location = table::ShadowLocation_TOP_LEFT;
1215 xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName(PROP_SHADOW_FORMAT), uno::makeAny(aShadow));
1218 // setting properties for all types
1219 if( m_pImpl->bPositionProtected )
1220 xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName( PROP_POSITION_PROTECTED ),
1221 uno::makeAny(true));
1222 if( m_pImpl->bSizeProtected )
1223 xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName( PROP_SIZE_PROTECTED ),
1224 uno::makeAny(true));
1226 sal_Int32 nWidth = m_pImpl->nRightPosition - m_pImpl->nLeftPosition;
1227 if (m_pImpl->eGraphicImportType == IMPORT_AS_DETECTED_ANCHOR)
1229 //adjust margins
1230 if( (m_pImpl->nHoriOrient == text::HoriOrientation::LEFT &&
1231 (m_pImpl->nHoriRelation == text::RelOrientation::PAGE_PRINT_AREA ||
1232 m_pImpl->nHoriRelation == text::RelOrientation::FRAME) ) ||
1233 (m_pImpl->nHoriOrient == text::HoriOrientation::INSIDE &&
1234 m_pImpl->nHoriRelation == text::RelOrientation::PAGE_PRINT_AREA ))
1235 m_pImpl->nLeftMargin = 0;
1236 if((m_pImpl->nHoriOrient == text::HoriOrientation::RIGHT &&
1237 (m_pImpl->nHoriRelation == text::RelOrientation::PAGE_PRINT_AREA ||
1238 m_pImpl->nHoriRelation == text::RelOrientation::FRAME) ) ||
1239 (m_pImpl->nHoriOrient == text::HoriOrientation::INSIDE &&
1240 m_pImpl->nHoriRelation == text::RelOrientation::PAGE_PRINT_AREA ))
1241 m_pImpl->nRightMargin = 0;
1242 // adjust top/bottom margins
1243 if( m_pImpl->nVertOrient == text::VertOrientation::TOP &&
1244 ( m_pImpl->nVertRelation == text::RelOrientation::PAGE_PRINT_AREA ||
1245 m_pImpl->nVertRelation == text::RelOrientation::PAGE_FRAME))
1246 m_pImpl->nTopMargin = 0;
1247 if( m_pImpl->nVertOrient == text::VertOrientation::BOTTOM &&
1248 ( m_pImpl->nVertRelation == text::RelOrientation::PAGE_PRINT_AREA ||
1249 m_pImpl->nVertRelation == text::RelOrientation::PAGE_FRAME))
1250 m_pImpl->nBottomMargin = 0;
1251 if( m_pImpl->nVertOrient == text::VertOrientation::BOTTOM &&
1252 m_pImpl->nVertRelation == text::RelOrientation::PAGE_PRINT_AREA )
1253 m_pImpl->nBottomMargin = 0;
1254 //adjust alignment
1255 if( m_pImpl->nHoriOrient == text::HoriOrientation::INSIDE &&
1256 m_pImpl->nHoriRelation == text::RelOrientation::PAGE_FRAME )
1258 // convert 'left to page' to 'from left -<width> to page text area'
1259 m_pImpl->nHoriOrient = text::HoriOrientation::NONE;
1260 m_pImpl->nHoriRelation = text::RelOrientation::PAGE_PRINT_AREA;
1261 m_pImpl->nLeftPosition = - nWidth;
1263 else if( m_pImpl->nHoriOrient == text::HoriOrientation::OUTSIDE &&
1264 m_pImpl->nHoriRelation == text::RelOrientation::PAGE_FRAME )
1266 // convert 'right to page' to 'from left 0 to right page border'
1267 m_pImpl->nHoriOrient = text::HoriOrientation::NONE;
1268 m_pImpl->nHoriRelation = text::RelOrientation::PAGE_RIGHT;
1269 m_pImpl->nLeftPosition = 0;
1272 m_pImpl->applyPosition(xGraphicObjectProperties);
1273 m_pImpl->applyRelativePosition(xGraphicObjectProperties);
1274 bool bOpaque = m_pImpl->bOpaque && !m_pImpl->rDomainMapper.IsInHeaderFooter( );
1275 if( !bOpaque )
1277 xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName( PROP_OPAQUE ),
1278 uno::makeAny(bOpaque));
1280 xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName( PROP_SURROUND ),
1281 uno::makeAny(m_pImpl->nWrap));
1282 if( m_pImpl->bLayoutInCell && m_pImpl->nWrap != text::WrapTextMode_THROUGHT )
1283 xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName( PROP_FOLLOW_TEXT_FLOW ),
1284 uno::makeAny(true));
1286 xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName( PROP_SURROUND_CONTOUR ),
1287 uno::makeAny(m_pImpl->bContour));
1288 xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName( PROP_CONTOUR_OUTSIDE ),
1289 uno::makeAny(m_pImpl->bContourOutside));
1290 m_pImpl->applyMargins(xGraphicObjectProperties);
1293 if( m_pImpl->eColorMode == drawing::ColorMode_STANDARD &&
1294 m_pImpl->nContrast == -70 &&
1295 m_pImpl->nBrightness == 70 )
1297 // strange definition of WATERMARK!
1298 m_pImpl->nContrast = 0;
1299 m_pImpl->nBrightness = 0;
1300 m_pImpl->eColorMode = drawing::ColorMode_WATERMARK;
1303 xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName( PROP_ADJUST_CONTRAST ),
1304 uno::makeAny((sal_Int16)m_pImpl->nContrast));
1305 xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName( PROP_ADJUST_LUMINANCE ),
1306 uno::makeAny((sal_Int16)m_pImpl->nBrightness));
1307 if(m_pImpl->eColorMode != drawing::ColorMode_STANDARD)
1309 xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName( PROP_GRAPHIC_COLOR_MODE ),
1310 uno::makeAny(m_pImpl->eColorMode));
1312 if(m_pImpl->fGamma > 0. )
1313 xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName( PROP_GAMMA ),
1314 uno::makeAny(m_pImpl->fGamma ));
1315 if(m_pImpl->bHoriFlip)
1317 xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName( PROP_HORI_MIRRORED_ON_EVEN_PAGES ),
1318 uno::makeAny( m_pImpl->bHoriFlip ));
1319 xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName( PROP_HORI_MIRRORED_ON_ODD_PAGES ),
1320 uno::makeAny( m_pImpl->bHoriFlip ));
1323 if( m_pImpl->bVertFlip )
1324 xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName( PROP_VERT_MIRRORED ),
1325 uno::makeAny( m_pImpl->bVertFlip ));
1326 xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName( PROP_BACK_COLOR ),
1327 uno::makeAny( m_pImpl->nFillColor ));
1329 m_pImpl->applyZOrder(xGraphicObjectProperties);
1331 //there seems to be no way to detect the original size via _real_ API
1332 uno::Reference< beans::XPropertySet > xGraphicProperties( xGraphic, uno::UNO_QUERY_THROW );
1333 awt::Size aGraphicSize, aGraphicSizePixel;
1334 xGraphicProperties->getPropertyValue(rPropNameSupplier.GetName( PROP_SIZE100th_M_M )) >>= aGraphicSize;
1335 xGraphicProperties->getPropertyValue(rPropNameSupplier.GetName( PROP_SIZE_PIXEL )) >>= aGraphicSizePixel;
1337 uno::Any aContourPolyPolygon;
1338 if( aGraphicSize.Width && aGraphicSize.Height &&
1339 m_pImpl->mpWrapPolygon.get() != nullptr)
1341 WrapPolygon::Pointer_t pCorrected = m_pImpl->mpWrapPolygon->correctWordWrapPolygon(aGraphicSize);
1342 aContourPolyPolygon <<= pCorrected->getPointSequenceSequence();
1345 xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName( PROP_CONTOUR_POLY_POLYGON),
1346 aContourPolyPolygon);
1348 if(m_pImpl->eGraphicImportType == IMPORT_AS_DETECTED_INLINE || m_pImpl->eGraphicImportType == IMPORT_AS_DETECTED_ANCHOR)
1350 if( m_pImpl->getXSize() && m_pImpl->getYSize() )
1351 xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName(PROP_SIZE),
1352 uno::makeAny( awt::Size( m_pImpl->getXSize(), m_pImpl->getYSize() )));
1353 m_pImpl->applyMargins(xGraphicObjectProperties);
1354 m_pImpl->applyName(xGraphicObjectProperties);
1358 catch( const uno::Exception& e )
1360 SAL_WARN("writerfilter", "failed. Message :" << e.Message);
1362 return xGraphicObject;
1367 void GraphicImport::data(const sal_uInt8* buf, size_t len, writerfilter::Reference<Properties>::Pointer_t /*ref*/)
1369 PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
1371 beans::PropertyValues aMediaProperties( 1 );
1372 aMediaProperties[0].Name = rPropNameSupplier.GetName(PROP_INPUT_STREAM);
1374 uno::Reference< io::XInputStream > xIStream = new XInputStreamHelper( buf, len, m_pImpl->bIsBitmap );
1375 aMediaProperties[0].Value <<= xIStream;
1377 uno::Reference<beans::XPropertySet> xPropertySet;
1378 m_xGraphicObject = createGraphicObject( aMediaProperties, xPropertySet );
1382 void GraphicImport::lcl_startSectionGroup()
1387 void GraphicImport::lcl_endSectionGroup()
1392 void GraphicImport::lcl_startParagraphGroup()
1397 void GraphicImport::lcl_endParagraphGroup()
1402 void GraphicImport::lcl_startCharacterGroup()
1407 void GraphicImport::lcl_endCharacterGroup()
1412 void GraphicImport::lcl_text(const sal_uInt8 * /*_data*/, size_t /*len*/)
1417 void GraphicImport::lcl_utext(const sal_uInt8 * /*_data*/, size_t /*len*/)
1422 void GraphicImport::lcl_props(writerfilter::Reference<Properties>::Pointer_t /*ref*/)
1427 void GraphicImport::lcl_table(Id /*name*/, writerfilter::Reference<Table>::Pointer_t /*ref*/)
1432 void GraphicImport::lcl_substream(Id /*name*/, ::writerfilter::Reference<Stream>::Pointer_t /*ref*/)
1437 void GraphicImport::lcl_info(const std::string& /*info*/)
1441 void GraphicImport::lcl_startShape(uno::Reference<drawing::XShape> const&)
1445 void GraphicImport::lcl_endShape( )
1449 bool GraphicImport::IsGraphic() const
1451 return m_pImpl->bIsGraphic;
1457 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */