On Monday 03 May 2004 09:22 pm, Lyle Johnson wrote:
> On May 3, 2004, at 8:46 PM, Claus Spitzer wrote:
> > Greetings!
>
> Wow, a post from a GMail account! How glamorous ;)
>
> > Is there a way to use gradients with FXDC::FillRectangle? Are there
> > other ways of implementing gradients in FXRuby? I couldn't find
> > anything relevant in the api docs. FXDC fill styles don't mention it,
> > but I wonder how this is implemented in the color wheel, and if there
> > are methods other than FXDC to implement this.
>
> [You might also want to post this question to the foxgui-users mailing
> list, since it's not FXRuby-specific.]
>
> I'm pretty sure that the disk used for the FXColorWheel is an FXImage
> with dithering turned on, and that's what's creating the gradient-like
> effect. Other than that, I don't think there was much support for
> painting with gradients in FOX 1.0. FOX 1.2 (available sometime in the
> future) will have better support for this, I think, but that's still a
> ways off, I think.
The support that Lyle is talking about is in FXImage, not in FXDC; in other
words, you have to generate a gradient into the image, then draw the image.
You can try drawing a gradient using many small rectangles, each filled
with uniform color.
I used the following code to do it:
#define MAXSTEPS 128
...
r1=FXREDVAL(fill.lower); r2=FXREDVAL(fill.upper); dr=r2-r1;
g1=FXGREENVAL(fill.lower); g2=FXGREENVAL(fill.upper); dg=g2-g1;
b1=FXBLUEVAL(fill.lower); b2=FXBLUEVAL(fill.upper); db=b2-b1;
n=FXABS(dr);
if((t=FXABS(dg))>n) n=t;
if((t=FXABS(db))>n) n=t;
n++;
if(n>width) n=width;
if(n>MAXSTEPS) n=MAXSTEPS;
rr=(r1<<16)+32767;
gg=(g1<<16)+32767;
bb=(b1<<16)+32767;
xx=32767;
dr=(dr<<16)/n;
dg=(dg<<16)/n;
db=(db<<16)/n;
dx=(width<<16)/n;
do{
xl=xx>>16;
xx+=dx;
xr=xx>>16;
dc.setForeground(FXRGB(rr>>16,gg>>16,bb>>16));
dc.fillRectangle(xl,0,xr-xl,height);
rr+=dr;
gg+=dg;
bb+=db;
}
while(xr<width);
The rationale of this code is as follows:
1) The number of rectangles is determined by the
variation of the largest color-component.
2) We draw no more rectangles than pixels (duh!)
3) We draw no more than MAXSTEPS rectangles, if (1) and (2)
would exceed this threshold.
4) All the math is evaluated in fixed-point (16.16) precision;
rounding is necessary to ensure that you're not off-by-one
near the borders.
On 24 bit color systems, the approach works pretty well, and in many
cases the color variations are not so dramatic so it can be pretty
fast.
The downside is that its not easy to draw gradients at an angle.
Anyway, this may make it into FXDC as an API one day; especially
if I manage to generalize it beyond drawing rectangles somehow.
Regards,
Jeroen
--
+----------------------------------------------------------------------------+
| Copyright (C) 23:50 12/11/2003 Jeroen van der Zijp. All Rights Reserved. |
+----------------------------------------------------------------------------+
|