diff options
author | Louis-Francis Ratté-Boulianne <lfrb@collabora.com> | 2014-11-12 18:11:34 -0500 |
---|---|---|
committer | Markus Mohrhard <markus.mohrhard@collabora.co.uk> | 2014-11-13 07:54:21 +0100 |
commit | afd759a583e9dcbbbdda0697b57f97f8235d2741 (patch) | |
tree | 785d4c17df300782e2321303d5dbb9206db4fe61 /vcl | |
parent | 6ff6d0b00dee5f9afbd4b4f0747183a3c8ba7939 (diff) |
vcl: Use stencil mask to clip gradient shape
Change-Id: I5dc17a20ab65f0b0bad4741a7d1ec76a0e028e23
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/inc/openglgdiimpl.hxx | 2 | ||||
-rw-r--r-- | vcl/opengl/gdiimpl.cxx | 78 |
2 files changed, 50 insertions, 30 deletions
diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx index 82bb919a5c3c..167fe60eb036 100644 --- a/vcl/inc/openglgdiimpl.hxx +++ b/vcl/inc/openglgdiimpl.hxx @@ -74,6 +74,8 @@ protected: GLuint mnRadialGradientEndColorUniform; GLuint mnRadialGradientCenterUniform; + void ImplSetClipBit( const vcl::Region& rClip, GLuint nMask ); + bool CreateSolidProgram( void ); bool CreateTextureProgram( void ); bool CreateMaskedTextureProgram( void ); diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx index f1206c35d04e..8396ffef54ab 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -102,7 +102,10 @@ void OpenGLSalGraphicsImpl::PreDraw() if( mbUseScissor ) glEnable( GL_SCISSOR_TEST ); if( mbUseStencil ) + { + glStencilFunc( GL_EQUAL, 1, 0x1 ); glEnable( GL_STENCIL_TEST ); + } CHECK_GL_ERROR(); } @@ -125,6 +128,24 @@ void OpenGLSalGraphicsImpl::freeResources() // TODO Delete shaders, programs and textures if not shared } +void OpenGLSalGraphicsImpl::ImplSetClipBit( const vcl::Region& rClip, GLuint nMask ) +{ + glEnable( GL_STENCIL_TEST ); + glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE ); + glStencilMask( nMask ); + glStencilFunc( GL_NEVER, nMask, 0xFF ); + glStencilOp( GL_REPLACE, GL_KEEP, GL_KEEP ); + + glClear( GL_STENCIL_BUFFER_BIT ); + BeginSolid( MAKE_SALCOLOR( 0xFF, 0xFF, 0xFF ) ); + DrawPolyPolygon( rClip.GetAsB2DPolyPolygon() ); + EndSolid(); + + glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE ); + glStencilMask( 0x00 ); + glDisable( GL_STENCIL_TEST ); +} + bool OpenGLSalGraphicsImpl::setClipRegion( const vcl::Region& rClip ) { SAL_INFO( "vcl.opengl", "::setClipRegion " << rClip ); @@ -150,22 +171,7 @@ bool OpenGLSalGraphicsImpl::setClipRegion( const vcl::Region& rClip ) mbUseScissor = false; maContext.makeCurrent(); glViewport( 0, 0, GetWidth(), GetHeight() ); - - glEnable( GL_STENCIL_TEST ); - glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE ); - glStencilMask( 0xFF ); - glStencilFunc( GL_NEVER, 1, 0xFF ); - glStencilOp( GL_REPLACE, GL_KEEP, GL_KEEP ); - - glClear( GL_STENCIL_BUFFER_BIT ); - BeginSolid( SALCOLOR_NONE ); - DrawPolyPolygon( rClip.GetAsB2DPolyPolygon() ); - EndSolid(); - - glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE ); - glStencilMask( 0x00 ); - glStencilFunc( GL_EQUAL, 1, 0xFF ); - glDisable( GL_STENCIL_TEST ); + ImplSetClipBit( rClip, 0x01 ); } return true; @@ -1333,42 +1339,54 @@ bool OpenGLSalGraphicsImpl::drawGradient(const tools::PolyPolygon& rPolyPoly, if( aBoundRect.IsEmpty() ) return true; + if( rGradient.GetStyle() != GradientStyle_LINEAR && + rGradient.GetStyle() != GradientStyle_RADIAL ) + return false; + aBoundRect.Left()--; aBoundRect.Top()--; aBoundRect.Right()++; aBoundRect.Bottom()++; + //TODO: lfrb: some missing transformation with the polygon in outdev + + PreDraw(); + + ImplSetClipBit( vcl::Region( rPolyPoly ), 0x02 ); + if( mbUseStencil ) + { + glEnable( GL_STENCIL_TEST ); + glStencilFunc( GL_EQUAL, 3, 0xFF ); + } + else + { + glEnable( GL_STENCIL_TEST ); + glStencilFunc( GL_EQUAL, 2, 0xFF ); + } // if border >= 100%, draw solid rectangle with start color if( rGradient.GetBorder() >= 100.0 ) { Color aCol = rGradient.GetStartColor(); long nF = rGradient.GetStartIntensity(); - PreDraw(); BeginSolid( MAKE_SALCOLOR( aCol.GetRed() * nF / 100, aCol.GetGreen() * nF / 100, aCol.GetBlue() * nF / 100 ) ); DrawRect( aBoundRect ); - EndSolid(); - PostDraw(); - return true; } - - //TODO: lfrb: some missing transformation with the polygon in outdev - if( rGradient.GetStyle() == GradientStyle_LINEAR ) + else if( rGradient.GetStyle() == GradientStyle_LINEAR ) { - PreDraw(); DrawLinearGradient( rGradient, aBoundRect ); - PostDraw(); - return true; } else if( rGradient.GetStyle() == GradientStyle_RADIAL ) { - PreDraw(); DrawRadialGradient( rGradient, aBoundRect ); - PostDraw(); - return true; } - return false; + + if( !mbUseStencil ) + glDisable( GL_STENCIL_TEST ); + PostDraw(); + + return true; } void OpenGLSalGraphicsImpl::beginPaint() |