summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLouis-Francis Ratté-Boulianne <lfrb@collabora.com>2014-11-13 22:24:35 -0500
committerMarkus Mohrhard <markus.mohrhard@googlemail.com>2014-11-15 12:17:43 +0100
commitb190ffe58796875eceaf340501a8832e222514fb (patch)
tree1369bc5d88f7f8884d8cf2336d74798f3de45716
parentfbe77f453cc9f6840b12d10982d972d6ef276549 (diff)
vcl: Add DrawAlphaTexture to directly render Cairo surface
Change-Id: I7aa824578b14999d0ef667a5bcfccd731f1d3b64
-rw-r--r--vcl/inc/openglgdiimpl.hxx4
-rw-r--r--vcl/opengl/gdiimpl.cxx16
-rw-r--r--vcl/unx/generic/gdi/openglx11cairotextrender.cxx45
-rw-r--r--vcl/win/source/gdi/winlayout.cxx6
4 files changed, 29 insertions, 42 deletions
diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx
index c6093b589c8d..67c0c308af77 100644
--- a/vcl/inc/openglgdiimpl.hxx
+++ b/vcl/inc/openglgdiimpl.hxx
@@ -84,6 +84,7 @@ protected:
bool CreateLinearGradientProgram( void );
bool CreateRadialGradientProgram( void );
+public:
void BeginSolid( SalColor nColor, sal_uInt8 nTransparency );
void BeginSolid( SalColor nColor, double fTransparency );
void BeginSolid( SalColor nColor );
@@ -102,12 +103,13 @@ protected:
void DrawPolyPolygon( const basegfx::B2DPolyPolygon& rPolyPolygon );
void DrawTextureRect( 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 DrawMask( OpenGLTexture& rTexture, SalColor nMaskColor, const SalTwoRect& rPosAry );
void DrawLinearGradient( const Gradient& rGradient, const Rectangle& rRect );
void DrawRadialGradient( const Gradient& rGradient, const Rectangle& rRect );
-protected:
+public:
// get the width of the device
virtual GLfloat GetWidth() const = 0;
diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index 8f60489c38d2..ef0c2bd03090 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -670,6 +670,17 @@ void OpenGLSalGraphicsImpl::DrawTexture( OpenGLTexture& rTexture, const SalTwoRe
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 )
{
if( mnMaskedTextureProgram == 0 )
@@ -1301,10 +1312,7 @@ bool OpenGLSalGraphicsImpl::drawAlphaBitmap(
SAL_INFO( "vcl.opengl", "::drawAlphaBitmap" );
PreDraw();
- glEnable( GL_BLEND );
- glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
- DrawTexture( rTexture, rPosAry );
- glDisable( GL_BLEND );
+ DrawAlphaTexture( rTexture, rPosAry );
PostDraw();
CHECK_GL_ERROR();
diff --git a/vcl/unx/generic/gdi/openglx11cairotextrender.cxx b/vcl/unx/generic/gdi/openglx11cairotextrender.cxx
index 36a76b06c6ee..38a7213cd815 100644
--- a/vcl/unx/generic/gdi/openglx11cairotextrender.cxx
+++ b/vcl/unx/generic/gdi/openglx11cairotextrender.cxx
@@ -9,6 +9,7 @@
#include "openglx11cairotextrender.hxx"
+#include "openglgdiimpl.hxx"
#include "salbmp.hxx"
#include <vcl/salbtype.hxx>
@@ -33,40 +34,8 @@ void OpenGLX11CairoTextRender::drawSurface(cairo_t* cr)
cairo_surface_t* pSurface = cairo_get_target(cr);
int nWidth = cairo_image_surface_get_width( 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 );
- BitmapBuffer* pBuffer = pBitmap->AcquireBuffer(false);
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;
aRect.mnSrcX = 0;
@@ -78,8 +47,16 @@ void OpenGLX11CairoTextRender::drawSurface(cairo_t* cr)
aRect.mnDestWidth = nWidth;
aRect.mnDestHeight = nHeight;
- mrParent.drawAlphaBitmap(aRect, *pBitmap);
- delete pBitmap;
+ // XXX: lfrb: GLES 2.0 doesn't support GL_UNSIGNED_INT_8_8_8_8_REV
+ 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: */
diff --git a/vcl/win/source/gdi/winlayout.cxx b/vcl/win/source/gdi/winlayout.cxx
index 0ec756645f11..30c62ef456de 100644
--- a/vcl/win/source/gdi/winlayout.cxx
+++ b/vcl/win/source/gdi/winlayout.cxx
@@ -202,9 +202,9 @@ void WinLayout::DrawText(SalGraphics& rGraphics) const
aRects.mnDestWidth = width;
aRects.mnDestHeight = height;
- // FIXME We don't have a method that could paint a texture with
- // transparency yet, use it when we have it
- pImpl->DrawTexture(aTexture, aRects);
+ pImpl->PreDraw();
+ pImpl->DrawAlphaTexture(aTexture, aRects);
+ pImpl->PostDraw();
}
DeleteObject(hBitmap);