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

Generated by: LCOV version 1.11