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