bump product version to 4.2.0.1
[LibreOffice.git] / vcl / source / gdi / impimage.cxx
blobf61a34588f2717c73c438dbd06c7f49d9bf522c1
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <vcl/outdev.hxx>
22 #include <vcl/bitmapex.hxx>
23 #include <vcl/alpha.hxx>
24 #include <vcl/window.hxx>
25 #include <vcl/bmpacc.hxx>
26 #include <vcl/virdev.hxx>
27 #include <vcl/image.hxx>
29 #include <image.h>
31 #define IMPSYSIMAGEITEM_MASK ( 0x01 )
32 #define IMPSYSIMAGEITEM_ALPHA ( 0x02 )
34 ImageAryData::ImageAryData( const ImageAryData& rData ) :
35 maName( rData.maName ),
36 mnId( rData.mnId ),
37 maBitmapEx( rData.maBitmapEx )
41 ImageAryData::ImageAryData( const OUString &aName,
42 sal_uInt16 nId, const BitmapEx &aBitmap )
43 : maName( aName ), mnId( nId ), maBitmapEx( aBitmap )
47 ImageAryData::~ImageAryData()
51 ImageAryData& ImageAryData::operator=( const ImageAryData& rData )
53 maName = rData.maName;
54 mnId = rData.mnId;
55 maBitmapEx = rData.maBitmapEx;
57 return *this;
60 ImplImageList::ImplImageList()
64 ImplImageList::ImplImageList( const ImplImageList &aSrc ) :
65 maPrefix( aSrc.maPrefix ),
66 maImageSize( aSrc.maImageSize ),
67 mnRefCount( 1 )
69 maImages.reserve( aSrc.maImages.size() );
70 for ( ImageAryDataVec::const_iterator aIt = aSrc.maImages.begin(), aEnd = aSrc.maImages.end(); aIt != aEnd; ++aIt )
72 ImageAryData* pAryData = new ImageAryData( **aIt );
73 maImages.push_back( pAryData );
74 if( !pAryData->maName.isEmpty() )
75 maNameHash [ pAryData->maName ] = pAryData;
79 ImplImageList::~ImplImageList()
81 for ( ImageAryDataVec::iterator aIt = maImages.begin(), aEnd = maImages.end(); aIt != aEnd; ++aIt )
82 delete *aIt;
85 void ImplImageList::AddImage( const OUString &aName,
86 sal_uInt16 nId, const BitmapEx &aBitmapEx )
88 ImageAryData *pImg = new ImageAryData( aName, nId, aBitmapEx );
89 maImages.push_back( pImg );
90 if( !aName.isEmpty() )
91 maNameHash [ aName ] = pImg;
94 void ImplImageList::RemoveImage( sal_uInt16 nPos )
96 ImageAryData *pImg = maImages[ nPos ];
97 if( !pImg->maName.isEmpty() )
98 maNameHash.erase( pImg->maName );
99 maImages.erase( maImages.begin() + nPos );
102 ImplImageData::ImplImageData( const BitmapEx& rBmpEx ) :
103 mpImageBitmap( NULL ),
104 maBmpEx( rBmpEx )
108 ImplImageData::~ImplImageData()
110 delete mpImageBitmap;
113 sal_Bool ImplImageData::IsEqual( const ImplImageData& rData )
115 return( maBmpEx == rData.maBmpEx );
118 ImplImage::ImplImage()
122 ImplImage::~ImplImage()
124 switch( meType )
126 case IMAGETYPE_BITMAP:
127 delete static_cast< Bitmap* >( mpData );
128 break;
130 case IMAGETYPE_IMAGE:
131 delete static_cast< ImplImageData* >( mpData );
132 break;
136 ImplImageBmp::ImplImageBmp() :
137 mpDisplayBmp( NULL ),
138 mpInfoAry( NULL ),
139 mnSize( 0 )
143 ImplImageBmp::~ImplImageBmp()
145 delete[] mpInfoAry;
146 delete mpDisplayBmp;
149 void ImplImageBmp::Create( const BitmapEx& rBmpEx, long nItemWidth, long nItemHeight, sal_uInt16 nInitSize )
151 maBmpEx = rBmpEx;
152 maDisabledBmpEx.SetEmpty();
154 delete mpDisplayBmp;
155 mpDisplayBmp = NULL;
157 maSize = Size( nItemWidth, nItemHeight );
158 mnSize = nInitSize;
160 delete[] mpInfoAry;
161 mpInfoAry = new sal_uInt8[ mnSize ];
162 memset( mpInfoAry,
163 rBmpEx.IsAlpha() ? IMPSYSIMAGEITEM_ALPHA : ( rBmpEx.IsTransparent() ? IMPSYSIMAGEITEM_MASK : 0 ),
164 mnSize );
167 void ImplImageBmp::Draw( sal_uInt16 nPos, OutputDevice* pOutDev,
168 const Point& rPos, sal_uInt16 nStyle,
169 const Size* pSize )
171 if( pOutDev->IsDeviceOutputNecessary() )
173 const Point aSrcPos( nPos * maSize.Width(), 0 );
174 Size aOutSize;
176 aOutSize = ( pSize ? *pSize : pOutDev->PixelToLogic( maSize ) );
178 if( nStyle & IMAGE_DRAW_DISABLE )
180 ImplUpdateDisabledBmpEx( nPos);
181 pOutDev->DrawBitmapEx( rPos, aOutSize, aSrcPos, maSize, maDisabledBmpEx );
183 else
185 if( nStyle & ( IMAGE_DRAW_COLORTRANSFORM |
186 IMAGE_DRAW_HIGHLIGHT | IMAGE_DRAW_DEACTIVE | IMAGE_DRAW_SEMITRANSPARENT ) )
188 BitmapEx aTmpBmpEx;
189 const Rectangle aCropRect( aSrcPos, maSize );
191 if( mpInfoAry[ nPos ] & ( IMPSYSIMAGEITEM_MASK | IMPSYSIMAGEITEM_ALPHA ) )
192 aTmpBmpEx = maBmpEx;
193 else
194 aTmpBmpEx = maBmpEx.GetBitmap();
196 aTmpBmpEx.Crop( aCropRect );
198 Bitmap aTmpBmp( aTmpBmpEx.GetBitmap() );
200 if( nStyle & ( IMAGE_DRAW_HIGHLIGHT | IMAGE_DRAW_DEACTIVE ) )
202 BitmapWriteAccess* pAcc = aTmpBmp.AcquireWriteAccess();
204 if( pAcc )
206 const StyleSettings& rSettings = pOutDev->GetSettings().GetStyleSettings();
207 Color aColor;
208 BitmapColor aCol;
209 const long nW = pAcc->Width();
210 const long nH = pAcc->Height();
211 sal_uInt8* pMapR = new sal_uInt8[ 256 ];
212 sal_uInt8* pMapG = new sal_uInt8[ 256 ];
213 sal_uInt8* pMapB = new sal_uInt8[ 256 ];
214 long nX, nY;
216 if( nStyle & IMAGE_DRAW_HIGHLIGHT )
217 aColor = rSettings.GetHighlightColor();
218 else
219 aColor = rSettings.GetDeactiveColor();
221 const sal_uInt8 cR = aColor.GetRed();
222 const sal_uInt8 cG = aColor.GetGreen();
223 const sal_uInt8 cB = aColor.GetBlue();
225 for( nX = 0L; nX < 256L; nX++ )
227 pMapR[ nX ] = (sal_uInt8) ( ( ( nY = ( nX + cR ) >> 1 ) > 255 ) ? 255 : nY );
228 pMapG[ nX ] = (sal_uInt8) ( ( ( nY = ( nX + cG ) >> 1 ) > 255 ) ? 255 : nY );
229 pMapB[ nX ] = (sal_uInt8) ( ( ( nY = ( nX + cB ) >> 1 ) > 255 ) ? 255 : nY );
232 if( pAcc->HasPalette() )
234 for( sal_uInt16 i = 0, nCount = pAcc->GetPaletteEntryCount(); i < nCount; i++ )
236 const BitmapColor& rCol = pAcc->GetPaletteColor( i );
237 aCol.SetRed( pMapR[ rCol.GetRed() ] );
238 aCol.SetGreen( pMapG[ rCol.GetGreen() ] );
239 aCol.SetBlue( pMapB[ rCol.GetBlue() ] );
240 pAcc->SetPaletteColor( i, aCol );
243 else if( pAcc->GetScanlineFormat() == BMP_FORMAT_24BIT_TC_BGR )
245 for( nY = 0L; nY < nH; nY++ )
247 Scanline pScan = pAcc->GetScanline( nY );
249 for( nX = 0L; nX < nW; nX++ )
251 *pScan = pMapB[ *pScan ]; pScan++;
252 *pScan = pMapG[ *pScan ]; pScan++;
253 *pScan = pMapR[ *pScan ]; pScan++;
257 else
259 for( nY = 0L; nY < nH; nY++ )
261 for( nX = 0L; nX < nW; nX++ )
263 aCol = pAcc->GetPixel( nY, nX );
264 aCol.SetRed( pMapR[ aCol.GetRed() ] );
265 aCol.SetGreen( pMapG[ aCol.GetGreen() ] );
266 aCol.SetBlue( pMapB[ aCol.GetBlue() ] );
267 pAcc->SetPixel( nY, nX, aCol );
272 delete[] pMapR;
273 delete[] pMapG;
274 delete[] pMapB;
275 aTmpBmp.ReleaseAccess( pAcc );
279 if( nStyle & IMAGE_DRAW_SEMITRANSPARENT )
281 if( aTmpBmpEx.IsTransparent() )
283 Bitmap aAlphaBmp( aTmpBmpEx.GetAlpha().GetBitmap() );
285 aAlphaBmp.Adjust( 50 );
286 aTmpBmpEx = BitmapEx( aTmpBmp, AlphaMask( aAlphaBmp ) );
288 else
290 sal_uInt8 cErase = 128;
291 aTmpBmpEx = BitmapEx( aTmpBmp, AlphaMask( aTmpBmp.GetSizePixel(), &cErase ) );
294 else
296 if( aTmpBmpEx.IsAlpha() )
297 aTmpBmpEx = BitmapEx( aTmpBmp, aTmpBmpEx.GetAlpha() );
298 else if( aTmpBmpEx.IsAlpha() )
299 aTmpBmpEx = BitmapEx( aTmpBmp, aTmpBmpEx.GetMask() );
302 pOutDev->DrawBitmapEx( rPos, aOutSize, aTmpBmpEx );
304 else
306 const BitmapEx* pOutputBmp;
308 if( pOutDev->GetOutDevType() == OUTDEV_WINDOW )
310 ImplUpdateDisplayBmp( pOutDev );
311 pOutputBmp = mpDisplayBmp;
313 else
314 pOutputBmp = &maBmpEx;
316 if( pOutputBmp )
317 pOutDev->DrawBitmapEx( rPos, aOutSize, aSrcPos, maSize, *pOutputBmp );
323 void ImplImageBmp::ImplUpdateDisplayBmp( OutputDevice*
324 #if defined WNT
325 pOutDev
326 #endif
329 if( !mpDisplayBmp && !maBmpEx.IsEmpty() )
331 #if defined WNT
332 if( maBmpEx.IsAlpha() )
333 mpDisplayBmp = new BitmapEx( maBmpEx );
334 else
336 const Bitmap aBmp( maBmpEx.GetBitmap().CreateDisplayBitmap( pOutDev ) );
338 if( maBmpEx.IsTransparent() )
339 mpDisplayBmp = new BitmapEx( aBmp, maBmpEx.GetMask().CreateDisplayBitmap( pOutDev ) );
340 else
341 mpDisplayBmp = new BitmapEx( aBmp );
343 #else
344 mpDisplayBmp = new BitmapEx( maBmpEx );
345 #endif
349 void ImplImageBmp::ImplUpdateDisabledBmpEx( int nPos )
351 const Size aTotalSize( maBmpEx.GetSizePixel() );
353 if( maDisabledBmpEx.IsEmpty() )
355 Bitmap aGrey( aTotalSize, 8, &Bitmap::GetGreyPalette( 256 ) );
356 AlphaMask aGreyAlphaMask( aTotalSize );
358 maDisabledBmpEx = BitmapEx( aGrey, aGreyAlphaMask );
359 nPos = -1;
362 Bitmap aBmp( maBmpEx.GetBitmap() );
363 BitmapReadAccess* pBmp( aBmp.AcquireReadAccess() );
364 AlphaMask aBmpAlphaMask( maBmpEx.GetAlpha() );
365 BitmapReadAccess* pBmpAlphaMask( aBmpAlphaMask.AcquireReadAccess() );
366 Bitmap aGrey( maDisabledBmpEx.GetBitmap() );
367 BitmapWriteAccess* pGrey( aGrey.AcquireWriteAccess() );
368 AlphaMask aGreyAlphaMask( maDisabledBmpEx.GetAlpha() );
369 BitmapWriteAccess* pGreyAlphaMask( aGreyAlphaMask.AcquireWriteAccess() );
371 if( pBmp && pBmpAlphaMask && pGrey && pGreyAlphaMask )
373 BitmapColor aGreyVal( 0 );
374 BitmapColor aGreyAlphaMaskVal( 0 );
375 const Point aPos( ( nPos < 0 ) ? 0 : ( nPos * maSize.Width() ), 0 );
376 const int nLeft = aPos.X(), nRight = nLeft + ( ( nPos < 0 ) ? aTotalSize.Width() : maSize.Width() );
377 const int nTop = aPos.Y(), nBottom = nTop + maSize.Height();
379 for( int nY = nTop; nY < nBottom; ++nY )
381 for( int nX = nLeft; nX < nRight; ++nX )
383 aGreyVal.SetIndex( pBmp->GetLuminance( nY, nX ) );
384 pGrey->SetPixel( nY, nX, aGreyVal );
386 const BitmapColor aBmpAlphaMaskVal( pBmpAlphaMask->GetPixel( nY, nX ) );
388 aGreyAlphaMaskVal.SetIndex( static_cast< sal_uInt8 >( ::std::min( aBmpAlphaMaskVal.GetIndex() + 178ul, 255ul ) ) );
389 pGreyAlphaMask->SetPixel( nY, nX, aGreyAlphaMaskVal );
394 aBmp.ReleaseAccess( pBmp );
395 aBmpAlphaMask.ReleaseAccess( pBmpAlphaMask );
396 aGrey.ReleaseAccess( pGrey );
397 aGreyAlphaMask.ReleaseAccess( pGreyAlphaMask );
399 maDisabledBmpEx = BitmapEx( aGrey, aGreyAlphaMask );
402 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */