xref: /AOO41X/main/vcl/source/gdi/bitmap.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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