[cairo] Adding support for quadratic beziers

Shriramana Sharma samjnaa at gmail.com
Wed Aug 8 15:53:51 PDT 2012


Hello -- I am new to this list. From the page
http://lists.cairographics.org/archives/cairo/ I tried searching the
archives for "quadratic bezier" but for some reason it took me to
https://www.google.com/search?q=quadratic+bezier&sitesearch=%25%28archive_url%29s%2F
-- something is broken. So I'm posting this here.

Frankly I am not an expert coder or anything (or even in the
programming field) but I've been using Inkscape quite some, and I've
been struck by how it doesn't have support for quadratic beziers
despite the SVG standard specifying it. And I went and filed this:
https://bugs.launchpad.net/inkscape/+bug/1009765. While that bug can
easily be fixed without any change to cairo, I thought "why doesn't
cairo have this?" I have been using Qt for some programming, and saw
that Qt easily implements quadratic beziers internally using cubics by
degree elevation:
http://qt.gitorious.org/qt/qt/blobs/4.8/src/gui/painting/qpainterpath.cpp

I'm sure the people here know that a quadratic represented by the
points (s, c, e) is identical to the cubic represented by (s,
(s+2c)/3, (e+2c)/3, e) -- so I was wondering why isn't it available in
Cairo? At least at a user level even if not in the underlying data
(because I realize many/most backends don't implement a separate
quadTo)?

Having contributed some easy patches to QPainterPath for relative
equivalents of QPainterPath::moveTo() etc after seeing Cairo have such
functions (https://bugreports.qt-project.org/browse/QTBUG-26789), I
thought it might be easy for me to do something similar for Cairo:

But apparently because of C's non-object-oriented nature, I ran into a
maze of abstractions and redirections --

To provide a quad_to on par with curve_to and using curve_to, I
investigated where the user-visible curve_to is coming from:

As per the version I downloaded from
http://cgit.freedesktop.org/cairo/plain/src/, my trace:

user visible cairo_curve_to calls cr->backend->curve_to at cairo.c l 1560
we have to find which function this curve_to actually points to
for that we have to find which backend structure backend actually points to
now cr->backend is equated to argument backend passed to _cairo_init at l 248
_cairo_init is called with _cairo_default_context_backend for argument
backend by _cairo_default_context_init at cairo-default-context.c l
1394
(common _cairo_init declaration for cairo.c and
cairo-default-context.c is at cairo_private.h l 56)
structure _cairo_default_context_backend is defined at l 1278 et suivant
_cairo_default_context_backend includes the function pointer
_cairo_default_context_curve_to at l 1335
_cairo_default_context_curve_to is defined at l 674 et suivant
it converts the coords from double to internal fixed point
representation and calls _cairo_path_fixed_curve_to at l 697
_cairo_path_fixed_curve_to is defined at cairo-path-fixed.c l 580 et suivant
(common _cairo_path_fixed_curve_to declaration for
cairo-default-context.c and cairo-path-fixed.c is at cairoint.h l 912)
therefore this is the function actually called by
cr->backend->curve_to at cairo.c l 1560

So for quad_to to be implemented on par with and using cubic_to, it
would have to be done here, but by this time it has been converted
into fixed point where doing 2/3 is probably out of place, so it has
to be done at the higher level in _cairo_default_context_curve_to. But
then that is not the actual function doing the actual job. The
required quirks like "if this curve does not move", "make sure
subpaths are started properly" (and returning an error for rel_*_to if
there is no current point) are done at the lower level in
cairo-path-fixed.c only...

OTOH, quad_to will have to call get_current_point to calculate the
control points to pass to curve_to. So maybe it would be best to leave
quad_to (and rel_quad_to) at the top level after all and not try to
put it on par with curve_to (which it uses anyway). So I opted for the
simple way out, and wrote two small patches for the two outermost API
files.

As I said, I'm not an experienced coder (much less so related to
cairo), so maybe I have missed something important. So I just content
myself with submitting my superficial patches to the developers and
saying that I feel it would be useful if cairo had a quad_to and
rel_quad_to function.

Thank you for all your great work on Cairo and FOSS!

-- 
Shriramana Sharma
-------------- next part --------------
A non-text attachment was scrubbed...
Name: cairo.c.patch
Type: application/octet-stream
Size: 3236 bytes
Desc: not available
URL: <http://lists.cairographics.org/archives/cairo/attachments/20120809/b9c7b9c6/attachment.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: cairo.h.patch
Type: application/octet-stream
Size: 423 bytes
Desc: not available
URL: <http://lists.cairographics.org/archives/cairo/attachments/20120809/b9c7b9c6/attachment-0001.obj>


More information about the cairo mailing list