19f62ea84SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 39f62ea84SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 49f62ea84SAndrew Rist * or more contributor license agreements. See the NOTICE file 59f62ea84SAndrew Rist * distributed with this work for additional information 69f62ea84SAndrew Rist * regarding copyright ownership. The ASF licenses this file 79f62ea84SAndrew Rist * to you under the Apache License, Version 2.0 (the 89f62ea84SAndrew Rist * "License"); you may not use this file except in compliance 99f62ea84SAndrew Rist * with the License. You may obtain a copy of the License at 109f62ea84SAndrew Rist * 119f62ea84SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 129f62ea84SAndrew Rist * 139f62ea84SAndrew Rist * Unless required by applicable law or agreed to in writing, 149f62ea84SAndrew Rist * software distributed under the License is distributed on an 159f62ea84SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 169f62ea84SAndrew Rist * KIND, either express or implied. See the License for the 179f62ea84SAndrew Rist * specific language governing permissions and limitations 189f62ea84SAndrew Rist * under the License. 199f62ea84SAndrew Rist * 209f62ea84SAndrew Rist *************************************************************/ 219f62ea84SAndrew Rist 22cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 23cdf0e10cSrcweir #include "precompiled_vcl.hxx" 24cdf0e10cSrcweir 25cdf0e10cSrcweir #include <ctype.h> 26cdf0e10cSrcweir #include <rtl/crc.h> 27cdf0e10cSrcweir #include <tools/stream.hxx> 28cdf0e10cSrcweir #include <tools/debug.hxx> 29cdf0e10cSrcweir #include <tools/rc.h> 30cdf0e10cSrcweir #include <vcl/salbtype.hxx> 31cdf0e10cSrcweir #include <vcl/outdev.hxx> 32cdf0e10cSrcweir #include <vcl/alpha.hxx> 33cdf0e10cSrcweir #include <vcl/bitmapex.hxx> 34cdf0e10cSrcweir #include <vcl/pngread.hxx> 35cdf0e10cSrcweir #include <vcl/svapp.hxx> 36cdf0e10cSrcweir #include <vcl/bmpacc.hxx> 3745fd3b9aSArmin Le Grand #include <vcl/dibtools.hxx> 38cdf0e10cSrcweir #include <image.h> 39cdf0e10cSrcweir #include <impimagetree.hxx> 405f27b83cSArmin Le Grand #include <basegfx/matrix/b2dhommatrixtools.hxx> 41cdf0e10cSrcweir 42cdf0e10cSrcweir // ------------ 43cdf0e10cSrcweir // - BitmapEx - 44cdf0e10cSrcweir // ------------ 45cdf0e10cSrcweir 46cdf0e10cSrcweir BitmapEx::BitmapEx() : 47cdf0e10cSrcweir eTransparent( TRANSPARENT_NONE ), 48cdf0e10cSrcweir bAlpha ( sal_False ) 49cdf0e10cSrcweir { 50cdf0e10cSrcweir } 51cdf0e10cSrcweir 52cdf0e10cSrcweir // ------------------------------------------------------------------ 53cdf0e10cSrcweir 54cdf0e10cSrcweir BitmapEx::BitmapEx( const BitmapEx& rBitmapEx ) : 55cdf0e10cSrcweir aBitmap ( rBitmapEx.aBitmap ), 56cdf0e10cSrcweir aMask ( rBitmapEx.aMask ), 57cdf0e10cSrcweir aBitmapSize ( rBitmapEx.aBitmapSize ), 58cdf0e10cSrcweir aTransparentColor ( rBitmapEx.aTransparentColor ), 59cdf0e10cSrcweir eTransparent ( rBitmapEx.eTransparent ), 60cdf0e10cSrcweir bAlpha ( rBitmapEx.bAlpha ) 61cdf0e10cSrcweir { 62cdf0e10cSrcweir } 63cdf0e10cSrcweir 64cdf0e10cSrcweir BitmapEx::BitmapEx( const BitmapEx& rBitmapEx, Point aSrc, Size aSize ) : 65cdf0e10cSrcweir eTransparent( TRANSPARENT_NONE ), 66cdf0e10cSrcweir bAlpha ( sal_False ) 67cdf0e10cSrcweir { 68cdf0e10cSrcweir if( rBitmapEx.IsEmpty() ) 69cdf0e10cSrcweir return; 70cdf0e10cSrcweir 71cdf0e10cSrcweir aBitmap = Bitmap( aSize, rBitmapEx.aBitmap.GetBitCount() ); 72cdf0e10cSrcweir aBitmapSize = aSize; 73cdf0e10cSrcweir if( rBitmapEx.IsAlpha() ) 74cdf0e10cSrcweir { 75cdf0e10cSrcweir bAlpha = sal_True; 76cdf0e10cSrcweir aMask = AlphaMask( aSize ).ImplGetBitmap(); 77cdf0e10cSrcweir } 78cdf0e10cSrcweir else if( rBitmapEx.IsTransparent() ) 79cdf0e10cSrcweir aMask = Bitmap( aSize, rBitmapEx.aMask.GetBitCount() ); 80cdf0e10cSrcweir 81cdf0e10cSrcweir Rectangle aDestRect( Point( 0, 0 ), aSize ); 82cdf0e10cSrcweir Rectangle aSrcRect( aSrc, aSize ); 83cdf0e10cSrcweir CopyPixel( aDestRect, aSrcRect, &rBitmapEx ); 84cdf0e10cSrcweir } 85cdf0e10cSrcweir 86cdf0e10cSrcweir // ------------------------------------------------------------------ 87cdf0e10cSrcweir 88cdf0e10cSrcweir BitmapEx::BitmapEx( const ResId& rResId ) : 89cdf0e10cSrcweir eTransparent( TRANSPARENT_NONE ), 90cdf0e10cSrcweir bAlpha ( sal_False ) 91cdf0e10cSrcweir { 92cdf0e10cSrcweir static ImplImageTreeSingletonRef aImageTree; 93cdf0e10cSrcweir ResMgr* pResMgr = NULL; 94cdf0e10cSrcweir 95cdf0e10cSrcweir ResMgr::GetResourceSkipHeader( rResId.SetRT( RSC_BITMAP ), &pResMgr ); 96cdf0e10cSrcweir pResMgr->ReadLong(); 97cdf0e10cSrcweir pResMgr->ReadLong(); 98cdf0e10cSrcweir 99cdf0e10cSrcweir const String aFileName( pResMgr->ReadString() ); 100cdf0e10cSrcweir ::rtl::OUString aCurrentSymbolsStyle = Application::GetSettings().GetStyleSettings().GetCurrentSymbolsStyleName(); 101cdf0e10cSrcweir 102cdf0e10cSrcweir if( !aImageTree->loadImage( aFileName, aCurrentSymbolsStyle, *this ) ) 103cdf0e10cSrcweir { 104cdf0e10cSrcweir #ifdef DBG_UTIL 105cdf0e10cSrcweir ByteString aErrorStr( "BitmapEx::BitmapEx( const ResId& rResId ): could not load image <" ); 106cdf0e10cSrcweir DBG_ERROR( ( ( aErrorStr += ByteString( aFileName, RTL_TEXTENCODING_ASCII_US ) ) += '>' ).GetBuffer() ); 107cdf0e10cSrcweir #endif 108cdf0e10cSrcweir } 109cdf0e10cSrcweir } 110cdf0e10cSrcweir 111cdf0e10cSrcweir // ------------------------------------------------------------------ 112cdf0e10cSrcweir 113cdf0e10cSrcweir BitmapEx::BitmapEx( const Bitmap& rBmp ) : 114cdf0e10cSrcweir aBitmap ( rBmp ), 115cdf0e10cSrcweir aBitmapSize ( aBitmap.GetSizePixel() ), 116cdf0e10cSrcweir eTransparent( TRANSPARENT_NONE ), 117cdf0e10cSrcweir bAlpha ( sal_False ) 118cdf0e10cSrcweir { 119cdf0e10cSrcweir } 120cdf0e10cSrcweir 121cdf0e10cSrcweir // ------------------------------------------------------------------ 122cdf0e10cSrcweir 123cdf0e10cSrcweir BitmapEx::BitmapEx( const Bitmap& rBmp, const Bitmap& rMask ) : 124cdf0e10cSrcweir aBitmap ( rBmp ), 125cdf0e10cSrcweir aMask ( rMask ), 126cdf0e10cSrcweir aBitmapSize ( aBitmap.GetSizePixel() ), 127cdf0e10cSrcweir eTransparent ( !rMask ? TRANSPARENT_NONE : TRANSPARENT_BITMAP ), 128cdf0e10cSrcweir bAlpha ( sal_False ) 129cdf0e10cSrcweir { 130ba5b0517SArmin Le Grand if(!!aBitmap && !!aMask && aBitmap.GetSizePixel() != aMask.GetSizePixel()) 131479f2b27SArmin Le Grand { 132479f2b27SArmin Le Grand OSL_ENSURE(false, "Mask size differs from Bitmap size, corrected Mask (!)"); 133ba5b0517SArmin Le Grand aMask.Scale(aBitmap.GetSizePixel()); 134479f2b27SArmin Le Grand } 135cdf0e10cSrcweir 136cdf0e10cSrcweir // #105489# Ensure a mask is exactly one bit deep 137cdf0e10cSrcweir if( !!aMask && aMask.GetBitCount() != 1 ) 138cdf0e10cSrcweir { 139cdf0e10cSrcweir OSL_TRACE("BitmapEx: forced mask to monochrome"); 140cdf0e10cSrcweir aMask.ImplMakeMono( 255 ); 141cdf0e10cSrcweir } 142cdf0e10cSrcweir } 143cdf0e10cSrcweir 144cdf0e10cSrcweir // ------------------------------------------------------------------ 145cdf0e10cSrcweir 146cdf0e10cSrcweir BitmapEx::BitmapEx( const Bitmap& rBmp, const AlphaMask& rAlphaMask ) : 147cdf0e10cSrcweir aBitmap ( rBmp ), 148cdf0e10cSrcweir aMask ( rAlphaMask.ImplGetBitmap() ), 149cdf0e10cSrcweir aBitmapSize ( aBitmap.GetSizePixel() ), 150cdf0e10cSrcweir eTransparent ( !rAlphaMask ? TRANSPARENT_NONE : TRANSPARENT_BITMAP ), 151cdf0e10cSrcweir bAlpha ( !rAlphaMask ? sal_False : sal_True ) 152cdf0e10cSrcweir { 153ba5b0517SArmin Le Grand if(!!aBitmap && !!aMask && aBitmap.GetSizePixel() != aMask.GetSizePixel()) 154479f2b27SArmin Le Grand { 155479f2b27SArmin Le Grand OSL_ENSURE(false, "Alpha size differs from Bitmap size, corrected Mask (!)"); 156479f2b27SArmin Le Grand aMask.Scale(rBmp.GetSizePixel()); 157479f2b27SArmin Le Grand } 158cdf0e10cSrcweir 159cdf0e10cSrcweir // #i75531# the workaround below can go when 160cdf0e10cSrcweir // X11SalGraphics::drawAlphaBitmap()'s render acceleration 161cdf0e10cSrcweir // can handle the bitmap depth mismatch directly 162cdf0e10cSrcweir if( aBitmap.GetBitCount() < aMask.GetBitCount() ) 163cdf0e10cSrcweir aBitmap.Convert( BMP_CONVERSION_24BIT ); 164cdf0e10cSrcweir } 165cdf0e10cSrcweir 166cdf0e10cSrcweir // ------------------------------------------------------------------ 167cdf0e10cSrcweir 168cdf0e10cSrcweir BitmapEx::BitmapEx( const Bitmap& rBmp, const Color& rTransparentColor ) : 169cdf0e10cSrcweir aBitmap ( rBmp ), 170cdf0e10cSrcweir aBitmapSize ( aBitmap.GetSizePixel() ), 171cdf0e10cSrcweir aTransparentColor ( rTransparentColor ), 172cdf0e10cSrcweir eTransparent ( TRANSPARENT_BITMAP ), 173cdf0e10cSrcweir bAlpha ( sal_False ) 174cdf0e10cSrcweir { 175cdf0e10cSrcweir aMask = aBitmap.CreateMask( aTransparentColor ); 176cdf0e10cSrcweir 177cdf0e10cSrcweir DBG_ASSERT( rBmp.GetSizePixel() == aMask.GetSizePixel(), 178cdf0e10cSrcweir "BitmapEx::BitmapEx(): size mismatch for bitmap and alpha mask." ); 179cdf0e10cSrcweir } 180cdf0e10cSrcweir 181cdf0e10cSrcweir // ------------------------------------------------------------------ 182cdf0e10cSrcweir 183cdf0e10cSrcweir BitmapEx::~BitmapEx() 184cdf0e10cSrcweir { 185cdf0e10cSrcweir } 186cdf0e10cSrcweir 187cdf0e10cSrcweir // ------------------------------------------------------------------ 188cdf0e10cSrcweir 189cdf0e10cSrcweir // ------------------------------------------------------------------ 190cdf0e10cSrcweir 191cdf0e10cSrcweir BitmapEx& BitmapEx::operator=( const BitmapEx& rBitmapEx ) 192cdf0e10cSrcweir { 193cdf0e10cSrcweir if( &rBitmapEx != this ) 194cdf0e10cSrcweir { 195cdf0e10cSrcweir aBitmap = rBitmapEx.aBitmap; 196cdf0e10cSrcweir aMask = rBitmapEx.aMask; 197cdf0e10cSrcweir aBitmapSize = rBitmapEx.aBitmapSize; 198cdf0e10cSrcweir aTransparentColor = rBitmapEx.aTransparentColor; 199cdf0e10cSrcweir eTransparent = rBitmapEx.eTransparent; 200cdf0e10cSrcweir bAlpha = rBitmapEx.bAlpha; 201cdf0e10cSrcweir } 202cdf0e10cSrcweir 203cdf0e10cSrcweir return *this; 204cdf0e10cSrcweir } 205cdf0e10cSrcweir 206cdf0e10cSrcweir // ------------------------------------------------------------------ 207cdf0e10cSrcweir 208cdf0e10cSrcweir sal_Bool BitmapEx::operator==( const BitmapEx& rBitmapEx ) const 209cdf0e10cSrcweir { 210cdf0e10cSrcweir if( eTransparent != rBitmapEx.eTransparent ) 211cdf0e10cSrcweir return sal_False; 212cdf0e10cSrcweir 213cdf0e10cSrcweir if( aBitmap != rBitmapEx.aBitmap ) 214cdf0e10cSrcweir return sal_False; 215cdf0e10cSrcweir 216cdf0e10cSrcweir if( aBitmapSize != rBitmapEx.aBitmapSize ) 217cdf0e10cSrcweir return sal_False; 218cdf0e10cSrcweir 219cdf0e10cSrcweir if( eTransparent == TRANSPARENT_NONE ) 220cdf0e10cSrcweir return sal_True; 221cdf0e10cSrcweir 222cdf0e10cSrcweir if( eTransparent == TRANSPARENT_COLOR ) 223cdf0e10cSrcweir return aTransparentColor == rBitmapEx.aTransparentColor; 224cdf0e10cSrcweir 225cdf0e10cSrcweir return( ( aMask == rBitmapEx.aMask ) && ( bAlpha == rBitmapEx.bAlpha ) ); 226cdf0e10cSrcweir } 227cdf0e10cSrcweir 228cdf0e10cSrcweir // ------------------------------------------------------------------ 229cdf0e10cSrcweir 230cdf0e10cSrcweir sal_Bool BitmapEx::IsEqual( const BitmapEx& rBmpEx ) const 231cdf0e10cSrcweir { 232cdf0e10cSrcweir return( rBmpEx.eTransparent == eTransparent && 233cdf0e10cSrcweir rBmpEx.bAlpha == bAlpha && 234cdf0e10cSrcweir rBmpEx.aBitmap.IsEqual( aBitmap ) && 235cdf0e10cSrcweir rBmpEx.aMask.IsEqual( aMask ) ); 236cdf0e10cSrcweir } 237cdf0e10cSrcweir 238cdf0e10cSrcweir // ------------------------------------------------------------------ 239cdf0e10cSrcweir 240cdf0e10cSrcweir sal_Bool BitmapEx::IsEmpty() const 241cdf0e10cSrcweir { 242cdf0e10cSrcweir return( aBitmap.IsEmpty() && aMask.IsEmpty() ); 243cdf0e10cSrcweir } 244cdf0e10cSrcweir 245cdf0e10cSrcweir // ------------------------------------------------------------------ 246cdf0e10cSrcweir 247cdf0e10cSrcweir void BitmapEx::SetEmpty() 248cdf0e10cSrcweir { 249cdf0e10cSrcweir aBitmap.SetEmpty(); 250cdf0e10cSrcweir aMask.SetEmpty(); 251cdf0e10cSrcweir eTransparent = TRANSPARENT_NONE; 252cdf0e10cSrcweir bAlpha = sal_False; 253cdf0e10cSrcweir } 254cdf0e10cSrcweir 255cdf0e10cSrcweir // ------------------------------------------------------------------ 256cdf0e10cSrcweir 257cdf0e10cSrcweir void BitmapEx::Clear() 258cdf0e10cSrcweir { 259cdf0e10cSrcweir SetEmpty(); 260cdf0e10cSrcweir } 261cdf0e10cSrcweir 262cdf0e10cSrcweir // ------------------------------------------------------------------ 263cdf0e10cSrcweir 264cdf0e10cSrcweir sal_Bool BitmapEx::IsTransparent() const 265cdf0e10cSrcweir { 266cdf0e10cSrcweir return( eTransparent != TRANSPARENT_NONE ); 267cdf0e10cSrcweir } 268cdf0e10cSrcweir 269cdf0e10cSrcweir // ------------------------------------------------------------------ 270cdf0e10cSrcweir 271cdf0e10cSrcweir sal_Bool BitmapEx::IsAlpha() const 272cdf0e10cSrcweir { 273cdf0e10cSrcweir return( IsTransparent() && bAlpha ); 274cdf0e10cSrcweir } 275cdf0e10cSrcweir 276cdf0e10cSrcweir // ------------------------------------------------------------------ 277cdf0e10cSrcweir 278cdf0e10cSrcweir Bitmap BitmapEx::GetBitmap( const Color* pTransReplaceColor ) const 279cdf0e10cSrcweir { 280cdf0e10cSrcweir Bitmap aRetBmp( aBitmap ); 281cdf0e10cSrcweir 282cdf0e10cSrcweir if( pTransReplaceColor && ( eTransparent != TRANSPARENT_NONE ) ) 283cdf0e10cSrcweir { 284cdf0e10cSrcweir Bitmap aTempMask; 285cdf0e10cSrcweir 286cdf0e10cSrcweir if( eTransparent == TRANSPARENT_COLOR ) 287cdf0e10cSrcweir aTempMask = aBitmap.CreateMask( aTransparentColor ); 288cdf0e10cSrcweir else 289cdf0e10cSrcweir aTempMask = aMask; 290cdf0e10cSrcweir 291cdf0e10cSrcweir if( !IsAlpha() ) 292cdf0e10cSrcweir aRetBmp.Replace( aTempMask, *pTransReplaceColor ); 293cdf0e10cSrcweir else 294cdf0e10cSrcweir aRetBmp.Replace( GetAlpha(), *pTransReplaceColor ); 295cdf0e10cSrcweir } 296cdf0e10cSrcweir 297cdf0e10cSrcweir return aRetBmp; 298cdf0e10cSrcweir } 299cdf0e10cSrcweir 300cdf0e10cSrcweir // ------------------------------------------------------------------ 301cdf0e10cSrcweir 302cdf0e10cSrcweir BitmapEx BitmapEx::GetColorTransformedBitmapEx( BmpColorMode eColorMode ) const 303cdf0e10cSrcweir { 304cdf0e10cSrcweir BitmapEx aRet; 305cdf0e10cSrcweir 306cdf0e10cSrcweir if( BMP_COLOR_HIGHCONTRAST == eColorMode ) 307cdf0e10cSrcweir { 308cdf0e10cSrcweir aRet = *this; 309cdf0e10cSrcweir aRet.aBitmap = aBitmap.GetColorTransformedBitmap( eColorMode ); 310cdf0e10cSrcweir } 311cdf0e10cSrcweir else if( BMP_COLOR_MONOCHROME_BLACK == eColorMode || 312cdf0e10cSrcweir BMP_COLOR_MONOCHROME_WHITE == eColorMode ) 313cdf0e10cSrcweir { 314cdf0e10cSrcweir aRet = *this; 315cdf0e10cSrcweir aRet.aBitmap = aRet.aBitmap.GetColorTransformedBitmap( eColorMode ); 316cdf0e10cSrcweir 317cdf0e10cSrcweir if( !aRet.aMask.IsEmpty() ) 318cdf0e10cSrcweir { 319cdf0e10cSrcweir aRet.aMask.CombineSimple( aRet.aBitmap, BMP_COMBINE_OR ); 320cdf0e10cSrcweir aRet.aBitmap.Erase( ( BMP_COLOR_MONOCHROME_BLACK == eColorMode ) ? COL_BLACK : COL_WHITE ); 321cdf0e10cSrcweir 322cdf0e10cSrcweir DBG_ASSERT( aRet.aBitmap.GetSizePixel() == aRet.aMask.GetSizePixel(), 323cdf0e10cSrcweir "BitmapEx::GetColorTransformedBitmapEx(): size mismatch for bitmap and alpha mask." ); 324cdf0e10cSrcweir } 325cdf0e10cSrcweir } 326cdf0e10cSrcweir 327cdf0e10cSrcweir return aRet; 328cdf0e10cSrcweir } 329cdf0e10cSrcweir 330cdf0e10cSrcweir // ------------------------------------------------------------------ 331cdf0e10cSrcweir 332cdf0e10cSrcweir Bitmap BitmapEx::GetMask() const 333cdf0e10cSrcweir { 334cdf0e10cSrcweir Bitmap aRet( aMask ); 335cdf0e10cSrcweir 336cdf0e10cSrcweir if( IsAlpha() ) 337cdf0e10cSrcweir aRet.ImplMakeMono( 255 ); 338cdf0e10cSrcweir 339cdf0e10cSrcweir return aRet; 340cdf0e10cSrcweir } 341cdf0e10cSrcweir 342cdf0e10cSrcweir // ------------------------------------------------------------------ 343cdf0e10cSrcweir 344cdf0e10cSrcweir AlphaMask BitmapEx::GetAlpha() const 345cdf0e10cSrcweir { 346cdf0e10cSrcweir AlphaMask aAlpha; 347cdf0e10cSrcweir 348cdf0e10cSrcweir if( IsAlpha() ) 349cdf0e10cSrcweir aAlpha.ImplSetBitmap( aMask ); 350cdf0e10cSrcweir else 351cdf0e10cSrcweir aAlpha = aMask; 352cdf0e10cSrcweir 353cdf0e10cSrcweir return aAlpha; 354cdf0e10cSrcweir } 355cdf0e10cSrcweir 356cdf0e10cSrcweir // ------------------------------------------------------------------ 357cdf0e10cSrcweir 358cdf0e10cSrcweir sal_uLong BitmapEx::GetSizeBytes() const 359cdf0e10cSrcweir { 360cdf0e10cSrcweir sal_uLong nSizeBytes = aBitmap.GetSizeBytes(); 361cdf0e10cSrcweir 362cdf0e10cSrcweir if( eTransparent == TRANSPARENT_BITMAP ) 363cdf0e10cSrcweir nSizeBytes += aMask.GetSizeBytes(); 364cdf0e10cSrcweir 365cdf0e10cSrcweir return nSizeBytes; 366cdf0e10cSrcweir } 367cdf0e10cSrcweir 368cdf0e10cSrcweir // ------------------------------------------------------------------ 369cdf0e10cSrcweir 370cdf0e10cSrcweir sal_uLong BitmapEx::GetChecksum() const 371cdf0e10cSrcweir { 372cdf0e10cSrcweir sal_uInt32 nCrc = aBitmap.GetChecksum(); 373cdf0e10cSrcweir SVBT32 aBT32; 374cdf0e10cSrcweir 375cdf0e10cSrcweir UInt32ToSVBT32( (long) eTransparent, aBT32 ); 376cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 377cdf0e10cSrcweir 378cdf0e10cSrcweir UInt32ToSVBT32( (long) bAlpha, aBT32 ); 379cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 380cdf0e10cSrcweir 381cdf0e10cSrcweir if( ( TRANSPARENT_BITMAP == eTransparent ) && !aMask.IsEmpty() ) 382cdf0e10cSrcweir { 383cdf0e10cSrcweir UInt32ToSVBT32( aMask.GetChecksum(), aBT32 ); 384cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 385cdf0e10cSrcweir } 386cdf0e10cSrcweir 387cdf0e10cSrcweir return nCrc; 388cdf0e10cSrcweir } 389cdf0e10cSrcweir 390cdf0e10cSrcweir // ------------------------------------------------------------------ 391cdf0e10cSrcweir 39254628ca4SArmin Le Grand void BitmapEx::SetSizePixel( const Size& rNewSize, sal_uInt32 nScaleFlag ) 393cdf0e10cSrcweir { 39454628ca4SArmin Le Grand if(GetSizePixel() != rNewSize) 39554628ca4SArmin Le Grand { 39654628ca4SArmin Le Grand Scale( rNewSize, nScaleFlag ); 39754628ca4SArmin Le Grand } 398cdf0e10cSrcweir } 399cdf0e10cSrcweir 400cdf0e10cSrcweir // ------------------------------------------------------------------ 401cdf0e10cSrcweir 402cdf0e10cSrcweir sal_Bool BitmapEx::Invert() 403cdf0e10cSrcweir { 404cdf0e10cSrcweir sal_Bool bRet = sal_False; 405cdf0e10cSrcweir 406cdf0e10cSrcweir if( !!aBitmap ) 407cdf0e10cSrcweir { 408cdf0e10cSrcweir bRet = aBitmap.Invert(); 409cdf0e10cSrcweir 410cdf0e10cSrcweir if( bRet && ( eTransparent == TRANSPARENT_COLOR ) ) 411cdf0e10cSrcweir aTransparentColor = BitmapColor( aTransparentColor ).Invert(); 412cdf0e10cSrcweir } 413cdf0e10cSrcweir 414cdf0e10cSrcweir return bRet; 415cdf0e10cSrcweir } 416cdf0e10cSrcweir 417cdf0e10cSrcweir // ------------------------------------------------------------------ 418cdf0e10cSrcweir 419cdf0e10cSrcweir sal_Bool BitmapEx::Mirror( sal_uLong nMirrorFlags ) 420cdf0e10cSrcweir { 421cdf0e10cSrcweir sal_Bool bRet = sal_False; 422cdf0e10cSrcweir 423cdf0e10cSrcweir if( !!aBitmap ) 424cdf0e10cSrcweir { 425cdf0e10cSrcweir bRet = aBitmap.Mirror( nMirrorFlags ); 426cdf0e10cSrcweir 427cdf0e10cSrcweir if( bRet && ( eTransparent == TRANSPARENT_BITMAP ) && !!aMask ) 428cdf0e10cSrcweir aMask.Mirror( nMirrorFlags ); 429cdf0e10cSrcweir } 430cdf0e10cSrcweir 431cdf0e10cSrcweir return bRet; 432cdf0e10cSrcweir } 433cdf0e10cSrcweir 434cdf0e10cSrcweir // ------------------------------------------------------------------ 435cdf0e10cSrcweir 43654628ca4SArmin Le Grand sal_Bool BitmapEx::Scale( const double& rScaleX, const double& rScaleY, sal_uInt32 nScaleFlag ) 437cdf0e10cSrcweir { 438cdf0e10cSrcweir sal_Bool bRet = sal_False; 439cdf0e10cSrcweir 440cdf0e10cSrcweir if( !!aBitmap ) 441cdf0e10cSrcweir { 442cdf0e10cSrcweir bRet = aBitmap.Scale( rScaleX, rScaleY, nScaleFlag ); 443cdf0e10cSrcweir 444cdf0e10cSrcweir if( bRet && ( eTransparent == TRANSPARENT_BITMAP ) && !!aMask ) 44537ab0f2dSArmin Le Grand { 44637ab0f2dSArmin Le Grand aMask.Scale( rScaleX, rScaleY, nScaleFlag ); 44737ab0f2dSArmin Le Grand } 448cdf0e10cSrcweir 449cdf0e10cSrcweir aBitmapSize = aBitmap.GetSizePixel(); 450cdf0e10cSrcweir 451cdf0e10cSrcweir DBG_ASSERT( !aMask || aBitmap.GetSizePixel() == aMask.GetSizePixel(), 452cdf0e10cSrcweir "BitmapEx::Scale(): size mismatch for bitmap and alpha mask." ); 453cdf0e10cSrcweir } 454cdf0e10cSrcweir 455cdf0e10cSrcweir return bRet; 456cdf0e10cSrcweir } 457cdf0e10cSrcweir 458cdf0e10cSrcweir // ------------------------------------------------------------------------ 459cdf0e10cSrcweir 46054628ca4SArmin Le Grand sal_Bool BitmapEx::Scale( const Size& rNewSize, sal_uInt32 nScaleFlag ) 461cdf0e10cSrcweir { 462cdf0e10cSrcweir sal_Bool bRet; 463cdf0e10cSrcweir 464cdf0e10cSrcweir if( aBitmapSize.Width() && aBitmapSize.Height() ) 465cdf0e10cSrcweir { 466cdf0e10cSrcweir bRet = Scale( (double) rNewSize.Width() / aBitmapSize.Width(), 467cdf0e10cSrcweir (double) rNewSize.Height() / aBitmapSize.Height(), 468cdf0e10cSrcweir nScaleFlag ); 469cdf0e10cSrcweir } 470cdf0e10cSrcweir else 471cdf0e10cSrcweir bRet = sal_True; 472cdf0e10cSrcweir 473cdf0e10cSrcweir return bRet; 474cdf0e10cSrcweir } 475cdf0e10cSrcweir 476cdf0e10cSrcweir // ------------------------------------------------------------------ 477cdf0e10cSrcweir 478cdf0e10cSrcweir sal_Bool BitmapEx::Rotate( long nAngle10, const Color& rFillColor ) 479cdf0e10cSrcweir { 480cdf0e10cSrcweir sal_Bool bRet = sal_False; 481cdf0e10cSrcweir 482cdf0e10cSrcweir if( !!aBitmap ) 483cdf0e10cSrcweir { 484cdf0e10cSrcweir const sal_Bool bTransRotate = ( Color( COL_TRANSPARENT ) == rFillColor ); 485cdf0e10cSrcweir 486cdf0e10cSrcweir if( bTransRotate ) 487cdf0e10cSrcweir { 488cdf0e10cSrcweir if( eTransparent == TRANSPARENT_COLOR ) 489cdf0e10cSrcweir bRet = aBitmap.Rotate( nAngle10, aTransparentColor ); 490cdf0e10cSrcweir else 491cdf0e10cSrcweir { 492cdf0e10cSrcweir bRet = aBitmap.Rotate( nAngle10, COL_BLACK ); 493cdf0e10cSrcweir 494cdf0e10cSrcweir if( eTransparent == TRANSPARENT_NONE ) 495cdf0e10cSrcweir { 496cdf0e10cSrcweir aMask = Bitmap( aBitmapSize, 1 ); 497cdf0e10cSrcweir aMask.Erase( COL_BLACK ); 498cdf0e10cSrcweir eTransparent = TRANSPARENT_BITMAP; 499cdf0e10cSrcweir } 500cdf0e10cSrcweir 501cdf0e10cSrcweir if( bRet && !!aMask ) 502cdf0e10cSrcweir aMask.Rotate( nAngle10, COL_WHITE ); 503cdf0e10cSrcweir } 504cdf0e10cSrcweir } 505cdf0e10cSrcweir else 506cdf0e10cSrcweir { 507cdf0e10cSrcweir bRet = aBitmap.Rotate( nAngle10, rFillColor ); 508cdf0e10cSrcweir 509cdf0e10cSrcweir if( bRet && ( eTransparent == TRANSPARENT_BITMAP ) && !!aMask ) 510cdf0e10cSrcweir aMask.Rotate( nAngle10, COL_WHITE ); 511cdf0e10cSrcweir } 512cdf0e10cSrcweir 513cdf0e10cSrcweir aBitmapSize = aBitmap.GetSizePixel(); 514cdf0e10cSrcweir 515cdf0e10cSrcweir DBG_ASSERT( !aMask || aBitmap.GetSizePixel() == aMask.GetSizePixel(), 516cdf0e10cSrcweir "BitmapEx::Rotate(): size mismatch for bitmap and alpha mask." ); 517cdf0e10cSrcweir } 518cdf0e10cSrcweir 519cdf0e10cSrcweir return bRet; 520cdf0e10cSrcweir } 521cdf0e10cSrcweir 522cdf0e10cSrcweir // ------------------------------------------------------------------ 523cdf0e10cSrcweir 524cdf0e10cSrcweir sal_Bool BitmapEx::Crop( const Rectangle& rRectPixel ) 525cdf0e10cSrcweir { 526cdf0e10cSrcweir sal_Bool bRet = sal_False; 527cdf0e10cSrcweir 528cdf0e10cSrcweir if( !!aBitmap ) 529cdf0e10cSrcweir { 530cdf0e10cSrcweir bRet = aBitmap.Crop( rRectPixel ); 531cdf0e10cSrcweir 532cdf0e10cSrcweir if( bRet && ( eTransparent == TRANSPARENT_BITMAP ) && !!aMask ) 533cdf0e10cSrcweir aMask.Crop( rRectPixel ); 534cdf0e10cSrcweir 535cdf0e10cSrcweir aBitmapSize = aBitmap.GetSizePixel(); 536cdf0e10cSrcweir 537cdf0e10cSrcweir DBG_ASSERT( !aMask || aBitmap.GetSizePixel() == aMask.GetSizePixel(), 538cdf0e10cSrcweir "BitmapEx::Crop(): size mismatch for bitmap and alpha mask." ); 539cdf0e10cSrcweir } 540cdf0e10cSrcweir 541cdf0e10cSrcweir return bRet; 542cdf0e10cSrcweir } 543cdf0e10cSrcweir 544cdf0e10cSrcweir // ------------------------------------------------------------------ 545cdf0e10cSrcweir 546cdf0e10cSrcweir sal_Bool BitmapEx::Convert( BmpConversion eConversion ) 547cdf0e10cSrcweir { 548cdf0e10cSrcweir return( !!aBitmap ? aBitmap.Convert( eConversion ) : sal_False ); 549cdf0e10cSrcweir } 550cdf0e10cSrcweir 551cdf0e10cSrcweir // ------------------------------------------------------------------ 552cdf0e10cSrcweir 553cdf0e10cSrcweir sal_Bool BitmapEx::ReduceColors( sal_uInt16 nNewColorCount, BmpReduce eReduce ) 554cdf0e10cSrcweir { 555cdf0e10cSrcweir return( !!aBitmap ? aBitmap.ReduceColors( nNewColorCount, eReduce ) : sal_False ); 556cdf0e10cSrcweir } 557cdf0e10cSrcweir 558cdf0e10cSrcweir // ------------------------------------------------------------------ 559cdf0e10cSrcweir 560cdf0e10cSrcweir sal_Bool BitmapEx::Expand( sal_uLong nDX, sal_uLong nDY, const Color* pInitColor, sal_Bool bExpandTransparent ) 561cdf0e10cSrcweir { 562cdf0e10cSrcweir sal_Bool bRet = sal_False; 563cdf0e10cSrcweir 564cdf0e10cSrcweir if( !!aBitmap ) 565cdf0e10cSrcweir { 566cdf0e10cSrcweir bRet = aBitmap.Expand( nDX, nDY, pInitColor ); 567cdf0e10cSrcweir 568cdf0e10cSrcweir if( bRet && ( eTransparent == TRANSPARENT_BITMAP ) && !!aMask ) 569cdf0e10cSrcweir { 570cdf0e10cSrcweir Color aColor( bExpandTransparent ? COL_WHITE : COL_BLACK ); 571cdf0e10cSrcweir aMask.Expand( nDX, nDY, &aColor ); 572cdf0e10cSrcweir } 573cdf0e10cSrcweir 574cdf0e10cSrcweir aBitmapSize = aBitmap.GetSizePixel(); 575cdf0e10cSrcweir 576cdf0e10cSrcweir DBG_ASSERT( !aMask || aBitmap.GetSizePixel() == aMask.GetSizePixel(), 577cdf0e10cSrcweir "BitmapEx::Expand(): size mismatch for bitmap and alpha mask." ); 578cdf0e10cSrcweir } 579cdf0e10cSrcweir 580cdf0e10cSrcweir return bRet; 581cdf0e10cSrcweir } 582cdf0e10cSrcweir 583cdf0e10cSrcweir // ------------------------------------------------------------------ 584cdf0e10cSrcweir 585cdf0e10cSrcweir sal_Bool BitmapEx::CopyPixel( const Rectangle& rRectDst, const Rectangle& rRectSrc, 586cdf0e10cSrcweir const BitmapEx* pBmpExSrc ) 587cdf0e10cSrcweir { 588cdf0e10cSrcweir sal_Bool bRet = sal_False; 589cdf0e10cSrcweir 590cdf0e10cSrcweir if( !pBmpExSrc || pBmpExSrc->IsEmpty() ) 591cdf0e10cSrcweir { 592cdf0e10cSrcweir if( !aBitmap.IsEmpty() ) 593cdf0e10cSrcweir { 594cdf0e10cSrcweir bRet = aBitmap.CopyPixel( rRectDst, rRectSrc ); 595cdf0e10cSrcweir 596cdf0e10cSrcweir if( bRet && ( eTransparent == TRANSPARENT_BITMAP ) && !!aMask ) 597cdf0e10cSrcweir aMask.CopyPixel( rRectDst, rRectSrc ); 598cdf0e10cSrcweir } 599cdf0e10cSrcweir } 600cdf0e10cSrcweir else 601cdf0e10cSrcweir { 602cdf0e10cSrcweir if( !aBitmap.IsEmpty() ) 603cdf0e10cSrcweir { 604cdf0e10cSrcweir bRet = aBitmap.CopyPixel( rRectDst, rRectSrc, &pBmpExSrc->aBitmap ); 605cdf0e10cSrcweir 606cdf0e10cSrcweir if( bRet ) 607cdf0e10cSrcweir { 608cdf0e10cSrcweir if( pBmpExSrc->IsAlpha() ) 609cdf0e10cSrcweir { 610cdf0e10cSrcweir if( IsAlpha() ) 611cdf0e10cSrcweir // cast to use the optimized AlphaMask::CopyPixel 612cdf0e10cSrcweir ((AlphaMask*) &aMask)->CopyPixel( rRectDst, rRectSrc, (AlphaMask*)&pBmpExSrc->aMask ); 613cdf0e10cSrcweir else if( IsTransparent() ) 614cdf0e10cSrcweir { 615cdf0e10cSrcweir AlphaMask* pAlpha = new AlphaMask( aMask ); 616cdf0e10cSrcweir 617cdf0e10cSrcweir aMask = pAlpha->ImplGetBitmap(); 618cdf0e10cSrcweir delete pAlpha; 619cdf0e10cSrcweir bAlpha = sal_True; 620cdf0e10cSrcweir aMask.CopyPixel( rRectDst, rRectSrc, &pBmpExSrc->aMask ); 621cdf0e10cSrcweir } 622cdf0e10cSrcweir else 623cdf0e10cSrcweir { 624cdf0e10cSrcweir sal_uInt8 cBlack = 0; 625cdf0e10cSrcweir AlphaMask* pAlpha = new AlphaMask( GetSizePixel(), &cBlack ); 626cdf0e10cSrcweir 627cdf0e10cSrcweir aMask = pAlpha->ImplGetBitmap(); 628cdf0e10cSrcweir delete pAlpha; 629cdf0e10cSrcweir eTransparent = TRANSPARENT_BITMAP; 630cdf0e10cSrcweir bAlpha = sal_True; 631cdf0e10cSrcweir aMask.CopyPixel( rRectDst, rRectSrc, &pBmpExSrc->aMask ); 632cdf0e10cSrcweir } 633cdf0e10cSrcweir } 634cdf0e10cSrcweir else if( pBmpExSrc->IsTransparent() ) 635cdf0e10cSrcweir { 636cdf0e10cSrcweir if( IsAlpha() ) 637cdf0e10cSrcweir { 638cdf0e10cSrcweir AlphaMask aAlpha( pBmpExSrc->aMask ); 639cdf0e10cSrcweir aMask.CopyPixel( rRectDst, rRectSrc, &aAlpha.ImplGetBitmap() ); 640cdf0e10cSrcweir } 641cdf0e10cSrcweir else if( IsTransparent() ) 642cdf0e10cSrcweir aMask.CopyPixel( rRectDst, rRectSrc, &pBmpExSrc->aMask ); 643cdf0e10cSrcweir else 644cdf0e10cSrcweir { 645cdf0e10cSrcweir aMask = Bitmap( GetSizePixel(), 1 ); 646cdf0e10cSrcweir aMask.Erase( Color( COL_BLACK ) ); 647cdf0e10cSrcweir eTransparent = TRANSPARENT_BITMAP; 648cdf0e10cSrcweir aMask.CopyPixel( rRectDst, rRectSrc, &pBmpExSrc->aMask ); 649cdf0e10cSrcweir } 650cdf0e10cSrcweir } 651cdf0e10cSrcweir else if( IsAlpha() ) 652cdf0e10cSrcweir { 653cdf0e10cSrcweir sal_uInt8 cBlack = 0; 654cdf0e10cSrcweir const AlphaMask aAlphaSrc( pBmpExSrc->GetSizePixel(), &cBlack ); 655cdf0e10cSrcweir 656cdf0e10cSrcweir aMask.CopyPixel( rRectDst, rRectSrc, &aAlphaSrc.ImplGetBitmap() ); 657cdf0e10cSrcweir } 658cdf0e10cSrcweir else if( IsTransparent() ) 659cdf0e10cSrcweir { 660cdf0e10cSrcweir Bitmap aMaskSrc( pBmpExSrc->GetSizePixel(), 1 ); 661cdf0e10cSrcweir 662cdf0e10cSrcweir aMaskSrc.Erase( Color( COL_BLACK ) ); 663cdf0e10cSrcweir aMask.CopyPixel( rRectDst, rRectSrc, &aMaskSrc ); 664cdf0e10cSrcweir } 665cdf0e10cSrcweir } 666cdf0e10cSrcweir } 667cdf0e10cSrcweir } 668cdf0e10cSrcweir 669cdf0e10cSrcweir return bRet; 670cdf0e10cSrcweir } 671cdf0e10cSrcweir 672cdf0e10cSrcweir // ------------------------------------------------------------------ 673cdf0e10cSrcweir 674cdf0e10cSrcweir sal_Bool BitmapEx::Erase( const Color& rFillColor ) 675cdf0e10cSrcweir { 676cdf0e10cSrcweir sal_Bool bRet = sal_False; 677cdf0e10cSrcweir 678cdf0e10cSrcweir if( !!aBitmap ) 679cdf0e10cSrcweir { 680cdf0e10cSrcweir bRet = aBitmap.Erase( rFillColor ); 681cdf0e10cSrcweir 682cdf0e10cSrcweir if( bRet && ( eTransparent == TRANSPARENT_BITMAP ) && !!aMask ) 683cdf0e10cSrcweir { 684cdf0e10cSrcweir // #104416# Respect transparency on fill color 685cdf0e10cSrcweir if( rFillColor.GetTransparency() ) 686cdf0e10cSrcweir { 687cdf0e10cSrcweir const Color aFill( rFillColor.GetTransparency(), rFillColor.GetTransparency(), rFillColor.GetTransparency() ); 688cdf0e10cSrcweir aMask.Erase( aFill ); 689cdf0e10cSrcweir } 690cdf0e10cSrcweir else 691cdf0e10cSrcweir { 692cdf0e10cSrcweir const Color aBlack( COL_BLACK ); 693cdf0e10cSrcweir aMask.Erase( aBlack ); 694cdf0e10cSrcweir } 695cdf0e10cSrcweir } 696cdf0e10cSrcweir } 697cdf0e10cSrcweir 698cdf0e10cSrcweir return bRet; 699cdf0e10cSrcweir } 700cdf0e10cSrcweir 701cdf0e10cSrcweir // ------------------------------------------------------------------ 702cdf0e10cSrcweir 703cdf0e10cSrcweir sal_Bool BitmapEx::Dither( sal_uLong nDitherFlags ) 704cdf0e10cSrcweir { 705cdf0e10cSrcweir return( !!aBitmap ? aBitmap.Dither( nDitherFlags ) : sal_False ); 706cdf0e10cSrcweir } 707cdf0e10cSrcweir 708cdf0e10cSrcweir // ------------------------------------------------------------------ 709cdf0e10cSrcweir 710cdf0e10cSrcweir sal_Bool BitmapEx::Replace( const Color& rSearchColor, const Color& rReplaceColor, sal_uLong nTol ) 711cdf0e10cSrcweir { 712cdf0e10cSrcweir return( !!aBitmap ? aBitmap.Replace( rSearchColor, rReplaceColor, nTol ) : sal_False ); 713cdf0e10cSrcweir } 714cdf0e10cSrcweir 715cdf0e10cSrcweir // ------------------------------------------------------------------ 716cdf0e10cSrcweir 717cdf0e10cSrcweir sal_Bool BitmapEx::Replace( const Color* pSearchColors, const Color* pReplaceColors, sal_uLong nColorCount, const sal_uLong* pTols ) 718cdf0e10cSrcweir { 719cdf0e10cSrcweir return( !!aBitmap ? aBitmap.Replace( pSearchColors, pReplaceColors, nColorCount, (sal_uLong*) pTols ) : sal_False ); 720cdf0e10cSrcweir } 721cdf0e10cSrcweir 722cdf0e10cSrcweir // ------------------------------------------------------------------ 723cdf0e10cSrcweir 724cdf0e10cSrcweir sal_Bool BitmapEx::Adjust( short nLuminancePercent, short nContrastPercent, 725cdf0e10cSrcweir short nChannelRPercent, short nChannelGPercent, short nChannelBPercent, 726cdf0e10cSrcweir double fGamma, sal_Bool bInvert ) 727cdf0e10cSrcweir { 728cdf0e10cSrcweir return( !!aBitmap ? aBitmap.Adjust( nLuminancePercent, nContrastPercent, 729cdf0e10cSrcweir nChannelRPercent, nChannelGPercent, nChannelBPercent, 730cdf0e10cSrcweir fGamma, bInvert ) : sal_False ); 731cdf0e10cSrcweir } 732cdf0e10cSrcweir 733cdf0e10cSrcweir // ------------------------------------------------------------------ 734cdf0e10cSrcweir 735cdf0e10cSrcweir sal_Bool BitmapEx::Filter( BmpFilter eFilter, const BmpFilterParam* pFilterParam, const Link* pProgress ) 736cdf0e10cSrcweir { 737cdf0e10cSrcweir return( !!aBitmap ? aBitmap.Filter( eFilter, pFilterParam, pProgress ) : sal_False ); 738cdf0e10cSrcweir } 739cdf0e10cSrcweir 740cdf0e10cSrcweir // ------------------------------------------------------------------ 741cdf0e10cSrcweir 742cdf0e10cSrcweir void BitmapEx::Draw( OutputDevice* pOutDev, const Point& rDestPt ) const 743cdf0e10cSrcweir { 744cdf0e10cSrcweir pOutDev->DrawBitmapEx( rDestPt, *this ); 745cdf0e10cSrcweir } 746cdf0e10cSrcweir 747cdf0e10cSrcweir // ------------------------------------------------------------------ 748cdf0e10cSrcweir 749cdf0e10cSrcweir void BitmapEx::Draw( OutputDevice* pOutDev, 750cdf0e10cSrcweir const Point& rDestPt, const Size& rDestSize ) const 751cdf0e10cSrcweir { 752cdf0e10cSrcweir pOutDev->DrawBitmapEx( rDestPt, rDestSize, *this ); 753cdf0e10cSrcweir } 754cdf0e10cSrcweir 755cdf0e10cSrcweir // ------------------------------------------------------------------ 756cdf0e10cSrcweir 757cdf0e10cSrcweir void BitmapEx::Draw( OutputDevice* pOutDev, 758cdf0e10cSrcweir const Point& rDestPt, const Size& rDestSize, 759cdf0e10cSrcweir const Point& rSrcPtPixel, const Size& rSrcSizePixel ) const 760cdf0e10cSrcweir { 761cdf0e10cSrcweir pOutDev->DrawBitmapEx( rDestPt, rDestSize, rSrcPtPixel, rSrcSizePixel, *this ); 762cdf0e10cSrcweir } 763cdf0e10cSrcweir 764cdf0e10cSrcweir // ------------------------------------------------------------------ 765cdf0e10cSrcweir 766cdf0e10cSrcweir sal_uInt8 BitmapEx::GetTransparency(sal_Int32 nX, sal_Int32 nY) const 767cdf0e10cSrcweir { 768cdf0e10cSrcweir sal_uInt8 nTransparency(0xff); 769cdf0e10cSrcweir 770cdf0e10cSrcweir if(!aBitmap.IsEmpty()) 771cdf0e10cSrcweir { 772cdf0e10cSrcweir if(nX >= 0 && nX < aBitmapSize.Width() && nY >= 0 && nY < aBitmapSize.Height()) 773cdf0e10cSrcweir { 774cdf0e10cSrcweir switch(eTransparent) 775cdf0e10cSrcweir { 776cdf0e10cSrcweir case TRANSPARENT_NONE: 777cdf0e10cSrcweir { 778cdf0e10cSrcweir // not transparent, ergo all covered 779cdf0e10cSrcweir nTransparency = 0x00; 780cdf0e10cSrcweir break; 781cdf0e10cSrcweir } 782cdf0e10cSrcweir case TRANSPARENT_COLOR: 783cdf0e10cSrcweir { 784cdf0e10cSrcweir Bitmap aTestBitmap(aBitmap); 785cdf0e10cSrcweir BitmapReadAccess* pRead = aTestBitmap.AcquireReadAccess(); 786cdf0e10cSrcweir 787cdf0e10cSrcweir if(pRead) 788cdf0e10cSrcweir { 789cdf0e10cSrcweir const Color aColor = pRead->GetColor(nY, nX); 790cdf0e10cSrcweir 791cdf0e10cSrcweir // if color is not equal to TransparentColor, we are not transparent 792cdf0e10cSrcweir if(aColor != aTransparentColor) 793cdf0e10cSrcweir { 794cdf0e10cSrcweir nTransparency = 0x00; 795cdf0e10cSrcweir } 796cdf0e10cSrcweir 797cdf0e10cSrcweir aTestBitmap.ReleaseAccess(pRead); 798cdf0e10cSrcweir } 799cdf0e10cSrcweir break; 800cdf0e10cSrcweir } 801cdf0e10cSrcweir case TRANSPARENT_BITMAP: 802cdf0e10cSrcweir { 803cdf0e10cSrcweir if(!aMask.IsEmpty()) 804cdf0e10cSrcweir { 805cdf0e10cSrcweir Bitmap aTestBitmap(aMask); 806cdf0e10cSrcweir BitmapReadAccess* pRead = aTestBitmap.AcquireReadAccess(); 807cdf0e10cSrcweir 808cdf0e10cSrcweir if(pRead) 809cdf0e10cSrcweir { 810cdf0e10cSrcweir const BitmapColor aBitmapColor(pRead->GetPixel(nY, nX)); 811cdf0e10cSrcweir 812cdf0e10cSrcweir if(bAlpha) 813cdf0e10cSrcweir { 814cdf0e10cSrcweir nTransparency = aBitmapColor.GetIndex(); 815cdf0e10cSrcweir } 816cdf0e10cSrcweir else 817cdf0e10cSrcweir { 818cdf0e10cSrcweir if(0x00 == aBitmapColor.GetIndex()) 819cdf0e10cSrcweir { 820cdf0e10cSrcweir nTransparency = 0x00; 821cdf0e10cSrcweir } 822cdf0e10cSrcweir } 823cdf0e10cSrcweir 824cdf0e10cSrcweir aTestBitmap.ReleaseAccess(pRead); 825cdf0e10cSrcweir } 826cdf0e10cSrcweir } 827cdf0e10cSrcweir break; 828cdf0e10cSrcweir } 829cdf0e10cSrcweir } 830cdf0e10cSrcweir } 831cdf0e10cSrcweir } 832cdf0e10cSrcweir 833cdf0e10cSrcweir return nTransparency; 834cdf0e10cSrcweir } 835cdf0e10cSrcweir 8365f27b83cSArmin Le Grand // ------------------------------------------------------------------ 8375f27b83cSArmin Le Grand 8385f27b83cSArmin Le Grand namespace 8395f27b83cSArmin Le Grand { 840*f8c0d554SArmin Le Grand Bitmap impTransformBitmap( 8415f27b83cSArmin Le Grand const Bitmap& rSource, 8425f27b83cSArmin Le Grand const Size aDestinationSize, 8435f27b83cSArmin Le Grand const basegfx::B2DHomMatrix& rTransform, 8445f27b83cSArmin Le Grand bool bSmooth) 845*f8c0d554SArmin Le Grand { 8465f27b83cSArmin Le Grand Bitmap aDestination(aDestinationSize, 24); 8475f27b83cSArmin Le Grand BitmapWriteAccess* pWrite = aDestination.AcquireWriteAccess(); 8485f27b83cSArmin Le Grand 849*f8c0d554SArmin Le Grand if(pWrite) 850*f8c0d554SArmin Le Grand { 851*f8c0d554SArmin Le Grand //const Size aContentSizePixel(rSource.GetSizePixel()); 852*f8c0d554SArmin Le Grand BitmapReadAccess* pRead = (const_cast< Bitmap& >(rSource)).AcquireReadAccess(); 8535f27b83cSArmin Le Grand 854*f8c0d554SArmin Le Grand if(pRead) 855*f8c0d554SArmin Le Grand { 856*f8c0d554SArmin Le Grand const Size aDestinationSizePixel(aDestination.GetSizePixel()); 857*f8c0d554SArmin Le Grand const BitmapColor aOutside(BitmapColor(0xff, 0xff, 0xff)); 8585f27b83cSArmin Le Grand 859*f8c0d554SArmin Le Grand for(sal_Int32 y(0L); y < aDestinationSizePixel.getHeight(); y++) 860*f8c0d554SArmin Le Grand { 861*f8c0d554SArmin Le Grand for(sal_Int32 x(0L); x < aDestinationSizePixel.getWidth(); x++) 862*f8c0d554SArmin Le Grand { 863*f8c0d554SArmin Le Grand const basegfx::B2DPoint aSourceCoor(rTransform * basegfx::B2DPoint(x, y)); 8645f27b83cSArmin Le Grand 865*f8c0d554SArmin Le Grand if(bSmooth) 866*f8c0d554SArmin Le Grand { 867*f8c0d554SArmin Le Grand pWrite->SetPixel( 868*f8c0d554SArmin Le Grand y, 869*f8c0d554SArmin Le Grand x, 870*f8c0d554SArmin Le Grand pRead->GetInterpolatedColorWithFallback( 871*f8c0d554SArmin Le Grand aSourceCoor.getY(), 872*f8c0d554SArmin Le Grand aSourceCoor.getX(), 873*f8c0d554SArmin Le Grand aOutside)); 874*f8c0d554SArmin Le Grand } 875*f8c0d554SArmin Le Grand else 876*f8c0d554SArmin Le Grand { 877*f8c0d554SArmin Le Grand // this version does the correct <= 0.0 checks, so no need 878*f8c0d554SArmin Le Grand // to do the static_cast< sal_Int32 > self and make an error 879*f8c0d554SArmin Le Grand pWrite->SetPixel( 880*f8c0d554SArmin Le Grand y, 881*f8c0d554SArmin Le Grand x, 882*f8c0d554SArmin Le Grand pRead->GetColorWithFallback( 883*f8c0d554SArmin Le Grand aSourceCoor.getY(), 884*f8c0d554SArmin Le Grand aSourceCoor.getX(), 885*f8c0d554SArmin Le Grand aOutside)); 886*f8c0d554SArmin Le Grand } 887*f8c0d554SArmin Le Grand } 888*f8c0d554SArmin Le Grand } 8895f27b83cSArmin Le Grand 890*f8c0d554SArmin Le Grand delete pRead; 891*f8c0d554SArmin Le Grand } 8925f27b83cSArmin Le Grand 893*f8c0d554SArmin Le Grand delete pWrite; 894*f8c0d554SArmin Le Grand } 8955f27b83cSArmin Le Grand 8965f27b83cSArmin Le Grand rSource.AdaptBitCount(aDestination); 8975f27b83cSArmin Le Grand 8985f27b83cSArmin Le Grand return aDestination; 899*f8c0d554SArmin Le Grand } 9005f27b83cSArmin Le Grand } // end of anonymous namespace 901*f8c0d554SArmin Le Grand 9025f27b83cSArmin Le Grand BitmapEx BitmapEx::TransformBitmapEx( 9035f27b83cSArmin Le Grand double fWidth, 9045f27b83cSArmin Le Grand double fHeight, 905*f8c0d554SArmin Le Grand const basegfx::B2DHomMatrix& rTransformation, 906*f8c0d554SArmin Le Grand bool bSmooth) const 9075f27b83cSArmin Le Grand { 9085f27b83cSArmin Le Grand if(fWidth <= 1 || fHeight <= 1) 9095f27b83cSArmin Le Grand return BitmapEx(); 9105f27b83cSArmin Le Grand 9115f27b83cSArmin Le Grand // force destination to 24 bit, we want to smooth output 9125f27b83cSArmin Le Grand const Size aDestinationSize(basegfx::fround(fWidth), basegfx::fround(fHeight)); 913*f8c0d554SArmin Le Grand const Bitmap aDestination(impTransformBitmap(GetBitmap(), aDestinationSize, rTransformation, bSmooth)); 9145f27b83cSArmin Le Grand 9155f27b83cSArmin Le Grand // create mask 9165f27b83cSArmin Le Grand if(IsTransparent()) 9175f27b83cSArmin Le Grand { 9185f27b83cSArmin Le Grand if(IsAlpha()) 9195f27b83cSArmin Le Grand { 920*f8c0d554SArmin Le Grand const Bitmap aAlpha(impTransformBitmap(GetAlpha().GetBitmap(), aDestinationSize, rTransformation, bSmooth)); 9215f27b83cSArmin Le Grand return BitmapEx(aDestination, AlphaMask(aAlpha)); 9225f27b83cSArmin Le Grand } 9235f27b83cSArmin Le Grand else 9245f27b83cSArmin Le Grand { 9255f27b83cSArmin Le Grand const Bitmap aMask(impTransformBitmap(GetMask(), aDestinationSize, rTransformation, false)); 9265f27b83cSArmin Le Grand return BitmapEx(aDestination, aMask); 9275f27b83cSArmin Le Grand } 9285f27b83cSArmin Le Grand } 9295f27b83cSArmin Le Grand 9305f27b83cSArmin Le Grand return BitmapEx(aDestination); 9315f27b83cSArmin Le Grand } 9325f27b83cSArmin Le Grand 9335f27b83cSArmin Le Grand // ------------------------------------------------------------------ 9345f27b83cSArmin Le Grand 9355f27b83cSArmin Le Grand BitmapEx BitmapEx::getTransformed( 9365f27b83cSArmin Le Grand const basegfx::B2DHomMatrix& rTransformation, 937*f8c0d554SArmin Le Grand const basegfx::B2DRange& rVisibleRange, 938*f8c0d554SArmin Le Grand double fMaximumArea, 939*f8c0d554SArmin Le Grand bool bSmooth) const 9405f27b83cSArmin Le Grand { 9415f27b83cSArmin Le Grand BitmapEx aRetval; 9425f27b83cSArmin Le Grand 9435f27b83cSArmin Le Grand if(IsEmpty()) 9445f27b83cSArmin Le Grand return aRetval; 9455f27b83cSArmin Le Grand 9465f27b83cSArmin Le Grand const sal_uInt32 nSourceWidth(GetSizePixel().Width()); 9475f27b83cSArmin Le Grand const sal_uInt32 nSourceHeight(GetSizePixel().Height()); 9485f27b83cSArmin Le Grand 9495f27b83cSArmin Le Grand if(!nSourceWidth || !nSourceHeight) 9505f27b83cSArmin Le Grand return aRetval; 9515f27b83cSArmin Le Grand 952*f8c0d554SArmin Le Grand // Get aOutlineRange 9535f27b83cSArmin Le Grand basegfx::B2DRange aOutlineRange(0.0, 0.0, 1.0, 1.0); 954*f8c0d554SArmin Le Grand 9555f27b83cSArmin Le Grand aOutlineRange.transform(rTransformation); 9565f27b83cSArmin Le Grand 957*f8c0d554SArmin Le Grand // create visible range from it by moving from relative to absolute 958*f8c0d554SArmin Le Grand basegfx::B2DRange aVisibleRange(rVisibleRange); 959*f8c0d554SArmin Le Grand 960*f8c0d554SArmin Le Grand aVisibleRange.transform( 961*f8c0d554SArmin Le Grand basegfx::tools::createScaleTranslateB2DHomMatrix( 962*f8c0d554SArmin Le Grand aOutlineRange.getRange(), 963*f8c0d554SArmin Le Grand aOutlineRange.getMinimum())); 964*f8c0d554SArmin Le Grand 965*f8c0d554SArmin Le Grand // get target size (which is visible range's size) 966*f8c0d554SArmin Le Grand double fWidth(aVisibleRange.getWidth()); 967*f8c0d554SArmin Le Grand double fHeight(aVisibleRange.getHeight()); 9685f27b83cSArmin Le Grand 9695f27b83cSArmin Le Grand if(fWidth < 1.0 || fHeight < 1.0) 970*f8c0d554SArmin Le Grand { 9715f27b83cSArmin Le Grand return aRetval; 972*f8c0d554SArmin Le Grand } 9735f27b83cSArmin Le Grand 9745f27b83cSArmin Le Grand // test if discrete size (pixel) maybe too big and limit it 9755f27b83cSArmin Le Grand const double fArea(fWidth * fHeight); 976*f8c0d554SArmin Le Grand const bool bNeedToReduce(basegfx::fTools::more(fArea, fMaximumArea)); 9775f27b83cSArmin Le Grand double fReduceFactor(1.0); 9785f27b83cSArmin Le Grand 9795f27b83cSArmin Le Grand if(bNeedToReduce) 9805f27b83cSArmin Le Grand { 9815f27b83cSArmin Le Grand fReduceFactor = sqrt(fMaximumArea / fArea); 9825f27b83cSArmin Le Grand fWidth *= fReduceFactor; 9835f27b83cSArmin Le Grand fHeight *= fReduceFactor; 9845f27b83cSArmin Le Grand } 9855f27b83cSArmin Le Grand 9865f27b83cSArmin Le Grand // Build complete transform from source pixels to target pixels. 9875f27b83cSArmin Le Grand // Start by scaling from source pixel size to unit coordinates 9885f27b83cSArmin Le Grand basegfx::B2DHomMatrix aTransform( 9895f27b83cSArmin Le Grand basegfx::tools::createScaleB2DHomMatrix( 9905f27b83cSArmin Le Grand 1.0 / nSourceWidth, 9915f27b83cSArmin Le Grand 1.0 / nSourceHeight)); 9925f27b83cSArmin Le Grand 9935f27b83cSArmin Le Grand // multiply with given transform which leads from unit coordinates inside 9945f27b83cSArmin Le Grand // aOutlineRange 9955f27b83cSArmin Le Grand aTransform = rTransformation * aTransform; 9965f27b83cSArmin Le Grand 997*f8c0d554SArmin Le Grand // substract top-left of absolute VisibleRange 998*f8c0d554SArmin Le Grand aTransform.translate( 999*f8c0d554SArmin Le Grand -aVisibleRange.getMinX(), 1000*f8c0d554SArmin Le Grand -aVisibleRange.getMinY()); 10015f27b83cSArmin Le Grand 10025f27b83cSArmin Le Grand // scale to target pixels (if needed) 10035f27b83cSArmin Le Grand if(bNeedToReduce) 10045f27b83cSArmin Le Grand { 10055f27b83cSArmin Le Grand aTransform.scale(fReduceFactor, fReduceFactor); 10065f27b83cSArmin Le Grand } 10075f27b83cSArmin Le Grand 10085f27b83cSArmin Le Grand // invert to get transformation from target pixel coordiates to source pixels 10095f27b83cSArmin Le Grand aTransform.invert(); 10105f27b83cSArmin Le Grand 10115f27b83cSArmin Le Grand // create bitmap using source, destination and linear back-transformation 1012*f8c0d554SArmin Le Grand aRetval = TransformBitmapEx(fWidth, fHeight, aTransform, bSmooth); 10135f27b83cSArmin Le Grand 10145f27b83cSArmin Le Grand return aRetval; 10155f27b83cSArmin Le Grand } 10165f27b83cSArmin Le Grand 10175f27b83cSArmin Le Grand // ------------------------------------------------------------------ 10185f27b83cSArmin Le Grand 10195f27b83cSArmin Le Grand BitmapEx BitmapEx::ModifyBitmapEx(const basegfx::BColorModifierStack& rBColorModifierStack) const 10205f27b83cSArmin Le Grand { 10215f27b83cSArmin Le Grand Bitmap aChangedBitmap(GetBitmap()); 10225f27b83cSArmin Le Grand bool bDone(false); 10235f27b83cSArmin Le Grand 10245f27b83cSArmin Le Grand for(sal_uInt32 a(rBColorModifierStack.count()); a && !bDone; ) 10255f27b83cSArmin Le Grand { 10265f27b83cSArmin Le Grand const basegfx::BColorModifier& rModifier = rBColorModifierStack.getBColorModifier(--a); 10275f27b83cSArmin Le Grand 10285f27b83cSArmin Le Grand switch(rModifier.getMode()) 10295f27b83cSArmin Le Grand { 10305f27b83cSArmin Le Grand case basegfx::BCOLORMODIFYMODE_REPLACE : 10315f27b83cSArmin Le Grand { 10325f27b83cSArmin Le Grand // complete replace 10335f27b83cSArmin Le Grand if(IsTransparent()) 10345f27b83cSArmin Le Grand { 10355f27b83cSArmin Le Grand // clear bitmap with dest color 10365f27b83cSArmin Le Grand if(aChangedBitmap.GetBitCount() <= 8) 10375f27b83cSArmin Le Grand { 10385f27b83cSArmin Le Grand // do NOT use erase; for e.g. 8bit Bitmaps, the nearest color to the given 10395f27b83cSArmin Le Grand // erase color is determined and used -> this may be different from what is 10405f27b83cSArmin Le Grand // wanted here. Better create a new bitmap with the needed color explicitely 10415f27b83cSArmin Le Grand BitmapReadAccess* pReadAccess = aChangedBitmap.AcquireReadAccess(); 10425f27b83cSArmin Le Grand OSL_ENSURE(pReadAccess, "Got no Bitmap ReadAccess ?!?"); 10435f27b83cSArmin Le Grand 10445f27b83cSArmin Le Grand if(pReadAccess) 10455f27b83cSArmin Le Grand { 10465f27b83cSArmin Le Grand BitmapPalette aNewPalette(pReadAccess->GetPalette()); 10475f27b83cSArmin Le Grand aNewPalette[0] = BitmapColor(Color(rModifier.getBColor())); 10485f27b83cSArmin Le Grand aChangedBitmap = Bitmap( 10495f27b83cSArmin Le Grand aChangedBitmap.GetSizePixel(), 10505f27b83cSArmin Le Grand aChangedBitmap.GetBitCount(), 10515f27b83cSArmin Le Grand &aNewPalette); 10525f27b83cSArmin Le Grand delete pReadAccess; 10535f27b83cSArmin Le Grand } 10545f27b83cSArmin Le Grand } 10555f27b83cSArmin Le Grand else 10565f27b83cSArmin Le Grand { 10575f27b83cSArmin Le Grand aChangedBitmap.Erase(Color(rModifier.getBColor())); 10585f27b83cSArmin Le Grand } 10595f27b83cSArmin Le Grand } 10605f27b83cSArmin Le Grand else 10615f27b83cSArmin Le Grand { 10625f27b83cSArmin Le Grand // erase bitmap, caller will know to paint direct 10635f27b83cSArmin Le Grand aChangedBitmap.SetEmpty(); 10645f27b83cSArmin Le Grand } 10655f27b83cSArmin Le Grand 10665f27b83cSArmin Le Grand bDone = true; 10675f27b83cSArmin Le Grand break; 10685f27b83cSArmin Le Grand } 10695f27b83cSArmin Le Grand 10705f27b83cSArmin Le Grand default : // BCOLORMODIFYMODE_INTERPOLATE, BCOLORMODIFYMODE_GRAY, BCOLORMODIFYMODE_BLACKANDWHITE 10715f27b83cSArmin Le Grand { 10725f27b83cSArmin Le Grand BitmapWriteAccess* pContent = aChangedBitmap.AcquireWriteAccess(); 10735f27b83cSArmin Le Grand 10745f27b83cSArmin Le Grand if(pContent) 10755f27b83cSArmin Le Grand { 10765f27b83cSArmin Le Grand const double fConvertColor(1.0 / 255.0); 10775f27b83cSArmin Le Grand 10785f27b83cSArmin Le Grand for(sal_uInt32 y(0L); y < (sal_uInt32)pContent->Height(); y++) 10795f27b83cSArmin Le Grand { 10805f27b83cSArmin Le Grand for(sal_uInt32 x(0L); x < (sal_uInt32)pContent->Width(); x++) 10815f27b83cSArmin Le Grand { 10825f27b83cSArmin Le Grand const BitmapColor aBMCol(pContent->GetColor(y, x)); 10835f27b83cSArmin Le Grand const basegfx::BColor aBSource( 10845f27b83cSArmin Le Grand (double)aBMCol.GetRed() * fConvertColor, 10855f27b83cSArmin Le Grand (double)aBMCol.GetGreen() * fConvertColor, 10865f27b83cSArmin Le Grand (double)aBMCol.GetBlue() * fConvertColor); 10875f27b83cSArmin Le Grand const basegfx::BColor aBDest(rModifier.getModifiedColor(aBSource)); 10885f27b83cSArmin Le Grand 10895f27b83cSArmin Le Grand pContent->SetPixel(y, x, BitmapColor(Color(aBDest))); 10905f27b83cSArmin Le Grand } 10915f27b83cSArmin Le Grand } 10925f27b83cSArmin Le Grand 10935f27b83cSArmin Le Grand delete pContent; 10945f27b83cSArmin Le Grand } 10955f27b83cSArmin Le Grand 10965f27b83cSArmin Le Grand break; 10975f27b83cSArmin Le Grand } 10985f27b83cSArmin Le Grand } 10995f27b83cSArmin Le Grand } 11005f27b83cSArmin Le Grand 11015f27b83cSArmin Le Grand if(aChangedBitmap.IsEmpty()) 11025f27b83cSArmin Le Grand { 11035f27b83cSArmin Le Grand return BitmapEx(); 11045f27b83cSArmin Le Grand } 11055f27b83cSArmin Le Grand else 11065f27b83cSArmin Le Grand { 11075f27b83cSArmin Le Grand if(IsTransparent()) 11085f27b83cSArmin Le Grand { 11095f27b83cSArmin Le Grand if(IsAlpha()) 11105f27b83cSArmin Le Grand { 11115f27b83cSArmin Le Grand return BitmapEx(aChangedBitmap, GetAlpha()); 11125f27b83cSArmin Le Grand } 11135f27b83cSArmin Le Grand else 11145f27b83cSArmin Le Grand { 11155f27b83cSArmin Le Grand return BitmapEx(aChangedBitmap, GetMask()); 11165f27b83cSArmin Le Grand } 11175f27b83cSArmin Le Grand } 11185f27b83cSArmin Le Grand else 11195f27b83cSArmin Le Grand { 11205f27b83cSArmin Le Grand return BitmapEx(aChangedBitmap); 11215f27b83cSArmin Le Grand } 11225f27b83cSArmin Le Grand } 11235f27b83cSArmin Le Grand } 11245f27b83cSArmin Le Grand 1125ff0f521cSArmin Le Grand // ----------------------------------------------------------------------------- 1126ff0f521cSArmin Le Grand 1127ff0f521cSArmin Le Grand BitmapEx VCL_DLLPUBLIC createBlendFrame( 1128ff0f521cSArmin Le Grand const Size& rSize, 1129ff0f521cSArmin Le Grand sal_uInt8 nAlpha, 1130ff0f521cSArmin Le Grand Color aColorTopLeft, 1131ff0f521cSArmin Le Grand Color aColorBottomRight) 1132ff0f521cSArmin Le Grand { 1133ff0f521cSArmin Le Grand const sal_uInt32 nW(rSize.Width()); 1134ff0f521cSArmin Le Grand const sal_uInt32 nH(rSize.Height()); 1135ff0f521cSArmin Le Grand 1136ff0f521cSArmin Le Grand if(nW || nH) 1137ff0f521cSArmin Le Grand { 1138ff0f521cSArmin Le Grand Color aColTopRight(aColorTopLeft); 1139ff0f521cSArmin Le Grand Color aColBottomLeft(aColorTopLeft); 1140ff0f521cSArmin Le Grand const sal_uInt32 nDE(nW + nH); 1141ff0f521cSArmin Le Grand 1142ff0f521cSArmin Le Grand aColTopRight.Merge(aColorBottomRight, 255 - sal_uInt8((nW * 255) / nDE)); 1143ff0f521cSArmin Le Grand aColBottomLeft.Merge(aColorBottomRight, 255 - sal_uInt8((nH * 255) / nDE)); 1144ff0f521cSArmin Le Grand 1145ff0f521cSArmin Le Grand return createBlendFrame(rSize, nAlpha, aColorTopLeft, aColTopRight, aColorBottomRight, aColBottomLeft); 1146ff0f521cSArmin Le Grand } 1147ff0f521cSArmin Le Grand 1148ff0f521cSArmin Le Grand return BitmapEx(); 1149ff0f521cSArmin Le Grand } 1150ff0f521cSArmin Le Grand 1151ff0f521cSArmin Le Grand BitmapEx VCL_DLLPUBLIC createBlendFrame( 1152ff0f521cSArmin Le Grand const Size& rSize, 1153ff0f521cSArmin Le Grand sal_uInt8 nAlpha, 1154ff0f521cSArmin Le Grand Color aColorTopLeft, 1155ff0f521cSArmin Le Grand Color aColorTopRight, 1156ff0f521cSArmin Le Grand Color aColorBottomRight, 1157ff0f521cSArmin Le Grand Color aColorBottomLeft) 1158ff0f521cSArmin Le Grand { 1159ff0f521cSArmin Le Grand static Size aLastSize(0, 0); 1160ff0f521cSArmin Le Grand static sal_uInt8 nLastAlpha(0); 1161ff0f521cSArmin Le Grand static Color aLastColorTopLeft(COL_BLACK); 1162ff0f521cSArmin Le Grand static Color aLastColorTopRight(COL_BLACK); 1163ff0f521cSArmin Le Grand static Color aLastColorBottomRight(COL_BLACK); 1164ff0f521cSArmin Le Grand static Color aLastColorBottomLeft(COL_BLACK); 1165ff0f521cSArmin Le Grand static BitmapEx aLastResult; 1166ff0f521cSArmin Le Grand 1167ff0f521cSArmin Le Grand if(aLastSize == rSize 1168ff0f521cSArmin Le Grand && nLastAlpha == nAlpha 11690d6bca7aSArmin Le Grand && aLastColorTopLeft == aColorTopLeft 11700d6bca7aSArmin Le Grand && aLastColorTopRight == aColorTopRight 11710d6bca7aSArmin Le Grand && aLastColorBottomRight == aColorBottomRight 11720d6bca7aSArmin Le Grand && aLastColorBottomLeft == aColorBottomLeft) 1173ff0f521cSArmin Le Grand { 1174ff0f521cSArmin Le Grand return aLastResult; 1175ff0f521cSArmin Le Grand } 1176ff0f521cSArmin Le Grand 1177ff0f521cSArmin Le Grand aLastSize = rSize; 1178ff0f521cSArmin Le Grand nLastAlpha = nAlpha; 11790d6bca7aSArmin Le Grand aLastColorTopLeft = aColorTopLeft; 11800d6bca7aSArmin Le Grand aLastColorTopRight = aColorTopRight; 11810d6bca7aSArmin Le Grand aLastColorBottomRight = aColorBottomRight; 11820d6bca7aSArmin Le Grand aLastColorBottomLeft = aColorBottomLeft; 1183ff0f521cSArmin Le Grand aLastResult.Clear(); 1184ff0f521cSArmin Le Grand 1185ff0f521cSArmin Le Grand const long nW(rSize.Width()); 1186ff0f521cSArmin Le Grand const long nH(rSize.Height()); 1187ff0f521cSArmin Le Grand 1188ff0f521cSArmin Le Grand if(nW && nH) 1189ff0f521cSArmin Le Grand { 1190ff0f521cSArmin Le Grand sal_uInt8 aEraseTrans(0xff); 1191ff0f521cSArmin Le Grand Bitmap aContent(rSize, 24); 1192ff0f521cSArmin Le Grand AlphaMask aAlpha(rSize, &aEraseTrans); 1193ff0f521cSArmin Le Grand 1194ff0f521cSArmin Le Grand aContent.Erase(COL_BLACK); 1195ff0f521cSArmin Le Grand 1196ff0f521cSArmin Le Grand BitmapWriteAccess* pContent = aContent.AcquireWriteAccess(); 1197ff0f521cSArmin Le Grand BitmapWriteAccess* pAlpha = aAlpha.AcquireWriteAccess(); 1198ff0f521cSArmin Le Grand 1199ff0f521cSArmin Le Grand if(pContent && pAlpha) 1200ff0f521cSArmin Le Grand { 1201ff0f521cSArmin Le Grand long x(0); 1202ff0f521cSArmin Le Grand long y(0); 1203ff0f521cSArmin Le Grand 1204ff0f521cSArmin Le Grand // x == 0, y == 0 1205ff0f521cSArmin Le Grand pContent->SetPixel(y, x, aColorTopLeft); 1206ff0f521cSArmin Le Grand pAlpha->SetPixelIndex(y, x, nAlpha); 1207ff0f521cSArmin Le Grand 1208ff0f521cSArmin Le Grand for(x = 1; x < nW - 1; x++) // y == 0 1209ff0f521cSArmin Le Grand { 1210ff0f521cSArmin Le Grand Color aMix(aColorTopLeft); 1211ff0f521cSArmin Le Grand 1212ff0f521cSArmin Le Grand aMix.Merge(aColorTopRight, 255 - sal_uInt8((x * 255) / nW)); 1213ff0f521cSArmin Le Grand pContent->SetPixel(y, x, aMix); 1214ff0f521cSArmin Le Grand pAlpha->SetPixelIndex(y, x, nAlpha); 1215ff0f521cSArmin Le Grand } 1216ff0f521cSArmin Le Grand 1217ff0f521cSArmin Le Grand // x == nW - 1, y == 0 1218ff0f521cSArmin Le Grand pContent->SetPixel(y, x, aColorTopRight); 1219ff0f521cSArmin Le Grand pAlpha->SetPixelIndex(y, x, nAlpha); 1220ff0f521cSArmin Le Grand 1221ff0f521cSArmin Le Grand for(y = 1; y < nH - 1; y++) // x == 0 and nW - 1 1222ff0f521cSArmin Le Grand { 1223ff0f521cSArmin Le Grand Color aMixA(aColorTopLeft); 1224ff0f521cSArmin Le Grand Color aMixB(aColorTopRight); 1225ff0f521cSArmin Le Grand 1226ff0f521cSArmin Le Grand aMixA.Merge(aColorBottomLeft, 255 - sal_uInt8((y * 255) / nH)); 1227ff0f521cSArmin Le Grand pContent->SetPixel(y, 0, aMixA); 1228ff0f521cSArmin Le Grand pAlpha->SetPixelIndex(y, 0, nAlpha); 1229ff0f521cSArmin Le Grand 1230ff0f521cSArmin Le Grand aMixB.Merge(aColorBottomRight, 255 - sal_uInt8((y * 255) / nH)); 1231ff0f521cSArmin Le Grand pContent->SetPixel(y, nW - 1, aMixB); 1232ff0f521cSArmin Le Grand pAlpha->SetPixelIndex(y, nW - 1, nAlpha); 1233ff0f521cSArmin Le Grand } 1234ff0f521cSArmin Le Grand 1235ff0f521cSArmin Le Grand x = 0; // x == 0, y == nH - 1 1236ff0f521cSArmin Le Grand pContent->SetPixel(y, x, aColorBottomLeft); 1237ff0f521cSArmin Le Grand pAlpha->SetPixelIndex(y, x, nAlpha); 1238ff0f521cSArmin Le Grand 1239ff0f521cSArmin Le Grand for(x = 1; x < nW - 1; x++) // y == nH - 1 1240ff0f521cSArmin Le Grand { 1241ff0f521cSArmin Le Grand Color aMix(aColorBottomLeft); 1242ff0f521cSArmin Le Grand 1243ff0f521cSArmin Le Grand aMix.Merge(aColorBottomRight, 255 - sal_uInt8(((x - 0)* 255) / nW)); 1244ff0f521cSArmin Le Grand pContent->SetPixel(y, x, aMix); 1245ff0f521cSArmin Le Grand pAlpha->SetPixelIndex(y, x, nAlpha); 1246ff0f521cSArmin Le Grand } 1247ff0f521cSArmin Le Grand 1248ff0f521cSArmin Le Grand // x == nW - 1, y == nH - 1 1249ff0f521cSArmin Le Grand pContent->SetPixel(y, x, aColorBottomRight); 1250ff0f521cSArmin Le Grand pAlpha->SetPixelIndex(y, x, nAlpha); 1251ff0f521cSArmin Le Grand 1252ff0f521cSArmin Le Grand aContent.ReleaseAccess(pContent); 1253ff0f521cSArmin Le Grand aAlpha.ReleaseAccess(pAlpha); 1254ff0f521cSArmin Le Grand 1255ff0f521cSArmin Le Grand aLastResult = BitmapEx(aContent, aAlpha); 1256ff0f521cSArmin Le Grand } 1257ff0f521cSArmin Le Grand else 1258ff0f521cSArmin Le Grand { 1259ff0f521cSArmin Le Grand if(pContent) 1260ff0f521cSArmin Le Grand { 1261ff0f521cSArmin Le Grand aContent.ReleaseAccess(pContent); 1262ff0f521cSArmin Le Grand } 1263ff0f521cSArmin Le Grand 1264ff0f521cSArmin Le Grand if(pAlpha) 1265ff0f521cSArmin Le Grand { 1266ff0f521cSArmin Le Grand aAlpha.ReleaseAccess(pAlpha); 1267ff0f521cSArmin Le Grand } 1268ff0f521cSArmin Le Grand } 1269ff0f521cSArmin Le Grand } 1270ff0f521cSArmin Le Grand 1271ff0f521cSArmin Le Grand return aLastResult; 1272ff0f521cSArmin Le Grand } 1273ff0f521cSArmin Le Grand 1274cdf0e10cSrcweir // ------------------------------------------------------------------ 127545fd3b9aSArmin Le Grand // eof 1276