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 <comphelper/fileformat.h>
25 #include <tools/fract.hxx>
26 #include <tools/vcompat.hxx>
27 #include <tools/urlobj.hxx>
28 #include <tools/stream.hxx>
29 #include <ucbhelper/content.hxx>
31 #include <unotools/tempfile.hxx>
32 #include <vcl/outdev.hxx>
33 #include <vcl/graphicfilter.hxx>
34 #include <vcl/virdev.hxx>
35 #include <vcl/gfxlink.hxx>
36 #include <vcl/cvtgrf.hxx>
37 #include <vcl/graph.hxx>
38 #include <vcl/metaact.hxx>
39 #include <impgraph.hxx>
40 #include <com/sun/star/ucb/CommandAbortedException.hpp>
41 #include <com/sun/star/ucb/ContentCreationException.hpp>
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 <TypeSerializer.hxx>
48 #include <vcl/pdfread.hxx>
49 
50 #define GRAPHIC_MTFTOBMP_MAXEXT 2048
51 #define GRAPHIC_STREAMBUFSIZE 8192UL
52 
53 #define SYS_WINMETAFILE 0x00000003L
54 #define SYS_WNTMETAFILE 0x00000004L
55 #define SYS_OS2METAFILE 0x00000005L
56 #define SYS_MACMETAFILE 0x00000006L
57 
58 #define GRAPHIC_FORMAT_50 COMPAT_FORMAT( 'G', 'R', 'F', '5' )
59 #define NATIVE_FORMAT_50 COMPAT_FORMAT( 'N', 'A', 'T', '5' )
60 
61 const sal_uInt32 nPdfMagic((sal_uInt32('p') << 24) | (sal_uInt32('d') << 16) | (sal_uInt32('f') << 8) | sal_uInt32('0'));
62 
63 using namespace com::sun::star;
64 
66 {
68  OUString maOriginURL;
69  ~ImpSwapFile();
70 };
71 
73 {
74 public:
76 };
77 
79 {
80 }
81 
83 {
84 }
85 
87 {
88  if( mpReaderData )
89  mpReaderData->maPreviewSize = Size( 0, 0 );
90 }
91 
92 void GraphicReader::SetPreviewSize( const Size& rSize )
93 {
94  if( !mpReaderData )
95  mpReaderData.reset( new ReaderData );
96  mpReaderData->maPreviewSize = rSize;
97 }
98 
100 {
101  Size aSize( 0, 0 );
102  if( mpReaderData )
103  aSize = mpReaderData->maPreviewSize;
104  return aSize;
105 }
106 
108 {
109  rGraphic.ensureAvailable();
110 
111  mnID1 = static_cast<sal_uLong>(rGraphic.ImplGetType()) << 28;
112  mnID2 = mnID3 = mnID4 = 0;
113 
114  if (rGraphic.ImplGetType() == GraphicType::Bitmap)
115  {
116  if (rGraphic.getVectorGraphicData().get())
117  {
118  const VectorGraphicDataPtr& rVectorGraphicDataPtr = rGraphic.getVectorGraphicData();
119  const basegfx::B2DRange& rRange = rVectorGraphicDataPtr->getRange();
120 
121  mnID1 |= rVectorGraphicDataPtr->getVectorGraphicDataArrayLength();
122  mnID2 = basegfx::fround(rRange.getWidth());
123  mnID3 = basegfx::fround(rRange.getHeight());
124  mnID4 = vcl_get_checksum(0, rVectorGraphicDataPtr->getVectorGraphicDataArray().getConstArray(), rVectorGraphicDataPtr->getVectorGraphicDataArrayLength());
125  }
126  else if (rGraphic.hasPdfData())
127  {
128  std::shared_ptr<std::vector<sal_Int8>> pPdfData = rGraphic.getPdfData();
129  const BitmapEx& rBmpEx = rGraphic.ImplGetBitmapExRef();
130 
131  mnID1 |= (rGraphic.mnPageNumber & 0x0fffffff);
132  mnID2 = rBmpEx.GetSizePixel().Width();
133  mnID3 = rBmpEx.GetSizePixel().Height();
134  mnID4 = vcl_get_checksum(0, pPdfData->data(), pPdfData->size());
135  }
136  else if (rGraphic.ImplIsAnimated())
137  {
138  const Animation aAnimation(rGraphic.ImplGetAnimation());
139 
140  mnID1 |= ( aAnimation.Count() & 0x0fffffff );
141  mnID2 = aAnimation.GetDisplaySizePixel().Width();
142  mnID3 = aAnimation.GetDisplaySizePixel().Height();
143  mnID4 = rGraphic.ImplGetChecksum();
144  }
145  else
146  {
147  const BitmapEx aBmpEx(rGraphic.ImplGetBitmapEx(GraphicConversionParameters()));
148 
149  mnID1 |= ( ( ( static_cast<sal_uLong>(aBmpEx.GetTransparentType()) << 8 ) | ( aBmpEx.IsAlpha() ? 1 : 0 ) ) & 0x0fffffff );
150  mnID2 = aBmpEx.GetSizePixel().Width();
151  mnID3 = aBmpEx.GetSizePixel().Height();
152  mnID4 = rGraphic.ImplGetChecksum();
153  }
154  }
155  else if (rGraphic.ImplGetType() == GraphicType::GdiMetafile)
156  {
157  const GDIMetaFile& rMtf = rGraphic.ImplGetGDIMetaFile();
158 
159  mnID1 |= ( rMtf.GetActionSize() & 0x0fffffff );
160  mnID2 = rMtf.GetPrefSize().Width();
161  mnID3 = rMtf.GetPrefSize().Height();
162  mnID4 = rGraphic.ImplGetChecksum();
163  }
164 }
165 
166 OString GraphicID::getIDString() const
167 {
168  static const char aHexData[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
169 
170  sal_Int32 nShift, nIndex = 0;
171  sal_Int32 nLen = 24 + (2 * BITMAP_CHECKSUM_SIZE);
172  OStringBuffer aHexStr(nLen);
173  aHexStr.setLength(nLen);
174 
175  for( nShift = 28; nShift >= 0; nShift -= 4 )
176  aHexStr[nIndex++] = aHexData[ ( mnID1 >> static_cast<sal_uInt32>(nShift) ) & 0xf ];
177 
178  for( nShift = 28; nShift >= 0; nShift -= 4 )
179  aHexStr[nIndex++] = aHexData[ ( mnID2 >> static_cast<sal_uInt32>(nShift) ) & 0xf ];
180 
181  for( nShift = 28; nShift >= 0; nShift -= 4 )
182  aHexStr[nIndex++] = aHexData[ ( mnID3 >> static_cast<sal_uInt32>(nShift) ) & 0xf ];
183 
184  for( nShift = ( 8 * BITMAP_CHECKSUM_SIZE ) - 4; nShift >= 0; nShift -= 4 )
185  aHexStr[nIndex++] = aHexData[ ( mnID4 >> static_cast<sal_uInt32>(nShift) ) & 0xf ];
186 
187  return aHexStr.makeStringAndClear();
188 }
189 
191  meType ( GraphicType::NONE ),
192  mnSizeBytes ( 0 ),
193  mbSwapOut ( false ),
194  mbDummyContext ( false ),
195  maLastUsed (std::chrono::high_resolution_clock::now()),
196  mbPrepared ( false ),
197  mnPageNumber(-1)
198 {
199 }
200 
202  : maMetaFile(rImpGraphic.maMetaFile)
203  , maEx(rImpGraphic.maEx)
204  , maSwapInfo(rImpGraphic.maSwapInfo)
205  , mpContext(rImpGraphic.mpContext)
206  , mpSwapFile(rImpGraphic.mpSwapFile)
207  , mpGfxLink(rImpGraphic.mpGfxLink)
208  , meType(rImpGraphic.meType)
209  , mnSizeBytes(rImpGraphic.mnSizeBytes)
210  , mbSwapOut(rImpGraphic.mbSwapOut)
211  , mbDummyContext(rImpGraphic.mbDummyContext)
212  , maVectorGraphicData(rImpGraphic.maVectorGraphicData)
213  , mpPdfData(rImpGraphic.mpPdfData)
214  , maGraphicExternalLink(rImpGraphic.maGraphicExternalLink)
215  , maLastUsed (std::chrono::high_resolution_clock::now())
216  , mbPrepared (rImpGraphic.mbPrepared)
217  , mnPageNumber(rImpGraphic.mnPageNumber)
218 {
219  if( rImpGraphic.mpAnimation )
220  {
221  mpAnimation = std::make_unique<Animation>( *rImpGraphic.mpAnimation );
222  maEx = mpAnimation->GetBitmapEx();
223  }
224 }
225 
226 ImpGraphic::ImpGraphic(ImpGraphic&& rImpGraphic) noexcept
227  : maMetaFile(std::move(rImpGraphic.maMetaFile))
228  , maEx(std::move(rImpGraphic.maEx))
229  , maSwapInfo(std::move(rImpGraphic.maSwapInfo))
230  , mpAnimation(std::move(rImpGraphic.mpAnimation))
231  , mpContext(std::move(rImpGraphic.mpContext))
232  , mpSwapFile(std::move(rImpGraphic.mpSwapFile))
233  , mpGfxLink(std::move(rImpGraphic.mpGfxLink))
234  , meType(rImpGraphic.meType)
235  , mnSizeBytes(rImpGraphic.mnSizeBytes)
236  , mbSwapOut(rImpGraphic.mbSwapOut)
237  , mbDummyContext(rImpGraphic.mbDummyContext)
238  , maVectorGraphicData(std::move(rImpGraphic.maVectorGraphicData))
239  , mpPdfData(std::move(rImpGraphic.mpPdfData))
240  , maGraphicExternalLink(rImpGraphic.maGraphicExternalLink)
241  , maLastUsed (std::chrono::high_resolution_clock::now())
242  , mbPrepared (rImpGraphic.mbPrepared)
243  , mnPageNumber(rImpGraphic.mnPageNumber)
244 {
245  rImpGraphic.ImplClear();
246  rImpGraphic.mbDummyContext = false;
247 }
248 
249 ImpGraphic::ImpGraphic(GraphicExternalLink const & rGraphicExternalLink) :
251  mnSizeBytes ( 0 ),
252  mbSwapOut ( false ),
253  mbDummyContext ( false ),
254  maGraphicExternalLink(rGraphicExternalLink),
255  maLastUsed (std::chrono::high_resolution_clock::now()),
256  mbPrepared (false),
257  mnPageNumber(-1)
258 {
259 }
260 
261 ImpGraphic::ImpGraphic( const Bitmap& rBitmap ) :
262  maEx ( rBitmap ),
263  meType ( !rBitmap.IsEmpty() ? GraphicType::Bitmap : GraphicType::NONE ),
264  mnSizeBytes ( 0 ),
265  mbSwapOut ( false ),
266  mbDummyContext ( false ),
267  maLastUsed (std::chrono::high_resolution_clock::now()),
268  mbPrepared (false),
269  mnPageNumber(-1)
270 {
271 }
272 
273 ImpGraphic::ImpGraphic( const BitmapEx& rBitmapEx ) :
274  maEx ( rBitmapEx ),
275  meType ( !rBitmapEx.IsEmpty() ? GraphicType::Bitmap : GraphicType::NONE ),
276  mnSizeBytes ( 0 ),
277  mbSwapOut ( false ),
278  mbDummyContext ( false ),
279  maLastUsed (std::chrono::high_resolution_clock::now()),
280  mbPrepared (false),
281  mnPageNumber(-1)
282 {
283 }
284 
285 ImpGraphic::ImpGraphic(const VectorGraphicDataPtr& rVectorGraphicDataPtr)
286 : meType( rVectorGraphicDataPtr.get() ? GraphicType::Bitmap : GraphicType::NONE ),
287  mnSizeBytes( 0 ),
288  mbSwapOut( false ),
289  mbDummyContext ( false ),
290  maVectorGraphicData(rVectorGraphicDataPtr),
291  maLastUsed (std::chrono::high_resolution_clock::now()),
292  mbPrepared (false),
293  mnPageNumber(-1)
294 {
295 }
296 
297 ImpGraphic::ImpGraphic( const Animation& rAnimation ) :
298  maEx ( rAnimation.GetBitmapEx() ),
299  mpAnimation ( std::make_unique<Animation>( rAnimation ) ),
301  mnSizeBytes ( 0 ),
302  mbSwapOut ( false ),
303  mbDummyContext ( false ),
304  maLastUsed (std::chrono::high_resolution_clock::now()),
305  mbPrepared (false),
306  mnPageNumber(-1)
307 {
308 }
309 
311  maMetaFile ( rMtf ),
313  mnSizeBytes ( 0 ),
314  mbSwapOut ( false ),
315  mbDummyContext ( false ),
316  maLastUsed (std::chrono::high_resolution_clock::now()),
317  mbPrepared (false),
318  mnPageNumber(-1)
319 {
320 }
321 
323 {
325 }
326 
328 {
329  if( &rImpGraphic != this )
330  {
331  sal_Int64 aOldSizeBytes = mnSizeBytes;
332 
333  maMetaFile = rImpGraphic.maMetaFile;
334  meType = rImpGraphic.meType;
335  mnSizeBytes = rImpGraphic.mnSizeBytes;
336 
337  maSwapInfo = rImpGraphic.maSwapInfo;
338  mpContext = rImpGraphic.mpContext;
339  mbDummyContext = rImpGraphic.mbDummyContext;
340  mnPageNumber = rImpGraphic.mnPageNumber;
342 
343  mpAnimation.reset();
344 
345  if ( rImpGraphic.mpAnimation )
346  {
347  mpAnimation = std::make_unique<Animation>( *rImpGraphic.mpAnimation );
348  maEx = mpAnimation->GetBitmapEx();
349  }
350  else
351  {
352  maEx = rImpGraphic.maEx;
353  }
354 
355  mbSwapOut = rImpGraphic.mbSwapOut;
356  mpSwapFile = rImpGraphic.mpSwapFile;
357  mbPrepared = rImpGraphic.mbPrepared;
358 
359  mpGfxLink = rImpGraphic.mpGfxLink;
360 
362  mpPdfData = rImpGraphic.mpPdfData;
363  maLastUsed = std::chrono::high_resolution_clock::now();
364 
365  vcl::graphic::Manager::get().changeExisting(this, aOldSizeBytes);
366  }
367 
368  return *this;
369 }
370 
372 {
373  sal_Int64 aOldSizeBytes = mnSizeBytes;
374 
375  maMetaFile = std::move(rImpGraphic.maMetaFile);
376  meType = rImpGraphic.meType;
377  mnSizeBytes = rImpGraphic.mnSizeBytes;
378  maSwapInfo = std::move(rImpGraphic.maSwapInfo);
379  mpContext = std::move(rImpGraphic.mpContext);
380  mbDummyContext = rImpGraphic.mbDummyContext;
381  mnPageNumber = rImpGraphic.mnPageNumber;
382  mpAnimation = std::move(rImpGraphic.mpAnimation);
383  maEx = std::move(rImpGraphic.maEx);
384  mbSwapOut = rImpGraphic.mbSwapOut;
385  mpSwapFile = std::move(rImpGraphic.mpSwapFile);
386  mpGfxLink = std::move(rImpGraphic.mpGfxLink);
387  maVectorGraphicData = std::move(rImpGraphic.maVectorGraphicData);
388  mpPdfData = std::move(rImpGraphic.mpPdfData);
389  maGraphicExternalLink = rImpGraphic.maGraphicExternalLink;
390  mbPrepared = rImpGraphic.mbPrepared;
391 
392  rImpGraphic.ImplClear();
393  rImpGraphic.mbDummyContext = false;
394  maLastUsed = std::chrono::high_resolution_clock::now();
395 
396  vcl::graphic::Manager::get().changeExisting(this, aOldSizeBytes);
397 
398  rImpGraphic.mnPageNumber = -1;
399 
400  return *this;
401 }
402 
403 bool ImpGraphic::operator==( const ImpGraphic& rImpGraphic ) const
404 {
405  bool bRet = false;
406 
407  if( this == &rImpGraphic )
408  bRet = true;
409  else if (mbPrepared && rImpGraphic.mbPrepared)
410  {
411  bRet = (*mpGfxLink == *rImpGraphic.mpGfxLink);
412  }
413  else if (isAvailable() && rImpGraphic.isAvailable())
414  {
415  switch( meType )
416  {
417  case GraphicType::NONE:
418  bRet = true;
419  break;
420 
422  {
423  if( rImpGraphic.maMetaFile == maMetaFile )
424  bRet = true;
425  }
426  break;
427 
428  case GraphicType::Bitmap:
429  {
430  if(maVectorGraphicData.get())
431  {
432  if(maVectorGraphicData == rImpGraphic.maVectorGraphicData)
433  {
434  // equal instances
435  bRet = true;
436  }
437  else if(rImpGraphic.maVectorGraphicData)
438  {
439  // equal content
440  bRet = (*maVectorGraphicData) == (*rImpGraphic.maVectorGraphicData);
441  }
442  }
443  else if (mpPdfData && !mpPdfData->empty())
444  {
445  bRet = (rImpGraphic.mpPdfData && *mpPdfData == *rImpGraphic.mpPdfData);
446  }
447  else if( mpAnimation )
448  {
449  if( rImpGraphic.mpAnimation && ( *rImpGraphic.mpAnimation == *mpAnimation ) )
450  bRet = true;
451  }
452  else if( !rImpGraphic.mpAnimation && ( rImpGraphic.maEx == maEx ) )
453  {
454  bRet = true;
455  }
456  }
457  break;
458 
459  default:
460  break;
461  }
462  }
463 
464  return bRet;
465 }
466 
468 {
469  ensureAvailable();
470 
471  return maVectorGraphicData;
472 }
473 
474 void ImpGraphic::setPdfData(const std::shared_ptr<std::vector<sal_Int8>>& rPdfData)
475 {
476  ensureAvailable();
477 
478  mpPdfData = rPdfData;
479 }
480 
481 const std::shared_ptr<std::vector<sal_Int8>> & ImpGraphic::getPdfData() const
482 {
483  ensureAvailable();
484 
485  return mpPdfData;
486 }
487 
489 {
490  if (!ImplIsSwapOut())
491  {
499  }
500 }
501 
503 {
504  maEx.Clear();
505  maMetaFile.Clear();
506  mpAnimation.reset();
507  mpGfxLink.reset();
508  maVectorGraphicData.reset();
509  mpPdfData.reset();
510 }
511 
513 {
514  try
515  {
517  css::uno::Reference< css::ucb::XCommandEnvironment >(),
519 
520  aCnt.executeCommand( "delete", css::uno::makeAny( true ) );
521  }
522  catch( const css::ucb::ContentCreationException& )
523  {
524  }
525  catch( const css::uno::RuntimeException& )
526  {
527  }
528  catch( const css::ucb::CommandAbortedException& )
529  {
530  }
531  catch( const css::uno::Exception& )
532  {
533  }
534 }
535 
536 void ImpGraphic::ImplSetPrepared(bool bAnimated, const Size* pSizeHint)
537 {
538  mbPrepared = true;
539  mbSwapOut = true;
541 
542  SvMemoryStream aMemoryStream(const_cast<sal_uInt8*>(mpGfxLink->GetData()), mpGfxLink->GetDataSize(), StreamMode::READ | StreamMode::WRITE);
543 
544  if (pSizeHint)
545  {
546  maSwapInfo.maPrefSize = *pSizeHint;
547  maSwapInfo.maPrefMapMode = MapMode(MapUnit::Map100thMM);
548  }
549 
550  GraphicDescriptor aDescriptor(aMemoryStream, nullptr);
551  if (aDescriptor.Detect(true))
552  {
553  if (!pSizeHint)
554  {
555  // If we have logic size, work with that, as later pixel -> logic
556  // conversion will work with the output device DPI, not the graphic
557  // DPI.
558  Size aLogSize = aDescriptor.GetSize_100TH_MM();
559  if (aLogSize.getWidth() && aLogSize.getHeight())
560  {
561  maSwapInfo.maPrefSize = aLogSize;
562  maSwapInfo.maPrefMapMode = MapMode(MapUnit::Map100thMM);
563  }
564  else
565  {
566  maSwapInfo.maPrefSize = aDescriptor.GetSizePixel();
567  maSwapInfo.maPrefMapMode = MapMode(MapUnit::MapPixel);
568  }
569  }
570 
571  maSwapInfo.maSizePixel = aDescriptor.GetSizePixel();
572  maSwapInfo.mbIsTransparent = aDescriptor.IsTransparent();
573  maSwapInfo.mbIsAlpha = aDescriptor.IsAlpha();
574  } else {
575  maSwapInfo.mbIsTransparent = false;
576  maSwapInfo.mbIsAlpha = false;
577  }
578 
580  maSwapInfo.mbIsEPS = false;
581  maSwapInfo.mbIsAnimated = bAnimated;
582 }
583 
585 {
586  mpSwapFile.reset();
587  mbSwapOut = false;
588  mbPrepared = false;
589 
590  // cleanup
593  sal_Int64 nOldSize = mnSizeBytes;
594  mnSizeBytes = 0;
595  vcl::graphic::Manager::get().changeExisting(this, nOldSize);
597 }
598 
600 {
601  ImplClear();
603 }
604 
606 {
607  return( meType != GraphicType::NONE );
608 }
609 
611 {
612  bool bRet(true);
613 
614  if (mbSwapOut)
615  {
617  }
618  else if (meType == GraphicType::Bitmap && !maVectorGraphicData.get())
619  {
620  bRet = mpAnimation ? mpAnimation->IsTransparent() : maEx.IsTransparent();
621  }
622 
623  return bRet;
624 }
625 
627 {
628  bool bRet(false);
629 
630  if (mbSwapOut)
631  {
632  bRet = maSwapInfo.mbIsAlpha;
633  }
634  else if (maVectorGraphicData.get())
635  {
636  bRet = true;
637  }
638  else if (meType == GraphicType::Bitmap)
639  {
640  bRet = (nullptr == mpAnimation && maEx.IsAlpha());
641  }
642 
643  return bRet;
644 }
645 
647 {
648  return mbSwapOut ? maSwapInfo.mbIsAnimated : mpAnimation != nullptr;
649 }
650 
652 {
653  if (mbSwapOut)
654  return maSwapInfo.mbIsEPS;
655 
656  return( ( meType == GraphicType::GdiMetafile ) &&
657  ( maMetaFile.GetActionSize() > 0 ) &&
659 }
660 
662 {
663  return !mbPrepared && !mbSwapOut;
664 }
665 
667 {
668  return ensureAvailable();
669 }
670 
672 {
673  Bitmap aRetBmp;
674 
675  ensureAvailable();
676 
677  if( meType == GraphicType::Bitmap )
678  {
679  if(maVectorGraphicData.get() && maEx.IsEmpty())
680  {
681  // use maEx as local buffer for rendered svg
682  const_cast< ImpGraphic* >(this)->maEx = maVectorGraphicData->getReplacement();
683  }
684 
685  const BitmapEx& rRetBmpEx = ( mpAnimation ? mpAnimation->GetBitmapEx() : maEx );
686 
687  aRetBmp = rRetBmpEx.GetBitmap( COL_WHITE );
688 
689  if(rParameters.getSizePixel().Width() || rParameters.getSizePixel().Height())
690  aRetBmp.Scale(rParameters.getSizePixel());
691  }
692  else if( ( meType != GraphicType::Default ) && ImplIsSupportedGraphic() )
693  {
694  if(maEx.IsEmpty())
695  {
696  // calculate size
698  Size aDrawSize(aVDev->LogicToPixel(maMetaFile.GetPrefSize(), maMetaFile.GetPrefMapMode()));
699 
700  if(rParameters.getSizePixel().Width() && rParameters.getSizePixel().Height())
701  {
702  // apply given size if exists
703  aDrawSize = rParameters.getSizePixel();
704  }
705 
706  if(aDrawSize.Width() && aDrawSize.Height() && !rParameters.getUnlimitedSize()
707  && (aDrawSize.Width() > GRAPHIC_MTFTOBMP_MAXEXT || aDrawSize.Height() > GRAPHIC_MTFTOBMP_MAXEXT))
708  {
709  // limit bitmap size to a maximum of GRAPHIC_MTFTOBMP_MAXEXT x GRAPHIC_MTFTOBMP_MAXEXT
710  double fWH(static_cast<double>(aDrawSize.Width()) / static_cast<double>(aDrawSize.Height()));
711 
712  if(fWH <= 1.0)
713  {
716  }
717  else
718  {
721  }
722  }
723 
724  // calculate pixel size. Normally, it's the same as aDrawSize, but may
725  // need to be extended when hairlines are on the right or bottom edge
726  Size aPixelSize(aDrawSize);
727 
729  {
730  // get hairline and full bound rect
731  tools::Rectangle aHairlineRect;
732  const tools::Rectangle aRect(maMetaFile.GetBoundRect(*aVDev, &aHairlineRect));
733 
734  if(!aRect.IsEmpty() && !aHairlineRect.IsEmpty())
735  {
736  // expand if needed to allow bottom and right hairlines to be added
737  if(aRect.Right() == aHairlineRect.Right())
738  {
739  aPixelSize.setWidth(aPixelSize.getWidth() + 1);
740  }
741 
742  if(aRect.Bottom() == aHairlineRect.Bottom())
743  {
744  aPixelSize.setHeight(aPixelSize.getHeight() + 1);
745  }
746  }
747  }
748 
749  if(aVDev->SetOutputSizePixel(aPixelSize))
750  {
751  if(rParameters.getAntiAliase())
752  {
753  aVDev->SetAntialiasing(aVDev->GetAntialiasing() | AntialiasingFlags::EnableB2dDraw);
754  }
755 
756  if(rParameters.getSnapHorVerLines())
757  {
758  aVDev->SetAntialiasing(aVDev->GetAntialiasing() | AntialiasingFlags::PixelSnapHairline);
759  }
760 
761  ImplDraw( aVDev.get(), Point(), aDrawSize );
762 
763  // use maEx as local buffer for rendered metafile
764  const_cast< ImpGraphic* >(this)->maEx = aVDev->GetBitmapEx( Point(), aVDev->GetOutputSizePixel() );
765  }
766  }
767 
768  aRetBmp = maEx.GetBitmap();
769  }
770 
771  if( !!aRetBmp )
772  {
773  aRetBmp.SetPrefMapMode( ImplGetPrefMapMode() );
774  aRetBmp.SetPrefSize( ImplGetPrefSize() );
775  }
776 
777  return aRetBmp;
778 }
779 
781 {
782  BitmapEx aRetBmpEx;
783 
784  ensureAvailable();
785 
786  if( meType == GraphicType::Bitmap )
787  {
788  if(maVectorGraphicData.get() && maEx.IsEmpty())
789  {
790  // use maEx as local buffer for rendered svg
791  const_cast< ImpGraphic* >(this)->maEx = maVectorGraphicData->getReplacement();
792  }
793 
794  aRetBmpEx = ( mpAnimation ? mpAnimation->GetBitmapEx() : maEx );
795 
796  if(rParameters.getSizePixel().Width() || rParameters.getSizePixel().Height())
797  {
798  aRetBmpEx.Scale(
799  rParameters.getSizePixel(),
801  }
802  }
803  else if( ( meType != GraphicType::Default ) && ImplIsSupportedGraphic() )
804  {
805  if(maEx.IsEmpty())
806  {
807  const ImpGraphic aMonoMask( maMetaFile.GetMonochromeMtf( COL_BLACK ) );
808 
809  // use maEx as local buffer for rendered metafile
810  const_cast< ImpGraphic* >(this)->maEx = BitmapEx(ImplGetBitmap(rParameters), aMonoMask.ImplGetBitmap(rParameters));
811  }
812 
813  aRetBmpEx = maEx;
814  }
815 
816  return aRetBmpEx;
817 }
818 
820 {
821  Animation aAnimation;
822 
823  ensureAvailable();
824  if( mpAnimation )
825  aAnimation = *mpAnimation;
826 
827  return aAnimation;
828 }
829 
831 {
832  ensureAvailable();
833  return maEx;
834 }
835 
837 {
838  ensureAvailable();
840  && maVectorGraphicData.get()
841  && (VectorGraphicDataType::Emf == maVectorGraphicData->getVectorGraphicDataType()
842  || VectorGraphicDataType::Wmf == maVectorGraphicData->getVectorGraphicDataType()))
843  {
844  // If we have a Emf/Wmf VectorGraphic object, we
845  // need a way to get the Metafile data out of the primitive
846  // representation. Use a strict virtual hook (MetafileAccessor)
847  // to access the MetafilePrimitive2D directly. Also see comments in
848  // XEmfParser about this.
849  const std::deque< css::uno::Reference< css::graphic::XPrimitive2D > > aSequence(maVectorGraphicData->getPrimitive2DSequence());
850 
851  if (1 == aSequence.size())
852  {
853  // try to cast to MetafileAccessor implementation
854  const css::uno::Reference< css::graphic::XPrimitive2D > xReference(aSequence[0]);
855  const MetafileAccessor* pMetafileAccessor = dynamic_cast< const MetafileAccessor* >(xReference.get());
856 
857  if (pMetafileAccessor)
858  {
859  // it is a MetafileAccessor implementation, get Metafile
860  pMetafileAccessor->accessMetafile(const_cast< ImpGraphic* >(this)->maMetaFile);
861  }
862  }
863  }
864 
866  {
867  // #i119735#
868  // Use the local maMetaFile as container for a metafile-representation
869  // of the bitmap graphic. This will be done only once, thus be buffered.
870  // I checked all usages of maMetaFile, it is only used when type is not
871  // GraphicType::Bitmap. In operator= it will get copied, thus buffering will
872  // survive copying (change this if not wanted)
873  ImpGraphic* pThat = const_cast< ImpGraphic* >(this);
874 
875  if(maVectorGraphicData.get() && !maEx)
876  {
877  // use maEx as local buffer for rendered svg
878  pThat->maEx = maVectorGraphicData->getReplacement();
879  }
880 
881  // #123983# directly create a metafile with the same PrefSize and PrefMapMode
882  // the bitmap has, this will be an always correct metafile
883  if(maEx.IsTransparent())
884  {
886  }
887  else
888  {
890  }
891 
892  pThat->maMetaFile.Stop();
893  pThat->maMetaFile.WindStart();
896  }
897 
898  return maMetaFile;
899 }
900 
902 {
903  Size aSize;
904 
905  if (ImplIsSwapOut())
906  aSize = maSwapInfo.maSizePixel;
907  else
909 
910  return aSize;
911 }
912 
914 {
915  Size aSize;
916 
917  if (ImplIsSwapOut())
918  {
919  aSize = maSwapInfo.maPrefSize;
920  }
921  else
922  {
923  switch( meType )
924  {
925  case GraphicType::NONE:
927  break;
928 
929  case GraphicType::Bitmap:
930  {
931  if(maVectorGraphicData.get() && maEx.IsEmpty())
932  {
933  // svg not yet buffered in maEx, return size derived from range
934  const basegfx::B2DRange& rRange = maVectorGraphicData->getRange();
935 
936  aSize = Size(basegfx::fround(rRange.getWidth()), basegfx::fround(rRange.getHeight()));
937  }
938  else
939  {
940  aSize = maEx.GetPrefSize();
941 
942  if( !aSize.Width() || !aSize.Height() )
943  {
944  aSize = maEx.GetSizePixel();
945  }
946  }
947  }
948  break;
949 
950  default:
951  {
952  if( ImplIsSupportedGraphic() )
953  aSize = maMetaFile.GetPrefSize();
954  }
955  break;
956  }
957  }
958 
959  return aSize;
960 }
961 
962 void ImpGraphic::ImplSetPrefSize( const Size& rPrefSize )
963 {
964  ensureAvailable();
965 
966  switch( meType )
967  {
968  case GraphicType::NONE:
970  break;
971 
972  case GraphicType::Bitmap:
973  {
974  // used when importing a writer FlyFrame with SVG as graphic, added conversion
975  // to allow setting the PrefSize at the BitmapEx to hold it
976  if(maVectorGraphicData.get() && maEx.IsEmpty())
977  {
978  // use maEx as local buffer for rendered svg
979  maEx = maVectorGraphicData->getReplacement();
980  }
981 
982  // #108077# Push through pref size to animation object,
983  // will be lost on copy otherwise
984  if( ImplIsAnimated() )
985  {
986  const_cast< BitmapEx& >(mpAnimation->GetBitmapEx()).SetPrefSize( rPrefSize );
987  }
988 
989  maEx.SetPrefSize( rPrefSize );
990  }
991  break;
992 
993  default:
994  {
995  if( ImplIsSupportedGraphic() )
996  maMetaFile.SetPrefSize( rPrefSize );
997  }
998  break;
999  }
1000 }
1001 
1003 {
1004  MapMode aMapMode;
1005 
1006  if (ImplIsSwapOut())
1007  {
1008  aMapMode = maSwapInfo.maPrefMapMode;
1009  }
1010  else
1011  {
1012  switch( meType )
1013  {
1014  case GraphicType::NONE:
1015  case GraphicType::Default:
1016  break;
1017 
1018  case GraphicType::Bitmap:
1019  {
1020  if(maVectorGraphicData.get() && maEx.IsEmpty())
1021  {
1022  // svg not yet buffered in maEx, return default PrefMapMode
1023  aMapMode = MapMode(MapUnit::Map100thMM);
1024  }
1025  else
1026  {
1027  const Size aSize( maEx.GetPrefSize() );
1028 
1029  if ( aSize.Width() && aSize.Height() )
1030  aMapMode = maEx.GetPrefMapMode();
1031  }
1032  }
1033  break;
1034 
1035  default:
1036  {
1037  if( ImplIsSupportedGraphic() )
1038  return maMetaFile.GetPrefMapMode();
1039  }
1040  break;
1041  }
1042  }
1043 
1044  return aMapMode;
1045 }
1046 
1047 void ImpGraphic::ImplSetPrefMapMode( const MapMode& rPrefMapMode )
1048 {
1049  ensureAvailable();
1050 
1051  switch( meType )
1052  {
1053  case GraphicType::NONE:
1054  case GraphicType::Default:
1055  break;
1056 
1057  case GraphicType::Bitmap:
1058  {
1059  if(maVectorGraphicData.get())
1060  {
1061  // ignore for Vector Graphic Data. If this is really used (except the grfcache)
1062  // it can be extended by using maEx as buffer for maVectorGraphicData->getReplacement()
1063  }
1064  else
1065  {
1066  // #108077# Push through pref mapmode to animation object,
1067  // will be lost on copy otherwise
1068  if( ImplIsAnimated() )
1069  {
1070  const_cast< BitmapEx& >(mpAnimation->GetBitmapEx()).SetPrefMapMode( rPrefMapMode );
1071  }
1072 
1073  maEx.SetPrefMapMode( rPrefMapMode );
1074  }
1075  }
1076  break;
1077 
1078  default:
1079  {
1080  if( ImplIsSupportedGraphic() )
1081  maMetaFile.SetPrefMapMode( rPrefMapMode );
1082  }
1083  break;
1084  }
1085 }
1086 
1088 {
1089  if( 0 == mnSizeBytes )
1090  {
1091  if (mbPrepared)
1092  ensureAvailable();
1093 
1094  if( meType == GraphicType::Bitmap )
1095  {
1096  if(maVectorGraphicData.get())
1097  {
1098  std::pair<VectorGraphicData::State, size_t> tmp(maVectorGraphicData->getSizeBytes());
1099  if (VectorGraphicData::State::UNPARSED == tmp.first)
1100  {
1101  return tmp.second; // don't cache it until Vector Graphic Data is parsed
1102  }
1103  mnSizeBytes = tmp.second;
1104  }
1105  else
1106  {
1107  mnSizeBytes = mpAnimation ? mpAnimation->GetSizeBytes() : maEx.GetSizeBytes();
1108  }
1109  }
1110  else if( meType == GraphicType::GdiMetafile )
1111  {
1113  }
1114  }
1115 
1116  return mnSizeBytes;
1117 }
1118 
1119 void ImpGraphic::ImplDraw( OutputDevice* pOutDev, const Point& rDestPt ) const
1120 {
1121  ensureAvailable();
1123  {
1124  switch( meType )
1125  {
1126  case GraphicType::Default:
1127  break;
1128 
1129  case GraphicType::Bitmap:
1130  {
1131  if(maVectorGraphicData.get() && !maEx)
1132  {
1133  // use maEx as local buffer for rendered svg
1134  const_cast< ImpGraphic* >(this)->maEx = maVectorGraphicData->getReplacement();
1135  }
1136 
1137  if ( mpAnimation )
1138  {
1139  mpAnimation->Draw( pOutDev, rDestPt );
1140  }
1141  else
1142  {
1143  maEx.Draw( pOutDev, rDestPt );
1144  }
1145  }
1146  break;
1147 
1148  default:
1149  ImplDraw( pOutDev, rDestPt, maMetaFile.GetPrefSize() );
1150  break;
1151  }
1152  }
1153 }
1154 
1156  const Point& rDestPt, const Size& rDestSize ) const
1157 {
1158  ensureAvailable();
1160  {
1161  switch( meType )
1162  {
1163  case GraphicType::Default:
1164  break;
1165 
1166  case GraphicType::Bitmap:
1167  {
1168  if(maVectorGraphicData.get() && maEx.IsEmpty())
1169  {
1170  // use maEx as local buffer for rendered svg
1171  const_cast< ImpGraphic* >(this)->maEx = maVectorGraphicData->getReplacement();
1172  }
1173 
1174  if( mpAnimation )
1175  {
1176  mpAnimation->Draw( pOutDev, rDestPt, rDestSize );
1177  }
1178  else
1179  {
1180  maEx.Draw( pOutDev, rDestPt, rDestSize );
1181  }
1182  }
1183  break;
1184 
1185  default:
1186  {
1187  const_cast<ImpGraphic*>(this)->maMetaFile.WindStart();
1188  const_cast<ImpGraphic*>(this)->maMetaFile.Play( pOutDev, rDestPt, rDestSize );
1189  const_cast<ImpGraphic*>(this)->maMetaFile.WindStart();
1190  }
1191  break;
1192  }
1193  }
1194 }
1195 
1196 void ImpGraphic::ImplStartAnimation( OutputDevice* pOutDev, const Point& rDestPt,
1197  const Size& rDestSize, long nExtraData,
1198  OutputDevice* pFirstFrameOutDev )
1199 {
1200  ensureAvailable();
1201 
1203  mpAnimation->Start( pOutDev, rDestPt, rDestSize, nExtraData, pFirstFrameOutDev );
1204 }
1205 
1206 void ImpGraphic::ImplStopAnimation( OutputDevice* pOutDev, long nExtraData )
1207 {
1208  ensureAvailable();
1209 
1211  mpAnimation->Stop( pOutDev, nExtraData );
1212 }
1213 
1215 {
1216  ensureAvailable();
1217 
1218  if( mpAnimation )
1219  mpAnimation->SetNotifyHdl( rLink );
1220 }
1221 
1223 {
1224  Link<Animation*,void> aLink;
1225 
1226  ensureAvailable();
1227 
1228  if( mpAnimation )
1229  aLink = mpAnimation->GetNotifyHdl();
1230 
1231  return aLink;
1232 }
1233 
1235 {
1236  if (mbSwapOut)
1238 
1239  return mpAnimation ? mpAnimation->GetLoopCount() : 0;
1240 }
1241 
1242 void ImpGraphic::ImplSetContext( const std::shared_ptr<GraphicReader>& pReader )
1243 {
1244  mpContext = pReader;
1245  mbDummyContext = false;
1246 }
1247 
1249 {
1250  ensureAvailable();
1251 
1252  MapMode aMapMode;
1253  Size aSize;
1254  sal_uInt32 nId;
1255  sal_Int32 nType;
1256  const SvStreamEndian nOldFormat = rIStm.GetEndian();
1257  bool bRet = false;
1258 
1259  rIStm.SetEndian( SvStreamEndian::LITTLE );
1260  rIStm.ReadUInt32( nId );
1261 
1262  // check version
1263  if( GRAPHIC_FORMAT_50 == nId )
1264  {
1265  // read new style header
1266  std::unique_ptr<VersionCompat> pCompat( new VersionCompat( rIStm, StreamMode::READ ) );
1267 
1268  rIStm.ReadInt32( nType );
1269  sal_Int32 nLen;
1270  rIStm.ReadInt32( nLen );
1271  TypeSerializer aSerializer(rIStm);
1272  aSerializer.readSize(aSize);
1273  ReadMapMode( rIStm, aMapMode );
1274  }
1275  else
1276  {
1277  // read old style header
1278  sal_Int32 nWidth, nHeight;
1279  sal_Int32 nMapMode, nScaleNumX, nScaleDenomX;
1280  sal_Int32 nScaleNumY, nScaleDenomY, nOffsX, nOffsY;
1281 
1282  rIStm.SeekRel( -4 );
1283 
1284  sal_Int32 nLen;
1285  rIStm.ReadInt32( nType ).ReadInt32( nLen ).ReadInt32( nWidth ).ReadInt32( nHeight );
1286  rIStm.ReadInt32( nMapMode ).ReadInt32( nScaleNumX ).ReadInt32( nScaleDenomX ).ReadInt32( nScaleNumY );
1287  rIStm.ReadInt32( nScaleDenomY ).ReadInt32( nOffsX ).ReadInt32( nOffsY );
1288 
1289  // swapped
1290  if( nType > 100 )
1291  {
1292  nType = OSL_SWAPDWORD( nType );
1293  nWidth = OSL_SWAPDWORD( nWidth );
1294  nHeight = OSL_SWAPDWORD( nHeight );
1295  nMapMode = OSL_SWAPDWORD( nMapMode );
1296  nScaleNumX = OSL_SWAPDWORD( nScaleNumX );
1297  nScaleDenomX = OSL_SWAPDWORD( nScaleDenomX );
1298  nScaleNumY = OSL_SWAPDWORD( nScaleNumY );
1299  nScaleDenomY = OSL_SWAPDWORD( nScaleDenomY );
1300  nOffsX = OSL_SWAPDWORD( nOffsX );
1301  nOffsY = OSL_SWAPDWORD( nOffsY );
1302  }
1303 
1304  aSize = Size( nWidth, nHeight );
1305  aMapMode = MapMode( static_cast<MapUnit>(nMapMode), Point( nOffsX, nOffsY ),
1306  Fraction( nScaleNumX, nScaleDenomX ),
1307  Fraction( nScaleNumY, nScaleDenomY ) );
1308  }
1309 
1310  meType = static_cast<GraphicType>(nType);
1311 
1312  if( meType != GraphicType::NONE )
1313  {
1314  if( meType == GraphicType::Bitmap )
1315  {
1316  if(maVectorGraphicData.get() && maEx.IsEmpty())
1317  {
1318  // use maEx as local buffer for rendered svg
1319  maEx = maVectorGraphicData->getReplacement();
1320  }
1321 
1322  maEx.SetSizePixel(aSize);
1323 
1324  if( aMapMode != MapMode() )
1325  {
1326  maEx.SetPrefMapMode( aMapMode );
1327  maEx.SetPrefSize( aSize );
1328  }
1329  }
1330  else
1331  {
1332  maMetaFile.SetPrefMapMode( aMapMode );
1333  maMetaFile.SetPrefSize( aSize );
1334  }
1335 
1337  {
1338  ReadImpGraphic( rIStm, *this );
1339  bRet = rIStm.GetError() == ERRCODE_NONE;
1340  }
1341  else if( sal::static_int_cast<sal_uLong>(meType) >= SYS_WINMETAFILE
1342  && sal::static_int_cast<sal_uLong>(meType) <= SYS_MACMETAFILE )
1343  {
1344  Graphic aSysGraphic;
1345  ConvertDataFormat nCvtType;
1346 
1347  switch( sal::static_int_cast<sal_uLong>(meType) )
1348  {
1349  case SYS_WINMETAFILE:
1350  case SYS_WNTMETAFILE: nCvtType = ConvertDataFormat::WMF; break;
1351  case SYS_OS2METAFILE: nCvtType = ConvertDataFormat::MET; break;
1352  case SYS_MACMETAFILE: nCvtType = ConvertDataFormat::PCT; break;
1353 
1354  default:
1355  nCvtType = ConvertDataFormat::Unknown;
1356  break;
1357  }
1358 
1359  if( nType && GraphicConverter::Import( rIStm, aSysGraphic, nCvtType ) == ERRCODE_NONE )
1360  {
1361  *this = ImpGraphic( aSysGraphic.GetGDIMetaFile() );
1362  bRet = rIStm.GetError() == ERRCODE_NONE;
1363  }
1364  else
1366  }
1367 
1368  if( bRet )
1369  {
1370  ImplSetPrefMapMode( aMapMode );
1371  ImplSetPrefSize( aSize );
1372  }
1373  }
1374  else
1375  bRet = true;
1376 
1377  rIStm.SetEndian( nOldFormat );
1378 
1379  return bRet;
1380 }
1381 
1383 {
1384  bool bRet = false;
1385 
1386  ensureAvailable();
1387 
1389  {
1390  const MapMode aMapMode( ImplGetPrefMapMode() );
1391  const Size aSize( ImplGetPrefSize() );
1392  const SvStreamEndian nOldFormat = rOStm.GetEndian();
1393  sal_uLong nDataFieldPos;
1394 
1395  rOStm.SetEndian( SvStreamEndian::LITTLE );
1396 
1397  // write correct version ( old style/new style header )
1398  if( rOStm.GetVersion() >= SOFFICE_FILEFORMAT_50 )
1399  {
1400  // write ID for new format (5.0)
1401  rOStm.WriteUInt32( GRAPHIC_FORMAT_50 );
1402 
1403  // write new style header
1404  std::unique_ptr<VersionCompat> pCompat( new VersionCompat( rOStm, StreamMode::WRITE, 1 ) );
1405 
1406  rOStm.WriteInt32( static_cast<sal_Int32>(meType) );
1407 
1408  // data size is updated later
1409  nDataFieldPos = rOStm.Tell();
1410  rOStm.WriteInt32( 0 );
1411 
1412  TypeSerializer aSerializer(rOStm);
1413  aSerializer.writeSize(aSize);
1414 
1415  WriteMapMode( rOStm, aMapMode );
1416  }
1417  else
1418  {
1419  // write old style (<=4.0) header
1420  rOStm.WriteInt32( static_cast<sal_Int32>(meType) );
1421 
1422  // data size is updated later
1423  nDataFieldPos = rOStm.Tell();
1424  rOStm.WriteInt32( 0 );
1425  rOStm.WriteInt32( aSize.Width() );
1426  rOStm.WriteInt32( aSize.Height() );
1427  rOStm.WriteInt32( static_cast<sal_uInt16>(aMapMode.GetMapUnit()) );
1428  rOStm.WriteInt32( aMapMode.GetScaleX().GetNumerator() );
1429  rOStm.WriteInt32( aMapMode.GetScaleX().GetDenominator() );
1430  rOStm.WriteInt32( aMapMode.GetScaleY().GetNumerator() );
1431  rOStm.WriteInt32( aMapMode.GetScaleY().GetDenominator() );
1432  rOStm.WriteInt32( aMapMode.GetOrigin().X() );
1433  rOStm.WriteInt32( aMapMode.GetOrigin().Y() );
1434  }
1435 
1436  // write data block
1437  if( !rOStm.GetError() )
1438  {
1439  const sal_uLong nDataStart = rOStm.Tell();
1440 
1441  if( ImplIsSupportedGraphic() )
1442  WriteImpGraphic( rOStm, *this );
1443 
1444  if( !rOStm.GetError() )
1445  {
1446  const sal_uLong nStmPos2 = rOStm.Tell();
1447  rOStm.Seek( nDataFieldPos );
1448  rOStm.WriteInt32( nStmPos2 - nDataStart );
1449  rOStm.Seek( nStmPos2 );
1450  bRet = true;
1451  }
1452  }
1453 
1454  rOStm.SetEndian( nOldFormat );
1455  }
1456 
1457  return bRet;
1458 }
1459 
1461 {
1462  bool bRet = false;
1463 
1464  if( !ImplIsSwapOut() )
1465  {
1466  ::utl::TempFile aTempFile;
1467  const INetURLObject aTmpURL( aTempFile.GetURL() );
1468 
1469  if( !aTmpURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ).isEmpty() )
1470  {
1471  std::unique_ptr<SvStream> xOStm;
1472  try
1473  {
1474  xOStm = ::utl::UcbStreamHelper::CreateStream( aTmpURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ), StreamMode::READWRITE | StreamMode::SHARE_DENYWRITE );
1475  }
1476  catch( const css::uno::Exception& )
1477  {
1478  }
1479  if( xOStm )
1480  {
1481  xOStm->SetVersion( SOFFICE_FILEFORMAT_50 );
1482  xOStm->SetCompressMode( SvStreamCompressFlags::NATIVE );
1483 
1484  bRet = ImplSwapOut( xOStm.get() );
1485  if( bRet )
1486  {
1487  mpSwapFile = std::make_unique<ImpSwapFile>();
1488  mpSwapFile->aSwapURL = aTmpURL;
1489  mpSwapFile->maOriginURL = getOriginURL();
1490  }
1491  else
1492  {
1493  xOStm.reset();
1494 
1495  try
1496  {
1497  ::ucbhelper::Content aCnt( aTmpURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ),
1498  css::uno::Reference< css::ucb::XCommandEnvironment >(),
1500 
1501  aCnt.executeCommand( "delete", css::uno::makeAny( true ) );
1502  }
1503  catch( const css::ucb::ContentCreationException& )
1504  {
1505  }
1506  catch( const css::uno::RuntimeException& )
1507  {
1508  }
1509  catch( const css::ucb::CommandAbortedException& )
1510  {
1511  }
1512  catch( const css::uno::Exception& )
1513  {
1514  }
1515  }
1516  }
1517  }
1518  }
1519 
1520  if (bRet)
1522  return bRet;
1523 }
1524 
1526 {
1527  bool bRet = false;
1528 
1529  if( xOStm )
1530  {
1532 
1533  if( !xOStm->GetError() && ImplWriteEmbedded( *xOStm ) )
1534  {
1535  xOStm->Flush();
1536 
1537  if( !xOStm->GetError() )
1538  {
1541  bRet = mbSwapOut = true;
1542  }
1543  }
1544  }
1545  else
1546  {
1547  SAL_WARN("vcl.gdi", "Graphic SwapOut: No stream for swap out!");
1548  }
1549 
1550  return bRet;
1551 }
1552 
1554 {
1555  auto pThis = const_cast<ImpGraphic*>(this);
1556 
1557  if (ImplIsSwapOut())
1558  return pThis->ImplSwapIn();
1559 
1560  pThis->maLastUsed = std::chrono::high_resolution_clock::now();
1561  return true;
1562 }
1563 
1565 {
1566  Graphic aGraphic;
1567  if (mpGfxLink->LoadNative(aGraphic))
1568  {
1570 
1571  Size aPrefSize = maSwapInfo.maPrefSize;
1572  MapMode aPrefMapMode = maSwapInfo.maPrefMapMode;
1573  *this = *aGraphic.ImplGetImpGraphic();
1574  if (aPrefSize.getWidth() && aPrefSize.getHeight() && aPrefMapMode == ImplGetPrefMapMode())
1575  {
1576  // Use custom preferred size if it was set when the graphic was still unloaded.
1577  // Only set the size in case the unloaded and loaded unit matches.
1578  ImplSetPrefSize(aPrefSize);
1579  }
1580 
1581  maGraphicExternalLink = aLink;
1582 
1583  return true;
1584  }
1585  return false;
1586 }
1587 
1589 {
1590  bool bRet = false;
1591 
1592  if (!ImplIsSwapOut())
1593  return bRet;
1594 
1595  if (mbPrepared)
1596  {
1597  bRet = loadPrepared();
1598  }
1599  else
1600  {
1601  OUString aSwapURL;
1602 
1603  if( mpSwapFile )
1604  aSwapURL = mpSwapFile->aSwapURL.GetMainURL( INetURLObject::DecodeMechanism::NONE );
1605 
1606  if( !aSwapURL.isEmpty() )
1607  {
1608  std::unique_ptr<SvStream> xIStm;
1609  try
1610  {
1611  xIStm = ::utl::UcbStreamHelper::CreateStream( aSwapURL, StreamMode::READWRITE | StreamMode::SHARE_DENYWRITE );
1612  }
1613  catch( const css::uno::Exception& )
1614  {
1615  }
1616 
1617  if( xIStm )
1618  {
1619  xIStm->SetVersion( SOFFICE_FILEFORMAT_50 );
1620  xIStm->SetCompressMode( SvStreamCompressFlags::NATIVE );
1621 
1622  bRet = ImplSwapIn( xIStm.get() );
1623  xIStm.reset();
1624  if (mpSwapFile)
1625  setOriginURL(mpSwapFile->maOriginURL);
1626  mpSwapFile.reset();
1627  }
1628  }
1629  }
1630 
1631  if (bRet)
1633 
1634  return bRet;
1635 }
1636 
1638 {
1639  bool bRet = false;
1640 
1641  if( xIStm )
1642  {
1644 
1645  if( !xIStm->GetError() )
1646  {
1647  //keep the swap file alive, because its quite possibly the backing storage
1648  //for xIStm
1649  std::shared_ptr<ImpSwapFile> xSwapFile(std::move(mpSwapFile));
1650  assert(!mpSwapFile);
1651 
1652  std::shared_ptr<GraphicReader> xContext(std::move(mpContext));
1653  assert(!mpContext);
1654 
1655  bool bDummyContext = mbDummyContext;
1656  mbDummyContext = false;
1657 
1658  bRet = ImplReadEmbedded( *xIStm );
1659 
1660  //restore ownership of the swap file and context
1661  mpSwapFile = std::move(xSwapFile);
1662  mpContext = std::move(xContext);
1663  mbDummyContext = bDummyContext;
1664 
1665  if (!bRet)
1666  {
1667  //throw away swapfile, etc.
1668  ImplClear();
1669  }
1670 
1671  mbSwapOut = false;
1672  }
1673  }
1674 
1675  return bRet;
1676 }
1677 
1678 void ImpGraphic::ImplSetLink(const std::shared_ptr<GfxLink>& rGfxLink)
1679 {
1680  ensureAvailable();
1681 
1682  mpGfxLink = rGfxLink;
1683 }
1684 
1685 std::shared_ptr<GfxLink> ImpGraphic::ImplGetSharedGfxLink() const
1686 {
1687  return mpGfxLink;
1688 }
1689 
1691 {
1692  ensureAvailable();
1693 
1694  return( mpGfxLink ? *mpGfxLink : GfxLink() );
1695 }
1696 
1698 {
1699  return ( bool(mpGfxLink) );
1700 }
1701 
1703 {
1704  if (mnChecksum != 0)
1705  return mnChecksum;
1706 
1707  BitmapChecksum nRet = 0;
1708 
1709  ensureAvailable();
1710 
1712  {
1713  switch( meType )
1714  {
1715  case GraphicType::Default:
1716  break;
1717 
1718  case GraphicType::Bitmap:
1719  {
1721  nRet = maVectorGraphicData->GetChecksum();
1722  else if (mpPdfData && !mpPdfData->empty())
1723  // Include the PDF data in the checksum, so a metafile with
1724  // and without PDF data is considered to be different.
1725  nRet = vcl_get_checksum(nRet, mpPdfData->data(), mpPdfData->size());
1726  else if( mpAnimation )
1727  nRet = mpAnimation->GetChecksum();
1728  else
1729  nRet = maEx.GetChecksum();
1730  }
1731  break;
1732 
1733  default:
1734  nRet = maMetaFile.GetChecksum();
1735  break;
1736  }
1737  }
1738 
1739  mnChecksum = nRet;
1740  return nRet;
1741 }
1742 
1744 {
1745  bool bResult = false;
1746 
1747  ensureAvailable();
1748 
1749  if( !rOStm.GetError() )
1750  {
1751  if( !ImplIsSwapOut() )
1752  {
1753  if( mpGfxLink && mpGfxLink->IsNative() )
1754  bResult = mpGfxLink->ExportNative( rOStm );
1755  else
1756  {
1757  WriteImpGraphic( rOStm, *this );
1758  bResult = ( rOStm.GetError() == ERRCODE_NONE );
1759  }
1760  }
1761  else
1763  }
1764 
1765  return bResult;
1766 }
1767 
1768 static std::map<BitmapChecksum, std::shared_ptr<std::vector<sal_Int8>>> sPdfDataCache;
1769 
1770 void ReadImpGraphic( SvStream& rIStm, ImpGraphic& rImpGraphic )
1771 {
1772  if (rIStm.GetError())
1773  return;
1774 
1775  const sal_uLong nStmPos1 = rIStm.Tell();
1776  sal_uInt32 nTmp;
1777 
1778  rImpGraphic.ImplClear();
1779 
1780  // read Id
1781  rIStm.ReadUInt32( nTmp );
1782 
1783  // if there is no more data, avoid further expensive
1784  // reading which will create VDevs and other stuff, just to
1785  // read nothing. CAUTION: Eof is only true AFTER reading another
1786  // byte, a speciality of SvMemoryStream (!)
1787  if (!rIStm.good())
1788  return;
1789 
1790  if (NATIVE_FORMAT_50 == nTmp)
1791  {
1792  Graphic aGraphic;
1793  GfxLink aLink;
1794 
1795  // read compat info
1796  std::unique_ptr<VersionCompat> pCompat(new VersionCompat( rIStm, StreamMode::READ ));
1797  pCompat.reset(); // destructor writes stuff into the header
1798 
1799  ReadGfxLink( rIStm, aLink );
1800 
1801  // set dummy link to avoid creation of additional link after filtering;
1802  // we set a default link to avoid unnecessary swapping of native data
1803  aGraphic.SetGfxLink(std::make_shared<GfxLink>());
1804 
1805  if( !rIStm.GetError() && aLink.LoadNative( aGraphic ) )
1806  {
1807  // set link only, if no other link was set
1808  const bool bSetLink = !rImpGraphic.mpGfxLink;
1809 
1810  // assign graphic
1811  rImpGraphic = *aGraphic.ImplGetImpGraphic();
1812 
1813  if( aLink.IsPrefMapModeValid() )
1814  rImpGraphic.ImplSetPrefMapMode( aLink.GetPrefMapMode() );
1815 
1816  if( aLink.IsPrefSizeValid() )
1817  rImpGraphic.ImplSetPrefSize( aLink.GetPrefSize() );
1818 
1819  if( bSetLink )
1820  rImpGraphic.ImplSetLink(std::make_shared<GfxLink>(aLink));
1821  }
1822  else
1823  {
1824  rIStm.Seek( nStmPos1 );
1826  }
1827  return;
1828  }
1829 
1830  BitmapEx aBmpEx;
1831  const SvStreamEndian nOldFormat = rIStm.GetEndian();
1832 
1833  rIStm.SeekRel( -4 );
1834  rIStm.SetEndian( SvStreamEndian::LITTLE );
1835  ReadDIBBitmapEx(aBmpEx, rIStm);
1836 
1837  if( !rIStm.GetError() )
1838  {
1839  sal_uInt32 nMagic1(0), nMagic2(0);
1840  sal_uLong nActPos = rIStm.Tell();
1841 
1842  rIStm.ReadUInt32( nMagic1 ).ReadUInt32( nMagic2 );
1843  rIStm.Seek( nActPos );
1844 
1845  rImpGraphic = ImpGraphic( aBmpEx );
1846 
1847  if( !rIStm.GetError() && ( 0x5344414e == nMagic1 ) && ( 0x494d4931 == nMagic2 ) )
1848  {
1849  rImpGraphic.mpAnimation = std::make_unique<Animation>();
1850  ReadAnimation( rIStm, *rImpGraphic.mpAnimation );
1851 
1852  // #108077# manually set loaded BmpEx to Animation
1853  // (which skips loading its BmpEx if already done)
1854  rImpGraphic.mpAnimation->SetBitmapEx(aBmpEx);
1855  }
1856  else
1857  rIStm.ResetError();
1858  }
1859  else
1860  {
1861  GDIMetaFile aMtf;
1862 
1863  rIStm.Seek( nStmPos1 );
1864  rIStm.ResetError();
1865  ReadGDIMetaFile( rIStm, aMtf );
1866 
1867  if( !rIStm.GetError() )
1868  {
1869  rImpGraphic = aMtf;
1870  }
1871  else
1872  {
1873  ErrCode nOrigError = rIStm.GetErrorCode();
1874  // try to stream in Svg defining data (length, byte array and evtl. path)
1875  // See below (operator<<) for more information
1876  const sal_uInt32 nSvgMagic((sal_uInt32('s') << 24) | (sal_uInt32('v') << 16) | (sal_uInt32('g') << 8) | sal_uInt32('0'));
1877  const sal_uInt32 nWmfMagic((sal_uInt32('w') << 24) | (sal_uInt32('m') << 16) | (sal_uInt32('f') << 8) | sal_uInt32('0'));
1878  const sal_uInt32 nEmfMagic((sal_uInt32('e') << 24) | (sal_uInt32('m') << 16) | (sal_uInt32('f') << 8) | sal_uInt32('0'));
1879  sal_uInt32 nMagic;
1880  rIStm.Seek(nStmPos1);
1881  rIStm.ResetError();
1882  rIStm.ReadUInt32( nMagic );
1883 
1884  if (nSvgMagic == nMagic || nWmfMagic == nMagic || nEmfMagic == nMagic)
1885  {
1886  sal_uInt32 nVectorGraphicDataArrayLength(0);
1887  rIStm.ReadUInt32(nVectorGraphicDataArrayLength);
1888 
1889  if (nVectorGraphicDataArrayLength)
1890  {
1891  VectorGraphicDataArray aNewData(nVectorGraphicDataArrayLength);
1892 
1893  rIStm.ReadBytes(aNewData.getArray(), nVectorGraphicDataArrayLength);
1894  OUString aPath = rIStm.ReadUniOrByteString(rIStm.GetStreamCharSet());
1895 
1896  if (!rIStm.GetError())
1897  {
1899 
1900  if (nWmfMagic == nMagic)
1901  {
1902  aDataType = VectorGraphicDataType::Wmf;
1903  }
1904  else if (nEmfMagic == nMagic)
1905  {
1906  aDataType = VectorGraphicDataType::Emf;
1907  }
1908 
1909  VectorGraphicDataPtr aVectorGraphicDataPtr(new VectorGraphicData(aNewData, aPath, aDataType));
1910  rImpGraphic = aVectorGraphicDataPtr;
1911  }
1912  }
1913  }
1914  else if (nMagic == nPdfMagic)
1915  {
1916  // Stream in PDF data.
1917  BitmapChecksum nPdfId = 0;
1918  rIStm.ReadUInt64(nPdfId);
1919 
1920  rImpGraphic.mnPageNumber = 0;
1921  rIStm.ReadInt32(rImpGraphic.mnPageNumber);
1922 
1923  auto it = sPdfDataCache.find(nPdfId);
1924  assert(it != sPdfDataCache.end());
1925 
1926  rImpGraphic.mpPdfData = it->second;
1927 
1928  Bitmap aBitmap;
1929  rImpGraphic.maEx = aBitmap;
1930 
1931  std::vector<Bitmap> aBitmaps;
1932  if (vcl::RenderPDFBitmaps(rImpGraphic.mpPdfData->data(), rImpGraphic.mpPdfData->size(), aBitmaps, rImpGraphic.mnPageNumber, 1) == 1)
1933  rImpGraphic.maEx = aBitmaps[0];
1934 
1935  rImpGraphic.meType = GraphicType::Bitmap;
1936  }
1937  else
1938  {
1939  rIStm.SetError(nOrigError);
1940  }
1941 
1942  rIStm.Seek(nStmPos1);
1943  }
1944  }
1945 
1946  rIStm.SetEndian( nOldFormat );
1947 }
1948 
1949 void WriteImpGraphic(SvStream& rOStm, const ImpGraphic& rImpGraphic)
1950 {
1951  if (rOStm.GetError())
1952  return;
1953 
1954  rImpGraphic.ensureAvailable();
1955 
1956  if (rImpGraphic.ImplIsSwapOut())
1957  {
1959  return;
1960  }
1961 
1962  if( ( rOStm.GetVersion() >= SOFFICE_FILEFORMAT_50 ) &&
1963  ( rOStm.GetCompressMode() & SvStreamCompressFlags::NATIVE ) &&
1964  rImpGraphic.mpGfxLink && rImpGraphic.mpGfxLink->IsNative() &&
1965  !rImpGraphic.hasPdfData())
1966  {
1967  // native format
1968  rOStm.WriteUInt32( NATIVE_FORMAT_50 );
1969 
1970  // write compat info
1971  std::unique_ptr<VersionCompat> pCompat(new VersionCompat( rOStm, StreamMode::WRITE, 1 ));
1972  pCompat.reset(); // destructor writes stuff into the header
1973 
1974  rImpGraphic.mpGfxLink->SetPrefMapMode( rImpGraphic.ImplGetPrefMapMode() );
1975  rImpGraphic.mpGfxLink->SetPrefSize( rImpGraphic.ImplGetPrefSize() );
1976  WriteGfxLink( rOStm, *rImpGraphic.mpGfxLink );
1977  }
1978  else
1979  {
1980  // own format
1981  const SvStreamEndian nOldFormat = rOStm.GetEndian();
1982  rOStm.SetEndian( SvStreamEndian::LITTLE );
1983 
1984  switch( rImpGraphic.ImplGetType() )
1985  {
1986  case GraphicType::NONE:
1987  case GraphicType::Default:
1988  break;
1989 
1990  case GraphicType::Bitmap:
1991  {
1992  if(rImpGraphic.getVectorGraphicData().get())
1993  {
1994  // stream out Vector Graphic defining data (length, byte array and evtl. path)
1995  // this is used e.g. in swapping out graphic data and in transporting it over UNO API
1996  // as sequence of bytes, but AFAIK not written anywhere to any kind of file, so it should be
1997  // no problem to extend it; only used at runtime
1998  switch (rImpGraphic.getVectorGraphicData()->getVectorGraphicDataType())
1999  {
2001  {
2002  const sal_uInt32 nWmfMagic((sal_uInt32('w') << 24) | (sal_uInt32('m') << 16) | (sal_uInt32('f') << 8) | sal_uInt32('0'));
2003  rOStm.WriteUInt32(nWmfMagic);
2004  break;
2005  }
2007  {
2008  const sal_uInt32 nEmfMagic((sal_uInt32('e') << 24) | (sal_uInt32('m') << 16) | (sal_uInt32('f') << 8) | sal_uInt32('0'));
2009  rOStm.WriteUInt32(nEmfMagic);
2010  break;
2011  }
2012  default: // case VectorGraphicDataType::Svg:
2013  {
2014  const sal_uInt32 nSvgMagic((sal_uInt32('s') << 24) | (sal_uInt32('v') << 16) | (sal_uInt32('g') << 8) | sal_uInt32('0'));
2015  rOStm.WriteUInt32(nSvgMagic);
2016  break;
2017  }
2018  }
2019 
2020  rOStm.WriteUInt32( rImpGraphic.getVectorGraphicData()->getVectorGraphicDataArrayLength() );
2021  rOStm.WriteBytes(rImpGraphic.getVectorGraphicData()->getVectorGraphicDataArray().getConstArray(),
2022  rImpGraphic.getVectorGraphicData()->getVectorGraphicDataArrayLength());
2023  rOStm.WriteUniOrByteString(rImpGraphic.getVectorGraphicData()->getPath(),
2024  rOStm.GetStreamCharSet());
2025  }
2026  else if (rImpGraphic.hasPdfData())
2027  {
2028  BitmapChecksum nPdfId = vcl_get_checksum(0, rImpGraphic.mpPdfData->data(), rImpGraphic.mpPdfData->size());
2029  if (sPdfDataCache.find(nPdfId) == sPdfDataCache.end())
2030  sPdfDataCache.emplace(nPdfId, rImpGraphic.mpPdfData);
2031 
2032  // Stream out PDF data.
2033  rOStm.WriteUInt32(nPdfMagic);
2034  rOStm.WriteUInt64(nPdfId);
2035  rOStm.WriteInt32(rImpGraphic.mnPageNumber);
2036  }
2037  else if( rImpGraphic.ImplIsAnimated())
2038  {
2039  WriteAnimation( rOStm, *rImpGraphic.mpAnimation );
2040  }
2041  else
2042  {
2043  WriteDIBBitmapEx(rImpGraphic.maEx, rOStm);
2044  }
2045  }
2046  break;
2047 
2048  default:
2049  {
2050  if( rImpGraphic.ImplIsSupportedGraphic() )
2051  WriteGDIMetaFile( rOStm, rImpGraphic.maMetaFile );
2052  }
2053  break;
2054  }
2055 
2056  rOStm.SetEndian( nOldFormat );
2057  }
2058 }
2059 
2060 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
#define SYS_OS2METAFILE
Definition: impgraph.cxx:55
css::uno::Reference< css::linguistic2::XProofreadingIterator > get(css::uno::Reference< css::uno::XComponentContext > const &context)
const Fraction & GetScaleX() const
Definition: mapmod.cxx:172
long Width() const
VectorGraphicDataType
ImpGraphic & operator=(const ImpGraphic &rImpGraphic)
Definition: impgraph.cxx:327
BitmapEx maEx
Definition: impgraph.hxx:77
bool mbDummyContext
Definition: impgraph.hxx:86
const GDIMetaFile & ImplGetGDIMetaFile() const
Definition: impgraph.cxx:836
sal_uInt64 BitmapChecksum
Definition: checksum.hxx:30
std::shared_ptr< GraphicReader > mpContext
Definition: impgraph.hxx:80
SvStream & WriteUInt64(sal_uInt64 nuInt64)
sal_Int32 nIndex
constexpr::Color COL_BLACK(0x00, 0x00, 0x00)
virtual void accessMetafile(GDIMetaFile &rTargetMetafile) const =0
void SetSizePixel(const Size &rNewSize)
Definition: bitmapex.cxx:313
double getHeight() const
SvStream & WriteInt32(sal_Int32 nInt32)
Bitmap ImplGetBitmap(const GraphicConversionParameters &rParameters) const
Definition: impgraph.cxx:671
MapMode ImplGetPrefMapMode() const
Definition: impgraph.cxx:1002
const MapMode & GetPrefMapMode() const
Definition: bitmapex.hxx:89
SvStream & WriteMapMode(SvStream &rOStm, const MapMode &rMapMode)
Definition: mapmod.cxx:152
sal_Int32 GetVersion() const
long Height() const
static std::map< BitmapChecksum, std::shared_ptr< std::vector< sal_Int8 > > > sPdfDataCache
Definition: impgraph.cxx:1768
const MapMode & GetPrefMapMode() const
Definition: gdimtf.hxx:176
bool Scale(const Size &rNewSize, BmpScaleFlag nScaleFlag=BmpScaleFlag::Default)
Scale the bitmap.
Definition: bitmapex.cxx:370
const BitmapEx & ImplGetBitmapExRef() const
Gives direct access to the contained BitmapEx.
Definition: impgraph.cxx:830
bool mbIsTransparent
Definition: impgraph.hxx:36
void unregisterGraphic(ImpGraphic *pImpGraphic)
Definition: Manager.cxx:156
sal_uIntPtr sal_uLong
#define GRAPHIC_FORMAT_50
Definition: impgraph.cxx:58
void writeSize(const Size &rSize)
bool ImplSwapOut()
Definition: impgraph.cxx:1460
void ImplSetPrefMapMode(const MapMode &rPrefMapMode)
Definition: impgraph.cxx:1047
void SetPrefMapMode(const MapMode &rPrefMapMode)
Definition: bitmapex.hxx:90
GraphicID(ImpGraphic const &rGraphic)
Definition: impgraph.cxx:107
GraphicType
Definition: graph.hxx:36
bool mbIsAlpha
Definition: impgraph.hxx:37
void SetPrefSize(const Size &rSize)
Definition: gdimtf.hxx:174
bool ImplWriteEmbedded(SvStream &rOStream)
Definition: impgraph.cxx:1382
void Clear()
Definition: gdimtf.cxx:248
sal_Int16 nId
sal_uInt64 Seek(sal_uInt64 nPos)
#define ERRCODE_IO_WRONGFORMAT
Definition: errcode.hxx:219
B2DVector getRange() const
bool ensureAvailable() const
Definition: impgraph.cxx:1553
BitmapChecksum vcl_get_checksum(BitmapChecksum Checksum, const void *Data, sal_uInt32 DatLen)
Definition: checksum.hxx:72
void Flush()
ParserContextSharedPtr mpContext
SvStream & ReadUInt64(sal_uInt64 &rUInt64)
bool mbSwapOut
Definition: impgraph.hxx:85
SvStreamCompressFlags GetCompressMode() const
SvStream & ReadAnimation(SvStream &rIStm, Animation &rAnimation)
Definition: Animation.cxx:600
#define SYS_WNTMETAFILE
Definition: impgraph.cxx:54
BitmapChecksum GetChecksum() const
Definition: bitmapex.cxx:292
sal_uInt64 SeekRel(sal_Int64 nPos)
std::shared_ptr< GfxLink > ImplGetSharedGfxLink() const
Definition: impgraph.cxx:1685
NONE
bool getUnlimitedSize() const
Definition: graph.hxx:99
bool IsEmpty() const
OUString const & getOriginURL() const
Definition: impgraph.hxx:127
bool IsAlpha() const
Definition: bitmapex.cxx:226
long Right() const
void DisablePreviewMode()
Definition: impgraph.cxx:86
double getWidth() const
ErrCode GetError() const
bool ImplReadEmbedded(SvStream &rIStream)
Definition: impgraph.cxx:1248
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:1740
bool IsAlpha() const
const Fraction & GetScaleY() const
Definition: mapmod.cxx:174
SvStream & WriteGDIMetaFile(SvStream &rOStm, const GDIMetaFile &rGDIMetaFile)
Definition: gdimtf.cxx:2709
const sal_uInt16 nMagic
const Size & GetPrefSize() const
Definition: bitmapex.hxx:86
sal_uInt32 mnAnimationLoopCount
Definition: impgraph.hxx:39
SvStream & WriteUniOrByteString(const OUString &rStr, rtl_TextEncoding eDestCharSet)
const GDIMetaFile & GetGDIMetaFile() const
Definition: graph.cxx:359
SvStream & WriteUInt32(sal_uInt32 nUInt32)
void ImplStartAnimation(OutputDevice *pOutDev, const Point &rDestPt, const Size &rDestSize, long nExtraData, OutputDevice *pFirstFrameOutDev)
Definition: impgraph.cxx:1196
void Play(GDIMetaFile &rMtf)
Definition: gdimtf.cxx:300
sal_uInt32 ImplGetAnimationLoopCount() const
Definition: impgraph.cxx:1234
GDIMetaFile GetMonochromeMtf(const Color &rCol) const
Definition: gdimtf.cxx:2185
GraphicType meType
Definition: impgraph.hxx:83
const Size & GetSize_100TH_MM() const
BitmapChecksum ImplGetChecksum() const
Definition: impgraph.cxx:1702
void SetGfxLink(const std::shared_ptr< GfxLink > &rGfxLink)
Definition: graph.cxx:516
void readSize(Size &rSize)
bool ImplIsTransparent() const
Definition: impgraph.cxx:610
Size GetPreviewSize() const
Definition: impgraph.cxx:99
Size maPrefSize
Definition: impgraph.hxx:31
B2IRange fround(const B2DRange &rRange)
void Clear()
Definition: bitmapex.cxx:216
const std::shared_ptr< std::vector< sal_Int8 > > & getPdfData() const
Definition: impgraph.cxx:481
#define NATIVE_FORMAT_50
Definition: impgraph.cxx:59
bool makeAvailable()
Definition: impgraph.cxx:666
const Size & getSizePixel() const
Definition: graph.hxx:98
std::unique_ptr< Animation > mpAnimation
Definition: impgraph.hxx:79
SvStream & ReadUInt32(sal_uInt32 &rUInt32)
std::shared_ptr< ImpSwapFile > mpSwapFile
Definition: impgraph.hxx:81
bool IsEmpty() const
Definition: bitmapex.cxx:203
void SetPrefMapMode(const MapMode &rMapMode)
Definition: bitmap.hxx:562
void setOriginURL(OUString const &rOriginURL)
Definition: impgraph.hxx:132
#define BITMAP_CHECKSUM_SIZE
Definition: checksum.hxx:28
OString getIDString() const
Definition: impgraph.cxx:166
#define SOFFICE_FILEFORMAT_50
bool WriteDIBBitmapEx(const BitmapEx &rSource, SvStream &rOStm)
Definition: dibtools.cxx:1871
SAL_DLLPRIVATE ImpGraphic * ImplGetImpGraphic() const
Definition: graph.hxx:114
bool getSnapHorVerLines() const
Definition: graph.hxx:101
SvStream & WriteAnimation(SvStream &rOStm, const Animation &rAnimation)
Definition: Animation.cxx:554
const Size & GetPrefSize() const
Definition: gdimtf.hxx:173
const Size & GetSizePixel() const
bool loadPrepared()
Definition: impgraph.cxx:1564
std::shared_ptr< std::vector< sal_Int8 > > mpPdfData
The PDF stream from which this Graphic is rendered, as converted (version downgraded) from the origin...
Definition: impgraph.hxx:94
GDIMetaFile maMetaFile
Definition: impgraph.hxx:76
OUString const & GetURL() const
void ImplClear()
Definition: impgraph.cxx:584
OUString maOriginURL
Definition: impgraph.cxx:68
BitmapEx ImplGetBitmapEx(const GraphicConversionParameters &rParameters) const
Definition: impgraph.cxx:780
void ImplSetPrepared(bool bAnimated, const Size *pSizeHint)
Definition: impgraph.cxx:536
ConvertDataFormat
Definition: salctype.hxx:27
void ReadImpGraphic(SvStream &rIStm, ImpGraphic &rImpGraphic)
Definition: impgraph.cxx:1770
static Manager & get()
Definition: Manager.cxx:56
QPRO_FUNC_TYPE const nType
void ImplSetAnimationNotifyHdl(const Link< Animation *, void > &rLink)
Definition: impgraph.cxx:1214
BitmapChecksum mnChecksum
Definition: impgraph.hxx:89
friend void WriteImpGraphic(SvStream &rOStm, const ImpGraphic &rImpGraphic)
Definition: impgraph.cxx:1949
Some things multiple-inherit from VclAbstractDialog and OutputDevice, so we need to use virtual inher...
Definition: outdev.hxx:304
std::size_t WriteBytes(const void *pData, std::size_t nSize)
sal_uLong GetSizeBytes() const
Definition: bitmapex.cxx:282
bool ImplExportNative(SvStream &rOStm) const
Definition: impgraph.cxx:1743
void changeExisting(const ImpGraphic *pImpGraphic, sal_Int64 nOldSize)
Definition: Manager.cxx:234
long Bottom() const
sal_uLong mnSizeBytes
Definition: impgraph.hxx:84
void SetPrefSize(const Size &rSize)
Definition: bitmap.hxx:572
void SetError(ErrCode nErrorCode)
GraphicType ImplGetType() const
Definition: impgraph.hxx:153
#define GRAPHIC_MTFTOBMP_MAXEXT
Definition: impgraph.cxx:50
void SetBufferSize(sal_uInt16 m_nBufSize)
Size maPreviewSize
Definition: impgraph.cxx:75
MapUnit GetMapUnit() const
Definition: mapmod.cxx:168
ErrCode const & GetErrorCode() const
bool ImplIsAnimated() const
Definition: impgraph.cxx:646
const Size & GetDisplaySizePixel() const
Definition: Animation.hxx:55
void WindStart()
Definition: gdimtf.cxx:531
bool IsTransparent() const
Definition: bitmapex.cxx:221
Link< Animation *, void > ImplGetAnimationNotifyHdl() const
Definition: impgraph.cxx:1222
void WriteImpGraphic(SvStream &rOStm, const ImpGraphic &rImpGraphic)
Definition: impgraph.cxx:1949
static ErrCode Import(SvStream &rIStm, Graphic &rGraphic, ConvertDataFormat nFormat=ConvertDataFormat::Unknown)
Definition: cvtgrf.cxx:34
void Draw(OutputDevice *pOutDev, const Point &rDestPt) const
Definition: bitmapex.cxx:617
long X() const
tools::Rectangle GetBoundRect(OutputDevice &i_rReference, tools::Rectangle *pHairline=nullptr) const
Definition: gdimtf.cxx:1285
bool ImplIsEPS() const
Definition: impgraph.cxx:651
#define SYS_MACMETAFILE
Definition: impgraph.cxx:56
bool mbPrepared
Definition: impgraph.hxx:99
SvStream & ReadInt32(sal_Int32 &rInt32)
std::shared_ptr< GfxLink > mpGfxLink
Definition: impgraph.hxx:82
std::size_t ReadBytes(void *pData, std::size_t nSize)
Bitmap GetBitmap(Color aTransparentReplaceColor) const
Definition: bitmapex.cxx:236
std::shared_ptr< VectorGraphicData > VectorGraphicDataPtr
OUString GetMainURL(DecodeMechanism eMechanism, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
Size ImplGetPrefSize() const
Definition: impgraph.cxx:913
std::chrono::high_resolution_clock::time_point maLastUsed
Definition: impgraph.hxx:98
SvStreamEndian GetEndian() const
void Stop()
Definition: gdimtf.cxx:518
void swappedIn(const ImpGraphic *pImpGraphic)
Definition: Manager.cxx:220
css::uno::Sequence< sal_Int8 > VectorGraphicDataArray
INetURLObject aSwapURL
Definition: impgraph.cxx:67
const VectorGraphicDataPtr & getVectorGraphicData() const
Definition: impgraph.cxx:467
void SetPreviewSize(const Size &)
Definition: impgraph.cxx:92
void ImplSetLink(const std::shared_ptr< GfxLink > &)
Definition: impgraph.cxx:1678
sal_Int32 mnPageNumber
Used with GfxLink and/or PdfData when they store original media which might be multi-page (PDF...
Definition: impgraph.hxx:104
void ImplDraw(OutputDevice *pOutDev, const Point &rDestPt) const
Definition: impgraph.cxx:1119
sal_Int32 GetDenominator() const
void ImplClearGraphics()
Definition: impgraph.cxx:502
BitmapChecksum GetChecksum() const
Definition: gdimtf.cxx:2200
#define ERRCODE_NONE
Definition: errcode.hxx:198
bool Scale(const Size &rNewSize, BmpScaleFlag nScaleFlag=BmpScaleFlag::Default)
Scale the bitmap.
Definition: bitmap3.cxx:828
void AddAction(const rtl::Reference< MetaAction > &pAction)
Definition: gdimtf.cxx:544
sal_uLong ImplGetSizeBytes() const
Definition: impgraph.cxx:1087
bool IsTransparent() const
MetaAction * GetAction(size_t nAction) const
Definition: gdimtf.cxx:162
SvStream & ReadGDIMetaFile(SvStream &rIStm, GDIMetaFile &rGDIMetaFile, ImplMetaReadData *pData)
Definition: gdimtf.cxx:2625
void SetEndian(SvStreamEndian SvStreamEndian)
rtl_TextEncoding GetStreamCharSet() const
void SetPrefSize(const Size &rPrefSize)
Definition: bitmapex.hxx:87
ImpSwapInfo maSwapInfo
Definition: impgraph.hxx:78
sal_uInt64 Tell() const
Reference< XComponentContext > getProcessComponentContext()
size_t GetActionSize() const
Definition: gdimtf.cxx:157
sal_Int32 GetNumerator() const
bool mbIsAnimated
Definition: impgraph.hxx:34
bool ImplIsSwapOut() const
Definition: impgraph.hxx:215
void swappedOut(const ImpGraphic *pImpGraphic)
Definition: Manager.cxx:227
Size ImplGetSizePixel() const
Definition: impgraph.cxx:901
constexpr::Color COL_WHITE(0xFF, 0xFF, 0xFF)
const Point & GetOrigin() const
Definition: mapmod.cxx:170
Animation ImplGetAnimation() const
Definition: impgraph.cxx:819
MetaActionType GetType() const
Definition: metaact.hxx:89
void ImplStopAnimation(OutputDevice *pOutputDevice, long nExtraData)
Definition: impgraph.cxx:1206
void ImplCreateSwapInfo()
Definition: impgraph.cxx:488
#define GRAPHIC_STREAMBUFSIZE
Definition: impgraph.cxx:51
void ImplSetDefaultType()
Definition: impgraph.cxx:599
bool isAvailable() const
Definition: impgraph.cxx:661
bool good() const
reference_type * get() const
Get the body.
Definition: vclptr.hxx:143
#define SAL_WARN(area, stream)
css::uno::Any executeCommand(const OUString &rCommandName, const css::uno::Any &rCommandArgument)
bool ImplIsLink() const
Definition: impgraph.cxx:1697
SvStreamEndian
SvStream & ReadMapMode(SvStream &rIStm, MapMode &rMapMode)
Definition: mapmod.cxx:136
ColorAnimationSharedPtr mpAnimation
virtual void ResetError()
size_t RenderPDFBitmaps(const void *pBuffer, int nSize, std::vector< Bitmap > &rBitmaps, const size_t nFirstPage, int nPages, const double fResolutionDPI)
Fills the rBitmaps vector with rendered pages.
Definition: pdfread.cxx:151
bool mbIsEPS
Definition: impgraph.hxx:35
long getHeight() const
virtual ~GraphicReader()
Definition: impgraph.cxx:82
void ImplSetContext(const std::shared_ptr< GraphicReader > &pReader)
Definition: impgraph.cxx:1242
bool getAntiAliase() const
Definition: graph.hxx:100
RedlineType const meType
bool hasPdfData() const
Definition: impgraph.hxx:144
void ImplSetPrefSize(const Size &rPrefSize)
Definition: impgraph.cxx:962
GraphicExternalLink maGraphicExternalLink
Definition: impgraph.hxx:96
GfxLink ImplGetLink()
Definition: impgraph.cxx:1690
bool Detect(bool bExtendedInfo=false)
starts the detection
const Size & GetSizePixel() const
Definition: bitmapex.hxx:83
bool operator==(const ImpGraphic &rImpGraphic) const
Definition: impgraph.cxx:403
#define SVSTREAM_GENERALERROR
Definition: errcode.hxx:242
long getWidth() const
void setWidth(long nWidth)
MapMode maPrefMapMode
Definition: impgraph.hxx:30
bool ImplIsSupportedGraphic() const
Definition: impgraph.cxx:605
#define SYS_WINMETAFILE
Definition: impgraph.cxx:53
void setPdfData(const std::shared_ptr< std::vector< sal_Int8 >> &rPdfData)
Definition: impgraph.cxx:474
VectorGraphicDataPtr maVectorGraphicData
Definition: impgraph.hxx:87
friend void ReadImpGraphic(SvStream &rIStm, ImpGraphic &rImpGraphic)
Definition: impgraph.cxx:1770
long Y() const
bool ImplIsAlpha() const
Definition: impgraph.cxx:626
Size maSizePixel
Definition: impgraph.hxx:32
void SetPrefMapMode(const MapMode &rMapMode)
Definition: gdimtf.hxx:177
const sal_uInt32 nPdfMagic((sal_uInt32('p')<< 24)|(sal_uInt32('d')<< 16)|(sal_uInt32('f')<< 8)|sal_uInt32('0'))
OUString ReadUniOrByteString(rtl_TextEncoding eSrcCharSet)
bool ImplSwapIn()
Definition: impgraph.cxx:1588
void setHeight(long nHeight)
sal_uLong GetSizeBytes() const
Definition: gdimtf.cxx:2544