summaryrefslogtreecommitdiffstats
path: root/gfx/cairo/11-quartz-surface-tags.patch
blob: 7f73d388ea8ce9b9603ef68420abdbde5cf31ca7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
diff --git a/gfx/cairo/cairo/src/cairo-quartz-surface.c b/gfx/cairo/cairo/src/cairo-quartz-surface.c
--- a/gfx/cairo/cairo/src/cairo-quartz-surface.c
+++ b/gfx/cairo/cairo/src/cairo-quartz-surface.c
@@ -48,6 +48,7 @@
 #include "cairo-surface-backend-private.h"
 #include "cairo-surface-clipper-private.h"
 #include "cairo-recording-surface-private.h"
+#include "cairo-tag-attributes-private.h"
 
 #include <dlfcn.h>
 
@@ -2313,6 +2314,70 @@ static cairo_status_t
     return CAIRO_STATUS_SUCCESS;
 }
 
+static cairo_int_status_t
+_cairo_quartz_surface_tag (void			       *abstract_surface,
+			   cairo_bool_t                 begin,
+			   const char                  *tag_name,
+			   const char                  *attributes,
+			   const cairo_pattern_t       *source,
+			   const cairo_stroke_style_t  *style,
+			   const cairo_matrix_t	       *ctm,
+			   const cairo_matrix_t	       *ctm_inverse,
+			   const cairo_clip_t	       *clip)
+{
+    cairo_link_attrs_t link_attrs;
+    cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
+    int i, num_rects;
+    cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
+
+    /* Currently the only tag we support is "Link" */
+    if (strcmp (tag_name, "Link"))
+        return CAIRO_INT_STATUS_UNSUPPORTED;
+
+    /* We only process the 'begin' tag, and expect a rect attribute;
+       using the extents of the drawing operations enclosed by the begin/end
+       link tags to define the clickable area is not implemented. */
+    if (!begin)
+        return status;
+
+    status = _cairo_tag_parse_link_attributes (attributes, &link_attrs);
+    if (unlikely (status))
+	return status;
+
+    num_rects = _cairo_array_num_elements (&link_attrs.rects);
+    if (num_rects > 0) {
+        CFURLRef url = CFURLCreateWithBytes (NULL,
+                                             (const UInt8 *) link_attrs.uri,
+                                             strlen (link_attrs.uri),
+                                             kCFStringEncodingUTF8,
+                                             NULL);
+
+        for (i = 0; i < num_rects; i++) {
+            CGRect link_rect;
+            cairo_rectangle_t rectf;
+
+            _cairo_array_copy_element (&link_attrs.rects, i, &rectf);
+
+            link_rect =
+                CGRectMake (rectf.x,
+                            surface->extents.height - rectf.y - rectf.height,
+                            rectf.width,
+                            rectf.height);
+
+            CGPDFContextSetURLForRect (surface->cgContext, url, link_rect);
+        }
+
+        CFRelease (url);
+    }
+
+    _cairo_array_fini (&link_attrs.rects);
+    free (link_attrs.dest);
+    free (link_attrs.uri);
+    free (link_attrs.file);
+
+    return status;
+}
+
 // XXXtodo implement show_page; need to figure out how to handle begin/end
 
 static const struct _cairo_surface_backend cairo_quartz_surface_backend = {
@@ -2346,6 +2411,11 @@ static const struct _cairo_surface_backe
     _cairo_quartz_surface_fill,
     NULL,  /* fill-stroke */
     _cairo_quartz_surface_glyphs,
+
+    NULL,  /* has_show_text_glyphs */
+    NULL,  /* show_text_glyphs */
+    NULL,  /* get_supported_mime_types */
+    _cairo_quartz_surface_tag   /* tag */
 };
 
 cairo_quartz_surface_t *