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
10cdf0e10cSrcweir *
119f62ea84SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir *
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.
19cdf0e10cSrcweir *
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
BitmapEx()46cdf0e10cSrcweir BitmapEx::BitmapEx() :
47cdf0e10cSrcweir eTransparent( TRANSPARENT_NONE ),
48cdf0e10cSrcweir bAlpha ( sal_False )
49cdf0e10cSrcweir {
50cdf0e10cSrcweir }
51cdf0e10cSrcweir
52cdf0e10cSrcweir // ------------------------------------------------------------------
53cdf0e10cSrcweir
BitmapEx(const BitmapEx & rBitmapEx)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
BitmapEx(const BitmapEx & rBitmapEx,Point aSrc,Size aSize)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
BitmapEx(const ResId & rResId)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
BitmapEx(const Bitmap & rBmp)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
BitmapEx(const Bitmap & rBmp,const Bitmap & rMask)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
BitmapEx(const Bitmap & rBmp,const AlphaMask & rAlphaMask)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
BitmapEx(const Bitmap & rBmp,const Color & rTransparentColor)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
~BitmapEx()183cdf0e10cSrcweir BitmapEx::~BitmapEx()
184cdf0e10cSrcweir {
185cdf0e10cSrcweir }
186cdf0e10cSrcweir
187cdf0e10cSrcweir // ------------------------------------------------------------------
188cdf0e10cSrcweir
189cdf0e10cSrcweir // ------------------------------------------------------------------
190cdf0e10cSrcweir
operator =(const BitmapEx & rBitmapEx)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
operator ==(const BitmapEx & rBitmapEx) const208cdf0e10cSrcweir 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
IsEqual(const BitmapEx & rBmpEx) const230cdf0e10cSrcweir 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
IsEmpty() const240cdf0e10cSrcweir sal_Bool BitmapEx::IsEmpty() const
241cdf0e10cSrcweir {
242cdf0e10cSrcweir return( aBitmap.IsEmpty() && aMask.IsEmpty() );
243cdf0e10cSrcweir }
244cdf0e10cSrcweir
245cdf0e10cSrcweir // ------------------------------------------------------------------
246cdf0e10cSrcweir
SetEmpty()247cdf0e10cSrcweir void BitmapEx::SetEmpty()
248cdf0e10cSrcweir {
249cdf0e10cSrcweir aBitmap.SetEmpty();
250cdf0e10cSrcweir aMask.SetEmpty();
251cdf0e10cSrcweir eTransparent = TRANSPARENT_NONE;
252cdf0e10cSrcweir bAlpha = sal_False;
253cdf0e10cSrcweir }
254cdf0e10cSrcweir
255cdf0e10cSrcweir // ------------------------------------------------------------------
256cdf0e10cSrcweir
Clear()257cdf0e10cSrcweir void BitmapEx::Clear()
258cdf0e10cSrcweir {
259cdf0e10cSrcweir SetEmpty();
260cdf0e10cSrcweir }
261cdf0e10cSrcweir
262cdf0e10cSrcweir // ------------------------------------------------------------------
263cdf0e10cSrcweir
IsTransparent() const264cdf0e10cSrcweir sal_Bool BitmapEx::IsTransparent() const
265cdf0e10cSrcweir {
266cdf0e10cSrcweir return( eTransparent != TRANSPARENT_NONE );
267cdf0e10cSrcweir }
268cdf0e10cSrcweir
269cdf0e10cSrcweir // ------------------------------------------------------------------
270cdf0e10cSrcweir
IsAlpha() const271cdf0e10cSrcweir sal_Bool BitmapEx::IsAlpha() const
272cdf0e10cSrcweir {
273cdf0e10cSrcweir return( IsTransparent() && bAlpha );
274cdf0e10cSrcweir }
275cdf0e10cSrcweir
276cdf0e10cSrcweir // ------------------------------------------------------------------
277cdf0e10cSrcweir
GetBitmap(const Color * pTransReplaceColor) const278cdf0e10cSrcweir 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
GetColorTransformedBitmapEx(BmpColorMode eColorMode) const302cdf0e10cSrcweir 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
GetMask() const332cdf0e10cSrcweir 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
GetAlpha() const344cdf0e10cSrcweir 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
GetSizeBytes() const358cdf0e10cSrcweir 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
GetChecksum() const370cdf0e10cSrcweir 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
SetSizePixel(const Size & rNewSize,sal_uInt32 nScaleFlag)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
Invert()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
Mirror(sal_uLong nMirrorFlags)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
Scale(const double & rScaleX,const double & rScaleY,sal_uInt32 nScaleFlag)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
Scale(const Size & rNewSize,sal_uInt32 nScaleFlag)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
Rotate(long nAngle10,const Color & rFillColor)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
Crop(const Rectangle & rRectPixel)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
Convert(BmpConversion eConversion)546cdf0e10cSrcweir sal_Bool BitmapEx::Convert( BmpConversion eConversion )
547cdf0e10cSrcweir {
548cdf0e10cSrcweir return( !!aBitmap ? aBitmap.Convert( eConversion ) : sal_False );
549cdf0e10cSrcweir }
550cdf0e10cSrcweir
551cdf0e10cSrcweir // ------------------------------------------------------------------
552cdf0e10cSrcweir
ReduceColors(sal_uInt16 nNewColorCount,BmpReduce eReduce)553cdf0e10cSrcweir sal_Bool BitmapEx::ReduceColors( sal_uInt16 nNewColorCount, BmpReduce eReduce )
554cdf0e10cSrcweir {
555cdf0e10cSrcweir return( !!aBitmap ? aBitmap.ReduceColors( nNewColorCount, eReduce ) : sal_False );
556cdf0e10cSrcweir }
557cdf0e10cSrcweir
558cdf0e10cSrcweir // ------------------------------------------------------------------
559cdf0e10cSrcweir
Expand(sal_uLong nDX,sal_uLong nDY,const Color * pInitColor,sal_Bool bExpandTransparent)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
CopyPixel(const Rectangle & rRectDst,const Rectangle & rRectSrc,const BitmapEx * pBmpExSrc)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
Erase(const Color & rFillColor)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
Dither(sal_uLong nDitherFlags)703cdf0e10cSrcweir sal_Bool BitmapEx::Dither( sal_uLong nDitherFlags )
704cdf0e10cSrcweir {
705cdf0e10cSrcweir return( !!aBitmap ? aBitmap.Dither( nDitherFlags ) : sal_False );
706cdf0e10cSrcweir }
707cdf0e10cSrcweir
708cdf0e10cSrcweir // ------------------------------------------------------------------
709cdf0e10cSrcweir
Replace(const Color & rSearchColor,const Color & rReplaceColor,sal_uLong nTol)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
Replace(const Color * pSearchColors,const Color * pReplaceColors,sal_uLong nColorCount,const sal_uLong * pTols)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
Adjust(short nLuminancePercent,short nContrastPercent,short nChannelRPercent,short nChannelGPercent,short nChannelBPercent,double fGamma,sal_Bool bInvert)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
Filter(BmpFilter eFilter,const BmpFilterParam * pFilterParam,const Link * pProgress)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
Draw(OutputDevice * pOutDev,const Point & rDestPt) const742cdf0e10cSrcweir void BitmapEx::Draw( OutputDevice* pOutDev, const Point& rDestPt ) const
743cdf0e10cSrcweir {
744cdf0e10cSrcweir pOutDev->DrawBitmapEx( rDestPt, *this );
745cdf0e10cSrcweir }
746cdf0e10cSrcweir
747cdf0e10cSrcweir // ------------------------------------------------------------------
748cdf0e10cSrcweir
Draw(OutputDevice * pOutDev,const Point & rDestPt,const Size & rDestSize) const749cdf0e10cSrcweir void BitmapEx::Draw( OutputDevice* pOutDev,
750cdf0e10cSrcweir const Point& rDestPt, const Size& rDestSize ) const
751cdf0e10cSrcweir {
752cdf0e10cSrcweir pOutDev->DrawBitmapEx( rDestPt, rDestSize, *this );
753cdf0e10cSrcweir }
754cdf0e10cSrcweir
755cdf0e10cSrcweir // ------------------------------------------------------------------
756cdf0e10cSrcweir
Draw(OutputDevice * pOutDev,const Point & rDestPt,const Size & rDestSize,const Point & rSrcPtPixel,const Size & rSrcSizePixel) const757cdf0e10cSrcweir 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
GetTransparency(sal_Int32 nX,sal_Int32 nY) const766cdf0e10cSrcweir 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
836cdf0e10cSrcweir // ------------------------------------------------------------------
8375f27b83cSArmin Le Grand
8385f27b83cSArmin Le Grand namespace
8395f27b83cSArmin Le Grand {
impTransformBitmap(const Bitmap & rSource,const Size aDestinationSize,const basegfx::B2DHomMatrix & rTransform,bool bSmooth)8405f27b83cSArmin Le Grand Bitmap impTransformBitmap(
8415f27b83cSArmin Le Grand const Bitmap& rSource,
8425f27b83cSArmin Le Grand const Size aDestinationSize,
8435f27b83cSArmin Le Grand const basegfx::B2DHomMatrix& rTransform,
8445f27b83cSArmin Le Grand bool bSmooth)
8455f27b83cSArmin Le Grand {
8465f27b83cSArmin Le Grand Bitmap aDestination(aDestinationSize, 24);
8475f27b83cSArmin Le Grand BitmapWriteAccess* pWrite = aDestination.AcquireWriteAccess();
8485f27b83cSArmin Le Grand
8495f27b83cSArmin Le Grand if(pWrite)
8505f27b83cSArmin Le Grand {
851f8c0d554SArmin Le Grand //const Size aContentSizePixel(rSource.GetSizePixel());
8525f27b83cSArmin Le Grand BitmapReadAccess* pRead = (const_cast< Bitmap& >(rSource)).AcquireReadAccess();
8535f27b83cSArmin Le Grand
8545f27b83cSArmin Le Grand if(pRead)
8555f27b83cSArmin Le Grand {
8565f27b83cSArmin Le Grand const Size aDestinationSizePixel(aDestination.GetSizePixel());
857f8c0d554SArmin Le Grand const BitmapColor aOutside(BitmapColor(0xff, 0xff, 0xff));
8585f27b83cSArmin Le Grand
8595f27b83cSArmin Le Grand for(sal_Int32 y(0L); y < aDestinationSizePixel.getHeight(); y++)
8605f27b83cSArmin Le Grand {
8615f27b83cSArmin Le Grand for(sal_Int32 x(0L); x < aDestinationSizePixel.getWidth(); x++)
8625f27b83cSArmin Le Grand {
8635f27b83cSArmin Le Grand const basegfx::B2DPoint aSourceCoor(rTransform * basegfx::B2DPoint(x, y));
8645f27b83cSArmin Le Grand
8655f27b83cSArmin Le Grand if(bSmooth)
8665f27b83cSArmin Le Grand {
867f8c0d554SArmin Le Grand pWrite->SetPixel(
868f8c0d554SArmin Le Grand y,
869f8c0d554SArmin Le Grand x,
870f8c0d554SArmin Le Grand pRead->GetInterpolatedColorWithFallback(
871f8c0d554SArmin Le Grand aSourceCoor.getY(),
872f8c0d554SArmin Le Grand aSourceCoor.getX(),
873f8c0d554SArmin Le Grand aOutside));
8745f27b83cSArmin Le Grand }
875f8c0d554SArmin Le Grand else
8765f27b83cSArmin Le Grand {
877f8c0d554SArmin Le Grand // this version does the correct <= 0.0 checks, so no need
878f8c0d554SArmin Le Grand // to do the static_cast< sal_Int32 > self and make an error
879f8c0d554SArmin Le Grand pWrite->SetPixel(
880f8c0d554SArmin Le Grand y,
881f8c0d554SArmin Le Grand x,
882f8c0d554SArmin Le Grand pRead->GetColorWithFallback(
883f8c0d554SArmin Le Grand aSourceCoor.getY(),
884f8c0d554SArmin Le Grand aSourceCoor.getX(),
885f8c0d554SArmin Le Grand aOutside));
8865f27b83cSArmin Le Grand }
8875f27b83cSArmin Le Grand }
8885f27b83cSArmin Le Grand }
8895f27b83cSArmin Le Grand
8905f27b83cSArmin Le Grand delete pRead;
8915f27b83cSArmin Le Grand }
8925f27b83cSArmin Le Grand
8935f27b83cSArmin Le Grand delete pWrite;
8945f27b83cSArmin Le Grand }
8955f27b83cSArmin Le Grand
8965f27b83cSArmin Le Grand rSource.AdaptBitCount(aDestination);
8975f27b83cSArmin Le Grand
8985f27b83cSArmin Le Grand return aDestination;
8995f27b83cSArmin Le Grand }
9005f27b83cSArmin Le Grand } // end of anonymous namespace
901f8c0d554SArmin Le Grand
TransformBitmapEx(double fWidth,double fHeight,const basegfx::B2DHomMatrix & rTransformation,bool bSmooth) const9025f27b83cSArmin Le Grand BitmapEx BitmapEx::TransformBitmapEx(
9035f27b83cSArmin Le Grand double fWidth,
9045f27b83cSArmin Le Grand double fHeight,
905f8c0d554SArmin Le Grand const basegfx::B2DHomMatrix& rTransformation,
906f8c0d554SArmin Le Grand bool bSmooth) const
9075f27b83cSArmin Le Grand {
9085f27b83cSArmin Le Grand if(fWidth <= 1 || fHeight <= 1)
9095f27b83cSArmin Le Grand return BitmapEx();
9105f27b83cSArmin Le Grand
9115f27b83cSArmin Le Grand // force destination to 24 bit, we want to smooth output
9125f27b83cSArmin Le Grand const Size aDestinationSize(basegfx::fround(fWidth), basegfx::fround(fHeight));
913f8c0d554SArmin Le Grand const Bitmap aDestination(impTransformBitmap(GetBitmap(), aDestinationSize, rTransformation, bSmooth));
9145f27b83cSArmin Le Grand
9155f27b83cSArmin Le Grand // create mask
9165f27b83cSArmin Le Grand if(IsTransparent())
9175f27b83cSArmin Le Grand {
9185f27b83cSArmin Le Grand if(IsAlpha())
9195f27b83cSArmin Le Grand {
920f8c0d554SArmin Le Grand const Bitmap aAlpha(impTransformBitmap(GetAlpha().GetBitmap(), aDestinationSize, rTransformation, bSmooth));
9215f27b83cSArmin Le Grand return BitmapEx(aDestination, AlphaMask(aAlpha));
9225f27b83cSArmin Le Grand }
9235f27b83cSArmin Le Grand else
9245f27b83cSArmin Le Grand {
9255f27b83cSArmin Le Grand const Bitmap aMask(impTransformBitmap(GetMask(), aDestinationSize, rTransformation, false));
9265f27b83cSArmin Le Grand return BitmapEx(aDestination, aMask);
9275f27b83cSArmin Le Grand }
9285f27b83cSArmin Le Grand }
9295f27b83cSArmin Le Grand
9305f27b83cSArmin Le Grand return BitmapEx(aDestination);
9315f27b83cSArmin Le Grand }
9325f27b83cSArmin Le Grand
9335f27b83cSArmin Le Grand // ------------------------------------------------------------------
9345f27b83cSArmin Le Grand
getTransformed(const basegfx::B2DHomMatrix & rTransformation,const basegfx::B2DRange & rVisibleRange,double fMaximumArea,bool bSmooth) const9355f27b83cSArmin Le Grand BitmapEx BitmapEx::getTransformed(
9365f27b83cSArmin Le Grand const basegfx::B2DHomMatrix& rTransformation,
937f8c0d554SArmin Le Grand const basegfx::B2DRange& rVisibleRange,
938f8c0d554SArmin Le Grand double fMaximumArea,
939f8c0d554SArmin Le Grand bool bSmooth) const
9405f27b83cSArmin Le Grand {
9415f27b83cSArmin Le Grand BitmapEx aRetval;
9425f27b83cSArmin Le Grand
9435f27b83cSArmin Le Grand if(IsEmpty())
9445f27b83cSArmin Le Grand return aRetval;
9455f27b83cSArmin Le Grand
9465f27b83cSArmin Le Grand const sal_uInt32 nSourceWidth(GetSizePixel().Width());
9475f27b83cSArmin Le Grand const sal_uInt32 nSourceHeight(GetSizePixel().Height());
9485f27b83cSArmin Le Grand
9495f27b83cSArmin Le Grand if(!nSourceWidth || !nSourceHeight)
9505f27b83cSArmin Le Grand return aRetval;
9515f27b83cSArmin Le Grand
952f8c0d554SArmin Le Grand // Get aOutlineRange
9535f27b83cSArmin Le Grand basegfx::B2DRange aOutlineRange(0.0, 0.0, 1.0, 1.0);
954f8c0d554SArmin Le Grand
9555f27b83cSArmin Le Grand aOutlineRange.transform(rTransformation);
9565f27b83cSArmin Le Grand
957f8c0d554SArmin Le Grand // create visible range from it by moving from relative to absolute
958f8c0d554SArmin Le Grand basegfx::B2DRange aVisibleRange(rVisibleRange);
959f8c0d554SArmin Le Grand
960f8c0d554SArmin Le Grand aVisibleRange.transform(
961f8c0d554SArmin Le Grand basegfx::tools::createScaleTranslateB2DHomMatrix(
962f8c0d554SArmin Le Grand aOutlineRange.getRange(),
963f8c0d554SArmin Le Grand aOutlineRange.getMinimum()));
964f8c0d554SArmin Le Grand
965f8c0d554SArmin Le Grand // get target size (which is visible range's size)
966f8c0d554SArmin Le Grand double fWidth(aVisibleRange.getWidth());
967f8c0d554SArmin Le Grand double fHeight(aVisibleRange.getHeight());
9685f27b83cSArmin Le Grand
9695f27b83cSArmin Le Grand if(fWidth < 1.0 || fHeight < 1.0)
970f8c0d554SArmin Le Grand {
9715f27b83cSArmin Le Grand return aRetval;
972f8c0d554SArmin Le Grand }
9735f27b83cSArmin Le Grand
9745f27b83cSArmin Le Grand // test if discrete size (pixel) maybe too big and limit it
9755f27b83cSArmin Le Grand const double fArea(fWidth * fHeight);
976f8c0d554SArmin Le Grand const bool bNeedToReduce(basegfx::fTools::more(fArea, fMaximumArea));
9775f27b83cSArmin Le Grand double fReduceFactor(1.0);
9785f27b83cSArmin Le Grand
9795f27b83cSArmin Le Grand if(bNeedToReduce)
9805f27b83cSArmin Le Grand {
9815f27b83cSArmin Le Grand fReduceFactor = sqrt(fMaximumArea / fArea);
9825f27b83cSArmin Le Grand fWidth *= fReduceFactor;
9835f27b83cSArmin Le Grand fHeight *= fReduceFactor;
9845f27b83cSArmin Le Grand }
9855f27b83cSArmin Le Grand
9865f27b83cSArmin Le Grand // Build complete transform from source pixels to target pixels.
9875f27b83cSArmin Le Grand // Start by scaling from source pixel size to unit coordinates
9885f27b83cSArmin Le Grand basegfx::B2DHomMatrix aTransform(
9895f27b83cSArmin Le Grand basegfx::tools::createScaleB2DHomMatrix(
9905f27b83cSArmin Le Grand 1.0 / nSourceWidth,
9915f27b83cSArmin Le Grand 1.0 / nSourceHeight));
9925f27b83cSArmin Le Grand
9935f27b83cSArmin Le Grand // multiply with given transform which leads from unit coordinates inside
9945f27b83cSArmin Le Grand // aOutlineRange
9955f27b83cSArmin Le Grand aTransform = rTransformation * aTransform;
9965f27b83cSArmin Le Grand
997f8c0d554SArmin Le Grand // substract top-left of absolute VisibleRange
998f8c0d554SArmin Le Grand aTransform.translate(
999f8c0d554SArmin Le Grand -aVisibleRange.getMinX(),
1000f8c0d554SArmin Le Grand -aVisibleRange.getMinY());
10015f27b83cSArmin Le Grand
10025f27b83cSArmin Le Grand // scale to target pixels (if needed)
10035f27b83cSArmin Le Grand if(bNeedToReduce)
10045f27b83cSArmin Le Grand {
10055f27b83cSArmin Le Grand aTransform.scale(fReduceFactor, fReduceFactor);
10065f27b83cSArmin Le Grand }
10075f27b83cSArmin Le Grand
10085f27b83cSArmin Le Grand // invert to get transformation from target pixel coordiates to source pixels
10095f27b83cSArmin Le Grand aTransform.invert();
10105f27b83cSArmin Le Grand
10115f27b83cSArmin Le Grand // create bitmap using source, destination and linear back-transformation
1012f8c0d554SArmin Le Grand aRetval = TransformBitmapEx(fWidth, fHeight, aTransform, bSmooth);
10135f27b83cSArmin Le Grand
10145f27b83cSArmin Le Grand return aRetval;
10155f27b83cSArmin Le Grand }
10165f27b83cSArmin Le Grand
10175f27b83cSArmin Le Grand // ------------------------------------------------------------------
10185f27b83cSArmin Le Grand
ModifyBitmapEx(const basegfx::BColorModifierStack & rBColorModifierStack) const10195f27b83cSArmin Le Grand BitmapEx BitmapEx::ModifyBitmapEx(const basegfx::BColorModifierStack& rBColorModifierStack) const
10205f27b83cSArmin Le Grand {
10215f27b83cSArmin Le Grand Bitmap aChangedBitmap(GetBitmap());
10225f27b83cSArmin Le Grand bool bDone(false);
10235f27b83cSArmin Le Grand
10245f27b83cSArmin Le Grand for(sal_uInt32 a(rBColorModifierStack.count()); a && !bDone; )
10255f27b83cSArmin Le Grand {
102649c58f9bSArmin Le Grand const basegfx::BColorModifierSharedPtr& rModifier = rBColorModifierStack.getBColorModifier(--a);
102749c58f9bSArmin Le Grand const basegfx::BColorModifier_replace* pReplace = dynamic_cast< const basegfx::BColorModifier_replace* >(rModifier.get());
10285f27b83cSArmin Le Grand
102949c58f9bSArmin Le Grand if(pReplace)
10305f27b83cSArmin Le Grand {
10315f27b83cSArmin Le Grand // complete replace
10325f27b83cSArmin Le Grand if(IsTransparent())
10335f27b83cSArmin Le Grand {
10345f27b83cSArmin Le Grand // clear bitmap with dest color
10355f27b83cSArmin Le Grand if(aChangedBitmap.GetBitCount() <= 8)
10365f27b83cSArmin Le Grand {
10375f27b83cSArmin Le Grand // do NOT use erase; for e.g. 8bit Bitmaps, the nearest color to the given
10385f27b83cSArmin Le Grand // erase color is determined and used -> this may be different from what is
10395f27b83cSArmin Le Grand // wanted here. Better create a new bitmap with the needed color explicitely
10405f27b83cSArmin Le Grand BitmapReadAccess* pReadAccess = aChangedBitmap.AcquireReadAccess();
10415f27b83cSArmin Le Grand OSL_ENSURE(pReadAccess, "Got no Bitmap ReadAccess ?!?");
10425f27b83cSArmin Le Grand
10435f27b83cSArmin Le Grand if(pReadAccess)
10445f27b83cSArmin Le Grand {
10455f27b83cSArmin Le Grand BitmapPalette aNewPalette(pReadAccess->GetPalette());
104649c58f9bSArmin Le Grand aNewPalette[0] = BitmapColor(Color(pReplace->getBColor()));
10475f27b83cSArmin Le Grand aChangedBitmap = Bitmap(
10485f27b83cSArmin Le Grand aChangedBitmap.GetSizePixel(),
10495f27b83cSArmin Le Grand aChangedBitmap.GetBitCount(),
10505f27b83cSArmin Le Grand &aNewPalette);
10515f27b83cSArmin Le Grand delete pReadAccess;
10525f27b83cSArmin Le Grand }
10535f27b83cSArmin Le Grand }
10545f27b83cSArmin Le Grand else
10555f27b83cSArmin Le Grand {
105649c58f9bSArmin Le Grand aChangedBitmap.Erase(Color(pReplace->getBColor()));
10575f27b83cSArmin Le Grand }
10585f27b83cSArmin Le Grand }
10595f27b83cSArmin Le Grand else
10605f27b83cSArmin Le Grand {
10615f27b83cSArmin Le Grand // erase bitmap, caller will know to paint direct
10625f27b83cSArmin Le Grand aChangedBitmap.SetEmpty();
10635f27b83cSArmin Le Grand }
10645f27b83cSArmin Le Grand
10655f27b83cSArmin Le Grand bDone = true;
10665f27b83cSArmin Le Grand }
106749c58f9bSArmin Le Grand else
10685f27b83cSArmin Le Grand {
10695f27b83cSArmin Le Grand BitmapWriteAccess* pContent = aChangedBitmap.AcquireWriteAccess();
10705f27b83cSArmin Le Grand
10715f27b83cSArmin Le Grand if(pContent)
10725f27b83cSArmin Le Grand {
10735f27b83cSArmin Le Grand const double fConvertColor(1.0 / 255.0);
10745f27b83cSArmin Le Grand
107549c58f9bSArmin Le Grand if(pContent->HasPalette())
107649c58f9bSArmin Le Grand {
107749c58f9bSArmin Le Grand const sal_uInt16 nCount(pContent->GetPaletteEntryCount());
107849c58f9bSArmin Le Grand
107949c58f9bSArmin Le Grand for(sal_uInt16 a(0); a < nCount; a++)
108049c58f9bSArmin Le Grand {
108149c58f9bSArmin Le Grand const BitmapColor& rCol = pContent->GetPaletteColor(a);
108249c58f9bSArmin Le Grand const basegfx::BColor aBSource(
108349c58f9bSArmin Le Grand rCol.GetRed() * fConvertColor,
108449c58f9bSArmin Le Grand rCol.GetGreen() * fConvertColor,
108549c58f9bSArmin Le Grand rCol.GetBlue() * fConvertColor);
108649c58f9bSArmin Le Grand const basegfx::BColor aBDest(rModifier->getModifiedColor(aBSource));
108749c58f9bSArmin Le Grand pContent->SetPaletteColor(a, BitmapColor(Color(aBDest)));
108849c58f9bSArmin Le Grand }
108949c58f9bSArmin Le Grand }
109049c58f9bSArmin Le Grand else if(BMP_FORMAT_24BIT_TC_BGR == pContent->GetScanlineFormat())
109149c58f9bSArmin Le Grand {
109249c58f9bSArmin Le Grand for(sal_uInt32 y(0L); y < (sal_uInt32)pContent->Height(); y++)
109349c58f9bSArmin Le Grand {
109449c58f9bSArmin Le Grand Scanline pScan = pContent->GetScanline(y);
109549c58f9bSArmin Le Grand
109649c58f9bSArmin Le Grand for(sal_uInt32 x(0L); x < (sal_uInt32)pContent->Width(); x++)
109749c58f9bSArmin Le Grand {
109849c58f9bSArmin Le Grand const basegfx::BColor aBSource(
109949c58f9bSArmin Le Grand *(pScan + 2)* fConvertColor,
110049c58f9bSArmin Le Grand *(pScan + 1) * fConvertColor,
110149c58f9bSArmin Le Grand *pScan * fConvertColor);
110249c58f9bSArmin Le Grand const basegfx::BColor aBDest(rModifier->getModifiedColor(aBSource));
110349c58f9bSArmin Le Grand *pScan++ = static_cast< sal_uInt8 >(aBDest.getBlue() * 255.0);
110449c58f9bSArmin Le Grand *pScan++ = static_cast< sal_uInt8 >(aBDest.getGreen() * 255.0);
110549c58f9bSArmin Le Grand *pScan++ = static_cast< sal_uInt8 >(aBDest.getRed() * 255.0);
110649c58f9bSArmin Le Grand }
110749c58f9bSArmin Le Grand }
110849c58f9bSArmin Le Grand }
110949c58f9bSArmin Le Grand else if(BMP_FORMAT_24BIT_TC_RGB == pContent->GetScanlineFormat())
111049c58f9bSArmin Le Grand {
111149c58f9bSArmin Le Grand for(sal_uInt32 y(0L); y < (sal_uInt32)pContent->Height(); y++)
111249c58f9bSArmin Le Grand {
111349c58f9bSArmin Le Grand Scanline pScan = pContent->GetScanline(y);
111449c58f9bSArmin Le Grand
111549c58f9bSArmin Le Grand for(sal_uInt32 x(0L); x < (sal_uInt32)pContent->Width(); x++)
111649c58f9bSArmin Le Grand {
111749c58f9bSArmin Le Grand const basegfx::BColor aBSource(
111849c58f9bSArmin Le Grand *pScan * fConvertColor,
111949c58f9bSArmin Le Grand *(pScan + 1) * fConvertColor,
112049c58f9bSArmin Le Grand *(pScan + 2) * fConvertColor);
112149c58f9bSArmin Le Grand const basegfx::BColor aBDest(rModifier->getModifiedColor(aBSource));
112249c58f9bSArmin Le Grand *pScan++ = static_cast< sal_uInt8 >(aBDest.getRed() * 255.0);
112349c58f9bSArmin Le Grand *pScan++ = static_cast< sal_uInt8 >(aBDest.getGreen() * 255.0);
112449c58f9bSArmin Le Grand *pScan++ = static_cast< sal_uInt8 >(aBDest.getBlue() * 255.0);
112549c58f9bSArmin Le Grand }
112649c58f9bSArmin Le Grand }
112749c58f9bSArmin Le Grand }
112849c58f9bSArmin Le Grand else
112949c58f9bSArmin Le Grand {
11305f27b83cSArmin Le Grand for(sal_uInt32 y(0L); y < (sal_uInt32)pContent->Height(); y++)
11315f27b83cSArmin Le Grand {
11325f27b83cSArmin Le Grand for(sal_uInt32 x(0L); x < (sal_uInt32)pContent->Width(); x++)
11335f27b83cSArmin Le Grand {
11345f27b83cSArmin Le Grand const BitmapColor aBMCol(pContent->GetColor(y, x));
11355f27b83cSArmin Le Grand const basegfx::BColor aBSource(
11365f27b83cSArmin Le Grand (double)aBMCol.GetRed() * fConvertColor,
11375f27b83cSArmin Le Grand (double)aBMCol.GetGreen() * fConvertColor,
11385f27b83cSArmin Le Grand (double)aBMCol.GetBlue() * fConvertColor);
113949c58f9bSArmin Le Grand const basegfx::BColor aBDest(rModifier->getModifiedColor(aBSource));
11405f27b83cSArmin Le Grand
11415f27b83cSArmin Le Grand pContent->SetPixel(y, x, BitmapColor(Color(aBDest)));
11425f27b83cSArmin Le Grand }
11435f27b83cSArmin Le Grand }
11445f27b83cSArmin Le Grand }
11455f27b83cSArmin Le Grand
114649c58f9bSArmin Le Grand delete pContent;
11475f27b83cSArmin Le Grand }
11485f27b83cSArmin Le Grand }
11495f27b83cSArmin Le Grand }
11505f27b83cSArmin Le Grand
11515f27b83cSArmin Le Grand if(aChangedBitmap.IsEmpty())
11525f27b83cSArmin Le Grand {
11535f27b83cSArmin Le Grand return BitmapEx();
11545f27b83cSArmin Le Grand }
11555f27b83cSArmin Le Grand else
11565f27b83cSArmin Le Grand {
11575f27b83cSArmin Le Grand if(IsTransparent())
11585f27b83cSArmin Le Grand {
11595f27b83cSArmin Le Grand if(IsAlpha())
11605f27b83cSArmin Le Grand {
11615f27b83cSArmin Le Grand return BitmapEx(aChangedBitmap, GetAlpha());
11625f27b83cSArmin Le Grand }
11635f27b83cSArmin Le Grand else
11645f27b83cSArmin Le Grand {
11655f27b83cSArmin Le Grand return BitmapEx(aChangedBitmap, GetMask());
11665f27b83cSArmin Le Grand }
11675f27b83cSArmin Le Grand }
11685f27b83cSArmin Le Grand else
11695f27b83cSArmin Le Grand {
11705f27b83cSArmin Le Grand return BitmapEx(aChangedBitmap);
11715f27b83cSArmin Le Grand }
11725f27b83cSArmin Le Grand }
11735f27b83cSArmin Le Grand }
11745f27b83cSArmin Le Grand
1175ff0f521cSArmin Le Grand // -----------------------------------------------------------------------------
1176ff0f521cSArmin Le Grand
createBlendFrame(const Size & rSize,sal_uInt8 nAlpha,Color aColorTopLeft,Color aColorBottomRight)1177ff0f521cSArmin Le Grand BitmapEx VCL_DLLPUBLIC createBlendFrame(
1178ff0f521cSArmin Le Grand const Size& rSize,
1179ff0f521cSArmin Le Grand sal_uInt8 nAlpha,
1180ff0f521cSArmin Le Grand Color aColorTopLeft,
1181ff0f521cSArmin Le Grand Color aColorBottomRight)
1182ff0f521cSArmin Le Grand {
1183ff0f521cSArmin Le Grand const sal_uInt32 nW(rSize.Width());
1184ff0f521cSArmin Le Grand const sal_uInt32 nH(rSize.Height());
1185ff0f521cSArmin Le Grand
1186ff0f521cSArmin Le Grand if(nW || nH)
1187ff0f521cSArmin Le Grand {
1188ff0f521cSArmin Le Grand Color aColTopRight(aColorTopLeft);
1189ff0f521cSArmin Le Grand Color aColBottomLeft(aColorTopLeft);
1190ff0f521cSArmin Le Grand const sal_uInt32 nDE(nW + nH);
1191ff0f521cSArmin Le Grand
1192ff0f521cSArmin Le Grand aColTopRight.Merge(aColorBottomRight, 255 - sal_uInt8((nW * 255) / nDE));
1193ff0f521cSArmin Le Grand aColBottomLeft.Merge(aColorBottomRight, 255 - sal_uInt8((nH * 255) / nDE));
1194ff0f521cSArmin Le Grand
1195ff0f521cSArmin Le Grand return createBlendFrame(rSize, nAlpha, aColorTopLeft, aColTopRight, aColorBottomRight, aColBottomLeft);
1196ff0f521cSArmin Le Grand }
1197ff0f521cSArmin Le Grand
1198ff0f521cSArmin Le Grand return BitmapEx();
1199ff0f521cSArmin Le Grand }
1200ff0f521cSArmin Le Grand
createBlendFrame(const Size & rSize,sal_uInt8 nAlpha,Color aColorTopLeft,Color aColorTopRight,Color aColorBottomRight,Color aColorBottomLeft)1201ff0f521cSArmin Le Grand BitmapEx VCL_DLLPUBLIC createBlendFrame(
1202ff0f521cSArmin Le Grand const Size& rSize,
1203ff0f521cSArmin Le Grand sal_uInt8 nAlpha,
1204ff0f521cSArmin Le Grand Color aColorTopLeft,
1205ff0f521cSArmin Le Grand Color aColorTopRight,
1206ff0f521cSArmin Le Grand Color aColorBottomRight,
1207ff0f521cSArmin Le Grand Color aColorBottomLeft)
1208ff0f521cSArmin Le Grand {
1209ff0f521cSArmin Le Grand static Size aLastSize(0, 0);
1210ff0f521cSArmin Le Grand static sal_uInt8 nLastAlpha(0);
1211ff0f521cSArmin Le Grand static Color aLastColorTopLeft(COL_BLACK);
1212ff0f521cSArmin Le Grand static Color aLastColorTopRight(COL_BLACK);
1213ff0f521cSArmin Le Grand static Color aLastColorBottomRight(COL_BLACK);
1214ff0f521cSArmin Le Grand static Color aLastColorBottomLeft(COL_BLACK);
1215ff0f521cSArmin Le Grand static BitmapEx aLastResult;
1216ff0f521cSArmin Le Grand
1217ff0f521cSArmin Le Grand if(aLastSize == rSize
1218ff0f521cSArmin Le Grand && nLastAlpha == nAlpha
12190d6bca7aSArmin Le Grand && aLastColorTopLeft == aColorTopLeft
12200d6bca7aSArmin Le Grand && aLastColorTopRight == aColorTopRight
12210d6bca7aSArmin Le Grand && aLastColorBottomRight == aColorBottomRight
12220d6bca7aSArmin Le Grand && aLastColorBottomLeft == aColorBottomLeft)
1223ff0f521cSArmin Le Grand {
1224ff0f521cSArmin Le Grand return aLastResult;
1225ff0f521cSArmin Le Grand }
1226ff0f521cSArmin Le Grand
1227ff0f521cSArmin Le Grand aLastSize = rSize;
1228ff0f521cSArmin Le Grand nLastAlpha = nAlpha;
12290d6bca7aSArmin Le Grand aLastColorTopLeft = aColorTopLeft;
12300d6bca7aSArmin Le Grand aLastColorTopRight = aColorTopRight;
12310d6bca7aSArmin Le Grand aLastColorBottomRight = aColorBottomRight;
12320d6bca7aSArmin Le Grand aLastColorBottomLeft = aColorBottomLeft;
1233ff0f521cSArmin Le Grand aLastResult.Clear();
1234ff0f521cSArmin Le Grand
1235ff0f521cSArmin Le Grand const long nW(rSize.Width());
1236ff0f521cSArmin Le Grand const long nH(rSize.Height());
1237ff0f521cSArmin Le Grand
1238ff0f521cSArmin Le Grand if(nW && nH)
1239ff0f521cSArmin Le Grand {
1240ff0f521cSArmin Le Grand sal_uInt8 aEraseTrans(0xff);
1241ff0f521cSArmin Le Grand Bitmap aContent(rSize, 24);
1242ff0f521cSArmin Le Grand AlphaMask aAlpha(rSize, &aEraseTrans);
1243ff0f521cSArmin Le Grand
1244ff0f521cSArmin Le Grand aContent.Erase(COL_BLACK);
1245ff0f521cSArmin Le Grand
1246ff0f521cSArmin Le Grand BitmapWriteAccess* pContent = aContent.AcquireWriteAccess();
1247ff0f521cSArmin Le Grand BitmapWriteAccess* pAlpha = aAlpha.AcquireWriteAccess();
1248ff0f521cSArmin Le Grand
1249ff0f521cSArmin Le Grand if(pContent && pAlpha)
1250ff0f521cSArmin Le Grand {
1251ff0f521cSArmin Le Grand long x(0);
1252ff0f521cSArmin Le Grand long y(0);
1253ff0f521cSArmin Le Grand
1254*2b3b47daSArmin Le Grand // x == 0, y == 0, top-left corner
1255*2b3b47daSArmin Le Grand pContent->SetPixel(0, 0, aColorTopLeft);
1256*2b3b47daSArmin Le Grand pAlpha->SetPixelIndex(0, 0, nAlpha);
1257ff0f521cSArmin Le Grand
1258*2b3b47daSArmin Le Grand // y == 0, top line left to right
1259*2b3b47daSArmin Le Grand for(x = 1; x < nW - 1; x++)
1260ff0f521cSArmin Le Grand {
1261ff0f521cSArmin Le Grand Color aMix(aColorTopLeft);
1262ff0f521cSArmin Le Grand
1263ff0f521cSArmin Le Grand aMix.Merge(aColorTopRight, 255 - sal_uInt8((x * 255) / nW));
1264*2b3b47daSArmin Le Grand pContent->SetPixel(0, x, aMix);
1265*2b3b47daSArmin Le Grand pAlpha->SetPixelIndex(0, x, nAlpha);
1266ff0f521cSArmin Le Grand }
1267ff0f521cSArmin Le Grand
1268*2b3b47daSArmin Le Grand // x == nW - 1, y == 0, top-right corner
1269*2b3b47daSArmin Le Grand // #123690# Caution! When nW is 1, x == nW is possible (!)
1270*2b3b47daSArmin Le Grand if(x < nW)
1271*2b3b47daSArmin Le Grand {
1272*2b3b47daSArmin Le Grand pContent->SetPixel(0, x, aColorTopRight);
1273*2b3b47daSArmin Le Grand pAlpha->SetPixelIndex(0, x, nAlpha);
1274*2b3b47daSArmin Le Grand }
1275ff0f521cSArmin Le Grand
1276*2b3b47daSArmin Le Grand // x == 0 and nW - 1, left and right line top-down
1277*2b3b47daSArmin Le Grand for(y = 1; y < nH - 1; y++)
1278ff0f521cSArmin Le Grand {
1279ff0f521cSArmin Le Grand Color aMixA(aColorTopLeft);
1280ff0f521cSArmin Le Grand
1281ff0f521cSArmin Le Grand aMixA.Merge(aColorBottomLeft, 255 - sal_uInt8((y * 255) / nH));
1282ff0f521cSArmin Le Grand pContent->SetPixel(y, 0, aMixA);
1283ff0f521cSArmin Le Grand pAlpha->SetPixelIndex(y, 0, nAlpha);
1284ff0f521cSArmin Le Grand
1285*2b3b47daSArmin Le Grand // #123690# Caution! When nW is 1, x == nW is possible (!)
1286*2b3b47daSArmin Le Grand if(x < nW)
1287*2b3b47daSArmin Le Grand {
1288*2b3b47daSArmin Le Grand Color aMixB(aColorTopRight);
1289*2b3b47daSArmin Le Grand
1290ff0f521cSArmin Le Grand aMixB.Merge(aColorBottomRight, 255 - sal_uInt8((y * 255) / nH));
1291*2b3b47daSArmin Le Grand pContent->SetPixel(y, x, aMixB);
1292*2b3b47daSArmin Le Grand pAlpha->SetPixelIndex(y, x, nAlpha);
1293*2b3b47daSArmin Le Grand }
1294ff0f521cSArmin Le Grand }
1295ff0f521cSArmin Le Grand
1296*2b3b47daSArmin Le Grand // #123690# Caution! When nH is 1, y == nH is possible (!)
1297*2b3b47daSArmin Le Grand if(y < nH)
1298*2b3b47daSArmin Le Grand {
1299*2b3b47daSArmin Le Grand // x == 0, y == nH - 1, bottom-left corner
1300*2b3b47daSArmin Le Grand pContent->SetPixel(y, 0, aColorBottomLeft);
1301*2b3b47daSArmin Le Grand pAlpha->SetPixelIndex(y, 0, nAlpha);
1302ff0f521cSArmin Le Grand
1303*2b3b47daSArmin Le Grand // y == nH - 1, bottom line left to right
1304*2b3b47daSArmin Le Grand for(x = 1; x < nW - 1; x++)
1305ff0f521cSArmin Le Grand {
1306ff0f521cSArmin Le Grand Color aMix(aColorBottomLeft);
1307ff0f521cSArmin Le Grand
1308ff0f521cSArmin Le Grand aMix.Merge(aColorBottomRight, 255 - sal_uInt8(((x - 0)* 255) / nW));
1309ff0f521cSArmin Le Grand pContent->SetPixel(y, x, aMix);
1310ff0f521cSArmin Le Grand pAlpha->SetPixelIndex(y, x, nAlpha);
1311ff0f521cSArmin Le Grand }
1312ff0f521cSArmin Le Grand
1313*2b3b47daSArmin Le Grand // x == nW - 1, y == nH - 1, bottom-right corner
1314*2b3b47daSArmin Le Grand // #123690# Caution! When nW is 1, x == nW is possible (!)
1315*2b3b47daSArmin Le Grand if(x < nW)
1316*2b3b47daSArmin Le Grand {
1317ff0f521cSArmin Le Grand pContent->SetPixel(y, x, aColorBottomRight);
1318ff0f521cSArmin Le Grand pAlpha->SetPixelIndex(y, x, nAlpha);
1319*2b3b47daSArmin Le Grand }
1320*2b3b47daSArmin Le Grand }
1321ff0f521cSArmin Le Grand
1322ff0f521cSArmin Le Grand aContent.ReleaseAccess(pContent);
1323ff0f521cSArmin Le Grand aAlpha.ReleaseAccess(pAlpha);
1324ff0f521cSArmin Le Grand
1325ff0f521cSArmin Le Grand aLastResult = BitmapEx(aContent, aAlpha);
1326ff0f521cSArmin Le Grand }
1327ff0f521cSArmin Le Grand else
1328ff0f521cSArmin Le Grand {
1329ff0f521cSArmin Le Grand if(pContent)
1330ff0f521cSArmin Le Grand {
1331ff0f521cSArmin Le Grand aContent.ReleaseAccess(pContent);
1332ff0f521cSArmin Le Grand }
1333ff0f521cSArmin Le Grand
1334ff0f521cSArmin Le Grand if(pAlpha)
1335ff0f521cSArmin Le Grand {
1336ff0f521cSArmin Le Grand aAlpha.ReleaseAccess(pAlpha);
1337ff0f521cSArmin Le Grand }
1338ff0f521cSArmin Le Grand }
1339ff0f521cSArmin Le Grand }
1340ff0f521cSArmin Le Grand
1341ff0f521cSArmin Le Grand return aLastResult;
1342ff0f521cSArmin Le Grand }
1343ff0f521cSArmin Le Grand
13445f27b83cSArmin Le Grand // ------------------------------------------------------------------
134545fd3b9aSArmin Le Grand // eof
1346