1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: salbmp.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_vcl.hxx"
38 #include <sys/types.h>
40 #include <tools/prex.h>
42 #include <tools/postx.h>
44 #include <osl/endian.h>
45 #include <rtl/memory.h>
46 #include <vcl/salbtype.hxx>
47 #include <saldata.hxx>
48 #include <saldisp.hxx>
52 #include <vcl/bitmap.hxx>
53 #include <com/sun/star/beans/XFastPropertySet.hpp>
59 #define SAL_DRAWPIXMAP_MAX_EXT 4096
65 SalBitmap
* X11SalInstance::CreateSalBitmap()
67 return new X11SalBitmap();
70 ImplSalBitmapCache
* X11SalBitmap::mpCache
= NULL
;
71 ULONG
X11SalBitmap::mnCacheInstCount
= 0;
73 // -----------------------------------------------------------------------------
75 X11SalBitmap::X11SalBitmap() :
82 // -----------------------------------------------------------------------------
84 X11SalBitmap::~X11SalBitmap()
89 // -----------------------------------------------------------------------------
91 void X11SalBitmap::ImplCreateCache()
93 if( !mnCacheInstCount
++ )
94 mpCache
= new ImplSalBitmapCache
;
97 // -----------------------------------------------------------------------------
99 void X11SalBitmap::ImplDestroyCache()
101 DBG_ASSERT( mnCacheInstCount
, "X11SalBitmap::ImplDestroyCache(): underflow" );
103 if( mnCacheInstCount
&& !--mnCacheInstCount
)
104 delete mpCache
, mpCache
= NULL
;
107 // -----------------------------------------------------------------------------
109 void X11SalBitmap::ImplRemovedFromCache()
112 delete mpDDB
, mpDDB
= NULL
;
115 // -----------------------------------------------------------------------------
117 BitmapBuffer
* X11SalBitmap::ImplCreateDIB( const Size
& rSize
, USHORT nBitCount
, const BitmapPalette
& rPal
)
119 DBG_ASSERT( nBitCount
== 1 || nBitCount
== 4 || nBitCount
== 8 || nBitCount
== 16 || nBitCount
== 24, "Unsupported BitCount!" );
121 BitmapBuffer
* pDIB
= NULL
;
123 if( rSize
.Width() && rSize
.Height() )
127 pDIB
= new BitmapBuffer
;
129 catch( std::bad_alloc
& )
136 const USHORT nColors
= ( nBitCount
<= 8 ) ? ( 1 << nBitCount
) : 0;
138 pDIB
->mnFormat
= BMP_FORMAT_BOTTOM_UP
;
142 case( 1 ): pDIB
->mnFormat
|= BMP_FORMAT_1BIT_MSB_PAL
; break;
143 case( 4 ): pDIB
->mnFormat
|= BMP_FORMAT_4BIT_MSN_PAL
; break;
144 case( 8 ): pDIB
->mnFormat
|= BMP_FORMAT_8BIT_PAL
; break;
147 pDIB
->mnFormat
|= BMP_FORMAT_16BIT_TC_MSB_MASK
;
148 pDIB
->maColorMask
= ColorMask( 0xf800, 0x07e0, 0x001f );
152 pDIB
->mnFormat
|= BMP_FORMAT_16BIT_TC_LSB_MASK
;
153 pDIB
->maColorMask
= ColorMask( 0xf800, 0x07e0, 0x001f );
160 pDIB
->mnFormat
|= BMP_FORMAT_24BIT_TC_BGR
;
164 pDIB
->mnWidth
= rSize
.Width();
165 pDIB
->mnHeight
= rSize
.Height();
166 pDIB
->mnScanlineSize
= AlignedWidth4Bytes( pDIB
->mnWidth
* nBitCount
);
167 pDIB
->mnBitCount
= nBitCount
;
171 pDIB
->maPalette
= rPal
;
172 pDIB
->maPalette
.SetEntryCount( nColors
);
177 pDIB
->mpBits
= new BYTE
[ pDIB
->mnScanlineSize
* pDIB
->mnHeight
];
179 catch(std::bad_alloc
&)
192 // -----------------------------------------------------------------------------
194 BitmapBuffer
* X11SalBitmap::ImplCreateDIB( Drawable aDrawable
,
198 long nWidth
, long nHeight
,
201 BitmapBuffer
* pDIB
= NULL
;
203 if( aDrawable
&& nWidth
&& nHeight
&& nDrawableDepth
)
205 SalDisplay
* pSalDisp
= GetX11SalData()->GetDisplay();
206 SalXLib
* pXLib
= pSalDisp
->GetXLib();
207 Display
* pXDisp
= pSalDisp
->GetDisplay();
209 // do not die on XError here
210 // alternatively one could check the coordinates for being offscreen
211 // but this call can actually work on servers with backing store
212 // defaults even if the rectangle is offscreen
213 // so better catch the XError
214 pXLib
->PushXErrorLevel( true );
215 XImage
* pImage
= XGetImage( pXDisp
, aDrawable
, nX
, nY
, nWidth
, nHeight
, AllPlanes
, ZPixmap
);
216 bool bWasError
= pXLib
->HasXErrorOccured() && pXLib
->GetLastXErrorRequestCode() == X_GetImage
;
217 pXLib
->PopXErrorLevel();
219 if( ! bWasError
&& pImage
&& pImage
->data
)
221 const SalTwoRect aTwoRect
= { 0, 0, nWidth
, nHeight
, 0, 0, nWidth
, nHeight
};
222 BitmapBuffer aSrcBuf
;
223 ULONG nDstFormat
= BMP_FORMAT_BOTTOM_UP
;
224 const BitmapPalette
* pDstPal
= NULL
;
226 aSrcBuf
.mnFormat
= BMP_FORMAT_TOP_DOWN
;
227 aSrcBuf
.mnWidth
= nWidth
;
228 aSrcBuf
.mnHeight
= nHeight
;
229 aSrcBuf
.mnBitCount
= pImage
->bits_per_pixel
;
230 aSrcBuf
.mnScanlineSize
= pImage
->bytes_per_line
;
231 aSrcBuf
.mpBits
= (BYTE
*) pImage
->data
;
233 pImage
->red_mask
= pSalDisp
->GetVisual( nScreen
).red_mask
;
234 pImage
->green_mask
= pSalDisp
->GetVisual( nScreen
).green_mask
;
235 pImage
->blue_mask
= pSalDisp
->GetVisual( nScreen
).blue_mask
;
237 switch( aSrcBuf
.mnBitCount
)
241 aSrcBuf
.mnFormat
|= ( LSBFirst
== pImage
->bitmap_bit_order
? BMP_FORMAT_1BIT_LSB_PAL
: BMP_FORMAT_1BIT_MSB_PAL
);
242 nDstFormat
|= BMP_FORMAT_1BIT_MSB_PAL
;
248 aSrcBuf
.mnFormat
|= ( LSBFirst
== pImage
->bitmap_bit_order
? BMP_FORMAT_4BIT_LSN_PAL
: BMP_FORMAT_4BIT_MSN_PAL
);
249 nDstFormat
|= BMP_FORMAT_4BIT_MSN_PAL
;
255 aSrcBuf
.mnFormat
|= BMP_FORMAT_8BIT_PAL
;
256 nDstFormat
|= BMP_FORMAT_8BIT_PAL
;
262 nDstFormat
|= BMP_FORMAT_24BIT_TC_BGR
;
263 aSrcBuf
.maColorMask
= ColorMask( pImage
->red_mask
, pImage
->green_mask
, pImage
->blue_mask
);
265 if( LSBFirst
== pImage
->byte_order
)
267 aSrcBuf
.mnFormat
|= BMP_FORMAT_16BIT_TC_LSB_MASK
;
271 aSrcBuf
.mnFormat
|= BMP_FORMAT_16BIT_TC_MSB_MASK
;
272 // aSrcBuf.maColorMask = ColorMask( pImage->red_mask ), SWAPSHORT( pImage->green_mask ), SWAPSHORT( pImage->blue_mask ) );
279 if( ( LSBFirst
== pImage
->byte_order
) && ( pImage
->red_mask
== 0xFF ) )
280 aSrcBuf
.mnFormat
|= BMP_FORMAT_24BIT_TC_RGB
;
282 aSrcBuf
.mnFormat
|= BMP_FORMAT_24BIT_TC_BGR
;
284 nDstFormat
|= BMP_FORMAT_24BIT_TC_BGR
;
290 if( LSBFirst
== pImage
->byte_order
)
291 aSrcBuf
.mnFormat
|= ( pSalDisp
->GetVisual(nScreen
).red_mask
== 0xFF ? BMP_FORMAT_32BIT_TC_RGBA
: BMP_FORMAT_32BIT_TC_BGRA
);
293 aSrcBuf
.mnFormat
|= ( pSalDisp
->GetVisual(nScreen
).red_mask
== 0xFF ? BMP_FORMAT_32BIT_TC_ABGR
: BMP_FORMAT_32BIT_TC_ARGB
);
295 nDstFormat
|= BMP_FORMAT_24BIT_TC_BGR
;
300 BitmapPalette
& rPal
= aSrcBuf
.maPalette
;
302 if( aSrcBuf
.mnBitCount
== 1 )
304 rPal
.SetEntryCount( 2 );
307 rPal
[ 0 ] = Color( COL_BLACK
);
308 rPal
[ 1 ] = Color( COL_WHITE
);
310 else if( pImage
->depth
== 8 && bGrey
)
312 rPal
.SetEntryCount( 256 );
315 for( USHORT i
= 0; i
< 256; i
++ )
317 BitmapColor
& rBmpCol
= rPal
[ i
];
320 rBmpCol
.SetGreen( i
);
321 rBmpCol
.SetBlue( i
);
325 else if( aSrcBuf
.mnBitCount
<= 8 )
327 const SalColormap
& rColMap
= pSalDisp
->GetColormap( nScreen
);
328 const USHORT nCols
= Min( (ULONG
)rColMap
.GetUsed(), (ULONG
)(1 << nDrawableDepth
) );
330 rPal
.SetEntryCount( nCols
);
333 for( USHORT i
= 0; i
< nCols
; i
++ )
335 const SalColor
nColor( rColMap
.GetColor( i
) );
336 BitmapColor
& rBmpCol
= rPal
[ i
];
338 rBmpCol
.SetRed( SALCOLOR_RED( nColor
) );
339 rBmpCol
.SetGreen( SALCOLOR_GREEN( nColor
) );
340 rBmpCol
.SetBlue( SALCOLOR_BLUE( nColor
) );
344 nDstFormat
= aSrcBuf
.mnFormat
;
345 pDIB
= StretchAndConvert( aSrcBuf
, aTwoRect
, nDstFormat
,
346 const_cast<BitmapPalette
*>(pDstPal
), &aSrcBuf
.maColorMask
);
347 XDestroyImage( pImage
);
354 // -----------------------------------------------------------------------------
356 XImage
* X11SalBitmap::ImplCreateXImage( SalDisplay
*pSalDisp
, int nScreen
, long nDepth
, const SalTwoRect
& rTwoRect
) const
358 XImage
* pImage
= NULL
;
360 if( !mpDIB
&& mpDDB
)
362 const_cast<X11SalBitmap
*>(this)->mpDIB
=
363 ImplCreateDIB( mpDDB
->ImplGetPixmap(),
364 mpDDB
->ImplGetScreen(),
365 mpDDB
->ImplGetDepth(),
367 mpDDB
->ImplGetWidth(),
368 mpDDB
->ImplGetHeight(),
372 if( mpDIB
&& mpDIB
->mnWidth
&& mpDIB
->mnHeight
)
374 Display
* pXDisp
= pSalDisp
->GetDisplay();
375 long nWidth
= rTwoRect
.mnDestWidth
;
376 long nHeight
= rTwoRect
.mnDestHeight
;
378 if( 1 == GetBitCount() )
381 pImage
= XCreateImage( pXDisp
, pSalDisp
->GetVisual( nScreen
).GetVisual(),
382 nDepth
, ( 1 == nDepth
) ? XYBitmap
:ZPixmap
, 0, NULL
,
383 nWidth
, nHeight
, 32, 0 );
387 BitmapBuffer
* pDstBuf
;
388 ULONG nDstFormat
= BMP_FORMAT_TOP_DOWN
;
389 BitmapPalette
* pPal
= NULL
;
390 ColorMask
* pMask
= NULL
;
392 switch( pImage
->bits_per_pixel
)
395 nDstFormat
|= ( LSBFirst
== pImage
->bitmap_bit_order
? BMP_FORMAT_1BIT_LSB_PAL
: BMP_FORMAT_1BIT_MSB_PAL
);
399 nDstFormat
|= ( LSBFirst
== pImage
->bitmap_bit_order
? BMP_FORMAT_4BIT_LSN_PAL
: BMP_FORMAT_4BIT_MSN_PAL
);
403 nDstFormat
|= BMP_FORMAT_8BIT_PAL
;
410 if( MSBFirst
== pImage
->byte_order
)
411 nDstFormat
|= BMP_FORMAT_16BIT_TC_MSB_MASK
;
413 nDstFormat
|= BMP_FORMAT_16BIT_TC_LSB_MASK
;
415 #else /* OSL_LITENDIAN */
417 nDstFormat
|= BMP_FORMAT_16BIT_TC_LSB_MASK
;
418 if( MSBFirst
== pImage
->byte_order
)
419 pImage
->byte_order
= LSBFirst
;
423 pMask
= new ColorMask( pImage
->red_mask
, pImage
->green_mask
, pImage
->blue_mask
);
429 if( ( LSBFirst
== pImage
->byte_order
) && ( pImage
->red_mask
== 0xFF ) )
430 nDstFormat
|= BMP_FORMAT_24BIT_TC_RGB
;
432 nDstFormat
|= BMP_FORMAT_24BIT_TC_BGR
;
438 if( LSBFirst
== pImage
->byte_order
)
439 nDstFormat
|= ( pImage
->red_mask
== 0xFF ? BMP_FORMAT_32BIT_TC_RGBA
: BMP_FORMAT_32BIT_TC_BGRA
);
441 nDstFormat
|= ( pImage
->red_mask
== 0xFF ? BMP_FORMAT_32BIT_TC_ABGR
: BMP_FORMAT_32BIT_TC_ARGB
);
446 if( pImage
->depth
== 1 )
448 pPal
= new BitmapPalette( 2 );
449 (*pPal
)[ 0 ] = Color( COL_BLACK
);
450 (*pPal
)[ 1 ] = Color( COL_WHITE
);
452 else if( pImage
->depth
== 8 && mbGrey
)
454 pPal
= new BitmapPalette( 256 );
456 for( USHORT i
= 0; i
< 256; i
++ )
458 BitmapColor
& rBmpCol
= (*pPal
)[ i
];
461 rBmpCol
.SetGreen( i
);
462 rBmpCol
.SetBlue( i
);
466 else if( pImage
->depth
<= 8 )
468 const SalColormap
& rColMap
= pSalDisp
->GetColormap( nScreen
);
469 const USHORT nCols
= Min( (ULONG
)rColMap
.GetUsed(), (ULONG
)(1 << pImage
->depth
) );
471 pPal
= new BitmapPalette( nCols
);
473 for( USHORT i
= 0; i
< nCols
; i
++ )
475 const SalColor
nColor( rColMap
.GetColor( i
) );
476 BitmapColor
& rBmpCol
= (*pPal
)[ i
];
478 rBmpCol
.SetRed( SALCOLOR_RED( nColor
) );
479 rBmpCol
.SetGreen( SALCOLOR_GREEN( nColor
) );
480 rBmpCol
.SetBlue( SALCOLOR_BLUE( nColor
) );
484 pDstBuf
= StretchAndConvert( *mpDIB
, rTwoRect
, nDstFormat
, pPal
, pMask
);
488 if( pDstBuf
&& pDstBuf
->mpBits
)
490 // set data in buffer as data member in pImage
491 pImage
->data
= (char*) pDstBuf
->mpBits
;
493 // destroy buffer; don't destroy allocated data in buffer
498 XDestroyImage( pImage
);
507 // -----------------------------------------------------------------------------
508 bool X11SalBitmap::ImplCreateFromDrawable( Drawable aDrawable
,
509 int nScreen
, long nDrawableDepth
,
510 long nX
, long nY
, long nWidth
, long nHeight
)
514 if( aDrawable
&& nWidth
&& nHeight
&& nDrawableDepth
)
515 mpDDB
= new ImplSalDDB( aDrawable
, nScreen
, nDrawableDepth
, nX
, nY
, nWidth
, nHeight
);
517 return( mpDDB
!= NULL
);
519 // -----------------------------------------------------------------------------
522 X11SalBitmap::SnapShot (Display
* pDisplay
, XLIB_Window hWindow
)
526 XWindowAttributes aAttribute
;
527 XGetWindowAttributes (pDisplay
, hWindow
, &aAttribute
);
528 if (aAttribute
.map_state
== IsViewable
)
530 // get coordinates relative to root window
531 XLIB_Window hPetitFleur
;
534 if (XTranslateCoordinates (pDisplay
, hWindow
, aAttribute
.root
,
535 0, 0, &nRootX
, &nRootY
, &hPetitFleur
))
537 XWindowAttributes aRootAttribute
;
538 XGetWindowAttributes (pDisplay
, aAttribute
.root
, &aRootAttribute
);
540 int width
= aAttribute
.width
;
541 int height
= aAttribute
.height
;
545 // horizontal range check
552 if (x
> aRootAttribute
.width
)
555 x
= aRootAttribute
.width
;
558 if (x
+ width
> aRootAttribute
.width
)
560 width
= aRootAttribute
.width
- x
;
563 // vertical range check
570 if (y
> aRootAttribute
.height
)
573 y
= aRootAttribute
.height
;
576 if (y
+ height
> aRootAttribute
.height
)
578 height
= aRootAttribute
.height
- y
;
581 if ((width
> 0) && (height
> 0))
583 XImage
* pImage
= XGetImage( pDisplay
, aAttribute
.root
,
584 x
, y
, width
, height
, AllPlanes
, ZPixmap
);
585 bool bSnapShot
= ImplCreateFromXImage( pDisplay
,
587 XScreenNumberOfScreen( aAttribute
.screen
),
589 XDestroyImage (pImage
);
601 X11SalBitmap::ImplCreateFromXImage (Display
* pDisplay
, XLIB_Window hWindow
, int nScreen
, XImage
* pImage
)
605 if (pImage
!= NULL
&& pImage
->width
!= 0 && pImage
->height
!= 0 && pImage
->depth
!= 0)
607 mpDDB
= new ImplSalDDB (pDisplay
, hWindow
, nScreen
, pImage
);
613 ImplSalDDB
* X11SalBitmap::ImplGetDDB( Drawable aDrawable
,
616 const SalTwoRect
& rTwoRect
) const
618 if( !mpDDB
|| !mpDDB
->ImplMatches( nScreen
, nDrawableDepth
, rTwoRect
) )
622 // do we already have a DIB? if not, create aDIB from current DDB first
625 const_cast<X11SalBitmap
*>(this)->mpDIB
= ImplCreateDIB( mpDDB
->ImplGetPixmap(),
626 mpDDB
->ImplGetScreen(),
627 mpDDB
->ImplGetDepth(),
629 mpDDB
->ImplGetWidth(),
630 mpDDB
->ImplGetHeight(),
634 delete mpDDB
, const_cast<X11SalBitmap
*>(this)->mpDDB
= NULL
;
638 mpCache
->ImplRemove( const_cast<X11SalBitmap
*>(this) );
640 SalTwoRect
aTwoRect( rTwoRect
);
641 if( aTwoRect
.mnSrcX
< 0 )
643 aTwoRect
.mnSrcWidth
+= aTwoRect
.mnSrcX
;
646 if( aTwoRect
.mnSrcY
< 0 )
648 aTwoRect
.mnSrcHeight
+= aTwoRect
.mnSrcY
;
652 // create new DDB from DIB
653 const Size
aSize( GetSize() );
654 if( aTwoRect
.mnSrcWidth
== aTwoRect
.mnDestWidth
&&
655 aTwoRect
.mnSrcHeight
== aTwoRect
.mnDestHeight
)
657 aTwoRect
.mnSrcX
= aTwoRect
.mnSrcY
= aTwoRect
.mnDestX
= aTwoRect
.mnDestY
= 0;
658 aTwoRect
.mnSrcWidth
= aTwoRect
.mnDestWidth
= aSize
.Width();
659 aTwoRect
.mnSrcHeight
= aTwoRect
.mnDestHeight
= aSize
.Height();
661 else if( aTwoRect
.mnSrcWidth
+aTwoRect
.mnSrcX
> aSize
.Width() ||
662 aTwoRect
.mnSrcHeight
+aTwoRect
.mnSrcY
> aSize
.Height() )
664 // #i47823# this should not happen at all, but does nonetheless
665 // because BitmapEx allows for mask bitmaps of different size
666 // than image bitmap (broken)
667 if( aTwoRect
.mnSrcX
>= aSize
.Width() ||
668 aTwoRect
.mnSrcY
>= aSize
.Height() )
669 return NULL
; // this would be a really mad case
671 if( aTwoRect
.mnSrcWidth
+aTwoRect
.mnSrcX
> aSize
.Width() )
673 aTwoRect
.mnSrcWidth
= aSize
.Width()-aTwoRect
.mnSrcX
;
674 if( aTwoRect
.mnSrcWidth
< 1 )
677 aTwoRect
.mnSrcWidth
= aSize
.Width();
680 if( aTwoRect
.mnSrcHeight
+aTwoRect
.mnSrcY
> aSize
.Height() )
682 aTwoRect
.mnSrcHeight
= aSize
.Height() - aTwoRect
.mnSrcY
;
683 if( aTwoRect
.mnSrcHeight
< 1 )
686 aTwoRect
.mnSrcHeight
= aSize
.Height();
691 XImage
* pImage
= ImplCreateXImage( GetX11SalData()->GetDisplay(), nScreen
,
692 nDrawableDepth
, aTwoRect
);
696 const_cast<X11SalBitmap
*>(this)->mpDDB
= new ImplSalDDB( pImage
, aDrawable
, nScreen
, aTwoRect
);
697 delete[] pImage
->data
, pImage
->data
= NULL
;
698 XDestroyImage( pImage
);
701 mpCache
->ImplAdd( const_cast<X11SalBitmap
*>(this), mpDDB
->ImplGetMemSize() );
708 // -----------------------------------------------------------------------------
710 void X11SalBitmap::ImplDraw( Drawable aDrawable
,
713 const SalTwoRect
& rTwoRect
,
714 const GC
& rGC
) const
716 ImplGetDDB( aDrawable
, nScreen
, nDrawableDepth
, rTwoRect
);
718 mpDDB
->ImplDraw( aDrawable
, nDrawableDepth
, rTwoRect
, rGC
);
721 // -----------------------------------------------------------------------------
723 bool X11SalBitmap::Create( const Size
& rSize
, USHORT nBitCount
, const BitmapPalette
& rPal
)
726 mpDIB
= ImplCreateDIB( rSize
, nBitCount
, rPal
);
728 return( mpDIB
!= NULL
);
731 // -----------------------------------------------------------------------------
733 bool X11SalBitmap::Create( const SalBitmap
& rSSalBmp
)
737 const X11SalBitmap
& rSalBmp
= static_cast<const X11SalBitmap
&>( rSSalBmp
);
741 // TODO: reference counting...
742 mpDIB
= new BitmapBuffer( *rSalBmp
.mpDIB
);
743 // TODO: get rid of this when BitmapBuffer gets copy constructor
746 mpDIB
->mpBits
= new BYTE
[ mpDIB
->mnScanlineSize
* mpDIB
->mnHeight
];
748 catch( std::bad_alloc
& )
755 memcpy( mpDIB
->mpBits
, rSalBmp
.mpDIB
->mpBits
, mpDIB
->mnScanlineSize
* mpDIB
->mnHeight
);
757 else if( rSalBmp
.mpDDB
)
758 ImplCreateFromDrawable( rSalBmp
.mpDDB
->ImplGetPixmap(),
759 rSalBmp
.mpDDB
->ImplGetScreen(),
760 rSalBmp
.mpDDB
->ImplGetDepth(),
761 0, 0, rSalBmp
.mpDDB
->ImplGetWidth(), rSalBmp
.mpDDB
->ImplGetHeight() );
763 return( ( !rSalBmp
.mpDIB
&& !rSalBmp
.mpDDB
) ||
764 ( rSalBmp
.mpDIB
&& ( mpDIB
!= NULL
) ) ||
765 ( rSalBmp
.mpDDB
&& ( mpDDB
!= NULL
) ) );
768 // -----------------------------------------------------------------------------
770 bool X11SalBitmap::Create( const SalBitmap
&, SalGraphics
* )
775 // -----------------------------------------------------------------------------
777 bool X11SalBitmap::Create( const SalBitmap
&, USHORT
)
782 // -----------------------------------------------------------------------------
784 bool X11SalBitmap::Create( const ::com::sun::star::uno::Reference
< ::com::sun::star::rendering::XBitmapCanvas
> xBitmapCanvas
, Size
& rSize
, bool bMask
)
786 ::com::sun::star::uno::Reference
< ::com::sun::star::beans::XFastPropertySet
> xFastPropertySet( xBitmapCanvas
, ::com::sun::star::uno::UNO_QUERY
);
787 if( xFastPropertySet
.get() ) {
790 ::com::sun::star::uno::Sequence
< ::com::sun::star::uno::Any
> args
;
792 if( xFastPropertySet
->getFastPropertyValue(bMask
? 2 : 1) >>= args
) {
793 if( ( args
[1] >>= pixmapHandle
) && ( args
[2] >>= depth
) ) {
796 bool bSuccess
= ImplCreateFromDrawable( pixmapHandle
, 0, depth
, 0, 0, (long) rSize
.Width(), (long) rSize
.Height() );
798 if( bSuccess
&& (args
[0] >>= bFreePixmap
) && bFreePixmap
)
799 XFreePixmap( GetX11SalData()->GetDisplay()->GetDisplay(), pixmapHandle
);
809 // -----------------------------------------------------------------------------
811 void X11SalBitmap::Destroy()
815 delete[] mpDIB
->mpBits
;
816 delete mpDIB
, mpDIB
= NULL
;
820 delete mpDDB
, mpDDB
= NULL
;
823 mpCache
->ImplRemove( this );
826 // -----------------------------------------------------------------------------
828 Size
X11SalBitmap::GetSize() const
833 aSize
.Width() = mpDIB
->mnWidth
, aSize
.Height() = mpDIB
->mnHeight
;
835 aSize
.Width() = mpDDB
->ImplGetWidth(), aSize
.Height() = mpDDB
->ImplGetHeight();
840 // -----------------------------------------------------------------------------
842 USHORT
X11SalBitmap::GetBitCount() const
847 nBitCount
= mpDIB
->mnBitCount
;
849 nBitCount
= mpDDB
->ImplGetDepth();
856 // -----------------------------------------------------------------------------
858 BitmapBuffer
* X11SalBitmap::AcquireBuffer( bool )
860 if( !mpDIB
&& mpDDB
)
862 mpDIB
= ImplCreateDIB( mpDDB
->ImplGetPixmap(),
863 mpDDB
->ImplGetScreen(),
864 mpDDB
->ImplGetDepth(),
865 0, 0, mpDDB
->ImplGetWidth(), mpDDB
->ImplGetHeight(), mbGrey
);
871 // -----------------------------------------------------------------------------
873 void X11SalBitmap::ReleaseBuffer( BitmapBuffer
*, bool bReadOnly
)
878 delete mpDDB
, mpDDB
= NULL
;
881 mpCache
->ImplRemove( this );
885 // -----------------------------------------------------------------------------
887 bool X11SalBitmap::GetSystemData( BitmapSystemData
& rData
)
891 // Rename/retype pDummy to your likings (though X11 Pixmap is
892 // prolly not a good idea, since it's accessed from
893 // non-platform aware code in vcl/bitmap.hxx)
894 rData
.aPixmap
= (void*)mpDDB
->ImplGetPixmap();
895 rData
.mnWidth
= mpDDB
->ImplGetWidth ();
896 rData
.mnHeight
= mpDDB
->ImplGetHeight ();
907 ImplSalDDB::ImplSalDDB( XImage
* pImage
, Drawable aDrawable
, int nScreen
, const SalTwoRect
& rTwoRect
) :
909 maTwoRect ( rTwoRect
),
910 mnDepth ( pImage
->depth
),
913 SalDisplay
* pSalDisp
= GetX11SalData()->GetDisplay();
914 Display
* pXDisp
= pSalDisp
->GetDisplay();
916 if( (maPixmap
= XCreatePixmap( pXDisp
, aDrawable
, ImplGetWidth(), ImplGetHeight(), ImplGetDepth() )) )
920 int nValues
= GCFunction
;
922 aValues
.function
= GXcopy
;
926 nValues
|= ( GCForeground
| GCBackground
);
927 aValues
.foreground
= 1, aValues
.background
= 0;
930 aGC
= XCreateGC( pXDisp
, maPixmap
, nValues
, &aValues
);
931 XPutImage( pXDisp
, maPixmap
, aGC
, pImage
, 0, 0, 0, 0, maTwoRect
.mnDestWidth
, maTwoRect
.mnDestHeight
);
932 XFreeGC( pXDisp
, aGC
);
936 // -----------------------------------------------------------------------------------------
937 // create from XImage
939 ImplSalDDB::ImplSalDDB (Display
* pDisplay
, XLIB_Window hWindow
, int nScreen
, XImage
* pImage
) :
942 maPixmap
= XCreatePixmap (pDisplay
, hWindow
, pImage
->width
, pImage
->height
, pImage
->depth
);
947 int nValues
= GCFunction
;
949 aValues
.function
= GXcopy
;
951 if (pImage
->depth
== 1)
953 nValues
|= ( GCForeground
| GCBackground
);
954 aValues
.foreground
= 1;
955 aValues
.background
= 0;
958 aGC
= XCreateGC (pDisplay
, maPixmap
, nValues
, &aValues
);
959 XPutImage (pDisplay
, maPixmap
, aGC
, pImage
, 0, 0, 0, 0, pImage
->width
, pImage
->height
);
960 XFreeGC (pDisplay
, aGC
);
962 maTwoRect
.mnSrcX
= 0;
963 maTwoRect
.mnSrcY
= 0;
964 maTwoRect
.mnDestX
= 0;
965 maTwoRect
.mnDestY
= 0;
966 maTwoRect
.mnSrcWidth
= pImage
->width
;
967 maTwoRect
.mnDestWidth
= pImage
->width
;
968 maTwoRect
.mnSrcHeight
= pImage
->height
;
969 maTwoRect
.mnDestHeight
= pImage
->height
;
971 mnDepth
= pImage
->depth
;
975 // -----------------------------------------------------------------------------
977 ImplSalDDB::ImplSalDDB( Drawable aDrawable
, int nScreen
, long nDrawableDepth
, long nX
, long nY
, long nWidth
, long nHeight
) :
978 mnDepth( nDrawableDepth
),
981 SalDisplay
* pSalDisp
= GetX11SalData()->GetDisplay();
982 Display
* pXDisp
= pSalDisp
->GetDisplay();
984 if( (maPixmap
= XCreatePixmap( pXDisp
, aDrawable
, nWidth
, nHeight
, nDrawableDepth
)) )
988 int nValues
= GCFunction
;
990 aValues
.function
= GXcopy
;
994 nValues
|= ( GCForeground
| GCBackground
);
995 aValues
.foreground
= 1, aValues
.background
= 0;
998 aGC
= XCreateGC( pXDisp
, maPixmap
, nValues
, &aValues
);
999 ImplDraw( aDrawable
, nDrawableDepth
, maPixmap
, mnDepth
,
1000 nX
, nY
, nWidth
, nHeight
, 0, 0, aGC
);
1001 XFreeGC( pXDisp
, aGC
);
1003 maTwoRect
.mnSrcX
= maTwoRect
.mnSrcY
= maTwoRect
.mnDestX
= maTwoRect
.mnDestY
= 0;
1004 maTwoRect
.mnSrcWidth
= maTwoRect
.mnDestWidth
= nWidth
;
1005 maTwoRect
.mnSrcHeight
= maTwoRect
.mnDestHeight
= nHeight
;
1009 // -----------------------------------------------------------------------------
1011 ImplSalDDB::~ImplSalDDB()
1013 if( maPixmap
&& ImplGetSVData() )
1014 XFreePixmap( GetX11SalData()->GetDisplay()->GetDisplay(), maPixmap
);
1017 // -----------------------------------------------------------------------------
1019 bool ImplSalDDB::ImplMatches( int nScreen
, long nDepth
, const SalTwoRect
& rTwoRect
) const
1023 if( ( maPixmap
!= 0 ) && ( ( mnDepth
== nDepth
) || ( 1 == mnDepth
) ) && nScreen
== mnScreen
)
1025 if( rTwoRect
.mnSrcX
== maTwoRect
.mnSrcX
&& rTwoRect
.mnSrcY
== maTwoRect
.mnSrcY
&&
1026 rTwoRect
.mnSrcWidth
== maTwoRect
.mnSrcWidth
&& rTwoRect
.mnSrcHeight
== maTwoRect
.mnSrcHeight
&&
1027 rTwoRect
.mnDestWidth
== maTwoRect
.mnDestWidth
&& rTwoRect
.mnDestHeight
== maTwoRect
.mnDestHeight
)
1029 // absolutely indentically
1032 else if( rTwoRect
.mnSrcWidth
== rTwoRect
.mnDestWidth
&& rTwoRect
.mnSrcHeight
== rTwoRect
.mnDestHeight
&&
1033 maTwoRect
.mnSrcWidth
== maTwoRect
.mnDestWidth
&& maTwoRect
.mnSrcHeight
== maTwoRect
.mnDestHeight
&&
1034 rTwoRect
.mnSrcX
>= maTwoRect
.mnSrcX
&& rTwoRect
.mnSrcY
>= maTwoRect
.mnSrcY
&&
1035 ( rTwoRect
.mnSrcX
+ rTwoRect
.mnSrcWidth
) <= ( maTwoRect
.mnSrcX
+ maTwoRect
.mnSrcWidth
) &&
1036 ( rTwoRect
.mnSrcY
+ rTwoRect
.mnSrcHeight
) <= ( maTwoRect
.mnSrcY
+ maTwoRect
.mnSrcHeight
) )
1045 // -----------------------------------------------------------------------------
1047 void ImplSalDDB::ImplDraw( Drawable aDrawable
, long nDrawableDepth
, const SalTwoRect
& rTwoRect
, const GC
& rGC
) const
1049 ImplDraw( maPixmap
, mnDepth
, aDrawable
, nDrawableDepth
,
1050 rTwoRect
.mnSrcX
- maTwoRect
.mnSrcX
, rTwoRect
.mnSrcY
- maTwoRect
.mnSrcY
,
1051 rTwoRect
.mnDestWidth
, rTwoRect
.mnDestHeight
,
1052 rTwoRect
.mnDestX
, rTwoRect
.mnDestY
, rGC
);
1055 // -----------------------------------------------------------------------------
1057 void ImplSalDDB::ImplDraw( Drawable aSrcDrawable
, long nSrcDrawableDepth
,
1058 Drawable aDstDrawable
, long,
1059 long nSrcX
, long nSrcY
,
1060 long nDestWidth
, long nDestHeight
,
1061 long nDestX
, long nDestY
, const GC
& rGC
)
1063 SalDisplay
* pSalDisp
= GetX11SalData()->GetDisplay();
1064 Display
* pXDisp
= pSalDisp
->GetDisplay();
1066 if( 1 == nSrcDrawableDepth
)
1068 XCopyPlane( pXDisp
, aSrcDrawable
, aDstDrawable
, rGC
,
1069 nSrcX
, nSrcY
, nDestWidth
, nDestHeight
, nDestX
, nDestY
, 1 );
1073 XCopyArea( pXDisp
, aSrcDrawable
, aDstDrawable
, rGC
,
1074 nSrcX
, nSrcY
, nDestWidth
, nDestHeight
, nDestX
, nDestY
);
1078 // ----------------------
1079 // - ImplSalBitmapCache -
1080 // ----------------------
1084 X11SalBitmap
* mpBmp
;
1088 ImplBmpObj( X11SalBitmap
* pBmp
, ULONG nMemSize
, ULONG nFlags
) :
1089 mpBmp( pBmp
), mnMemSize( nMemSize
), mnFlags( nFlags
) {}
1092 // -----------------------------------------------------------------------------
1094 ImplSalBitmapCache::ImplSalBitmapCache() :
1099 // -----------------------------------------------------------------------------
1101 ImplSalBitmapCache::~ImplSalBitmapCache()
1106 // -----------------------------------------------------------------------------
1108 void ImplSalBitmapCache::ImplAdd( X11SalBitmap
* pBmp
, ULONG nMemSize
, ULONG nFlags
)
1111 bool bFound
= FALSE
;
1113 for( pObj
= (ImplBmpObj
*) maBmpList
.Last(); pObj
&& !bFound
; pObj
= (ImplBmpObj
*) maBmpList
.Prev() )
1114 if( pObj
->mpBmp
== pBmp
)
1117 mnTotalSize
+= nMemSize
;
1121 mnTotalSize
-= pObj
->mnMemSize
;
1122 pObj
->mnMemSize
= nMemSize
, pObj
->mnFlags
= nFlags
;
1125 maBmpList
.Insert( new ImplBmpObj( pBmp
, nMemSize
, nFlags
), LIST_APPEND
);
1128 // -----------------------------------------------------------------------------
1130 void ImplSalBitmapCache::ImplRemove( X11SalBitmap
* pBmp
)
1132 for( ImplBmpObj
* pObj
= (ImplBmpObj
*) maBmpList
.Last(); pObj
; pObj
= (ImplBmpObj
*) maBmpList
.Prev() )
1134 if( pObj
->mpBmp
== pBmp
)
1136 maBmpList
.Remove( pObj
);
1137 pObj
->mpBmp
->ImplRemovedFromCache();
1138 mnTotalSize
-= pObj
->mnMemSize
;
1145 // -----------------------------------------------------------------------------
1147 void ImplSalBitmapCache::ImplClear()
1149 for( ImplBmpObj
* pObj
= (ImplBmpObj
*) maBmpList
.First(); pObj
; pObj
= (ImplBmpObj
*) maBmpList
.Next() )
1151 pObj
->mpBmp
->ImplRemovedFromCache();