merge the formfield patch from ooo-build
[ooovba.git] / vcl / source / gdi / imgcons.cxx
blobdd151bba9547383225480601300534415d9c943f
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: imgcons.cxx,v $
10 * $Revision: 1.8 $
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"
34 #include <tools/stream.hxx>
35 #include <vcl/bmpacc.hxx>
36 #include <vcl/bitmapex.hxx>
37 #include <vcl/image.hxx>
38 #include <vcl/imgcons.hxx>
40 // -------------------
41 // - ImplColorMapper -
42 // -------------------
44 class ImplColorMapper
46 Color maCol;
47 ULONG mnR;
48 ULONG mnG;
49 ULONG mnB;
50 ULONG mnT;
51 ULONG mnRShift;
52 ULONG mnGShift;
53 ULONG mnBShift;
54 ULONG mnTShift;
56 ULONG ImplCalcMaskShift( ULONG nVal );
58 public:
60 ImplColorMapper( ULONG nRMask, ULONG nGMask, ULONG nBMask, ULONG nTMask );
61 ~ImplColorMapper();
63 const Color& ImplGetColor( ULONG nColor )
65 maCol.SetRed( (UINT8) ( ( nColor & mnR ) >> mnRShift ) );
66 maCol.SetGreen( (UINT8) ( ( nColor & mnG ) >> mnGShift ) );
67 maCol.SetBlue( (UINT8) ( ( nColor & mnB ) >> mnBShift ) );
68 maCol.SetTransparency( (UINT8) ( ( nColor & mnT ) >> mnTShift ) );
69 return maCol;
73 // -----------------------------------------------------------------------------
75 ImplColorMapper::ImplColorMapper( ULONG nRMask, ULONG nGMask, ULONG nBMask, ULONG nTMask ) :
76 mnR( nRMask ),
77 mnG( nGMask ),
78 mnB( nBMask ),
79 mnT( nTMask )
81 mnRShift = ImplCalcMaskShift( mnR );
82 mnGShift = ImplCalcMaskShift( mnG );
83 mnBShift = ImplCalcMaskShift( mnB );
84 mnTShift = ImplCalcMaskShift( mnT );
87 // -----------------------------------------------------------------------------
89 ImplColorMapper::~ImplColorMapper()
93 // -----------------------------------------------------------------------------
95 ULONG ImplColorMapper::ImplCalcMaskShift( ULONG nVal )
97 DBG_ASSERT( nVal > 0, "Mask has no value!" );
99 ULONG nRet = 0UL;
101 for( ULONG i = 0UL; i < 32; i++ )
103 if( nVal & ( 1UL << i ) )
105 nRet = i;
106 break;
110 return nRet;
113 // -----------------
114 // - ImageConsumer -
115 // -----------------
117 ImageConsumer::ImageConsumer() :
118 mpMapper( NULL ),
119 mpPal ( NULL ),
120 mnStatus( 0UL ),
121 mbTrans ( FALSE )
125 // -----------------------------------------------------------------------------
127 ImageConsumer::~ImageConsumer()
129 delete[] mpPal;
130 delete mpMapper;
133 // -----------------------------------------------------------------------------
135 void ImageConsumer::Init( sal_uInt32 nWidth, sal_uInt32 nHeight )
137 maSize = Size( nWidth, nHeight );
138 maBitmap = maMask = Bitmap();
139 mnStatus = 0UL;
140 mbTrans = FALSE;
143 // -----------------------------------------------------------------------------
145 void ImageConsumer::SetColorModel( USHORT nBitCount,
146 sal_uInt32 nPalEntries, const sal_uInt32* pRGBAPal,
147 sal_uInt32 nRMask, sal_uInt32 nGMask, sal_uInt32 nBMask, sal_uInt32 nAMask )
149 DBG_ASSERT( maSize.Width() && maSize.Height(), "Missing call to ImageConsumer::Init(...)!" );
151 BitmapPalette aPal( Min( (USHORT) nPalEntries, (USHORT) 256 ) );
153 if( nPalEntries )
155 BitmapColor aCol;
156 const sal_Int32* pTmp = (sal_Int32*) pRGBAPal;
158 delete mpMapper;
159 mpMapper = NULL;
161 delete[] mpPal;
162 mpPal = new Color[ nPalEntries ];
164 for( ULONG i = 0; i < nPalEntries; i++, pTmp++ )
166 Color& rCol = mpPal[ i ];
167 BYTE cVal;
169 cVal = (BYTE) ( ( *pTmp & 0xff000000UL ) >> 24L );
170 rCol.SetRed( cVal );
172 if( i < (ULONG) aPal.GetEntryCount() )
173 aPal[ (USHORT) i ].SetRed( cVal );
175 cVal = (BYTE) ( ( *pTmp & 0x00ff0000UL ) >> 16L );
176 rCol.SetGreen( cVal );
178 if( i < (ULONG) aPal.GetEntryCount() )
179 aPal[ (USHORT) i ].SetGreen( cVal );
181 cVal = (BYTE) ( ( *pTmp & 0x0000ff00UL ) >> 8L );
182 rCol.SetBlue( cVal );
184 if( i < (ULONG) aPal.GetEntryCount() )
185 aPal[ (USHORT) i ].SetBlue( cVal );
187 rCol.SetTransparency( (BYTE) ( ( *pTmp & 0x000000ffL ) ) );
190 if( nBitCount <= 1 )
191 nBitCount = 1;
192 else if( nBitCount <= 4 )
193 nBitCount = 4;
194 else if( nBitCount <= 8 )
195 nBitCount = 8;
196 else
197 nBitCount = 24;
199 else
201 delete mpMapper;
202 mpMapper = new ImplColorMapper( nRMask, nGMask, nBMask, nAMask );
204 delete[] mpPal;
205 mpPal = NULL;
207 nBitCount = 24;
210 if( !maBitmap )
213 maBitmap = Bitmap( maSize, nBitCount, &aPal );
214 maMask = Bitmap( maSize, 1 );
215 maMask.Erase( COL_BLACK );
216 mbTrans = FALSE;
220 // -----------------------------------------------------------------------------
222 void ImageConsumer::SetPixelsByBytes( sal_uInt32 nConsX, sal_uInt32 nConsY,
223 sal_uInt32 nConsWidth, sal_uInt32 nConsHeight,
224 const BYTE* pData, sal_uInt32 nOffset, sal_uInt32 nScanSize )
226 DBG_ASSERT( !!maBitmap && !!maMask, "Missing call to ImageConsumer::SetColorModel(...)!" );
228 BitmapWriteAccess* pBmpAcc = maBitmap.AcquireWriteAccess();
229 BitmapWriteAccess* pMskAcc = maMask.AcquireWriteAccess();
230 sal_Bool bDataChanged = sal_False;
232 if( pBmpAcc && pMskAcc )
234 const long nWidth = pBmpAcc->Width();
235 const long nHeight = pBmpAcc->Height();
237 maChangedRect = Rectangle( Point(), Size( nWidth, nHeight ) );
238 maChangedRect.Intersection( Rectangle( Point( nConsX, nConsY ), Size( nConsWidth, nConsHeight ) ) );
240 if( !maChangedRect.IsEmpty() )
242 const long nStartX = maChangedRect.Left();
243 const long nEndX = maChangedRect.Right();
244 const long nStartY = maChangedRect.Top();
245 const long nEndY = maChangedRect.Bottom();
247 if( mpMapper && ( pBmpAcc->GetBitCount() > 8 ) )
249 BitmapColor aCol;
250 BitmapColor aMskWhite( pMskAcc->GetBestMatchingColor( Color( COL_WHITE ) ) );
252 for( long nY = nStartY; nY <= nEndY; nY++ )
254 const BYTE* pTmp = pData + ( nY - nStartY ) * nScanSize + nOffset;
256 for( long nX = nStartX; nX <= nEndX; nX++ )
258 const Color& rCol = mpMapper->ImplGetColor( *pTmp++ );
260 // 0: Transparent; >0: Non-Transparent
261 if( !rCol.GetTransparency() )
263 pMskAcc->SetPixel( nY, nX, aMskWhite );
264 mbTrans = TRUE;
266 else
268 aCol.SetRed( rCol.GetRed() );
269 aCol.SetGreen( rCol.GetGreen() );
270 aCol.SetBlue( rCol.GetBlue() );
271 pBmpAcc->SetPixel( nY, nX, aCol );
276 bDataChanged = sal_True;
278 else if( mpPal && ( pBmpAcc->GetBitCount() <= 8 ) )
280 BitmapColor aIndex( (BYTE) 0 );
281 BitmapColor aMskWhite( pMskAcc->GetBestMatchingColor( Color( COL_WHITE ) ) );
283 for( long nY = nStartY; nY <= nEndY; nY++ )
285 const BYTE* pTmp = pData + ( nY - nStartY ) * nScanSize + nOffset;
287 for( long nX = nStartX; nX <= nEndX; nX++ )
289 const BYTE cIndex = *pTmp++;
290 const Color& rCol = mpPal[ cIndex ];
292 // 0: Transparent; >0: Non-Transparent
293 if( !rCol.GetTransparency() )
295 pMskAcc->SetPixel( nY, nX, aMskWhite );
296 mbTrans = TRUE;
298 else
300 aIndex.SetIndex( cIndex );
301 pBmpAcc->SetPixel( nY, nX, aIndex );
306 bDataChanged = sal_True;
308 else if( mpPal && ( pBmpAcc->GetBitCount() > 8 ) )
310 BitmapColor aCol;
311 BitmapColor aMskWhite( pMskAcc->GetBestMatchingColor( Color( COL_WHITE ) ) );
313 for( long nY = nStartY; nY <= nEndY; nY++ )
315 const BYTE* pTmp = pData + ( nY - nStartY ) * nScanSize + nOffset;
317 for( long nX = nStartX; nX <= nEndX; nX++ )
319 const BYTE cIndex = *pTmp++;
320 const Color& rCol = mpPal[ cIndex ];
322 // 0: Transparent; >0: Non-Transparent
323 if( !rCol.GetTransparency() )
325 pMskAcc->SetPixel( nY, nX, aMskWhite );
326 mbTrans = TRUE;
328 else
330 aCol.SetRed( rCol.GetRed() );
331 aCol.SetGreen( rCol.GetGreen() );
332 aCol.SetBlue( rCol.GetBlue() );
333 pBmpAcc->SetPixel( nY, nX, aCol );
338 bDataChanged = sal_True;
340 else
342 DBG_ERROR( "Producer format error!" );
343 maChangedRect.SetEmpty();
347 else
348 maChangedRect.SetEmpty();
350 maBitmap.ReleaseAccess( pBmpAcc );
351 maMask.ReleaseAccess( pMskAcc );
353 if( bDataChanged )
354 DataChanged();
357 // -----------------------------------------------------------------------------
359 void ImageConsumer::SetPixelsByLongs( sal_uInt32 nConsX, sal_uInt32 nConsY,
360 sal_uInt32 nConsWidth, sal_uInt32 nConsHeight,
361 const sal_uInt32* pData, sal_uInt32 nOffset, sal_uInt32 nScanSize )
363 DBG_ASSERT( !!maBitmap && !!maMask, "Missing call to ImageConsumer::SetColorModel(...)!" );
365 BitmapWriteAccess* pBmpAcc = maBitmap.AcquireWriteAccess();
366 BitmapWriteAccess* pMskAcc = maMask.AcquireWriteAccess();
367 sal_Bool bDataChanged = sal_False;
369 if( pBmpAcc && pMskAcc )
371 const long nWidth = pBmpAcc->Width();
372 const long nHeight = pBmpAcc->Height();
374 maChangedRect = Rectangle( Point(), Size( nWidth, nHeight ) );
375 maChangedRect.Intersection( Rectangle( Point( nConsX, nConsY ), Size( nConsWidth, nConsHeight ) ) );
377 if( !maChangedRect.IsEmpty() )
379 const long nStartX = maChangedRect.Left();
380 const long nEndX = maChangedRect.Right();
381 const long nStartY = maChangedRect.Top();
382 const long nEndY = maChangedRect.Bottom();
384 if( mpMapper && ( pBmpAcc->GetBitCount() > 8 ) )
386 BitmapColor aCol;
387 BitmapColor aMskWhite( pMskAcc->GetBestMatchingColor( Color( COL_WHITE ) ) );
389 for( long nY = nStartY; nY <= nEndY; nY++ )
391 const sal_Int32* pTmp = (sal_Int32*) pData + ( nY - nStartY ) * nScanSize + nOffset;
393 for( long nX = nStartX; nX <= nEndX; nX++ )
395 const Color& rCol = mpMapper->ImplGetColor( *pTmp++ );
397 // 0: Transparent; >0: Non-Transparent
398 if( !rCol.GetTransparency() )
400 pMskAcc->SetPixel( nY, nX, aMskWhite );
401 mbTrans = TRUE;
403 else
405 aCol.SetRed( rCol.GetRed() );
406 aCol.SetGreen( rCol.GetGreen() );
407 aCol.SetBlue( rCol.GetBlue() );
408 pBmpAcc->SetPixel( nY, nX, aCol );
413 bDataChanged = sal_True;
415 else if( mpPal && ( pBmpAcc->GetBitCount() <= 8 ) )
417 BitmapColor aIndex( (BYTE) 0 );
418 BitmapColor aMskWhite( pMskAcc->GetBestMatchingColor( Color( COL_WHITE ) ) );
420 for( long nY = nStartY; nY <= nEndY; nY++ )
422 const sal_Int32* pTmp = (sal_Int32*) pData + ( nY - nStartY ) * nScanSize + nOffset;
424 for( long nX = nStartX; nX <= nEndX; nX++ )
426 const sal_Int32 nIndex = *pTmp++;
427 const Color& rCol = mpPal[ nIndex ];
429 // 0: Transparent; >0: Non-Transparent
430 if( !rCol.GetTransparency() )
432 pMskAcc->SetPixel( nY, nX, aMskWhite );
433 mbTrans = TRUE;
435 else
437 aIndex.SetIndex( (BYTE) nIndex );
438 pBmpAcc->SetPixel( nY, nX, aIndex );
443 bDataChanged = sal_True;
445 else if( mpPal && ( pBmpAcc->GetBitCount() > 8 ) )
447 BitmapColor aCol;
448 BitmapColor aMskWhite( pMskAcc->GetBestMatchingColor( Color( COL_WHITE ) ) );
450 for( long nY = nStartY; nY <= nEndY; nY++ )
452 const sal_Int32* pTmp = (sal_Int32*) pData + ( nY - nStartY ) * nScanSize + nOffset;
454 for( long nX = nStartX; nX <= nEndX; nX++ )
456 const sal_Int32 nIndex = *pTmp++;
457 const Color& rCol = mpPal[ nIndex ];
459 // 0: Transparent; >0: Non-Transparent
460 if( !rCol.GetTransparency() )
462 pMskAcc->SetPixel( nY, nX, aMskWhite );
463 mbTrans = TRUE;
465 else
467 aCol.SetRed( rCol.GetRed() );
468 aCol.SetGreen( rCol.GetGreen() );
469 aCol.SetBlue( rCol.GetBlue() );
470 pBmpAcc->SetPixel( nY, nX, aCol );
475 bDataChanged = sal_True;
477 else
479 DBG_ERROR( "Producer format error!" );
480 maChangedRect.SetEmpty();
484 else
485 maChangedRect.SetEmpty();
487 maBitmap.ReleaseAccess( pBmpAcc );
488 maMask.ReleaseAccess( pMskAcc );
490 if( bDataChanged )
491 DataChanged();
494 // -----------------------------------------------------------------------------
496 void ImageConsumer::Completed( sal_uInt32 nStatus /*, ImageProducer& rProducer */ )
498 delete mpMapper;
499 mpMapper = NULL;
500 delete[] mpPal;
501 mpPal = NULL;
502 maSize = Size();
503 mnStatus = nStatus;
505 switch( nStatus )
507 case( SINGLEFRAMEDONE ):
508 case( STATICIMAGEDONE ):
510 if( !mbTrans )
511 maMask = Bitmap();
513 break;
515 case( IMAGEERROR ):
516 case( IMAGEABORTED ):
517 maBitmap = maMask = Bitmap();
518 break;
520 default:
521 break;
524 // rProducer.RemoveConsumer( *this );
526 if( maDoneLink.IsSet() )
527 maDoneLink.Call( this );
530 // -----------------------------------------------------------------------------
532 void ImageConsumer::DataChanged()
534 if( maChgLink.IsSet() )
535 maChgLink.Call( this );
538 // -----------------------------------------------------------------------------
540 sal_uInt32 ImageConsumer::GetStatus() const
542 return mnStatus;
545 // -----------------------------------------------------------------------------
547 BOOL ImageConsumer::GetData( BitmapEx& rBmpEx ) const
549 const BOOL bRet = ( SINGLEFRAMEDONE == mnStatus || STATICIMAGEDONE == mnStatus );
551 if( bRet )
553 if( !!maMask )
554 rBmpEx = BitmapEx( maBitmap, maMask );
555 else
556 rBmpEx = BitmapEx( maBitmap );
559 return bRet;
562 // -----------------------------------------------------------------------------
564 BOOL ImageConsumer::GetData( Image& rImage ) const
566 const BOOL bRet = ( SINGLEFRAMEDONE == mnStatus || STATICIMAGEDONE == mnStatus );
568 if( bRet )
570 if( !!maMask )
571 rImage = Image( maBitmap, maMask );
572 else
573 rImage = Image( maBitmap );
576 return bRet;