LibreOffice Module sw (master)  1
ndgrf.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <sal/config.h>
21 
22 #include <string_view>
23 
24 #include <hintids.hxx>
25 #include <tools/helpers.hxx>
26 #include <tools/urlobj.hxx>
27 #include <tools/fract.hxx>
28 #include <tools/UnitConversion.hxx>
29 #include <svl/fstathelper.hxx>
30 #include <vcl/imap.hxx>
31 #include <sfx2/docfile.hxx>
32 #include <sfx2/linkmgr.hxx>
33 #include <editeng/boxitem.hxx>
34 #include <sot/formats.hxx>
35 #include <fmtfsize.hxx>
36 #include <fmturl.hxx>
37 #include <frmfmt.hxx>
38 #include <doc.hxx>
41 #include <frmatr.hxx>
42 #include <grfatr.hxx>
43 #include <swtypes.hxx>
44 #include <ndgrf.hxx>
45 #include <fmtcol.hxx>
46 #include <hints.hxx>
47 #include <swbaslnk.hxx>
48 #include <pagefrm.hxx>
49 
50 #include <rtl/ustring.hxx>
51 #include <o3tl/deleter.hxx>
55 
56 using namespace com::sun::star;
57 
59  const SwNodeIndex & rWhere,
60  const OUString& rGrfName,
61  const OUString& rFltName,
62  const Graphic* pGraphic,
63  SwGrfFormatColl *pGrfColl,
64  SwAttrSet const * pAutoAttr ) :
65  SwNoTextNode( rWhere, SwNodeType::Grf, pGrfColl, pAutoAttr ),
66  mbInBaseLinkSwapIn(true),
67  // #i73788#
68  mbLinkedInputStreamReady( false ),
69  mbIsStreamReadOnly( false )
70 {
73 
74  ReRead(rGrfName, rFltName, pGraphic, false);
75 }
76 
78  const GraphicObject& rGrfObj,
79  SwGrfFormatColl *pGrfColl,
80  SwAttrSet const * pAutoAttr ) :
81  SwNoTextNode( rWhere, SwNodeType::Grf, pGrfColl, pAutoAttr ),
82  maGrfObj(rGrfObj),
83  mbInBaseLinkSwapIn(true),
84  // #i73788#
85  mbLinkedInputStreamReady( false ),
86  mbIsStreamReadOnly( false )
87 {
90 }
91 
99  const OUString& rGrfName,
100  const OUString& rFltName,
101  SwGrfFormatColl *pGrfColl,
102  SwAttrSet const * pAutoAttr ) :
103  SwNoTextNode( rWhere, SwNodeType::Grf, pGrfColl, pAutoAttr ),
104  mbInBaseLinkSwapIn(true),
105  // #i73788#
106  mbLinkedInputStreamReady( false ),
107  mbIsStreamReadOnly( false )
108 {
109  Graphic aGrf; aGrf.SetDefaultType();
110  maGrfObj.SetGraphic( aGrf );
111 
114 
115  InsertLink( rGrfName, rFltName );
116  if( IsLinkedFile() )
117  {
118  INetURLObject aUrl( rGrfName );
119  if( INetProtocol::File == aUrl.GetProtocol() &&
121  {
122  // file exists, so create connection without an update
123  static_cast<SwBaseLink*>( mxLink.get() )->Connect();
124  }
125  }
126 }
127 
129  const OUString& rGrfName, const OUString& rFltName,
130  const Graphic* pGraphic,
131  bool bNewGrf )
132 {
133  bool bReadGrf = false;
134  bool bSetTwipSize = true;
135  mpReplacementGraphic.reset();
136 
137  OSL_ENSURE( pGraphic || !rGrfName.isEmpty(),
138  "GraphicNode without a name, Graphic or GraphicObject" );
139 
140  OUString sURLLink;
141  if (pGraphic)
142  {
143  Graphic aGraphic(*pGraphic);
144 
145  sURLLink = aGraphic.getOriginURL();
146  if (sURLLink.isEmpty() && !rGrfName.isEmpty())
147  {
148  sURLLink = rGrfName;
149  aGraphic.setOriginURL(sURLLink);
150  }
151  }
152  else
153  {
154  sURLLink = rGrfName;
155  }
156 
157  // with name
158  if( mxLink.is() )
159  {
160  OSL_ENSURE( !mbInSwapIn, "ReRead: I am still in SwapIn" );
161 
162  if( !sURLLink.isEmpty() )
163  {
164  // Note: if there is DDE in the FltName, then it is a DDE-linked graphic
165  OUString sCmd( sURLLink );
166  if( !rFltName.isEmpty() )
167  {
169  if( rFltName == "DDE" )
171  else
172  {
173  sfx2::MakeLnkName( sCmd, nullptr, sURLLink, std::u16string_view(), &rFltName );
175  }
176 
177  if( nNewType != mxLink->GetObjType() )
178  {
179  mxLink->Disconnect();
180  static_cast<SwBaseLink*>( mxLink.get() )->SetObjType( nNewType );
181  }
182  }
183 
184  mxLink->SetLinkSourceName( sCmd );
185  }
186  else // no name anymore, so remove link
187  {
189  mxLink.clear();
190  }
191 
192  if( pGraphic )
193  {
194  maGrfObj.SetGraphic( *pGraphic );
196  bReadGrf = true;
197  }
198  else
199  {
200  // reset data of the old graphic so that the correct placeholder is
201  // shown in case the new link could not be loaded
202  Graphic aGrf; aGrf.SetDefaultType();
203  maGrfObj.SetGraphic( aGrf );
204 
205  if( mxLink.is() )
206  {
207  if( getLayoutFrame( GetDoc().getIDocumentLayoutAccess().GetCurrentLayout() ) )
208  {
210  }
211  else if ( bNewGrf )
212  {
213  //TODO refLink->setInputStream(getInputStream());
214  static_cast<SwBaseLink*>( mxLink.get() )->SwapIn();
215  }
216  }
218  bSetTwipSize = false;
219  }
220  }
221  else if( pGraphic && sURLLink.isEmpty() )
222  {
223  maGrfObj.SetGraphic( *pGraphic );
225  bReadGrf = true;
226  }
227  // Was the graphic already loaded?
228  else if( !bNewGrf && GraphicType::NONE != maGrfObj.GetType() )
229  return true;
230  else
231  {
232  // create new link for the graphic object
233  InsertLink( sURLLink, rFltName );
234 
235  if( GetNodes().IsDocNodes() )
236  {
237  if( pGraphic )
238  {
239  maGrfObj.SetGraphic( *pGraphic );
241  bReadGrf = true;
242  // create connection without update, as we have the graphic
243  static_cast<SwBaseLink*>( mxLink.get() )->Connect();
244  }
245  else
246  {
247  Graphic aGrf;
248  aGrf.SetDefaultType();
249  maGrfObj.SetGraphic( aGrf );
251  if ( bNewGrf )
252  {
253  static_cast<SwBaseLink*>( mxLink.get() )->SwapIn();
254  }
255  }
256  }
257  }
258 
259  // Bug 39281: Do not delete Size immediately - Events on ImageMaps should have
260  // something to work with when swapping
261  if( bSetTwipSize )
263 
264  // create an updates for the frames
265  if( bReadGrf && bNewGrf )
266  {
267  const SwUpdateAttr aHint(0,0,0);
268  CallSwClientNotify(sw::LegacyModifyHint(&aHint, &aHint));
269  }
270 
271  return bReadGrf;
272 }
273 
275 {
276  mpReplacementGraphic.reset();
277 
278  // #i73788#
279  mpThreadConsumer.reset();
280 
281  SwDoc& rDoc = GetDoc();
282  if( mxLink.is() )
283  {
284  OSL_ENSURE( !mbInSwapIn, "DTOR: I am still in SwapIn" );
286  mxLink->Disconnect();
287  }
288  else
289  {
290  // #i40014# - A graphic node, which is in a linked
291  // section, whose link is another section in the document, doesn't
292  // have to remove the stream from the storage.
293  // Because it's hard to detect this case here and it would only fix
294  // one problem with shared graphic files - there are also problems,
295  // a certain graphic file is referenced by two independent graphic nodes,
296  // brush item or drawing objects, the stream isn't no longer removed here.
297  // To do this stuff correctly, a reference counting on shared streams
298  // inside one document has to be implemented.
299  }
300  //#39289# delete frames already here since the Frames' dtor needs the graphic for its StopAnimation
301  if( HasWriterListeners() )
302  DelFrames(nullptr);
304 }
305 
308 {
309  // try to access SwFlyFrameFormat; since title/desc/name are set there, there is no
310  // use to continue if it is not yet set. If not yet set, call onGraphicChanged()
311  // when it is set.
312  SwFlyFrameFormat* pFlyFormat = dynamic_cast< SwFlyFrameFormat* >(GetFlyFormat());
313 
314  if(!pFlyFormat)
315  return;
316 
317  OUString aName;
318  OUString aTitle;
319  OUString aDesc;
320  auto const & rVectorGraphicDataPtr = GetGrf().getVectorGraphicData();
321 
322  if (rVectorGraphicDataPtr)
323  {
324  const drawinglayer::primitive2d::Primitive2DContainer aSequence(rVectorGraphicDataPtr->getPrimitive2DSequence());
325 
326  if(!aSequence.empty())
327  {
329  drawinglayer::processor2d::ObjectInfoPrimitiveExtractor2D aProcessor(aViewInformation2D);
330 
331  aProcessor.process(aSequence);
332 
333  const drawinglayer::primitive2d::ObjectInfoPrimitive2D* pResult = aProcessor.getResult();
334 
335  if(pResult)
336  {
337  aName = pResult->getName();
338  aTitle = pResult->getTitle();
339  aDesc = pResult->getDesc();
340  }
341  }
342  }
343 
344  if(!aTitle.isEmpty())
345  {
346  SetTitle(aTitle);
347  }
348  else if (!aName.isEmpty())
349  {
350  SetTitle(aName);
351  }
352 
353  if(!aDesc.isEmpty())
354  {
355  SetDescription(aDesc);
356  }
357 }
358 
359 void SwGrfNode::SetGraphic(const Graphic& rGraphic)
360 {
361  maGrfObj.SetGraphic(rGraphic);
363 }
364 
366 {
369 }
370 
371 const Graphic& SwGrfNode::GetGrf(bool bWait) const
372 {
373  const_cast<SwGrfNode*>(this)->SwapIn(bWait);
374  return maGrfObj.GetGraphic();
375 }
376 
377 const GraphicObject& SwGrfNode::GetGrfObj(bool bWait) const
378 {
379  const_cast<SwGrfNode*>(this)->SwapIn(bWait);
380  return maGrfObj;
381 }
382 
384 {
386  {
387  auto const & rVectorGraphicDataPtr = GetGrfObj().GetGraphic().getVectorGraphicData();
388 
389  if (rVectorGraphicDataPtr)
390  {
391  const_cast< SwGrfNode* >(this)->mpReplacementGraphic.reset( new GraphicObject(rVectorGraphicDataPtr->getReplacement()) );
392  }
393  else if (GetGrfObj().GetGraphic().GetType() == GraphicType::GdiMetafile)
394  {
395  // Replacement graphic for PDF and metafiles is just the bitmap.
396  const_cast<SwGrfNode*>(this)->mpReplacementGraphic.reset( new GraphicObject(GetGrfObj().GetGraphic().GetBitmapEx()) );
397  }
398  }
399 
400  return mpReplacementGraphic.get();
401 }
402 
404  const OUString& rGrfName,
405  const OUString& rFltName,
406  const Graphic* pGraphic,
407  SwGrfFormatColl* pGrfColl,
408  SwAttrSet const * pAutoAttr )
409 {
410  OSL_ENSURE( pGrfColl, "MakeGrfNode: Formatpointer is 0." );
411  SwGrfNode *pNode;
412  // create object delayed, only from a SW/G-reader
413  if( !pGraphic )
414  pNode = new SwGrfNode( rWhere, rGrfName,
415  rFltName, pGrfColl, pAutoAttr );
416  else
417  pNode = new SwGrfNode( rWhere, rGrfName,
418  rFltName, pGraphic, pGrfColl, pAutoAttr );
419  return pNode;
420 }
421 
423  const GraphicObject& rGrfObj,
424  SwGrfFormatColl* pGrfColl )
425 {
426  OSL_ENSURE( pGrfColl, "MakeGrfNode: Formatpointer is 0." );
427  return new SwGrfNode( rWhere, rGrfObj, pGrfColl, nullptr );
428 }
429 
431 {
432  if( !mnGrfSize.Width() && !mnGrfSize.Height() )
433  {
434  const_cast<SwGrfNode*>(this)->SwapIn();
435  }
436  return mnGrfSize;
437 }
438 
443 bool SwGrfNode::SwapIn(bool bWaitForData)
444 {
445  if(mbInSwapIn) // not recursively!
446  return true;
447 
448  bool bRet = false;
449  mbInSwapIn = true;
450  SwBaseLink* pLink = static_cast<SwBaseLink*>( mxLink.get() );
451 
452  if( pLink )
453  {
454  if( (GraphicType::NONE == maGrfObj.GetType() ||
455  GraphicType::Default == maGrfObj.GetType()) &&
457  {
458  // link was not loaded yet
459  if( pLink->SwapIn( bWaitForData ) )
460  {
461  bRet = true;
462  mbInBaseLinkSwapIn = false;
463  }
464  else if( GraphicType::Default == maGrfObj.GetType() )
465  {
466  // no default bitmap anymore, thus re-paint
467  mpReplacementGraphic.reset();
468 
472  CallSwClientNotify(sw::LegacyModifyHint(&aMsgHint, &aMsgHint));
473  }
474  }
475  else
476  {
477  bRet = true;
478  }
479  }
480  else
481  bRet = true;
482 
483  if (bRet)
484  {
485  if( !mnGrfSize.Width() && !mnGrfSize.Height() )
487  }
488  mbInSwapIn = false;
489  return bRet;
490 }
491 
492 bool SwGrfNode::GetFileFilterNms( OUString* pFileNm, OUString* pFilterNm ) const
493 {
494  bool bRet = false;
495  if( mxLink.is() && mxLink->GetLinkManager() )
496  {
500  mxLink.get(), nullptr, pFileNm, nullptr, pFilterNm );
501  else if( sfx2::SvBaseLinkObjectType::ClientDde == nType && pFileNm && pFilterNm )
502  {
503  OUString sApp;
504  OUString sTopic;
505  OUString sItem;
507  mxLink.get(), &sApp, &sTopic, &sItem ) )
508  {
509  *pFileNm = sApp + OUStringChar(sfx2::cTokenSeparator)
510  + sTopic + OUStringChar(sfx2::cTokenSeparator)
511  + sItem;
512  *pFilterNm = "DDE";
513  bRet = true;
514  }
515  }
516  }
517  return bRet;
518 }
519 
525 {
526  if( mxLink.is() )
527  {
528  OSL_ENSURE( !mbInSwapIn, "SavePersistentData: I am still in SwapIn" );
530  return true;
531  }
532 
533  // swap in first if in storage
534  if( HasEmbeddedStreamName() && !SwapIn() )
535  return false;
536 
537  // #i44367#
538  // Do not delete graphic file in storage, because the graphic file could
539  // be referenced by other graphic nodes.
540  // Because it's hard to detect this case here and it would only fix
541  // one problem with shared graphic files - there are also problems, if
542  // a certain graphic file is referenced by two independent graphic nodes,
543  // brush item or drawing objects, the stream isn't no longer removed here.
544  // To do this stuff correct, a reference counting on shared streams
545  // inside one document has to be implemented.
546  // Important note: see also fix for #i40014#
547 
548  // swap out into temp file
549  return true;
550 }
551 
553 {
554  if( mxLink.is() )
555  {
557  mxLink->SetVisible( rIDLA.IsVisibleLinks() );
558  rIDLA.GetLinkManager().InsertDDELink( mxLink.get() );
560  mxLink->Update();
561  }
562  return true;
563 }
564 
565 void SwGrfNode::InsertLink( const OUString& rGrfName, const OUString& rFltName )
566 {
567  mxLink = new SwBaseLink( SfxLinkUpdateMode::ONCALL, SotClipboardFormatId::GDIMETAFILE, this );
568 
570  if( !GetNodes().IsDocNodes() )
571  return;
572 
573  mxLink->SetVisible( rIDLA.IsVisibleLinks() );
574  if( rFltName == "DDE" )
575  {
576  sal_Int32 nTmp = 0;
577  const OUString sApp{ rGrfName.getToken( 0, sfx2::cTokenSeparator, nTmp ) };
578  const OUString sTopic{ rGrfName.getToken( 0, sfx2::cTokenSeparator, nTmp ) };
579  const OUString sItem{ rGrfName.copy( nTmp ) };
580  rIDLA.GetLinkManager().InsertDDELink( mxLink.get(), sApp, sTopic, sItem );
581  }
582  else
583  {
584  const bool bSync = rFltName == "SYNCHRON";
585  mxLink->SetSynchron( bSync );
586  mxLink->SetContentType( SotClipboardFormatId::SVXB );
587 
590  (!bSync && !rFltName.isEmpty() ? &rFltName : nullptr) );
591  }
592 }
593 
595 {
596  if( !mxLink.is() )
597  return;
598 
599  Graphic aLocalGraphic(maGrfObj.GetGraphic());
600  const bool bHasOriginalData(aLocalGraphic.IsGfxLink());
601 
602  {
603  mbInSwapIn = true;
604  SwBaseLink* pLink = static_cast<SwBaseLink*>( mxLink.get() );
605  pLink->SwapIn( true, true );
606  mbInSwapIn = false;
607  }
608 
610  mxLink.clear();
611  aLocalGraphic.setOriginURL("");
612 
613  // #i15508# added extra processing after getting rid of the link. Use whatever is
614  // known from the formerly linked graphic to get to a state as close to a directly
615  // unlinked inserted graphic as possible. Goal is to have a valid GfxLink at the
616  // ImplGraphic (see there) that holds temporary data to the original data and type
617  // information about the original data. Only when this is given will
618  // SvXMLGraphicHelper::ImplInsertGraphicURL which is used at export use that type
619  // and use the original graphic at export for the ODF, without evtl. recoding
620  // of the bitmap graphic data to something without loss (e.g. PNG) but bigger
621  if(bHasOriginalData)
622  {
623  // #i15508# if we have the original data at the Graphic, let it survive
624  // by using that Graphic again, this time at a GraphicObject without link.
625  // This happens e.g. when inserting a linked graphic and breaking the link
626  maGrfObj.SetGraphic(aLocalGraphic);
627  }
628 }
629 
630 void SwGrfNode::SetTwipSize( const Size& rSz )
631 {
632  mnGrfSize = rSz;
634  {
635  // resize Image-Map to size of the graphic
636  ScaleImageMap();
637 
638  // do not re-scale Image-Map
639  SetScaleImageMap( false );
640  }
641 }
642 
644 {
645  if( !mnGrfSize.Width() || !mnGrfSize.Height() )
646  return;
647 
648  // re-scale Image-Map
649  SwFrameFormat* pFormat = GetFlyFormat();
650 
651  if( !pFormat )
652  return;
653 
654  SwFormatURL aURL( pFormat->GetURL() );
655  if ( !aURL.GetMap() )
656  return;
657 
658  bool bScale = false;
659  Fraction aScaleX( 1, 1 );
660  Fraction aScaleY( 1, 1 );
661 
662  const SwFormatFrameSize& rFrameSize = pFormat->GetFrameSize();
663  const SvxBoxItem& rBox = pFormat->GetBox();
664 
665  if( !rFrameSize.GetWidthPercent() )
666  {
667  SwTwips nWidth = rFrameSize.GetWidth();
668 
669  nWidth -= rBox.CalcLineSpace(SvxBoxItemLine::LEFT) +
670  rBox.CalcLineSpace(SvxBoxItemLine::RIGHT);
671 
672  OSL_ENSURE( nWidth>0, "Do any 0 twip wide graphics exist!?" );
673 
674  if( mnGrfSize.Width() != nWidth )
675  {
676  aScaleX = Fraction( mnGrfSize.Width(), nWidth );
677  bScale = true;
678  }
679  }
680  if( !rFrameSize.GetHeightPercent() )
681  {
682  SwTwips nHeight = rFrameSize.GetHeight();
683 
684  nHeight -= rBox.CalcLineSpace(SvxBoxItemLine::TOP) +
685  rBox.CalcLineSpace(SvxBoxItemLine::BOTTOM);
686 
687  OSL_ENSURE( nHeight>0, "Do any 0 twip high graphics exist!?" );
688 
689  if( mnGrfSize.Height() != nHeight )
690  {
691  aScaleY = Fraction( mnGrfSize.Height(), nHeight );
692  bScale = true;
693  }
694  }
695 
696  if( bScale )
697  {
698  aURL.GetMap()->Scale( aScaleX, aScaleY );
699  pFormat->SetFormatAttr( aURL );
700  }
701 }
702 
703 SwContentNode* SwGrfNode::MakeCopy(SwDoc& rDoc, const SwNodeIndex& rIdx, bool) const
704 {
705  // copy formats into the other document
706  SwGrfFormatColl* pColl = rDoc.CopyGrfColl( *GetGrfColl() );
707 
708  Graphic aTmpGrf = GetGrf();
709 
710  OUString sFile, sFilter;
711  if( IsLinkedFile() )
712  sfx2::LinkManager::GetDisplayNames( mxLink.get(), nullptr, &sFile, nullptr, &sFilter );
713  else if( IsLinkedDDE() )
714  {
715  OUString sTmp1, sTmp2;
716  sfx2::LinkManager::GetDisplayNames( mxLink.get(), &sTmp1, &sTmp2, &sFilter );
717  sfx2::MakeLnkName( sFile, &sTmp1, sTmp2, sFilter );
718  sFilter = "DDE";
719  }
720 
721  SwGrfNode* pGrfNd = SwNodes::MakeGrfNode( rIdx, sFile, sFilter,
722  &aTmpGrf, pColl,
723  GetpSwAttrSet() );
724  pGrfNd->SetTitle( GetTitle() );
725  pGrfNd->SetDescription( GetDescription() );
726  pGrfNd->SetContour( HasContour(), HasAutomaticContour() );
727  return pGrfNd;
728 }
729 
732  const SwFrame* pFrame ) const
733 {
734  const SwAttrSet& rSet = GetSwAttrSet();
735 
736  rGA.SetDrawMode( rSet.GetDrawModeGrf().GetValue() );
737 
738  const SwMirrorGrf & rMirror = rSet.GetMirrorGrf();
739  BmpMirrorFlags nMirror = BmpMirrorFlags::NONE;
740  if( rMirror.IsGrfToggle() && pFrame && !pFrame->FindPageFrame()->OnRightPage() )
741  {
742  switch( rMirror.GetValue() )
743  {
744  case MirrorGraph::Dont:
745  nMirror = BmpMirrorFlags::Horizontal;
746  break;
748  nMirror = BmpMirrorFlags::NONE;
749  break;
751  nMirror = BmpMirrorFlags::Horizontal|BmpMirrorFlags::Vertical;
752  break;
753  default:
754  nMirror = BmpMirrorFlags::Vertical;
755  break;
756  }
757  }
758  else
759  switch( rMirror.GetValue() )
760  {
761  case MirrorGraph::Both:
762  nMirror = BmpMirrorFlags::Horizontal|BmpMirrorFlags::Vertical;
763  break;
765  nMirror = BmpMirrorFlags::Horizontal;
766  break;
768  nMirror = BmpMirrorFlags::Vertical;
769  break;
770  default: break;
771  }
772 
773  rGA.SetMirrorFlags( nMirror );
774 
775  const SwCropGrf& rCrop = rSet.GetCropGrf();
776 
777  tools::Long nCropLeft = rCrop.GetLeft();
778  tools::Long nCropTop = rCrop.GetTop();
779  tools::Long nCropRight = rCrop.GetRight();
780  tools::Long nCropBottom = rCrop.GetBottom();
781 
782  // take mirroring of crop values into consideration
783  // while cropping a flipped image. otherwise,
784  // cropping will crop the opposite side of the image.
785  if (rGA.GetMirrorFlags() & BmpMirrorFlags::Vertical)
786  {
787  nCropTop = rCrop.GetBottom();
788  nCropBottom = rCrop.GetTop();
789  }
790 
791  if (rGA.GetMirrorFlags() & BmpMirrorFlags::Horizontal)
792  {
793  nCropLeft = rCrop.GetRight();
794  nCropRight = rCrop.GetLeft();
795  }
796 
797  rGA.SetCrop( convertTwipToMm100( nCropLeft ),
798  convertTwipToMm100( nCropTop ),
799  convertTwipToMm100( nCropRight ),
800  convertTwipToMm100( nCropBottom ));
801 
802  const SwRotationGrf& rRotation = rSet.GetRotationGrf();
803  rGA.SetRotation( rRotation.GetValue() );
804 
805  rGA.SetLuminance( rSet.GetLuminanceGrf().GetValue() );
806  rGA.SetContrast( rSet.GetContrastGrf().GetValue() );
807  rGA.SetChannelR( rSet.GetChannelRGrf().GetValue() );
808  rGA.SetChannelG( rSet.GetChannelGGrf().GetValue() );
809  rGA.SetChannelB( rSet.GetChannelBGrf().GetValue() );
810  rGA.SetGamma( rSet.GetGammaGrf().GetValue() );
811  rGA.SetInvert( rSet.GetInvertGrf().GetValue() );
812 
813  const sal_uInt16 nTrans = rSet.GetTransparencyGrf().GetValue();
814  rGA.SetAlpha( 255 - static_cast<sal_uInt8>(FRound(
815  std::min( nTrans, sal_uInt16(100) ) * 2.55 )) );
816 
817  return rGA;
818 }
819 
821 {
822  return maGrfObj.IsTransparent() ||
824 }
825 
827 {
828  if ( !IsLinkedFile() )
829  {
830  OSL_FAIL( "<SwGrfNode::TriggerAsyncLoad()> - Method is misused. Method call is only valid for graphic nodes, which refer a linked graphic file" );
831  return;
832  }
833 
834  if (mpThreadConsumer != nullptr)
835  return;
836 
838 
839  OUString sGrfNm;
840  sfx2::LinkManager::GetDisplayNames( mxLink.get(), nullptr, &sGrfNm );
841  OUString sReferer;
842  SfxObjectShell * sh = GetDoc().GetPersist();
843  if (sh != nullptr && sh->HasName())
844  {
845  sReferer = sh->GetMedium()->GetName();
846  }
847  mpThreadConsumer->CreateThread( sGrfNm, sReferer );
848 }
849 
850 
852  const css::uno::Reference<css::io::XInputStream>& xInputStream,
853  const bool bIsStreamReadOnly )
854 {
855  if ( IsLinkedFile() )
856  {
857  if ( xInputStream.is() )
858  {
859  mxInputStream = xInputStream;
860  mbIsStreamReadOnly = bIsStreamReadOnly;
863  CallSwClientNotify(sw::LegacyModifyHint(&aMsgHint, &aMsgHint));
864  }
865  }
866 }
867 
869 {
870  // do not work on link, if a <SwapIn> has been triggered.
871  if ( mbInSwapIn || !IsLinkedFile() )
872  return;
873 
875  GetLink()->Update();
877 
878  // #i88291#
879  mxInputStream.clear();
881  mbLinkedInputStreamReady = false;
882  mpThreadConsumer.reset();
883 }
884 
885 // #i90395#
887 {
888  bool bRet = false;
889 
890  if ( IsLinkedFile() )
891  {
892  OUString sGrfNm;
893  sfx2::LinkManager::GetDisplayNames( mxLink.get(), nullptr, &sGrfNm );
894  if ( !sGrfNm.startsWith( "vnd.sun.star.pkg:" ) )
895  {
896  bRet = true;
897  }
898  }
899 
900  return bRet;
901 }
902 
903 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
BitmapEx GetBitmapEx(BitmapEx const &rBitmapEx, DrawModeFlags nDrawMode)
SwGrfNode(const SwNodeIndex &rWhere, const OUString &rGrfName, const OUString &rFltName, const Graphic *pGraphic, SwGrfFormatColl *pGrfColl, SwAttrSet const *pAutoAttr)
Ctor for reading (SW/G) without graphics.
Definition: ndgrf.cxx:58
bool GetValue() const
Graphic GetGraphic() const
Definition: ndnotxt.cxx:229
bool is() const
SwNodeOffset min(const SwNodeOffset &a, const SwNodeOffset &b)
Definition: nodeoffset.hxx:33
void SetDescription(const OUString &rDescription)
Definition: ndnotxt.cxx:270
void SetGamma(double fGamma)
Base class of the Writer layout elements.
Definition: frame.hxx:315
tools::Long GetWidth() const
constexpr TypedWhichId< SwFormatPageDesc > RES_PAGEDESC(93)
std::shared_ptr< SwAsyncRetrieveInputStreamThreadConsumer > mpThreadConsumer
Definition: ndgrf.hxx:49
SVL_DLLPUBLIC bool IsDocument(const OUString &rURL)
URL aURL
const SwGammaGrf & GetGammaGrf(bool=true) const
Definition: grfatr.hxx:298
void ApplyInputStream(const css::uno::Reference< css::io::XInputStream > &xInputStream, const bool bIsStreamReadOnly)
Definition: ndgrf.cxx:851
const double & GetValue() const
Definition: grfatr.hxx:211
sal_Int32 GetLeft() const
bool HasEmbeddedStreamName() const
Definition: ndgrf.hxx:122
const tools::SvRef< sfx2::SvBaseLink > & GetLink() const
Definition: ndgrf.hxx:132
BmpMirrorFlags GetMirrorFlags() const
bool HasAutomaticContour() const
Definition: ndnotxt.hxx:78
virtual const SwRootFrame * GetCurrentLayout() const =0
tools::SvRef< sfx2::SvBaseLink > mxLink
If graphics only as link then pointer is set.
Definition: ndgrf.hxx:40
void ScaleImageMap()
Scale an image-map: the image-map becomes zoomed in / out by factor between graphic-size and border-s...
Definition: ndgrf.cxx:643
void InsertFileLink(sfx2::SvBaseLink &, SvBaseLinkObjectType nFileType, std::u16string_view rFileNm, const OUString *pFilterNm=nullptr, const OUString *pRange=nullptr)
const OUString & GetName() const
void SetInvert(bool bInvert)
long Long
void SetTitle(const OUString &rTitle)
Definition: ndnotxt.cxx:245
const sal_Unicode cTokenSeparator
constexpr TypedWhichId< SwMsgPoolItem > RES_LINKED_GRAPHIC_STREAM_ARRIVED(189)
SwContentFrame * getLayoutFrame(const SwRootFrame *, const SwPosition *pPos=nullptr, std::pair< Point, bool > const *pViewPosAndCalcFrame=nullptr) const
Definition: node.cxx:1213
Definition: doc.hxx:188
IDocumentLinksAdministration const & getIDocumentLinksAdministration() const
Definition: doc.cxx:260
void SetMirrorFlags(BmpMirrorFlags nMirrFlags)
void setOriginURL(OUString const &rOriginURL)
bool IsLinkedFile() const
Definition: ndgrf.hxx:164
const SwChannelRGrf & GetChannelRGrf(bool=true) const
Definition: grfatr.hxx:292
bool mbScaleImageMap
Scale image map in SetTwipSize.
Definition: ndgrf.hxx:47
const GraphicObject * GetReplacementGrfObj() const
Definition: ndgrf.cxx:383
bool HasWriterListeners() const
Definition: calbck.hxx:203
void SetDrawMode(GraphicDrawMode eDrawMode)
bool mbInSwapIn
Definition: ndgrf.hxx:42
virtual ~SwGrfNode() override
Definition: ndgrf.cxx:274
const SvxBoxItem & GetBox(bool=true) const
Definition: frmatr.hxx:84
const tools::PolyPolygon * HasContour() const
Definition: ndnotxt.cxx:105
constexpr auto convertTwipToMm100(N n)
constexpr tools::Long Width() const
Size mnGrfSize
Definition: ndgrf.hxx:41
const SwChannelBGrf & GetChannelBGrf(bool=true) const
Definition: grfatr.hxx:296
bool IsAsyncRetrieveInputStreamPossible() const
Definition: ndgrf.cxx:886
const SwTransparencyGrf & GetTransparencyGrf(bool=true) const
Definition: grfatr.hxx:302
void TriggerAsyncRetrieveInputStream()
Definition: ndgrf.cxx:826
GraphicAttr & GetGraphicAttr(GraphicAttr &, const SwFrame *pFrame) const
Returns the with our graphic attributes filled Graphic-Attr-Structure.
Definition: ndgrf.cxx:731
static SwGrfNode * MakeGrfNode(const SwNodeIndex &rWhere, const OUString &rGrfName, const OUString &rFltName, const Graphic *pGraphic, SwGrfFormatColl *pColl, SwAttrSet const *pAutoAttr=nullptr)
in ndgrf.cxx
Definition: ndgrf.cxx:403
bool OnRightPage() const
Definition: frame.hxx:734
class to provide creation of a thread to retrieve an input stream given by a URL and to consume the r...
bool GetFileFilterNms(OUString *pFileNm, OUString *pFilterNm) const
Definition: ndgrf.cxx:492
const SwCropGrf & GetCropGrf(bool=true) const
Definition: grfatr.hxx:284
const IDocumentLinksAdministration & getIDocumentLinksAdministration() const
Provides access to the document links administration interface.
Definition: node.cxx:2100
virtual bool ResetAttr(sal_uInt16 nWhich1, sal_uInt16 nWhich2=0)
Definition: node.cxx:1658
SwGrfFormatColl * GetGrfColl() const
Definition: ndnotxt.hxx:58
const SwAttrSet * GetpSwAttrSet() const
Definition: node.hxx:451
T * get() const
Style of a layout element.
Definition: frmfmt.hxx:59
SwNodeType
Definition: ndtyp.hxx:28
sal_Int16 GetValue() const
bool mbLinkedInputStreamReady
Definition: ndgrf.hxx:50
void SetAlpha(sal_uInt8 cAlpha)
SwDoc & GetDoc()
Definition: node.hxx:213
virtual SwContentNode * MakeCopy(SwDoc &, const SwNodeIndex &, bool bNewFrames) const override
in ndcopy.cxx
Definition: ndgrf.cxx:703
void SetGraphic(const Graphic &rGraphic)
isolated only way to set GraphicObject to allow more actions when doing so
Definition: ndgrf.cxx:359
GraphicType GetType() const
css::uno::Reference< css::io::XInputStream > mxInputStream
Definition: ndgrf.hxx:51
void Remove(SvBaseLink const *pLink)
void SetContrast(short nContrastPercent)
tools::Long FRound(double fVal)
SwPageFrame * FindPageFrame()
Definition: frame.hxx:681
virtual bool SavePersistentData() override
Communicate to graphic that node is in Undo-range.
Definition: ndgrf.cxx:524
void SetRotation(Degree10 nRotate10)
const primitive2d::ObjectInfoPrimitive2D * getResult() const
sal_uInt8 GetHeightPercent() const
Definition: fmtfsize.hxx:88
void DelFrames(SwRootFrame const *pLayout)
Method deletes all views of document for the node.
Definition: node.cxx:1409
const SwFormatURL & GetURL(bool=true) const
Definition: fmturl.hxx:78
void SetChannelG(short nChannelGPercent)
SvBaseLinkObjectType
void TriggerGraphicArrived()
Definition: ndgrf.cxx:365
void process(const primitive2d::Primitive2DContainer &rSource)
bool mbChangeTwipSize
Definition: ndgrf.hxx:45
GraphicObject maGrfObj
Definition: ndgrf.hxx:38
Marks a node in the document model.
Definition: ndindex.hxx:32
bool HasName() const
OUString getOriginURL() const
SwNodes & GetNodes()
Node is in which nodes-array/doc?
Definition: node.hxx:695
Document links administration interface.
const SwRotationGrf & GetRotationGrf(bool=true) const
Definition: grfatr.hxx:286
const SwContrastGrf & GetContrastGrf(bool=true) const
Definition: grfatr.hxx:290
OUString GetDescription() const
Definition: ndnotxt.cxx:282
sal_uInt8 GetWidthPercent() const
Definition: fmtfsize.hxx:91
void SetChannelR(short nChannelRPercent)
tools::Long GetHeight() const
bool ReRead(const OUString &rGrfName, const OUString &rFltName, const Graphic *pGraphic=nullptr, bool bModify=true)
Re-read in case graphic was not OK.
Definition: ndgrf.cxx:128
void SetTwipSize(const Size &rSz)
Definition: ndgrf.cxx:630
constexpr TypedWhichId< SwMsgPoolItem > RES_GRAPHIC_PIECE_ARRIVED(177)
const GraphicObject & GetGrfObj(bool bWait=false) const
Definition: ndgrf.cxx:377
bool IsScaleImageMap() const
Definition: ndgrf.hxx:106
tools::Long SwTwips
Definition: swtypes.hxx:52
GraphicType GetType() const
virtual Size GetTwipSize() const override
Definition: ndgrf.cxx:430
void InsertLink(const OUString &rGrfName, const OUString &rFltName)
Definition: ndgrf.cxx:565
void SetChannelB(short nChannelBPercent)
Degree10 GetValue() const
Definition: grfatr.hxx:109
SwGrfFormatColl * CopyGrfColl(const SwGrfFormatColl &rColl)
copy the graphic nodes
Definition: docfmt.cxx:1245
const IDocumentLayoutAccess & getIDocumentLayoutAccess() const
Provides access to the document layout interface.
Definition: node.cxx:2098
virtual bool SetFormatAttr(const SfxPoolItem &rAttr)
Definition: format.cxx:450
void MakeLnkName(OUString &rName, const OUString *pType, std::u16string_view rFile, std::u16string_view rLink, const OUString *pFilter)
sal_Int32 GetBottom() const
OUString GetMainURL(DecodeMechanism eMechanism, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
const SwMirrorGrf & GetMirrorGrf(bool=true) const
Definition: grfatr.hxx:282
static bool GetDisplayNames(const SvBaseLink *, OUString *pType, OUString *pFile=nullptr, OUString *pLink=nullptr, OUString *pFilter=nullptr)
sal_Int32 GetTop() const
void InsertDDELink(SvBaseLink *, const OUString &rServer, std::u16string_view rTopic, std::u16string_view rItem)
bool IsLinkedDDE() const
Definition: ndgrf.hxx:169
void SetScaleImageMap(bool b)
Definition: ndgrf.hxx:107
const Graphic & GetGraphic() const
SvBaseLink * pLink
constexpr tools::Long Height() const
OUString GetTitle() const
Definition: ndnotxt.cxx:258
void SetGraphic(const Graphic &rGraphic)
void SetLuminance(short nLuminancePercent)
OUString aName
INetProtocol GetProtocol() const
bool mbIsStreamReadOnly
Definition: ndgrf.hxx:52
SfxObjectShell * GetPersist() const
Definition: docnew.cxx:639
void UpdateLinkWithInputStream()
Definition: ndgrf.cxx:868
std::unique_ptr< GraphicObject > mpReplacementGraphic
Definition: ndgrf.hxx:39
void onGraphicChanged()
allow reaction on change of content of GraphicObject, so always call when GraphicObject content chang...
Definition: ndgrf.cxx:307
const SwChannelGGrf & GetChannelGGrf(bool=true) const
Definition: grfatr.hxx:294
QPRO_FUNC_TYPE nType
const SwFormatFrameSize & GetFrameSize(bool=true) const
Definition: fmtfsize.hxx:104
const SwAttrSet & GetSwAttrSet() const
Does node has already its own auto-attributes? Access to SwAttrSet.
Definition: node.hxx:716
virtual void CallSwClientNotify(const SfxHint &rHint) const override
Definition: calbck.cxx:326
sal_uInt16 CalcLineSpace(SvxBoxItemLine nLine, bool bEvenIfNoLine=false) const
sal_Int32 GetRight() const
virtual sfx2::LinkManager & GetLinkManager()=0
const SwDrawModeGrf & GetDrawModeGrf(bool=true) const
Definition: grfatr.hxx:304
bool SwapIn(bool bWaitForData=false)
Loading of graphic immediately before displaying.
Definition: ndgrf.cxx:443
void ReleaseLink()
Definition: ndgrf.cxx:594
const SwInvertGrf & GetInvertGrf(bool=true) const
Definition: grfatr.hxx:300
bool IsTransparent() const
Definition: ndgrf.cxx:820
void SetDefaultType()
void SetCrop(tools::Long nLeft_100TH_MM, tools::Long nTop_100TH_MM, tools::Long nRight_100TH_MM, tools::Long nBottom_100TH_MM)
sal_uInt8 GetValue() const
bool mbInBaseLinkSwapIn
Definition: ndgrf.hxx:43
const SwLuminanceGrf & GetLuminanceGrf(bool=true) const
Definition: grfatr.hxx:288
const std::shared_ptr< VectorGraphicData > & getVectorGraphicData() const
virtual bool RestorePersistentData() override
Dummies for loading/saving of persistent data when working with graphics and OLE objects.
Definition: ndgrf.cxx:552
bool IsTransparent() const
bool IsGrfToggle() const
Definition: grfatr.hxx:65
SwFrameFormat * GetFlyFormat() const
If node is in a fly return the respective format.
Definition: node.cxx:719
const Graphic & GetGrf(bool bWait=false) const
Definition: ndgrf.cxx:371
void SetContour(const tools::PolyPolygon *pPoly, bool bAutomatic=false)
Definition: ndnotxt.cxx:85
bool mbFrameInPaint
To avoid Start-/EndActions in Paint via SwapIn.
Definition: ndgrf.hxx:46
Size GetGraphicSizeTwip(const Graphic &rGraphic, vcl::RenderContext *pOutDev)
Definition: swtypes.cxx:28
virtual bool IsVisibleLinks() const =0
Insert links in-/visibly into LinkManager (linked ranges).
EnumT GetValue() const
BmpMirrorFlags
SfxMedium * GetMedium() const