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