Kaydet (Commit) 46e53913 authored tarafından Radek Doulik's avatar Radek Doulik

fix canvas bitmap rendering (argb32 pixmaps) fixes color issue in n#780830

Change-Id: I5242bbb171ba21da43e535255b7e9dd73c1d4930
üst cd2c3e72
......@@ -47,6 +47,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;
......
......@@ -74,6 +74,7 @@ private:
BitmapBuffer* mpDIB;
ImplSalDDB* mpDDB;
bool mbGrey;
bool mbHasAlpha;
public:
......@@ -148,6 +149,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; }
};
// --------------
......
......@@ -324,6 +324,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 );
......
......@@ -496,20 +496,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;
}
}
}
......
......@@ -42,6 +42,7 @@
#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>
......@@ -65,6 +66,7 @@ X11SalBitmap::X11SalBitmap()
: mpDIB( NULL )
, mpDDB( NULL )
, mbGrey( false )
, mbHasAlpha( false )
{
}
......
......@@ -495,6 +495,9 @@ void X11SalGraphics::drawBitmap( const SalTwoRect* pPosAry, const SalBitmap& rSa
XChangeGC( pXDisp, aGC, nValues, &aNewVal );
}
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 )
......@@ -624,9 +627,16 @@ void X11SalGraphics::drawMaskedBitmap( const SalTwoRect* pPosAry,
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
bool X11SalGraphics::drawAlphaBitmap( const SalTwoRect& rTR,
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
......@@ -648,10 +658,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;
......@@ -659,7 +671,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();
......@@ -670,13 +682,14 @@ 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;
if ( bUseAlphaBitmap ) {
// create alpha Picture
// TODO: use SalX11Bitmap functionality and caching for the Alpha Pixmap
......@@ -713,7 +726,7 @@ bool X11SalGraphics::drawAlphaBitmap( const SalTwoRect& rTR,
pAlphaBits, pAlphaBuffer->mnWidth, pAlphaBuffer->mnHeight,
pAlphaFormat->depth, pAlphaBuffer->mnScanlineSize );
Pixmap aAlphaPM = limitXCreatePixmap( pXDisplay, hDrawable_,
aAlphaPM = limitXCreatePixmap( pXDisplay, hDrawable_,
rTR.mnDestWidth, rTR.mnDestHeight, 8 );
XGCValues aAlphaGCV;
......@@ -730,21 +743,25 @@ bool X11SalGraphics::drawAlphaBitmap( const SalTwoRect& rTR,
XRenderPictureAttributes aAttr;
aAttr.repeat = true;
Picture aAlphaPic = rPeer.CreatePicture( aAlphaPM, pAlphaFormat, CPRepeat, &aAttr );
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,
rPeer.CompositePicture( PictOpOver, aSrcPic, bUseAlphaBitmap ? aAlphaPic : None, aDstPic,
rTR.mnSrcX, rTR.mnSrcY, 0, 0,
rTR.mnDestX, rTR.mnDestY, rTR.mnDestWidth, rTR.mnDestHeight );
if ( bUseAlphaBitmap )
{
rPeer.FreePicture( aAlphaPic );
XFreePixmap(pXDisplay, aAlphaPM);
XFreePixmap( pXDisplay, aAlphaPM);
}
rPeer.FreePicture( aSrcPic );
return true;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment