1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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>
31 #define IMPSYSIMAGEITEM_MASK ( 0x01 )
32 #define IMPSYSIMAGEITEM_ALPHA ( 0x02 )
34 ImageAryData::ImageAryData( const ImageAryData
& rData
) :
35 maName( rData
.maName
),
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
;
55 maBitmapEx
= rData
.maBitmapEx
;
60 ImplImageList::ImplImageList()
64 ImplImageList::ImplImageList( const ImplImageList
&aSrc
) :
65 maPrefix( aSrc
.maPrefix
),
66 maImageSize( aSrc
.maImageSize
),
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
)
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
),
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()
126 case IMAGETYPE_BITMAP
:
127 delete static_cast< Bitmap
* >( mpData
);
130 case IMAGETYPE_IMAGE
:
131 delete static_cast< ImplImageData
* >( mpData
);
136 ImplImageBmp::ImplImageBmp() :
137 mpDisplayBmp( NULL
),
143 ImplImageBmp::~ImplImageBmp()
149 void ImplImageBmp::Create( const BitmapEx
& rBmpEx
, long nItemWidth
, long nItemHeight
, sal_uInt16 nInitSize
)
152 maDisabledBmpEx
.SetEmpty();
157 maSize
= Size( nItemWidth
, nItemHeight
);
161 mpInfoAry
= new sal_uInt8
[ mnSize
];
163 rBmpEx
.IsAlpha() ? IMPSYSIMAGEITEM_ALPHA
: ( rBmpEx
.IsTransparent() ? IMPSYSIMAGEITEM_MASK
: 0 ),
167 void ImplImageBmp::Draw( sal_uInt16 nPos
, OutputDevice
* pOutDev
,
168 const Point
& rPos
, sal_uInt16 nStyle
,
171 if( pOutDev
->IsDeviceOutputNecessary() )
173 const Point
aSrcPos( nPos
* maSize
.Width(), 0 );
176 aOutSize
= ( pSize
? *pSize
: pOutDev
->PixelToLogic( maSize
) );
178 if( nStyle
& IMAGE_DRAW_DISABLE
)
180 ImplUpdateDisabledBmpEx( nPos
);
181 pOutDev
->DrawBitmapEx( rPos
, aOutSize
, aSrcPos
, maSize
, maDisabledBmpEx
);
185 if( nStyle
& ( IMAGE_DRAW_COLORTRANSFORM
|
186 IMAGE_DRAW_HIGHLIGHT
| IMAGE_DRAW_DEACTIVE
| IMAGE_DRAW_SEMITRANSPARENT
) )
189 const Rectangle
aCropRect( aSrcPos
, maSize
);
191 if( mpInfoAry
[ nPos
] & ( IMPSYSIMAGEITEM_MASK
| IMPSYSIMAGEITEM_ALPHA
) )
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();
206 const StyleSettings
& rSettings
= pOutDev
->GetSettings().GetStyleSettings();
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 ];
216 if( nStyle
& IMAGE_DRAW_HIGHLIGHT
)
217 aColor
= rSettings
.GetHighlightColor();
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
++;
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
);
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
) );
290 sal_uInt8 cErase
= 128;
291 aTmpBmpEx
= BitmapEx( aTmpBmp
, AlphaMask( aTmpBmp
.GetSizePixel(), &cErase
) );
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
);
306 const BitmapEx
* pOutputBmp
;
308 if( pOutDev
->GetOutDevType() == OUTDEV_WINDOW
)
310 ImplUpdateDisplayBmp( pOutDev
);
311 pOutputBmp
= mpDisplayBmp
;
314 pOutputBmp
= &maBmpEx
;
317 pOutDev
->DrawBitmapEx( rPos
, aOutSize
, aSrcPos
, maSize
, *pOutputBmp
);
323 void ImplImageBmp::ImplUpdateDisplayBmp( OutputDevice
*
329 if( !mpDisplayBmp
&& !maBmpEx
.IsEmpty() )
332 if( maBmpEx
.IsAlpha() )
333 mpDisplayBmp
= new BitmapEx( maBmpEx
);
336 const Bitmap
aBmp( maBmpEx
.GetBitmap().CreateDisplayBitmap( pOutDev
) );
338 if( maBmpEx
.IsTransparent() )
339 mpDisplayBmp
= new BitmapEx( aBmp
, maBmpEx
.GetMask().CreateDisplayBitmap( pOutDev
) );
341 mpDisplayBmp
= new BitmapEx( aBmp
);
344 mpDisplayBmp
= new BitmapEx( maBmpEx
);
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
);
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: */