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
wxInt32 cx = rect.GetWidth() / 2;
wxInt32 cy = rect.GetHeight() / 2;
wxInt32 nRadius;
double cx = rect.GetWidth() / 2;
double cy = rect.GetHeight() / 2;
double dRadius;
if (cx < cy)
nRadius = cx;
dRadius = cx;
else
nRadius = cy;
dRadius = cy;
//Offset of circle
wxInt32 nCircleOffX = circleCenter.x - (rect.GetWidth() / 2);
wxInt32 nCircleOffY = circleCenter.y - (rect.GetHeight() / 2);
double ptX, ptY;
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 y = 0; y < rect.GetHeight(); y++ )
{
//get color difference
wxInt32 nGradient = ((nRadius -
(wxInt32)sqrt(
pow((double)(x - cx - nCircleOffX), 2) +
pow((double)(y - cy - nCircleOffY), 2)
)) * 100) / nRadius;
dx = x;
dy = y;
dGradient = ((dRadius - sqrt( (dx - cx - nCircleOffX) * (dx - cx - nCircleOffX)
+(dy - cy - nCircleOffY) * (dy - cy - nCircleOffY)
)
) * 100
) / dRadius;
//normalize Gradient
if (nGradient < 0 )
nGradient = 0;
if (dGradient < 0)
dGradient = 0.0;
//get dest colors
nR = (wxUint8)(nR1 + ((nR2 - nR1) * nGradient / 100));
nG = (wxUint8)(nG1 + ((nG2 - nG1) * nGradient / 100));
nB = (wxUint8)(nB1 + ((nB2 - nB1) * nGradient / 100));
nR = (wxUint8)(nR1 + ((nR2 - nR1) * dGradient / 100));
nG = (wxUint8)(nG1 + ((nG2 - nG1) * dGradient / 100));
nB = (wxUint8)(nB1 + ((nB2 - nB1) * dGradient / 100));
//set the pixel
SetPen(wxColour(nR,nG,nB));