office-gobmx/vcl/unx/generic/gdi/salbmp.cxx
Marcos Paulo de Souza 0f200cc30e fdo#63154: Change Min/Max/Abs for std::min/max/abs
Now all these usages were removed from LO.

Change-Id: I8a7233db20abdcdbb18428ad4004c78cc516a0e6
Reviewed-on: https://gerrit.libreoffice.org/3326
Reviewed-by: David Tardon <dtardon@redhat.com>
Tested-by: David Tardon <dtardon@redhat.com>
2013-04-20 11:09:54 +00:00

1167 lines
36 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#include <string.h>
#include <stdio.h>
#include <errno.h>
#ifdef FREEBSD
#include <sys/types.h>
#endif
#include <prex.h>
#include <X11/Xproto.h>
#include <postx.h>
#include <osl/endian.h>
#include <vcl/bitmap.hxx>
#include <vcl/salbtype.hxx>
#include <com/sun/star/beans/XFastPropertySet.hpp>
#include <unx/salunx.h>
#include <unx/saldata.hxx>
#include <unx/saldisp.hxx>
#include <unx/salgdi.h>
#include <unx/salbmp.h>
#include <unx/salinst.h>
#include <unx/x11/xlimits.hxx>
#include "xrender_peer.hxx"
#if defined HAVE_VALGRIND_HEADERS
#include <valgrind/memcheck.h>
#endif
// -------------
// - SalBitmap -
// -------------
SalBitmap* X11SalInstance::CreateSalBitmap()
{
return new X11SalBitmap();
}
ImplSalBitmapCache* X11SalBitmap::mpCache = NULL;
sal_uLong X11SalBitmap::mnCacheInstCount = 0;
// -----------------------------------------------------------------------------
X11SalBitmap::X11SalBitmap()
: mpDIB( NULL )
, mpDDB( NULL )
, mbGrey( false )
, mbHasAlpha( false )
{
}
// -----------------------------------------------------------------------------
X11SalBitmap::~X11SalBitmap()
{
Destroy();
}
// -----------------------------------------------------------------------------
void X11SalBitmap::ImplCreateCache()
{
if( !mnCacheInstCount++ )
mpCache = new ImplSalBitmapCache;
}
// -----------------------------------------------------------------------------
void X11SalBitmap::ImplDestroyCache()
{
DBG_ASSERT( mnCacheInstCount, "X11SalBitmap::ImplDestroyCache(): underflow" );
if( mnCacheInstCount && !--mnCacheInstCount )
delete mpCache, mpCache = NULL;
}
// -----------------------------------------------------------------------------
void X11SalBitmap::ImplRemovedFromCache()
{
if( mpDDB )
delete mpDDB, mpDDB = NULL;
}
#if defined HAVE_VALGRIND_HEADERS
namespace
{
void blankExtraSpace(BitmapBuffer* pDIB)
{
size_t nExtraSpaceInScanLine = pDIB->mnScanlineSize - pDIB->mnWidth * pDIB->mnBitCount / 8;
if (nExtraSpaceInScanLine)
{
for (long i = 0; i < pDIB->mnHeight; ++i)
{
sal_uInt8 *pRow = pDIB->mpBits + (i * pDIB->mnScanlineSize);
memset(pRow + (pDIB->mnScanlineSize - nExtraSpaceInScanLine), 0, nExtraSpaceInScanLine);
}
}
}
}
#endif
// -----------------------------------------------------------------------------
BitmapBuffer* X11SalBitmap::ImplCreateDIB(
const Size& rSize,
sal_uInt16 nBitCount,
const BitmapPalette& rPal
) {
DBG_ASSERT(
nBitCount == 1
|| nBitCount == 4
|| nBitCount == 8
|| nBitCount == 16
|| nBitCount == 24
, "Unsupported BitCount!"
);
BitmapBuffer* pDIB = NULL;
if( rSize.Width() && rSize.Height() )
{
try
{
pDIB = new BitmapBuffer;
}
catch (const std::bad_alloc&)
{
pDIB = NULL;
}
if( pDIB )
{
const sal_uInt16 nColors = ( nBitCount <= 8 ) ? ( 1 << nBitCount ) : 0;
pDIB->mnFormat = BMP_FORMAT_BOTTOM_UP;
switch( nBitCount )
{
case( 1 ): pDIB->mnFormat |= BMP_FORMAT_1BIT_MSB_PAL; break;
case( 4 ): pDIB->mnFormat |= BMP_FORMAT_4BIT_MSN_PAL; break;
case( 8 ): pDIB->mnFormat |= BMP_FORMAT_8BIT_PAL; break;
#ifdef OSL_BIGENDIAN
case(16 ):
pDIB->mnFormat|= BMP_FORMAT_16BIT_TC_MSB_MASK;
pDIB->maColorMask = ColorMask( 0xf800, 0x07e0, 0x001f );
break;
#else
case(16 ):
pDIB->mnFormat|= BMP_FORMAT_16BIT_TC_LSB_MASK;
pDIB->maColorMask = ColorMask( 0xf800, 0x07e0, 0x001f );
break;
#endif
default:
nBitCount = 24;
//fall through
case 24:
pDIB->mnFormat |= BMP_FORMAT_24BIT_TC_BGR;
break;
}
pDIB->mnWidth = rSize.Width();
pDIB->mnHeight = rSize.Height();
pDIB->mnScanlineSize = AlignedWidth4Bytes( pDIB->mnWidth * nBitCount );
pDIB->mnBitCount = nBitCount;
if( nColors )
{
pDIB->maPalette = rPal;
pDIB->maPalette.SetEntryCount( nColors );
}
try
{
pDIB->mpBits = new sal_uInt8[ pDIB->mnScanlineSize * pDIB->mnHeight ];
#if defined HAVE_VALGRIND_HEADERS
if (RUNNING_ON_VALGRIND)
blankExtraSpace(pDIB);
#endif
}
catch (const std::bad_alloc&)
{
delete pDIB;
pDIB = NULL;
}
}
}
else
pDIB = NULL;
return pDIB;
}
// -----------------------------------------------------------------------------
BitmapBuffer* X11SalBitmap::ImplCreateDIB(
Drawable aDrawable,
SalX11Screen nScreen,
long nDrawableDepth,
long nX,
long nY,
long nWidth,
long nHeight,
bool bGrey
) {
BitmapBuffer* pDIB = NULL;
if( aDrawable && nWidth && nHeight && nDrawableDepth )
{
SalDisplay* pSalDisp = GetGenericData()->GetSalDisplay();
Display* pXDisp = pSalDisp->GetDisplay();
// do not die on XError here
// alternatively one could check the coordinates for being offscreen
// but this call can actually work on servers with backing store
// defaults even if the rectangle is offscreen
// so better catch the XError
GetGenericData()->ErrorTrapPush();
XImage* pImage = XGetImage( pXDisp, aDrawable, nX, nY, nWidth, nHeight, AllPlanes, ZPixmap );
bool bWasError = GetGenericData()->ErrorTrapPop( false );
if( ! bWasError && pImage && pImage->data )
{
const SalTwoRect aTwoRect = { 0, 0, nWidth, nHeight, 0, 0, nWidth, nHeight };
BitmapBuffer aSrcBuf;
sal_uLong nDstFormat = BMP_FORMAT_BOTTOM_UP;
const BitmapPalette* pDstPal = NULL;
aSrcBuf.mnFormat = BMP_FORMAT_TOP_DOWN;
aSrcBuf.mnWidth = nWidth;
aSrcBuf.mnHeight = nHeight;
aSrcBuf.mnBitCount = pImage->bits_per_pixel;
aSrcBuf.mnScanlineSize = pImage->bytes_per_line;
aSrcBuf.mpBits = (sal_uInt8*) pImage->data;
pImage->red_mask = pSalDisp->GetVisual( nScreen ).red_mask;
pImage->green_mask = pSalDisp->GetVisual( nScreen ).green_mask;
pImage->blue_mask = pSalDisp->GetVisual( nScreen ).blue_mask;
switch( aSrcBuf.mnBitCount )
{
case( 1 ):
{
aSrcBuf.mnFormat |= ( LSBFirst == pImage->bitmap_bit_order
? BMP_FORMAT_1BIT_LSB_PAL
: BMP_FORMAT_1BIT_MSB_PAL
);
nDstFormat |= BMP_FORMAT_1BIT_MSB_PAL;
}
break;
case( 4 ):
{
aSrcBuf.mnFormat |= ( LSBFirst == pImage->bitmap_bit_order
? BMP_FORMAT_4BIT_LSN_PAL
: BMP_FORMAT_4BIT_MSN_PAL
);
nDstFormat |= BMP_FORMAT_4BIT_MSN_PAL;
}
break;
case( 8 ):
{
aSrcBuf.mnFormat |= BMP_FORMAT_8BIT_PAL;
nDstFormat |= BMP_FORMAT_8BIT_PAL;
}
break;
case( 16 ):
{
nDstFormat |= BMP_FORMAT_24BIT_TC_BGR;
aSrcBuf.maColorMask = ColorMask( pImage->red_mask, pImage->green_mask, pImage->blue_mask );
if( LSBFirst == pImage->byte_order )
{
aSrcBuf.mnFormat |= BMP_FORMAT_16BIT_TC_LSB_MASK;
}
else
{
aSrcBuf.mnFormat |= BMP_FORMAT_16BIT_TC_MSB_MASK;
}
}
break;
case( 24 ):
{
if( ( LSBFirst == pImage->byte_order ) && ( pImage->red_mask == 0xFF ) )
aSrcBuf.mnFormat |= BMP_FORMAT_24BIT_TC_RGB;
else
aSrcBuf.mnFormat |= BMP_FORMAT_24BIT_TC_BGR;
nDstFormat |= BMP_FORMAT_24BIT_TC_BGR;
}
break;
case( 32 ):
{
if( LSBFirst == pImage->byte_order )
aSrcBuf.mnFormat |= ( pSalDisp->GetVisual(nScreen).red_mask == 0xFF
? BMP_FORMAT_32BIT_TC_RGBA
: BMP_FORMAT_32BIT_TC_BGRA
);
else
aSrcBuf.mnFormat |= ( pSalDisp->GetVisual(nScreen).red_mask == 0xFF
? BMP_FORMAT_32BIT_TC_ABGR
: BMP_FORMAT_32BIT_TC_ARGB
);
nDstFormat |= BMP_FORMAT_24BIT_TC_BGR;
}
break;
}
BitmapPalette& rPal = aSrcBuf.maPalette;
if( aSrcBuf.mnBitCount == 1 )
{
rPal.SetEntryCount( 2 );
pDstPal = &rPal;
rPal[ 0 ] = Color( COL_BLACK );
rPal[ 1 ] = Color( COL_WHITE );
}
else if( pImage->depth == 8 && bGrey )
{
rPal.SetEntryCount( 256 );
pDstPal = &rPal;
for( sal_uInt16 i = 0; i < 256; i++ )
{
BitmapColor& rBmpCol = rPal[ i ];
rBmpCol.SetRed( i );
rBmpCol.SetGreen( i );
rBmpCol.SetBlue( i );
}
}
else if( aSrcBuf.mnBitCount <= 8 )
{
const SalColormap& rColMap = pSalDisp->GetColormap( nScreen );
const sal_uInt16 nCols = std::min( (sal_uLong)rColMap.GetUsed()
, (sal_uLong)(1 << nDrawableDepth)
);
rPal.SetEntryCount( nCols );
pDstPal = &rPal;
for( sal_uInt16 i = 0; i < nCols; i++ )
{
const SalColor nColor( rColMap.GetColor( i ) );
BitmapColor& rBmpCol = rPal[ i ];
rBmpCol.SetRed( SALCOLOR_RED( nColor ) );
rBmpCol.SetGreen( SALCOLOR_GREEN( nColor ) );
rBmpCol.SetBlue( SALCOLOR_BLUE( nColor ) );
}
}
nDstFormat = aSrcBuf.mnFormat;
pDIB = StretchAndConvert( aSrcBuf, aTwoRect, nDstFormat,
const_cast<BitmapPalette*>(pDstPal), &aSrcBuf.maColorMask );
XDestroyImage( pImage );
}
}
return pDIB;
}
// -----------------------------------------------------------------------------
XImage* X11SalBitmap::ImplCreateXImage(
SalDisplay *pSalDisp,
SalX11Screen nScreen,
long nDepth,
const SalTwoRect& rTwoRect
) const
{
XImage* pImage = NULL;
if( !mpDIB && mpDDB )
{
const_cast<X11SalBitmap*>(this)->mpDIB =
ImplCreateDIB( mpDDB->ImplGetPixmap(),
mpDDB->ImplGetScreen(),
mpDDB->ImplGetDepth(),
0, 0,
mpDDB->ImplGetWidth(),
mpDDB->ImplGetHeight(),
mbGrey );
}
if( mpDIB && mpDIB->mnWidth && mpDIB->mnHeight )
{
Display* pXDisp = pSalDisp->GetDisplay();
long nWidth = rTwoRect.mnDestWidth;
long nHeight = rTwoRect.mnDestHeight;
if( 1 == GetBitCount() )
nDepth = 1;
pImage = XCreateImage( pXDisp, pSalDisp->GetVisual( nScreen ).GetVisual(),
nDepth, ( 1 == nDepth ) ? XYBitmap :ZPixmap, 0, NULL,
nWidth, nHeight, 32, 0 );
if( pImage )
{
BitmapBuffer* pDstBuf;
sal_uLong nDstFormat = BMP_FORMAT_TOP_DOWN;
BitmapPalette* pPal = NULL;
ColorMask* pMask = NULL;
switch( pImage->bits_per_pixel )
{
case( 1 ):
nDstFormat |= ( LSBFirst == pImage->bitmap_bit_order
? BMP_FORMAT_1BIT_LSB_PAL
: BMP_FORMAT_1BIT_MSB_PAL
);
break;
case( 4 ):
nDstFormat |= ( LSBFirst == pImage->bitmap_bit_order
? BMP_FORMAT_4BIT_LSN_PAL
: BMP_FORMAT_4BIT_MSN_PAL
);
break;
case( 8 ):
nDstFormat |= BMP_FORMAT_8BIT_PAL;
break;
case( 16 ):
{
#ifdef OSL_BIGENDIAN
if( MSBFirst == pImage->byte_order )
nDstFormat |= BMP_FORMAT_16BIT_TC_MSB_MASK;
else
nDstFormat |= BMP_FORMAT_16BIT_TC_LSB_MASK;
#else /* OSL_LITENDIAN */
nDstFormat |= BMP_FORMAT_16BIT_TC_LSB_MASK;
if( MSBFirst == pImage->byte_order )
pImage->byte_order = LSBFirst;
#endif
pMask = new ColorMask( pImage->red_mask, pImage->green_mask, pImage->blue_mask );
}
break;
case( 24 ):
{
if( ( LSBFirst == pImage->byte_order ) && ( pImage->red_mask == 0xFF ) )
nDstFormat |= BMP_FORMAT_24BIT_TC_RGB;
else
nDstFormat |= BMP_FORMAT_24BIT_TC_BGR;
}
break;
case( 32 ):
{
if( LSBFirst == pImage->byte_order )
nDstFormat |= ( pImage->red_mask == 0xFF
? BMP_FORMAT_32BIT_TC_RGBA
: BMP_FORMAT_32BIT_TC_BGRA
);
else
nDstFormat |= ( pImage->red_mask == 0xFF
? BMP_FORMAT_32BIT_TC_ABGR
: BMP_FORMAT_32BIT_TC_ARGB
);
}
break;
}
if( pImage->depth == 1 )
{
pPal = new BitmapPalette( 2 );
(*pPal)[ 0 ] = Color( COL_BLACK );
(*pPal)[ 1 ] = Color( COL_WHITE );
}
else if( pImage->depth == 8 && mbGrey )
{
pPal = new BitmapPalette( 256 );
for( sal_uInt16 i = 0; i < 256; i++ )
{
BitmapColor& rBmpCol = (*pPal)[ i ];
rBmpCol.SetRed( i );
rBmpCol.SetGreen( i );
rBmpCol.SetBlue( i );
}
}
else if( pImage->depth <= 8 )
{
const SalColormap& rColMap = pSalDisp->GetColormap( nScreen );
const sal_uInt16 nCols = std::min( (sal_uLong)rColMap.GetUsed()
, (sal_uLong)(1 << pImage->depth)
);
pPal = new BitmapPalette( nCols );
for( sal_uInt16 i = 0; i < nCols; i++ )
{
const SalColor nColor( rColMap.GetColor( i ) );
BitmapColor& rBmpCol = (*pPal)[ i ];
rBmpCol.SetRed( SALCOLOR_RED( nColor ) );
rBmpCol.SetGreen( SALCOLOR_GREEN( nColor ) );
rBmpCol.SetBlue( SALCOLOR_BLUE( nColor ) );
}
}
pDstBuf = StretchAndConvert( *mpDIB, rTwoRect, nDstFormat, pPal, pMask );
delete pPal;
delete pMask;
if( pDstBuf && pDstBuf->mpBits )
{
#if defined HAVE_VALGRIND_HEADERS
if (RUNNING_ON_VALGRIND)
blankExtraSpace(pDstBuf);
#endif
// set data in buffer as data member in pImage
pImage->data = (char*) pDstBuf->mpBits;
// destroy buffer; don't destroy allocated data in buffer
delete pDstBuf;
}
else
{
XDestroyImage( pImage );
pImage = NULL;
}
}
}
return pImage;
}
// -----------------------------------------------------------------------------
bool X11SalBitmap::ImplCreateFromDrawable(
Drawable aDrawable,
void *pVisual,
SalX11Screen nScreen,
long nDrawableDepth,
long nX,
long nY,
long nWidth,
long nHeight
) {
Destroy();
if( aDrawable && nWidth && nHeight && nDrawableDepth )
mpDDB = new ImplSalDDB( aDrawable, pVisual, nScreen, nDrawableDepth, nX, nY, nWidth, nHeight );
return( mpDDB != NULL );
}
// -----------------------------------------------------------------------------
ImplSalDDB* X11SalBitmap::ImplGetDDB(
Drawable aDrawable,
SalX11Screen nXScreen,
long nDrawableDepth,
const SalTwoRect& rTwoRect
) const
{
if( !mpDDB || !mpDDB->ImplMatches( nXScreen, nDrawableDepth, rTwoRect ) )
{
if( mpDDB )
{
// do we already have a DIB? if not, create aDIB from current DDB first
if( !mpDIB )
{
const_cast<X11SalBitmap*>(this)->mpDIB = ImplCreateDIB( mpDDB->ImplGetPixmap(),
mpDDB->ImplGetScreen(),
mpDDB->ImplGetDepth(),
0, 0,
mpDDB->ImplGetWidth(),
mpDDB->ImplGetHeight(),
mbGrey );
}
delete mpDDB, const_cast<X11SalBitmap*>(this)->mpDDB = NULL;
}
if( mpCache )
mpCache->ImplRemove( const_cast<X11SalBitmap*>(this) );
SalTwoRect aTwoRect( rTwoRect );
if( aTwoRect.mnSrcX < 0 )
{
aTwoRect.mnSrcWidth += aTwoRect.mnSrcX;
aTwoRect.mnSrcX = 0;
}
if( aTwoRect.mnSrcY < 0 )
{
aTwoRect.mnSrcHeight += aTwoRect.mnSrcY;
aTwoRect.mnSrcY = 0;
}
// create new DDB from DIB
const Size aSize( GetSize() );
if( aTwoRect.mnSrcWidth == aTwoRect.mnDestWidth &&
aTwoRect.mnSrcHeight == aTwoRect.mnDestHeight )
{
aTwoRect.mnSrcX = aTwoRect.mnSrcY = aTwoRect.mnDestX = aTwoRect.mnDestY = 0;
aTwoRect.mnSrcWidth = aTwoRect.mnDestWidth = aSize.Width();
aTwoRect.mnSrcHeight = aTwoRect.mnDestHeight = aSize.Height();
}
else if( aTwoRect.mnSrcWidth+aTwoRect.mnSrcX > aSize.Width() ||
aTwoRect.mnSrcHeight+aTwoRect.mnSrcY > aSize.Height() )
{
// #i47823# this should not happen at all, but does nonetheless
// because BitmapEx allows for mask bitmaps of different size
// than image bitmap (broken)
if( aTwoRect.mnSrcX >= aSize.Width() ||
aTwoRect.mnSrcY >= aSize.Height() )
return NULL; // this would be a really mad case
if( aTwoRect.mnSrcWidth+aTwoRect.mnSrcX > aSize.Width() )
{
aTwoRect.mnSrcWidth = aSize.Width()-aTwoRect.mnSrcX;
if( aTwoRect.mnSrcWidth < 1 )
{
aTwoRect.mnSrcX = 0;
aTwoRect.mnSrcWidth = aSize.Width();
}
}
if( aTwoRect.mnSrcHeight+aTwoRect.mnSrcY > aSize.Height() )
{
aTwoRect.mnSrcHeight = aSize.Height() - aTwoRect.mnSrcY;
if( aTwoRect.mnSrcHeight < 1 )
{
aTwoRect.mnSrcY = 0;
aTwoRect.mnSrcHeight = aSize.Height();
}
}
}
XImage* pImage = ImplCreateXImage( GetGenericData()->GetSalDisplay(), nXScreen,
nDrawableDepth, aTwoRect );
if( pImage )
{
const_cast<X11SalBitmap*>(this)->mpDDB = new ImplSalDDB( pImage, aDrawable, nXScreen, aTwoRect );
delete[] pImage->data, pImage->data = NULL;
XDestroyImage( pImage );
if( mpCache )
mpCache->ImplAdd( const_cast<X11SalBitmap*>(this), mpDDB->ImplGetMemSize() );
}
}
return mpDDB;
}
// -----------------------------------------------------------------------------
void X11SalBitmap::ImplDraw(
Drawable aDrawable,
SalX11Screen nXScreen,
long nDrawableDepth,
const SalTwoRect& rTwoRect,
const GC& rGC
) const
{
ImplGetDDB( aDrawable, nXScreen, nDrawableDepth, rTwoRect );
if( mpDDB )
mpDDB->ImplDraw( aDrawable, nDrawableDepth, rTwoRect, rGC );
}
// -----------------------------------------------------------------------------
bool X11SalBitmap::Create( const Size& rSize, sal_uInt16 nBitCount, const BitmapPalette& rPal )
{
Destroy();
mpDIB = ImplCreateDIB( rSize, nBitCount, rPal );
return( mpDIB != NULL );
}
// -----------------------------------------------------------------------------
bool X11SalBitmap::Create( const SalBitmap& rSSalBmp )
{
Destroy();
const X11SalBitmap& rSalBmp = static_cast<const X11SalBitmap&>( rSSalBmp );
if( rSalBmp.mpDIB )
{
// TODO: reference counting...
mpDIB = new BitmapBuffer( *rSalBmp.mpDIB );
// TODO: get rid of this when BitmapBuffer gets copy constructor
try
{
mpDIB->mpBits = new sal_uInt8[ mpDIB->mnScanlineSize * mpDIB->mnHeight ];
#if defined HAVE_VALGRIND_HEADERS
if (RUNNING_ON_VALGRIND)
blankExtraSpace(mpDIB);
#endif
}
catch (const std::bad_alloc&)
{
delete mpDIB;
mpDIB = NULL;
}
if( mpDIB )
memcpy( mpDIB->mpBits, rSalBmp.mpDIB->mpBits, mpDIB->mnScanlineSize * mpDIB->mnHeight );
}
else if( rSalBmp.mpDDB )
ImplCreateFromDrawable( rSalBmp.mpDDB->ImplGetPixmap(),
rSalBmp.mpDDB->ImplGetVisual(),
rSalBmp.mpDDB->ImplGetScreen(),
rSalBmp.mpDDB->ImplGetDepth(),
0, 0, rSalBmp.mpDDB->ImplGetWidth(), rSalBmp.mpDDB->ImplGetHeight() );
return( ( !rSalBmp.mpDIB && !rSalBmp.mpDDB ) ||
( rSalBmp.mpDIB && ( mpDIB != NULL ) ) ||
( rSalBmp.mpDDB && ( mpDDB != NULL ) ) );
}
// -----------------------------------------------------------------------------
bool X11SalBitmap::Create( const SalBitmap&, SalGraphics* )
{
return false;
}
// -----------------------------------------------------------------------------
bool X11SalBitmap::Create( const SalBitmap&, sal_uInt16 )
{
return false;
}
// -----------------------------------------------------------------------------
bool X11SalBitmap::Create(
const ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XBitmapCanvas > xBitmapCanvas,
Size& rSize,
bool bMask
) {
::com::sun::star::uno::Reference< ::com::sun::star::beans::XFastPropertySet >
xFastPropertySet( xBitmapCanvas, ::com::sun::star::uno::UNO_QUERY );
if( xFastPropertySet.get() ) {
sal_Int32 depth;
::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > args;
if( xFastPropertySet->getFastPropertyValue(bMask ? 2 : 1) >>= args ) {
long pixmapHandle;
sal_Int64 nVisualPtr;
if( args.getLength() >= 4 && ( args[1] >>= pixmapHandle ) && ( args[2] >>= depth ) && ( args[3] >>= nVisualPtr ) ) {
mbGrey = bMask;
bool bSuccess = ImplCreateFromDrawable(
pixmapHandle,
reinterpret_cast<void*>(nVisualPtr),
// FIXME: this seems multi-screen broken to me
SalX11Screen( 0 ),
depth,
0,
0,
(long) rSize.Width(),
(long) rSize.Height()
);
bool bFreePixmap = false;
if( bSuccess && (args[0] >>= bFreePixmap) && bFreePixmap )
XFreePixmap( GetGenericData()->GetSalDisplay()->GetDisplay(), pixmapHandle );
return bSuccess;
}
}
}
return false;
}
// -----------------------------------------------------------------------------
void X11SalBitmap::Destroy()
{
if( mpDIB )
{
delete[] mpDIB->mpBits;
delete mpDIB, mpDIB = NULL;
}
if( mpDDB )
delete mpDDB, mpDDB = NULL;
if( mpCache )
mpCache->ImplRemove( this );
}
// -----------------------------------------------------------------------------
Size X11SalBitmap::GetSize() const
{
Size aSize;
if( mpDIB )
aSize.Width() = mpDIB->mnWidth, aSize.Height() = mpDIB->mnHeight;
else if( mpDDB )
aSize.Width() = mpDDB->ImplGetWidth(), aSize.Height() = mpDDB->ImplGetHeight();
return aSize;
}
// -----------------------------------------------------------------------------
sal_uInt16 X11SalBitmap::GetBitCount() const
{
sal_uInt16 nBitCount;
if( mpDIB )
nBitCount = mpDIB->mnBitCount;
else if( mpDDB )
nBitCount = mpDDB->ImplGetDepth();
else
nBitCount = 0;
return nBitCount;
}
// -----------------------------------------------------------------------------
BitmapBuffer* X11SalBitmap::AcquireBuffer( bool )
{
if( !mpDIB && mpDDB )
{
mpDIB = ImplCreateDIB(
mpDDB->ImplGetPixmap(),
mpDDB->ImplGetScreen(),
mpDDB->ImplGetDepth(),
0, 0,
mpDDB->ImplGetWidth(),
mpDDB->ImplGetHeight(),
mbGrey
);
}
return mpDIB;
}
// -----------------------------------------------------------------------------
void X11SalBitmap::ReleaseBuffer( BitmapBuffer*, bool bReadOnly )
{
if( !bReadOnly )
{
if( mpDDB )
delete mpDDB, mpDDB = NULL;
if( mpCache )
mpCache->ImplRemove( this );
}
}
// -----------------------------------------------------------------------------
bool X11SalBitmap::GetSystemData( BitmapSystemData& rData )
{
if( mpDDB )
{
// Rename/retype pDummy to your likings (though X11 Pixmap is
// prolly not a good idea, since it's accessed from
// non-platform aware code in vcl/bitmap.hxx)
rData.aPixmap = (void*)mpDDB->ImplGetPixmap();
rData.aVisual = mpDDB->ImplGetVisual ();
rData.mnWidth = mpDDB->ImplGetWidth ();
rData.mnHeight = mpDDB->ImplGetHeight ();
return true;
}
return false;
}
// --------------
// - ImplSalDDB -
// --------------
ImplSalDDB::ImplSalDDB( XImage* pImage, Drawable aDrawable,
SalX11Screen nXScreen, const SalTwoRect& rTwoRect )
: maPixmap ( 0 )
, mpVisual ( NULL )
, maTwoRect ( rTwoRect )
, mnDepth ( pImage->depth )
, mnXScreen ( nXScreen )
{
SalDisplay* pSalDisp = GetGenericData()->GetSalDisplay();
Display* pXDisp = pSalDisp->GetDisplay();
if( (maPixmap = limitXCreatePixmap( pXDisp, aDrawable, ImplGetWidth(), ImplGetHeight(), ImplGetDepth() )) )
{
XGCValues aValues;
GC aGC;
int nValues = GCFunction;
aValues.function = GXcopy;
if( 1 == mnDepth )
{
nValues |= ( GCForeground | GCBackground );
aValues.foreground = 1, aValues.background = 0;
}
aGC = XCreateGC( pXDisp, maPixmap, nValues, &aValues );
XPutImage( pXDisp, maPixmap, aGC, pImage, 0, 0, 0, 0, maTwoRect.mnDestWidth, maTwoRect.mnDestHeight );
XFreeGC( pXDisp, aGC );
}
}
// -----------------------------------------------------------------------------
ImplSalDDB::ImplSalDDB(
Drawable aDrawable,
void *pVisual,
SalX11Screen nXScreen,
long nDrawableDepth,
long nX,
long nY,
long nWidth,
long nHeight
) : mpVisual ( pVisual )
, mnDepth( nDrawableDepth )
, mnXScreen( nXScreen )
{
SalDisplay* pSalDisp = GetGenericData()->GetSalDisplay();
Display* pXDisp = pSalDisp->GetDisplay();
if( (maPixmap = limitXCreatePixmap( pXDisp, aDrawable, nWidth, nHeight, nDrawableDepth )) )
{
XGCValues aValues;
GC aGC;
int nValues = GCFunction;
aValues.function = GXcopy;
if( 1 == mnDepth )
{
nValues |= ( GCForeground | GCBackground );
aValues.foreground = 1, aValues.background = 0;
}
aGC = XCreateGC( pXDisp, maPixmap, nValues, &aValues );
ImplDraw( aDrawable, nDrawableDepth, maPixmap, mnDepth,
nX, nY, nWidth, nHeight, 0, 0, aGC );
XFreeGC( pXDisp, aGC );
maTwoRect.mnSrcX = maTwoRect.mnSrcY = maTwoRect.mnDestX = maTwoRect.mnDestY = 0;
maTwoRect.mnSrcWidth = maTwoRect.mnDestWidth = nWidth;
maTwoRect.mnSrcHeight = maTwoRect.mnDestHeight = nHeight;
}
}
// -----------------------------------------------------------------------------
ImplSalDDB::~ImplSalDDB()
{
if( maPixmap && ImplGetSVData() )
XFreePixmap( GetGenericData()->GetSalDisplay()->GetDisplay(), maPixmap );
}
// -----------------------------------------------------------------------------
bool ImplSalDDB::ImplMatches( SalX11Screen nXScreen, long nDepth, const SalTwoRect& rTwoRect ) const
{
bool bRet = false;
if( ( maPixmap != 0 ) && ( ( mnDepth == nDepth ) || ( 1 == mnDepth ) ) && nXScreen == mnXScreen)
{
if ( rTwoRect.mnSrcX == maTwoRect.mnSrcX
&& rTwoRect.mnSrcY == maTwoRect.mnSrcY
&& rTwoRect.mnSrcWidth == maTwoRect.mnSrcWidth
&& rTwoRect.mnSrcHeight == maTwoRect.mnSrcHeight
&& rTwoRect.mnDestWidth == maTwoRect.mnDestWidth
&& rTwoRect.mnDestHeight == maTwoRect.mnDestHeight
)
{
// absolutely indentically
bRet = true;
}
else if( rTwoRect.mnSrcWidth == rTwoRect.mnDestWidth
&& rTwoRect.mnSrcHeight == rTwoRect.mnDestHeight
&& maTwoRect.mnSrcWidth == maTwoRect.mnDestWidth
&& maTwoRect.mnSrcHeight == maTwoRect.mnDestHeight
&& rTwoRect.mnSrcX >= maTwoRect.mnSrcX
&& rTwoRect.mnSrcY >= maTwoRect.mnSrcY
&& ( rTwoRect.mnSrcX + rTwoRect.mnSrcWidth ) <= ( maTwoRect.mnSrcX + maTwoRect.mnSrcWidth )
&& ( rTwoRect.mnSrcY + rTwoRect.mnSrcHeight ) <= ( maTwoRect.mnSrcY + maTwoRect.mnSrcHeight )
)
{
bRet = true;
}
}
return bRet;
}
// -----------------------------------------------------------------------------
void ImplSalDDB::ImplDraw(
Drawable aDrawable,
long nDrawableDepth,
const SalTwoRect& rTwoRect,
const GC& rGC
) const
{
ImplDraw( maPixmap, mnDepth, aDrawable, nDrawableDepth,
rTwoRect.mnSrcX - maTwoRect.mnSrcX, rTwoRect.mnSrcY - maTwoRect.mnSrcY,
rTwoRect.mnDestWidth, rTwoRect.mnDestHeight,
rTwoRect.mnDestX, rTwoRect.mnDestY, rGC );
}
// -----------------------------------------------------------------------------
void ImplSalDDB::ImplDraw(
Drawable aSrcDrawable,
long nSrcDrawableDepth,
Drawable aDstDrawable,
long,
long nSrcX,
long nSrcY,
long nDestWidth,
long nDestHeight,
long nDestX,
long nDestY,
const GC& rGC
) {
SalDisplay* pSalDisp = GetGenericData()->GetSalDisplay();
Display* pXDisp = pSalDisp->GetDisplay();
if( 1 == nSrcDrawableDepth )
{
XCopyPlane( pXDisp, aSrcDrawable, aDstDrawable, rGC,
nSrcX, nSrcY, nDestWidth, nDestHeight, nDestX, nDestY, 1 );
}
else
{
XCopyArea( pXDisp, aSrcDrawable, aDstDrawable, rGC,
nSrcX, nSrcY, nDestWidth, nDestHeight, nDestX, nDestY );
}
}
// ----------------------
// - ImplSalBitmapCache -
// ----------------------
struct ImplBmpObj
{
X11SalBitmap* mpBmp;
sal_uLong mnMemSize;
sal_uLong mnFlags;
ImplBmpObj( X11SalBitmap* pBmp, sal_uLong nMemSize, sal_uLong nFlags ) :
mpBmp( pBmp ), mnMemSize( nMemSize ), mnFlags( nFlags ) {}
};
// -----------------------------------------------------------------------------
ImplSalBitmapCache::ImplSalBitmapCache() :
mnTotalSize( 0UL )
{
}
// -----------------------------------------------------------------------------
ImplSalBitmapCache::~ImplSalBitmapCache()
{
ImplClear();
}
// -----------------------------------------------------------------------------
void ImplSalBitmapCache::ImplAdd( X11SalBitmap* pBmp, sal_uLong nMemSize, sal_uLong nFlags )
{
ImplBmpObj* pObj = NULL;
bool bFound = false;
for(
BmpList_impl::iterator it = maBmpList.begin();
(it != maBmpList.end() ) && !bFound ;
++it
) {
pObj = *it;
if( pObj->mpBmp == pBmp )
bFound = true;
}
mnTotalSize += nMemSize;
if( bFound )
{
mnTotalSize -= pObj->mnMemSize;
pObj->mnMemSize = nMemSize, pObj->mnFlags = nFlags;
}
else
maBmpList.push_back( new ImplBmpObj( pBmp, nMemSize, nFlags ) );
}
// -----------------------------------------------------------------------------
void ImplSalBitmapCache::ImplRemove( X11SalBitmap* pBmp )
{
for(
BmpList_impl::iterator it = maBmpList.begin();
it != maBmpList.end();
++it
) {
if( (*it)->mpBmp == pBmp )
{
(*it)->mpBmp->ImplRemovedFromCache();
mnTotalSize -= (*it)->mnMemSize;
delete *it;
maBmpList.erase( it );
break;
}
}
}
// -----------------------------------------------------------------------------
void ImplSalBitmapCache::ImplClear()
{
for(
BmpList_impl::iterator it = maBmpList.begin();
it != maBmpList.end();
++it
) {
(*it)->mpBmp->ImplRemovedFromCache();
delete *it;
}
maBmpList.clear();
mnTotalSize = 0;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */