diff options
author | Louis-Francis Ratté-Boulianne <lfrb@collabora.com> | 2014-11-13 22:24:35 -0500 |
---|---|---|
committer | Markus Mohrhard <markus.mohrhard@googlemail.com> | 2014-11-15 12:17:43 +0100 |
commit | b190ffe58796875eceaf340501a8832e222514fb (patch) | |
tree | 1369bc5d88f7f8884d8cf2336d74798f3de45716 | |
parent | fbe77f453cc9f6840b12d10982d972d6ef276549 (diff) |
vcl: Add DrawAlphaTexture to directly render Cairo surface
Change-Id: I7aa824578b14999d0ef667a5bcfccd731f1d3b64
-rw-r--r-- | vcl/inc/openglgdiimpl.hxx | 4 | ||||
-rw-r--r-- | vcl/opengl/gdiimpl.cxx | 16 | ||||
-rw-r--r-- | vcl/unx/generic/gdi/openglx11cairotextrender.cxx | 45 | ||||
-rw-r--r-- | vcl/win/source/gdi/winlayout.cxx | 6 |
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); |