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 .
20 #include <hintids.hxx>
21 #include <tools/helpers.hxx>
22 #include <tools/urlobj.hxx>
23 #include <tools/fract.hxx>
24 #include <tools/UnitConversion.hxx>
25 #include <svl/fstathelper.hxx>
26 #include <vcl/imap.hxx>
27 #include <sfx2/docfile.hxx>
28 #include <sfx2/linkmgr.hxx>
29 #include <editeng/boxitem.hxx>
30 #include <sot/formats.hxx>
31 #include <fmtfsize.hxx>
35 #include <IDocumentLinksAdministration.hxx>
36 #include <IDocumentLayoutAccess.hxx>
39 #include <swtypes.hxx>
43 #include <swbaslnk.hxx>
44 #include <pagefrm.hxx>
47 #include <rtl/ustring.hxx>
48 #include <o3tl/deleter.hxx>
49 #include <retrieveinputstreamconsumer.hxx>
50 #include <drawinglayer/processor2d/objectinfoextractor2d.hxx>
51 #include <drawinglayer/primitive2d/objectinfoprimitive2d.hxx>
53 using namespace com::sun::star
;
56 const SwNodeIndex
& rWhere
,
57 const OUString
& rGrfName
,
58 const OUString
& rFltName
,
59 const Graphic
* pGraphic
,
60 SwGrfFormatColl
*pGrfColl
,
61 SwAttrSet
const * pAutoAttr
) :
62 SwNoTextNode( rWhere
, SwNodeType::Grf
, pGrfColl
, pAutoAttr
),
64 mbInBaseLinkSwapIn(true),
66 mbLinkedInputStreamReady( false ),
67 mbIsStreamReadOnly( false )
69 mbInSwapIn
= mbChangeTwipSize
=
70 mbFrameInPaint
= mbScaleImageMap
= false;
72 ReRead(rGrfName
, rFltName
, pGraphic
, false);
75 SwGrfNode::SwGrfNode( const SwNodeIndex
& rWhere
,
76 const GraphicObject
& rGrfObj
,
77 SwGrfFormatColl
*pGrfColl
,
78 SwAttrSet
const * pAutoAttr
) :
79 SwNoTextNode( rWhere
, SwNodeType::Grf
, pGrfColl
, pAutoAttr
),
81 mbInBaseLinkSwapIn(true),
83 mbLinkedInputStreamReady( false ),
84 mbIsStreamReadOnly( false )
86 mbInSwapIn
= mbChangeTwipSize
=
87 mbFrameInPaint
= mbScaleImageMap
= false;
90 /** Create new SW/G reader.
92 * Use this ctor if you want to read a linked graphic.
94 * @note Does not read/open the image itself!
96 SwGrfNode::SwGrfNode( const SwNodeIndex
& rWhere
,
97 const OUString
& rGrfName
,
98 const OUString
& rFltName
,
99 SwGrfFormatColl
*pGrfColl
,
100 SwAttrSet
const * pAutoAttr
) :
101 SwNoTextNode( rWhere
, SwNodeType::Grf
, pGrfColl
, pAutoAttr
),
103 mbInBaseLinkSwapIn(true),
105 mbLinkedInputStreamReady( false ),
106 mbIsStreamReadOnly( false )
108 Graphic aGrf
; aGrf
.SetDefaultType();
109 maGrfObj
.SetGraphic( aGrf
);
111 mbInSwapIn
= mbChangeTwipSize
=
112 mbFrameInPaint
= mbScaleImageMap
= false;
114 InsertLink( rGrfName
, rFltName
);
117 INetURLObject
aUrl( rGrfName
);
118 if( INetProtocol::File
== aUrl
.GetProtocol() &&
119 FStatHelper::IsDocument( aUrl
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) ))
121 // file exists, so create connection without an update
122 static_cast<SwBaseLink
*>( mxLink
.get() )->Connect();
127 bool SwGrfNode::ReRead(
128 const OUString
& rGrfName
, const OUString
& rFltName
,
129 const Graphic
* pGraphic
,
132 bool bReadGrf
= false;
133 bool bSetTwipSize
= true;
134 mpReplacementGraphic
.reset();
136 OSL_ENSURE( pGraphic
|| !rGrfName
.isEmpty(),
137 "GraphicNode without a name, Graphic or GraphicObject" );
142 Graphic
aGraphic(*pGraphic
);
144 sURLLink
= aGraphic
.getOriginURL();
145 if (sURLLink
.isEmpty() && !rGrfName
.isEmpty())
148 aGraphic
.setOriginURL(sURLLink
);
159 OSL_ENSURE( !mbInSwapIn
, "ReRead: I am still in SwapIn" );
161 if( !sURLLink
.isEmpty() )
163 // Note: if there is DDE in the FltName, then it is a DDE-linked graphic
164 OUString
sCmd( sURLLink
);
165 if( !rFltName
.isEmpty() )
167 sfx2::SvBaseLinkObjectType nNewType
;
168 if( rFltName
== "DDE" )
169 nNewType
= sfx2::SvBaseLinkObjectType::ClientDde
;
172 sfx2::MakeLnkName( sCmd
, nullptr, sURLLink
, OUString(), &rFltName
);
173 nNewType
= sfx2::SvBaseLinkObjectType::ClientGraphic
;
176 if( nNewType
!= mxLink
->GetObjType() )
178 mxLink
->Disconnect();
179 static_cast<SwBaseLink
*>( mxLink
.get() )->SetObjType( nNewType
);
183 mxLink
->SetLinkSourceName( sCmd
);
185 else // no name anymore, so remove link
187 GetDoc().getIDocumentLinksAdministration().GetLinkManager().Remove( mxLink
.get() );
193 maGrfObj
.SetGraphic( *pGraphic
);
199 // reset data of the old graphic so that the correct placeholder is
200 // shown in case the new link could not be loaded
201 Graphic aGrf
; aGrf
.SetDefaultType();
202 maGrfObj
.SetGraphic( aGrf
);
206 if( getLayoutFrame( GetDoc().getIDocumentLayoutAccess().GetCurrentLayout() ) )
208 CallSwClientNotify(sw::GrfRereadAndInCacheHint());
212 //TODO refLink->setInputStream(getInputStream());
213 static_cast<SwBaseLink
*>( mxLink
.get() )->SwapIn();
217 bSetTwipSize
= false;
220 else if( pGraphic
&& sURLLink
.isEmpty() )
222 maGrfObj
.SetGraphic( *pGraphic
);
226 // Was the graphic already loaded?
227 else if( !bNewGrf
&& GraphicType::NONE
!= maGrfObj
.GetType() )
231 // create new link for the graphic object
232 InsertLink( sURLLink
, rFltName
);
234 if( GetNodes().IsDocNodes() )
238 maGrfObj
.SetGraphic( *pGraphic
);
241 // create connection without update, as we have the graphic
242 static_cast<SwBaseLink
*>( mxLink
.get() )->Connect();
247 aGrf
.SetDefaultType();
248 maGrfObj
.SetGraphic( aGrf
);
252 static_cast<SwBaseLink
*>( mxLink
.get() )->SwapIn();
258 // Bug 39281: Do not delete Size immediately - Events on ImageMaps should have
259 // something to work with when swapping
261 SetTwipSize( ::GetGraphicSizeTwip( maGrfObj
.GetGraphic(), nullptr ) );
263 // create an updates for the frames
264 if( bReadGrf
&& bNewGrf
)
266 const SwUpdateAttr
aHint(0,0,0);
267 CallSwClientNotify(sw::LegacyModifyHint(&aHint
, &aHint
));
273 SwGrfNode::~SwGrfNode()
275 mpReplacementGraphic
.reset();
278 mpThreadConsumer
.reset();
280 SwDoc
& rDoc
= GetDoc();
283 OSL_ENSURE( !mbInSwapIn
, "DTOR: I am still in SwapIn" );
284 rDoc
.getIDocumentLinksAdministration().GetLinkManager().Remove( mxLink
.get() );
285 mxLink
->Disconnect();
289 // #i40014# - A graphic node, which is in a linked
290 // section, whose link is another section in the document, doesn't
291 // have to remove the stream from the storage.
292 // Because it's hard to detect this case here and it would only fix
293 // one problem with shared graphic files - there are also problems,
294 // a certain graphic file is referenced by two independent graphic nodes,
295 // brush item or drawing objects, the stream isn't no longer removed here.
296 // To do this stuff correctly, a reference counting on shared streams
297 // inside one document has to be implemented.
299 //#39289# delete frames already here since the Frames' dtor needs the graphic for its StopAnimation
300 if( HasWriterListeners() )
304 /// allow reaction on change of content of GraphicObject
305 void SwGrfNode::onGraphicChanged()
307 // try to access SwFlyFrameFormat; since title/desc/name are set there, there is no
308 // use to continue if it is not yet set. If not yet set, call onGraphicChanged()
310 SwFlyFrameFormat
* pFlyFormat
= dynamic_cast< SwFlyFrameFormat
* >(GetFlyFormat());
318 auto const & rVectorGraphicDataPtr
= GetGrf().getVectorGraphicData();
320 if (rVectorGraphicDataPtr
)
322 const drawinglayer::primitive2d::Primitive2DContainer
aSequence(rVectorGraphicDataPtr
->getPrimitive2DSequence());
324 if(!aSequence
.empty())
326 drawinglayer::geometry::ViewInformation2D aViewInformation2D
;
327 drawinglayer::processor2d::ObjectInfoPrimitiveExtractor2D
aProcessor(aViewInformation2D
);
329 aProcessor
.process(aSequence
);
331 const drawinglayer::primitive2d::ObjectInfoPrimitive2D
* pResult
= aProcessor
.getResult();
335 aName
= pResult
->getName();
336 aTitle
= pResult
->getTitle();
337 aDesc
= pResult
->getDesc();
342 if(!aTitle
.isEmpty())
346 else if (!aName
.isEmpty())
353 SetDescription(aDesc
);
357 void SwGrfNode::SetGraphic(const Graphic
& rGraphic
)
359 maGrfObj
.SetGraphic(rGraphic
);
363 void SwGrfNode::TriggerGraphicArrived()
365 CallSwClientNotify(sw::PreGraphicArrivedHint());
366 CallSwClientNotify(sw::PostGraphicArrivedHint());
369 const Graphic
& SwGrfNode::GetGrf(bool bWait
) const
371 const_cast<SwGrfNode
*>(this)->SwapIn(bWait
);
372 return maGrfObj
.GetGraphic();
375 const GraphicObject
& SwGrfNode::GetGrfObj(bool bWait
) const
377 const_cast<SwGrfNode
*>(this)->SwapIn(bWait
);
381 const GraphicObject
* SwGrfNode::GetReplacementGrfObj() const
383 if(!mpReplacementGraphic
)
385 auto const & rVectorGraphicDataPtr
= GetGrfObj().GetGraphic().getVectorGraphicData();
387 if (rVectorGraphicDataPtr
)
389 const_cast< SwGrfNode
* >(this)->mpReplacementGraphic
.reset( new GraphicObject(rVectorGraphicDataPtr
->getReplacement()) );
391 else if (GetGrfObj().GetGraphic().GetType() == GraphicType::GdiMetafile
)
393 // Replacement graphic for PDF and metafiles is just the bitmap.
394 const_cast<SwGrfNode
*>(this)->mpReplacementGraphic
.reset( new GraphicObject(GetGrfObj().GetGraphic().GetBitmapEx()) );
398 return mpReplacementGraphic
.get();
401 SwGrfNode
* SwNodes::MakeGrfNode( const SwNodeIndex
& rWhere
,
402 const OUString
& rGrfName
,
403 const OUString
& rFltName
,
404 const Graphic
* pGraphic
,
405 SwGrfFormatColl
* pGrfColl
,
406 SwAttrSet
const * pAutoAttr
)
408 OSL_ENSURE( pGrfColl
, "MakeGrfNode: Formatpointer is 0." );
410 // create object delayed, only from a SW/G-reader
412 pNode
= new SwGrfNode( rWhere
, rGrfName
,
413 rFltName
, pGrfColl
, pAutoAttr
);
415 pNode
= new SwGrfNode( rWhere
, rGrfName
,
416 rFltName
, pGraphic
, pGrfColl
, pAutoAttr
);
420 SwGrfNode
* SwNodes::MakeGrfNode( const SwNodeIndex
& rWhere
,
421 const GraphicObject
& rGrfObj
,
422 SwGrfFormatColl
* pGrfColl
)
424 OSL_ENSURE( pGrfColl
, "MakeGrfNode: Formatpointer is 0." );
425 return new SwGrfNode( rWhere
, rGrfObj
, pGrfColl
, nullptr );
428 Size
SwGrfNode::GetTwipSize() const
430 if( !mnGrfSize
.Width() && !mnGrfSize
.Height() )
432 const_cast<SwGrfNode
*>(this)->SwapIn();
438 * @return true if ReRead or reading successful,
439 * false if not loaded
441 bool SwGrfNode::SwapIn(bool bWaitForData
)
443 if(mbInSwapIn
) // not recursively!
448 SwBaseLink
* pLink
= static_cast<SwBaseLink
*>( mxLink
.get() );
452 if( (GraphicType::NONE
== maGrfObj
.GetType() ||
453 GraphicType::Default
== maGrfObj
.GetType()) &&
456 // link was not loaded yet
457 if( pLink
->SwapIn( bWaitForData
) )
460 mbInBaseLinkSwapIn
= false;
462 else if( GraphicType::Default
== maGrfObj
.GetType() )
464 // no default bitmap anymore, thus re-paint
465 mpReplacementGraphic
.reset();
467 maGrfObj
.SetGraphic( Graphic() );
469 SwMsgPoolItem
aMsgHint( RES_GRAPHIC_PIECE_ARRIVED
);
470 CallSwClientNotify(sw::LegacyModifyHint(&aMsgHint
, &aMsgHint
));
483 if( !mnGrfSize
.Width() && !mnGrfSize
.Height() )
484 SetTwipSize( ::GetGraphicSizeTwip( maGrfObj
.GetGraphic(), nullptr ) );
490 bool SwGrfNode::GetFileFilterNms( OUString
* pFileNm
, OUString
* pFilterNm
) const
493 if( mxLink
.is() && mxLink
->GetLinkManager() )
495 sfx2::SvBaseLinkObjectType nType
= mxLink
->GetObjType();
496 if( sfx2::SvBaseLinkObjectType::ClientGraphic
== nType
)
497 bRet
= sfx2::LinkManager::GetDisplayNames(
498 mxLink
.get(), nullptr, pFileNm
, nullptr, pFilterNm
);
499 else if( sfx2::SvBaseLinkObjectType::ClientDde
== nType
&& pFileNm
&& pFilterNm
)
504 if( sfx2::LinkManager::GetDisplayNames(
505 mxLink
.get(), &sApp
, &sTopic
, &sItem
) )
507 *pFileNm
= sApp
+ OUStringChar(sfx2::cTokenSeparator
)
508 + sTopic
+ OUStringChar(sfx2::cTokenSeparator
)
518 /** Make a graphic object ready for UNDO.
520 * If it is already in storage, it needs to be loaded.
522 bool SwGrfNode::SavePersistentData()
526 OSL_ENSURE( !mbInSwapIn
, "SavePersistentData: I am still in SwapIn" );
527 GetDoc().getIDocumentLinksAdministration().GetLinkManager().Remove( mxLink
.get() );
531 // swap in first if in storage
532 if( HasEmbeddedStreamName() && !SwapIn() )
536 // Do not delete graphic file in storage, because the graphic file could
537 // be referenced by other graphic nodes.
538 // Because it's hard to detect this case here and it would only fix
539 // one problem with shared graphic files - there are also problems, if
540 // a certain graphic file is referenced by two independent graphic nodes,
541 // brush item or drawing objects, the stream isn't no longer removed here.
542 // To do this stuff correct, a reference counting on shared streams
543 // inside one document has to be implemented.
544 // Important note: see also fix for #i40014#
546 // swap out into temp file
550 bool SwGrfNode::RestorePersistentData()
554 IDocumentLinksAdministration
& rIDLA
= getIDocumentLinksAdministration();
555 mxLink
->SetVisible( rIDLA
.IsVisibleLinks() );
556 rIDLA
.GetLinkManager().InsertDDELink( mxLink
.get() );
557 if( getIDocumentLayoutAccess().GetCurrentLayout() )
563 void SwGrfNode::InsertLink( const OUString
& rGrfName
, const OUString
& rFltName
)
565 mxLink
= new SwBaseLink( SfxLinkUpdateMode::ONCALL
, SotClipboardFormatId::GDIMETAFILE
, this );
567 IDocumentLinksAdministration
& rIDLA
= getIDocumentLinksAdministration();
568 if( !GetNodes().IsDocNodes() )
571 mxLink
->SetVisible( rIDLA
.IsVisibleLinks() );
572 if( rFltName
== "DDE" )
575 const OUString sApp
{ rGrfName
.getToken( 0, sfx2::cTokenSeparator
, nTmp
) };
576 const OUString sTopic
{ rGrfName
.getToken( 0, sfx2::cTokenSeparator
, nTmp
) };
577 const OUString sItem
{ rGrfName
.copy( nTmp
) };
578 rIDLA
.GetLinkManager().InsertDDELink( mxLink
.get(), sApp
, sTopic
, sItem
);
582 const bool bSync
= rFltName
== "SYNCHRON";
583 mxLink
->SetSynchron( bSync
);
584 mxLink
->SetContentType( SotClipboardFormatId::SVXB
);
586 rIDLA
.GetLinkManager().InsertFileLink( *mxLink
,
587 sfx2::SvBaseLinkObjectType::ClientGraphic
, rGrfName
,
588 (!bSync
&& !rFltName
.isEmpty() ? &rFltName
: nullptr) );
592 void SwGrfNode::ReleaseLink()
597 Graphic
aLocalGraphic(maGrfObj
.GetGraphic());
598 const bool bHasOriginalData(aLocalGraphic
.IsGfxLink());
602 SwBaseLink
* pLink
= static_cast<SwBaseLink
*>( mxLink
.get() );
603 pLink
->SwapIn( true, true );
607 getIDocumentLinksAdministration().GetLinkManager().Remove( mxLink
.get() );
609 aLocalGraphic
.setOriginURL("");
611 // #i15508# added extra processing after getting rid of the link. Use whatever is
612 // known from the formerly linked graphic to get to a state as close to a directly
613 // unlinked inserted graphic as possible. Goal is to have a valid GfxLink at the
614 // ImplGraphic (see there) that holds temporary data to the original data and type
615 // information about the original data. Only when this is given will
616 // SvXMLGraphicHelper::ImplInsertGraphicURL which is used at export use that type
617 // and use the original graphic at export for the ODF, without evtl. recoding
618 // of the bitmap graphic data to something without loss (e.g. PNG) but bigger
621 // #i15508# if we have the original data at the Graphic, let it survive
622 // by using that Graphic again, this time at a GraphicObject without link.
623 // This happens e.g. when inserting a linked graphic and breaking the link
624 maGrfObj
.SetGraphic(aLocalGraphic
);
628 void SwGrfNode::SetTwipSize( const Size
& rSz
)
631 if( IsScaleImageMap() && mnGrfSize
.Width() && mnGrfSize
.Height() )
633 // resize Image-Map to size of the graphic
636 // do not re-scale Image-Map
637 SetScaleImageMap( false );
641 void SwGrfNode::ScaleImageMap()
643 if( !mnGrfSize
.Width() || !mnGrfSize
.Height() )
646 // re-scale Image-Map
647 SwFrameFormat
* pFormat
= GetFlyFormat();
652 SwFormatURL
aURL( pFormat
->GetURL() );
653 if ( !aURL
.GetMap() )
657 Fraction
aScaleX( 1, 1 );
658 Fraction
aScaleY( 1, 1 );
660 const SwFormatFrameSize
& rFrameSize
= pFormat
->GetFrameSize();
661 const SvxBoxItem
& rBox
= pFormat
->GetBox();
663 if( !rFrameSize
.GetWidthPercent() )
665 SwTwips nWidth
= rFrameSize
.GetWidth();
667 nWidth
-= rBox
.CalcLineSpace(SvxBoxItemLine::LEFT
) +
668 rBox
.CalcLineSpace(SvxBoxItemLine::RIGHT
);
670 OSL_ENSURE( nWidth
>0, "Do any 0 twip wide graphics exist!?" );
672 if( mnGrfSize
.Width() != nWidth
)
674 aScaleX
= Fraction( mnGrfSize
.Width(), nWidth
);
678 if( !rFrameSize
.GetHeightPercent() )
680 SwTwips nHeight
= rFrameSize
.GetHeight();
682 nHeight
-= rBox
.CalcLineSpace(SvxBoxItemLine::TOP
) +
683 rBox
.CalcLineSpace(SvxBoxItemLine::BOTTOM
);
685 OSL_ENSURE( nHeight
>0, "Do any 0 twip high graphics exist!?" );
687 if( mnGrfSize
.Height() != nHeight
)
689 aScaleY
= Fraction( mnGrfSize
.Height(), nHeight
);
696 aURL
.GetMap()->Scale( aScaleX
, aScaleY
);
697 pFormat
->SetFormatAttr( aURL
);
701 SwContentNode
* SwGrfNode::MakeCopy(SwDoc
& rDoc
, const SwNodeIndex
& rIdx
, bool) const
703 // copy formats into the other document
704 SwGrfFormatColl
* pColl
= rDoc
.CopyGrfColl( *GetGrfColl() );
706 Graphic aTmpGrf
= GetGrf();
708 OUString sFile
, sFilter
;
710 sfx2::LinkManager::GetDisplayNames( mxLink
.get(), nullptr, &sFile
, nullptr, &sFilter
);
711 else if( IsLinkedDDE() )
713 OUString sTmp1
, sTmp2
;
714 sfx2::LinkManager::GetDisplayNames( mxLink
.get(), &sTmp1
, &sTmp2
, &sFilter
);
715 sfx2::MakeLnkName( sFile
, &sTmp1
, sTmp2
, sFilter
);
719 SwGrfNode
* pGrfNd
= SwNodes::MakeGrfNode( rIdx
, sFile
, sFilter
,
722 pGrfNd
->SetTitle( GetTitle() );
723 pGrfNd
->SetDescription( GetDescription() );
724 pGrfNd
->SetContour( HasContour(), HasAutomaticContour() );
728 /// returns the Graphic-Attr-Structure filled with our graphic attributes
729 GraphicAttr
& SwGrfNode::GetGraphicAttr( GraphicAttr
& rGA
,
730 const SwFrame
* pFrame
) const
732 const SwAttrSet
& rSet
= GetSwAttrSet();
734 rGA
.SetDrawMode( rSet
.GetDrawModeGrf().GetValue() );
736 const SwMirrorGrf
& rMirror
= rSet
.GetMirrorGrf();
737 BmpMirrorFlags nMirror
= BmpMirrorFlags::NONE
;
738 if( rMirror
.IsGrfToggle() && pFrame
&& !pFrame
->FindPageFrame()->OnRightPage() )
740 switch( rMirror
.GetValue() )
742 case MirrorGraph::Dont
:
743 nMirror
= BmpMirrorFlags::Horizontal
;
745 case MirrorGraph::Vertical
:
746 nMirror
= BmpMirrorFlags::NONE
;
748 case MirrorGraph::Horizontal
:
749 nMirror
= BmpMirrorFlags::Horizontal
|BmpMirrorFlags::Vertical
;
752 nMirror
= BmpMirrorFlags::Vertical
;
757 switch( rMirror
.GetValue() )
759 case MirrorGraph::Both
:
760 nMirror
= BmpMirrorFlags::Horizontal
|BmpMirrorFlags::Vertical
;
762 case MirrorGraph::Vertical
:
763 nMirror
= BmpMirrorFlags::Horizontal
;
765 case MirrorGraph::Horizontal
:
766 nMirror
= BmpMirrorFlags::Vertical
;
771 rGA
.SetMirrorFlags( nMirror
);
773 const SwCropGrf
& rCrop
= rSet
.GetCropGrf();
774 rGA
.SetCrop( convertTwipToMm100( rCrop
.GetLeft() ),
775 convertTwipToMm100( rCrop
.GetTop() ),
776 convertTwipToMm100( rCrop
.GetRight() ),
777 convertTwipToMm100( rCrop
.GetBottom() ));
779 const SwRotationGrf
& rRotation
= rSet
.GetRotationGrf();
780 rGA
.SetRotation( Degree10(rRotation
.GetValue()) );
782 rGA
.SetLuminance( rSet
.GetLuminanceGrf().GetValue() );
783 rGA
.SetContrast( rSet
.GetContrastGrf().GetValue() );
784 rGA
.SetChannelR( rSet
.GetChannelRGrf().GetValue() );
785 rGA
.SetChannelG( rSet
.GetChannelGGrf().GetValue() );
786 rGA
.SetChannelB( rSet
.GetChannelBGrf().GetValue() );
787 rGA
.SetGamma( rSet
.GetGammaGrf().GetValue() );
788 rGA
.SetInvert( rSet
.GetInvertGrf().GetValue() );
790 const sal_uInt16 nTrans
= rSet
.GetTransparencyGrf().GetValue();
791 rGA
.SetTransparency( static_cast<sal_uInt8
>(FRound(
792 std::min( nTrans
, sal_uInt16(100) ) * 2.55 )) );
797 bool SwGrfNode::IsTransparent() const
799 return maGrfObj
.IsTransparent() ||
800 GetSwAttrSet().GetTransparencyGrf().GetValue() != 0;
803 void SwGrfNode::TriggerAsyncRetrieveInputStream()
805 if ( !IsLinkedFile() )
807 OSL_FAIL( "<SwGrfNode::TriggerAsyncLoad()> - Method is misused. Method call is only valid for graphic nodes, which refer a linked graphic file" );
811 if (mpThreadConsumer
!= nullptr)
814 mpThreadConsumer
.reset(new SwAsyncRetrieveInputStreamThreadConsumer(*this), o3tl::default_delete
<SwAsyncRetrieveInputStreamThreadConsumer
>());
817 sfx2::LinkManager::GetDisplayNames( mxLink
.get(), nullptr, &sGrfNm
);
819 SfxObjectShell
* sh
= GetDoc().GetPersist();
820 if (sh
!= nullptr && sh
->HasName())
822 sReferer
= sh
->GetMedium()->GetName();
824 mpThreadConsumer
->CreateThread( sGrfNm
, sReferer
);
828 void SwGrfNode::ApplyInputStream(
829 const css::uno::Reference
<css::io::XInputStream
>& xInputStream
,
830 const bool bIsStreamReadOnly
)
832 if ( IsLinkedFile() )
834 if ( xInputStream
.is() )
836 mxInputStream
= xInputStream
;
837 mbIsStreamReadOnly
= bIsStreamReadOnly
;
838 mbLinkedInputStreamReady
= true;
839 SwMsgPoolItem
aMsgHint( RES_LINKED_GRAPHIC_STREAM_ARRIVED
);
840 CallSwClientNotify(sw::LegacyModifyHint(&aMsgHint
, &aMsgHint
));
845 void SwGrfNode::UpdateLinkWithInputStream()
847 // do not work on link, if a <SwapIn> has been triggered.
848 if ( mbInSwapIn
|| !IsLinkedFile() )
851 GetLink()->setStreamToLoadFrom( mxInputStream
, mbIsStreamReadOnly
);
853 TriggerGraphicArrived();
856 mxInputStream
.clear();
857 GetLink()->clearStreamToLoadFrom();
858 mbLinkedInputStreamReady
= false;
859 mpThreadConsumer
.reset();
863 bool SwGrfNode::IsAsyncRetrieveInputStreamPossible() const
867 if ( IsLinkedFile() )
870 sfx2::LinkManager::GetDisplayNames( mxLink
.get(), nullptr, &sGrfNm
);
871 if ( !sGrfNm
.startsWith( "vnd.sun.star.pkg:" ) )
880 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */