LCOV - code coverage report
Current view: top level - vcl/source/gdi - bitmapex.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 351 588 59.7 %
Date: 2014-04-11 Functions: 36 50 72.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <ctype.h>
      21             : #include <rtl/crc.h>
      22             : #include <rtl/strbuf.hxx>
      23             : 
      24             : #include <tools/stream.hxx>
      25             : #include <tools/debug.hxx>
      26             : #include <tools/rc.h>
      27             : #include <vcl/salbtype.hxx>
      28             : #include <vcl/outdev.hxx>
      29             : #include <vcl/alpha.hxx>
      30             : #include <vcl/bitmapex.hxx>
      31             : #include <vcl/dibtools.hxx>
      32             : #include <vcl/pngread.hxx>
      33             : #include <vcl/svapp.hxx>
      34             : #include <vcl/bmpacc.hxx>
      35             : #include <vcl/virdev.hxx>
      36             : #include <vcl/settings.hxx>
      37             : 
      38             : #include <image.h>
      39             : #include <impimagetree.hxx>
      40             : #include <basegfx/matrix/b2dhommatrixtools.hxx>
      41             : 
      42             : // BitmapEx::Create
      43             : #include <salbmp.hxx>
      44             : #include <salinst.hxx>
      45             : #include <svdata.hxx>
      46             : #include <com/sun/star/beans/XFastPropertySet.hpp>
      47             : #include <boost/scoped_ptr.hpp>
      48             : using namespace ::com::sun::star;
      49             : 
      50      477767 : BitmapEx::BitmapEx() :
      51             :         eTransparent( TRANSPARENT_NONE ),
      52      477767 :         bAlpha      ( false )
      53             : {
      54      477767 : }
      55             : 
      56      819520 : BitmapEx::BitmapEx( const BitmapEx& rBitmapEx ) :
      57             :         aBitmap             ( rBitmapEx.aBitmap ),
      58             :         aMask               ( rBitmapEx.aMask ),
      59             :         aBitmapSize         ( rBitmapEx.aBitmapSize ),
      60             :         aTransparentColor   ( rBitmapEx.aTransparentColor ),
      61             :         eTransparent        ( rBitmapEx.eTransparent ),
      62      819520 :         bAlpha              ( rBitmapEx.bAlpha )
      63             : {
      64      819520 : }
      65             : 
      66        1836 : BitmapEx::BitmapEx( const BitmapEx& rBitmapEx, Point aSrc, Size aSize ) :
      67             :         eTransparent( TRANSPARENT_NONE ),
      68        1836 :         bAlpha      ( false )
      69             : {
      70        1836 :     if( rBitmapEx.IsEmpty() )
      71        1836 :         return;
      72             : 
      73        1836 :     aBitmap = Bitmap( aSize, rBitmapEx.aBitmap.GetBitCount() );
      74        1836 :     aBitmapSize = aSize;
      75        1836 :     if( rBitmapEx.IsAlpha() )
      76             :     {
      77        1701 :         bAlpha = true;
      78        1701 :         aMask = AlphaMask( aSize ).ImplGetBitmap();
      79             :     }
      80         135 :     else if( rBitmapEx.IsTransparent() )
      81         135 :         aMask = Bitmap( aSize, rBitmapEx.aMask.GetBitCount() );
      82             : 
      83        1836 :     Rectangle aDestRect( Point( 0, 0 ), aSize );
      84        1836 :     Rectangle aSrcRect( aSrc, aSize );
      85        1836 :     CopyPixel( aDestRect, aSrcRect, &rBitmapEx );
      86             : }
      87             : 
      88       15757 : BitmapEx::BitmapEx( const ResId& rResId ) :
      89             :         eTransparent( TRANSPARENT_NONE ),
      90       15757 :         bAlpha      ( false )
      91             : {
      92       15757 :     static ImplImageTreeSingletonRef    aImageTree;
      93       15757 :     ResMgr*                             pResMgr = NULL;
      94             : 
      95       15757 :     ResMgr::GetResourceSkipHeader( rResId.SetRT( RSC_BITMAP ), &pResMgr );
      96       15757 :     pResMgr->ReadLong();
      97       15757 :     pResMgr->ReadLong();
      98             : 
      99       15757 :     const OUString aFileName( pResMgr->ReadString() );
     100       31514 :     OUString aIconTheme = Application::GetSettings().GetStyleSettings().DetermineIconTheme();
     101             : 
     102       15757 :     if( !aImageTree->loadImage( aFileName, aIconTheme, *this, true ) )
     103             :     {
     104             : #ifdef DBG_UTIL
     105             :         OStringBuffer aErrorStr(
     106             :             "BitmapEx::BitmapEx( const ResId& rResId ): could not load image <");
     107             :         aErrorStr.append(OUStringToOString(aFileName, RTL_TEXTENCODING_ASCII_US)).append('>');
     108             :         OSL_FAIL(aErrorStr.getStr());
     109             : #endif
     110       15757 :     }
     111       15757 : }
     112             : 
     113        5332 : BitmapEx::BitmapEx( const Bitmap& rBmp ) :
     114             :         aBitmap     ( rBmp ),
     115        5332 :         aBitmapSize ( aBitmap.GetSizePixel() ),
     116             :         eTransparent( TRANSPARENT_NONE ),
     117       10664 :         bAlpha      ( false )
     118             : {
     119        5332 : }
     120             : 
     121        4417 : BitmapEx::BitmapEx( const Bitmap& rBmp, const Bitmap& rMask ) :
     122             :         aBitmap         ( rBmp ),
     123             :         aMask           ( rMask ),
     124        4417 :         aBitmapSize     ( aBitmap.GetSizePixel() ),
     125        4417 :         eTransparent    ( !rMask ? TRANSPARENT_NONE : TRANSPARENT_BITMAP ),
     126       13251 :         bAlpha          ( false )
     127             : {
     128        4417 :     if(!!aBitmap && !!aMask && aBitmap.GetSizePixel() != aMask.GetSizePixel())
     129             :     {
     130             :         OSL_ENSURE(false, "Mask size differs from Bitmap size, corrected Mask (!)");
     131           0 :         aMask.Scale(aBitmap.GetSizePixel());
     132             :     }
     133             : 
     134             :     // Ensure a mask is exactly one bit deep
     135        4417 :     if( !!aMask && aMask.GetBitCount() != 1 )
     136             :     {
     137             :         OSL_TRACE("BitmapEx: forced mask to monochrome");
     138          19 :         aMask.ImplMakeMono( 255 );
     139             :     }
     140        4417 : }
     141             : 
     142       29494 : BitmapEx::BitmapEx( const Bitmap& rBmp, const AlphaMask& rAlphaMask ) :
     143             :         aBitmap         ( rBmp ),
     144       29494 :         aMask           ( rAlphaMask.ImplGetBitmap() ),
     145       29494 :         aBitmapSize     ( aBitmap.GetSizePixel() ),
     146       29494 :         eTransparent    ( !rAlphaMask ? TRANSPARENT_NONE : TRANSPARENT_BITMAP ),
     147      117976 :         bAlpha          ( !rAlphaMask ? false : true )
     148             : {
     149       29494 :     if(!!aBitmap && !!aMask && aBitmap.GetSizePixel() != aMask.GetSizePixel())
     150             :     {
     151             :         OSL_ENSURE(false, "Alpha size differs from Bitmap size, corrected Mask (!)");
     152           0 :         aMask.Scale(rBmp.GetSizePixel());
     153             :     }
     154             : 
     155             :     // #i75531# the workaround below can go when
     156             :     // X11SalGraphics::drawAlphaBitmap()'s render acceleration
     157             :     // can handle the bitmap depth mismatch directly
     158       29494 :     if( aBitmap.GetBitCount() < aMask.GetBitCount() )
     159          36 :         aBitmap.Convert( BMP_CONVERSION_24BIT );
     160       29494 : }
     161             : 
     162         140 : BitmapEx::BitmapEx( const Bitmap& rBmp, const Color& rTransparentColor ) :
     163             :         aBitmap             ( rBmp ),
     164         140 :         aBitmapSize         ( aBitmap.GetSizePixel() ),
     165             :         aTransparentColor   ( rTransparentColor ),
     166             :         eTransparent        ( TRANSPARENT_BITMAP ),
     167         280 :         bAlpha              ( false )
     168             : {
     169         140 :     aMask = aBitmap.CreateMask( aTransparentColor );
     170             : 
     171             :     DBG_ASSERT( rBmp.GetSizePixel() == aMask.GetSizePixel(),
     172             :                 "BitmapEx::BitmapEx(): size mismatch for bitmap and alpha mask." );
     173         140 : }
     174             : 
     175     1352666 : BitmapEx::~BitmapEx()
     176             : {
     177     1352666 : }
     178             : 
     179      200930 : BitmapEx& BitmapEx::operator=( const BitmapEx& rBitmapEx )
     180             : {
     181      200930 :     if( &rBitmapEx != this )
     182             :     {
     183      200930 :         aBitmap = rBitmapEx.aBitmap;
     184      200930 :         aMask = rBitmapEx.aMask;
     185      200930 :         aBitmapSize = rBitmapEx.aBitmapSize;
     186      200930 :         aTransparentColor = rBitmapEx.aTransparentColor;
     187      200930 :         eTransparent = rBitmapEx.eTransparent;
     188      200930 :         bAlpha = rBitmapEx.bAlpha;
     189             :     }
     190             : 
     191      200930 :     return *this;
     192             : }
     193             : 
     194        1865 : bool BitmapEx::operator==( const BitmapEx& rBitmapEx ) const
     195             : {
     196        1865 :     if( eTransparent != rBitmapEx.eTransparent )
     197           0 :         return false;
     198             : 
     199        1865 :     if( aBitmap != rBitmapEx.aBitmap )
     200           2 :         return false;
     201             : 
     202        1863 :     if( aBitmapSize != rBitmapEx.aBitmapSize )
     203           0 :         return false;
     204             : 
     205        1863 :     if( eTransparent == TRANSPARENT_NONE )
     206         277 :         return true;
     207             : 
     208        1586 :     if( eTransparent == TRANSPARENT_COLOR )
     209           0 :         return aTransparentColor == rBitmapEx.aTransparentColor;
     210             : 
     211        1586 :     return( ( aMask == rBitmapEx.aMask ) && ( bAlpha == rBitmapEx.bAlpha ) );
     212             : }
     213             : 
     214           0 : bool BitmapEx::IsEqual( const BitmapEx& rBmpEx ) const
     215             : {
     216           0 :     return( rBmpEx.eTransparent == eTransparent &&
     217           0 :             rBmpEx.bAlpha == bAlpha &&
     218           0 :             rBmpEx.aBitmap.IsEqual( aBitmap ) &&
     219           0 :             rBmpEx.aMask.IsEqual( aMask ) );
     220             : }
     221             : 
     222      503209 : bool BitmapEx::IsEmpty() const
     223             : {
     224      503209 :     return( aBitmap.IsEmpty() && aMask.IsEmpty() );
     225             : }
     226             : 
     227      267295 : void BitmapEx::SetEmpty()
     228             : {
     229      267295 :     aBitmap.SetEmpty();
     230      267295 :     aMask.SetEmpty();
     231      267295 :     eTransparent = TRANSPARENT_NONE;
     232      267295 :     bAlpha = false;
     233      267295 : }
     234             : 
     235      232723 : void BitmapEx::Clear()
     236             : {
     237      232723 :     SetEmpty();
     238      232723 : }
     239             : 
     240      364780 : bool BitmapEx::IsTransparent() const
     241             : {
     242      364780 :     return( eTransparent != TRANSPARENT_NONE );
     243             : }
     244             : 
     245      356695 : bool BitmapEx::IsAlpha() const
     246             : {
     247      356695 :     return( IsTransparent() && bAlpha );
     248             : }
     249             : 
     250      181774 : Bitmap BitmapEx::GetBitmap( const Color* pTransReplaceColor ) const
     251             : {
     252      181774 :     Bitmap aRetBmp( aBitmap );
     253             : 
     254      181774 :     if( pTransReplaceColor && ( eTransparent != TRANSPARENT_NONE ) )
     255             :     {
     256           0 :         Bitmap aTempMask;
     257             : 
     258           0 :         if( eTransparent == TRANSPARENT_COLOR )
     259           0 :             aTempMask = aBitmap.CreateMask( aTransparentColor );
     260             :         else
     261           0 :             aTempMask = aMask;
     262             : 
     263           0 :         if( !IsAlpha() )
     264           0 :             aRetBmp.Replace( aTempMask, *pTransReplaceColor );
     265             :         else
     266           0 :             aRetBmp.Replace( GetAlpha(), *pTransReplaceColor );
     267             :     }
     268             : 
     269      181774 :     return aRetBmp;
     270             : }
     271             : 
     272         616 : Bitmap BitmapEx::GetMask() const
     273             : {
     274         616 :     Bitmap aRet( aMask );
     275             : 
     276         616 :     if( IsAlpha() )
     277           3 :         aRet.ImplMakeMono( 255 );
     278             : 
     279         616 :     return aRet;
     280             : }
     281             : 
     282      155756 : AlphaMask BitmapEx::GetAlpha() const
     283             : {
     284      155756 :     if( IsAlpha() )
     285             :     {
     286      155756 :         AlphaMask aAlpha;
     287      155756 :         aAlpha.ImplSetBitmap( aMask );
     288      155756 :         return aAlpha;
     289             :     }
     290             :     else
     291             :     {
     292           0 :         return aMask;
     293             :     }
     294             : }
     295             : 
     296        2002 : sal_uLong BitmapEx::GetSizeBytes() const
     297             : {
     298        2002 :     sal_uLong nSizeBytes = aBitmap.GetSizeBytes();
     299             : 
     300        2002 :     if( eTransparent == TRANSPARENT_BITMAP )
     301         712 :         nSizeBytes += aMask.GetSizeBytes();
     302             : 
     303        2002 :     return nSizeBytes;
     304             : }
     305             : 
     306        1303 : sal_uLong BitmapEx::GetChecksum() const
     307             : {
     308        1303 :     sal_uInt32  nCrc = aBitmap.GetChecksum();
     309             :     SVBT32      aBT32;
     310             : 
     311        1303 :     UInt32ToSVBT32( (long) eTransparent, aBT32 );
     312        1303 :     nCrc = rtl_crc32( nCrc, aBT32, 4 );
     313             : 
     314        1303 :     UInt32ToSVBT32( (long) bAlpha, aBT32 );
     315        1303 :     nCrc = rtl_crc32( nCrc, aBT32, 4 );
     316             : 
     317        1303 :     if( ( TRANSPARENT_BITMAP == eTransparent ) && !aMask.IsEmpty() )
     318             :     {
     319         480 :         UInt32ToSVBT32( aMask.GetChecksum(), aBT32 );
     320         480 :         nCrc = rtl_crc32( nCrc, aBT32, 4 );
     321             :     }
     322             : 
     323        1303 :     return nCrc;
     324             : }
     325             : 
     326        2267 : void BitmapEx::SetSizePixel( const Size& rNewSize, sal_uInt32 nScaleFlag )
     327             : {
     328        2267 :     if(GetSizePixel() != rNewSize)
     329             :     {
     330          53 :         Scale( rNewSize, nScaleFlag );
     331             :     }
     332        2267 : }
     333             : 
     334           0 : bool BitmapEx::Invert()
     335             : {
     336           0 :     bool bRet = false;
     337             : 
     338           0 :     if( !!aBitmap )
     339             :     {
     340           0 :         bRet = aBitmap.Invert();
     341             : 
     342           0 :         if( bRet && ( eTransparent == TRANSPARENT_COLOR ) )
     343           0 :             aTransparentColor = BitmapColor( aTransparentColor ).Invert();
     344             :     }
     345             : 
     346           0 :     return bRet;
     347             : }
     348             : 
     349           0 : bool BitmapEx::Mirror( sal_uLong nMirrorFlags )
     350             : {
     351           0 :     bool bRet = false;
     352             : 
     353           0 :     if( !!aBitmap )
     354             :     {
     355           0 :         bRet = aBitmap.Mirror( nMirrorFlags );
     356             : 
     357           0 :         if( bRet && ( eTransparent == TRANSPARENT_BITMAP ) && !!aMask )
     358           0 :             aMask.Mirror( nMirrorFlags );
     359             :     }
     360             : 
     361           0 :     return bRet;
     362             : }
     363             : 
     364        3359 : bool BitmapEx::Scale( const double& rScaleX, const double& rScaleY, sal_uInt32 nScaleFlag )
     365             : {
     366        3359 :     bool bRet = false;
     367             : 
     368        3359 :     if( !!aBitmap )
     369             :     {
     370        3359 :         bRet = aBitmap.Scale( rScaleX, rScaleY, nScaleFlag );
     371             : 
     372        3359 :         if( bRet && ( eTransparent == TRANSPARENT_BITMAP ) && !!aMask )
     373             :         {
     374        3200 :             aMask.Scale( rScaleX, rScaleY, nScaleFlag );
     375             :         }
     376             : 
     377        3359 :         aBitmapSize = aBitmap.GetSizePixel();
     378             : 
     379             :         DBG_ASSERT( !aMask || aBitmap.GetSizePixel() == aMask.GetSizePixel(),
     380             :                     "BitmapEx::Scale(): size mismatch for bitmap and alpha mask." );
     381             :     }
     382             : 
     383        3359 :     return bRet;
     384             : }
     385             : 
     386        1306 : bool BitmapEx::Scale( const Size& rNewSize, sal_uInt32 nScaleFlag )
     387             : {
     388             :     bool bRet;
     389             : 
     390        3918 :     if( aBitmapSize.Width() && aBitmapSize.Height() &&
     391        1774 :         ( rNewSize.Width()  != aBitmapSize.Width() ||
     392         468 :           rNewSize.Height() != aBitmapSize.Height() ) )
     393             :     {
     394        1306 :         bRet = Scale( (double) rNewSize.Width() / aBitmapSize.Width(),
     395        1306 :                       (double) rNewSize.Height() / aBitmapSize.Height(),
     396        2612 :                       nScaleFlag );
     397             :     }
     398             :     else
     399           0 :         bRet = true;
     400             : 
     401        1306 :     return bRet;
     402             : }
     403             : 
     404           0 : bool BitmapEx::Rotate( long nAngle10, const Color& rFillColor )
     405             : {
     406           0 :     bool bRet = false;
     407             : 
     408           0 :     if( !!aBitmap )
     409             :     {
     410           0 :         const bool bTransRotate = ( Color( COL_TRANSPARENT ) == rFillColor );
     411             : 
     412           0 :         if( bTransRotate )
     413             :         {
     414           0 :             if( eTransparent == TRANSPARENT_COLOR )
     415           0 :                 bRet = aBitmap.Rotate( nAngle10, aTransparentColor );
     416             :             else
     417             :             {
     418           0 :                 bRet = aBitmap.Rotate( nAngle10, COL_BLACK );
     419             : 
     420           0 :                 if( eTransparent == TRANSPARENT_NONE )
     421             :                 {
     422           0 :                     aMask = Bitmap( aBitmapSize, 1 );
     423           0 :                     aMask.Erase( COL_BLACK );
     424           0 :                     eTransparent = TRANSPARENT_BITMAP;
     425             :                 }
     426             : 
     427           0 :                 if( bRet && !!aMask )
     428           0 :                     aMask.Rotate( nAngle10, COL_WHITE );
     429             :             }
     430             :         }
     431             :         else
     432             :         {
     433           0 :             bRet = aBitmap.Rotate( nAngle10, rFillColor );
     434             : 
     435           0 :             if( bRet && ( eTransparent == TRANSPARENT_BITMAP ) && !!aMask )
     436           0 :                 aMask.Rotate( nAngle10, COL_WHITE );
     437             :         }
     438             : 
     439           0 :         aBitmapSize = aBitmap.GetSizePixel();
     440             : 
     441             :         DBG_ASSERT( !aMask || aBitmap.GetSizePixel() == aMask.GetSizePixel(),
     442             :                     "BitmapEx::Rotate(): size mismatch for bitmap and alpha mask." );
     443             :     }
     444             : 
     445           0 :     return bRet;
     446             : }
     447             : 
     448         651 : bool BitmapEx::Crop( const Rectangle& rRectPixel )
     449             : {
     450         651 :     bool bRet = false;
     451             : 
     452         651 :     if( !!aBitmap )
     453             :     {
     454         651 :         bRet = aBitmap.Crop( rRectPixel );
     455             : 
     456         651 :         if( bRet && ( eTransparent == TRANSPARENT_BITMAP ) && !!aMask )
     457         651 :             aMask.Crop( rRectPixel );
     458             : 
     459         651 :         aBitmapSize = aBitmap.GetSizePixel();
     460             : 
     461             :         DBG_ASSERT( !aMask || aBitmap.GetSizePixel() == aMask.GetSizePixel(),
     462             :                     "BitmapEx::Crop(): size mismatch for bitmap and alpha mask." );
     463             :     }
     464             : 
     465         651 :     return bRet;
     466             : }
     467             : 
     468         468 : bool BitmapEx::Convert( BmpConversion eConversion )
     469             : {
     470         468 :     return( !!aBitmap ? aBitmap.Convert( eConversion ) : false );
     471             : }
     472             : 
     473           0 : bool BitmapEx::ReduceColors( sal_uInt16 nNewColorCount, BmpReduce eReduce )
     474             : {
     475           0 :     return( !!aBitmap ? aBitmap.ReduceColors( nNewColorCount, eReduce ) : false );
     476             : }
     477             : 
     478           0 : bool BitmapEx::Expand( sal_uLong nDX, sal_uLong nDY, const Color* pInitColor, bool bExpandTransparent )
     479             : {
     480           0 :     bool bRet = false;
     481             : 
     482           0 :     if( !!aBitmap )
     483             :     {
     484           0 :         bRet = aBitmap.Expand( nDX, nDY, pInitColor );
     485             : 
     486           0 :         if( bRet && ( eTransparent == TRANSPARENT_BITMAP ) && !!aMask )
     487             :         {
     488           0 :             Color aColor( bExpandTransparent ? COL_WHITE : COL_BLACK );
     489           0 :             aMask.Expand( nDX, nDY, &aColor );
     490             :         }
     491             : 
     492           0 :         aBitmapSize = aBitmap.GetSizePixel();
     493             : 
     494             :         DBG_ASSERT( !aMask || aBitmap.GetSizePixel() == aMask.GetSizePixel(),
     495             :                     "BitmapEx::Expand(): size mismatch for bitmap and alpha mask." );
     496             :     }
     497             : 
     498           0 :     return bRet;
     499             : }
     500             : 
     501        5502 : bool BitmapEx::CopyPixel( const Rectangle& rRectDst, const Rectangle& rRectSrc,
     502             :                           const BitmapEx* pBmpExSrc )
     503             : {
     504        5502 :     bool bRet = false;
     505             : 
     506        5502 :     if( !pBmpExSrc || pBmpExSrc->IsEmpty() )
     507             :     {
     508           0 :         if( !aBitmap.IsEmpty() )
     509             :         {
     510           0 :             bRet = aBitmap.CopyPixel( rRectDst, rRectSrc );
     511             : 
     512           0 :             if( bRet && ( eTransparent == TRANSPARENT_BITMAP ) && !!aMask )
     513           0 :                 aMask.CopyPixel( rRectDst, rRectSrc );
     514             :         }
     515             :     }
     516             :     else
     517             :     {
     518        5502 :         if( !aBitmap.IsEmpty() )
     519             :         {
     520        5502 :             bRet = aBitmap.CopyPixel( rRectDst, rRectSrc, &pBmpExSrc->aBitmap );
     521             : 
     522        5502 :             if( bRet )
     523             :             {
     524        5502 :                 if( pBmpExSrc->IsAlpha() )
     525             :                 {
     526        5367 :                     if( IsAlpha() )
     527             :                         // cast to use the optimized AlphaMask::CopyPixel
     528        3666 :                         ((AlphaMask*) &aMask)->CopyPixel( rRectDst, rRectSrc, (AlphaMask*)&pBmpExSrc->aMask );
     529        1701 :                     else if( IsTransparent() )
     530             :                     {
     531           0 :                         AlphaMask* pAlpha = new AlphaMask( aMask );
     532             : 
     533           0 :                         aMask = pAlpha->ImplGetBitmap();
     534           0 :                         delete pAlpha;
     535           0 :                         bAlpha = true;
     536           0 :                         aMask.CopyPixel( rRectDst, rRectSrc, &pBmpExSrc->aMask );
     537             :                     }
     538             :                     else
     539             :                     {
     540        1701 :                         sal_uInt8   cBlack = 0;
     541        1701 :                         AlphaMask*  pAlpha = new AlphaMask( GetSizePixel(), &cBlack );
     542             : 
     543        1701 :                         aMask = pAlpha->ImplGetBitmap();
     544        1701 :                         delete pAlpha;
     545        1701 :                         eTransparent = TRANSPARENT_BITMAP;
     546        1701 :                         bAlpha = true;
     547        1701 :                         aMask.CopyPixel( rRectDst, rRectSrc, &pBmpExSrc->aMask );
     548             :                     }
     549             :                 }
     550         135 :                 else if( pBmpExSrc->IsTransparent() )
     551             :                 {
     552         135 :                     if( IsAlpha() )
     553             :                     {
     554           0 :                         AlphaMask aAlpha( pBmpExSrc->aMask );
     555           0 :                         aMask.CopyPixel( rRectDst, rRectSrc, &aAlpha.ImplGetBitmap() );
     556             :                     }
     557         135 :                     else if( IsTransparent() )
     558           0 :                         aMask.CopyPixel( rRectDst, rRectSrc, &pBmpExSrc->aMask );
     559             :                     else
     560             :                     {
     561         135 :                         aMask = Bitmap( GetSizePixel(), 1 );
     562         135 :                         aMask.Erase( Color( COL_BLACK ) );
     563         135 :                         eTransparent = TRANSPARENT_BITMAP;
     564         135 :                         aMask.CopyPixel( rRectDst, rRectSrc, &pBmpExSrc->aMask );
     565             :                     }
     566             :                 }
     567           0 :                 else if( IsAlpha() )
     568             :                 {
     569           0 :                     sal_uInt8         cBlack = 0;
     570           0 :                     const AlphaMask   aAlphaSrc( pBmpExSrc->GetSizePixel(), &cBlack );
     571             : 
     572           0 :                     aMask.CopyPixel( rRectDst, rRectSrc, &aAlphaSrc.ImplGetBitmap() );
     573             :                 }
     574           0 :                 else if( IsTransparent() )
     575             :                 {
     576           0 :                     Bitmap aMaskSrc( pBmpExSrc->GetSizePixel(), 1 );
     577             : 
     578           0 :                     aMaskSrc.Erase( Color( COL_BLACK ) );
     579           0 :                     aMask.CopyPixel( rRectDst, rRectSrc, &aMaskSrc );
     580             :                 }
     581             :             }
     582             :         }
     583             :     }
     584             : 
     585        5502 :     return bRet;
     586             : }
     587             : 
     588        1975 : bool BitmapEx::Erase( const Color& rFillColor )
     589             : {
     590        1975 :     bool bRet = false;
     591             : 
     592        1975 :     if( !!aBitmap )
     593             :     {
     594        1975 :         bRet = aBitmap.Erase( rFillColor );
     595             : 
     596        1975 :         if( bRet && ( eTransparent == TRANSPARENT_BITMAP ) && !!aMask )
     597             :         {
     598             :             // Respect transparency on fill color
     599        1975 :             if( rFillColor.GetTransparency() )
     600             :             {
     601        1975 :                 const Color aFill( rFillColor.GetTransparency(), rFillColor.GetTransparency(), rFillColor.GetTransparency() );
     602        1975 :                 aMask.Erase( aFill );
     603             :             }
     604             :             else
     605             :             {
     606           0 :                 const Color aBlack( COL_BLACK );
     607           0 :                 aMask.Erase( aBlack );
     608             :             }
     609             :         }
     610             :     }
     611             : 
     612        1975 :     return bRet;
     613             : }
     614             : 
     615           0 : bool BitmapEx::Dither( sal_uLong nDitherFlags )
     616             : {
     617           0 :     return( !!aBitmap ? aBitmap.Dither( nDitherFlags ) : false );
     618             : }
     619             : 
     620         567 : bool BitmapEx::Replace( const Color& rSearchColor, const Color& rReplaceColor, sal_uLong nTol )
     621             : {
     622         567 :     return( !!aBitmap ? aBitmap.Replace( rSearchColor, rReplaceColor, nTol ) : false );
     623             : }
     624             : 
     625          18 : bool BitmapEx::Replace( const Color* pSearchColors, const Color* pReplaceColors, sal_uLong nColorCount, const sal_uLong* pTols )
     626             : {
     627          18 :     return( !!aBitmap ? aBitmap.Replace( pSearchColors, pReplaceColors, nColorCount, (sal_uLong*) pTols ) : false );
     628             : }
     629             : 
     630           0 : bool BitmapEx::Adjust( short nLuminancePercent, short nContrastPercent,
     631             :                        short nChannelRPercent, short nChannelGPercent, short nChannelBPercent,
     632             :                        double fGamma, bool bInvert )
     633             : {
     634           0 :     return( !!aBitmap ? aBitmap.Adjust( nLuminancePercent, nContrastPercent,
     635             :                                         nChannelRPercent, nChannelGPercent, nChannelBPercent,
     636           0 :                                         fGamma, bInvert ) : false );
     637             : }
     638             : 
     639           0 : bool BitmapEx::Filter( BmpFilter eFilter, const BmpFilterParam* pFilterParam, const Link* pProgress )
     640             : {
     641           0 :     return( !!aBitmap ? aBitmap.Filter( eFilter, pFilterParam, pProgress ) : false );
     642             : }
     643             : 
     644           0 : void BitmapEx::Draw( OutputDevice* pOutDev, const Point& rDestPt ) const
     645             : {
     646           0 :     pOutDev->DrawBitmapEx( rDestPt, *this );
     647           0 : }
     648             : 
     649           0 : void BitmapEx::Draw( OutputDevice* pOutDev,
     650             :                      const Point& rDestPt, const Size& rDestSize ) const
     651             : {
     652           0 :     pOutDev->DrawBitmapEx( rDestPt, rDestSize, *this );
     653           0 : }
     654             : 
     655           0 : BitmapEx BitmapEx:: AutoScaleBitmap(BitmapEx & aBitmap, const long aStandardSize)
     656             : {
     657           0 :     Point aEmptyPoint(0,0);
     658           0 :     double imgposX = 0;
     659           0 :     double imgposY = 0;
     660           0 :     BitmapEx  aRet = aBitmap;
     661           0 :     double imgOldWidth = aRet.GetSizePixel().Width();
     662           0 :     double imgOldHeight =aRet.GetSizePixel().Height();
     663             : 
     664           0 :     Size aScaledSize;
     665           0 :     if (imgOldWidth >= aStandardSize || imgOldHeight >= aStandardSize)
     666             :     {
     667           0 :         sal_Int32 imgNewWidth = 0;
     668           0 :         sal_Int32 imgNewHeight = 0;
     669           0 :         if (imgOldWidth >= imgOldHeight)
     670             :         {
     671           0 :             imgNewWidth = aStandardSize;
     672           0 :             imgNewHeight = sal_Int32(imgOldHeight / (imgOldWidth / aStandardSize) + 0.5);
     673           0 :             imgposX = 0;
     674           0 :             imgposY = (aStandardSize - (imgOldHeight / (imgOldWidth / aStandardSize) + 0.5)) / 2 + 0.5;
     675             :         }
     676             :         else
     677             :         {
     678           0 :             imgNewHeight = aStandardSize;
     679           0 :             imgNewWidth = sal_Int32(imgOldWidth / (imgOldHeight / aStandardSize) + 0.5);
     680           0 :             imgposY = 0;
     681           0 :             imgposX = (aStandardSize - (imgOldWidth / (imgOldHeight / aStandardSize) + 0.5)) / 2 + 0.5;
     682             :         }
     683             : 
     684           0 :         aScaledSize = Size( imgNewWidth, imgNewHeight );
     685           0 :         aRet.Scale( aScaledSize, BMP_SCALE_BESTQUALITY );
     686             :     }
     687             :     else
     688             :     {
     689           0 :         imgposX = (aStandardSize - imgOldWidth) / 2 + 0.5;
     690           0 :         imgposY = (aStandardSize - imgOldHeight) / 2 + 0.5;
     691             :     }
     692             : 
     693           0 :     Size aStdSize( aStandardSize, aStandardSize );
     694           0 :     Rectangle aRect(aEmptyPoint, aStdSize );
     695             : 
     696           0 :     VirtualDevice aVirDevice( *Application::GetDefaultDevice(), 0, 1 );
     697           0 :     aVirDevice.SetOutputSizePixel( aStdSize );
     698           0 :     aVirDevice.SetFillColor( COL_TRANSPARENT );
     699           0 :     aVirDevice.SetLineColor( COL_TRANSPARENT );
     700             : 
     701             :     // Draw a rect into virDevice
     702           0 :     aVirDevice.DrawRect( aRect );
     703           0 :     Point aPointPixel( (long)imgposX, (long)imgposY );
     704           0 :     aVirDevice.DrawBitmapEx( aPointPixel, aRet );
     705           0 :     aRet = aVirDevice.GetBitmapEx( aEmptyPoint, aStdSize );
     706             : 
     707           0 :     return aRet;
     708             : }
     709             : 
     710           0 : sal_uInt8 BitmapEx::GetTransparency(sal_Int32 nX, sal_Int32 nY) const
     711             : {
     712           0 :     sal_uInt8 nTransparency(0xff);
     713             : 
     714           0 :     if(!aBitmap.IsEmpty())
     715             :     {
     716           0 :         if(nX >= 0 && nX < aBitmapSize.Width() && nY >= 0 && nY < aBitmapSize.Height())
     717             :         {
     718           0 :             switch(eTransparent)
     719             :             {
     720             :                 case TRANSPARENT_NONE:
     721             :                 {
     722             :                     // Not transparent, ergo all covered
     723           0 :                     nTransparency = 0x00;
     724           0 :                     break;
     725             :                 }
     726             :                 case TRANSPARENT_COLOR:
     727             :                 {
     728           0 :                     Bitmap aTestBitmap(aBitmap);
     729           0 :                     BitmapReadAccess* pRead = aTestBitmap.AcquireReadAccess();
     730             : 
     731           0 :                     if(pRead)
     732             :                     {
     733           0 :                         const Color aColor = pRead->GetColor(nY, nX);
     734             : 
     735             :                         // If color is not equal to TransparentColor, we are not transparent
     736           0 :                         if(aColor != aTransparentColor)
     737             :                         {
     738           0 :                             nTransparency = 0x00;
     739             :                         }
     740             : 
     741           0 :                         aTestBitmap.ReleaseAccess(pRead);
     742             :                     }
     743           0 :                     break;
     744             :                 }
     745             :                 case TRANSPARENT_BITMAP:
     746             :                 {
     747           0 :                     if(!aMask.IsEmpty())
     748             :                     {
     749           0 :                         Bitmap aTestBitmap(aMask);
     750           0 :                         BitmapReadAccess* pRead = aTestBitmap.AcquireReadAccess();
     751             : 
     752           0 :                         if(pRead)
     753             :                         {
     754           0 :                             const BitmapColor aBitmapColor(pRead->GetPixel(nY, nX));
     755             : 
     756           0 :                             if(bAlpha)
     757             :                             {
     758           0 :                                 nTransparency = aBitmapColor.GetIndex();
     759             :                             }
     760             :                             else
     761             :                             {
     762           0 :                                 if(0x00 == aBitmapColor.GetIndex())
     763             :                                 {
     764           0 :                                     nTransparency = 0x00;
     765             :                                 }
     766             :                             }
     767             : 
     768           0 :                             aTestBitmap.ReleaseAccess(pRead);
     769           0 :                         }
     770             :                     }
     771           0 :                     break;
     772             :                 }
     773             :             }
     774             :         }
     775             :     }
     776             : 
     777           0 :     return nTransparency;
     778             : }
     779             : 
     780             : // Shift alpha transparent pixels between cppcanvas/ implementations
     781             : // and vcl in a generally grotesque and under-performing fashion
     782           0 : bool BitmapEx::Create( const ::com::sun::star::uno::Reference<
     783             :                        ::com::sun::star::rendering::XBitmapCanvas > &xBitmapCanvas,
     784             :                        const Size &rSize )
     785             : {
     786           0 :     uno::Reference< beans::XFastPropertySet > xFastPropertySet( xBitmapCanvas, uno::UNO_QUERY );
     787           0 :     if( xFastPropertySet.get() )
     788             :     {
     789             :         // 0 means get BitmapEx
     790           0 :         uno::Any aAny = xFastPropertySet->getFastPropertyValue( 0 );
     791           0 :         boost::scoped_ptr<BitmapEx> pBitmapEx((BitmapEx*) *reinterpret_cast<const sal_Int64*>(aAny.getValue()));
     792           0 :         if( pBitmapEx )
     793             :         {
     794           0 :             *this = *pBitmapEx;
     795           0 :             return true;
     796           0 :         }
     797             :     }
     798             : 
     799             :     SalBitmap* pSalBmp, *pSalMask;
     800             : 
     801           0 :     pSalBmp = ImplGetSVData()->mpDefInst->CreateSalBitmap();
     802           0 :     pSalMask = ImplGetSVData()->mpDefInst->CreateSalBitmap();
     803             : 
     804           0 :     Size aLocalSize(rSize);
     805           0 :     if( pSalBmp->Create( xBitmapCanvas, aLocalSize ) )
     806             :     {
     807           0 :         if ( pSalMask->Create( xBitmapCanvas, aLocalSize, true ) )
     808             :         {
     809           0 :             *this = BitmapEx(Bitmap(pSalBmp), Bitmap(pSalMask) );
     810           0 :             return true;
     811             :         }
     812             :         else
     813             :         {
     814           0 :             *this = BitmapEx(Bitmap(pSalBmp));
     815           0 :             return true;
     816             :         }
     817             :     }
     818             : 
     819           0 :     delete pSalBmp;
     820           0 :     delete pSalMask;
     821             : 
     822           0 :     return false;
     823             : }
     824             : 
     825             : namespace
     826             : {
     827          68 :     Bitmap impTransformBitmap(
     828             :         const Bitmap& rSource,
     829             :         const Size aDestinationSize,
     830             :         const basegfx::B2DHomMatrix& rTransform,
     831             :         bool bSmooth)
     832             :     {
     833          68 :         Bitmap aDestination(aDestinationSize, 24);
     834         136 :         boost::scoped_ptr<BitmapWriteAccess> pWrite(aDestination.AcquireWriteAccess());
     835             : 
     836          68 :         if(pWrite)
     837             :         {
     838             :             //const Size aContentSizePixel(rSource.GetSizePixel());
     839          68 :             boost::scoped_ptr<BitmapReadAccess> pRead((const_cast< Bitmap& >(rSource)).AcquireReadAccess());
     840             : 
     841          68 :             if(pRead)
     842             :             {
     843          68 :                 const Size aDestinationSizePixel(aDestination.GetSizePixel());
     844          68 :                 const BitmapColor aOutside(BitmapColor(0xff, 0xff, 0xff));
     845             : 
     846        9940 :                 for(sal_Int32 y(0L); y < aDestinationSizePixel.getHeight(); y++)
     847             :                 {
     848     1533376 :                     for(sal_Int32 x(0L); x < aDestinationSizePixel.getWidth(); x++)
     849             :                     {
     850     1523504 :                         const basegfx::B2DPoint aSourceCoor(rTransform * basegfx::B2DPoint(x, y));
     851             : 
     852     1523504 :                         if(bSmooth)
     853             :                         {
     854             :                             pWrite->SetPixel(
     855             :                                 y,
     856             :                                 x,
     857             :                                 pRead->GetInterpolatedColorWithFallback(
     858             :                                     aSourceCoor.getY(),
     859             :                                     aSourceCoor.getX(),
     860     1523504 :                                     aOutside));
     861             :                         }
     862             :                         else
     863             :                         {
     864             :                             // this version does the correct <= 0.0 checks, so no need
     865             :                             // to do the static_cast< sal_Int32 > self and make an error
     866             :                             pWrite->SetPixel(
     867             :                                 y,
     868             :                                 x,
     869             :                                 pRead->GetColorWithFallback(
     870             :                                     aSourceCoor.getY(),
     871             :                                     aSourceCoor.getX(),
     872           0 :                                     aOutside));
     873             :                         }
     874     1523504 :                     }
     875          68 :                 }
     876          68 :             }
     877             :         }
     878             : 
     879          68 :         rSource.AdaptBitCount(aDestination);
     880             : 
     881         136 :         return aDestination;
     882             :     }
     883             : } // end of anonymous namespace
     884             : 
     885          34 : BitmapEx BitmapEx::TransformBitmapEx(
     886             :     double fWidth,
     887             :     double fHeight,
     888             :     const basegfx::B2DHomMatrix& rTransformation,
     889             :     bool bSmooth) const
     890             : {
     891          34 :     if(fWidth <= 1 || fHeight <= 1)
     892           0 :         return BitmapEx();
     893             : 
     894             :     // force destination to 24 bit, we want to smooth output
     895          34 :     const Size aDestinationSize(basegfx::fround(fWidth), basegfx::fround(fHeight));
     896          34 :     const Bitmap aDestination(impTransformBitmap(GetBitmap(), aDestinationSize, rTransformation, bSmooth));
     897             : 
     898             :     // create mask
     899          34 :     if(IsTransparent())
     900             :     {
     901          34 :         if(IsAlpha())
     902             :         {
     903          34 :             const Bitmap aAlpha(impTransformBitmap(GetAlpha().GetBitmap(), aDestinationSize, rTransformation, bSmooth));
     904          34 :             return BitmapEx(aDestination, AlphaMask(aAlpha));
     905             :         }
     906             :         else
     907             :         {
     908           0 :             const Bitmap aLclMask(impTransformBitmap(GetMask(), aDestinationSize, rTransformation, false));
     909           0 :             return BitmapEx(aDestination, aLclMask);
     910             :         }
     911             :     }
     912             : 
     913           0 :     return BitmapEx(aDestination);
     914             : }
     915             : 
     916          34 : BitmapEx BitmapEx::getTransformed(
     917             :     const basegfx::B2DHomMatrix& rTransformation,
     918             :     const basegfx::B2DRange& rVisibleRange,
     919             :     double fMaximumArea,
     920             :     bool bSmooth) const
     921             : {
     922          34 :     BitmapEx aRetval;
     923             : 
     924          34 :     if(IsEmpty())
     925           0 :         return aRetval;
     926             : 
     927          34 :     const sal_uInt32 nSourceWidth(GetSizePixel().Width());
     928          34 :     const sal_uInt32 nSourceHeight(GetSizePixel().Height());
     929             : 
     930          34 :     if(!nSourceWidth || !nSourceHeight)
     931           0 :         return aRetval;
     932             : 
     933             :     // Get aOutlineRange
     934          34 :     basegfx::B2DRange aOutlineRange(0.0, 0.0, 1.0, 1.0);
     935             : 
     936          34 :     aOutlineRange.transform(rTransformation);
     937             : 
     938             :     // create visible range from it by moving from relative to absolute
     939          34 :     basegfx::B2DRange aVisibleRange(rVisibleRange);
     940             : 
     941             :     aVisibleRange.transform(
     942             :         basegfx::tools::createScaleTranslateB2DHomMatrix(
     943             :             aOutlineRange.getRange(),
     944          34 :             aOutlineRange.getMinimum()));
     945             : 
     946             :     // get target size (which is visible range's size)
     947          34 :     double fWidth(aVisibleRange.getWidth());
     948          34 :     double fHeight(aVisibleRange.getHeight());
     949             : 
     950          34 :     if(fWidth < 1.0 || fHeight < 1.0)
     951             :     {
     952           0 :         return aRetval;
     953             :     }
     954             : 
     955             :     // test if discrete size (pixel) maybe too big and limit it
     956          34 :     const double fArea(fWidth * fHeight);
     957          34 :     const bool bNeedToReduce(basegfx::fTools::more(fArea, fMaximumArea));
     958          34 :     double fReduceFactor(1.0);
     959             : 
     960          34 :     if(bNeedToReduce)
     961             :     {
     962           0 :         fReduceFactor = sqrt(fMaximumArea / fArea);
     963           0 :         fWidth *= fReduceFactor;
     964           0 :         fHeight *= fReduceFactor;
     965             :     }
     966             : 
     967             :     // Build complete transform from source pixels to target pixels.
     968             :     // Start by scaling from source pixel size to unit coordinates
     969             :     basegfx::B2DHomMatrix aTransform(
     970             :         basegfx::tools::createScaleB2DHomMatrix(
     971             :             1.0 / nSourceWidth,
     972          68 :             1.0 / nSourceHeight));
     973             : 
     974             :     // multiply with given transform which leads from unit coordinates inside
     975             :     // aOutlineRange
     976          34 :     aTransform = rTransformation * aTransform;
     977             : 
     978             :     // substract top-left of absolute VisibleRange
     979             :     aTransform.translate(
     980          34 :         -aVisibleRange.getMinX(),
     981          68 :         -aVisibleRange.getMinY());
     982             : 
     983             :     // scale to target pixels (if needed)
     984          34 :     if(bNeedToReduce)
     985             :     {
     986           0 :         aTransform.scale(fReduceFactor, fReduceFactor);
     987             :     }
     988             : 
     989             :     // invert to get transformation from target pixel coordiates to source pixels
     990          34 :     aTransform.invert();
     991             : 
     992             :     // create bitmap using source, destination and linear back-transformation
     993          34 :     aRetval = TransformBitmapEx(fWidth, fHeight, aTransform, bSmooth);
     994             : 
     995          34 :     return aRetval;
     996             : }
     997             : 
     998         210 : BitmapEx BitmapEx::ModifyBitmapEx(const basegfx::BColorModifierStack& rBColorModifierStack) const
     999             : {
    1000         210 :     Bitmap aChangedBitmap(GetBitmap());
    1001         210 :     bool bDone(false);
    1002             : 
    1003         630 :     for(sal_uInt32 a(rBColorModifierStack.count()); a && !bDone; )
    1004             :     {
    1005         210 :         const basegfx::BColorModifierSharedPtr& rModifier = rBColorModifierStack.getBColorModifier(--a);
    1006         210 :         const basegfx::BColorModifier_replace* pReplace = dynamic_cast< const basegfx::BColorModifier_replace* >(rModifier.get());
    1007             : 
    1008         210 :         if(pReplace)
    1009             :         {
    1010             :             // complete replace
    1011         196 :             if(IsTransparent())
    1012             :             {
    1013             :                 // clear bitmap with dest color
    1014         190 :                 if(aChangedBitmap.GetBitCount() <= 8)
    1015             :                 {
    1016             :                     // do NOT use erase; for e.g. 8bit Bitmaps, the nearest color to the given
    1017             :                     // erase color is determined and used -> this may be different from what is
    1018             :                     // wanted here. Better create a new bitmap with the needed color explicitely
    1019           0 :                     boost::scoped_ptr<BitmapReadAccess> pReadAccess(aChangedBitmap.AcquireReadAccess());
    1020             :                     OSL_ENSURE(pReadAccess, "Got no Bitmap ReadAccess ?!?");
    1021             : 
    1022           0 :                     if(pReadAccess)
    1023             :                     {
    1024           0 :                         BitmapPalette aNewPalette(pReadAccess->GetPalette());
    1025           0 :                         aNewPalette[0] = BitmapColor(Color(pReplace->getBColor()));
    1026           0 :                         aChangedBitmap = Bitmap(
    1027             :                             aChangedBitmap.GetSizePixel(),
    1028           0 :                             aChangedBitmap.GetBitCount(),
    1029           0 :                             &aNewPalette);
    1030           0 :                     }
    1031             :                 }
    1032             :                 else
    1033             :                 {
    1034         190 :                     aChangedBitmap.Erase(Color(pReplace->getBColor()));
    1035             :                 }
    1036             :             }
    1037             :             else
    1038             :             {
    1039             :                 // erase bitmap, caller will know to paint direct
    1040           6 :                 aChangedBitmap.SetEmpty();
    1041             :             }
    1042             : 
    1043         196 :             bDone = true;
    1044             :         }
    1045             :         else
    1046             :         {
    1047          14 :             boost::scoped_ptr<BitmapWriteAccess> pContent(aChangedBitmap.AcquireWriteAccess());
    1048             : 
    1049          14 :             if(pContent)
    1050             :             {
    1051          14 :                 const double fConvertColor(1.0 / 255.0);
    1052             : 
    1053          14 :                 if(pContent->HasPalette())
    1054             :                 {
    1055           0 :                     const sal_uInt16 nCount(pContent->GetPaletteEntryCount());
    1056             : 
    1057           0 :                     for(sal_uInt16 b(0); b < nCount; b++)
    1058             :                     {
    1059           0 :                         const BitmapColor& rCol = pContent->GetPaletteColor(b);
    1060             :                         const basegfx::BColor aBSource(
    1061           0 :                             rCol.GetRed() * fConvertColor,
    1062           0 :                             rCol.GetGreen() * fConvertColor,
    1063           0 :                             rCol.GetBlue() * fConvertColor);
    1064           0 :                         const basegfx::BColor aBDest(rModifier->getModifiedColor(aBSource));
    1065           0 :                         pContent->SetPaletteColor(b, BitmapColor(Color(aBDest)));
    1066           0 :                     }
    1067             :                 }
    1068          14 :                 else if(BMP_FORMAT_24BIT_TC_BGR == pContent->GetScanlineFormat())
    1069             :                 {
    1070        1408 :                     for(sal_uInt32 y(0L); y < (sal_uInt32)pContent->Height(); y++)
    1071             :                     {
    1072        1394 :                         Scanline pScan = pContent->GetScanline(y);
    1073             : 
    1074      185690 :                         for(sal_uInt32 x(0L); x < (sal_uInt32)pContent->Width(); x++)
    1075             :                         {
    1076             :                             const basegfx::BColor aBSource(
    1077      184296 :                                 *(pScan + 2)* fConvertColor,
    1078      184296 :                                 *(pScan + 1) * fConvertColor,
    1079      552888 :                                 *pScan * fConvertColor);
    1080      368592 :                             const basegfx::BColor aBDest(rModifier->getModifiedColor(aBSource));
    1081      184296 :                             *pScan++ = static_cast< sal_uInt8 >(aBDest.getBlue() * 255.0);
    1082      184296 :                             *pScan++ = static_cast< sal_uInt8 >(aBDest.getGreen() * 255.0);
    1083      184296 :                             *pScan++ = static_cast< sal_uInt8 >(aBDest.getRed() * 255.0);
    1084      184296 :                         }
    1085             :                     }
    1086             :                 }
    1087           0 :                 else if(BMP_FORMAT_24BIT_TC_RGB == pContent->GetScanlineFormat())
    1088             :                 {
    1089           0 :                     for(sal_uInt32 y(0L); y < (sal_uInt32)pContent->Height(); y++)
    1090             :                     {
    1091           0 :                         Scanline pScan = pContent->GetScanline(y);
    1092             : 
    1093           0 :                         for(sal_uInt32 x(0L); x < (sal_uInt32)pContent->Width(); x++)
    1094             :                         {
    1095             :                             const basegfx::BColor aBSource(
    1096             :                                 *pScan * fConvertColor,
    1097           0 :                                 *(pScan + 1) * fConvertColor,
    1098           0 :                                 *(pScan + 2) * fConvertColor);
    1099           0 :                             const basegfx::BColor aBDest(rModifier->getModifiedColor(aBSource));
    1100           0 :                             *pScan++ = static_cast< sal_uInt8 >(aBDest.getRed() * 255.0);
    1101           0 :                             *pScan++ = static_cast< sal_uInt8 >(aBDest.getGreen() * 255.0);
    1102           0 :                             *pScan++ = static_cast< sal_uInt8 >(aBDest.getBlue() * 255.0);
    1103           0 :                         }
    1104             :                     }
    1105             :                 }
    1106             :                 else
    1107             :                 {
    1108           0 :                     for(sal_uInt32 y(0L); y < (sal_uInt32)pContent->Height(); y++)
    1109             :                     {
    1110           0 :                         for(sal_uInt32 x(0L); x < (sal_uInt32)pContent->Width(); x++)
    1111             :                         {
    1112           0 :                             const BitmapColor aBMCol(pContent->GetColor(y, x));
    1113             :                             const basegfx::BColor aBSource(
    1114           0 :                                 (double)aBMCol.GetRed() * fConvertColor,
    1115           0 :                                 (double)aBMCol.GetGreen() * fConvertColor,
    1116           0 :                                 (double)aBMCol.GetBlue() * fConvertColor);
    1117           0 :                             const basegfx::BColor aBDest(rModifier->getModifiedColor(aBSource));
    1118             : 
    1119           0 :                             pContent->SetPixel(y, x, BitmapColor(Color(aBDest)));
    1120           0 :                         }
    1121             :                     }
    1122             :                 }
    1123          14 :             }
    1124             :         }
    1125             :     }
    1126             : 
    1127         210 :     if(aChangedBitmap.IsEmpty())
    1128             :     {
    1129           6 :         return BitmapEx();
    1130             :     }
    1131             :     else
    1132             :     {
    1133         204 :         if(IsTransparent())
    1134             :         {
    1135         190 :             if(IsAlpha())
    1136             :             {
    1137         190 :                 return BitmapEx(aChangedBitmap, GetAlpha());
    1138             :             }
    1139             :             else
    1140             :             {
    1141           0 :                 return BitmapEx(aChangedBitmap, GetMask());
    1142             :             }
    1143             :         }
    1144             :         else
    1145             :         {
    1146          14 :             return BitmapEx(aChangedBitmap);
    1147             :         }
    1148         210 :     }
    1149             : }
    1150             : 
    1151         201 : BitmapEx VCL_DLLPUBLIC createBlendFrame(
    1152             :     const Size& rSize,
    1153             :     sal_uInt8 nAlpha,
    1154             :     Color aColorTopLeft,
    1155             :     Color aColorBottomRight)
    1156             : {
    1157         201 :     const sal_uInt32 nW(rSize.Width());
    1158         201 :     const sal_uInt32 nH(rSize.Height());
    1159             : 
    1160         201 :     if(nW || nH)
    1161             :     {
    1162         201 :         Color aColTopRight(aColorTopLeft);
    1163         201 :         Color aColBottomLeft(aColorTopLeft);
    1164         201 :         const sal_uInt32 nDE(nW + nH);
    1165             : 
    1166         201 :         aColTopRight.Merge(aColorBottomRight, 255 - sal_uInt8((nW * 255) / nDE));
    1167         201 :         aColBottomLeft.Merge(aColorBottomRight, 255 - sal_uInt8((nH * 255) / nDE));
    1168             : 
    1169         201 :         return createBlendFrame(rSize, nAlpha, aColorTopLeft, aColTopRight, aColorBottomRight, aColBottomLeft);
    1170             :     }
    1171             : 
    1172           0 :     return BitmapEx();
    1173             : }
    1174             : 
    1175         201 : BitmapEx VCL_DLLPUBLIC createBlendFrame(
    1176             :     const Size& rSize,
    1177             :     sal_uInt8 nAlpha,
    1178             :     Color aColorTopLeft,
    1179             :     Color aColorTopRight,
    1180             :     Color aColorBottomRight,
    1181             :     Color aColorBottomLeft)
    1182             : {
    1183         201 :     BlendFrameCache* pBlendFrameCache = ImplGetBlendFrameCache();
    1184             : 
    1185         402 :     if(pBlendFrameCache->m_aLastSize == rSize
    1186         193 :         && pBlendFrameCache->m_nLastAlpha == nAlpha
    1187         193 :         && pBlendFrameCache->m_aLastColorTopLeft == aColorTopLeft
    1188         193 :         && pBlendFrameCache->m_aLastColorTopRight == aColorTopRight
    1189         193 :         && pBlendFrameCache->m_aLastColorBottomRight == aColorBottomRight
    1190         394 :         && pBlendFrameCache->m_aLastColorBottomLeft == aColorBottomLeft)
    1191             :     {
    1192         193 :         return pBlendFrameCache->m_aLastResult;
    1193             :     }
    1194             : 
    1195           8 :     pBlendFrameCache->m_aLastSize = rSize;
    1196           8 :     pBlendFrameCache->m_nLastAlpha = nAlpha;
    1197           8 :     pBlendFrameCache->m_aLastColorTopLeft = aColorTopLeft;
    1198           8 :     pBlendFrameCache->m_aLastColorTopRight = aColorTopRight;
    1199           8 :     pBlendFrameCache->m_aLastColorBottomRight = aColorBottomRight;
    1200           8 :     pBlendFrameCache->m_aLastColorBottomLeft = aColorBottomLeft;
    1201           8 :     pBlendFrameCache->m_aLastResult.Clear();
    1202             : 
    1203           8 :     const long nW(rSize.Width());
    1204           8 :     const long nH(rSize.Height());
    1205             : 
    1206           8 :     if(nW > 1 && nH > 1)
    1207             :     {
    1208           8 :         sal_uInt8 aEraseTrans(0xff);
    1209           8 :         Bitmap aContent(rSize, 24);
    1210          16 :         AlphaMask aAlpha(rSize, &aEraseTrans);
    1211             : 
    1212           8 :         aContent.Erase(COL_BLACK);
    1213             : 
    1214           8 :         BitmapWriteAccess* pContent = aContent.AcquireWriteAccess();
    1215           8 :         BitmapWriteAccess* pAlpha = aAlpha.AcquireWriteAccess();
    1216             : 
    1217           8 :         if(pContent && pAlpha)
    1218             :         {
    1219           8 :             long x(0);
    1220           8 :             long y(0);
    1221             : 
    1222             :             // x == 0, y == 0, top-left corner
    1223           8 :             pContent->SetPixel(0, 0, aColorTopLeft);
    1224           8 :             pAlpha->SetPixelIndex(0, 0, nAlpha);
    1225             : 
    1226             :             // y == 0, top line left to right
    1227         240 :             for(x = 1; x < nW - 1; x++)
    1228             :             {
    1229         232 :                 Color aMix(aColorTopLeft);
    1230             : 
    1231         232 :                 aMix.Merge(aColorTopRight, 255 - sal_uInt8((x * 255) / nW));
    1232         232 :                 pContent->SetPixel(0, x, aMix);
    1233         232 :                 pAlpha->SetPixelIndex(0, x, nAlpha);
    1234             :             }
    1235             : 
    1236             :             // x == nW - 1, y == 0, top-right corner
    1237             :             // #i123690# Caution! When nW is 1, x == nW is possible (!)
    1238           8 :             if(x < nW)
    1239             :             {
    1240           8 :                 pContent->SetPixel(0, x, aColorTopRight);
    1241           8 :                 pAlpha->SetPixelIndex(0, x, nAlpha);
    1242             :             }
    1243             : 
    1244             :             // x == 0 and nW - 1, left and right line top-down
    1245          80 :             for(y = 1; y < nH - 1; y++)
    1246             :             {
    1247          72 :                 Color aMixA(aColorTopLeft);
    1248             : 
    1249          72 :                 aMixA.Merge(aColorBottomLeft, 255 - sal_uInt8((y * 255) / nH));
    1250          72 :                 pContent->SetPixel(y, 0, aMixA);
    1251          72 :                 pAlpha->SetPixelIndex(y, 0, nAlpha);
    1252             : 
    1253             :                 // #i123690# Caution! When nW is 1, x == nW is possible (!)
    1254          72 :                 if(x < nW)
    1255             :                 {
    1256          72 :                     Color aMixB(aColorTopRight);
    1257             : 
    1258          72 :                     aMixB.Merge(aColorBottomRight, 255 - sal_uInt8((y * 255) / nH));
    1259          72 :                     pContent->SetPixel(y, x, aMixB);
    1260          72 :                     pAlpha->SetPixelIndex(y, x, nAlpha);
    1261             :                 }
    1262             :             }
    1263             : 
    1264             :             // #i123690# Caution! When nH is 1, y == nH is possible (!)
    1265           8 :             if(y < nH)
    1266             :             {
    1267             :                 // x == 0, y == nH - 1, bottom-left corner
    1268           8 :                 pContent->SetPixel(y, 0, aColorBottomLeft);
    1269           8 :                 pAlpha->SetPixelIndex(y, 0, nAlpha);
    1270             : 
    1271             :                 // y == nH - 1, bottom line left to right
    1272         240 :                 for(x = 1; x < nW - 1; x++)
    1273             :                 {
    1274         232 :                     Color aMix(aColorBottomLeft);
    1275             : 
    1276         232 :                     aMix.Merge(aColorBottomRight, 255 - sal_uInt8(((x - 0)* 255) / nW));
    1277         232 :                     pContent->SetPixel(y, x, aMix);
    1278         232 :                     pAlpha->SetPixelIndex(y, x, nAlpha);
    1279             :                 }
    1280             : 
    1281             :                 // x == nW - 1, y == nH - 1, bottom-right corner
    1282             :                 // #i123690# Caution! When nW is 1, x == nW is possible (!)
    1283           8 :                 if(x < nW)
    1284             :                 {
    1285           8 :                     pContent->SetPixel(y, x, aColorBottomRight);
    1286           8 :                     pAlpha->SetPixelIndex(y, x, nAlpha);
    1287             :                 }
    1288             :             }
    1289             : 
    1290           8 :             aContent.ReleaseAccess(pContent);
    1291           8 :             aAlpha.ReleaseAccess(pAlpha);
    1292             : 
    1293           8 :             pBlendFrameCache->m_aLastResult = BitmapEx(aContent, aAlpha);
    1294             :         }
    1295             :         else
    1296             :         {
    1297           0 :             if(pContent)
    1298             :             {
    1299           0 :                 aContent.ReleaseAccess(pContent);
    1300             :             }
    1301             : 
    1302           0 :             if(pAlpha)
    1303             :             {
    1304           0 :                 aAlpha.ReleaseAccess(pAlpha);
    1305             :             }
    1306           8 :         }
    1307             :     }
    1308             : 
    1309           8 :     return pBlendFrameCache->m_aLastResult;
    1310             : }
    1311             : 
    1312             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10