[cairo] [PATCH] Conical gradients with pixman with rotation
sandmann at daimi.au.dk
Sat Jun 19 16:28:09 PDT 2010
> "Soeren Sandmann" <sandmann at daimi.au.dk> writes:
> > There used to be a bug where pixman would miscalculate the
> > angle. Maybe that's what you are seeing? That bug is fixed in 0.18.0.
> I've now upgraded to 0.18.2 but I'm afraid the problem is still there. I'm not sure whether this is actually a bug or whether it is a feature :) I'm attaching a small example source code that shows what I mean. The 45 degree rotated conical gradient generated by my example looks like this:
> But I think this look is wrong. Instead, 45 degree rotation should look like this: (generated in CorelDraw)
> But I'm unable to achieve this look with the conical gradient
> functions in pixman. Is it really intended this way or is this a bug
> in pixman?
[adding the X and pixman mailing lists]
The gradients were added to the X Render extension several years ago,
but the Render specification doesn't say anything about how they
should actually be rendered, so what is intended is somewhat difficult
to say. The radial gradients were pretty broken until cairo started
using them and Carl had to actually make them work. So it's not too
surprising if the conical gradients don't work.
The current behavior pretty clearly is just plain buggy. What is going
on is that the output of atan2() is in the range of [-pi, pi] and we
never correct for that, which means we get a discontinuity at pi,
where the angle, and therefore the parameter, suddenly becomes
negative. That cannot possibly be right.
If we simply fix that, then we get something more plausible where the
gradient starts at the given angle and is interpolated 360 degrees
clockwise around the center.
However, the conical gradients were (I suppose, since the code was
written by TrollTech people) intended to match what Qt does:
which uses a counter-clockwise interpolation. Given how we normally
measure angles, that makes sense to me.
The appended patch makes the pixman conical gradients match what
QConicalGradient is documented to do. With that applied, you can
achieve something similar to the Corel Draw output by using three
color stops. See this modified version of your test program:
However, since clearly no one has actually used the conical gradients
before, we are not really constrained in what they can be made to do,
so I'm open to other interpretations.
The patch is available in a git repository here:
More information about the cairo