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

Carl Worth cworth at cworth.org
Fri Feb 25 07:01:33 PST 2005


On Fri, 25 Feb 2005 14:02:30 +0100, David Reveman wrote:
> I think that this optimization should not be done before sending the
> pattern to the backend.

Yes, that's fine.

> 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,

Right. The problem I've run into is that result is actually
different. I'm working through a fix now.

> just a bit slower and I didn't know that single color stop
> gradients were actually used.  

I didn't realize it either. But apparently they appear in the W3C SVG
test suite, (and there they are specified to be treated as a solid
color fill).

> 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"...    

For surface-based patterns, EXTEND_REPEAT is likely common. But for
gradient patterns, EXTEND_REPEAT can introduce a nasty discontinuity
if the shape being filled ends up just larger than intended.

And, remember that in the new rendering model, there's no such thing
as cairo_show_surface. Instead, the latest proposal for compositing
one surface onto another now looks like this:

	cairo_set_source_surface (cr, surface);
	cairo_paint (cr);

Where cairo_set_source_surface is a convenience function so that the
above is equivalent to:

	pattern = cairo_pattern_create_for_surface (surface);
	cairo_set_source (cr, pattern);
	cairo_pattern_destroy (pattern);
	cairo_paint (cr);

These sequences give the desired behavior of the old
cairo_show_surface only if the default extend mode is
EXTEND_TRANSPARENT.

I think EXTEND_TRANSPARENT by default is justified in terms of
consistently requiring the user to specify "additional" behavior,
rather than selectively performing some behavior by default that the
user may want to turn off.

> 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.  

Hmmm... I think that could yield some surprising results. Imagine a
gradient with opaque color stops at say 0.25 and 0.75. Instead of an
opaque gradient, the user would get smooth fades to transparent.

In my view, the extend mode should only effect behavior "outside" the
surface, (which for gradients would mean < 0.0 and > 1.0).

Oh, one approach would be to implicitly copy the nearest color stops
to 0.0 and 1.0. Then your implicit transparent stops could go to 0.0 -
epsilon and 1.0 + epsilon and everything should work.

> EXTEND_REPEAT as default and this is less of a problem.

I don't think so.

Your implicit transparent color stops effectively make the behavior of
EXTEND_TRANSPARENT reach "inside" the [0..1] range. Would we want the
same for EXTEND_REPEAT? That is, would an under-specified gradient
begin repeating earlier than the 0.0 and 1.0? That seems confusing to
me.

Padding the specified color stops to 0.0 and 1.0, and then only using
extend for regions beyond would eliminate that problem as well.

Oh, and while I'm arguing for a default of EXTEND_TRANSPARENT, and
you've proposed EXTEND_REPEAT, I should point out that the default
"spreadMethod" for an SVG gradient is "pad". So I guess we've got
every option on the table. ;-)

However, SVG doesn't make the "inside" vs. "outside" distinction for
gradients like I have. (SVG also doesn't unify patterns and gradients
as we have done, which is one way in which the inside/outside
distinction is useful). Also, my proposal is consistent with SVG as
far as padding the gradient color "inside" the [0..1] range.

> 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.

Agreed.

And my guess is that we won't provide anything but linear
gradients. They are simple to understand and sufficient as a base for
building more elaborate functions. This philosophy is similar to what
we use to justify providing only cubic Bézier splines and (extended
range) sRGB color.


> The filter parameter in the pattern should be used for
> "fetching" a color fragment, just as for surface patterns.

Yes. Though I don't know yet the answers to the questions you pose
about efficiency. It seems that correctness should be easy enough to
achieve by pre-rendering the gradient to a surface and doing the
filtered fetch from there. That suggests to me that we're not
specifying anything unimplementable here.

-Carl

-------------- 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/20050225/c1f6ecf6/attachment.pgp


More information about the cairo mailing list