xref: /aoo42x/main/vcl/source/gdi/bitmapex.cxx (revision 45fd3b9a)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 // MARKER(update_precomp.py): autogen include statement, do not remove
23 #include "precompiled_vcl.hxx"
24 
25 #include <ctype.h>
26 #include <rtl/crc.h>
27 #include <tools/stream.hxx>
28 #include <tools/debug.hxx>
29 #include <tools/rc.h>
30 #include <vcl/salbtype.hxx>
31 #include <vcl/outdev.hxx>
32 #include <vcl/alpha.hxx>
33 #include <vcl/bitmapex.hxx>
34 #include <vcl/pngread.hxx>
35 #include <vcl/svapp.hxx>
36 #include <vcl/bmpacc.hxx>
37 #include <vcl/dibtools.hxx>
38 #include <image.h>
39 #include <impimagetree.hxx>
40 
41 // ------------
42 // - BitmapEx -
43 // ------------
44 
45 BitmapEx::BitmapEx() :
46 		eTransparent( TRANSPARENT_NONE ),
47 		bAlpha		( sal_False )
48 {
49 }
50 
51 // ------------------------------------------------------------------
52 
53 BitmapEx::BitmapEx( const BitmapEx& rBitmapEx ) :
54 		aBitmap				( rBitmapEx.aBitmap ),
55 		aMask				( rBitmapEx.aMask ),
56 		aBitmapSize			( rBitmapEx.aBitmapSize ),
57 		aTransparentColor	( rBitmapEx.aTransparentColor ),
58 		eTransparent		( rBitmapEx.eTransparent ),
59 		bAlpha				( rBitmapEx.bAlpha )
60 {
61 }
62 
63 BitmapEx::BitmapEx( const BitmapEx& rBitmapEx, Point aSrc, Size aSize ) :
64 		eTransparent( TRANSPARENT_NONE ),
65 		bAlpha		( sal_False )
66 {
67 	if( rBitmapEx.IsEmpty() )
68 		return;
69 
70 	aBitmap = Bitmap( aSize, rBitmapEx.aBitmap.GetBitCount() );
71 	aBitmapSize = aSize;
72 	if( rBitmapEx.IsAlpha() )
73 	{
74 		bAlpha = sal_True;
75 		aMask = AlphaMask( aSize ).ImplGetBitmap();
76 	}
77 	else if( rBitmapEx.IsTransparent() )
78 		aMask = Bitmap( aSize, rBitmapEx.aMask.GetBitCount() );
79 
80 	Rectangle aDestRect( Point( 0, 0 ), aSize );
81 	Rectangle aSrcRect( aSrc, aSize );
82 	CopyPixel( aDestRect, aSrcRect, &rBitmapEx );
83 }
84 
85 // ------------------------------------------------------------------
86 
87 BitmapEx::BitmapEx( const ResId& rResId ) :
88 		eTransparent( TRANSPARENT_NONE ),
89 		bAlpha		( sal_False )
90 {
91 	static ImplImageTreeSingletonRef	aImageTree;
92 	ResMgr* 							pResMgr = NULL;
93 
94 	ResMgr::GetResourceSkipHeader( rResId.SetRT( RSC_BITMAP ), &pResMgr );
95 	pResMgr->ReadLong();
96 	pResMgr->ReadLong();
97 
98 	const String aFileName( pResMgr->ReadString() );
99 	::rtl::OUString aCurrentSymbolsStyle = Application::GetSettings().GetStyleSettings().GetCurrentSymbolsStyleName();
100 
101 	if( !aImageTree->loadImage( aFileName, aCurrentSymbolsStyle, *this ) )
102 	{
103 #ifdef DBG_UTIL
104 		ByteString aErrorStr( "BitmapEx::BitmapEx( const ResId& rResId ): could not load image <" );
105 		DBG_ERROR( ( ( aErrorStr += ByteString( aFileName, RTL_TEXTENCODING_ASCII_US ) ) += '>' ).GetBuffer() );
106 #endif
107 	}
108 }
109 
110 // ------------------------------------------------------------------
111 
112 BitmapEx::BitmapEx( const Bitmap& rBmp ) :
113 		aBitmap		( rBmp ),
114 		aBitmapSize	( aBitmap.GetSizePixel() ),
115 		eTransparent( TRANSPARENT_NONE ),
116 		bAlpha		( sal_False )
117 {
118 }
119 
120 // ------------------------------------------------------------------
121 
122 BitmapEx::BitmapEx( const Bitmap& rBmp, const Bitmap& rMask ) :
123 		aBitmap			( rBmp ),
124 		aMask			( rMask ),
125 		aBitmapSize		( aBitmap.GetSizePixel() ),
126 		eTransparent	( !rMask ? TRANSPARENT_NONE : TRANSPARENT_BITMAP ),
127 		bAlpha			( sal_False )
128 {
129     if(!!aBitmap && !!aMask && aBitmap.GetSizePixel() != aMask.GetSizePixel())
130     {
131         OSL_ENSURE(false, "Mask size differs from Bitmap size, corrected Mask (!)");
132         aMask.Scale(aBitmap.GetSizePixel());
133     }
134 
135     // #105489# Ensure a mask is exactly one bit deep
136     if( !!aMask && aMask.GetBitCount() != 1 )
137     {
138         OSL_TRACE("BitmapEx: forced mask to monochrome");
139         aMask.ImplMakeMono( 255 );
140     }
141 }
142 
143 // ------------------------------------------------------------------
144 
145 BitmapEx::BitmapEx( const Bitmap& rBmp, const AlphaMask& rAlphaMask ) :
146 		aBitmap			( rBmp ),
147 		aMask			( rAlphaMask.ImplGetBitmap() ),
148 		aBitmapSize		( aBitmap.GetSizePixel() ),
149 		eTransparent	( !rAlphaMask ? TRANSPARENT_NONE : TRANSPARENT_BITMAP ),
150 		bAlpha			( !rAlphaMask ? sal_False : sal_True )
151 {
152     if(!!aBitmap && !!aMask && aBitmap.GetSizePixel() != aMask.GetSizePixel())
153     {
154         OSL_ENSURE(false, "Alpha size differs from Bitmap size, corrected Mask (!)");
155         aMask.Scale(rBmp.GetSizePixel());
156     }
157 
158     // #i75531# the workaround below can go when
159     // X11SalGraphics::drawAlphaBitmap()'s render acceleration
160     // can handle the bitmap depth mismatch directly
161     if( aBitmap.GetBitCount() < aMask.GetBitCount() )
162         aBitmap.Convert( BMP_CONVERSION_24BIT );
163 }
164 
165 // ------------------------------------------------------------------
166 
167 BitmapEx::BitmapEx( const Bitmap& rBmp, const Color& rTransparentColor ) :
168 		aBitmap				( rBmp ),
169 		aBitmapSize			( aBitmap.GetSizePixel() ),
170 		aTransparentColor	( rTransparentColor ),
171 		eTransparent		( TRANSPARENT_BITMAP ),
172 		bAlpha				( sal_False )
173 {
174 	aMask = aBitmap.CreateMask( aTransparentColor );
175 
176     DBG_ASSERT( rBmp.GetSizePixel() == aMask.GetSizePixel(),
177                 "BitmapEx::BitmapEx(): size mismatch for bitmap and alpha mask." );
178 }
179 
180 // ------------------------------------------------------------------
181 
182 BitmapEx::~BitmapEx()
183 {
184 }
185 
186 // ------------------------------------------------------------------
187 
188 // ------------------------------------------------------------------
189 
190 BitmapEx& BitmapEx::operator=( const BitmapEx& rBitmapEx )
191 {
192 	if( &rBitmapEx != this )
193 	{
194 		aBitmap = rBitmapEx.aBitmap;
195 		aMask = rBitmapEx.aMask;
196 		aBitmapSize = rBitmapEx.aBitmapSize;
197 		aTransparentColor = rBitmapEx.aTransparentColor;
198 		eTransparent = rBitmapEx.eTransparent;
199 		bAlpha = rBitmapEx.bAlpha;
200 	}
201 
202 	return *this;
203 }
204 
205 // ------------------------------------------------------------------
206 
207 sal_Bool BitmapEx::operator==( const BitmapEx& rBitmapEx ) const
208 {
209 	if( eTransparent != rBitmapEx.eTransparent )
210 		return sal_False;
211 
212 	if( aBitmap != rBitmapEx.aBitmap )
213 		return sal_False;
214 
215 	if( aBitmapSize != rBitmapEx.aBitmapSize )
216 		return sal_False;
217 
218 	if( eTransparent == TRANSPARENT_NONE )
219 		return sal_True;
220 
221 	if( eTransparent == TRANSPARENT_COLOR )
222 		return aTransparentColor == rBitmapEx.aTransparentColor;
223 
224 	return( ( aMask == rBitmapEx.aMask ) && ( bAlpha == rBitmapEx.bAlpha ) );
225 }
226 
227 // ------------------------------------------------------------------
228 
229 sal_Bool BitmapEx::IsEqual( const BitmapEx& rBmpEx ) const
230 {
231 	return( rBmpEx.eTransparent == eTransparent &&
232 			rBmpEx.bAlpha == bAlpha &&
233 			rBmpEx.aBitmap.IsEqual( aBitmap ) &&
234 			rBmpEx.aMask.IsEqual( aMask ) );
235 }
236 
237 // ------------------------------------------------------------------
238 
239 sal_Bool BitmapEx::IsEmpty() const
240 {
241 	return( aBitmap.IsEmpty() && aMask.IsEmpty() );
242 }
243 
244 // ------------------------------------------------------------------
245 
246 void BitmapEx::SetEmpty()
247 {
248 	aBitmap.SetEmpty();
249 	aMask.SetEmpty();
250 	eTransparent = TRANSPARENT_NONE;
251 	bAlpha = sal_False;
252 }
253 
254 // ------------------------------------------------------------------
255 
256 void BitmapEx::Clear()
257 {
258 	SetEmpty();
259 }
260 
261 // ------------------------------------------------------------------
262 
263 sal_Bool BitmapEx::IsTransparent() const
264 {
265 	return( eTransparent != TRANSPARENT_NONE );
266 }
267 
268 // ------------------------------------------------------------------
269 
270 sal_Bool BitmapEx::IsAlpha() const
271 {
272 	return( IsTransparent() && bAlpha );
273 }
274 
275 // ------------------------------------------------------------------
276 
277 Bitmap BitmapEx::GetBitmap( const Color* pTransReplaceColor ) const
278 {
279 	Bitmap aRetBmp( aBitmap );
280 
281 	if( pTransReplaceColor && ( eTransparent != TRANSPARENT_NONE ) )
282 	{
283 		Bitmap aTempMask;
284 
285 		if( eTransparent == TRANSPARENT_COLOR )
286 			aTempMask = aBitmap.CreateMask( aTransparentColor );
287 		else
288 			aTempMask = aMask;
289 
290 		if( !IsAlpha() )
291 			aRetBmp.Replace( aTempMask, *pTransReplaceColor );
292 		else
293 			aRetBmp.Replace( GetAlpha(), *pTransReplaceColor );
294 	}
295 
296 	return aRetBmp;
297 }
298 
299 // ------------------------------------------------------------------
300 
301 BitmapEx BitmapEx::GetColorTransformedBitmapEx( BmpColorMode eColorMode ) const
302 {
303 	BitmapEx aRet;
304 
305 	if( BMP_COLOR_HIGHCONTRAST == eColorMode )
306 	{
307 		aRet = *this;
308 		aRet.aBitmap = aBitmap.GetColorTransformedBitmap( eColorMode );
309 	}
310 	else if( BMP_COLOR_MONOCHROME_BLACK == eColorMode ||
311 			 BMP_COLOR_MONOCHROME_WHITE == eColorMode )
312 	{
313 		aRet = *this;
314 		aRet.aBitmap = aRet.aBitmap.GetColorTransformedBitmap( eColorMode );
315 
316 		if( !aRet.aMask.IsEmpty() )
317 		{
318 			aRet.aMask.CombineSimple( aRet.aBitmap, BMP_COMBINE_OR );
319 			aRet.aBitmap.Erase( ( BMP_COLOR_MONOCHROME_BLACK == eColorMode ) ? COL_BLACK : COL_WHITE );
320 
321             DBG_ASSERT( aRet.aBitmap.GetSizePixel() == aRet.aMask.GetSizePixel(),
322                         "BitmapEx::GetColorTransformedBitmapEx(): size mismatch for bitmap and alpha mask." );
323 		}
324 	}
325 
326 	return aRet;
327 }
328 
329 // ------------------------------------------------------------------
330 
331 Bitmap BitmapEx::GetMask() const
332 {
333 	Bitmap aRet( aMask );
334 
335 	if( IsAlpha() )
336 		aRet.ImplMakeMono( 255 );
337 
338 	return aRet;
339 }
340 
341 // ------------------------------------------------------------------
342 
343 AlphaMask BitmapEx::GetAlpha() const
344 {
345 	AlphaMask aAlpha;
346 
347 	if( IsAlpha() )
348 		aAlpha.ImplSetBitmap( aMask );
349 	else
350 		aAlpha = aMask;
351 
352 	return aAlpha;
353 }
354 
355 // ------------------------------------------------------------------
356 
357 sal_uLong BitmapEx::GetSizeBytes() const
358 {
359 	sal_uLong nSizeBytes = aBitmap.GetSizeBytes();
360 
361 	if( eTransparent == TRANSPARENT_BITMAP )
362 		nSizeBytes += aMask.GetSizeBytes();
363 
364 	return nSizeBytes;
365 }
366 
367 // ------------------------------------------------------------------
368 
369 sal_uLong BitmapEx::GetChecksum() const
370 {
371 	sal_uInt32	nCrc = aBitmap.GetChecksum();
372 	SVBT32		aBT32;
373 
374 	UInt32ToSVBT32( (long) eTransparent, aBT32 );
375 	nCrc = rtl_crc32( nCrc, aBT32, 4 );
376 
377 	UInt32ToSVBT32( (long) bAlpha, aBT32 );
378 	nCrc = rtl_crc32( nCrc, aBT32, 4 );
379 
380 	if( ( TRANSPARENT_BITMAP == eTransparent ) && !aMask.IsEmpty() )
381 	{
382 		UInt32ToSVBT32( aMask.GetChecksum(), aBT32 );
383 		nCrc = rtl_crc32( nCrc, aBT32, 4 );
384 	}
385 
386 	return nCrc;
387 }
388 
389 // ------------------------------------------------------------------
390 
391 void BitmapEx::SetSizePixel( const Size& rNewSize, sal_uInt32 nScaleFlag )
392 {
393     if(GetSizePixel() != rNewSize)
394     {
395         Scale( rNewSize, nScaleFlag );
396     }
397 }
398 
399 // ------------------------------------------------------------------
400 
401 sal_Bool BitmapEx::Invert()
402 {
403 	sal_Bool bRet = sal_False;
404 
405 	if( !!aBitmap )
406 	{
407 		bRet = aBitmap.Invert();
408 
409 		if( bRet && ( eTransparent == TRANSPARENT_COLOR ) )
410 			aTransparentColor = BitmapColor( aTransparentColor ).Invert();
411 	}
412 
413 	return bRet;
414 }
415 
416 // ------------------------------------------------------------------
417 
418 sal_Bool BitmapEx::Mirror( sal_uLong nMirrorFlags )
419 {
420 	sal_Bool bRet = sal_False;
421 
422 	if( !!aBitmap )
423 	{
424 		bRet = aBitmap.Mirror( nMirrorFlags );
425 
426 		if( bRet && ( eTransparent == TRANSPARENT_BITMAP ) && !!aMask )
427 			aMask.Mirror( nMirrorFlags );
428 	}
429 
430 	return bRet;
431 }
432 
433 // ------------------------------------------------------------------
434 
435 sal_Bool BitmapEx::Scale( const double& rScaleX, const double& rScaleY, sal_uInt32 nScaleFlag )
436 {
437 	sal_Bool bRet = sal_False;
438 
439 	if( !!aBitmap )
440 	{
441 		bRet = aBitmap.Scale( rScaleX, rScaleY, nScaleFlag );
442 
443 		if( bRet && ( eTransparent == TRANSPARENT_BITMAP ) && !!aMask )
444         {
445 			aMask.Scale( rScaleX, rScaleY, nScaleFlag );
446         }
447 
448 		aBitmapSize = aBitmap.GetSizePixel();
449 
450         DBG_ASSERT( !aMask || aBitmap.GetSizePixel() == aMask.GetSizePixel(),
451                     "BitmapEx::Scale(): size mismatch for bitmap and alpha mask." );
452 	}
453 
454 	return bRet;
455 }
456 
457 // ------------------------------------------------------------------------
458 
459 sal_Bool BitmapEx::Scale( const Size& rNewSize, sal_uInt32 nScaleFlag )
460 {
461 	sal_Bool bRet;
462 
463 	if( aBitmapSize.Width() && aBitmapSize.Height() )
464 	{
465 		bRet = Scale( (double) rNewSize.Width() / aBitmapSize.Width(),
466 					  (double) rNewSize.Height() / aBitmapSize.Height(),
467 					  nScaleFlag );
468 	}
469 	else
470 		bRet = sal_True;
471 
472 	return bRet;
473 }
474 
475 // ------------------------------------------------------------------
476 
477 sal_Bool BitmapEx::Rotate( long nAngle10, const Color& rFillColor )
478 {
479 	sal_Bool bRet = sal_False;
480 
481 	if( !!aBitmap )
482 	{
483 		const sal_Bool bTransRotate = ( Color( COL_TRANSPARENT ) == rFillColor );
484 
485 		if( bTransRotate )
486 		{
487 			if( eTransparent == TRANSPARENT_COLOR )
488 				bRet = aBitmap.Rotate( nAngle10, aTransparentColor );
489 			else
490 			{
491 				bRet = aBitmap.Rotate( nAngle10, COL_BLACK );
492 
493 				if( eTransparent == TRANSPARENT_NONE )
494 				{
495 					aMask = Bitmap( aBitmapSize, 1 );
496 					aMask.Erase( COL_BLACK );
497 					eTransparent = TRANSPARENT_BITMAP;
498 				}
499 
500 				if( bRet && !!aMask )
501 					aMask.Rotate( nAngle10, COL_WHITE );
502 			}
503 		}
504 		else
505 		{
506 			bRet = aBitmap.Rotate( nAngle10, rFillColor );
507 
508 			if( bRet && ( eTransparent == TRANSPARENT_BITMAP ) && !!aMask )
509 				aMask.Rotate( nAngle10, COL_WHITE );
510 		}
511 
512 		aBitmapSize = aBitmap.GetSizePixel();
513 
514         DBG_ASSERT( !aMask || aBitmap.GetSizePixel() == aMask.GetSizePixel(),
515                     "BitmapEx::Rotate(): size mismatch for bitmap and alpha mask." );
516 	}
517 
518 	return bRet;
519 }
520 
521 // ------------------------------------------------------------------
522 
523 sal_Bool BitmapEx::Crop( const Rectangle& rRectPixel )
524 {
525 	sal_Bool bRet = sal_False;
526 
527 	if( !!aBitmap )
528 	{
529 		bRet = aBitmap.Crop( rRectPixel );
530 
531 		if( bRet && ( eTransparent == TRANSPARENT_BITMAP ) && !!aMask )
532 			aMask.Crop( rRectPixel );
533 
534 		aBitmapSize = aBitmap.GetSizePixel();
535 
536         DBG_ASSERT( !aMask || aBitmap.GetSizePixel() == aMask.GetSizePixel(),
537                     "BitmapEx::Crop(): size mismatch for bitmap and alpha mask." );
538 	}
539 
540 	return bRet;
541 }
542 
543 // ------------------------------------------------------------------
544 
545 sal_Bool BitmapEx::Convert( BmpConversion eConversion )
546 {
547 	return( !!aBitmap ? aBitmap.Convert( eConversion ) : sal_False );
548 }
549 
550 // ------------------------------------------------------------------
551 
552 sal_Bool BitmapEx::ReduceColors( sal_uInt16 nNewColorCount, BmpReduce eReduce )
553 {
554 	return( !!aBitmap ? aBitmap.ReduceColors( nNewColorCount, eReduce ) : sal_False );
555 }
556 
557 // ------------------------------------------------------------------
558 
559 sal_Bool BitmapEx::Expand( sal_uLong nDX, sal_uLong nDY, const Color* pInitColor, sal_Bool bExpandTransparent )
560 {
561 	sal_Bool bRet = sal_False;
562 
563 	if( !!aBitmap )
564 	{
565 		bRet = aBitmap.Expand( nDX, nDY, pInitColor );
566 
567 		if( bRet && ( eTransparent == TRANSPARENT_BITMAP ) && !!aMask )
568 		{
569 			Color aColor( bExpandTransparent ? COL_WHITE : COL_BLACK );
570 			aMask.Expand( nDX, nDY, &aColor );
571 		}
572 
573 		aBitmapSize = aBitmap.GetSizePixel();
574 
575         DBG_ASSERT( !aMask || aBitmap.GetSizePixel() == aMask.GetSizePixel(),
576                     "BitmapEx::Expand(): size mismatch for bitmap and alpha mask." );
577 	}
578 
579 	return bRet;
580 }
581 
582 // ------------------------------------------------------------------
583 
584 sal_Bool BitmapEx::CopyPixel( const Rectangle& rRectDst, const Rectangle& rRectSrc,
585 						  const BitmapEx* pBmpExSrc )
586 {
587 	sal_Bool bRet = sal_False;
588 
589 	if( !pBmpExSrc || pBmpExSrc->IsEmpty() )
590 	{
591 		if( !aBitmap.IsEmpty() )
592 		{
593 			bRet = aBitmap.CopyPixel( rRectDst, rRectSrc );
594 
595 			if( bRet && ( eTransparent == TRANSPARENT_BITMAP ) && !!aMask )
596 				aMask.CopyPixel( rRectDst, rRectSrc );
597 		}
598 	}
599 	else
600 	{
601 		if( !aBitmap.IsEmpty() )
602 		{
603 			bRet = aBitmap.CopyPixel( rRectDst, rRectSrc, &pBmpExSrc->aBitmap );
604 
605 			if( bRet )
606 			{
607 				if( pBmpExSrc->IsAlpha() )
608 				{
609 					if( IsAlpha() )
610                         // cast to use the optimized AlphaMask::CopyPixel
611 						((AlphaMask*) &aMask)->CopyPixel( rRectDst, rRectSrc, (AlphaMask*)&pBmpExSrc->aMask );
612 					else if( IsTransparent() )
613 					{
614 						AlphaMask* pAlpha = new AlphaMask( aMask );
615 
616 						aMask = pAlpha->ImplGetBitmap();
617 						delete pAlpha;
618 						bAlpha = sal_True;
619 						aMask.CopyPixel( rRectDst, rRectSrc, &pBmpExSrc->aMask );
620 					}
621 					else
622 					{
623 						sal_uInt8	cBlack = 0;
624 						AlphaMask*	pAlpha = new AlphaMask( GetSizePixel(), &cBlack );
625 
626 						aMask = pAlpha->ImplGetBitmap();
627 						delete pAlpha;
628 						eTransparent = TRANSPARENT_BITMAP;
629 						bAlpha = sal_True;
630 						aMask.CopyPixel( rRectDst, rRectSrc, &pBmpExSrc->aMask );
631 					}
632 				}
633 				else if( pBmpExSrc->IsTransparent() )
634 				{
635 					if( IsAlpha() )
636 					{
637 						AlphaMask aAlpha( pBmpExSrc->aMask );
638 						aMask.CopyPixel( rRectDst, rRectSrc, &aAlpha.ImplGetBitmap() );
639 					}
640 					else if( IsTransparent() )
641 						aMask.CopyPixel( rRectDst, rRectSrc, &pBmpExSrc->aMask );
642 					else
643 					{
644 						aMask = Bitmap( GetSizePixel(), 1 );
645 						aMask.Erase( Color( COL_BLACK ) );
646 						eTransparent = TRANSPARENT_BITMAP;
647 						aMask.CopyPixel( rRectDst, rRectSrc, &pBmpExSrc->aMask );
648 					}
649 				}
650                 else if( IsAlpha() )
651                 {
652                     sal_uInt8	      cBlack = 0;
653                     const AlphaMask   aAlphaSrc( pBmpExSrc->GetSizePixel(), &cBlack );
654 
655                     aMask.CopyPixel( rRectDst, rRectSrc, &aAlphaSrc.ImplGetBitmap() );
656                 }
657                 else if( IsTransparent() )
658                 {
659                     Bitmap aMaskSrc( pBmpExSrc->GetSizePixel(), 1 );
660 
661                     aMaskSrc.Erase( Color( COL_BLACK ) );
662                     aMask.CopyPixel( rRectDst, rRectSrc, &aMaskSrc );
663                 }
664 			}
665 		}
666 	}
667 
668 	return bRet;
669 }
670 
671 // ------------------------------------------------------------------
672 
673 sal_Bool BitmapEx::Erase( const Color& rFillColor )
674 {
675 	sal_Bool bRet = sal_False;
676 
677 	if( !!aBitmap )
678 	{
679 		bRet = aBitmap.Erase( rFillColor );
680 
681 		if( bRet && ( eTransparent == TRANSPARENT_BITMAP ) && !!aMask )
682 		{
683             // #104416# Respect transparency on fill color
684             if( rFillColor.GetTransparency() )
685             {
686                 const Color aFill( rFillColor.GetTransparency(), rFillColor.GetTransparency(), rFillColor.GetTransparency() );
687                 aMask.Erase( aFill );
688             }
689             else
690             {
691                 const Color aBlack( COL_BLACK );
692                 aMask.Erase( aBlack );
693             }
694 		}
695 	}
696 
697 	return bRet;
698 }
699 
700 // ------------------------------------------------------------------
701 
702 sal_Bool BitmapEx::Dither( sal_uLong nDitherFlags )
703 {
704 	return( !!aBitmap ? aBitmap.Dither( nDitherFlags ) : sal_False );
705 }
706 
707 // ------------------------------------------------------------------
708 
709 sal_Bool BitmapEx::Replace( const Color& rSearchColor, const Color& rReplaceColor, sal_uLong nTol )
710 {
711 	return( !!aBitmap ? aBitmap.Replace( rSearchColor, rReplaceColor, nTol ) : sal_False );
712 }
713 
714 // ------------------------------------------------------------------
715 
716 sal_Bool BitmapEx::Replace( const Color* pSearchColors, const Color* pReplaceColors, sal_uLong nColorCount, const sal_uLong* pTols )
717 {
718 	return( !!aBitmap ? aBitmap.Replace( pSearchColors, pReplaceColors, nColorCount, (sal_uLong*) pTols ) : sal_False );
719 }
720 
721 // ------------------------------------------------------------------
722 
723 sal_Bool BitmapEx::Adjust( short nLuminancePercent, short nContrastPercent,
724 					   short nChannelRPercent, short nChannelGPercent, short nChannelBPercent,
725 					   double fGamma, sal_Bool bInvert )
726 {
727 	return( !!aBitmap ? aBitmap.Adjust( nLuminancePercent, nContrastPercent,
728 										nChannelRPercent, nChannelGPercent, nChannelBPercent,
729 										fGamma, bInvert ) : sal_False );
730 }
731 
732 // ------------------------------------------------------------------
733 
734 sal_Bool BitmapEx::Filter( BmpFilter eFilter, const BmpFilterParam* pFilterParam, const Link* pProgress )
735 {
736 	return( !!aBitmap ? aBitmap.Filter( eFilter, pFilterParam, pProgress ) : sal_False );
737 }
738 
739 // ------------------------------------------------------------------
740 
741 void BitmapEx::Draw( OutputDevice* pOutDev, const Point& rDestPt ) const
742 {
743 	pOutDev->DrawBitmapEx( rDestPt, *this );
744 }
745 
746 // ------------------------------------------------------------------
747 
748 void BitmapEx::Draw( OutputDevice* pOutDev,
749 					 const Point& rDestPt, const Size& rDestSize ) const
750 {
751 	pOutDev->DrawBitmapEx( rDestPt, rDestSize, *this );
752 }
753 
754 // ------------------------------------------------------------------
755 
756 void BitmapEx::Draw( OutputDevice* pOutDev,
757 					 const Point& rDestPt, const Size& rDestSize,
758 					 const Point& rSrcPtPixel, const Size& rSrcSizePixel ) const
759 {
760 	pOutDev->DrawBitmapEx( rDestPt, rDestSize, rSrcPtPixel, rSrcSizePixel, *this );
761 }
762 
763 // ------------------------------------------------------------------
764 
765 sal_uInt8 BitmapEx::GetTransparency(sal_Int32 nX, sal_Int32 nY) const
766 {
767     sal_uInt8 nTransparency(0xff);
768 
769     if(!aBitmap.IsEmpty())
770     {
771         if(nX >= 0 && nX < aBitmapSize.Width() && nY >= 0 && nY < aBitmapSize.Height())
772         {
773             switch(eTransparent)
774             {
775                 case TRANSPARENT_NONE:
776                 {
777                     // not transparent, ergo all covered
778                     nTransparency = 0x00;
779                     break;
780                 }
781                 case TRANSPARENT_COLOR:
782                 {
783                     Bitmap aTestBitmap(aBitmap);
784                     BitmapReadAccess* pRead = aTestBitmap.AcquireReadAccess();
785 
786                     if(pRead)
787                     {
788                         const Color aColor = pRead->GetColor(nY, nX);
789 
790                         // if color is not equal to TransparentColor, we are not transparent
791                         if(aColor != aTransparentColor)
792                         {
793                             nTransparency = 0x00;
794                         }
795 
796                         aTestBitmap.ReleaseAccess(pRead);
797                     }
798                     break;
799                 }
800                 case TRANSPARENT_BITMAP:
801                 {
802                     if(!aMask.IsEmpty())
803                     {
804                         Bitmap aTestBitmap(aMask);
805                         BitmapReadAccess* pRead = aTestBitmap.AcquireReadAccess();
806 
807                         if(pRead)
808                         {
809                             const BitmapColor aBitmapColor(pRead->GetPixel(nY, nX));
810 
811                             if(bAlpha)
812                             {
813                                 nTransparency = aBitmapColor.GetIndex();
814                             }
815                             else
816                             {
817                                 if(0x00 == aBitmapColor.GetIndex())
818                                 {
819                                     nTransparency = 0x00;
820                                 }
821                             }
822 
823                             aTestBitmap.ReleaseAccess(pRead);
824                         }
825                     }
826                     break;
827                 }
828             }
829         }
830     }
831 
832     return nTransparency;
833 }
834 
835 // ------------------------------------------------------------------
836 // eof
837