Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include <string.h>
31 : : #include <stdio.h>
32 : : #include <errno.h>
33 : :
34 : : #ifdef FREEBSD
35 : : #include <sys/types.h>
36 : : #endif
37 : :
38 : : #include <osl/endian.h>
39 : :
40 : : #include <vcl/bitmap.hxx>
41 : : #include <vcl/salbtype.hxx>
42 : : #include <com/sun/star/beans/XFastPropertySet.hpp>
43 : :
44 : : #include <tools/prex.h>
45 : : #include "unx/Xproto.h"
46 : : #include <tools/postx.h>
47 : : #include <unx/salunx.h>
48 : : #include <unx/saldata.hxx>
49 : : #include <unx/saldisp.hxx>
50 : : #include <unx/salgdi.h>
51 : : #include <unx/salbmp.h>
52 : : #include <unx/salinst.h>
53 : : #include <unx/x11/xlimits.hxx>
54 : :
55 : : #if defined(HAVE_MEMCHECK_H)
56 : : #include <memcheck.h>
57 : : #endif
58 : :
59 : : // -------------
60 : : // - SalBitmap -
61 : : // -------------
62 : :
63 : 0 : SalBitmap* X11SalInstance::CreateSalBitmap()
64 : : {
65 : 0 : return new X11SalBitmap();
66 : : }
67 : :
68 : : ImplSalBitmapCache* X11SalBitmap::mpCache = NULL;
69 : : sal_uLong X11SalBitmap::mnCacheInstCount = 0;
70 : :
71 : : // -----------------------------------------------------------------------------
72 : :
73 : 0 : X11SalBitmap::X11SalBitmap()
74 : : : mpDIB( NULL )
75 : : , mpDDB( NULL )
76 : 0 : , mbGrey( false )
77 : : {
78 : 0 : }
79 : :
80 : : // -----------------------------------------------------------------------------
81 : :
82 : 0 : X11SalBitmap::~X11SalBitmap()
83 : : {
84 : 0 : Destroy();
85 : 0 : }
86 : :
87 : : // -----------------------------------------------------------------------------
88 : :
89 : 0 : void X11SalBitmap::ImplCreateCache()
90 : : {
91 : 0 : if( !mnCacheInstCount++ )
92 : 0 : mpCache = new ImplSalBitmapCache;
93 : 0 : }
94 : :
95 : : // -----------------------------------------------------------------------------
96 : :
97 : 0 : void X11SalBitmap::ImplDestroyCache()
98 : : {
99 : : DBG_ASSERT( mnCacheInstCount, "X11SalBitmap::ImplDestroyCache(): underflow" );
100 : :
101 : 0 : if( mnCacheInstCount && !--mnCacheInstCount )
102 : 0 : delete mpCache, mpCache = NULL;
103 : 0 : }
104 : :
105 : : // -----------------------------------------------------------------------------
106 : :
107 : 0 : void X11SalBitmap::ImplRemovedFromCache()
108 : : {
109 : 0 : if( mpDDB )
110 : 0 : delete mpDDB, mpDDB = NULL;
111 : 0 : }
112 : :
113 : : #if defined(HAVE_MEMCHECK_H)
114 : : namespace
115 : : {
116 : : void blankExtraSpace(BitmapBuffer* pDIB)
117 : : {
118 : : size_t nExtraSpaceInScanLine = pDIB->mnScanlineSize - pDIB->mnWidth * pDIB->mnBitCount / 8;
119 : : if (nExtraSpaceInScanLine)
120 : : {
121 : : for (long i = 0; i < pDIB->mnHeight; ++i)
122 : : {
123 : : sal_uInt8 *pRow = pDIB->mpBits + (i * pDIB->mnScanlineSize);
124 : : memset(pRow + (pDIB->mnScanlineSize - nExtraSpaceInScanLine), 0, nExtraSpaceInScanLine);
125 : : }
126 : : }
127 : : }
128 : : }
129 : : #endif
130 : :
131 : : // -----------------------------------------------------------------------------
132 : :
133 : 0 : BitmapBuffer* X11SalBitmap::ImplCreateDIB(
134 : : const Size& rSize,
135 : : sal_uInt16 nBitCount,
136 : : const BitmapPalette& rPal
137 : : ) {
138 : : DBG_ASSERT(
139 : : nBitCount == 1
140 : : || nBitCount == 4
141 : : || nBitCount == 8
142 : : || nBitCount == 16
143 : : || nBitCount == 24
144 : : , "Unsupported BitCount!"
145 : : );
146 : :
147 : 0 : BitmapBuffer* pDIB = NULL;
148 : :
149 : 0 : if( rSize.Width() && rSize.Height() )
150 : : {
151 : : try
152 : : {
153 : 0 : pDIB = new BitmapBuffer;
154 : : }
155 : 0 : catch (const std::bad_alloc&)
156 : : {
157 : 0 : pDIB = NULL;
158 : : }
159 : :
160 : 0 : if( pDIB )
161 : : {
162 : 0 : const sal_uInt16 nColors = ( nBitCount <= 8 ) ? ( 1 << nBitCount ) : 0;
163 : :
164 : 0 : pDIB->mnFormat = BMP_FORMAT_BOTTOM_UP;
165 : :
166 : 0 : switch( nBitCount )
167 : : {
168 : 0 : case( 1 ): pDIB->mnFormat |= BMP_FORMAT_1BIT_MSB_PAL; break;
169 : 0 : case( 4 ): pDIB->mnFormat |= BMP_FORMAT_4BIT_MSN_PAL; break;
170 : 0 : case( 8 ): pDIB->mnFormat |= BMP_FORMAT_8BIT_PAL; break;
171 : : #ifdef OSL_BIGENDIAN
172 : : case(16 ):
173 : : pDIB->mnFormat|= BMP_FORMAT_16BIT_TC_MSB_MASK;
174 : : pDIB->maColorMask = ColorMask( 0xf800, 0x07e0, 0x001f );
175 : : break;
176 : : #else
177 : : case(16 ):
178 : 0 : pDIB->mnFormat|= BMP_FORMAT_16BIT_TC_LSB_MASK;
179 : 0 : pDIB->maColorMask = ColorMask( 0xf800, 0x07e0, 0x001f );
180 : 0 : break;
181 : : #endif
182 : : default:
183 : 0 : nBitCount = 24;
184 : : //fall through
185 : : case 24:
186 : 0 : pDIB->mnFormat |= BMP_FORMAT_24BIT_TC_BGR;
187 : 0 : break;
188 : : }
189 : :
190 : 0 : pDIB->mnWidth = rSize.Width();
191 : 0 : pDIB->mnHeight = rSize.Height();
192 : 0 : pDIB->mnScanlineSize = AlignedWidth4Bytes( pDIB->mnWidth * nBitCount );
193 : 0 : pDIB->mnBitCount = nBitCount;
194 : :
195 : 0 : if( nColors )
196 : : {
197 : 0 : pDIB->maPalette = rPal;
198 : 0 : pDIB->maPalette.SetEntryCount( nColors );
199 : : }
200 : :
201 : : try
202 : : {
203 : 0 : pDIB->mpBits = new sal_uInt8[ pDIB->mnScanlineSize * pDIB->mnHeight ];
204 : : #if defined(HAVE_MEMCHECK_H)
205 : : if (RUNNING_ON_VALGRIND)
206 : : blankExtraSpace(pDIB);
207 : : #endif
208 : : }
209 : 0 : catch (const std::bad_alloc&)
210 : : {
211 : 0 : delete pDIB;
212 : 0 : pDIB = NULL;
213 : : }
214 : : }
215 : : }
216 : : else
217 : 0 : pDIB = NULL;
218 : :
219 : 0 : return pDIB;
220 : : }
221 : :
222 : : // -----------------------------------------------------------------------------
223 : :
224 : 0 : BitmapBuffer* X11SalBitmap::ImplCreateDIB(
225 : : Drawable aDrawable,
226 : : SalX11Screen nScreen,
227 : : long nDrawableDepth,
228 : : long nX,
229 : : long nY,
230 : : long nWidth,
231 : : long nHeight,
232 : : bool bGrey
233 : : ) {
234 : 0 : BitmapBuffer* pDIB = NULL;
235 : :
236 : 0 : if( aDrawable && nWidth && nHeight && nDrawableDepth )
237 : : {
238 : 0 : SalDisplay* pSalDisp = GetGenericData()->GetSalDisplay();
239 : 0 : Display* pXDisp = pSalDisp->GetDisplay();
240 : :
241 : : // do not die on XError here
242 : : // alternatively one could check the coordinates for being offscreen
243 : : // but this call can actually work on servers with backing store
244 : : // defaults even if the rectangle is offscreen
245 : : // so better catch the XError
246 : 0 : GetGenericData()->ErrorTrapPush();
247 : 0 : XImage* pImage = XGetImage( pXDisp, aDrawable, nX, nY, nWidth, nHeight, AllPlanes, ZPixmap );
248 : 0 : bool bWasError = GetGenericData()->ErrorTrapPop( false );
249 : :
250 : 0 : if( ! bWasError && pImage && pImage->data )
251 : : {
252 : 0 : const SalTwoRect aTwoRect = { 0, 0, nWidth, nHeight, 0, 0, nWidth, nHeight };
253 : 0 : BitmapBuffer aSrcBuf;
254 : 0 : sal_uLong nDstFormat = BMP_FORMAT_BOTTOM_UP;
255 : 0 : const BitmapPalette* pDstPal = NULL;
256 : :
257 : 0 : aSrcBuf.mnFormat = BMP_FORMAT_TOP_DOWN;
258 : 0 : aSrcBuf.mnWidth = nWidth;
259 : 0 : aSrcBuf.mnHeight = nHeight;
260 : 0 : aSrcBuf.mnBitCount = pImage->bits_per_pixel;
261 : 0 : aSrcBuf.mnScanlineSize = pImage->bytes_per_line;
262 : 0 : aSrcBuf.mpBits = (sal_uInt8*) pImage->data;
263 : :
264 : 0 : pImage->red_mask = pSalDisp->GetVisual( nScreen ).red_mask;
265 : 0 : pImage->green_mask = pSalDisp->GetVisual( nScreen ).green_mask;
266 : 0 : pImage->blue_mask = pSalDisp->GetVisual( nScreen ).blue_mask;
267 : :
268 : 0 : switch( aSrcBuf.mnBitCount )
269 : : {
270 : : case( 1 ):
271 : : {
272 : : aSrcBuf.mnFormat |= ( LSBFirst == pImage->bitmap_bit_order
273 : : ? BMP_FORMAT_1BIT_LSB_PAL
274 : : : BMP_FORMAT_1BIT_MSB_PAL
275 : 0 : );
276 : 0 : nDstFormat |= BMP_FORMAT_1BIT_MSB_PAL;
277 : : }
278 : 0 : break;
279 : :
280 : : case( 4 ):
281 : : {
282 : : aSrcBuf.mnFormat |= ( LSBFirst == pImage->bitmap_bit_order
283 : : ? BMP_FORMAT_4BIT_LSN_PAL
284 : : : BMP_FORMAT_4BIT_MSN_PAL
285 : 0 : );
286 : 0 : nDstFormat |= BMP_FORMAT_4BIT_MSN_PAL;
287 : : }
288 : 0 : break;
289 : :
290 : : case( 8 ):
291 : : {
292 : 0 : aSrcBuf.mnFormat |= BMP_FORMAT_8BIT_PAL;
293 : 0 : nDstFormat |= BMP_FORMAT_8BIT_PAL;
294 : : }
295 : 0 : break;
296 : :
297 : : case( 16 ):
298 : : {
299 : 0 : nDstFormat |= BMP_FORMAT_24BIT_TC_BGR;
300 : 0 : aSrcBuf.maColorMask = ColorMask( pImage->red_mask, pImage->green_mask, pImage->blue_mask );
301 : :
302 : 0 : if( LSBFirst == pImage->byte_order )
303 : : {
304 : 0 : aSrcBuf.mnFormat |= BMP_FORMAT_16BIT_TC_LSB_MASK;
305 : : }
306 : : else
307 : : {
308 : 0 : aSrcBuf.mnFormat |= BMP_FORMAT_16BIT_TC_MSB_MASK;
309 : : }
310 : : }
311 : 0 : break;
312 : :
313 : : case( 24 ):
314 : : {
315 : 0 : if( ( LSBFirst == pImage->byte_order ) && ( pImage->red_mask == 0xFF ) )
316 : 0 : aSrcBuf.mnFormat |= BMP_FORMAT_24BIT_TC_RGB;
317 : : else
318 : 0 : aSrcBuf.mnFormat |= BMP_FORMAT_24BIT_TC_BGR;
319 : :
320 : 0 : nDstFormat |= BMP_FORMAT_24BIT_TC_BGR;
321 : : }
322 : 0 : break;
323 : :
324 : : case( 32 ):
325 : : {
326 : 0 : if( LSBFirst == pImage->byte_order )
327 : 0 : aSrcBuf.mnFormat |= ( pSalDisp->GetVisual(nScreen).red_mask == 0xFF
328 : : ? BMP_FORMAT_32BIT_TC_RGBA
329 : : : BMP_FORMAT_32BIT_TC_BGRA
330 : 0 : );
331 : : else
332 : 0 : aSrcBuf.mnFormat |= ( pSalDisp->GetVisual(nScreen).red_mask == 0xFF
333 : : ? BMP_FORMAT_32BIT_TC_ABGR
334 : : : BMP_FORMAT_32BIT_TC_ARGB
335 : 0 : );
336 : 0 : nDstFormat |= BMP_FORMAT_24BIT_TC_BGR;
337 : : }
338 : 0 : break;
339 : : }
340 : :
341 : 0 : BitmapPalette& rPal = aSrcBuf.maPalette;
342 : :
343 : 0 : if( aSrcBuf.mnBitCount == 1 )
344 : : {
345 : 0 : rPal.SetEntryCount( 2 );
346 : 0 : pDstPal = &rPal;
347 : :
348 : 0 : rPal[ 0 ] = Color( COL_BLACK );
349 : 0 : rPal[ 1 ] = Color( COL_WHITE );
350 : : }
351 : 0 : else if( pImage->depth == 8 && bGrey )
352 : : {
353 : 0 : rPal.SetEntryCount( 256 );
354 : 0 : pDstPal = &rPal;
355 : :
356 : 0 : for( sal_uInt16 i = 0; i < 256; i++ )
357 : : {
358 : 0 : BitmapColor& rBmpCol = rPal[ i ];
359 : :
360 : 0 : rBmpCol.SetRed( i );
361 : 0 : rBmpCol.SetGreen( i );
362 : 0 : rBmpCol.SetBlue( i );
363 : 0 : }
364 : :
365 : : }
366 : 0 : else if( aSrcBuf.mnBitCount <= 8 )
367 : : {
368 : 0 : const SalColormap& rColMap = pSalDisp->GetColormap( nScreen );
369 : : const sal_uInt16 nCols = Min( (sal_uLong)rColMap.GetUsed()
370 : : , (sal_uLong)(1 << nDrawableDepth)
371 : 0 : );
372 : :
373 : 0 : rPal.SetEntryCount( nCols );
374 : 0 : pDstPal = &rPal;
375 : :
376 : 0 : for( sal_uInt16 i = 0; i < nCols; i++ )
377 : : {
378 : 0 : const SalColor nColor( rColMap.GetColor( i ) );
379 : 0 : BitmapColor& rBmpCol = rPal[ i ];
380 : :
381 : 0 : rBmpCol.SetRed( SALCOLOR_RED( nColor ) );
382 : 0 : rBmpCol.SetGreen( SALCOLOR_GREEN( nColor ) );
383 : 0 : rBmpCol.SetBlue( SALCOLOR_BLUE( nColor ) );
384 : : }
385 : : }
386 : :
387 : 0 : nDstFormat = aSrcBuf.mnFormat;
388 : : pDIB = StretchAndConvert( aSrcBuf, aTwoRect, nDstFormat,
389 : 0 : const_cast<BitmapPalette*>(pDstPal), &aSrcBuf.maColorMask );
390 : 0 : XDestroyImage( pImage );
391 : : }
392 : : }
393 : :
394 : 0 : return pDIB;
395 : : }
396 : :
397 : : // -----------------------------------------------------------------------------
398 : :
399 : 0 : XImage* X11SalBitmap::ImplCreateXImage(
400 : : SalDisplay *pSalDisp,
401 : : SalX11Screen nScreen,
402 : : long nDepth,
403 : : const SalTwoRect& rTwoRect
404 : : ) const
405 : : {
406 : 0 : XImage* pImage = NULL;
407 : :
408 : 0 : if( !mpDIB && mpDDB )
409 : : {
410 : : const_cast<X11SalBitmap*>(this)->mpDIB =
411 : : ImplCreateDIB( mpDDB->ImplGetPixmap(),
412 : : mpDDB->ImplGetScreen(),
413 : : mpDDB->ImplGetDepth(),
414 : : 0, 0,
415 : : mpDDB->ImplGetWidth(),
416 : : mpDDB->ImplGetHeight(),
417 : 0 : mbGrey );
418 : : }
419 : :
420 : 0 : if( mpDIB && mpDIB->mnWidth && mpDIB->mnHeight )
421 : : {
422 : 0 : Display* pXDisp = pSalDisp->GetDisplay();
423 : 0 : long nWidth = rTwoRect.mnDestWidth;
424 : 0 : long nHeight = rTwoRect.mnDestHeight;
425 : :
426 : 0 : if( 1 == GetBitCount() )
427 : 0 : nDepth = 1;
428 : :
429 : 0 : pImage = XCreateImage( pXDisp, pSalDisp->GetVisual( nScreen ).GetVisual(),
430 : : nDepth, ( 1 == nDepth ) ? XYBitmap :ZPixmap, 0, NULL,
431 : 0 : nWidth, nHeight, 32, 0 );
432 : :
433 : 0 : if( pImage )
434 : : {
435 : : BitmapBuffer* pDstBuf;
436 : 0 : sal_uLong nDstFormat = BMP_FORMAT_TOP_DOWN;
437 : 0 : BitmapPalette* pPal = NULL;
438 : 0 : ColorMask* pMask = NULL;
439 : :
440 : 0 : switch( pImage->bits_per_pixel )
441 : : {
442 : : case( 1 ):
443 : : nDstFormat |= ( LSBFirst == pImage->bitmap_bit_order
444 : : ? BMP_FORMAT_1BIT_LSB_PAL
445 : : : BMP_FORMAT_1BIT_MSB_PAL
446 : 0 : );
447 : 0 : break;
448 : :
449 : : case( 4 ):
450 : : nDstFormat |= ( LSBFirst == pImage->bitmap_bit_order
451 : : ? BMP_FORMAT_4BIT_LSN_PAL
452 : : : BMP_FORMAT_4BIT_MSN_PAL
453 : 0 : );
454 : 0 : break;
455 : :
456 : : case( 8 ):
457 : 0 : nDstFormat |= BMP_FORMAT_8BIT_PAL;
458 : 0 : break;
459 : :
460 : : case( 16 ):
461 : : {
462 : : #ifdef OSL_BIGENDIAN
463 : :
464 : : if( MSBFirst == pImage->byte_order )
465 : : nDstFormat |= BMP_FORMAT_16BIT_TC_MSB_MASK;
466 : : else
467 : : nDstFormat |= BMP_FORMAT_16BIT_TC_LSB_MASK;
468 : :
469 : : #else /* OSL_LITENDIAN */
470 : :
471 : 0 : nDstFormat |= BMP_FORMAT_16BIT_TC_LSB_MASK;
472 : 0 : if( MSBFirst == pImage->byte_order )
473 : 0 : pImage->byte_order = LSBFirst;
474 : :
475 : : #endif
476 : :
477 : 0 : pMask = new ColorMask( pImage->red_mask, pImage->green_mask, pImage->blue_mask );
478 : : }
479 : 0 : break;
480 : :
481 : : case( 24 ):
482 : : {
483 : 0 : if( ( LSBFirst == pImage->byte_order ) && ( pImage->red_mask == 0xFF ) )
484 : 0 : nDstFormat |= BMP_FORMAT_24BIT_TC_RGB;
485 : : else
486 : 0 : nDstFormat |= BMP_FORMAT_24BIT_TC_BGR;
487 : : }
488 : 0 : break;
489 : :
490 : : case( 32 ):
491 : : {
492 : 0 : if( LSBFirst == pImage->byte_order )
493 : : nDstFormat |= ( pImage->red_mask == 0xFF
494 : : ? BMP_FORMAT_32BIT_TC_RGBA
495 : : : BMP_FORMAT_32BIT_TC_BGRA
496 : 0 : );
497 : : else
498 : : nDstFormat |= ( pImage->red_mask == 0xFF
499 : : ? BMP_FORMAT_32BIT_TC_ABGR
500 : : : BMP_FORMAT_32BIT_TC_ARGB
501 : 0 : );
502 : : }
503 : 0 : break;
504 : : }
505 : :
506 : 0 : if( pImage->depth == 1 )
507 : : {
508 : 0 : pPal = new BitmapPalette( 2 );
509 : 0 : (*pPal)[ 0 ] = Color( COL_BLACK );
510 : 0 : (*pPal)[ 1 ] = Color( COL_WHITE );
511 : : }
512 : 0 : else if( pImage->depth == 8 && mbGrey )
513 : : {
514 : 0 : pPal = new BitmapPalette( 256 );
515 : :
516 : 0 : for( sal_uInt16 i = 0; i < 256; i++ )
517 : : {
518 : 0 : BitmapColor& rBmpCol = (*pPal)[ i ];
519 : :
520 : 0 : rBmpCol.SetRed( i );
521 : 0 : rBmpCol.SetGreen( i );
522 : 0 : rBmpCol.SetBlue( i );
523 : 0 : }
524 : :
525 : : }
526 : 0 : else if( pImage->depth <= 8 )
527 : : {
528 : 0 : const SalColormap& rColMap = pSalDisp->GetColormap( nScreen );
529 : : const sal_uInt16 nCols = Min( (sal_uLong)rColMap.GetUsed()
530 : : , (sal_uLong)(1 << pImage->depth)
531 : 0 : );
532 : :
533 : 0 : pPal = new BitmapPalette( nCols );
534 : :
535 : 0 : for( sal_uInt16 i = 0; i < nCols; i++ )
536 : : {
537 : 0 : const SalColor nColor( rColMap.GetColor( i ) );
538 : 0 : BitmapColor& rBmpCol = (*pPal)[ i ];
539 : :
540 : 0 : rBmpCol.SetRed( SALCOLOR_RED( nColor ) );
541 : 0 : rBmpCol.SetGreen( SALCOLOR_GREEN( nColor ) );
542 : 0 : rBmpCol.SetBlue( SALCOLOR_BLUE( nColor ) );
543 : : }
544 : : }
545 : :
546 : 0 : pDstBuf = StretchAndConvert( *mpDIB, rTwoRect, nDstFormat, pPal, pMask );
547 : 0 : delete pPal;
548 : 0 : delete pMask;
549 : :
550 : 0 : if( pDstBuf && pDstBuf->mpBits )
551 : : {
552 : : #if defined(HAVE_MEMCHECK_H)
553 : : if (RUNNING_ON_VALGRIND)
554 : : blankExtraSpace(pDstBuf);
555 : : #endif
556 : : // set data in buffer as data member in pImage
557 : 0 : pImage->data = (char*) pDstBuf->mpBits;
558 : :
559 : : // destroy buffer; don't destroy allocated data in buffer
560 : 0 : delete pDstBuf;
561 : : }
562 : : else
563 : : {
564 : 0 : XDestroyImage( pImage );
565 : 0 : pImage = NULL;
566 : : }
567 : : }
568 : : }
569 : :
570 : 0 : return pImage;
571 : : }
572 : :
573 : : // -----------------------------------------------------------------------------
574 : 0 : bool X11SalBitmap::ImplCreateFromDrawable(
575 : : Drawable aDrawable,
576 : : SalX11Screen nScreen,
577 : : long nDrawableDepth,
578 : : long nX,
579 : : long nY,
580 : : long nWidth,
581 : : long nHeight
582 : : ) {
583 : 0 : Destroy();
584 : :
585 : 0 : if( aDrawable && nWidth && nHeight && nDrawableDepth )
586 : 0 : mpDDB = new ImplSalDDB( aDrawable, nScreen, nDrawableDepth, nX, nY, nWidth, nHeight );
587 : :
588 : 0 : return( mpDDB != NULL );
589 : : }
590 : : // -----------------------------------------------------------------------------
591 : :
592 : 0 : ImplSalDDB* X11SalBitmap::ImplGetDDB(
593 : : Drawable aDrawable,
594 : : SalX11Screen nXScreen,
595 : : long nDrawableDepth,
596 : : const SalTwoRect& rTwoRect
597 : : ) const
598 : : {
599 : 0 : if( !mpDDB || !mpDDB->ImplMatches( nXScreen, nDrawableDepth, rTwoRect ) )
600 : : {
601 : 0 : if( mpDDB )
602 : : {
603 : : // do we already have a DIB? if not, create aDIB from current DDB first
604 : 0 : if( !mpDIB )
605 : : {
606 : : const_cast<X11SalBitmap*>(this)->mpDIB = ImplCreateDIB( mpDDB->ImplGetPixmap(),
607 : : mpDDB->ImplGetScreen(),
608 : : mpDDB->ImplGetDepth(),
609 : : 0, 0,
610 : : mpDDB->ImplGetWidth(),
611 : : mpDDB->ImplGetHeight(),
612 : 0 : mbGrey );
613 : : }
614 : :
615 : 0 : delete mpDDB, const_cast<X11SalBitmap*>(this)->mpDDB = NULL;
616 : : }
617 : :
618 : 0 : if( mpCache )
619 : 0 : mpCache->ImplRemove( const_cast<X11SalBitmap*>(this) );
620 : :
621 : 0 : SalTwoRect aTwoRect( rTwoRect );
622 : 0 : if( aTwoRect.mnSrcX < 0 )
623 : : {
624 : 0 : aTwoRect.mnSrcWidth += aTwoRect.mnSrcX;
625 : 0 : aTwoRect.mnSrcX = 0;
626 : : }
627 : 0 : if( aTwoRect.mnSrcY < 0 )
628 : : {
629 : 0 : aTwoRect.mnSrcHeight += aTwoRect.mnSrcY;
630 : 0 : aTwoRect.mnSrcY = 0;
631 : : }
632 : :
633 : : // create new DDB from DIB
634 : 0 : const Size aSize( GetSize() );
635 : 0 : if( aTwoRect.mnSrcWidth == aTwoRect.mnDestWidth &&
636 : : aTwoRect.mnSrcHeight == aTwoRect.mnDestHeight )
637 : : {
638 : 0 : aTwoRect.mnSrcX = aTwoRect.mnSrcY = aTwoRect.mnDestX = aTwoRect.mnDestY = 0;
639 : 0 : aTwoRect.mnSrcWidth = aTwoRect.mnDestWidth = aSize.Width();
640 : 0 : aTwoRect.mnSrcHeight = aTwoRect.mnDestHeight = aSize.Height();
641 : : }
642 : 0 : else if( aTwoRect.mnSrcWidth+aTwoRect.mnSrcX > aSize.Width() ||
643 : 0 : aTwoRect.mnSrcHeight+aTwoRect.mnSrcY > aSize.Height() )
644 : : {
645 : : // #i47823# this should not happen at all, but does nonetheless
646 : : // because BitmapEx allows for mask bitmaps of different size
647 : : // than image bitmap (broken)
648 : 0 : if( aTwoRect.mnSrcX >= aSize.Width() ||
649 : 0 : aTwoRect.mnSrcY >= aSize.Height() )
650 : 0 : return NULL; // this would be a really mad case
651 : :
652 : 0 : if( aTwoRect.mnSrcWidth+aTwoRect.mnSrcX > aSize.Width() )
653 : : {
654 : 0 : aTwoRect.mnSrcWidth = aSize.Width()-aTwoRect.mnSrcX;
655 : 0 : if( aTwoRect.mnSrcWidth < 1 )
656 : : {
657 : 0 : aTwoRect.mnSrcX = 0;
658 : 0 : aTwoRect.mnSrcWidth = aSize.Width();
659 : : }
660 : : }
661 : 0 : if( aTwoRect.mnSrcHeight+aTwoRect.mnSrcY > aSize.Height() )
662 : : {
663 : 0 : aTwoRect.mnSrcHeight = aSize.Height() - aTwoRect.mnSrcY;
664 : 0 : if( aTwoRect.mnSrcHeight < 1 )
665 : : {
666 : 0 : aTwoRect.mnSrcY = 0;
667 : 0 : aTwoRect.mnSrcHeight = aSize.Height();
668 : : }
669 : : }
670 : : }
671 : :
672 : : XImage* pImage = ImplCreateXImage( GetGenericData()->GetSalDisplay(), nXScreen,
673 : 0 : nDrawableDepth, aTwoRect );
674 : :
675 : 0 : if( pImage )
676 : : {
677 : 0 : const_cast<X11SalBitmap*>(this)->mpDDB = new ImplSalDDB( pImage, aDrawable, nXScreen, aTwoRect );
678 : 0 : delete[] pImage->data, pImage->data = NULL;
679 : 0 : XDestroyImage( pImage );
680 : :
681 : 0 : if( mpCache )
682 : 0 : mpCache->ImplAdd( const_cast<X11SalBitmap*>(this), mpDDB->ImplGetMemSize() );
683 : : }
684 : : }
685 : :
686 : 0 : return mpDDB;
687 : : }
688 : :
689 : : // -----------------------------------------------------------------------------
690 : :
691 : 0 : void X11SalBitmap::ImplDraw(
692 : : Drawable aDrawable,
693 : : SalX11Screen nXScreen,
694 : : long nDrawableDepth,
695 : : const SalTwoRect& rTwoRect,
696 : : const GC& rGC
697 : : ) const
698 : : {
699 : 0 : ImplGetDDB( aDrawable, nXScreen, nDrawableDepth, rTwoRect );
700 : 0 : if( mpDDB )
701 : 0 : mpDDB->ImplDraw( aDrawable, nDrawableDepth, rTwoRect, rGC );
702 : 0 : }
703 : :
704 : : // -----------------------------------------------------------------------------
705 : :
706 : 0 : bool X11SalBitmap::Create( const Size& rSize, sal_uInt16 nBitCount, const BitmapPalette& rPal )
707 : : {
708 : 0 : Destroy();
709 : 0 : mpDIB = ImplCreateDIB( rSize, nBitCount, rPal );
710 : :
711 : 0 : return( mpDIB != NULL );
712 : : }
713 : :
714 : : // -----------------------------------------------------------------------------
715 : :
716 : 0 : bool X11SalBitmap::Create( const SalBitmap& rSSalBmp )
717 : : {
718 : 0 : Destroy();
719 : :
720 : 0 : const X11SalBitmap& rSalBmp = static_cast<const X11SalBitmap&>( rSSalBmp );
721 : :
722 : 0 : if( rSalBmp.mpDIB )
723 : : {
724 : : // TODO: reference counting...
725 : 0 : mpDIB = new BitmapBuffer( *rSalBmp.mpDIB );
726 : : // TODO: get rid of this when BitmapBuffer gets copy constructor
727 : : try
728 : : {
729 : 0 : mpDIB->mpBits = new sal_uInt8[ mpDIB->mnScanlineSize * mpDIB->mnHeight ];
730 : : #if defined(HAVE_MEMCHECK_H)
731 : : if (RUNNING_ON_VALGRIND)
732 : : blankExtraSpace(mpDIB);
733 : : #endif
734 : : }
735 : 0 : catch (const std::bad_alloc&)
736 : : {
737 : 0 : delete mpDIB;
738 : 0 : mpDIB = NULL;
739 : : }
740 : :
741 : 0 : if( mpDIB )
742 : 0 : memcpy( mpDIB->mpBits, rSalBmp.mpDIB->mpBits, mpDIB->mnScanlineSize * mpDIB->mnHeight );
743 : : }
744 : 0 : else if( rSalBmp.mpDDB )
745 : : ImplCreateFromDrawable( rSalBmp.mpDDB->ImplGetPixmap(),
746 : : rSalBmp.mpDDB->ImplGetScreen(),
747 : : rSalBmp.mpDDB->ImplGetDepth(),
748 : 0 : 0, 0, rSalBmp.mpDDB->ImplGetWidth(), rSalBmp.mpDDB->ImplGetHeight() );
749 : :
750 : 0 : return( ( !rSalBmp.mpDIB && !rSalBmp.mpDDB ) ||
751 : : ( rSalBmp.mpDIB && ( mpDIB != NULL ) ) ||
752 : 0 : ( rSalBmp.mpDDB && ( mpDDB != NULL ) ) );
753 : : }
754 : :
755 : : // -----------------------------------------------------------------------------
756 : :
757 : 0 : bool X11SalBitmap::Create( const SalBitmap&, SalGraphics* )
758 : : {
759 : 0 : return false;
760 : : }
761 : :
762 : : // -----------------------------------------------------------------------------
763 : :
764 : 0 : bool X11SalBitmap::Create( const SalBitmap&, sal_uInt16 )
765 : : {
766 : 0 : return false;
767 : : }
768 : :
769 : : // -----------------------------------------------------------------------------
770 : :
771 : 0 : bool X11SalBitmap::Create(
772 : : const ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XBitmapCanvas > xBitmapCanvas,
773 : : Size& rSize,
774 : : bool bMask
775 : : ) {
776 : : ::com::sun::star::uno::Reference< ::com::sun::star::beans::XFastPropertySet >
777 : 0 : xFastPropertySet( xBitmapCanvas, ::com::sun::star::uno::UNO_QUERY );
778 : :
779 : 0 : if( xFastPropertySet.get() ) {
780 : : sal_Int32 depth;
781 : 0 : ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > args;
782 : :
783 : 0 : if( xFastPropertySet->getFastPropertyValue(bMask ? 2 : 1) >>= args ) {
784 : : long pixmapHandle;
785 : 0 : if( ( args[1] >>= pixmapHandle ) && ( args[2] >>= depth ) ) {
786 : :
787 : 0 : mbGrey = bMask;
788 : : bool bSuccess = ImplCreateFromDrawable(
789 : : pixmapHandle,
790 : : // FIXME: this seems multi-screen broken to me
791 : : SalX11Screen( 0 ),
792 : : depth,
793 : : 0,
794 : : 0,
795 : 0 : (long) rSize.Width(),
796 : 0 : (long) rSize.Height()
797 : 0 : );
798 : 0 : bool bFreePixmap = false;
799 : 0 : if( bSuccess && (args[0] >>= bFreePixmap) && bFreePixmap )
800 : 0 : XFreePixmap( GetGenericData()->GetSalDisplay()->GetDisplay(), pixmapHandle );
801 : :
802 : 0 : return bSuccess;
803 : : }
804 : 0 : }
805 : : }
806 : :
807 : 0 : return false;
808 : : }
809 : :
810 : : // -----------------------------------------------------------------------------
811 : :
812 : 0 : void X11SalBitmap::Destroy()
813 : : {
814 : 0 : if( mpDIB )
815 : : {
816 : 0 : delete[] mpDIB->mpBits;
817 : 0 : delete mpDIB, mpDIB = NULL;
818 : : }
819 : :
820 : 0 : if( mpDDB )
821 : 0 : delete mpDDB, mpDDB = NULL;
822 : :
823 : 0 : if( mpCache )
824 : 0 : mpCache->ImplRemove( this );
825 : 0 : }
826 : :
827 : : // -----------------------------------------------------------------------------
828 : :
829 : 0 : Size X11SalBitmap::GetSize() const
830 : : {
831 : 0 : Size aSize;
832 : :
833 : 0 : if( mpDIB )
834 : 0 : aSize.Width() = mpDIB->mnWidth, aSize.Height() = mpDIB->mnHeight;
835 : 0 : else if( mpDDB )
836 : 0 : aSize.Width() = mpDDB->ImplGetWidth(), aSize.Height() = mpDDB->ImplGetHeight();
837 : :
838 : 0 : return aSize;
839 : : }
840 : :
841 : : // -----------------------------------------------------------------------------
842 : :
843 : 0 : sal_uInt16 X11SalBitmap::GetBitCount() const
844 : : {
845 : : sal_uInt16 nBitCount;
846 : :
847 : 0 : if( mpDIB )
848 : 0 : nBitCount = mpDIB->mnBitCount;
849 : 0 : else if( mpDDB )
850 : 0 : nBitCount = mpDDB->ImplGetDepth();
851 : : else
852 : 0 : nBitCount = 0;
853 : :
854 : 0 : return nBitCount;
855 : : }
856 : :
857 : : // -----------------------------------------------------------------------------
858 : :
859 : 0 : BitmapBuffer* X11SalBitmap::AcquireBuffer( bool )
860 : : {
861 : 0 : if( !mpDIB && mpDDB )
862 : : {
863 : : mpDIB = ImplCreateDIB(
864 : : mpDDB->ImplGetPixmap(),
865 : : mpDDB->ImplGetScreen(),
866 : : mpDDB->ImplGetDepth(),
867 : : 0, 0,
868 : : mpDDB->ImplGetWidth(),
869 : : mpDDB->ImplGetHeight(),
870 : : mbGrey
871 : 0 : );
872 : : }
873 : :
874 : 0 : return mpDIB;
875 : : }
876 : :
877 : : // -----------------------------------------------------------------------------
878 : :
879 : 0 : void X11SalBitmap::ReleaseBuffer( BitmapBuffer*, bool bReadOnly )
880 : : {
881 : 0 : if( !bReadOnly )
882 : : {
883 : 0 : if( mpDDB )
884 : 0 : delete mpDDB, mpDDB = NULL;
885 : :
886 : 0 : if( mpCache )
887 : 0 : mpCache->ImplRemove( this );
888 : : }
889 : 0 : }
890 : :
891 : : // -----------------------------------------------------------------------------
892 : :
893 : 0 : bool X11SalBitmap::GetSystemData( BitmapSystemData& rData )
894 : : {
895 : 0 : if( mpDDB )
896 : : {
897 : : // Rename/retype pDummy to your likings (though X11 Pixmap is
898 : : // prolly not a good idea, since it's accessed from
899 : : // non-platform aware code in vcl/bitmap.hxx)
900 : 0 : rData.aPixmap = (void*)mpDDB->ImplGetPixmap();
901 : 0 : rData.mnWidth = mpDDB->ImplGetWidth ();
902 : 0 : rData.mnHeight = mpDDB->ImplGetHeight ();
903 : 0 : return true;
904 : : }
905 : :
906 : 0 : return false;
907 : : }
908 : :
909 : : // --------------
910 : : // - ImplSalDDB -
911 : : // --------------
912 : :
913 : 0 : ImplSalDDB::ImplSalDDB( XImage* pImage, Drawable aDrawable,
914 : : SalX11Screen nXScreen, const SalTwoRect& rTwoRect )
915 : : : maPixmap ( 0 )
916 : : , maTwoRect ( rTwoRect )
917 : : , mnDepth ( pImage->depth )
918 : 0 : , mnXScreen ( nXScreen )
919 : : {
920 : 0 : SalDisplay* pSalDisp = GetGenericData()->GetSalDisplay();
921 : 0 : Display* pXDisp = pSalDisp->GetDisplay();
922 : :
923 : 0 : if( (maPixmap = limitXCreatePixmap( pXDisp, aDrawable, ImplGetWidth(), ImplGetHeight(), ImplGetDepth() )) )
924 : : {
925 : : XGCValues aValues;
926 : : GC aGC;
927 : 0 : int nValues = GCFunction;
928 : :
929 : 0 : aValues.function = GXcopy;
930 : :
931 : 0 : if( 1 == mnDepth )
932 : : {
933 : 0 : nValues |= ( GCForeground | GCBackground );
934 : 0 : aValues.foreground = 1, aValues.background = 0;
935 : : }
936 : :
937 : 0 : aGC = XCreateGC( pXDisp, maPixmap, nValues, &aValues );
938 : 0 : XPutImage( pXDisp, maPixmap, aGC, pImage, 0, 0, 0, 0, maTwoRect.mnDestWidth, maTwoRect.mnDestHeight );
939 : 0 : XFreeGC( pXDisp, aGC );
940 : : }
941 : 0 : }
942 : :
943 : : // -----------------------------------------------------------------------------
944 : :
945 : 0 : ImplSalDDB::ImplSalDDB(
946 : : Drawable aDrawable,
947 : : SalX11Screen nXScreen,
948 : : long nDrawableDepth,
949 : : long nX,
950 : : long nY,
951 : : long nWidth,
952 : : long nHeight
953 : : ) : mnDepth( nDrawableDepth )
954 : 0 : , mnXScreen( nXScreen )
955 : : {
956 : 0 : SalDisplay* pSalDisp = GetGenericData()->GetSalDisplay();
957 : 0 : Display* pXDisp = pSalDisp->GetDisplay();
958 : :
959 : 0 : if( (maPixmap = limitXCreatePixmap( pXDisp, aDrawable, nWidth, nHeight, nDrawableDepth )) )
960 : : {
961 : : XGCValues aValues;
962 : : GC aGC;
963 : 0 : int nValues = GCFunction;
964 : :
965 : 0 : aValues.function = GXcopy;
966 : :
967 : 0 : if( 1 == mnDepth )
968 : : {
969 : 0 : nValues |= ( GCForeground | GCBackground );
970 : 0 : aValues.foreground = 1, aValues.background = 0;
971 : : }
972 : :
973 : 0 : aGC = XCreateGC( pXDisp, maPixmap, nValues, &aValues );
974 : : ImplDraw( aDrawable, nDrawableDepth, maPixmap, mnDepth,
975 : 0 : nX, nY, nWidth, nHeight, 0, 0, aGC );
976 : 0 : XFreeGC( pXDisp, aGC );
977 : :
978 : 0 : maTwoRect.mnSrcX = maTwoRect.mnSrcY = maTwoRect.mnDestX = maTwoRect.mnDestY = 0;
979 : 0 : maTwoRect.mnSrcWidth = maTwoRect.mnDestWidth = nWidth;
980 : 0 : maTwoRect.mnSrcHeight = maTwoRect.mnDestHeight = nHeight;
981 : : }
982 : 0 : }
983 : :
984 : : // -----------------------------------------------------------------------------
985 : :
986 : 0 : ImplSalDDB::~ImplSalDDB()
987 : : {
988 : 0 : if( maPixmap && ImplGetSVData() )
989 : 0 : XFreePixmap( GetGenericData()->GetSalDisplay()->GetDisplay(), maPixmap );
990 : 0 : }
991 : :
992 : : // -----------------------------------------------------------------------------
993 : :
994 : 0 : bool ImplSalDDB::ImplMatches( SalX11Screen nXScreen, long nDepth, const SalTwoRect& rTwoRect ) const
995 : : {
996 : 0 : bool bRet = false;
997 : :
998 : 0 : if( ( maPixmap != 0 ) && ( ( mnDepth == nDepth ) || ( 1 == mnDepth ) ) && nXScreen == mnXScreen)
999 : : {
1000 : 0 : if ( rTwoRect.mnSrcX == maTwoRect.mnSrcX
1001 : : && rTwoRect.mnSrcY == maTwoRect.mnSrcY
1002 : : && rTwoRect.mnSrcWidth == maTwoRect.mnSrcWidth
1003 : : && rTwoRect.mnSrcHeight == maTwoRect.mnSrcHeight
1004 : : && rTwoRect.mnDestWidth == maTwoRect.mnDestWidth
1005 : : && rTwoRect.mnDestHeight == maTwoRect.mnDestHeight
1006 : : )
1007 : : {
1008 : : // absolutely indentically
1009 : 0 : bRet = true;
1010 : : }
1011 : 0 : else if( rTwoRect.mnSrcWidth == rTwoRect.mnDestWidth
1012 : : && rTwoRect.mnSrcHeight == rTwoRect.mnDestHeight
1013 : : && maTwoRect.mnSrcWidth == maTwoRect.mnDestWidth
1014 : : && maTwoRect.mnSrcHeight == maTwoRect.mnDestHeight
1015 : : && rTwoRect.mnSrcX >= maTwoRect.mnSrcX
1016 : : && rTwoRect.mnSrcY >= maTwoRect.mnSrcY
1017 : : && ( rTwoRect.mnSrcX + rTwoRect.mnSrcWidth ) <= ( maTwoRect.mnSrcX + maTwoRect.mnSrcWidth )
1018 : : && ( rTwoRect.mnSrcY + rTwoRect.mnSrcHeight ) <= ( maTwoRect.mnSrcY + maTwoRect.mnSrcHeight )
1019 : : )
1020 : : {
1021 : 0 : bRet = true;
1022 : : }
1023 : : }
1024 : :
1025 : 0 : return bRet;
1026 : : }
1027 : :
1028 : : // -----------------------------------------------------------------------------
1029 : :
1030 : 0 : void ImplSalDDB::ImplDraw(
1031 : : Drawable aDrawable,
1032 : : long nDrawableDepth,
1033 : : const SalTwoRect& rTwoRect,
1034 : : const GC& rGC
1035 : : ) const
1036 : : {
1037 : : ImplDraw( maPixmap, mnDepth, aDrawable, nDrawableDepth,
1038 : : rTwoRect.mnSrcX - maTwoRect.mnSrcX, rTwoRect.mnSrcY - maTwoRect.mnSrcY,
1039 : : rTwoRect.mnDestWidth, rTwoRect.mnDestHeight,
1040 : 0 : rTwoRect.mnDestX, rTwoRect.mnDestY, rGC );
1041 : 0 : }
1042 : :
1043 : : // -----------------------------------------------------------------------------
1044 : :
1045 : 0 : void ImplSalDDB::ImplDraw(
1046 : : Drawable aSrcDrawable,
1047 : : long nSrcDrawableDepth,
1048 : : Drawable aDstDrawable,
1049 : : long,
1050 : : long nSrcX,
1051 : : long nSrcY,
1052 : : long nDestWidth,
1053 : : long nDestHeight,
1054 : : long nDestX,
1055 : : long nDestY,
1056 : : const GC& rGC
1057 : : ) {
1058 : 0 : SalDisplay* pSalDisp = GetGenericData()->GetSalDisplay();
1059 : 0 : Display* pXDisp = pSalDisp->GetDisplay();
1060 : :
1061 : 0 : if( 1 == nSrcDrawableDepth )
1062 : : {
1063 : : XCopyPlane( pXDisp, aSrcDrawable, aDstDrawable, rGC,
1064 : 0 : nSrcX, nSrcY, nDestWidth, nDestHeight, nDestX, nDestY, 1 );
1065 : : }
1066 : : else
1067 : : {
1068 : : XCopyArea( pXDisp, aSrcDrawable, aDstDrawable, rGC,
1069 : 0 : nSrcX, nSrcY, nDestWidth, nDestHeight, nDestX, nDestY );
1070 : : }
1071 : 0 : }
1072 : :
1073 : : // ----------------------
1074 : : // - ImplSalBitmapCache -
1075 : : // ----------------------
1076 : :
1077 : : struct ImplBmpObj
1078 : : {
1079 : : X11SalBitmap* mpBmp;
1080 : : sal_uLong mnMemSize;
1081 : : sal_uLong mnFlags;
1082 : :
1083 : 0 : ImplBmpObj( X11SalBitmap* pBmp, sal_uLong nMemSize, sal_uLong nFlags ) :
1084 : 0 : mpBmp( pBmp ), mnMemSize( nMemSize ), mnFlags( nFlags ) {}
1085 : : };
1086 : :
1087 : : // -----------------------------------------------------------------------------
1088 : :
1089 : 0 : ImplSalBitmapCache::ImplSalBitmapCache() :
1090 : 0 : mnTotalSize( 0UL )
1091 : : {
1092 : 0 : }
1093 : :
1094 : : // -----------------------------------------------------------------------------
1095 : :
1096 : 0 : ImplSalBitmapCache::~ImplSalBitmapCache()
1097 : : {
1098 : 0 : ImplClear();
1099 : 0 : }
1100 : :
1101 : : // -----------------------------------------------------------------------------
1102 : :
1103 : 0 : void ImplSalBitmapCache::ImplAdd( X11SalBitmap* pBmp, sal_uLong nMemSize, sal_uLong nFlags )
1104 : : {
1105 : 0 : ImplBmpObj* pObj = NULL;
1106 : 0 : bool bFound = false;
1107 : :
1108 : 0 : for(
1109 : 0 : BmpList_impl::iterator it = maBmpList.begin();
1110 : 0 : (it != maBmpList.end() ) && !bFound ;
1111 : : ++it
1112 : : ) {
1113 : 0 : pObj = *it;
1114 : 0 : if( pObj->mpBmp == pBmp )
1115 : 0 : bFound = true;
1116 : : }
1117 : :
1118 : 0 : mnTotalSize += nMemSize;
1119 : :
1120 : 0 : if( bFound )
1121 : : {
1122 : 0 : mnTotalSize -= pObj->mnMemSize;
1123 : 0 : pObj->mnMemSize = nMemSize, pObj->mnFlags = nFlags;
1124 : : }
1125 : : else
1126 : 0 : maBmpList.push_back( new ImplBmpObj( pBmp, nMemSize, nFlags ) );
1127 : 0 : }
1128 : :
1129 : : // -----------------------------------------------------------------------------
1130 : :
1131 : 0 : void ImplSalBitmapCache::ImplRemove( X11SalBitmap* pBmp )
1132 : : {
1133 : 0 : for(
1134 : 0 : BmpList_impl::iterator it = maBmpList.begin();
1135 : 0 : it != maBmpList.end();
1136 : : ++it
1137 : : ) {
1138 : 0 : if( (*it)->mpBmp == pBmp )
1139 : : {
1140 : 0 : (*it)->mpBmp->ImplRemovedFromCache();
1141 : 0 : mnTotalSize -= (*it)->mnMemSize;
1142 : 0 : delete *it;
1143 : 0 : maBmpList.erase( it );
1144 : 0 : break;
1145 : : }
1146 : : }
1147 : 0 : }
1148 : :
1149 : : // -----------------------------------------------------------------------------
1150 : :
1151 : 0 : void ImplSalBitmapCache::ImplClear()
1152 : : {
1153 : 0 : for(
1154 : 0 : BmpList_impl::iterator it = maBmpList.begin();
1155 : 0 : it != maBmpList.end();
1156 : : ++it
1157 : : ) {
1158 : 0 : (*it)->mpBmp->ImplRemovedFromCache();
1159 : 0 : delete *it;
1160 : : }
1161 : 0 : maBmpList.clear();
1162 : 0 : mnTotalSize = 0;
1163 : 0 : }
1164 : :
1165 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|