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:
@@ -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));
|
||||||
|
Reference in New Issue
Block a user