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 61233 : ImageAryData::ImageAryData( const OUString &aName,
43 : sal_uInt16 nId, const BitmapEx &aBitmap )
44 61233 : : maName( aName ), mnId( nId ), maBitmapEx( aBitmap )
45 : {
46 61233 : }
47 :
48 59725 : ImageAryData::~ImageAryData()
49 : {
50 59725 : }
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 2131 : ImplImageList::ImplImageList()
62 2131 : : mnRefCount(1)
63 : {
64 2131 : }
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 4166 : ImplImageList::~ImplImageList()
82 : {
83 61808 : for ( ImageAryDataVec::iterator aIt = maImages.begin(), aEnd = maImages.end(); aIt != aEnd; ++aIt )
84 59725 : delete *aIt;
85 2083 : }
86 :
87 61233 : void ImplImageList::AddImage( const OUString &aName,
88 : sal_uInt16 nId, const BitmapEx &aBitmapEx )
89 : {
90 61233 : ImageAryData *pImg = new ImageAryData( aName, nId, aBitmapEx );
91 61233 : maImages.push_back( pImg );
92 61233 : if( !aName.isEmpty() )
93 60969 : maNameHash [ aName ] = pImg;
94 61233 : }
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 399501 : ImplImageData::ImplImageData( const BitmapEx& rBmpEx ) :
105 : mpImageBitmap( NULL ),
106 399501 : maBmpEx( rBmpEx )
107 : {
108 399501 : }
109 :
110 798490 : ImplImageData::~ImplImageData()
111 : {
112 399245 : delete mpImageBitmap;
113 399245 : }
114 :
115 1084 : bool ImplImageData::IsEqual( const ImplImageData& rData )
116 : {
117 1084 : return( maBmpEx == rData.maBmpEx );
118 : }
119 :
120 412009 : ImplImage::ImplImage()
121 : : mnRefCount(1)
122 : , mpData(NULL)
123 412009 : , meType(IMAGETYPE_BITMAP)
124 : {
125 412009 : }
126 :
127 411621 : ImplImage::~ImplImage()
128 : {
129 411621 : switch( meType )
130 : {
131 : case IMAGETYPE_BITMAP:
132 12376 : delete static_cast< Bitmap* >( mpData );
133 12376 : break;
134 :
135 : case IMAGETYPE_IMAGE:
136 399245 : delete static_cast< ImplImageData* >( mpData );
137 399245 : break;
138 : }
139 411621 : }
140 :
141 87883 : ImplImageBmp::ImplImageBmp() :
142 : mpDisplayBmp( NULL ),
143 : mpInfoAry( NULL ),
144 87883 : mnSize( 0 )
145 : {
146 87883 : }
147 :
148 175594 : ImplImageBmp::~ImplImageBmp()
149 : {
150 87797 : delete[] mpInfoAry;
151 87797 : delete mpDisplayBmp;
152 87797 : }
153 :
154 87883 : void ImplImageBmp::Create( const BitmapEx& rBmpEx, long nItemWidth, long nItemHeight, sal_uInt16 nInitSize )
155 : {
156 87883 : maBmpEx = rBmpEx;
157 87883 : maDisabledBmpEx.SetEmpty();
158 :
159 87883 : delete mpDisplayBmp;
160 87883 : mpDisplayBmp = NULL;
161 :
162 87883 : maSize = Size( nItemWidth, nItemHeight );
163 87883 : mnSize = nInitSize;
164 :
165 87883 : delete[] mpInfoAry;
166 87883 : mpInfoAry = new sal_uInt8[ mnSize ];
167 : memset( mpInfoAry,
168 89056 : rBmpEx.IsAlpha() ? IMPSYSIMAGEITEM_ALPHA : ( rBmpEx.IsTransparent() ? IMPSYSIMAGEITEM_MASK : 0 ),
169 176939 : mnSize );
170 87883 : }
171 :
172 181953 : void ImplImageBmp::Draw( sal_uInt16 nPos, OutputDevice* pOutDev,
173 : const Point& rPos, sal_uInt16 nStyle,
174 : const Size* pSize )
175 : {
176 181953 : if( pOutDev->IsDeviceOutputNecessary() )
177 : {
178 181945 : const Point aSrcPos( nPos * maSize.Width(), 0 );
179 181945 : Size aOutSize;
180 :
181 181945 : aOutSize = ( pSize ? *pSize : pOutDev->PixelToLogic( maSize ) );
182 :
183 181945 : if( nStyle & IMAGE_DRAW_DISABLE )
184 : {
185 7850 : ImplUpdateDisabledBmpEx( nPos);
186 7850 : pOutDev->DrawBitmapEx( rPos, aOutSize, aSrcPos, maSize, maDisabledBmpEx );
187 : }
188 : else
189 : {
190 174095 : if( nStyle & ( IMAGE_DRAW_COLORTRANSFORM |
191 : IMAGE_DRAW_HIGHLIGHT | IMAGE_DRAW_DEACTIVE | IMAGE_DRAW_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 & ( IMAGE_DRAW_HIGHLIGHT | IMAGE_DRAW_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 & IMAGE_DRAW_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 : aTmpBmp.ReleaseAccess( pAcc );
278 : }
279 : }
280 :
281 0 : if( nStyle & IMAGE_DRAW_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 174095 : if( pOutDev->GetOutDevType() == OUTDEV_WINDOW )
311 : {
312 172100 : ImplUpdateDisplayBmp( pOutDev );
313 172100 : pOutputBmp = mpDisplayBmp;
314 : }
315 : else
316 1995 : pOutputBmp = &maBmpEx;
317 :
318 174095 : if( pOutputBmp )
319 174095 : pOutDev->DrawBitmapEx( rPos, aOutSize, aSrcPos, maSize, *pOutputBmp );
320 : }
321 : }
322 : }
323 181953 : }
324 :
325 172100 : void ImplImageBmp::ImplUpdateDisplayBmp( OutputDevice*
326 : #if defined WNT
327 : pOutDev
328 : #endif
329 : )
330 : {
331 172100 : if( !mpDisplayBmp && !maBmpEx.IsEmpty() )
332 : {
333 : #if defined WNT
334 : if( maBmpEx.IsAlpha() )
335 : mpDisplayBmp = new BitmapEx( maBmpEx );
336 : else
337 : {
338 : const Bitmap aBmp( maBmpEx.GetBitmap().CreateDisplayBitmap( pOutDev ) );
339 :
340 : if( maBmpEx.IsTransparent() )
341 : mpDisplayBmp = new BitmapEx( aBmp, maBmpEx.GetMask().CreateDisplayBitmap( pOutDev ) );
342 : else
343 : mpDisplayBmp = new BitmapEx( aBmp );
344 : }
345 : #else
346 86738 : mpDisplayBmp = new BitmapEx( maBmpEx );
347 : #endif
348 : }
349 172100 : }
350 :
351 7850 : void ImplImageBmp::ImplUpdateDisabledBmpEx( int nPos )
352 : {
353 7850 : const Size aTotalSize( maBmpEx.GetSizePixel() );
354 :
355 7850 : if( maDisabledBmpEx.IsEmpty() )
356 : {
357 6473 : Bitmap aGrey( aTotalSize, 8, &Bitmap::GetGreyPalette( 256 ) );
358 12946 : AlphaMask aGreyAlphaMask( aTotalSize );
359 :
360 6473 : maDisabledBmpEx = BitmapEx( aGrey, aGreyAlphaMask );
361 12946 : nPos = -1;
362 : }
363 :
364 7850 : Bitmap aBmp( maBmpEx.GetBitmap() );
365 7850 : BitmapReadAccess* pBmp( aBmp.AcquireReadAccess() );
366 15700 : AlphaMask aBmpAlphaMask( maBmpEx.GetAlpha() );
367 7850 : BitmapReadAccess* pBmpAlphaMask( aBmpAlphaMask.AcquireReadAccess() );
368 15700 : Bitmap aGrey( maDisabledBmpEx.GetBitmap() );
369 7850 : BitmapWriteAccess* pGrey( aGrey.AcquireWriteAccess() );
370 15700 : AlphaMask aGreyAlphaMask( maDisabledBmpEx.GetAlpha() );
371 7850 : BitmapWriteAccess* pGreyAlphaMask( aGreyAlphaMask.AcquireWriteAccess() );
372 :
373 7850 : if( pBmp && pBmpAlphaMask && pGrey && pGreyAlphaMask )
374 : {
375 7850 : BitmapColor aGreyVal( 0 );
376 15700 : BitmapColor aGreyAlphaMaskVal( 0 );
377 7850 : const Point aPos( ( nPos < 0 ) ? 0 : ( nPos * maSize.Width() ), 0 );
378 7850 : const int nLeft = aPos.X(), nRight = nLeft + ( ( nPos < 0 ) ? aTotalSize.Width() : maSize.Width() );
379 7850 : const int nTop = aPos.Y(), nBottom = nTop + maSize.Height();
380 :
381 133853 : for( int nY = nTop; nY < nBottom; ++nY )
382 : {
383 2155822 : for( int nX = nLeft; nX < nRight; ++nX )
384 : {
385 2029819 : aGreyVal.SetIndex( pBmp->GetLuminance( nY, nX ) );
386 2029819 : pGrey->SetPixel( nY, nX, aGreyVal );
387 :
388 2029819 : const BitmapColor aBmpAlphaMaskVal( pBmpAlphaMask->GetPixel( nY, nX ) );
389 :
390 2029819 : aGreyAlphaMaskVal.SetIndex( static_cast< sal_uInt8 >( ::std::min( aBmpAlphaMaskVal.GetIndex() + 178ul, 255ul ) ) );
391 2029819 : pGreyAlphaMask->SetPixel( nY, nX, aGreyAlphaMaskVal );
392 2029819 : }
393 7850 : }
394 : }
395 :
396 7850 : aBmp.ReleaseAccess( pBmp );
397 7850 : aBmpAlphaMask.ReleaseAccess( pBmpAlphaMask );
398 7850 : aGrey.ReleaseAccess( pGrey );
399 7850 : aGreyAlphaMask.ReleaseAccess( pGreyAlphaMask );
400 :
401 15700 : maDisabledBmpEx = BitmapEx( aGrey, aGreyAlphaMask );
402 9083 : }
403 :
404 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|