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  const Color aReplaceColor( COL_WHITE );
687 
688  aRetBmp = rRetBmpEx.GetBitmap( &aReplaceColor );
689 
690  if(rParameters.getSizePixel().Width() || rParameters.getSizePixel().Height())
691  aRetBmp.Scale(rParameters.getSizePixel());
692  }
693  else if( ( meType != GraphicType::Default ) && ImplIsSupportedGraphic() )
694  {
695  if(maEx.IsEmpty())
696  {
697  // calculate size
699  Size aDrawSize(aVDev->LogicToPixel(maMetaFile.GetPrefSize(), maMetaFile.GetPrefMapMode()));
700 
701  if(rParameters.getSizePixel().Width() && rParameters.getSizePixel().Height())
702  {
703  // apply given size if exists
704  aDrawSize = rParameters.getSizePixel();
705  }
706 
707  if(aDrawSize.Width() && aDrawSize.Height() && !rParameters.getUnlimitedSize()
708  && (aDrawSize.Width() > GRAPHIC_MTFTOBMP_MAXEXT || aDrawSize.Height() > GRAPHIC_MTFTOBMP_MAXEXT))
709  {
710  // limit bitmap size to a maximum of GRAPHIC_MTFTOBMP_MAXEXT x GRAPHIC_MTFTOBMP_MAXEXT
711  double fWH(static_cast<double>(aDrawSize.Width()) / static_cast<double>(aDrawSize.Height()));
712 
713  if(fWH <= 1.0)
714  {
717  }
718  else
719  {
722  }
723  }
724 
725  // calculate pixel size. Normally, it's the same as aDrawSize, but may
726  // need to be extended when hairlines are on the right or bottom edge
727  Size aPixelSize(aDrawSize);
728 
730  {
731  // get hairline and full bound rect
732  tools::Rectangle aHairlineRect;
733  const tools::Rectangle aRect(maMetaFile.GetBoundRect(*aVDev, &aHairlineRect));
734 
735  if(!aRect.IsEmpty() && !aHairlineRect.IsEmpty())
736  {
737  // expand if needed to allow bottom and right hairlines to be added
738  if(aRect.Right() == aHairlineRect.Right())
739  {
740  aPixelSize.setWidth(aPixelSize.getWidth() + 1);
741  }
742 
743  if(aRect.Bottom() == aHairlineRect.Bottom())
744  {
745  aPixelSize.setHeight(aPixelSize.getHeight() + 1);
746  }
747  }
748  }
749 
750  if(aVDev->SetOutputSizePixel(aPixelSize))
751  {
752  if(rParameters.getAntiAliase())
753  {
754  aVDev->SetAntialiasing(aVDev->GetAntialiasing() | AntialiasingFlags::EnableB2dDraw);
755  }
756 
757  if(rParameters.getSnapHorVerLines())
758  {
759  aVDev->SetAntialiasing(aVDev->GetAntialiasing() | AntialiasingFlags::PixelSnapHairline);
760  }
761 
762  ImplDraw( aVDev.get(), Point(), aDrawSize );
763 
764  // use maEx as local buffer for rendered metafile
765  const_cast< ImpGraphic* >(this)->maEx = aVDev->GetBitmapEx( Point(), aVDev->GetOutputSizePixel() );
766  }
767  }
768 
769  aRetBmp = maEx.GetBitmap();
770  }
771 
772  if( !!aRetBmp )
773  {
774  aRetBmp.SetPrefMapMode( ImplGetPrefMapMode() );
775  aRetBmp.SetPrefSize( ImplGetPrefSize() );
776  }
777 
778  return aRetBmp;
779 }
780 
782 {
783  BitmapEx aRetBmpEx;
784 
785  ensureAvailable();
786 
787  if( meType == GraphicType::Bitmap )
788  {
789  if(maVectorGraphicData.get() && maEx.IsEmpty())
790  {
791  // use maEx as local buffer for rendered svg
792  const_cast< ImpGraphic* >(this)->maEx = maVectorGraphicData->getReplacement();
793  }
794 
795  aRetBmpEx = ( mpAnimation ? mpAnimation->GetBitmapEx() : maEx );
796 
797  if(rParameters.getSizePixel().Width() || rParameters.getSizePixel().Height())
798  {
799  aRetBmpEx.Scale(
800  rParameters.getSizePixel(),
802  }
803  }
804  else if( ( meType != GraphicType::Default ) && ImplIsSupportedGraphic() )
805  {
806  if(maEx.IsEmpty())
807  {
808  const ImpGraphic aMonoMask( maMetaFile.GetMonochromeMtf( COL_BLACK ) );
809 
810  // use maEx as local buffer for rendered metafile
811  const_cast< ImpGraphic* >(this)->maEx = BitmapEx(ImplGetBitmap(rParameters), aMonoMask.ImplGetBitmap(rParameters));
812  }
813 
814  aRetBmpEx = maEx;
815  }
816 
817  return aRetBmpEx;
818 }
819 
821 {
822  Animation aAnimation;
823 
824  ensureAvailable();
825  if( mpAnimation )
826  aAnimation = *mpAnimation;
827 
828  return aAnimation;
829 }
830 
832 {
833  ensureAvailable();
834  return maEx;
835 }
836 
838 {
839  ensureAvailable();
841  && maVectorGraphicData.get()
842  && (VectorGraphicDataType::Emf == maVectorGraphicData->getVectorGraphicDataType()
843  || VectorGraphicDataType::Wmf == maVectorGraphicData->getVectorGraphicDataType()))
844  {
845  // If we have a Emf/Wmf VectorGraphic object, we
846  // need a way to get the Metafile data out of the primitive
847  // representation. Use a strict virtual hook (MetafileAccessor)
848  // to access the MetafilePrimitive2D directly. Also see comments in
849  // XEmfParser about this.
850  const std::deque< css::uno::Reference< css::graphic::XPrimitive2D > > aSequence(maVectorGraphicData->getPrimitive2DSequence());
851 
852  if (1 == aSequence.size())
853  {
854  // try to cast to MetafileAccessor implementation
855  const css::uno::Reference< css::graphic::XPrimitive2D > xReference(aSequence[0]);
856  const MetafileAccessor* pMetafileAccessor = dynamic_cast< const MetafileAccessor* >(xReference.get());
857 
858  if (pMetafileAccessor)
859  {
860  // it is a MetafileAccessor implementation, get Metafile
861  pMetafileAccessor->accessMetafile(const_cast< ImpGraphic* >(this)->maMetaFile);
862  }
863  }
864  }
865 
867  {
868  // #i119735#
869  // Use the local maMetaFile as container for a metafile-representation
870  // of the bitmap graphic. This will be done only once, thus be buffered.
871  // I checked all usages of maMetaFile, it is only used when type is not
872  // GraphicType::Bitmap. In operator= it will get copied, thus buffering will
873  // survive copying (change this if not wanted)
874  ImpGraphic* pThat = const_cast< ImpGraphic* >(this);
875 
876  if(maVectorGraphicData.get() && !maEx)
877  {
878  // use maEx as local buffer for rendered svg
879  pThat->maEx = maVectorGraphicData->getReplacement();
880  }
881 
882  // #123983# directly create a metafile with the same PrefSize and PrefMapMode
883  // the bitmap has, this will be an always correct metafile
884  if(maEx.IsTransparent())
885  {
887  }
888  else
889  {
891  }
892 
893  pThat->maMetaFile.Stop();
894  pThat->maMetaFile.WindStart();
897  }
898 
899  return maMetaFile;
900 }
901 
903 {
904  Size aSize;
905 
906  if (ImplIsSwapOut())
907  aSize = maSwapInfo.maSizePixel;
908  else
910 
911  return aSize;
912 }
913 
915 {
916  Size aSize;
917 
918  if (ImplIsSwapOut())
919  {
920  aSize = maSwapInfo.maPrefSize;
921  }
922  else
923  {
924  switch( meType )
925  {
926  case GraphicType::NONE:
928  break;
929 
930  case GraphicType::Bitmap:
931  {
932  if(maVectorGraphicData.get() && maEx.IsEmpty())
933  {
934  // svg not yet buffered in maEx, return size derived from range
935  const basegfx::B2DRange& rRange = maVectorGraphicData->getRange();
936 
937  aSize = Size(basegfx::fround(rRange.getWidth()), basegfx::fround(rRange.getHeight()));
938  }
939  else
940  {
941  aSize = maEx.GetPrefSize();
942 
943  if( !aSize.Width() || !aSize.Height() )
944  {
945  aSize = maEx.GetSizePixel();
946  }
947  }
948  }
949  break;
950 
951  default:
952  {
953  if( ImplIsSupportedGraphic() )
954  aSize = maMetaFile.GetPrefSize();
955  }
956  break;
957  }
958  }
959 
960  return aSize;
961 }
962 
963 void ImpGraphic::ImplSetPrefSize( const Size& rPrefSize )
964 {
965  ensureAvailable();
966 
967  switch( meType )
968  {
969  case GraphicType::NONE:
971  break;
972 
973  case GraphicType::Bitmap:
974  {
975  // used when importing a writer FlyFrame with SVG as graphic, added conversion
976  // to allow setting the PrefSize at the BitmapEx to hold it
977  if(maVectorGraphicData.get() && maEx.IsEmpty())
978  {
979  // use maEx as local buffer for rendered svg
980  maEx = maVectorGraphicData->getReplacement();
981  }
982 
983  // #108077# Push through pref size to animation object,
984  // will be lost on copy otherwise
985  if( ImplIsAnimated() )
986  {
987  const_cast< BitmapEx& >(mpAnimation->GetBitmapEx()).SetPrefSize( rPrefSize );
988  }
989 
990  maEx.SetPrefSize( rPrefSize );
991  }
992  break;
993 
994  default:
995  {
996  if( ImplIsSupportedGraphic() )
997  maMetaFile.SetPrefSize( rPrefSize );
998  }
999  break;
1000  }
1001 }
1002 
1004 {
1005  MapMode aMapMode;
1006 
1007  if (ImplIsSwapOut())
1008  {
1009  aMapMode = maSwapInfo.maPrefMapMode;
1010  }
1011  else
1012  {
1013  switch( meType )
1014  {
1015  case GraphicType::NONE:
1016  case GraphicType::Default:
1017  break;
1018 
1019  case GraphicType::Bitmap:
1020  {
1021  if(maVectorGraphicData.get() && maEx.IsEmpty())
1022  {
1023  // svg not yet buffered in maEx, return default PrefMapMode
1024  aMapMode = MapMode(MapUnit::Map100thMM);
1025  }
1026  else
1027  {
1028  const Size aSize( maEx.GetPrefSize() );
1029 
1030  if ( aSize.Width() && aSize.Height() )
1031  aMapMode = maEx.GetPrefMapMode();
1032  }
1033  }
1034  break;
1035 
1036  default:
1037  {
1038  if( ImplIsSupportedGraphic() )
1039  return maMetaFile.GetPrefMapMode();
1040  }
1041  break;
1042  }
1043  }
1044 
1045  return aMapMode;
1046 }
1047 
1048 void ImpGraphic::ImplSetPrefMapMode( const MapMode& rPrefMapMode )
1049 {
1050  ensureAvailable();
1051 
1052  switch( meType )
1053  {
1054  case GraphicType::NONE:
1055  case GraphicType::Default:
1056  break;
1057 
1058  case GraphicType::Bitmap:
1059  {
1060  if(maVectorGraphicData.get())
1061  {
1062  // ignore for Vector Graphic Data. If this is really used (except the grfcache)
1063  // it can be extended by using maEx as buffer for maVectorGraphicData->getReplacement()
1064  }
1065  else
1066  {
1067  // #108077# Push through pref mapmode to animation object,
1068  // will be lost on copy otherwise
1069  if( ImplIsAnimated() )
1070  {
1071  const_cast< BitmapEx& >(mpAnimation->GetBitmapEx()).SetPrefMapMode( rPrefMapMode );
1072  }
1073 
1074  maEx.SetPrefMapMode( rPrefMapMode );
1075  }
1076  }
1077  break;
1078 
1079  default:
1080  {
1081  if( ImplIsSupportedGraphic() )
1082  maMetaFile.SetPrefMapMode( rPrefMapMode );
1083  }
1084  break;
1085  }
1086 }
1087 
1089 {
1090  if( 0 == mnSizeBytes )
1091  {
1092  if (mbPrepared)
1093  ensureAvailable();
1094 
1095  if( meType == GraphicType::Bitmap )
1096  {
1097  if(maVectorGraphicData.get())
1098  {
1099  std::pair<VectorGraphicData::State, size_t> tmp(maVectorGraphicData->getSizeBytes());
1100  if (VectorGraphicData::State::UNPARSED == tmp.first)
1101  {
1102  return tmp.second; // don't cache it until Vector Graphic Data is parsed
1103  }
1104  mnSizeBytes = tmp.second;
1105  }
1106  else
1107  {
1108  mnSizeBytes = mpAnimation ? mpAnimation->GetSizeBytes() : maEx.GetSizeBytes();
1109  }
1110  }
1111  else if( meType == GraphicType::GdiMetafile )
1112  {
1114  }
1115  }
1116 
1117  return mnSizeBytes;
1118 }
1119 
1120 void ImpGraphic::ImplDraw( OutputDevice* pOutDev, const Point& rDestPt ) const
1121 {
1122  ensureAvailable();
1124  {
1125  switch( meType )
1126  {
1127  case GraphicType::Default:
1128  break;
1129 
1130  case GraphicType::Bitmap:
1131  {
1132  if(maVectorGraphicData.get() && !maEx)
1133  {
1134  // use maEx as local buffer for rendered svg
1135  const_cast< ImpGraphic* >(this)->maEx = maVectorGraphicData->getReplacement();
1136  }
1137 
1138  if ( mpAnimation )
1139  {
1140  mpAnimation->Draw( pOutDev, rDestPt );
1141  }
1142  else
1143  {
1144  maEx.Draw( pOutDev, rDestPt );
1145  }
1146  }
1147  break;
1148 
1149  default:
1150  ImplDraw( pOutDev, rDestPt, maMetaFile.GetPrefSize() );
1151  break;
1152  }
1153  }
1154 }
1155 
1157  const Point& rDestPt, const Size& rDestSize ) const
1158 {
1159  ensureAvailable();
1161  {
1162  switch( meType )
1163  {
1164  case GraphicType::Default:
1165  break;
1166 
1167  case GraphicType::Bitmap:
1168  {
1169  if(maVectorGraphicData.get() && maEx.IsEmpty())
1170  {
1171  // use maEx as local buffer for rendered svg
1172  const_cast< ImpGraphic* >(this)->maEx = maVectorGraphicData->getReplacement();
1173  }
1174 
1175  if( mpAnimation )
1176  {
1177  mpAnimation->Draw( pOutDev, rDestPt, rDestSize );
1178  }
1179  else
1180  {
1181  maEx.Draw( pOutDev, rDestPt, rDestSize );
1182  }
1183  }
1184  break;
1185 
1186  default:
1187  {
1188  const_cast<ImpGraphic*>(this)->maMetaFile.WindStart();
1189  const_cast<ImpGraphic*>(this)->maMetaFile.Play( pOutDev, rDestPt, rDestSize );
1190  const_cast<ImpGraphic*>(this)->maMetaFile.WindStart();
1191  }
1192  break;
1193  }
1194  }
1195 }
1196 
1197 void ImpGraphic::ImplStartAnimation( OutputDevice* pOutDev, const Point& rDestPt,
1198  const Size& rDestSize, long nExtraData,
1199  OutputDevice* pFirstFrameOutDev )
1200 {
1201  ensureAvailable();
1202 
1204  mpAnimation->Start( pOutDev, rDestPt, rDestSize, nExtraData, pFirstFrameOutDev );
1205 }
1206 
1207 void ImpGraphic::ImplStopAnimation( OutputDevice* pOutDev, long nExtraData )
1208 {
1209  ensureAvailable();
1210 
1212  mpAnimation->Stop( pOutDev, nExtraData );
1213 }
1214 
1216 {
1217  ensureAvailable();
1218 
1219  if( mpAnimation )
1220  mpAnimation->SetNotifyHdl( rLink );
1221 }
1222 
1224 {
1225  Link<Animation*,void> aLink;
1226 
1227  ensureAvailable();
1228 
1229  if( mpAnimation )
1230  aLink = mpAnimation->GetNotifyHdl();
1231 
1232  return aLink;
1233 }
1234 
1236 {
1237  if (mbSwapOut)
1239 
1240  return mpAnimation ? mpAnimation->GetLoopCount() : 0;
1241 }
1242 
1243 void ImpGraphic::ImplSetContext( const std::shared_ptr<GraphicReader>& pReader )
1244 {
1245  mpContext = pReader;
1246  mbDummyContext = false;
1247 }
1248 
1250 {
1251  ensureAvailable();
1252 
1253  MapMode aMapMode;
1254  Size aSize;
1255  sal_uInt32 nId;
1256  sal_Int32 nType;
1257  const SvStreamEndian nOldFormat = rIStm.GetEndian();
1258  bool bRet = false;
1259 
1260  rIStm.SetEndian( SvStreamEndian::LITTLE );
1261  rIStm.ReadUInt32( nId );
1262 
1263  // check version
1264  if( GRAPHIC_FORMAT_50 == nId )
1265  {
1266  // read new style header
1267  std::unique_ptr<VersionCompat> pCompat( new VersionCompat( rIStm, StreamMode::READ ) );
1268 
1269  rIStm.ReadInt32( nType );
1270  sal_Int32 nLen;
1271  rIStm.ReadInt32( nLen );
1272  TypeSerializer aSerializer(rIStm);
1273  aSerializer.readSize(aSize);
1274  ReadMapMode( rIStm, aMapMode );
1275  }
1276  else
1277  {
1278  // read old style header
1279  sal_Int32 nWidth, nHeight;
1280  sal_Int32 nMapMode, nScaleNumX, nScaleDenomX;
1281  sal_Int32 nScaleNumY, nScaleDenomY, nOffsX, nOffsY;
1282 
1283  rIStm.SeekRel( -4 );
1284 
1285  sal_Int32 nLen;
1286  rIStm.ReadInt32( nType ).ReadInt32( nLen ).ReadInt32( nWidth ).ReadInt32( nHeight );
1287  rIStm.ReadInt32( nMapMode ).ReadInt32( nScaleNumX ).ReadInt32( nScaleDenomX ).ReadInt32( nScaleNumY );
1288  rIStm.ReadInt32( nScaleDenomY ).ReadInt32( nOffsX ).ReadInt32( nOffsY );
1289 
1290  // swapped
1291  if( nType > 100 )
1292  {
1293  nType = OSL_SWAPDWORD( nType );
1294  nWidth = OSL_SWAPDWORD( nWidth );
1295  nHeight = OSL_SWAPDWORD( nHeight );
1296  nMapMode = OSL_SWAPDWORD( nMapMode );
1297  nScaleNumX = OSL_SWAPDWORD( nScaleNumX );
1298  nScaleDenomX = OSL_SWAPDWORD( nScaleDenomX );
1299  nScaleNumY = OSL_SWAPDWORD( nScaleNumY );
1300  nScaleDenomY = OSL_SWAPDWORD( nScaleDenomY );
1301  nOffsX = OSL_SWAPDWORD( nOffsX );
1302  nOffsY = OSL_SWAPDWORD( nOffsY );
1303  }
1304 
1305  aSize = Size( nWidth, nHeight );
1306  aMapMode = MapMode( static_cast<MapUnit>(nMapMode), Point( nOffsX, nOffsY ),
1307  Fraction( nScaleNumX, nScaleDenomX ),
1308  Fraction( nScaleNumY, nScaleDenomY ) );
1309  }
1310 
1311  meType = static_cast<GraphicType>(nType);
1312 
1313  if( meType != GraphicType::NONE )
1314  {
1315  if( meType == GraphicType::Bitmap )
1316  {
1317  if(maVectorGraphicData.get() && maEx.IsEmpty())
1318  {
1319  // use maEx as local buffer for rendered svg
1320  maEx = maVectorGraphicData->getReplacement();
1321  }
1322 
1323  maEx.SetSizePixel(aSize);
1324 
1325  if( aMapMode != MapMode() )
1326  {
1327  maEx.SetPrefMapMode( aMapMode );
1328  maEx.SetPrefSize( aSize );
1329  }
1330  }
1331  else
1332  {
1333  maMetaFile.SetPrefMapMode( aMapMode );
1334  maMetaFile.SetPrefSize( aSize );
1335  }
1336 
1338  {
1339  ReadImpGraphic( rIStm, *this );
1340  bRet = rIStm.GetError() == ERRCODE_NONE;
1341  }
1342  else if( sal::static_int_cast<sal_uLong>(meType) >= SYS_WINMETAFILE
1343  && sal::static_int_cast<sal_uLong>(meType) <= SYS_MACMETAFILE )
1344  {
1345  Graphic aSysGraphic;
1346  ConvertDataFormat nCvtType;
1347 
1348  switch( sal::static_int_cast<sal_uLong>(meType) )
1349  {
1350  case SYS_WINMETAFILE:
1351  case SYS_WNTMETAFILE: nCvtType = ConvertDataFormat::WMF; break;
1352  case SYS_OS2METAFILE: nCvtType = ConvertDataFormat::MET; break;
1353  case SYS_MACMETAFILE: nCvtType = ConvertDataFormat::PCT; break;
1354 
1355  default:
1356  nCvtType = ConvertDataFormat::Unknown;
1357  break;
1358  }
1359 
1360  if( nType && GraphicConverter::Import( rIStm, aSysGraphic, nCvtType ) == ERRCODE_NONE )
1361  {
1362  *this = ImpGraphic( aSysGraphic.GetGDIMetaFile() );
1363  bRet = rIStm.GetError() == ERRCODE_NONE;
1364  }
1365  else
1367  }
1368 
1369  if( bRet )
1370  {
1371  ImplSetPrefMapMode( aMapMode );
1372  ImplSetPrefSize( aSize );
1373  }
1374  }
1375  else
1376  bRet = true;
1377 
1378  rIStm.SetEndian( nOldFormat );
1379 
1380  return bRet;
1381 }
1382 
1384 {
1385  bool bRet = false;
1386 
1387  ensureAvailable();
1388 
1390  {
1391  const MapMode aMapMode( ImplGetPrefMapMode() );
1392  const Size aSize( ImplGetPrefSize() );
1393  const SvStreamEndian nOldFormat = rOStm.GetEndian();
1394  sal_uLong nDataFieldPos;
1395 
1396  rOStm.SetEndian( SvStreamEndian::LITTLE );
1397 
1398  // write correct version ( old style/new style header )
1399  if( rOStm.GetVersion() >= SOFFICE_FILEFORMAT_50 )
1400  {
1401  // write ID for new format (5.0)
1402  rOStm.WriteUInt32( GRAPHIC_FORMAT_50 );
1403 
1404  // write new style header
1405  std::unique_ptr<VersionCompat> pCompat( new VersionCompat( rOStm, StreamMode::WRITE, 1 ) );
1406 
1407  rOStm.WriteInt32( static_cast<sal_Int32>(meType) );
1408 
1409  // data size is updated later
1410  nDataFieldPos = rOStm.Tell();
1411  rOStm.WriteInt32( 0 );
1412 
1413  TypeSerializer aSerializer(rOStm);
1414  aSerializer.writeSize(aSize);
1415 
1416  WriteMapMode( rOStm, aMapMode );
1417  }
1418  else
1419  {
1420  // write old style (<=4.0) header
1421  rOStm.WriteInt32( static_cast<sal_Int32>(meType) );
1422 
1423  // data size is updated later
1424  nDataFieldPos = rOStm.Tell();
1425  rOStm.WriteInt32( 0 );
1426  rOStm.WriteInt32( aSize.Width() );
1427  rOStm.WriteInt32( aSize.Height() );
1428  rOStm.WriteInt32( static_cast<sal_uInt16>(aMapMode.GetMapUnit()) );
1429  rOStm.WriteInt32( aMapMode.GetScaleX().GetNumerator() );
1430  rOStm.WriteInt32( aMapMode.GetScaleX().GetDenominator() );
1431  rOStm.WriteInt32( aMapMode.GetScaleY().GetNumerator() );
1432  rOStm.WriteInt32( aMapMode.GetScaleY().GetDenominator() );
1433  rOStm.WriteInt32( aMapMode.GetOrigin().X() );
1434  rOStm.WriteInt32( aMapMode.GetOrigin().Y() );
1435  }
1436 
1437  // write data block
1438  if( !rOStm.GetError() )
1439  {
1440  const sal_uLong nDataStart = rOStm.Tell();
1441 
1442  if( ImplIsSupportedGraphic() )
1443  WriteImpGraphic( rOStm, *this );
1444 
1445  if( !rOStm.GetError() )
1446  {
1447  const sal_uLong nStmPos2 = rOStm.Tell();
1448  rOStm.Seek( nDataFieldPos );
1449  rOStm.WriteInt32( nStmPos2 - nDataStart );
1450  rOStm.Seek( nStmPos2 );
1451  bRet = true;
1452  }
1453  }
1454 
1455  rOStm.SetEndian( nOldFormat );
1456  }
1457 
1458  return bRet;
1459 }
1460 
1462 {
1463  bool bRet = false;
1464 
1465  if( !ImplIsSwapOut() )
1466  {
1467  ::utl::TempFile aTempFile;
1468  const INetURLObject aTmpURL( aTempFile.GetURL() );
1469 
1470  if( !aTmpURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ).isEmpty() )
1471  {
1472  std::unique_ptr<SvStream> xOStm;
1473  try
1474  {
1475  xOStm = ::utl::UcbStreamHelper::CreateStream( aTmpURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ), StreamMode::READWRITE | StreamMode::SHARE_DENYWRITE );
1476  }
1477  catch( const css::uno::Exception& )
1478  {
1479  }
1480  if( xOStm )
1481  {
1482  xOStm->SetVersion( SOFFICE_FILEFORMAT_50 );
1483  xOStm->SetCompressMode( SvStreamCompressFlags::NATIVE );
1484 
1485  bRet = ImplSwapOut( xOStm.get() );
1486  if( bRet )
1487  {
1488  mpSwapFile = std::make_unique<ImpSwapFile>();
1489  mpSwapFile->aSwapURL = aTmpURL;
1490  mpSwapFile->maOriginURL = getOriginURL();
1491  }
1492  else
1493  {
1494  xOStm.reset();
1495 
1496  try
1497  {
1498  ::ucbhelper::Content aCnt( aTmpURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ),
1499  css::uno::Reference< css::ucb::XCommandEnvironment >(),
1501 
1502  aCnt.executeCommand( "delete", css::uno::makeAny( true ) );
1503  }
1504  catch( const css::ucb::ContentCreationException& )
1505  {
1506  }
1507  catch( const css::uno::RuntimeException& )
1508  {
1509  }
1510  catch( const css::ucb::CommandAbortedException& )
1511  {
1512  }
1513  catch( const css::uno::Exception& )
1514  {
1515  }
1516  }
1517  }
1518  }
1519  }
1520 
1521  if (bRet)
1523  return bRet;
1524 }
1525 
1527 {
1528  bool bRet = false;
1529 
1530  if( xOStm )
1531  {
1533 
1534  if( !xOStm->GetError() && ImplWriteEmbedded( *xOStm ) )
1535  {
1536  xOStm->Flush();
1537 
1538  if( !xOStm->GetError() )
1539  {
1542  bRet = mbSwapOut = true;
1543  }
1544  }
1545  }
1546  else
1547  {
1548  SAL_WARN("vcl.gdi", "Graphic SwapOut: No stream for swap out!");
1549  }
1550 
1551  return bRet;
1552 }
1553 
1555 {
1556  auto pThis = const_cast<ImpGraphic*>(this);
1557 
1558  if (ImplIsSwapOut())
1559  return pThis->ImplSwapIn();
1560 
1561  pThis->maLastUsed = std::chrono::high_resolution_clock::now();
1562  return true;
1563 }
1564 
1566 {
1567  Graphic aGraphic;
1568  if (mpGfxLink->LoadNative(aGraphic))
1569  {
1571 
1572  Size aPrefSize = maSwapInfo.maPrefSize;
1573  *this = *aGraphic.ImplGetImpGraphic();
1574  if (aPrefSize.getWidth() && aPrefSize.getHeight())
1575  {
1576  // Use custom preferred size if it was set when the graphic was still unloaded.
1577  ImplSetPrefSize(aPrefSize);
1578  }
1579 
1580  maGraphicExternalLink = aLink;
1581 
1582  return true;
1583  }
1584  return false;
1585 }
1586 
1588 {
1589  bool bRet = false;
1590 
1591  if (!ImplIsSwapOut())
1592  return bRet;
1593 
1594  if (mbPrepared)
1595  {
1596  bRet = loadPrepared();
1597  }
1598  else
1599  {
1600  OUString aSwapURL;
1601 
1602  if( mpSwapFile )
1603  aSwapURL = mpSwapFile->aSwapURL.GetMainURL( INetURLObject::DecodeMechanism::NONE );
1604 
1605  if( !aSwapURL.isEmpty() )
1606  {
1607  std::unique_ptr<SvStream> xIStm;
1608  try
1609  {
1610  xIStm = ::utl::UcbStreamHelper::CreateStream( aSwapURL, StreamMode::READWRITE | StreamMode::SHARE_DENYWRITE );
1611  }
1612  catch( const css::uno::Exception& )
1613  {
1614  }
1615 
1616  if( xIStm )
1617  {
1618  xIStm->SetVersion( SOFFICE_FILEFORMAT_50 );
1619  xIStm->SetCompressMode( SvStreamCompressFlags::NATIVE );
1620 
1621  bRet = ImplSwapIn( xIStm.get() );
1622  xIStm.reset();
1623  if (mpSwapFile)
1624  setOriginURL(mpSwapFile->maOriginURL);
1625  mpSwapFile.reset();
1626  }
1627  }
1628  }
1629 
1630  if (bRet)
1632 
1633  return bRet;
1634 }
1635 
1637 {
1638  bool bRet = false;
1639 
1640  if( xIStm )
1641  {
1643 
1644  if( !xIStm->GetError() )
1645  {
1646  //keep the swap file alive, because its quite possibly the backing storage
1647  //for xIStm
1648  std::shared_ptr<ImpSwapFile> xSwapFile(std::move(mpSwapFile));
1649  assert(!mpSwapFile);
1650 
1651  std::shared_ptr<GraphicReader> xContext(std::move(mpContext));
1652  assert(!mpContext);
1653 
1654  bool bDummyContext = mbDummyContext;
1655  mbDummyContext = false;
1656 
1657  bRet = ImplReadEmbedded( *xIStm );
1658 
1659  //restore ownership of the swap file and context
1660  mpSwapFile = std::move(xSwapFile);
1661  mpContext = std::move(xContext);
1662  mbDummyContext = bDummyContext;
1663 
1664  if (!bRet)
1665  {
1666  //throw away swapfile, etc.
1667  ImplClear();
1668  }
1669 
1670  mbSwapOut = false;
1671  }
1672  }
1673 
1674  return bRet;
1675 }
1676 
1677 void ImpGraphic::ImplSetLink(const std::shared_ptr<GfxLink>& rGfxLink)
1678 {
1679  ensureAvailable();
1680 
1681  mpGfxLink = rGfxLink;
1682 }
1683 
1684 std::shared_ptr<GfxLink> ImpGraphic::ImplGetSharedGfxLink() const
1685 {
1686  return mpGfxLink;
1687 }
1688 
1690 {
1691  ensureAvailable();
1692 
1693  return( mpGfxLink ? *mpGfxLink : GfxLink() );
1694 }
1695 
1697 {
1698  return ( bool(mpGfxLink) );
1699 }
1700 
1702 {
1703  if (mnChecksum != 0)
1704  return mnChecksum;
1705 
1706  BitmapChecksum nRet = 0;
1707 
1708  ensureAvailable();
1709 
1711  {
1712  switch( meType )
1713  {
1714  case GraphicType::Default:
1715  break;
1716 
1717  case GraphicType::Bitmap:
1718  {
1720  nRet = maVectorGraphicData->GetChecksum();
1721  else if (mpPdfData && !mpPdfData->empty())
1722  // Include the PDF data in the checksum, so a metafile with
1723  // and without PDF data is considered to be different.
1724  nRet = vcl_get_checksum(nRet, mpPdfData->data(), mpPdfData->size());
1725  else if( mpAnimation )
1726  nRet = mpAnimation->GetChecksum();
1727  else
1728  nRet = maEx.GetChecksum();
1729  }
1730  break;
1731 
1732  default:
1733  nRet = maMetaFile.GetChecksum();
1734  break;
1735  }
1736  }
1737 
1738  mnChecksum = nRet;
1739  return nRet;
1740 }
1741 
1743 {
1744  bool bResult = false;
1745 
1746  ensureAvailable();
1747 
1748  if( !rOStm.GetError() )
1749  {
1750  if( !ImplIsSwapOut() )
1751  {
1752  if( mpGfxLink && mpGfxLink->IsNative() )
1753  bResult = mpGfxLink->ExportNative( rOStm );
1754  else
1755  {
1756  WriteImpGraphic( rOStm, *this );
1757  bResult = ( rOStm.GetError() == ERRCODE_NONE );
1758  }
1759  }
1760  else
1762  }
1763 
1764  return bResult;
1765 }
1766 
1767 static std::map<BitmapChecksum, std::shared_ptr<std::vector<sal_Int8>>> sPdfDataCache;
1768 
1769 void ReadImpGraphic( SvStream& rIStm, ImpGraphic& rImpGraphic )
1770 {
1771  if (rIStm.GetError())
1772  return;
1773 
1774  const sal_uLong nStmPos1 = rIStm.Tell();
1775  sal_uInt32 nTmp;
1776 
1777  rImpGraphic.ImplClear();
1778 
1779  // read Id
1780  rIStm.ReadUInt32( nTmp );
1781 
1782  // if there is no more data, avoid further expensive
1783  // reading which will create VDevs and other stuff, just to
1784  // read nothing. CAUTION: Eof is only true AFTER reading another
1785  // byte, a speciality of SvMemoryStream (!)
1786  if (!rIStm.good())
1787  return;
1788 
1789  if (NATIVE_FORMAT_50 == nTmp)
1790  {
1791  Graphic aGraphic;
1792  GfxLink aLink;
1793 
1794  // read compat info
1795  std::unique_ptr<VersionCompat> pCompat(new VersionCompat( rIStm, StreamMode::READ ));
1796  pCompat.reset(); // destructor writes stuff into the header
1797 
1798  ReadGfxLink( rIStm, aLink );
1799 
1800  // set dummy link to avoid creation of additional link after filtering;
1801  // we set a default link to avoid unnecessary swapping of native data
1802  aGraphic.SetGfxLink(std::make_shared<GfxLink>());
1803 
1804  if( !rIStm.GetError() && aLink.LoadNative( aGraphic ) )
1805  {
1806  // set link only, if no other link was set
1807  const bool bSetLink = !rImpGraphic.mpGfxLink;
1808 
1809  // assign graphic
1810  rImpGraphic = *aGraphic.ImplGetImpGraphic();
1811 
1812  if( aLink.IsPrefMapModeValid() )
1813  rImpGraphic.ImplSetPrefMapMode( aLink.GetPrefMapMode() );
1814 
1815  if( aLink.IsPrefSizeValid() )
1816  rImpGraphic.ImplSetPrefSize( aLink.GetPrefSize() );
1817 
1818  if( bSetLink )
1819  rImpGraphic.ImplSetLink(std::make_shared<GfxLink>(aLink));
1820  }
1821  else
1822  {
1823  rIStm.Seek( nStmPos1 );
1825  }
1826  return;
1827  }
1828 
1829  BitmapEx aBmpEx;
1830  const SvStreamEndian nOldFormat = rIStm.GetEndian();
1831 
1832  rIStm.SeekRel( -4 );
1833  rIStm.SetEndian( SvStreamEndian::LITTLE );
1834  ReadDIBBitmapEx(aBmpEx, rIStm);
1835 
1836  if( !rIStm.GetError() )
1837  {
1838  sal_uInt32 nMagic1(0), nMagic2(0);
1839  sal_uLong nActPos = rIStm.Tell();
1840 
1841  rIStm.ReadUInt32( nMagic1 ).ReadUInt32( nMagic2 );
1842  rIStm.Seek( nActPos );
1843 
1844  rImpGraphic = ImpGraphic( aBmpEx );
1845 
1846  if( !rIStm.GetError() && ( 0x5344414e == nMagic1 ) && ( 0x494d4931 == nMagic2 ) )
1847  {
1848  rImpGraphic.mpAnimation = std::make_unique<Animation>();
1849  ReadAnimation( rIStm, *rImpGraphic.mpAnimation );
1850 
1851  // #108077# manually set loaded BmpEx to Animation
1852  // (which skips loading its BmpEx if already done)
1853  rImpGraphic.mpAnimation->SetBitmapEx(aBmpEx);
1854  }
1855  else
1856  rIStm.ResetError();
1857  }
1858  else
1859  {
1860  GDIMetaFile aMtf;
1861 
1862  rIStm.Seek( nStmPos1 );
1863  rIStm.ResetError();
1864  ReadGDIMetaFile( rIStm, aMtf );
1865 
1866  if( !rIStm.GetError() )
1867  {
1868  rImpGraphic = aMtf;
1869  }
1870  else
1871  {
1872  ErrCode nOrigError = rIStm.GetErrorCode();
1873  // try to stream in Svg defining data (length, byte array and evtl. path)
1874  // See below (operator<<) for more information
1875  const sal_uInt32 nSvgMagic((sal_uInt32('s') << 24) | (sal_uInt32('v') << 16) | (sal_uInt32('g') << 8) | sal_uInt32('0'));
1876  const sal_uInt32 nWmfMagic((sal_uInt32('w') << 24) | (sal_uInt32('m') << 16) | (sal_uInt32('f') << 8) | sal_uInt32('0'));
1877  const sal_uInt32 nEmfMagic((sal_uInt32('e') << 24) | (sal_uInt32('m') << 16) | (sal_uInt32('f') << 8) | sal_uInt32('0'));
1878  sal_uInt32 nMagic;
1879  rIStm.Seek(nStmPos1);
1880  rIStm.ResetError();
1881  rIStm.ReadUInt32( nMagic );
1882 
1883  if (nSvgMagic == nMagic || nWmfMagic == nMagic || nEmfMagic == nMagic)
1884  {
1885  sal_uInt32 nVectorGraphicDataArrayLength(0);
1886  rIStm.ReadUInt32(nVectorGraphicDataArrayLength);
1887 
1888  if (nVectorGraphicDataArrayLength)
1889  {
1890  VectorGraphicDataArray aNewData(nVectorGraphicDataArrayLength);
1891 
1892  rIStm.ReadBytes(aNewData.getArray(), nVectorGraphicDataArrayLength);
1893  OUString aPath = rIStm.ReadUniOrByteString(rIStm.GetStreamCharSet());
1894 
1895  if (!rIStm.GetError())
1896  {
1898 
1899  if (nWmfMagic == nMagic)
1900  {
1901  aDataType = VectorGraphicDataType::Wmf;
1902  }
1903  else if (nEmfMagic == nMagic)
1904  {
1905  aDataType = VectorGraphicDataType::Emf;
1906  }
1907 
1908  VectorGraphicDataPtr aVectorGraphicDataPtr(new VectorGraphicData(aNewData, aPath, aDataType));
1909  rImpGraphic = aVectorGraphicDataPtr;
1910  }
1911  }
1912  }
1913  else if (nMagic == nPdfMagic)
1914  {
1915  // Stream in PDF data.
1916  BitmapChecksum nPdfId = 0;
1917  rIStm.ReadUInt64(nPdfId);
1918 
1919  rImpGraphic.mnPageNumber = 0;
1920  rIStm.ReadInt32(rImpGraphic.mnPageNumber);
1921 
1922  auto it = sPdfDataCache.find(nPdfId);
1923  assert(it != sPdfDataCache.end());
1924 
1925  rImpGraphic.mpPdfData = it->second;
1926 
1927  Bitmap aBitmap;
1928  rImpGraphic.maEx = aBitmap;
1929 
1930  std::vector<Bitmap> aBitmaps;
1931  if (vcl::RenderPDFBitmaps(rImpGraphic.mpPdfData->data(), rImpGraphic.mpPdfData->size(), aBitmaps, rImpGraphic.mnPageNumber, 1) == 1)
1932  rImpGraphic.maEx = aBitmaps[0];
1933 
1934  rImpGraphic.meType = GraphicType::Bitmap;
1935  }
1936  else
1937  {
1938  rIStm.SetError(nOrigError);
1939  }
1940 
1941  rIStm.Seek(nStmPos1);
1942  }
1943  }
1944 
1945  rIStm.SetEndian( nOldFormat );
1946 }
1947 
1948 void WriteImpGraphic(SvStream& rOStm, const ImpGraphic& rImpGraphic)
1949 {
1950  if (rOStm.GetError())
1951  return;
1952 
1953  rImpGraphic.ensureAvailable();
1954 
1955  if (rImpGraphic.ImplIsSwapOut())
1956  {
1958  return;
1959  }
1960 
1961  if( ( rOStm.GetVersion() >= SOFFICE_FILEFORMAT_50 ) &&
1962  ( rOStm.GetCompressMode() & SvStreamCompressFlags::NATIVE ) &&
1963  rImpGraphic.mpGfxLink && rImpGraphic.mpGfxLink->IsNative() &&
1964  !rImpGraphic.hasPdfData())
1965  {
1966  // native format
1967  rOStm.WriteUInt32( NATIVE_FORMAT_50 );
1968 
1969  // write compat info
1970  std::unique_ptr<VersionCompat> pCompat(new VersionCompat( rOStm, StreamMode::WRITE, 1 ));
1971  pCompat.reset(); // destructor writes stuff into the header
1972 
1973  rImpGraphic.mpGfxLink->SetPrefMapMode( rImpGraphic.ImplGetPrefMapMode() );
1974  rImpGraphic.mpGfxLink->SetPrefSize( rImpGraphic.ImplGetPrefSize() );
1975  WriteGfxLink( rOStm, *rImpGraphic.mpGfxLink );
1976  }
1977  else
1978  {
1979  // own format
1980  const SvStreamEndian nOldFormat = rOStm.GetEndian();
1981  rOStm.SetEndian( SvStreamEndian::LITTLE );
1982 
1983  switch( rImpGraphic.ImplGetType() )
1984  {
1985  case GraphicType::NONE:
1986  case GraphicType::Default:
1987  break;
1988 
1989  case GraphicType::Bitmap:
1990  {
1991  if(rImpGraphic.getVectorGraphicData().get())
1992  {
1993  // stream out Vector Graphic defining data (length, byte array and evtl. path)
1994  // this is used e.g. in swapping out graphic data and in transporting it over UNO API
1995  // as sequence of bytes, but AFAIK not written anywhere to any kind of file, so it should be
1996  // no problem to extend it; only used at runtime
1997  switch (rImpGraphic.getVectorGraphicData()->getVectorGraphicDataType())
1998  {
2000  {
2001  const sal_uInt32 nWmfMagic((sal_uInt32('w') << 24) | (sal_uInt32('m') << 16) | (sal_uInt32('f') << 8) | sal_uInt32('0'));
2002  rOStm.WriteUInt32(nWmfMagic);
2003  break;
2004  }
2006  {
2007  const sal_uInt32 nEmfMagic((sal_uInt32('e') << 24) | (sal_uInt32('m') << 16) | (sal_uInt32('f') << 8) | sal_uInt32('0'));
2008  rOStm.WriteUInt32(nEmfMagic);
2009  break;
2010  }
2011  default: // case VectorGraphicDataType::Svg:
2012  {
2013  const sal_uInt32 nSvgMagic((sal_uInt32('s') << 24) | (sal_uInt32('v') << 16) | (sal_uInt32('g') << 8) | sal_uInt32('0'));
2014  rOStm.WriteUInt32(nSvgMagic);
2015  break;
2016  }
2017  }
2018 
2019  rOStm.WriteUInt32( rImpGraphic.getVectorGraphicData()->getVectorGraphicDataArrayLength() );
2020  rOStm.WriteBytes(rImpGraphic.getVectorGraphicData()->getVectorGraphicDataArray().getConstArray(),
2021  rImpGraphic.getVectorGraphicData()->getVectorGraphicDataArrayLength());
2022  rOStm.WriteUniOrByteString(rImpGraphic.getVectorGraphicData()->getPath(),
2023  rOStm.GetStreamCharSet());
2024  }
2025  else if (rImpGraphic.hasPdfData())
2026  {
2027  BitmapChecksum nPdfId = vcl_get_checksum(0, rImpGraphic.mpPdfData->data(), rImpGraphic.mpPdfData->size());
2028  if (sPdfDataCache.find(nPdfId) == sPdfDataCache.end())
2029  sPdfDataCache.emplace(nPdfId, rImpGraphic.mpPdfData);
2030 
2031  // Stream out PDF data.
2032  rOStm.WriteUInt32(nPdfMagic);
2033  rOStm.WriteUInt64(nPdfId);
2034  rOStm.WriteInt32(rImpGraphic.mnPageNumber);
2035  }
2036  else if( rImpGraphic.ImplIsAnimated())
2037  {
2038  WriteAnimation( rOStm, *rImpGraphic.mpAnimation );
2039  }
2040  else
2041  {
2042  WriteDIBBitmapEx(rImpGraphic.maEx, rOStm);
2043  }
2044  }
2045  break;
2046 
2047  default:
2048  {
2049  if( rImpGraphic.ImplIsSupportedGraphic() )
2050  WriteGDIMetaFile( rOStm, rImpGraphic.maMetaFile );
2051  }
2052  break;
2053  }
2054 
2055  rOStm.SetEndian( nOldFormat );
2056  }
2057 }
2058 
2059 /* 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:837
sal_uInt64 BitmapChecksum
Definition: checksum.hxx:30
std::shared_ptr< GraphicReader > mpContext
Definition: impgraph.hxx:80
SvStream & WriteUInt64(sal_uInt64 nuInt64)
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:1003
PrimitiveType meType
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:1767
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:831
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:1461
void ImplSetPrefMapMode(const MapMode &rPrefMapMode)
Definition: impgraph.cxx:1048
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:1383
void Clear()
Definition: gdimtf.cxx:244
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:1554
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:616
#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:1684
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:1249
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:2705
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:1197
void Play(GDIMetaFile &rMtf)
Definition: gdimtf.cxx:296
sal_uInt32 ImplGetAnimationLoopCount() const
Definition: impgraph.cxx:1235
GDIMetaFile GetMonochromeMtf(const Color &rCol) const
Definition: gdimtf.cxx:2181
GraphicType meType
Definition: impgraph.hxx:83
const Size & GetSize_100TH_MM() const
BitmapChecksum ImplGetChecksum() const
Definition: impgraph.cxx:1701
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
Bitmap GetBitmap(const Color *pTransReplaceColor=nullptr) const
Definition: bitmapex.cxx:236
SvStream & ReadUInt32(sal_uInt32 &rUInt32)
std::shared_ptr< ImpSwapFile > mpSwapFile
Definition: impgraph.hxx:81
bool IsEmpty() const
Definition: bitmapex.cxx:203
NONE
void SetPrefMapMode(const MapMode &rMapMode)
Definition: bitmap.hxx:561
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:570
const Size & GetPrefSize() const
Definition: gdimtf.hxx:173
const Size & GetSizePixel() const
bool loadPrepared()
Definition: impgraph.cxx:1565
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:781
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:1769
static Manager & get()
Definition: Manager.cxx:56
QPRO_FUNC_TYPE const nType
void ImplSetAnimationNotifyHdl(const Link< Animation *, void > &rLink)
Definition: impgraph.cxx:1215
BitmapChecksum mnChecksum
Definition: impgraph.hxx:89
friend void WriteImpGraphic(SvStream &rOStm, const ImpGraphic &rImpGraphic)
Definition: impgraph.cxx:1948
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:1742
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:571
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:527
bool IsTransparent() const
Definition: bitmapex.cxx:221
Link< Animation *, void > ImplGetAnimationNotifyHdl() const
Definition: impgraph.cxx:1223
void WriteImpGraphic(SvStream &rOStm, const ImpGraphic &rImpGraphic)
Definition: impgraph.cxx:1948
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:1281
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)
std::shared_ptr< VectorGraphicData > VectorGraphicDataPtr
OUString GetMainURL(DecodeMechanism eMechanism, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
Size ImplGetPrefSize() const
Definition: impgraph.cxx:914
std::chrono::high_resolution_clock::time_point maLastUsed
Definition: impgraph.hxx:98
SvStreamEndian GetEndian() const
void Stop()
Definition: gdimtf.cxx:514
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:1677
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:1120
sal_Int32 GetDenominator() const
void ImplClearGraphics()
Definition: impgraph.cxx:502
BitmapChecksum GetChecksum() const
Definition: gdimtf.cxx:2196
#define ERRCODE_NONE
Definition: errcode.hxx:198
bool Scale(const Size &rNewSize, BmpScaleFlag nScaleFlag=BmpScaleFlag::Default)
Scale the bitmap.
Definition: bitmap3.cxx:818
void AddAction(const rtl::Reference< MetaAction > &pAction)
Definition: gdimtf.cxx:540
sal_uLong ImplGetSizeBytes() const
Definition: impgraph.cxx:1088
bool IsTransparent() const
MetaAction * GetAction(size_t nAction) const
Definition: gdimtf.cxx:158
SvStream & ReadGDIMetaFile(SvStream &rIStm, GDIMetaFile &rGDIMetaFile, ImplMetaReadData *pData)
Definition: gdimtf.cxx:2621
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:153
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:902
constexpr::Color COL_WHITE(0xFF, 0xFF, 0xFF)
const Point & GetOrigin() const
Definition: mapmod.cxx:170
Animation ImplGetAnimation() const
Definition: impgraph.cxx:820
MetaActionType GetType() const
Definition: metaact.hxx:89
void ImplStopAnimation(OutputDevice *pOutputDevice, long nExtraData)
Definition: impgraph.cxx:1207
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:1696
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:1243
bool getAntiAliase() const
Definition: graph.hxx:100
bool hasPdfData() const
Definition: impgraph.hxx:144
void ImplSetPrefSize(const Size &rPrefSize)
Definition: impgraph.cxx:963
GraphicExternalLink maGraphicExternalLink
Definition: impgraph.hxx:96
GfxLink ImplGetLink()
Definition: impgraph.cxx:1689
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:1769
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:1587
void setHeight(long nHeight)
sal_uLong GetSizeBytes() const
Definition: gdimtf.cxx:2540