[cairo] RFC: Shadow API

Chris Wilson chris at chris-wilson.co.uk
Wed Oct 22 02:10:14 PDT 2014


On Wed, Oct 22, 2014 at 01:20:56AM -0700, Bryce Harrington wrote:
> In September 2013, Henry proposed[0] adding a feature for Gaussian blur
> and shadow, based on work carried in his cairogles branch[1].  The
> proposed API[2] was felt to have too many entry points to the context for
> setting all the various parameters (shadow color and type, blur
> direction, etc.), and Chris suggested[3] coming up with a more generic
> API that would handle path effects in a way more analogous to patterns.
> 
> Following is my own rough cut at making it more akin to cairo_pattern's
> API design:
> 
> 
> /*
>  * Effect object management
>  */
> cairo_public cairo_effect_t *
> cairo_effect_create_drop_shadow (double x_offset, double y_offset,
>                                  double x_blur,   double y_blur);
> 
> cairo_public cairo_effect_t *
> cairo_effect_create_inset_shadow (double x_offset, double y_offset,
>                                   double x_blur,   double y_blur);
> 
> cairo_public cairo_status_t
> cairo_effect_status (cairo_effect_t *effect);
> 
> cairo_public cairo_effect_t *
> cairo_effect_reference (cairo_effect_t *effect);
> 
> cairo_public void
> cairo_effect_destroy (cairo_effect_t *effect);

You need a couple more for the cairo_object_t api:

get_reference_count,
get_user_data,
set_user_data,

That's the idea I had...

> /*
>  * Effect properties
>  */
> typedef enum _cairo_effect_type {
>     CAIRO_EFFECT_NONE = 0,
>     CAIRO_EFFECT_DROP_SHADOW,
>     CAIRO_EFFECT_INSET_SHADOW
> } cairo_effect_type_t;
> 
> cairo_public cairo_effect_type_t
> cairo_effect_get_type (cairo_effect_t *effect);
> 
> cairo_public void
> cairo_effect_set_rgb (cairo_pattern_t *pattern,
>                       double red, double green, double blue);
> 
> cairo_public void
> cairo_effect_set_rgba (cairo_pattern_t *pattern,
>                        double red, double green, double blue,
>                        double alpha);
> 
> 
> /*
>  * Applying effects to the context
>  */
> cairo_public void
> cairo_set_path_effect (cairo_t *cr, cairo_effect_t *source);
> 
> cairo_public cairo_effect_t *
> cairo_get_path_effect (cairo_t *cr);
> 
> 
> 
> Henry's API proposal included provision for shadow caching by the
> application.  That certainly made a huge difference in the demos, so
> maybe it's still going to be needed.  But I'm not sure whether this must
> be switched on via an API call, or if the optimization can somehow be
> handled internally.  If it does need an API call, it could be handled as an
> effect property and set via something like cairo_effect_set_cached.

Yes, we will need something like that. My plan was to make the path
first class so we could bake effects into it, or apply them on the fly
depending on backend/user preference. (Using cairo_shape_t to
disambuiguate with the existing cairo_path_t). And also to expose the
ability to bypass cairo_t and apply operators + shapes + patterns
directly onto surfaces.  We would have two levels of user API, the
canvas style cairo_t for simply drawing, and a lower level surface
interface for toolkits (and since the high level interface is just a
state tracker around the lower level interface, they could both be used
interchangeably). The drawback is that you need to work with a large
application in order to sanity check an alternate api. And you need to
work with <canvas> and <svg> style applications as well as PDF, to be
sure that we capture all the requirements. On the backend side, you also
need to compare/contrast with NV_path_rendering (which is actually a
pretty good design on how to integrate with OpenGL, something we should
strive to emulate), Direct2D, OpenVG, PDF, SVG and a new protocol for
X11 (so that at least is not restrictive).

> Last time, there was also some discussion regarding handling of inset
> shadows, and whether the original object should be drawn with the shadow
> or drawn as a second cairo operation.  These both remain open points of
> discussion.

IMO, that's a little too implicit even for the high level cairo
interface, and keeping the interface focused arounds effects with a
straightforward pipeline should allow users to develop higher level
effects efficiently.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre


More information about the cairo mailing list