[cairo] Re: Under-specified gradients (was: cairo pattern/glitz patches)

David Reveman davidr at novell.com
Fri Feb 25 05:02:30 PST 2005


On Thu, 2005-02-24 at 16:47 -0500, Carl Worth wrote: 
> On Fri, 18 Feb 2005 16:06:39 -0500, David Reveman wrote:
> > I've split up my pending pattern updates and glitz backend updates as
> > much as possible. Here's a set of patches. They need to be applied in
> > the following order:
> 
> I'm starting to work through these now.
> 
> > cairo-surface-fallback-fix-1.diff
> 
> This one I committed earlier (as mentioned here before).
> 
> > cairo-gstate-pattern-init-1.diff
> 
> I just committed this one today with some minor cleanups.
> 
> > cairo-gstate-pattern-copy-show-1.diff
> 
> I've run into a functional change with this one. It looks like the
> issue is with a removed optimization that turned a gradient with a
> single color stop into a solid pattern (when copying).

I think that this optimization should not be done before sending the
pattern to the backend. e.g. pdf or svg backend where you for editing
reasons actually want this pattern to appear as a gradient with one
color stop and not as a solid color.

> 
> Apparently, a gradient with a single color stop is not treated as a
> solid pattern of the color in the only color stop, and it seems that
> that would be the most reasonable behavior.

This optimization can easily be done in cairo_pattern_acquire_surface. I
didn't implement this yet as the result should of course not be
different, just a bit slower and I didn't know that single color stop
gradients were actually used.  

> 
> Actually, there's a slightly more general form of the question here.
> 
> I've been assuming that we want a default extend of EXTEND_TRANSPARENT
> for all patterns. So outside of the [0..1] range, gradients are
> transparent unless the user requests otherwise.

I'd actually prefer EXTEND_REPEAT as default. If you want to fill a
shape using a pattern, having the pattern repeat over the shape by
default seems nice. I'm thinking that a pattern is similar to a
"brush"...    

> 
> But, within the [0..1] range, we know to do linear interpolation
> between color stops. But what to do when the provided color stops do
> not reach 0.0 or 1.0? I propose that the nearest color stop value
> should be used, (and this behavior should be independent of the extend
> parameter).

In my current gradient implementation in glitz and in my
cairo-extend-type-update patch I'm treating EXTEND_TRANSPARENT as two
implicit transparent color stops at offset 0.0 and 1.0. I like that
better than using the nearest color stop.  

> 
> This specification would yield the desired behavior for
> single-color-stop-gradients, (namely, that they are a solid color
> within the [0..1] range).

EXTEND_REPEAT as default and this is less of a problem.


BTW, the current gradient implementation is sort of broken. I believe
that filters are handled completely wrong. Right now, the pattern filter
defines, which interpolation function that should be used between color
stops, this is wrong. Interpolation between color stops should always be
linear, if we want something else, that should be a different type of
gradient. The filter parameter in the pattern should be used for
"fetching" a color fragment, just as for surface patterns.
FILTER_NEAREST is always used with the current gradient implementation,
which basically means that you can't get smooth edges between color
stops that are close together. FILTER_GAUSSIAN can be useful here, but
it will be hard to get it efficient. I'm not sure how FILTER_BILINEAR is
going to work (how do we compute weights?). 
I'll make sure this gets fixed before 1.0.

-David




More information about the cairo mailing list