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