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