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

Generated by: LCOV version 1.10