[cairo] Radii of radial gradients

Carl Worth cworth at cworth.org
Fri Feb 23 09:50:47 PST 2007


On Fri, 9 Feb 2007 08:49:23 -0600, "Michael Urman" wrote:
> On 2/9/07, KUROSAWA, Takeshi <taken.spc at gmail.com> wrote:
> > I tried the radial gradients with cairo 1.3.13.
> > The following code generates an image(*1) I unexpected.
>
> Hi, this sounds likely to be the same as
> https://bugs.freedesktop.org/show_bug.cgi?id=7685 which I saw in cairo
> 1.2. The best workaround I found was to use an inner radius=0 and
> recalculate the stops accordingly.

Hi Michael,

I probably should have replied at this point in the thread earlier. I
wanted to thank you for originally reporting the bug (months ago!) and
also following multiple times with other poor users that also hit the
same bug and providing them a useful workaround.

I apologize that I haven't been able to look at the bug more closely
until now. And I do hope that we'll see a complete fix quite soon.

One other detail I should mention is that I carefully constructed the
test case to avoid the case where any portion of the inner circle is
outside, (or perhaps even coincident with), the outer circle. As it
turns out, cairo has pretty much always blown up in spectacular ways
in that case.

Since I'm now thinking about fixing radial gradients, I'm thinking
about that case as well. And the question is, what do we actually want
to draw in that case? And the answer isn't immediately obvious.

Here are some references to defined behavior in existing systems:

SVG: The SVG specification avoids the problem by defining a radial
     gradient not in terms of two circles, but in terms of one circle
     and one focal point, (that is, this is similar to the inner
     radius being fixed at size 0 in cairo's specification). Also, SVG
     defines the case of a focal point that's outside the circle by
     snapping it to the point on the circle which is intersected by
     the line connecting the circle's center and the focal point.

So, cairo allows something that is not possible to express in SVG. So
SVG won't help us define the behavior. Let's look at PDF, (which
inspired the two-circle radial gradient specification in cairo):

PDF: With PDF, the defined result "depicts a sphere" if the smaller
     circle is withing the larger circle and "depicts a cone" if any
     portion of the smaller circle is outside the larger circle. This
     "cone" can result triangular wedge with a sharp point if the
     smaller circle has a radius of 0, (or if it is extended).

Following the PDF definition seems quite tempting.

We would first need to extend it slightly to accommodate the
availability of translucence in our color stops, (the PDF specification
is defined in terms of sequentially drawn opaque circles, with later
circles overwriting earlier color values). In cairo, this would be
replaced by the natural extension, which is that the circles are drawn
with the appropriate alpha so that later circles would blend over
previously drawn circles.

Second, there is one thing I find extremely dissatisfying about the
defined PDF result. Specifically, it's the discontinuity of changing
from "depicts a sphere" to "depicts a cone" which can be triggered by
an infinitesimally small change in the input.

For example, imagine a PDF gradient with a starting radius of 0.0 a
final radius of R and the final extend mode to true. In this state, if
the starting circle's center is within the final circle, then the
gradient will extend "infinitely", (or as large as the object being
drawn). Now, imagine nudging the starting circle's center point to
just outside the final circle. Now, with the new "wedge" that appears,
there will suddenly be big blank regions no filled at all, (initially
a half-plane tangent to the circle at the point where the starting
circle's center point lies exactly on the circle).

So, an infinitesimally small change results in a half-plane of color
suddenly disappearing. That's something we like to avoid in cairo.

I'm actually curious as to what SVG implementations do in this
case. Anyway have Batik running and can test drawing a large shape
filled with an extend="pad" radial gradient with the focal point set
to outside the circle?

I can't find any details in the SVG specification about this, but the
closest thing is the definition of the solid fill color that results
with a degenerate linear gradient of coincident points---that solid
fill color comes from the final color stop.

So, I think using the final color stop as a solid fill color for all
of the otherwise undefined regions, (outside the "wedge"), would give
us the continuity we want in cairo.

I think I'll need to experiment with an implementation, and write up a
more terse specification for this to make sure it works. But I thought
I'd at least capture the thoughts I have now.

Thanks for reading, (and thanks in advance for any thoughts or
feedback).

-Carl

PS. Oh, even though this specification will be slightly different than
the PDF specification, I think the PDF behavior should still be
possible to achieve---it can get tricky as cairo only has a single
extend mode while PDF has separate extend for initial/final
circles---but I think judicious use of fully transparent color stops
on the ends should still be able to achieve the defined PDF result in
something like poppler.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
Url : http://lists.freedesktop.org/archives/cairo/attachments/20070223/904d287d/attachment-0001.pgp


More information about the cairo mailing list