[cairo] API proposal for document links

Alp Toker alp at atoker.com
Mon Nov 19 16:26:52 PST 2007


I've started adding printing support to WebKit/GTK+. One feature that 
we're missing from Cairo is support for hyperlinks and destinations in 
document surfaces.

I've studied the PDF and XPS specifications and come up with a first 
draft for a proposed general API to mark link sources and destinations. 
The API is slightly more expressive than the CoreGraphics equivalent in 
that it allows for an arbitrary path to provide the area of the link, 
rather than just a rectangle, and is generalised to apply to any 
portable document formats that Cairo might support rather than just PDF.

The API is easy to follow if you're familiar with the cairo_set_source() 
variants and cairo_fill(). Here's it is along with commentary from the 
PDF and XPS specifications where appropriate:

/* Document functions */

/* cairo_destination(): Mark the current point on the current page as a 
link destination with the given name. This can later be used as the 
destination for a link using cairo_set_link_destination(). */
/* Commentary: PDF: "Instead of being defined directly ... a destination 
may be referred to indirectly by means of a name object." */
/* Commentary: XPS: "Producers can mark any <FixedPage>, <Canvas>, 
<Path>, or <Glyphs> element as an addressable location within the XPS 
Document by specifying a value for the Name attribute." */

cairo_destination (cairo_t *cr, const char *name);

/* cairo_set_link_destination(): Set the link destination within cr to 
the destination of the given name. This destination will be used for 
subsequent link operations. */
/* Commentary: XPS: There are some fairly strict restrictions on 
internal link names since they end up being represented as part of the 
fragment component of the URI schema. We might need to do some 
normalisation. */

cairo_set_link_destination (cairo_t *cr, const char *name);

/* cairo_set_link_page(): Set the link destination within cr to the 
given absolute page number. This destination will be used for subsequent 
link operations. */
/* Commentary: PDF: There is built-in support for linking to a page 
number. */
/* Commentary: XPS: My understanding is that the page number to link to 
is equivalent to a destination name with the number as a string, and is 
contained in the fragment component of the URI schema. */

cairo_set_link_destination (cairo_t *cr, const char *name);

/* cairo_set_link_uri(): Set the link destination within cr to link to 
the given URI. This destination will be used for subsequent link 
operations. */

cairo_set_link_uri (cairo_t *cr, const char *uri);

/* cairo_link(): A document operator that links the fill of the current 
path (according to the current fill rule) to the currently set 
destination. If a document surface supports only rectangular link areas, 
this operation will use the fill extents of the current path. The 
current path will be cleared from the cairo context. */
/* Commentary: PDF: "A link annotation represents either a hypertext 
link to a destination elsewhere in the document." */
/* Commentary: XPS: "Hyperlinks are specified inline on any <Canvas>, 
<Path>, or <Glyphs> element by means of the FixedPage.NavigateUri 
attribute. The value of the attribute is the destination URI." External 
and internal links are both represented using URIs. */

cairo_link (cairo_t *cr);

/* cairo_link_preserve(): Like cairo_link(), but preserves the path 
within the cairo context. */
cairo_link_preserve (cairo_t *cr);

More information about the cairo mailing list