[cairo-commit] 17 commits - doc/public src/cairo-meta-surface.c src/cairo-svg.h src/cairo-svg-surface.c test/cairo-test.c test/caps-joins-alpha-svg-argb32-ref.png test/caps-joins-alpha-svg-rgb24-ref.png test/.gitignore test/linear-gradient-svg-argb32-ref.png test/linear-gradient-svg-rgb24-ref.png test/mask-ctm-svg-argb32-ref.png test/mask-ctm-svg-rgb24-ref.png test/mask-surface-ctm-svg-argb32-ref.png test/mask-surface-ctm-svg-rgb24-ref.png test/mask-svg-argb32-ref.png test/mask-svg-rgb24-ref.png test/set-source-svg-argb32-ref.png test/set-source-svg-rgb24-ref.png test/show-text-current-point-svg-rgb24-ref.png test/text-antialias-gray-svg-rgb24-ref.png test/text-antialias-none-svg-rgb24-ref.png test/text-antialias-subpixel-svg-rgb24-ref.png test/text-pattern-svg-rgb24-ref.png test/trap-clip-svg-argb32-ref.png test/trap-clip-svg-rgb24-ref.png

Emmanuel Pacaud emmanuel at kemper.freedesktop.org
Mon May 1 14:27:35 PDT 2006


 doc/public/cairo-sections.txt                  |    4 
 doc/public/tmpl/cairo-svg.sgml                 |   46 ++
 src/cairo-meta-surface.c                       |    1 
 src/cairo-svg-surface.c                        |  496 +++++++++++++++++++------
 src/cairo-svg.h                                |   18 
 test/.gitignore                                |    2 
 test/cairo-test.c                              |   10 
 test/caps-joins-alpha-svg-argb32-ref.png       |binary
 test/caps-joins-alpha-svg-rgb24-ref.png        |binary
 test/linear-gradient-svg-argb32-ref.png        |binary
 test/linear-gradient-svg-rgb24-ref.png         |binary
 test/mask-ctm-svg-argb32-ref.png               |binary
 test/mask-ctm-svg-rgb24-ref.png                |binary
 test/mask-surface-ctm-svg-argb32-ref.png       |binary
 test/mask-surface-ctm-svg-rgb24-ref.png        |binary
 test/mask-svg-argb32-ref.png                   |binary
 test/mask-svg-rgb24-ref.png                    |binary
 test/set-source-svg-argb32-ref.png             |binary
 test/set-source-svg-rgb24-ref.png              |binary
 test/show-text-current-point-svg-rgb24-ref.png |binary
 test/text-antialias-gray-svg-rgb24-ref.png     |binary
 test/text-antialias-none-svg-rgb24-ref.png     |binary
 test/text-antialias-subpixel-svg-rgb24-ref.png |binary
 test/text-pattern-svg-rgb24-ref.png            |binary
 test/trap-clip-svg-argb32-ref.png              |binary
 test/trap-clip-svg-rgb24-ref.png               |binary
 26 files changed, 464 insertions(+), 113 deletions(-)

New commits:
diff-tree 0c927c53880f9ece2903a9b2c7843aaff1c78dec (from e3b3402eb82786c4b1faf0d25b6ed322bf5545aa)
Author: Emmanuel Pacaud <emmanuel.pacaud at free.fr>
Date:   Mon May 1 23:23:02 2006 +0200

    SVG: Add reference images for tests failing on 1 digit error on color.

diff --git a/test/caps-joins-alpha-svg-argb32-ref.png b/test/caps-joins-alpha-svg-argb32-ref.png
new file mode 100644
index 0000000..2468936
Binary files /dev/null and b/test/caps-joins-alpha-svg-argb32-ref.png differ
diff --git a/test/caps-joins-alpha-svg-rgb24-ref.png b/test/caps-joins-alpha-svg-rgb24-ref.png
new file mode 100644
index 0000000..2468936
Binary files /dev/null and b/test/caps-joins-alpha-svg-rgb24-ref.png differ
diff --git a/test/linear-gradient-svg-argb32-ref.png b/test/linear-gradient-svg-argb32-ref.png
new file mode 100644
index 0000000..a3c0f6c
Binary files /dev/null and b/test/linear-gradient-svg-argb32-ref.png differ
diff --git a/test/linear-gradient-svg-rgb24-ref.png b/test/linear-gradient-svg-rgb24-ref.png
new file mode 100644
index 0000000..a3c0f6c
Binary files /dev/null and b/test/linear-gradient-svg-rgb24-ref.png differ
diff --git a/test/mask-ctm-svg-argb32-ref.png b/test/mask-ctm-svg-argb32-ref.png
new file mode 100644
index 0000000..049d5f0
Binary files /dev/null and b/test/mask-ctm-svg-argb32-ref.png differ
diff --git a/test/mask-ctm-svg-rgb24-ref.png b/test/mask-ctm-svg-rgb24-ref.png
new file mode 100644
index 0000000..90628a6
Binary files /dev/null and b/test/mask-ctm-svg-rgb24-ref.png differ
diff --git a/test/mask-surface-ctm-svg-argb32-ref.png b/test/mask-surface-ctm-svg-argb32-ref.png
new file mode 100644
index 0000000..049d5f0
Binary files /dev/null and b/test/mask-surface-ctm-svg-argb32-ref.png differ
diff --git a/test/mask-surface-ctm-svg-rgb24-ref.png b/test/mask-surface-ctm-svg-rgb24-ref.png
new file mode 100644
index 0000000..90628a6
Binary files /dev/null and b/test/mask-surface-ctm-svg-rgb24-ref.png differ
diff --git a/test/mask-svg-argb32-ref.png b/test/mask-svg-argb32-ref.png
new file mode 100644
index 0000000..1c0aea8
Binary files /dev/null and b/test/mask-svg-argb32-ref.png differ
diff --git a/test/mask-svg-rgb24-ref.png b/test/mask-svg-rgb24-ref.png
new file mode 100644
index 0000000..b8b4bdb
Binary files /dev/null and b/test/mask-svg-rgb24-ref.png differ
diff --git a/test/set-source-svg-argb32-ref.png b/test/set-source-svg-argb32-ref.png
new file mode 100644
index 0000000..754f1c4
Binary files /dev/null and b/test/set-source-svg-argb32-ref.png differ
diff --git a/test/set-source-svg-rgb24-ref.png b/test/set-source-svg-rgb24-ref.png
new file mode 100644
index 0000000..802147f
Binary files /dev/null and b/test/set-source-svg-rgb24-ref.png differ
diff --git a/test/trap-clip-svg-argb32-ref.png b/test/trap-clip-svg-argb32-ref.png
new file mode 100644
index 0000000..1748bc2
Binary files /dev/null and b/test/trap-clip-svg-argb32-ref.png differ
diff --git a/test/trap-clip-svg-rgb24-ref.png b/test/trap-clip-svg-rgb24-ref.png
new file mode 100644
index 0000000..1c7512a
Binary files /dev/null and b/test/trap-clip-svg-rgb24-ref.png differ
diff-tree e3b3402eb82786c4b1faf0d25b6ed322bf5545aa (from 8e5ada5201dd8a39026e8973d2590fec5ebf2d00)
Author: Emmanuel Pacaud <emmanuel.pacaud at free.fr>
Date:   Mon May 1 23:21:37 2006 +0200

    SVG: Correct use of paginated surface. Fix emit of alpha filter.

diff --git a/src/cairo-svg-surface.c b/src/cairo-svg-surface.c
index 05d3b0c..27ade28 100644
--- a/src/cairo-svg-surface.c
+++ b/src/cairo-svg-surface.c
@@ -136,11 +136,8 @@ _cairo_svg_surface_create_for_document (
 					double			 width,
 					double			 height);
 
-static void
-_cairo_svg_set_paginated_mode (cairo_surface_t *target,
-			       cairo_paginated_mode_t mode);
-
 static const cairo_surface_backend_t cairo_svg_surface_backend;
+static const cairo_paginated_surface_backend_t cairo_svg_surface_paginated_backend;
 
 static cairo_surface_t *
 _cairo_svg_surface_create_for_stream_internal (cairo_output_stream_t	*stream,
@@ -166,7 +163,7 @@ _cairo_svg_surface_create_for_stream_int
     return _cairo_paginated_surface_create (surface,
 					    CAIRO_CONTENT_COLOR_ALPHA,
 					    width, height,
-					    _cairo_svg_set_paginated_mode);
+					    &cairo_svg_surface_paginated_backend);
 }
 
 static cairo_surface_t *
@@ -450,10 +447,9 @@ _cairo_svg_surface_create_for_document (
 	xmlSetProp (rect, CC2XML ("style"), CC2XML ("opacity:1; stroke:none; fill:rgb(0,0,0);"));
     }
 
+    surface->paginated_mode = CAIRO_PAGINATED_MODE_ANALYZE;
     surface->content = content;
 
-    surface->paginated_mode = CAIRO_PAGINATED_MODE_ANALYZE;
-    
     return &surface->base;
 }
 
@@ -1383,13 +1379,13 @@ _cairo_svg_surface_mask (void		    *abst
     xmlNodePtr child, mask_node;
     char buffer[CAIRO_SVG_DTOSTR_BUFFER_LEN];
 
-    emit_alpha_filter (document);
-
     if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
 	return _analyze_operation (surface, op, source);
 
     assert (_operation_supported (surface, op, source));
     
+    emit_alpha_filter (document);
+
     mask_node = xmlNewNode (NULL, CC2XML ("mask"));
     snprintf (buffer, sizeof buffer, "mask%d", document->mask_id);
     xmlSetProp (mask_node, CC2XML ("id"), C2XML (buffer));
@@ -1785,10 +1781,15 @@ _cairo_svg_document_finish (cairo_svg_do
 }
 
 static void
-_cairo_svg_set_paginated_mode (cairo_surface_t *target,
-			       cairo_paginated_mode_t paginated_mode)
+_cairo_svg_surface_set_paginated_mode (void 		      	*abstract_surface,
+				       cairo_paginated_mode_t 	 paginated_mode)
 {
-    cairo_svg_surface_t *surface = (cairo_svg_surface_t *) target;
+    cairo_svg_surface_t *surface = abstract_surface;
 
     surface->paginated_mode = paginated_mode;
 }
+
+static const cairo_paginated_surface_backend_t cairo_svg_surface_paginated_backend = {
+    NULL /*_cairo_svg_surface_start_page*/,
+    _cairo_svg_surface_set_paginated_mode
+};
diff-tree 8e5ada5201dd8a39026e8973d2590fec5ebf2d00 (from 62831dc10ec7601869a01041c845d5dc2f15db49)
Author: Emmanuel Pacaud <emmanuel.pacaud at free.fr>
Date:   Mon May 1 22:53:46 2006 +0200

    SVG: Trivial indentation and comment fixes.

diff --git a/src/cairo-svg-surface.c b/src/cairo-svg-surface.c
index 51660ce..05d3b0c 100644
--- a/src/cairo-svg-surface.c
+++ b/src/cairo-svg-surface.c
@@ -852,8 +852,10 @@ emit_operator (xmlNodePtr node, cairo_op
 }
 
 static void
-emit_color (cairo_color_t const *color, xmlBufferPtr style,
-	    char const *color_str, char const *opacity_str)
+emit_color (cairo_color_t const *color, 
+	    xmlBufferPtr	 style,
+	    char const		*color_str, 
+	    char const		*opacity_str)
 {
     char buffer[CAIRO_SVG_DTOSTR_BUFFER_LEN];
 
@@ -876,9 +878,10 @@ emit_color (cairo_color_t const *color, 
 }
 
 static void
-emit_solid_pattern (cairo_svg_surface_t *surface,
-		    cairo_solid_pattern_t *pattern,
-		    xmlBufferPtr style, int is_stroke)
+emit_solid_pattern (cairo_svg_surface_t	    *surface,
+		    cairo_solid_pattern_t   *pattern,
+		    xmlBufferPtr	     style, 
+		    int			     is_stroke)
 {
     emit_color (&pattern->color, 
 		style, is_stroke ? "stroke" : "fill", 
@@ -886,9 +889,10 @@ emit_solid_pattern (cairo_svg_surface_t 
 }
 
 static void
-emit_surface_pattern (cairo_svg_surface_t *surface,
-		      cairo_surface_pattern_t *pattern,
-		      xmlBufferPtr style, int is_stroke)
+emit_surface_pattern (cairo_svg_surface_t	*surface,
+		      cairo_surface_pattern_t	*pattern,
+		      xmlBufferPtr		 style, 
+		      int			 is_stroke)
 {
     cairo_svg_document_t *document = surface->document;
     xmlNodePtr child;
@@ -980,9 +984,10 @@ emit_pattern_extend (xmlNodePtr node, ca
 }
 
 static void
-emit_linear_pattern (cairo_svg_surface_t *surface, 
+emit_linear_pattern (cairo_svg_surface_t    *surface, 
 		     cairo_linear_pattern_t *pattern,
-		     xmlBufferPtr style, int is_stroke)
+		     xmlBufferPtr	     style, 
+		     int		     is_stroke)
 {
     cairo_svg_document_t *document = surface->document;
     xmlNodePtr child;
@@ -1143,7 +1148,7 @@ _cairo_svg_path_move_to (void *closure, 
     return CAIRO_STATUS_SUCCESS;
 }
 
-    static cairo_status_t
+static cairo_status_t
 _cairo_svg_path_line_to (void *closure, cairo_point_t *point)
 {
     svg_path_info_t *info = closure;
@@ -1274,7 +1279,7 @@ _cairo_svg_surface_get_extents (void		  
 }
 
 static xmlNodePtr
-emit_paint (xmlNodePtr node,
+emit_paint (xmlNodePtr		 node,
 	    cairo_svg_surface_t	*surface,
 	    cairo_operator_t	 op,
 	    cairo_pattern_t	*source)
@@ -1532,7 +1537,7 @@ _cairo_svg_surface_show_glyphs (void			*
 
     assert (_operation_supported (surface, op, pattern));
 
-    /* FIXME: We don't really want to keep this as is. There's to possibilities:
+    /* FIXME: We don't really want to keep this as is. There's two possibilities:
      *   - Use SVG fonts. But support for them seems very rare in SVG renderers.
      *   - Or store glyph outlines in <symbol> or <g> elements.
      * 
diff-tree 62831dc10ec7601869a01041c845d5dc2f15db49 (from 22c799d5b3cae2a98ab927b2b38911ac89cac61e)
Author: Emmanuel Pacaud <emmanuel.pacaud at free.fr>
Date:   Mon May 1 22:53:12 2006 +0200

    SVG: Remove outdated comment.

diff --git a/src/cairo-svg-surface.c b/src/cairo-svg-surface.c
index 932b86e..51660ce 100644
--- a/src/cairo-svg-surface.c
+++ b/src/cairo-svg-surface.c
@@ -832,10 +832,6 @@ emit_composite_pattern (xmlNodePtr node,
     return emit_composite_image_pattern (node, pattern, width, height, is_pattern);
 }
 
-/* FIXME: Here we use a SVG 1.2 feature. We should probably have
- * an API to limit output SVG version, and fallback to image when
- * necessary. */
-
 static void
 emit_operator (xmlNodePtr node, cairo_operator_t op)
 {
diff-tree 22c799d5b3cae2a98ab927b2b38911ac89cac61e (from 6f49f7b76d69c185d6f97e50d8a57914a9a9fca1)
Author: Emmanuel Pacaud <emmanuel.pacaud at free.fr>
Date:   Mon May 1 22:52:47 2006 +0200

    SVG: Fix error handling in create_for_document and in composite_image_pattern.

diff --git a/src/cairo-svg-surface.c b/src/cairo-svg-surface.c
index aa437e5..932b86e 100644
--- a/src/cairo-svg-surface.c
+++ b/src/cairo-svg-surface.c
@@ -127,7 +127,7 @@ _cairo_svg_document_destroy (cairo_svg_d
 static cairo_status_t
 _cairo_svg_document_finish (cairo_svg_document_t *document);
 
-static void
+static cairo_svg_document_t *
 _cairo_svg_document_reference (cairo_svg_document_t *document);
 
 static cairo_surface_t *
@@ -407,16 +407,17 @@ _cairo_svg_surface_create_for_document (
     char buffer[CAIRO_SVG_DTOSTR_BUFFER_LEN];
 
     surface = malloc (sizeof (cairo_svg_surface_t));
-    if (surface == NULL)
-	return NULL;
+    if (surface == NULL) {
+	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	return (cairo_surface_t*) &_cairo_surface_nil;
+    }
 
     _cairo_surface_init (&surface->base, &cairo_svg_surface_backend);
 
     surface->width = width;
     surface->height = height;
 
-    _cairo_svg_document_reference (document);
-    surface->document = document;
+    surface->document = _cairo_svg_document_reference (document);
 
     surface->clip_level = 0;
 
@@ -681,7 +682,7 @@ emit_composite_image_pattern (xmlNodePtr
     cairo_image_surface_t *image;
     cairo_status_t status;
     cairo_matrix_t p2u;
-    xmlNodePtr child;
+    xmlNodePtr child = NULL;
     xmlBufferPtr image_buffer;
     char buffer[CAIRO_SVG_DTOSTR_BUFFER_LEN];
     void *image_extra;
@@ -692,7 +693,7 @@ emit_composite_image_pattern (xmlNodePtr
 
     status = _cairo_surface_base64_encode (surface, &image_buffer);
     if (status)
-	return NULL;
+	goto BAIL;
 
     child = xmlNewChild (node, NULL, CC2XML ("image"), NULL);
     _cairo_dtostr (buffer, sizeof buffer, image->width);
@@ -714,6 +715,7 @@ emit_composite_image_pattern (xmlNodePtr
     if (height != NULL)
 	    *height = image->height;
 
+BAIL:
     _cairo_surface_release_source_image (pattern->surface, image, image_extra);
 
     return child;
@@ -1710,10 +1712,12 @@ _cairo_svg_document_create (cairo_output
     return document;
 }
 
-static void
+static cairo_svg_document_t *
 _cairo_svg_document_reference (cairo_svg_document_t *document)
 {
     document->refcount++;
+
+    return document;
 }
 
 static void
diff-tree 6f49f7b76d69c185d6f97e50d8a57914a9a9fca1 (from 2e4d0e5ba71fc320e2b96526a28b654231cb9dbe)
Author: Emmanuel Pacaud <emmanuel.pacaud at free.fr>
Date:   Mon May 1 22:51:25 2006 +0200

    SVG: Add an additionnal API for creating SVG 1.1 or 1.2 files.
    
    And update documentation.

diff --git a/doc/public/cairo-sections.txt b/doc/public/cairo-sections.txt
index 59f5098..de1feb3 100644
--- a/doc/public/cairo-sections.txt
+++ b/doc/public/cairo-sections.txt
@@ -112,7 +112,11 @@ cairo_xlib_surface_create_with_xrender_f
 <FILE>cairo-svg</FILE>
 <TITLE>SVG Surfaces</TITLE>
 cairo_svg_surface_create
+cairo_svg_surface_create_1_1
+cairo_svg_surface_create_1_2
 cairo_svg_surface_create_for_stream
+cairo_svg_surface_create_for_stream_1_1
+cairo_svg_surface_create_for_stream_1_2
 cairo_svg_surface_set_dpi
 </SECTION>
 
diff --git a/doc/public/tmpl/cairo-svg.sgml b/doc/public/tmpl/cairo-svg.sgml
index 31bf692..fdf167a 100644
--- a/doc/public/tmpl/cairo-svg.sgml
+++ b/doc/public/tmpl/cairo-svg.sgml
@@ -28,6 +28,28 @@ Rendering SVG documents
 @Returns: 
 
 
+<!-- ##### FUNCTION cairo_svg_surface_create_1_1 ##### -->
+<para>
+
+</para>
+
+ at filename: 
+ at width_in_points: 
+ at height_in_points: 
+ at Returns: 
+
+
+<!-- ##### FUNCTION cairo_svg_surface_create_1_2 ##### -->
+<para>
+
+</para>
+
+ at filename: 
+ at width_in_points: 
+ at height_in_points: 
+ at Returns: 
+
+
 <!-- ##### FUNCTION cairo_svg_surface_create_for_stream ##### -->
 <para>
 
@@ -40,6 +62,30 @@ Rendering SVG documents
 @Returns: 
 
 
+<!-- ##### FUNCTION cairo_svg_surface_create_for_stream_1_1 ##### -->
+<para>
+
+</para>
+
+ at write_func: 
+ at closure: 
+ at width_in_points: 
+ at height_in_points: 
+ at Returns: 
+
+
+<!-- ##### FUNCTION cairo_svg_surface_create_for_stream_1_2 ##### -->
+<para>
+
+</para>
+
+ at write_func: 
+ at closure: 
+ at width_in_points: 
+ at height_in_points: 
+ at Returns: 
+
+
 <!-- ##### FUNCTION cairo_svg_surface_set_dpi ##### -->
 <para>
 
diff --git a/src/cairo-svg-surface.c b/src/cairo-svg-surface.c
index de30b0f..aa437e5 100644
--- a/src/cairo-svg-surface.c
+++ b/src/cairo-svg-surface.c
@@ -116,9 +116,10 @@ typedef struct {
 } cairo_meta_snapshot_t;
 
 static cairo_svg_document_t *
-_cairo_svg_document_create (cairo_output_stream_t	*stream,
-			    double			width,
-			    double			height);
+_cairo_svg_document_create (cairo_output_stream_t   *stream,
+			    double		     width,
+			    double		     height,
+			    cairo_svg_version_t	     version);
 
 static void
 _cairo_svg_document_destroy (cairo_svg_document_t *document);
@@ -143,13 +144,14 @@ static const cairo_surface_backend_t cai
 
 static cairo_surface_t *
 _cairo_svg_surface_create_for_stream_internal (cairo_output_stream_t	*stream,
-					       double			width,
-					       double			height)
+					       double			 width,
+					       double			 height,
+					       cairo_svg_version_t	 version)
 {
     cairo_svg_document_t *document;
     cairo_surface_t *surface;
 
-    document = _cairo_svg_document_create (stream, width, height);
+    document = _cairo_svg_document_create (stream, width, height, version);
     if (document == NULL) {
 	_cairo_error (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_surface_t *) &_cairo_surface_nil;
@@ -167,6 +169,26 @@ _cairo_svg_surface_create_for_stream_int
 					    _cairo_svg_set_paginated_mode);
 }
 
+static cairo_surface_t *
+_cairo_svg_surface_create_for_stream (cairo_write_func_t     write,
+				      void		    *closure,
+				      double		     width,
+				      double		     height, 
+				      cairo_svg_version_t    version)
+{
+    cairo_status_t status;
+    cairo_output_stream_t *stream;
+
+    stream = _cairo_output_stream_create (write, NULL, closure);
+    status = _cairo_output_stream_get_status (stream);
+    if (status) {
+	_cairo_error (status);
+	return (cairo_surface_t *) &_cairo_surface_nil;
+    }
+
+    return _cairo_svg_surface_create_for_stream_internal (stream, width, height, version);
+}
+
 /**
  * cairo_svg_surface_create_for_stream:
  * @write: a #cairo_write_func_t to accept the output data
@@ -186,22 +208,80 @@ _cairo_svg_surface_create_for_stream_int
  * occurs. You can use cairo_surface_status() to check for this.
  */
 cairo_surface_t *
-cairo_svg_surface_create_for_stream (cairo_write_func_t		write,
+cairo_svg_surface_create_for_stream (cairo_write_func_t		 write,
 				     void			*closure,
-				     double			width,
-				     double			height)
+				     double			 width,
+				     double			 height)
+{
+    return _cairo_svg_surface_create_for_stream (write, closure, width, height, 
+						 CAIRO_SVG_VERSION_1_1);
+}
+
+/**
+ * cairo_svg_surface_create_for_stream_1_1:
+ * @write: a #cairo_write_func_t to accept the output data
+ * @closure: the closure argument for @write
+ * @width_in_points: width of the surface
+ * @height_in_points: height of the surface
+ * 
+ * Creates a SVG 1.1 surface of the specified size in points to be written
+ * incrementally to the stream represented by @write and @closure
+ * (see @cairo_svg_surface_create_for_stream and @cairo_svg_surface_create_1_1).
+ *
+ * Return value: a pointer to the newly created surface. 
+ */
+
+cairo_surface_t *
+cairo_svg_surface_create_for_stream_1_1 (cairo_write_func_t  write,
+					 void		    *closure,
+					 double		     width,
+					 double		     height)
+{
+    return _cairo_svg_surface_create_for_stream (write, closure, width, height, 
+						 CAIRO_SVG_VERSION_1_1);
+}
+
+/**
+ * cairo_svg_surface_create_for_stream_1_2:
+ * @write: a #cairo_write_func_t to accept the output data
+ * @closure: the closure argument for @write
+ * @width_in_points: width of the surface
+ * @height_in_points: height of the surface
+ * 
+ * Creates a SVG 1.2 surface of the specified size in points to be written
+ * incrementally to the stream represented by @write and @closure
+ * (see @cairo_svg_surface_create_for_stream and @cairo_svg_surface_create_1_2).
+ *
+ * Return value: a pointer to the newly created surface. 
+ */
+
+cairo_surface_t *
+cairo_svg_surface_create_for_stream_1_2 (cairo_write_func_t  write,
+					 void		    *closure,
+					 double		     width,
+					 double		     height)
+{
+    return _cairo_svg_surface_create_for_stream (write, closure, width, height, 
+						 CAIRO_SVG_VERSION_1_2);
+}
+
+static cairo_surface_t *
+_cairo_svg_surface_create (const char		*filename,
+			   double		 width,
+			   double		 height,
+			   cairo_svg_version_t   version)
 {
     cairo_status_t status;
     cairo_output_stream_t *stream;
 
-    stream = _cairo_output_stream_create (write, NULL, closure);
+    stream = _cairo_output_stream_create_for_filename (filename);
     status = _cairo_output_stream_get_status (stream);
     if (status) {
 	_cairo_error (status);
 	return (cairo_surface_t *) &_cairo_surface_nil;
     }
 
-    return _cairo_svg_surface_create_for_stream_internal (stream, width, height);
+    return _cairo_svg_surface_create_for_stream_internal (stream, width, height, version);
 }
 
 /**
@@ -221,22 +301,53 @@ cairo_svg_surface_create_for_stream (cai
  * pointer to a "nil" surface if an error such as out of memory
  * occurs. You can use cairo_surface_status() to check for this.
  **/
+
 cairo_surface_t *
 cairo_svg_surface_create (const char	*filename,
-			  double	width,
-			  double	height)
+			  double	 width,
+			  double	 height)
 {
-    cairo_status_t status;
-    cairo_output_stream_t *stream;
+    return _cairo_svg_surface_create (filename, width, height, CAIRO_SVG_VERSION_1_1);
+}
 
-    stream = _cairo_output_stream_create_for_filename (filename);
-    status = _cairo_output_stream_get_status (stream);
-    if (status) {
-	_cairo_error (status);
-	return (cairo_surface_t *) &_cairo_surface_nil;
-    }
+/**
+ * cairo_svg_surface_create_1_1:
+ * @filename: a filename for the SVG output.
+ * @width_in_points: width of the surface, in points. 
+ * @height_in_points: height of the surface, in points.
+ * 
+ * Creates a SVG 1.1 surface (see @cairo_svg_surface_create). 
+ * Compositing operations not supported by SVG 1.1 are emulated via
+ * image fallbacks, except for unclipped CLEAR and SOURCE operators.
+ * 
+ * Return value: a pointer to the newly created surface.
+ **/
+
+cairo_surface_t *
+cairo_svg_surface_create_1_1 (const char    *filename,
+			      double	     width,
+			      double	     height)
+{
+    return _cairo_svg_surface_create (filename, width, height, CAIRO_SVG_VERSION_1_1);
+}
+
+/**
+ * cairo_svg_surface_create_1_2:
+ * @filename: a filename for the SVG output.
+ * @width_in_points: width of the surface, in points. 
+ * @height_in_points: height of the surface, in points.
+ * 
+ * Creates a SVG 1.2 surface (see @cairo_svg_surface_create). 
+ * 
+ * Return value: a pointer to the newly created surface.
+ **/
 
-    return _cairo_svg_surface_create_for_stream_internal (stream, width, height);
+cairo_surface_t *
+cairo_svg_surface_create_1_2 (const char    *filename,
+			      double	     width,
+			      double	     height)
+{
+    return _cairo_svg_surface_create (filename, width, height, CAIRO_SVG_VERSION_1_2);
 }
 
 static cairo_bool_t
@@ -254,7 +365,7 @@ _cairo_surface_is_svg (cairo_surface_t *
  * Set the horizontal and vertical resolution for image fallbacks.
  * When the svg backend needs to fall back to image overlays, it will
  * use this resolution. These DPI values are not used for any other
- * purpose, (in particular, they do not have any bearing on the size
+ * purpose (in particular, they do not have any bearing on the size
  * passed to cairo_pdf_surface_create() nor on the CTM).
  **/
 
@@ -1543,8 +1654,9 @@ static const cairo_surface_backend_t cai
 
 static cairo_svg_document_t *
 _cairo_svg_document_create (cairo_output_stream_t	*output_stream,
-			    double			width,
-			    double			height)
+			    double			 width,
+			    double			 height,
+			    cairo_svg_version_t		 version)
 {
     cairo_svg_document_t *document;
     xmlDocPtr doc;
@@ -1593,7 +1705,7 @@ _cairo_svg_document_create (cairo_output
 
     _cairo_array_init (&document->meta_snapshots, sizeof (cairo_meta_snapshot_t));
 
-    document->svg_version = CAIRO_SVG_VERSION_1_1;
+    document->svg_version = version;
     
     return document;
 }
diff --git a/src/cairo-svg.h b/src/cairo-svg.h
index 51ccb98..d428fe3 100644
--- a/src/cairo-svg.h
+++ b/src/cairo-svg.h
@@ -42,12 +42,30 @@ cairo_surface_t *
 cairo_svg_surface_create (const char   *filename,
 			  double	width_in_points,
 			  double	height_in_points);
+cairo_surface_t *
+cairo_svg_surface_create_1_1 (const char   *filename,
+			      double	    width_in_points,
+			      double	    height_in_points);
+cairo_surface_t *
+cairo_svg_surface_create_1_2 (const char   *filename,
+			     double	    width_in_points,
+			     double	    height_in_points);
 
 cairo_surface_t *
 cairo_svg_surface_create_for_stream (cairo_write_func_t	write_func,
 				     void	       *closure,
 				     double		width_in_points,
 				     double		height_in_points);
+cairo_surface_t *
+cairo_svg_surface_create_for_stream_1_1 (cairo_write_func_t  write_func,
+					 void		    *closure,
+					 double		     width_in_points,
+					 double		     height_in_points);
+cairo_surface_t *
+cairo_svg_surface_create_for_stream_1_2 (cairo_write_func_t  write_func,
+					 void		    *closure,
+					 double		     width_in_points,
+					 double		     height_in_points);
 
 void
 cairo_svg_surface_set_dpi (cairo_surface_t     *surface,
diff-tree 2e4d0e5ba71fc320e2b96526a28b654231cb9dbe (from e5ea8268b0c693b7b0940d2f638c94dff93e8d9b)
Author: Emmanuel Pacaud <emmanuel.pacaud at free.fr>
Date:   Mon May 1 22:50:42 2006 +0200

    SVG: Some variable/type renaming.

diff --git a/src/cairo-svg-surface.c b/src/cairo-svg-surface.c
index 06c1228..de30b0f 100644
--- a/src/cairo-svg-surface.c
+++ b/src/cairo-svg-surface.c
@@ -85,7 +85,7 @@ struct cairo_svg_document {
 
     cairo_bool_t alpha_filter;
 
-    cairo_array_t pattern_snapshots;
+    cairo_array_t meta_snapshots;
 
     cairo_svg_version_t svg_version;
 };
@@ -110,6 +110,11 @@ struct cairo_svg_surface {
     cairo_paginated_mode_t paginated_mode;
 };
 
+typedef struct {
+    unsigned int id;
+    cairo_meta_surface_t *meta;
+} cairo_meta_snapshot_t;
+
 static cairo_svg_document_t *
 _cairo_svg_document_create (cairo_output_stream_t	*stream,
 			    double			width,
@@ -603,27 +608,22 @@ emit_composite_image_pattern (xmlNodePtr
     return child;
 }
 
-typedef struct {
-    unsigned int id;
-    cairo_meta_surface_t *meta;
-} pattern_snapshot_t;
-
 static int
-_emit_meta_surface_with_snapshot (cairo_svg_document_t *document,
-				  cairo_meta_surface_t *surface)
+emit_meta_surface (cairo_svg_document_t *document,
+		   cairo_meta_surface_t *surface)
 {
     cairo_meta_surface_t *meta;
-    pattern_snapshot_t *pattern_snapshot;
+    cairo_meta_snapshot_t *snapshot;
     int num_elements;
     unsigned int i, id;
 
-    num_elements = document->pattern_snapshots.num_elements;
+    num_elements = document->meta_snapshots.num_elements;
     for (i = 0; i < num_elements; i++) {
-	pattern_snapshot = _cairo_array_index (&document->pattern_snapshots, i);
-	meta = pattern_snapshot->meta;
+	snapshot = _cairo_array_index (&document->meta_snapshots, i);
+	meta = snapshot->meta;
 	if (meta->commands.num_elements == surface->commands.num_elements &&
 	    _cairo_array_index (&meta->commands, 0) == _cairo_array_index (&surface->commands, 0)) {
-	    id = pattern_snapshot->id;
+	    id = snapshot->id;
 	    break;
 	}
     }
@@ -631,7 +631,7 @@ _emit_meta_surface_with_snapshot (cairo_
     if (i >= num_elements) {
 	cairo_surface_t *paginated_surface;
 	cairo_surface_t *svg_surface;
-	pattern_snapshot_t snapshot;
+	cairo_meta_snapshot_t new_snapshot;
 	xmlNodePtr child;
 
 	meta = (cairo_meta_surface_t *) _cairo_surface_snapshot ((cairo_surface_t *)surface);
@@ -647,9 +647,9 @@ _emit_meta_surface_with_snapshot (cairo_
 	_cairo_meta_surface_replay ((cairo_surface_t *)meta, paginated_surface);
 	_cairo_surface_show_page (paginated_surface);
 	
-	snapshot.meta = meta;
-	snapshot.id = ((cairo_svg_surface_t *) svg_surface)->id;
-	_cairo_array_append (&document->pattern_snapshots, &snapshot);
+	new_snapshot.meta = meta;
+	new_snapshot.id = ((cairo_svg_surface_t *) svg_surface)->id;
+	_cairo_array_append (&document->meta_snapshots, &new_snapshot);
 	
 	if (meta->content == CAIRO_CONTENT_ALPHA) 
 	    emit_alpha_filter (document);
@@ -658,7 +658,7 @@ _emit_meta_surface_with_snapshot (cairo_
 	if (meta->content == CAIRO_CONTENT_ALPHA) 
 	    xmlSetProp (child, CC2XML ("filter"), CC2XML("url(#alpha)"));
 
-	id = snapshot.id;
+	id = new_snapshot.id;
 
 	cairo_surface_destroy (paginated_surface);
     }
@@ -683,7 +683,7 @@ emit_composite_meta_pattern (xmlNodePtr 
 
     meta_surface = (cairo_meta_surface_t *) pattern->surface;
     
-    id = _emit_meta_surface_with_snapshot (document, meta_surface);
+    id = emit_meta_surface (document, meta_surface);
     
     child = xmlNewChild (node, NULL, CC2XML("use"), NULL);
     snprintf (buffer, sizeof buffer, "#surface%d", id);
@@ -1591,7 +1591,7 @@ _cairo_svg_document_create (cairo_output
 
     document->alpha_filter = FALSE;
 
-    _cairo_array_init (&document->pattern_snapshots, sizeof (pattern_snapshot_t));
+    _cairo_array_init (&document->meta_snapshots, sizeof (cairo_meta_snapshot_t));
 
     document->svg_version = CAIRO_SVG_VERSION_1_1;
     
@@ -1638,7 +1638,7 @@ _cairo_svg_document_finish (cairo_svg_do
 {
     cairo_status_t status;
     cairo_output_stream_t *output = document->output_stream;
-    pattern_snapshot_t *pattern_snapshot;
+    cairo_meta_snapshot_t *snapshot;
     xmlOutputBufferPtr xml_output_buffer;
     unsigned int i;
 
@@ -1656,11 +1656,11 @@ _cairo_svg_document_finish (cairo_svg_do
     status = _cairo_output_stream_get_status (output);
     _cairo_output_stream_destroy (output);
 
-    for (i = 0; i < document->pattern_snapshots.num_elements; i++) {
-	pattern_snapshot = _cairo_array_index (&document->pattern_snapshots, i);
-	cairo_surface_destroy ((cairo_surface_t *) pattern_snapshot->meta);
+    for (i = 0; i < document->meta_snapshots.num_elements; i++) {
+	snapshot = _cairo_array_index (&document->meta_snapshots, i);
+	cairo_surface_destroy ((cairo_surface_t *) snapshot->meta);
     }
-    _cairo_array_fini (&document->pattern_snapshots);
+    _cairo_array_fini (&document->meta_snapshots);
 
     document->finished = TRUE;
 
diff-tree e5ea8268b0c693b7b0940d2f638c94dff93e8d9b (from 55685d7173adc2e13c21f8830aa38ffc7d1e026f)
Author: Emmanuel Pacaud <emmanuel.pacaud at free.fr>
Date:   Mon May 1 22:49:58 2006 +0200

    SVG: Reenable optimisation of CLEAR and SOURCE in paint when there's
    no active clipping path.

diff --git a/src/cairo-svg-surface.c b/src/cairo-svg-surface.c
index 2240f24..06c1228 100644
--- a/src/cairo-svg-surface.c
+++ b/src/cairo-svg-surface.c
@@ -1207,7 +1207,10 @@ _cairo_svg_surface_paint (void		    *abs
 {
     cairo_svg_surface_t *surface = abstract_surface;
     
-    if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
+    if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE && 
+	!(surface->clip_level == 0 && 
+	  (op == CAIRO_OPERATOR_CLEAR ||
+	   op == CAIRO_OPERATOR_SOURCE)))
 	return _analyze_operation (surface, op, source);
 
     /* XXX: It would be nice to be able to assert this condition
@@ -1220,7 +1223,6 @@ _cairo_svg_surface_paint (void		    *abs
     assert (_operation_supported (surface, op, source));
     */
 
-#if 0
     /* Emulation of clear and source operators, when no clipping region
      * is defined. We just delete existing content of surface root node,
      * and exit early if operator is clear. */ 
@@ -1250,7 +1252,6 @@ _cairo_svg_surface_paint (void		    *abs
 	    return CAIRO_STATUS_SUCCESS;
 	}
     }
-#endif
 
     emit_paint (surface->xml_node, surface, op, source);
     
diff-tree 55685d7173adc2e13c21f8830aa38ffc7d1e026f (from 926bb6480c0542a0928e8b109009be4b24c81344)
Author: Emmanuel Pacaud <emmanuel.pacaud at free.fr>
Date:   Mon May 1 22:49:29 2006 +0200

    SVG: Code cleanup.

diff --git a/src/cairo-svg-surface.c b/src/cairo-svg-surface.c
index 7d2ac7a..2240f24 100644
--- a/src/cairo-svg-surface.c
+++ b/src/cairo-svg-surface.c
@@ -107,8 +107,6 @@ struct cairo_svg_surface {
 
     unsigned int clip_level;
 
-    unsigned int previous_id;
-
     cairo_paginated_mode_t paginated_mode;
 };
 
@@ -335,7 +333,6 @@ _cairo_svg_surface_create_for_document (
 	xmlSetProp (rect, CC2XML ("style"), CC2XML ("opacity:1; stroke:none; fill:rgb(0,0,0);"));
     }
 
-    surface->previous_id = surface->id;
     surface->content = content;
 
     surface->paginated_mode = CAIRO_PAGINATED_MODE_ANALYZE;
@@ -384,7 +381,6 @@ _cairo_svg_surface_finish (void *abstrac
     cairo_svg_surface_t *surface = abstract_surface;
     cairo_svg_document_t *document = surface->document;
     
-
     if (document->owner == &surface->base) {
 	xmlAddChild (document->xml_node_main, xmlCopyNode (surface->xml_root_node, 1));
 	status = _cairo_svg_document_finish (document);
@@ -395,6 +391,7 @@ _cairo_svg_surface_finish (void *abstrac
 
     xmlFreeNode (surface->xml_root_node);
     surface->xml_node = NULL;
+    surface->xml_root_node = NULL;
 
     return status;
 }
diff-tree 926bb6480c0542a0928e8b109009be4b24c81344 (from 061d5088985a5e0b16202a4f031938772749940a)
Author: Emmanuel Pacaud <emmanuel.pacaud at free.fr>
Date:   Mon May 1 22:47:41 2006 +0200

    SVG: Initial support of operators support via image fallbacks.
    
    We need to add a public API that will let user select
    a compatibility level regarding produced SVG files.
    
    This patch also plugs a memleak.

diff --git a/src/cairo-svg-surface.c b/src/cairo-svg-surface.c
index 35ed860..7d2ac7a 100644
--- a/src/cairo-svg-surface.c
+++ b/src/cairo-svg-surface.c
@@ -52,6 +52,11 @@
 
 #define CAIRO_SVG_DEFAULT_DPI 300
 
+typedef enum {
+    CAIRO_SVG_VERSION_1_1,
+    CAIRO_SVG_VERSION_1_2
+} cairo_svg_version_t;
+
 typedef struct cairo_svg_document cairo_svg_document_t;
 typedef struct cairo_svg_surface cairo_svg_surface_t;
 
@@ -81,6 +86,8 @@ struct cairo_svg_document {
     cairo_bool_t alpha_filter;
 
     cairo_array_t pattern_snapshots;
+
+    cairo_svg_version_t svg_version;
 };
 
 struct cairo_svg_surface {
@@ -100,7 +107,6 @@ struct cairo_svg_surface {
 
     unsigned int clip_level;
 
-    cairo_bool_t modified;
     unsigned int previous_id;
 
     cairo_paginated_mode_t paginated_mode;
@@ -329,7 +335,6 @@ _cairo_svg_surface_create_for_document (
 	xmlSetProp (rect, CC2XML ("style"), CC2XML ("opacity:1; stroke:none; fill:rgb(0,0,0);"));
     }
 
-    surface->modified = TRUE;
     surface->previous_id = surface->id;
     surface->content = content;
 
@@ -338,6 +343,31 @@ _cairo_svg_surface_create_for_document (
     return &surface->base;
 }
 
+static cairo_int_status_t
+_operation_supported (cairo_svg_surface_t *surface,
+		      cairo_operator_t op,
+		      const cairo_pattern_t *pattern)
+{
+    cairo_svg_document_t *document = surface->document;
+    
+    if (document->svg_version < CAIRO_SVG_VERSION_1_2)
+	if (op != CAIRO_OPERATOR_OVER)
+	    return FALSE;
+
+    return TRUE;
+}
+
+static cairo_int_status_t
+_analyze_operation (cairo_svg_surface_t *surface,
+		    cairo_operator_t op,
+		    const cairo_pattern_t *pattern)
+{
+    if (_operation_supported (surface, op, pattern))
+	return CAIRO_STATUS_SUCCESS;
+    else
+	return CAIRO_INT_STATUS_UNSUPPORTED;
+}
+
 static cairo_surface_t *
 _cairo_svg_surface_create_similar (void			*abstract_src,
 				   cairo_content_t	 content,
@@ -369,21 +399,6 @@ _cairo_svg_surface_finish (void *abstrac
     return status;
 }
 
-static cairo_bool_t
-operator_supported (cairo_operator_t op)
-{
-    return (op == CAIRO_OPERATOR_SOURCE);
-}
-
-static cairo_int_status_t
-operator_analyze (cairo_operator_t op)
-{
-    if (operator_supported (op))
-	return CAIRO_STATUS_SUCCESS;
-    else
-	return CAIRO_INT_STATUS_UNSUPPORTED;
-}
-
 static void
 emit_alpha_filter (cairo_svg_document_t *document)
 {
@@ -1101,7 +1116,9 @@ _cairo_svg_surface_fill (void			*abstrac
     xmlBufferPtr style;
 
     if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
-	return operator_analyze (op);
+	return _analyze_operation (surface, op, source);
+
+    assert (_operation_supported (surface, op, source));
 
     info.document = document;
     info.path = xmlBufferCreate ();
@@ -1128,7 +1145,6 @@ _cairo_svg_surface_fill (void			*abstrac
     xmlBufferFree (info.path);
     xmlBufferFree (style);
 
-    surface->modified = TRUE;
     return status;
 }
 
@@ -1194,6 +1210,20 @@ _cairo_svg_surface_paint (void		    *abs
 {
     cairo_svg_surface_t *surface = abstract_surface;
     
+    if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
+	return _analyze_operation (surface, op, source);
+
+    /* XXX: It would be nice to be able to assert this condition
+     * here. But, we actually allow one 'cheat' that is used when
+     * painting the final image-based fallbacks. The final fallbacks
+     * do have alpha which we support by blending with white. This is
+     * possible only because there is nothing between the fallback
+     * images and the paper, nor is anything painted above. */
+    /*
+    assert (_operation_supported (surface, op, source));
+    */
+
+#if 0
     /* Emulation of clear and source operators, when no clipping region
      * is defined. We just delete existing content of surface root node,
      * and exit early if operator is clear. */ 
@@ -1220,17 +1250,13 @@ _cairo_svg_surface_paint (void		    *abs
 		xmlSetProp (rect, CC2XML ("height"), C2XML (buffer));
 		xmlSetProp (rect, CC2XML ("style"), CC2XML ("opacity:1; stroke:none; fill:rgb(0,0,0);"));
 	    } 
-	    surface->modified = TRUE;
 	    return CAIRO_STATUS_SUCCESS;
 	}
     }
-
-    if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
-	return operator_analyze (op);
+#endif
 
     emit_paint (surface->xml_node, surface, op, source);
     
-    surface->modified = TRUE;
     return CAIRO_STATUS_SUCCESS;
 }
 
@@ -1248,7 +1274,9 @@ _cairo_svg_surface_mask (void		    *abst
     emit_alpha_filter (document);
 
     if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
-	return operator_analyze (op);
+	return _analyze_operation (surface, op, source);
+
+    assert (_operation_supported (surface, op, source));
     
     mask_node = xmlNewNode (NULL, CC2XML ("mask"));
     snprintf (buffer, sizeof buffer, "mask%d", document->mask_id);
@@ -1268,7 +1296,6 @@ _cairo_svg_surface_mask (void		    *abst
 
     document->mask_id++;
 
-    surface->modified = TRUE;
     return CAIRO_STATUS_SUCCESS;
 }
 
@@ -1294,7 +1321,9 @@ _cairo_svg_surface_stroke (void			*abstr
     char buffer[CAIRO_SVG_DTOSTR_BUFFER_LEN];
     
     if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
-	return operator_analyze (op);
+	return _analyze_operation (surface, op, source);
+
+    assert (_operation_supported (surface, op, source));
 
     info.document = document;
     info.path = xmlBufferCreate ();
@@ -1376,7 +1405,6 @@ _cairo_svg_surface_stroke (void			*abstr
     xmlBufferFree (info.path);
     xmlBufferFree (style);
 
-    surface->modified = TRUE;
     return status;
 }
 
@@ -1393,7 +1421,9 @@ _cairo_svg_surface_show_glyphs (void			*
     cairo_status_t status;
     
     if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
-	return operator_analyze (op);
+	return _analyze_operation (surface, op, pattern);
+
+    assert (_operation_supported (surface, op, pattern));
 
     /* FIXME: We don't really want to keep this as is. There's to possibilities:
      *   - Use SVG fonts. But support for them seems very rare in SVG renderers.
@@ -1415,7 +1445,6 @@ _cairo_svg_surface_show_glyphs (void			*
 
     _cairo_path_fixed_fini (&path);
 
-    surface->modified = TRUE;
     return status;
 }
 
@@ -1433,9 +1462,6 @@ _cairo_svg_surface_intersect_clip_path (
     svg_path_info_t info;
     char buffer[CAIRO_SVG_DTOSTR_BUFFER_LEN];
 
-    if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
-	return CAIRO_STATUS_SUCCESS;
-
     if (path == NULL) {
 	surface->xml_node = surface->xml_root_node;
 	surface->clip_level = 0;
@@ -1568,6 +1594,8 @@ _cairo_svg_document_create (cairo_output
     document->alpha_filter = FALSE;
 
     _cairo_array_init (&document->pattern_snapshots, sizeof (pattern_snapshot_t));
+
+    document->svg_version = CAIRO_SVG_VERSION_1_1;
     
     return document;
 }
@@ -1612,7 +1640,9 @@ _cairo_svg_document_finish (cairo_svg_do
 {
     cairo_status_t status;
     cairo_output_stream_t *output = document->output_stream;
+    pattern_snapshot_t *pattern_snapshot;
     xmlOutputBufferPtr xml_output_buffer;
+    unsigned int i;
 
     if (document->finished)
 	return CAIRO_STATUS_SUCCESS;
@@ -1628,6 +1658,10 @@ _cairo_svg_document_finish (cairo_svg_do
     status = _cairo_output_stream_get_status (output);
     _cairo_output_stream_destroy (output);
 
+    for (i = 0; i < document->pattern_snapshots.num_elements; i++) {
+	pattern_snapshot = _cairo_array_index (&document->pattern_snapshots, i);
+	cairo_surface_destroy ((cairo_surface_t *) pattern_snapshot->meta);
+    }
     _cairo_array_fini (&document->pattern_snapshots);
 
     document->finished = TRUE;
diff-tree 061d5088985a5e0b16202a4f031938772749940a (from 59dcb95ce5fed8264bc161979e615609c38ace2d)
Author: Emmanuel Pacaud <emmanuel.pacaud at free.fr>
Date:   Mon May 1 22:43:15 2006 +0200

    SVG: Sort of working implementation of a SVG backend with paginated surface
        support.
    
            Unoptimized and with memory leaks.

diff --git a/src/cairo-svg-surface.c b/src/cairo-svg-surface.c
index eea0647..35ed860 100644
--- a/src/cairo-svg-surface.c
+++ b/src/cairo-svg-surface.c
@@ -40,6 +40,7 @@
 #include "cairo-svg.h"
 #include "cairo-path-fixed-private.h"
 #include "cairo-ft-private.h"
+#include "cairo-meta-surface-private.h"
 #include "cairo-paginated-surface-private.h"
 
 #include <libxml/tree.h>
@@ -78,6 +79,8 @@ struct cairo_svg_document {
     unsigned int mask_id;
 
     cairo_bool_t alpha_filter;
+
+    cairo_array_t pattern_snapshots;
 };
 
 struct cairo_svg_surface {
@@ -337,14 +340,11 @@ _cairo_svg_surface_create_for_document (
 
 static cairo_surface_t *
 _cairo_svg_surface_create_similar (void			*abstract_src,
-				   cairo_content_t	content,
-				   int			width,
-				   int			height)
+				   cairo_content_t	 content,
+				   int			 width,
+				   int			 height)
 {
-    cairo_svg_surface_t *template = abstract_src;
-
-    return _cairo_svg_surface_create_for_document (template->document,
-						   content, width, height);
+    return _cairo_meta_surface_create (content, width, height);
 }
 
 static cairo_status_t
@@ -591,30 +591,90 @@ emit_composite_image_pattern (xmlNodePtr
     return child;
 }
 
+typedef struct {
+    unsigned int id;
+    cairo_meta_surface_t *meta;
+} pattern_snapshot_t;
+
+static int
+_emit_meta_surface_with_snapshot (cairo_svg_document_t *document,
+				  cairo_meta_surface_t *surface)
+{
+    cairo_meta_surface_t *meta;
+    pattern_snapshot_t *pattern_snapshot;
+    int num_elements;
+    unsigned int i, id;
+
+    num_elements = document->pattern_snapshots.num_elements;
+    for (i = 0; i < num_elements; i++) {
+	pattern_snapshot = _cairo_array_index (&document->pattern_snapshots, i);
+	meta = pattern_snapshot->meta;
+	if (meta->commands.num_elements == surface->commands.num_elements &&
+	    _cairo_array_index (&meta->commands, 0) == _cairo_array_index (&surface->commands, 0)) {
+	    id = pattern_snapshot->id;
+	    break;
+	}
+    }
+    
+    if (i >= num_elements) {
+	cairo_surface_t *paginated_surface;
+	cairo_surface_t *svg_surface;
+	pattern_snapshot_t snapshot;
+	xmlNodePtr child;
+
+	meta = (cairo_meta_surface_t *) _cairo_surface_snapshot ((cairo_surface_t *)surface);
+	svg_surface = _cairo_svg_surface_create_for_document (document,
+							      meta->content,
+							      meta->width_pixels, 
+							      meta->height_pixels);
+	paginated_surface = _cairo_paginated_surface_create (svg_surface,
+							     meta->content,
+							     meta->width_pixels, 
+							     meta->height_pixels,
+							     &cairo_svg_surface_paginated_backend);
+	_cairo_meta_surface_replay ((cairo_surface_t *)meta, paginated_surface);
+	_cairo_surface_show_page (paginated_surface);
+	
+	snapshot.meta = meta;
+	snapshot.id = ((cairo_svg_surface_t *) svg_surface)->id;
+	_cairo_array_append (&document->pattern_snapshots, &snapshot);
+	
+	if (meta->content == CAIRO_CONTENT_ALPHA) 
+	    emit_alpha_filter (document);
+	child = xmlAddChild (document->xml_node_defs, 
+			     xmlCopyNode (((cairo_svg_surface_t *) svg_surface)->xml_root_node, 1));
+	if (meta->content == CAIRO_CONTENT_ALPHA) 
+	    xmlSetProp (child, CC2XML ("filter"), CC2XML("url(#alpha)"));
+
+	id = snapshot.id;
+
+	cairo_surface_destroy (paginated_surface);
+    }
+
+    return id;
+}
+
 static xmlNodePtr
-emit_composite_svg_pattern (xmlNodePtr node, 
-			    cairo_surface_pattern_t *pattern,
-			    double *width, 
-			    double *height,
-			    cairo_bool_t is_pattern)
+emit_composite_meta_pattern (xmlNodePtr node, 
+			     cairo_svg_surface_t	*surface,
+			     cairo_surface_pattern_t	*pattern,
+			     double *width, 
+			     double *height,
+			     cairo_bool_t is_pattern)
 {
-    cairo_svg_surface_t *surface = (cairo_svg_surface_t *) pattern->surface;
     cairo_svg_document_t *document = surface->document;
+    cairo_meta_surface_t *meta_surface;
     cairo_matrix_t p2u;
     xmlNodePtr child;
+    int id;
     char buffer[CAIRO_SVG_DTOSTR_BUFFER_LEN];
 
-    if (surface->modified) {
-	    if (surface->content == CAIRO_CONTENT_ALPHA) 
-		emit_alpha_filter (document);
-	    child = xmlAddChild (document->xml_node_defs, xmlCopyNode (surface->xml_root_node, 1));
-	    if (surface->content == CAIRO_CONTENT_ALPHA) 
-		    xmlSetProp (child, CC2XML ("filter"), CC2XML("url(#alpha)"));
-    }
+    meta_surface = (cairo_meta_surface_t *) pattern->surface;
+    
+    id = _emit_meta_surface_with_snapshot (document, meta_surface);
     
     child = xmlNewChild (node, NULL, CC2XML("use"), NULL);
-    snprintf (buffer, sizeof buffer, "#surface%d", 
-	      surface->modified ? surface->id : surface->previous_id);
+    snprintf (buffer, sizeof buffer, "#surface%d", id);
     xmlSetProp (child, CC2XML ("xlink:href"), C2XML (buffer));
 
     if (!is_pattern) {
@@ -624,32 +684,27 @@ emit_composite_svg_pattern (xmlNodePtr n
     }
 
     if (width != NULL)
-	    *width = surface->width;
+	    *width = meta_surface->width_pixels;
     if (height != NULL)
-	    *height = surface->height;
-
-    if (surface->modified) {
-	    surface->modified = FALSE;
-	    surface->previous_id = surface->id;
-	    surface->id = document->surface_id++;
-	    snprintf (buffer, sizeof buffer, "surface%d", surface->id);
-	    xmlSetProp (surface->xml_root_node, CC2XML ("id"), C2XML (buffer));
-    }
+	    *height = meta_surface->height_pixels;
 
     return child;
 }
 
 static xmlNodePtr
 emit_composite_pattern (xmlNodePtr node, 
+			cairo_svg_surface_t	*surface,
 			cairo_surface_pattern_t *pattern,
 			double *width,
 			double *height,
 			int is_pattern)
 {
-    if (_cairo_surface_is_svg (pattern->surface))
-	return emit_composite_svg_pattern (node, pattern, width, height, is_pattern);
-    else
-	return emit_composite_image_pattern (node, pattern, width, height, is_pattern);
+
+    if (_cairo_surface_is_meta (pattern->surface)) { 
+	return emit_composite_meta_pattern (node, surface, pattern, width, height, is_pattern);
+    }
+
+    return emit_composite_image_pattern (node, pattern, width, height, is_pattern);
 }
 
 /* FIXME: Here we use a SVG 1.2 feature. We should probably have
@@ -736,7 +791,7 @@ emit_surface_pattern (cairo_svg_surface_
 
     document->pattern_id++;
 
-    emit_composite_pattern (child, pattern, &width, &height, TRUE);
+    emit_composite_pattern (child, surface, pattern, &width, &height, TRUE);
 
     _cairo_dtostr (buffer, sizeof buffer, width);
     xmlSetProp (child, CC2XML ("width"), C2XML (buffer));
@@ -1109,6 +1164,7 @@ emit_paint (xmlNodePtr node,
     if (source->type == CAIRO_PATTERN_TYPE_SURFACE && 
 	source->extend == CAIRO_EXTEND_NONE)
 	return emit_composite_pattern (node, 
+				       surface,
 				       (cairo_surface_pattern_t *) source, 
 				       NULL, NULL, FALSE);
 
@@ -1511,6 +1567,8 @@ _cairo_svg_document_create (cairo_output
 
     document->alpha_filter = FALSE;
 
+    _cairo_array_init (&document->pattern_snapshots, sizeof (pattern_snapshot_t));
+    
     return document;
 }
 
@@ -1570,6 +1628,8 @@ _cairo_svg_document_finish (cairo_svg_do
     status = _cairo_output_stream_get_status (output);
     _cairo_output_stream_destroy (output);
 
+    _cairo_array_fini (&document->pattern_snapshots);
+
     document->finished = TRUE;
 
     return status;
diff-tree 59dcb95ce5fed8264bc161979e615609c38ace2d (from 0625d4cd3fb6145e7f9a7474d03945a497b12406)
Author: Emmanuel Pacaud <emmanuel.pacaud at free.fr>
Date:   Mon May 1 22:41:12 2006 +0200

    SVG: First pass for analyze-surface support

diff --git a/src/cairo-svg-surface.c b/src/cairo-svg-surface.c
index 90a053a..eea0647 100644
--- a/src/cairo-svg-surface.c
+++ b/src/cairo-svg-surface.c
@@ -1,7 +1,7 @@
 /* cairo - a vector graphics library with display and print output
  *
  * Copyright © 2004 Red Hat, Inc
- * Copyright © 2005 Emmanuel Pacaud <emmanuel.pacaud at free.fr>
+ * Copyright © 2005-2006 Emmanuel Pacaud <emmanuel.pacaud at free.fr>
  *
  * This library is free software; you can redistribute it and/or
  * modify it either under the terms of the GNU Lesser General Public
@@ -40,6 +40,7 @@
 #include "cairo-svg.h"
 #include "cairo-path-fixed-private.h"
 #include "cairo-ft-private.h"
+#include "cairo-paginated-surface-private.h"
 
 #include <libxml/tree.h>
 
@@ -98,6 +99,8 @@ struct cairo_svg_surface {
 
     cairo_bool_t modified;
     unsigned int previous_id;
+
+    cairo_paginated_mode_t paginated_mode;
 };
 
 static cairo_svg_document_t *
@@ -120,6 +123,10 @@ _cairo_svg_surface_create_for_document (
 					double			 width,
 					double			 height);
 
+static void
+_cairo_svg_set_paginated_mode (cairo_surface_t *target,
+			       cairo_paginated_mode_t mode);
+
 static const cairo_surface_backend_t cairo_svg_surface_backend;
 
 static cairo_surface_t *
@@ -131,8 +138,10 @@ _cairo_svg_surface_create_for_stream_int
     cairo_surface_t *surface;
 
     document = _cairo_svg_document_create (stream, width, height);
-    if (document == NULL)
-      return NULL;
+    if (document == NULL) {
+	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	return (cairo_surface_t *) &_cairo_surface_nil;
+    }
 
     surface = _cairo_svg_surface_create_for_document (document, CAIRO_CONTENT_COLOR_ALPHA, 
 						      width, height);
@@ -140,7 +149,10 @@ _cairo_svg_surface_create_for_stream_int
     document->owner = surface;
     _cairo_svg_document_destroy (document);
 
-    return surface;
+    return _cairo_paginated_surface_create (surface,
+					    CAIRO_CONTENT_COLOR_ALPHA,
+					    width, height,
+					    _cairo_svg_set_paginated_mode);
 }
 
 /**
@@ -215,6 +227,12 @@ cairo_svg_surface_create (const char	*fi
     return _cairo_svg_surface_create_for_stream_internal (stream, width, height);
 }
 
+static cairo_bool_t
+_cairo_surface_is_svg (cairo_surface_t *surface)
+{
+    return surface->backend == &cairo_svg_surface_backend;
+}
+
 /**
  * cairo_svg_surface_set_dpi:
  * @surface: a svg cairo_surface_t
@@ -225,14 +243,30 @@ cairo_svg_surface_create (const char	*fi
  * When the svg backend needs to fall back to image overlays, it will
  * use this resolution. These DPI values are not used for any other
  * purpose, (in particular, they do not have any bearing on the size
- * passed to cairo_svg_surface_create() nor on the CTM).
+ * passed to cairo_pdf_surface_create() nor on the CTM).
  **/
+
 void
 cairo_svg_surface_set_dpi (cairo_surface_t	*surface,
 			   double		x_dpi,
 			   double		y_dpi)
 {
-    cairo_svg_surface_t *svg_surface = (cairo_svg_surface_t *) surface;
+    cairo_surface_t *target;
+    cairo_svg_surface_t *svg_surface;
+
+    if (!_cairo_surface_is_paginated (surface)) {
+	_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
+	return;
+    }
+
+    target = _cairo_paginated_surface_get_target (surface);
+
+    if (!_cairo_surface_is_svg (target)) {
+	_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
+	return;
+    }
+
+    svg_surface = (cairo_svg_surface_t *) target;
 
     svg_surface->document->x_dpi = x_dpi;    
     svg_surface->document->y_dpi = y_dpi;    
@@ -296,6 +330,8 @@ _cairo_svg_surface_create_for_document (
     surface->previous_id = surface->id;
     surface->content = content;
 
+    surface->paginated_mode = CAIRO_PAGINATED_MODE_ANALYZE;
+    
     return &surface->base;
 }
 
@@ -333,6 +369,21 @@ _cairo_svg_surface_finish (void *abstrac
     return status;
 }
 
+static cairo_bool_t
+operator_supported (cairo_operator_t op)
+{
+    return (op == CAIRO_OPERATOR_SOURCE);
+}
+
+static cairo_int_status_t
+operator_analyze (cairo_operator_t op)
+{
+    if (operator_supported (op))
+	return CAIRO_STATUS_SUCCESS;
+    else
+	return CAIRO_INT_STATUS_UNSUPPORTED;
+}
+
 static void
 emit_alpha_filter (cairo_svg_document_t *document)
 {
@@ -595,7 +646,7 @@ emit_composite_pattern (xmlNodePtr node,
 			double *height,
 			int is_pattern)
 {
-    if (pattern->surface->backend == &cairo_svg_surface_backend)
+    if (_cairo_surface_is_svg (pattern->surface))
 	return emit_composite_svg_pattern (node, pattern, width, height, is_pattern);
     else
 	return emit_composite_image_pattern (node, pattern, width, height, is_pattern);
@@ -994,6 +1045,9 @@ _cairo_svg_surface_fill (void			*abstrac
     xmlNodePtr child;
     xmlBufferPtr style;
 
+    if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
+	return operator_analyze (op);
+
     info.document = document;
     info.path = xmlBufferCreate ();
     
@@ -1115,6 +1169,9 @@ _cairo_svg_surface_paint (void		    *abs
 	}
     }
 
+    if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
+	return operator_analyze (op);
+
     emit_paint (surface->xml_node, surface, op, source);
     
     surface->modified = TRUE;
@@ -1134,6 +1191,9 @@ _cairo_svg_surface_mask (void		    *abst
 
     emit_alpha_filter (document);
 
+    if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
+	return operator_analyze (op);
+    
     mask_node = xmlNewNode (NULL, CC2XML ("mask"));
     snprintf (buffer, sizeof buffer, "mask%d", document->mask_id);
     xmlSetProp (mask_node, CC2XML ("id"), C2XML (buffer));
@@ -1177,6 +1237,9 @@ _cairo_svg_surface_stroke (void			*abstr
     unsigned int i;
     char buffer[CAIRO_SVG_DTOSTR_BUFFER_LEN];
     
+    if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
+	return operator_analyze (op);
+
     info.document = document;
     info.path = xmlBufferCreate ();
 
@@ -1272,6 +1335,9 @@ _cairo_svg_surface_show_glyphs (void			*
     cairo_svg_surface_t *surface = abstract_surface;
     cairo_path_fixed_t path;
     cairo_status_t status;
+    
+    if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
+	return operator_analyze (op);
 
     /* FIXME: We don't really want to keep this as is. There's to possibilities:
      *   - Use SVG fonts. But support for them seems very rare in SVG renderers.
@@ -1311,6 +1377,9 @@ _cairo_svg_surface_intersect_clip_path (
     svg_path_info_t info;
     char buffer[CAIRO_SVG_DTOSTR_BUFFER_LEN];
 
+    if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
+	return CAIRO_STATUS_SUCCESS;
+
     if (path == NULL) {
 	surface->xml_node = surface->xml_root_node;
 	surface->clip_level = 0;
@@ -1505,3 +1574,12 @@ _cairo_svg_document_finish (cairo_svg_do
 
     return status;
 }
+
+static void
+_cairo_svg_set_paginated_mode (cairo_surface_t *target,
+			       cairo_paginated_mode_t paginated_mode)
+{
+    cairo_svg_surface_t *surface = (cairo_svg_surface_t *) target;
+
+    surface->paginated_mode = paginated_mode;
+}
diff-tree 0625d4cd3fb6145e7f9a7474d03945a497b12406 (from d1dcbbb8c34ed160d2b24a9afc8f30ac9de87d91)
Author: Emmanuel Pacaud <emmanuel.pacaud at free.fr>
Date:   Mon May 1 22:15:38 2006 +0200

    SVG: Ignore SVG test files.

diff --git a/test/.gitignore b/test/.gitignore
index 5ffa61d..b1704f6 100644
--- a/test/.gitignore
+++ b/test/.gitignore
@@ -99,6 +99,8 @@ xlib-surface
 *-ps-rgb24-out.ps
 *-svg-argb32-out.png
 *-svg-argb32-out.svg
+*-svg-rgb24-out.png
+*-svg-rgb24-out.svg
 *-test-fallback-argb32-out.png
 *-test-fallback-rgb24-out.png
 *-test-meta-argb32-out.png
diff-tree d1dcbbb8c34ed160d2b24a9afc8f30ac9de87d91 (from bdc1c1ac783f1d2bda742ea7150de2c4b0751a29)
Author: Emmanuel Pacaud <emmanuel.pacaud at free.fr>
Date:   Tue Apr 25 22:48:21 2006 +0200

    SVG: Update rgb24 reference files.
    (cherry picked from 7173951535f4b95da37cbf3d51143deeec95e47a commit)

diff --git a/test/show-text-current-point-svg-rgb24-ref.png b/test/show-text-current-point-svg-rgb24-ref.png
index 717ad7e..2c4bcd7 100644
Binary files a/test/show-text-current-point-svg-rgb24-ref.png and b/test/show-text-current-point-svg-rgb24-ref.png differ
diff --git a/test/text-antialias-gray-svg-rgb24-ref.png b/test/text-antialias-gray-svg-rgb24-ref.png
index aa64fbb..20f0d58 100644
Binary files a/test/text-antialias-gray-svg-rgb24-ref.png and b/test/text-antialias-gray-svg-rgb24-ref.png differ
diff --git a/test/text-antialias-none-svg-rgb24-ref.png b/test/text-antialias-none-svg-rgb24-ref.png
index aa64fbb..20f0d58 100644
Binary files a/test/text-antialias-none-svg-rgb24-ref.png and b/test/text-antialias-none-svg-rgb24-ref.png differ
diff --git a/test/text-antialias-subpixel-svg-rgb24-ref.png b/test/text-antialias-subpixel-svg-rgb24-ref.png
index aa64fbb..20f0d58 100644
Binary files a/test/text-antialias-subpixel-svg-rgb24-ref.png and b/test/text-antialias-subpixel-svg-rgb24-ref.png differ
diff --git a/test/text-pattern-svg-rgb24-ref.png b/test/text-pattern-svg-rgb24-ref.png
index 6f3510c..c33e77e 100644
Binary files a/test/text-pattern-svg-rgb24-ref.png and b/test/text-pattern-svg-rgb24-ref.png differ
diff-tree bdc1c1ac783f1d2bda742ea7150de2c4b0751a29 (from 6a33993b1510d1c0d311f4a10832ab2bc5ea8f4e)
Author: Emmanuel Pacaud <emmanuel.pacaud at free.fr>
Date:   Mon May 1 22:12:20 2006 +0200

    Copy content property when doing a snapshot of a meta surface.

diff --git a/src/cairo-meta-surface.c b/src/cairo-meta-surface.c
index f02f0a7..c7e4f25 100644
--- a/src/cairo-meta-surface.c
+++ b/src/cairo-meta-surface.c
@@ -483,6 +483,7 @@ _cairo_meta_surface_snapshot (void *abst
     meta->width_pixels = other->width_pixels;
     meta->height_pixels = other->height_pixels;
     meta->replay_start_idx = other->replay_start_idx;
+    meta->content = other->content;
 
     _cairo_array_init_snapshot (&meta->commands, &other->commands);
     meta->commands_owner = cairo_surface_reference (&other->base);
diff-tree 6a33993b1510d1c0d311f4a10832ab2bc5ea8f4e (from parents)
Merge: b920dfd3df7ac1a0e49b7417b710f111a3780700 3aa5d76d23ad9005d296fbb852e75924b0933c82
Author: Emmanuel Pacaud <emmanuel.pacaud at free.fr>
Date:   Mon May 1 22:01:38 2006 +0200

    Merge branch 'origin'

diff-tree b920dfd3df7ac1a0e49b7417b710f111a3780700 (from fe8bf47afc11b12034fd2c92caf424c8911d630b)
Author: Emmanuel Pacaud <emmanuel.pacaud at free.fr>
Date:   Mon May 1 21:59:53 2006 +0200

    SVG: Reenable operator tests, and rgb24 surface are meta-surfaces.

diff --git a/test/cairo-test.c b/test/cairo-test.c
index 46cf5f4..8250125 100644
--- a/test/cairo-test.c
+++ b/test/cairo-test.c
@@ -1305,10 +1305,6 @@ cleanup_pdf (void *closure)
 #include "cairo-svg.h"
 
 static const char *svg_ignored_tests[] = {
-    "operator-source",
-    "operator-clear",
-    "clip-operator",
-    "unbounded-operator",
     NULL
 };
 
@@ -1638,11 +1634,7 @@ cairo_test_expecting (cairo_test_t *test
 #if CAIRO_HAS_SVG_SURFACE && CAIRO_CAN_TEST_SVG_SURFACE
 	    { "svg", CAIRO_SURFACE_TYPE_SVG, CAIRO_CONTENT_COLOR_ALPHA,
 		    create_svg_surface, svg_surface_write_to_png, cleanup_svg },
-
-	    /* A SVG surface is COLOR_APLHA by default, and currently a create
-	     * similar with content != COLOR_ALPHA will return a nil surface.
-	     * So don't test COLOR for now. */
-	    { "svg", CAIRO_SURFACE_TYPE_SVG, CAIRO_CONTENT_COLOR,
+	    { "svg", CAIRO_INTERNAL_SURFACE_TYPE_META, CAIRO_CONTENT_COLOR,
 		    create_svg_surface, svg_surface_write_to_png, cleanup_svg },
 #endif
 #if CAIRO_HAS_BEOS_SURFACE


More information about the cairo-commit mailing list