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

Generated by: LCOV version 1.10