vcl: Add DrawAlphaTexture to directly render Cairo surface
Change-Id: I7aa824578b14999d0ef667a5bcfccd731f1d3b64
This commit is contained in:
committed by
Markus Mohrhard
parent
fbe77f453c
commit
b190ffe587
@@ -84,6 +84,7 @@ protected:
|
|||||||
bool CreateLinearGradientProgram( void );
|
bool CreateLinearGradientProgram( void );
|
||||||
bool CreateRadialGradientProgram( void );
|
bool CreateRadialGradientProgram( void );
|
||||||
|
|
||||||
|
public:
|
||||||
void BeginSolid( SalColor nColor, sal_uInt8 nTransparency );
|
void BeginSolid( SalColor nColor, sal_uInt8 nTransparency );
|
||||||
void BeginSolid( SalColor nColor, double fTransparency );
|
void BeginSolid( SalColor nColor, double fTransparency );
|
||||||
void BeginSolid( SalColor nColor );
|
void BeginSolid( SalColor nColor );
|
||||||
@@ -102,12 +103,13 @@ protected:
|
|||||||
void DrawPolyPolygon( const basegfx::B2DPolyPolygon& rPolyPolygon );
|
void DrawPolyPolygon( const basegfx::B2DPolyPolygon& rPolyPolygon );
|
||||||
void DrawTextureRect( OpenGLTexture& rTexture, const SalTwoRect& rPosAry, bool bInverted = false );
|
void DrawTextureRect( OpenGLTexture& rTexture, const SalTwoRect& rPosAry, bool bInverted = false );
|
||||||
void DrawTexture( OpenGLTexture& rTexture, const SalTwoRect& rPosAry, bool bInverted = false );
|
void DrawTexture( OpenGLTexture& rTexture, const SalTwoRect& rPosAry, bool bInverted = false );
|
||||||
|
void DrawAlphaTexture( OpenGLTexture& rTexture, const SalTwoRect& rPosAry, bool bInverted = false, bool pPremultiplied = false );
|
||||||
void DrawTextureWithMask( OpenGLTexture& rTexture, OpenGLTexture& rMask, const SalTwoRect& rPosAry );
|
void DrawTextureWithMask( OpenGLTexture& rTexture, OpenGLTexture& rMask, const SalTwoRect& rPosAry );
|
||||||
void DrawMask( OpenGLTexture& rTexture, SalColor nMaskColor, const SalTwoRect& rPosAry );
|
void DrawMask( OpenGLTexture& rTexture, SalColor nMaskColor, const SalTwoRect& rPosAry );
|
||||||
void DrawLinearGradient( const Gradient& rGradient, const Rectangle& rRect );
|
void DrawLinearGradient( const Gradient& rGradient, const Rectangle& rRect );
|
||||||
void DrawRadialGradient( const Gradient& rGradient, const Rectangle& rRect );
|
void DrawRadialGradient( const Gradient& rGradient, const Rectangle& rRect );
|
||||||
|
|
||||||
protected:
|
public:
|
||||||
// get the width of the device
|
// get the width of the device
|
||||||
virtual GLfloat GetWidth() const = 0;
|
virtual GLfloat GetWidth() const = 0;
|
||||||
|
|
||||||
|
@@ -670,6 +670,17 @@ void OpenGLSalGraphicsImpl::DrawTexture( OpenGLTexture& rTexture, const SalTwoRe
|
|||||||
CHECK_GL_ERROR();
|
CHECK_GL_ERROR();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OpenGLSalGraphicsImpl::DrawAlphaTexture( OpenGLTexture& rTexture, const SalTwoRect& rPosAry, bool bInverted, bool bPremultiplied )
|
||||||
|
{
|
||||||
|
glEnable( GL_BLEND );
|
||||||
|
if( bPremultiplied )
|
||||||
|
glBlendFunc( GL_ONE, GL_ONE_MINUS_SRC_ALPHA );
|
||||||
|
else
|
||||||
|
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
||||||
|
DrawTexture( rTexture, rPosAry, bInverted );
|
||||||
|
glDisable( GL_BLEND );
|
||||||
|
}
|
||||||
|
|
||||||
void OpenGLSalGraphicsImpl::DrawTextureWithMask( OpenGLTexture& rTexture, OpenGLTexture& rMask, const SalTwoRect& pPosAry )
|
void OpenGLSalGraphicsImpl::DrawTextureWithMask( OpenGLTexture& rTexture, OpenGLTexture& rMask, const SalTwoRect& pPosAry )
|
||||||
{
|
{
|
||||||
if( mnMaskedTextureProgram == 0 )
|
if( mnMaskedTextureProgram == 0 )
|
||||||
@@ -1301,10 +1312,7 @@ bool OpenGLSalGraphicsImpl::drawAlphaBitmap(
|
|||||||
|
|
||||||
SAL_INFO( "vcl.opengl", "::drawAlphaBitmap" );
|
SAL_INFO( "vcl.opengl", "::drawAlphaBitmap" );
|
||||||
PreDraw();
|
PreDraw();
|
||||||
glEnable( GL_BLEND );
|
DrawAlphaTexture( rTexture, rPosAry );
|
||||||
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
|
||||||
DrawTexture( rTexture, rPosAry );
|
|
||||||
glDisable( GL_BLEND );
|
|
||||||
PostDraw();
|
PostDraw();
|
||||||
|
|
||||||
CHECK_GL_ERROR();
|
CHECK_GL_ERROR();
|
||||||
|
@@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#include "openglx11cairotextrender.hxx"
|
#include "openglx11cairotextrender.hxx"
|
||||||
|
|
||||||
|
#include "openglgdiimpl.hxx"
|
||||||
#include "salbmp.hxx"
|
#include "salbmp.hxx"
|
||||||
#include <vcl/salbtype.hxx>
|
#include <vcl/salbtype.hxx>
|
||||||
|
|
||||||
@@ -33,40 +34,8 @@ void OpenGLX11CairoTextRender::drawSurface(cairo_t* cr)
|
|||||||
cairo_surface_t* pSurface = cairo_get_target(cr);
|
cairo_surface_t* pSurface = cairo_get_target(cr);
|
||||||
int nWidth = cairo_image_surface_get_width( pSurface );
|
int nWidth = cairo_image_surface_get_width( pSurface );
|
||||||
int nHeight = cairo_image_surface_get_height( pSurface );
|
int nHeight = cairo_image_surface_get_height( pSurface );
|
||||||
SalBitmap* pBitmap = ImplGetSVData()->mpDefInst->CreateSalBitmap();
|
|
||||||
pBitmap->Create(Size(nWidth, nHeight), 32, BitmapPalette());
|
|
||||||
|
|
||||||
cairo_surface_flush( pSurface );
|
cairo_surface_flush( pSurface );
|
||||||
BitmapBuffer* pBuffer = pBitmap->AcquireBuffer(false);
|
|
||||||
unsigned char *pSrc = cairo_image_surface_get_data( pSurface );
|
unsigned char *pSrc = cairo_image_surface_get_data( pSurface );
|
||||||
unsigned int nSrcStride = cairo_image_surface_get_stride( pSurface );
|
|
||||||
unsigned int nDestStride = pBuffer->mnScanlineSize;
|
|
||||||
for( unsigned long y = 0; y < (unsigned long) nHeight; y++ )
|
|
||||||
{
|
|
||||||
// Cairo surface is y-inverse
|
|
||||||
sal_uInt32 *pSrcPix = (sal_uInt32 *)(pSrc + nSrcStride * (nHeight - y - 1));
|
|
||||||
sal_uInt32 *pDestPix = (sal_uInt32 *)(pBuffer->mpBits + nDestStride * y);
|
|
||||||
for( unsigned long x = 0; x < (unsigned long) nWidth; x++ )
|
|
||||||
{
|
|
||||||
sal_uInt8 nAlpha = (*pSrcPix >> 24);
|
|
||||||
sal_uInt8 nR = (*pSrcPix >> 16) & 0xff;
|
|
||||||
sal_uInt8 nG = (*pSrcPix >> 8) & 0xff;
|
|
||||||
sal_uInt8 nB = *pSrcPix & 0xff;
|
|
||||||
if( nAlpha != 0 && nAlpha != 255 )
|
|
||||||
{
|
|
||||||
// Cairo uses pre-multiplied alpha - we do not => re-multiply
|
|
||||||
nR = (sal_uInt8) MinMax( ((sal_uInt32)nR * 255) / nAlpha, 0, 255 );
|
|
||||||
nG = (sal_uInt8) MinMax( ((sal_uInt32)nG * 255) / nAlpha, 0, 255 );
|
|
||||||
nB = (sal_uInt8) MinMax( ((sal_uInt32)nB * 255) / nAlpha, 0, 255 );
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: lfrb: depends on endianness (use BitmapWriteAccess)
|
|
||||||
*pDestPix = (nAlpha << 24) + (nB << 16) + (nG << 8) + nR;
|
|
||||||
pSrcPix++;
|
|
||||||
pDestPix++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pBitmap->ReleaseBuffer(pBuffer, false);
|
|
||||||
|
|
||||||
SalTwoRect aRect;
|
SalTwoRect aRect;
|
||||||
aRect.mnSrcX = 0;
|
aRect.mnSrcX = 0;
|
||||||
@@ -78,8 +47,16 @@ void OpenGLX11CairoTextRender::drawSurface(cairo_t* cr)
|
|||||||
aRect.mnDestWidth = nWidth;
|
aRect.mnDestWidth = nWidth;
|
||||||
aRect.mnDestHeight = nHeight;
|
aRect.mnDestHeight = nHeight;
|
||||||
|
|
||||||
mrParent.drawAlphaBitmap(aRect, *pBitmap);
|
// XXX: lfrb: GLES 2.0 doesn't support GL_UNSIGNED_INT_8_8_8_8_REV
|
||||||
delete pBitmap;
|
OpenGLSalGraphicsImpl *pImpl = dynamic_cast< OpenGLSalGraphicsImpl* >(mrParent.GetImpl());
|
||||||
|
if( pImpl )
|
||||||
|
{
|
||||||
|
// Cairo surface data is ARGB with premultiplied alpha and is Y-inverted
|
||||||
|
OpenGLTexture aTexture( nWidth, nHeight, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, pSrc );
|
||||||
|
pImpl->PreDraw();
|
||||||
|
pImpl->DrawAlphaTexture( aTexture, aRect, true, true );
|
||||||
|
pImpl->PostDraw();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
||||||
|
@@ -202,9 +202,9 @@ void WinLayout::DrawText(SalGraphics& rGraphics) const
|
|||||||
aRects.mnDestWidth = width;
|
aRects.mnDestWidth = width;
|
||||||
aRects.mnDestHeight = height;
|
aRects.mnDestHeight = height;
|
||||||
|
|
||||||
// FIXME We don't have a method that could paint a texture with
|
pImpl->PreDraw();
|
||||||
// transparency yet, use it when we have it
|
pImpl->DrawAlphaTexture(aTexture, aRects);
|
||||||
pImpl->DrawTexture(aTexture, aRects);
|
pImpl->PostDraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
DeleteObject(hBitmap);
|
DeleteObject(hBitmap);
|
||||||
|
Reference in New Issue
Block a user