There are two problems with the fillRectHGradient and fillRectVGradient routines, one trivial and one deeper.
In the fillRectHGradient routine, each h in the line
should be w. The fillRectHGradient routine was probably written by copying the fillRectVGradient routine, making (almost all) the changes necessary.
Unfortunately, there is a deeper problem with that line. To see the deeper problem, consider (for definiteness) the problem of filling a 100-pixel line (W = 100) with a gradient running from RedLeft = 0 to RedRight = 9. The expected line will have 10 pixels with Red = 0, 10 with Red = 1, and so on. Conceptually, each pixel will be 0.1 units redder than the previous one, but that will be visible only each time the accumulated steps have added up to one unit.
The code in the fillRectXGradient routines follows that pattern, but in the quoted code that defines the R/G/B steps (dr/dg/db) , all the variables are integers, so in my example dr would be 9/100 in integer arithmetic, or zero.
These routines might seem to work with broad color ranges in narrow rectangles, but not otherwise.
In the fillRectHGradient routine, each h in the line
Code:
dr=(r2-r1)/h; dg=(g2-g1)/h; db=(b2-b1)/h;
Unfortunately, there is a deeper problem with that line. To see the deeper problem, consider (for definiteness) the problem of filling a 100-pixel line (W = 100) with a gradient running from RedLeft = 0 to RedRight = 9. The expected line will have 10 pixels with Red = 0, 10 with Red = 1, and so on. Conceptually, each pixel will be 0.1 units redder than the previous one, but that will be visible only each time the accumulated steps have added up to one unit.
The code in the fillRectXGradient routines follows that pattern, but in the quoted code that defines the R/G/B steps (dr/dg/db) , all the variables are integers, so in my example dr would be 9/100 in integer arithmetic, or zero.
These routines might seem to work with broad color ranges in narrow rectangles, but not otherwise.
- The simplest possible fix would be to have the dr/dg/db variables be floating-point.
- Alternatively, if integer variables must be used, the step size could be implicit, so that (for example) the Red value to be used in Pixel #X in my example could be RedLeft + (X * (RedRight - RedLeft)) / W. Here, (RedRight - RedLeft) could be pre-computed, but the division would need to stay in the loop.