Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include <vcl/outdev.hxx>
21 : #include <vcl/bitmapex.hxx>
22 : #include <vcl/alpha.hxx>
23 : #include <vcl/window.hxx>
24 : #include <vcl/bmpacc.hxx>
25 : #include <vcl/virdev.hxx>
26 : #include <vcl/image.hxx>
27 : #include <vcl/settings.hxx>
28 :
29 : #include <image.h>
30 : #include <boost/scoped_array.hpp>
31 :
32 : #define IMPSYSIMAGEITEM_MASK ( 0x01 )
33 : #define IMPSYSIMAGEITEM_ALPHA ( 0x02 )
34 :
35 0 : ImageAryData::ImageAryData( const ImageAryData& rData ) :
36 : maName( rData.maName ),
37 : mnId( rData.mnId ),
38 0 : maBitmapEx( rData.maBitmapEx )
39 : {
40 0 : }
41 :
42 37141 : ImageAryData::ImageAryData( const OUString &aName,
43 : sal_uInt16 nId, const BitmapEx &aBitmap )
44 37141 : : maName( aName ), mnId( nId ), maBitmapEx( aBitmap )
45 : {
46 37141 : }
47 :
48 35778 : ImageAryData::~ImageAryData()
49 : {
50 35778 : }
51 :
52 0 : ImageAryData& ImageAryData::operator=( const ImageAryData& rData )
53 : {
54 0 : maName = rData.maName;
55 0 : mnId = rData.mnId;
56 0 : maBitmapEx = rData.maBitmapEx;
57 :
58 0 : return *this;
59 : }
60 :
61 267 : ImplImageList::ImplImageList()
62 267 : : mnRefCount(1)
63 : {
64 267 : }
65 :
66 0 : ImplImageList::ImplImageList( const ImplImageList &aSrc )
67 : : maPrefix(aSrc.maPrefix)
68 : , maImageSize(aSrc.maImageSize)
69 0 : , mnRefCount(1)
70 : {
71 0 : maImages.reserve( aSrc.maImages.size() );
72 0 : for ( ImageAryDataVec::const_iterator aIt = aSrc.maImages.begin(), aEnd = aSrc.maImages.end(); aIt != aEnd; ++aIt )
73 : {
74 0 : ImageAryData* pAryData = new ImageAryData( **aIt );
75 0 : maImages.push_back( pAryData );
76 0 : if( !pAryData->maName.isEmpty() )
77 0 : maNameHash [ pAryData->maName ] = pAryData;
78 : }
79 0 : }
80 :
81 472 : ImplImageList::~ImplImageList()
82 : {
83 36014 : for ( ImageAryDataVec::iterator aIt = maImages.begin(), aEnd = maImages.end(); aIt != aEnd; ++aIt )
84 35778 : delete *aIt;
85 236 : }
86 :
87 37141 : void ImplImageList::AddImage( const OUString &aName,
88 : sal_uInt16 nId, const BitmapEx &aBitmapEx )
89 : {
90 37141 : ImageAryData *pImg = new ImageAryData( aName, nId, aBitmapEx );
91 37141 : maImages.push_back( pImg );
92 37141 : if( !aName.isEmpty() )
93 36856 : maNameHash [ aName ] = pImg;
94 37141 : }
95 :
96 0 : void ImplImageList::RemoveImage( sal_uInt16 nPos )
97 : {
98 0 : ImageAryData *pImg = maImages[ nPos ];
99 0 : if( !pImg->maName.isEmpty() )
100 0 : maNameHash.erase( pImg->maName );
101 0 : maImages.erase( maImages.begin() + nPos );
102 0 : }
103 :
104 214089 : ImplImageData::ImplImageData( const BitmapEx& rBmpEx ) :
105 : mpImageBitmap( NULL ),
106 214089 : maBmpEx( rBmpEx )
107 : {
108 214089 : }
109 :
110 394672 : ImplImageData::~ImplImageData()
111 : {
112 197336 : delete mpImageBitmap;
113 197336 : }
114 :
115 90 : bool ImplImageData::IsEqual( const ImplImageData& rData )
116 : {
117 90 : return( maBmpEx == rData.maBmpEx );
118 : }
119 :
120 217857 : ImplImage::ImplImage()
121 : : mnRefCount(1)
122 : , mpData(NULL)
123 217857 : , meType(IMAGETYPE_BITMAP)
124 : {
125 217857 : }
126 :
127 201014 : ImplImage::~ImplImage()
128 : {
129 201014 : switch( meType )
130 : {
131 : case IMAGETYPE_BITMAP:
132 3678 : delete static_cast< Bitmap* >( mpData );
133 3678 : break;
134 :
135 : case IMAGETYPE_IMAGE:
136 197336 : delete static_cast< ImplImageData* >( mpData );
137 197336 : break;
138 : }
139 201014 : }
140 :
141 35640 : ImplImageBmp::ImplImageBmp() :
142 : mpDisplayBmp( NULL ),
143 : mpInfoAry( NULL ),
144 35640 : mnSize( 0 )
145 : {
146 35640 : }
147 :
148 71212 : ImplImageBmp::~ImplImageBmp()
149 : {
150 35606 : delete[] mpInfoAry;
151 35606 : delete mpDisplayBmp;
152 35606 : }
153 :
154 35640 : void ImplImageBmp::Create( const BitmapEx& rBmpEx, long nItemWidth, long nItemHeight, sal_uInt16 nInitSize )
155 : {
156 35640 : maBmpEx = rBmpEx;
157 35640 : maDisabledBmpEx.SetEmpty();
158 :
159 35640 : delete mpDisplayBmp;
160 35640 : mpDisplayBmp = NULL;
161 :
162 35640 : maSize = Size( nItemWidth, nItemHeight );
163 35640 : mnSize = nInitSize;
164 :
165 35640 : delete[] mpInfoAry;
166 35640 : mpInfoAry = new sal_uInt8[ mnSize ];
167 : memset( mpInfoAry,
168 36364 : rBmpEx.IsAlpha() ? IMPSYSIMAGEITEM_ALPHA : ( rBmpEx.IsTransparent() ? IMPSYSIMAGEITEM_MASK : 0 ),
169 72004 : mnSize );
170 35640 : }
171 :
172 98251 : void ImplImageBmp::Draw( sal_uInt16 nPos, OutputDevice* pOutDev,
173 : const Point& rPos, DrawImageFlags nStyle,
174 : const Size* pSize )
175 : {
176 98251 : if( pOutDev->IsDeviceOutputNecessary() )
177 : {
178 98251 : const Point aSrcPos( nPos * maSize.Width(), 0 );
179 98251 : Size aOutSize;
180 :
181 98251 : aOutSize = ( pSize ? *pSize : pOutDev->PixelToLogic( maSize ) );
182 :
183 98251 : if( nStyle & DrawImageFlags::Disable )
184 : {
185 7927 : ImplUpdateDisabledBmpEx( nPos);
186 7927 : pOutDev->DrawBitmapEx( rPos, aOutSize, aSrcPos, maSize, maDisabledBmpEx );
187 : }
188 : else
189 : {
190 90324 : if( nStyle & ( DrawImageFlags::ColorTransform |
191 90324 : DrawImageFlags::Highlight | DrawImageFlags::Deactive | DrawImageFlags::SemiTransparent ) )
192 : {
193 0 : BitmapEx aTmpBmpEx;
194 0 : const Rectangle aCropRect( aSrcPos, maSize );
195 :
196 0 : if( mpInfoAry[ nPos ] & ( IMPSYSIMAGEITEM_MASK | IMPSYSIMAGEITEM_ALPHA ) )
197 0 : aTmpBmpEx = maBmpEx;
198 : else
199 0 : aTmpBmpEx = maBmpEx.GetBitmap();
200 :
201 0 : aTmpBmpEx.Crop( aCropRect );
202 :
203 0 : Bitmap aTmpBmp( aTmpBmpEx.GetBitmap() );
204 :
205 0 : if( nStyle & ( DrawImageFlags::Highlight | DrawImageFlags::Deactive ) )
206 : {
207 0 : BitmapWriteAccess* pAcc = aTmpBmp.AcquireWriteAccess();
208 :
209 0 : if( pAcc )
210 : {
211 0 : const StyleSettings& rSettings = pOutDev->GetSettings().GetStyleSettings();
212 0 : Color aColor;
213 0 : BitmapColor aCol;
214 0 : const long nW = pAcc->Width();
215 0 : const long nH = pAcc->Height();
216 0 : boost::scoped_array<sal_uInt8> pMapR(new sal_uInt8[ 256 ]);
217 0 : boost::scoped_array<sal_uInt8> pMapG(new sal_uInt8[ 256 ]);
218 0 : boost::scoped_array<sal_uInt8> pMapB(new sal_uInt8[ 256 ]);
219 : long nX, nY;
220 :
221 0 : if( nStyle & DrawImageFlags::Highlight )
222 0 : aColor = rSettings.GetHighlightColor();
223 : else
224 0 : aColor = rSettings.GetDeactiveColor();
225 :
226 0 : const sal_uInt8 cR = aColor.GetRed();
227 0 : const sal_uInt8 cG = aColor.GetGreen();
228 0 : const sal_uInt8 cB = aColor.GetBlue();
229 :
230 0 : for( nX = 0L; nX < 256L; nX++ )
231 : {
232 0 : pMapR[ nX ] = (sal_uInt8) ( ( ( nY = ( nX + cR ) >> 1 ) > 255 ) ? 255 : nY );
233 0 : pMapG[ nX ] = (sal_uInt8) ( ( ( nY = ( nX + cG ) >> 1 ) > 255 ) ? 255 : nY );
234 0 : pMapB[ nX ] = (sal_uInt8) ( ( ( nY = ( nX + cB ) >> 1 ) > 255 ) ? 255 : nY );
235 : }
236 :
237 0 : if( pAcc->HasPalette() )
238 : {
239 0 : for( sal_uInt16 i = 0, nCount = pAcc->GetPaletteEntryCount(); i < nCount; i++ )
240 : {
241 0 : const BitmapColor& rCol = pAcc->GetPaletteColor( i );
242 0 : aCol.SetRed( pMapR[ rCol.GetRed() ] );
243 0 : aCol.SetGreen( pMapG[ rCol.GetGreen() ] );
244 0 : aCol.SetBlue( pMapB[ rCol.GetBlue() ] );
245 0 : pAcc->SetPaletteColor( i, aCol );
246 : }
247 : }
248 0 : else if( pAcc->GetScanlineFormat() == BMP_FORMAT_24BIT_TC_BGR )
249 : {
250 0 : for( nY = 0L; nY < nH; nY++ )
251 : {
252 0 : Scanline pScan = pAcc->GetScanline( nY );
253 :
254 0 : for( nX = 0L; nX < nW; nX++ )
255 : {
256 0 : *pScan = pMapB[ *pScan ]; pScan++;
257 0 : *pScan = pMapG[ *pScan ]; pScan++;
258 0 : *pScan = pMapR[ *pScan ]; pScan++;
259 : }
260 : }
261 : }
262 : else
263 : {
264 0 : for( nY = 0L; nY < nH; nY++ )
265 : {
266 0 : for( nX = 0L; nX < nW; nX++ )
267 : {
268 0 : aCol = pAcc->GetPixel( nY, nX );
269 0 : aCol.SetRed( pMapR[ aCol.GetRed() ] );
270 0 : aCol.SetGreen( pMapG[ aCol.GetGreen() ] );
271 0 : aCol.SetBlue( pMapB[ aCol.GetBlue() ] );
272 0 : pAcc->SetPixel( nY, nX, aCol );
273 : }
274 : }
275 : }
276 :
277 0 : Bitmap::ReleaseAccess( pAcc );
278 : }
279 : }
280 :
281 0 : if( nStyle & DrawImageFlags::SemiTransparent )
282 : {
283 0 : if( aTmpBmpEx.IsTransparent() )
284 : {
285 0 : Bitmap aAlphaBmp( aTmpBmpEx.GetAlpha().GetBitmap() );
286 :
287 0 : aAlphaBmp.Adjust( 50 );
288 0 : aTmpBmpEx = BitmapEx( aTmpBmp, AlphaMask( aAlphaBmp ) );
289 : }
290 : else
291 : {
292 0 : sal_uInt8 cErase = 128;
293 0 : aTmpBmpEx = BitmapEx( aTmpBmp, AlphaMask( aTmpBmp.GetSizePixel(), &cErase ) );
294 : }
295 : }
296 : else
297 : {
298 0 : if( aTmpBmpEx.IsAlpha() )
299 0 : aTmpBmpEx = BitmapEx( aTmpBmp, aTmpBmpEx.GetAlpha() );
300 0 : else if( aTmpBmpEx.IsTransparent() )
301 0 : aTmpBmpEx = BitmapEx( aTmpBmp, aTmpBmpEx.GetMask() );
302 : }
303 :
304 0 : pOutDev->DrawBitmapEx( rPos, aOutSize, aTmpBmpEx );
305 : }
306 : else
307 : {
308 : const BitmapEx* pOutputBmp;
309 :
310 90324 : if( pOutDev->GetOutDevType() == OUTDEV_WINDOW )
311 : {
312 61229 : ImplUpdateDisplayBmp( pOutDev );
313 61229 : pOutputBmp = mpDisplayBmp;
314 : }
315 : else
316 29095 : pOutputBmp = &maBmpEx;
317 :
318 90324 : if( pOutputBmp )
319 90324 : pOutDev->DrawBitmapEx( rPos, aOutSize, aSrcPos, maSize, *pOutputBmp );
320 : }
321 : }
322 : }
323 98251 : }
324 :
325 61229 : void ImplImageBmp::ImplUpdateDisplayBmp( OutputDevice*
326 : #if defined WNT
327 : pOutDev
328 : #endif
329 : )
330 : {
331 61229 : if( !mpDisplayBmp && !maBmpEx.IsEmpty() )
332 : {
333 : #if defined WNT
334 : if( !maBmpEx.IsAlpha() )
335 : {
336 : // FIXME: this looks like rather an obsolete code-path to me.
337 : const Bitmap aBmp( maBmpEx.GetBitmap().CreateDisplayBitmap( pOutDev ) );
338 :
339 : if( maBmpEx.IsTransparent() )
340 : mpDisplayBmp = new BitmapEx( aBmp, maBmpEx.GetMask().CreateDisplayBitmap( pOutDev ) );
341 : else
342 : mpDisplayBmp = new BitmapEx( aBmp );
343 : }
344 : else
345 : #endif
346 29022 : mpDisplayBmp = new BitmapEx( maBmpEx );
347 : }
348 61229 : }
349 :
350 7927 : void ImplImageBmp::ImplUpdateDisabledBmpEx( int nPos )
351 : {
352 7927 : const Size aTotalSize( maBmpEx.GetSizePixel() );
353 :
354 7927 : if( maDisabledBmpEx.IsEmpty() )
355 : {
356 4021 : Bitmap aGrey( aTotalSize, 8, &Bitmap::GetGreyPalette( 256 ) );
357 8042 : AlphaMask aGreyAlphaMask( aTotalSize );
358 :
359 4021 : maDisabledBmpEx = BitmapEx( aGrey, aGreyAlphaMask );
360 8042 : nPos = -1;
361 : }
362 :
363 7927 : Bitmap aBmp( maBmpEx.GetBitmap() );
364 7927 : BitmapReadAccess* pBmp( aBmp.AcquireReadAccess() );
365 15854 : AlphaMask aBmpAlphaMask( maBmpEx.GetAlpha() );
366 7927 : BitmapReadAccess* pBmpAlphaMask( aBmpAlphaMask.AcquireReadAccess() );
367 15854 : Bitmap aGrey( maDisabledBmpEx.GetBitmap() );
368 7927 : BitmapWriteAccess* pGrey( aGrey.AcquireWriteAccess() );
369 15854 : AlphaMask aGreyAlphaMask( maDisabledBmpEx.GetAlpha() );
370 7927 : BitmapWriteAccess* pGreyAlphaMask( aGreyAlphaMask.AcquireWriteAccess() );
371 :
372 7927 : if( pBmp && pBmpAlphaMask && pGrey && pGreyAlphaMask )
373 : {
374 7927 : BitmapColor aGreyVal( 0 );
375 15854 : BitmapColor aGreyAlphaMaskVal( 0 );
376 7927 : const Point aPos( ( nPos < 0 ) ? 0 : ( nPos * maSize.Width() ), 0 );
377 7927 : const int nLeft = aPos.X(), nRight = nLeft + ( ( nPos < 0 ) ? aTotalSize.Width() : maSize.Width() );
378 7927 : const int nTop = aPos.Y(), nBottom = nTop + maSize.Height();
379 :
380 137020 : for( int nY = nTop; nY < nBottom; ++nY )
381 : {
382 2250028 : for( int nX = nLeft; nX < nRight; ++nX )
383 : {
384 2120935 : aGreyVal.SetIndex( pBmp->GetLuminance( nY, nX ) );
385 2120935 : pGrey->SetPixel( nY, nX, aGreyVal );
386 :
387 2120935 : const BitmapColor aBmpAlphaMaskVal( pBmpAlphaMask->GetPixel( nY, nX ) );
388 :
389 2120935 : aGreyAlphaMaskVal.SetIndex( static_cast< sal_uInt8 >( ::std::min( aBmpAlphaMaskVal.GetIndex() + 178ul, 255ul ) ) );
390 2120935 : pGreyAlphaMask->SetPixel( nY, nX, aGreyAlphaMaskVal );
391 2120935 : }
392 7927 : }
393 : }
394 :
395 7927 : Bitmap::ReleaseAccess( pBmp );
396 7927 : aBmpAlphaMask.ReleaseAccess( pBmpAlphaMask );
397 7927 : Bitmap::ReleaseAccess( pGrey );
398 7927 : aGreyAlphaMask.ReleaseAccess( pGreyAlphaMask );
399 :
400 15854 : maDisabledBmpEx = BitmapEx( aGrey, aGreyAlphaMask );
401 7927 : }
402 :
403 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|