merge the formfield patch from ooo-build
[ooovba.git] / vcl / source / gdi / alpha.cxx
blobda0b1c028929d7abca8b58aee0d51839b0ac8a97
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: alpha.cxx,v $
10 * $Revision: 1.11 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_vcl.hxx"
33 #include <tools/debug.hxx>
34 #include <vcl/bmpacc.hxx>
35 #include <tools/color.hxx>
36 #include <vcl/alpha.hxx>
38 // -------------
39 // - AlphaMask -
40 // -------------
42 AlphaMask::AlphaMask()
46 // -----------------------------------------------------------------------------
48 AlphaMask::AlphaMask( const Bitmap& rBitmap ) :
49 Bitmap( rBitmap )
51 if( !!rBitmap )
52 Bitmap::Convert( BMP_CONVERSION_8BIT_GREYS );
55 // -----------------------------------------------------------------------------
57 AlphaMask::AlphaMask( const AlphaMask& rAlphaMask ) :
58 Bitmap( rAlphaMask )
62 // -----------------------------------------------------------------------------
64 AlphaMask::AlphaMask( const Size& rSizePixel, BYTE* pEraseTransparency ) :
65 Bitmap( rSizePixel, 8, &Bitmap::GetGreyPalette( 256 ) )
67 if( pEraseTransparency )
68 Bitmap::Erase( Color( *pEraseTransparency, *pEraseTransparency, *pEraseTransparency ) );
71 // -----------------------------------------------------------------------------
73 AlphaMask::~AlphaMask()
77 // -----------------------------------------------------------------------------
79 AlphaMask& AlphaMask::operator=( const Bitmap& rBitmap )
81 *(Bitmap*) this = rBitmap;
83 if( !!rBitmap )
84 Bitmap::Convert( BMP_CONVERSION_8BIT_GREYS );
86 return *this;
89 // -----------------------------------------------------------------------------
91 const Bitmap& AlphaMask::ImplGetBitmap() const
93 return( (const Bitmap&) *this );
96 // -----------------------------------------------------------------------------
98 void AlphaMask::ImplSetBitmap( const Bitmap& rBitmap )
100 DBG_ASSERT( ( 8 == rBitmap.GetBitCount() ) && rBitmap.HasGreyPalette(), "AlphaMask::ImplSetBitmap: invalid bitmap" );
101 *(Bitmap*) this = rBitmap;
104 // -----------------------------------------------------------------------------
106 Bitmap AlphaMask::GetBitmap() const
108 return ImplGetBitmap();
111 // -----------------------------------------------------------------------------
113 BOOL AlphaMask::Crop( const Rectangle& rRectPixel )
115 return Bitmap::Crop( rRectPixel );
118 // -----------------------------------------------------------------------------
120 BOOL AlphaMask::Expand( ULONG nDX, ULONG nDY, BYTE* pInitTransparency )
122 Color aColor;
124 if( pInitTransparency )
125 aColor = Color( *pInitTransparency, *pInitTransparency, *pInitTransparency );
127 return Bitmap::Expand( nDX, nDY, pInitTransparency ? &aColor : NULL );
130 // -----------------------------------------------------------------------------
132 BOOL AlphaMask::CopyPixel( const Rectangle& rRectDst, const Rectangle& rRectSrc,
133 const AlphaMask* pAlphaSrc )
135 // Note: this code is copied from Bitmap::CopyPixel but avoids any palette lookups
136 // this optimization is possible because the palettes of AlphaMasks are always identical (8bit GreyPalette, see ctor)
138 const Size aSizePix( GetSizePixel() );
139 Rectangle aRectDst( rRectDst );
140 BOOL bRet = FALSE;
142 aRectDst.Intersection( Rectangle( Point(), aSizePix ) );
144 if( !aRectDst.IsEmpty() )
146 if( pAlphaSrc && ( *pAlphaSrc != *this ) )
148 Bitmap* pSrc = (Bitmap*) pAlphaSrc;
149 const Size aCopySizePix( pSrc->GetSizePixel() );
150 Rectangle aRectSrc( rRectSrc );
152 aRectSrc.Intersection( Rectangle( Point(), aCopySizePix ) );
154 if( !aRectSrc.IsEmpty() )
156 BitmapReadAccess* pReadAcc = pSrc->AcquireReadAccess();
158 if( pReadAcc )
160 BitmapWriteAccess* pWriteAcc = AcquireWriteAccess();
162 if( pWriteAcc )
164 const long nWidth = Min( aRectSrc.GetWidth(), aRectDst.GetWidth() );
165 const long nHeight = Min( aRectSrc.GetHeight(), aRectDst.GetHeight() );
166 const long nSrcEndX = aRectSrc.Left() + nWidth;
167 const long nSrcEndY = aRectSrc.Top() + nHeight;
168 long nDstY = aRectDst.Top();
170 for( long nSrcY = aRectSrc.Top(); nSrcY < nSrcEndY; nSrcY++, nDstY++ )
171 for( long nSrcX = aRectSrc.Left(), nDstX = aRectDst.Left(); nSrcX < nSrcEndX; nSrcX++, nDstX++ )
172 pWriteAcc->SetPixel( nDstY, nDstX, pReadAcc->GetPixel( nSrcY, nSrcX ) );
174 ReleaseAccess( pWriteAcc );
175 bRet = ( nWidth > 0L ) && ( nHeight > 0L );
178 pSrc->ReleaseAccess( pReadAcc );
182 else
184 Rectangle aRectSrc( rRectSrc );
186 aRectSrc.Intersection( Rectangle( Point(), aSizePix ) );
188 if( !aRectSrc.IsEmpty() && ( aRectSrc != aRectDst ) )
190 BitmapWriteAccess* pWriteAcc = AcquireWriteAccess();
192 if( pWriteAcc )
194 const long nWidth = Min( aRectSrc.GetWidth(), aRectDst.GetWidth() );
195 const long nHeight = Min( aRectSrc.GetHeight(), aRectDst.GetHeight() );
196 const long nSrcX = aRectSrc.Left();
197 const long nSrcY = aRectSrc.Top();
198 const long nSrcEndX1 = nSrcX + nWidth - 1L;
199 const long nSrcEndY1 = nSrcY + nHeight - 1L;
200 const long nDstX = aRectDst.Left();
201 const long nDstY = aRectDst.Top();
202 const long nDstEndX1 = nDstX + nWidth - 1L;
203 const long nDstEndY1 = nDstY + nHeight - 1L;
205 if( ( nDstX <= nSrcX ) && ( nDstY <= nSrcY ) )
207 for( long nY = nSrcY, nYN = nDstY; nY <= nSrcEndY1; nY++, nYN++ )
208 for( long nX = nSrcX, nXN = nDstX; nX <= nSrcEndX1; nX++, nXN++ )
209 pWriteAcc->SetPixel( nYN, nXN, pWriteAcc->GetPixel( nY, nX ) );
211 else if( ( nDstX <= nSrcX ) && ( nDstY >= nSrcY ) )
213 for( long nY = nSrcEndY1, nYN = nDstEndY1; nY >= nSrcY; nY--, nYN-- )
214 for( long nX = nSrcX, nXN = nDstX; nX <= nSrcEndX1; nX++, nXN++ )
215 pWriteAcc->SetPixel( nYN, nXN, pWriteAcc->GetPixel( nY, nX ) );
217 else if( ( nDstX >= nSrcX ) && ( nDstY <= nSrcY ) )
219 for( long nY = nSrcY, nYN = nDstY; nY <= nSrcEndY1; nY++, nYN++ )
220 for( long nX = nSrcEndX1, nXN = nDstEndX1; nX >= nSrcX; nX--, nXN-- )
221 pWriteAcc->SetPixel( nYN, nXN, pWriteAcc->GetPixel( nY, nX ) );
223 else
225 for( long nY = nSrcEndY1, nYN = nDstEndY1; nY >= nSrcY; nY--, nYN-- )
226 for( long nX = nSrcEndX1, nXN = nDstEndX1; nX >= nSrcX; nX--, nXN-- )
227 pWriteAcc->SetPixel( nYN, nXN, pWriteAcc->GetPixel( nY, nX ) );
230 ReleaseAccess( pWriteAcc );
231 bRet = TRUE;
237 return bRet;
241 // -----------------------------------------------------------------------------
243 BOOL AlphaMask::Erase( BYTE cTransparency )
245 return Bitmap::Erase( Color( cTransparency, cTransparency, cTransparency ) );
248 // -----------------------------------------------------------------------------
250 BOOL AlphaMask::Invert()
252 BitmapWriteAccess* pAcc = AcquireWriteAccess();
253 BOOL bRet = FALSE;
255 if( pAcc && pAcc->GetBitCount() == 8 )
257 BitmapColor aCol( 0 );
258 const long nWidth = pAcc->Width(), nHeight = pAcc->Height();
259 BYTE* pMap = new BYTE[ 256 ];
261 for( long i = 0; i < 256; i++ )
262 pMap[ i ] = ~(BYTE) i;
264 for( long nY = 0L; nY < nHeight; nY++ )
266 for( long nX = 0L; nX < nWidth; nX++ )
268 aCol.SetIndex( pMap[ pAcc->GetPixel( nY, nX ).GetIndex() ] );
269 pAcc->SetPixel( nY, nX, aCol );
273 delete[] pMap;
274 bRet = TRUE;
277 if( pAcc )
278 ReleaseAccess( pAcc );
280 return bRet;
283 // -----------------------------------------------------------------------------
285 BOOL AlphaMask::Mirror( ULONG nMirrorFlags )
287 return Bitmap::Mirror( nMirrorFlags );
290 // -----------------------------------------------------------------------------
292 BOOL AlphaMask::Scale( const Size& rNewSize, ULONG nScaleFlag )
294 BOOL bRet = Bitmap::Scale( rNewSize, nScaleFlag );
296 if( bRet && ( nScaleFlag == BMP_SCALE_INTERPOLATE ) )
297 Bitmap::Convert( BMP_CONVERSION_8BIT_GREYS );
299 return bRet;
302 // -----------------------------------------------------------------------------
304 BOOL AlphaMask::Scale( const double& rScaleX, const double& rScaleY, ULONG nScaleFlag )
306 BOOL bRet = Bitmap::Scale( rScaleX, rScaleY, nScaleFlag );
308 if( bRet && ( nScaleFlag == BMP_SCALE_INTERPOLATE ) )
309 Bitmap::Convert( BMP_CONVERSION_8BIT_GREYS );
311 return bRet;
314 // -----------------------------------------------------------------------------
316 BOOL AlphaMask::Rotate( long nAngle10, BYTE cFillTransparency )
318 return Bitmap::Rotate( nAngle10, Color( cFillTransparency, cFillTransparency, cFillTransparency ) );
321 // -----------------------------------------------------------------------------
323 BOOL AlphaMask::Replace( const Bitmap& rMask, BYTE cReplaceTransparency )
325 BitmapReadAccess* pMaskAcc = ( (Bitmap&) rMask ).AcquireReadAccess();
326 BitmapWriteAccess* pAcc = AcquireWriteAccess();
327 BOOL bRet = FALSE;
329 if( pMaskAcc && pAcc )
331 const BitmapColor aReplace( cReplaceTransparency );
332 const long nWidth = Min( pMaskAcc->Width(), pAcc->Width() );
333 const long nHeight = Min( pMaskAcc->Height(), pAcc->Height() );
334 const BitmapColor aMaskWhite( pMaskAcc->GetBestMatchingColor( Color( COL_WHITE ) ) );
336 for( long nY = 0L; nY < nHeight; nY++ )
337 for( long nX = 0L; nX < nWidth; nX++ )
338 if( pMaskAcc->GetPixel( nY, nX ) == aMaskWhite )
339 pAcc->SetPixel( nY, nX, aReplace );
342 ( (Bitmap&) rMask ).ReleaseAccess( pMaskAcc );
343 ReleaseAccess( pAcc );
345 return bRet;
348 // -----------------------------------------------------------------------------
350 BOOL AlphaMask::Replace( BYTE cSearchTransparency, BYTE cReplaceTransparency, ULONG
351 #ifdef DBG_UTIL
352 nTol
353 #endif
356 BitmapWriteAccess* pAcc = AcquireWriteAccess();
357 BOOL bRet = FALSE;
359 DBG_ASSERT( !nTol, "AlphaMask::Replace: nTol not used yet" );
361 if( pAcc && pAcc->GetBitCount() == 8 )
363 const long nWidth = pAcc->Width(), nHeight = pAcc->Height();
365 if( pAcc->GetScanlineFormat() == BMP_FORMAT_8BIT_PAL )
367 for( long nY = 0L; nY < nHeight; nY++ )
369 Scanline pScan = pAcc->GetScanline( nY );
371 for( long nX = 0L; nX < nWidth; nX++, pScan++ )
373 if( *pScan == cSearchTransparency )
374 *pScan = cReplaceTransparency;
378 else
380 BitmapColor aReplace( cReplaceTransparency );
382 for( long nY = 0L; nY < nHeight; nY++ )
384 for( long nX = 0L; nX < nWidth; nX++ )
386 if( pAcc->GetPixel( nY, nX ).GetIndex() == cSearchTransparency )
387 pAcc->SetPixel( nY, nX, aReplace );
392 bRet = TRUE;
395 if( pAcc )
396 ReleaseAccess( pAcc );
398 return bRet;
401 // -----------------------------------------------------------------------------
403 BOOL AlphaMask::Replace( BYTE* pSearchTransparencies, BYTE* pReplaceTransparencies,
404 ULONG nColorCount, ULONG* pTols )
406 Color* pSearchColors = new Color[ nColorCount ];
407 Color* pReplaceColors = new Color[ nColorCount ];
408 BOOL bRet;
410 for( ULONG i = 0; i < nColorCount; i++ )
412 const BYTE cSearchTransparency = pSearchTransparencies[ i ];
413 const BYTE cReplaceTransparency = pReplaceTransparencies[ i ];
415 pSearchColors[ i ] = Color( cSearchTransparency, cSearchTransparency, cSearchTransparency );
416 pReplaceColors[ i ] = Color( cReplaceTransparency, cReplaceTransparency, cReplaceTransparency );
419 bRet = Bitmap::Replace( pSearchColors, pReplaceColors, nColorCount, pTols ) &&
420 Bitmap::Convert( BMP_CONVERSION_8BIT_GREYS );
422 delete[] pSearchColors;
423 delete[] pReplaceColors;
425 return bRet;
428 // -----------------------------------------------------------------------------
430 void AlphaMask::ReleaseAccess( BitmapReadAccess* pAccess )
432 if( pAccess )
434 Bitmap::ReleaseAccess( pAccess );
435 Bitmap::Convert( BMP_CONVERSION_8BIT_GREYS );