[cairo] Cairo gradients and pre-mul data
jose_ogp at juno.com
jose_ogp at juno.com
Tue Jun 20 18:53:04 PDT 2006
> > While it's true that one can't obtain the same results if
> > one were to pre-mul the input color data (or require them pre-mul)
> > and do the linear interpolation with such, that alone is
> > insufficient reason for not doing so. I would suspect that the
> > current semantics, differing from the rest of Cairo, would be
> > unwise...
> >
> > What is the actual overriding reason that decided Cairo
> > on using its current approach for gradients?
>
> This is actually an open issue that has been bothering me for some
> time. A little over a year ago, and before the 1.0 release, we did a
> careful scan of the cairo API looking for things we wanted to change
> as a last chance before freezing on API we would be committing to
> maintain "forever".
>
> When we did that scan I noticed this issue that cairo accepted both
> pre- and non-premultiplied colors in different parts of the API.
> So I made a proposal that would have also added two variations of
> the above:
>
> cairo_set_source_rgba_premultiplied
> cairo_add_color_stop_rgba_premultiplied
>
> Here's that first proposal:
>
> http://article.gmane.org/gmane.comp.lib.cairo/2797 [*]
>
> I even attempted an implementation of the idea:
>
> http://article.gmane.org/gmane.comp.lib.cairo/3438
>
> but then we ran into a problem with the interpolation of gradient
> color stops specified with pre-multiplied values:
>
> http://article.gmane.org/gmane.comp.lib.cairo/3458
>
> In particular, (as noted in the message above), with stops specified
> as pre-multiplied color values, there's no way specify a gradient
that
> smoothly blends from red to blue (say) while also blending from
alpha
> 1.0 to alpha 0.0. This turns out to be a very useful thing to do,
and
> is easy to specify with non-premultiplied color, (which also happens
> to match how gradients are specified in SVG, for example).
>
> So it seems we hit a fairly fundamental problem with pre-multiplied
> color stops. We could still add the proposed API back as long as it
> comes with clear specifications on what the semantics should be. I
> asked last April if anybody had any proposal for what these
semantics
> should be, but nobody had brought up the issue again until now, (as
> far as I recall).
>
> But I don't think there's any real inconsistency in cairo right now.
> (Admittedly, there is a sentence or two missing from the
documentation
> to indicate that set_source_rgba and add_color_stop_rgba expect
> non-premultiplied color values.)
>
> -Carl
>
It's true that one can't create a ramp as you want above,
but that alone would seem to me a somewhat weak reason to adopt a
'non-premul only' interface *and* implementation..
By a similar token, it's also useful to be able to take
non-premul image data, scale it, and then premul the result for
compositing... but should that be an overriding factor for choosing
non-premul image data over premul?
Basically, what linear interpolation in non-premul color space
does is to create a kind of quadratic ramp on the premul versions..
If one wished to remain in a 'premul only' world, one can approximate
such a ramp, in premul color space, to whatever degree desired by
suitably adding other (premul) stops
One of the consequences of a 'non-premul only' interface and
implementation is that it's then very difficult, in general, to create
a linear ramp between premul colors if non-trivial alphas are
involved. Scaling transforms is left as the only direct way to obtain
a linear spectrum from a sequence of premul color stops that have
alpha < 1.0, but that's really outside the gradient api.
As to the SVG spec.. Well, good or bad, no spec should really
be considered as the best, last word on anything.. If conforming to
it is feasible, then that surely is a good idea, and if you can do
more or better somehow, then that too would surely be a good idea :)
I can't really suggest to you a 'better' api that would take
into account having premul color stops then what you already thought,
only point out that a non-premul only interface and implementation
is limiting as well.. And if you think enough about what's actually
'behind' gradients -- one-dimensional texture data -- then, having
non-premul semantics there but premul semantics for the two-dim
case.. seems like a somewhat arbitrary inconsistency from that
perspective.
Thanks for your time.. :)
jose.
More information about the cairo
mailing list