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