xref: /AOO41X/main/vcl/source/gdi/impimage.cxx (revision 9f62ea84a806e17e6f2bbff75724a7257a0eb5d9)
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