LibreOffice Module vcl (master)  1
BitmapEx.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/log.hxx>
21 #include <rtl/math.hxx>
23 #include <osl/diagnose.h>
26 
27 #include <vcl/ImageTree.hxx>
28 #include <vcl/outdev.hxx>
29 #include <vcl/alpha.hxx>
30 #include <vcl/bitmapex.hxx>
31 #include <vcl/svapp.hxx>
32 #include <vcl/virdev.hxx>
33 #include <vcl/settings.hxx>
35 
36 // BitmapEx::Create
37 #include <salbmp.hxx>
38 #include <salinst.hxx>
39 #include <svdata.hxx>
41 
42 #include <o3tl/any.hxx>
43 
44 #include <com/sun/star/beans/XFastPropertySet.hpp>
45 
46 #include <memory>
47 
48 using namespace ::com::sun::star;
49 
51  : meTransparent(TransparentType::NONE)
52  , mbAlpha(false)
53 {
54 }
55 
56 BitmapEx::BitmapEx( const BitmapEx& ) = default;
57 
58 BitmapEx::BitmapEx( const BitmapEx& rBitmapEx, Point aSrc, Size aSize )
59  : meTransparent(TransparentType::NONE)
60  , mbAlpha(false)
61 {
62  if( rBitmapEx.IsEmpty() )
63  return;
64 
65  maBitmap = Bitmap( aSize, rBitmapEx.maBitmap.GetBitCount() );
66  SetSizePixel(aSize);
67  if( rBitmapEx.IsAlpha() )
68  {
69  mbAlpha = true;
70  maMask = AlphaMask( aSize ).ImplGetBitmap();
71  }
72  else if( rBitmapEx.IsTransparent() )
73  maMask = Bitmap( aSize, rBitmapEx.maMask.GetBitCount() );
74 
75  tools::Rectangle aDestRect( Point( 0, 0 ), aSize );
76  tools::Rectangle aSrcRect( aSrc, aSize );
77  CopyPixel( aDestRect, aSrcRect, &rBitmapEx );
78 }
79 
80 BitmapEx::BitmapEx( Size aSize, sal_uInt16 nBitCount )
81  : meTransparent(TransparentType::NONE)
82  , mbAlpha(false)
83 {
84  maBitmap = Bitmap( aSize, nBitCount );
85  SetSizePixel(aSize);
86 }
87 
88 BitmapEx::BitmapEx( const OUString& rIconName )
89  : meTransparent(TransparentType::NONE)
90  , mbAlpha(false)
91 {
92  loadFromIconTheme( rIconName );
93 }
94 
95 void BitmapEx::loadFromIconTheme( const OUString& rIconName )
96 {
97  bool bSuccess;
98  OUString aIconTheme;
99 
100  try
101  {
103  bSuccess = ImageTree::get().loadImage(rIconName, aIconTheme, *this, true);
104  }
105  catch (...)
106  {
107  bSuccess = false;
108  }
109 
110  SAL_WARN_IF( !bSuccess, "vcl", "BitmapEx::BitmapEx(): could not load image " << rIconName << " via icon theme " << aIconTheme);
111 }
112 
113 BitmapEx::BitmapEx( const Bitmap& rBmp ) :
114  maBitmap ( rBmp ),
115  maBitmapSize ( maBitmap.GetSizePixel() ),
116  meTransparent( TransparentType::NONE ),
117  mbAlpha ( false )
118 {
119 }
120 
121 BitmapEx::BitmapEx( const Bitmap& rBmp, const Bitmap& rMask ) :
122  maBitmap ( rBmp ),
123  maMask ( rMask ),
124  maBitmapSize ( maBitmap.GetSizePixel() ),
125  meTransparent ( !rMask ? TransparentType::NONE : TransparentType::Bitmap ),
126  mbAlpha ( false )
127 {
128  // Ensure a mask is exactly one bit deep,
129  // alternatively also allow 8bpp masks.
130  if( !!maMask && maMask.GetBitCount() != 1 && !(maMask.GetBitCount() == 8 && maMask.HasGreyPalette8Bit()))
131  {
132  SAL_WARN( "vcl", "BitmapEx: forced mask to monochrome");
133  BitmapEx aMaskEx(maMask);
135  maMask = aMaskEx.GetBitmap();
136  }
137 
139  {
140  OSL_ENSURE(false, "Mask size differs from Bitmap size, corrected Mask (!)");
142  }
143 }
144 
145 BitmapEx::BitmapEx( const Bitmap& rBmp, const AlphaMask& rAlphaMask ) :
146  maBitmap ( rBmp ),
147  maMask ( rAlphaMask.ImplGetBitmap() ),
148  maBitmapSize ( maBitmap.GetSizePixel() ),
149  meTransparent ( !rAlphaMask ? TransparentType::NONE : TransparentType::Bitmap ),
150  mbAlpha ( !rAlphaMask.IsEmpty() )
151 {
153  {
154  OSL_ENSURE(false, "Alpha size differs from Bitmap size, corrected Mask (!)");
155  maMask.Scale(rBmp.GetSizePixel());
156  }
157 }
158 
159 BitmapEx::BitmapEx( const Bitmap& rBmp, const Color& rTransparentColor ) :
160  maBitmap ( rBmp ),
161  maBitmapSize ( maBitmap.GetSizePixel() ),
162  maTransparentColor ( rTransparentColor ),
163  meTransparent ( TransparentType::Bitmap ),
164  mbAlpha ( false )
165 {
167 
168  SAL_WARN_IF(rBmp.GetSizePixel() != maMask.GetSizePixel(), "vcl",
169  "BitmapEx::BitmapEx(): size mismatch for bitmap and alpha mask.");
170 }
171 
172 BitmapEx& BitmapEx::operator=( const BitmapEx& ) = default;
173 
174 bool BitmapEx::operator==( const BitmapEx& rBitmapEx ) const
175 {
176  if (meTransparent != rBitmapEx.meTransparent)
177  return false;
178 
179  if (GetSizePixel() != rBitmapEx.GetSizePixel())
180  return false;
181 
182  if (meTransparent != rBitmapEx.meTransparent)
183  return false;
184 
186  && maTransparentColor != rBitmapEx.maTransparentColor)
187  return false;
188 
189  if (mbAlpha != rBitmapEx.mbAlpha)
190  return false;
191 
192  if (maBitmap != rBitmapEx.maBitmap)
193  return false;
194 
195  return maMask == rBitmapEx.maMask;
196 }
197 
198 bool BitmapEx::IsEmpty() const
199 {
200  return( maBitmap.IsEmpty() && maMask.IsEmpty() );
201 }
202 
204 {
205  maBitmap.SetEmpty();
206  maMask.SetEmpty();
208  mbAlpha = false;
209 }
210 
212 {
213  SetEmpty();
214 }
215 
217 {
219 }
220 
221 bool BitmapEx::IsAlpha() const
222 {
223  return( IsTransparent() && mbAlpha );
224 }
225 
227 {
228  return maBitmap;
229 }
230 
231 Bitmap BitmapEx::GetBitmap( Color aTransparentReplaceColor ) const
232 {
233  Bitmap aRetBmp( maBitmap );
234 
236  {
237  Bitmap aTempMask;
238 
240  aTempMask = maBitmap.CreateMask( maTransparentColor );
241  else
242  aTempMask = maMask;
243 
244  if( !IsAlpha() )
245  aRetBmp.Replace( aTempMask, aTransparentReplaceColor );
246  else
247  aRetBmp.Replace( GetAlpha(), aTransparentReplaceColor );
248  }
249 
250  return aRetBmp;
251 }
252 
254 {
255  if (!IsAlpha())
256  return maMask;
257 
258  BitmapEx aMaskEx(maMask);
260  return aMaskEx.GetBitmap();
261 }
262 
264 {
265  if( IsAlpha() )
266  {
267  AlphaMask aAlpha;
268  aAlpha.ImplSetBitmap( maMask );
269  return aAlpha;
270  }
271  else
272  {
273  return AlphaMask(maMask);
274  }
275 }
276 
278 {
279  sal_uLong nSizeBytes = maBitmap.GetSizeBytes();
280 
282  nSizeBytes += maMask.GetSizeBytes();
283 
284  return nSizeBytes;
285 }
286 
288 {
290  SVBT32 aBT32;
291 
292  UInt32ToSVBT32( o3tl::underlyingEnumValue(meTransparent), aBT32 );
293  nCrc = vcl_get_checksum( nCrc, aBT32, 4 );
294 
295  UInt32ToSVBT32( sal_uInt32(mbAlpha), aBT32 );
296  nCrc = vcl_get_checksum( nCrc, aBT32, 4 );
297 
299  {
301  BCToBCOA( maMask.GetChecksum(), aBCOA );
302  nCrc = vcl_get_checksum( nCrc, aBCOA, BITMAP_CHECKSUM_SIZE );
303  }
304 
305  return nCrc;
306 }
307 
308 void BitmapEx::SetSizePixel(const Size& rNewSize)
309 {
310  maBitmapSize = rNewSize;
311 }
312 
314 {
315  bool bRet = false;
316 
317  if (!!maBitmap)
318  {
319  bRet = maBitmap.Invert();
320 
321  if (bRet && (meTransparent == TransparentType::Color))
323  }
324 
325  return bRet;
326 }
327 
328 bool BitmapEx::Mirror( BmpMirrorFlags nMirrorFlags )
329 {
330  bool bRet = false;
331 
332  if( !!maBitmap )
333  {
334  bRet = maBitmap.Mirror( nMirrorFlags );
335 
336  if( bRet && ( meTransparent == TransparentType::Bitmap ) && !!maMask )
337  maMask.Mirror( nMirrorFlags );
338  }
339 
340  return bRet;
341 }
342 
343 bool BitmapEx::Scale( const double& rScaleX, const double& rScaleY, BmpScaleFlag nScaleFlag )
344 {
345  bool bRet = false;
346 
347  if( !!maBitmap )
348  {
349  bRet = maBitmap.Scale( rScaleX, rScaleY, nScaleFlag );
350 
351  if( bRet && ( meTransparent == TransparentType::Bitmap ) && !!maMask )
352  {
353  maMask.Scale( rScaleX, rScaleY, nScaleFlag );
354  }
355 
357 
359  "BitmapEx::Scale(): size mismatch for bitmap and alpha mask." );
360  }
361 
362  return bRet;
363 }
364 
365 bool BitmapEx::Scale( const Size& rNewSize, BmpScaleFlag nScaleFlag )
366 {
367  bool bRet;
368 
369  if (GetSizePixel().Width() && GetSizePixel().Height()
370  && (rNewSize.Width() != GetSizePixel().Width()
371  || rNewSize.Height() != GetSizePixel().Height() ) )
372  {
373  bRet = Scale( static_cast<double>(rNewSize.Width()) / GetSizePixel().Width(),
374  static_cast<double>(rNewSize.Height()) / GetSizePixel().Height(),
375  nScaleFlag );
376  }
377  else
378  {
379  bRet = true;
380  }
381 
382  return bRet;
383 }
384 
385 bool BitmapEx::Rotate( Degree10 nAngle10, const Color& rFillColor )
386 {
387  bool bRet = false;
388 
389  if( !!maBitmap )
390  {
391  const bool bTransRotate = ( COL_TRANSPARENT == rFillColor );
392 
393  if( bTransRotate )
394  {
396  bRet = maBitmap.Rotate( nAngle10, maTransparentColor );
397  else
398  {
399  bRet = maBitmap.Rotate( nAngle10, COL_BLACK );
400 
402  {
403  maMask = Bitmap(GetSizePixel(), 1);
406  }
407 
408  if( bRet && !!maMask )
409  maMask.Rotate( nAngle10, COL_WHITE );
410  }
411  }
412  else
413  {
414  bRet = maBitmap.Rotate( nAngle10, rFillColor );
415 
416  if( bRet && ( meTransparent == TransparentType::Bitmap ) && !!maMask )
417  maMask.Rotate( nAngle10, COL_WHITE );
418  }
419 
421 
423  "BitmapEx::Rotate(): size mismatch for bitmap and alpha mask.");
424  }
425 
426  return bRet;
427 }
428 
429 bool BitmapEx::Crop( const tools::Rectangle& rRectPixel )
430 {
431  bool bRet = false;
432 
433  if( !!maBitmap )
434  {
435  bRet = maBitmap.Crop( rRectPixel );
436 
437  if( bRet && ( meTransparent == TransparentType::Bitmap ) && !!maMask )
438  maMask.Crop( rRectPixel );
439 
441 
443  "BitmapEx::Crop(): size mismatch for bitmap and alpha mask.");
444  }
445 
446  return bRet;
447 }
448 
449 bool BitmapEx::Convert( BmpConversion eConversion )
450 {
451  return !!maBitmap && maBitmap.Convert( eConversion );
452 }
453 
454 void BitmapEx::Expand( sal_uLong nDX, sal_uLong nDY, bool bExpandTransparent )
455 {
456  bool bRet = false;
457 
458  if( !maBitmap )
459  return;
460 
461  bRet = maBitmap.Expand( nDX, nDY );
462 
463  if( bRet && ( meTransparent == TransparentType::Bitmap ) && !!maMask )
464  {
465  Color aColor( bExpandTransparent ? COL_WHITE : COL_BLACK );
466  maMask.Expand( nDX, nDY, &aColor );
467  }
468 
470 
472  "BitmapEx::Expand(): size mismatch for bitmap and alpha mask.");
473 }
474 
475 bool BitmapEx::CopyPixel( const tools::Rectangle& rRectDst, const tools::Rectangle& rRectSrc,
476  const BitmapEx* pBmpExSrc )
477 {
478  bool bRet = false;
479 
480  if( !pBmpExSrc || pBmpExSrc->IsEmpty() )
481  {
482  if( !maBitmap.IsEmpty() )
483  {
484  bRet = maBitmap.CopyPixel( rRectDst, rRectSrc );
485 
486  if( bRet && ( meTransparent == TransparentType::Bitmap ) && !!maMask )
487  maMask.CopyPixel( rRectDst, rRectSrc );
488  }
489  }
490  else
491  {
492  if( !maBitmap.IsEmpty() )
493  {
494  bRet = maBitmap.CopyPixel( rRectDst, rRectSrc, &pBmpExSrc->maBitmap );
495 
496  if( bRet )
497  {
498  if( pBmpExSrc->IsAlpha() )
499  {
500  if( IsAlpha() )
501  // cast to use the optimized AlphaMask::CopyPixel
502  maMask.CopyPixel_AlphaOptimized( rRectDst, rRectSrc, &pBmpExSrc->maMask );
503  else if( IsTransparent() )
504  {
505  std::unique_ptr<AlphaMask> pAlpha(new AlphaMask( maMask ));
506 
507  maMask = pAlpha->ImplGetBitmap();
508  pAlpha.reset();
509  mbAlpha = true;
510  maMask.CopyPixel( rRectDst, rRectSrc, &pBmpExSrc->maMask );
511  }
512  else
513  {
514  sal_uInt8 cBlack = 0;
515  std::unique_ptr<AlphaMask> pAlpha(new AlphaMask(GetSizePixel(), &cBlack));
516 
517  maMask = pAlpha->ImplGetBitmap();
518  pAlpha.reset();
520  mbAlpha = true;
521  maMask.CopyPixel( rRectDst, rRectSrc, &pBmpExSrc->maMask );
522  }
523  }
524  else if( pBmpExSrc->IsTransparent() )
525  {
526  if (IsAlpha())
527  {
528  AlphaMask aAlpha( pBmpExSrc->maMask );
529  maMask.CopyPixel( rRectDst, rRectSrc, &aAlpha.ImplGetBitmap() );
530  }
531  else if (IsTransparent())
532  {
533  maMask.CopyPixel( rRectDst, rRectSrc, &pBmpExSrc->maMask );
534  }
535  else
536  {
537  maMask = Bitmap(GetSizePixel(), 1);
540  maMask.CopyPixel( rRectDst, rRectSrc, &pBmpExSrc->maMask );
541  }
542  }
543  else if (IsAlpha())
544  {
545  sal_uInt8 cBlack = 0;
546  const AlphaMask aAlphaSrc(pBmpExSrc->GetSizePixel(), &cBlack);
547 
548  maMask.CopyPixel( rRectDst, rRectSrc, &aAlphaSrc.ImplGetBitmap() );
549  }
550  else if (IsTransparent())
551  {
552  Bitmap aMaskSrc(pBmpExSrc->GetSizePixel(), 1);
553 
554  aMaskSrc.Erase( COL_BLACK );
555  maMask.CopyPixel( rRectDst, rRectSrc, &aMaskSrc );
556  }
557  }
558  }
559  }
560 
561  return bRet;
562 }
563 
564 bool BitmapEx::Erase( const Color& rFillColor )
565 {
566  bool bRet = false;
567 
568  if( !!maBitmap )
569  {
570  bRet = maBitmap.Erase( rFillColor );
571 
572  if( bRet && ( meTransparent == TransparentType::Bitmap ) && !!maMask )
573  {
574  // Respect transparency on fill color
575  if( rFillColor.IsTransparent() )
576  {
577  const Color aFill( 255 - rFillColor.GetAlpha(), 255 - rFillColor.GetAlpha(), 255 - rFillColor.GetAlpha() );
578  maMask.Erase( aFill );
579  }
580  else
581  {
582  const Color aBlack( COL_BLACK );
583  maMask.Erase( aBlack );
584  }
585  }
586  }
587 
588  return bRet;
589 }
590 
591 void BitmapEx::Replace( const Color& rSearchColor, const Color& rReplaceColor )
592 {
593  if (!!maBitmap)
594  maBitmap.Replace( rSearchColor, rReplaceColor );
595 }
596 
597 void BitmapEx::Replace( const Color* pSearchColors, const Color* pReplaceColors, size_t nColorCount )
598 {
599  if (!!maBitmap)
600  maBitmap.Replace( pSearchColors, pReplaceColors, nColorCount, /*pTols*/nullptr );
601 }
602 
603 bool BitmapEx::Adjust( short nLuminancePercent, short nContrastPercent,
604  short nChannelRPercent, short nChannelGPercent, short nChannelBPercent,
605  double fGamma, bool bInvert, bool msoBrightness )
606 {
607  return !!maBitmap && maBitmap.Adjust( nLuminancePercent, nContrastPercent,
608  nChannelRPercent, nChannelGPercent, nChannelBPercent,
609  fGamma, bInvert, msoBrightness );
610 }
611 
612 void BitmapEx::Draw( OutputDevice* pOutDev, const Point& rDestPt ) const
613 {
614  pOutDev->DrawBitmapEx( rDestPt, *this );
615 }
616 
618  const Point& rDestPt, const Size& rDestSize ) const
619 {
620  pOutDev->DrawBitmapEx( rDestPt, rDestSize, *this );
621 }
622 
623 BitmapEx BitmapEx:: AutoScaleBitmap(BitmapEx const & aBitmap, const tools::Long aStandardSize)
624 {
625  Point aEmptyPoint(0,0);
626  double imgposX = 0;
627  double imgposY = 0;
628  BitmapEx aRet = aBitmap;
629  double imgOldWidth = aRet.GetSizePixel().Width();
630  double imgOldHeight = aRet.GetSizePixel().Height();
631 
632  if (imgOldWidth >= aStandardSize || imgOldHeight >= aStandardSize)
633  {
634  sal_Int32 imgNewWidth = 0;
635  sal_Int32 imgNewHeight = 0;
636  if (imgOldWidth >= imgOldHeight)
637  {
638  imgNewWidth = aStandardSize;
639  imgNewHeight = sal_Int32(imgOldHeight / (imgOldWidth / aStandardSize) + 0.5);
640  imgposX = 0;
641  imgposY = (aStandardSize - (imgOldHeight / (imgOldWidth / aStandardSize) + 0.5)) / 2 + 0.5;
642  }
643  else
644  {
645  imgNewHeight = aStandardSize;
646  imgNewWidth = sal_Int32(imgOldWidth / (imgOldHeight / aStandardSize) + 0.5);
647  imgposY = 0;
648  imgposX = (aStandardSize - (imgOldWidth / (imgOldHeight / aStandardSize) + 0.5)) / 2 + 0.5;
649  }
650 
651  Size aScaledSize( imgNewWidth, imgNewHeight );
652  aRet.Scale( aScaledSize, BmpScaleFlag::BestQuality );
653  }
654  else
655  {
656  imgposX = (aStandardSize - imgOldWidth) / 2 + 0.5;
657  imgposY = (aStandardSize - imgOldHeight) / 2 + 0.5;
658  }
659 
660  Size aStdSize( aStandardSize, aStandardSize );
661  tools::Rectangle aRect(aEmptyPoint, aStdSize );
662 
665  aVirDevice->SetOutputSizePixel( aStdSize );
666  aVirDevice->SetFillColor( COL_TRANSPARENT );
667  aVirDevice->SetLineColor( COL_TRANSPARENT );
668 
669  // Draw a rect into virDevice
670  aVirDevice->DrawRect( aRect );
671  Point aPointPixel( static_cast<tools::Long>(imgposX), static_cast<tools::Long>(imgposY) );
672  aVirDevice->DrawBitmapEx( aPointPixel, aRet );
673  aRet = aVirDevice->GetBitmapEx( aEmptyPoint, aStdSize );
674 
675  return aRet;
676 }
677 
678 sal_uInt8 BitmapEx::GetAlpha(sal_Int32 nX, sal_Int32 nY) const
679 {
680  sal_uInt8 nAlpha(0);
681 
682  if(!maBitmap.IsEmpty())
683  {
684  if (nX >= 0 && nX < GetSizePixel().Width() && nY >= 0 && nY < GetSizePixel().Height())
685  {
686  if (maBitmap.GetBitCount() == 32)
687  return GetPixelColor(nX, nY).GetAlpha();
688  switch(meTransparent)
689  {
691  {
692  // Not transparent, ergo all covered
693  nAlpha = 255;
694  break;
695  }
697  {
698  Bitmap aTestBitmap(maBitmap);
699  Bitmap::ScopedReadAccess pRead(aTestBitmap);
700 
701  if(pRead)
702  {
703  const BitmapColor aBmpColor = pRead->GetColor(nY, nX);
704 
705  // If color is not equal to TransparentColor, we are not transparent
706  if (aBmpColor != maTransparentColor)
707  nAlpha = 255;
708 
709  }
710  break;
711  }
713  {
714  if(!maMask.IsEmpty())
715  {
716  Bitmap aTestBitmap(maMask);
717  Bitmap::ScopedReadAccess pRead(aTestBitmap);
718 
719  if(pRead)
720  {
721  const BitmapColor aBitmapColor(pRead->GetPixel(nY, nX));
722 
723  if(mbAlpha)
724  {
725  nAlpha = 255 - aBitmapColor.GetIndex();
726  }
727  else
728  {
729  if(0x00 == aBitmapColor.GetIndex())
730  {
731  nAlpha = 255;
732  }
733  }
734  }
735  }
736  break;
737  }
738  }
739  }
740  }
741 
742  return nAlpha;
743 }
744 
745 
746 Color BitmapEx::GetPixelColor(sal_Int32 nX, sal_Int32 nY) const
747 {
748  Bitmap::ScopedReadAccess pReadAccess( const_cast<Bitmap&>(maBitmap) );
749  assert(pReadAccess);
750 
751  BitmapColor aColor = pReadAccess->GetColor(nY, nX);
752 
753  if (IsAlpha())
754  {
755  AlphaMask aAlpha = GetAlpha();
756  AlphaMask::ScopedReadAccess pAlphaReadAccess(aAlpha);
757  aColor.SetAlpha(255 - pAlphaReadAccess->GetPixel(nY, nX).GetIndex());
758  }
759  else if (maBitmap.GetBitCount() != 32)
760  {
761  aColor.SetAlpha(255);
762  }
763  return aColor;
764 }
765 
766 // Shift alpha transparent pixels between cppcanvas/ implementations
767 // and vcl in a generally grotesque and under-performing fashion
768 bool BitmapEx::Create( const css::uno::Reference< css::rendering::XBitmapCanvas > &xBitmapCanvas,
769  const Size &rSize )
770 {
771  uno::Reference< beans::XFastPropertySet > xFastPropertySet( xBitmapCanvas, uno::UNO_QUERY );
772  if( xFastPropertySet )
773  {
774  // 0 means get BitmapEx
775  uno::Any aAny = xFastPropertySet->getFastPropertyValue( 0 );
776  std::unique_ptr<BitmapEx> xBitmapEx(reinterpret_cast<BitmapEx*>(*o3tl::doAccess<sal_Int64>(aAny)));
777  if( xBitmapEx )
778  {
779  *this = *xBitmapEx;
780  return true;
781  }
782  }
783 
784  std::shared_ptr<SalBitmap> pSalBmp;
785  std::shared_ptr<SalBitmap> pSalMask;
786 
787  pSalBmp = ImplGetSVData()->mpDefInst->CreateSalBitmap();
788 
789  Size aLocalSize(rSize);
790  if( pSalBmp->Create( xBitmapCanvas, aLocalSize ) )
791  {
792  pSalMask = ImplGetSVData()->mpDefInst->CreateSalBitmap();
793  if ( pSalMask->Create( xBitmapCanvas, aLocalSize, true ) )
794  {
795  *this = BitmapEx(Bitmap(pSalBmp), Bitmap(pSalMask) );
796  return true;
797  }
798  else
799  {
800  *this = BitmapEx(Bitmap(pSalBmp));
801  return true;
802  }
803  }
804 
805  return false;
806 }
807 
808 namespace
809 {
810  Bitmap impTransformBitmap(
811  const Bitmap& rSource,
812  const Size& rDestinationSize,
813  const basegfx::B2DHomMatrix& rTransform,
814  bool bSmooth)
815  {
816  Bitmap aDestination(rDestinationSize, 24);
817  BitmapScopedWriteAccess xWrite(aDestination);
818 
819  if(xWrite)
820  {
821  Bitmap::ScopedReadAccess xRead(const_cast< Bitmap& >(rSource));
822 
823  if (xRead)
824  {
825  const Size aDestinationSizePixel(aDestination.GetSizePixel());
826  const BitmapColor aOutside(BitmapColor(0xff, 0xff, 0xff));
827 
828  for(tools::Long y(0); y < aDestinationSizePixel.getHeight(); y++)
829  {
830  Scanline pScanline = xWrite->GetScanline( y );
831  for(tools::Long x(0); x < aDestinationSizePixel.getWidth(); x++)
832  {
833  const basegfx::B2DPoint aSourceCoor(rTransform * basegfx::B2DPoint(x, y));
834 
835  if(bSmooth)
836  {
837  xWrite->SetPixelOnData(
838  pScanline,
839  x,
840  xRead->GetInterpolatedColorWithFallback(
841  aSourceCoor.getY(),
842  aSourceCoor.getX(),
843  aOutside));
844  }
845  else
846  {
847  // this version does the correct <= 0.0 checks, so no need
848  // to do the static_cast< sal_Int32 > self and make an error
849  xWrite->SetPixelOnData(
850  pScanline,
851  x,
852  xRead->GetColorWithFallback(
853  aSourceCoor.getY(),
854  aSourceCoor.getX(),
855  aOutside));
856  }
857  }
858  }
859  }
860  }
861  xWrite.reset();
862 
863  rSource.AdaptBitCount(aDestination);
864 
865  return aDestination;
866  }
867 
869  bool implTransformNeedsSmooth(const basegfx::B2DHomMatrix& rTransformation)
870  {
871  basegfx::B2DVector aScale, aTranslate;
872  double fRotate, fShearX;
873  rTransformation.decompose(aScale, aTranslate, fRotate, fShearX);
874  if (aScale != basegfx::B2DVector(1, 1))
875  {
876  return true;
877  }
878 
879  fRotate = fmod( fRotate, F_2PI );
880  if (fRotate < 0)
881  {
882  fRotate += F_2PI;
883  }
884  if (!rtl::math::approxEqual(fRotate, 0)
885  && !rtl::math::approxEqual(fRotate, F_PI2)
886  && !rtl::math::approxEqual(fRotate, F_PI)
887  && !rtl::math::approxEqual(fRotate, 3 * F_PI2))
888  {
889  return true;
890  }
891 
892  if (!rtl::math::approxEqual(fShearX, 0))
893  {
894  return true;
895  }
896 
897  return false;
898  }
899 } // end of anonymous namespace
900 
902  double fWidth,
903  double fHeight,
904  const basegfx::B2DHomMatrix& rTransformation) const
905 {
906  if(fWidth <= 1 || fHeight <= 1)
907  return BitmapEx();
908 
909  // force destination to 24 bit, we want to smooth output
910  const Size aDestinationSize(basegfx::fround(fWidth), basegfx::fround(fHeight));
911  bool bSmooth = implTransformNeedsSmooth(rTransformation);
912  const Bitmap aDestination(impTransformBitmap(GetBitmap(), aDestinationSize, rTransformation, bSmooth));
913 
914  // create mask
915  if(IsTransparent())
916  {
917  if(IsAlpha())
918  {
919  const Bitmap aAlpha(impTransformBitmap(GetAlpha().GetBitmap(), aDestinationSize, rTransformation, bSmooth));
920  return BitmapEx(aDestination, AlphaMask(aAlpha));
921  }
922  else
923  {
924  const Bitmap aLclMask(impTransformBitmap(GetMask(), aDestinationSize, rTransformation, false));
925  return BitmapEx(aDestination, aLclMask);
926  }
927  }
928 
929  return BitmapEx(aDestination);
930 }
931 
933  const basegfx::B2DHomMatrix& rTransformation,
934  const basegfx::B2DRange& rVisibleRange,
935  double fMaximumArea) const
936 {
937  BitmapEx aRetval;
938 
939  if(IsEmpty())
940  return aRetval;
941 
942  const sal_uInt32 nSourceWidth(GetSizePixel().Width());
943  const sal_uInt32 nSourceHeight(GetSizePixel().Height());
944 
945  if(!nSourceWidth || !nSourceHeight)
946  return aRetval;
947 
948  // Get aOutlineRange
949  basegfx::B2DRange aOutlineRange(0.0, 0.0, 1.0, 1.0);
950 
951  aOutlineRange.transform(rTransformation);
952 
953  // create visible range from it by moving from relative to absolute
954  basegfx::B2DRange aVisibleRange(rVisibleRange);
955 
956  aVisibleRange.transform(
958  aOutlineRange.getRange(),
959  aOutlineRange.getMinimum()));
960 
961  // get target size (which is visible range's size)
962  double fWidth(aVisibleRange.getWidth());
963  double fHeight(aVisibleRange.getHeight());
964 
965  if(fWidth < 1.0 || fHeight < 1.0)
966  {
967  return aRetval;
968  }
969 
970  // test if discrete size (pixel) maybe too big and limit it
971  const double fArea(fWidth * fHeight);
972  const bool bNeedToReduce(basegfx::fTools::more(fArea, fMaximumArea));
973  double fReduceFactor(1.0);
974 
975  if(bNeedToReduce)
976  {
977  fReduceFactor = sqrt(fMaximumArea / fArea);
978  fWidth *= fReduceFactor;
979  fHeight *= fReduceFactor;
980  }
981 
982  // Build complete transform from source pixels to target pixels.
983  // Start by scaling from source pixel size to unit coordinates
984  basegfx::B2DHomMatrix aTransform(
986  1.0 / nSourceWidth,
987  1.0 / nSourceHeight));
988 
989  // multiply with given transform which leads from unit coordinates inside
990  // aOutlineRange
991  aTransform = rTransformation * aTransform;
992 
993  // subtract top-left of absolute VisibleRange
994  aTransform.translate(
995  -aVisibleRange.getMinX(),
996  -aVisibleRange.getMinY());
997 
998  // scale to target pixels (if needed)
999  if(bNeedToReduce)
1000  {
1001  aTransform.scale(fReduceFactor, fReduceFactor);
1002  }
1003 
1004  // invert to get transformation from target pixel coordinates to source pixels
1005  aTransform.invert();
1006 
1007  // create bitmap using source, destination and linear back-transformation
1008  aRetval = TransformBitmapEx(fWidth, fHeight, aTransform);
1009 
1010  return aRetval;
1011 }
1012 
1013 BitmapEx BitmapEx::ModifyBitmapEx(const basegfx::BColorModifierStack& rBColorModifierStack) const
1014 {
1015  Bitmap aChangedBitmap(GetBitmap());
1016  bool bDone(false);
1017 
1018  for(sal_uInt32 a(rBColorModifierStack.count()); a && !bDone; )
1019  {
1020  const basegfx::BColorModifierSharedPtr& rModifier = rBColorModifierStack.getBColorModifier(--a);
1021  const basegfx::BColorModifier_replace* pReplace = dynamic_cast< const basegfx::BColorModifier_replace* >(rModifier.get());
1022 
1023  if(pReplace)
1024  {
1025  // complete replace
1026  if(IsTransparent())
1027  {
1028  // clear bitmap with dest color
1029  if(aChangedBitmap.GetBitCount() <= 8)
1030  {
1031  // For e.g. 8bit Bitmaps, the nearest color to the given erase color is
1032  // determined and used -> this may be different from what is wanted here.
1033  // Better create a new bitmap with the needed color explicitly.
1034  Bitmap::ScopedReadAccess xReadAccess(aChangedBitmap);
1035  OSL_ENSURE(xReadAccess, "Got no Bitmap ReadAccess ?!?");
1036 
1037  if(xReadAccess)
1038  {
1039  BitmapPalette aNewPalette(xReadAccess->GetPalette());
1040  aNewPalette[0] = BitmapColor(Color(pReplace->getBColor()));
1041  aChangedBitmap = Bitmap(
1042  aChangedBitmap.GetSizePixel(),
1043  aChangedBitmap.GetBitCount(),
1044  &aNewPalette);
1045  }
1046  }
1047  aChangedBitmap.Erase(Color(pReplace->getBColor()));
1048  }
1049  else
1050  {
1051  // erase bitmap, caller will know to paint direct
1052  aChangedBitmap.SetEmpty();
1053  }
1054 
1055  bDone = true;
1056  }
1057  else
1058  {
1059  BitmapScopedWriteAccess xContent(aChangedBitmap);
1060 
1061  if(xContent)
1062  {
1063  const double fConvertColor(1.0 / 255.0);
1064 
1065  if(xContent->HasPalette())
1066  {
1067  const sal_uInt16 nCount(xContent->GetPaletteEntryCount());
1068 
1069  for(sal_uInt16 b(0); b < nCount; b++)
1070  {
1071  const BitmapColor& rCol = xContent->GetPaletteColor(b);
1072  const basegfx::BColor aBSource(
1073  rCol.GetRed() * fConvertColor,
1074  rCol.GetGreen() * fConvertColor,
1075  rCol.GetBlue() * fConvertColor);
1076  const basegfx::BColor aBDest(rModifier->getModifiedColor(aBSource));
1077  xContent->SetPaletteColor(b, BitmapColor(Color(aBDest)));
1078  }
1079  }
1080  else if(ScanlineFormat::N24BitTcBgr == xContent->GetScanlineFormat())
1081  {
1082  for(tools::Long y(0); y < xContent->Height(); y++)
1083  {
1084  Scanline pScan = xContent->GetScanline(y);
1085 
1086  for(tools::Long x(0); x < xContent->Width(); x++)
1087  {
1088  const basegfx::BColor aBSource(
1089  *(pScan + 2)* fConvertColor,
1090  *(pScan + 1) * fConvertColor,
1091  *pScan * fConvertColor);
1092  const basegfx::BColor aBDest(rModifier->getModifiedColor(aBSource));
1093  *pScan++ = static_cast< sal_uInt8 >(aBDest.getBlue() * 255.0);
1094  *pScan++ = static_cast< sal_uInt8 >(aBDest.getGreen() * 255.0);
1095  *pScan++ = static_cast< sal_uInt8 >(aBDest.getRed() * 255.0);
1096  }
1097  }
1098  }
1099  else if(ScanlineFormat::N24BitTcRgb == xContent->GetScanlineFormat())
1100  {
1101  for(tools::Long y(0); y < xContent->Height(); y++)
1102  {
1103  Scanline pScan = xContent->GetScanline(y);
1104 
1105  for(tools::Long x(0); x < xContent->Width(); x++)
1106  {
1107  const basegfx::BColor aBSource(
1108  *pScan * fConvertColor,
1109  *(pScan + 1) * fConvertColor,
1110  *(pScan + 2) * fConvertColor);
1111  const basegfx::BColor aBDest(rModifier->getModifiedColor(aBSource));
1112  *pScan++ = static_cast< sal_uInt8 >(aBDest.getRed() * 255.0);
1113  *pScan++ = static_cast< sal_uInt8 >(aBDest.getGreen() * 255.0);
1114  *pScan++ = static_cast< sal_uInt8 >(aBDest.getBlue() * 255.0);
1115  }
1116  }
1117  }
1118  else
1119  {
1120  for(tools::Long y(0); y < xContent->Height(); y++)
1121  {
1122  Scanline pScanline = xContent->GetScanline( y );
1123  for(tools::Long x(0); x < xContent->Width(); x++)
1124  {
1125  const BitmapColor aBMCol(xContent->GetColor(y, x));
1126  const basegfx::BColor aBSource(
1127  static_cast<double>(aBMCol.GetRed()) * fConvertColor,
1128  static_cast<double>(aBMCol.GetGreen()) * fConvertColor,
1129  static_cast<double>(aBMCol.GetBlue()) * fConvertColor);
1130  const basegfx::BColor aBDest(rModifier->getModifiedColor(aBSource));
1131 
1132  xContent->SetPixelOnData(pScanline, x, BitmapColor(Color(aBDest)));
1133  }
1134  }
1135  }
1136  }
1137  }
1138  }
1139 
1140  if(aChangedBitmap.IsEmpty())
1141  {
1142  return BitmapEx();
1143  }
1144  else
1145  {
1146  if(IsTransparent())
1147  {
1148  if(IsAlpha())
1149  {
1150  return BitmapEx(aChangedBitmap, GetAlpha());
1151  }
1152  else
1153  {
1154  return BitmapEx(aChangedBitmap, GetMask());
1155  }
1156  }
1157  else
1158  {
1159  return BitmapEx(aChangedBitmap);
1160  }
1161  }
1162 }
1163 
1165  const Size& rSize,
1166  sal_uInt8 nAlpha,
1167  Color aColorTopLeft,
1168  Color aColorBottomRight)
1169 {
1170  const sal_uInt32 nW(rSize.Width());
1171  const sal_uInt32 nH(rSize.Height());
1172 
1173  if(nW || nH)
1174  {
1175  Color aColTopRight(aColorTopLeft);
1176  Color aColBottomLeft(aColorTopLeft);
1177  const sal_uInt32 nDE(nW + nH);
1178 
1179  aColTopRight.Merge(aColorBottomRight, 255 - sal_uInt8((nW * 255) / nDE));
1180  aColBottomLeft.Merge(aColorBottomRight, 255 - sal_uInt8((nH * 255) / nDE));
1181 
1182  return createBlendFrame(rSize, nAlpha, aColorTopLeft, aColTopRight, aColorBottomRight, aColBottomLeft);
1183  }
1184 
1185  return BitmapEx();
1186 }
1187 
1189  const Size& rSize,
1190  sal_uInt8 nAlpha,
1191  Color aColorTopLeft,
1192  Color aColorTopRight,
1193  Color aColorBottomRight,
1194  Color aColorBottomLeft)
1195 {
1196  BlendFrameCache* pBlendFrameCache = ImplGetBlendFrameCache();
1197 
1198  if(pBlendFrameCache->m_aLastSize == rSize
1199  && pBlendFrameCache->m_nLastAlpha == nAlpha
1200  && pBlendFrameCache->m_aLastColorTopLeft == aColorTopLeft
1201  && pBlendFrameCache->m_aLastColorTopRight == aColorTopRight
1202  && pBlendFrameCache->m_aLastColorBottomRight == aColorBottomRight
1203  && pBlendFrameCache->m_aLastColorBottomLeft == aColorBottomLeft)
1204  {
1205  return pBlendFrameCache->m_aLastResult;
1206  }
1207 
1208  pBlendFrameCache->m_aLastSize = rSize;
1209  pBlendFrameCache->m_nLastAlpha = nAlpha;
1210  pBlendFrameCache->m_aLastColorTopLeft = aColorTopLeft;
1211  pBlendFrameCache->m_aLastColorTopRight = aColorTopRight;
1212  pBlendFrameCache->m_aLastColorBottomRight = aColorBottomRight;
1213  pBlendFrameCache->m_aLastColorBottomLeft = aColorBottomLeft;
1214  pBlendFrameCache->m_aLastResult.Clear();
1215 
1216  const tools::Long nW(rSize.Width());
1217  const tools::Long nH(rSize.Height());
1218 
1219  if(nW > 1 && nH > 1)
1220  {
1221  sal_uInt8 aEraseTrans(0xff);
1222  Bitmap aContent(rSize, 24);
1223  AlphaMask aAlpha(rSize, &aEraseTrans);
1224 
1225  aContent.Erase(COL_BLACK);
1226 
1228  AlphaScopedWriteAccess pAlpha(aAlpha);
1229 
1230  if(pContent && pAlpha)
1231  {
1232  tools::Long x(0);
1233  tools::Long y(0);
1234  Scanline pScanContent = pContent->GetScanline( 0 );
1235  Scanline pScanAlpha = pContent->GetScanline( 0 );
1236 
1237  // x == 0, y == 0, top-left corner
1238  pContent->SetPixelOnData(pScanContent, 0, aColorTopLeft);
1239  pAlpha->SetPixelOnData(pScanAlpha, 0, BitmapColor(nAlpha));
1240 
1241  // y == 0, top line left to right
1242  for(x = 1; x < nW - 1; x++)
1243  {
1244  Color aMix(aColorTopLeft);
1245 
1246  aMix.Merge(aColorTopRight, 255 - sal_uInt8((x * 255) / nW));
1247  pContent->SetPixelOnData(pScanContent, x, aMix);
1248  pAlpha->SetPixelOnData(pScanAlpha, x, BitmapColor(nAlpha));
1249  }
1250 
1251  // x == nW - 1, y == 0, top-right corner
1252  // #i123690# Caution! When nW is 1, x == nW is possible (!)
1253  if(x < nW)
1254  {
1255  pContent->SetPixelOnData(pScanContent, x, aColorTopRight);
1256  pAlpha->SetPixelOnData(pScanAlpha, x, BitmapColor(nAlpha));
1257  }
1258 
1259  // x == 0 and nW - 1, left and right line top-down
1260  for(y = 1; y < nH - 1; y++)
1261  {
1262  pScanContent = pContent->GetScanline( y );
1263  pScanAlpha = pContent->GetScanline( y );
1264  Color aMixA(aColorTopLeft);
1265 
1266  aMixA.Merge(aColorBottomLeft, 255 - sal_uInt8((y * 255) / nH));
1267  pContent->SetPixelOnData(pScanContent, 0, aMixA);
1268  pAlpha->SetPixelOnData(pScanAlpha, 0, BitmapColor(nAlpha));
1269 
1270  // #i123690# Caution! When nW is 1, x == nW is possible (!)
1271  if(x < nW)
1272  {
1273  Color aMixB(aColorTopRight);
1274 
1275  aMixB.Merge(aColorBottomRight, 255 - sal_uInt8((y * 255) / nH));
1276  pContent->SetPixelOnData(pScanContent, x, aMixB);
1277  pAlpha->SetPixelOnData(pScanAlpha, x, BitmapColor(nAlpha));
1278  }
1279  }
1280 
1281  // #i123690# Caution! When nH is 1, y == nH is possible (!)
1282  if(y < nH)
1283  {
1284  // x == 0, y == nH - 1, bottom-left corner
1285  pContent->SetPixelOnData(pScanContent, 0, aColorBottomLeft);
1286  pAlpha->SetPixelOnData(pScanAlpha, 0, BitmapColor(nAlpha));
1287 
1288  // y == nH - 1, bottom line left to right
1289  for(x = 1; x < nW - 1; x++)
1290  {
1291  Color aMix(aColorBottomLeft);
1292 
1293  aMix.Merge(aColorBottomRight, 255 - sal_uInt8(((x - 0)* 255) / nW));
1294  pContent->SetPixelOnData(pScanContent, x, aMix);
1295  pAlpha->SetPixelOnData(pScanAlpha, x, BitmapColor(nAlpha));
1296  }
1297 
1298  // x == nW - 1, y == nH - 1, bottom-right corner
1299  // #i123690# Caution! When nW is 1, x == nW is possible (!)
1300  if(x < nW)
1301  {
1302  pContent->SetPixelOnData(pScanContent, x, aColorBottomRight);
1303  pAlpha->SetPixelOnData(pScanAlpha, x, BitmapColor(nAlpha));
1304  }
1305  }
1306 
1307  pContent.reset();
1308  pAlpha.reset();
1309 
1310  pBlendFrameCache->m_aLastResult = BitmapEx(aContent, aAlpha);
1311  }
1312  }
1313 
1314  return pBlendFrameCache->m_aLastResult;
1315 }
1316 
1317 void BitmapEx::Replace(const Color& rSearchColor,
1318  const Color& rReplaceColor,
1319  sal_uInt8 nTolerance)
1320 {
1321  maBitmap.Replace(rSearchColor, rReplaceColor, nTolerance);
1322 }
1323 
1324 void BitmapEx::Replace( const Color* pSearchColors,
1325  const Color* pReplaceColors,
1326  size_t nColorCount,
1327  sal_uInt8 const * pTols )
1328 {
1329  maBitmap.Replace( pSearchColors, pReplaceColors, nColorCount, pTols );
1330 }
1331 
1333 {
1334  if( IsTransparent() )
1335  {
1336  maBitmap.Replace( GetMask(), rColor );
1337  maMask = Bitmap();
1341  mbAlpha = false;
1342  }
1343 }
1344 
1345 static Bitmap DetectEdges( const Bitmap& rBmp )
1346 {
1347  constexpr sal_uInt8 cEdgeDetectThreshold = 128;
1348  const Size aSize( rBmp.GetSizePixel() );
1349  Bitmap aRetBmp;
1350 
1351  if( ( aSize.Width() > 2 ) && ( aSize.Height() > 2 ) )
1352  {
1353  Bitmap aWorkBmp( rBmp );
1354 
1355  if( aWorkBmp.Convert( BmpConversion::N8BitGreys ) )
1356  {
1357  bool bRet = false;
1358 
1360  pVirDev->SetOutputSizePixel(aSize);
1361  Bitmap::ScopedReadAccess pReadAcc(aWorkBmp);
1362 
1363  if( pReadAcc )
1364  {
1365  const tools::Long nWidth = aSize.Width();
1366  const tools::Long nWidth2 = nWidth - 2;
1367  const tools::Long nHeight = aSize.Height();
1368  const tools::Long nHeight2 = nHeight - 2;
1369  const tools::Long lThres2 = static_cast<tools::Long>(cEdgeDetectThreshold) * cEdgeDetectThreshold;
1370  tools::Long nSum1;
1371  tools::Long nSum2;
1372  tools::Long lGray;
1373 
1374  // initialize border with white pixels
1375  pVirDev->SetLineColor( COL_WHITE );
1376  pVirDev->DrawLine( Point(), Point( nWidth - 1, 0L ) );
1377  pVirDev->DrawLine( Point( nWidth - 1, 0L ), Point( nWidth - 1, nHeight - 1 ) );
1378  pVirDev->DrawLine( Point( nWidth - 1, nHeight - 1 ), Point( 0L, nHeight - 1 ) );
1379  pVirDev->DrawLine( Point( 0, nHeight - 1 ), Point() );
1380 
1381  for( tools::Long nY = 0, nY1 = 1, nY2 = 2; nY < nHeight2; nY++, nY1++, nY2++ )
1382  {
1383  Scanline pScanlineRead = pReadAcc->GetScanline( nY );
1384  Scanline pScanlineRead1 = pReadAcc->GetScanline( nY1 );
1385  Scanline pScanlineRead2 = pReadAcc->GetScanline( nY2 );
1386  for( tools::Long nX = 0, nXDst = 1, nXTmp; nX < nWidth2; nX++, nXDst++ )
1387  {
1388  nXTmp = nX;
1389 
1390  nSum2 = pReadAcc->GetIndexFromData( pScanlineRead, nXTmp++ );
1391  nSum1 = -nSum2;
1392  nSum2 += static_cast<tools::Long>(pReadAcc->GetIndexFromData( pScanlineRead, nXTmp++ )) << 1;
1393  lGray = pReadAcc->GetIndexFromData( pScanlineRead, nXTmp );
1394  nSum1 += lGray;
1395  nSum2 += lGray;
1396 
1397  nSum1 += static_cast<tools::Long>(pReadAcc->GetIndexFromData( pScanlineRead1, nXTmp )) << 1;
1398  nXTmp -= 2;
1399  nSum1 -= static_cast<tools::Long>(pReadAcc->GetIndexFromData( pScanlineRead1, nXTmp )) << 1;
1400 
1401  lGray = -static_cast<tools::Long>(pReadAcc->GetIndexFromData( pScanlineRead2, nXTmp++ ));
1402  nSum1 += lGray;
1403  nSum2 += lGray;
1404  nSum2 -= static_cast<tools::Long>(pReadAcc->GetIndexFromData( pScanlineRead2, nXTmp++ )) << 1;
1405  lGray = static_cast<tools::Long>(pReadAcc->GetIndexFromData( pScanlineRead2, nXTmp ));
1406  nSum1 += lGray;
1407  nSum2 -= lGray;
1408 
1409  if( ( nSum1 * nSum1 + nSum2 * nSum2 ) < lThres2 )
1410  pVirDev->DrawPixel( Point(nXDst, nY), COL_WHITE );
1411  else
1412  pVirDev->DrawPixel( Point(nXDst, nY), COL_BLACK );
1413  }
1414  }
1415 
1416  bRet = true;
1417  }
1418 
1419  pReadAcc.reset();
1420 
1421  if( bRet )
1422  aRetBmp = pVirDev->GetBitmap(Point(0,0), aSize);
1423  }
1424  }
1425 
1426  if( !aRetBmp )
1427  aRetBmp = rBmp;
1428  else
1429  {
1430  aRetBmp.SetPrefMapMode( rBmp.GetPrefMapMode() );
1431  aRetBmp.SetPrefSize( rBmp.GetPrefSize() );
1432  }
1433 
1434  return aRetBmp;
1435 }
1436 
1438 tools::Polygon BitmapEx::GetContour( bool bContourEdgeDetect,
1439  const tools::Rectangle* pWorkRectPixel )
1440 {
1441  Bitmap aWorkBmp;
1442  tools::Polygon aRetPoly;
1443  tools::Rectangle aWorkRect( Point(), maBitmap.GetSizePixel() );
1444 
1445  if( pWorkRectPixel )
1446  aWorkRect.Intersection( *pWorkRectPixel );
1447 
1448  aWorkRect.Justify();
1449 
1450  if( ( aWorkRect.GetWidth() > 4 ) && ( aWorkRect.GetHeight() > 4 ) )
1451  {
1452  // if the flag is set, we need to detect edges
1453  if( bContourEdgeDetect )
1454  aWorkBmp = DetectEdges( maBitmap );
1455  else
1456  aWorkBmp = maBitmap;
1457 
1458  BitmapReadAccess* pAcc = aWorkBmp.AcquireReadAccess();
1459 
1460  const tools::Long nWidth = pAcc ? pAcc->Width() : 0;
1461  const tools::Long nHeight = pAcc ? pAcc->Height() : 0;
1462 
1463  if (pAcc && nWidth && nHeight)
1464  {
1465  const Size& rPrefSize = aWorkBmp.GetPrefSize();
1466  const double fFactorX = static_cast<double>(rPrefSize.Width()) / nWidth;
1467  const double fFactorY = static_cast<double>(rPrefSize.Height()) / nHeight;
1468  const tools::Long nStartX1 = aWorkRect.Left() + 1;
1469  const tools::Long nEndX1 = aWorkRect.Right();
1470  const tools::Long nStartX2 = nEndX1 - 1;
1471  const tools::Long nStartY1 = aWorkRect.Top() + 1;
1472  const tools::Long nEndY1 = aWorkRect.Bottom();
1473  std::unique_ptr<Point[]> pPoints1;
1474  std::unique_ptr<Point[]> pPoints2;
1475  tools::Long nX, nY;
1476  sal_uInt16 nPolyPos = 0;
1477  const BitmapColor aBlack = pAcc->GetBestMatchingColor( COL_BLACK );
1478 
1479  pPoints1.reset(new Point[ nHeight ]);
1480  pPoints2.reset(new Point[ nHeight ]);
1481 
1482  for ( nY = nStartY1; nY < nEndY1; nY++ )
1483  {
1484  nX = nStartX1;
1485  Scanline pScanline = pAcc->GetScanline( nY );
1486 
1487  // scan row from left to right
1488  while( nX < nEndX1 )
1489  {
1490  if( aBlack == pAcc->GetPixelFromData( pScanline, nX ) )
1491  {
1492  pPoints1[ nPolyPos ] = Point( nX, nY );
1493  nX = nStartX2;
1494 
1495  // this loop always breaks eventually as there is at least one pixel
1496  while( true )
1497  {
1498  if( aBlack == pAcc->GetPixelFromData( pScanline, nX ) )
1499  {
1500  pPoints2[ nPolyPos ] = Point( nX, nY );
1501  break;
1502  }
1503 
1504  nX--;
1505  }
1506 
1507  nPolyPos++;
1508  break;
1509  }
1510 
1511  nX++;
1512  }
1513  }
1514 
1515  const sal_uInt16 nNewSize1 = nPolyPos << 1;
1516 
1517  aRetPoly = tools::Polygon( nPolyPos, pPoints1.get() );
1518  aRetPoly.SetSize( nNewSize1 + 1 );
1519  aRetPoly[ nNewSize1 ] = aRetPoly[ 0 ];
1520 
1521  for( sal_uInt16 j = nPolyPos; nPolyPos < nNewSize1; )
1522  aRetPoly[ nPolyPos++ ] = pPoints2[ --j ];
1523 
1524  if( ( fFactorX != 0. ) && ( fFactorY != 0. ) )
1525  aRetPoly.Scale( fFactorX, fFactorY );
1526  }
1527 
1528  Bitmap::ReleaseAccess(pAcc);
1529  }
1530 
1531  return aRetPoly;
1532 }
1533 
1534 void BitmapEx::setAlphaFrom( sal_uInt8 cIndexFrom, sal_Int8 nAlphaTo )
1535 {
1536  AlphaMask aAlphaMask(GetAlpha());
1537  BitmapScopedWriteAccess pWriteAccess(aAlphaMask);
1538  Bitmap::ScopedReadAccess pReadAccess(maBitmap);
1539  assert( pReadAccess.get() && pWriteAccess.get() );
1540  if ( !(pReadAccess.get() && pWriteAccess.get()) )
1541  return;
1542 
1543  for ( tools::Long nY = 0; nY < pReadAccess->Height(); nY++ )
1544  {
1545  Scanline pScanline = pWriteAccess->GetScanline( nY );
1546  Scanline pScanlineRead = pReadAccess->GetScanline( nY );
1547  for ( tools::Long nX = 0; nX < pReadAccess->Width(); nX++ )
1548  {
1549  const sal_uInt8 cIndex = pReadAccess->GetPixelFromData( pScanlineRead, nX ).GetIndex();
1550  if ( cIndex == cIndexFrom )
1551  pWriteAccess->SetPixelOnData( pScanline, nX, BitmapColor(nAlphaTo) );
1552  }
1553  }
1554  *this = BitmapEx( GetBitmap(), aAlphaMask );
1555 }
1556 
1558 {
1559  AlphaMask aAlpha;
1560 
1561  if (!IsTransparent())
1562  {
1563  aAlpha = AlphaMask(GetSizePixel(), &cTrans);
1564  }
1565  else if( !IsAlpha() )
1566  {
1567  aAlpha = GetMask();
1568  aAlpha.Replace( 0, cTrans );
1569  }
1570  else
1571  {
1572  aAlpha = GetAlpha();
1573  BitmapScopedWriteAccess pA(aAlpha);
1574  assert(pA);
1575 
1576  if( !pA )
1577  return;
1578 
1579  sal_uLong nTrans = cTrans, nNewTrans;
1580  const tools::Long nWidth = pA->Width(), nHeight = pA->Height();
1581 
1583  {
1584  for( tools::Long nY = 0; nY < nHeight; nY++ )
1585  {
1586  Scanline pAScan = pA->GetScanline( nY );
1587 
1588  for( tools::Long nX = 0; nX < nWidth; nX++ )
1589  {
1590  nNewTrans = nTrans + *pAScan;
1591  *pAScan++ = static_cast<sal_uInt8>( ( nNewTrans & 0xffffff00 ) ? 255 : nNewTrans );
1592  }
1593  }
1594  }
1595  else
1596  {
1597  BitmapColor aAlphaValue( 0 );
1598 
1599  for( tools::Long nY = 0; nY < nHeight; nY++ )
1600  {
1601  Scanline pScanline = pA->GetScanline( nY );
1602  for( tools::Long nX = 0; nX < nWidth; nX++ )
1603  {
1604  nNewTrans = nTrans + pA->GetIndexFromData( pScanline, nX );
1605  aAlphaValue.SetIndex( static_cast<sal_uInt8>( ( nNewTrans & 0xffffff00 ) ? 255 : nNewTrans ) );
1606  pA->SetPixelOnData( pScanline, nX, aAlphaValue );
1607  }
1608  }
1609  }
1610  }
1611  *this = BitmapEx( GetBitmap(), aAlpha );
1612 }
1613 
1615 {
1616  Bitmap aNewMask = maBitmap.CreateMask( maskColor, nTol );
1617  if ( IsTransparent() )
1618  aNewMask.CombineSimple( maMask, BmpCombine::Or );
1619  maMask = aNewMask;
1621 }
1622 
1626 void BitmapEx::GetColorModel(css::uno::Sequence< sal_Int32 >& rRGBPalette,
1627  sal_uInt32& rnRedMask, sal_uInt32& rnGreenMask, sal_uInt32& rnBlueMask, sal_uInt32& rnAlphaMask, sal_uInt32& rnTransparencyIndex,
1628  sal_uInt32& rnWidth, sal_uInt32& rnHeight, sal_uInt8& rnBitCount)
1629 {
1630  Bitmap::ScopedReadAccess pReadAccess( maBitmap );
1631  assert( pReadAccess );
1632 
1633  if( pReadAccess->HasPalette() )
1634  {
1635  sal_uInt16 nPalCount = pReadAccess->GetPaletteEntryCount();
1636 
1637  if( nPalCount )
1638  {
1639  rRGBPalette = css::uno::Sequence< sal_Int32 >( nPalCount + 1 );
1640 
1641  sal_Int32* pTmp = rRGBPalette.getArray();
1642 
1643  for( sal_uInt32 i = 0; i < nPalCount; i++, pTmp++ )
1644  {
1645  const BitmapColor& rCol = pReadAccess->GetPaletteColor( static_cast<sal_uInt16>(i) );
1646 
1647  *pTmp = static_cast<sal_Int32>(rCol.GetRed()) << sal_Int32(24);
1648  *pTmp |= static_cast<sal_Int32>(rCol.GetGreen()) << sal_Int32(16);
1649  *pTmp |= static_cast<sal_Int32>(rCol.GetBlue()) << sal_Int32(8);
1650  *pTmp |= sal_Int32(0x000000ffL);
1651  }
1652 
1653  if( IsTransparent() )
1654  {
1655  // append transparent entry
1656  *pTmp = sal_Int32(0xffffff00L);
1657  rnTransparencyIndex = nPalCount;
1658  nPalCount++;
1659  }
1660  else
1661  rnTransparencyIndex = 0;
1662  }
1663  }
1664  else
1665  {
1666  rnRedMask = 0xff000000UL;
1667  rnGreenMask = 0x00ff0000UL;
1668  rnBlueMask = 0x0000ff00UL;
1669  rnAlphaMask = 0x000000ffUL;
1670  rnTransparencyIndex = 0;
1671  }
1672 
1673  rnWidth = pReadAccess->Width();
1674  rnHeight = pReadAccess->Height();
1675  rnBitCount = pReadAccess->GetBitCount();
1676 }
1677 
1678 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
bool operator==(const BitmapEx &rBitmapEx) const
Definition: BitmapEx.cxx:174
Color m_aLastColorBottomLeft
Definition: svdata.hxx:350
void Replace(const Bitmap &rMask, sal_uInt8 rReplaceTransparency)
Definition: alpha.cxx:83
sal_uInt8 GetIndexFromData(const sal_uInt8 *pData, tools::Long nX) const
bool Erase(const Color &rFillColor)
Fill the entire bitmap with the given color.
Definition: BitmapEx.cxx:564
Bitmap GetMask() const
Definition: BitmapEx.cxx:253
sal_uInt64 BitmapChecksum
Definition: checksum.hxx:30
bool Adjust(short nLuminancePercent, short nContrastPercent=0, short nChannelRPercent=0, short nChannelGPercent=0, short nChannelBPercent=0, double fGamma=1.0, bool bInvert=false, bool msoBrightness=false)
Change various global color characteristics.
sal_uInt8 GetIndex() const
Definition: BitmapColor.hxx:70
tools::Long Height() const
BitmapEx TransformBitmapEx(double fWidth, double fHeight, const basegfx::B2DHomMatrix &rTransformation) const
Create transformed Bitmap.
Definition: BitmapEx.cxx:901
sal_uInt8 GetAlpha() const
void SetAlpha(sal_uInt8 nAlpha)
sal_uInt8 GetRed() const
void SetSizePixel(const Size &rNewSize)
Definition: BitmapEx.cxx:308
double getHeight() const
tools::Rectangle & Intersection(const tools::Rectangle &rRect)
OUString DetermineIconTheme() const
Determine which icon theme should be used.
bool Adjust(short nLuminancePercent, short nContrastPercent, short nChannelRPercent, short nChannelGPercent, short nChannelBPercent, double fGamma=1.0, bool bInvert=false, bool msoBrightness=false)
Change various global color characteristics.
Definition: BitmapEx.cxx:603
void Replace(const Color &rSearchColor, const Color &rReplaceColor)
Replace all pixel having the search color with the specified color.
Definition: BitmapEx.cxx:591
Bitmap maMask
Definition: bitmapex.hxx:476
void Merge(const Color &rMergeColor, sal_uInt8 cTransparency)
BitmapEx createBlendFrame(const Size &rSize, sal_uInt8 nAlpha, Color aColorTopLeft, Color aColorBottomRight)
Create a blend frame as BitmapEx.
Definition: BitmapEx.cxx:1164
bool IsTransparent() const
static bool more(const double &rfValA, const double &rfValB)
A thin wrapper around rtl::Reference to implement the acquire and dispose semantics we want for refer...
Definition: button.hxx:34
signed char sal_Int8
TransparentType
Definition: bitmapex.hxx:37
void DrawBitmapEx(const Point &rDestPt, const BitmapEx &rBitmapEx)
This is an overloaded member function, provided for convenience. It differs from the above function o...
BitmapEx m_aLastResult
Definition: svdata.hxx:351
bool Scale(const Size &rNewSize, BmpScaleFlag nScaleFlag=BmpScaleFlag::Default)
Scale the bitmap.
Definition: BitmapEx.cxx:365
sal_uIntPtr sal_uLong
long Long
constexpr::Color COL_TRANSPARENT(ColorTransparency, 0xFF, 0xFF, 0xFF, 0xFF)
const StyleSettings & GetStyleSettings() const
static const AllSettings & GetSettings()
Gets the application's settings.
Definition: svapp.cxx:728
tools::Polygon GetContour(bool bContourEdgeDetect, const tools::Rectangle *pWorkRect)
Get contours in image.
Definition: BitmapEx.cxx:1438
void Expand(sal_uLong nDX, sal_uLong nDY, bool bExpandTransparent=false)
Expand the bitmap by pixel padding.
Definition: BitmapEx.cxx:454
BitmapEx getTransformed(const basegfx::B2DHomMatrix &rTransformation, const basegfx::B2DRange &rVisibleRange, double fMaximumArea) const
Create transformed Bitmap.
Definition: BitmapEx.cxx:932
constexpr std::underlying_type_t< T > underlyingEnumValue(T e)
sal_uInt16 GetBitCount() const
B2DVector getRange() const
void SetSize(sal_uInt16 nNewSize)
BitmapChecksum vcl_get_checksum(BitmapChecksum Checksum, const void *Data, sal_uInt32 DatLen)
Definition: checksum.hxx:72
BitmapReadAccess * AcquireReadAccess()
SAL_DLLPRIVATE void ImplSetBitmap(const Bitmap &rBitmap)
Definition: alpha.cxx:66
Size GetSizePixel() const
Size m_aLastSize
Definition: svdata.hxx:345
bool Expand(sal_uLong nDX, sal_uLong nDY, const Color *pInitColor=nullptr)
Expand the bitmap by pixel padding.
float x
BlendFrameCache * ImplGetBlendFrameCache()
Definition: svdata.cxx:308
bool Convert(BmpConversion eConversion)
Convert bitmap format.
Definition: BitmapEx.cxx:449
BitmapChecksum GetChecksum() const
Definition: BitmapEx.cxx:287
static Bitmap DetectEdges(const Bitmap &rBmp)
Definition: BitmapEx.cxx:1345
Size maBitmapSize
Definition: bitmapex.hxx:477
void Scale(double fScaleX, double fScaleY)
sal_uInt8 SVBT32[4]
NONE
const Size & GetPrefSize() const
Definition: bitmap.hxx:571
static OutputDevice * GetDefaultDevice()
Get the default "device" (in this case the default window).
Definition: svapp.cxx:1068
bool Crop(const tools::Rectangle &rRectPixel)
Crop the bitmap.
void SetPixelOnData(sal_uInt8 *pData, tools::Long nX, const BitmapColor &rBitmapColor)
static VCL_DLLPUBLIC ImageTree & get()
Definition: ImageTree.cxx:16
bool IsAlpha() const
Definition: BitmapEx.cxx:221
bool CombineSimple(const Bitmap &rMask, BmpCombine eCombine)
Perform boolean operations with another bitmap.
bool Mirror(BmpMirrorFlags nMirrorFlags)
Mirror the bitmap.
double getWidth() const
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
BASEGFX_DLLPUBLIC void transform(const B2DHomMatrix &rMatrix)
BitmapEx & operator=(const BitmapEx &rBitmapEx)
class SAL_WARN_UNUSED UNLESS_MERGELIBS(BASEGFX_DLLPUBLIC) BColorModifier_black_and_white final class SAL_WARN_UNUSED UNLESS_MERGELIBS(BASEGFX_DLLPUBLIC) BColorModifier_gamma final class SAL_WARN_UNUSED UNLESS_MERGELIBS(BASEGFX_DLLPUBLIC) BColorModifier_RGBLuminanceContrast final typedef std::shared_ptr< BColorModifier > BColorModifierSharedPtr
bool HasGreyPalette8Bit() const
B2DHomMatrix createScaleB2DHomMatrix(double fScaleX, double fScaleY)
bool mbAlpha
Definition: bitmapex.hxx:480
Scanline GetScanline(tools::Long nY) const
int nCount
static bool Filter(BitmapEx &rBmpEx, BitmapFilter const &rFilter)
B2DHomMatrix createScaleTranslateB2DHomMatrix(double fScaleX, double fScaleY, double fTranslateX, double fTranslateY)
void loadFromIconTheme(const OUString &rIconName)
Definition: BitmapEx.cxx:95
sal_uInt8 m_nLastAlpha
Definition: svdata.hxx:346
sal_uInt8 GetBlue() const
B2IRange fround(const B2DRange &rRange)
void Clear()
Definition: BitmapEx.cxx:211
float y
bool Mirror(BmpMirrorFlags nMirrorFlags)
Mirror the bitmap.
Definition: BitmapEx.cxx:328
void CombineMaskOr(Color maskColor, sal_uInt8 nTol)
Definition: BitmapEx.cxx:1614
BitmapEx ModifyBitmapEx(const basegfx::BColorModifierStack &rBColorModifierStack) const
Create ColorStack-modified version of this BitmapEx.
Definition: BitmapEx.cxx:1013
Color m_aLastColorTopRight
Definition: svdata.hxx:348
void AdjustTransparency(sal_uInt8 cTrans)
Definition: BitmapEx.cxx:1557
void Invert()
void SetEmpty()
Definition: BitmapEx.cxx:203
bool IsEmpty() const
Definition: BitmapEx.cxx:198
ImplSVData * ImplGetSVData()
Definition: svdata.cxx:74
const MapMode & GetPrefMapMode() const
Definition: bitmap.hxx:561
VCL_DLLPUBLIC bool loadImage(OUString const &name, OUString const &style, BitmapEx &bitmap, bool localized, const ImageLoadFlags eFlags=ImageLoadFlags::NONE)
Definition: ImageTree.cxx:45
void SetPrefMapMode(const MapMode &rMapMode)
Definition: bitmap.hxx:566
bool Create(const css::uno::Reference< css::rendering::XBitmapCanvas > &xBitmapCanvas, const Size &rSize)
populate from a canvas implementation
Definition: BitmapEx.cxx:768
#define BITMAP_CHECKSUM_SIZE
Definition: checksum.hxx:28
Bitmap maBitmap
Definition: bitmapex.hxx:475
sal_uInt8 * Scanline
Definition: Scanline.hxx:25
static BitmapEx AutoScaleBitmap(BitmapEx const &aBitmap, const tools::Long aStandardSize)
Definition: BitmapEx.cxx:623
Color m_aLastColorTopLeft
Definition: svdata.hxx:347
int i
bool HasPalette() const
bool Rotate(Degree10 nAngle10, const Color &rFillColor)
Rotate bitmap by the specified angle.
uno_Any a
ScanlineFormat GetScanlineFormat() const
bool decompose(B2DTuple &rScale, B2DTuple &rTranslate, double &rRotate, double &rShearX) const
Color m_aLastColorBottomRight
Definition: svdata.hxx:349
BitmapChecksum GetChecksum() const
bool Invert()
Perform the Invert operation on every pixel.
Definition: BitmapEx.cxx:313
BitmapColor GetColor(tools::Long nY, tools::Long nX) const
sal_uLong GetSizeBytes() const
Definition: bitmap.hxx:586
#define F_2PI
tools::Long Width() const
Some things multiple-inherit from VclAbstractDialog and OutputDevice, so we need to use virtual inher...
Definition: outdev.hxx:303
tools::Long Width() const
sal_uLong GetSizeBytes() const
Definition: BitmapEx.cxx:277
::rtl::Reference< Content > pContent
BmpMirrorFlags
Definition: bitmap.hxx:41
bool Invert()
Perform the Invert operation on every pixel.
Definition: bitmappaint.cxx:64
BmpScaleFlag
Definition: bitmap.hxx:53
static void ReleaseAccess(BitmapInfoAccess *pAccess)
::Color GetPixelColor(sal_Int32 nX, sal_Int32 nY) const
Get pixel color (including alpha) at given position.
Definition: BitmapEx.cxx:746
bool CopyPixel(const tools::Rectangle &rRectDst, const tools::Rectangle &rRectSrc, const BitmapEx *pBmpExSrc)
Copy a rectangular area from another bitmap.
Definition: BitmapEx.cxx:475
BmpConversion
Definition: bitmap.hxx:70
bool IsTransparent() const
Definition: BitmapEx.cxx:216
const Bitmap & GetBitmap() const
Gives direct access to the contained bitmap.
Definition: BitmapEx.cxx:226
bool CopyPixel_AlphaOptimized(const tools::Rectangle &rRectDst, const tools::Rectangle &rRectSrc, const Bitmap *pBmpSrc)
void Draw(OutputDevice *pOutDev, const Point &rDestPt) const
Definition: BitmapEx.cxx:612
bool Rotate(Degree10 nAngle10, const Color &rFillColor)
Rotate bitmap by the specified angle.
Definition: BitmapEx.cxx:385
short nBitCount
Definition: ipict.cxx:80
sal_uInt16 GetPaletteEntryCount() const
void SetIndex(sal_uInt8 cIndex)
Definition: BitmapColor.hxx:75
void SetEmpty()
Bitmap GetBitmap(Color aTransparentReplaceColor) const
Definition: BitmapEx.cxx:231
sal_uInt8 GetGreen() const
SAL_DLLPRIVATE const Bitmap & ImplGetBitmap() const
Definition: alpha.cxx:61
double getMinY() const
virtual std::shared_ptr< SalBitmap > CreateSalBitmap()=0
AlphaMask GetAlpha() const
Definition: BitmapEx.cxx:263
#define SAL_WARN_IF(condition, area, stream)
unsigned char sal_uInt8
bool Scale(const Size &rNewSize, BmpScaleFlag nScaleFlag=BmpScaleFlag::Default)
Scale the bitmap.
void BCToBCOA(BitmapChecksum n, BitmapChecksumOctetArray p)
Definition: checksum.hxx:34
bool Convert(BmpConversion eConversion)
Convert bitmap format.
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_WHITE
const BitmapPalette & GetPalette() const
tools::Long Height() const
B2DPoint getMinimum() const
bool IsEmpty() const
Definition: bitmap.hxx:556
void GetColorModel(css::uno::Sequence< sal_Int32 > &rRGBPalette, sal_uInt32 &rnRedMask, sal_uInt32 &rnGreenMask, sal_uInt32 &rnBlueMask, sal_uInt32 &rnAlphaMask, sal_uInt32 &rnTransparencyIndex, sal_uInt32 &rnWidth, sal_uInt32 &rnHeight, sal_uInt8 &rnBitCount)
Retrieves the color model data we need for the XImageConsumer stuff.
Definition: BitmapEx.cxx:1626
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_BLACK
BitmapEx()
Definition: BitmapEx.cxx:50
BitmapColor GetPixelFromData(const sal_uInt8 *pData, tools::Long nX) const
void translate(double fX, double fY)
void AdaptBitCount(Bitmap &rNew) const
TransparentType meTransparent
Definition: bitmapex.hxx:479
bool Erase(const Color &rFillColor)
Fill the entire bitmap with the given color.
Definition: bitmappaint.cxx:34
uno::Reference< ucb::XContent > xContent
void setAlphaFrom(sal_uInt8 cIndexFrom, sal_Int8 nAlphaTo)
Definition: BitmapEx.cxx:1534
#define SAL_WARN(area, stream)
sal_uInt8 BitmapChecksumOctetArray[BITMAP_CHECKSUM_SIZE]
Definition: checksum.hxx:31
double getMinX() const
const BitmapColor & GetPaletteColor(sal_uInt16 nColor) const
void ReplaceTransparency(const Color &rColor)
Replace transparency with given color.
Definition: BitmapEx.cxx:1332
sal_uInt16 GetBitCount() const
bool CopyPixel(const tools::Rectangle &rRectDst, const tools::Rectangle &rRectSrc, const Bitmap *pBmpSrc=nullptr)
Copy a rectangular area from another bitmap.
bool Replace(const Bitmap &rMask, const Color &rReplaceColor)
Replace all pixel where the given mask is on with the specified color.
const Size & GetSizePixel() const
Definition: bitmapex.hxx:84
BitmapColor GetPixel(tools::Long nY, tools::Long nX) const
Color maTransparentColor
Definition: bitmapex.hxx:478
BitmapColor GetBestMatchingColor(const BitmapColor &rBitmapColor)
bool Crop(const tools::Rectangle &rRectPixel)
Crop the bitmap.
Definition: BitmapEx.cxx:429
Bitmap CreateMask(const Color &rTransColor, sal_uInt8 nTol=0) const
Create on-off mask from bitmap.
void SetPaletteColor(sal_uInt16 nColor, const BitmapColor &rBitmapColor)
SalInstance * mpDefInst
Definition: svdata.hxx:383