diff options
author | Louis-Francis Ratté-Boulianne <lfrb@collabora.com> | 2014-11-18 12:34:53 -0500 |
---|---|---|
committer | Jan Holesovsky <kendy@collabora.com> | 2014-11-22 20:14:16 +0100 |
commit | 4b6feefa51405e1313de62e1a19c4c213e79c22f (patch) | |
tree | 13796bcb39957f93c01bf338fc605204027bee48 | |
parent | 121b8487f13b4ac3e3a9517a02000c9fe55afd68 (diff) |
vcl: Add support for backend-dependent blending of bitmaps (mask and alpha)
Change-Id: Iba64eb42965c86ca5655b9a105ef3f397e033ecf
-rw-r--r-- | include/vcl/outdev.hxx | 4 | ||||
-rw-r--r-- | vcl/Package_opengl.mk | 2 | ||||
-rw-r--r-- | vcl/generic/print/genpspgraphics.cxx | 10 | ||||
-rw-r--r-- | vcl/headless/svpgdi.cxx | 10 | ||||
-rw-r--r-- | vcl/inc/generic/genpspgraphics.h | 6 | ||||
-rw-r--r-- | vcl/inc/headless/svpgdi.hxx | 5 | ||||
-rw-r--r-- | vcl/inc/openglgdiimpl.hxx | 17 | ||||
-rw-r--r-- | vcl/inc/quartz/salgdi.h | 8 | ||||
-rw-r--r-- | vcl/inc/salgdi.hxx | 24 | ||||
-rw-r--r-- | vcl/inc/salgdiimpl.hxx | 10 | ||||
-rw-r--r-- | vcl/inc/unx/salgdi.h | 8 | ||||
-rw-r--r-- | vcl/inc/win/salgdi.h | 8 | ||||
-rw-r--r-- | vcl/opengl/blendedTextureFragmentShader.glsl | 27 | ||||
-rw-r--r-- | vcl/opengl/blendedTextureVertexShader.glsl | 22 | ||||
-rw-r--r-- | vcl/opengl/gdiimpl.cxx | 107 | ||||
-rw-r--r-- | vcl/quartz/salgdicommon.cxx | 14 | ||||
-rw-r--r-- | vcl/source/gdi/salgdilayout.cxx | 30 | ||||
-rw-r--r-- | vcl/source/outdev/bitmap.cxx | 27 | ||||
-rw-r--r-- | vcl/unx/generic/gdi/gdiimpl.cxx | 12 | ||||
-rw-r--r-- | vcl/unx/generic/gdi/gdiimpl.hxx | 12 | ||||
-rw-r--r-- | vcl/unx/generic/gdi/salgdi2.cxx | 14 | ||||
-rw-r--r-- | vcl/win/source/gdi/gdiimpl.cxx | 16 | ||||
-rw-r--r-- | vcl/win/source/gdi/gdiimpl.hxx | 10 | ||||
-rw-r--r-- | vcl/win/source/gdi/salgdi_gdiplus.cxx | 16 |
24 files changed, 414 insertions, 5 deletions
diff --git a/include/vcl/outdev.hxx b/include/vcl/outdev.hxx index 19c43eddda18..a5b575132146 100644 --- a/include/vcl/outdev.hxx +++ b/include/vcl/outdev.hxx @@ -1407,6 +1407,10 @@ private: const Point& rSrcPtPixel, const Size& rSrcSizePixel ); + SAL_DLLPRIVATE bool BlendBitmap( + const SalTwoRect& rPosAry, + const Bitmap& rBmp ); + SAL_DLLPRIVATE Bitmap BlendBitmap( Bitmap& aBmp, BitmapReadAccess* pP, diff --git a/vcl/Package_opengl.mk b/vcl/Package_opengl.mk index 9151d94b675d..4a4f30fa9d1d 100644 --- a/vcl/Package_opengl.mk +++ b/vcl/Package_opengl.mk @@ -10,6 +10,8 @@ $(eval $(call gb_Package_Package,vcl_opengl_shader,$(SRCDIR)/vcl/opengl)) $(eval $(call gb_Package_add_files,vcl_opengl_shader,$(LIBO_ETC_FOLDER)/opengl,\ + blendedTextureFragmentShader.glsl \ + blendedTextureVertexShader.glsl \ convolutionFragmentShader.glsl \ linearGradientFragmentShader.glsl \ maskFragmentShader.glsl \ diff --git a/vcl/generic/print/genpspgraphics.cxx b/vcl/generic/print/genpspgraphics.cxx index db904da984cf..f548cee834dc 100644 --- a/vcl/generic/print/genpspgraphics.cxx +++ b/vcl/generic/print/genpspgraphics.cxx @@ -1166,6 +1166,16 @@ void GenPspGraphics::AnnounceFonts( PhysicalFontCollection* pFontCollection, con pFontCollection->Add( pFD ); } +bool GenPspGraphics::blendBitmap( const SalTwoRect&, const SalBitmap& ) +{ + return false; +} + +bool GenPspGraphics::blendAlphaBitmap( const SalTwoRect&, const SalBitmap&, const SalBitmap&, const SalBitmap& ) +{ + return false; +} + bool GenPspGraphics::drawAlphaBitmap( const SalTwoRect&, const SalBitmap&, const SalBitmap& ) diff --git a/vcl/headless/svpgdi.cxx b/vcl/headless/svpgdi.cxx index 9ad4c7bccdad..a72c901714a6 100644 --- a/vcl/headless/svpgdi.cxx +++ b/vcl/headless/svpgdi.cxx @@ -61,6 +61,16 @@ rDevice #ifndef IOS +bool SvpSalGraphics::blendBitmap( const SalTwoRect&, const SalBitmap& /*rBitmap*/ ) +{ + return false; +} + +bool SvpSalGraphics::blendAlphaBitmap( const SalTwoRect&, const SalBitmap&, const SalBitmap&, const SalBitmap& ) +{ + return false; +} + bool SvpSalGraphics::drawAlphaBitmap( const SalTwoRect&, const SalBitmap& /*rSourceBitmap*/, const SalBitmap& /*rAlphaBitmap*/ ) { // TODO(P3) implement alpha blending diff --git a/vcl/inc/generic/genpspgraphics.h b/vcl/inc/generic/genpspgraphics.h index 382a69300e41..18a434fa67b5 100644 --- a/vcl/inc/generic/genpspgraphics.h +++ b/vcl/inc/generic/genpspgraphics.h @@ -180,6 +180,12 @@ public: virtual bool drawEPS( long nX, long nY, long nWidth, long nHeight, void* pPtr, sal_uIntPtr nSize ) SAL_OVERRIDE; + virtual bool blendBitmap( const SalTwoRect&, + const SalBitmap& rBitmap ) SAL_OVERRIDE; + virtual bool blendAlphaBitmap( const SalTwoRect&, + const SalBitmap& rSrcBitmap, + const SalBitmap& rMaskBitmap, + const SalBitmap& rAlphaBitmap ) SAL_OVERRIDE; virtual bool drawAlphaBitmap( const SalTwoRect&, const SalBitmap& rSourceBitmap, const SalBitmap& rAlphaBitmap ) SAL_OVERRIDE; diff --git a/vcl/inc/headless/svpgdi.hxx b/vcl/inc/headless/svpgdi.hxx index 4da3ffa1a59b..9ae3d0539796 100644 --- a/vcl/inc/headless/svpgdi.hxx +++ b/vcl/inc/headless/svpgdi.hxx @@ -124,6 +124,11 @@ protected: vcl::Region m_aClipRegion; protected: + virtual bool blendBitmap( const SalTwoRect&, const SalBitmap& rBitmap ) SAL_OVERRIDE; + virtual bool blendAlphaBitmap( const SalTwoRect&, + const SalBitmap& rSrcBitmap, + const SalBitmap& rMaskBitmap, + const SalBitmap& rAlphaBitmap ) SAL_OVERRIDE; virtual bool drawAlphaBitmap( const SalTwoRect&, const SalBitmap& rSourceBitmap, const SalBitmap& rAlphaBitmap ) SAL_OVERRIDE; virtual bool drawTransformedBitmap( const basegfx::B2DPoint& rNull, diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx index 5e4af511ef77..b26e10ce7ae0 100644 --- a/vcl/inc/openglgdiimpl.hxx +++ b/vcl/inc/openglgdiimpl.hxx @@ -71,6 +71,11 @@ protected: GLuint mnMaskedSamplerUniform; GLuint mnMaskSamplerUniform; + GLuint mnBlendedTextureProgram; + GLuint mnBlendedTextureUniform; + GLuint mnBlendedMaskUniform; + GLuint mnBlendedAlphaUniform; + GLuint mnMaskProgram; GLuint mnMaskUniform; GLuint mnMaskColorUniform; @@ -92,6 +97,7 @@ protected: bool CreateTextureProgram( void ); bool CreateTransformedTextureProgram( void ); bool CreateMaskedTextureProgram( void ); + bool CreateBlendedTextureProgram( void ); bool CreateTransformedMaskedTextureProgram( void ); bool CreateMaskProgram( void ); bool CreateLinearGradientProgram( void ); @@ -119,6 +125,7 @@ public: void DrawTransformedTexture( OpenGLTexture& rTexture, OpenGLTexture& rMask, const basegfx::B2DPoint& rNull, const basegfx::B2DPoint& rX, const basegfx::B2DPoint& rY ); void DrawAlphaTexture( OpenGLTexture& rTexture, const SalTwoRect& rPosAry, bool bInverted = false, bool pPremultiplied = false ); void DrawTextureWithMask( OpenGLTexture& rTexture, OpenGLTexture& rMask, const SalTwoRect& rPosAry ); + void DrawBlendedTexture( OpenGLTexture& rTexture, OpenGLTexture& rMask, OpenGLTexture& rAlpha, const SalTwoRect& rPosAry ); void DrawMask( OpenGLTexture& rTexture, SalColor nMaskColor, const SalTwoRect& rPosAry ); void DrawLinearGradient( const Gradient& rGradient, const Rectangle& rRect ); void DrawAxialGradient( const Gradient& rGradient, const Rectangle& rRect ); @@ -232,6 +239,16 @@ public: // CopyBits() --> pSrcGraphics == NULL, then CopyBits on same Graphics void DoCopyBits(const SalTwoRect& rPosAry, OpenGLSalGraphicsImpl &rSrcImpl); + virtual bool blendBitmap( + const SalTwoRect&, + const SalBitmap& rBitmap ) SAL_OVERRIDE; + + virtual bool blendAlphaBitmap( + const SalTwoRect&, + const SalBitmap& rSrcBitmap, + const SalBitmap& rMaskBitmap, + const SalBitmap& rAlphaBitmap ) SAL_OVERRIDE; + virtual void drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap ) SAL_OVERRIDE; virtual void drawBitmap( diff --git a/vcl/inc/quartz/salgdi.h b/vcl/inc/quartz/salgdi.h index d25b09373ff3..9a5d4da8ab05 100644 --- a/vcl/inc/quartz/salgdi.h +++ b/vcl/inc/quartz/salgdi.h @@ -268,6 +268,14 @@ public: virtual bool drawEPS( long nX, long nY, long nWidth, long nHeight, void* pPtr, sal_uLong nSize ) SAL_OVERRIDE; + virtual bool blendBitmap( const SalTwoRect&, + const SalBitmap& rBitmap ) SAL_OVERRIDE; + + virtual bool blendAlphaBitmap( const SalTwoRect&, + const SalBitmap& rSrcBitmap, + const SalBitmap& rMaskBitmap, + const SalBitmap& rAlphaBitmap ) SAL_OVERRIDE; + virtual bool drawAlphaBitmap( const SalTwoRect&, const SalBitmap& rSourceBitmap, const SalBitmap& rAlphaBitmap ) SAL_OVERRIDE; diff --git a/vcl/inc/salgdi.hxx b/vcl/inc/salgdi.hxx index 95920a050157..ff6271c8d88c 100644 --- a/vcl/inc/salgdi.hxx +++ b/vcl/inc/salgdi.hxx @@ -399,6 +399,18 @@ public: Rectangle &rNativeContentRegion, const OutputDevice *pOutDev ); + bool BlendBitmap( + const SalTwoRect& rPosAry, + const SalBitmap& rSalBitmap, + const OutputDevice *pOutDev ); + + bool BlendAlphaBitmap( + const SalTwoRect& rPosAry, + const SalBitmap& rSalSrcBitmap, + const SalBitmap& rSalMaskBitmap, + const SalBitmap& rSalAlphaBitmap, + const OutputDevice *pOutDev ); + bool DrawAlphaBitmap( const SalTwoRect&, const SalBitmap& rSourceBitmap, @@ -541,6 +553,18 @@ protected: Rectangle &rNativeBoundingRegion, Rectangle &rNativeContentRegion ); + /** Blend the bitmap with the current buffer */ + virtual bool blendBitmap( + const SalTwoRect&, + const SalBitmap& rBitmap ) = 0; + + /** Draw the bitmap by blending using the mask and alpha channel */ + virtual bool blendAlphaBitmap( + const SalTwoRect&, + const SalBitmap& rSrcBitmap, + const SalBitmap& rMaskBitmap, + const SalBitmap& rAlphaBitmap ) = 0; + /** Render bitmap with alpha channel @param rSourceBitmap diff --git a/vcl/inc/salgdiimpl.hxx b/vcl/inc/salgdiimpl.hxx index 09ea28fdc92b..2fd7f56df28e 100644 --- a/vcl/inc/salgdiimpl.hxx +++ b/vcl/inc/salgdiimpl.hxx @@ -164,6 +164,16 @@ public: void* pPtr, sal_uLong nSize ) = 0; + virtual bool blendBitmap( + const SalTwoRect&, + const SalBitmap& rBitmap ) = 0; + + virtual bool blendAlphaBitmap( + const SalTwoRect&, + const SalBitmap& rSrcBitmap, + const SalBitmap& rMaskBitmap, + const SalBitmap& rAlphaBitmap ) = 0; + /** Render bitmap with alpha channel @param rSourceBitmap diff --git a/vcl/inc/unx/salgdi.h b/vcl/inc/unx/salgdi.h index 5caf7b944840..97f9d60c8dde 100644 --- a/vcl/inc/unx/salgdi.h +++ b/vcl/inc/unx/salgdi.h @@ -249,6 +249,14 @@ public: virtual bool drawEPS( long nX, long nY, long nWidth, long nHeight, void* pPtr, sal_uIntPtr nSize ) SAL_OVERRIDE; + virtual bool blendBitmap( const SalTwoRect&, + const SalBitmap& rBitmap ) SAL_OVERRIDE; + + virtual bool blendAlphaBitmap( const SalTwoRect&, + const SalBitmap& rSrcBitmap, + const SalBitmap& rMaskBitmap, + const SalBitmap& rAlphaBitmap ) SAL_OVERRIDE; + virtual bool drawAlphaBitmap( const SalTwoRect&, const SalBitmap& rSourceBitmap, const SalBitmap& rAlphaBitmap ) SAL_OVERRIDE; diff --git a/vcl/inc/win/salgdi.h b/vcl/inc/win/salgdi.h index 8d88784c805f..1af78077584c 100644 --- a/vcl/inc/win/salgdi.h +++ b/vcl/inc/win/salgdi.h @@ -312,6 +312,14 @@ protected: const ImplControlValue& aValue, const OUString& aCaption, Rectangle &rNativeBoundingRegion, Rectangle &rNativeContentRegion ); + virtual bool blendBitmap( const SalTwoRect&, + const SalBitmap& rBitmap ) SAL_OVERRIDE; + + virtual bool blendAlphaBitmap( const SalTwoRect&, + const SalBitmap& rSrcBitmap, + const SalBitmap& rMaskBitmap, + const SalBitmap& rAlphaBitmap ) SAL_OVERRIDE; + virtual bool drawAlphaBitmap( const SalTwoRect&, const SalBitmap& rSourceBitmap, const SalBitmap& rAlphaBitmap ); diff --git a/vcl/opengl/blendedTextureFragmentShader.glsl b/vcl/opengl/blendedTextureFragmentShader.glsl new file mode 100644 index 000000000000..b46f6ce5fb9d --- /dev/null +++ b/vcl/opengl/blendedTextureFragmentShader.glsl @@ -0,0 +1,27 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +varying vec2 tex_coord; +varying vec2 alpha_coord; +uniform sampler2D sampler; +uniform sampler2D mask; +uniform sampler2D alpha; + +void main() { + vec4 texel0, texel1, texel2; + texel0 = texture2D(sampler, tex_coord); + texel1 = texture2D(mask, tex_coord); + texel2 = texture2D(alpha, alpha_coord); + gl_FragColor = texel0; + + /* Only blend if the the alpha texture wasn't fully transparent */ + gl_FragColor.a = 1.0 - (1.0 - floor(texel2.r)) * texel1.r; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/opengl/blendedTextureVertexShader.glsl b/vcl/opengl/blendedTextureVertexShader.glsl new file mode 100644 index 000000000000..bc8972c271d0 --- /dev/null +++ b/vcl/opengl/blendedTextureVertexShader.glsl @@ -0,0 +1,22 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +attribute vec4 position; +attribute vec2 tex_coord_in; +attribute vec2 alpha_coord_in; +varying vec2 tex_coord; +varying vec2 alpha_coord; + +void main() { + gl_Position = position; + tex_coord = tex_coord_in; + alpha_coord = alpha_coord_in; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx index c34d085b2537..bf7406fee372 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -37,8 +37,9 @@ #include <glm/gtc/type_ptr.hpp> #include <vector> -#define GL_ATTRIB_POS 0 -#define GL_ATTRIB_TEX 1 +#define GL_ATTRIB_POS 0 +#define GL_ATTRIB_TEX 1 +#define GL_ATTRIB_TEX2 2 #define glUniformColor(nUniform, nColor, nTransparency) \ glUniform4f( nUniform, \ @@ -86,6 +87,10 @@ OpenGLSalGraphicsImpl::OpenGLSalGraphicsImpl() , mnMaskedTextureProgram(0) , mnMaskedSamplerUniform(0) , mnMaskSamplerUniform(0) + , mnBlendedTextureProgram(0) + , mnBlendedTextureUniform(0) + , mnBlendedMaskUniform(0) + , mnBlendedAlphaUniform(0) , mnMaskProgram(0) , mnMaskUniform(0) , mnMaskColorUniform(0) @@ -399,6 +404,23 @@ bool OpenGLSalGraphicsImpl::CreateTransformedMaskedTextureProgram( void ) return true; } +bool OpenGLSalGraphicsImpl::CreateBlendedTextureProgram( void ) +{ + mnBlendedTextureProgram = OpenGLHelper::LoadShaders( "blendedTextureVertexShader", "blendedTextureFragmentShader" ); + if( mnBlendedTextureProgram == 0 ) + return false; + + glBindAttribLocation( mnBlendedTextureProgram, GL_ATTRIB_POS, "position" ); + glBindAttribLocation( mnBlendedTextureProgram, GL_ATTRIB_TEX, "tex_coord_in" ); + glBindAttribLocation( mnBlendedTextureProgram, GL_ATTRIB_TEX2, "alpha_coord_in" ); + mnBlendedTextureUniform = glGetUniformLocation( mnBlendedTextureProgram, "sampler" ); + mnBlendedMaskUniform = glGetUniformLocation( mnBlendedTextureProgram, "mask" ); + mnBlendedAlphaUniform = glGetUniformLocation( mnBlendedTextureProgram, "alpha" ); + + CHECK_GL_ERROR(); + return true; +} + bool OpenGLSalGraphicsImpl::CreateMaskProgram( void ) { mnMaskProgram = OpenGLHelper::LoadShaders( "maskVertexShader", "maskFragmentShader" ); @@ -849,6 +871,50 @@ void OpenGLSalGraphicsImpl::DrawTextureWithMask( OpenGLTexture& rTexture, OpenGL CHECK_GL_ERROR(); } +void OpenGLSalGraphicsImpl::DrawBlendedTexture( OpenGLTexture& rTexture, OpenGLTexture& rMask, OpenGLTexture& rAlpha, const SalTwoRect& rPosAry ) +{ + GLfloat aTexCoord[8]; + + if( mnBlendedTextureProgram == 0 ) + { + if( !CreateBlendedTextureProgram() ) + return; + } + + glUseProgram( mnBlendedTextureProgram ); + glUniform1i( mnBlendedTextureUniform, 0 ); + glUniform1i( mnBlendedMaskUniform, 1 ); + glUniform1i( mnBlendedAlphaUniform, 2 ); + glActiveTexture( GL_TEXTURE0 ); + rTexture.Bind(); + glActiveTexture( GL_TEXTURE1 ); + rMask.Bind(); + glActiveTexture( GL_TEXTURE2 ); + rAlpha.Bind(); + + rAlpha.GetCoord( aTexCoord, rPosAry ); + glEnableVertexAttribArray( GL_ATTRIB_TEX2 ); + glVertexAttribPointer( GL_ATTRIB_TEX2, 2, GL_FLOAT, GL_FALSE, 0, aTexCoord ); + + glEnable( GL_BLEND ); + glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); + DrawTextureRect( rTexture, rPosAry ); + glDisable( GL_BLEND ); + + glDisableVertexAttribArray( GL_ATTRIB_TEX2 ); + + glActiveTexture( GL_TEXTURE0 ); + rTexture.Unbind(); + glActiveTexture( GL_TEXTURE1 ); + rMask.Unbind(); + glActiveTexture( GL_TEXTURE2 ); + rAlpha.Unbind(); + glActiveTexture( GL_TEXTURE0 ); + glUseProgram( 0 ); + + CHECK_GL_ERROR(); +} + void OpenGLSalGraphicsImpl::DrawMask( OpenGLTexture& rMask, SalColor nMaskColor, const SalTwoRect& pPosAry ) { if( mnMaskProgram == 0 ) @@ -1475,6 +1541,43 @@ bool OpenGLSalGraphicsImpl::drawEPS( return false; } +bool OpenGLSalGraphicsImpl::blendBitmap( + const SalTwoRect& rPosAry, + const SalBitmap& rSalBitmap ) +{ + const OpenGLSalBitmap& rBitmap = static_cast<const OpenGLSalBitmap&>(rSalBitmap); + OpenGLTexture& rTexture( rBitmap.GetTexture() ); + + SAL_INFO( "vcl.opengl", "::blendBitmap" ); + PreDraw(); + glEnable( GL_BLEND ); + glBlendFunc( GL_ZERO, GL_SRC_COLOR ); + DrawTexture( rTexture, rPosAry ); + glDisable( GL_BLEND ); + PostDraw(); + return true; +} + +bool OpenGLSalGraphicsImpl::blendAlphaBitmap( + const SalTwoRect& rPosAry, + const SalBitmap& rSalSrcBitmap, + const SalBitmap& rSalMaskBitmap, + const SalBitmap& rSalAlphaBitmap ) +{ + const OpenGLSalBitmap& rSrcBitmap = static_cast<const OpenGLSalBitmap&>(rSalSrcBitmap); + const OpenGLSalBitmap& rMaskBitmap = static_cast<const OpenGLSalBitmap&>(rSalMaskBitmap); + const OpenGLSalBitmap& rAlphaBitmap = static_cast<const OpenGLSalBitmap&>(rSalAlphaBitmap); + OpenGLTexture& rTexture( rSrcBitmap.GetTexture() ); + OpenGLTexture& rMask( rMaskBitmap.GetTexture() ); + OpenGLTexture& rAlpha( rAlphaBitmap.GetTexture() ); + + SAL_INFO( "vcl.opengl", "::blendAlphaBitmap" ); + PreDraw(); + DrawBlendedTexture( rTexture, rMask, rAlpha, rPosAry ); + PostDraw(); + return true; +} + /** Render bitmap with alpha channel @param rSourceBitmap diff --git a/vcl/quartz/salgdicommon.cxx b/vcl/quartz/salgdicommon.cxx index 6a8d953a32e2..21c8d2a1ea5d 100644 --- a/vcl/quartz/salgdicommon.cxx +++ b/vcl/quartz/salgdicommon.cxx @@ -562,6 +562,20 @@ void AquaSalGraphics::copyResolution( AquaSalGraphics& rGraphics ) #endif +bool AquaSalGraphics::blendBitmap( const SalTwoRect&, + const SalBitmap& ) +{ + return false; +} + +bool AquaSalGraphics::blendAlphaBitmap( const SalTwoRect&, + const SalBitmap&, + const SalBitmap&, + const SalBitmap& ) +{ + return false; +} + bool AquaSalGraphics::drawAlphaBitmap( const SalTwoRect& rTR, const SalBitmap& rSrcBitmap, const SalBitmap& rAlphaBmp ) diff --git a/vcl/source/gdi/salgdilayout.cxx b/vcl/source/gdi/salgdilayout.cxx index 59b39ced9cee..dc419a0b7ef4 100644 --- a/vcl/source/gdi/salgdilayout.cxx +++ b/vcl/source/gdi/salgdilayout.cxx @@ -738,6 +738,36 @@ bool SalGraphics::GetNativeControlRegion( ControlType nType, ControlPart nPart, rNativeBoundingRegion, rNativeContentRegion ); } +bool SalGraphics::BlendBitmap( const SalTwoRect& rPosAry, + const SalBitmap& rBitmap, + const OutputDevice *pOutDev ) +{ + if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (pOutDev && pOutDev->IsRTLEnabled()) ) + { + SalTwoRect aPosAry2 = rPosAry; + mirror( aPosAry2.mnDestX, aPosAry2.mnDestWidth, pOutDev ); + return blendBitmap( aPosAry2, rBitmap ); + } + else + return blendBitmap( rPosAry, rBitmap ); +} + +bool SalGraphics::BlendAlphaBitmap( const SalTwoRect& rPosAry, + const SalBitmap& rSrcBitmap, + const SalBitmap& rMaskBitmap, + const SalBitmap& rAlphaBitmap, + const OutputDevice *pOutDev ) +{ + if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (pOutDev && pOutDev->IsRTLEnabled()) ) + { + SalTwoRect aPosAry2 = rPosAry; + mirror( aPosAry2.mnDestX, aPosAry2.mnDestWidth, pOutDev ); + return blendAlphaBitmap( aPosAry2, rSrcBitmap, rMaskBitmap, rAlphaBitmap ); + } + else + return blendAlphaBitmap( rPosAry, rSrcBitmap, rMaskBitmap, rAlphaBitmap ); +} + bool SalGraphics::DrawAlphaBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSourceBitmap, const SalBitmap& rAlphaBitmap, diff --git a/vcl/source/outdev/bitmap.cxx b/vcl/source/outdev/bitmap.cxx index 93a04b850372..cb7d594aea89 100644 --- a/vcl/source/outdev/bitmap.cxx +++ b/vcl/source/outdev/bitmap.cxx @@ -648,7 +648,7 @@ void OutputDevice::DrawDeviceAlphaBitmap( const Bitmap& rBmp, const AlphaMask& r static const char* pDisableNative = getenv( "SAL_DISABLE_NATIVE_ALPHA"); // #i83087# Naturally, system alpha blending cannot work with // separate alpha VDev - bool bTryDirectPaint(!mpAlphaVDev && !pDisableNative && !bHMirr && !bVMirr); + bool bTryDirectPaint(!pDisableNative && !bHMirr && !bVMirr); if(bTryDirectPaint) { @@ -662,8 +662,22 @@ void OutputDevice::DrawDeviceAlphaBitmap( const Bitmap& rBmp, const AlphaMask& r SalBitmap* pSalSrcBmp = rBmp.ImplGetImpBitmap()->ImplGetSalBitmap(); SalBitmap* pSalAlphaBmp = rAlpha.ImplGetImpBitmap()->ImplGetSalBitmap(); - if (mpGraphics->DrawAlphaBitmap( aTR, *pSalSrcBmp, *pSalAlphaBmp, this )) - return; + // try the blen the alpha bitmap with the alpha virtual device + if( mpAlphaVDev ) + { + Bitmap aAlphaBitmap( mpAlphaVDev->GetBitmap( aRelPt, aOutSz ) ); + SalBitmap* pSalAlphaBmp2 = aAlphaBitmap.ImplGetImpBitmap()->ImplGetSalBitmap(); + if( mpGraphics->BlendAlphaBitmap( aTR, *pSalSrcBmp, *pSalAlphaBmp, *pSalAlphaBmp2, this ) ) + { + mpAlphaVDev->BlendBitmap( aTR, rAlpha ); + return; + } + } + else + { + if (mpGraphics->DrawAlphaBitmap( aTR, *pSalSrcBmp, *pSalAlphaBmp, this )) + return; + } } // we need to make sure OpenGL never reaches this slow code path @@ -1194,6 +1208,13 @@ namespace } } +bool OutputDevice::BlendBitmap( + const SalTwoRect& rPosAry, + const Bitmap& rBmp ) +{ + return mpGraphics->BlendBitmap( rPosAry, *rBmp.ImplGetImpBitmap()->ImplGetSalBitmap(), this ); +} + Bitmap OutputDevice::BlendBitmapWithAlpha( Bitmap& aBmp, BitmapReadAccess* pP, diff --git a/vcl/unx/generic/gdi/gdiimpl.cxx b/vcl/unx/generic/gdi/gdiimpl.cxx index ee7e596fbc95..bcf8d0523abd 100644 --- a/vcl/unx/generic/gdi/gdiimpl.cxx +++ b/vcl/unx/generic/gdi/gdiimpl.cxx @@ -821,6 +821,18 @@ void X11SalGraphicsImpl::drawMaskedBitmap( const SalTwoRect& rPosAry, XFreePixmap( pXDisp, aBG ); } +bool X11SalGraphicsImpl::blendBitmap( const SalTwoRect&, + const SalBitmap& ) +{ + return false; +} + +bool X11SalGraphicsImpl::blendAlphaBitmap( const SalTwoRect&, + const SalBitmap&, const SalBitmap&, const SalBitmap& ) +{ + return false; +} + bool X11SalGraphicsImpl::drawAlphaBitmap( const SalTwoRect& rTR, const SalBitmap& rSrcBitmap, const SalBitmap& rAlphaBmp ) { diff --git a/vcl/unx/generic/gdi/gdiimpl.hxx b/vcl/unx/generic/gdi/gdiimpl.hxx index 2d9294a629d9..20c995fa6a7e 100644 --- a/vcl/unx/generic/gdi/gdiimpl.hxx +++ b/vcl/unx/generic/gdi/gdiimpl.hxx @@ -225,6 +225,18 @@ public: void* pPtr, sal_uLong nSize ) SAL_OVERRIDE; + /** Blend bitmap with color channels */ + virtual bool blendBitmap( + const SalTwoRect&, + const SalBitmap& rBitmap ) SAL_OVERRIDE; + + /** Render bitmap by blending using the mask and alpha channel */ + virtual bool blendAlphaBitmap( + const SalTwoRect&, + const SalBitmap& rSrcBitmap, + const SalBitmap& rMaskBitmap, + const SalBitmap& rAlphaBitmap ) SAL_OVERRIDE; + /** Render bitmap with alpha channel @param rSourceBitmap diff --git a/vcl/unx/generic/gdi/salgdi2.cxx b/vcl/unx/generic/gdi/salgdi2.cxx index 9ef50b87c747..b848d660447b 100644 --- a/vcl/unx/generic/gdi/salgdi2.cxx +++ b/vcl/unx/generic/gdi/salgdi2.cxx @@ -167,6 +167,20 @@ void X11SalGraphics::copyArea ( long nDestX, long nDestY, mpImpl->copyArea( nDestX, nDestY, nSrcX, nSrcY, nSrcWidth, nSrcHeight, n ); } +bool X11SalGraphics::blendBitmap( const SalTwoRect& rTR, + const SalBitmap& rBitmap ) +{ + return mpImpl->blendBitmap( rTR, rBitmap ); +} + +bool X11SalGraphics::blendAlphaBitmap( const SalTwoRect& rTR, + const SalBitmap& rSrcBitmap, + const SalBitmap& rMaskBitmap, + const SalBitmap& rAlphaBitmap ) +{ + return mpImpl->blendAlphaBitmap( rTR, rSrcBitmap, rMaskBitmap, rAlphaBitmap ); +} + void X11SalGraphics::drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap ) { mpImpl->drawBitmap( rPosAry, rSalBitmap ); diff --git a/vcl/win/source/gdi/gdiimpl.cxx b/vcl/win/source/gdi/gdiimpl.cxx index 03ad55465fd2..8a4b39062363 100644 --- a/vcl/win/source/gdi/gdiimpl.cxx +++ b/vcl/win/source/gdi/gdiimpl.cxx @@ -2252,6 +2252,22 @@ bool WinSalGraphicsImpl::tryDrawBitmapGdiPlus(const SalTwoRect& rTR, const SalBi return false; } +bool WinSalGraphicsImpl::blendBitmap( + const SalTwoRect&, + const SalBitmap&) +{ + return false; +} + +bool WinSalGraphicsImpl::blendAlphaBitmap( + const SalTwoRect&, + const SalBitmap&, + const SalBitmap&, + const SalBitmap&) +{ + return false; +} + bool WinSalGraphicsImpl::drawAlphaBitmap( const SalTwoRect& rTR, const SalBitmap& rSrcBitmap, diff --git a/vcl/win/source/gdi/gdiimpl.hxx b/vcl/win/source/gdi/gdiimpl.hxx index a1c781a36676..ded35ac85041 100644 --- a/vcl/win/source/gdi/gdiimpl.hxx +++ b/vcl/win/source/gdi/gdiimpl.hxx @@ -172,6 +172,16 @@ public: void* pPtr, sal_uLong nSize ) SAL_OVERRIDE; + virtual bool blendBitmap( + const SalTwoRect&, + const SalBitmap& rBitmap ) SAL_OVERRIDE; + + virtual bool blendAlphaBitmap( + const SalTwoRect&, + const SalBitmap& rSrcBitmap, + const SalBitmap& rMaskBitmap, + const SalBitmap& rAlphaBitmap ) SAL_OVERRIDE; + /** Render bitmap with alpha channel @param rSourceBitmap diff --git a/vcl/win/source/gdi/salgdi_gdiplus.cxx b/vcl/win/source/gdi/salgdi_gdiplus.cxx index 65dbdd84acec..094a05c62b16 100644 --- a/vcl/win/source/gdi/salgdi_gdiplus.cxx +++ b/vcl/win/source/gdi/salgdi_gdiplus.cxx @@ -43,6 +43,22 @@ bool WinSalGraphics::drawPolyLine( eLineJoin, eLineCap); } +bool WinSalGraphics::blendBitmap( + const SalTwoRect& rTR, + const SalBitmap& rBmp) +{ + return mpImpl->blendBitmap(rTR, rBmp); +} + +bool WinSalGraphics::blendAlphaBitmap( + const SalTwoRect& rTR, + const SalBitmap& rSrcBmp, + const SalBitmap& rMaskBmp, + const SalBitmap& rAlphaBmp) +{ + return mpImpl->blendAlphaBitmap(rTR, rSrcBmp, rMaskBmp, rAlphaBmp); +} + bool WinSalGraphics::drawAlphaBitmap( const SalTwoRect& rTR, const SalBitmap& rSrcBitmap, |