[cairo] Path Gradients

Bill Spitzak spitzak at thefoundry.co.uk
Sat Dec 22 19:08:43 PST 2007


On Dec 21, 2007, at 1:28 PM, jose_ogp at juno.com wrote:

>
> 	Behdad wrote:
>
>> Humm, meshes in general would have made much more sense in cairo
>> if it supported projective transformations.  What's people's insight
>> about that?  Am I right that Xrender supports them?  What about
>> PS/PDF/SVG?
>
> 	"Meshes" would need a suitable definition, but rectangular
> and/or triangle meshes would likely be a welcome addition. Xrender
> initially played around with "triangle fans and strips", but it seems
> that never made it very far(?).

Unfortnately too much data is not a simple mesh. There needs to be a 
method to draw a completely arbitrary connected graph of points.

My recommendation is to add some way to indicate that the current path 
edge is going to be drawn adjacent to another filled object with the 
exact same path edge. This would allow Cairo to remain thinking about 
single fills, and a single transform of the source image per fill.

The biggest problem with my idea is that points must be sent many 
times, for a triangle mesh the point would be resent for every 
triangle. Now Cairo is not going to be used to draw games, so this may 
not be a problem. But if it is, there will probably have to be a way to 
send a whole set of points once, and then index into this set when 
building the paths.

There is also a lot of desire to say "this point should get this x+y 
coordinate from the source pattern, or this value from the gradient". 
Technically this can be achieved with the current Cairo api, but it 
involves a lot of really ugly math, and seems to be the sort of thing 
that Cairo should do for you.

> 	I'm not sure why you feel that meshes would make 'more sense'
> with projective transforms..?

I believe he means that we need projective transforms for source 
patterns. This is needed to distort a texture map to match the mesh, 
and produce images that look like 3d renders.

Anything else having to do with 3D can be done by code calling Cairo by 
transforming the 3D position to the correct 2D screen positing before 
passing it to Cairo.

>  As far as projective transforms go, there
> are certain "issues" you'd have to deal with because such transforms
> don't - in general - preserve lines, or quadratics, or cubics... thus
> making their use as transforms of "paths" somewhat problematic.
> 	Not to mention that transforms are often used via sampling in
> an 'inverse' way.. and such transforms, while their 3x3 matrices may
> be invertible, may not in effect be invertible when used as transforms
> acting on 2D coordinates.
> 	It is possible to do things in a 2-step process, wherein one
> could apply an affine transform on paths and a projective one on the
> rasterized result - ie. first transform back via the projective one,
> and then work 'as usual' in that coordinate system.

Quadratics and Cubics are preserved through perspective transformations 
if you use interpolate homoginized coordinates (ie where there is x,y,w 
for the projected point, and the resulting point on the screen is x/w, 
y/w. Interpolate the x,y, and the w according to the cubic and it will 
be projected correctly).

My biggest problem with making Cairo do 3D is that as currently defined 
it is useless. Supposedly the pen and font are always transformed by 
the current transform. This would mean that any projected path would be 
equivalent to drawing that path using the current pen in 2D and then 
pespective transforming the resulting surface. This is trivial to do by 
using a seperate surface (and pretty much impossible to achieve in any 
other way). A far more useful result is to draw the resulting path with 
a fixed-size pen, this is also much easier to implement. This is the 
main reason why I want to see Cairo changed so that the pen and font 
are fixed in device space at the moment they are set, rather than being 
modified by further transforms.

There is also problems with the path object in that there is no way to 
cleanly add a z or w to the points. It should instead be a 1-d list of 
ops alternated with coordinates, and the ops have an argument in them 
indicating how many numbers are provided. This would also be more 
compact than the current representation.



More information about the cairo mailing list