[cairo] Cairo gradients and pre-mul data
jose_ogp at juno.com
jose_ogp at juno.com
Wed Jun 21 02:12:26 PDT 2006
> > We recognised the limitations and inconsistency when this choice
> > was made, but we did it for entirely practical reasons --
> > we wanted to implement SVG drawing with the cairo API, and
> > non-premul gradient stops were required for this case. There's
> > nothing preventing the addition of premultiplied gradient stops
> > through an added API in the future; we just haven't found a
> > significant need for it as yet.
>
> Since I'm too lazy to figure out the math...
>
> What's the premultiplied equivalent of a non-premult gradient from
> (1, 0, 0, 0) to (1, 1, 1, 0)? I.e. transparent red to solid white.
> On the GIMP this gives me a transparent-to-white gradient with a
> red tinge in the middle section.
>
> Would one need to overlay two premultiplied gradients or something
> like that?
>
> Federico
>
Therein lies part of the problem with premul and non-premul..
two different color spaces to deal with.
There are many subtle issues of consistency and predictability
that arise from dealing with mixing these two.
For example, if you want to create a radial gradient which
forms an ellipse, then you have two possibly different approaches -
the implementation could create a symmetric radial one, and then
use a scaling transformation on premul data to 'ellongate' it, or
it could scale it in non-premul color space and then premul that
result, ... or some other way. These could give different results.
Which is the "correct" one, and how do you know which one you're
getting?
Consider also for example if you create a linear gradient
(from some set of color stops), render copy the result to a zeroed
1-dim surface of same length and grab those pixels. You would expect
to be able to duplicate the gradient from this info.. eg. take the
colors, un-premul them, give them equal stop distances from each
other... But, that may fail to faithfully regenerate the gradient.
There are quite a few other such 'aspects' that entail from
mixing the two color spaces.
Your example/question seems to give the deciding reason for
why SVG, and thus Cairo, chose to want non-premul color stops --
namely so as to "easily obtain" what you describe.
If you were to simply premul "tansparent red" and "solid
white" (by which you may have meant (1,1,1,1)?), and use them to
generate a linear spectrum, then you would get an alpha-grey
spectrum, ie. linearly varying from transp black to solid white.
Not at all what you wanted to see.
However, if you take instead the three premul color stops:
transp-black half-opaque-redish fully-opaque-white
then the result would be quite close to what you describe.. and
the set of stops actually describes the result itself.
If you add more such stops you can get as close as you want
to a given variation, and you know exactly how the variance is
obtained - linearly from the premul color stops.
I understand the desire to have support for the SVG spec,
but there are aspects there that are less then satisfactory (and
they are not strictly necessary in order to obtain things like
fading-out-to-a-color), and it may be wise to keep such in mind.
jose.
More information about the cairo
mailing list