LibreOffice Module vcl (master)  1
impgraph.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 #include <sal/log.hxx>
22 
23 #include <SwapFile.hxx>
24 
25 #include <comphelper/fileformat.h>
26 #include <o3tl/make_shared.hxx>
27 #include <tools/fract.hxx>
28 #include <tools/vcompat.hxx>
29 #include <tools/urlobj.hxx>
30 #include <tools/stream.hxx>
31 #include <unotools/ucbhelper.hxx>
33 #include <unotools/tempfile.hxx>
34 #include <vcl/filter/SvmReader.hxx>
35 #include <vcl/filter/SvmWriter.hxx>
36 #include <vcl/outdev.hxx>
37 #include <vcl/graphicfilter.hxx>
38 #include <vcl/virdev.hxx>
39 #include <vcl/gfxlink.hxx>
40 #include <vcl/cvtgrf.hxx>
41 #include <vcl/graph.hxx>
42 #include <vcl/metaact.hxx>
43 #include <impgraph.hxx>
44 #include <com/sun/star/graphic/XPrimitive2D.hpp>
46 #include <vcl/dibtools.hxx>
47 #include <map>
48 #include <memory>
49 #include <vcl/gdimetafiletools.hxx>
50 #include <vcl/TypeSerializer.hxx>
51 #include <vcl/pdfread.hxx>
53 
54 #define GRAPHIC_MTFTOBMP_MAXEXT 2048
55 #define GRAPHIC_STREAMBUFSIZE 8192UL
56 
57 #define SWAP_FORMAT_ID COMPAT_FORMAT( 'S', 'W', 'A', 'P' )
58 
59 using namespace com::sun::star;
60 
61 class ImpSwapFile : public vcl::SwapFile
62 {
63 private:
64  OUString maOriginURL;
65 
66 public:
67  ImpSwapFile(INetURLObject const & rSwapURL, OUString const & rOriginURL)
68  : SwapFile(rSwapURL)
69  , maOriginURL(rOriginURL)
70  {
71  }
72 
73  OUString const & getOriginURL() const { return maOriginURL; }
74 };
75 
77 {
78  if (mpSwapFile)
79  return mpSwapFile->getSwapURL().GetMainURL(INetURLObject::DecodeMechanism::NONE);
80  return OUString();
81 }
82 
84  meType ( GraphicType::NONE ),
85  mnSizeBytes ( 0 ),
86  mbSwapOut ( false ),
87  mbDummyContext ( false ),
88  maLastUsed (std::chrono::high_resolution_clock::now()),
89  mbPrepared ( false )
90 {
91 }
92 
94  : maMetaFile(rImpGraphic.maMetaFile)
95  , maBitmapEx(rImpGraphic.maBitmapEx)
96  , maSwapInfo(rImpGraphic.maSwapInfo)
97  , mpContext(rImpGraphic.mpContext)
98  , mpSwapFile(rImpGraphic.mpSwapFile)
99  , mpGfxLink(rImpGraphic.mpGfxLink)
100  , meType(rImpGraphic.meType)
101  , mnSizeBytes(rImpGraphic.mnSizeBytes)
102  , mbSwapOut(rImpGraphic.mbSwapOut)
103  , mbDummyContext(rImpGraphic.mbDummyContext)
104  , maVectorGraphicData(rImpGraphic.maVectorGraphicData)
105  , maGraphicExternalLink(rImpGraphic.maGraphicExternalLink)
106  , maLastUsed (std::chrono::high_resolution_clock::now())
107  , mbPrepared (rImpGraphic.mbPrepared)
108 {
109  if( rImpGraphic.mpAnimation )
110  {
111  mpAnimation = std::make_unique<Animation>( *rImpGraphic.mpAnimation );
112  maBitmapEx = mpAnimation->GetBitmapEx();
113  }
114 }
115 
116 ImpGraphic::ImpGraphic(ImpGraphic&& rImpGraphic) noexcept
117  : maMetaFile(std::move(rImpGraphic.maMetaFile))
118  , maBitmapEx(std::move(rImpGraphic.maBitmapEx))
119  , maSwapInfo(std::move(rImpGraphic.maSwapInfo))
120  , mpAnimation(std::move(rImpGraphic.mpAnimation))
121  , mpContext(std::move(rImpGraphic.mpContext))
122  , mpSwapFile(std::move(rImpGraphic.mpSwapFile))
123  , mpGfxLink(std::move(rImpGraphic.mpGfxLink))
124  , meType(rImpGraphic.meType)
125  , mnSizeBytes(rImpGraphic.mnSizeBytes)
126  , mbSwapOut(rImpGraphic.mbSwapOut)
127  , mbDummyContext(rImpGraphic.mbDummyContext)
128  , maVectorGraphicData(std::move(rImpGraphic.maVectorGraphicData))
129  , maGraphicExternalLink(rImpGraphic.maGraphicExternalLink)
130  , maLastUsed (std::chrono::high_resolution_clock::now())
131  , mbPrepared (rImpGraphic.mbPrepared)
132 {
133  rImpGraphic.clear();
134  rImpGraphic.mbDummyContext = false;
135 }
136 
137 ImpGraphic::ImpGraphic(std::shared_ptr<GfxLink> const & rGfxLink, sal_Int32 nPageIndex)
138  : mpGfxLink(rGfxLink)
140  , mnSizeBytes(0)
141  , mbSwapOut(true)
142  , mbDummyContext(false)
143  , maLastUsed (std::chrono::high_resolution_clock::now())
144  , mbPrepared (false)
145 {
147  maSwapInfo.mbIsAlpha = true;
148  maSwapInfo.mbIsEPS = false;
149  maSwapInfo.mbIsAnimated = false;
151  maSwapInfo.mnPageIndex = nPageIndex;
152 }
153 
154 ImpGraphic::ImpGraphic(GraphicExternalLink const & rGraphicExternalLink) :
156  mnSizeBytes ( 0 ),
157  mbSwapOut ( false ),
158  mbDummyContext ( false ),
159  maGraphicExternalLink(rGraphicExternalLink),
160  maLastUsed (std::chrono::high_resolution_clock::now()),
161  mbPrepared (false)
162 {
163 }
164 
165 ImpGraphic::ImpGraphic( const BitmapEx& rBitmapEx ) :
166  maBitmapEx ( rBitmapEx ),
167  meType ( !rBitmapEx.IsEmpty() ? GraphicType::Bitmap : GraphicType::NONE ),
168  mnSizeBytes ( 0 ),
169  mbSwapOut ( false ),
170  mbDummyContext ( false ),
171  maLastUsed (std::chrono::high_resolution_clock::now()),
172  mbPrepared (false)
173 {
174 }
175 
176 ImpGraphic::ImpGraphic(const std::shared_ptr<VectorGraphicData>& rVectorGraphicDataPtr)
177 : meType( rVectorGraphicDataPtr ? GraphicType::Bitmap : GraphicType::NONE ),
178  mnSizeBytes( 0 ),
179  mbSwapOut( false ),
180  mbDummyContext ( false ),
181  maVectorGraphicData(rVectorGraphicDataPtr),
182  maLastUsed (std::chrono::high_resolution_clock::now()),
183  mbPrepared (false)
184 {
185 }
186 
187 ImpGraphic::ImpGraphic( const Animation& rAnimation ) :
188  maBitmapEx ( rAnimation.GetBitmapEx() ),
189  mpAnimation ( std::make_unique<Animation>( rAnimation ) ),
191  mnSizeBytes ( 0 ),
192  mbSwapOut ( false ),
193  mbDummyContext ( false ),
194  maLastUsed (std::chrono::high_resolution_clock::now()),
195  mbPrepared (false)
196 {
197 }
198 
200  maMetaFile ( rMtf ),
202  mnSizeBytes ( 0 ),
203  mbSwapOut ( false ),
204  mbDummyContext ( false ),
205  maLastUsed (std::chrono::high_resolution_clock::now()),
206  mbPrepared (false)
207 {
208 }
209 
211 {
213 }
214 
216 {
217  if( &rImpGraphic != this )
218  {
219  sal_Int64 aOldSizeBytes = mnSizeBytes;
220 
221  maMetaFile = rImpGraphic.maMetaFile;
222  meType = rImpGraphic.meType;
223  mnSizeBytes = rImpGraphic.mnSizeBytes;
224 
225  maSwapInfo = rImpGraphic.maSwapInfo;
226  mpContext = rImpGraphic.mpContext;
227  mbDummyContext = rImpGraphic.mbDummyContext;
229 
230  mpAnimation.reset();
231 
232  if ( rImpGraphic.mpAnimation )
233  {
234  mpAnimation = std::make_unique<Animation>( *rImpGraphic.mpAnimation );
235  maBitmapEx = mpAnimation->GetBitmapEx();
236  }
237  else
238  {
239  maBitmapEx = rImpGraphic.maBitmapEx;
240  }
241 
242  mbSwapOut = rImpGraphic.mbSwapOut;
243  mpSwapFile = rImpGraphic.mpSwapFile;
244  mbPrepared = rImpGraphic.mbPrepared;
245 
246  mpGfxLink = rImpGraphic.mpGfxLink;
247 
249  maLastUsed = std::chrono::high_resolution_clock::now();
250 
251  vcl::graphic::Manager::get().changeExisting(this, aOldSizeBytes);
252  }
253 
254  return *this;
255 }
256 
258 {
259  sal_Int64 aOldSizeBytes = mnSizeBytes;
260 
261  maMetaFile = std::move(rImpGraphic.maMetaFile);
262  meType = rImpGraphic.meType;
263  mnSizeBytes = rImpGraphic.mnSizeBytes;
264  maSwapInfo = std::move(rImpGraphic.maSwapInfo);
265  mpContext = std::move(rImpGraphic.mpContext);
266  mbDummyContext = rImpGraphic.mbDummyContext;
267  mpAnimation = std::move(rImpGraphic.mpAnimation);
268  maBitmapEx = std::move(rImpGraphic.maBitmapEx);
269  mbSwapOut = rImpGraphic.mbSwapOut;
270  mpSwapFile = std::move(rImpGraphic.mpSwapFile);
271  mpGfxLink = std::move(rImpGraphic.mpGfxLink);
272  maVectorGraphicData = std::move(rImpGraphic.maVectorGraphicData);
273  maGraphicExternalLink = rImpGraphic.maGraphicExternalLink;
274  mbPrepared = rImpGraphic.mbPrepared;
275 
276  rImpGraphic.clear();
277  rImpGraphic.mbDummyContext = false;
278  maLastUsed = std::chrono::high_resolution_clock::now();
279 
280  vcl::graphic::Manager::get().changeExisting(this, aOldSizeBytes);
281 
282  return *this;
283 }
284 
285 bool ImpGraphic::operator==( const ImpGraphic& rImpGraphic ) const
286 {
287  bool bRet = false;
288 
289  if( this == &rImpGraphic )
290  bRet = true;
291  else if (mbPrepared && rImpGraphic.mbPrepared)
292  {
293  bRet = (*mpGfxLink == *rImpGraphic.mpGfxLink);
294  }
295  else if (isAvailable() && rImpGraphic.isAvailable())
296  {
297  switch( meType )
298  {
299  case GraphicType::NONE:
300  bRet = true;
301  break;
302 
304  {
305  if( rImpGraphic.maMetaFile == maMetaFile )
306  bRet = true;
307  }
308  break;
309 
310  case GraphicType::Bitmap:
311  {
313  {
314  if(maVectorGraphicData == rImpGraphic.maVectorGraphicData)
315  {
316  // equal instances
317  bRet = true;
318  }
319  else if(rImpGraphic.maVectorGraphicData)
320  {
321  // equal content
322  bRet = (*maVectorGraphicData) == (*rImpGraphic.maVectorGraphicData);
323  }
324  }
325  else if( mpAnimation )
326  {
327  if( rImpGraphic.mpAnimation && ( *rImpGraphic.mpAnimation == *mpAnimation ) )
328  bRet = true;
329  }
330  else if( !rImpGraphic.mpAnimation && ( rImpGraphic.maBitmapEx == maBitmapEx ) )
331  {
332  bRet = true;
333  }
334  }
335  break;
336 
338  break;
339  }
340  }
341 
342  return bRet;
343 }
344 
345 const std::shared_ptr<VectorGraphicData>& ImpGraphic::getVectorGraphicData() const
346 {
347  ensureAvailable();
348 
349  return maVectorGraphicData;
350 }
351 
353 {
354  if (isSwappedOut())
355  return;
356 
357  if (!maBitmapEx.IsEmpty())
359  else
361 
370 }
371 
373 {
374  maBitmapEx.Clear();
375  maMetaFile.Clear();
376  mpAnimation.reset();
377  maVectorGraphicData.reset();
378 }
379 
380 void ImpGraphic::setPrepared(bool bAnimated, const Size* pSizeHint)
381 {
382  mbPrepared = true;
383  mbSwapOut = true;
385 
386  SvMemoryStream aMemoryStream(const_cast<sal_uInt8*>(mpGfxLink->GetData()), mpGfxLink->GetDataSize(), StreamMode::READ | StreamMode::WRITE);
387 
388  if (pSizeHint)
389  {
390  maSwapInfo.maPrefSize = *pSizeHint;
391  maSwapInfo.maPrefMapMode = MapMode(MapUnit::Map100thMM);
392  }
393 
394  GraphicDescriptor aDescriptor(aMemoryStream, nullptr);
395  if (aDescriptor.Detect(true))
396  {
397  if (!pSizeHint)
398  {
399  // If we have logic size, work with that, as later pixel -> logic
400  // conversion will work with the output device DPI, not the graphic
401  // DPI.
402  Size aLogSize = aDescriptor.GetSize_100TH_MM();
403  if (aDescriptor.GetPreferredLogSize() && aDescriptor.GetPreferredMapMode())
404  {
405  maSwapInfo.maPrefSize = *aDescriptor.GetPreferredLogSize();
407  }
408  else if (aLogSize.getWidth() && aLogSize.getHeight())
409  {
410  maSwapInfo.maPrefSize = aLogSize;
411  maSwapInfo.maPrefMapMode = MapMode(MapUnit::Map100thMM);
412  }
413  else
414  {
415  maSwapInfo.maPrefSize = aDescriptor.GetSizePixel();
416  maSwapInfo.maPrefMapMode = MapMode(MapUnit::MapPixel);
417  }
418  }
419 
420  maSwapInfo.maSizePixel = aDescriptor.GetSizePixel();
421  maSwapInfo.mbIsTransparent = aDescriptor.IsTransparent();
422  maSwapInfo.mbIsAlpha = aDescriptor.IsAlpha();
423  } else {
424  maSwapInfo.mbIsTransparent = false;
425  maSwapInfo.mbIsAlpha = false;
426  }
427 
429  maSwapInfo.mbIsEPS = false;
430  maSwapInfo.mbIsAnimated = bAnimated;
431 
433  maSwapInfo.mnPageIndex = maVectorGraphicData->getPageIndex();
434 }
435 
437 {
438  mpSwapFile.reset();
439  mbSwapOut = false;
440  mbPrepared = false;
441 
442  // cleanup
443  clearGraphics();
445  sal_Int64 nOldSize = mnSizeBytes;
446  mnSizeBytes = 0;
447  vcl::graphic::Manager::get().changeExisting(this, nOldSize);
449 }
450 
452 {
453  clear();
455 }
456 
458 {
459  return( meType != GraphicType::NONE );
460 }
461 
463 {
464  bool bRet(true);
465 
466  if (mbSwapOut)
467  {
469  }
471  {
472  bRet = mpAnimation ? mpAnimation->IsTransparent() : maBitmapEx.IsAlpha();
473  }
474 
475  return bRet;
476 }
477 
479 {
480  bool bRet(false);
481 
482  if (mbSwapOut)
483  {
484  bRet = maSwapInfo.mbIsAlpha;
485  }
486  else if (maVectorGraphicData)
487  {
488  bRet = true;
489  }
490  else if (meType == GraphicType::Bitmap)
491  {
492  bRet = (nullptr == mpAnimation && maBitmapEx.IsAlpha());
493  }
494 
495  return bRet;
496 }
497 
499 {
500  return mbSwapOut ? maSwapInfo.mbIsAnimated : mpAnimation != nullptr;
501 }
502 
503 bool ImpGraphic::isEPS() const
504 {
505  if (mbSwapOut)
506  return maSwapInfo.mbIsEPS;
507 
508  return( ( meType == GraphicType::GdiMetafile ) &&
509  ( maMetaFile.GetActionSize() > 0 ) &&
511 }
512 
514 {
515  return !mbPrepared && !mbSwapOut;
516 }
517 
519 {
520  return ensureAvailable();
521 }
522 
524 {
525  BitmapEx aRet = maVectorGraphicData->getReplacement();
526 
528  {
530  }
531 
532  return aRet;
533 }
534 
536 {
537  Bitmap aRetBmp;
538 
539  ensureAvailable();
540 
541  if( meType == GraphicType::Bitmap )
542  {
544  {
545  // use maBitmapEx as local buffer for rendered svg
546  const_cast< ImpGraphic* >(this)->maBitmapEx = getVectorGraphicReplacement();
547  }
548 
549  const BitmapEx& rRetBmpEx = ( mpAnimation ? mpAnimation->GetBitmapEx() : maBitmapEx );
550 
551  aRetBmp = rRetBmpEx.GetBitmap( COL_WHITE );
552 
553  if(rParameters.getSizePixel().Width() || rParameters.getSizePixel().Height())
554  aRetBmp.Scale(rParameters.getSizePixel());
555  }
556  else if( ( meType != GraphicType::Default ) && isSupportedGraphic() )
557  {
558  if(maBitmapEx.IsEmpty())
559  {
560  // calculate size
562  Size aDrawSize(aVDev->LogicToPixel(maMetaFile.GetPrefSize(), maMetaFile.GetPrefMapMode()));
563 
564  if(rParameters.getSizePixel().Width() && rParameters.getSizePixel().Height())
565  {
566  // apply given size if exists
567  aDrawSize = rParameters.getSizePixel();
568  }
569 
570  if(aDrawSize.Width() && aDrawSize.Height() && !rParameters.getUnlimitedSize()
571  && (aDrawSize.Width() > GRAPHIC_MTFTOBMP_MAXEXT || aDrawSize.Height() > GRAPHIC_MTFTOBMP_MAXEXT))
572  {
573  // limit bitmap size to a maximum of GRAPHIC_MTFTOBMP_MAXEXT x GRAPHIC_MTFTOBMP_MAXEXT
574  double fWH(static_cast<double>(aDrawSize.Width()) / static_cast<double>(aDrawSize.Height()));
575 
576  if(fWH <= 1.0)
577  {
580  }
581  else
582  {
585  }
586  }
587 
588  // calculate pixel size. Normally, it's the same as aDrawSize, but may
589  // need to be extended when hairlines are on the right or bottom edge
590  Size aPixelSize(aDrawSize);
591 
593  {
594  // tdf#126319 Removed correction based on hairline-at-the-extremes of
595  // the metafile. The task shows that this is no longer sufficient since
596  // less hairlines get used in general - what is good, but breaks that
597  // old fix. Anyways, hairlines are a left-over from non-AA times
598  // when it was not possible to paint lines taller than one pixel.
599  // This might need to be corrected further using primitives and
600  // the possibility to get better-quality ranges for correction. For
601  // now, always add that one pixel.
602  aPixelSize.setWidth(aPixelSize.getWidth() + 1);
603  aPixelSize.setHeight(aPixelSize.getHeight() + 1);
604  }
605 
606  if(aVDev->SetOutputSizePixel(aPixelSize))
607  {
608  if(rParameters.getAntiAliase())
609  {
610  aVDev->SetAntialiasing(aVDev->GetAntialiasing() | AntialiasingFlags::Enable);
611  }
612 
613  if(rParameters.getSnapHorVerLines())
614  {
615  aVDev->SetAntialiasing(aVDev->GetAntialiasing() | AntialiasingFlags::PixelSnapHairline);
616  }
617 
618  draw(*aVDev, Point(), aDrawSize);
619 
620  // use maBitmapEx as local buffer for rendered metafile
621  const_cast< ImpGraphic* >(this)->maBitmapEx = aVDev->GetBitmapEx( Point(), aVDev->GetOutputSizePixel() );
622  }
623  }
624 
625  aRetBmp = maBitmapEx.GetBitmap();
626  }
627 
628  if( !aRetBmp.IsEmpty() )
629  {
630  aRetBmp.SetPrefMapMode(getPrefMapMode());
631  aRetBmp.SetPrefSize(getPrefSize());
632  }
633 
634  return aRetBmp;
635 }
636 
638 {
639  BitmapEx aRetBmpEx;
640 
641  ensureAvailable();
642 
643  if( meType == GraphicType::Bitmap )
644  {
646  {
647  // use maBitmapEx as local buffer for rendered svg
648  const_cast< ImpGraphic* >(this)->maBitmapEx = getVectorGraphicReplacement();
649  }
650 
651  aRetBmpEx = ( mpAnimation ? mpAnimation->GetBitmapEx() : maBitmapEx );
652 
653  if(rParameters.getSizePixel().Width() || rParameters.getSizePixel().Height())
654  {
655  aRetBmpEx.Scale(
656  rParameters.getSizePixel(),
658  }
659  }
660  else if( ( meType != GraphicType::Default ) && isSupportedGraphic() )
661  {
662  if(maBitmapEx.IsEmpty())
663  {
664  const ImpGraphic aMonoMask( maMetaFile.GetMonochromeMtf( COL_BLACK ) );
665 
666  // use maBitmapEx as local buffer for rendered metafile
667  const_cast< ImpGraphic* >(this)->maBitmapEx = BitmapEx(getBitmap(rParameters), aMonoMask.getBitmap(rParameters));
668  }
669 
670  aRetBmpEx = maBitmapEx;
671  }
672 
673  return aRetBmpEx;
674 }
675 
677 {
678  Animation aAnimation;
679 
680  ensureAvailable();
681  if( mpAnimation )
682  aAnimation = *mpAnimation;
683 
684  return aAnimation;
685 }
686 
688 {
689  ensureAvailable();
690  return maBitmapEx;
691 }
692 
694 {
695  ensureAvailable();
700  {
701  // If we have a Emf/Wmf VectorGraphic object, we
702  // need a way to get the Metafile data out of the primitive
703  // representation. Use a strict virtual hook (MetafileAccessor)
704  // to access the MetafilePrimitive2D directly. Also see comments in
705  // XEmfParser about this.
706  const std::deque< css::uno::Reference< css::graphic::XPrimitive2D > > aSequence(maVectorGraphicData->getPrimitive2DSequence());
707 
708  if (1 == aSequence.size())
709  {
710  // try to cast to MetafileAccessor implementation
711  const css::uno::Reference< css::graphic::XPrimitive2D > xReference(aSequence[0]);
712  auto pUnoPrimitive = static_cast< const drawinglayer::primitive2d::UnoPrimitive2D* >(xReference.get());
713  if (pUnoPrimitive)
714  {
715  const MetafileAccessor* pMetafileAccessor = dynamic_cast< const MetafileAccessor* >(pUnoPrimitive->getBasePrimitive2D().get());
716 
717  if (pMetafileAccessor)
718  {
719  // it is a MetafileAccessor implementation, get Metafile
720  pMetafileAccessor->accessMetafile(const_cast< ImpGraphic* >(this)->maMetaFile);
721  }
722  }
723  }
724  }
725 
727  {
728  // #i119735#
729  // Use the local maMetaFile as container for a metafile-representation
730  // of the bitmap graphic. This will be done only once, thus be buffered.
731  // I checked all usages of maMetaFile, it is only used when type is not
732  // GraphicType::Bitmap. In operator= it will get copied, thus buffering will
733  // survive copying (change this if not wanted)
734  ImpGraphic* pThat = const_cast< ImpGraphic* >(this);
735 
737  {
738  // use maBitmapEx as local buffer for rendered svg
740  }
741 
742  // #123983# directly create a metafile with the same PrefSize and PrefMapMode
743  // the bitmap has, this will be an always correct metafile
744  if(maBitmapEx.IsAlpha())
745  {
747  }
748  else
749  {
751  }
752 
753  pThat->maMetaFile.Stop();
754  pThat->maMetaFile.WindStart();
757  }
758 
759  return maMetaFile;
760 }
761 
763 {
764  Size aSize;
765 
766  if (isSwappedOut())
767  aSize = maSwapInfo.maSizePixel;
768  else
770 
771  return aSize;
772 }
773 
775 {
776  Size aSize;
777 
778  if (isSwappedOut())
779  {
780  aSize = maSwapInfo.maPrefSize;
781  }
782  else
783  {
784  switch (meType)
785  {
786  case GraphicType::Bitmap:
787  {
789  {
791  {
792  // svg not yet buffered in maBitmapEx, return size derived from range
793  const basegfx::B2DRange& rRange = maVectorGraphicData->getRange();
794 
795  aSize = Size(basegfx::fround(rRange.getWidth()), basegfx::fround(rRange.getHeight()));
796  }
797  else
798  {
799  aSize = maExPrefSize;
800  }
801  }
802  else
803  {
804  aSize = maBitmapEx.GetPrefSize();
805 
806  if( !aSize.Width() || !aSize.Height() )
807  {
808  aSize = maBitmapEx.GetSizePixel();
809  }
810  }
811  }
812  break;
813 
815  {
816  aSize = maMetaFile.GetPrefSize();
817  }
818  break;
819 
820  case GraphicType::NONE:
822  break;
823  }
824  }
825 
826  return aSize;
827 }
828 
830 {
831  switch (meType)
832  {
833  case GraphicType::Bitmap:
834  {
835  // used when importing a writer FlyFrame with SVG as graphic, added conversion
836  // to allow setting the PrefSize at the BitmapEx to hold it
838  {
839  maExPrefSize = rPrefSize;
840  }
841 
842  // #108077# Push through pref size to animation object,
843  // will be lost on copy otherwise
844  if (isAnimated())
845  {
846  const_cast< BitmapEx& >(mpAnimation->GetBitmapEx()).SetPrefSize(rPrefSize);
847  }
848 
850  {
851  maBitmapEx.SetPrefSize(rPrefSize);
852  }
853  }
854  break;
855 
857  {
858  if (isSupportedGraphic())
859  maMetaFile.SetPrefSize(rPrefSize);
860  }
861  break;
862 
863  case GraphicType::NONE:
865  break;
866  }
867 }
868 
869 void ImpGraphic::setPrefSize(const Size& rPrefSize)
870 {
871  ensureAvailable();
872  setValuesForPrefSize(rPrefSize);
873 }
874 
876 {
877  MapMode aMapMode;
878 
879  if (isSwappedOut())
880  {
881  aMapMode = maSwapInfo.maPrefMapMode;
882  }
883  else
884  {
885  switch (meType)
886  {
887  case GraphicType::Bitmap:
888  {
890  {
891  // svg not yet buffered in maBitmapEx, return default PrefMapMode
892  aMapMode = MapMode(MapUnit::Map100thMM);
893  }
894  else
895  {
896  const Size aSize(maBitmapEx.GetPrefSize());
897 
898  if (aSize.Width() && aSize.Height())
899  aMapMode = maBitmapEx.GetPrefMapMode();
900  }
901  }
902  break;
903 
905  {
906  return maMetaFile.GetPrefMapMode();
907  }
908  break;
909 
910  case GraphicType::NONE:
912  break;
913  }
914  }
915 
916  return aMapMode;
917 }
918 
920 {
921  switch (meType)
922  {
923  case GraphicType::Bitmap:
924  {
926  {
927  // ignore for Vector Graphic Data. If this is really used (except the grfcache)
928  // it can be extended by using maBitmapEx as buffer for getVectorGraphicReplacement()
929  }
930  else
931  {
932  // #108077# Push through pref mapmode to animation object,
933  // will be lost on copy otherwise
934  if (isAnimated())
935  {
936  const_cast<BitmapEx&>(mpAnimation->GetBitmapEx()).SetPrefMapMode(rPrefMapMode);
937  }
938 
939  maBitmapEx.SetPrefMapMode(rPrefMapMode);
940  }
941  }
942  break;
943 
945  {
946  maMetaFile.SetPrefMapMode(rPrefMapMode);
947  }
948  break;
949 
950  case GraphicType::NONE:
952  break;
953  }
954 }
955 
956 void ImpGraphic::setPrefMapMode(const MapMode& rPrefMapMode)
957 {
958  ensureAvailable();
959  setValuesForPrefMapMod(rPrefMapMode);
960 }
961 
963 {
964  if (mnSizeBytes > 0)
965  return mnSizeBytes;
966 
967  if (mbPrepared)
968  ensureAvailable();
969 
970  switch (meType)
971  {
972  case GraphicType::Bitmap:
973  {
975  {
976  std::pair<VectorGraphicData::State, size_t> aPair(maVectorGraphicData->getSizeBytes());
977  if (VectorGraphicData::State::UNPARSED == aPair.first)
978  {
979  return aPair.second; // don't cache it until Vector Graphic Data is parsed
980  }
981  mnSizeBytes = aPair.second;
982  }
983  else
984  {
986  }
987  }
988  break;
989 
991  {
993  }
994  break;
995 
996  case GraphicType::NONE:
998  break;
999  }
1000 
1001  return mnSizeBytes;
1002 }
1003 
1004 void ImpGraphic::draw(OutputDevice& rOutDev, const Point& rDestPt) const
1005 {
1006  ensureAvailable();
1007 
1008  if (isSwappedOut())
1009  return;
1010 
1011  switch (meType)
1012  {
1013  case GraphicType::Bitmap:
1014  {
1016  {
1017  // use maBitmapEx as local buffer for rendered svg
1018  const_cast<ImpGraphic*>(this)->maBitmapEx = getVectorGraphicReplacement();
1019  }
1020 
1021  if (mpAnimation)
1022  {
1023  mpAnimation->Draw(rOutDev, rDestPt);
1024  }
1025  else
1026  {
1027  maBitmapEx.Draw(&rOutDev, rDestPt);
1028  }
1029  }
1030  break;
1031 
1033  {
1034  draw(rOutDev, rDestPt, maMetaFile.GetPrefSize());
1035  }
1036  break;
1037 
1038  case GraphicType::Default:
1039  case GraphicType::NONE:
1040  break;
1041  }
1042 }
1043 
1045  const Point& rDestPt, const Size& rDestSize) const
1046 {
1047  ensureAvailable();
1048 
1049  if (isSwappedOut())
1050  return;
1051 
1052  switch (meType)
1053  {
1054  case GraphicType::Bitmap:
1055  {
1057  {
1058  // use maBitmapEx as local buffer for rendered svg
1059  const_cast<ImpGraphic*>(this)->maBitmapEx = getVectorGraphicReplacement();
1060  }
1061 
1062  if (mpAnimation)
1063  {
1064  mpAnimation->Draw(rOutDev, rDestPt, rDestSize);
1065  }
1066  else
1067  {
1068  maBitmapEx.Draw(&rOutDev, rDestPt, rDestSize);
1069  }
1070  }
1071  break;
1072 
1074  {
1075  const_cast<ImpGraphic*>(this)->maMetaFile.WindStart();
1076  const_cast<ImpGraphic*>(this)->maMetaFile.Play(rOutDev, rDestPt, rDestSize);
1077  const_cast<ImpGraphic*>(this)->maMetaFile.WindStart();
1078  }
1079  break;
1080 
1081  case GraphicType::Default:
1082  case GraphicType::NONE:
1083  break;
1084  }
1085 }
1086 
1087 void ImpGraphic::startAnimation(OutputDevice& rOutDev, const Point& rDestPt,
1088  const Size& rDestSize, tools::Long nExtraData,
1089  OutputDevice* pFirstFrameOutDev )
1090 {
1091  ensureAvailable();
1092 
1094  mpAnimation->Start(rOutDev, rDestPt, rDestSize, nExtraData, pFirstFrameOutDev);
1095 }
1096 
1097 void ImpGraphic::stopAnimation( const OutputDevice* pOutDev, tools::Long nExtraData )
1098 {
1099  ensureAvailable();
1100 
1102  mpAnimation->Stop( pOutDev, nExtraData );
1103 }
1104 
1106 {
1107  ensureAvailable();
1108 
1109  if( mpAnimation )
1110  mpAnimation->SetNotifyHdl( rLink );
1111 }
1112 
1114 {
1115  Link<Animation*,void> aLink;
1116 
1117  ensureAvailable();
1118 
1119  if( mpAnimation )
1120  aLink = mpAnimation->GetNotifyHdl();
1121 
1122  return aLink;
1123 }
1124 
1126 {
1127  if (mbSwapOut)
1129 
1130  return mpAnimation ? mpAnimation->GetLoopCount() : 0;
1131 }
1132 
1133 void ImpGraphic::setContext( const std::shared_ptr<GraphicReader>& pReader )
1134 {
1135  mpContext = pReader;
1136  mbDummyContext = false;
1137 }
1138 
1140 {
1141  bool bRet = false;
1142 
1143  sal_uInt32 nId;
1144  sal_Int32 nType;
1145  sal_Int32 nLength;
1146 
1147  rStream.ReadUInt32(nId);
1148 
1149  // check version
1150  if (SWAP_FORMAT_ID != nId)
1151  {
1152  SAL_WARN("vcl", "Incompatible swap file!");
1153  return false;
1154  }
1155 
1156  rStream.ReadInt32(nType);
1157  rStream.ReadInt32(nLength);
1158 
1159  meType = static_cast<GraphicType>(nType);
1160 
1162  {
1163  return true;
1164  }
1165  else
1166  {
1167  bRet = swapInGraphic(rStream);
1168  }
1169 
1170  return bRet;
1171 }
1172 
1174 {
1175  if (rStream.GetError())
1176  return false;
1177 
1178  ensureAvailable();
1179 
1180  if (isSwappedOut())
1181  {
1183  return false;
1184  }
1185 
1186  switch (meType)
1187  {
1189  {
1190  if(!rStream.GetError())
1191  {
1192  SvmWriter aWriter(rStream);
1193  aWriter.Write(maMetaFile);
1194  }
1195  }
1196  break;
1197 
1198  case GraphicType::Bitmap:
1199  {
1200  if (maVectorGraphicData)
1201  {
1202  rStream.WriteInt32(sal_Int32(GraphicContentType::Vector));
1203  // stream out Vector Graphic defining data (length, byte array and evtl. path)
1204  // this is used e.g. in swapping out graphic data and in transporting it over UNO API
1205  // as sequence of bytes, but AFAIK not written anywhere to any kind of file, so it should be
1206  // no problem to extend it; only used at runtime
1207  switch (maVectorGraphicData->getType())
1208  {
1210  {
1211  rStream.WriteUInt32(constWmfMagic);
1212  break;
1213  }
1215  {
1216  rStream.WriteUInt32(constEmfMagic);
1217  break;
1218  }
1220  {
1221  rStream.WriteUInt32(constSvgMagic);
1222  break;
1223  }
1225  {
1226  rStream.WriteUInt32(constPdfMagic);
1227  break;
1228  }
1229  }
1230 
1231  rStream.WriteUInt32(maVectorGraphicData->getBinaryDataContainer().getSize());
1232 
1233  rStream.WriteBytes(
1234  maVectorGraphicData->getBinaryDataContainer().getData(),
1235  maVectorGraphicData->getBinaryDataContainer().getSize());
1236  }
1237  else if (isAnimated())
1238  {
1239  rStream.WriteInt32(sal_Int32(GraphicContentType::Animation));
1240  WriteAnimation(rStream, *mpAnimation);
1241  }
1242  else
1243  {
1244  rStream.WriteInt32(sal_Int32(GraphicContentType::Bitmap));
1245  WriteDIBBitmapEx(maBitmapEx, rStream);
1246  }
1247  }
1248  break;
1249 
1250  case GraphicType::NONE:
1251  case GraphicType::Default:
1252  break;
1253  }
1254 
1255  return true;
1256 }
1257 
1259 {
1260  ensureAvailable();
1261 
1262  bool bRet = false;
1263 
1265  return false;
1266 
1267  sal_uLong nDataFieldPos;
1268 
1269  // Write the SWAP ID
1270  rStream.WriteUInt32(SWAP_FORMAT_ID);
1271 
1272  rStream.WriteInt32(static_cast<sal_Int32>(meType));
1273 
1274  // data size is updated later
1275  nDataFieldPos = rStream.Tell();
1276  rStream.WriteInt32(0);
1277 
1278  // write data block
1279  const sal_uInt64 nDataStart = rStream.Tell();
1280 
1281  swapOutGraphic(rStream);
1282 
1283  if (!rStream.GetError())
1284  {
1285  // Write the written length th the header
1286  const sal_uInt64 nCurrentPosition = rStream.Tell();
1287  rStream.Seek(nDataFieldPos);
1288  rStream.WriteInt32(nCurrentPosition - nDataStart);
1289  rStream.Seek(nCurrentPosition);
1290  bRet = true;
1291  }
1292 
1293  return bRet;
1294 }
1295 
1297 {
1298  if (isSwappedOut())
1299  return false;
1300 
1301  bool bResult = false;
1302 
1303  sal_Int64 nByteSize = getSizeBytes();
1304 
1305  // We have GfxLink so we have the source available
1306  if (mpGfxLink && mpGfxLink->IsNative())
1307  {
1308  createSwapInfo();
1309 
1310  clearGraphics();
1311 
1312  // reset the swap file
1313  mpSwapFile.reset();
1314 
1315  // mark as swapped out
1316  mbSwapOut = true;
1317 
1318  bResult = true;
1319  }
1320  else
1321  {
1322  // Create a temp filename for the swap file
1323  utl::TempFile aTempFile;
1324  const INetURLObject aTempFileURL(aTempFile.GetURL());
1325 
1326  // Create a swap file
1327  auto pSwapFile = o3tl::make_shared<ImpSwapFile>(aTempFileURL, getOriginURL());
1328 
1329  // Open a stream to write the swap file to
1330  {
1331  std::unique_ptr<SvStream> xOutputStream = pSwapFile->openOutputStream();
1332 
1333  if (!xOutputStream)
1334  return false;
1335 
1336  // Write to stream
1337  xOutputStream->SetVersion(SOFFICE_FILEFORMAT_50);
1338  xOutputStream->SetCompressMode(SvStreamCompressFlags::NATIVE);
1339  xOutputStream->SetBufferSize(GRAPHIC_STREAMBUFSIZE);
1340 
1341  if (!xOutputStream->GetError() && swapOutContent(*xOutputStream))
1342  {
1343  xOutputStream->FlushBuffer();
1344  bResult = !xOutputStream->GetError();
1345  }
1346  }
1347 
1348  // Check if writing was successful
1349  if (bResult)
1350  {
1351  // We have swapped out, so can clean memory and prepare swap info
1352  createSwapInfo();
1353  clearGraphics();
1354 
1355  mpSwapFile = std::move(pSwapFile);
1356  mbSwapOut = true;
1357  }
1358  }
1359 
1360  if (bResult)
1361  {
1362  // Signal to manager that we have swapped out
1363  vcl::graphic::Manager::get().swappedOut(this, nByteSize);
1364  }
1365 
1366  return bResult;
1367 }
1368 
1370 {
1371  auto pThis = const_cast<ImpGraphic*>(this);
1372 
1373  bool bResult = true;
1374 
1375  if (isSwappedOut())
1376  bResult = pThis->swapIn();
1377 
1378  pThis->maLastUsed = std::chrono::high_resolution_clock::now();
1379  return bResult;
1380 }
1381 
1383 {
1384  if (mbPrepared)
1385  {
1387  Size aPrefSize = maSwapInfo.maPrefSize;
1388  MapMode aPrefMapMode = maSwapInfo.maPrefMapMode;
1389  *this = *pGraphic;
1390  if (aPrefSize.getWidth() && aPrefSize.getHeight() && aPrefMapMode == getPrefMapMode())
1391  {
1392  // Use custom preferred size if it was set when the graphic was still unloaded.
1393  // Only set the size in case the unloaded and loaded unit matches.
1394  setPrefSize(aPrefSize);
1395  }
1396  maGraphicExternalLink = aLink;
1397  }
1398  else
1399  {
1400  // Move over only graphic content
1401  mpAnimation.reset();
1402  if (pGraphic->mpAnimation)
1403  {
1404  mpAnimation = std::make_unique<Animation>(*pGraphic->mpAnimation);
1405  maBitmapEx = mpAnimation->GetBitmapEx();
1406  }
1407  else
1408  {
1409  maBitmapEx = pGraphic->maBitmapEx;
1410  }
1411 
1412  maMetaFile = pGraphic->maMetaFile;
1414 
1415  // Set to 0, to force recalculation
1416  mnSizeBytes = 0;
1417  mnChecksum = 0;
1418 
1420 
1421  mbSwapOut = false;
1422  }
1423 }
1424 
1426 {
1429 
1430  if (maVectorGraphicData)
1431  {
1433  }
1434 }
1435 
1436 namespace
1437 {
1438 
1439 std::optional<VectorGraphicDataType> lclConvertToVectorGraphicType(GfxLink const & rLink)
1440 {
1441  switch(rLink.GetType())
1442  {
1445 
1447  if (rLink.IsEMF())
1449  else
1451 
1454 
1455  default:
1456  break;
1457  }
1458  return std::optional<VectorGraphicDataType>();
1459 }
1460 
1461 } // end namespace
1462 
1464 {
1465  if (!isSwappedOut())
1466  return false;
1467 
1468  bool bReturn = false;
1469 
1470  if (mbPrepared)
1471  {
1472  Graphic aGraphic;
1473  if (!mpGfxLink->LoadNative(aGraphic))
1474  return false;
1475 
1477 
1478  maLastUsed = std::chrono::high_resolution_clock::now();
1479  bReturn = true;
1480  }
1481  else if (mpGfxLink && mpGfxLink->IsNative())
1482  {
1483  std::optional<VectorGraphicDataType> oType = lclConvertToVectorGraphicType(*mpGfxLink);
1484  if (oType)
1485  {
1486  maVectorGraphicData = vcl::loadVectorGraphic(mpGfxLink->getDataContainer(), *oType);
1487 
1488  // Set to 0, to force recalculation
1489  mnSizeBytes = 0;
1490  mnChecksum = 0;
1491 
1493 
1494  mbSwapOut = false;
1495  }
1496  else
1497  {
1498  Graphic aGraphic;
1499  if (!mpGfxLink->LoadNative(aGraphic))
1500  return false;
1501 
1502  ImpGraphic* pImpGraphic = aGraphic.ImplGetImpGraphic();
1503  if (meType != pImpGraphic->meType)
1504  return false;
1505 
1506  updateFromLoadedGraphic(pImpGraphic);
1507  }
1508 
1509  maLastUsed = std::chrono::high_resolution_clock::now();
1510  bReturn = true;
1511  }
1512  else
1513  {
1514  OUString aSwapURL;
1515 
1516  if (mpSwapFile)
1517  aSwapURL = mpSwapFile->getSwapURL().GetMainURL(INetURLObject::DecodeMechanism::NONE);
1518 
1519  if (!aSwapURL.isEmpty())
1520  {
1521  std::unique_ptr<SvStream> xStream;
1522  try
1523  {
1524  xStream = ::utl::UcbStreamHelper::CreateStream(aSwapURL, StreamMode::READWRITE | StreamMode::SHARE_DENYWRITE);
1525  }
1526  catch( const css::uno::Exception& )
1527  {
1528  }
1529 
1530  if (xStream)
1531  {
1532  xStream->SetVersion(SOFFICE_FILEFORMAT_50);
1533  xStream->SetCompressMode(SvStreamCompressFlags::NATIVE);
1534  xStream->SetBufferSize(GRAPHIC_STREAMBUFSIZE);
1535 
1536  bReturn = swapInFromStream(*xStream);
1537 
1538  xStream.reset();
1539 
1541 
1542  if (mpSwapFile)
1543  setOriginURL(mpSwapFile->getOriginURL());
1544 
1545  mpSwapFile.reset();
1546  }
1547  }
1548  }
1549 
1550  if (bReturn)
1551  {
1553  }
1554 
1555  return bReturn;
1556 }
1557 
1559 {
1560  bool bRet = false;
1561 
1562  if (rStream.GetError())
1563  return false;
1564 
1565  clearGraphics();
1566  mnSizeBytes = 0;
1567  mnChecksum = 0;
1568 
1569  bRet = swapInContent(rStream);
1570 
1571  if (!bRet)
1572  {
1573  //throw away swapfile, etc.
1574  clear();
1575  }
1576 
1577  mbSwapOut = false;
1578 
1579  return bRet;
1580 }
1581 
1583 {
1584  bool bReturn = false;
1585 
1586  if (rStream.GetError())
1587  return bReturn;
1588 
1589  if (meType == GraphicType::Bitmap)
1590  {
1591  sal_Int32 nContentType = -1;
1592  rStream.ReadInt32(nContentType);
1593  if (nContentType < 0)
1594  return false;
1595 
1596  auto eContentType = static_cast<GraphicContentType>(nContentType);
1597 
1598  switch (eContentType)
1599  {
1601  {
1602  BitmapEx aBitmapEx;
1603  ReadDIBBitmapEx(aBitmapEx, rStream);
1604  if (!rStream.GetError())
1605  {
1606  maBitmapEx = aBitmapEx;
1607  bReturn = true;
1608  }
1609  }
1610  break;
1611 
1613  {
1614  auto pAnimation = std::make_unique<Animation>();
1615  ReadAnimation(rStream, *pAnimation);
1616  if (!rStream.GetError())
1617  {
1618  mpAnimation = std::move(pAnimation);
1619  maBitmapEx = mpAnimation->GetBitmapEx();
1620  bReturn = true;
1621  }
1622  }
1623  break;
1624 
1626  {
1627  // try to stream in Svg defining data (length, byte array and evtl. path)
1628  // See below (operator<<) for more information
1629  sal_uInt32 nMagic;
1630  rStream.ReadUInt32(nMagic);
1631 
1632  if (constSvgMagic == nMagic || constWmfMagic == nMagic || constEmfMagic == nMagic || constPdfMagic == nMagic)
1633  {
1634  sal_uInt32 nVectorGraphicDataSize(0);
1635  rStream.ReadUInt32(nVectorGraphicDataSize);
1636 
1637  if (nVectorGraphicDataSize)
1638  {
1639  auto rData = std::make_unique<std::vector<sal_uInt8>>(nVectorGraphicDataSize);
1640  rStream.ReadBytes(rData->data(), nVectorGraphicDataSize);
1641  BinaryDataContainer aDataContainer(std::move(rData));
1642 
1643  if (rStream.GetError())
1644  return false;
1645 
1646  VectorGraphicDataType aDataType;
1647 
1648  switch (nMagic)
1649  {
1650  case constSvgMagic:
1651  aDataType = VectorGraphicDataType::Svg;
1652  break;
1653  case constWmfMagic:
1654  aDataType = VectorGraphicDataType::Wmf;
1655  break;
1656  case constEmfMagic:
1657  aDataType = VectorGraphicDataType::Emf;
1658  break;
1659  case constPdfMagic:
1660  aDataType = VectorGraphicDataType::Pdf;
1661  break;
1662  default:
1663  return false;
1664  }
1665 
1666  auto aVectorGraphicDataPtr = std::make_shared<VectorGraphicData>(aDataContainer, aDataType);
1667 
1668  if (!rStream.GetError())
1669  {
1670  maVectorGraphicData = aVectorGraphicDataPtr;
1671  bReturn = true;
1672  }
1673  }
1674  }
1675  }
1676  break;
1677  }
1678  }
1679  else if (meType == GraphicType::GdiMetafile)
1680  {
1681  GDIMetaFile aMetaFile;
1682  SvmReader aReader(rStream);
1683  aReader.Read(aMetaFile);
1684  if (!rStream.GetError())
1685  {
1686  maMetaFile = aMetaFile;
1687  bReturn = true;
1688  }
1689  }
1690  return bReturn;
1691 }
1692 
1693 void ImpGraphic::setGfxLink(const std::shared_ptr<GfxLink>& rGfxLink)
1694 {
1695  ensureAvailable();
1696 
1697  mpGfxLink = rGfxLink;
1698 }
1699 
1700 const std::shared_ptr<GfxLink> & ImpGraphic::getSharedGfxLink() const
1701 {
1702  return mpGfxLink;
1703 }
1704 
1706 {
1707  ensureAvailable();
1708 
1709  return( mpGfxLink ? *mpGfxLink : GfxLink() );
1710 }
1711 
1713 {
1714  return ( bool(mpGfxLink) );
1715 }
1716 
1718 {
1719  if (mnChecksum != 0)
1720  return mnChecksum;
1721 
1722  ensureAvailable();
1723 
1724  switch (meType)
1725  {
1726  case GraphicType::NONE:
1727  case GraphicType::Default:
1728  break;
1729 
1730  case GraphicType::Bitmap:
1731  {
1732  if (maVectorGraphicData)
1733  mnChecksum = maVectorGraphicData->GetChecksum();
1734  else if (mpAnimation)
1735  mnChecksum = mpAnimation->GetChecksum();
1736  else
1738  }
1739  break;
1740 
1742  {
1744  }
1745  break;
1746  }
1747  return mnChecksum;
1748 }
1749 
1750 sal_Int32 ImpGraphic::getPageNumber() const
1751 {
1752  if (isSwappedOut())
1753  return maSwapInfo.mnPageIndex;
1754 
1755  if (maVectorGraphicData)
1756  return maVectorGraphicData->getPageIndex();
1757  return -1;
1758 }
1759 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
constexpr sal_uInt32 constSvgMagic
BitmapEx GetBitmapEx(BitmapEx const &rBitmapEx, DrawModeFlags nDrawMode)
Definition: drawmode.cxx:224
bool swapInContent(SvStream &rStream)
Definition: impgraph.cxx:1139
VectorGraphicDataType
ImpGraphic & operator=(const ImpGraphic &rImpGraphic)
Definition: impgraph.cxx:215
bool mbDummyContext
Definition: impgraph.hxx:78
sal_uInt64 BitmapChecksum
Definition: checksum.hxx:30
std::shared_ptr< GraphicReader > mpContext
Definition: impgraph.hxx:72
void setValuesForPrefSize(const Size &rPrefSize)
Definition: impgraph.cxx:829
void setPrepared(bool bAnimated, const Size *pSizeHint)
Definition: impgraph.cxx:380
void setAnimationNotifyHdl(const Link< Animation *, void > &rLink)
Definition: impgraph.cxx:1105
void setWidth(tools::Long nWidth)
SvStream & WriteInt32(sal_Int32 nInt32)
const MapMode & GetPrefMapMode() const
Definition: bitmapex.hxx:78
const MapMode & GetPrefMapMode() const
Definition: gdimtf.hxx:175
bool Scale(const Size &rNewSize, BmpScaleFlag nScaleFlag=BmpScaleFlag::Default)
Scale the bitmap.
Definition: BitmapEx.cxx:296
bool mbIsTransparent
Definition: impgraph.hxx:38
void unregisterGraphic(ImpGraphic *pImpGraphic)
Definition: Manager.cxx:200
sal_uIntPtr sal_uLong
long Long
void SetPrefMapMode(const MapMode &rPrefMapMode)
Definition: bitmapex.hxx:79
OUString maOriginURL
Definition: impgraph.cxx:64
GraphicType
Definition: graph.hxx:34
void startAnimation(OutputDevice &rOutDev, const Point &rDestPt, const Size &rDestSize, tools::Long nExtraData, OutputDevice *pFirstFrameOutDev)
Definition: impgraph.cxx:1087
bool mbIsAlpha
Definition: impgraph.hxx:39
void SetPrefSize(const Size &rSize)
Definition: gdimtf.hxx:173
void Clear()
Definition: gdimtf.cxx:270
sal_Int16 nId
const ContentProperties & rData
sal_uInt64 Seek(sal_uInt64 nPos)
bool swapOutContent(SvStream &rStream)
Definition: impgraph.cxx:1258
bool ensureAvailable() const
Definition: impgraph.cxx:1369
bool isSupportedGraphic() const
Definition: impgraph.cxx:457
void updateFromLoadedGraphic(const ImpGraphic *graphic)
Definition: impgraph.cxx:1382
ParserContextSharedPtr mpContext
void setPrefMapMode(const MapMode &rPrefMapMode)
Definition: impgraph.cxx:956
bool swapIn()
Definition: impgraph.cxx:1463
bool mbSwapOut
Definition: impgraph.hxx:77
GraphicContentType
Definition: impgraph.hxx:51
SvStream & ReadAnimation(SvStream &rIStm, Animation &rAnimation)
Definition: Animation.cxx:599
BitmapChecksum GetChecksum() const
Definition: BitmapEx.cxx:230
SvStream & Read(GDIMetaFile &rMetaFile, ImplMetaReadData *pData=nullptr)
Definition: SvmReader.cxx:63
void swappedIn(const ImpGraphic *pImpGraphic, sal_Int64 nSizeBytes)
Definition: Manager.cxx:266
NONE
bool getUnlimitedSize() const
Definition: graph.hxx:76
constexpr tools::Long Width() const
OUString const & getOriginURL() const
Definition: impgraph.hxx:110
bool IsAlpha() const
Definition: BitmapEx.cxx:193
SvStream & Write(const GDIMetaFile &rMetaFile)
Definition: SvmWriter.cxx:38
ErrCode GetError() const
Reference< XInputStream > xStream
static std::unique_ptr< SvStream > CreateStream(const OUString &rFileName, StreamMode eOpenMode, css::uno::Reference< css::awt::XWindow > xParentWin=nullptr)
bool ReadDIBBitmapEx(BitmapEx &rTarget, SvStream &rIStm, bool bFileHeader, bool bMSOFormat)
Definition: dibtools.cxx:1718
constexpr sal_uInt32 constEmfMagic
bool swapInFromStream(SvStream &rStream)
Definition: impgraph.cxx:1558
bool IsAlpha() const
Container for the binary data, whose responsibility is to manage the make it as simple as possible to...
void setDefaultType()
Definition: impgraph.cxx:451
const sal_uInt16 nMagic
const Size & GetPrefSize() const
Definition: bitmapex.hxx:75
sal_uInt32 mnAnimationLoopCount
Definition: impgraph.hxx:41
bool isEPS() const
Definition: impgraph.cxx:503
SvStream & WriteUInt32(sal_uInt32 nUInt32)
void Play(GDIMetaFile &rMtf)
Definition: gdimtf.cxx:322
constexpr tools::Long getHeight() const
GDIMetaFile GetMonochromeMtf(const Color &rCol) const
Definition: gdimtf.cxx:2188
GraphicType meType
Definition: impgraph.hxx:75
const Size & GetSize_100TH_MM() const
Size maPrefSize
Definition: impgraph.hxx:33
B2IRange fround(const B2DRange &rRange)
void Clear()
Definition: BitmapEx.cxx:188
void restoreFromSwapInfo()
Definition: impgraph.cxx:1425
bool makeAvailable()
Definition: impgraph.cxx:518
const Size & getSizePixel() const
Definition: graph.hxx:75
std::unique_ptr< Animation > mpAnimation
Definition: impgraph.hxx:71
BitmapEx maBitmapEx
Definition: impgraph.hxx:67
SvStream & ReadUInt32(sal_uInt32 &rUInt32)
bool isSwappedOut() const
Definition: impgraph.hxx:218
std::shared_ptr< ImpSwapFile > mpSwapFile
Definition: impgraph.hxx:73
sal_Int32 mnPageIndex
Definition: impgraph.hxx:42
bool IsEmpty() const
Definition: BitmapEx.cxx:177
void SetPrefMapMode(const MapMode &rMapMode)
void setOriginURL(OUString const &rOriginURL)
Definition: impgraph.hxx:115
#define SOFFICE_FILEFORMAT_50
bool WriteDIBBitmapEx(const BitmapEx &rSource, SvStream &rOStm)
Definition: dibtools.cxx:1849
SAL_DLLPRIVATE ImpGraphic * ImplGetImpGraphic() const
Definition: graph.hxx:89
bool getSnapHorVerLines() const
Definition: graph.hxx:78
SvStream & WriteAnimation(SvStream &rOStm, const Animation &rAnimation)
Definition: Animation.cxx:553
const Size & GetPrefSize() const
Definition: gdimtf.hxx:172
const Size & GetSizePixel() const
Bitmap getBitmap(const GraphicConversionParameters &rParameters) const
Definition: impgraph.cxx:535
GDIMetaFile maMetaFile
Definition: impgraph.hxx:66
OUString const & GetURL() const
static Manager & get()
Definition: Manager.cxx:54
void setValuesForPrefMapMod(const MapMode &rPrefMapMode)
Definition: impgraph.cxx:919
BitmapChecksum mnChecksum
Definition: impgraph.hxx:81
const std::optional< MapMode > & GetPreferredMapMode() const
If available, this returns the map mode the graphic prefers, which may be other than pixel or 100th m...
const std::optional< Size > & GetPreferredLogSize() const
Returns the logic size, according to the map mode available via GetPreferredMapMode().
sal_uInt32 getAnimationLoopCount() const
Definition: impgraph.cxx:1125
BitmapEx getVectorGraphicReplacement() const
Gets the bitmap replacement for a vector graphic.
Definition: impgraph.cxx:523
Some things multiple-inherit from VclAbstractDialog and OutputDevice, so we need to use virtual inher...
Definition: outdev.hxx:175
std::size_t WriteBytes(const void *pData, std::size_t nSize)
void changeExisting(const ImpGraphic *pImpGraphic, sal_Int64 nOldSize)
Definition: Manager.cxx:284
sal_uLong mnSizeBytes
Definition: impgraph.hxx:76
void SetPrefSize(const Size &rSize)
void SetError(ErrCode nErrorCode)
#define GRAPHIC_MTFTOBMP_MAXEXT
Definition: impgraph.cxx:54
const std::shared_ptr< VectorGraphicData > & getVectorGraphicData() const
Definition: impgraph.cxx:345
void WindStart()
Definition: gdimtf.cxx:568
void stopAnimation(const OutputDevice *pOutputDevice, tools::Long nExtraData)
Definition: impgraph.cxx:1097
void Draw(OutputDevice *pOutDev, const Point &rDestPt) const
Definition: BitmapEx.cxx:500
bool mbPrepared
Definition: impgraph.hxx:87
SvStream & ReadInt32(sal_Int32 &rInt32)
Size maExPrefSize
If maBitmapEx is empty, this preferred size will be set on it when it gets initialized.
Definition: impgraph.hxx:69
std::shared_ptr< GfxLink > mpGfxLink
Definition: impgraph.hxx:74
std::size_t ReadBytes(void *pData, std::size_t nSize)
Bitmap GetBitmap(Color aTransparentReplaceColor) const
Definition: BitmapEx.cxx:203
std::chrono::high_resolution_clock::time_point maLastUsed
Definition: impgraph.hxx:86
GfxLink getGfxLink() const
Definition: impgraph.cxx:1705
void Stop()
Definition: gdimtf.cxx:555
const std::shared_ptr< GfxLink > & getSharedGfxLink() const
Definition: impgraph.cxx:1700
bool swapInGraphic(SvStream &rStream)
Definition: impgraph.cxx:1582
sal_uLong getSizeBytes() const
Definition: impgraph.cxx:962
constexpr tools::Long Height() const
std::shared_ptr< VectorGraphicData > maVectorGraphicData
Definition: impgraph.hxx:79
bool isAlpha() const
Definition: impgraph.cxx:478
bool Scale(const Size &rNewSize, BmpScaleFlag nScaleFlag=BmpScaleFlag::Default)
Scale the bitmap.
ImpSwapFile(INetURLObject const &rSwapURL, OUString const &rOriginURL)
Definition: impgraph.cxx:67
void AddAction(const rtl::Reference< MetaAction > &pAction)
Definition: gdimtf.cxx:581
bool IsTransparent() const
void clear()
Definition: impgraph.cxx:436
MetaAction * GetAction(size_t nAction) const
Definition: gdimtf.cxx:184
Link< Animation *, void > getAnimationNotifyHdl() const
Definition: impgraph.cxx:1113
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_WHITE
GraphicType getType() const
Definition: impgraph.hxx:133
bool isAnimated() const
Definition: impgraph.cxx:498
sal_Int64 GetSizeBytes() const
Definition: BitmapEx.cxx:220
BitmapEx getBitmapEx(const GraphicConversionParameters &rParameters) const
Definition: impgraph.cxx:637
void SetPrefSize(const Size &rPrefSize)
Definition: bitmapex.hxx:76
sal_Int32 getPageNumber() const
Definition: impgraph.cxx:1750
ImpSwapInfo maSwapInfo
Definition: impgraph.hxx:70
bool IsEmpty() const
sal_uInt64 Tell() const
size_t GetActionSize() const
Definition: gdimtf.cxx:179
QPRO_FUNC_TYPE nType
void setGfxLink(const std::shared_ptr< GfxLink > &)
Definition: impgraph.cxx:1693
void draw(OutputDevice &rOutDev, const Point &rDestPt) const
Definition: impgraph.cxx:1004
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_BLACK
std::shared_ptr< VectorGraphicData > loadVectorGraphic(BinaryDataContainer const &rDataContainer, VectorGraphicDataType eType)
bool mbIsAnimated
Definition: impgraph.hxx:36
MetaActionType GetType() const
Definition: metaact.hxx:94
#define GRAPHIC_STREAMBUFSIZE
Definition: impgraph.cxx:55
OUString getSwapFileURL() const
Definition: impgraph.cxx:76
bool isAvailable() const
Definition: impgraph.cxx:513
static BitmapChecksum GetChecksum(const GDIMetaFile &rMetaFile)
Definition: SvmWriter.cxx:72
void setHeight(tools::Long nHeight)
void setPrefSize(const Size &rPrefSize)
Definition: impgraph.cxx:869
const GDIMetaFile & getGDIMetaFile() const
Definition: impgraph.cxx:693
#define SAL_WARN(area, stream)
void createSwapInfo()
Definition: impgraph.cxx:352
ColorAnimationSharedPtr mpAnimation
constexpr tools::Long getWidth() const
bool swapOutGraphic(SvStream &rStream)
Definition: impgraph.cxx:1173
sal_Int32 nLength
void setContext(const std::shared_ptr< GraphicReader > &pReader)
Definition: impgraph.cxx:1133
bool mbIsEPS
Definition: impgraph.hxx:37
bool getAntiAliase() const
Definition: graph.hxx:77
#define SWAP_FORMAT_ID
Definition: impgraph.cxx:57
OUString const & getOriginURL() const
Definition: impgraph.cxx:73
Size getPrefSize() const
Definition: impgraph.cxx:774
GraphicExternalLink maGraphicExternalLink
Definition: impgraph.hxx:84
Animation getAnimation() const
Definition: impgraph.cxx:676
Size getSizePixel() const
Definition: impgraph.cxx:762
bool Detect(bool bExtendedInfo=false)
starts the detection
void swappedOut(const ImpGraphic *pImpGraphic, sal_Int64 nSizeBytes)
Definition: Manager.cxx:275
const Size & GetSizePixel() const
Definition: bitmapex.hxx:72
bool operator==(const ImpGraphic &rImpGraphic) const
Definition: impgraph.cxx:285
#define SVSTREAM_GENERALERROR
Definition: errcode.hxx:240
constexpr sal_uInt32 constWmfMagic
MapMode maPrefMapMode
Definition: impgraph.hxx:32
RedlineType meType
bool isTransparent() const
Definition: impgraph.cxx:462
bool isGfxLink() const
Definition: impgraph.cxx:1712
constexpr sal_uInt32 constPdfMagic
bool swapOut()
Definition: impgraph.cxx:1296
Size maSizePixel
Definition: impgraph.hxx:34
const BitmapEx & getBitmapExRef() const
Gives direct access to the contained BitmapEx.
Definition: impgraph.cxx:687
void SetPrefMapMode(const MapMode &rMapMode)
Definition: gdimtf.hxx:176
bool m_bDetectedRangeSegmentation false
BitmapChecksum getChecksum() const
Definition: impgraph.cxx:1717
MapMode getPrefMapMode() const
Definition: impgraph.cxx:875
void clearGraphics()
Definition: impgraph.cxx:372
sal_uLong GetSizeBytes() const
Definition: gdimtf.cxx:2203