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

Generated by: LCOV version 1.10