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