summaryrefslogtreecommitdiff
path: root/src/cairo.c
diff options
context:
space:
mode:
authorAdrian Johnson <ajohnson@redneon.com>2016-10-01 22:05:42 +0930
committerAdrian Johnson <ajohnson@redneon.com>2016-10-01 22:05:42 +0930
commitdcbfb726478f5ab2277bd52813b40e565612566a (patch)
treebba0e6de102a3fac24d9c80bcc23c595266d2e2d /src/cairo.c
parent25da407a5f1d136345759c0d0a2a1d985eb2b392 (diff)
downloadcairo-dcbfb726478f5ab2277bd52813b40e565612566a.tar.gz
pdf: structured text and hyperlink support
Diffstat (limited to 'src/cairo.c')
-rw-r--r--src/cairo.c262
1 files changed, 261 insertions, 1 deletions
diff --git a/src/cairo.c b/src/cairo.c
index 76d8c56ce..02b917102 100644
--- a/src/cairo.c
+++ b/src/cairo.c
@@ -107,6 +107,220 @@
* space</firstterm>.
**/
+/**
+ * SECTION:cairo-tag
+ * @Title: Tags and Links
+ * @Short_Description: Hyperlinks and document structure
+ * @See_Also: #cairo_pdf_surface_t
+ *
+ * The tag functions provide the ability to specify hyperlinks and
+ * document logical structure on supported backends. The following tags are supported:
+ * * [Link][link] - Create a hyperlink
+ * * [Destinations][dest] - Create a hyperlink destination
+ * * [Document Structure Tags][doc-struct] - Create PDF Document Structure
+ *
+ * # Link Tags # {#link}
+ * A hyperlink is specified by enclosing the hyperlink text with the %CAIRO_TAG_LINK tag.
+ *
+ * For example:
+ * <informalexample><programlisting>
+ * cairo_tag_begin (cr, CAIRO_TAG_LINK, "uri='http://cairographics.org'");
+ * cairo_move_to (cr, 50, 50);
+ * cairo_show_text (cr, "This is a link to the cairo website.");
+ * cairo_tag_end (cr, CAIRO_TAG_LINK);
+ * </programlisting></informalexample>
+ *
+ * The PDF backend uses one or more rectangles to define the clickable
+ * area of the link. By default cairo will use the extents of the
+ * drawing operations enclosed by the begin/end link tags to define the
+ * clickable area. In some cases, such as a link split across two
+ * lines, the default rectangle is undesirable.
+ *
+ * @rect: [optional] The "rect" attribute allows the application to
+ * specify one or more rectangles that form the clickable region. The
+ * value of this attribute is an array of floats. Each rectangle is
+ * specified by four elements in the array: x, y, width, height. The
+ * array size must be a multiple of four.
+ *
+ * An example of creating a link with user specified clickable region:
+ * <informalexample><programlisting>
+ * cairo_font_extents_t font_extents;
+ * cairo_text_extents_t text1_extents;
+ * cairo_text_extents_t text2_extents;
+ * char attribs[100];
+ * const char *text1 = "This link is split";
+ * const char *text2 = "across two lines";
+ *
+ * cairo_font_extents (cr, &font_extents);
+ * cairo_move_to (cr, 450, 50);
+ * cairo_text_extents (cr, text1, &text1_extents);
+ * cairo_move_to (cr, 50, 70);
+ * cairo_text_extents (cr, text2, &text2_extents);
+ * sprintf (attribs,
+ * "rect=[%f %f %f %f %f %f %f %f] uri='http://cairographics.org'",
+ * text1_extents.x_bearing,
+ * text1_extents.y_bearing,
+ * text1_extents.width,
+ * text1_extents.height,
+ * text2_extents.x_bearing,
+ * text2_extents.y_bearing,
+ * text2_extents.width,
+ * text2_extents.height);
+ *
+ * cairo_tag_begin (cr, CAIRO_TAG_LINK, attribs);
+ * cairo_show_text (cr, "This is a link to the cairo website");
+ * cairo_move_to (cr, 450, 50);
+ * cairo_show_text (cr, text1);
+ * cairo_move_to (cr, 50, 70);
+ * cairo_show_text (cr, text2);
+ * cairo_tag_end (cr, CAIRO_TAG_LINK);
+ * </programlisting></informalexample>
+ *
+ * There are three types of links. Each type has its own attributes as detailed below.
+ * * [Internal Links][internal-link] - A link to a location in the same document
+ * * [URI Links][uri-link] - A link to a Uniform resource identifier
+ * * [File Links][file-link] - A link to a location in another document
+ *
+ * ## Internal Links ## {#internal-link}
+ * An internal link is a link to a location in the same document. The destination
+ * is specified with either:
+ *
+ * @dest: a UTF-8 string specifying the destination in the PDF file to link
+ * to. Destinations are created with the %CAIRO_TAG_DEST tag.
+ *
+ * or the two attributes:
+ *
+ * @page: An integer specifying the page number in the PDF file to link to.
+ *
+ * @pos: [optional] An array of two floats specifying the x,y position
+ * on the page. Default is 0,0.
+ *
+ * An example of the link attributes to link to a page and x,y position:
+ * <programlisting>
+ * "page=3 pos=[3.1 6.2]"
+ * </programlisting>
+ *
+ * ## URI Links ## {#uri-link}
+ * A URI link is a link to a Uniform Resource Identifier ([RFC 2396](http://tools.ietf.org/html/rfc2396)).
+ *
+ * A URI is specified with the following attribute:
+ *
+ * @uri: An ASCII string specifying the URI.
+ *
+ * An example of the link attributes to the cairo website:
+ * <programlisting>
+ * "uri='http://cairographics.org'"
+ * </programlisting>
+ *
+ * ## File Links ## {#file-link}
+ * A file link is a link a location in another PDF file.
+ *
+ * The file attribute (required) specifies the name of the PDF file:
+ *
+ * @file: File name of PDF file to link to.
+ *
+ * The position is specified by either:
+ *
+ * @dest: a UTF-8 string specifying the named destination in the PDF file.
+ *
+ * or
+ *
+ * @page: An integer specifying the page number in the PDF file.
+ *
+ * @pos: [optional] An array of two floats specifying the x,y position
+ * on the page. Default is 0,0.
+ *
+ * An example of the link attributes to PDF file:
+ * <programlisting>
+ * "file='document.pdf' page=16 pos=[25 40]"
+ * </programlisting>
+ *
+ * # Destination Tags # {#dest}
+
+ * A destination is specified by enclosing the destination drawing
+ * operations with the %CAIRO_TAG_DEST tag.
+ *
+ * @name: [required] A UTF-8 string specifying the name of this destination.
+ *
+ * @x: [optional] A float specifying the x coordinate of destination
+ * position on this page. If not specified the default
+ * x coordinate is the left side of the extents of the
+ * operations enclosed by the %CAIRO_TAG_DEST begin/end tags. If
+ * no operations are enclosed, the x coordidate is 0.
+ *
+ * @y: [optional] A float specifying the y coordinate of destination
+ * position on this page. If not specified the default
+ * y coordinate is the top of the extents of the
+ * operations enclosed by the %CAIRO_TAG_DEST begin/end tags. If
+ * no operations are enclosed, the y coordidate is 0.
+ *
+ * @internal: A boolean that if true, the destination name may be
+ * ommitted from PDF where possible. In this case, links
+ * refer directly to the page and position instead of via
+ * the named destination table. Note that if this
+ * destination is referenced by another PDF (see [File Links][file-link]),
+ * this attribute must be false. Default is false.
+ *
+ * <informalexample><programlisting>
+ * /&ast; Create a hyperlink &ast;/
+ * cairo_tag_begin (cr, CAIRO_TAG_LINK, "dest='mydest' internal");
+ * cairo_move_to (cr, 50, 50);
+ * cairo_show_text (cr, "This is a hyperlink.");
+ * cairo_tag_end (cr, CAIRO_TAG_LINK);
+ *
+ * /&ast; Create a destination &ast;/
+ * cairo_tag_begin (cr, CAIRO_TAG_DEST, "name='mydest'");
+ * cairo_move_to (cr, 50, 250);
+ * cairo_show_text (cr, "This paragraph is the destination of the above link.");
+ * cairo_tag_end (cr, CAIRO_TAG_DEST);
+ * </programlisting></informalexample>
+ *
+ * # Document Structure (PDF) # {#doc-struct}
+ *
+ * The document structure tags provide a means of specifying structural information
+ * such as headers, paragraphs, tables, and figures. The inclusion of structural information faciliates:
+ * * Extraction of text and graphics for copy and paste
+ * * Reflow of text and graphics in the viewer
+ * * Proccessing text eg searching and indexing
+ * * Conversion to other formats
+ * * Accessability support
+ *
+ * The list of structure types is specified in section 14.8.4 of the
+ * [PDF Reference](http://www.adobe.com/content/dam/Adobe/en/devnet/acrobat/pdfs/PDF32000_2008.pdf).
+ *
+ * Note the PDF "Link" structure tag is the same as the cairo %CAIRO_TAG_LINK tag.
+ *
+ * The following example creates a document structure for a document containing two section, each with
+ * a header and a paragraph.
+ *
+ * <informalexample><programlisting>
+ * cairo_tag_begin (cr, "Document", NULL);
+ *
+ * cairo_tag_begin (cr, "Sect", NULL);
+ * cairo_tag_begin (cr, "H1", NULL);
+ * cairo_show_text (cr, "Heading 1");
+ * cairo_tag_end (cr, "H1");
+ *
+ * cairo_tag_begin (cr, "P", NULL);
+ * cairo_show_text (cr, "Paragraph 1");
+ * cairo_tag_end (cr, "P");
+ * cairo_tag_end (cr, "Sect");
+ *
+ * cairo_tag_begin (cr, "Sect", NULL);
+ * cairo_tag_begin (cr, "H1", NULL);
+ * cairo_show_text (cr, "Heading 2");
+ * cairo_tag_end (cr, "H1");
+ *
+ * cairo_tag_begin (cr, "P", NULL);
+ * cairo_show_text (cr, "Paragraph 2");
+ * cairo_tag_end (cr, "P");
+ * cairo_tag_end (cr, "Sect");
+ *
+ * cairo_tag_end (cr, "Document");
+ * </programlisting></informalexample>
+ *
+ **/
+
#define DEFINE_NIL_CONTEXT(status) \
{ \
CAIRO_REFERENCE_COUNT_INVALID, /* ref_count */ \
@@ -156,7 +370,8 @@ static const cairo_t _cairo_nil[] = {
DEFINE_NIL_CONTEXT (CAIRO_STATUS_JBIG2_GLOBAL_MISSING),
DEFINE_NIL_CONTEXT (CAIRO_STATUS_PNG_ERROR),
DEFINE_NIL_CONTEXT (CAIRO_STATUS_FREETYPE_ERROR),
- DEFINE_NIL_CONTEXT (CAIRO_STATUS_WIN32_GDI_ERROR)
+ DEFINE_NIL_CONTEXT (CAIRO_STATUS_WIN32_GDI_ERROR),
+ DEFINE_NIL_CONTEXT (CAIRO_STATUS_TAG_ERROR)
};
COMPILE_TIME_ASSERT (ARRAY_LENGTH (_cairo_nil) == CAIRO_STATUS_LAST_STATUS - 1);
@@ -2667,6 +2882,24 @@ cairo_copy_clip_rectangle_list (cairo_t *cr)
}
/**
+ * CAIRO_TAG_DEST:
+ *
+ * Create a destination for a hyperlink. Destination tag attributes
+ * are detailed at [Destinations][dests].
+ *
+ * Since: 1.16
+ **/
+
+/**
+ * CAIRO_TAG_LINK:
+ *
+ * Create hyperlink. Link tag attributes are detailed at
+ * [Links][links].
+ *
+ * Since: 1.16
+ **/
+
+/**
* cairo_tag_begin:
* @cr: a cairo context
* @tag_name: tag name
@@ -2676,6 +2909,30 @@ cairo_copy_clip_rectangle_list (cairo_t *cr)
* cairo_tag_end() with the same @tag_name to mark the end of the
* structure.
*
+ * The attributes string is of the form "key1=value2 key2=value2 ...".
+ * Values may be boolean (true/false or 1/0), integer, float, string,
+ * or an array.
+ *
+ * String values are enclosed in single quotes
+ * ('). Single quotes and backslashes inside the string should be
+ * escaped with a backslash.
+ *
+ * Boolean values may be set to true by only
+ * specifying the key. eg the attribute string "key" is the equivalent
+ * to "key=true".
+ *
+ * Arrays are enclosed in '[]'. eg "rect=[1.2 4.3 2.0 3.0]".
+ *
+ * If no attributes are required, @attributes can be an empty string or NULL.
+ *
+ * See [Tags and Links Description][cairo-Tags-and-Links.description]
+ * for the list of tags and attributes.
+ *
+ * Invalid nesting of tags or invalid attributes will cause @cr to
+ * shutdown with a status of %CAIRO_STATUS_TAG_ERROR.
+ *
+ * See cairo_tag_end().
+ *
* Since: 1.16
**/
void
@@ -2698,6 +2955,9 @@ cairo_tag_begin (cairo_t *cr, const char *tag_name, const char *attributes)
*
* Marks the end of the @tag_name structure.
*
+ * Invalid nesting of tags will cause @cr to shutdown with a status of
+ * %CAIRO_STATUS_TAG_ERROR.
+ *
* See cairo_tag_begin().
*
* Since: 1.16