xref: /aoo42x/main/vcl/source/gdi/bitmapex.cxx (revision f2e5373e)
19f62ea84SAndrew Rist /**************************************************************
2*f2e5373eSmseidel  *
39f62ea84SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
49f62ea84SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
59f62ea84SAndrew Rist  * distributed with this work for additional information
69f62ea84SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
79f62ea84SAndrew Rist  * to you under the Apache License, Version 2.0 (the
89f62ea84SAndrew Rist  * "License"); you may not use this file except in compliance
99f62ea84SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*f2e5373eSmseidel  *
119f62ea84SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*f2e5373eSmseidel  *
139f62ea84SAndrew Rist  * Unless required by applicable law or agreed to in writing,
149f62ea84SAndrew Rist  * software distributed under the License is distributed on an
159f62ea84SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
169f62ea84SAndrew Rist  * KIND, either express or implied.  See the License for the
179f62ea84SAndrew Rist  * specific language governing permissions and limitations
189f62ea84SAndrew Rist  * under the License.
19*f2e5373eSmseidel  *
209f62ea84SAndrew Rist  *************************************************************/
219f62ea84SAndrew Rist 
22*f2e5373eSmseidel 
23*f2e5373eSmseidel 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_vcl.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include <ctype.h>
28cdf0e10cSrcweir #include <rtl/crc.h>
29cdf0e10cSrcweir #include <tools/stream.hxx>
30cdf0e10cSrcweir #include <tools/debug.hxx>
31cdf0e10cSrcweir #include <tools/rc.h>
32cdf0e10cSrcweir #include <vcl/salbtype.hxx>
33cdf0e10cSrcweir #include <vcl/outdev.hxx>
34cdf0e10cSrcweir #include <vcl/alpha.hxx>
35cdf0e10cSrcweir #include <vcl/bitmapex.hxx>
36cdf0e10cSrcweir #include <vcl/pngread.hxx>
37cdf0e10cSrcweir #include <vcl/svapp.hxx>
38cdf0e10cSrcweir #include <vcl/bmpacc.hxx>
3945fd3b9aSArmin Le Grand #include <vcl/dibtools.hxx>
40cdf0e10cSrcweir #include <image.h>
41cdf0e10cSrcweir #include <impimagetree.hxx>
425f27b83cSArmin Le Grand #include <basegfx/matrix/b2dhommatrixtools.hxx>
43cdf0e10cSrcweir 
44cdf0e10cSrcweir // ------------
45cdf0e10cSrcweir // - BitmapEx -
46cdf0e10cSrcweir // ------------
47cdf0e10cSrcweir 
BitmapEx()48cdf0e10cSrcweir BitmapEx::BitmapEx() :
49cdf0e10cSrcweir 		eTransparent( TRANSPARENT_NONE ),
50cdf0e10cSrcweir 		bAlpha		( sal_False )
51cdf0e10cSrcweir {
52cdf0e10cSrcweir }
53cdf0e10cSrcweir 
54cdf0e10cSrcweir // ------------------------------------------------------------------
55cdf0e10cSrcweir 
BitmapEx(const BitmapEx & rBitmapEx)56cdf0e10cSrcweir BitmapEx::BitmapEx( const BitmapEx& rBitmapEx ) :
57cdf0e10cSrcweir 		aBitmap				( rBitmapEx.aBitmap ),
58cdf0e10cSrcweir 		aMask				( rBitmapEx.aMask ),
59cdf0e10cSrcweir 		aBitmapSize			( rBitmapEx.aBitmapSize ),
60cdf0e10cSrcweir 		aTransparentColor	( rBitmapEx.aTransparentColor ),
61cdf0e10cSrcweir 		eTransparent		( rBitmapEx.eTransparent ),
62cdf0e10cSrcweir 		bAlpha				( rBitmapEx.bAlpha )
63cdf0e10cSrcweir {
64cdf0e10cSrcweir }
65cdf0e10cSrcweir 
BitmapEx(const BitmapEx & rBitmapEx,Point aSrc,Size aSize)66cdf0e10cSrcweir BitmapEx::BitmapEx( const BitmapEx& rBitmapEx, Point aSrc, Size aSize ) :
67cdf0e10cSrcweir 		eTransparent( TRANSPARENT_NONE ),
68cdf0e10cSrcweir 		bAlpha		( sal_False )
69cdf0e10cSrcweir {
70cdf0e10cSrcweir 	if( rBitmapEx.IsEmpty() )
71cdf0e10cSrcweir 		return;
72cdf0e10cSrcweir 
73cdf0e10cSrcweir 	aBitmap = Bitmap( aSize, rBitmapEx.aBitmap.GetBitCount() );
74cdf0e10cSrcweir 	aBitmapSize = aSize;
75cdf0e10cSrcweir 	if( rBitmapEx.IsAlpha() )
76cdf0e10cSrcweir 	{
77cdf0e10cSrcweir 		bAlpha = sal_True;
78cdf0e10cSrcweir 		aMask = AlphaMask( aSize ).ImplGetBitmap();
79cdf0e10cSrcweir 	}
80cdf0e10cSrcweir 	else if( rBitmapEx.IsTransparent() )
81cdf0e10cSrcweir 		aMask = Bitmap( aSize, rBitmapEx.aMask.GetBitCount() );
82*f2e5373eSmseidel 
83cdf0e10cSrcweir 	Rectangle aDestRect( Point( 0, 0 ), aSize );
84cdf0e10cSrcweir 	Rectangle aSrcRect( aSrc, aSize );
85cdf0e10cSrcweir 	CopyPixel( aDestRect, aSrcRect, &rBitmapEx );
86cdf0e10cSrcweir }
87cdf0e10cSrcweir 
88cdf0e10cSrcweir // ------------------------------------------------------------------
89cdf0e10cSrcweir 
BitmapEx(const ResId & rResId)90cdf0e10cSrcweir BitmapEx::BitmapEx( const ResId& rResId ) :
91cdf0e10cSrcweir 		eTransparent( TRANSPARENT_NONE ),
92cdf0e10cSrcweir 		bAlpha		( sal_False )
93cdf0e10cSrcweir {
94cdf0e10cSrcweir 	static ImplImageTreeSingletonRef	aImageTree;
95cdf0e10cSrcweir 	ResMgr* 							pResMgr = NULL;
96cdf0e10cSrcweir 
97cdf0e10cSrcweir 	ResMgr::GetResourceSkipHeader( rResId.SetRT( RSC_BITMAP ), &pResMgr );
98cdf0e10cSrcweir 	pResMgr->ReadLong();
99cdf0e10cSrcweir 	pResMgr->ReadLong();
100*f2e5373eSmseidel 
101cdf0e10cSrcweir 	const String aFileName( pResMgr->ReadString() );
102cdf0e10cSrcweir 	::rtl::OUString aCurrentSymbolsStyle = Application::GetSettings().GetStyleSettings().GetCurrentSymbolsStyleName();
103*f2e5373eSmseidel 
104cdf0e10cSrcweir 	if( !aImageTree->loadImage( aFileName, aCurrentSymbolsStyle, *this ) )
105cdf0e10cSrcweir 	{
106*f2e5373eSmseidel #ifdef DBG_UTIL
107cdf0e10cSrcweir 		ByteString aErrorStr( "BitmapEx::BitmapEx( const ResId& rResId ): could not load image <" );
108cdf0e10cSrcweir 		DBG_ERROR( ( ( aErrorStr += ByteString( aFileName, RTL_TEXTENCODING_ASCII_US ) ) += '>' ).GetBuffer() );
109cdf0e10cSrcweir #endif
110cdf0e10cSrcweir 	}
111cdf0e10cSrcweir }
112cdf0e10cSrcweir 
113cdf0e10cSrcweir // ------------------------------------------------------------------
114cdf0e10cSrcweir 
BitmapEx(const Bitmap & rBmp)115cdf0e10cSrcweir BitmapEx::BitmapEx( const Bitmap& rBmp ) :
116cdf0e10cSrcweir 		aBitmap		( rBmp ),
117cdf0e10cSrcweir 		aBitmapSize	( aBitmap.GetSizePixel() ),
118cdf0e10cSrcweir 		eTransparent( TRANSPARENT_NONE ),
119cdf0e10cSrcweir 		bAlpha		( sal_False )
120cdf0e10cSrcweir {
121cdf0e10cSrcweir }
122cdf0e10cSrcweir 
123cdf0e10cSrcweir // ------------------------------------------------------------------
124cdf0e10cSrcweir 
BitmapEx(const Bitmap & rBmp,const Bitmap & rMask)125cdf0e10cSrcweir BitmapEx::BitmapEx( const Bitmap& rBmp, const Bitmap& rMask ) :
126cdf0e10cSrcweir 		aBitmap			( rBmp ),
127cdf0e10cSrcweir 		aMask			( rMask ),
128cdf0e10cSrcweir 		aBitmapSize		( aBitmap.GetSizePixel() ),
129cdf0e10cSrcweir 		eTransparent	( !rMask ? TRANSPARENT_NONE : TRANSPARENT_BITMAP ),
130cdf0e10cSrcweir 		bAlpha			( sal_False )
131cdf0e10cSrcweir {
132*f2e5373eSmseidel 	if(!!aBitmap && !!aMask && aBitmap.GetSizePixel() != aMask.GetSizePixel())
133*f2e5373eSmseidel 	{
134*f2e5373eSmseidel 		OSL_ENSURE(false, "Mask size differs from Bitmap size, corrected Mask (!)");
135*f2e5373eSmseidel 		aMask.Scale(aBitmap.GetSizePixel());
136*f2e5373eSmseidel 	}
137*f2e5373eSmseidel 
138*f2e5373eSmseidel 	// #105489# Ensure a mask is exactly one bit deep
139*f2e5373eSmseidel 	if( !!aMask && aMask.GetBitCount() != 1 )
140*f2e5373eSmseidel 	{
141*f2e5373eSmseidel 		OSL_TRACE("BitmapEx: forced mask to monochrome");
142*f2e5373eSmseidel 		aMask.ImplMakeMono( 255 );
143*f2e5373eSmseidel 	}
144cdf0e10cSrcweir }
145cdf0e10cSrcweir 
146cdf0e10cSrcweir // ------------------------------------------------------------------
147cdf0e10cSrcweir 
BitmapEx(const Bitmap & rBmp,const AlphaMask & rAlphaMask)148cdf0e10cSrcweir BitmapEx::BitmapEx( const Bitmap& rBmp, const AlphaMask& rAlphaMask ) :
149cdf0e10cSrcweir 		aBitmap			( rBmp ),
150cdf0e10cSrcweir 		aMask			( rAlphaMask.ImplGetBitmap() ),
151cdf0e10cSrcweir 		aBitmapSize		( aBitmap.GetSizePixel() ),
152cdf0e10cSrcweir 		eTransparent	( !rAlphaMask ? TRANSPARENT_NONE : TRANSPARENT_BITMAP ),
153cdf0e10cSrcweir 		bAlpha			( !rAlphaMask ? sal_False : sal_True )
154cdf0e10cSrcweir {
155*f2e5373eSmseidel 	if(!!aBitmap && !!aMask && aBitmap.GetSizePixel() != aMask.GetSizePixel())
156*f2e5373eSmseidel 	{
157*f2e5373eSmseidel 		OSL_ENSURE(false, "Alpha size differs from Bitmap size, corrected Mask (!)");
158*f2e5373eSmseidel 		aMask.Scale(rBmp.GetSizePixel());
159*f2e5373eSmseidel 	}
160*f2e5373eSmseidel 
161*f2e5373eSmseidel 	// #i75531# the workaround below can go when
162*f2e5373eSmseidel 	// X11SalGraphics::drawAlphaBitmap()'s render acceleration
163*f2e5373eSmseidel 	// can handle the bitmap depth mismatch directly
164*f2e5373eSmseidel 	if( aBitmap.GetBitCount() < aMask.GetBitCount() )
165*f2e5373eSmseidel 		aBitmap.Convert( BMP_CONVERSION_24BIT );
166cdf0e10cSrcweir }
167cdf0e10cSrcweir 
168cdf0e10cSrcweir // ------------------------------------------------------------------
169cdf0e10cSrcweir 
BitmapEx(const Bitmap & rBmp,const Color & rTransparentColor)170cdf0e10cSrcweir BitmapEx::BitmapEx( const Bitmap& rBmp, const Color& rTransparentColor ) :
171cdf0e10cSrcweir 		aBitmap				( rBmp ),
172cdf0e10cSrcweir 		aBitmapSize			( aBitmap.GetSizePixel() ),
173cdf0e10cSrcweir 		aTransparentColor	( rTransparentColor ),
174cdf0e10cSrcweir 		eTransparent		( TRANSPARENT_BITMAP ),
175cdf0e10cSrcweir 		bAlpha				( sal_False )
176cdf0e10cSrcweir {
177cdf0e10cSrcweir 	aMask = aBitmap.CreateMask( aTransparentColor );
178cdf0e10cSrcweir 
179*f2e5373eSmseidel 	DBG_ASSERT( rBmp.GetSizePixel() == aMask.GetSizePixel(),
180*f2e5373eSmseidel 				"BitmapEx::BitmapEx(): size mismatch for bitmap and alpha mask." );
181cdf0e10cSrcweir }
182cdf0e10cSrcweir 
183cdf0e10cSrcweir // ------------------------------------------------------------------
184cdf0e10cSrcweir 
~BitmapEx()185cdf0e10cSrcweir BitmapEx::~BitmapEx()
186cdf0e10cSrcweir {
187cdf0e10cSrcweir }
188cdf0e10cSrcweir 
189cdf0e10cSrcweir // ------------------------------------------------------------------
190cdf0e10cSrcweir 
191cdf0e10cSrcweir // ------------------------------------------------------------------
192cdf0e10cSrcweir 
operator =(const BitmapEx & rBitmapEx)193cdf0e10cSrcweir BitmapEx& BitmapEx::operator=( const BitmapEx& rBitmapEx )
194cdf0e10cSrcweir {
195cdf0e10cSrcweir 	if( &rBitmapEx != this )
196cdf0e10cSrcweir 	{
197cdf0e10cSrcweir 		aBitmap = rBitmapEx.aBitmap;
198cdf0e10cSrcweir 		aMask = rBitmapEx.aMask;
199cdf0e10cSrcweir 		aBitmapSize = rBitmapEx.aBitmapSize;
200cdf0e10cSrcweir 		aTransparentColor = rBitmapEx.aTransparentColor;
201cdf0e10cSrcweir 		eTransparent = rBitmapEx.eTransparent;
202cdf0e10cSrcweir 		bAlpha = rBitmapEx.bAlpha;
203cdf0e10cSrcweir 	}
204cdf0e10cSrcweir 
205cdf0e10cSrcweir 	return *this;
206cdf0e10cSrcweir }
207cdf0e10cSrcweir 
208cdf0e10cSrcweir // ------------------------------------------------------------------
209cdf0e10cSrcweir 
operator ==(const BitmapEx & rBitmapEx) const210cdf0e10cSrcweir sal_Bool BitmapEx::operator==( const BitmapEx& rBitmapEx ) const
211cdf0e10cSrcweir {
212cdf0e10cSrcweir 	if( eTransparent != rBitmapEx.eTransparent )
213cdf0e10cSrcweir 		return sal_False;
214cdf0e10cSrcweir 
215cdf0e10cSrcweir 	if( aBitmap != rBitmapEx.aBitmap )
216cdf0e10cSrcweir 		return sal_False;
217cdf0e10cSrcweir 
218cdf0e10cSrcweir 	if( aBitmapSize != rBitmapEx.aBitmapSize )
219cdf0e10cSrcweir 		return sal_False;
220cdf0e10cSrcweir 
221cdf0e10cSrcweir 	if( eTransparent == TRANSPARENT_NONE )
222cdf0e10cSrcweir 		return sal_True;
223cdf0e10cSrcweir 
224cdf0e10cSrcweir 	if( eTransparent == TRANSPARENT_COLOR )
225cdf0e10cSrcweir 		return aTransparentColor == rBitmapEx.aTransparentColor;
226cdf0e10cSrcweir 
227cdf0e10cSrcweir 	return( ( aMask == rBitmapEx.aMask ) && ( bAlpha == rBitmapEx.bAlpha ) );
228cdf0e10cSrcweir }
229cdf0e10cSrcweir 
230cdf0e10cSrcweir // ------------------------------------------------------------------
231cdf0e10cSrcweir 
IsEqual(const BitmapEx & rBmpEx) const232cdf0e10cSrcweir sal_Bool BitmapEx::IsEqual( const BitmapEx& rBmpEx ) const
233cdf0e10cSrcweir {
234cdf0e10cSrcweir 	return( rBmpEx.eTransparent == eTransparent &&
235cdf0e10cSrcweir 			rBmpEx.bAlpha == bAlpha &&
236cdf0e10cSrcweir 			rBmpEx.aBitmap.IsEqual( aBitmap ) &&
237cdf0e10cSrcweir 			rBmpEx.aMask.IsEqual( aMask ) );
238cdf0e10cSrcweir }
239cdf0e10cSrcweir 
240cdf0e10cSrcweir // ------------------------------------------------------------------
241cdf0e10cSrcweir 
IsEmpty() const242cdf0e10cSrcweir sal_Bool BitmapEx::IsEmpty() const
243cdf0e10cSrcweir {
244cdf0e10cSrcweir 	return( aBitmap.IsEmpty() && aMask.IsEmpty() );
245cdf0e10cSrcweir }
246cdf0e10cSrcweir 
247cdf0e10cSrcweir // ------------------------------------------------------------------
248cdf0e10cSrcweir 
SetEmpty()249cdf0e10cSrcweir void BitmapEx::SetEmpty()
250cdf0e10cSrcweir {
251cdf0e10cSrcweir 	aBitmap.SetEmpty();
252cdf0e10cSrcweir 	aMask.SetEmpty();
253cdf0e10cSrcweir 	eTransparent = TRANSPARENT_NONE;
254cdf0e10cSrcweir 	bAlpha = sal_False;
255cdf0e10cSrcweir }
256cdf0e10cSrcweir 
257cdf0e10cSrcweir // ------------------------------------------------------------------
258cdf0e10cSrcweir 
Clear()259cdf0e10cSrcweir void BitmapEx::Clear()
260cdf0e10cSrcweir {
261cdf0e10cSrcweir 	SetEmpty();
262cdf0e10cSrcweir }
263cdf0e10cSrcweir 
264cdf0e10cSrcweir // ------------------------------------------------------------------
265cdf0e10cSrcweir 
IsTransparent() const266cdf0e10cSrcweir sal_Bool BitmapEx::IsTransparent() const
267cdf0e10cSrcweir {
268cdf0e10cSrcweir 	return( eTransparent != TRANSPARENT_NONE );
269cdf0e10cSrcweir }
270cdf0e10cSrcweir 
271cdf0e10cSrcweir // ------------------------------------------------------------------
272cdf0e10cSrcweir 
IsAlpha() const273cdf0e10cSrcweir sal_Bool BitmapEx::IsAlpha() const
274cdf0e10cSrcweir {
275cdf0e10cSrcweir 	return( IsTransparent() && bAlpha );
276cdf0e10cSrcweir }
277cdf0e10cSrcweir 
278cdf0e10cSrcweir // ------------------------------------------------------------------
279cdf0e10cSrcweir 
GetBitmap(const Color * pTransReplaceColor) const280cdf0e10cSrcweir Bitmap BitmapEx::GetBitmap( const Color* pTransReplaceColor ) const
281cdf0e10cSrcweir {
282cdf0e10cSrcweir 	Bitmap aRetBmp( aBitmap );
283cdf0e10cSrcweir 
284cdf0e10cSrcweir 	if( pTransReplaceColor && ( eTransparent != TRANSPARENT_NONE ) )
285cdf0e10cSrcweir 	{
286cdf0e10cSrcweir 		Bitmap aTempMask;
287cdf0e10cSrcweir 
288cdf0e10cSrcweir 		if( eTransparent == TRANSPARENT_COLOR )
289cdf0e10cSrcweir 			aTempMask = aBitmap.CreateMask( aTransparentColor );
290cdf0e10cSrcweir 		else
291cdf0e10cSrcweir 			aTempMask = aMask;
292cdf0e10cSrcweir 
293cdf0e10cSrcweir 		if( !IsAlpha() )
294cdf0e10cSrcweir 			aRetBmp.Replace( aTempMask, *pTransReplaceColor );
295cdf0e10cSrcweir 		else
296cdf0e10cSrcweir 			aRetBmp.Replace( GetAlpha(), *pTransReplaceColor );
297cdf0e10cSrcweir 	}
298cdf0e10cSrcweir 
299cdf0e10cSrcweir 	return aRetBmp;
300cdf0e10cSrcweir }
301cdf0e10cSrcweir 
302cdf0e10cSrcweir // ------------------------------------------------------------------
303cdf0e10cSrcweir 
GetColorTransformedBitmapEx(BmpColorMode eColorMode) const304cdf0e10cSrcweir BitmapEx BitmapEx::GetColorTransformedBitmapEx( BmpColorMode eColorMode ) const
305cdf0e10cSrcweir {
306cdf0e10cSrcweir 	BitmapEx aRet;
307*f2e5373eSmseidel 
308cdf0e10cSrcweir 	if( BMP_COLOR_HIGHCONTRAST == eColorMode )
309cdf0e10cSrcweir 	{
310cdf0e10cSrcweir 		aRet = *this;
311cdf0e10cSrcweir 		aRet.aBitmap = aBitmap.GetColorTransformedBitmap( eColorMode );
312cdf0e10cSrcweir 	}
313cdf0e10cSrcweir 	else if( BMP_COLOR_MONOCHROME_BLACK == eColorMode ||
314cdf0e10cSrcweir 			 BMP_COLOR_MONOCHROME_WHITE == eColorMode )
315cdf0e10cSrcweir 	{
316cdf0e10cSrcweir 		aRet = *this;
317cdf0e10cSrcweir 		aRet.aBitmap = aRet.aBitmap.GetColorTransformedBitmap( eColorMode );
318*f2e5373eSmseidel 
319cdf0e10cSrcweir 		if( !aRet.aMask.IsEmpty() )
320cdf0e10cSrcweir 		{
321cdf0e10cSrcweir 			aRet.aMask.CombineSimple( aRet.aBitmap, BMP_COMBINE_OR );
322cdf0e10cSrcweir 			aRet.aBitmap.Erase( ( BMP_COLOR_MONOCHROME_BLACK == eColorMode ) ? COL_BLACK : COL_WHITE );
323cdf0e10cSrcweir 
324*f2e5373eSmseidel 			DBG_ASSERT( aRet.aBitmap.GetSizePixel() == aRet.aMask.GetSizePixel(),
325*f2e5373eSmseidel 						"BitmapEx::GetColorTransformedBitmapEx(): size mismatch for bitmap and alpha mask." );
326cdf0e10cSrcweir 		}
327cdf0e10cSrcweir 	}
328cdf0e10cSrcweir 
329cdf0e10cSrcweir 	return aRet;
330cdf0e10cSrcweir }
331cdf0e10cSrcweir 
332cdf0e10cSrcweir // ------------------------------------------------------------------
333cdf0e10cSrcweir 
GetMask() const334cdf0e10cSrcweir Bitmap BitmapEx::GetMask() const
335cdf0e10cSrcweir {
336cdf0e10cSrcweir 	Bitmap aRet( aMask );
337cdf0e10cSrcweir 
338cdf0e10cSrcweir 	if( IsAlpha() )
339cdf0e10cSrcweir 		aRet.ImplMakeMono( 255 );
340cdf0e10cSrcweir 
341cdf0e10cSrcweir 	return aRet;
342cdf0e10cSrcweir }
343cdf0e10cSrcweir 
344cdf0e10cSrcweir // ------------------------------------------------------------------
345cdf0e10cSrcweir 
GetAlpha() const346cdf0e10cSrcweir AlphaMask BitmapEx::GetAlpha() const
347cdf0e10cSrcweir {
348cdf0e10cSrcweir 	AlphaMask aAlpha;
349cdf0e10cSrcweir 
350cdf0e10cSrcweir 	if( IsAlpha() )
351cdf0e10cSrcweir 		aAlpha.ImplSetBitmap( aMask );
352cdf0e10cSrcweir 	else
353cdf0e10cSrcweir 		aAlpha = aMask;
354cdf0e10cSrcweir 
355cdf0e10cSrcweir 	return aAlpha;
356cdf0e10cSrcweir }
357cdf0e10cSrcweir 
358cdf0e10cSrcweir // ------------------------------------------------------------------
359cdf0e10cSrcweir 
GetSizeBytes() const360cdf0e10cSrcweir sal_uLong BitmapEx::GetSizeBytes() const
361cdf0e10cSrcweir {
362cdf0e10cSrcweir 	sal_uLong nSizeBytes = aBitmap.GetSizeBytes();
363cdf0e10cSrcweir 
364cdf0e10cSrcweir 	if( eTransparent == TRANSPARENT_BITMAP )
365cdf0e10cSrcweir 		nSizeBytes += aMask.GetSizeBytes();
366cdf0e10cSrcweir 
367cdf0e10cSrcweir 	return nSizeBytes;
368cdf0e10cSrcweir }
369cdf0e10cSrcweir 
370cdf0e10cSrcweir // ------------------------------------------------------------------
371cdf0e10cSrcweir 
GetChecksum() const372cdf0e10cSrcweir sal_uLong BitmapEx::GetChecksum() const
373cdf0e10cSrcweir {
374cdf0e10cSrcweir 	sal_uInt32	nCrc = aBitmap.GetChecksum();
375cdf0e10cSrcweir 	SVBT32		aBT32;
376cdf0e10cSrcweir 
377cdf0e10cSrcweir 	UInt32ToSVBT32( (long) eTransparent, aBT32 );
378cdf0e10cSrcweir 	nCrc = rtl_crc32( nCrc, aBT32, 4 );
379cdf0e10cSrcweir 
380cdf0e10cSrcweir 	UInt32ToSVBT32( (long) bAlpha, aBT32 );
381cdf0e10cSrcweir 	nCrc = rtl_crc32( nCrc, aBT32, 4 );
382cdf0e10cSrcweir 
383cdf0e10cSrcweir 	if( ( TRANSPARENT_BITMAP == eTransparent ) && !aMask.IsEmpty() )
384cdf0e10cSrcweir 	{
385cdf0e10cSrcweir 		UInt32ToSVBT32( aMask.GetChecksum(), aBT32 );
386cdf0e10cSrcweir 		nCrc = rtl_crc32( nCrc, aBT32, 4 );
387cdf0e10cSrcweir 	}
388cdf0e10cSrcweir 
389cdf0e10cSrcweir 	return nCrc;
390cdf0e10cSrcweir }
391cdf0e10cSrcweir 
392cdf0e10cSrcweir // ------------------------------------------------------------------
393cdf0e10cSrcweir 
SetSizePixel(const Size & rNewSize,sal_uInt32 nScaleFlag)39454628ca4SArmin Le Grand void BitmapEx::SetSizePixel( const Size& rNewSize, sal_uInt32 nScaleFlag )
395cdf0e10cSrcweir {
396*f2e5373eSmseidel 	if(GetSizePixel() != rNewSize)
397*f2e5373eSmseidel 	{
398*f2e5373eSmseidel 		Scale( rNewSize, nScaleFlag );
399*f2e5373eSmseidel 	}
400cdf0e10cSrcweir }
401cdf0e10cSrcweir 
402cdf0e10cSrcweir // ------------------------------------------------------------------
403cdf0e10cSrcweir 
Invert()404cdf0e10cSrcweir sal_Bool BitmapEx::Invert()
405cdf0e10cSrcweir {
406cdf0e10cSrcweir 	sal_Bool bRet = sal_False;
407cdf0e10cSrcweir 
408cdf0e10cSrcweir 	if( !!aBitmap )
409cdf0e10cSrcweir 	{
410cdf0e10cSrcweir 		bRet = aBitmap.Invert();
411cdf0e10cSrcweir 
412cdf0e10cSrcweir 		if( bRet && ( eTransparent == TRANSPARENT_COLOR ) )
413cdf0e10cSrcweir 			aTransparentColor = BitmapColor( aTransparentColor ).Invert();
414cdf0e10cSrcweir 	}
415cdf0e10cSrcweir 
416cdf0e10cSrcweir 	return bRet;
417cdf0e10cSrcweir }
418cdf0e10cSrcweir 
419cdf0e10cSrcweir // ------------------------------------------------------------------
420cdf0e10cSrcweir 
Mirror(sal_uLong nMirrorFlags)421cdf0e10cSrcweir sal_Bool BitmapEx::Mirror( sal_uLong nMirrorFlags )
422cdf0e10cSrcweir {
423cdf0e10cSrcweir 	sal_Bool bRet = sal_False;
424cdf0e10cSrcweir 
425cdf0e10cSrcweir 	if( !!aBitmap )
426cdf0e10cSrcweir 	{
427cdf0e10cSrcweir 		bRet = aBitmap.Mirror( nMirrorFlags );
428cdf0e10cSrcweir 
429cdf0e10cSrcweir 		if( bRet && ( eTransparent == TRANSPARENT_BITMAP ) && !!aMask )
430cdf0e10cSrcweir 			aMask.Mirror( nMirrorFlags );
431cdf0e10cSrcweir 	}
432cdf0e10cSrcweir 
433cdf0e10cSrcweir 	return bRet;
434cdf0e10cSrcweir }
435cdf0e10cSrcweir 
436cdf0e10cSrcweir // ------------------------------------------------------------------
437cdf0e10cSrcweir 
Scale(const double & rScaleX,const double & rScaleY,sal_uInt32 nScaleFlag)43854628ca4SArmin Le Grand sal_Bool BitmapEx::Scale( const double& rScaleX, const double& rScaleY, sal_uInt32 nScaleFlag )
439cdf0e10cSrcweir {
440cdf0e10cSrcweir 	sal_Bool bRet = sal_False;
441cdf0e10cSrcweir 
442cdf0e10cSrcweir 	if( !!aBitmap )
443cdf0e10cSrcweir 	{
444cdf0e10cSrcweir 		bRet = aBitmap.Scale( rScaleX, rScaleY, nScaleFlag );
445cdf0e10cSrcweir 
446cdf0e10cSrcweir 		if( bRet && ( eTransparent == TRANSPARENT_BITMAP ) && !!aMask )
447*f2e5373eSmseidel 		{
44837ab0f2dSArmin Le Grand 			aMask.Scale( rScaleX, rScaleY, nScaleFlag );
449*f2e5373eSmseidel 		}
450cdf0e10cSrcweir 
451cdf0e10cSrcweir 		aBitmapSize = aBitmap.GetSizePixel();
452cdf0e10cSrcweir 
453*f2e5373eSmseidel 		DBG_ASSERT( !aMask || aBitmap.GetSizePixel() == aMask.GetSizePixel(),
454*f2e5373eSmseidel 					"BitmapEx::Scale(): size mismatch for bitmap and alpha mask." );
455cdf0e10cSrcweir 	}
456cdf0e10cSrcweir 
457cdf0e10cSrcweir 	return bRet;
458cdf0e10cSrcweir }
459cdf0e10cSrcweir 
460cdf0e10cSrcweir // ------------------------------------------------------------------------
461cdf0e10cSrcweir 
Scale(const Size & rNewSize,sal_uInt32 nScaleFlag)46254628ca4SArmin Le Grand sal_Bool BitmapEx::Scale( const Size& rNewSize, sal_uInt32 nScaleFlag )
463cdf0e10cSrcweir {
464cdf0e10cSrcweir 	sal_Bool bRet;
465cdf0e10cSrcweir 
466cdf0e10cSrcweir 	if( aBitmapSize.Width() && aBitmapSize.Height() )
467cdf0e10cSrcweir 	{
468cdf0e10cSrcweir 		bRet = Scale( (double) rNewSize.Width() / aBitmapSize.Width(),
469cdf0e10cSrcweir 					  (double) rNewSize.Height() / aBitmapSize.Height(),
470cdf0e10cSrcweir 					  nScaleFlag );
471cdf0e10cSrcweir 	}
472cdf0e10cSrcweir 	else
473cdf0e10cSrcweir 		bRet = sal_True;
474cdf0e10cSrcweir 
475cdf0e10cSrcweir 	return bRet;
476cdf0e10cSrcweir }
477cdf0e10cSrcweir 
478cdf0e10cSrcweir // ------------------------------------------------------------------
479cdf0e10cSrcweir 
Rotate(long nAngle10,const Color & rFillColor)480cdf0e10cSrcweir sal_Bool BitmapEx::Rotate( long nAngle10, const Color& rFillColor )
481cdf0e10cSrcweir {
482cdf0e10cSrcweir 	sal_Bool bRet = sal_False;
483cdf0e10cSrcweir 
484cdf0e10cSrcweir 	if( !!aBitmap )
485cdf0e10cSrcweir 	{
486cdf0e10cSrcweir 		const sal_Bool bTransRotate = ( Color( COL_TRANSPARENT ) == rFillColor );
487cdf0e10cSrcweir 
488cdf0e10cSrcweir 		if( bTransRotate )
489cdf0e10cSrcweir 		{
490cdf0e10cSrcweir 			if( eTransparent == TRANSPARENT_COLOR )
491cdf0e10cSrcweir 				bRet = aBitmap.Rotate( nAngle10, aTransparentColor );
492cdf0e10cSrcweir 			else
493cdf0e10cSrcweir 			{
494cdf0e10cSrcweir 				bRet = aBitmap.Rotate( nAngle10, COL_BLACK );
495cdf0e10cSrcweir 
496cdf0e10cSrcweir 				if( eTransparent == TRANSPARENT_NONE )
497cdf0e10cSrcweir 				{
498cdf0e10cSrcweir 					aMask = Bitmap( aBitmapSize, 1 );
499cdf0e10cSrcweir 					aMask.Erase( COL_BLACK );
500cdf0e10cSrcweir 					eTransparent = TRANSPARENT_BITMAP;
501cdf0e10cSrcweir 				}
502cdf0e10cSrcweir 
503cdf0e10cSrcweir 				if( bRet && !!aMask )
504cdf0e10cSrcweir 					aMask.Rotate( nAngle10, COL_WHITE );
505cdf0e10cSrcweir 			}
506cdf0e10cSrcweir 		}
507cdf0e10cSrcweir 		else
508cdf0e10cSrcweir 		{
509cdf0e10cSrcweir 			bRet = aBitmap.Rotate( nAngle10, rFillColor );
510cdf0e10cSrcweir 
511cdf0e10cSrcweir 			if( bRet && ( eTransparent == TRANSPARENT_BITMAP ) && !!aMask )
512cdf0e10cSrcweir 				aMask.Rotate( nAngle10, COL_WHITE );
513cdf0e10cSrcweir 		}
514cdf0e10cSrcweir 
515cdf0e10cSrcweir 		aBitmapSize = aBitmap.GetSizePixel();
516cdf0e10cSrcweir 
517*f2e5373eSmseidel 		DBG_ASSERT( !aMask || aBitmap.GetSizePixel() == aMask.GetSizePixel(),
518*f2e5373eSmseidel 					"BitmapEx::Rotate(): size mismatch for bitmap and alpha mask." );
519cdf0e10cSrcweir 	}
520cdf0e10cSrcweir 
521cdf0e10cSrcweir 	return bRet;
522cdf0e10cSrcweir }
523cdf0e10cSrcweir 
524cdf0e10cSrcweir // ------------------------------------------------------------------
525cdf0e10cSrcweir 
Crop(const Rectangle & rRectPixel)526cdf0e10cSrcweir sal_Bool BitmapEx::Crop( const Rectangle& rRectPixel )
527cdf0e10cSrcweir {
528cdf0e10cSrcweir 	sal_Bool bRet = sal_False;
529cdf0e10cSrcweir 
530cdf0e10cSrcweir 	if( !!aBitmap )
531cdf0e10cSrcweir 	{
532cdf0e10cSrcweir 		bRet = aBitmap.Crop( rRectPixel );
533cdf0e10cSrcweir 
534cdf0e10cSrcweir 		if( bRet && ( eTransparent == TRANSPARENT_BITMAP ) && !!aMask )
535cdf0e10cSrcweir 			aMask.Crop( rRectPixel );
536cdf0e10cSrcweir 
537cdf0e10cSrcweir 		aBitmapSize = aBitmap.GetSizePixel();
538cdf0e10cSrcweir 
539*f2e5373eSmseidel 		DBG_ASSERT( !aMask || aBitmap.GetSizePixel() == aMask.GetSizePixel(),
540*f2e5373eSmseidel 					"BitmapEx::Crop(): size mismatch for bitmap and alpha mask." );
541cdf0e10cSrcweir 	}
542cdf0e10cSrcweir 
543cdf0e10cSrcweir 	return bRet;
544cdf0e10cSrcweir }
545cdf0e10cSrcweir 
546cdf0e10cSrcweir // ------------------------------------------------------------------
547cdf0e10cSrcweir 
Convert(BmpConversion eConversion)548cdf0e10cSrcweir sal_Bool BitmapEx::Convert( BmpConversion eConversion )
549cdf0e10cSrcweir {
550cdf0e10cSrcweir 	return( !!aBitmap ? aBitmap.Convert( eConversion ) : sal_False );
551cdf0e10cSrcweir }
552cdf0e10cSrcweir 
553cdf0e10cSrcweir // ------------------------------------------------------------------
554cdf0e10cSrcweir 
ReduceColors(sal_uInt16 nNewColorCount,BmpReduce eReduce)555cdf0e10cSrcweir sal_Bool BitmapEx::ReduceColors( sal_uInt16 nNewColorCount, BmpReduce eReduce )
556cdf0e10cSrcweir {
557cdf0e10cSrcweir 	return( !!aBitmap ? aBitmap.ReduceColors( nNewColorCount, eReduce ) : sal_False );
558cdf0e10cSrcweir }
559cdf0e10cSrcweir 
560cdf0e10cSrcweir // ------------------------------------------------------------------
561cdf0e10cSrcweir 
Expand(sal_uLong nDX,sal_uLong nDY,const Color * pInitColor,sal_Bool bExpandTransparent)562cdf0e10cSrcweir sal_Bool BitmapEx::Expand( sal_uLong nDX, sal_uLong nDY, const Color* pInitColor, sal_Bool bExpandTransparent )
563cdf0e10cSrcweir {
564cdf0e10cSrcweir 	sal_Bool bRet = sal_False;
565cdf0e10cSrcweir 
566cdf0e10cSrcweir 	if( !!aBitmap )
567cdf0e10cSrcweir 	{
568cdf0e10cSrcweir 		bRet = aBitmap.Expand( nDX, nDY, pInitColor );
569cdf0e10cSrcweir 
570cdf0e10cSrcweir 		if( bRet && ( eTransparent == TRANSPARENT_BITMAP ) && !!aMask )
571cdf0e10cSrcweir 		{
572cdf0e10cSrcweir 			Color aColor( bExpandTransparent ? COL_WHITE : COL_BLACK );
573cdf0e10cSrcweir 			aMask.Expand( nDX, nDY, &aColor );
574cdf0e10cSrcweir 		}
575cdf0e10cSrcweir 
576cdf0e10cSrcweir 		aBitmapSize = aBitmap.GetSizePixel();
577cdf0e10cSrcweir 
578*f2e5373eSmseidel 		DBG_ASSERT( !aMask || aBitmap.GetSizePixel() == aMask.GetSizePixel(),
579*f2e5373eSmseidel 					"BitmapEx::Expand(): size mismatch for bitmap and alpha mask." );
580cdf0e10cSrcweir 	}
581cdf0e10cSrcweir 
582cdf0e10cSrcweir 	return bRet;
583cdf0e10cSrcweir }
584cdf0e10cSrcweir 
585cdf0e10cSrcweir // ------------------------------------------------------------------
586cdf0e10cSrcweir 
CopyPixel(const Rectangle & rRectDst,const Rectangle & rRectSrc,const BitmapEx * pBmpExSrc)587cdf0e10cSrcweir sal_Bool BitmapEx::CopyPixel( const Rectangle& rRectDst, const Rectangle& rRectSrc,
588cdf0e10cSrcweir 						  const BitmapEx* pBmpExSrc )
589cdf0e10cSrcweir {
590cdf0e10cSrcweir 	sal_Bool bRet = sal_False;
591cdf0e10cSrcweir 
592cdf0e10cSrcweir 	if( !pBmpExSrc || pBmpExSrc->IsEmpty() )
593cdf0e10cSrcweir 	{
594cdf0e10cSrcweir 		if( !aBitmap.IsEmpty() )
595cdf0e10cSrcweir 		{
596cdf0e10cSrcweir 			bRet = aBitmap.CopyPixel( rRectDst, rRectSrc );
597cdf0e10cSrcweir 
598cdf0e10cSrcweir 			if( bRet && ( eTransparent == TRANSPARENT_BITMAP ) && !!aMask )
599cdf0e10cSrcweir 				aMask.CopyPixel( rRectDst, rRectSrc );
600cdf0e10cSrcweir 		}
601cdf0e10cSrcweir 	}
602cdf0e10cSrcweir 	else
603cdf0e10cSrcweir 	{
604cdf0e10cSrcweir 		if( !aBitmap.IsEmpty() )
605cdf0e10cSrcweir 		{
606cdf0e10cSrcweir 			bRet = aBitmap.CopyPixel( rRectDst, rRectSrc, &pBmpExSrc->aBitmap );
607cdf0e10cSrcweir 
608cdf0e10cSrcweir 			if( bRet )
609cdf0e10cSrcweir 			{
610cdf0e10cSrcweir 				if( pBmpExSrc->IsAlpha() )
611cdf0e10cSrcweir 				{
612cdf0e10cSrcweir 					if( IsAlpha() )
613*f2e5373eSmseidel 						// cast to use the optimized AlphaMask::CopyPixel
614cdf0e10cSrcweir 						((AlphaMask*) &aMask)->CopyPixel( rRectDst, rRectSrc, (AlphaMask*)&pBmpExSrc->aMask );
615cdf0e10cSrcweir 					else if( IsTransparent() )
616cdf0e10cSrcweir 					{
617cdf0e10cSrcweir 						AlphaMask* pAlpha = new AlphaMask( aMask );
618cdf0e10cSrcweir 
619cdf0e10cSrcweir 						aMask = pAlpha->ImplGetBitmap();
620cdf0e10cSrcweir 						delete pAlpha;
621cdf0e10cSrcweir 						bAlpha = sal_True;
622cdf0e10cSrcweir 						aMask.CopyPixel( rRectDst, rRectSrc, &pBmpExSrc->aMask );
623cdf0e10cSrcweir 					}
624cdf0e10cSrcweir 					else
625cdf0e10cSrcweir 					{
626cdf0e10cSrcweir 						sal_uInt8	cBlack = 0;
627cdf0e10cSrcweir 						AlphaMask*	pAlpha = new AlphaMask( GetSizePixel(), &cBlack );
628cdf0e10cSrcweir 
629cdf0e10cSrcweir 						aMask = pAlpha->ImplGetBitmap();
630cdf0e10cSrcweir 						delete pAlpha;
631cdf0e10cSrcweir 						eTransparent = TRANSPARENT_BITMAP;
632cdf0e10cSrcweir 						bAlpha = sal_True;
633cdf0e10cSrcweir 						aMask.CopyPixel( rRectDst, rRectSrc, &pBmpExSrc->aMask );
634cdf0e10cSrcweir 					}
635cdf0e10cSrcweir 				}
636cdf0e10cSrcweir 				else if( pBmpExSrc->IsTransparent() )
637cdf0e10cSrcweir 				{
638cdf0e10cSrcweir 					if( IsAlpha() )
639cdf0e10cSrcweir 					{
640cdf0e10cSrcweir 						AlphaMask aAlpha( pBmpExSrc->aMask );
641cdf0e10cSrcweir 						aMask.CopyPixel( rRectDst, rRectSrc, &aAlpha.ImplGetBitmap() );
642cdf0e10cSrcweir 					}
643cdf0e10cSrcweir 					else if( IsTransparent() )
644cdf0e10cSrcweir 						aMask.CopyPixel( rRectDst, rRectSrc, &pBmpExSrc->aMask );
645cdf0e10cSrcweir 					else
646cdf0e10cSrcweir 					{
647cdf0e10cSrcweir 						aMask = Bitmap( GetSizePixel(), 1 );
648cdf0e10cSrcweir 						aMask.Erase( Color( COL_BLACK ) );
649cdf0e10cSrcweir 						eTransparent = TRANSPARENT_BITMAP;
650cdf0e10cSrcweir 						aMask.CopyPixel( rRectDst, rRectSrc, &pBmpExSrc->aMask );
651cdf0e10cSrcweir 					}
652cdf0e10cSrcweir 				}
653*f2e5373eSmseidel 				else if( IsAlpha() )
654*f2e5373eSmseidel 				{
655*f2e5373eSmseidel 					sal_uInt8			cBlack = 0;
656*f2e5373eSmseidel 					const AlphaMask		aAlphaSrc( pBmpExSrc->GetSizePixel(), &cBlack );
657*f2e5373eSmseidel 
658*f2e5373eSmseidel 					aMask.CopyPixel( rRectDst, rRectSrc, &aAlphaSrc.ImplGetBitmap() );
659*f2e5373eSmseidel 				}
660*f2e5373eSmseidel 				else if( IsTransparent() )
661*f2e5373eSmseidel 				{
662*f2e5373eSmseidel 					Bitmap aMaskSrc( pBmpExSrc->GetSizePixel(), 1 );
663*f2e5373eSmseidel 
664*f2e5373eSmseidel 					aMaskSrc.Erase( Color( COL_BLACK ) );
665*f2e5373eSmseidel 					aMask.CopyPixel( rRectDst, rRectSrc, &aMaskSrc );
666*f2e5373eSmseidel 				}
667cdf0e10cSrcweir 			}
668cdf0e10cSrcweir 		}
669cdf0e10cSrcweir 	}
670cdf0e10cSrcweir 
671cdf0e10cSrcweir 	return bRet;
672cdf0e10cSrcweir }
673cdf0e10cSrcweir 
674cdf0e10cSrcweir // ------------------------------------------------------------------
675cdf0e10cSrcweir 
Erase(const Color & rFillColor)676cdf0e10cSrcweir sal_Bool BitmapEx::Erase( const Color& rFillColor )
677cdf0e10cSrcweir {
678cdf0e10cSrcweir 	sal_Bool bRet = sal_False;
679cdf0e10cSrcweir 
680cdf0e10cSrcweir 	if( !!aBitmap )
681cdf0e10cSrcweir 	{
682cdf0e10cSrcweir 		bRet = aBitmap.Erase( rFillColor );
683cdf0e10cSrcweir 
684cdf0e10cSrcweir 		if( bRet && ( eTransparent == TRANSPARENT_BITMAP ) && !!aMask )
685cdf0e10cSrcweir 		{
686*f2e5373eSmseidel 			// #104416# Respect transparency on fill color
687*f2e5373eSmseidel 			if( rFillColor.GetTransparency() )
688*f2e5373eSmseidel 			{
689*f2e5373eSmseidel 				const Color aFill( rFillColor.GetTransparency(), rFillColor.GetTransparency(), rFillColor.GetTransparency() );
690*f2e5373eSmseidel 				aMask.Erase( aFill );
691*f2e5373eSmseidel 			}
692*f2e5373eSmseidel 			else
693*f2e5373eSmseidel 			{
694*f2e5373eSmseidel 				const Color aBlack( COL_BLACK );
695*f2e5373eSmseidel 				aMask.Erase( aBlack );
696*f2e5373eSmseidel 			}
697cdf0e10cSrcweir 		}
698cdf0e10cSrcweir 	}
699cdf0e10cSrcweir 
700cdf0e10cSrcweir 	return bRet;
701cdf0e10cSrcweir }
702cdf0e10cSrcweir 
703cdf0e10cSrcweir // ------------------------------------------------------------------
704cdf0e10cSrcweir 
Dither(sal_uLong nDitherFlags)705cdf0e10cSrcweir sal_Bool BitmapEx::Dither( sal_uLong nDitherFlags )
706cdf0e10cSrcweir {
707cdf0e10cSrcweir 	return( !!aBitmap ? aBitmap.Dither( nDitherFlags ) : sal_False );
708cdf0e10cSrcweir }
709cdf0e10cSrcweir 
710cdf0e10cSrcweir // ------------------------------------------------------------------
711cdf0e10cSrcweir 
Replace(const Color & rSearchColor,const Color & rReplaceColor,sal_uLong nTol)712cdf0e10cSrcweir sal_Bool BitmapEx::Replace( const Color& rSearchColor, const Color& rReplaceColor, sal_uLong nTol )
713cdf0e10cSrcweir {
714cdf0e10cSrcweir 	return( !!aBitmap ? aBitmap.Replace( rSearchColor, rReplaceColor, nTol ) : sal_False );
715cdf0e10cSrcweir }
716cdf0e10cSrcweir 
717cdf0e10cSrcweir // ------------------------------------------------------------------
718cdf0e10cSrcweir 
Replace(const Color * pSearchColors,const Color * pReplaceColors,sal_uLong nColorCount,const sal_uLong * pTols)719cdf0e10cSrcweir sal_Bool BitmapEx::Replace( const Color* pSearchColors, const Color* pReplaceColors, sal_uLong nColorCount, const sal_uLong* pTols )
720cdf0e10cSrcweir {
721cdf0e10cSrcweir 	return( !!aBitmap ? aBitmap.Replace( pSearchColors, pReplaceColors, nColorCount, (sal_uLong*) pTols ) : sal_False );
722cdf0e10cSrcweir }
723cdf0e10cSrcweir 
724cdf0e10cSrcweir // ------------------------------------------------------------------
725cdf0e10cSrcweir 
Adjust(short nLuminancePercent,short nContrastPercent,short nChannelRPercent,short nChannelGPercent,short nChannelBPercent,double fGamma,sal_Bool bInvert)726cdf0e10cSrcweir sal_Bool BitmapEx::Adjust( short nLuminancePercent, short nContrastPercent,
727cdf0e10cSrcweir 					   short nChannelRPercent, short nChannelGPercent, short nChannelBPercent,
728cdf0e10cSrcweir 					   double fGamma, sal_Bool bInvert )
729cdf0e10cSrcweir {
730cdf0e10cSrcweir 	return( !!aBitmap ? aBitmap.Adjust( nLuminancePercent, nContrastPercent,
731cdf0e10cSrcweir 										nChannelRPercent, nChannelGPercent, nChannelBPercent,
732cdf0e10cSrcweir 										fGamma, bInvert ) : sal_False );
733cdf0e10cSrcweir }
734cdf0e10cSrcweir 
735cdf0e10cSrcweir // ------------------------------------------------------------------
736cdf0e10cSrcweir 
Filter(BmpFilter eFilter,const BmpFilterParam * pFilterParam,const Link * pProgress)737cdf0e10cSrcweir sal_Bool BitmapEx::Filter( BmpFilter eFilter, const BmpFilterParam* pFilterParam, const Link* pProgress )
738cdf0e10cSrcweir {
739cdf0e10cSrcweir 	return( !!aBitmap ? aBitmap.Filter( eFilter, pFilterParam, pProgress ) : sal_False );
740cdf0e10cSrcweir }
741cdf0e10cSrcweir 
742cdf0e10cSrcweir // ------------------------------------------------------------------
743cdf0e10cSrcweir 
Draw(OutputDevice * pOutDev,const Point & rDestPt) const744cdf0e10cSrcweir void BitmapEx::Draw( OutputDevice* pOutDev, const Point& rDestPt ) const
745cdf0e10cSrcweir {
746cdf0e10cSrcweir 	pOutDev->DrawBitmapEx( rDestPt, *this );
747cdf0e10cSrcweir }
748cdf0e10cSrcweir 
749cdf0e10cSrcweir // ------------------------------------------------------------------
750cdf0e10cSrcweir 
Draw(OutputDevice * pOutDev,const Point & rDestPt,const Size & rDestSize) const751cdf0e10cSrcweir void BitmapEx::Draw( OutputDevice* pOutDev,
752cdf0e10cSrcweir 					 const Point& rDestPt, const Size& rDestSize ) const
753cdf0e10cSrcweir {
754cdf0e10cSrcweir 	pOutDev->DrawBitmapEx( rDestPt, rDestSize, *this );
755cdf0e10cSrcweir }
756cdf0e10cSrcweir 
757cdf0e10cSrcweir // ------------------------------------------------------------------
758cdf0e10cSrcweir 
Draw(OutputDevice * pOutDev,const Point & rDestPt,const Size & rDestSize,const Point & rSrcPtPixel,const Size & rSrcSizePixel) const759cdf0e10cSrcweir void BitmapEx::Draw( OutputDevice* pOutDev,
760cdf0e10cSrcweir 					 const Point& rDestPt, const Size& rDestSize,
761cdf0e10cSrcweir 					 const Point& rSrcPtPixel, const Size& rSrcSizePixel ) const
762cdf0e10cSrcweir {
763cdf0e10cSrcweir 	pOutDev->DrawBitmapEx( rDestPt, rDestSize, rSrcPtPixel, rSrcSizePixel, *this );
764cdf0e10cSrcweir }
765cdf0e10cSrcweir 
766cdf0e10cSrcweir // ------------------------------------------------------------------
767cdf0e10cSrcweir 
GetTransparency(sal_Int32 nX,sal_Int32 nY) const768cdf0e10cSrcweir sal_uInt8 BitmapEx::GetTransparency(sal_Int32 nX, sal_Int32 nY) const
769cdf0e10cSrcweir {
770*f2e5373eSmseidel 	sal_uInt8 nTransparency(0xff);
771*f2e5373eSmseidel 
772*f2e5373eSmseidel 	if(!aBitmap.IsEmpty())
773*f2e5373eSmseidel 	{
774*f2e5373eSmseidel 		if(nX >= 0 && nX < aBitmapSize.Width() && nY >= 0 && nY < aBitmapSize.Height())
775*f2e5373eSmseidel 		{
776*f2e5373eSmseidel 			switch(eTransparent)
777*f2e5373eSmseidel 			{
778*f2e5373eSmseidel 				case TRANSPARENT_NONE:
779*f2e5373eSmseidel 				{
780*f2e5373eSmseidel 					// not transparent, ergo all covered
781*f2e5373eSmseidel 					nTransparency = 0x00;
782*f2e5373eSmseidel 					break;
783*f2e5373eSmseidel 				}
784*f2e5373eSmseidel 				case TRANSPARENT_COLOR:
785*f2e5373eSmseidel 				{
786*f2e5373eSmseidel 					Bitmap aTestBitmap(aBitmap);
787*f2e5373eSmseidel 					BitmapReadAccess* pRead = aTestBitmap.AcquireReadAccess();
788*f2e5373eSmseidel 
789*f2e5373eSmseidel 					if(pRead)
790*f2e5373eSmseidel 					{
791*f2e5373eSmseidel 						const Color aColor = pRead->GetColor(nY, nX);
792*f2e5373eSmseidel 
793*f2e5373eSmseidel 						// if color is not equal to TransparentColor, we are not transparent
794*f2e5373eSmseidel 						if(aColor != aTransparentColor)
795*f2e5373eSmseidel 						{
796*f2e5373eSmseidel 							nTransparency = 0x00;
797*f2e5373eSmseidel 						}
798*f2e5373eSmseidel 
799*f2e5373eSmseidel 						aTestBitmap.ReleaseAccess(pRead);
800*f2e5373eSmseidel 					}
801*f2e5373eSmseidel 					break;
802*f2e5373eSmseidel 				}
803*f2e5373eSmseidel 				case TRANSPARENT_BITMAP:
804*f2e5373eSmseidel 				{
805*f2e5373eSmseidel 					if(!aMask.IsEmpty())
806*f2e5373eSmseidel 					{
807*f2e5373eSmseidel 						Bitmap aTestBitmap(aMask);
808*f2e5373eSmseidel 						BitmapReadAccess* pRead = aTestBitmap.AcquireReadAccess();
809*f2e5373eSmseidel 
810*f2e5373eSmseidel 						if(pRead)
811*f2e5373eSmseidel 						{
812*f2e5373eSmseidel 							const BitmapColor aBitmapColor(pRead->GetPixel(nY, nX));
813*f2e5373eSmseidel 
814*f2e5373eSmseidel 							if(bAlpha)
815*f2e5373eSmseidel 							{
816*f2e5373eSmseidel 								nTransparency = aBitmapColor.GetIndex();
817*f2e5373eSmseidel 							}
818*f2e5373eSmseidel 							else
819*f2e5373eSmseidel 							{
820*f2e5373eSmseidel 								if(0x00 == aBitmapColor.GetIndex())
821*f2e5373eSmseidel 								{
822*f2e5373eSmseidel 									nTransparency = 0x00;
823*f2e5373eSmseidel 								}
824*f2e5373eSmseidel 							}
825*f2e5373eSmseidel 
826*f2e5373eSmseidel 							aTestBitmap.ReleaseAccess(pRead);
827*f2e5373eSmseidel 						}
828*f2e5373eSmseidel 					}
829*f2e5373eSmseidel 					break;
830*f2e5373eSmseidel 				}
831*f2e5373eSmseidel 			}
832*f2e5373eSmseidel 		}
833*f2e5373eSmseidel 	}
834*f2e5373eSmseidel 
835*f2e5373eSmseidel 	return nTransparency;
836cdf0e10cSrcweir }
837cdf0e10cSrcweir 
8385f27b83cSArmin Le Grand // ------------------------------------------------------------------
8395f27b83cSArmin Le Grand 
8405f27b83cSArmin Le Grand namespace
8415f27b83cSArmin Le Grand {
impTransformBitmap(const Bitmap & rSource,const Size aDestinationSize,const basegfx::B2DHomMatrix & rTransform,bool bSmooth)842*f2e5373eSmseidel 	Bitmap impTransformBitmap(
843*f2e5373eSmseidel 		const Bitmap& rSource,
844*f2e5373eSmseidel 		const Size aDestinationSize,
845*f2e5373eSmseidel 		const basegfx::B2DHomMatrix& rTransform,
846*f2e5373eSmseidel 		bool bSmooth)
847*f2e5373eSmseidel 	{
848*f2e5373eSmseidel 		Bitmap aDestination(aDestinationSize, 24);
849*f2e5373eSmseidel 		BitmapWriteAccess* pWrite = aDestination.AcquireWriteAccess();
850*f2e5373eSmseidel 
851*f2e5373eSmseidel 		if(pWrite)
852*f2e5373eSmseidel 		{
853*f2e5373eSmseidel 			//const Size aContentSizePixel(rSource.GetSizePixel());
854*f2e5373eSmseidel 			BitmapReadAccess* pRead = (const_cast< Bitmap& >(rSource)).AcquireReadAccess();
855*f2e5373eSmseidel 
856*f2e5373eSmseidel 			if(pRead)
857*f2e5373eSmseidel 			{
858*f2e5373eSmseidel 				const Size aDestinationSizePixel(aDestination.GetSizePixel());
859*f2e5373eSmseidel 				const BitmapColor aOutside(BitmapColor(0xff, 0xff, 0xff));
860*f2e5373eSmseidel 
861*f2e5373eSmseidel 				for(sal_Int32 y(0L); y < aDestinationSizePixel.getHeight(); y++)
862*f2e5373eSmseidel 				{
863*f2e5373eSmseidel 					for(sal_Int32 x(0L); x < aDestinationSizePixel.getWidth(); x++)
864*f2e5373eSmseidel 					{
865*f2e5373eSmseidel 						const basegfx::B2DPoint aSourceCoor(rTransform * basegfx::B2DPoint(x, y));
866*f2e5373eSmseidel 
867*f2e5373eSmseidel 						if(bSmooth)
868*f2e5373eSmseidel 						{
869*f2e5373eSmseidel 							pWrite->SetPixel(
870*f2e5373eSmseidel 								y,
871*f2e5373eSmseidel 								x,
872*f2e5373eSmseidel 								pRead->GetInterpolatedColorWithFallback(
873*f2e5373eSmseidel 									aSourceCoor.getY(),
874*f2e5373eSmseidel 									aSourceCoor.getX(),
875*f2e5373eSmseidel 									aOutside));
876*f2e5373eSmseidel 						}
877*f2e5373eSmseidel 						else
878*f2e5373eSmseidel 						{
879*f2e5373eSmseidel 							// this version does the correct <= 0.0 checks, so no need
880*f2e5373eSmseidel 							// to do the static_cast< sal_Int32 > self and make an error
881*f2e5373eSmseidel 							pWrite->SetPixel(
882*f2e5373eSmseidel 								y,
883*f2e5373eSmseidel 								x,
884*f2e5373eSmseidel 								pRead->GetColorWithFallback(
885*f2e5373eSmseidel 									aSourceCoor.getY(),
886*f2e5373eSmseidel 									aSourceCoor.getX(),
887*f2e5373eSmseidel 									aOutside));
888*f2e5373eSmseidel 						}
889*f2e5373eSmseidel 					}
890*f2e5373eSmseidel 				}
891*f2e5373eSmseidel 
892*f2e5373eSmseidel 				delete pRead;
893*f2e5373eSmseidel 			}
894*f2e5373eSmseidel 
895*f2e5373eSmseidel 			delete pWrite;
896*f2e5373eSmseidel 		}
897*f2e5373eSmseidel 
898*f2e5373eSmseidel 		rSource.AdaptBitCount(aDestination);
899*f2e5373eSmseidel 
900*f2e5373eSmseidel 		return aDestination;
901*f2e5373eSmseidel 	}
9025f27b83cSArmin Le Grand } // end of anonymous namespace
903f8c0d554SArmin Le Grand 
TransformBitmapEx(double fWidth,double fHeight,const basegfx::B2DHomMatrix & rTransformation,bool bSmooth) const9045f27b83cSArmin Le Grand BitmapEx BitmapEx::TransformBitmapEx(
905*f2e5373eSmseidel 	double fWidth,
906*f2e5373eSmseidel 	double fHeight,
907*f2e5373eSmseidel 	const basegfx::B2DHomMatrix& rTransformation,
908*f2e5373eSmseidel 	bool bSmooth) const
9095f27b83cSArmin Le Grand {
910*f2e5373eSmseidel 	if(fWidth <= 1 || fHeight <= 1)
911*f2e5373eSmseidel 		return BitmapEx();
912*f2e5373eSmseidel 
913*f2e5373eSmseidel 	// force destination to 24 bit, we want to smooth output
914*f2e5373eSmseidel 	const Size aDestinationSize(basegfx::fround(fWidth), basegfx::fround(fHeight));
915*f2e5373eSmseidel 	const Bitmap aDestination(impTransformBitmap(GetBitmap(), aDestinationSize, rTransformation, bSmooth));
916*f2e5373eSmseidel 
917*f2e5373eSmseidel 	// create mask
918*f2e5373eSmseidel 	if(IsTransparent())
919*f2e5373eSmseidel 	{
920*f2e5373eSmseidel 		if(IsAlpha())
921*f2e5373eSmseidel 		{
922*f2e5373eSmseidel 			const Bitmap aAlpha(impTransformBitmap(GetAlpha().GetBitmap(), aDestinationSize, rTransformation, bSmooth));
923*f2e5373eSmseidel 			return BitmapEx(aDestination, AlphaMask(aAlpha));
924*f2e5373eSmseidel 		}
925*f2e5373eSmseidel 		else
926*f2e5373eSmseidel 		{
927*f2e5373eSmseidel 			const Bitmap aMask(impTransformBitmap(GetMask(), aDestinationSize, rTransformation, false));
928*f2e5373eSmseidel 			return BitmapEx(aDestination, aMask);
929*f2e5373eSmseidel 		}
930*f2e5373eSmseidel 	}
931*f2e5373eSmseidel 
932*f2e5373eSmseidel 	return BitmapEx(aDestination);
9335f27b83cSArmin Le Grand }
9345f27b83cSArmin Le Grand 
9355f27b83cSArmin Le Grand // ------------------------------------------------------------------
9365f27b83cSArmin Le Grand 
getTransformed(const basegfx::B2DHomMatrix & rTransformation,const basegfx::B2DRange & rVisibleRange,double fMaximumArea,bool bSmooth) const9375f27b83cSArmin Le Grand BitmapEx BitmapEx::getTransformed(
938*f2e5373eSmseidel 	const basegfx::B2DHomMatrix& rTransformation,
939*f2e5373eSmseidel 	const basegfx::B2DRange& rVisibleRange,
940*f2e5373eSmseidel 	double fMaximumArea,
941*f2e5373eSmseidel 	bool bSmooth) const
9425f27b83cSArmin Le Grand {
943*f2e5373eSmseidel 	BitmapEx aRetval;
944*f2e5373eSmseidel 
945*f2e5373eSmseidel 	if(IsEmpty())
946*f2e5373eSmseidel 		return aRetval;
947*f2e5373eSmseidel 
948*f2e5373eSmseidel 	const sal_uInt32 nSourceWidth(GetSizePixel().Width());
949*f2e5373eSmseidel 	const sal_uInt32 nSourceHeight(GetSizePixel().Height());
950*f2e5373eSmseidel 
951*f2e5373eSmseidel 	if(!nSourceWidth || !nSourceHeight)
952*f2e5373eSmseidel 		return aRetval;
953*f2e5373eSmseidel 
954*f2e5373eSmseidel 	// Get aOutlineRange
955*f2e5373eSmseidel 	basegfx::B2DRange aOutlineRange(0.0, 0.0, 1.0, 1.0);
956*f2e5373eSmseidel 
957*f2e5373eSmseidel 	aOutlineRange.transform(rTransformation);
958*f2e5373eSmseidel 
959*f2e5373eSmseidel 	// create visible range from it by moving from relative to absolute
960*f2e5373eSmseidel 	basegfx::B2DRange aVisibleRange(rVisibleRange);
961*f2e5373eSmseidel 
962*f2e5373eSmseidel 	aVisibleRange.transform(
963*f2e5373eSmseidel 		basegfx::tools::createScaleTranslateB2DHomMatrix(
964*f2e5373eSmseidel 			aOutlineRange.getRange(),
965*f2e5373eSmseidel 			aOutlineRange.getMinimum()));
966*f2e5373eSmseidel 
967*f2e5373eSmseidel 	// get target size (which is visible range's size)
968*f2e5373eSmseidel 	double fWidth(aVisibleRange.getWidth());
969*f2e5373eSmseidel 	double fHeight(aVisibleRange.getHeight());
970*f2e5373eSmseidel 
971*f2e5373eSmseidel 	if(fWidth < 1.0 || fHeight < 1.0)
972*f2e5373eSmseidel 	{
973*f2e5373eSmseidel 		return aRetval;
974*f2e5373eSmseidel 	}
975*f2e5373eSmseidel 
976*f2e5373eSmseidel 	// test if discrete size (pixel) maybe too big and limit it
977*f2e5373eSmseidel 	const double fArea(fWidth * fHeight);
978*f2e5373eSmseidel 	const bool bNeedToReduce(basegfx::fTools::more(fArea, fMaximumArea));
979*f2e5373eSmseidel 	double fReduceFactor(1.0);
980*f2e5373eSmseidel 
981*f2e5373eSmseidel 	if(bNeedToReduce)
982*f2e5373eSmseidel 	{
983*f2e5373eSmseidel 		fReduceFactor = sqrt(fMaximumArea / fArea);
984*f2e5373eSmseidel 		fWidth *= fReduceFactor;
985*f2e5373eSmseidel 		fHeight *= fReduceFactor;
986*f2e5373eSmseidel 	}
987*f2e5373eSmseidel 
988*f2e5373eSmseidel 	// Build complete transform from source pixels to target pixels.
989*f2e5373eSmseidel 	// Start by scaling from source pixel size to unit coordinates
990*f2e5373eSmseidel 	basegfx::B2DHomMatrix aTransform(
991*f2e5373eSmseidel 		basegfx::tools::createScaleB2DHomMatrix(
992*f2e5373eSmseidel 			1.0 / nSourceWidth,
993*f2e5373eSmseidel 			1.0 / nSourceHeight));
994*f2e5373eSmseidel 
995*f2e5373eSmseidel 	// multiply with given transform which leads from unit coordinates inside
996*f2e5373eSmseidel 	// aOutlineRange
997*f2e5373eSmseidel 	aTransform = rTransformation * aTransform;
998*f2e5373eSmseidel 
999*f2e5373eSmseidel 	// subtract top-left of absolute VisibleRange
1000*f2e5373eSmseidel 	aTransform.translate(
1001*f2e5373eSmseidel 		-aVisibleRange.getMinX(),
1002*f2e5373eSmseidel 		-aVisibleRange.getMinY());
1003*f2e5373eSmseidel 
1004*f2e5373eSmseidel 	// scale to target pixels (if needed)
1005*f2e5373eSmseidel 	if(bNeedToReduce)
1006*f2e5373eSmseidel 	{
1007*f2e5373eSmseidel 		aTransform.scale(fReduceFactor, fReduceFactor);
1008*f2e5373eSmseidel 	}
1009*f2e5373eSmseidel 
1010*f2e5373eSmseidel 	// invert to get transformation from target pixel coordinates to source pixels
1011*f2e5373eSmseidel 	aTransform.invert();
1012*f2e5373eSmseidel 
1013*f2e5373eSmseidel 	// create bitmap using source, destination and linear back-transformation
1014*f2e5373eSmseidel 	aRetval = TransformBitmapEx(fWidth, fHeight, aTransform, bSmooth);
1015*f2e5373eSmseidel 
1016*f2e5373eSmseidel 	return aRetval;
10175f27b83cSArmin Le Grand }
10185f27b83cSArmin Le Grand 
10195f27b83cSArmin Le Grand // ------------------------------------------------------------------
10205f27b83cSArmin Le Grand 
ModifyBitmapEx(const basegfx::BColorModifierStack & rBColorModifierStack) const10215f27b83cSArmin Le Grand BitmapEx BitmapEx::ModifyBitmapEx(const basegfx::BColorModifierStack& rBColorModifierStack) const
10225f27b83cSArmin Le Grand {
1023*f2e5373eSmseidel 	Bitmap aChangedBitmap(GetBitmap());
1024*f2e5373eSmseidel 	bool bDone(false);
1025*f2e5373eSmseidel 
1026*f2e5373eSmseidel 	for(sal_uInt32 a(rBColorModifierStack.count()); a && !bDone; )
1027*f2e5373eSmseidel 	{
1028*f2e5373eSmseidel 		const basegfx::BColorModifierSharedPtr& rModifier = rBColorModifierStack.getBColorModifier(--a);
1029*f2e5373eSmseidel 		const basegfx::BColorModifier_replace* pReplace = dynamic_cast< const basegfx::BColorModifier_replace* >(rModifier.get());
1030*f2e5373eSmseidel 
1031*f2e5373eSmseidel 		if(pReplace)
1032*f2e5373eSmseidel 		{
1033*f2e5373eSmseidel 			// complete replace
1034*f2e5373eSmseidel 			if(IsTransparent())
1035*f2e5373eSmseidel 			{
1036*f2e5373eSmseidel 				// clear bitmap with dest color
1037*f2e5373eSmseidel 				if(aChangedBitmap.GetBitCount() <= 8)
1038*f2e5373eSmseidel 				{
1039*f2e5373eSmseidel 					// do NOT use erase; for e.g. 8bit Bitmaps, the nearest color to the given
1040*f2e5373eSmseidel 					// erase color is determined and used -> this may be different from what is
1041*f2e5373eSmseidel 					// wanted here. Better create a new bitmap with the needed color explicitly
1042*f2e5373eSmseidel 					BitmapReadAccess* pReadAccess = aChangedBitmap.AcquireReadAccess();
1043*f2e5373eSmseidel 					OSL_ENSURE(pReadAccess, "Got no Bitmap ReadAccess ?!?");
1044*f2e5373eSmseidel 
1045*f2e5373eSmseidel 					if(pReadAccess)
1046*f2e5373eSmseidel 					{
1047*f2e5373eSmseidel 						BitmapPalette aNewPalette(pReadAccess->GetPalette());
1048*f2e5373eSmseidel 						aNewPalette[0] = BitmapColor(Color(pReplace->getBColor()));
1049*f2e5373eSmseidel 						aChangedBitmap = Bitmap(
1050*f2e5373eSmseidel 							aChangedBitmap.GetSizePixel(),
1051*f2e5373eSmseidel 							aChangedBitmap.GetBitCount(),
1052*f2e5373eSmseidel 							&aNewPalette);
1053*f2e5373eSmseidel 						delete pReadAccess;
1054*f2e5373eSmseidel 					}
1055*f2e5373eSmseidel 				}
1056*f2e5373eSmseidel 				else
1057*f2e5373eSmseidel 				{
1058*f2e5373eSmseidel 					aChangedBitmap.Erase(Color(pReplace->getBColor()));
1059*f2e5373eSmseidel 				}
1060*f2e5373eSmseidel 			}
1061*f2e5373eSmseidel 			else
1062*f2e5373eSmseidel 			{
1063*f2e5373eSmseidel 				// erase bitmap, caller will know to paint direct
1064*f2e5373eSmseidel 				aChangedBitmap.SetEmpty();
1065*f2e5373eSmseidel 			}
1066*f2e5373eSmseidel 
1067*f2e5373eSmseidel 			bDone = true;
1068*f2e5373eSmseidel 		}
1069*f2e5373eSmseidel 		else
1070*f2e5373eSmseidel 		{
1071*f2e5373eSmseidel 			BitmapWriteAccess* pContent = aChangedBitmap.AcquireWriteAccess();
1072*f2e5373eSmseidel 
1073*f2e5373eSmseidel 			if(pContent)
1074*f2e5373eSmseidel 			{
1075*f2e5373eSmseidel 				const double fConvertColor(1.0 / 255.0);
1076*f2e5373eSmseidel 
1077*f2e5373eSmseidel 				if(pContent->HasPalette())
1078*f2e5373eSmseidel 				{
1079*f2e5373eSmseidel 					const sal_uInt16 nCount(pContent->GetPaletteEntryCount());
1080*f2e5373eSmseidel 
1081*f2e5373eSmseidel 					for(sal_uInt16 a(0); a < nCount; a++)
1082*f2e5373eSmseidel 					{
1083*f2e5373eSmseidel 						const BitmapColor& rCol = pContent->GetPaletteColor(a);
1084*f2e5373eSmseidel 						const basegfx::BColor aBSource(
1085*f2e5373eSmseidel 							rCol.GetRed() * fConvertColor,
1086*f2e5373eSmseidel 							rCol.GetGreen() * fConvertColor,
1087*f2e5373eSmseidel 							rCol.GetBlue() * fConvertColor);
1088*f2e5373eSmseidel 						const basegfx::BColor aBDest(rModifier->getModifiedColor(aBSource));
1089*f2e5373eSmseidel 						pContent->SetPaletteColor(a, BitmapColor(Color(aBDest)));
1090*f2e5373eSmseidel 					}
1091*f2e5373eSmseidel 				}
1092*f2e5373eSmseidel 				else if(BMP_FORMAT_24BIT_TC_BGR == pContent->GetScanlineFormat())
1093*f2e5373eSmseidel 				{
1094*f2e5373eSmseidel 					for(sal_uInt32 y(0L); y < (sal_uInt32)pContent->Height(); y++)
1095*f2e5373eSmseidel 					{
1096*f2e5373eSmseidel 						Scanline pScan = pContent->GetScanline(y);
1097*f2e5373eSmseidel 
1098*f2e5373eSmseidel 						for(sal_uInt32 x(0L); x < (sal_uInt32)pContent->Width(); x++)
1099*f2e5373eSmseidel 						{
1100*f2e5373eSmseidel 							const basegfx::BColor aBSource(
1101*f2e5373eSmseidel 								*(pScan + 2)* fConvertColor,
1102*f2e5373eSmseidel 								*(pScan + 1) * fConvertColor,
1103*f2e5373eSmseidel 								*pScan * fConvertColor);
1104*f2e5373eSmseidel 							const basegfx::BColor aBDest(rModifier->getModifiedColor(aBSource));
1105*f2e5373eSmseidel 							*pScan++ = static_cast< sal_uInt8 >(aBDest.getBlue() * 255.0);
1106*f2e5373eSmseidel 							*pScan++ = static_cast< sal_uInt8 >(aBDest.getGreen() * 255.0);
1107*f2e5373eSmseidel 							*pScan++ = static_cast< sal_uInt8 >(aBDest.getRed() * 255.0);
1108*f2e5373eSmseidel 						}
1109*f2e5373eSmseidel 					}
1110*f2e5373eSmseidel 				}
1111*f2e5373eSmseidel 				else if(BMP_FORMAT_24BIT_TC_RGB == pContent->GetScanlineFormat())
1112*f2e5373eSmseidel 				{
1113*f2e5373eSmseidel 					for(sal_uInt32 y(0L); y < (sal_uInt32)pContent->Height(); y++)
1114*f2e5373eSmseidel 					{
1115*f2e5373eSmseidel 						Scanline pScan = pContent->GetScanline(y);
1116*f2e5373eSmseidel 
1117*f2e5373eSmseidel 						for(sal_uInt32 x(0L); x < (sal_uInt32)pContent->Width(); x++)
1118*f2e5373eSmseidel 						{
1119*f2e5373eSmseidel 							const basegfx::BColor aBSource(
1120*f2e5373eSmseidel 								*pScan * fConvertColor,
1121*f2e5373eSmseidel 								*(pScan + 1) * fConvertColor,
1122*f2e5373eSmseidel 								*(pScan + 2) * fConvertColor);
1123*f2e5373eSmseidel 							const basegfx::BColor aBDest(rModifier->getModifiedColor(aBSource));
1124*f2e5373eSmseidel 							*pScan++ = static_cast< sal_uInt8 >(aBDest.getRed() * 255.0);
1125*f2e5373eSmseidel 							*pScan++ = static_cast< sal_uInt8 >(aBDest.getGreen() * 255.0);
1126*f2e5373eSmseidel 							*pScan++ = static_cast< sal_uInt8 >(aBDest.getBlue() * 255.0);
1127*f2e5373eSmseidel 						}
1128*f2e5373eSmseidel 					}
1129*f2e5373eSmseidel 				}
1130*f2e5373eSmseidel 				else
1131*f2e5373eSmseidel 				{
1132*f2e5373eSmseidel 					for(sal_uInt32 y(0L); y < (sal_uInt32)pContent->Height(); y++)
1133*f2e5373eSmseidel 					{
1134*f2e5373eSmseidel 						for(sal_uInt32 x(0L); x < (sal_uInt32)pContent->Width(); x++)
1135*f2e5373eSmseidel 						{
1136*f2e5373eSmseidel 							const BitmapColor aBMCol(pContent->GetColor(y, x));
1137*f2e5373eSmseidel 							const basegfx::BColor aBSource(
1138*f2e5373eSmseidel 								(double)aBMCol.GetRed() * fConvertColor,
1139*f2e5373eSmseidel 								(double)aBMCol.GetGreen() * fConvertColor,
1140*f2e5373eSmseidel 								(double)aBMCol.GetBlue() * fConvertColor);
1141*f2e5373eSmseidel 							const basegfx::BColor aBDest(rModifier->getModifiedColor(aBSource));
1142*f2e5373eSmseidel 
1143*f2e5373eSmseidel 							pContent->SetPixel(y, x, BitmapColor(Color(aBDest)));
1144*f2e5373eSmseidel 						}
1145*f2e5373eSmseidel 					}
1146*f2e5373eSmseidel 				}
1147*f2e5373eSmseidel 
1148*f2e5373eSmseidel 				delete pContent;
1149*f2e5373eSmseidel 			}
1150*f2e5373eSmseidel 		}
1151*f2e5373eSmseidel 	}
1152*f2e5373eSmseidel 
1153*f2e5373eSmseidel 	if(aChangedBitmap.IsEmpty())
1154*f2e5373eSmseidel 	{
1155*f2e5373eSmseidel 		return BitmapEx();
1156*f2e5373eSmseidel 	}
1157*f2e5373eSmseidel 	else
1158*f2e5373eSmseidel 	{
1159*f2e5373eSmseidel 		if(IsTransparent())
1160*f2e5373eSmseidel 		{
1161*f2e5373eSmseidel 			if(IsAlpha())
1162*f2e5373eSmseidel 			{
1163*f2e5373eSmseidel 				return BitmapEx(aChangedBitmap, GetAlpha());
1164*f2e5373eSmseidel 			}
1165*f2e5373eSmseidel 			else
1166*f2e5373eSmseidel 			{
1167*f2e5373eSmseidel 				return BitmapEx(aChangedBitmap, GetMask());
1168*f2e5373eSmseidel 			}
1169*f2e5373eSmseidel 		}
1170*f2e5373eSmseidel 		else
1171*f2e5373eSmseidel 		{
1172*f2e5373eSmseidel 			return BitmapEx(aChangedBitmap);
1173*f2e5373eSmseidel 		}
1174*f2e5373eSmseidel 	}
11755f27b83cSArmin Le Grand }
11765f27b83cSArmin Le Grand 
1177ff0f521cSArmin Le Grand // -----------------------------------------------------------------------------
1178ff0f521cSArmin Le Grand 
createBlendFrame(const Size & rSize,sal_uInt8 nAlpha,Color aColorTopLeft,Color aColorBottomRight)1179ff0f521cSArmin Le Grand BitmapEx VCL_DLLPUBLIC createBlendFrame(
1180*f2e5373eSmseidel 	const Size& rSize,
1181*f2e5373eSmseidel 	sal_uInt8 nAlpha,
1182*f2e5373eSmseidel 	Color aColorTopLeft,
1183*f2e5373eSmseidel 	Color aColorBottomRight)
1184ff0f521cSArmin Le Grand {
1185*f2e5373eSmseidel 	const sal_uInt32 nW(rSize.Width());
1186*f2e5373eSmseidel 	const sal_uInt32 nH(rSize.Height());
1187ff0f521cSArmin Le Grand 
1188*f2e5373eSmseidel 	if(nW || nH)
1189*f2e5373eSmseidel 	{
1190*f2e5373eSmseidel 		Color aColTopRight(aColorTopLeft);
1191*f2e5373eSmseidel 		Color aColBottomLeft(aColorTopLeft);
1192*f2e5373eSmseidel 		const sal_uInt32 nDE(nW + nH);
1193ff0f521cSArmin Le Grand 
1194*f2e5373eSmseidel 		aColTopRight.Merge(aColorBottomRight, 255 - sal_uInt8((nW * 255) / nDE));
1195*f2e5373eSmseidel 		aColBottomLeft.Merge(aColorBottomRight, 255 - sal_uInt8((nH * 255) / nDE));
1196ff0f521cSArmin Le Grand 
1197*f2e5373eSmseidel 		return createBlendFrame(rSize, nAlpha, aColorTopLeft, aColTopRight, aColorBottomRight, aColBottomLeft);
1198*f2e5373eSmseidel 	}
1199ff0f521cSArmin Le Grand 
1200*f2e5373eSmseidel 	return BitmapEx();
1201ff0f521cSArmin Le Grand }
1202ff0f521cSArmin Le Grand 
createBlendFrame(const Size & rSize,sal_uInt8 nAlpha,Color aColorTopLeft,Color aColorTopRight,Color aColorBottomRight,Color aColorBottomLeft)1203ff0f521cSArmin Le Grand BitmapEx VCL_DLLPUBLIC createBlendFrame(
1204*f2e5373eSmseidel 	const Size& rSize,
1205*f2e5373eSmseidel 	sal_uInt8 nAlpha,
1206*f2e5373eSmseidel 	Color aColorTopLeft,
1207*f2e5373eSmseidel 	Color aColorTopRight,
1208*f2e5373eSmseidel 	Color aColorBottomRight,
1209*f2e5373eSmseidel 	Color aColorBottomLeft)
1210ff0f521cSArmin Le Grand {
1211*f2e5373eSmseidel 	static Size aLastSize(0, 0);
1212*f2e5373eSmseidel 	static sal_uInt8 nLastAlpha(0);
1213*f2e5373eSmseidel 	static Color aLastColorTopLeft(COL_BLACK);
1214*f2e5373eSmseidel 	static Color aLastColorTopRight(COL_BLACK);
1215*f2e5373eSmseidel 	static Color aLastColorBottomRight(COL_BLACK);
1216*f2e5373eSmseidel 	static Color aLastColorBottomLeft(COL_BLACK);
1217*f2e5373eSmseidel 	static BitmapEx aLastResult;
1218*f2e5373eSmseidel 
1219*f2e5373eSmseidel 	if(aLastSize == rSize
1220*f2e5373eSmseidel 		&& nLastAlpha == nAlpha
1221*f2e5373eSmseidel 		&& aLastColorTopLeft == aColorTopLeft
1222*f2e5373eSmseidel 		&& aLastColorTopRight == aColorTopRight
1223*f2e5373eSmseidel 		&& aLastColorBottomRight == aColorBottomRight
1224*f2e5373eSmseidel 		&& aLastColorBottomLeft == aColorBottomLeft)
1225*f2e5373eSmseidel 	{
1226*f2e5373eSmseidel 		return aLastResult;
1227*f2e5373eSmseidel 	}
1228*f2e5373eSmseidel 
1229*f2e5373eSmseidel 	aLastSize = rSize;
1230*f2e5373eSmseidel 	nLastAlpha = nAlpha;
1231*f2e5373eSmseidel 	aLastColorTopLeft = aColorTopLeft;
1232*f2e5373eSmseidel 	aLastColorTopRight = aColorTopRight;
1233*f2e5373eSmseidel 	aLastColorBottomRight = aColorBottomRight;
1234*f2e5373eSmseidel 	aLastColorBottomLeft = aColorBottomLeft;
1235*f2e5373eSmseidel 	aLastResult.Clear();
1236*f2e5373eSmseidel 
1237*f2e5373eSmseidel 	const long nW(rSize.Width());
1238*f2e5373eSmseidel 	const long nH(rSize.Height());
1239*f2e5373eSmseidel 
1240*f2e5373eSmseidel 	if(nW && nH)
1241*f2e5373eSmseidel 	{
1242*f2e5373eSmseidel 		sal_uInt8 aEraseTrans(0xff);
1243*f2e5373eSmseidel 		Bitmap aContent(rSize, 24);
1244*f2e5373eSmseidel 		AlphaMask aAlpha(rSize, &aEraseTrans);
1245*f2e5373eSmseidel 
1246*f2e5373eSmseidel 		aContent.Erase(COL_BLACK);
1247*f2e5373eSmseidel 
1248*f2e5373eSmseidel 		BitmapWriteAccess* pContent = aContent.AcquireWriteAccess();
1249*f2e5373eSmseidel 		BitmapWriteAccess* pAlpha = aAlpha.AcquireWriteAccess();
1250*f2e5373eSmseidel 
1251*f2e5373eSmseidel 		if(pContent && pAlpha)
1252*f2e5373eSmseidel 		{
1253*f2e5373eSmseidel 			long x(0);
1254*f2e5373eSmseidel 			long y(0);
1255*f2e5373eSmseidel 
1256*f2e5373eSmseidel 			// x == 0, y == 0, top-left corner
1257*f2e5373eSmseidel 			pContent->SetPixel(0, 0, aColorTopLeft);
1258*f2e5373eSmseidel 			pAlpha->SetPixelIndex(0, 0, nAlpha);
1259*f2e5373eSmseidel 
1260*f2e5373eSmseidel 			// y == 0, top line left to right
1261*f2e5373eSmseidel 			for(x = 1; x < nW - 1; x++)
1262*f2e5373eSmseidel 			{
1263*f2e5373eSmseidel 				Color aMix(aColorTopLeft);
1264*f2e5373eSmseidel 
1265*f2e5373eSmseidel 				aMix.Merge(aColorTopRight, 255 - sal_uInt8((x * 255) / nW));
1266*f2e5373eSmseidel 				pContent->SetPixel(0, x, aMix);
1267*f2e5373eSmseidel 				pAlpha->SetPixelIndex(0, x, nAlpha);
1268*f2e5373eSmseidel 			}
1269*f2e5373eSmseidel 
1270*f2e5373eSmseidel 			// x == nW - 1, y == 0, top-right corner
1271*f2e5373eSmseidel 			// #123690# Caution! When nW is 1, x == nW is possible (!)
1272*f2e5373eSmseidel 			if(x < nW)
1273*f2e5373eSmseidel 			{
1274*f2e5373eSmseidel 				pContent->SetPixel(0, x, aColorTopRight);
1275*f2e5373eSmseidel 				pAlpha->SetPixelIndex(0, x, nAlpha);
1276*f2e5373eSmseidel 			}
1277*f2e5373eSmseidel 
1278*f2e5373eSmseidel 			// x == 0 and nW - 1, left and right line top-down
1279*f2e5373eSmseidel 			for(y = 1; y < nH - 1; y++)
1280*f2e5373eSmseidel 			{
1281*f2e5373eSmseidel 				Color aMixA(aColorTopLeft);
1282*f2e5373eSmseidel 
1283*f2e5373eSmseidel 				aMixA.Merge(aColorBottomLeft, 255 - sal_uInt8((y * 255) / nH));
1284*f2e5373eSmseidel 				pContent->SetPixel(y, 0, aMixA);
1285*f2e5373eSmseidel 				pAlpha->SetPixelIndex(y, 0, nAlpha);
1286*f2e5373eSmseidel 
1287*f2e5373eSmseidel 				// #123690# Caution! When nW is 1, x == nW is possible (!)
1288*f2e5373eSmseidel 				if(x < nW)
1289*f2e5373eSmseidel 				{
1290*f2e5373eSmseidel 					Color aMixB(aColorTopRight);
1291*f2e5373eSmseidel 
1292*f2e5373eSmseidel 					aMixB.Merge(aColorBottomRight, 255 - sal_uInt8((y * 255) / nH));
1293*f2e5373eSmseidel 					pContent->SetPixel(y, x, aMixB);
1294*f2e5373eSmseidel 					pAlpha->SetPixelIndex(y, x, nAlpha);
1295*f2e5373eSmseidel 				}
1296*f2e5373eSmseidel 			}
1297*f2e5373eSmseidel 
1298*f2e5373eSmseidel 			// #123690# Caution! When nH is 1, y == nH is possible (!)
1299*f2e5373eSmseidel 			if(y < nH)
1300*f2e5373eSmseidel 			{
1301*f2e5373eSmseidel 				// x == 0, y == nH - 1, bottom-left corner
1302*f2e5373eSmseidel 				pContent->SetPixel(y, 0, aColorBottomLeft);
1303*f2e5373eSmseidel 				pAlpha->SetPixelIndex(y, 0, nAlpha);
1304*f2e5373eSmseidel 
1305*f2e5373eSmseidel 				// y == nH - 1, bottom line left to right
1306*f2e5373eSmseidel 				for(x = 1; x < nW - 1; x++)
1307*f2e5373eSmseidel 				{
1308*f2e5373eSmseidel 					Color aMix(aColorBottomLeft);
1309*f2e5373eSmseidel 
1310*f2e5373eSmseidel 					aMix.Merge(aColorBottomRight, 255 - sal_uInt8(((x - 0)* 255) / nW));
1311*f2e5373eSmseidel 					pContent->SetPixel(y, x, aMix);
1312*f2e5373eSmseidel 					pAlpha->SetPixelIndex(y, x, nAlpha);
1313*f2e5373eSmseidel 				}
1314*f2e5373eSmseidel 
1315*f2e5373eSmseidel 				// x == nW - 1, y == nH - 1, bottom-right corner
1316*f2e5373eSmseidel 				// #123690# Caution! When nW is 1, x == nW is possible (!)
1317*f2e5373eSmseidel 				if(x < nW)
1318*f2e5373eSmseidel 				{
1319*f2e5373eSmseidel 					pContent->SetPixel(y, x, aColorBottomRight);
1320*f2e5373eSmseidel 					pAlpha->SetPixelIndex(y, x, nAlpha);
1321*f2e5373eSmseidel 				}
1322*f2e5373eSmseidel 			}
1323*f2e5373eSmseidel 
1324*f2e5373eSmseidel 			aContent.ReleaseAccess(pContent);
1325*f2e5373eSmseidel 			aAlpha.ReleaseAccess(pAlpha);
1326*f2e5373eSmseidel 
1327*f2e5373eSmseidel 			aLastResult = BitmapEx(aContent, aAlpha);
1328*f2e5373eSmseidel 		}
1329*f2e5373eSmseidel 		else
1330*f2e5373eSmseidel 		{
1331*f2e5373eSmseidel 			if(pContent)
1332*f2e5373eSmseidel 			{
1333*f2e5373eSmseidel 				aContent.ReleaseAccess(pContent);
1334*f2e5373eSmseidel 			}
1335*f2e5373eSmseidel 
1336*f2e5373eSmseidel 			if(pAlpha)
1337*f2e5373eSmseidel 			{
1338*f2e5373eSmseidel 				aAlpha.ReleaseAccess(pAlpha);
1339*f2e5373eSmseidel 			}
1340*f2e5373eSmseidel 		}
1341*f2e5373eSmseidel 	}
1342*f2e5373eSmseidel 
1343*f2e5373eSmseidel 	return aLastResult;
1344ff0f521cSArmin Le Grand }
1345ff0f521cSArmin Le Grand 
1346*f2e5373eSmseidel /* vim: set noet sw=4 ts=4: */
1347