[cairo] [RFC] cairo_path_extents()

Baz brian.ewins at gmail.com
Thu Nov 22 09:32:24 PST 2007

On Nov 22, 2007 3:13 PM, Leon Woestenberg <leon.woestenberg at gmail.com> wrote:
> Hello,
> On Nov 22, 2007 9:11 AM, Jonathan Watt <jwatt at jwatt.org> wrote:
> > Baz wrote:
> > > Behdad suggested adding a cairo_path_extents() call to meet their
> > > need; to me this sounds like a better option than special-casing
> > > stroke_extents or fill_extents for hairlines. The proposed api is:
> > >
> > > void        cairo_path_extents (cairo_t *cr,
> > >                                              double *x1,
> > >                                              double *y1,
> > >                                              double *x2,
> > >                                              double *y2);
> > >
> > > "Computes a bounding box in user coordinates covering the all points
> > > on the current path. If the current path is empty, returns an empty
> > > rectangle (0,0, 0,0). Stroke parameters, surface dimensions and
> > > clipping are not taken into account."
> >
> > s/the all/all the/
> >
> "covering all the points on the current path"
> What exactly are "all the points on the current path". Does this mean
> the extents of the path, if it was traced by an infinitely small point
> with an infinitely small curve error tolerance?

Pretty much. It is the limit of stroke_extents as stroke_width tends
to zero (except that stroke extents are defined as zero for stroke
width = 0). The implementation I posted uses the tolerance you set
with cairo_set_tolerance. The motivation is SVGLocatable.getBBox():

BTW Carl also originally suggested on the bug that the behaviour of
stroke_extents for a stroke_width of 0 should be what this
path_extents does. It's one alternative, although some people might be
relying on stroke_extents returning inked bounds, for damage detection

> Is this function more performant than a stroke_extents()?

As I said, stroke_extents does not return the same results - see
above. You could get the same numbers by resetting the stroke width to
a known non-zero value, the line caps to round, the dashing to none,
and subtract the stroke width from the resulting stroke_extents.
However, calling path_extents should be faster as it does not need to
tesselate, deal with caps, etc - it just iterates over the path and
calculates the extents as it goes.

You could estimate a bounding box from the control points of the
curves (aka 'the control box'), and go faster, but the result will not
be tight. cairo_path_bounds.c was doing that, but Carl described it as
'obviously wrong' in the bug. Reading back I havent made it clear that
the first of these patches changes the behaviour of
_cairo_analysis_surface_intersect_clip_path and _cairo_path_bounds to
use the tight bounds instead of the control box, which will make that
code slower.


More information about the cairo mailing list