[cairo] shading (again)

Thomas Hunger info at teh-web.de
Thu Feb 26 13:37:24 PST 2004


Hello

I tried to add shading to cairo, it is still very rough:

you can get it here [1] as a tarball, since it is very intrusive and modifies 
a lot of things I did not create a patchset. You should have a spare copy of 
cairo since it may break everything.

There is a new exposed type, called a cairo_shader_t:

struct cairo_shader {
  unsigned int refcount;
  int nr_points;
  int nr_colors;
  double *points; // an array of control points in xy xy xy ... layout
  double *colors; // array of colors in rgba rgba ...
  cairo_shader_func_t *shader_func;
};

Whenever cairo does a cairo_(stroke|fill), it calculates the bounding box 
using a newly introduced function:

     _cairo_traps_bounds (&traps, &left, &right, &top, &bottom);

which assigns the rectangular area covered by a stroke or fill to the doubles 
left, right, ...

then this information gets passed to the shader_func in the cairo_shader_t, 
along with the cairo_shader_t itself:

      gstate->shader->shader_func (gstate->shader, top, bottom, left, right, 
&shader_surface);

the shader func creates a new surface which is then used by cairo as source 
instead of a pattern or a solid color.

reasoning
----------------
- I wanted to expose the structure and not hide it away so that new shaders 
could be added from the outside
- the points-member are controlpoints e.g. to describe the vector for a linear 
gradient, radius of a radial one, or maybe someday a lot of control points.
- control points will be transformed by all operations, so rotating will 
rotate the gradient, too (see screenshot [1])
- the colors are seperated from control points since there may be more points 
than colors, e.g. when describing a gradient with a spline.

drawbacks
------------------
- for testing I did a linear shader which has errors and is clumsy, so 
actually no real shaders exist so far
- I do not know if hardware acceleration can be used in any way if done like 
this
- it wont work with different backends other than pixel-orientated ones yet 
(no idea how it  could be mapped to postscript or pdf shading)
- the _cairo_traps_bounds is ugly as our neighbours dog
- writing an own shader is not exactly fun
- very slow since the shader needs to calculate every pixel itself
- should be able to work with tolerance

[1] http://www.iqo.uni-hannover.de/gnome/cairo/

P.S. if this test restarts discussion about shading and everything is done in 
a completely different way then, I am a happy man :)





More information about the cairo mailing list