[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