[cairo] RFC v3: Path Effects API

Bryce Harrington bryce at osg.samsung.com
Tue Oct 18 23:11:03 UTC 2016


On Tue, Oct 18, 2016 at 11:01:03PM +0200, Petr Kobalíček wrote:
> What about chaining effects, the API seems to only deal with one effect at
> time, is that correct?

I'd like the API to support chained effects, although you're right the
API suggests there can be only one effect at a time.

I'd like it to also support booleaned effects, which implies applying
two effects and then a boolean on top to merge them together.  However,
I'm a bit vague on exactly how all that should work.  Suggestions?

Bryce
 
> On Tue, Oct 18, 2016 at 6:27 PM, Bill Spitzak <spitzak at gmail.com> wrote:
> 
> > On Mon, Oct 17, 2016 at 11:15 AM, Bryce Harrington
> > <bryce at osg.samsung.com> 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.
> > >
> > > In 2014 I posted[4] a rough cut at such an API, following
> > > cairo_pattern's API design, and a v2 shortly thereafter[5].  Following
> > > is a v3 of that proposal, incorporating some of Chris Wilson's suggested
> > > changes.
> > >
> > > In particular, this divides the API into a base class (Effects), and
> > > sub-class (Path Effects), allowing for future introduction of pen
> > > effects, material effects, etc.  This common API is intended to
> > > provide a consistent way of handling all effects in the rendering
> > > pipeline.
> > >
> > > v2:
> > >   + Add get_data, set_data, reference_count for the cairo_object_t api
> > >   + Rename enums
> > > v3:
> > >   + Path Effects are handled as a subclass of Effects
> > >
> > > ---
> > >
> > > /*
> > >  * Effect lifecycle management
> > >  */
> > > 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);
> > >
> > > cairo_public unsigned int
> > > cairo_effect_get_reference_count (cairo_effect_t *effect);
> > >
> > > cairo_public void *
> > > cairo_effect_get_user_data (cairo_effect_t *effect,
> > >                             const cairo_user_data_key_t *key);
> > > cairo_public cairo_status_t
> > > cairo_effect_set_user_data (cairo_effect_t *effect,
> > >                             const cairo_user_data_key_t *key,
> > >                             void *user_data,
> > >                             cairo_destroy_funct_t destroy);
> > >
> > > /*
> > >  * Effect properties
> > >  */
> > > typedef enum _cairo_effect_type {
> > >     CAIRO_EFFECT_TYPE_NONE = 0,
> > >     CAIRO_EFFECT_TYPE_PATH
> > > } cairo_effect_type_t;
> > >
> > > /* Future types might include:
> > >  *  CAIRO_EFFECT_TYPE_PEN
> > >  *  CAIRO_EFFECT_TYPE_MATERIAL
> > >  *  CAIRO_EFFECT_TYPE_OPERATOR
> > >  *  CAIRO_EFFECT_TYPE_CLIP
> > >  *  ...
> > >  */
> > >
> > > cairo_public cairo_effect_type_t
> > > cairo_effect_get_type (cairo_effect_t *effect);
> > >
> > >
> > >
> > > /* ----------------------------------------------------------------------
> > */
> > >
> > > /*
> > >  * Path effect creation
> > >  *
> > >  * These create effects of type CAIRO_EFFECT_TYPE_PATH.
> > >  */
> > > cairo_public cairo_effect_t *
> > > cairo_effect_create_drop_shadow_path (double x_offset, double y_offset,
> > >                                       double x_blur,   double y_blur);
> > >
> > > cairo_public cairo_effect_t *
> > > cairo_effect_create_inset_shadow_path (double x_inset, double y_inset,
> > >                                        double x_blur,  double y_blur);
> > >
> > > /*
> > >  * Applying path 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);
> > >
> > > /*
> > >  * Path effect properties
> > >  */
> > > typedef enum _cairo_path_effect_type {
> > >     CAIRO_PATH_EFFECT_NONE = 0,
> > >     CAIRO_PATH_EFFECT_DROP_SHADOW,
> > >     CAIRO_PATH_EFFECT_INSET_SHADOW
> > > } cairo_path_effect_type_t;
> > >
> > > /* Future path effect types could include:
> > >  *  CAIRO_PATH_EFFECT_PATTERN
> > >  *  CAIRO_PATH_EFFECT_UNION
> > >  *  CAIRO_PATH_EFFECT_DIFFERENCE
> > >  *  CAIRO_PATH_EFFECT_INTERSECTION
> > >  *  ...
> > >  */
> > >
> > > cairo_public cairo_path_effect_type_t
> > > cairo_path_effect_get_subtype (cairo_effect_t *effect);
> > >
> > > cairo_public void
> > > cairo_path_effect_set_rgba (cairo_path_effect_t *path_effect,
> > >                             double red, double green, double blue,
> > >                             double alpha);
> > >
> > > Internally, both the effect type and subtype can be tracked in a single
> > > property, e.g.:
> > >
> > >     type = CAIRO_EFFECT_TYPE_PATH << 24 | CAIRO_PATH_EFFECT_DROP_SHADOW;
> > >
> > >
> > > 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.  An idea is to provide a
> > > backend/user preference as to whether effects should be cached or
> > > applied on the fly, e.g. cairo_effect_set_cached.
> > >
> > > Bryce
> > >
> > > 0:  https://lists.cairographics.org/archives/cairo/2013-
> > September/024596.html
> > > 1:  The cairogles branch is no longer available publically.  The private
> > >     branch is at https://github.com/SRA-SiliconValley/cairogles
> > > 2:  https://lists.cairographics.org/archives/cairo/2013-
> > September/024598.html
> > > 3:  https://lists.cairographics.org/archives/cairo/2013-
> > September/024597.html
> > > 4:  https://lists.cairographics.org/archives/cairo/2014-
> > October/025748.html
> > > 5:  https://lists.cairographics.org/archives/cairo/2014-
> > October/025766.html
> > > --
> > > cairo mailing list
> > > cairo at cairographics.org
> > > https://lists.cairographics.org/mailman/listinfo/cairo
> >
> > Seems to me there is excessive namespacing here. There is no need for
> > an "effect type", it should just be clear from the effect description
> > whether it has an effect on stroke, fill, or text, or which parts of
> > the inputs it changes.
> >
> > Possibly you are thinking that the effects would be mutually exclusive
> > and that the type is to identify the mutually exclusive set, but that
> > seems really limiting and I think you will end up with one "type" for
> > each effect. Instead just allow arbitrary sets of effects to be
> > active. If two effects can't be done at the same time, it is either an
> > error, or one of them takes precedence.
> >
> > I would also remove "PATH" from all your enumerations and function
> > names. Some of them are really confusing now, for instance
> > "cairo_effect_create_inset_shadow_path" does not create a path, it
> > creates an effect.
> > --
> > cairo mailing list
> > cairo at cairographics.org
> > https://lists.cairographics.org/mailman/listinfo/cairo
> >


More information about the cairo mailing list