From d176b30156f3e215df74eaa0c2494f0c267beb5f Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 28 Oct 2010 14:23:18 +0000 Subject: [PATCH] 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 --- src/common/dcbase.cpp | 43 ++++++++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/src/common/dcbase.cpp b/src/common/dcbase.cpp index df11b95eea..fdb0a2f1b7 100644 --- a/src/common/dcbase.cpp +++ b/src/common/dcbase.cpp @@ -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));