LCOV - code coverage report
Current view: top level - vcl/source/gdi - bitmap.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 496 1028 48.2 %
Date: 2014-11-03 Functions: 32 44 72.7 %
Legend: Lines: hit not hit

          Line data    Source code
       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 <algorithm>
      21             : #include <rtl/crc.h>
      22             : #include <tools/stream.hxx>
      23             : #include <tools/poly.hxx>
      24             : #include <tools/rc.h>
      25             : #include <vcl/salbtype.hxx>
      26             : #include <vcl/bmpacc.hxx>
      27             : #include <vcl/outdev.hxx>
      28             : #include <vcl/bitmap.hxx>
      29             : #include <vcl/bitmapex.hxx>
      30             : #include <vcl/svapp.hxx>
      31             : #include <vcl/image.hxx>
      32             : 
      33             : #include <impbmp.hxx>
      34             : #include <salbmp.hxx>
      35             : #include <boost/scoped_array.hpp>
      36             : 
      37     5076682 : Bitmap::Bitmap() :
      38     5076682 :     mpImpBmp( NULL )
      39             : {
      40     5076682 : }
      41             : 
      42        6024 : Bitmap::Bitmap( const ResId& rResId ) :
      43        6024 :     mpImpBmp( NULL )
      44             : {
      45        6024 :     const BitmapEx aBmpEx( rResId );
      46             : 
      47        6024 :     if( !aBmpEx.IsEmpty() )
      48        6024 :         *this = aBmpEx.GetBitmap();
      49        6024 : }
      50             : 
      51     4623390 : Bitmap::Bitmap( const Bitmap& rBitmap ) :
      52             :     maPrefMapMode   ( rBitmap.maPrefMapMode ),
      53     4623390 :     maPrefSize      ( rBitmap.maPrefSize )
      54             : {
      55     4623390 :     mpImpBmp = rBitmap.mpImpBmp;
      56             : 
      57     4623390 :     if ( mpImpBmp )
      58     3023956 :         mpImpBmp->ImplIncRefCount();
      59     4623390 : }
      60             : 
      61           0 : Bitmap::Bitmap( SalBitmap* pSalBitmap )
      62             : {
      63           0 :     mpImpBmp = new ImpBitmap();
      64           0 :     mpImpBmp->ImplSetSalBitmap( pSalBitmap );
      65           0 :     maPrefMapMode = MapMode( MAP_PIXEL );
      66           0 :     maPrefSize = mpImpBmp->ImplGetSize();
      67           0 : }
      68             : 
      69      111419 : Bitmap::Bitmap( const Size& rSizePixel, sal_uInt16 nBitCount, const BitmapPalette* pPal )
      70             : {
      71      111419 :     if( rSizePixel.Width() && rSizePixel.Height() )
      72             :     {
      73      111419 :         BitmapPalette   aPal;
      74      111419 :         BitmapPalette*  pRealPal = NULL;
      75             : 
      76      111419 :         if( nBitCount <= 8 )
      77             :         {
      78       84897 :             if( !pPal )
      79             :             {
      80       19972 :                 if( 1 == nBitCount )
      81             :                 {
      82        1867 :                     aPal.SetEntryCount( 2 );
      83        1867 :                     aPal[ 0 ] = Color( COL_BLACK );
      84        1867 :                     aPal[ 1 ] = Color( COL_WHITE );
      85             :                 }
      86       18105 :                 else if( ( 4 == nBitCount ) || ( 8 == nBitCount ) )
      87             :                 {
      88       18105 :                     aPal.SetEntryCount( 1 << nBitCount );
      89       18105 :                     aPal[ 0 ] = Color( COL_BLACK );
      90       18105 :                     aPal[ 1 ] = Color( COL_BLUE );
      91       18105 :                     aPal[ 2 ] = Color( COL_GREEN );
      92       18105 :                     aPal[ 3 ] = Color( COL_CYAN );
      93       18105 :                     aPal[ 4 ] = Color( COL_RED );
      94       18105 :                     aPal[ 5 ] = Color( COL_MAGENTA );
      95       18105 :                     aPal[ 6 ] = Color( COL_BROWN );
      96       18105 :                     aPal[ 7 ] = Color( COL_GRAY );
      97       18105 :                     aPal[ 8 ] = Color( COL_LIGHTGRAY );
      98       18105 :                     aPal[ 9 ] = Color( COL_LIGHTBLUE );
      99       18105 :                     aPal[ 10 ] = Color( COL_LIGHTGREEN );
     100       18105 :                     aPal[ 11 ] = Color( COL_LIGHTCYAN );
     101       18105 :                     aPal[ 12 ] = Color( COL_LIGHTRED );
     102       18105 :                     aPal[ 13 ] = Color( COL_LIGHTMAGENTA );
     103       18105 :                     aPal[ 14 ] = Color( COL_YELLOW );
     104       18105 :                     aPal[ 15 ] = Color( COL_WHITE );
     105             : 
     106             :                     // Create dither palette
     107       18105 :                     if( 8 == nBitCount )
     108             :                     {
     109       17901 :                         sal_uInt16 nActCol = 16;
     110             : 
     111      125307 :                         for( sal_uInt16 nB = 0; nB < 256; nB += 51 )
     112      751842 :                             for( sal_uInt16 nG = 0; nG < 256; nG += 51 )
     113     4511052 :                                 for( sal_uInt16 nR = 0; nR < 256; nR += 51 )
     114     3866616 :                                     aPal[ nActCol++ ] = BitmapColor( (sal_uInt8) nR, (sal_uInt8) nG, (sal_uInt8) nB );
     115             : 
     116             :                         // Set standard Office colors
     117       17901 :                         aPal[ nActCol++ ] = BitmapColor( 0, 184, 255 );
     118             :                     }
     119             :                 }
     120             :             }
     121             :             else
     122       64925 :                 pRealPal = (BitmapPalette*) pPal;
     123             :         }
     124             : 
     125      111419 :         mpImpBmp = new ImpBitmap;
     126      111419 :         mpImpBmp->ImplCreate( rSizePixel, nBitCount, pRealPal ? *pRealPal : aPal );
     127             :     }
     128             :     else
     129           0 :         mpImpBmp = NULL;
     130      111419 : }
     131             : 
     132    19663314 : Bitmap::~Bitmap()
     133             : {
     134     9812480 :     ImplReleaseRef();
     135     9850834 : }
     136             : 
     137      325824 : const BitmapPalette& Bitmap::GetGreyPalette( int nEntries )
     138             : {
     139      325824 :     static BitmapPalette aGreyPalette2;
     140      325824 :     static BitmapPalette aGreyPalette4;
     141      325824 :     static BitmapPalette aGreyPalette16;
     142      325824 :     static BitmapPalette aGreyPalette256;
     143             : 
     144             :     // Create greyscale palette with 2, 4, 16 or 256 entries
     145      325824 :     if( 2 == nEntries || 4 == nEntries || 16 == nEntries || 256 == nEntries )
     146             :     {
     147      325824 :         if( 2 == nEntries )
     148             :         {
     149           0 :             if( !aGreyPalette2.GetEntryCount() )
     150             :             {
     151           0 :                 aGreyPalette2.SetEntryCount( 2 );
     152           0 :                 aGreyPalette2[ 0 ] = BitmapColor( 0, 0, 0 );
     153           0 :                 aGreyPalette2[ 1 ] = BitmapColor( 255, 255, 255 );
     154             :             }
     155             : 
     156           0 :             return aGreyPalette2;
     157             :         }
     158      325824 :         else if( 4 == nEntries )
     159             :         {
     160           0 :             if( !aGreyPalette4.GetEntryCount() )
     161             :             {
     162           0 :                 aGreyPalette4.SetEntryCount( 4 );
     163           0 :                 aGreyPalette4[ 0 ] = BitmapColor( 0, 0, 0 );
     164           0 :                 aGreyPalette4[ 1 ] = BitmapColor( 85, 85, 85 );
     165           0 :                 aGreyPalette4[ 2 ] = BitmapColor( 170, 170, 170 );
     166           0 :                 aGreyPalette4[ 3 ] = BitmapColor( 255, 255, 255 );
     167             :             }
     168             : 
     169           0 :             return aGreyPalette4;
     170             :         }
     171      325824 :         else if( 16 == nEntries )
     172             :         {
     173           4 :             if( !aGreyPalette16.GetEntryCount() )
     174             :             {
     175           2 :                 sal_uInt8 cGrey = 0, cGreyInc = 17;
     176             : 
     177           2 :                 aGreyPalette16.SetEntryCount( 16 );
     178             : 
     179          34 :                 for( sal_uInt16 i = 0; i < 16; i++, cGrey = sal::static_int_cast<sal_uInt8>(cGrey + cGreyInc) )
     180          32 :                     aGreyPalette16[ i ] = BitmapColor( cGrey, cGrey, cGrey );
     181             :             }
     182             : 
     183           4 :             return aGreyPalette16;
     184             :         }
     185             :         else
     186             :         {
     187      325820 :             if( !aGreyPalette256.GetEntryCount() )
     188             :             {
     189         180 :                 aGreyPalette256.SetEntryCount( 256 );
     190             : 
     191       46260 :                 for( sal_uInt16 i = 0; i < 256; i++ )
     192       46080 :                     aGreyPalette256[ i ] = BitmapColor( (sal_uInt8) i, (sal_uInt8) i, (sal_uInt8) i );
     193             :             }
     194             : 
     195      325820 :             return aGreyPalette256;
     196             :         }
     197             :     }
     198             :     else
     199             :     {
     200             :         OSL_FAIL( "Bitmap::GetGreyPalette: invalid entry count (2/4/16/256 allowed)" );
     201           0 :         return aGreyPalette2;
     202             :     }
     203             : }
     204             : 
     205         569 : bool BitmapPalette::IsGreyPalette() const
     206             : {
     207         569 :     const int nEntryCount = GetEntryCount();
     208         569 :     if( !nEntryCount ) // NOTE: an empty palette means 1:1 mapping
     209           0 :         return true;
     210             :     // See above: only certain entry values will result in a valid call to GetGreyPalette
     211         569 :     if( nEntryCount == 2 || nEntryCount == 4 || nEntryCount == 16 || nEntryCount == 256 )
     212             :     {
     213         569 :         const BitmapPalette& rGreyPalette = Bitmap::GetGreyPalette( nEntryCount );
     214         569 :         if( rGreyPalette == *this )
     215         553 :             return true;
     216             :     }
     217             : 
     218          16 :     bool bRet = false;
     219             :     // TODO: is it worth to compare the entries for the general case?
     220          16 :     if (nEntryCount == 2)
     221             :     {
     222           0 :        const BitmapColor& rCol0(mpBitmapColor[0]);
     223           0 :        const BitmapColor& rCol1(mpBitmapColor[1]);
     224           0 :        bRet = rCol0.GetRed() == rCol0.GetGreen() && rCol0.GetRed() == rCol0.GetBlue() &&
     225           0 :               rCol1.GetRed() == rCol1.GetGreen() && rCol1.GetRed() == rCol1.GetBlue();
     226             :     }
     227          16 :     return bRet;
     228             : }
     229             : 
     230     3230347 : Bitmap& Bitmap::operator=( const Bitmap& rBitmap )
     231             : {
     232     3230347 :     if (this == &rBitmap)
     233           0 :         return *this;
     234             : 
     235     3230347 :     maPrefSize = rBitmap.maPrefSize;
     236     3230347 :     maPrefMapMode = rBitmap.maPrefMapMode;
     237             : 
     238     3230347 :     if ( rBitmap.mpImpBmp )
     239     3182565 :         rBitmap.mpImpBmp->ImplIncRefCount();
     240             : 
     241     3230347 :     ImplReleaseRef();
     242     3230347 :     mpImpBmp = rBitmap.mpImpBmp;
     243             : 
     244     3230347 :     return *this;
     245             : }
     246             : 
     247           0 : bool Bitmap::IsEqual( const Bitmap& rBmp ) const
     248             : {
     249           0 :     return( IsSameInstance( rBmp ) ||
     250           0 :             ( rBmp.GetSizePixel() == GetSizePixel() &&
     251           0 :               rBmp.GetBitCount() == GetBitCount() &&
     252           0 :               rBmp.GetChecksum() == GetChecksum() ) );
     253             : }
     254             : 
     255     1461536 : void Bitmap::SetEmpty()
     256             : {
     257     1461536 :     maPrefMapMode = MapMode();
     258     1461536 :     maPrefSize = Size();
     259             : 
     260     1461536 :     ImplReleaseRef();
     261     1461536 :     mpImpBmp = NULL;
     262     1461536 : }
     263             : 
     264     1285861 : Size Bitmap::GetSizePixel() const
     265             : {
     266     1285861 :     return( mpImpBmp ? mpImpBmp->ImplGetSize() : Size() );
     267             : }
     268             : 
     269      495299 : sal_uInt16 Bitmap::GetBitCount() const
     270             : {
     271      495299 :     return( mpImpBmp ? mpImpBmp->ImplGetBitCount() : 0 );
     272             : }
     273             : 
     274         569 : bool Bitmap::HasGreyPalette() const
     275             : {
     276         569 :     const sal_uInt16    nBitCount = GetBitCount();
     277         569 :     bool            bRet = nBitCount == 1;
     278             : 
     279         569 :     BitmapReadAccess* pRAcc = ( (Bitmap*) this )->AcquireReadAccess();
     280             : 
     281         569 :     if( pRAcc )
     282             :     {
     283         569 :         bRet = pRAcc->HasPalette() && pRAcc->GetPalette().IsGreyPalette();
     284         569 :         ( (Bitmap*) this )->ReleaseAccess( pRAcc );
     285             :     }
     286             : 
     287         569 :     return bRet;
     288             : }
     289             : 
     290        6829 : sal_uLong Bitmap::GetChecksum() const
     291             : {
     292        6829 :     sal_uLong nRet = 0UL;
     293             : 
     294        6829 :     if( mpImpBmp )
     295             :     {
     296        6829 :         nRet = mpImpBmp->ImplGetChecksum();
     297             : 
     298        6829 :         if( !nRet )
     299             :         {
     300        2286 :             BitmapReadAccess* pRAcc = ( (Bitmap*) this )->AcquireReadAccess();
     301             : 
     302        2286 :             if( pRAcc && pRAcc->Width() && pRAcc->Height() )
     303             :             {
     304        2286 :                 sal_uInt32  nCrc = 0;
     305             :                 SVBT32      aBT32;
     306             : 
     307        2286 :                 pRAcc->ImplZeroInitUnusedBits();
     308             : 
     309        2286 :                 UInt32ToSVBT32( pRAcc->Width(), aBT32 );
     310        2286 :                 nCrc = rtl_crc32( nCrc, aBT32, 4 );
     311             : 
     312        2286 :                 UInt32ToSVBT32( pRAcc->Height(), aBT32 );
     313        2286 :                 nCrc = rtl_crc32( nCrc, aBT32, 4 );
     314             : 
     315        2286 :                 UInt32ToSVBT32( pRAcc->GetBitCount(), aBT32 );
     316        2286 :                 nCrc = rtl_crc32( nCrc, aBT32, 4 );
     317             : 
     318        2286 :                 UInt32ToSVBT32( pRAcc->GetColorMask().GetRedMask(), aBT32 );
     319        2286 :                 nCrc = rtl_crc32( nCrc, aBT32, 4 );
     320             : 
     321        2286 :                 UInt32ToSVBT32( pRAcc->GetColorMask().GetGreenMask(), aBT32 );
     322        2286 :                 nCrc = rtl_crc32( nCrc, aBT32, 4 );
     323             : 
     324        2286 :                 UInt32ToSVBT32( pRAcc->GetColorMask().GetBlueMask(), aBT32 );
     325        2286 :                 nCrc = rtl_crc32( nCrc, aBT32, 4 );
     326             : 
     327        2286 :                 if( pRAcc->HasPalette() )
     328             :                 {
     329        1236 :                     nCrc = rtl_crc32( nCrc, pRAcc->GetPalette().ImplGetColorBuffer(),
     330        2472 :                                       pRAcc->GetPaletteEntryCount() * sizeof( BitmapColor ) );
     331             :                 }
     332             : 
     333        2286 :                 nCrc = rtl_crc32( nCrc, pRAcc->GetBuffer(), pRAcc->GetScanlineSize() * pRAcc->Height() );
     334             : 
     335        2286 :                 mpImpBmp->ImplSetChecksum( nRet = nCrc );
     336             :             }
     337             : 
     338        2286 :             if (pRAcc) ( (Bitmap*) this )->ReleaseAccess( pRAcc );
     339             :         }
     340             :     }
     341             : 
     342        6829 :     return nRet;
     343             : }
     344             : 
     345    14755340 : void Bitmap::ImplReleaseRef()
     346             : {
     347    14755340 :     if( mpImpBmp )
     348             :     {
     349     6567549 :         if( mpImpBmp->ImplGetRefCount() > 1UL )
     350     6164361 :             mpImpBmp->ImplDecRefCount();
     351             :         else
     352             :         {
     353      403188 :             delete mpImpBmp;
     354      403188 :             mpImpBmp = NULL;
     355             :         }
     356             :     }
     357    14755340 : }
     358             : 
     359      397719 : void Bitmap::ImplMakeUnique()
     360             : {
     361      397719 :     if( mpImpBmp && mpImpBmp->ImplGetRefCount() > 1UL )
     362             :     {
     363       41788 :         ImpBitmap* pOldImpBmp = mpImpBmp;
     364             : 
     365       41788 :         pOldImpBmp->ImplDecRefCount();
     366             : 
     367       41788 :         mpImpBmp = new ImpBitmap;
     368       41788 :         mpImpBmp->ImplCreate( *pOldImpBmp );
     369             :     }
     370      397719 : }
     371             : 
     372        7002 : void Bitmap::ImplAssignWithSize( const Bitmap& rBitmap )
     373             : {
     374        7002 :     const Size      aOldSizePix( GetSizePixel() );
     375        7002 :     const Size      aNewSizePix( rBitmap.GetSizePixel() );
     376        7002 :     const MapMode   aOldMapMode( maPrefMapMode );
     377        7002 :     Size            aNewPrefSize;
     378             : 
     379        7002 :     if( ( aOldSizePix != aNewSizePix ) && aOldSizePix.Width() && aOldSizePix.Height() )
     380             :     {
     381        6918 :         aNewPrefSize.Width() = FRound( maPrefSize.Width() * aNewSizePix.Width() / aOldSizePix.Width() );
     382        6918 :         aNewPrefSize.Height() = FRound( maPrefSize.Height() * aNewSizePix.Height() / aOldSizePix.Height() );
     383             :     }
     384             :     else
     385          84 :         aNewPrefSize = maPrefSize;
     386             : 
     387        7002 :     *this = rBitmap;
     388             : 
     389        7002 :     maPrefSize = aNewPrefSize;
     390        7002 :     maPrefMapMode = aOldMapMode;
     391        7002 : }
     392             : 
     393             : 
     394      250977 : void Bitmap::ImplSetImpBitmap( ImpBitmap* pImpBmp )
     395             : {
     396      250977 :     if( pImpBmp != mpImpBmp )
     397             :     {
     398      250977 :         ImplReleaseRef();
     399      250977 :         mpImpBmp = pImpBmp;
     400             :     }
     401      250977 : }
     402             : 
     403      770547 : BitmapReadAccess* Bitmap::AcquireReadAccess()
     404             : {
     405      770547 :     BitmapReadAccess* pReadAccess = new BitmapReadAccess( *this );
     406             : 
     407      770547 :     if( !*pReadAccess )
     408             :     {
     409           0 :         delete pReadAccess;
     410           0 :         pReadAccess = NULL;
     411             :     }
     412             : 
     413      770547 :     return pReadAccess;
     414             : }
     415             : 
     416      397719 : BitmapWriteAccess* Bitmap::AcquireWriteAccess()
     417             : {
     418      397719 :     BitmapWriteAccess* pWriteAccess = new BitmapWriteAccess( *this );
     419             : 
     420      397719 :     if( !*pWriteAccess )
     421             :     {
     422           6 :         delete pWriteAccess;
     423           6 :         pWriteAccess = NULL;
     424             :     }
     425             : 
     426      397719 :     return pWriteAccess;
     427             : }
     428             : 
     429     1168106 : void Bitmap::ReleaseAccess( BitmapReadAccess* pBitmapAccess )
     430             : {
     431     1168106 :     delete pBitmapAccess;
     432     1168106 : }
     433             : 
     434       42868 : bool Bitmap::Erase( const Color& rFillColor )
     435             : {
     436       42868 :     if( !(*this) )
     437           0 :         return true;
     438             : 
     439       42868 :     BitmapWriteAccess*  pWriteAcc = AcquireWriteAccess();
     440       42868 :     bool                bRet = false;
     441             : 
     442       42868 :     if( pWriteAcc )
     443             :     {
     444       42868 :         const sal_uLong nFormat = pWriteAcc->GetScanlineFormat();
     445       42868 :         sal_uInt8       cIndex = 0;
     446       42868 :         bool            bFast = false;
     447             : 
     448       42868 :         switch( nFormat )
     449             :         {
     450             :             case( BMP_FORMAT_1BIT_MSB_PAL ):
     451             :             case( BMP_FORMAT_1BIT_LSB_PAL ):
     452             :             {
     453         386 :                 cIndex = (sal_uInt8) pWriteAcc->GetBestPaletteIndex( rFillColor );
     454         386 :                 cIndex = ( cIndex ? 255 : 0 );
     455         386 :                 bFast = true;
     456             :             }
     457         386 :             break;
     458             : 
     459             :             case( BMP_FORMAT_4BIT_MSN_PAL ):
     460             :             case( BMP_FORMAT_4BIT_LSN_PAL ):
     461             :             {
     462          40 :                 cIndex = (sal_uInt8) pWriteAcc->GetBestPaletteIndex( rFillColor );
     463          40 :                 cIndex = cIndex | ( cIndex << 4 );
     464          40 :                 bFast = true;
     465             :             }
     466          40 :             break;
     467             : 
     468             :             case( BMP_FORMAT_8BIT_PAL ):
     469             :             {
     470       41651 :                 cIndex = (sal_uInt8) pWriteAcc->GetBestPaletteIndex( rFillColor );
     471       41651 :                 bFast = true;
     472             :             }
     473       41651 :             break;
     474             : 
     475             :             case( BMP_FORMAT_24BIT_TC_BGR ):
     476             :             case( BMP_FORMAT_24BIT_TC_RGB ):
     477             :             {
     478        1578 :                 if( ( rFillColor.GetRed() == rFillColor.GetGreen() ) &&
     479         789 :                     ( rFillColor.GetRed() == rFillColor.GetBlue() ) )
     480             :                 {
     481         789 :                     cIndex = rFillColor.GetRed();
     482         789 :                     bFast = true;
     483             :                 }
     484             :                 else
     485           0 :                     bFast = false;
     486             :             }
     487         789 :             break;
     488             : 
     489             :             default:
     490           2 :                 bFast = false;
     491           2 :             break;
     492             :         }
     493             : 
     494       42868 :         if( bFast )
     495             :         {
     496       42866 :             const sal_uLong nBufSize = pWriteAcc->GetScanlineSize() * pWriteAcc->Height();
     497       42866 :             memset( pWriteAcc->GetBuffer(), cIndex, nBufSize );
     498             :         }
     499             :         else
     500             :         {
     501           2 :             Point aTmpPoint;
     502           2 :             const Rectangle aRect( aTmpPoint, Size( pWriteAcc->Width(), pWriteAcc->Height() ) );
     503           2 :             pWriteAcc->SetFillColor( rFillColor );
     504           2 :             pWriteAcc->FillRect( aRect );
     505             :         }
     506             : 
     507       42868 :         ReleaseAccess( pWriteAcc );
     508       42868 :         bRet = true;
     509             :     }
     510             : 
     511       42868 :     return bRet;
     512             : }
     513             : 
     514          38 : bool Bitmap::Invert()
     515             : {
     516          38 :     BitmapWriteAccess*  pAcc = AcquireWriteAccess();
     517          38 :     bool                bRet = false;
     518             : 
     519          38 :     if( pAcc )
     520             :     {
     521          38 :         if( pAcc->HasPalette() )
     522             :         {
     523          28 :             BitmapPalette   aBmpPal( pAcc->GetPalette() );
     524          28 :             const sal_uInt16    nCount = aBmpPal.GetEntryCount();
     525             : 
     526          84 :             for( sal_uInt16 i = 0; i < nCount; i++ )
     527          56 :                 aBmpPal[ i ].Invert();
     528             : 
     529          28 :             pAcc->SetPalette( aBmpPal );
     530             :         }
     531             :         else
     532             :         {
     533          10 :             const long  nWidth = pAcc->Width();
     534          10 :             const long  nHeight = pAcc->Height();
     535             : 
     536         330 :             for( long nX = 0L; nX < nWidth; nX++ )
     537       10560 :                 for( long nY = 0L; nY < nHeight; nY++ )
     538       10240 :                     pAcc->SetPixel( nY, nX, pAcc->GetPixel( nY, nX ).Invert() );
     539             :         }
     540             : 
     541          38 :         ReleaseAccess( pAcc );
     542          38 :         bRet = true;
     543             :     }
     544             : 
     545          38 :     return bRet;
     546             : }
     547             : 
     548           0 : bool Bitmap::Mirror( sal_uLong nMirrorFlags )
     549             : {
     550           0 :     bool bHorz = ( ( nMirrorFlags & BMP_MIRROR_HORZ ) == BMP_MIRROR_HORZ );
     551           0 :     bool bVert = ( ( nMirrorFlags & BMP_MIRROR_VERT ) == BMP_MIRROR_VERT );
     552           0 :     bool bRet = false;
     553             : 
     554           0 :     if( bHorz && !bVert )
     555             :     {
     556           0 :         BitmapWriteAccess*  pAcc = AcquireWriteAccess();
     557             : 
     558           0 :         if( pAcc )
     559             :         {
     560           0 :             const long  nWidth = pAcc->Width();
     561           0 :             const long  nHeight = pAcc->Height();
     562           0 :             const long  nWidth1 = nWidth - 1L;
     563           0 :             const long  nWidth_2 = nWidth >> 1L;
     564             : 
     565           0 :             for( long nY = 0L; nY < nHeight; nY++ )
     566             :             {
     567           0 :                 for( long nX = 0L, nOther = nWidth1; nX < nWidth_2; nX++, nOther-- )
     568             :                 {
     569           0 :                     const BitmapColor aTemp( pAcc->GetPixel( nY, nX ) );
     570             : 
     571           0 :                     pAcc->SetPixel( nY, nX, pAcc->GetPixel( nY, nOther ) );
     572           0 :                     pAcc->SetPixel( nY, nOther, aTemp );
     573           0 :                 }
     574             :             }
     575             : 
     576           0 :             ReleaseAccess( pAcc );
     577           0 :             bRet = true;
     578           0 :         }
     579             :     }
     580           0 :     else if( bVert && !bHorz )
     581             :     {
     582           0 :         BitmapWriteAccess*  pAcc = AcquireWriteAccess();
     583             : 
     584           0 :         if( pAcc )
     585             :         {
     586           0 :             const long  nScanSize = pAcc->GetScanlineSize();
     587           0 :             boost::scoped_array<sal_uInt8> pBuffer(new sal_uInt8[ nScanSize ]);
     588           0 :             const long  nHeight = pAcc->Height();
     589           0 :             const long  nHeight1 = nHeight - 1L;
     590           0 :             const long  nHeight_2 = nHeight >> 1L;
     591             : 
     592           0 :             for( long nY = 0L, nOther = nHeight1; nY < nHeight_2; nY++, nOther-- )
     593             :             {
     594           0 :                 memcpy( pBuffer.get(), pAcc->GetScanline( nY ), nScanSize );
     595           0 :                 memcpy( pAcc->GetScanline( nY ), pAcc->GetScanline( nOther ), nScanSize );
     596           0 :                 memcpy( pAcc->GetScanline( nOther ), pBuffer.get(), nScanSize );
     597             :             }
     598             : 
     599           0 :             ReleaseAccess( pAcc );
     600           0 :             bRet = true;
     601           0 :         }
     602             :     }
     603           0 :     else if( bHorz && bVert )
     604             :     {
     605           0 :         BitmapWriteAccess*  pAcc = AcquireWriteAccess();
     606             : 
     607           0 :         if( pAcc )
     608             :         {
     609           0 :             const long  nWidth = pAcc->Width();
     610           0 :             const long  nWidth1 = nWidth - 1L;
     611           0 :             const long  nHeight = pAcc->Height();
     612           0 :             long        nHeight_2 = nHeight >> 1;
     613             : 
     614           0 :             for( long nY = 0L, nOtherY = nHeight - 1L; nY < nHeight_2; nY++, nOtherY-- )
     615             :             {
     616           0 :                 for( long nX = 0L, nOtherX = nWidth1; nX < nWidth; nX++, nOtherX-- )
     617             :                 {
     618           0 :                     const BitmapColor aTemp( pAcc->GetPixel( nY, nX ) );
     619             : 
     620           0 :                     pAcc->SetPixel( nY, nX, pAcc->GetPixel( nOtherY, nOtherX ) );
     621           0 :                     pAcc->SetPixel( nOtherY, nOtherX, aTemp );
     622           0 :                 }
     623             :             }
     624             : 
     625             :             // ggf. noch mittlere Zeile horizontal spiegeln
     626           0 :             if( nHeight & 1 )
     627             :             {
     628           0 :                 for( long nX = 0L, nOtherX = nWidth1, nWidth_2 = nWidth >> 1; nX < nWidth_2; nX++, nOtherX-- )
     629             :                 {
     630           0 :                     const BitmapColor aTemp( pAcc->GetPixel( nHeight_2, nX ) );
     631           0 :                     pAcc->SetPixel( nHeight_2, nX, pAcc->GetPixel( nHeight_2, nOtherX ) );
     632           0 :                     pAcc->SetPixel( nHeight_2, nOtherX, aTemp );
     633           0 :                 }
     634             :             }
     635             : 
     636           0 :             ReleaseAccess( pAcc );
     637           0 :             bRet = true;
     638           0 :         }
     639             :     }
     640             :     else
     641           0 :         bRet = true;
     642             : 
     643           0 :     return bRet;
     644             : }
     645             : 
     646           0 : bool Bitmap::Rotate( long nAngle10, const Color& rFillColor )
     647             : {
     648           0 :     bool bRet = false;
     649             : 
     650           0 :     nAngle10 %= 3600L;
     651           0 :     nAngle10 = ( nAngle10 < 0L ) ? ( 3599L + nAngle10 ) : nAngle10;
     652             : 
     653           0 :     if( !nAngle10    )
     654           0 :         bRet = true;
     655           0 :     else if( 1800L == nAngle10 )
     656           0 :         bRet = Mirror( BMP_MIRROR_HORZ | BMP_MIRROR_VERT );
     657             :     else
     658             :     {
     659           0 :         BitmapReadAccess*   pReadAcc = AcquireReadAccess();
     660           0 :         Bitmap              aRotatedBmp;
     661             : 
     662           0 :         if( pReadAcc )
     663             :         {
     664           0 :             const Size  aSizePix( GetSizePixel() );
     665             : 
     666           0 :             if( ( 900L == nAngle10 ) || ( 2700L == nAngle10 ) )
     667             :             {
     668           0 :                 const Size          aNewSizePix( aSizePix.Height(), aSizePix.Width() );
     669           0 :                 Bitmap              aNewBmp( aNewSizePix, GetBitCount(), &pReadAcc->GetPalette() );
     670           0 :                 BitmapWriteAccess*  pWriteAcc = aNewBmp.AcquireWriteAccess();
     671             : 
     672           0 :                 if( pWriteAcc )
     673             :                 {
     674           0 :                     const long  nWidth = aSizePix.Width();
     675           0 :                     const long  nWidth1 = nWidth - 1L;
     676           0 :                     const long  nHeight = aSizePix.Height();
     677           0 :                     const long  nHeight1 = nHeight - 1L;
     678           0 :                     const long  nNewWidth = aNewSizePix.Width();
     679           0 :                     const long  nNewHeight = aNewSizePix.Height();
     680             : 
     681           0 :                     if( 900L == nAngle10 )
     682             :                     {
     683           0 :                         for( long nY = 0L, nOtherX = nWidth1; nY < nNewHeight; nY++, nOtherX-- )
     684           0 :                             for( long nX = 0L, nOtherY = 0L; nX < nNewWidth; nX++ )
     685           0 :                                 pWriteAcc->SetPixel( nY, nX, pReadAcc->GetPixel( nOtherY++, nOtherX ) );
     686             :                     }
     687           0 :                     else if( 2700L == nAngle10 )
     688             :                     {
     689           0 :                         for( long nY = 0L, nOtherX = 0L; nY < nNewHeight; nY++, nOtherX++ )
     690           0 :                             for( long nX = 0L, nOtherY = nHeight1; nX < nNewWidth; nX++ )
     691           0 :                                 pWriteAcc->SetPixel( nY, nX, pReadAcc->GetPixel( nOtherY--, nOtherX ) );
     692             :                     }
     693             : 
     694           0 :                     aNewBmp.ReleaseAccess( pWriteAcc );
     695             :                 }
     696             : 
     697           0 :                 aRotatedBmp = aNewBmp;
     698             :             }
     699             :             else
     700             :             {
     701           0 :                 Point       aTmpPoint;
     702           0 :                 Rectangle   aTmpRectangle( aTmpPoint, aSizePix );
     703           0 :                 Polygon     aPoly( aTmpRectangle );
     704           0 :                 aPoly.Rotate( aTmpPoint, (sal_uInt16) nAngle10 );
     705             : 
     706           0 :                 Rectangle           aNewBound( aPoly.GetBoundRect() );
     707           0 :                 const Size          aNewSizePix( aNewBound.GetSize() );
     708           0 :                 Bitmap              aNewBmp( aNewSizePix, GetBitCount(), &pReadAcc->GetPalette() );
     709           0 :                 BitmapWriteAccess*  pWriteAcc = aNewBmp.AcquireWriteAccess();
     710             : 
     711           0 :                 if( pWriteAcc )
     712             :                 {
     713           0 :                     const BitmapColor   aFillColor( pWriteAcc->GetBestMatchingColor( rFillColor ) );
     714           0 :                     const double        fCosAngle = cos( nAngle10 * F_PI1800 );
     715           0 :                     const double        fSinAngle = sin( nAngle10 * F_PI1800 );
     716           0 :                     const double        fXMin = aNewBound.Left();
     717           0 :                     const double        fYMin = aNewBound.Top();
     718           0 :                     const long          nWidth = aSizePix.Width();
     719           0 :                     const long          nHeight = aSizePix.Height();
     720           0 :                     const long          nNewWidth = aNewSizePix.Width();
     721           0 :                     const long          nNewHeight = aNewSizePix.Height();
     722             :                     long                nX;
     723             :                     long                nY;
     724             :                     long                nRotX;
     725             :                     long                nRotY;
     726           0 :                     boost::scoped_array<long> pCosX(new long[ nNewWidth ]);
     727           0 :                     boost::scoped_array<long> pSinX(new long[ nNewWidth ]);
     728           0 :                     boost::scoped_array<long> pCosY(new long[ nNewHeight ]);
     729           0 :                     boost::scoped_array<long> pSinY(new long[ nNewHeight ]);
     730             : 
     731           0 :                     for ( nX = 0; nX < nNewWidth; nX++ )
     732             :                     {
     733           0 :                         const double fTmp = ( fXMin + nX ) * 64.;
     734             : 
     735           0 :                         pCosX[ nX ] = FRound( fCosAngle * fTmp );
     736           0 :                         pSinX[ nX ] = FRound( fSinAngle * fTmp );
     737             :                     }
     738             : 
     739           0 :                     for ( nY = 0; nY < nNewHeight; nY++ )
     740             :                     {
     741           0 :                         const double fTmp = ( fYMin + nY ) * 64.;
     742             : 
     743           0 :                         pCosY[ nY ] = FRound( fCosAngle * fTmp );
     744           0 :                         pSinY[ nY ] = FRound( fSinAngle * fTmp );
     745             :                     }
     746             : 
     747           0 :                     for( nY = 0L; nY < nNewHeight; nY++ )
     748             :                     {
     749           0 :                         long nSinY = pSinY[ nY ];
     750           0 :                         long nCosY = pCosY[ nY ];
     751             : 
     752           0 :                         for( nX = 0L; nX < nNewWidth; nX++ )
     753             :                         {
     754           0 :                             nRotX = ( pCosX[ nX ] - nSinY ) >> 6;
     755           0 :                             nRotY = ( pSinX[ nX ] + nCosY ) >> 6;
     756             : 
     757           0 :                             if ( ( nRotX > -1L ) && ( nRotX < nWidth ) && ( nRotY > -1L ) && ( nRotY < nHeight ) )
     758           0 :                                 pWriteAcc->SetPixel( nY, nX, pReadAcc->GetPixel( nRotY, nRotX ) );
     759             :                             else
     760           0 :                                 pWriteAcc->SetPixel( nY, nX, aFillColor );
     761             :                         }
     762             :                     }
     763             : 
     764           0 :                     aNewBmp.ReleaseAccess( pWriteAcc );
     765             :                 }
     766             : 
     767           0 :                 aRotatedBmp = aNewBmp;
     768             :             }
     769             : 
     770           0 :             ReleaseAccess( pReadAcc );
     771             :         }
     772             : 
     773           0 :         if( ( bRet = !!aRotatedBmp ) )
     774           0 :             ImplAssignWithSize( aRotatedBmp );
     775             :     }
     776             : 
     777           0 :     return bRet;
     778             : };
     779             : 
     780        2650 : bool Bitmap::Crop( const Rectangle& rRectPixel )
     781             : {
     782        2650 :     const Size          aSizePix( GetSizePixel() );
     783        2650 :     Rectangle           aRect( rRectPixel );
     784        2650 :     bool                bRet = false;
     785             : 
     786        2650 :     aRect.Intersection( Rectangle( Point(), aSizePix ) );
     787             : 
     788        2650 :     if( !aRect.IsEmpty() )
     789             :     {
     790        2650 :         BitmapReadAccess* pReadAcc = AcquireReadAccess();
     791             : 
     792        2650 :         if( pReadAcc )
     793             :         {
     794        2650 :             Point               aTmpPoint;
     795        2650 :             const Rectangle     aNewRect( aTmpPoint, aRect.GetSize() );
     796        2650 :             Bitmap              aNewBmp( aNewRect.GetSize(), GetBitCount(), &pReadAcc->GetPalette() );
     797        2650 :             BitmapWriteAccess*  pWriteAcc = aNewBmp.AcquireWriteAccess();
     798             : 
     799        2650 :             if( pWriteAcc )
     800             :             {
     801        2650 :                 const long nOldX = aRect.Left();
     802        2650 :                 const long nOldY = aRect.Top();
     803        2650 :                 const long nNewWidth = aNewRect.GetWidth();
     804        2650 :                 const long nNewHeight = aNewRect.GetHeight();
     805             : 
     806       34640 :                 for( long nY = 0, nY2 = nOldY; nY < nNewHeight; nY++, nY2++ )
     807     1639344 :                     for( long nX = 0, nX2 = nOldX; nX < nNewWidth; nX++, nX2++ )
     808     1607354 :                         pWriteAcc->SetPixel( nY, nX, pReadAcc->GetPixel( nY2, nX2 ) );
     809             : 
     810        2650 :                 aNewBmp.ReleaseAccess( pWriteAcc );
     811        2650 :                 bRet = true;
     812             :             }
     813             : 
     814        2650 :             ReleaseAccess( pReadAcc );
     815             : 
     816        2650 :             if( bRet )
     817        2650 :                 ImplAssignWithSize( aNewBmp );
     818             :         }
     819             :     }
     820             : 
     821        2650 :     return bRet;
     822             : };
     823             : 
     824       19620 : bool Bitmap::CopyPixel( const Rectangle& rRectDst,
     825             :                         const Rectangle& rRectSrc, const Bitmap* pBmpSrc )
     826             : {
     827       19620 :     const Size  aSizePix( GetSizePixel() );
     828       19620 :     Rectangle   aRectDst( rRectDst );
     829       19620 :     bool        bRet = false;
     830             : 
     831       19620 :     aRectDst.Intersection( Rectangle( Point(), aSizePix ) );
     832             : 
     833       19620 :     if( !aRectDst.IsEmpty() )
     834             :     {
     835       19620 :         if( pBmpSrc && ( *pBmpSrc != *this ) )
     836             :         {
     837       19620 :             Bitmap*         pSrc = (Bitmap*) pBmpSrc;
     838       19620 :             const Size      aCopySizePix( pSrc->GetSizePixel() );
     839       19620 :             Rectangle       aRectSrc( rRectSrc );
     840       19620 :             const sal_uInt16    nSrcBitCount = pBmpSrc->GetBitCount();
     841       19620 :             const sal_uInt16    nDstBitCount = GetBitCount();
     842             : 
     843       19620 :             if( nSrcBitCount > nDstBitCount )
     844             :             {
     845           0 :                 long nNextIndex = 0L;
     846             : 
     847           0 :                 if( ( nSrcBitCount == 24 ) && ( nDstBitCount < 24 ) )
     848           0 :                     Convert( BMP_CONVERSION_24BIT );
     849           0 :                 else if( ( nSrcBitCount == 8 ) && ( nDstBitCount < 8 ) )
     850             :                 {
     851           0 :                     Convert( BMP_CONVERSION_8BIT_COLORS );
     852           0 :                     nNextIndex = 16;
     853             :                 }
     854           0 :                 else if( ( nSrcBitCount == 4 ) && ( nDstBitCount < 4 ) )
     855             :                 {
     856           0 :                     Convert( BMP_CONVERSION_4BIT_COLORS );
     857           0 :                     nNextIndex = 2;
     858             :                 }
     859             : 
     860           0 :                 if( nNextIndex )
     861             :                 {
     862           0 :                     BitmapReadAccess*   pSrcAcc = pSrc->AcquireReadAccess();
     863           0 :                     BitmapWriteAccess*  pDstAcc = AcquireWriteAccess();
     864             : 
     865           0 :                     if( pSrcAcc && pDstAcc )
     866             :                     {
     867           0 :                         const long      nSrcCount = pDstAcc->GetPaletteEntryCount();
     868           0 :                         const long      nDstCount = 1 << nDstBitCount;
     869             : 
     870           0 :                         for( long i = 0L; ( i < nSrcCount ) && ( nNextIndex < nSrcCount ); i++ )
     871             :                         {
     872           0 :                             const BitmapColor& rSrcCol = pSrcAcc->GetPaletteColor( (sal_uInt16) i );
     873             : 
     874           0 :                             bool bFound = false;
     875             : 
     876           0 :                             for( long j = 0L; j < nDstCount; j++ )
     877             :                             {
     878           0 :                                 if( rSrcCol == pDstAcc->GetPaletteColor( (sal_uInt16) j ) )
     879             :                                 {
     880           0 :                                     bFound = true;
     881           0 :                                     break;
     882             :                                 }
     883             :                             }
     884             : 
     885           0 :                             if( !bFound )
     886           0 :                                 pDstAcc->SetPaletteColor( (sal_uInt16) nNextIndex++, rSrcCol );
     887             :                         }
     888             :                     }
     889             : 
     890           0 :                     if( pSrcAcc )
     891           0 :                         pSrc->ReleaseAccess( pSrcAcc );
     892             : 
     893           0 :                     if( pDstAcc )
     894           0 :                         ReleaseAccess( pDstAcc );
     895             :                 }
     896             :             }
     897             : 
     898       19620 :             aRectSrc.Intersection( Rectangle( Point(), aCopySizePix ) );
     899             : 
     900       19620 :             if( !aRectSrc.IsEmpty() )
     901             :             {
     902       19620 :                 BitmapReadAccess* pReadAcc = pSrc->AcquireReadAccess();
     903             : 
     904       19620 :                 if( pReadAcc )
     905             :                 {
     906       19620 :                     BitmapWriteAccess* pWriteAcc = AcquireWriteAccess();
     907             : 
     908       19620 :                     if( pWriteAcc )
     909             :                     {
     910       19620 :                         const long  nWidth = std::min( aRectSrc.GetWidth(), aRectDst.GetWidth() );
     911       19620 :                         const long  nHeight = std::min( aRectSrc.GetHeight(), aRectDst.GetHeight() );
     912       19620 :                         const long  nSrcEndX = aRectSrc.Left() + nWidth;
     913       19620 :                         const long  nSrcEndY = aRectSrc.Top() + nHeight;
     914       19620 :                         long        nDstY = aRectDst.Top();
     915             : 
     916       19620 :                         if( pReadAcc->HasPalette() && pWriteAcc->HasPalette() )
     917             :                         {
     918        9056 :                             const sal_uInt16    nCount = pReadAcc->GetPaletteEntryCount();
     919        9056 :                             boost::scoped_array<sal_uInt8> pMap(new sal_uInt8[ nCount ]);
     920             : 
     921             :                             // Create index map for the color table, as the bitmap should be copied
     922             :                             // retaining it's color information relatively well
     923     2243056 :                             for( sal_uInt16 i = 0; i < nCount; i++ )
     924     2234000 :                                 pMap[ i ] = (sal_uInt8) pWriteAcc->GetBestPaletteIndex( pReadAcc->GetPaletteColor( i ) );
     925             : 
     926       75960 :                             for( long nSrcY = aRectSrc.Top(); nSrcY < nSrcEndY; nSrcY++, nDstY++ )
     927      597728 :                                 for( long nSrcX = aRectSrc.Left(), nDstX = aRectDst.Left(); nSrcX < nSrcEndX; nSrcX++, nDstX++ )
     928      539880 :                                     pWriteAcc->SetPixelIndex( nDstY, nDstX, pMap[ pReadAcc->GetPixelIndex( nSrcY, nSrcX ) ] );
     929             :                         }
     930       10564 :                         else if( pReadAcc->HasPalette() )
     931             :                         {
     932       33252 :                             for( long nSrcY = aRectSrc.Top(); nSrcY < nSrcEndY; nSrcY++, nDstY++ )
     933      532032 :                                 for( long nSrcX = aRectSrc.Left(), nDstX = aRectDst.Left(); nSrcX < nSrcEndX; nSrcX++, nDstX++ )
     934      500736 :                                     pWriteAcc->SetPixel( nDstY, nDstX, pReadAcc->GetPaletteColor( pReadAcc->GetPixelIndex( nSrcY, nSrcX ) ) );
     935             :                         }
     936             :                         else
     937      113384 :                             for( long nSrcY = aRectSrc.Top(); nSrcY < nSrcEndY; nSrcY++, nDstY++ )
     938     2448160 :                                 for( long nSrcX = aRectSrc.Left(), nDstX = aRectDst.Left(); nSrcX < nSrcEndX; nSrcX++, nDstX++ )
     939     2343384 :                                     pWriteAcc->SetPixel( nDstY, nDstX, pReadAcc->GetPixel( nSrcY, nSrcX ) );
     940             : 
     941       19620 :                         ReleaseAccess( pWriteAcc );
     942       19620 :                         bRet = ( nWidth > 0L ) && ( nHeight > 0L );
     943             :                     }
     944             : 
     945       19620 :                     pSrc->ReleaseAccess( pReadAcc );
     946             :                 }
     947             :             }
     948             :         }
     949             :         else
     950             :         {
     951           0 :             Rectangle aRectSrc( rRectSrc );
     952             : 
     953           0 :             aRectSrc.Intersection( Rectangle( Point(), aSizePix ) );
     954             : 
     955           0 :             if( !aRectSrc.IsEmpty() && ( aRectSrc != aRectDst ) )
     956             :             {
     957           0 :                 BitmapWriteAccess*  pWriteAcc = AcquireWriteAccess();
     958             : 
     959           0 :                 if( pWriteAcc )
     960             :                 {
     961           0 :                     const long  nWidth = std::min( aRectSrc.GetWidth(), aRectDst.GetWidth() );
     962           0 :                     const long  nHeight = std::min( aRectSrc.GetHeight(), aRectDst.GetHeight() );
     963           0 :                     const long  nSrcX = aRectSrc.Left();
     964           0 :                     const long  nSrcY = aRectSrc.Top();
     965           0 :                     const long  nSrcEndX1 = nSrcX + nWidth - 1L;
     966           0 :                     const long  nSrcEndY1 = nSrcY + nHeight - 1L;
     967           0 :                     const long  nDstX = aRectDst.Left();
     968           0 :                     const long  nDstY = aRectDst.Top();
     969           0 :                     const long  nDstEndX1 = nDstX + nWidth - 1L;
     970           0 :                     const long  nDstEndY1 = nDstY + nHeight - 1L;
     971             : 
     972           0 :                     if( ( nDstX <= nSrcX ) && ( nDstY <= nSrcY ) )
     973             :                     {
     974           0 :                         for( long nY = nSrcY, nYN = nDstY; nY <= nSrcEndY1; nY++, nYN++ )
     975           0 :                             for( long nX = nSrcX, nXN = nDstX; nX <= nSrcEndX1; nX++, nXN++ )
     976           0 :                                 pWriteAcc->SetPixel( nYN, nXN, pWriteAcc->GetPixel( nY, nX ) );
     977             :                     }
     978           0 :                     else if( ( nDstX <= nSrcX ) && ( nDstY >= nSrcY ) )
     979             :                     {
     980           0 :                         for( long nY = nSrcEndY1, nYN = nDstEndY1; nY >= nSrcY; nY--, nYN-- )
     981           0 :                             for( long nX = nSrcX, nXN = nDstX; nX <= nSrcEndX1; nX++, nXN++ )
     982           0 :                                 pWriteAcc->SetPixel( nYN, nXN, pWriteAcc->GetPixel( nY, nX ) );
     983             :                     }
     984           0 :                     else if( ( nDstX >= nSrcX ) && ( nDstY <= nSrcY ) )
     985             :                     {
     986           0 :                         for( long nY = nSrcY, nYN = nDstY; nY <= nSrcEndY1; nY++, nYN++ )
     987           0 :                             for( long nX = nSrcEndX1, nXN = nDstEndX1; nX >= nSrcX; nX--, nXN-- )
     988           0 :                                 pWriteAcc->SetPixel( nYN, nXN, pWriteAcc->GetPixel( nY, nX ) );
     989             :                     }
     990             :                     else
     991             :                     {
     992           0 :                         for( long nY = nSrcEndY1, nYN = nDstEndY1; nY >= nSrcY; nY--, nYN-- )
     993           0 :                             for( long nX = nSrcEndX1, nXN = nDstEndX1; nX >= nSrcX; nX--, nXN-- )
     994           0 :                                 pWriteAcc->SetPixel( nYN, nXN, pWriteAcc->GetPixel( nY, nX ) );
     995             :                     }
     996             : 
     997           0 :                     ReleaseAccess( pWriteAcc );
     998           0 :                     bRet = true;
     999             :                 }
    1000             :             }
    1001             :         }
    1002             :     }
    1003             : 
    1004       19620 :     return bRet;
    1005             : }
    1006             : 
    1007       12900 : bool Bitmap::CopyPixel_AlphaOptimized( const Rectangle& rRectDst, const Rectangle& rRectSrc,
    1008             :                            const Bitmap* pBmpSrc )
    1009             : {
    1010             :     // Note: this code is copied from Bitmap::CopyPixel but avoids any palette lookups
    1011             :     // This optimization is possible because the palettes of AlphaMasks are always identical (8bit GreyPalette, see ctor)
    1012       12900 :     const Size  aSizePix( GetSizePixel() );
    1013       12900 :     Rectangle   aRectDst( rRectDst );
    1014       12900 :     bool        bRet = false;
    1015             : 
    1016       12900 :     aRectDst.Intersection( Rectangle( Point(), aSizePix ) );
    1017             : 
    1018       12900 :     if( !aRectDst.IsEmpty() )
    1019             :     {
    1020       12900 :         if( pBmpSrc && ( *pBmpSrc != *this ) )
    1021             :         {
    1022       12900 :             Bitmap*         pSrc = (Bitmap*) pBmpSrc;
    1023       12900 :             const Size      aCopySizePix( pSrc->GetSizePixel() );
    1024       12900 :             Rectangle       aRectSrc( rRectSrc );
    1025             : 
    1026       12900 :             aRectSrc.Intersection( Rectangle( Point(), aCopySizePix ) );
    1027             : 
    1028       12900 :             if( !aRectSrc.IsEmpty() )
    1029             :             {
    1030       12900 :                 BitmapReadAccess* pReadAcc = pSrc->AcquireReadAccess();
    1031             : 
    1032       12900 :                 if( pReadAcc )
    1033             :                 {
    1034       12900 :                     BitmapWriteAccess* pWriteAcc = AcquireWriteAccess();
    1035             : 
    1036       12900 :                     if( pWriteAcc )
    1037             :                     {
    1038       12900 :                         const long  nWidth = std::min( aRectSrc.GetWidth(), aRectDst.GetWidth() );
    1039       12900 :                         const long  nHeight = std::min( aRectSrc.GetHeight(), aRectDst.GetHeight() );
    1040       12900 :                         const long  nSrcEndX = aRectSrc.Left() + nWidth;
    1041       12900 :                         const long  nSrcEndY = aRectSrc.Top() + nHeight;
    1042       12900 :                         long        nDstY = aRectDst.Top();
    1043             : 
    1044      175844 :                         for( long nSrcY = aRectSrc.Top(); nSrcY < nSrcEndY; nSrcY++, nDstY++ )
    1045     3260768 :                             for( long nSrcX = aRectSrc.Left(), nDstX = aRectDst.Left(); nSrcX < nSrcEndX; nSrcX++, nDstX++ )
    1046     3097824 :                                 pWriteAcc->SetPixel( nDstY, nDstX, pReadAcc->GetPixel( nSrcY, nSrcX ) );
    1047             : 
    1048       12900 :                         ReleaseAccess( pWriteAcc );
    1049       12900 :                         bRet = ( nWidth > 0L ) && ( nHeight > 0L );
    1050             :                     }
    1051             : 
    1052       12900 :                     pSrc->ReleaseAccess( pReadAcc );
    1053             :                 }
    1054             :             }
    1055             :         }
    1056             :         else
    1057             :         {
    1058           0 :             Rectangle aRectSrc( rRectSrc );
    1059             : 
    1060           0 :             aRectSrc.Intersection( Rectangle( Point(), aSizePix ) );
    1061             : 
    1062           0 :             if( !aRectSrc.IsEmpty() && ( aRectSrc != aRectDst ) )
    1063             :             {
    1064           0 :                 BitmapWriteAccess*  pWriteAcc = AcquireWriteAccess();
    1065             : 
    1066           0 :                 if( pWriteAcc )
    1067             :                 {
    1068           0 :                     const long  nWidth = std::min( aRectSrc.GetWidth(), aRectDst.GetWidth() );
    1069           0 :                     const long  nHeight = std::min( aRectSrc.GetHeight(), aRectDst.GetHeight() );
    1070           0 :                     const long  nSrcX = aRectSrc.Left();
    1071           0 :                     const long  nSrcY = aRectSrc.Top();
    1072           0 :                     const long  nSrcEndX1 = nSrcX + nWidth - 1L;
    1073           0 :                     const long  nSrcEndY1 = nSrcY + nHeight - 1L;
    1074           0 :                     const long  nDstX = aRectDst.Left();
    1075           0 :                     const long  nDstY = aRectDst.Top();
    1076           0 :                     const long  nDstEndX1 = nDstX + nWidth - 1L;
    1077           0 :                     const long  nDstEndY1 = nDstY + nHeight - 1L;
    1078             : 
    1079           0 :                     if( ( nDstX <= nSrcX ) && ( nDstY <= nSrcY ) )
    1080             :                     {
    1081           0 :                         for( long nY = nSrcY, nYN = nDstY; nY <= nSrcEndY1; nY++, nYN++ )
    1082           0 :                             for( long nX = nSrcX, nXN = nDstX; nX <= nSrcEndX1; nX++, nXN++ )
    1083           0 :                                 pWriteAcc->SetPixel( nYN, nXN, pWriteAcc->GetPixel( nY, nX ) );
    1084             :                     }
    1085           0 :                     else if( ( nDstX <= nSrcX ) && ( nDstY >= nSrcY ) )
    1086             :                     {
    1087           0 :                         for( long nY = nSrcEndY1, nYN = nDstEndY1; nY >= nSrcY; nY--, nYN-- )
    1088           0 :                             for( long nX = nSrcX, nXN = nDstX; nX <= nSrcEndX1; nX++, nXN++ )
    1089           0 :                                 pWriteAcc->SetPixel( nYN, nXN, pWriteAcc->GetPixel( nY, nX ) );
    1090             :                     }
    1091           0 :                     else if( ( nDstX >= nSrcX ) && ( nDstY <= nSrcY ) )
    1092             :                     {
    1093           0 :                         for( long nY = nSrcY, nYN = nDstY; nY <= nSrcEndY1; nY++, nYN++ )
    1094           0 :                             for( long nX = nSrcEndX1, nXN = nDstEndX1; nX >= nSrcX; nX--, nXN-- )
    1095           0 :                                 pWriteAcc->SetPixel( nYN, nXN, pWriteAcc->GetPixel( nY, nX ) );
    1096             :                     }
    1097             :                     else
    1098             :                     {
    1099           0 :                         for( long nY = nSrcEndY1, nYN = nDstEndY1; nY >= nSrcY; nY--, nYN-- )
    1100           0 :                             for( long nX = nSrcEndX1, nXN = nDstEndX1; nX >= nSrcX; nX--, nXN-- )
    1101           0 :                                 pWriteAcc->SetPixel( nYN, nXN, pWriteAcc->GetPixel( nY, nX ) );
    1102             :                     }
    1103             : 
    1104           0 :                     ReleaseAccess( pWriteAcc );
    1105           0 :                     bRet = true;
    1106             :                 }
    1107             :             }
    1108             :         }
    1109             :     }
    1110             : 
    1111       12900 :     return bRet;
    1112             : 
    1113             : }
    1114             : 
    1115           0 : bool Bitmap::Expand( sal_uLong nDX, sal_uLong nDY, const Color* pInitColor )
    1116             : {
    1117           0 :     bool bRet = false;
    1118             : 
    1119           0 :     if( nDX || nDY )
    1120             :     {
    1121           0 :         const Size          aSizePixel( GetSizePixel() );
    1122           0 :         const long          nWidth = aSizePixel.Width();
    1123           0 :         const long          nHeight = aSizePixel.Height();
    1124           0 :         const Size          aNewSize( nWidth + nDX, nHeight + nDY );
    1125           0 :         BitmapReadAccess*   pReadAcc = AcquireReadAccess();
    1126             : 
    1127           0 :         if( pReadAcc )
    1128             :         {
    1129           0 :             BitmapPalette       aBmpPal( pReadAcc->GetPalette() );
    1130           0 :             Bitmap              aNewBmp( aNewSize, GetBitCount(), &aBmpPal );
    1131           0 :             BitmapWriteAccess*  pWriteAcc = aNewBmp.AcquireWriteAccess();
    1132             : 
    1133           0 :             if( pWriteAcc )
    1134             :             {
    1135           0 :                 BitmapColor aColor;
    1136           0 :                 const long  nNewX = nWidth;
    1137           0 :                 const long  nNewY = nHeight;
    1138           0 :                 const long  nNewWidth = pWriteAcc->Width();
    1139           0 :                 const long  nNewHeight = pWriteAcc->Height();
    1140             :                 long        nX;
    1141             :                 long        nY;
    1142             : 
    1143           0 :                 if( pInitColor )
    1144           0 :                     aColor = pWriteAcc->GetBestMatchingColor( *pInitColor );
    1145             : 
    1146           0 :                 for( nY = 0L; nY < nHeight; nY++ )
    1147             :                 {
    1148           0 :                     pWriteAcc->CopyScanline( nY, *pReadAcc );
    1149             : 
    1150           0 :                     if( pInitColor && nDX )
    1151           0 :                         for( nX = nNewX; nX < nNewWidth; nX++ )
    1152           0 :                             pWriteAcc->SetPixel( nY, nX, aColor );
    1153             :                 }
    1154             : 
    1155           0 :                 if( pInitColor && nDY )
    1156           0 :                     for( nY = nNewY; nY < nNewHeight; nY++ )
    1157           0 :                         for( nX = 0; nX < nNewWidth; nX++ )
    1158           0 :                             pWriteAcc->SetPixel( nY, nX, aColor );
    1159             : 
    1160           0 :                 aNewBmp.ReleaseAccess( pWriteAcc );
    1161           0 :                 bRet = true;
    1162             :             }
    1163             : 
    1164           0 :             ReleaseAccess( pReadAcc );
    1165             : 
    1166           0 :             if( bRet )
    1167           0 :                 ImplAssignWithSize( aNewBmp );
    1168             :         }
    1169             :     }
    1170             : 
    1171           0 :     return bRet;
    1172             : }
    1173             : 
    1174         324 : Bitmap Bitmap::CreateMask( const Color& rTransColor, sal_uLong nTol ) const
    1175             : {
    1176         324 :     Bitmap              aNewBmp( GetSizePixel(), 1 );
    1177         324 :     BitmapWriteAccess*  pWriteAcc = aNewBmp.AcquireWriteAccess();
    1178         324 :     bool                bRet = false;
    1179             : 
    1180         324 :     if( pWriteAcc )
    1181             :     {
    1182         324 :         BitmapReadAccess* pReadAcc = ( (Bitmap*) this )->AcquireReadAccess();
    1183             : 
    1184         324 :         if( pReadAcc )
    1185             :         {
    1186         324 :             const long          nWidth = pReadAcc->Width();
    1187         324 :             const long          nHeight = pReadAcc->Height();
    1188         324 :             const BitmapColor   aBlack( pWriteAcc->GetBestMatchingColor( Color( COL_BLACK ) ) );
    1189         648 :             const BitmapColor   aWhite( pWriteAcc->GetBestMatchingColor( Color( COL_WHITE ) ) );
    1190             : 
    1191         324 :             if( !nTol )
    1192             :             {
    1193         316 :                 const BitmapColor   aTest( pReadAcc->GetBestMatchingColor( rTransColor ) );
    1194             :                 long nX, nY;
    1195             : 
    1196         622 :                 if( pReadAcc->GetScanlineFormat() == BMP_FORMAT_4BIT_MSN_PAL ||
    1197         306 :                     pReadAcc->GetScanlineFormat() == BMP_FORMAT_4BIT_LSN_PAL )
    1198             :                 {
    1199             :                     // optimized for 4Bit-MSN/LSN source palette
    1200          10 :                     const sal_uInt8 cTest = aTest.GetIndex();
    1201          10 :                     const long nShiftInit = ( ( pReadAcc->GetScanlineFormat() == BMP_FORMAT_4BIT_MSN_PAL ) ? 4 : 0 );
    1202             : 
    1203          20 :                     if( pWriteAcc->GetScanlineFormat() == BMP_FORMAT_1BIT_MSB_PAL &&
    1204          10 :                         aWhite.GetIndex() == 1 )
    1205             :                     {
    1206             :                         // optimized for 1Bit-MSB destination palette
    1207         140 :                         for( nY = 0L; nY < nHeight; nY++ )
    1208             :                         {
    1209         130 :                             Scanline pSrc = pReadAcc->GetScanline( nY );
    1210         130 :                             Scanline pDst = pWriteAcc->GetScanline( nY );
    1211         130 :                             long nShift = 0;
    1212       12298 :                             for( nX = 0L, nShift = nShiftInit; nX < nWidth; nX++, nShift ^= 4 )
    1213             :                             {
    1214       12168 :                                 if( cTest == ( ( pSrc[ nX >> 1 ] >> nShift ) & 0x0f ) )
    1215        2052 :                                     pDst[ nX >> 3 ] |= 1 << ( 7 - ( nX & 7 ) );
    1216             :                                 else
    1217       10116 :                                     pDst[ nX >> 3 ] &= ~( 1 << ( 7 - ( nX & 7 ) ) );
    1218             :                             }
    1219             :                         }
    1220             :                     }
    1221             :                     else
    1222             :                     {
    1223           0 :                         for( nY = 0L; nY < nHeight; nY++ )
    1224             :                         {
    1225           0 :                             Scanline pSrc = pReadAcc->GetScanline( nY );
    1226           0 :                             long nShift = 0;
    1227           0 :                             for( nX = 0L, nShift = nShiftInit; nX < nWidth; nX++, nShift ^= 4 )
    1228             :                             {
    1229           0 :                                 if( cTest == ( ( pSrc[ nX >> 1 ] >> nShift ) & 0x0f ) )
    1230           0 :                                     pWriteAcc->SetPixel( nY, nX, aWhite );
    1231             :                                 else
    1232           0 :                                     pWriteAcc->SetPixel( nY, nX, aBlack );
    1233             :                             }
    1234             :                         }
    1235             :                     }
    1236             :                 }
    1237         306 :                 else if( pReadAcc->GetScanlineFormat() == BMP_FORMAT_8BIT_PAL )
    1238             :                 {
    1239             :                     // optimized for 8Bit source palette
    1240         286 :                     const sal_uInt8 cTest = aTest.GetIndex();
    1241             : 
    1242         572 :                     if( pWriteAcc->GetScanlineFormat() == BMP_FORMAT_1BIT_MSB_PAL &&
    1243         286 :                         aWhite.GetIndex() == 1 )
    1244             :                     {
    1245             :                         // optimized for 1Bit-MSB destination palette
    1246        2964 :                         for( nY = 0L; nY < nHeight; nY++ )
    1247             :                         {
    1248        2678 :                             Scanline pSrc = pReadAcc->GetScanline( nY );
    1249        2678 :                             Scanline pDst = pWriteAcc->GetScanline( nY );
    1250       56186 :                             for( nX = 0L; nX < nWidth; nX++ )
    1251             :                             {
    1252       53508 :                                 if( cTest == pSrc[ nX ] )
    1253        6840 :                                     pDst[ nX >> 3 ] |= 1 << ( 7 - ( nX & 7 ) );
    1254             :                                 else
    1255       46668 :                                     pDst[ nX >> 3 ] &= ~( 1 << ( 7 - ( nX & 7 ) ) );
    1256             :                             }
    1257             :                         }
    1258             :                     }
    1259             :                     else
    1260             :                     {
    1261           0 :                         for( nY = 0L; nY < nHeight; nY++ )
    1262             :                         {
    1263           0 :                             Scanline pSrc = pReadAcc->GetScanline( nY );
    1264           0 :                             for( nX = 0L; nX < nWidth; nX++ )
    1265             :                             {
    1266           0 :                                 if( cTest == pSrc[ nX ] )
    1267           0 :                                     pWriteAcc->SetPixel( nY, nX, aWhite );
    1268             :                                 else
    1269           0 :                                     pWriteAcc->SetPixel( nY, nX, aBlack );
    1270             :                             }
    1271             :                         }
    1272             :                     }
    1273             :                 }
    1274             :                 else
    1275             :                 {
    1276             :                     // not optimized
    1277         660 :                     for( nY = 0L; nY < nHeight; nY++ )
    1278             :                     {
    1279       22280 :                         for( nX = 0L; nX < nWidth; nX++ )
    1280             :                         {
    1281       21640 :                             if( aTest == pReadAcc->GetPixel( nY, nX ) )
    1282        8676 :                                 pWriteAcc->SetPixel( nY, nX, aWhite );
    1283             :                             else
    1284       12964 :                                 pWriteAcc->SetPixel( nY, nX, aBlack );
    1285             :                         }
    1286             :                     }
    1287         316 :                 }
    1288             :             }
    1289             :             else
    1290             :             {
    1291           8 :                 BitmapColor aCol;
    1292             :                 long        nR, nG, nB;
    1293           8 :                 const long  nMinR = MinMax( (long) rTransColor.GetRed() - nTol, 0, 255 );
    1294           8 :                 const long  nMaxR = MinMax( (long) rTransColor.GetRed() + nTol, 0, 255 );
    1295           8 :                 const long  nMinG = MinMax( (long) rTransColor.GetGreen() - nTol, 0, 255 );
    1296           8 :                 const long  nMaxG = MinMax( (long) rTransColor.GetGreen() + nTol, 0, 255 );
    1297           8 :                 const long  nMinB = MinMax( (long) rTransColor.GetBlue() - nTol, 0, 255 );
    1298           8 :                 const long  nMaxB = MinMax( (long) rTransColor.GetBlue() + nTol, 0, 255 );
    1299             : 
    1300           8 :                 if( pReadAcc->HasPalette() )
    1301             :                 {
    1302           0 :                     for( long nY = 0L; nY < nHeight; nY++ )
    1303             :                     {
    1304           0 :                         for( long nX = 0L; nX < nWidth; nX++ )
    1305             :                         {
    1306           0 :                             aCol = pReadAcc->GetPaletteColor( pReadAcc->GetPixelIndex( nY, nX ) );
    1307           0 :                             nR = aCol.GetRed();
    1308           0 :                             nG = aCol.GetGreen();
    1309           0 :                             nB = aCol.GetBlue();
    1310             : 
    1311           0 :                             if( nMinR <= nR && nMaxR >= nR &&
    1312           0 :                                 nMinG <= nG && nMaxG >= nG &&
    1313           0 :                                 nMinB <= nB && nMaxB >= nB )
    1314             :                             {
    1315           0 :                                 pWriteAcc->SetPixel( nY, nX, aWhite );
    1316             :                             }
    1317             :                             else
    1318           0 :                                 pWriteAcc->SetPixel( nY, nX, aBlack );
    1319             :                         }
    1320             :                     }
    1321             :                 }
    1322             :                 else
    1323             :                 {
    1324         136 :                     for( long nY = 0L; nY < nHeight; nY++ )
    1325             :                     {
    1326        9728 :                         for( long nX = 0L; nX < nWidth; nX++ )
    1327             :                         {
    1328        9600 :                             aCol = pReadAcc->GetPixel( nY, nX );
    1329        9600 :                             nR = aCol.GetRed();
    1330        9600 :                             nG = aCol.GetGreen();
    1331        9600 :                             nB = aCol.GetBlue();
    1332             : 
    1333        9600 :                             if( nMinR <= nR && nMaxR >= nR &&
    1334        7816 :                                 nMinG <= nG && nMaxG >= nG &&
    1335        7568 :                                 nMinB <= nB && nMaxB >= nB )
    1336             :                             {
    1337        7568 :                                 pWriteAcc->SetPixel( nY, nX, aWhite );
    1338             :                             }
    1339             :                             else
    1340        2032 :                                 pWriteAcc->SetPixel( nY, nX, aBlack );
    1341             :                         }
    1342             :                     }
    1343           8 :                 }
    1344             :             }
    1345             : 
    1346         324 :             ( (Bitmap*) this )->ReleaseAccess( pReadAcc );
    1347         648 :             bRet = true;
    1348             :         }
    1349             : 
    1350         324 :         aNewBmp.ReleaseAccess( pWriteAcc );
    1351             :     }
    1352             : 
    1353         324 :     if( bRet )
    1354             :     {
    1355         324 :         aNewBmp.maPrefSize = maPrefSize;
    1356         324 :         aNewBmp.maPrefMapMode = maPrefMapMode;
    1357             :     }
    1358             :     else
    1359           0 :         aNewBmp = Bitmap();
    1360             : 
    1361         324 :     return aNewBmp;
    1362             : }
    1363             : 
    1364           0 : vcl::Region Bitmap::CreateRegion( const Color& rColor, const Rectangle& rRect ) const
    1365             : {
    1366           0 :     vcl::Region              aRegion;
    1367           0 :     Rectangle           aRect( rRect );
    1368           0 :     BitmapReadAccess*   pReadAcc = ( (Bitmap*) this )->AcquireReadAccess();
    1369             : 
    1370           0 :     aRect.Intersection( Rectangle( Point(), GetSizePixel() ) );
    1371           0 :     aRect.Justify();
    1372             : 
    1373           0 :     if( pReadAcc )
    1374             :     {
    1375             :         //Rectangle         aSubRect;
    1376           0 :         const long          nLeft = aRect.Left();
    1377           0 :         const long          nTop = aRect.Top();
    1378           0 :         const long          nRight = aRect.Right();
    1379           0 :         const long          nBottom = aRect.Bottom();
    1380           0 :         const BitmapColor   aMatch( pReadAcc->GetBestMatchingColor( rColor ) );
    1381             : 
    1382             :         //RectangleVector aRectangles;
    1383             :         //aRegion.ImplBeginAddRect();
    1384           0 :         std::vector< long > aLine;
    1385           0 :         long nYStart(nTop);
    1386           0 :         long nY(nTop);
    1387             : 
    1388           0 :         for( ; nY <= nBottom; nY++ )
    1389             :         {
    1390             :             //aSubRect.Top() = aSubRect.Bottom() = nY;
    1391           0 :             std::vector< long > aNewLine;
    1392           0 :             long nX(nLeft);
    1393             : 
    1394           0 :             for( ; nX <= nRight; )
    1395             :             {
    1396           0 :                 while( ( nX <= nRight ) && ( aMatch != pReadAcc->GetPixel( nY, nX ) ) )
    1397           0 :                     nX++;
    1398             : 
    1399           0 :                 if( nX <= nRight )
    1400             :                 {
    1401           0 :                     aNewLine.push_back(nX);
    1402             :                     //aSubRect.Left() = nX;
    1403             : 
    1404           0 :                     while( ( nX <= nRight ) && ( aMatch == pReadAcc->GetPixel( nY, nX ) ) )
    1405           0 :                         nX++;
    1406             : 
    1407             :                     //aSubRect.Right() = nX - 1L;
    1408           0 :                     aNewLine.push_back(nX - 1);
    1409             : 
    1410             :                     //aRegion.ImplAddRect( aSubRect );
    1411             :                     //aRectangles.push_back(aSubRect);
    1412             :                     //aRegion.Union(aSubRect);
    1413             :                 }
    1414             :             }
    1415             : 
    1416           0 :             if(aNewLine != aLine)
    1417             :             {
    1418             :                 // need to write aLine, it's different from the next line
    1419           0 :                 if(aLine.size())
    1420             :                 {
    1421           0 :                     Rectangle aSubRect;
    1422             : 
    1423             :                     // enter y values and proceed ystart
    1424           0 :                     aSubRect.Top() = nYStart;
    1425           0 :                     aSubRect.Bottom() = nY ? nY - 1 : 0;
    1426             : 
    1427           0 :                     for(sal_uInt32 a(0); a < aLine.size();)
    1428             :                     {
    1429           0 :                         aSubRect.Left() = aLine[a++];
    1430           0 :                         aSubRect.Right() = aLine[a++];
    1431           0 :                         aRegion.Union(aSubRect);
    1432             :                     }
    1433             :                 }
    1434             : 
    1435             :                 // copy line as new line
    1436           0 :                 aLine = aNewLine;
    1437           0 :                 nYStart = nY;
    1438             :             }
    1439           0 :         }
    1440             : 
    1441             :         // write last line if used
    1442           0 :         if(aLine.size())
    1443             :         {
    1444           0 :             Rectangle aSubRect;
    1445             : 
    1446             :             // enter y values
    1447           0 :             aSubRect.Top() = nYStart;
    1448           0 :             aSubRect.Bottom() = nY ? nY - 1 : 0;
    1449             : 
    1450           0 :             for(sal_uInt32 a(0); a < aLine.size();)
    1451             :             {
    1452           0 :                 aSubRect.Left() = aLine[a++];
    1453           0 :                 aSubRect.Right() = aLine[a++];
    1454           0 :                 aRegion.Union(aSubRect);
    1455             :             }
    1456             :         }
    1457             : 
    1458             :         //aRegion.ImplEndAddRect();
    1459             :         //aRegion.SetRegionRectangles(aRectangles);
    1460             : 
    1461           0 :         ( (Bitmap*) this )->ReleaseAccess( pReadAcc );
    1462             :     }
    1463             :     else
    1464           0 :         aRegion = aRect;
    1465             : 
    1466           0 :     return aRegion;
    1467             : }
    1468             : 
    1469          22 : bool Bitmap::Replace( const Bitmap& rMask, const Color& rReplaceColor )
    1470             : {
    1471          22 :     BitmapReadAccess*   pMaskAcc = ( (Bitmap&) rMask ).AcquireReadAccess();
    1472          22 :     BitmapWriteAccess*  pAcc = AcquireWriteAccess();
    1473          22 :     bool                bRet = false;
    1474             : 
    1475          22 :     if( pMaskAcc && pAcc )
    1476             :     {
    1477          22 :         const long          nWidth = std::min( pMaskAcc->Width(), pAcc->Width() );
    1478          22 :         const long          nHeight = std::min( pMaskAcc->Height(), pAcc->Height() );
    1479          22 :         const BitmapColor   aMaskWhite( pMaskAcc->GetBestMatchingColor( Color( COL_WHITE ) ) );
    1480          44 :         BitmapColor         aReplace;
    1481             : 
    1482          22 :         if( pAcc->HasPalette() )
    1483             :         {
    1484           2 :             const sal_uInt16 nActColors = pAcc->GetPaletteEntryCount();
    1485           2 :             const sal_uInt16 nMaxColors = 1 << pAcc->GetBitCount();
    1486             : 
    1487             :             // default to the nearest color
    1488           2 :             aReplace = pAcc->GetBestMatchingColor( rReplaceColor );
    1489             : 
    1490             :             // for paletted images without a matching palette entry
    1491             :             // look for an unused palette entry (NOTE: expensive!)
    1492           2 :             if( pAcc->GetPaletteColor( aReplace.GetIndex() ) != BitmapColor( rReplaceColor ) )
    1493             :             {
    1494             :                 // if the palette has empty entries use the last one
    1495           0 :                 if( nActColors < nMaxColors )
    1496             :                 {
    1497           0 :                     pAcc->SetPaletteEntryCount( nActColors + 1 );
    1498           0 :                     pAcc->SetPaletteColor( nActColors, rReplaceColor );
    1499           0 :                     aReplace = BitmapColor( (sal_uInt8) nActColors );
    1500             :                 }
    1501             :                 else
    1502             :                 {
    1503           0 :                     boost::scoped_array<bool> pFlags(new bool[ nMaxColors ]);
    1504             : 
    1505             :                     // Set all entries to false
    1506           0 :                     std::fill( pFlags.get(), pFlags.get()+nMaxColors, false );
    1507             : 
    1508           0 :                     for( long nY = 0L; nY < nHeight; nY++ )
    1509           0 :                         for( long nX = 0L; nX < nWidth; nX++ )
    1510           0 :                             pFlags[ pAcc->GetPixelIndex( nY, nX ) ] = true;
    1511             : 
    1512           0 :                     for( sal_uInt16 i = 0UL; i < nMaxColors; i++ )
    1513             :                     {
    1514             :                         // Hurray, we do have an unsused entry
    1515           0 :                         if( !pFlags[ i ] )
    1516             :                         {
    1517           0 :                             pAcc->SetPaletteColor( (sal_uInt16) i, rReplaceColor );
    1518           0 :                             aReplace = BitmapColor( (sal_uInt8) i );
    1519             :                         }
    1520           0 :                     }
    1521             :                 }
    1522             :             }
    1523             :         }
    1524             :         else
    1525          20 :             aReplace = rReplaceColor;
    1526             : 
    1527        3474 :         for( long nY = 0L; nY < nHeight; nY++ )
    1528     2885400 :             for( long nX = 0L; nX < nWidth; nX++ )
    1529     2881948 :                 if( pMaskAcc->GetPixel( nY, nX ) == aMaskWhite )
    1530       12608 :                     pAcc->SetPixel( nY, nX, aReplace );
    1531             : 
    1532          44 :         bRet = true;
    1533             :     }
    1534             : 
    1535          22 :     ( (Bitmap&) rMask ).ReleaseAccess( pMaskAcc );
    1536          22 :     ReleaseAccess( pAcc );
    1537             : 
    1538          22 :     return bRet;
    1539             : }
    1540             : 
    1541           0 : bool Bitmap::Replace( const AlphaMask& rAlpha, const Color& rMergeColor )
    1542             : {
    1543           0 :     Bitmap              aNewBmp( GetSizePixel(), 24 );
    1544           0 :     BitmapReadAccess*   pAcc = AcquireReadAccess();
    1545           0 :     BitmapReadAccess*   pAlphaAcc = ( (AlphaMask&) rAlpha ).AcquireReadAccess();
    1546           0 :     BitmapWriteAccess*  pNewAcc = aNewBmp.AcquireWriteAccess();
    1547           0 :     bool                bRet = false;
    1548             : 
    1549           0 :     if( pAcc && pAlphaAcc && pNewAcc )
    1550             :     {
    1551           0 :         BitmapColor aCol;
    1552           0 :         const long  nWidth = std::min( pAlphaAcc->Width(), pAcc->Width() );
    1553           0 :         const long  nHeight = std::min( pAlphaAcc->Height(), pAcc->Height() );
    1554             : 
    1555           0 :         for( long nY = 0L; nY < nHeight; nY++ )
    1556             :         {
    1557           0 :             for( long nX = 0L; nX < nWidth; nX++ )
    1558             :             {
    1559           0 :                 aCol = pAcc->GetColor( nY, nX );
    1560           0 :                 pNewAcc->SetPixel( nY, nX, aCol.Merge( rMergeColor, 255 - pAlphaAcc->GetPixelIndex( nY, nX ) ) );
    1561             :             }
    1562             :         }
    1563             : 
    1564           0 :         bRet = true;
    1565             :     }
    1566             : 
    1567           0 :     ReleaseAccess( pAcc );
    1568           0 :     ( (AlphaMask&) rAlpha ).ReleaseAccess( pAlphaAcc );
    1569           0 :     aNewBmp.ReleaseAccess( pNewAcc );
    1570             : 
    1571           0 :     if( bRet )
    1572             :     {
    1573           0 :         const MapMode   aMap( maPrefMapMode );
    1574           0 :         const Size      aSize( maPrefSize );
    1575             : 
    1576           0 :         *this = aNewBmp;
    1577             : 
    1578           0 :         maPrefMapMode = aMap;
    1579           0 :         maPrefSize = aSize;
    1580             :     }
    1581             : 
    1582           0 :     return bRet;
    1583             : }
    1584             : 
    1585         872 : bool Bitmap::Replace( const Color& rSearchColor, const Color& rReplaceColor, sal_uLong nTol )
    1586             : {
    1587             :     // Bitmaps with 1 bit color depth can cause problems
    1588             :     // if they have other entries than black/white in their palette
    1589         872 :     if( 1 == GetBitCount() )
    1590           0 :         Convert( BMP_CONVERSION_4BIT_COLORS );
    1591             : 
    1592         872 :     BitmapWriteAccess*  pAcc = AcquireWriteAccess();
    1593         872 :     bool                bRet = false;
    1594             : 
    1595         872 :     if( pAcc )
    1596             :     {
    1597         872 :         const long  nMinR = MinMax( (long) rSearchColor.GetRed() - nTol, 0, 255 );
    1598         872 :         const long  nMaxR = MinMax( (long) rSearchColor.GetRed() + nTol, 0, 255 );
    1599         872 :         const long  nMinG = MinMax( (long) rSearchColor.GetGreen() - nTol, 0, 255 );
    1600         872 :         const long  nMaxG = MinMax( (long) rSearchColor.GetGreen() + nTol, 0, 255 );
    1601         872 :         const long  nMinB = MinMax( (long) rSearchColor.GetBlue() - nTol, 0, 255 );
    1602         872 :         const long  nMaxB = MinMax( (long) rSearchColor.GetBlue() + nTol, 0, 255 );
    1603             : 
    1604         872 :         if( pAcc->HasPalette() )
    1605             :         {
    1606           0 :             for( sal_uInt16 i = 0, nPalCount = pAcc->GetPaletteEntryCount(); i < nPalCount; i++ )
    1607             :             {
    1608           0 :                 const BitmapColor& rCol = pAcc->GetPaletteColor( i );
    1609             : 
    1610           0 :                 if( nMinR <= rCol.GetRed() && nMaxR >= rCol.GetRed() &&
    1611           0 :                     nMinG <= rCol.GetGreen() && nMaxG >= rCol.GetGreen() &&
    1612           0 :                     nMinB <= rCol.GetBlue() && nMaxB >= rCol.GetBlue() )
    1613             :                 {
    1614           0 :                     pAcc->SetPaletteColor( i, rReplaceColor );
    1615             :                 }
    1616             :             }
    1617             :         }
    1618             :         else
    1619             :         {
    1620         872 :             BitmapColor         aCol;
    1621        1744 :             const BitmapColor   aReplace( pAcc->GetBestMatchingColor( rReplaceColor ) );
    1622             : 
    1623       20710 :             for( long nY = 0L, nHeight = pAcc->Height(); nY < nHeight; nY++ )
    1624             :             {
    1625      306290 :                 for( long nX = 0L, nWidth = pAcc->Width(); nX < nWidth; nX++ )
    1626             :                 {
    1627      286452 :                     aCol = pAcc->GetPixel( nY, nX );
    1628             : 
    1629      769104 :                     if( nMinR <= aCol.GetRed() && nMaxR >= aCol.GetRed() &&
    1630      294300 :                         nMinG <= aCol.GetGreen() && nMaxG >= aCol.GetGreen() &&
    1631      482652 :                         nMinB <= aCol.GetBlue() && nMaxB >= aCol.GetBlue() )
    1632             :                     {
    1633       98100 :                         pAcc->SetPixel( nY, nX, aReplace );
    1634             :                     }
    1635             :                 }
    1636         872 :             }
    1637             :         }
    1638             : 
    1639         872 :         ReleaseAccess( pAcc );
    1640         872 :         bRet = true;
    1641             :     }
    1642             : 
    1643         872 :     return bRet;
    1644             : }
    1645             : 
    1646          36 : bool Bitmap::Replace( const Color* pSearchColors, const Color* pReplaceColors,
    1647             :                       sal_uLong nColorCount, sal_uLong* _pTols )
    1648             : {
    1649             :     // Bitmaps with 1 bit color depth can cause problems
    1650             :     // if they have other entries than black/white in their palette
    1651          36 :     if( 1 == GetBitCount() )
    1652           0 :         Convert( BMP_CONVERSION_4BIT_COLORS );
    1653             : 
    1654          36 :     BitmapWriteAccess*  pAcc = AcquireWriteAccess();
    1655          36 :     bool                bRet = false;
    1656             : 
    1657          36 :     if( pAcc )
    1658             :     {
    1659          36 :         boost::scoped_array<long> pMinR(new long[ nColorCount ]);
    1660          72 :         boost::scoped_array<long> pMaxR(new long[ nColorCount ]);
    1661          72 :         boost::scoped_array<long> pMinG(new long[ nColorCount ]);
    1662          72 :         boost::scoped_array<long> pMaxG(new long[ nColorCount ]);
    1663          72 :         boost::scoped_array<long> pMinB(new long[ nColorCount ]);
    1664          72 :         boost::scoped_array<long> pMaxB(new long[ nColorCount ]);
    1665             :         long*   pTols;
    1666             :         sal_uLong   i;
    1667             : 
    1668          36 :         if( !_pTols )
    1669             :         {
    1670          36 :             pTols = new long[ nColorCount ];
    1671          36 :             memset( pTols, 0, nColorCount * sizeof( long ) );
    1672             :         }
    1673             :         else
    1674           0 :             pTols = (long*) _pTols;
    1675             : 
    1676         252 :         for( i = 0UL; i < nColorCount; i++ )
    1677             :         {
    1678         216 :             const Color&    rCol = pSearchColors[ i ];
    1679         216 :             const long      nTol = pTols[ i ];
    1680             : 
    1681         216 :             pMinR[ i ] = MinMax( (long) rCol.GetRed() - nTol, 0, 255 );
    1682         216 :             pMaxR[ i ] = MinMax( (long) rCol.GetRed() + nTol, 0, 255 );
    1683         216 :             pMinG[ i ] = MinMax( (long) rCol.GetGreen() - nTol, 0, 255 );
    1684         216 :             pMaxG[ i ] = MinMax( (long) rCol.GetGreen() + nTol, 0, 255 );
    1685         216 :             pMinB[ i ] = MinMax( (long) rCol.GetBlue() - nTol, 0, 255 );
    1686         216 :             pMaxB[ i ] = MinMax( (long) rCol.GetBlue() + nTol, 0, 255 );
    1687             :         }
    1688             : 
    1689          36 :         if( pAcc->HasPalette() )
    1690             :         {
    1691        6852 :             for( sal_uInt16 nEntry = 0, nPalCount = pAcc->GetPaletteEntryCount(); nEntry < nPalCount; nEntry++ )
    1692             :             {
    1693        6816 :                 const BitmapColor& rCol = pAcc->GetPaletteColor( nEntry );
    1694             : 
    1695       21012 :                 for( i = 0UL; i < nColorCount; i++ )
    1696             :                 {
    1697       75410 :                     if( pMinR[ i ] <= rCol.GetRed() && pMaxR[ i ] >= rCol.GetRed() &&
    1698       40080 :                         pMinG[ i ] <= rCol.GetGreen() && pMaxG[ i ] >= rCol.GetGreen() &&
    1699       47444 :                         pMinB[ i ] <= rCol.GetBlue() && pMaxB[ i ] >= rCol.GetBlue() )
    1700             :                     {
    1701        6702 :                         pAcc->SetPaletteColor( (sal_uInt16)nEntry, pReplaceColors[ i ] );
    1702        6702 :                         break;
    1703             :                     }
    1704             :                 }
    1705             :             }
    1706             :         }
    1707             :         else
    1708             :         {
    1709           0 :             BitmapColor     aCol;
    1710           0 :             boost::scoped_array<BitmapColor> pReplaces(new BitmapColor[ nColorCount ]);
    1711             : 
    1712           0 :             for( i = 0UL; i < nColorCount; i++ )
    1713           0 :                 pReplaces[ i ] = pAcc->GetBestMatchingColor( pReplaceColors[ i ] );
    1714             : 
    1715           0 :             for( long nY = 0L, nHeight = pAcc->Height(); nY < nHeight; nY++ )
    1716             :             {
    1717           0 :                 for( long nX = 0L, nWidth = pAcc->Width(); nX < nWidth; nX++ )
    1718             :                 {
    1719           0 :                     aCol = pAcc->GetPixel( nY, nX );
    1720             : 
    1721           0 :                     for( i = 0UL; i < nColorCount; i++ )
    1722             :                     {
    1723           0 :                         if( pMinR[ i ] <= aCol.GetRed() && pMaxR[ i ] >= aCol.GetRed() &&
    1724           0 :                             pMinG[ i ] <= aCol.GetGreen() && pMaxG[ i ] >= aCol.GetGreen() &&
    1725           0 :                             pMinB[ i ] <= aCol.GetBlue() && pMaxB[ i ] >= aCol.GetBlue() )
    1726             :                         {
    1727           0 :                             pAcc->SetPixel( nY, nX, pReplaces[ i ] );
    1728           0 :                             break;
    1729             :                         }
    1730             :                     }
    1731             :                 }
    1732           0 :             }
    1733             :         }
    1734             : 
    1735          36 :         if( !_pTols )
    1736          36 :             delete[] pTols;
    1737             : 
    1738          36 :         ReleaseAccess( pAcc );
    1739          72 :         bRet = true;
    1740             :     }
    1741             : 
    1742          36 :     return bRet;
    1743             : }
    1744             : 
    1745           0 : Bitmap Bitmap::CreateDisplayBitmap( OutputDevice* pDisplay )
    1746             : {
    1747           0 :     Bitmap aDispBmp( *this );
    1748             : 
    1749           0 :     if( mpImpBmp && ( pDisplay->mpGraphics || pDisplay->AcquireGraphics() ) )
    1750             :     {
    1751           0 :         ImpBitmap* pImpDispBmp = new ImpBitmap;
    1752             : 
    1753           0 :         if( pImpDispBmp->ImplCreate( *mpImpBmp, pDisplay->mpGraphics ) )
    1754           0 :             aDispBmp.ImplSetImpBitmap( pImpDispBmp );
    1755             :         else
    1756           0 :             delete pImpDispBmp;
    1757             :     }
    1758             : 
    1759           0 :     return aDispBmp;
    1760             : }
    1761             : 
    1762           0 : bool Bitmap::CombineSimple( const Bitmap& rMask, BmpCombine eCombine )
    1763             : {
    1764           0 :     BitmapReadAccess*   pMaskAcc = ( (Bitmap&) rMask ).AcquireReadAccess();
    1765           0 :     BitmapWriteAccess*  pAcc = AcquireWriteAccess();
    1766           0 :     bool                bRet = false;
    1767             : 
    1768           0 :     if( pMaskAcc && pAcc )
    1769             :     {
    1770           0 :         const long          nWidth = std::min( pMaskAcc->Width(), pAcc->Width() );
    1771           0 :         const long          nHeight = std::min( pMaskAcc->Height(), pAcc->Height() );
    1772           0 :         const Color         aColBlack( COL_BLACK );
    1773           0 :         BitmapColor         aPixel;
    1774           0 :         BitmapColor         aMaskPixel;
    1775           0 :         const BitmapColor   aWhite( pAcc->GetBestMatchingColor( Color( COL_WHITE ) ) );
    1776           0 :         const BitmapColor   aBlack( pAcc->GetBestMatchingColor( aColBlack ) );
    1777           0 :         const BitmapColor   aMaskBlack( pMaskAcc->GetBestMatchingColor( aColBlack ) );
    1778             : 
    1779           0 :         switch( eCombine )
    1780             :         {
    1781             :             case( BMP_COMBINE_COPY ):
    1782             :             {
    1783           0 :                 for( long nY = 0L; nY < nHeight; nY++ ) for( long nX = 0L; nX < nWidth; nX++ )
    1784             :                 {
    1785           0 :                     if( pMaskAcc->GetPixel( nY, nX ) == aMaskBlack )
    1786           0 :                         pAcc->SetPixel( nY, nX, aBlack );
    1787             :                     else
    1788           0 :                         pAcc->SetPixel( nY, nX, aWhite );
    1789             :                 }
    1790             :             }
    1791           0 :             break;
    1792             : 
    1793             :             case( BMP_COMBINE_INVERT ):
    1794             :             {
    1795           0 :                 for( long nY = 0L; nY < nHeight; nY++ ) for( long nX = 0L; nX < nWidth; nX++ )
    1796             :                 {
    1797           0 :                     if( pAcc->GetPixel( nY, nX ) == aBlack )
    1798           0 :                         pAcc->SetPixel( nY, nX, aWhite );
    1799             :                     else
    1800           0 :                         pAcc->SetPixel( nY, nX, aBlack );
    1801             :                 }
    1802             :             }
    1803           0 :             break;
    1804             : 
    1805             :             case( BMP_COMBINE_AND ):
    1806             :             {
    1807           0 :                 for( long nY = 0L; nY < nHeight; nY++ ) for( long nX = 0L; nX < nWidth; nX++ )
    1808             :                 {
    1809           0 :                     if( pMaskAcc->GetPixel( nY, nX ) != aMaskBlack && pAcc->GetPixel( nY, nX ) != aBlack )
    1810           0 :                         pAcc->SetPixel( nY, nX, aWhite );
    1811             :                     else
    1812           0 :                         pAcc->SetPixel( nY, nX, aBlack );
    1813             :                 }
    1814             :             }
    1815           0 :             break;
    1816             : 
    1817             :             case( BMP_COMBINE_NAND ):
    1818             :             {
    1819           0 :                 for( long nY = 0L; nY < nHeight; nY++ ) for( long nX = 0L; nX < nWidth; nX++ )
    1820             :                 {
    1821           0 :                     if( pMaskAcc->GetPixel( nY, nX ) != aMaskBlack && pAcc->GetPixel( nY, nX ) != aBlack )
    1822           0 :                         pAcc->SetPixel( nY, nX, aBlack );
    1823             :                     else
    1824           0 :                         pAcc->SetPixel( nY, nX, aWhite );
    1825             :                 }
    1826             :             }
    1827           0 :             break;
    1828             : 
    1829             :             case( BMP_COMBINE_OR ):
    1830             :             {
    1831           0 :                 for( long nY = 0L; nY < nHeight; nY++ ) for( long nX = 0L; nX < nWidth; nX++ )
    1832             :                 {
    1833           0 :                     if( pMaskAcc->GetPixel( nY, nX ) != aMaskBlack || pAcc->GetPixel( nY, nX ) != aBlack )
    1834           0 :                         pAcc->SetPixel( nY, nX, aWhite );
    1835             :                     else
    1836           0 :                         pAcc->SetPixel( nY, nX, aBlack );
    1837             :                 }
    1838             :             }
    1839           0 :             break;
    1840             : 
    1841             :             case( BMP_COMBINE_NOR ):
    1842             :             {
    1843           0 :                 for( long nY = 0L; nY < nHeight; nY++ ) for( long nX = 0L; nX < nWidth; nX++ )
    1844             :                 {
    1845           0 :                     if( pMaskAcc->GetPixel( nY, nX ) != aMaskBlack || pAcc->GetPixel( nY, nX ) != aBlack )
    1846           0 :                         pAcc->SetPixel( nY, nX, aBlack );
    1847             :                     else
    1848           0 :                         pAcc->SetPixel( nY, nX, aWhite );
    1849             :                 }
    1850             :             }
    1851           0 :             break;
    1852             : 
    1853             :             case( BMP_COMBINE_XOR ):
    1854             :             {
    1855           0 :                 for( long nY = 0L; nY < nHeight; nY++ ) for( long nX = 0L; nX < nWidth; nX++ )
    1856             :                 {
    1857           0 :                     aPixel = pAcc->GetPixel( nY, nX );
    1858           0 :                     aMaskPixel = pMaskAcc->GetPixel( nY, nX );
    1859             : 
    1860           0 :                     if( ( aMaskPixel != aMaskBlack && aPixel == aBlack ) ||
    1861           0 :                         ( aMaskPixel == aMaskBlack && aPixel != aBlack ) )
    1862             :                     {
    1863           0 :                         pAcc->SetPixel( nY, nX, aWhite );
    1864             :                     }
    1865             :                     else
    1866           0 :                         pAcc->SetPixel( nY, nX, aBlack );
    1867             :                 }
    1868             :             }
    1869           0 :             break;
    1870             : 
    1871             :             case( BMP_COMBINE_NXOR ):
    1872             :             {
    1873           0 :                 for( long nY = 0L; nY < nHeight; nY++ ) for( long nX = 0L; nX < nWidth; nX++ )
    1874             :                 {
    1875           0 :                     aPixel = pAcc->GetPixel( nY, nX );
    1876           0 :                     aMaskPixel = pMaskAcc->GetPixel( nY, nX );
    1877             : 
    1878           0 :                     if( ( aMaskPixel != aMaskBlack && aPixel == aBlack ) ||
    1879           0 :                         ( aMaskPixel == aMaskBlack && aPixel != aBlack ) )
    1880             :                     {
    1881           0 :                         pAcc->SetPixel( nY, nX, aBlack );
    1882             :                     }
    1883             :                     else
    1884           0 :                         pAcc->SetPixel( nY, nX, aWhite );
    1885             :                 }
    1886             :             }
    1887           0 :             break;
    1888             :         }
    1889             : 
    1890           0 :         bRet = true;
    1891             :     }
    1892             : 
    1893           0 :     ( (Bitmap&) rMask ).ReleaseAccess( pMaskAcc );
    1894           0 :     ReleaseAccess( pAcc );
    1895             : 
    1896           0 :     return bRet;
    1897             : }
    1898             : 
    1899             : // TODO: Have a look at OutputDevice::ImplDrawAlpha() for some
    1900             : // optimizations. Might even consolidate the code here and there.
    1901           0 : bool Bitmap::Blend( const AlphaMask& rAlpha, const Color& rBackgroundColor )
    1902             : {
    1903             :     // Convert to a truecolor bitmap, if we're a paletted one. There's
    1904             :     // room for tradeoff decision here, maybe later for an overload (or a flag)
    1905           0 :     if( GetBitCount() <= 8 )
    1906           0 :         Convert( BMP_CONVERSION_24BIT );
    1907             : 
    1908           0 :     BitmapReadAccess*   pAlphaAcc = const_cast<AlphaMask&>(rAlpha).AcquireReadAccess();
    1909           0 :     BitmapWriteAccess*  pAcc = AcquireWriteAccess();
    1910           0 :     bool                bRet = false;
    1911             : 
    1912           0 :     if( pAlphaAcc && pAcc )
    1913             :     {
    1914           0 :         const long          nWidth = std::min( pAlphaAcc->Width(), pAcc->Width() );
    1915           0 :         const long          nHeight = std::min( pAlphaAcc->Height(), pAcc->Height() );
    1916             : 
    1917           0 :         for( long nY = 0L; nY < nHeight; ++nY )
    1918           0 :             for( long nX = 0L; nX < nWidth; ++nX )
    1919             :                 pAcc->SetPixel( nY, nX,
    1920             :                                 pAcc->GetPixel( nY, nX ).Merge( rBackgroundColor,
    1921           0 :                                                                 255 - pAlphaAcc->GetPixelIndex( nY, nX ) ) );
    1922             : 
    1923           0 :         bRet = true;
    1924             :     }
    1925             : 
    1926           0 :     const_cast<AlphaMask&>(rAlpha).ReleaseAccess( pAlphaAcc );
    1927           0 :     ReleaseAccess( pAcc );
    1928             : 
    1929           0 :     return bRet;
    1930             : }
    1931             : 
    1932           0 : bool Bitmap::MakeMono( sal_uInt8 cThreshold )
    1933             : {
    1934           0 :     return ImplMakeMono( cThreshold );
    1935             : }
    1936             : 
    1937           0 : bool Bitmap::GetSystemData( BitmapSystemData& rData ) const
    1938             : {
    1939           0 :     bool bRet = false;
    1940           0 :     if( mpImpBmp )
    1941             :     {
    1942           0 :         SalBitmap* pSalBitmap = mpImpBmp->ImplGetSalBitmap();
    1943           0 :         if( pSalBitmap )
    1944           0 :             bRet = pSalBitmap->GetSystemData( rData );
    1945             :     }
    1946             : 
    1947           0 :     return bRet;
    1948        1233 : }
    1949             : 
    1950             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10