[cairo-commit] 4 commits - src/cairo-svg-surface.c test/fallback-resolution.c test/pixman-rotate.c

Emmanuel Pacaud emmanuel at kemper.freedesktop.org
Sat Nov 18 04:11:51 PST 2006


 src/cairo-svg-surface.c    |  125 ++++++++++++++++++++++++++++++++++++++++-----
 test/fallback-resolution.c |   33 +----------
 test/pixman-rotate.c       |    2 
 3 files changed, 115 insertions(+), 45 deletions(-)

New commits:
diff-tree 10920c1326362b4fadfa01019223647c23351127 (from parents)
Merge: 1ed3811338a03068b7ce60f83fdd23fe01fec972 2928f6eb5f5bd207f8f41a628ad95d6552aa8246
Author: Emmanuel Pacaud <emmanuel.pacaud at free.fr>
Date:   Sat Nov 18 12:59:12 2006 +0100

    Merge branch 'svgprint'

diff-tree 2928f6eb5f5bd207f8f41a628ad95d6552aa8246 (from 4f02395267dc0cccef231e548a914329dce2831f)
Author: Emmanuel Pacaud <emmanuel.pacaud at free.fr>
Date:   Sun Nov 12 20:49:34 2006 +0100

    test/pixman-rotate.c: Don't issue a show_page, it's already done in cairo-test.c

diff --git a/test/pixman-rotate.c b/test/pixman-rotate.c
index 425f883..ca4d961 100644
--- a/test/pixman-rotate.c
+++ b/test/pixman-rotate.c
@@ -63,8 +63,6 @@ draw (cairo_t *cr, int width, int height
     cairo_set_source_surface (cr, stamp, 0, 0);
     cairo_paint (cr);
 
-    cairo_show_page (cr);
-
     cairo_surface_destroy (stamp);
 
     return CAIRO_TEST_SUCCESS;
diff-tree 4f02395267dc0cccef231e548a914329dce2831f (from ad6d3a8369569cefde4984c0102cacf56b159cc7)
Author: Emmanuel Pacaud <emmanuel.pacaud at free.fr>
Date:   Sun Nov 12 20:45:50 2006 +0100

    Use SVG multipage capability.

diff --git a/test/fallback-resolution.c b/test/fallback-resolution.c
index 25cdcdc..5448765 100644
--- a/test/fallback-resolution.c
+++ b/test/fallback-resolution.c
@@ -112,7 +112,8 @@ main (void)
 	    break;
 	case SVG:
 	    surface = cairo_svg_surface_create (backend_filename[backend],
-						SIZE, SIZE * num_pages);
+						SIZE, SIZE);
+	    cairo_svg_surface_restrict_to_version (surface, CAIRO_SVG_VERSION_1_2);
 	    _cairo_svg_test_force_fallbacks ();
 	    break;
 	}
@@ -125,35 +126,7 @@ main (void)
 
 	    draw_with_ppi (cr, SIZE, SIZE, ppi[page]);
 
-	    /* Backend-specific means of "advancing a page" */
-	    switch (backend) {
-	    case PDF:
-	    case PS:
-		cairo_show_page (cr);
-		break;
-	    case SVG:
-		/* Since the SVG backend doesn't natively support multiple
-		 * pages, we just move further down for each logical
-		 * page, then finally do a show_page at the end. */
-		if (page < num_pages - 1) {
-		    cairo_translate (cr, 0, SIZE);
-		} else {
-		    /* XXX: The goal of this test is to show the
-		     * effect of several different fallback
-		     * resolutions in a single output document. But
-		     * since fallback_resolution only takes effect at
-		     * the time of show_page, we only get once for the
-		     * SVG backend. I'm just re-setting the first one
-		     * here so we actually get legible output.
-		     *
-		     * To fix this properly we'll need some sort of
-		     * multi-page support in the SVG backend I think.
-		     */
-		    cairo_surface_set_fallback_resolution (surface, ppi[0], ppi[0]);
-		    cairo_show_page (cr);
-		}
-		break;
-	    }
+	    cairo_show_page (cr);
 	}
 
 	status = cairo_status (cr);
diff-tree ad6d3a8369569cefde4984c0102cacf56b159cc7 (from 26b74049e79a6137e8556e1b3e5c3aedd780abb0)
Author: Emmanuel Pacaud <emmanuel.pacaud at free.fr>
Date:   Sun Nov 12 20:45:10 2006 +0100

    Add SVGPrint support.
    
    It's only activated when svg version >= 1.2.
    Last page without a show page call is ignored if blank.

diff --git a/src/cairo-svg-surface.c b/src/cairo-svg-surface.c
index d4c60b6..258fe24 100644
--- a/src/cairo-svg-surface.c
+++ b/src/cairo-svg-surface.c
@@ -49,6 +49,7 @@
 
 typedef struct cairo_svg_document cairo_svg_document_t;
 typedef struct cairo_svg_surface cairo_svg_surface_t;
+typedef struct cairo_svg_page cairo_svg_page_t;
 
 static const int invalid_pattern_id = -1;
 
@@ -60,6 +61,12 @@ static const cairo_svg_version_t _cairo_
 
 #define CAIRO_SVG_VERSION_LAST ((int)(sizeof (_cairo_svg_versions) / sizeof (_cairo_svg_versions[0])))
 
+static cairo_bool_t
+_cairo_svg_version_has_page_set_support (cairo_svg_version_t version)
+{
+    return version > CAIRO_SVG_VERSION_1_1;
+}
+
 static const char * _cairo_svg_version_strings[CAIRO_SVG_VERSION_LAST] =
 {
     "SVG 1.1",
@@ -72,6 +79,13 @@ static const char * _cairo_svg_internal_
     "1.2"
 };
 
+struct cairo_svg_page {
+    unsigned int surface_id;
+    unsigned int clip_id;
+    unsigned int clip_level;
+    cairo_output_stream_t *xml_node;
+};
+
 struct cairo_svg_document {
     cairo_output_stream_t *output_stream;
     unsigned long refcount;
@@ -114,6 +128,7 @@ struct cairo_svg_surface {
     cairo_svg_document_t *document;
 
     cairo_output_stream_t *xml_node;
+    cairo_array_t	   page_set;
 
     unsigned int clip_level;
     unsigned int base_clip;
@@ -370,6 +385,7 @@ _cairo_svg_surface_create_for_document (
 				 width, height);
 
     surface->xml_node = _cairo_memory_stream_create ();
+    _cairo_array_init (&surface->page_set, sizeof (cairo_svg_page_t));
 
     if (content == CAIRO_CONTENT_COLOR) {
 	_cairo_output_stream_printf (surface->xml_node,
@@ -412,6 +428,53 @@ _cairo_svg_surface_create_for_stream_int
     return surface;
 }
 
+static cairo_svg_page_t *
+_cairo_svg_surface_store_page (cairo_svg_surface_t *surface)
+{
+    unsigned int i;
+    cairo_svg_page_t page;
+
+    page.xml_node = _cairo_memory_stream_create ();
+    page.surface_id = surface->id;
+    page.clip_id = surface->base_clip;
+    page.clip_level = surface->clip_level;
+
+    page.xml_node = surface->xml_node;
+    surface->xml_node = _cairo_memory_stream_create ();
+    surface->clip_level = 0;
+
+    for (i = 0; i < page.clip_level; i++)
+	_cairo_output_stream_printf (page.xml_node, "</g>\n");
+
+    _cairo_array_append (&surface->page_set, &page);
+
+    return _cairo_array_index (&surface->page_set, surface->page_set.num_elements - 1);
+}
+
+static cairo_int_status_t
+_cairo_svg_surface_copy_page (void *abstract_surface)
+{
+    cairo_svg_surface_t *surface = abstract_surface;
+    cairo_svg_page_t *page;
+
+    page = _cairo_svg_surface_store_page (surface);
+
+    _cairo_memory_stream_copy (page->xml_node, surface->xml_node);
+    surface->clip_level = page->clip_level;
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_int_status_t
+_cairo_svg_surface_show_page (void *abstract_surface)
+{
+    cairo_svg_surface_t *surface = abstract_surface;
+
+    _cairo_svg_surface_store_page (surface);
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
 static void
 emit_transform (cairo_output_stream_t *output,
 		char const *attribute_str,
@@ -716,6 +779,8 @@ _cairo_svg_surface_finish (void *abstrac
     cairo_status_t status;
     cairo_svg_surface_t *surface = abstract_surface;
     cairo_svg_document_t *document = surface->document;
+    cairo_svg_page_t *page;
+    unsigned int i;
 
     if (_cairo_paginated_surface_get_target (document->owner) == &surface->base)
 	status = _cairo_svg_document_finish (document);
@@ -724,6 +789,12 @@ _cairo_svg_surface_finish (void *abstrac
 
     _cairo_output_stream_destroy (surface->xml_node);
 
+    for (i = 0; i < surface->page_set.num_elements; i++) {
+	page = _cairo_array_index (&surface->page_set, i);
+	_cairo_output_stream_destroy (page->xml_node);
+    }
+    _cairo_array_fini (&surface->page_set);
+
     _cairo_svg_document_destroy (document);
 
     return status;
@@ -923,6 +994,7 @@ emit_meta_surface (cairo_svg_document_t 
 	cairo_surface_t *paginated_surface;
 	cairo_surface_t *svg_surface;
 	cairo_meta_snapshot_t new_snapshot;
+	cairo_array_t *page_set;
 
 	meta = (cairo_meta_surface_t *) _cairo_surface_snapshot ((cairo_surface_t *)surface);
 	paginated_surface = _cairo_svg_surface_create_for_document (document,
@@ -957,10 +1029,17 @@ emit_meta_surface (cairo_svg_document_t 
 	}
 
 	contents = ((cairo_svg_surface_t *) svg_surface)->xml_node;
-	_cairo_memory_stream_copy (contents, document->xml_node_defs);
+	page_set = &((cairo_svg_surface_t *) svg_surface)->page_set;
 
-	for (i = 0; i < ((cairo_svg_surface_t *) svg_surface)->clip_level; i++)
-	    _cairo_output_stream_printf (document->xml_node_defs, "</g>\n");
+	if (_cairo_memory_stream_length (contents) > 0)
+	    _cairo_svg_surface_store_page ((cairo_svg_surface_t *) svg_surface);
+
+	if (page_set->num_elements > 0) {
+	    cairo_svg_page_t *page;
+
+	    page = _cairo_array_index (page_set, page_set->num_elements - 1);
+	    _cairo_memory_stream_copy (page->xml_node, document->xml_node_defs);
+	}
 
 	_cairo_output_stream_printf (document->xml_node_defs, "</g>\n");
 
@@ -1664,8 +1743,8 @@ static const cairo_surface_backend_t cai
 	NULL, /* _cairo_svg_surface_composite, */
 	NULL, /* _cairo_svg_surface_fill_rectangles, */
 	NULL, /* _cairo_svg_surface_composite_trapezoids,*/
-	NULL, /* copy_page */
-	NULL, /* show_page */
+	_cairo_svg_surface_copy_page,
+	_cairo_svg_surface_show_page,
 	NULL, /* set_clip_region */
 	_cairo_svg_surface_intersect_clip_path,
 	_cairo_svg_surface_get_extents,
@@ -1759,6 +1838,7 @@ _cairo_svg_document_finish (cairo_svg_do
     cairo_output_stream_t *output = document->output_stream;
     cairo_meta_snapshot_t *snapshot;
     cairo_svg_surface_t *surface;
+    cairo_svg_page_t *page;
     unsigned int i;
 
     if (document->finished)
@@ -1788,17 +1868,36 @@ _cairo_svg_document_finish (cairo_svg_do
     }
 
     surface = (cairo_svg_surface_t *) _cairo_paginated_surface_get_target (document->owner);
-    _cairo_output_stream_printf (output,
-				 "<g id=\"surface%d\" "
-				 "clip-path=\"url(#clip%d)\">\n",
-				 surface->id,
-				 surface->base_clip);
-    _cairo_memory_stream_copy (surface->xml_node, output);
+    if (_cairo_memory_stream_length (surface->xml_node) > 0)
+	_cairo_svg_surface_store_page (surface);
 
-    for (i = 0; i < surface->clip_level; i++)
+    if (surface->page_set.num_elements > 1 &&
+	_cairo_svg_version_has_page_set_support (document->svg_version)) {
+	_cairo_output_stream_printf (output, "<pageSet>\n");
+	for (i = 0; i < surface->page_set.num_elements; i++) {
+	    page = _cairo_array_index (&surface->page_set, i);
+	    _cairo_output_stream_printf (output, "<page>\n");
+	    _cairo_output_stream_printf (output,
+					 "<g id=\"surface%d\" "
+					 "clip-path=\"url(#clip%d)\">\n",
+					 page->surface_id,
+					 page->clip_id);
+	    _cairo_memory_stream_copy (page->xml_node, output);
+	    _cairo_output_stream_printf (output, "</g>\n</page>\n");
+	}
+	_cairo_output_stream_printf (output, "</pageSet>\n");
+    } else if (surface->page_set.num_elements > 0) {
+	page = _cairo_array_index (&surface->page_set, surface->page_set.num_elements - 1);
+	_cairo_output_stream_printf (output,
+				     "<g id=\"surface%d\" "
+				     "clip-path=\"url(#clip%d)\">\n",
+				     page->surface_id,
+				     page->clip_id);
+	_cairo_memory_stream_copy (page->xml_node, output);
 	_cairo_output_stream_printf (output, "</g>\n");
+    }
 
-    _cairo_output_stream_printf (output, "</g>\n</svg>\n");
+    _cairo_output_stream_printf (output, "</svg>\n");
 
     _cairo_output_stream_destroy (document->xml_node_glyphs);
     _cairo_output_stream_destroy (document->xml_node_defs);


More information about the cairo-commit mailing list