[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