[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