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 <vcl/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/outdev.hxx>
35 #include <vcl/graphicfilter.hxx>
36 #include <vcl/virdev.hxx>
37 #include <vcl/gfxlink.hxx>
38 #include <vcl/cvtgrf.hxx>
39 #include <vcl/graph.hxx>
40 #include <vcl/metaact.hxx>
41 #include <impgraph.hxx>
42 #include <com/sun/star/graphic/XPrimitive2D.hpp>
43 #include <vcl/dibtools.hxx>
44 #include <map>
45 #include <memory>
46 #include <vcl/gdimetafiletools.hxx>
47 #include <vcl/TypeSerializer.hxx>
48 #include <vcl/pdfread.hxx>
50 
51 #define GRAPHIC_MTFTOBMP_MAXEXT 2048
52 #define GRAPHIC_STREAMBUFSIZE 8192UL
53 
54 #define SWAP_FORMAT_ID COMPAT_FORMAT( 'S', 'W', 'A', 'P' )
55 
56 using namespace com::sun::star;
57 
58 class ImpSwapFile : public vcl::SwapFile
59 {
60 private:
61  OUString maOriginURL;
62 
63 public:
64  ImpSwapFile(INetURLObject const & rSwapURL, OUString const & rOriginURL)
65  : SwapFile(rSwapURL)
66  , maOriginURL(rOriginURL)
67  {
68  }
69 
70  OUString const & getOriginURL() const { return maOriginURL; }
71 };
72 
74 {
75  if (mpSwapFile)
76  return mpSwapFile->getSwapURL().GetMainURL(INetURLObject::DecodeMechanism::NONE);
77  return OUString();
78 }
79 
81  meType ( GraphicType::NONE ),
82  mnSizeBytes ( 0 ),
83  mbSwapOut ( false ),
84  mbDummyContext ( false ),
85  maLastUsed (std::chrono::high_resolution_clock::now()),
86  mbPrepared ( false )
87 {
88 }
89 
91  : maMetaFile(rImpGraphic.maMetaFile)
92  , maBitmapEx(rImpGraphic.maBitmapEx)
93  , maSwapInfo(rImpGraphic.maSwapInfo)
94  , mpContext(rImpGraphic.mpContext)
95  , mpSwapFile(rImpGraphic.mpSwapFile)
96  , mpGfxLink(rImpGraphic.mpGfxLink)
97  , meType(rImpGraphic.meType)
98  , mnSizeBytes(rImpGraphic.mnSizeBytes)
99  , mbSwapOut(rImpGraphic.mbSwapOut)
100  , mbDummyContext(rImpGraphic.mbDummyContext)
101  , maVectorGraphicData(rImpGraphic.maVectorGraphicData)
102  , maGraphicExternalLink(rImpGraphic.maGraphicExternalLink)
103  , maLastUsed (std::chrono::high_resolution_clock::now())
104  , mbPrepared (rImpGraphic.mbPrepared)
105 {
106  if( rImpGraphic.mpAnimation )
107  {
108  mpAnimation = std::make_unique<Animation>( *rImpGraphic.mpAnimation );
109  maBitmapEx = mpAnimation->GetBitmapEx();
110  }
111 }
112 
113 ImpGraphic::ImpGraphic(ImpGraphic&& rImpGraphic) noexcept
114  : maMetaFile(std::move(rImpGraphic.maMetaFile))
115  , maBitmapEx(std::move(rImpGraphic.maBitmapEx))
116  , maSwapInfo(std::move(rImpGraphic.maSwapInfo))
117  , mpAnimation(std::move(rImpGraphic.mpAnimation))
118  , mpContext(std::move(rImpGraphic.mpContext))
119  , mpSwapFile(std::move(rImpGraphic.mpSwapFile))
120  , mpGfxLink(std::move(rImpGraphic.mpGfxLink))
121  , meType(rImpGraphic.meType)
122  , mnSizeBytes(rImpGraphic.mnSizeBytes)
123  , mbSwapOut(rImpGraphic.mbSwapOut)
124  , mbDummyContext(rImpGraphic.mbDummyContext)
125  , maVectorGraphicData(std::move(rImpGraphic.maVectorGraphicData))
126  , maGraphicExternalLink(rImpGraphic.maGraphicExternalLink)
127  , maLastUsed (std::chrono::high_resolution_clock::now())
128  , mbPrepared (rImpGraphic.mbPrepared)
129 {
130  rImpGraphic.clear();
131  rImpGraphic.mbDummyContext = false;
132 }
133 
134 ImpGraphic::ImpGraphic(std::shared_ptr<GfxLink> const & rGfxLink, sal_Int32 nPageIndex)
135  : mpGfxLink(rGfxLink)
137  , mnSizeBytes(0)
138  , mbSwapOut(true)
139  , mbDummyContext(false)
140  , maLastUsed (std::chrono::high_resolution_clock::now())
141  , mbPrepared (false)
142 {
144  maSwapInfo.mbIsAlpha = true;
145  maSwapInfo.mbIsEPS = false;
146  maSwapInfo.mbIsAnimated = false;
148  maSwapInfo.mnPageIndex = nPageIndex;
149 }
150 
151 ImpGraphic::ImpGraphic(GraphicExternalLink const & rGraphicExternalLink) :
153  mnSizeBytes ( 0 ),
154  mbSwapOut ( false ),
155  mbDummyContext ( false ),
156  maGraphicExternalLink(rGraphicExternalLink),
157  maLastUsed (std::chrono::high_resolution_clock::now()),
158  mbPrepared (false)
159 {
160 }
161 
162 ImpGraphic::ImpGraphic( const BitmapEx& rBitmapEx ) :
163  maBitmapEx ( rBitmapEx ),
164  meType ( !rBitmapEx.IsEmpty() ? GraphicType::Bitmap : GraphicType::NONE ),
165  mnSizeBytes ( 0 ),
166  mbSwapOut ( false ),
167  mbDummyContext ( false ),
168  maLastUsed (std::chrono::high_resolution_clock::now()),
169  mbPrepared (false)
170 {
171 }
172 
173 ImpGraphic::ImpGraphic(const std::shared_ptr<VectorGraphicData>& rVectorGraphicDataPtr)
174 : meType( rVectorGraphicDataPtr ? GraphicType::Bitmap : GraphicType::NONE ),
175  mnSizeBytes( 0 ),
176  mbSwapOut( false ),
177  mbDummyContext ( false ),
178  maVectorGraphicData(rVectorGraphicDataPtr),
179  maLastUsed (std::chrono::high_resolution_clock::now()),
180  mbPrepared (false)
181 {
182 }
183 
184 ImpGraphic::ImpGraphic( const Animation& rAnimation ) :
185  maBitmapEx ( rAnimation.GetBitmapEx() ),
186  mpAnimation ( std::make_unique<Animation>( rAnimation ) ),
188  mnSizeBytes ( 0 ),
189  mbSwapOut ( false ),
190  mbDummyContext ( false ),
191  maLastUsed (std::chrono::high_resolution_clock::now()),
192  mbPrepared (false)
193 {
194 }
195 
197  maMetaFile ( rMtf ),
199  mnSizeBytes ( 0 ),
200  mbSwapOut ( false ),
201  mbDummyContext ( false ),
202  maLastUsed (std::chrono::high_resolution_clock::now()),
203  mbPrepared (false)
204 {
205 }
206 
208 {
210 }
211 
213 {
214  if( &rImpGraphic != this )
215  {
216  sal_Int64 aOldSizeBytes = mnSizeBytes;
217 
218  maMetaFile = rImpGraphic.maMetaFile;
219  meType = rImpGraphic.meType;
220  mnSizeBytes = rImpGraphic.mnSizeBytes;
221 
222  maSwapInfo = rImpGraphic.maSwapInfo;
223  mpContext = rImpGraphic.mpContext;
224  mbDummyContext = rImpGraphic.mbDummyContext;
226 
227  mpAnimation.reset();
228 
229  if ( rImpGraphic.mpAnimation )
230  {
231  mpAnimation = std::make_unique<Animation>( *rImpGraphic.mpAnimation );
232  maBitmapEx = mpAnimation->GetBitmapEx();
233  }
234  else
235  {
236  maBitmapEx = rImpGraphic.maBitmapEx;
237  }
238 
239  mbSwapOut = rImpGraphic.mbSwapOut;
240  mpSwapFile = rImpGraphic.mpSwapFile;
241  mbPrepared = rImpGraphic.mbPrepared;
242 
243  mpGfxLink = rImpGraphic.mpGfxLink;
244 
246  maLastUsed = std::chrono::high_resolution_clock::now();
247 
248  vcl::graphic::Manager::get().changeExisting(this, aOldSizeBytes);
249  }
250 
251  return *this;
252 }
253 
255 {
256  sal_Int64 aOldSizeBytes = mnSizeBytes;
257 
258  maMetaFile = std::move(rImpGraphic.maMetaFile);
259  meType = rImpGraphic.meType;
260  mnSizeBytes = rImpGraphic.mnSizeBytes;
261  maSwapInfo = std::move(rImpGraphic.maSwapInfo);
262  mpContext = std::move(rImpGraphic.mpContext);
263  mbDummyContext = rImpGraphic.mbDummyContext;
264  mpAnimation = std::move(rImpGraphic.mpAnimation);
265  maBitmapEx = std::move(rImpGraphic.maBitmapEx);
266  mbSwapOut = rImpGraphic.mbSwapOut;
267  mpSwapFile = std::move(rImpGraphic.mpSwapFile);
268  mpGfxLink = std::move(rImpGraphic.mpGfxLink);
269  maVectorGraphicData = std::move(rImpGraphic.maVectorGraphicData);
270  maGraphicExternalLink = rImpGraphic.maGraphicExternalLink;
271  mbPrepared = rImpGraphic.mbPrepared;
272 
273  rImpGraphic.clear();
274  rImpGraphic.mbDummyContext = false;
275  maLastUsed = std::chrono::high_resolution_clock::now();
276 
277  vcl::graphic::Manager::get().changeExisting(this, aOldSizeBytes);
278 
279  return *this;
280 }
281 
282 bool ImpGraphic::operator==( const ImpGraphic& rImpGraphic ) const
283 {
284  bool bRet = false;
285 
286  if( this == &rImpGraphic )
287  bRet = true;
288  else if (mbPrepared && rImpGraphic.mbPrepared)
289  {
290  bRet = (*mpGfxLink == *rImpGraphic.mpGfxLink);
291  }
292  else if (isAvailable() && rImpGraphic.isAvailable())
293  {
294  switch( meType )
295  {
296  case GraphicType::NONE:
297  bRet = true;
298  break;
299 
301  {
302  if( rImpGraphic.maMetaFile == maMetaFile )
303  bRet = true;
304  }
305  break;
306 
307  case GraphicType::Bitmap:
308  {
310  {
311  if(maVectorGraphicData == rImpGraphic.maVectorGraphicData)
312  {
313  // equal instances
314  bRet = true;
315  }
316  else if(rImpGraphic.maVectorGraphicData)
317  {
318  // equal content
319  bRet = (*maVectorGraphicData) == (*rImpGraphic.maVectorGraphicData);
320  }
321  }
322  else if( mpAnimation )
323  {
324  if( rImpGraphic.mpAnimation && ( *rImpGraphic.mpAnimation == *mpAnimation ) )
325  bRet = true;
326  }
327  else if( !rImpGraphic.mpAnimation && ( rImpGraphic.maBitmapEx == maBitmapEx ) )
328  {
329  bRet = true;
330  }
331  }
332  break;
333 
335  break;
336  }
337  }
338 
339  return bRet;
340 }
341 
342 const std::shared_ptr<VectorGraphicData>& ImpGraphic::getVectorGraphicData() const
343 {
344  ensureAvailable();
345 
346  return maVectorGraphicData;
347 }
348 
350 {
351  if (isSwappedOut())
352  return;
353 
354  if (!maBitmapEx.IsEmpty())
356  else
358 
367 }
368 
370 {
371  maBitmapEx.Clear();
372  maMetaFile.Clear();
373  mpAnimation.reset();
374  maVectorGraphicData.reset();
375 }
376 
377 void ImpGraphic::setPrepared(bool bAnimated, const Size* pSizeHint)
378 {
379  mbPrepared = true;
380  mbSwapOut = true;
382 
383  SvMemoryStream aMemoryStream(const_cast<sal_uInt8*>(mpGfxLink->GetData()), mpGfxLink->GetDataSize(), StreamMode::READ | StreamMode::WRITE);
384 
385  if (pSizeHint)
386  {
387  maSwapInfo.maPrefSize = *pSizeHint;
388  maSwapInfo.maPrefMapMode = MapMode(MapUnit::Map100thMM);
389  }
390 
391  GraphicDescriptor aDescriptor(aMemoryStream, nullptr);
392  if (aDescriptor.Detect(true))
393  {
394  if (!pSizeHint)
395  {
396  // If we have logic size, work with that, as later pixel -> logic
397  // conversion will work with the output device DPI, not the graphic
398  // DPI.
399  Size aLogSize = aDescriptor.GetSize_100TH_MM();
400  if (aDescriptor.GetPreferredLogSize() && aDescriptor.GetPreferredMapMode())
401  {
402  maSwapInfo.maPrefSize = *aDescriptor.GetPreferredLogSize();
404  }
405  else if (aLogSize.getWidth() && aLogSize.getHeight())
406  {
407  maSwapInfo.maPrefSize = aLogSize;
408  maSwapInfo.maPrefMapMode = MapMode(MapUnit::Map100thMM);
409  }
410  else
411  {
412  maSwapInfo.maPrefSize = aDescriptor.GetSizePixel();
413  maSwapInfo.maPrefMapMode = MapMode(MapUnit::MapPixel);
414  }
415  }
416 
417  maSwapInfo.maSizePixel = aDescriptor.GetSizePixel();
418  maSwapInfo.mbIsTransparent = aDescriptor.IsTransparent();
419  maSwapInfo.mbIsAlpha = aDescriptor.IsAlpha();
420  } else {
421  maSwapInfo.mbIsTransparent = false;
422  maSwapInfo.mbIsAlpha = false;
423  }
424 
426  maSwapInfo.mbIsEPS = false;
427  maSwapInfo.mbIsAnimated = bAnimated;
428 
430  maSwapInfo.mnPageIndex = maVectorGraphicData->getPageIndex();
431 }
432 
434 {
435  mpSwapFile.reset();
436  mbSwapOut = false;
437  mbPrepared = false;
438 
439  // cleanup
440  clearGraphics();
442  sal_Int64 nOldSize = mnSizeBytes;
443  mnSizeBytes = 0;
444  vcl::graphic::Manager::get().changeExisting(this, nOldSize);
446 }
447 
449 {
450  clear();
452 }
453 
455 {
456  return( meType != GraphicType::NONE );
457 }
458 
460 {
461  bool bRet(true);
462 
463  if (mbSwapOut)
464  {
466  }
468  {
469  bRet = mpAnimation ? mpAnimation->IsTransparent() : maBitmapEx.IsTransparent();
470  }
471 
472  return bRet;
473 }
474 
476 {
477  bool bRet(false);
478 
479  if (mbSwapOut)
480  {
481  bRet = maSwapInfo.mbIsAlpha;
482  }
483  else if (maVectorGraphicData)
484  {
485  bRet = true;
486  }
487  else if (meType == GraphicType::Bitmap)
488  {
489  bRet = (nullptr == mpAnimation && maBitmapEx.IsAlpha());
490  }
491 
492  return bRet;
493 }
494 
496 {
497  return mbSwapOut ? maSwapInfo.mbIsAnimated : mpAnimation != nullptr;
498 }
499 
500 bool ImpGraphic::isEPS() const
501 {
502  if (mbSwapOut)
503  return maSwapInfo.mbIsEPS;
504 
505  return( ( meType == GraphicType::GdiMetafile ) &&
506  ( maMetaFile.GetActionSize() > 0 ) &&
508 }
509 
511 {
512  return !mbPrepared && !mbSwapOut;
513 }
514 
516 {
517  return ensureAvailable();
518 }
519 
521 {
522  BitmapEx aRet = maVectorGraphicData->getReplacement();
523 
525  {
527  }
528 
529  return aRet;
530 }
531 
533 {
534  Bitmap aRetBmp;
535 
536  ensureAvailable();
537 
538  if( meType == GraphicType::Bitmap )
539  {
541  {
542  // use maBitmapEx as local buffer for rendered svg
543  const_cast< ImpGraphic* >(this)->maBitmapEx = getVectorGraphicReplacement();
544  }
545 
546  const BitmapEx& rRetBmpEx = ( mpAnimation ? mpAnimation->GetBitmapEx() : maBitmapEx );
547 
548  aRetBmp = rRetBmpEx.GetBitmap( COL_WHITE );
549 
550  if(rParameters.getSizePixel().Width() || rParameters.getSizePixel().Height())
551  aRetBmp.Scale(rParameters.getSizePixel());
552  }
553  else if( ( meType != GraphicType::Default ) && isSupportedGraphic() )
554  {
555  if(maBitmapEx.IsEmpty())
556  {
557  // calculate size
559  Size aDrawSize(aVDev->LogicToPixel(maMetaFile.GetPrefSize(), maMetaFile.GetPrefMapMode()));
560 
561  if(rParameters.getSizePixel().Width() && rParameters.getSizePixel().Height())
562  {
563  // apply given size if exists
564  aDrawSize = rParameters.getSizePixel();
565  }
566 
567  if(aDrawSize.Width() && aDrawSize.Height() && !rParameters.getUnlimitedSize()
568  && (aDrawSize.Width() > GRAPHIC_MTFTOBMP_MAXEXT || aDrawSize.Height() > GRAPHIC_MTFTOBMP_MAXEXT))
569  {
570  // limit bitmap size to a maximum of GRAPHIC_MTFTOBMP_MAXEXT x GRAPHIC_MTFTOBMP_MAXEXT
571  double fWH(static_cast<double>(aDrawSize.Width()) / static_cast<double>(aDrawSize.Height()));
572 
573  if(fWH <= 1.0)
574  {
577  }
578  else
579  {
582  }
583  }
584 
585  // calculate pixel size. Normally, it's the same as aDrawSize, but may
586  // need to be extended when hairlines are on the right or bottom edge
587  Size aPixelSize(aDrawSize);
588 
590  {
591  // get hairline and full bound rect
592  tools::Rectangle aHairlineRect;
593  const tools::Rectangle aRect(maMetaFile.GetBoundRect(*aVDev, &aHairlineRect));
594 
595  if(!aRect.IsEmpty() && !aHairlineRect.IsEmpty())
596  {
597  // expand if needed to allow bottom and right hairlines to be added
598  if(aRect.Right() == aHairlineRect.Right())
599  {
600  aPixelSize.setWidth(aPixelSize.getWidth() + 1);
601  }
602 
603  if(aRect.Bottom() == aHairlineRect.Bottom())
604  {
605  aPixelSize.setHeight(aPixelSize.getHeight() + 1);
606  }
607  }
608  }
609 
610  if(aVDev->SetOutputSizePixel(aPixelSize))
611  {
612  if(rParameters.getAntiAliase())
613  {
614  aVDev->SetAntialiasing(aVDev->GetAntialiasing() | AntialiasingFlags::Enable);
615  }
616 
617  if(rParameters.getSnapHorVerLines())
618  {
619  aVDev->SetAntialiasing(aVDev->GetAntialiasing() | AntialiasingFlags::PixelSnapHairline);
620  }
621 
622  draw( aVDev.get(), Point(), aDrawSize );
623 
624  // use maBitmapEx as local buffer for rendered metafile
625  const_cast< ImpGraphic* >(this)->maBitmapEx = aVDev->GetBitmapEx( Point(), aVDev->GetOutputSizePixel() );
626  }
627  }
628 
629  aRetBmp = maBitmapEx.GetBitmap();
630  }
631 
632  if( !!aRetBmp )
633  {
634  aRetBmp.SetPrefMapMode(getPrefMapMode());
635  aRetBmp.SetPrefSize(getPrefSize());
636  }
637 
638  return aRetBmp;
639 }
640 
642 {
643  BitmapEx aRetBmpEx;
644 
645  ensureAvailable();
646 
647  if( meType == GraphicType::Bitmap )
648  {
650  {
651  // use maBitmapEx as local buffer for rendered svg
652  const_cast< ImpGraphic* >(this)->maBitmapEx = getVectorGraphicReplacement();
653  }
654 
655  aRetBmpEx = ( mpAnimation ? mpAnimation->GetBitmapEx() : maBitmapEx );
656 
657  if(rParameters.getSizePixel().Width() || rParameters.getSizePixel().Height())
658  {
659  aRetBmpEx.Scale(
660  rParameters.getSizePixel(),
662  }
663  }
664  else if( ( meType != GraphicType::Default ) && isSupportedGraphic() )
665  {
666  if(maBitmapEx.IsEmpty())
667  {
668  const ImpGraphic aMonoMask( maMetaFile.GetMonochromeMtf( COL_BLACK ) );
669 
670  // use maBitmapEx as local buffer for rendered metafile
671  const_cast< ImpGraphic* >(this)->maBitmapEx = BitmapEx(getBitmap(rParameters), aMonoMask.getBitmap(rParameters));
672  }
673 
674  aRetBmpEx = maBitmapEx;
675  }
676 
677  return aRetBmpEx;
678 }
679 
681 {
682  Animation aAnimation;
683 
684  ensureAvailable();
685  if( mpAnimation )
686  aAnimation = *mpAnimation;
687 
688  return aAnimation;
689 }
690 
692 {
693  ensureAvailable();
694  return maBitmapEx;
695 }
696 
698 {
699  ensureAvailable();
704  {
705  // If we have a Emf/Wmf VectorGraphic object, we
706  // need a way to get the Metafile data out of the primitive
707  // representation. Use a strict virtual hook (MetafileAccessor)
708  // to access the MetafilePrimitive2D directly. Also see comments in
709  // XEmfParser about this.
710  const std::deque< css::uno::Reference< css::graphic::XPrimitive2D > > aSequence(maVectorGraphicData->getPrimitive2DSequence());
711 
712  if (1 == aSequence.size())
713  {
714  // try to cast to MetafileAccessor implementation
715  const css::uno::Reference< css::graphic::XPrimitive2D > xReference(aSequence[0]);
716  const MetafileAccessor* pMetafileAccessor = dynamic_cast< const MetafileAccessor* >(xReference.get());
717 
718  if (pMetafileAccessor)
719  {
720  // it is a MetafileAccessor implementation, get Metafile
721  pMetafileAccessor->accessMetafile(const_cast< ImpGraphic* >(this)->maMetaFile);
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
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* pOutDev, 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(pOutDev, rDestPt);
1024  }
1025  else
1026  {
1027  maBitmapEx.Draw(pOutDev, rDestPt);
1028  }
1029  }
1030  break;
1031 
1033  {
1034  draw(pOutDev, 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(pOutDev, rDestPt, rDestSize);
1065  }
1066  else
1067  {
1068  maBitmapEx.Draw(pOutDev, rDestPt, rDestSize);
1069  }
1070  }
1071  break;
1072 
1074  {
1075  const_cast<ImpGraphic*>(this)->maMetaFile.WindStart();
1076  const_cast<ImpGraphic*>(this)->maMetaFile.Play(pOutDev, 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* pOutDev, const Point& rDestPt,
1088  const Size& rDestSize, tools::Long nExtraData,
1089  OutputDevice* pFirstFrameOutDev )
1090 {
1091  ensureAvailable();
1092 
1094  mpAnimation->Start( pOutDev, 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  WriteGDIMetaFile(rStream, maMetaFile);
1191  }
1192  break;
1193 
1194  case GraphicType::Bitmap:
1195  {
1196  if (maVectorGraphicData)
1197  {
1198  rStream.WriteInt32(sal_Int32(GraphicContentType::Vector));
1199  // stream out Vector Graphic defining data (length, byte array and evtl. path)
1200  // this is used e.g. in swapping out graphic data and in transporting it over UNO API
1201  // as sequence of bytes, but AFAIK not written anywhere to any kind of file, so it should be
1202  // no problem to extend it; only used at runtime
1203  switch (maVectorGraphicData->getType())
1204  {
1206  {
1207  rStream.WriteUInt32(constWmfMagic);
1208  break;
1209  }
1211  {
1212  rStream.WriteUInt32(constEmfMagic);
1213  break;
1214  }
1216  {
1217  rStream.WriteUInt32(constSvgMagic);
1218  break;
1219  }
1221  {
1222  rStream.WriteUInt32(constPdfMagic);
1223  break;
1224  }
1225  }
1226 
1227  rStream.WriteUInt32(maVectorGraphicData->getBinaryDataContainer().getSize());
1228 
1229  rStream.WriteBytes(
1230  maVectorGraphicData->getBinaryDataContainer().getData(),
1231  maVectorGraphicData->getBinaryDataContainer().getSize());
1232  }
1233  else if (isAnimated())
1234  {
1235  rStream.WriteInt32(sal_Int32(GraphicContentType::Animation));
1236  WriteAnimation(rStream, *mpAnimation);
1237  }
1238  else
1239  {
1240  rStream.WriteInt32(sal_Int32(GraphicContentType::Bitmap));
1241  WriteDIBBitmapEx(maBitmapEx, rStream);
1242  }
1243  }
1244  break;
1245 
1246  case GraphicType::NONE:
1247  case GraphicType::Default:
1248  break;
1249  }
1250 
1251  return true;
1252 }
1253 
1255 {
1256  ensureAvailable();
1257 
1258  bool bRet = false;
1259 
1261  return false;
1262 
1263  sal_uLong nDataFieldPos;
1264 
1265  // Write the SWAP ID
1266  rStream.WriteUInt32(SWAP_FORMAT_ID);
1267 
1268  rStream.WriteInt32(static_cast<sal_Int32>(meType));
1269 
1270  // data size is updated later
1271  nDataFieldPos = rStream.Tell();
1272  rStream.WriteInt32(0);
1273 
1274  // write data block
1275  const sal_uLong nDataStart = rStream.Tell();
1276 
1277  swapOutGraphic(rStream);
1278 
1279  if (!rStream.GetError())
1280  {
1281  // Write the written length th the header
1282  const sal_uLong nCurrentPosition = rStream.Tell();
1283  rStream.Seek(nDataFieldPos);
1284  rStream.WriteInt32(nCurrentPosition - nDataStart);
1285  rStream.Seek(nCurrentPosition);
1286  bRet = true;
1287  }
1288 
1289  return bRet;
1290 }
1291 
1293 {
1294  if (isSwappedOut())
1295  return false;
1296 
1297  bool bResult = false;
1298 
1299  sal_Int64 nByteSize = getSizeBytes();
1300 
1301  // We have GfxLink so we have the source available
1302  if (mpGfxLink && mpGfxLink->IsNative())
1303  {
1304  createSwapInfo();
1305 
1306  clearGraphics();
1307 
1308  // reset the swap file
1309  mpSwapFile.reset();
1310 
1311  // mark as swapped out
1312  mbSwapOut = true;
1313 
1314  bResult = true;
1315  }
1316  else
1317  {
1318  // Create a temp filename for the swap file
1319  utl::TempFile aTempFile;
1320  const INetURLObject aTempFileURL(aTempFile.GetURL());
1321 
1322  // Create a swap file
1323  auto pSwapFile = o3tl::make_shared<ImpSwapFile>(aTempFileURL, getOriginURL());
1324 
1325  // Open a stream to write the swap file to
1326  {
1327  std::unique_ptr<SvStream> xOutputStream = pSwapFile->openOutputStream();
1328 
1329  if (!xOutputStream)
1330  return false;
1331 
1332  // Write to stream
1333  xOutputStream->SetVersion(SOFFICE_FILEFORMAT_50);
1334  xOutputStream->SetCompressMode(SvStreamCompressFlags::NATIVE);
1335  xOutputStream->SetBufferSize(GRAPHIC_STREAMBUFSIZE);
1336 
1337  if (!xOutputStream->GetError() && swapOutContent(*xOutputStream))
1338  {
1339  xOutputStream->Flush();
1340  bResult = !xOutputStream->GetError();
1341  }
1342  }
1343 
1344  // Check if writing was successful
1345  if (bResult)
1346  {
1347  // We have swapped out, so can clean memory and prepare swap info
1348  createSwapInfo();
1349  clearGraphics();
1350 
1351  mpSwapFile = std::move(pSwapFile);
1352  mbSwapOut = true;
1353  }
1354  }
1355 
1356  if (bResult)
1357  {
1358  // Signal to manager that we have swapped out
1359  vcl::graphic::Manager::get().swappedOut(this, nByteSize);
1360  }
1361 
1362  return bResult;
1363 }
1364 
1366 {
1367  auto pThis = const_cast<ImpGraphic*>(this);
1368 
1369  bool bResult = true;
1370 
1371  if (isSwappedOut())
1372  bResult = pThis->swapIn();
1373 
1374  pThis->maLastUsed = std::chrono::high_resolution_clock::now();
1375  return bResult;
1376 }
1377 
1379 {
1380  if (mbPrepared)
1381  {
1383  Size aPrefSize = maSwapInfo.maPrefSize;
1384  MapMode aPrefMapMode = maSwapInfo.maPrefMapMode;
1385  *this = *pGraphic;
1386  if (aPrefSize.getWidth() && aPrefSize.getHeight() && aPrefMapMode == getPrefMapMode())
1387  {
1388  // Use custom preferred size if it was set when the graphic was still unloaded.
1389  // Only set the size in case the unloaded and loaded unit matches.
1390  setPrefSize(aPrefSize);
1391  }
1392  maGraphicExternalLink = aLink;
1393  }
1394  else
1395  {
1396  // Move over only graphic content
1397  mpAnimation.reset();
1398  if (pGraphic->mpAnimation)
1399  {
1400  mpAnimation = std::make_unique<Animation>(*pGraphic->mpAnimation);
1401  maBitmapEx = mpAnimation->GetBitmapEx();
1402  }
1403  else
1404  {
1405  maBitmapEx = pGraphic->maBitmapEx;
1406  }
1407 
1408  maMetaFile = pGraphic->maMetaFile;
1410 
1411  // Set to 0, to force recalculation
1412  mnSizeBytes = 0;
1413  mnChecksum = 0;
1414 
1416 
1417  mbSwapOut = false;
1418  }
1419 }
1420 
1422 {
1425 
1426  if (maVectorGraphicData)
1427  {
1429  }
1430 }
1431 
1432 namespace
1433 {
1434 
1435 std::optional<VectorGraphicDataType> lclConvertToVectorGraphicType(GfxLink const & rLink)
1436 {
1437  switch(rLink.GetType())
1438  {
1441 
1443  if (rLink.IsEMF())
1445  else
1447 
1450 
1451  default:
1452  break;
1453  }
1454  return std::optional<VectorGraphicDataType>();
1455 }
1456 
1457 } // end namespace
1458 
1460 {
1461  if (!isSwappedOut())
1462  return false;
1463 
1464  bool bReturn = false;
1465 
1466  if (mbPrepared)
1467  {
1468  Graphic aGraphic;
1469  if (!mpGfxLink->LoadNative(aGraphic))
1470  return false;
1471 
1473 
1474  maLastUsed = std::chrono::high_resolution_clock::now();
1475  bReturn = true;
1476  }
1477  else if (mpGfxLink && mpGfxLink->IsNative())
1478  {
1479  std::optional<VectorGraphicDataType> oType = lclConvertToVectorGraphicType(*mpGfxLink);
1480  if (oType)
1481  {
1482  maVectorGraphicData = vcl::loadVectorGraphic(mpGfxLink->getDataContainer(), *oType);
1483 
1484  // Set to 0, to force recalculation
1485  mnSizeBytes = 0;
1486  mnChecksum = 0;
1487 
1489 
1490  mbSwapOut = false;
1491  }
1492  else
1493  {
1494  Graphic aGraphic;
1495  if (!mpGfxLink->LoadNative(aGraphic))
1496  return false;
1497 
1498  ImpGraphic* pImpGraphic = aGraphic.ImplGetImpGraphic();
1499  if (meType != pImpGraphic->meType)
1500  return false;
1501 
1502  updateFromLoadedGraphic(pImpGraphic);
1503  }
1504 
1505  maLastUsed = std::chrono::high_resolution_clock::now();
1506  bReturn = true;
1507  }
1508  else
1509  {
1510  OUString aSwapURL;
1511 
1512  if (mpSwapFile)
1513  aSwapURL = mpSwapFile->getSwapURL().GetMainURL(INetURLObject::DecodeMechanism::NONE);
1514 
1515  if (!aSwapURL.isEmpty())
1516  {
1517  std::unique_ptr<SvStream> xStream;
1518  try
1519  {
1520  xStream = ::utl::UcbStreamHelper::CreateStream(aSwapURL, StreamMode::READWRITE | StreamMode::SHARE_DENYWRITE);
1521  }
1522  catch( const css::uno::Exception& )
1523  {
1524  }
1525 
1526  if (xStream)
1527  {
1528  xStream->SetVersion(SOFFICE_FILEFORMAT_50);
1529  xStream->SetCompressMode(SvStreamCompressFlags::NATIVE);
1530  xStream->SetBufferSize(GRAPHIC_STREAMBUFSIZE);
1531 
1532  bReturn = swapInFromStream(*xStream);
1533 
1534  xStream.reset();
1535 
1537 
1538  if (mpSwapFile)
1539  setOriginURL(mpSwapFile->getOriginURL());
1540 
1541  mpSwapFile.reset();
1542  }
1543  }
1544  }
1545 
1546  if (bReturn)
1547  {
1549  }
1550 
1551  return bReturn;
1552 }
1553 
1555 {
1556  bool bRet = false;
1557 
1558  if (rStream.GetError())
1559  return false;
1560 
1561  clearGraphics();
1562  mnSizeBytes = 0;
1563  mnChecksum = 0;
1564 
1565  bRet = swapInContent(rStream);
1566 
1567  if (!bRet)
1568  {
1569  //throw away swapfile, etc.
1570  clear();
1571  }
1572 
1573  mbSwapOut = false;
1574 
1575  return bRet;
1576 }
1577 
1579 {
1580  bool bReturn = false;
1581 
1582  if (rStream.GetError())
1583  return bReturn;
1584 
1585  if (meType == GraphicType::Bitmap)
1586  {
1587  sal_Int32 nContentType = -1;
1588  rStream.ReadInt32(nContentType);
1589  if (nContentType < 0)
1590  return false;
1591 
1592  auto eContentType = static_cast<GraphicContentType>(nContentType);
1593 
1594  switch (eContentType)
1595  {
1597  {
1598  BitmapEx aBitmapEx;
1599  ReadDIBBitmapEx(aBitmapEx, rStream);
1600  if (!rStream.GetError())
1601  {
1602  maBitmapEx = aBitmapEx;
1603  bReturn = true;
1604  }
1605  }
1606  break;
1607 
1609  {
1610  auto pAnimation = std::make_unique<Animation>();
1611  ReadAnimation(rStream, *pAnimation);
1612  if (!rStream.GetError())
1613  {
1614  mpAnimation = std::move(pAnimation);
1615  maBitmapEx = mpAnimation->GetBitmapEx();
1616  bReturn = true;
1617  }
1618  }
1619  break;
1620 
1622  {
1623  // try to stream in Svg defining data (length, byte array and evtl. path)
1624  // See below (operator<<) for more information
1625  sal_uInt32 nMagic;
1626  rStream.ReadUInt32(nMagic);
1627 
1628  if (constSvgMagic == nMagic || constWmfMagic == nMagic || constEmfMagic == nMagic || constPdfMagic == nMagic)
1629  {
1630  sal_uInt32 nVectorGraphicDataSize(0);
1631  rStream.ReadUInt32(nVectorGraphicDataSize);
1632 
1633  if (nVectorGraphicDataSize)
1634  {
1635  auto rData = std::make_unique<std::vector<sal_uInt8>>(nVectorGraphicDataSize);
1636  rStream.ReadBytes(rData->data(), nVectorGraphicDataSize);
1637  BinaryDataContainer aDataContainer(std::move(rData));
1638 
1639  if (rStream.GetError())
1640  return false;
1641 
1642  VectorGraphicDataType aDataType;
1643 
1644  switch (nMagic)
1645  {
1646  case constSvgMagic:
1647  aDataType = VectorGraphicDataType::Svg;
1648  break;
1649  case constWmfMagic:
1650  aDataType = VectorGraphicDataType::Wmf;
1651  break;
1652  case constEmfMagic:
1653  aDataType = VectorGraphicDataType::Emf;
1654  break;
1655  case constPdfMagic:
1656  aDataType = VectorGraphicDataType::Pdf;
1657  break;
1658  default:
1659  return false;
1660  }
1661 
1662  auto aVectorGraphicDataPtr = std::make_shared<VectorGraphicData>(aDataContainer, aDataType);
1663 
1664  if (!rStream.GetError())
1665  {
1666  maVectorGraphicData = aVectorGraphicDataPtr;
1667  bReturn = true;
1668  }
1669  }
1670  }
1671  }
1672  break;
1673  }
1674  }
1675  else if (meType == GraphicType::GdiMetafile)
1676  {
1677  GDIMetaFile aMetaFile;
1678  ReadGDIMetaFile(rStream, aMetaFile);
1679  if (!rStream.GetError())
1680  {
1681  maMetaFile = aMetaFile;
1682  bReturn = true;
1683  }
1684  }
1685  return bReturn;
1686 }
1687 
1688 void ImpGraphic::setGfxLink(const std::shared_ptr<GfxLink>& rGfxLink)
1689 {
1690  ensureAvailable();
1691 
1692  mpGfxLink = rGfxLink;
1693 }
1694 
1695 const std::shared_ptr<GfxLink> & ImpGraphic::getSharedGfxLink() const
1696 {
1697  return mpGfxLink;
1698 }
1699 
1701 {
1702  ensureAvailable();
1703 
1704  return( mpGfxLink ? *mpGfxLink : GfxLink() );
1705 }
1706 
1708 {
1709  return ( bool(mpGfxLink) );
1710 }
1711 
1713 {
1714  if (mnChecksum != 0)
1715  return mnChecksum;
1716 
1717  ensureAvailable();
1718 
1719  switch (meType)
1720  {
1721  case GraphicType::NONE:
1722  case GraphicType::Default:
1723  break;
1724 
1725  case GraphicType::Bitmap:
1726  {
1727  if (maVectorGraphicData)
1728  mnChecksum = maVectorGraphicData->GetChecksum();
1729  else if (mpAnimation)
1730  mnChecksum = mpAnimation->GetChecksum();
1731  else
1733  }
1734  break;
1735 
1737  {
1739  }
1740  break;
1741  }
1742  return mnChecksum;
1743 }
1744 
1745 sal_Int32 ImpGraphic::getPageNumber() const
1746 {
1747  if (isSwappedOut())
1748  return maSwapInfo.mnPageIndex;
1749 
1750  if (maVectorGraphicData)
1751  return maVectorGraphicData->getPageIndex();
1752  return -1;
1753 }
1754 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
constexpr sal_uInt32 constSvgMagic
bool swapInContent(SvStream &rStream)
Definition: impgraph.cxx:1139
VectorGraphicDataType
ImpGraphic & operator=(const ImpGraphic &rImpGraphic)
Definition: impgraph.cxx:212
bool mbDummyContext
Definition: impgraph.hxx:77
sal_uInt64 BitmapChecksum
Definition: checksum.hxx:30
std::shared_ptr< GraphicReader > mpContext
Definition: impgraph.hxx:71
void setValuesForPrefSize(const Size &rPrefSize)
Definition: impgraph.cxx:829
void draw(OutputDevice *pOutDev, const Point &rDestPt) const
Definition: impgraph.cxx:1004
double getHeight() const
void setPrepared(bool bAnimated, const Size *pSizeHint)
Definition: impgraph.cxx:377
void setAnimationNotifyHdl(const Link< Animation *, void > &rLink)
Definition: impgraph.cxx:1105
void setWidth(tools::Long nWidth)
SvStream & WriteInt32(sal_Int32 nInt32)
std::optional< Size > GetPreferredLogSize() const
Returns the logic size, according to the map mode available via GetPreferredMapMode().
const MapMode & GetPrefMapMode() const
Definition: bitmapex.hxx:90
tools::Long getWidth() const
const MapMode & GetPrefMapMode() const
Definition: gdimtf.hxx:178
bool Scale(const Size &rNewSize, BmpScaleFlag nScaleFlag=BmpScaleFlag::Default)
Scale the bitmap.
Definition: BitmapEx.cxx:365
bool mbIsTransparent
Definition: impgraph.hxx:37
void unregisterGraphic(ImpGraphic *pImpGraphic)
Definition: Manager.cxx:184
sal_uIntPtr sal_uLong
long Long
void SetPrefMapMode(const MapMode &rPrefMapMode)
Definition: bitmapex.hxx:91
OUString maOriginURL
Definition: impgraph.cxx:61
GraphicType
Definition: graph.hxx:34
bool mbIsAlpha
Definition: impgraph.hxx:38
void SetPrefSize(const Size &rSize)
Definition: gdimtf.hxx:176
void Clear()
Definition: gdimtf.cxx:271
sal_Int16 nId
const ContentProperties & rData
sal_uInt64 Seek(sal_uInt64 nPos)
bool swapOutContent(SvStream &rStream)
Definition: impgraph.cxx:1254
bool ensureAvailable() const
Definition: impgraph.cxx:1365
bool isSupportedGraphic() const
Definition: impgraph.cxx:454
ParserContextSharedPtr mpContext
void setPrefMapMode(const MapMode &rPrefMapMode)
Definition: impgraph.cxx:956
bool swapIn()
Definition: impgraph.cxx:1459
bool mbSwapOut
Definition: impgraph.hxx:76
GraphicContentType
Definition: impgraph.hxx:50
SvStream & ReadAnimation(SvStream &rIStm, Animation &rAnimation)
Definition: Animation.cxx:597
BitmapChecksum GetChecksum() const
Definition: BitmapEx.cxx:287
void updateFromLoadedGraphic(ImpGraphic *graphic)
Definition: impgraph.cxx:1378
void swappedIn(const ImpGraphic *pImpGraphic, sal_Int64 nSizeBytes)
Definition: Manager.cxx:250
NONE
bool getUnlimitedSize() const
Definition: graph.hxx:76
bool IsEmpty() const
OUString const & getOriginURL() const
Definition: impgraph.hxx:109
bool IsAlpha() const
Definition: BitmapEx.cxx:221
double getWidth() const
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:1744
constexpr sal_uInt32 constEmfMagic
bool swapInFromStream(SvStream &rStream)
Definition: impgraph.cxx:1554
bool IsAlpha() const
Container for the binary data, whose responsibility is to manage the make it as simple as possible to...
SvStream & WriteGDIMetaFile(SvStream &rOStm, const GDIMetaFile &rGDIMetaFile)
Definition: gdimtf.cxx:2727
void setDefaultType()
Definition: impgraph.cxx:448
const sal_uInt16 nMagic
const Size & GetPrefSize() const
Definition: bitmapex.hxx:87
sal_uInt32 mnAnimationLoopCount
Definition: impgraph.hxx:40
tools::Long Bottom() const
bool isEPS() const
Definition: impgraph.cxx:500
SvStream & WriteUInt32(sal_uInt32 nUInt32)
void Play(GDIMetaFile &rMtf)
Definition: gdimtf.cxx:323
GDIMetaFile GetMonochromeMtf(const Color &rCol) const
Definition: gdimtf.cxx:2204
GraphicType meType
Definition: impgraph.hxx:74
const Size & GetSize_100TH_MM() const
Size maPrefSize
Definition: impgraph.hxx:32
B2IRange fround(const B2DRange &rRange)
void Clear()
Definition: BitmapEx.cxx:211
void restoreFromSwapInfo()
Definition: impgraph.cxx:1421
bool makeAvailable()
Definition: impgraph.cxx:515
const Size & getSizePixel() const
Definition: graph.hxx:75
std::unique_ptr< Animation > mpAnimation
Definition: impgraph.hxx:70
BitmapEx maBitmapEx
Definition: impgraph.hxx:66
SvStream & ReadUInt32(sal_uInt32 &rUInt32)
bool isSwappedOut() const
Definition: impgraph.hxx:219
std::shared_ptr< ImpSwapFile > mpSwapFile
Definition: impgraph.hxx:72
tools::Long getHeight() const
sal_Int32 mnPageIndex
Definition: impgraph.hxx:41
bool IsEmpty() const
Definition: BitmapEx.cxx:198
void SetPrefMapMode(const MapMode &rMapMode)
Definition: bitmap.hxx:566
void setOriginURL(OUString const &rOriginURL)
Definition: impgraph.hxx:114
#define SOFFICE_FILEFORMAT_50
bool WriteDIBBitmapEx(const BitmapEx &rSource, SvStream &rOStm)
Definition: dibtools.cxx:1876
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:551
const Size & GetPrefSize() const
Definition: gdimtf.hxx:175
const Size & GetSizePixel() const
Bitmap getBitmap(const GraphicConversionParameters &rParameters) const
Definition: impgraph.cxx:532
GDIMetaFile maMetaFile
Definition: impgraph.hxx:65
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:80
sal_uInt32 getAnimationLoopCount() const
Definition: impgraph.cxx:1125
BitmapEx getVectorGraphicReplacement() const
Gets the bitmap replacement for a vector graphic.
Definition: impgraph.cxx:520
tools::Long Width() const
Some things multiple-inherit from VclAbstractDialog and OutputDevice, so we need to use virtual inher...
Definition: outdev.hxx:303
std::size_t WriteBytes(const void *pData, std::size_t nSize)
sal_uLong GetSizeBytes() const
Definition: BitmapEx.cxx:277
void changeExisting(const ImpGraphic *pImpGraphic, sal_Int64 nOldSize)
Definition: Manager.cxx:268
sal_uLong mnSizeBytes
Definition: impgraph.hxx:75
void SetPrefSize(const Size &rSize)
Definition: bitmap.hxx:576
void SetError(ErrCode nErrorCode)
#define GRAPHIC_MTFTOBMP_MAXEXT
Definition: impgraph.cxx:51
const std::shared_ptr< VectorGraphicData > & getVectorGraphicData() const
Definition: impgraph.cxx:342
void WindStart()
Definition: gdimtf.cxx:551
bool IsTransparent() const
Definition: BitmapEx.cxx:216
void stopAnimation(const OutputDevice *pOutputDevice, tools::Long nExtraData)
Definition: impgraph.cxx:1097
void Draw(OutputDevice *pOutDev, const Point &rDestPt) const
Definition: BitmapEx.cxx:612
tools::Rectangle GetBoundRect(OutputDevice &i_rReference, tools::Rectangle *pHairline=nullptr) const
Definition: gdimtf.cxx:1305
bool mbPrepared
Definition: impgraph.hxx:86
SvStream & ReadInt32(sal_Int32 &rInt32)
std::optional< MapMode > GetPreferredMapMode() const
If available, this returns the map mode the graphic prefers, which may be other than pixel or 100th m...
Size maExPrefSize
If maBitmapEx is empty, this preferred size will be set on it when it gets initialized.
Definition: impgraph.hxx:68
std::shared_ptr< GfxLink > mpGfxLink
Definition: impgraph.hxx:73
std::size_t ReadBytes(void *pData, std::size_t nSize)
Bitmap GetBitmap(Color aTransparentReplaceColor) const
Definition: BitmapEx.cxx:231
std::chrono::high_resolution_clock::time_point maLastUsed
Definition: impgraph.hxx:85
void Stop()
Definition: gdimtf.cxx:538
const std::shared_ptr< GfxLink > & getSharedGfxLink() const
Definition: impgraph.cxx:1695
bool swapInGraphic(SvStream &rStream)
Definition: impgraph.cxx:1578
sal_uLong getSizeBytes() const
Definition: impgraph.cxx:962
BitmapChecksum GetChecksum() const
Definition: gdimtf.cxx:2219
std::shared_ptr< VectorGraphicData > maVectorGraphicData
Definition: impgraph.hxx:78
bool isAlpha() const
Definition: impgraph.cxx:475
bool Scale(const Size &rNewSize, BmpScaleFlag nScaleFlag=BmpScaleFlag::Default)
Scale the bitmap.
ImpSwapFile(INetURLObject const &rSwapURL, OUString const &rOriginURL)
Definition: impgraph.cxx:64
void AddAction(const rtl::Reference< MetaAction > &pAction)
Definition: gdimtf.cxx:564
bool IsTransparent() const
void clear()
Definition: impgraph.cxx:433
MetaAction * GetAction(size_t nAction) const
Definition: gdimtf.cxx:185
Link< Animation *, void > getAnimationNotifyHdl() const
Definition: impgraph.cxx:1113
SvStream & ReadGDIMetaFile(SvStream &rIStm, GDIMetaFile &rGDIMetaFile, ImplMetaReadData *pData)
Definition: gdimtf.cxx:2643
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_WHITE
GraphicType getType() const
Definition: impgraph.hxx:132
bool isAnimated() const
Definition: impgraph.cxx:495
BitmapEx getBitmapEx(const GraphicConversionParameters &rParameters) const
Definition: impgraph.cxx:641
void SetPrefSize(const Size &rPrefSize)
Definition: bitmapex.hxx:88
sal_Int32 getPageNumber() const
Definition: impgraph.cxx:1745
tools::Long Height() const
ImpSwapInfo maSwapInfo
Definition: impgraph.hxx:69
sal_uInt64 Tell() const
size_t GetActionSize() const
Definition: gdimtf.cxx:180
QPRO_FUNC_TYPE nType
void setGfxLink(const std::shared_ptr< GfxLink > &)
Definition: impgraph.cxx:1688
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_BLACK
std::shared_ptr< VectorGraphicData > loadVectorGraphic(BinaryDataContainer const &rDataContainer, VectorGraphicDataType eType)
bool mbIsAnimated
Definition: impgraph.hxx:35
MetaActionType GetType() const
Definition: metaact.hxx:90
#define GRAPHIC_STREAMBUFSIZE
Definition: impgraph.cxx:52
void startAnimation(OutputDevice *pOutDev, const Point &rDestPt, const Size &rDestSize, tools::Long nExtraData, OutputDevice *pFirstFrameOutDev)
Definition: impgraph.cxx:1087
OUString getSwapFileURL() const
Definition: impgraph.cxx:73
bool isAvailable() const
Definition: impgraph.cxx:510
void setHeight(tools::Long nHeight)
reference_type * get() const
Get the body.
Definition: vclptr.hxx:143
void setPrefSize(const Size &rPrefSize)
Definition: impgraph.cxx:869
const GDIMetaFile & getGDIMetaFile() const
Definition: impgraph.cxx:697
#define SAL_WARN(area, stream)
void createSwapInfo()
Definition: impgraph.cxx:349
ColorAnimationSharedPtr mpAnimation
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:36
bool getAntiAliase() const
Definition: graph.hxx:77
#define SWAP_FORMAT_ID
Definition: impgraph.cxx:54
OUString const & getOriginURL() const
Definition: impgraph.cxx:70
Size getPrefSize() const
Definition: impgraph.cxx:774
GraphicExternalLink maGraphicExternalLink
Definition: impgraph.hxx:83
Animation getAnimation() const
Definition: impgraph.cxx:680
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:259
const Size & GetSizePixel() const
Definition: bitmapex.hxx:84
bool operator==(const ImpGraphic &rImpGraphic) const
Definition: impgraph.cxx:282
#define SVSTREAM_GENERALERROR
Definition: errcode.hxx:240
constexpr sal_uInt32 constWmfMagic
MapMode maPrefMapMode
Definition: impgraph.hxx:31
RedlineType meType
bool isTransparent() const
Definition: impgraph.cxx:459
bool isGfxLink() const
Definition: impgraph.cxx:1707
constexpr sal_uInt32 constPdfMagic
bool swapOut()
Definition: impgraph.cxx:1292
tools::Long Right() const
Size maSizePixel
Definition: impgraph.hxx:33
const BitmapEx & getBitmapExRef() const
Gives direct access to the contained BitmapEx.
Definition: impgraph.cxx:691
GfxLink getGfxLink()
Definition: impgraph.cxx:1700
void SetPrefMapMode(const MapMode &rMapMode)
Definition: gdimtf.hxx:179
BitmapChecksum getChecksum() const
Definition: impgraph.cxx:1712
MapMode getPrefMapMode() const
Definition: impgraph.cxx:875
void clearGraphics()
Definition: impgraph.cxx:369
sal_uLong GetSizeBytes() const
Definition: gdimtf.cxx:2562