Use floating point arithmetic in wxDC::GradientFillConcentric().

Use doubles to avoid accumulated rounding errors from using integers in the
generic implementation of wxDC::GradientFillConcentric(). This results in
smoother gradient.

Also avoid using the expensive pow() function inside the inner loop when we
just need to calculate a square.

Closes #12337.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@65944 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2010-10-28 14:23:18 +00:00
parent 7825e32171
commit d176b30156

View File

@@ -1075,37 +1075,46 @@ void wxDCImpl::DoGradientFillConcentric(const wxRect& rect,
//Radius //Radius
wxInt32 cx = rect.GetWidth() / 2; double cx = rect.GetWidth() / 2;
wxInt32 cy = rect.GetHeight() / 2; double cy = rect.GetHeight() / 2;
wxInt32 nRadius; double dRadius;
if (cx < cy) if (cx < cy)
nRadius = cx; dRadius = cx;
else else
nRadius = cy; dRadius = cy;
//Offset of circle //Offset of circle
wxInt32 nCircleOffX = circleCenter.x - (rect.GetWidth() / 2); double ptX, ptY;
wxInt32 nCircleOffY = circleCenter.y - (rect.GetHeight() / 2); ptX = circleCenter.x;
ptY = circleCenter.y;
double nCircleOffX = ptX - cx;
double nCircleOffY = ptY - cy;
double dGradient;
double dx, dy;
for ( wxInt32 x = 0; x < rect.GetWidth(); x++ ) for ( wxInt32 x = 0; x < rect.GetWidth(); x++ )
{ {
for ( wxInt32 y = 0; y < rect.GetHeight(); y++ ) for ( wxInt32 y = 0; y < rect.GetHeight(); y++ )
{ {
//get color difference //get color difference
wxInt32 nGradient = ((nRadius - dx = x;
(wxInt32)sqrt( dy = y;
pow((double)(x - cx - nCircleOffX), 2) +
pow((double)(y - cy - nCircleOffY), 2) dGradient = ((dRadius - sqrt( (dx - cx - nCircleOffX) * (dx - cx - nCircleOffX)
)) * 100) / nRadius; +(dy - cy - nCircleOffY) * (dy - cy - nCircleOffY)
)
) * 100
) / dRadius;
//normalize Gradient //normalize Gradient
if (nGradient < 0 ) if (dGradient < 0)
nGradient = 0; dGradient = 0.0;
//get dest colors //get dest colors
nR = (wxUint8)(nR1 + ((nR2 - nR1) * nGradient / 100)); nR = (wxUint8)(nR1 + ((nR2 - nR1) * dGradient / 100));
nG = (wxUint8)(nG1 + ((nG2 - nG1) * nGradient / 100)); nG = (wxUint8)(nG1 + ((nG2 - nG1) * dGradient / 100));
nB = (wxUint8)(nB1 + ((nB2 - nB1) * nGradient / 100)); nB = (wxUint8)(nB1 + ((nB2 - nB1) * dGradient / 100));
//set the pixel //set the pixel
SetPen(wxColour(nR,nG,nB)); SetPen(wxColour(nR,nG,nB));