[Libreoffice-commits] core.git: Branch 'distro/suse/suse-3.6' - 2 commits - canvas/source vcl/inc vcl/source vcl/unx
Radek Doulik
rodo at novell.com
Thu Mar 14 02:20:45 PDT 2013
canvas/source/cairo/cairo_canvasbitmap.cxx | 30 +++++
canvas/source/cairo/cairo_canvasbitmap.hxx | 4
canvas/source/cairo/cairo_xlib_cairo.cxx | 7 +
canvas/source/cairo/cairo_xlib_cairo.hxx | 1
vcl/inc/salbmp.hxx | 2
vcl/inc/unx/salbmp.h | 7 +
vcl/inc/unx/salgdi.h | 5
vcl/inc/vcl/bitmap.hxx | 3
vcl/source/gdi/bitmap.cxx | 13 ++
vcl/source/gdi/gdimtf.cxx | 10 -
vcl/source/helper/canvastools.cxx | 25 ++++
vcl/unx/generic/gdi/salbmp.cxx | 18 ++-
vcl/unx/generic/gdi/salgdi2.cxx | 149 ++++++++++++++++-------------
13 files changed, 191 insertions(+), 83 deletions(-)
New commits:
commit c6c0e73e0fda18b7bb37685ab8f8630e15bb427a
Author: Radek Doulik <rodo at novell.com>
Date: Thu Mar 14 09:36:43 2013 +0100
pass argb32 pixmaps from vcl to canvas, avoiding costly x11 roundtrips
- fixes also problem with emf+ rendering for slideshow
Change-Id: Icb894d3f37b29f23d3f267c944d827eefbf47fda
diff --git a/canvas/source/cairo/cairo_canvasbitmap.cxx b/canvas/source/cairo/cairo_canvasbitmap.cxx
index 1d62554..949a9ca 100644
--- a/canvas/source/cairo/cairo_canvasbitmap.cxx
+++ b/canvas/source/cairo/cairo_canvasbitmap.cxx
@@ -143,6 +143,30 @@ namespace cairocanvas
return maCanvasHelper.repaint( pSurface, viewState, renderState );
}
+ void SAL_CALL CanvasBitmap::setFastPropertyValue( sal_Int32 nHandle, const ::com::sun::star::uno::Any& rAny ) throw (uno::RuntimeException)
+ {
+ sal_Int64 nPointer;
+
+ if ( nHandle == 0 )
+ {
+ rAny >>= nPointer;
+
+ if ( nPointer )
+ {
+ ::Bitmap *pBitmap = reinterpret_cast< ::Bitmap* >( nPointer );
+
+ mpBufferSurface = createSurface( *pBitmap );
+ mpBufferCairo = mpBufferSurface->getCairo();
+
+ ::Size aSize( pBitmap->GetSizePixel() );
+ maSize = ::basegfx::B2ISize( aSize.getWidth(), aSize.getHeight() );
+
+ maCanvasHelper.setSize( maSize );
+ maCanvasHelper.setSurface( mpBufferSurface, mbHasAlpha );
+ }
+ }
+ }
+
uno::Any SAL_CALL CanvasBitmap::getFastPropertyValue( sal_Int32 nHandle ) throw (uno::RuntimeException)
{
uno::Any aRV( sal_Int32(0) );
@@ -161,10 +185,11 @@ namespace cairocanvas
#ifdef CAIRO_HAS_XLIB_SURFACE
X11Surface* pXlibSurface=dynamic_cast<X11Surface*>(mpBufferSurface.get());
OSL_ASSERT(pXlibSurface);
- uno::Sequence< uno::Any > args( 3 );
+ uno::Sequence< uno::Any > args( 4 );
args[0] = uno::Any( false ); // do not call XFreePixmap on it
args[1] = uno::Any( pXlibSurface->getPixmap()->mhDrawable );
args[2] = uno::Any( sal_Int32( pXlibSurface->getDepth() ) );
+ args[3] = uno::Any( sal_Int64( pXlibSurface->getVisual () ) );
aRV = uno::Any( args );
#elif defined CAIRO_HAS_QUARTZ_SURFACE
@@ -189,7 +214,7 @@ namespace cairocanvas
case 2:
{
#ifdef CAIRO_HAS_XLIB_SURFACE
- uno::Sequence< uno::Any > args( 3 );
+ uno::Sequence< uno::Any > args( 4 );
SurfaceSharedPtr pAlphaSurface = mpSurfaceProvider->createSurface( maSize, CAIRO_CONTENT_COLOR );
CairoSharedPtr pAlphaCairo = pAlphaSurface->getCairo();
X11Surface* pXlibSurface=dynamic_cast<X11Surface*>(pAlphaSurface.get());
@@ -208,6 +233,7 @@ namespace cairocanvas
args[0] = uno::Any( true );
args[1] = ::com::sun::star::uno::Any( pPixmap->mhDrawable );
args[2] = ::com::sun::star::uno::Any( sal_Int32( pXlibSurface->getDepth () ) );
+ args[3] = ::com::sun::star::uno::Any( sal_Int64( pXlibSurface->getVisual () ) );
pPixmap->clear(); // caller takes ownership of pixmap
// return pixmap and alphachannel pixmap - it will be used in BitmapEx
diff --git a/canvas/source/cairo/cairo_canvasbitmap.hxx b/canvas/source/cairo/cairo_canvasbitmap.hxx
index 1626c92..523228c 100644
--- a/canvas/source/cairo/cairo_canvasbitmap.hxx
+++ b/canvas/source/cairo/cairo_canvasbitmap.hxx
@@ -124,14 +124,14 @@ namespace cairocanvas
// 2nd the pixmap handle
// 3rd the pixmap depth
virtual ::com::sun::star::uno::Any SAL_CALL getFastPropertyValue(sal_Int32 nHandle) throw (::com::sun::star::uno::RuntimeException);
- virtual void SAL_CALL setFastPropertyValue(sal_Int32, const ::com::sun::star::uno::Any&) throw (::com::sun::star::uno::RuntimeException) {}
+ virtual void SAL_CALL setFastPropertyValue(sal_Int32, const ::com::sun::star::uno::Any&) throw (::com::sun::star::uno::RuntimeException);
private:
SurfaceProviderRef mpSurfaceProvider;
::cairo::SurfaceSharedPtr mpBufferSurface;
::cairo::CairoSharedPtr mpBufferCairo;
- const ::basegfx::B2ISize maSize;
+ ::basegfx::B2ISize maSize;
const bool mbHasAlpha;
};
}
diff --git a/canvas/source/cairo/cairo_xlib_cairo.cxx b/canvas/source/cairo/cairo_xlib_cairo.cxx
index 0259154..c75bc96 100644
--- a/canvas/source/cairo/cairo_xlib_cairo.cxx
+++ b/canvas/source/cairo/cairo_xlib_cairo.cxx
@@ -196,7 +196,7 @@ namespace cairo
mpSurface(
cairo_xlib_surface_create( (Display*)rSysData.pDisplay,
(Drawable)rData.aPixmap,
- (Visual*) rSysData.pVisual,
+ (Visual*) (rData.aVisual ? rData.aVisual : rSysData.pVisual),
rData.mnWidth, rData.mnHeight ),
&cairo_surface_destroy)
{
@@ -321,6 +321,11 @@ namespace cairo
return -1;
}
+ void* X11Surface::getVisual() const
+ {
+ return cairo_xlib_surface_get_visual( mpSurface.get() );
+ }
+
SurfaceSharedPtr createSurface( const CairoSurfaceSharedPtr& rSurface )
{
return SurfaceSharedPtr(new X11Surface(rSurface));
diff --git a/canvas/source/cairo/cairo_xlib_cairo.hxx b/canvas/source/cairo/cairo_xlib_cairo.hxx
index 92ca044..2736ed4 100644
--- a/canvas/source/cairo/cairo_xlib_cairo.hxx
+++ b/canvas/source/cairo/cairo_xlib_cairo.hxx
@@ -101,6 +101,7 @@ namespace cairo {
X11PixmapSharedPtr getPixmap() const { return mpPixmap; }
void* getRenderFormat() const { return maSysData.pRenderFormat; }
long getDrawable() const { return mpPixmap ? mpPixmap->mhDrawable : maSysData.hDrawable; }
+ void* getVisual() const;
};
}
diff --git a/vcl/inc/unx/salbmp.h b/vcl/inc/unx/salbmp.h
index d9ce192..e97b9b9 100644
--- a/vcl/inc/unx/salbmp.h
+++ b/vcl/inc/unx/salbmp.h
@@ -89,6 +89,7 @@ public:
SAL_DLLPRIVATE bool ImplCreateFromDrawable(
Drawable aDrawable,
+ void* pVisual,
SalX11Screen nXScreen,
long nDrawableDepth,
long nX,
@@ -171,6 +172,7 @@ class ImplSalDDB
private:
Pixmap maPixmap;
+ void* mpVisual;
SalTwoRect maTwoRect;
long mnDepth;
SalX11Screen mnXScreen;
@@ -202,6 +204,7 @@ public:
ImplSalDDB(
Drawable aDrawable,
+ void *pVisual,
SalX11Screen nXScreen,
long nDrawableDepth,
long nX,
@@ -213,6 +216,7 @@ public:
~ImplSalDDB();
Pixmap ImplGetPixmap() const { return maPixmap; }
+ void* ImplGetVisual() const { return mpVisual; }
long ImplGetWidth() const { return maTwoRect.mnDestWidth; }
long ImplGetHeight() const { return maTwoRect.mnDestHeight; }
long ImplGetDepth() const { return mnDepth; }
diff --git a/vcl/inc/vcl/bitmap.hxx b/vcl/inc/vcl/bitmap.hxx
index efc37a0..d162daa 100644
--- a/vcl/inc/vcl/bitmap.hxx
+++ b/vcl/inc/vcl/bitmap.hxx
@@ -330,6 +330,7 @@ struct BitmapSystemData
void* rImageContext; //Image context (CGContextRef)
#else
void* aPixmap;
+ void* aVisual;
#endif
int mnWidth;
int mnHeight;
@@ -847,6 +848,8 @@ public:
const BmpFilterParam* pFilterParam = NULL,
const Link* pProgress = NULL );
+ bool HasAlpha();
+
public:
BitmapReadAccess* AcquireReadAccess();
BitmapWriteAccess* AcquireWriteAccess();
diff --git a/vcl/source/gdi/bitmap.cxx b/vcl/source/gdi/bitmap.cxx
index 3d298b7..dc279cf 100644
--- a/vcl/source/gdi/bitmap.cxx
+++ b/vcl/source/gdi/bitmap.cxx
@@ -1910,4 +1910,17 @@ bool Bitmap::GetSystemData( BitmapSystemData& rData ) const
return bRet;
}
+bool Bitmap::HasAlpha()
+{
+ bool bRet = false;
+ if( mpImpBmp )
+ {
+ SalBitmap* pSalBitmap = mpImpBmp->ImplGetSalBitmap();
+ if( pSalBitmap )
+ bRet = pSalBitmap->HasAlpha();
+ }
+
+ return bRet;
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/helper/canvastools.cxx b/vcl/source/helper/canvastools.cxx
index b8dce8d..a0a6937 100644
--- a/vcl/source/helper/canvastools.cxx
+++ b/vcl/source/helper/canvastools.cxx
@@ -30,6 +30,8 @@
#include <rtl/logfile.hxx>
#include <cppuhelper/compbase1.hxx>
+#include <com/sun/star/beans/XFastPropertySet.hpp>
+
#include <com/sun/star/geometry/RealSize2D.hpp>
#include <com/sun/star/geometry/RealPoint2D.hpp>
#include <com/sun/star/geometry/RealRectangle2D.hpp>
@@ -79,11 +81,32 @@ namespace vcl
{
namespace unotools
{
- uno::Reference< rendering::XBitmap > xBitmapFromBitmapEx( const uno::Reference< rendering::XGraphicDevice >& /*xGraphicDevice*/,
+ uno::Reference< rendering::XBitmap > xBitmapFromBitmapEx( const uno::Reference< rendering::XGraphicDevice >& xGraphicDevice,
const ::BitmapEx& inputBitmap )
{
RTL_LOGFILE_CONTEXT( aLog, "::vcl::unotools::xBitmapFromBitmapEx()" );
+ if ( inputBitmap.GetBitmap().HasAlpha() )
+ {
+ geometry::IntegerSize2D aSize;
+
+ aSize.Width = aSize.Height = 1;
+
+ uno::Reference< rendering::XBitmap > xBitmap = xGraphicDevice->createCompatibleAlphaBitmap( aSize );
+
+ uno::Reference< beans::XFastPropertySet > rPropSet( xBitmap, uno::UNO_QUERY );
+ if ( rPropSet.is() )
+ {
+ Bitmap aBitmap = inputBitmap.GetBitmap();
+ rPropSet->setFastPropertyValue( 0, uno::Any( sal_Int64( &aBitmap )));
+
+ aSize = xBitmap->getSize();
+
+ if ( aSize.Width != 1 || aSize.Height != 1 )
+ return xBitmap;
+ }
+ }
+
return new vcl::unotools::VclCanvasBitmap( inputBitmap );
}
diff --git a/vcl/unx/generic/gdi/salbmp.cxx b/vcl/unx/generic/gdi/salbmp.cxx
index 7902458..9528ee2 100644
--- a/vcl/unx/generic/gdi/salbmp.cxx
+++ b/vcl/unx/generic/gdi/salbmp.cxx
@@ -576,6 +576,7 @@ XImage* X11SalBitmap::ImplCreateXImage(
// -----------------------------------------------------------------------------
bool X11SalBitmap::ImplCreateFromDrawable(
Drawable aDrawable,
+ void *pVisual,
SalX11Screen nScreen,
long nDrawableDepth,
long nX,
@@ -586,7 +587,7 @@ bool X11SalBitmap::ImplCreateFromDrawable(
Destroy();
if( aDrawable && nWidth && nHeight && nDrawableDepth )
- mpDDB = new ImplSalDDB( aDrawable, nScreen, nDrawableDepth, nX, nY, nWidth, nHeight );
+ mpDDB = new ImplSalDDB( aDrawable, pVisual, nScreen, nDrawableDepth, nX, nY, nWidth, nHeight );
return( mpDDB != NULL );
}
@@ -746,7 +747,8 @@ bool X11SalBitmap::Create( const SalBitmap& rSSalBmp )
}
else if( rSalBmp.mpDDB )
ImplCreateFromDrawable( rSalBmp.mpDDB->ImplGetPixmap(),
- rSalBmp.mpDDB->ImplGetScreen(),
+ rSalBmp.mpDDB->ImplGetVisual(),
+ rSalBmp.mpDDB->ImplGetScreen(),
rSalBmp.mpDDB->ImplGetDepth(),
0, 0, rSalBmp.mpDDB->ImplGetWidth(), rSalBmp.mpDDB->ImplGetHeight() );
@@ -785,11 +787,13 @@ bool X11SalBitmap::Create(
if( xFastPropertySet->getFastPropertyValue(bMask ? 2 : 1) >>= args ) {
long pixmapHandle;
- if( ( args[1] >>= pixmapHandle ) && ( args[2] >>= depth ) ) {
+ 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,
@@ -901,6 +905,7 @@ bool X11SalBitmap::GetSystemData( BitmapSystemData& rData )
// 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;
@@ -916,6 +921,7 @@ bool X11SalBitmap::GetSystemData( BitmapSystemData& rData )
ImplSalDDB::ImplSalDDB( XImage* pImage, Drawable aDrawable,
SalX11Screen nXScreen, const SalTwoRect& rTwoRect )
: maPixmap ( 0 )
+ , mpVisual ( NULL )
, maTwoRect ( rTwoRect )
, mnDepth ( pImage->depth )
, mnXScreen ( nXScreen )
@@ -947,13 +953,15 @@ ImplSalDDB::ImplSalDDB( XImage* pImage, Drawable aDrawable,
ImplSalDDB::ImplSalDDB(
Drawable aDrawable,
+ void *pVisual,
SalX11Screen nXScreen,
long nDrawableDepth,
long nX,
long nY,
long nWidth,
long nHeight
-) : mnDepth( nDrawableDepth )
+) : mpVisual ( pVisual )
+ , mnDepth( nDrawableDepth )
, mnXScreen( nXScreen )
{
SalDisplay* pSalDisp = GetGenericData()->GetSalDisplay();
diff --git a/vcl/unx/generic/gdi/salgdi2.cxx b/vcl/unx/generic/gdi/salgdi2.cxx
index 3a2f63f..7ae904a 100644
--- a/vcl/unx/generic/gdi/salgdi2.cxx
+++ b/vcl/unx/generic/gdi/salgdi2.cxx
@@ -99,7 +99,7 @@ void X11SalGraphics::CopyScreenArea( Display* pDisplay,
else
{
X11SalBitmap aBM;
- aBM.ImplCreateFromDrawable( aSrc, nXScreenSrc, nSrcDepth, src_x, src_y, w, h );
+ aBM.ImplCreateFromDrawable( aSrc, NULL, nXScreenSrc, nSrcDepth, src_x, src_y, w, h );
SalTwoRect aTwoRect;
aTwoRect.mnSrcX = aTwoRect.mnSrcY = 0;
aTwoRect.mnSrcWidth = aTwoRect.mnDestWidth = w;
@@ -808,8 +808,8 @@ bool X11SalGraphics::drawAlphaBitmapOpt( const SalTwoRect& rTR,
const SalVisual& rSalVis = pSalDisp->GetVisual( m_nXScreen );
Display* pXDisplay = pSalDisp->GetDisplay();
- Picture aAlphaPic;
- Pixmap aAlphaPM;
+ Picture aAlphaPic = 0;
+ Pixmap aAlphaPM = 0;
// create source Picture
int nDepth = m_pVDev ? m_pVDev->GetDepth() : rSalVis.GetDepth();
const X11SalBitmap& rSrcX11Bmp = static_cast<const X11SalBitmap&>( rSrcBitmap );
@@ -1061,7 +1061,7 @@ SalBitmap *X11SalGraphics::getBitmap( long nX, long nY, long nDX, long nDY )
nBitCount = 1;
if( ! bFakeWindowBG )
- pSalBitmap->ImplCreateFromDrawable( GetDrawable(), m_nXScreen, nBitCount, nX, nY, nDX, nDY );
+ pSalBitmap->ImplCreateFromDrawable( GetDrawable(), NULL, m_nXScreen, nBitCount, nX, nY, nDX, nDY );
else
pSalBitmap->Create( Size( nDX, nDY ), (nBitCount > 8) ? 24 : nBitCount, BitmapPalette( nBitCount > 8 ? nBitCount : 0 ) );
commit 35e2749cb534fdbe355166ec656beb72248cb096
Author: Radek Doulik <rodo at novell.com>
Date: Thu Mar 7 13:31:34 2013 +0100
fix canvas bitmap rendering (argb32 pixmaps) fixes color issue in n#780830
Change-Id: I5242bbb171ba21da43e535255b7e9dd73c1d4930
diff --git a/vcl/inc/salbmp.hxx b/vcl/inc/salbmp.hxx
index d880be0..cdcace6 100644
--- a/vcl/inc/salbmp.hxx
+++ b/vcl/inc/salbmp.hxx
@@ -56,6 +56,8 @@ public:
virtual bool Create( const ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XBitmapCanvas > xBitmapCanvas,
Size& rSize,
bool bMask = false ) = 0;
+ virtual bool HasAlpha() const { return false; }
+ virtual void SetHasAlpha( bool ) { }
virtual void Destroy() = 0;
virtual Size GetSize() const = 0;
virtual sal_uInt16 GetBitCount() const = 0;
diff --git a/vcl/inc/unx/salbmp.h b/vcl/inc/unx/salbmp.h
index 942a1f7..d9ce192 100644
--- a/vcl/inc/unx/salbmp.h
+++ b/vcl/inc/unx/salbmp.h
@@ -83,6 +83,7 @@ private:
BitmapBuffer* mpDIB;
ImplSalDDB* mpDDB;
bool mbGrey;
+ bool mbHasAlpha;
public:
@@ -157,6 +158,8 @@ public:
virtual BitmapBuffer* AcquireBuffer( bool bReadOnly );
virtual void ReleaseBuffer( BitmapBuffer* pBuffer, bool bReadOnly );
virtual bool GetSystemData( BitmapSystemData& rData );
+ virtual bool HasAlpha() const { return mbHasAlpha; }
+ virtual void SetHasAlpha( bool bHasAlpha ) { mbHasAlpha = bHasAlpha; }
};
// --------------
diff --git a/vcl/inc/unx/salgdi.h b/vcl/inc/unx/salgdi.h
index fd0ffbe..c6ae8fb 100644
--- a/vcl/inc/unx/salgdi.h
+++ b/vcl/inc/unx/salgdi.h
@@ -350,6 +350,11 @@ public:
const SalBitmap& rSourceBitmap,
const SalBitmap& rAlphaBitmap );
+ bool drawAlphaBitmapOpt( const SalTwoRect&,
+ const SalBitmap& rSourceBitmap,
+ const SalBitmap& rAlphaBitmap,
+ bool bUseAlphaBitmap = true );
+
virtual bool drawAlphaRect( long nX, long nY, long nWidth,
long nHeight, sal_uInt8 nTransparency );
diff --git a/vcl/source/gdi/gdimtf.cxx b/vcl/source/gdi/gdimtf.cxx
index e26907b..703dd9b 100644
--- a/vcl/source/gdi/gdimtf.cxx
+++ b/vcl/source/gdi/gdimtf.cxx
@@ -500,20 +500,16 @@ bool GDIMetaFile::ImplPlayWithRenderer( OutputDevice* pOut, const Point& rPos, S
}
SalBitmap* pSalBmp = ImplGetSVData()->mpDefInst->CreateSalBitmap();
- SalBitmap* pSalMask = ImplGetSVData()->mpDefInst->CreateSalBitmap();
+ pSalBmp->SetHasAlpha( true );
- if( pSalBmp->Create( xBitmapCanvas, aSize ) && pSalMask->Create( xBitmapCanvas, aSize, true ) )
+ if( pSalBmp->Create( xBitmapCanvas, aSize ) )
{
Bitmap aBitmap( pSalBmp );
- Bitmap aMask( pSalMask );
- AlphaMask aAlphaMask( aMask );
- BitmapEx aBitmapEx( aBitmap, aAlphaMask );
- pOut->DrawBitmapEx( rPos, aBitmapEx );
+ pOut->DrawBitmap( rPos, aBitmap );
return true;
}
delete pSalBmp;
- delete pSalMask;
}
}
}
diff --git a/vcl/unx/generic/gdi/salbmp.cxx b/vcl/unx/generic/gdi/salbmp.cxx
index 46f1169..7902458 100644
--- a/vcl/unx/generic/gdi/salbmp.cxx
+++ b/vcl/unx/generic/gdi/salbmp.cxx
@@ -52,6 +52,7 @@
#include <unx/salbmp.h>
#include <unx/salinst.h>
#include <unx/x11/xlimits.hxx>
+#include "xrender_peer.hxx"
#if defined(HAVE_MEMCHECK_H)
#include <memcheck.h>
@@ -75,6 +76,7 @@ X11SalBitmap::X11SalBitmap()
: mpDIB( NULL )
, mpDDB( NULL )
, mbGrey( false )
+ , mbHasAlpha( false )
{
}
diff --git a/vcl/unx/generic/gdi/salgdi2.cxx b/vcl/unx/generic/gdi/salgdi2.cxx
index 033055a..3a2f63f 100644
--- a/vcl/unx/generic/gdi/salgdi2.cxx
+++ b/vcl/unx/generic/gdi/salgdi2.cxx
@@ -645,7 +645,10 @@ void X11SalGraphics::drawBitmap( const SalTwoRect* pPosAry, const SalBitmap& rSa
XChangeGC( pXDisp, aGC, nValues, &aNewVal );
}
- static_cast<const X11SalBitmap&>(rSalBitmap).ImplDraw( aDrawable, m_nXScreen, nDepth, *pPosAry, aGC );
+ if ( rSalBitmap.GetBitCount() == 32 && rSalBitmap.HasAlpha() )
+ drawAlphaBitmapOpt( *pPosAry, rSalBitmap, rSalBitmap, false );
+ else
+ static_cast<const X11SalBitmap&>(rSalBitmap).ImplDraw( aDrawable, m_nXScreen, nDepth, *pPosAry, aGC );
if( rSalBitmap.GetBitCount() == 1 )
XChangeGC( pXDisp, aGC, nValues, &aOldVal );
@@ -773,10 +776,17 @@ void X11SalGraphics::drawMaskedBitmap( const SalTwoRect* pPosAry,
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
bool X11SalGraphics::drawAlphaBitmap( const SalTwoRect& rTR,
- const SalBitmap& rSrcBitmap, const SalBitmap& rAlphaBmp )
+ const SalBitmap& rSrcBitmap, const SalBitmap& rAlphaBmp )
+{
+ return drawAlphaBitmapOpt( rTR, rSrcBitmap, rAlphaBmp );
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+bool X11SalGraphics::drawAlphaBitmapOpt( const SalTwoRect& rTR,
+ const SalBitmap& rSrcBitmap, const SalBitmap& rAlphaBmp, bool bUseAlphaBitmap )
{
// non 8-bit alpha not implemented yet
- if( rAlphaBmp.GetBitCount() != 8 )
+ if( bUseAlphaBitmap && rAlphaBmp.GetBitCount() != 8 )
return false;
// horizontal mirroring not implemented yet
@@ -798,10 +808,12 @@ bool X11SalGraphics::drawAlphaBitmap( const SalTwoRect& rTR,
const SalVisual& rSalVis = pSalDisp->GetVisual( m_nXScreen );
Display* pXDisplay = pSalDisp->GetDisplay();
+ Picture aAlphaPic;
+ Pixmap aAlphaPM;
// create source Picture
int nDepth = m_pVDev ? m_pVDev->GetDepth() : rSalVis.GetDepth();
const X11SalBitmap& rSrcX11Bmp = static_cast<const X11SalBitmap&>( rSrcBitmap );
- ImplSalDDB* pSrcDDB = rSrcX11Bmp.ImplGetDDB( hDrawable_, m_nXScreen, nDepth, rTR );
+ ImplSalDDB* pSrcDDB = rSrcX11Bmp.ImplGetDDB( hDrawable_, m_nXScreen, bUseAlphaBitmap ? nDepth : 32, rTR );
if( !pSrcDDB )
return false;
@@ -809,7 +821,7 @@ bool X11SalGraphics::drawAlphaBitmap( const SalTwoRect& rTR,
// we requested. E.g. mask pixmaps are always compatible with the drawable
// TODO: find an appropriate picture format for these cases
// then remove the workaround below and the one for #i75531#
- if( nDepth != pSrcDDB->ImplGetDepth() )
+ if( bUseAlphaBitmap && nDepth != pSrcDDB->ImplGetDepth() )
return false;
Pixmap aSrcPM = pSrcDDB->ImplGetPixmap();
@@ -820,81 +832,86 @@ bool X11SalGraphics::drawAlphaBitmap( const SalTwoRect& rTR,
// TODO: use scoped picture
Visual* pSrcXVisual = rSalVis.GetVisual();
XRenderPeer& rPeer = XRenderPeer::GetInstance();
- XRenderPictFormat* pSrcVisFmt = rPeer.FindVisualFormat( pSrcXVisual );
+ XRenderPictFormat* pSrcVisFmt = bUseAlphaBitmap ? rPeer.FindVisualFormat( pSrcXVisual ) : rPeer.FindStandardFormat( PictStandardARGB32 );
if( !pSrcVisFmt )
return false;
Picture aSrcPic = rPeer.CreatePicture( aSrcPM, pSrcVisFmt, 0, NULL );
if( !aSrcPic )
return false;
- // create alpha Picture
+ if ( bUseAlphaBitmap ) {
+ // create alpha Picture
- // TODO: use SalX11Bitmap functionality and caching for the Alpha Pixmap
- // problem is that they don't provide an 8bit Pixmap on a non-8bit display
- BitmapBuffer* pAlphaBuffer = const_cast<SalBitmap&>(rAlphaBmp).AcquireBuffer( sal_True );
+ // TODO: use SalX11Bitmap functionality and caching for the Alpha Pixmap
+ // problem is that they don't provide an 8bit Pixmap on a non-8bit display
+ BitmapBuffer* pAlphaBuffer = const_cast<SalBitmap&>(rAlphaBmp).AcquireBuffer( sal_True );
- // an XImage needs its data top_down
- // TODO: avoid wrongly oriented images in upper layers!
- const int nImageSize = pAlphaBuffer->mnHeight * pAlphaBuffer->mnScanlineSize;
- const char* pSrcBits = (char*)pAlphaBuffer->mpBits;
- char* pAlphaBits = new char[ nImageSize ];
- if( BMP_SCANLINE_ADJUSTMENT( pAlphaBuffer->mnFormat ) == BMP_FORMAT_TOP_DOWN )
- memcpy( pAlphaBits, pSrcBits, nImageSize );
- else
- {
- char* pDstBits = pAlphaBits + nImageSize;
- const int nLineSize = pAlphaBuffer->mnScanlineSize;
- for(; (pDstBits -= nLineSize) >= pAlphaBits; pSrcBits += nLineSize )
- memcpy( pDstBits, pSrcBits, nLineSize );
- }
+ // an XImage needs its data top_down
+ // TODO: avoid wrongly oriented images in upper layers!
+ const int nImageSize = pAlphaBuffer->mnHeight * pAlphaBuffer->mnScanlineSize;
+ const char* pSrcBits = (char*)pAlphaBuffer->mpBits;
+ char* pAlphaBits = new char[ nImageSize ];
+ if( BMP_SCANLINE_ADJUSTMENT( pAlphaBuffer->mnFormat ) == BMP_FORMAT_TOP_DOWN )
+ memcpy( pAlphaBits, pSrcBits, nImageSize );
+ else
+ {
+ char* pDstBits = pAlphaBits + nImageSize;
+ const int nLineSize = pAlphaBuffer->mnScanlineSize;
+ for(; (pDstBits -= nLineSize) >= pAlphaBits; pSrcBits += nLineSize )
+ memcpy( pDstBits, pSrcBits, nLineSize );
+ }
- // the alpha values need to be inverted for XRender
- // TODO: make upper layers use standard alpha
- long* pLDst = (long*)pAlphaBits;
- for( int i = nImageSize/sizeof(long); --i >= 0; ++pLDst )
- *pLDst = ~*pLDst;
-
- char* pCDst = (char*)pLDst;
- for( int i = nImageSize & (sizeof(long)-1); --i >= 0; ++pCDst )
- *pCDst = ~*pCDst;
-
- const XRenderPictFormat* pAlphaFormat = rPeer.GetStandardFormatA8();
- XImage* pAlphaImg = XCreateImage( pXDisplay, pSrcXVisual, 8, ZPixmap, 0,
- pAlphaBits, pAlphaBuffer->mnWidth, pAlphaBuffer->mnHeight,
- pAlphaFormat->depth, pAlphaBuffer->mnScanlineSize );
-
- Pixmap aAlphaPM = limitXCreatePixmap( pXDisplay, hDrawable_,
- rTR.mnDestWidth, rTR.mnDestHeight, 8 );
-
- XGCValues aAlphaGCV;
- aAlphaGCV.function = GXcopy;
- GC aAlphaGC = XCreateGC( pXDisplay, aAlphaPM, GCFunction, &aAlphaGCV );
- XPutImage( pXDisplay, aAlphaPM, aAlphaGC, pAlphaImg,
- rTR.mnSrcX, rTR.mnSrcY, 0, 0, rTR.mnDestWidth, rTR.mnDestHeight );
- XFreeGC( pXDisplay, aAlphaGC );
- XFree( pAlphaImg );
- if( pAlphaBits != (char*)pAlphaBuffer->mpBits )
- delete[] pAlphaBits;
-
- const_cast<SalBitmap&>(rAlphaBmp).ReleaseBuffer( pAlphaBuffer, sal_True );
-
- XRenderPictureAttributes aAttr;
- aAttr.repeat = true;
- Picture aAlphaPic = rPeer.CreatePicture( aAlphaPM, pAlphaFormat, CPRepeat, &aAttr );
- if( !aAlphaPic )
- return false;
+ // the alpha values need to be inverted for XRender
+ // TODO: make upper layers use standard alpha
+ long* pLDst = (long*)pAlphaBits;
+ for( int i = nImageSize/sizeof(long); --i >= 0; ++pLDst )
+ *pLDst = ~*pLDst;
+
+ char* pCDst = (char*)pLDst;
+ for( int i = nImageSize & (sizeof(long)-1); --i >= 0; ++pCDst )
+ *pCDst = ~*pCDst;
+
+ const XRenderPictFormat* pAlphaFormat = rPeer.GetStandardFormatA8();
+ XImage* pAlphaImg = XCreateImage( pXDisplay, pSrcXVisual, 8, ZPixmap, 0,
+ pAlphaBits, pAlphaBuffer->mnWidth, pAlphaBuffer->mnHeight,
+ pAlphaFormat->depth, pAlphaBuffer->mnScanlineSize );
+
+ aAlphaPM = limitXCreatePixmap( pXDisplay, hDrawable_,
+ rTR.mnDestWidth, rTR.mnDestHeight, 8 );
+
+ XGCValues aAlphaGCV;
+ aAlphaGCV.function = GXcopy;
+ GC aAlphaGC = XCreateGC( pXDisplay, aAlphaPM, GCFunction, &aAlphaGCV );
+ XPutImage( pXDisplay, aAlphaPM, aAlphaGC, pAlphaImg,
+ rTR.mnSrcX, rTR.mnSrcY, 0, 0, rTR.mnDestWidth, rTR.mnDestHeight );
+ XFreeGC( pXDisplay, aAlphaGC );
+ XFree( pAlphaImg );
+ if( pAlphaBits != (char*)pAlphaBuffer->mpBits )
+ delete[] pAlphaBits;
+
+ const_cast<SalBitmap&>(rAlphaBmp).ReleaseBuffer( pAlphaBuffer, sal_True );
+
+ XRenderPictureAttributes aAttr;
+ aAttr.repeat = true;
+ aAlphaPic = rPeer.CreatePicture( aAlphaPM, pAlphaFormat, CPRepeat, &aAttr );
+ if( !aAlphaPic )
+ return false;
+ }
// set clipping
if( mpClipRegion && !XEmptyRegion( mpClipRegion ) )
rPeer.SetPictureClipRegion( aDstPic, mpClipRegion );
// paint source * mask over destination picture
- rPeer.CompositePicture( PictOpOver, aSrcPic, aAlphaPic, aDstPic,
- rTR.mnSrcX, rTR.mnSrcY, 0, 0,
- rTR.mnDestX, rTR.mnDestY, rTR.mnDestWidth, rTR.mnDestHeight );
+ rPeer.CompositePicture( PictOpOver, aSrcPic, bUseAlphaBitmap ? aAlphaPic : None, aDstPic,
+ rTR.mnSrcX, rTR.mnSrcY, 0, 0,
+ rTR.mnDestX, rTR.mnDestY, rTR.mnDestWidth, rTR.mnDestHeight );
- rPeer.FreePicture( aAlphaPic );
- XFreePixmap(pXDisplay, aAlphaPM);
+ if ( bUseAlphaBitmap )
+ {
+ rPeer.FreePicture( aAlphaPic );
+ XFreePixmap( pXDisplay, aAlphaPM);
+ }
rPeer.FreePicture( aSrcPic );
return true;
}
More information about the Libreoffice-commits
mailing list