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

Generated by: LCOV version 1.10