Kaydet (Commit) b76532e1 authored tarafından thb's avatar thb

Fix dxcanvas gradient glitches

 * moved common gradient step size code
   out to canvastools to share
 * reverted back to manual polygon rendering
   for anisotrophic rect and ellipse gradients
 * fixed tilemode==none case for bitmap fills
üst 9f357719
...@@ -69,6 +69,7 @@ namespace com { namespace sun { namespace star { namespace rendering ...@@ -69,6 +69,7 @@ namespace com { namespace sun { namespace star { namespace rendering
struct ViewState; struct ViewState;
struct IntegerBitmapLayout; struct IntegerBitmapLayout;
class XCanvas; class XCanvas;
struct Texture;
class XIntegerBitmapColorSpace; class XIntegerBitmapColorSpace;
class XPolyPolygon2D; class XPolyPolygon2D;
...@@ -499,6 +500,18 @@ namespace canvas ...@@ -499,6 +500,18 @@ namespace canvas
*/ */
::basegfx::B2DPolyPolygon getBoundMarksPolyPolygon( const ::basegfx::B2DRange& rRange ); ::basegfx::B2DPolyPolygon getBoundMarksPolyPolygon( const ::basegfx::B2DRange& rRange );
/** Calculate number of gradient "strips" to generate (takes
into account device resolution)
@param nColorSteps
Maximal integer difference between all color stops, needed
for smooth gradient color differences
*/
int calcGradientStepCount( ::basegfx::B2DHomMatrix& rTotalTransform,
const ::com::sun::star::rendering::ViewState& viewState,
const ::com::sun::star::rendering::RenderState& renderState,
const ::com::sun::star::rendering::Texture& texture,
int nColorSteps );
/** A very simplistic map for ASCII strings and arbitrary value /** A very simplistic map for ASCII strings and arbitrary value
types. types.
......
...@@ -199,7 +199,7 @@ namespace dxcanvas ...@@ -199,7 +199,7 @@ namespace dxcanvas
{ {
const sal_uInt32 nPoints( rPoly.count() ); const sal_uInt32 nPoints( rPoly.count() );
if( !nPoints ) if( nPoints < 2 )
return; return;
rOutput->StartFigure(); rOutput->StartFigure();
......
...@@ -994,6 +994,54 @@ namespace canvas ...@@ -994,6 +994,54 @@ namespace canvas
return aPolyPoly; return aPolyPoly;
} }
int calcGradientStepCount( ::basegfx::B2DHomMatrix& rTotalTransform,
const rendering::ViewState& viewState,
const rendering::RenderState& renderState,
const rendering::Texture& texture,
int nColorSteps )
{
// calculate overall texture transformation (directly from
// texture to device space).
::basegfx::B2DHomMatrix aMatrix;
rTotalTransform.identity();
::basegfx::unotools::homMatrixFromAffineMatrix( rTotalTransform,
texture.AffineTransform );
::canvas::tools::mergeViewAndRenderTransform(aMatrix,
viewState,
renderState);
rTotalTransform *= aMatrix; // prepend total view/render transformation
// determine size of gradient in device coordinate system
// (to e.g. determine sensible number of gradient steps)
::basegfx::B2DPoint aLeftTop( 0.0, 0.0 );
::basegfx::B2DPoint aLeftBottom( 0.0, 1.0 );
::basegfx::B2DPoint aRightTop( 1.0, 0.0 );
::basegfx::B2DPoint aRightBottom( 1.0, 1.0 );
aLeftTop *= rTotalTransform;
aLeftBottom *= rTotalTransform;
aRightTop *= rTotalTransform;
aRightBottom*= rTotalTransform;
// longest line in gradient bound rect
const int nGradientSize(
static_cast<int>(
::std::max(
::basegfx::B2DVector(aRightBottom-aLeftTop).getLength(),
::basegfx::B2DVector(aRightTop-aLeftBottom).getLength() ) + 1.0 ) );
// typical number for pixel of the same color (strip size)
const int nStripSize( nGradientSize < 50 ? 2 : 4 );
// use at least three steps, and at utmost the number of color
// steps
return ::std::max( 3,
::std::min(
nGradientSize / nStripSize,
nColorSteps ) );
}
} // namespace tools } // namespace tools
} // namespace canvas } // namespace canvas
...@@ -562,62 +562,27 @@ namespace vclcanvas ...@@ -562,62 +562,27 @@ namespace vclcanvas
// deadlocks, canvashelper calls this method with locked own // deadlocks, canvashelper calls this method with locked own
// mutex. // mutex.
// calculate overall texture transformation (directly from
// texture to device space).
::basegfx::B2DHomMatrix aMatrix;
::basegfx::B2DHomMatrix aTextureTransform;
::basegfx::unotools::homMatrixFromAffineMatrix( aTextureTransform,
texture.AffineTransform );
::canvas::tools::mergeViewAndRenderTransform(aMatrix,
viewState,
renderState);
aTextureTransform *= aMatrix; // prepend total view/render transformation
// determine maximal bound rect of gradient-filled polygon
const ::Rectangle aPolygonDeviceRectOrig(
rPoly.GetBoundRect() );
// determine size of gradient in device coordinate system
// (to e.g. determine sensible number of gradient steps)
::basegfx::B2DPoint aLeftTop( 0.0, 0.0 );
::basegfx::B2DPoint aLeftBottom( 0.0, 1.0 );
::basegfx::B2DPoint aRightTop( 1.0, 0.0 );
::basegfx::B2DPoint aRightBottom( 1.0, 1.0 );
aLeftTop *= aTextureTransform;
aLeftBottom *= aTextureTransform;
aRightTop *= aTextureTransform;
aRightBottom*= aTextureTransform;
// calc step size // calc step size
// -------------- // --------------
int nColorSteps = 0; int nColorSteps = 0;
for( size_t i=0; i<rColors.size()-1; ++i ) for( size_t i=0; i<rColors.size()-1; ++i )
nColorSteps += numColorSteps(rColors[i],rColors[i+1]); nColorSteps += numColorSteps(rColors[i],rColors[i+1]);
// longest line in gradient bound rect ::basegfx::B2DHomMatrix aTotalTransform;
const int nGradientSize( const int nStepCount=
static_cast<int>( ::canvas::tools::calcGradientStepCount(aTotalTransform,
::std::max( viewState,
::basegfx::B2DVector(aRightBottom-aLeftTop).getLength(), renderState,
::basegfx::B2DVector(aRightTop-aLeftBottom).getLength() ) + 1.0 ) ); texture,
nColorSteps);
// typical number for pixel of the same color (strip size)
const int nStripSize( nGradientSize < 50 ? 2 : 4 );
// use at least three steps, and at utmost the number of color
// steps
const int nStepCount(
::std::max(
3,
::std::min(
nGradientSize / nStripSize,
nColorSteps ) ) );
rOutDev.SetLineColor(); rOutDev.SetLineColor();
// determine maximal bound rect of texture-filled
// polygon
const ::Rectangle aPolygonDeviceRectOrig(
rPoly.GetBoundRect() );
if( tools::isRectangle( rPoly ) ) if( tools::isRectangle( rPoly ) )
{ {
// use optimized output path // use optimized output path
...@@ -635,7 +600,7 @@ namespace vclcanvas ...@@ -635,7 +600,7 @@ namespace vclcanvas
doGradientFill( rOutDev, doGradientFill( rOutDev,
rValues, rValues,
rColors, rColors,
aTextureTransform, aTotalTransform,
aPolygonDeviceRectOrig, aPolygonDeviceRectOrig,
nStepCount, nStepCount,
false ); false );
...@@ -648,7 +613,7 @@ namespace vclcanvas ...@@ -648,7 +613,7 @@ namespace vclcanvas
doGradientFill( *p2ndOutDev, doGradientFill( *p2ndOutDev,
rValues, rValues,
rColors, rColors,
aTextureTransform, aTotalTransform,
aPolygonDeviceRectOrig, aPolygonDeviceRectOrig,
nStepCount, nStepCount,
false ); false );
...@@ -666,7 +631,7 @@ namespace vclcanvas ...@@ -666,7 +631,7 @@ namespace vclcanvas
doGradientFill( rOutDev, doGradientFill( rOutDev,
rValues, rValues,
rColors, rColors,
aTextureTransform, aTotalTransform,
aPolygonDeviceRectOrig, aPolygonDeviceRectOrig,
nStepCount, nStepCount,
false ); false );
...@@ -679,7 +644,7 @@ namespace vclcanvas ...@@ -679,7 +644,7 @@ namespace vclcanvas
doGradientFill( *p2ndOutDev, doGradientFill( *p2ndOutDev,
rValues, rValues,
rColors, rColors,
aTextureTransform, aTotalTransform,
aPolygonDeviceRectOrig, aPolygonDeviceRectOrig,
nStepCount, nStepCount,
false ); false );
...@@ -694,7 +659,7 @@ namespace vclcanvas ...@@ -694,7 +659,7 @@ namespace vclcanvas
doGradientFill( rOutDev, doGradientFill( rOutDev,
rValues, rValues,
rColors, rColors,
aTextureTransform, aTotalTransform,
aPolygonDeviceRectOrig, aPolygonDeviceRectOrig,
nStepCount, nStepCount,
true ); true );
...@@ -705,7 +670,7 @@ namespace vclcanvas ...@@ -705,7 +670,7 @@ namespace vclcanvas
doGradientFill( rOutDev, doGradientFill( rOutDev,
rValues, rValues,
rColors, rColors,
aTextureTransform, aTotalTransform,
aPolygonDeviceRectOrig, aPolygonDeviceRectOrig,
nStepCount, nStepCount,
true ); true );
...@@ -718,7 +683,7 @@ namespace vclcanvas ...@@ -718,7 +683,7 @@ namespace vclcanvas
doGradientFill( *p2ndOutDev, doGradientFill( *p2ndOutDev,
rValues, rValues,
rColors, rColors,
aTextureTransform, aTotalTransform,
aPolygonDeviceRectOrig, aPolygonDeviceRectOrig,
nStepCount, nStepCount,
true ); true );
...@@ -729,7 +694,7 @@ namespace vclcanvas ...@@ -729,7 +694,7 @@ namespace vclcanvas
doGradientFill( *p2ndOutDev, doGradientFill( *p2ndOutDev,
rValues, rValues,
rColors, rColors,
aTextureTransform, aTotalTransform,
aPolygonDeviceRectOrig, aPolygonDeviceRectOrig,
nStepCount, nStepCount,
true ); true );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment