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