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