xref: /aoo42x/main/vcl/source/gdi/bitmapex.cxx (revision ff0f521c)
19f62ea84SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
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
109f62ea84SAndrew Rist  *
119f62ea84SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
129f62ea84SAndrew Rist  *
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.
199f62ea84SAndrew Rist  *
209f62ea84SAndrew Rist  *************************************************************/
219f62ea84SAndrew Rist 
22cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
23cdf0e10cSrcweir #include "precompiled_vcl.hxx"
24cdf0e10cSrcweir 
25cdf0e10cSrcweir #include <ctype.h>
26cdf0e10cSrcweir #include <rtl/crc.h>
27cdf0e10cSrcweir #include <tools/stream.hxx>
28cdf0e10cSrcweir #include <tools/debug.hxx>
29cdf0e10cSrcweir #include <tools/rc.h>
30cdf0e10cSrcweir #include <vcl/salbtype.hxx>
31cdf0e10cSrcweir #include <vcl/outdev.hxx>
32cdf0e10cSrcweir #include <vcl/alpha.hxx>
33cdf0e10cSrcweir #include <vcl/bitmapex.hxx>
34cdf0e10cSrcweir #include <vcl/pngread.hxx>
35cdf0e10cSrcweir #include <vcl/svapp.hxx>
36cdf0e10cSrcweir #include <vcl/bmpacc.hxx>
3745fd3b9aSArmin Le Grand #include <vcl/dibtools.hxx>
38cdf0e10cSrcweir #include <image.h>
39cdf0e10cSrcweir #include <impimagetree.hxx>
405f27b83cSArmin Le Grand #include <basegfx/matrix/b2dhommatrixtools.hxx>
41cdf0e10cSrcweir 
42cdf0e10cSrcweir // ------------
43cdf0e10cSrcweir // - BitmapEx -
44cdf0e10cSrcweir // ------------
45cdf0e10cSrcweir 
46cdf0e10cSrcweir BitmapEx::BitmapEx() :
47cdf0e10cSrcweir 		eTransparent( TRANSPARENT_NONE ),
48cdf0e10cSrcweir 		bAlpha		( sal_False )
49cdf0e10cSrcweir {
50cdf0e10cSrcweir }
51cdf0e10cSrcweir 
52cdf0e10cSrcweir // ------------------------------------------------------------------
53cdf0e10cSrcweir 
54cdf0e10cSrcweir BitmapEx::BitmapEx( const BitmapEx& rBitmapEx ) :
55cdf0e10cSrcweir 		aBitmap				( rBitmapEx.aBitmap ),
56cdf0e10cSrcweir 		aMask				( rBitmapEx.aMask ),
57cdf0e10cSrcweir 		aBitmapSize			( rBitmapEx.aBitmapSize ),
58cdf0e10cSrcweir 		aTransparentColor	( rBitmapEx.aTransparentColor ),
59cdf0e10cSrcweir 		eTransparent		( rBitmapEx.eTransparent ),
60cdf0e10cSrcweir 		bAlpha				( rBitmapEx.bAlpha )
61cdf0e10cSrcweir {
62cdf0e10cSrcweir }
63cdf0e10cSrcweir 
64cdf0e10cSrcweir BitmapEx::BitmapEx( const BitmapEx& rBitmapEx, Point aSrc, Size aSize ) :
65cdf0e10cSrcweir 		eTransparent( TRANSPARENT_NONE ),
66cdf0e10cSrcweir 		bAlpha		( sal_False )
67cdf0e10cSrcweir {
68cdf0e10cSrcweir 	if( rBitmapEx.IsEmpty() )
69cdf0e10cSrcweir 		return;
70cdf0e10cSrcweir 
71cdf0e10cSrcweir 	aBitmap = Bitmap( aSize, rBitmapEx.aBitmap.GetBitCount() );
72cdf0e10cSrcweir 	aBitmapSize = aSize;
73cdf0e10cSrcweir 	if( rBitmapEx.IsAlpha() )
74cdf0e10cSrcweir 	{
75cdf0e10cSrcweir 		bAlpha = sal_True;
76cdf0e10cSrcweir 		aMask = AlphaMask( aSize ).ImplGetBitmap();
77cdf0e10cSrcweir 	}
78cdf0e10cSrcweir 	else if( rBitmapEx.IsTransparent() )
79cdf0e10cSrcweir 		aMask = Bitmap( aSize, rBitmapEx.aMask.GetBitCount() );
80cdf0e10cSrcweir 
81cdf0e10cSrcweir 	Rectangle aDestRect( Point( 0, 0 ), aSize );
82cdf0e10cSrcweir 	Rectangle aSrcRect( aSrc, aSize );
83cdf0e10cSrcweir 	CopyPixel( aDestRect, aSrcRect, &rBitmapEx );
84cdf0e10cSrcweir }
85cdf0e10cSrcweir 
86cdf0e10cSrcweir // ------------------------------------------------------------------
87cdf0e10cSrcweir 
88cdf0e10cSrcweir BitmapEx::BitmapEx( const ResId& rResId ) :
89cdf0e10cSrcweir 		eTransparent( TRANSPARENT_NONE ),
90cdf0e10cSrcweir 		bAlpha		( sal_False )
91cdf0e10cSrcweir {
92cdf0e10cSrcweir 	static ImplImageTreeSingletonRef	aImageTree;
93cdf0e10cSrcweir 	ResMgr* 							pResMgr = NULL;
94cdf0e10cSrcweir 
95cdf0e10cSrcweir 	ResMgr::GetResourceSkipHeader( rResId.SetRT( RSC_BITMAP ), &pResMgr );
96cdf0e10cSrcweir 	pResMgr->ReadLong();
97cdf0e10cSrcweir 	pResMgr->ReadLong();
98cdf0e10cSrcweir 
99cdf0e10cSrcweir 	const String aFileName( pResMgr->ReadString() );
100cdf0e10cSrcweir 	::rtl::OUString aCurrentSymbolsStyle = Application::GetSettings().GetStyleSettings().GetCurrentSymbolsStyleName();
101cdf0e10cSrcweir 
102cdf0e10cSrcweir 	if( !aImageTree->loadImage( aFileName, aCurrentSymbolsStyle, *this ) )
103cdf0e10cSrcweir 	{
104cdf0e10cSrcweir #ifdef DBG_UTIL
105cdf0e10cSrcweir 		ByteString aErrorStr( "BitmapEx::BitmapEx( const ResId& rResId ): could not load image <" );
106cdf0e10cSrcweir 		DBG_ERROR( ( ( aErrorStr += ByteString( aFileName, RTL_TEXTENCODING_ASCII_US ) ) += '>' ).GetBuffer() );
107cdf0e10cSrcweir #endif
108cdf0e10cSrcweir 	}
109cdf0e10cSrcweir }
110cdf0e10cSrcweir 
111cdf0e10cSrcweir // ------------------------------------------------------------------
112cdf0e10cSrcweir 
113cdf0e10cSrcweir BitmapEx::BitmapEx( const Bitmap& rBmp ) :
114cdf0e10cSrcweir 		aBitmap		( rBmp ),
115cdf0e10cSrcweir 		aBitmapSize	( aBitmap.GetSizePixel() ),
116cdf0e10cSrcweir 		eTransparent( TRANSPARENT_NONE ),
117cdf0e10cSrcweir 		bAlpha		( sal_False )
118cdf0e10cSrcweir {
119cdf0e10cSrcweir }
120cdf0e10cSrcweir 
121cdf0e10cSrcweir // ------------------------------------------------------------------
122cdf0e10cSrcweir 
123cdf0e10cSrcweir BitmapEx::BitmapEx( const Bitmap& rBmp, const Bitmap& rMask ) :
124cdf0e10cSrcweir 		aBitmap			( rBmp ),
125cdf0e10cSrcweir 		aMask			( rMask ),
126cdf0e10cSrcweir 		aBitmapSize		( aBitmap.GetSizePixel() ),
127cdf0e10cSrcweir 		eTransparent	( !rMask ? TRANSPARENT_NONE : TRANSPARENT_BITMAP ),
128cdf0e10cSrcweir 		bAlpha			( sal_False )
129cdf0e10cSrcweir {
130ba5b0517SArmin Le Grand     if(!!aBitmap && !!aMask && aBitmap.GetSizePixel() != aMask.GetSizePixel())
131479f2b27SArmin Le Grand     {
132479f2b27SArmin Le Grand         OSL_ENSURE(false, "Mask size differs from Bitmap size, corrected Mask (!)");
133ba5b0517SArmin Le Grand         aMask.Scale(aBitmap.GetSizePixel());
134479f2b27SArmin Le Grand     }
135cdf0e10cSrcweir 
136cdf0e10cSrcweir     // #105489# Ensure a mask is exactly one bit deep
137cdf0e10cSrcweir     if( !!aMask && aMask.GetBitCount() != 1 )
138cdf0e10cSrcweir     {
139cdf0e10cSrcweir         OSL_TRACE("BitmapEx: forced mask to monochrome");
140cdf0e10cSrcweir         aMask.ImplMakeMono( 255 );
141cdf0e10cSrcweir     }
142cdf0e10cSrcweir }
143cdf0e10cSrcweir 
144cdf0e10cSrcweir // ------------------------------------------------------------------
145cdf0e10cSrcweir 
146cdf0e10cSrcweir BitmapEx::BitmapEx( const Bitmap& rBmp, const AlphaMask& rAlphaMask ) :
147cdf0e10cSrcweir 		aBitmap			( rBmp ),
148cdf0e10cSrcweir 		aMask			( rAlphaMask.ImplGetBitmap() ),
149cdf0e10cSrcweir 		aBitmapSize		( aBitmap.GetSizePixel() ),
150cdf0e10cSrcweir 		eTransparent	( !rAlphaMask ? TRANSPARENT_NONE : TRANSPARENT_BITMAP ),
151cdf0e10cSrcweir 		bAlpha			( !rAlphaMask ? sal_False : sal_True )
152cdf0e10cSrcweir {
153ba5b0517SArmin Le Grand     if(!!aBitmap && !!aMask && aBitmap.GetSizePixel() != aMask.GetSizePixel())
154479f2b27SArmin Le Grand     {
155479f2b27SArmin Le Grand         OSL_ENSURE(false, "Alpha size differs from Bitmap size, corrected Mask (!)");
156479f2b27SArmin Le Grand         aMask.Scale(rBmp.GetSizePixel());
157479f2b27SArmin Le Grand     }
158cdf0e10cSrcweir 
159cdf0e10cSrcweir     // #i75531# the workaround below can go when
160cdf0e10cSrcweir     // X11SalGraphics::drawAlphaBitmap()'s render acceleration
161cdf0e10cSrcweir     // can handle the bitmap depth mismatch directly
162cdf0e10cSrcweir     if( aBitmap.GetBitCount() < aMask.GetBitCount() )
163cdf0e10cSrcweir         aBitmap.Convert( BMP_CONVERSION_24BIT );
164cdf0e10cSrcweir }
165cdf0e10cSrcweir 
166cdf0e10cSrcweir // ------------------------------------------------------------------
167cdf0e10cSrcweir 
168cdf0e10cSrcweir BitmapEx::BitmapEx( const Bitmap& rBmp, const Color& rTransparentColor ) :
169cdf0e10cSrcweir 		aBitmap				( rBmp ),
170cdf0e10cSrcweir 		aBitmapSize			( aBitmap.GetSizePixel() ),
171cdf0e10cSrcweir 		aTransparentColor	( rTransparentColor ),
172cdf0e10cSrcweir 		eTransparent		( TRANSPARENT_BITMAP ),
173cdf0e10cSrcweir 		bAlpha				( sal_False )
174cdf0e10cSrcweir {
175cdf0e10cSrcweir 	aMask = aBitmap.CreateMask( aTransparentColor );
176cdf0e10cSrcweir 
177cdf0e10cSrcweir     DBG_ASSERT( rBmp.GetSizePixel() == aMask.GetSizePixel(),
178cdf0e10cSrcweir                 "BitmapEx::BitmapEx(): size mismatch for bitmap and alpha mask." );
179cdf0e10cSrcweir }
180cdf0e10cSrcweir 
181cdf0e10cSrcweir // ------------------------------------------------------------------
182cdf0e10cSrcweir 
183cdf0e10cSrcweir BitmapEx::~BitmapEx()
184cdf0e10cSrcweir {
185cdf0e10cSrcweir }
186cdf0e10cSrcweir 
187cdf0e10cSrcweir // ------------------------------------------------------------------
188cdf0e10cSrcweir 
189cdf0e10cSrcweir // ------------------------------------------------------------------
190cdf0e10cSrcweir 
191cdf0e10cSrcweir BitmapEx& BitmapEx::operator=( const BitmapEx& rBitmapEx )
192cdf0e10cSrcweir {
193cdf0e10cSrcweir 	if( &rBitmapEx != this )
194cdf0e10cSrcweir 	{
195cdf0e10cSrcweir 		aBitmap = rBitmapEx.aBitmap;
196cdf0e10cSrcweir 		aMask = rBitmapEx.aMask;
197cdf0e10cSrcweir 		aBitmapSize = rBitmapEx.aBitmapSize;
198cdf0e10cSrcweir 		aTransparentColor = rBitmapEx.aTransparentColor;
199cdf0e10cSrcweir 		eTransparent = rBitmapEx.eTransparent;
200cdf0e10cSrcweir 		bAlpha = rBitmapEx.bAlpha;
201cdf0e10cSrcweir 	}
202cdf0e10cSrcweir 
203cdf0e10cSrcweir 	return *this;
204cdf0e10cSrcweir }
205cdf0e10cSrcweir 
206cdf0e10cSrcweir // ------------------------------------------------------------------
207cdf0e10cSrcweir 
208cdf0e10cSrcweir sal_Bool BitmapEx::operator==( const BitmapEx& rBitmapEx ) const
209cdf0e10cSrcweir {
210cdf0e10cSrcweir 	if( eTransparent != rBitmapEx.eTransparent )
211cdf0e10cSrcweir 		return sal_False;
212cdf0e10cSrcweir 
213cdf0e10cSrcweir 	if( aBitmap != rBitmapEx.aBitmap )
214cdf0e10cSrcweir 		return sal_False;
215cdf0e10cSrcweir 
216cdf0e10cSrcweir 	if( aBitmapSize != rBitmapEx.aBitmapSize )
217cdf0e10cSrcweir 		return sal_False;
218cdf0e10cSrcweir 
219cdf0e10cSrcweir 	if( eTransparent == TRANSPARENT_NONE )
220cdf0e10cSrcweir 		return sal_True;
221cdf0e10cSrcweir 
222cdf0e10cSrcweir 	if( eTransparent == TRANSPARENT_COLOR )
223cdf0e10cSrcweir 		return aTransparentColor == rBitmapEx.aTransparentColor;
224cdf0e10cSrcweir 
225cdf0e10cSrcweir 	return( ( aMask == rBitmapEx.aMask ) && ( bAlpha == rBitmapEx.bAlpha ) );
226cdf0e10cSrcweir }
227cdf0e10cSrcweir 
228cdf0e10cSrcweir // ------------------------------------------------------------------
229cdf0e10cSrcweir 
230cdf0e10cSrcweir sal_Bool BitmapEx::IsEqual( const BitmapEx& rBmpEx ) const
231cdf0e10cSrcweir {
232cdf0e10cSrcweir 	return( rBmpEx.eTransparent == eTransparent &&
233cdf0e10cSrcweir 			rBmpEx.bAlpha == bAlpha &&
234cdf0e10cSrcweir 			rBmpEx.aBitmap.IsEqual( aBitmap ) &&
235cdf0e10cSrcweir 			rBmpEx.aMask.IsEqual( aMask ) );
236cdf0e10cSrcweir }
237cdf0e10cSrcweir 
238cdf0e10cSrcweir // ------------------------------------------------------------------
239cdf0e10cSrcweir 
240cdf0e10cSrcweir sal_Bool BitmapEx::IsEmpty() const
241cdf0e10cSrcweir {
242cdf0e10cSrcweir 	return( aBitmap.IsEmpty() && aMask.IsEmpty() );
243cdf0e10cSrcweir }
244cdf0e10cSrcweir 
245cdf0e10cSrcweir // ------------------------------------------------------------------
246cdf0e10cSrcweir 
247cdf0e10cSrcweir void BitmapEx::SetEmpty()
248cdf0e10cSrcweir {
249cdf0e10cSrcweir 	aBitmap.SetEmpty();
250cdf0e10cSrcweir 	aMask.SetEmpty();
251cdf0e10cSrcweir 	eTransparent = TRANSPARENT_NONE;
252cdf0e10cSrcweir 	bAlpha = sal_False;
253cdf0e10cSrcweir }
254cdf0e10cSrcweir 
255cdf0e10cSrcweir // ------------------------------------------------------------------
256cdf0e10cSrcweir 
257cdf0e10cSrcweir void BitmapEx::Clear()
258cdf0e10cSrcweir {
259cdf0e10cSrcweir 	SetEmpty();
260cdf0e10cSrcweir }
261cdf0e10cSrcweir 
262cdf0e10cSrcweir // ------------------------------------------------------------------
263cdf0e10cSrcweir 
264cdf0e10cSrcweir sal_Bool BitmapEx::IsTransparent() const
265cdf0e10cSrcweir {
266cdf0e10cSrcweir 	return( eTransparent != TRANSPARENT_NONE );
267cdf0e10cSrcweir }
268cdf0e10cSrcweir 
269cdf0e10cSrcweir // ------------------------------------------------------------------
270cdf0e10cSrcweir 
271cdf0e10cSrcweir sal_Bool BitmapEx::IsAlpha() const
272cdf0e10cSrcweir {
273cdf0e10cSrcweir 	return( IsTransparent() && bAlpha );
274cdf0e10cSrcweir }
275cdf0e10cSrcweir 
276cdf0e10cSrcweir // ------------------------------------------------------------------
277cdf0e10cSrcweir 
278cdf0e10cSrcweir Bitmap BitmapEx::GetBitmap( const Color* pTransReplaceColor ) const
279cdf0e10cSrcweir {
280cdf0e10cSrcweir 	Bitmap aRetBmp( aBitmap );
281cdf0e10cSrcweir 
282cdf0e10cSrcweir 	if( pTransReplaceColor && ( eTransparent != TRANSPARENT_NONE ) )
283cdf0e10cSrcweir 	{
284cdf0e10cSrcweir 		Bitmap aTempMask;
285cdf0e10cSrcweir 
286cdf0e10cSrcweir 		if( eTransparent == TRANSPARENT_COLOR )
287cdf0e10cSrcweir 			aTempMask = aBitmap.CreateMask( aTransparentColor );
288cdf0e10cSrcweir 		else
289cdf0e10cSrcweir 			aTempMask = aMask;
290cdf0e10cSrcweir 
291cdf0e10cSrcweir 		if( !IsAlpha() )
292cdf0e10cSrcweir 			aRetBmp.Replace( aTempMask, *pTransReplaceColor );
293cdf0e10cSrcweir 		else
294cdf0e10cSrcweir 			aRetBmp.Replace( GetAlpha(), *pTransReplaceColor );
295cdf0e10cSrcweir 	}
296cdf0e10cSrcweir 
297cdf0e10cSrcweir 	return aRetBmp;
298cdf0e10cSrcweir }
299cdf0e10cSrcweir 
300cdf0e10cSrcweir // ------------------------------------------------------------------
301cdf0e10cSrcweir 
302cdf0e10cSrcweir BitmapEx BitmapEx::GetColorTransformedBitmapEx( BmpColorMode eColorMode ) const
303cdf0e10cSrcweir {
304cdf0e10cSrcweir 	BitmapEx aRet;
305cdf0e10cSrcweir 
306cdf0e10cSrcweir 	if( BMP_COLOR_HIGHCONTRAST == eColorMode )
307cdf0e10cSrcweir 	{
308cdf0e10cSrcweir 		aRet = *this;
309cdf0e10cSrcweir 		aRet.aBitmap = aBitmap.GetColorTransformedBitmap( eColorMode );
310cdf0e10cSrcweir 	}
311cdf0e10cSrcweir 	else if( BMP_COLOR_MONOCHROME_BLACK == eColorMode ||
312cdf0e10cSrcweir 			 BMP_COLOR_MONOCHROME_WHITE == eColorMode )
313cdf0e10cSrcweir 	{
314cdf0e10cSrcweir 		aRet = *this;
315cdf0e10cSrcweir 		aRet.aBitmap = aRet.aBitmap.GetColorTransformedBitmap( eColorMode );
316cdf0e10cSrcweir 
317cdf0e10cSrcweir 		if( !aRet.aMask.IsEmpty() )
318cdf0e10cSrcweir 		{
319cdf0e10cSrcweir 			aRet.aMask.CombineSimple( aRet.aBitmap, BMP_COMBINE_OR );
320cdf0e10cSrcweir 			aRet.aBitmap.Erase( ( BMP_COLOR_MONOCHROME_BLACK == eColorMode ) ? COL_BLACK : COL_WHITE );
321cdf0e10cSrcweir 
322cdf0e10cSrcweir             DBG_ASSERT( aRet.aBitmap.GetSizePixel() == aRet.aMask.GetSizePixel(),
323cdf0e10cSrcweir                         "BitmapEx::GetColorTransformedBitmapEx(): size mismatch for bitmap and alpha mask." );
324cdf0e10cSrcweir 		}
325cdf0e10cSrcweir 	}
326cdf0e10cSrcweir 
327cdf0e10cSrcweir 	return aRet;
328cdf0e10cSrcweir }
329cdf0e10cSrcweir 
330cdf0e10cSrcweir // ------------------------------------------------------------------
331cdf0e10cSrcweir 
332cdf0e10cSrcweir Bitmap BitmapEx::GetMask() const
333cdf0e10cSrcweir {
334cdf0e10cSrcweir 	Bitmap aRet( aMask );
335cdf0e10cSrcweir 
336cdf0e10cSrcweir 	if( IsAlpha() )
337cdf0e10cSrcweir 		aRet.ImplMakeMono( 255 );
338cdf0e10cSrcweir 
339cdf0e10cSrcweir 	return aRet;
340cdf0e10cSrcweir }
341cdf0e10cSrcweir 
342cdf0e10cSrcweir // ------------------------------------------------------------------
343cdf0e10cSrcweir 
344cdf0e10cSrcweir AlphaMask BitmapEx::GetAlpha() const
345cdf0e10cSrcweir {
346cdf0e10cSrcweir 	AlphaMask aAlpha;
347cdf0e10cSrcweir 
348cdf0e10cSrcweir 	if( IsAlpha() )
349cdf0e10cSrcweir 		aAlpha.ImplSetBitmap( aMask );
350cdf0e10cSrcweir 	else
351cdf0e10cSrcweir 		aAlpha = aMask;
352cdf0e10cSrcweir 
353cdf0e10cSrcweir 	return aAlpha;
354cdf0e10cSrcweir }
355cdf0e10cSrcweir 
356cdf0e10cSrcweir // ------------------------------------------------------------------
357cdf0e10cSrcweir 
358cdf0e10cSrcweir sal_uLong BitmapEx::GetSizeBytes() const
359cdf0e10cSrcweir {
360cdf0e10cSrcweir 	sal_uLong nSizeBytes = aBitmap.GetSizeBytes();
361cdf0e10cSrcweir 
362cdf0e10cSrcweir 	if( eTransparent == TRANSPARENT_BITMAP )
363cdf0e10cSrcweir 		nSizeBytes += aMask.GetSizeBytes();
364cdf0e10cSrcweir 
365cdf0e10cSrcweir 	return nSizeBytes;
366cdf0e10cSrcweir }
367cdf0e10cSrcweir 
368cdf0e10cSrcweir // ------------------------------------------------------------------
369cdf0e10cSrcweir 
370cdf0e10cSrcweir sal_uLong BitmapEx::GetChecksum() const
371cdf0e10cSrcweir {
372cdf0e10cSrcweir 	sal_uInt32	nCrc = aBitmap.GetChecksum();
373cdf0e10cSrcweir 	SVBT32		aBT32;
374cdf0e10cSrcweir 
375cdf0e10cSrcweir 	UInt32ToSVBT32( (long) eTransparent, aBT32 );
376cdf0e10cSrcweir 	nCrc = rtl_crc32( nCrc, aBT32, 4 );
377cdf0e10cSrcweir 
378cdf0e10cSrcweir 	UInt32ToSVBT32( (long) bAlpha, aBT32 );
379cdf0e10cSrcweir 	nCrc = rtl_crc32( nCrc, aBT32, 4 );
380cdf0e10cSrcweir 
381cdf0e10cSrcweir 	if( ( TRANSPARENT_BITMAP == eTransparent ) && !aMask.IsEmpty() )
382cdf0e10cSrcweir 	{
383cdf0e10cSrcweir 		UInt32ToSVBT32( aMask.GetChecksum(), aBT32 );
384cdf0e10cSrcweir 		nCrc = rtl_crc32( nCrc, aBT32, 4 );
385cdf0e10cSrcweir 	}
386cdf0e10cSrcweir 
387cdf0e10cSrcweir 	return nCrc;
388cdf0e10cSrcweir }
389cdf0e10cSrcweir 
390cdf0e10cSrcweir // ------------------------------------------------------------------
391cdf0e10cSrcweir 
39254628ca4SArmin Le Grand void BitmapEx::SetSizePixel( const Size& rNewSize, sal_uInt32 nScaleFlag )
393cdf0e10cSrcweir {
39454628ca4SArmin Le Grand     if(GetSizePixel() != rNewSize)
39554628ca4SArmin Le Grand     {
39654628ca4SArmin Le Grand         Scale( rNewSize, nScaleFlag );
39754628ca4SArmin Le Grand     }
398cdf0e10cSrcweir }
399cdf0e10cSrcweir 
400cdf0e10cSrcweir // ------------------------------------------------------------------
401cdf0e10cSrcweir 
402cdf0e10cSrcweir sal_Bool BitmapEx::Invert()
403cdf0e10cSrcweir {
404cdf0e10cSrcweir 	sal_Bool bRet = sal_False;
405cdf0e10cSrcweir 
406cdf0e10cSrcweir 	if( !!aBitmap )
407cdf0e10cSrcweir 	{
408cdf0e10cSrcweir 		bRet = aBitmap.Invert();
409cdf0e10cSrcweir 
410cdf0e10cSrcweir 		if( bRet && ( eTransparent == TRANSPARENT_COLOR ) )
411cdf0e10cSrcweir 			aTransparentColor = BitmapColor( aTransparentColor ).Invert();
412cdf0e10cSrcweir 	}
413cdf0e10cSrcweir 
414cdf0e10cSrcweir 	return bRet;
415cdf0e10cSrcweir }
416cdf0e10cSrcweir 
417cdf0e10cSrcweir // ------------------------------------------------------------------
418cdf0e10cSrcweir 
419cdf0e10cSrcweir sal_Bool BitmapEx::Mirror( sal_uLong nMirrorFlags )
420cdf0e10cSrcweir {
421cdf0e10cSrcweir 	sal_Bool bRet = sal_False;
422cdf0e10cSrcweir 
423cdf0e10cSrcweir 	if( !!aBitmap )
424cdf0e10cSrcweir 	{
425cdf0e10cSrcweir 		bRet = aBitmap.Mirror( nMirrorFlags );
426cdf0e10cSrcweir 
427cdf0e10cSrcweir 		if( bRet && ( eTransparent == TRANSPARENT_BITMAP ) && !!aMask )
428cdf0e10cSrcweir 			aMask.Mirror( nMirrorFlags );
429cdf0e10cSrcweir 	}
430cdf0e10cSrcweir 
431cdf0e10cSrcweir 	return bRet;
432cdf0e10cSrcweir }
433cdf0e10cSrcweir 
434cdf0e10cSrcweir // ------------------------------------------------------------------
435cdf0e10cSrcweir 
43654628ca4SArmin Le Grand sal_Bool BitmapEx::Scale( const double& rScaleX, const double& rScaleY, sal_uInt32 nScaleFlag )
437cdf0e10cSrcweir {
438cdf0e10cSrcweir 	sal_Bool bRet = sal_False;
439cdf0e10cSrcweir 
440cdf0e10cSrcweir 	if( !!aBitmap )
441cdf0e10cSrcweir 	{
442cdf0e10cSrcweir 		bRet = aBitmap.Scale( rScaleX, rScaleY, nScaleFlag );
443cdf0e10cSrcweir 
444cdf0e10cSrcweir 		if( bRet && ( eTransparent == TRANSPARENT_BITMAP ) && !!aMask )
44537ab0f2dSArmin Le Grand         {
44637ab0f2dSArmin Le Grand 			aMask.Scale( rScaleX, rScaleY, nScaleFlag );
44737ab0f2dSArmin Le Grand         }
448cdf0e10cSrcweir 
449cdf0e10cSrcweir 		aBitmapSize = aBitmap.GetSizePixel();
450cdf0e10cSrcweir 
451cdf0e10cSrcweir         DBG_ASSERT( !aMask || aBitmap.GetSizePixel() == aMask.GetSizePixel(),
452cdf0e10cSrcweir                     "BitmapEx::Scale(): size mismatch for bitmap and alpha mask." );
453cdf0e10cSrcweir 	}
454cdf0e10cSrcweir 
455cdf0e10cSrcweir 	return bRet;
456cdf0e10cSrcweir }
457cdf0e10cSrcweir 
458cdf0e10cSrcweir // ------------------------------------------------------------------------
459cdf0e10cSrcweir 
46054628ca4SArmin Le Grand sal_Bool BitmapEx::Scale( const Size& rNewSize, sal_uInt32 nScaleFlag )
461cdf0e10cSrcweir {
462cdf0e10cSrcweir 	sal_Bool bRet;
463cdf0e10cSrcweir 
464cdf0e10cSrcweir 	if( aBitmapSize.Width() && aBitmapSize.Height() )
465cdf0e10cSrcweir 	{
466cdf0e10cSrcweir 		bRet = Scale( (double) rNewSize.Width() / aBitmapSize.Width(),
467cdf0e10cSrcweir 					  (double) rNewSize.Height() / aBitmapSize.Height(),
468cdf0e10cSrcweir 					  nScaleFlag );
469cdf0e10cSrcweir 	}
470cdf0e10cSrcweir 	else
471cdf0e10cSrcweir 		bRet = sal_True;
472cdf0e10cSrcweir 
473cdf0e10cSrcweir 	return bRet;
474cdf0e10cSrcweir }
475cdf0e10cSrcweir 
476cdf0e10cSrcweir // ------------------------------------------------------------------
477cdf0e10cSrcweir 
478cdf0e10cSrcweir sal_Bool BitmapEx::Rotate( long nAngle10, const Color& rFillColor )
479cdf0e10cSrcweir {
480cdf0e10cSrcweir 	sal_Bool bRet = sal_False;
481cdf0e10cSrcweir 
482cdf0e10cSrcweir 	if( !!aBitmap )
483cdf0e10cSrcweir 	{
484cdf0e10cSrcweir 		const sal_Bool bTransRotate = ( Color( COL_TRANSPARENT ) == rFillColor );
485cdf0e10cSrcweir 
486cdf0e10cSrcweir 		if( bTransRotate )
487cdf0e10cSrcweir 		{
488cdf0e10cSrcweir 			if( eTransparent == TRANSPARENT_COLOR )
489cdf0e10cSrcweir 				bRet = aBitmap.Rotate( nAngle10, aTransparentColor );
490cdf0e10cSrcweir 			else
491cdf0e10cSrcweir 			{
492cdf0e10cSrcweir 				bRet = aBitmap.Rotate( nAngle10, COL_BLACK );
493cdf0e10cSrcweir 
494cdf0e10cSrcweir 				if( eTransparent == TRANSPARENT_NONE )
495cdf0e10cSrcweir 				{
496cdf0e10cSrcweir 					aMask = Bitmap( aBitmapSize, 1 );
497cdf0e10cSrcweir 					aMask.Erase( COL_BLACK );
498cdf0e10cSrcweir 					eTransparent = TRANSPARENT_BITMAP;
499cdf0e10cSrcweir 				}
500cdf0e10cSrcweir 
501cdf0e10cSrcweir 				if( bRet && !!aMask )
502cdf0e10cSrcweir 					aMask.Rotate( nAngle10, COL_WHITE );
503cdf0e10cSrcweir 			}
504cdf0e10cSrcweir 		}
505cdf0e10cSrcweir 		else
506cdf0e10cSrcweir 		{
507cdf0e10cSrcweir 			bRet = aBitmap.Rotate( nAngle10, rFillColor );
508cdf0e10cSrcweir 
509cdf0e10cSrcweir 			if( bRet && ( eTransparent == TRANSPARENT_BITMAP ) && !!aMask )
510cdf0e10cSrcweir 				aMask.Rotate( nAngle10, COL_WHITE );
511cdf0e10cSrcweir 		}
512cdf0e10cSrcweir 
513cdf0e10cSrcweir 		aBitmapSize = aBitmap.GetSizePixel();
514cdf0e10cSrcweir 
515cdf0e10cSrcweir         DBG_ASSERT( !aMask || aBitmap.GetSizePixel() == aMask.GetSizePixel(),
516cdf0e10cSrcweir                     "BitmapEx::Rotate(): size mismatch for bitmap and alpha mask." );
517cdf0e10cSrcweir 	}
518cdf0e10cSrcweir 
519cdf0e10cSrcweir 	return bRet;
520cdf0e10cSrcweir }
521cdf0e10cSrcweir 
522cdf0e10cSrcweir // ------------------------------------------------------------------
523cdf0e10cSrcweir 
524cdf0e10cSrcweir sal_Bool BitmapEx::Crop( const Rectangle& rRectPixel )
525cdf0e10cSrcweir {
526cdf0e10cSrcweir 	sal_Bool bRet = sal_False;
527cdf0e10cSrcweir 
528cdf0e10cSrcweir 	if( !!aBitmap )
529cdf0e10cSrcweir 	{
530cdf0e10cSrcweir 		bRet = aBitmap.Crop( rRectPixel );
531cdf0e10cSrcweir 
532cdf0e10cSrcweir 		if( bRet && ( eTransparent == TRANSPARENT_BITMAP ) && !!aMask )
533cdf0e10cSrcweir 			aMask.Crop( rRectPixel );
534cdf0e10cSrcweir 
535cdf0e10cSrcweir 		aBitmapSize = aBitmap.GetSizePixel();
536cdf0e10cSrcweir 
537cdf0e10cSrcweir         DBG_ASSERT( !aMask || aBitmap.GetSizePixel() == aMask.GetSizePixel(),
538cdf0e10cSrcweir                     "BitmapEx::Crop(): size mismatch for bitmap and alpha mask." );
539cdf0e10cSrcweir 	}
540cdf0e10cSrcweir 
541cdf0e10cSrcweir 	return bRet;
542cdf0e10cSrcweir }
543cdf0e10cSrcweir 
544cdf0e10cSrcweir // ------------------------------------------------------------------
545cdf0e10cSrcweir 
546cdf0e10cSrcweir sal_Bool BitmapEx::Convert( BmpConversion eConversion )
547cdf0e10cSrcweir {
548cdf0e10cSrcweir 	return( !!aBitmap ? aBitmap.Convert( eConversion ) : sal_False );
549cdf0e10cSrcweir }
550cdf0e10cSrcweir 
551cdf0e10cSrcweir // ------------------------------------------------------------------
552cdf0e10cSrcweir 
553cdf0e10cSrcweir sal_Bool BitmapEx::ReduceColors( sal_uInt16 nNewColorCount, BmpReduce eReduce )
554cdf0e10cSrcweir {
555cdf0e10cSrcweir 	return( !!aBitmap ? aBitmap.ReduceColors( nNewColorCount, eReduce ) : sal_False );
556cdf0e10cSrcweir }
557cdf0e10cSrcweir 
558cdf0e10cSrcweir // ------------------------------------------------------------------
559cdf0e10cSrcweir 
560cdf0e10cSrcweir sal_Bool BitmapEx::Expand( sal_uLong nDX, sal_uLong nDY, const Color* pInitColor, sal_Bool bExpandTransparent )
561cdf0e10cSrcweir {
562cdf0e10cSrcweir 	sal_Bool bRet = sal_False;
563cdf0e10cSrcweir 
564cdf0e10cSrcweir 	if( !!aBitmap )
565cdf0e10cSrcweir 	{
566cdf0e10cSrcweir 		bRet = aBitmap.Expand( nDX, nDY, pInitColor );
567cdf0e10cSrcweir 
568cdf0e10cSrcweir 		if( bRet && ( eTransparent == TRANSPARENT_BITMAP ) && !!aMask )
569cdf0e10cSrcweir 		{
570cdf0e10cSrcweir 			Color aColor( bExpandTransparent ? COL_WHITE : COL_BLACK );
571cdf0e10cSrcweir 			aMask.Expand( nDX, nDY, &aColor );
572cdf0e10cSrcweir 		}
573cdf0e10cSrcweir 
574cdf0e10cSrcweir 		aBitmapSize = aBitmap.GetSizePixel();
575cdf0e10cSrcweir 
576cdf0e10cSrcweir         DBG_ASSERT( !aMask || aBitmap.GetSizePixel() == aMask.GetSizePixel(),
577cdf0e10cSrcweir                     "BitmapEx::Expand(): size mismatch for bitmap and alpha mask." );
578cdf0e10cSrcweir 	}
579cdf0e10cSrcweir 
580cdf0e10cSrcweir 	return bRet;
581cdf0e10cSrcweir }
582cdf0e10cSrcweir 
583cdf0e10cSrcweir // ------------------------------------------------------------------
584cdf0e10cSrcweir 
585cdf0e10cSrcweir sal_Bool BitmapEx::CopyPixel( const Rectangle& rRectDst, const Rectangle& rRectSrc,
586cdf0e10cSrcweir 						  const BitmapEx* pBmpExSrc )
587cdf0e10cSrcweir {
588cdf0e10cSrcweir 	sal_Bool bRet = sal_False;
589cdf0e10cSrcweir 
590cdf0e10cSrcweir 	if( !pBmpExSrc || pBmpExSrc->IsEmpty() )
591cdf0e10cSrcweir 	{
592cdf0e10cSrcweir 		if( !aBitmap.IsEmpty() )
593cdf0e10cSrcweir 		{
594cdf0e10cSrcweir 			bRet = aBitmap.CopyPixel( rRectDst, rRectSrc );
595cdf0e10cSrcweir 
596cdf0e10cSrcweir 			if( bRet && ( eTransparent == TRANSPARENT_BITMAP ) && !!aMask )
597cdf0e10cSrcweir 				aMask.CopyPixel( rRectDst, rRectSrc );
598cdf0e10cSrcweir 		}
599cdf0e10cSrcweir 	}
600cdf0e10cSrcweir 	else
601cdf0e10cSrcweir 	{
602cdf0e10cSrcweir 		if( !aBitmap.IsEmpty() )
603cdf0e10cSrcweir 		{
604cdf0e10cSrcweir 			bRet = aBitmap.CopyPixel( rRectDst, rRectSrc, &pBmpExSrc->aBitmap );
605cdf0e10cSrcweir 
606cdf0e10cSrcweir 			if( bRet )
607cdf0e10cSrcweir 			{
608cdf0e10cSrcweir 				if( pBmpExSrc->IsAlpha() )
609cdf0e10cSrcweir 				{
610cdf0e10cSrcweir 					if( IsAlpha() )
611cdf0e10cSrcweir                         // cast to use the optimized AlphaMask::CopyPixel
612cdf0e10cSrcweir 						((AlphaMask*) &aMask)->CopyPixel( rRectDst, rRectSrc, (AlphaMask*)&pBmpExSrc->aMask );
613cdf0e10cSrcweir 					else if( IsTransparent() )
614cdf0e10cSrcweir 					{
615cdf0e10cSrcweir 						AlphaMask* pAlpha = new AlphaMask( aMask );
616cdf0e10cSrcweir 
617cdf0e10cSrcweir 						aMask = pAlpha->ImplGetBitmap();
618cdf0e10cSrcweir 						delete pAlpha;
619cdf0e10cSrcweir 						bAlpha = sal_True;
620cdf0e10cSrcweir 						aMask.CopyPixel( rRectDst, rRectSrc, &pBmpExSrc->aMask );
621cdf0e10cSrcweir 					}
622cdf0e10cSrcweir 					else
623cdf0e10cSrcweir 					{
624cdf0e10cSrcweir 						sal_uInt8	cBlack = 0;
625cdf0e10cSrcweir 						AlphaMask*	pAlpha = new AlphaMask( GetSizePixel(), &cBlack );
626cdf0e10cSrcweir 
627cdf0e10cSrcweir 						aMask = pAlpha->ImplGetBitmap();
628cdf0e10cSrcweir 						delete pAlpha;
629cdf0e10cSrcweir 						eTransparent = TRANSPARENT_BITMAP;
630cdf0e10cSrcweir 						bAlpha = sal_True;
631cdf0e10cSrcweir 						aMask.CopyPixel( rRectDst, rRectSrc, &pBmpExSrc->aMask );
632cdf0e10cSrcweir 					}
633cdf0e10cSrcweir 				}
634cdf0e10cSrcweir 				else if( pBmpExSrc->IsTransparent() )
635cdf0e10cSrcweir 				{
636cdf0e10cSrcweir 					if( IsAlpha() )
637cdf0e10cSrcweir 					{
638cdf0e10cSrcweir 						AlphaMask aAlpha( pBmpExSrc->aMask );
639cdf0e10cSrcweir 						aMask.CopyPixel( rRectDst, rRectSrc, &aAlpha.ImplGetBitmap() );
640cdf0e10cSrcweir 					}
641cdf0e10cSrcweir 					else if( IsTransparent() )
642cdf0e10cSrcweir 						aMask.CopyPixel( rRectDst, rRectSrc, &pBmpExSrc->aMask );
643cdf0e10cSrcweir 					else
644cdf0e10cSrcweir 					{
645cdf0e10cSrcweir 						aMask = Bitmap( GetSizePixel(), 1 );
646cdf0e10cSrcweir 						aMask.Erase( Color( COL_BLACK ) );
647cdf0e10cSrcweir 						eTransparent = TRANSPARENT_BITMAP;
648cdf0e10cSrcweir 						aMask.CopyPixel( rRectDst, rRectSrc, &pBmpExSrc->aMask );
649cdf0e10cSrcweir 					}
650cdf0e10cSrcweir 				}
651cdf0e10cSrcweir                 else if( IsAlpha() )
652cdf0e10cSrcweir                 {
653cdf0e10cSrcweir                     sal_uInt8	      cBlack = 0;
654cdf0e10cSrcweir                     const AlphaMask   aAlphaSrc( pBmpExSrc->GetSizePixel(), &cBlack );
655cdf0e10cSrcweir 
656cdf0e10cSrcweir                     aMask.CopyPixel( rRectDst, rRectSrc, &aAlphaSrc.ImplGetBitmap() );
657cdf0e10cSrcweir                 }
658cdf0e10cSrcweir                 else if( IsTransparent() )
659cdf0e10cSrcweir                 {
660cdf0e10cSrcweir                     Bitmap aMaskSrc( pBmpExSrc->GetSizePixel(), 1 );
661cdf0e10cSrcweir 
662cdf0e10cSrcweir                     aMaskSrc.Erase( Color( COL_BLACK ) );
663cdf0e10cSrcweir                     aMask.CopyPixel( rRectDst, rRectSrc, &aMaskSrc );
664cdf0e10cSrcweir                 }
665cdf0e10cSrcweir 			}
666cdf0e10cSrcweir 		}
667cdf0e10cSrcweir 	}
668cdf0e10cSrcweir 
669cdf0e10cSrcweir 	return bRet;
670cdf0e10cSrcweir }
671cdf0e10cSrcweir 
672cdf0e10cSrcweir // ------------------------------------------------------------------
673cdf0e10cSrcweir 
674cdf0e10cSrcweir sal_Bool BitmapEx::Erase( const Color& rFillColor )
675cdf0e10cSrcweir {
676cdf0e10cSrcweir 	sal_Bool bRet = sal_False;
677cdf0e10cSrcweir 
678cdf0e10cSrcweir 	if( !!aBitmap )
679cdf0e10cSrcweir 	{
680cdf0e10cSrcweir 		bRet = aBitmap.Erase( rFillColor );
681cdf0e10cSrcweir 
682cdf0e10cSrcweir 		if( bRet && ( eTransparent == TRANSPARENT_BITMAP ) && !!aMask )
683cdf0e10cSrcweir 		{
684cdf0e10cSrcweir             // #104416# Respect transparency on fill color
685cdf0e10cSrcweir             if( rFillColor.GetTransparency() )
686cdf0e10cSrcweir             {
687cdf0e10cSrcweir                 const Color aFill( rFillColor.GetTransparency(), rFillColor.GetTransparency(), rFillColor.GetTransparency() );
688cdf0e10cSrcweir                 aMask.Erase( aFill );
689cdf0e10cSrcweir             }
690cdf0e10cSrcweir             else
691cdf0e10cSrcweir             {
692cdf0e10cSrcweir                 const Color aBlack( COL_BLACK );
693cdf0e10cSrcweir                 aMask.Erase( aBlack );
694cdf0e10cSrcweir             }
695cdf0e10cSrcweir 		}
696cdf0e10cSrcweir 	}
697cdf0e10cSrcweir 
698cdf0e10cSrcweir 	return bRet;
699cdf0e10cSrcweir }
700cdf0e10cSrcweir 
701cdf0e10cSrcweir // ------------------------------------------------------------------
702cdf0e10cSrcweir 
703cdf0e10cSrcweir sal_Bool BitmapEx::Dither( sal_uLong nDitherFlags )
704cdf0e10cSrcweir {
705cdf0e10cSrcweir 	return( !!aBitmap ? aBitmap.Dither( nDitherFlags ) : sal_False );
706cdf0e10cSrcweir }
707cdf0e10cSrcweir 
708cdf0e10cSrcweir // ------------------------------------------------------------------
709cdf0e10cSrcweir 
710cdf0e10cSrcweir sal_Bool BitmapEx::Replace( const Color& rSearchColor, const Color& rReplaceColor, sal_uLong nTol )
711cdf0e10cSrcweir {
712cdf0e10cSrcweir 	return( !!aBitmap ? aBitmap.Replace( rSearchColor, rReplaceColor, nTol ) : sal_False );
713cdf0e10cSrcweir }
714cdf0e10cSrcweir 
715cdf0e10cSrcweir // ------------------------------------------------------------------
716cdf0e10cSrcweir 
717cdf0e10cSrcweir sal_Bool BitmapEx::Replace( const Color* pSearchColors, const Color* pReplaceColors, sal_uLong nColorCount, const sal_uLong* pTols )
718cdf0e10cSrcweir {
719cdf0e10cSrcweir 	return( !!aBitmap ? aBitmap.Replace( pSearchColors, pReplaceColors, nColorCount, (sal_uLong*) pTols ) : sal_False );
720cdf0e10cSrcweir }
721cdf0e10cSrcweir 
722cdf0e10cSrcweir // ------------------------------------------------------------------
723cdf0e10cSrcweir 
724cdf0e10cSrcweir sal_Bool BitmapEx::Adjust( short nLuminancePercent, short nContrastPercent,
725cdf0e10cSrcweir 					   short nChannelRPercent, short nChannelGPercent, short nChannelBPercent,
726cdf0e10cSrcweir 					   double fGamma, sal_Bool bInvert )
727cdf0e10cSrcweir {
728cdf0e10cSrcweir 	return( !!aBitmap ? aBitmap.Adjust( nLuminancePercent, nContrastPercent,
729cdf0e10cSrcweir 										nChannelRPercent, nChannelGPercent, nChannelBPercent,
730cdf0e10cSrcweir 										fGamma, bInvert ) : sal_False );
731cdf0e10cSrcweir }
732cdf0e10cSrcweir 
733cdf0e10cSrcweir // ------------------------------------------------------------------
734cdf0e10cSrcweir 
735cdf0e10cSrcweir sal_Bool BitmapEx::Filter( BmpFilter eFilter, const BmpFilterParam* pFilterParam, const Link* pProgress )
736cdf0e10cSrcweir {
737cdf0e10cSrcweir 	return( !!aBitmap ? aBitmap.Filter( eFilter, pFilterParam, pProgress ) : sal_False );
738cdf0e10cSrcweir }
739cdf0e10cSrcweir 
740cdf0e10cSrcweir // ------------------------------------------------------------------
741cdf0e10cSrcweir 
742cdf0e10cSrcweir void BitmapEx::Draw( OutputDevice* pOutDev, const Point& rDestPt ) const
743cdf0e10cSrcweir {
744cdf0e10cSrcweir 	pOutDev->DrawBitmapEx( rDestPt, *this );
745cdf0e10cSrcweir }
746cdf0e10cSrcweir 
747cdf0e10cSrcweir // ------------------------------------------------------------------
748cdf0e10cSrcweir 
749cdf0e10cSrcweir void BitmapEx::Draw( OutputDevice* pOutDev,
750cdf0e10cSrcweir 					 const Point& rDestPt, const Size& rDestSize ) const
751cdf0e10cSrcweir {
752cdf0e10cSrcweir 	pOutDev->DrawBitmapEx( rDestPt, rDestSize, *this );
753cdf0e10cSrcweir }
754cdf0e10cSrcweir 
755cdf0e10cSrcweir // ------------------------------------------------------------------
756cdf0e10cSrcweir 
757cdf0e10cSrcweir void BitmapEx::Draw( OutputDevice* pOutDev,
758cdf0e10cSrcweir 					 const Point& rDestPt, const Size& rDestSize,
759cdf0e10cSrcweir 					 const Point& rSrcPtPixel, const Size& rSrcSizePixel ) const
760cdf0e10cSrcweir {
761cdf0e10cSrcweir 	pOutDev->DrawBitmapEx( rDestPt, rDestSize, rSrcPtPixel, rSrcSizePixel, *this );
762cdf0e10cSrcweir }
763cdf0e10cSrcweir 
764cdf0e10cSrcweir // ------------------------------------------------------------------
765cdf0e10cSrcweir 
766cdf0e10cSrcweir sal_uInt8 BitmapEx::GetTransparency(sal_Int32 nX, sal_Int32 nY) const
767cdf0e10cSrcweir {
768cdf0e10cSrcweir     sal_uInt8 nTransparency(0xff);
769cdf0e10cSrcweir 
770cdf0e10cSrcweir     if(!aBitmap.IsEmpty())
771cdf0e10cSrcweir     {
772cdf0e10cSrcweir         if(nX >= 0 && nX < aBitmapSize.Width() && nY >= 0 && nY < aBitmapSize.Height())
773cdf0e10cSrcweir         {
774cdf0e10cSrcweir             switch(eTransparent)
775cdf0e10cSrcweir             {
776cdf0e10cSrcweir                 case TRANSPARENT_NONE:
777cdf0e10cSrcweir                 {
778cdf0e10cSrcweir                     // not transparent, ergo all covered
779cdf0e10cSrcweir                     nTransparency = 0x00;
780cdf0e10cSrcweir                     break;
781cdf0e10cSrcweir                 }
782cdf0e10cSrcweir                 case TRANSPARENT_COLOR:
783cdf0e10cSrcweir                 {
784cdf0e10cSrcweir                     Bitmap aTestBitmap(aBitmap);
785cdf0e10cSrcweir                     BitmapReadAccess* pRead = aTestBitmap.AcquireReadAccess();
786cdf0e10cSrcweir 
787cdf0e10cSrcweir                     if(pRead)
788cdf0e10cSrcweir                     {
789cdf0e10cSrcweir                         const Color aColor = pRead->GetColor(nY, nX);
790cdf0e10cSrcweir 
791cdf0e10cSrcweir                         // if color is not equal to TransparentColor, we are not transparent
792cdf0e10cSrcweir                         if(aColor != aTransparentColor)
793cdf0e10cSrcweir                         {
794cdf0e10cSrcweir                             nTransparency = 0x00;
795cdf0e10cSrcweir                         }
796cdf0e10cSrcweir 
797cdf0e10cSrcweir                         aTestBitmap.ReleaseAccess(pRead);
798cdf0e10cSrcweir                     }
799cdf0e10cSrcweir                     break;
800cdf0e10cSrcweir                 }
801cdf0e10cSrcweir                 case TRANSPARENT_BITMAP:
802cdf0e10cSrcweir                 {
803cdf0e10cSrcweir                     if(!aMask.IsEmpty())
804cdf0e10cSrcweir                     {
805cdf0e10cSrcweir                         Bitmap aTestBitmap(aMask);
806cdf0e10cSrcweir                         BitmapReadAccess* pRead = aTestBitmap.AcquireReadAccess();
807cdf0e10cSrcweir 
808cdf0e10cSrcweir                         if(pRead)
809cdf0e10cSrcweir                         {
810cdf0e10cSrcweir                             const BitmapColor aBitmapColor(pRead->GetPixel(nY, nX));
811cdf0e10cSrcweir 
812cdf0e10cSrcweir                             if(bAlpha)
813cdf0e10cSrcweir                             {
814cdf0e10cSrcweir                                 nTransparency = aBitmapColor.GetIndex();
815cdf0e10cSrcweir                             }
816cdf0e10cSrcweir                             else
817cdf0e10cSrcweir                             {
818cdf0e10cSrcweir                                 if(0x00 == aBitmapColor.GetIndex())
819cdf0e10cSrcweir                                 {
820cdf0e10cSrcweir                                     nTransparency = 0x00;
821cdf0e10cSrcweir                                 }
822cdf0e10cSrcweir                             }
823cdf0e10cSrcweir 
824cdf0e10cSrcweir                             aTestBitmap.ReleaseAccess(pRead);
825cdf0e10cSrcweir                         }
826cdf0e10cSrcweir                     }
827cdf0e10cSrcweir                     break;
828cdf0e10cSrcweir                 }
829cdf0e10cSrcweir             }
830cdf0e10cSrcweir         }
831cdf0e10cSrcweir     }
832cdf0e10cSrcweir 
833cdf0e10cSrcweir     return nTransparency;
834cdf0e10cSrcweir }
835cdf0e10cSrcweir 
8365f27b83cSArmin Le Grand // ------------------------------------------------------------------
8375f27b83cSArmin Le Grand 
8385f27b83cSArmin Le Grand namespace
8395f27b83cSArmin Le Grand {
8405f27b83cSArmin Le Grand 	void impSmoothPoint(BitmapColor& rValue, const basegfx::B2DPoint& rSource, sal_Int32 nIntX, sal_Int32 nIntY, BitmapReadAccess& rRead)
8415f27b83cSArmin Le Grand 	{
8425f27b83cSArmin Le Grand 		double fDeltaX(rSource.getX() - nIntX);
8435f27b83cSArmin Le Grand 		double fDeltaY(rSource.getY() - nIntY);
8445f27b83cSArmin Le Grand 		sal_Int32 nIndX(0L);
8455f27b83cSArmin Le Grand 		sal_Int32 nIndY(0L);
8465f27b83cSArmin Le Grand 
8475f27b83cSArmin Le Grand 		if(fDeltaX > 0.0 && nIntX + 1L < rRead.Width())
8485f27b83cSArmin Le Grand 		{
8495f27b83cSArmin Le Grand 			nIndX++;
8505f27b83cSArmin Le Grand 		}
8515f27b83cSArmin Le Grand 		else if(fDeltaX < 0.0 && nIntX >= 1L)
8525f27b83cSArmin Le Grand 		{
8535f27b83cSArmin Le Grand 			fDeltaX = -fDeltaX;
8545f27b83cSArmin Le Grand 			nIndX--;
8555f27b83cSArmin Le Grand 		}
8565f27b83cSArmin Le Grand 
8575f27b83cSArmin Le Grand 		if(fDeltaY > 0.0 && nIntY + 1L < rRead.Height())
8585f27b83cSArmin Le Grand 		{
8595f27b83cSArmin Le Grand 			nIndY++;
8605f27b83cSArmin Le Grand 		}
8615f27b83cSArmin Le Grand 		else if(fDeltaY < 0.0 && nIntY >= 1L)
8625f27b83cSArmin Le Grand 		{
8635f27b83cSArmin Le Grand 			fDeltaY = -fDeltaY;
8645f27b83cSArmin Le Grand 			nIndY--;
8655f27b83cSArmin Le Grand 		}
8665f27b83cSArmin Le Grand 
8675f27b83cSArmin Le Grand 		if(nIndX || nIndY)
8685f27b83cSArmin Le Grand 		{
8695f27b83cSArmin Le Grand 			const double fColorToReal(1.0 / 255.0);
8705f27b83cSArmin Le Grand 			double fR(rValue.GetRed() * fColorToReal);
8715f27b83cSArmin Le Grand 			double fG(rValue.GetGreen() * fColorToReal);
8725f27b83cSArmin Le Grand 			double fB(rValue.GetBlue() * fColorToReal);
8735f27b83cSArmin Le Grand 			double fRBottom(0.0), fGBottom(0.0), fBBottom(0.0);
8745f27b83cSArmin Le Grand 
8755f27b83cSArmin Le Grand 			if(nIndX)
8765f27b83cSArmin Le Grand 			{
8775f27b83cSArmin Le Grand 				const double fMulA(fDeltaX * fColorToReal);
8785f27b83cSArmin Le Grand 				double fMulB(1.0 - fDeltaX);
8795f27b83cSArmin Le Grand 				const BitmapColor aTopPartner(rRead.GetColor(nIntY, nIntX + nIndX));
8805f27b83cSArmin Le Grand 
8815f27b83cSArmin Le Grand 				fR = (fR * fMulB) + (aTopPartner.GetRed() * fMulA);
8825f27b83cSArmin Le Grand 				fG = (fG * fMulB) + (aTopPartner.GetGreen() * fMulA);
8835f27b83cSArmin Le Grand 				fB = (fB * fMulB) + (aTopPartner.GetBlue() * fMulA);
8845f27b83cSArmin Le Grand 
8855f27b83cSArmin Le Grand 				if(nIndY)
8865f27b83cSArmin Le Grand 				{
8875f27b83cSArmin Le Grand 					fMulB *= fColorToReal;
8885f27b83cSArmin Le Grand 					const BitmapColor aBottom(rRead.GetColor(nIntY + nIndY, nIntX));
8895f27b83cSArmin Le Grand 					const BitmapColor aBottomPartner(rRead.GetColor(nIntY + nIndY, nIntX + nIndX));
8905f27b83cSArmin Le Grand 
8915f27b83cSArmin Le Grand 					fRBottom = (aBottom.GetRed() * fMulB) + (aBottomPartner.GetRed() * fMulA);
8925f27b83cSArmin Le Grand 					fGBottom = (aBottom.GetGreen() * fMulB) + (aBottomPartner.GetGreen() * fMulA);
8935f27b83cSArmin Le Grand 					fBBottom = (aBottom.GetBlue() * fMulB) + (aBottomPartner.GetBlue() * fMulA);
8945f27b83cSArmin Le Grand 				}
8955f27b83cSArmin Le Grand 			}
8965f27b83cSArmin Le Grand 
8975f27b83cSArmin Le Grand 			if(nIndY)
8985f27b83cSArmin Le Grand 			{
8995f27b83cSArmin Le Grand 				if(!nIndX)
9005f27b83cSArmin Le Grand 				{
9015f27b83cSArmin Le Grand 					const BitmapColor aBottom(rRead.GetColor(nIntY + nIndY, nIntX));
9025f27b83cSArmin Le Grand 
9035f27b83cSArmin Le Grand 					fRBottom = aBottom.GetRed() * fColorToReal;
9045f27b83cSArmin Le Grand 					fGBottom = aBottom.GetGreen() * fColorToReal;
9055f27b83cSArmin Le Grand 					fBBottom = aBottom.GetBlue() * fColorToReal;
9065f27b83cSArmin Le Grand 				}
9075f27b83cSArmin Le Grand 
9085f27b83cSArmin Le Grand 				const double fMulB(1.0 - fDeltaY);
9095f27b83cSArmin Le Grand 
9105f27b83cSArmin Le Grand 				fR = (fR * fMulB) + (fRBottom * fDeltaY);
9115f27b83cSArmin Le Grand 				fG = (fG * fMulB) + (fGBottom * fDeltaY);
9125f27b83cSArmin Le Grand 				fB = (fB * fMulB) + (fBBottom * fDeltaY);
9135f27b83cSArmin Le Grand 			}
9145f27b83cSArmin Le Grand 
9155f27b83cSArmin Le Grand 			rValue.SetRed((sal_uInt8)(fR * 255.0));
9165f27b83cSArmin Le Grand 			rValue.SetGreen((sal_uInt8)(fG * 255.0));
9175f27b83cSArmin Le Grand 			rValue.SetBlue((sal_uInt8)(fB * 255.0));
9185f27b83cSArmin Le Grand 		}
9195f27b83cSArmin Le Grand 	}
9205f27b83cSArmin Le Grand 
9215f27b83cSArmin Le Grand 	Bitmap impTransformBitmap(
9225f27b83cSArmin Le Grand         const Bitmap& rSource,
9235f27b83cSArmin Le Grand         const Size aDestinationSize,
9245f27b83cSArmin Le Grand         const basegfx::B2DHomMatrix& rTransform,
9255f27b83cSArmin Le Grand         bool bSmooth)
9265f27b83cSArmin Le Grand 	{
9275f27b83cSArmin Le Grand         Bitmap aDestination(aDestinationSize, 24);
9285f27b83cSArmin Le Grand         BitmapWriteAccess* pWrite = aDestination.AcquireWriteAccess();
9295f27b83cSArmin Le Grand 
9305f27b83cSArmin Le Grand 		if(pWrite)
9315f27b83cSArmin Le Grand 		{
9325f27b83cSArmin Le Grand 			const Size aContentSizePixel(rSource.GetSizePixel());
9335f27b83cSArmin Le Grand 			BitmapReadAccess* pRead = (const_cast< Bitmap& >(rSource)).AcquireReadAccess();
9345f27b83cSArmin Le Grand 
9355f27b83cSArmin Le Grand 			if(pRead)
9365f27b83cSArmin Le Grand 			{
9375f27b83cSArmin Le Grand 				const Size aDestinationSizePixel(aDestination.GetSizePixel());
9385f27b83cSArmin Le Grand 				bool bWorkWithIndex(rSource.GetBitCount() <= 8);
9395f27b83cSArmin Le Grand 				BitmapColor aOutside(BitmapColor(0xff, 0xff, 0xff));
9405f27b83cSArmin Le Grand 
9415f27b83cSArmin Le Grand 				for(sal_Int32 y(0L); y < aDestinationSizePixel.getHeight(); y++)
9425f27b83cSArmin Le Grand 				{
9435f27b83cSArmin Le Grand 					for(sal_Int32 x(0L); x < aDestinationSizePixel.getWidth(); x++)
9445f27b83cSArmin Le Grand 					{
9455f27b83cSArmin Le Grand 						const basegfx::B2DPoint aSourceCoor(rTransform * basegfx::B2DPoint(x, y));
9465f27b83cSArmin Le Grand 						const sal_Int32 nIntX(basegfx::fround(aSourceCoor.getX()));
9475f27b83cSArmin Le Grand 
9485f27b83cSArmin Le Grand 						if(nIntX >= 0L && nIntX < aContentSizePixel.getWidth())
9495f27b83cSArmin Le Grand 						{
9505f27b83cSArmin Le Grand 							const sal_Int32 nIntY(basegfx::fround(aSourceCoor.getY()));
9515f27b83cSArmin Le Grand 
9525f27b83cSArmin Le Grand 							if(nIntY >= 0L && nIntY < aContentSizePixel.getHeight())
9535f27b83cSArmin Le Grand 							{
9545f27b83cSArmin Le Grand                                 // inside pixel
9555f27b83cSArmin Le Grand                                 BitmapColor aValue;
9565f27b83cSArmin Le Grand 
9575f27b83cSArmin Le Grand                                 if(bWorkWithIndex)
9585f27b83cSArmin Le Grand                                 {
9595f27b83cSArmin Le Grand                                     aValue = pRead->GetPaletteColor(pRead->GetPixelIndex(nIntY, nIntX));
9605f27b83cSArmin Le Grand                                 }
9615f27b83cSArmin Le Grand                                 else
9625f27b83cSArmin Le Grand                                 {
9635f27b83cSArmin Le Grand                                     aValue = pRead->GetPixel(nIntY, nIntX);
9645f27b83cSArmin Le Grand                                 }
9655f27b83cSArmin Le Grand 
9665f27b83cSArmin Le Grand                                 if(bSmooth)
9675f27b83cSArmin Le Grand                                 {
9685f27b83cSArmin Le Grand                                     impSmoothPoint(aValue, aSourceCoor, nIntX, nIntY, *pRead);
9695f27b83cSArmin Le Grand                                 }
9705f27b83cSArmin Le Grand 
9715f27b83cSArmin Le Grand                                 pWrite->SetPixel(y, x, aValue);
9725f27b83cSArmin Le Grand                                 continue;
9735f27b83cSArmin Le Grand 							}
9745f27b83cSArmin Le Grand 						}
9755f27b83cSArmin Le Grand 
9765f27b83cSArmin Le Grand 						// here are outside pixels. Complete mask
9775f27b83cSArmin Le Grand 						if(bWorkWithIndex)
9785f27b83cSArmin Le Grand 						{
9795f27b83cSArmin Le Grand 							pWrite->SetPixel(y, x, aOutside);
9805f27b83cSArmin Le Grand 						}
9815f27b83cSArmin Le Grand 					}
9825f27b83cSArmin Le Grand 				}
9835f27b83cSArmin Le Grand 
9845f27b83cSArmin Le Grand 				delete pRead;
9855f27b83cSArmin Le Grand 			}
9865f27b83cSArmin Le Grand 
9875f27b83cSArmin Le Grand 			delete pWrite;
9885f27b83cSArmin Le Grand 		}
9895f27b83cSArmin Le Grand 
9905f27b83cSArmin Le Grand         rSource.AdaptBitCount(aDestination);
9915f27b83cSArmin Le Grand 
9925f27b83cSArmin Le Grand         return aDestination;
9935f27b83cSArmin Le Grand 	}
9945f27b83cSArmin Le Grand } // end of anonymous namespace
9955f27b83cSArmin Le Grand BitmapEx BitmapEx::TransformBitmapEx(
9965f27b83cSArmin Le Grand     double fWidth,
9975f27b83cSArmin Le Grand     double fHeight,
9985f27b83cSArmin Le Grand     const basegfx::B2DHomMatrix& rTransformation) const
9995f27b83cSArmin Le Grand {
10005f27b83cSArmin Le Grand     if(fWidth <= 1 || fHeight <= 1)
10015f27b83cSArmin Le Grand         return BitmapEx();
10025f27b83cSArmin Le Grand 
10035f27b83cSArmin Le Grand     // force destination to 24 bit, we want to smooth output
10045f27b83cSArmin Le Grand     const Size aDestinationSize(basegfx::fround(fWidth), basegfx::fround(fHeight));
10055f27b83cSArmin Le Grand     static bool bDoSmoothAtAll(true);
10065f27b83cSArmin Le Grand     const Bitmap aDestination(impTransformBitmap(GetBitmap(), aDestinationSize, rTransformation, bDoSmoothAtAll));
10075f27b83cSArmin Le Grand 
10085f27b83cSArmin Le Grand     // create mask
10095f27b83cSArmin Le Grand     if(IsTransparent())
10105f27b83cSArmin Le Grand     {
10115f27b83cSArmin Le Grand         if(IsAlpha())
10125f27b83cSArmin Le Grand         {
10135f27b83cSArmin Le Grand             const Bitmap aAlpha(impTransformBitmap(GetAlpha().GetBitmap(), aDestinationSize, rTransformation, bDoSmoothAtAll));
10145f27b83cSArmin Le Grand             return BitmapEx(aDestination, AlphaMask(aAlpha));
10155f27b83cSArmin Le Grand         }
10165f27b83cSArmin Le Grand         else
10175f27b83cSArmin Le Grand         {
10185f27b83cSArmin Le Grand             const Bitmap aMask(impTransformBitmap(GetMask(), aDestinationSize, rTransformation, false));
10195f27b83cSArmin Le Grand             return BitmapEx(aDestination, aMask);
10205f27b83cSArmin Le Grand         }
10215f27b83cSArmin Le Grand     }
10225f27b83cSArmin Le Grand 
10235f27b83cSArmin Le Grand     return BitmapEx(aDestination);
10245f27b83cSArmin Le Grand }
10255f27b83cSArmin Le Grand 
10265f27b83cSArmin Le Grand // ------------------------------------------------------------------
10275f27b83cSArmin Le Grand 
10285f27b83cSArmin Le Grand BitmapEx BitmapEx::getTransformed(
10295f27b83cSArmin Le Grand     const basegfx::B2DHomMatrix& rTransformation,
10305f27b83cSArmin Le Grand     double fMaximumArea) const
10315f27b83cSArmin Le Grand {
10325f27b83cSArmin Le Grand     BitmapEx aRetval;
10335f27b83cSArmin Le Grand 
10345f27b83cSArmin Le Grand     if(IsEmpty())
10355f27b83cSArmin Le Grand         return aRetval;
10365f27b83cSArmin Le Grand 
10375f27b83cSArmin Le Grand     const sal_uInt32 nSourceWidth(GetSizePixel().Width());
10385f27b83cSArmin Le Grand     const sal_uInt32 nSourceHeight(GetSizePixel().Height());
10395f27b83cSArmin Le Grand 
10405f27b83cSArmin Le Grand     if(!nSourceWidth || !nSourceHeight)
10415f27b83cSArmin Le Grand         return aRetval;
10425f27b83cSArmin Le Grand 
10435f27b83cSArmin Le Grand     // Get dest range
10445f27b83cSArmin Le Grand     basegfx::B2DRange aOutlineRange(0.0, 0.0, 1.0, 1.0);
10455f27b83cSArmin Le Grand     aOutlineRange.transform(rTransformation);
10465f27b83cSArmin Le Grand 
10475f27b83cSArmin Le Grand     // get target size
10485f27b83cSArmin Le Grand     double fWidth(aOutlineRange.getWidth());
10495f27b83cSArmin Le Grand     double fHeight(aOutlineRange.getHeight());
10505f27b83cSArmin Le Grand 
10515f27b83cSArmin Le Grand     if(fWidth < 1.0 || fHeight < 1.0)
10525f27b83cSArmin Le Grand         return aRetval;
10535f27b83cSArmin Le Grand 
10545f27b83cSArmin Le Grand     // test if discrete size (pixel) maybe too big and limit it
10555f27b83cSArmin Le Grand     const double fArea(fWidth * fHeight);
10565f27b83cSArmin Le Grand     const bool bNeedToReduce(fArea > fMaximumArea);
10575f27b83cSArmin Le Grand     double fReduceFactor(1.0);
10585f27b83cSArmin Le Grand 
10595f27b83cSArmin Le Grand     if(bNeedToReduce)
10605f27b83cSArmin Le Grand     {
10615f27b83cSArmin Le Grand         fReduceFactor = sqrt(fMaximumArea / fArea);
10625f27b83cSArmin Le Grand         fWidth *= fReduceFactor;
10635f27b83cSArmin Le Grand         fHeight *= fReduceFactor;
10645f27b83cSArmin Le Grand     }
10655f27b83cSArmin Le Grand 
10665f27b83cSArmin Le Grand     // Build complete transform from source pixels to target pixels.
10675f27b83cSArmin Le Grand     // Start by scaling from source pixel size to unit coordinates
10685f27b83cSArmin Le Grand     basegfx::B2DHomMatrix aTransform(
10695f27b83cSArmin Le Grand         basegfx::tools::createScaleB2DHomMatrix(
10705f27b83cSArmin Le Grand             1.0 / nSourceWidth,
10715f27b83cSArmin Le Grand             1.0 / nSourceHeight));
10725f27b83cSArmin Le Grand 
10735f27b83cSArmin Le Grand     // multiply with given transform which leads from unit coordinates inside
10745f27b83cSArmin Le Grand     // aOutlineRange
10755f27b83cSArmin Le Grand     aTransform = rTransformation * aTransform;
10765f27b83cSArmin Le Grand 
10775f27b83cSArmin Le Grand     // substract top-left of aOutlineRange
10785f27b83cSArmin Le Grand     aTransform.translate(-aOutlineRange.getMinX(), -aOutlineRange.getMinY());
10795f27b83cSArmin Le Grand 
10805f27b83cSArmin Le Grand     // scale to target pixels (if needed)
10815f27b83cSArmin Le Grand     if(bNeedToReduce)
10825f27b83cSArmin Le Grand     {
10835f27b83cSArmin Le Grand         aTransform.scale(fReduceFactor, fReduceFactor);
10845f27b83cSArmin Le Grand     }
10855f27b83cSArmin Le Grand 
10865f27b83cSArmin Le Grand     // invert to get transformation from target pixel coordiates to source pixels
10875f27b83cSArmin Le Grand     aTransform.invert();
10885f27b83cSArmin Le Grand 
10895f27b83cSArmin Le Grand     // create bitmap using source, destination and linear back-transformation
10905f27b83cSArmin Le Grand     aRetval = TransformBitmapEx(fWidth, fHeight, aTransform);
10915f27b83cSArmin Le Grand 
10925f27b83cSArmin Le Grand     return aRetval;
10935f27b83cSArmin Le Grand }
10945f27b83cSArmin Le Grand 
10955f27b83cSArmin Le Grand // ------------------------------------------------------------------
10965f27b83cSArmin Le Grand 
10975f27b83cSArmin Le Grand BitmapEx BitmapEx::ModifyBitmapEx(const basegfx::BColorModifierStack& rBColorModifierStack) const
10985f27b83cSArmin Le Grand {
10995f27b83cSArmin Le Grand 	Bitmap aChangedBitmap(GetBitmap());
11005f27b83cSArmin Le Grand 	bool bDone(false);
11015f27b83cSArmin Le Grand 
11025f27b83cSArmin Le Grand 	for(sal_uInt32 a(rBColorModifierStack.count()); a && !bDone; )
11035f27b83cSArmin Le Grand 	{
11045f27b83cSArmin Le Grand 		const basegfx::BColorModifier& rModifier = rBColorModifierStack.getBColorModifier(--a);
11055f27b83cSArmin Le Grand 
11065f27b83cSArmin Le Grand 		switch(rModifier.getMode())
11075f27b83cSArmin Le Grand 		{
11085f27b83cSArmin Le Grand 			case basegfx::BCOLORMODIFYMODE_REPLACE :
11095f27b83cSArmin Le Grand 			{
11105f27b83cSArmin Le Grand 				// complete replace
11115f27b83cSArmin Le Grand 				if(IsTransparent())
11125f27b83cSArmin Le Grand 				{
11135f27b83cSArmin Le Grand 					// clear bitmap with dest color
11145f27b83cSArmin Le Grand 				    if(aChangedBitmap.GetBitCount() <= 8)
11155f27b83cSArmin Le Grand 				    {
11165f27b83cSArmin Le Grand                         // do NOT use erase; for e.g. 8bit Bitmaps, the nearest color to the given
11175f27b83cSArmin Le Grand                         // erase color is determined and used -> this may be different from what is
11185f27b83cSArmin Le Grand                         // wanted here. Better create a new bitmap with the needed color explicitely
11195f27b83cSArmin Le Grand                 		BitmapReadAccess* pReadAccess = aChangedBitmap.AcquireReadAccess();
11205f27b83cSArmin Le Grand                         OSL_ENSURE(pReadAccess, "Got no Bitmap ReadAccess ?!?");
11215f27b83cSArmin Le Grand 
11225f27b83cSArmin Le Grand                         if(pReadAccess)
11235f27b83cSArmin Le Grand                         {
11245f27b83cSArmin Le Grand     					    BitmapPalette aNewPalette(pReadAccess->GetPalette());
11255f27b83cSArmin Le Grand                             aNewPalette[0] = BitmapColor(Color(rModifier.getBColor()));
11265f27b83cSArmin Le Grand 	    				    aChangedBitmap = Bitmap(
11275f27b83cSArmin Le Grand                                 aChangedBitmap.GetSizePixel(),
11285f27b83cSArmin Le Grand                                 aChangedBitmap.GetBitCount(),
11295f27b83cSArmin Le Grand                                 &aNewPalette);
11305f27b83cSArmin Le Grand                             delete pReadAccess;
11315f27b83cSArmin Le Grand                         }
11325f27b83cSArmin Le Grand 				    }
11335f27b83cSArmin Le Grand 				    else
11345f27b83cSArmin Le Grand 				    {
11355f27b83cSArmin Le Grand 						aChangedBitmap.Erase(Color(rModifier.getBColor()));
11365f27b83cSArmin Le Grand                     }
11375f27b83cSArmin Le Grand 				}
11385f27b83cSArmin Le Grand 				else
11395f27b83cSArmin Le Grand 				{
11405f27b83cSArmin Le Grand 					// erase bitmap, caller will know to paint direct
11415f27b83cSArmin Le Grand 					aChangedBitmap.SetEmpty();
11425f27b83cSArmin Le Grand 				}
11435f27b83cSArmin Le Grand 
11445f27b83cSArmin Le Grand 				bDone = true;
11455f27b83cSArmin Le Grand 				break;
11465f27b83cSArmin Le Grand 			}
11475f27b83cSArmin Le Grand 
11485f27b83cSArmin Le Grand 			default : // BCOLORMODIFYMODE_INTERPOLATE, BCOLORMODIFYMODE_GRAY, BCOLORMODIFYMODE_BLACKANDWHITE
11495f27b83cSArmin Le Grand 			{
11505f27b83cSArmin Le Grand 				BitmapWriteAccess* pContent = aChangedBitmap.AcquireWriteAccess();
11515f27b83cSArmin Le Grand 
11525f27b83cSArmin Le Grand 				if(pContent)
11535f27b83cSArmin Le Grand 				{
11545f27b83cSArmin Le Grand 					const double fConvertColor(1.0 / 255.0);
11555f27b83cSArmin Le Grand 
11565f27b83cSArmin Le Grand 					for(sal_uInt32 y(0L); y < (sal_uInt32)pContent->Height(); y++)
11575f27b83cSArmin Le Grand 					{
11585f27b83cSArmin Le Grand 						for(sal_uInt32 x(0L); x < (sal_uInt32)pContent->Width(); x++)
11595f27b83cSArmin Le Grand 						{
11605f27b83cSArmin Le Grand 							const BitmapColor aBMCol(pContent->GetColor(y, x));
11615f27b83cSArmin Le Grand 							const basegfx::BColor aBSource(
11625f27b83cSArmin Le Grand 								(double)aBMCol.GetRed() * fConvertColor,
11635f27b83cSArmin Le Grand 								(double)aBMCol.GetGreen() * fConvertColor,
11645f27b83cSArmin Le Grand 								(double)aBMCol.GetBlue() * fConvertColor);
11655f27b83cSArmin Le Grand 							const basegfx::BColor aBDest(rModifier.getModifiedColor(aBSource));
11665f27b83cSArmin Le Grand 
11675f27b83cSArmin Le Grand 							pContent->SetPixel(y, x, BitmapColor(Color(aBDest)));
11685f27b83cSArmin Le Grand 						}
11695f27b83cSArmin Le Grand 					}
11705f27b83cSArmin Le Grand 
11715f27b83cSArmin Le Grand 					delete pContent;
11725f27b83cSArmin Le Grand 				}
11735f27b83cSArmin Le Grand 
11745f27b83cSArmin Le Grand 				break;
11755f27b83cSArmin Le Grand 			}
11765f27b83cSArmin Le Grand 		}
11775f27b83cSArmin Le Grand 	}
11785f27b83cSArmin Le Grand 
11795f27b83cSArmin Le Grand 	if(aChangedBitmap.IsEmpty())
11805f27b83cSArmin Le Grand 	{
11815f27b83cSArmin Le Grand 		return BitmapEx();
11825f27b83cSArmin Le Grand 	}
11835f27b83cSArmin Le Grand 	else
11845f27b83cSArmin Le Grand 	{
11855f27b83cSArmin Le Grand 		if(IsTransparent())
11865f27b83cSArmin Le Grand 		{
11875f27b83cSArmin Le Grand 			if(IsAlpha())
11885f27b83cSArmin Le Grand 			{
11895f27b83cSArmin Le Grand 				return BitmapEx(aChangedBitmap, GetAlpha());
11905f27b83cSArmin Le Grand 			}
11915f27b83cSArmin Le Grand 			else
11925f27b83cSArmin Le Grand 			{
11935f27b83cSArmin Le Grand 				return BitmapEx(aChangedBitmap, GetMask());
11945f27b83cSArmin Le Grand 			}
11955f27b83cSArmin Le Grand 		}
11965f27b83cSArmin Le Grand 		else
11975f27b83cSArmin Le Grand 		{
11985f27b83cSArmin Le Grand 			return BitmapEx(aChangedBitmap);
11995f27b83cSArmin Le Grand 		}
12005f27b83cSArmin Le Grand 	}
12015f27b83cSArmin Le Grand }
12025f27b83cSArmin Le Grand 
1203*ff0f521cSArmin Le Grand // -----------------------------------------------------------------------------
1204*ff0f521cSArmin Le Grand 
1205*ff0f521cSArmin Le Grand BitmapEx VCL_DLLPUBLIC createBlendFrame(
1206*ff0f521cSArmin Le Grand     const Size& rSize,
1207*ff0f521cSArmin Le Grand     sal_uInt8 nAlpha,
1208*ff0f521cSArmin Le Grand     Color aColorTopLeft,
1209*ff0f521cSArmin Le Grand     Color aColorBottomRight)
1210*ff0f521cSArmin Le Grand {
1211*ff0f521cSArmin Le Grand     const sal_uInt32 nW(rSize.Width());
1212*ff0f521cSArmin Le Grand     const sal_uInt32 nH(rSize.Height());
1213*ff0f521cSArmin Le Grand 
1214*ff0f521cSArmin Le Grand     if(nW || nH)
1215*ff0f521cSArmin Le Grand     {
1216*ff0f521cSArmin Le Grand         Color aColTopRight(aColorTopLeft);
1217*ff0f521cSArmin Le Grand         Color aColBottomLeft(aColorTopLeft);
1218*ff0f521cSArmin Le Grand         const sal_uInt32 nDE(nW + nH);
1219*ff0f521cSArmin Le Grand 
1220*ff0f521cSArmin Le Grand         aColTopRight.Merge(aColorBottomRight, 255 - sal_uInt8((nW * 255) / nDE));
1221*ff0f521cSArmin Le Grand         aColBottomLeft.Merge(aColorBottomRight, 255 - sal_uInt8((nH * 255) / nDE));
1222*ff0f521cSArmin Le Grand 
1223*ff0f521cSArmin Le Grand         return createBlendFrame(rSize, nAlpha, aColorTopLeft, aColTopRight, aColorBottomRight, aColBottomLeft);
1224*ff0f521cSArmin Le Grand     }
1225*ff0f521cSArmin Le Grand 
1226*ff0f521cSArmin Le Grand     return BitmapEx();
1227*ff0f521cSArmin Le Grand }
1228*ff0f521cSArmin Le Grand 
1229*ff0f521cSArmin Le Grand BitmapEx VCL_DLLPUBLIC createBlendFrame(
1230*ff0f521cSArmin Le Grand     const Size& rSize,
1231*ff0f521cSArmin Le Grand     sal_uInt8 nAlpha,
1232*ff0f521cSArmin Le Grand     Color aColorTopLeft,
1233*ff0f521cSArmin Le Grand     Color aColorTopRight,
1234*ff0f521cSArmin Le Grand     Color aColorBottomRight,
1235*ff0f521cSArmin Le Grand     Color aColorBottomLeft)
1236*ff0f521cSArmin Le Grand {
1237*ff0f521cSArmin Le Grand     static Size aLastSize(0, 0);
1238*ff0f521cSArmin Le Grand     static sal_uInt8 nLastAlpha(0);
1239*ff0f521cSArmin Le Grand     static Color aLastColorTopLeft(COL_BLACK);
1240*ff0f521cSArmin Le Grand     static Color aLastColorTopRight(COL_BLACK);
1241*ff0f521cSArmin Le Grand     static Color aLastColorBottomRight(COL_BLACK);
1242*ff0f521cSArmin Le Grand     static Color aLastColorBottomLeft(COL_BLACK);
1243*ff0f521cSArmin Le Grand     static BitmapEx aLastResult;
1244*ff0f521cSArmin Le Grand 
1245*ff0f521cSArmin Le Grand     if(aLastSize == rSize
1246*ff0f521cSArmin Le Grand         && nLastAlpha == nAlpha
1247*ff0f521cSArmin Le Grand         && aLastColorTopLeft == aLastColorTopLeft
1248*ff0f521cSArmin Le Grand         && aLastColorTopRight == aLastColorTopRight
1249*ff0f521cSArmin Le Grand         && aLastColorBottomRight == aLastColorBottomRight
1250*ff0f521cSArmin Le Grand         && aLastColorBottomLeft == aLastColorBottomLeft)
1251*ff0f521cSArmin Le Grand     {
1252*ff0f521cSArmin Le Grand         return aLastResult;
1253*ff0f521cSArmin Le Grand     }
1254*ff0f521cSArmin Le Grand 
1255*ff0f521cSArmin Le Grand     aLastSize = rSize;
1256*ff0f521cSArmin Le Grand     nLastAlpha = nAlpha;
1257*ff0f521cSArmin Le Grand     aLastColorTopLeft = aLastColorTopLeft;
1258*ff0f521cSArmin Le Grand     aLastColorTopRight = aLastColorTopRight;
1259*ff0f521cSArmin Le Grand     aLastColorBottomRight = aLastColorBottomRight;
1260*ff0f521cSArmin Le Grand     aLastColorBottomLeft = aLastColorBottomLeft;
1261*ff0f521cSArmin Le Grand     aLastResult.Clear();
1262*ff0f521cSArmin Le Grand 
1263*ff0f521cSArmin Le Grand     const long nW(rSize.Width());
1264*ff0f521cSArmin Le Grand     const long nH(rSize.Height());
1265*ff0f521cSArmin Le Grand 
1266*ff0f521cSArmin Le Grand     if(nW && nH)
1267*ff0f521cSArmin Le Grand     {
1268*ff0f521cSArmin Le Grand         sal_uInt8 aEraseTrans(0xff);
1269*ff0f521cSArmin Le Grand         Bitmap aContent(rSize, 24);
1270*ff0f521cSArmin Le Grand         AlphaMask aAlpha(rSize, &aEraseTrans);
1271*ff0f521cSArmin Le Grand 
1272*ff0f521cSArmin Le Grand         aContent.Erase(COL_BLACK);
1273*ff0f521cSArmin Le Grand 
1274*ff0f521cSArmin Le Grand         BitmapWriteAccess* pContent = aContent.AcquireWriteAccess();
1275*ff0f521cSArmin Le Grand         BitmapWriteAccess* pAlpha = aAlpha.AcquireWriteAccess();
1276*ff0f521cSArmin Le Grand 
1277*ff0f521cSArmin Le Grand         if(pContent && pAlpha)
1278*ff0f521cSArmin Le Grand         {
1279*ff0f521cSArmin Le Grand             long x(0);
1280*ff0f521cSArmin Le Grand             long y(0);
1281*ff0f521cSArmin Le Grand 
1282*ff0f521cSArmin Le Grand             // x == 0, y == 0
1283*ff0f521cSArmin Le Grand             pContent->SetPixel(y, x, aColorTopLeft);
1284*ff0f521cSArmin Le Grand             pAlpha->SetPixelIndex(y, x, nAlpha);
1285*ff0f521cSArmin Le Grand 
1286*ff0f521cSArmin Le Grand             for(x = 1; x < nW - 1; x++) // y == 0
1287*ff0f521cSArmin Le Grand             {
1288*ff0f521cSArmin Le Grand                 Color aMix(aColorTopLeft);
1289*ff0f521cSArmin Le Grand 
1290*ff0f521cSArmin Le Grand                 aMix.Merge(aColorTopRight, 255 - sal_uInt8((x * 255) / nW));
1291*ff0f521cSArmin Le Grand                 pContent->SetPixel(y, x, aMix);
1292*ff0f521cSArmin Le Grand                 pAlpha->SetPixelIndex(y, x, nAlpha);
1293*ff0f521cSArmin Le Grand             }
1294*ff0f521cSArmin Le Grand 
1295*ff0f521cSArmin Le Grand             // x == nW - 1, y == 0
1296*ff0f521cSArmin Le Grand             pContent->SetPixel(y, x, aColorTopRight);
1297*ff0f521cSArmin Le Grand             pAlpha->SetPixelIndex(y, x, nAlpha);
1298*ff0f521cSArmin Le Grand 
1299*ff0f521cSArmin Le Grand             for(y = 1; y < nH - 1; y++) // x == 0 and nW - 1
1300*ff0f521cSArmin Le Grand             {
1301*ff0f521cSArmin Le Grand                 Color aMixA(aColorTopLeft);
1302*ff0f521cSArmin Le Grand                 Color aMixB(aColorTopRight);
1303*ff0f521cSArmin Le Grand 
1304*ff0f521cSArmin Le Grand                 aMixA.Merge(aColorBottomLeft, 255 - sal_uInt8((y * 255) / nH));
1305*ff0f521cSArmin Le Grand                 pContent->SetPixel(y, 0, aMixA);
1306*ff0f521cSArmin Le Grand                 pAlpha->SetPixelIndex(y, 0, nAlpha);
1307*ff0f521cSArmin Le Grand 
1308*ff0f521cSArmin Le Grand                 aMixB.Merge(aColorBottomRight, 255 - sal_uInt8((y * 255) / nH));
1309*ff0f521cSArmin Le Grand                 pContent->SetPixel(y, nW - 1, aMixB);
1310*ff0f521cSArmin Le Grand                 pAlpha->SetPixelIndex(y, nW - 1, nAlpha);
1311*ff0f521cSArmin Le Grand             }
1312*ff0f521cSArmin Le Grand 
1313*ff0f521cSArmin Le Grand             x = 0; // x == 0, y == nH - 1
1314*ff0f521cSArmin Le Grand             pContent->SetPixel(y, x, aColorBottomLeft);
1315*ff0f521cSArmin Le Grand             pAlpha->SetPixelIndex(y, x, nAlpha);
1316*ff0f521cSArmin Le Grand 
1317*ff0f521cSArmin Le Grand             for(x = 1; x < nW - 1; x++) // y == nH - 1
1318*ff0f521cSArmin Le Grand             {
1319*ff0f521cSArmin Le Grand                 Color aMix(aColorBottomLeft);
1320*ff0f521cSArmin Le Grand 
1321*ff0f521cSArmin Le Grand                 aMix.Merge(aColorBottomRight, 255 - sal_uInt8(((x - 0)* 255) / nW));
1322*ff0f521cSArmin Le Grand                 pContent->SetPixel(y, x, aMix);
1323*ff0f521cSArmin Le Grand                 pAlpha->SetPixelIndex(y, x, nAlpha);
1324*ff0f521cSArmin Le Grand             }
1325*ff0f521cSArmin Le Grand 
1326*ff0f521cSArmin Le Grand             // x == nW - 1, y == nH - 1
1327*ff0f521cSArmin Le Grand             pContent->SetPixel(y, x, aColorBottomRight);
1328*ff0f521cSArmin Le Grand             pAlpha->SetPixelIndex(y, x, nAlpha);
1329*ff0f521cSArmin Le Grand 
1330*ff0f521cSArmin Le Grand             aContent.ReleaseAccess(pContent);
1331*ff0f521cSArmin Le Grand             aAlpha.ReleaseAccess(pAlpha);
1332*ff0f521cSArmin Le Grand 
1333*ff0f521cSArmin Le Grand             aLastResult = BitmapEx(aContent, aAlpha);
1334*ff0f521cSArmin Le Grand         }
1335*ff0f521cSArmin Le Grand         else
1336*ff0f521cSArmin Le Grand         {
1337*ff0f521cSArmin Le Grand             if(pContent)
1338*ff0f521cSArmin Le Grand             {
1339*ff0f521cSArmin Le Grand                 aContent.ReleaseAccess(pContent);
1340*ff0f521cSArmin Le Grand             }
1341*ff0f521cSArmin Le Grand 
1342*ff0f521cSArmin Le Grand             if(pAlpha)
1343*ff0f521cSArmin Le Grand             {
1344*ff0f521cSArmin Le Grand                 aAlpha.ReleaseAccess(pAlpha);
1345*ff0f521cSArmin Le Grand             }
1346*ff0f521cSArmin Le Grand         }
1347*ff0f521cSArmin Le Grand     }
1348*ff0f521cSArmin Le Grand 
1349*ff0f521cSArmin Le Grand     return aLastResult;
1350*ff0f521cSArmin Le Grand }
1351*ff0f521cSArmin Le Grand 
1352cdf0e10cSrcweir // ------------------------------------------------------------------
135345fd3b9aSArmin Le Grand // eof
1354