xref: /trunk/main/vcl/source/gdi/impimage.cxx (revision 9f62ea84)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_vcl.hxx"
26 
27 #include <vcl/outdev.hxx>
28 #include <vcl/bitmapex.hxx>
29 #include <vcl/alpha.hxx>
30 #include <vcl/window.hxx>
31 #include <vcl/bmpacc.hxx>
32 #include <vcl/virdev.hxx>
33 #include <vcl/image.hxx>
34 
35 #include <image.h>
36 
37 // -----------
38 // - Defines -
39 // -----------
40 
41 #define IMPSYSIMAGEITEM_MASK		( 0x01 )
42 #define IMPSYSIMAGEITEM_ALPHA		( 0x02 )
43 #define DISA_ALL					( 0xffff )
44 
45 // ----------------
46 // - ImageAryData -
47 // ----------------
48 
ImageAryData()49 ImageAryData::ImageAryData() :
50 	maName(),
51 	mnId( 0 ),
52 	maBitmapEx()
53 {
54 }
55 
56 // -----------------------------------------------------------------------
57 
ImageAryData(const ImageAryData & rData)58 ImageAryData::ImageAryData( const ImageAryData& rData ) :
59 	maName( rData.maName ),
60 	mnId( rData.mnId ),
61 	maBitmapEx( rData.maBitmapEx )
62 {
63 }
64 
ImageAryData(const rtl::OUString & aName,sal_uInt16 nId,const BitmapEx & aBitmap)65 ImageAryData::ImageAryData( const rtl::OUString &aName,
66 							sal_uInt16 nId, const BitmapEx &aBitmap )
67 		: maName( aName ), mnId( nId ), maBitmapEx( aBitmap )
68 {
69 }
70 
71 // -----------------------------------------------------------------------
72 
~ImageAryData()73 ImageAryData::~ImageAryData()
74 {
75 }
76 
77 // -----------------------------------------------------------------------
78 
operator =(const ImageAryData & rData)79 ImageAryData& ImageAryData::operator=( const ImageAryData& rData )
80 {
81 	maName = rData.maName;
82 	mnId = rData.mnId;
83 	maBitmapEx = rData.maBitmapEx;
84 
85 	return *this;
86 }
87 
88 // -----------------
89 // - ImplImageList -
90 // -----------------
91 
ImplImageList()92 ImplImageList::ImplImageList()
93 {
94 }
95 
ImplImageList(const ImplImageList & aSrc)96 ImplImageList::ImplImageList( const ImplImageList &aSrc ) :
97     maPrefix( aSrc.maPrefix ),
98     maImageSize( aSrc.maImageSize ),
99     mnRefCount( 1 )
100 {
101 	maImages.reserve( aSrc.maImages.size() );
102     for ( ImageAryDataVec::const_iterator aIt = aSrc.maImages.begin(), aEnd = aSrc.maImages.end(); aIt != aEnd; ++aIt )
103 	{
104         ImageAryData* pAryData = new ImageAryData( **aIt );
105         maImages.push_back( pAryData );
106         if( pAryData->maName.getLength() )
107             maNameHash [ pAryData->maName ] = pAryData;
108 	}
109 }
110 
~ImplImageList()111 ImplImageList::~ImplImageList()
112 {
113     for ( ImageAryDataVec::iterator aIt = maImages.begin(), aEnd = maImages.end(); aIt != aEnd; ++aIt )
114         delete *aIt;
115 }
116 
AddImage(const::rtl::OUString & aName,sal_uInt16 nId,const BitmapEx & aBitmapEx)117 void ImplImageList::AddImage( const ::rtl::OUString &aName,
118 							  sal_uInt16 nId, const BitmapEx &aBitmapEx )
119 {
120 	ImageAryData *pImg = new ImageAryData( aName, nId, aBitmapEx );
121 	maImages.push_back( pImg );
122 	if( aName.getLength() )
123 		maNameHash [ aName ] = pImg;
124 }
125 
RemoveImage(sal_uInt16 nPos)126 void ImplImageList::RemoveImage( sal_uInt16 nPos )
127 {
128 	ImageAryData *pImg = maImages[ nPos ];
129 	if( pImg->maName.getLength() )
130 		maNameHash.erase( pImg->maName );
131 	maImages.erase( maImages.begin() + nPos );
132 }
133 
GetImageCount() const134 sal_uInt16 ImplImageList::GetImageCount() const
135 {
136     return sal::static_int_cast< sal_uInt16 >( maImages.size() );
137 }
138 
139 // -----------------
140 // - ImplImageData -
141 // -----------------
142 
ImplImageData(const BitmapEx & rBmpEx)143 ImplImageData::ImplImageData( const BitmapEx& rBmpEx ) :
144 	mpImageBitmap( NULL ),
145 	maBmpEx( rBmpEx )
146 {
147 }
148 
149 // -----------------------------------------------------------------------
150 
~ImplImageData()151 ImplImageData::~ImplImageData()
152 {
153 	delete mpImageBitmap;
154 }
155 
156 // -----------------
157 // - ImplImageData -
158 // -----------------
159 
IsEqual(const ImplImageData & rData)160 sal_Bool ImplImageData::IsEqual( const ImplImageData& rData )
161 {
162 	return( maBmpEx == rData.maBmpEx );
163 }
164 
165 // -------------
166 // - ImplImage -
167 // -------------
168 
ImplImage()169 ImplImage::ImplImage()
170 {
171 }
172 
173 // ------------------------------------------------------------------------------
174 
~ImplImage()175 ImplImage::~ImplImage()
176 {
177 	switch( meType )
178 	{
179 		case IMAGETYPE_BITMAP:
180 			delete static_cast< Bitmap* >( mpData );
181 		break;
182 
183 		case IMAGETYPE_IMAGE:
184 			delete static_cast< ImplImageData* >( mpData );
185 		break;
186 	}
187 }
188 
189 // ----------------
190 // - ImplImageBmp -
191 // ----------------
192 
ImplImageBmp()193 ImplImageBmp::ImplImageBmp() :
194 	mpDisplayBmp( NULL ),
195 	mpInfoAry( NULL ),
196 	mnSize( 0 )
197 {
198 }
199 
200 // -------------
201 // - ImplImage -
202 // -------------
203 
~ImplImageBmp()204 ImplImageBmp::~ImplImageBmp()
205 {
206 	delete[] mpInfoAry;
207 	delete mpDisplayBmp;
208 }
209 
210 // -----------------------------------------------------------------------
211 
Create(long nItemWidth,long nItemHeight,sal_uInt16 nInitSize)212 void ImplImageBmp::Create( long nItemWidth, long nItemHeight, sal_uInt16 nInitSize )
213 {
214 	const Size aTotalSize( nInitSize * nItemWidth, nItemHeight );
215 
216 	maBmpEx = Bitmap( aTotalSize, 24 );
217 	maDisabledBmpEx.SetEmpty();
218 
219 	delete mpDisplayBmp;
220 	mpDisplayBmp = NULL;
221 
222 	maSize = Size( nItemWidth, nItemHeight );
223 	mnSize = nInitSize;
224 
225 	delete[] mpInfoAry;
226 	mpInfoAry = new sal_uInt8[ mnSize ];
227 	memset( mpInfoAry, 0, mnSize );
228 }
229 
230 // -----------------------------------------------------------------------
231 
Create(const BitmapEx & rBmpEx,long nItemWidth,long nItemHeight,sal_uInt16 nInitSize)232 void ImplImageBmp::Create( const BitmapEx& rBmpEx, long nItemWidth, long nItemHeight, sal_uInt16 nInitSize )
233 {
234 	maBmpEx = rBmpEx;
235 	maDisabledBmpEx.SetEmpty();
236 
237 	delete mpDisplayBmp;
238 	mpDisplayBmp = NULL;
239 
240 	maSize = Size( nItemWidth, nItemHeight );
241 	mnSize = nInitSize;
242 
243 	delete[] mpInfoAry;
244 	mpInfoAry = new sal_uInt8[ mnSize ];
245 	memset( mpInfoAry,
246 			rBmpEx.IsAlpha() ? IMPSYSIMAGEITEM_ALPHA : ( rBmpEx.IsTransparent() ? IMPSYSIMAGEITEM_MASK : 0 ),
247 			mnSize );
248 }
249 
250 // -----------------------------------------------------------------------
251 
Expand(sal_uInt16 nGrowSize)252 void ImplImageBmp::Expand( sal_uInt16 nGrowSize )
253 {
254 	const sal_uLong 	nDX = nGrowSize * maSize.Width();
255 	const sal_uInt16	nOldSize = mnSize;
256 	sal_uInt8*			pNewAry = new sal_uInt8[ mnSize = sal::static_int_cast<sal_uInt16>(mnSize+nGrowSize) ];
257 
258 	maBmpEx.Expand( nDX, 0UL );
259 
260 	if( !maDisabledBmpEx.IsEmpty() )
261 		maDisabledBmpEx.Expand( nDX, 0UL );
262 
263 	delete mpDisplayBmp;
264 	mpDisplayBmp = NULL;
265 
266 	memset( pNewAry, 0, mnSize );
267 	memcpy( pNewAry, mpInfoAry, nOldSize );
268 	delete[] mpInfoAry;
269 	mpInfoAry = pNewAry;
270 }
271 
272 // -----------------------------------------------------------------------
273 
Invert()274 void ImplImageBmp::Invert()
275 {
276 	delete mpDisplayBmp;
277 	mpDisplayBmp = NULL;
278 
279     maBmpEx.Invert();
280 }
281 
282 // -----------------------------------------------------------------------
283 
Replace(sal_uInt16 nPos,sal_uInt16 nSrcPos)284 void ImplImageBmp::Replace( sal_uInt16 nPos, sal_uInt16 nSrcPos )
285 {
286     const Point     aSrcPos( nSrcPos * maSize.Width(), 0L ), aPos( nPos * maSize.Width(), 0L );
287 	const Rectangle aSrcRect( aSrcPos, maSize );
288 	const Rectangle aDstRect( aPos, maSize );
289 
290 	maBmpEx.CopyPixel( aDstRect, aSrcRect );
291 
292 	if( !maDisabledBmpEx.IsEmpty() )
293 		maDisabledBmpEx.CopyPixel( aDstRect, aSrcRect );
294 
295 	delete mpDisplayBmp;
296 	mpDisplayBmp = NULL;
297 
298 	mpInfoAry[ nPos ] = mpInfoAry[ nSrcPos ];
299 }
300 
301 // -----------------------------------------------------------------------
302 
Replace(sal_uInt16 nPos,const ImplImageBmp & rImageBmp,sal_uInt16 nSrcPos)303 void ImplImageBmp::Replace( sal_uInt16 nPos, const ImplImageBmp& rImageBmp, sal_uInt16 nSrcPos )
304 {
305     const Point     aSrcPos( nSrcPos * maSize.Width(), 0L ), aPos( nPos * maSize.Width(), 0L );
306 	const Rectangle aSrcRect( aSrcPos, maSize );
307 	const Rectangle aDstRect( aPos, maSize );
308 
309 	maBmpEx.CopyPixel( aDstRect, aSrcRect, &rImageBmp.maBmpEx );
310 
311 	ImplUpdateDisabledBmpEx( nPos );
312 	delete mpDisplayBmp;
313 	mpDisplayBmp = NULL;
314 
315 	mpInfoAry[ nPos ] = rImageBmp.mpInfoAry[ nSrcPos ];
316 }
317 
318 // -----------------------------------------------------------------------
319 
Replace(sal_uInt16 nPos,const BitmapEx & rBmpEx)320 void ImplImageBmp::Replace( sal_uInt16 nPos, const BitmapEx& rBmpEx )
321 {
322     const Point     aNullPos, aPos( nPos * maSize.Width(), 0L );
323 	const Rectangle aSrcRect( aNullPos, maSize );
324 	const Rectangle aDstRect( aPos, maSize );
325 
326 	maBmpEx.CopyPixel( aDstRect, aSrcRect, &rBmpEx );
327 
328 	ImplUpdateDisabledBmpEx( nPos );
329 	delete mpDisplayBmp;
330 	mpDisplayBmp = NULL;
331 
332 	mpInfoAry[ nPos ] &= ~( IMPSYSIMAGEITEM_MASK | IMPSYSIMAGEITEM_ALPHA );
333 	mpInfoAry[ nPos ] |= ( rBmpEx.IsAlpha() ? IMPSYSIMAGEITEM_ALPHA : ( rBmpEx.IsTransparent() ? IMPSYSIMAGEITEM_MASK : 0 ) );
334 }
335 
336 // -----------------------------------------------------------------------
337 
ReplaceColors(const Color * pSrcColors,const Color * pDstColors,sal_uLong nColorCount)338 void ImplImageBmp::ReplaceColors( const Color* pSrcColors, const Color* pDstColors, sal_uLong nColorCount )
339 {
340 	maBmpEx.Replace( pSrcColors, pDstColors, nColorCount );
341 	delete mpDisplayBmp;
342 	mpDisplayBmp = NULL;
343 }
344 
345 // -----------------------------------------------------------------------
346 
ColorTransform(BmpColorMode eColorMode)347 void ImplImageBmp::ColorTransform( BmpColorMode eColorMode )
348 {
349 	maBmpEx = maBmpEx.GetColorTransformedBitmapEx( eColorMode );
350 	delete mpDisplayBmp;
351 	mpDisplayBmp = NULL;
352 }
353 
354 // -----------------------------------------------------------------------
355 
GetBitmapEx(sal_uInt16 nPosCount,sal_uInt16 * pPosAry) const356 BitmapEx ImplImageBmp::GetBitmapEx( sal_uInt16 nPosCount, sal_uInt16* pPosAry ) const
357 {
358 	const Bitmap	aNewBmp( Size( nPosCount * maSize.Width(), maSize.Height() ),  maBmpEx.GetBitmap().GetBitCount() );
359 	BitmapEx 		aRet;
360     if( maBmpEx.IsAlpha() )
361     {
362         // initialize target bitmap with an empty alpha mask
363         // which allows for using an optimized copypixel later on (see AlphaMask::CopyPixel)
364         // that avoids palette lookups
365         AlphaMask aAlpha( Size( nPosCount * maSize.Width(), maSize.Height() ) );
366         aRet = BitmapEx( aNewBmp, aAlpha );
367     }
368     else
369         aRet  = BitmapEx( aNewBmp );
370 
371 	for( sal_uInt16 i = 0; i < nPosCount; i++ )
372 	{
373         const Point     aSrcPos( pPosAry[ i ] * maSize.Width(), 0L );
374 		const Point		aPos( i * maSize.Width(), 0L );
375 		const Rectangle aSrcRect( aSrcPos, maSize );
376 		const Rectangle aDstRect( aPos, maSize );
377 
378 		aRet.CopyPixel( aDstRect, aSrcRect, &maBmpEx );
379 	}
380 
381 	return aRet;
382 }
383 
384 // -----------------------------------------------------------------------
385 
Draw(sal_uInt16 nPos,OutputDevice * pOutDev,const Point & rPos,sal_uInt16 nStyle,const Size * pSize)386 void ImplImageBmp::Draw( sal_uInt16 nPos, OutputDevice* pOutDev,
387 						 const Point& rPos, sal_uInt16 nStyle,
388 						 const Size* pSize )
389 {
390 	if( pOutDev->IsDeviceOutputNecessary() )
391 	{
392         const Point aSrcPos( nPos * maSize.Width(), 0 );
393 		Size 		aOutSize;
394 
395 		aOutSize = ( pSize ? *pSize : pOutDev->PixelToLogic( maSize ) );
396 
397 		if( nStyle & IMAGE_DRAW_DISABLE )
398 		{
399             ImplUpdateDisabledBmpEx( nPos);
400             pOutDev->DrawBitmapEx( rPos, aOutSize, aSrcPos, maSize, maDisabledBmpEx );
401 		}
402 		else
403 		{
404 			if( nStyle & ( IMAGE_DRAW_COLORTRANSFORM |
405 						   IMAGE_DRAW_MONOCHROME_BLACK | IMAGE_DRAW_MONOCHROME_WHITE |
406 						   IMAGE_DRAW_HIGHLIGHT | IMAGE_DRAW_DEACTIVE | IMAGE_DRAW_SEMITRANSPARENT ) )
407 			{
408 				BitmapEx        aTmpBmpEx;
409 				const Rectangle aCropRect( aSrcPos, maSize );
410 
411 				if( mpInfoAry[ nPos ] & ( IMPSYSIMAGEITEM_MASK | IMPSYSIMAGEITEM_ALPHA ) )
412 					aTmpBmpEx = maBmpEx;
413 				else
414 					aTmpBmpEx = maBmpEx.GetBitmap();
415 
416 				aTmpBmpEx.Crop( aCropRect );
417 
418 				if( nStyle & ( IMAGE_DRAW_COLORTRANSFORM | IMAGE_DRAW_MONOCHROME_BLACK | IMAGE_DRAW_MONOCHROME_WHITE ) )
419 				{
420 					const BmpColorMode eMode = ( nStyle & IMAGE_DRAW_COLORTRANSFORM ) ? BMP_COLOR_HIGHCONTRAST :
421 										 	   ( ( nStyle & IMAGE_DRAW_MONOCHROME_BLACK ) ? BMP_COLOR_MONOCHROME_BLACK : BMP_COLOR_MONOCHROME_WHITE );
422 
423 					aTmpBmpEx = aTmpBmpEx.GetColorTransformedBitmapEx( eMode );
424 				}
425 
426 				Bitmap aTmpBmp( aTmpBmpEx.GetBitmap() );
427 
428 				if( nStyle & ( IMAGE_DRAW_HIGHLIGHT | IMAGE_DRAW_DEACTIVE ) )
429 				{
430 					BitmapWriteAccess* pAcc = aTmpBmp.AcquireWriteAccess();
431 
432 					if( pAcc )
433 					{
434 						const StyleSettings&	rSettings = pOutDev->GetSettings().GetStyleSettings();
435 						Color					aColor;
436 						BitmapColor				aCol;
437 						const long				nW = pAcc->Width();
438 						const long				nH = pAcc->Height();
439 						sal_uInt8*					pMapR = new sal_uInt8[ 256 ];
440 						sal_uInt8*					pMapG = new sal_uInt8[ 256 ];
441 						sal_uInt8*					pMapB = new sal_uInt8[ 256 ];
442 						long					nX, nY;
443 
444 						if( nStyle & IMAGE_DRAW_HIGHLIGHT )
445 							aColor = rSettings.GetHighlightColor();
446 						else
447 							aColor = rSettings.GetDeactiveColor();
448 
449 						const sal_uInt8 cR = aColor.GetRed();
450 						const sal_uInt8 cG = aColor.GetGreen();
451 						const sal_uInt8 cB = aColor.GetBlue();
452 
453 						for( nX = 0L; nX < 256L; nX++ )
454 						{
455 							pMapR[ nX ] = (sal_uInt8) ( ( ( nY = ( nX + cR ) >> 1 ) > 255 ) ? 255 : nY );
456 							pMapG[ nX ] = (sal_uInt8) ( ( ( nY = ( nX + cG ) >> 1 ) > 255 ) ? 255 : nY );
457 							pMapB[ nX ] = (sal_uInt8) ( ( ( nY = ( nX + cB ) >> 1 ) > 255 ) ? 255 : nY );
458 						}
459 
460 						if( pAcc->HasPalette() )
461 						{
462 							for( sal_uInt16 i = 0, nCount = pAcc->GetPaletteEntryCount(); i < nCount; i++ )
463 							{
464 								const BitmapColor& rCol = pAcc->GetPaletteColor( i );
465 								aCol.SetRed( pMapR[ rCol.GetRed() ] );
466 								aCol.SetGreen( pMapG[ rCol.GetGreen() ] );
467 								aCol.SetBlue( pMapB[ rCol.GetBlue() ] );
468 								pAcc->SetPaletteColor( i, aCol );
469 							}
470 						}
471 						else if( pAcc->GetScanlineFormat() == BMP_FORMAT_24BIT_TC_BGR )
472 						{
473 							for( nY = 0L; nY < nH; nY++ )
474 							{
475 								Scanline pScan = pAcc->GetScanline( nY );
476 
477 								for( nX = 0L; nX < nW; nX++ )
478 								{
479 									*pScan = pMapB[ *pScan ]; pScan++;
480 									*pScan = pMapG[ *pScan ]; pScan++;
481 									*pScan = pMapR[ *pScan ]; pScan++;
482 								}
483 							}
484 						}
485 						else
486 						{
487 							for( nY = 0L; nY < nH; nY++ )
488 							{
489 								for( nX = 0L; nX < nW; nX++ )
490 								{
491 									aCol = pAcc->GetPixel( nY, nX );
492 									aCol.SetRed( pMapR[ aCol.GetRed() ] );
493 									aCol.SetGreen( pMapG[ aCol.GetGreen() ] );
494 									aCol.SetBlue( pMapB[ aCol.GetBlue() ] );
495 									pAcc->SetPixel( nY, nX, aCol );
496 								}
497 							}
498 						}
499 
500 						delete[] pMapR;
501 						delete[] pMapG;
502 						delete[] pMapB;
503 						aTmpBmp.ReleaseAccess( pAcc );
504 					}
505 				}
506 
507 				if( nStyle & IMAGE_DRAW_SEMITRANSPARENT )
508 				{
509 					if( aTmpBmpEx.IsTransparent()  )
510 					{
511 						Bitmap aAlphaBmp( aTmpBmpEx.GetAlpha().GetBitmap() );
512 
513 						aAlphaBmp.Adjust( 50 );
514 						aTmpBmpEx = BitmapEx( aTmpBmp, AlphaMask( aAlphaBmp ) );
515 					}
516 					else
517 					{
518 						sal_uInt8 cErase = 128;
519 						aTmpBmpEx = BitmapEx( aTmpBmp, AlphaMask( aTmpBmp.GetSizePixel(),  &cErase ) );
520 					}
521 				}
522 				else
523 				{
524 					if( aTmpBmpEx.IsAlpha() )
525 						aTmpBmpEx = BitmapEx( aTmpBmp, aTmpBmpEx.GetAlpha() );
526 					else if( aTmpBmpEx.IsAlpha() )
527 						aTmpBmpEx = BitmapEx( aTmpBmp, aTmpBmpEx.GetMask() );
528 				}
529 
530 				pOutDev->DrawBitmapEx( rPos, aOutSize, aTmpBmpEx );
531 			}
532 			else
533 			{
534 				const BitmapEx* pOutputBmp;
535 
536 				if( pOutDev->GetOutDevType() == OUTDEV_WINDOW )
537 				{
538 					ImplUpdateDisplayBmp( pOutDev );
539 					pOutputBmp = mpDisplayBmp;
540 				}
541 				else
542 					pOutputBmp = &maBmpEx;
543 
544 				if( pOutputBmp )
545 					pOutDev->DrawBitmapEx( rPos, aOutSize, aSrcPos, maSize, *pOutputBmp );
546 			}
547 		}
548 	}
549 }
550 
551 // -----------------------------------------------------------------------
552 
ImplUpdateDisplayBmp(OutputDevice * pOutDev)553 void ImplImageBmp::ImplUpdateDisplayBmp( OutputDevice*
554 #if defined WNT
555 pOutDev
556 #endif
557 )
558 {
559 	if( !mpDisplayBmp && !maBmpEx.IsEmpty() )
560 	{
561 #if defined WNT
562 		if( maBmpEx.IsAlpha() )
563 			mpDisplayBmp = new BitmapEx( maBmpEx );
564 		else
565 		{
566 			const Bitmap aBmp( maBmpEx.GetBitmap().CreateDisplayBitmap( pOutDev ) );
567 
568 			if( maBmpEx.IsTransparent() )
569 				mpDisplayBmp = new BitmapEx( aBmp, maBmpEx.GetMask().CreateDisplayBitmap( pOutDev ) );
570 			else
571 				mpDisplayBmp = new BitmapEx( aBmp );
572 		}
573 #else
574 		mpDisplayBmp = new BitmapEx( maBmpEx );
575 #endif
576 	}
577 }
578 
579 // -----------------------------------------------------------------------
580 
ImplUpdateDisabledBmpEx(int nPos)581 void ImplImageBmp::ImplUpdateDisabledBmpEx( int nPos )
582 {
583     const Size aTotalSize( maBmpEx.GetSizePixel() );
584 
585     if( maDisabledBmpEx.IsEmpty() )
586     {
587         Bitmap      aGrey( aTotalSize, 8, &Bitmap::GetGreyPalette( 256 ) );
588         AlphaMask   aGreyAlphaMask( aTotalSize );
589 
590         maDisabledBmpEx = BitmapEx( aGrey, aGreyAlphaMask );
591         nPos = -1;
592     }
593 
594     Bitmap              aBmp( maBmpEx.GetBitmap() );
595     BitmapReadAccess*   pBmp( aBmp.AcquireReadAccess() );
596     AlphaMask           aBmpAlphaMask( maBmpEx.GetAlpha() );
597     BitmapReadAccess*   pBmpAlphaMask( aBmpAlphaMask.AcquireReadAccess() );
598     Bitmap              aGrey( maDisabledBmpEx.GetBitmap() );
599     BitmapWriteAccess*  pGrey( aGrey.AcquireWriteAccess() );
600     AlphaMask           aGreyAlphaMask( maDisabledBmpEx.GetAlpha() );
601     BitmapWriteAccess*  pGreyAlphaMask( aGreyAlphaMask.AcquireWriteAccess() );
602 
603     if( pBmp && pBmpAlphaMask && pGrey && pGreyAlphaMask )
604     {
605         BitmapColor	aGreyVal( 0 );
606         BitmapColor aGreyAlphaMaskVal( 0 );
607         const Point aPos( ( nPos < 0 ) ? 0 : ( nPos * maSize.Width() ), 0 );
608         const int  nLeft = aPos.X(), nRight = nLeft + ( ( nPos < 0 ) ? aTotalSize.Width() : maSize.Width() );
609         const int  nTop = aPos.Y(), nBottom = nTop + maSize.Height();
610 
611         for( int nY = nTop; nY < nBottom; ++nY )
612         {
613             for( int nX = nLeft; nX < nRight; ++nX )
614             {
615                 aGreyVal.SetIndex( pBmp->GetLuminance( nY, nX ) );
616                 pGrey->SetPixel( nY, nX, aGreyVal );
617 
618                 const BitmapColor aBmpAlphaMaskVal( pBmpAlphaMask->GetPixel( nY, nX ) );
619 
620                 aGreyAlphaMaskVal.SetIndex( static_cast< sal_uInt8 >( ::std::min( aBmpAlphaMaskVal.GetIndex() + 178ul, 255ul ) ) );
621                 pGreyAlphaMask->SetPixel( nY, nX, aGreyAlphaMaskVal );
622             }
623         }
624     }
625 
626     aBmp.ReleaseAccess( pBmp );
627     aBmpAlphaMask.ReleaseAccess( pBmpAlphaMask );
628     aGrey.ReleaseAccess( pGrey );
629     aGreyAlphaMask.ReleaseAccess( pGreyAlphaMask );
630 
631     maDisabledBmpEx = BitmapEx( aGrey, aGreyAlphaMask );
632 }
633