[cairo-commit] src/cairo-svg-surface.c
Emmanuel Pacaud
emmanuel at kemper.freedesktop.org
Tue Apr 1 07:49:17 PDT 2008
src/cairo-svg-surface.c | 96 ++++++++++++++++++++++++++++++------------------
1 file changed, 60 insertions(+), 36 deletions(-)
New commits:
commit 9e6d6798700cf629abbd921cf744babeb49215a1
Author: Emmanuel Pacaud <emmanuel.pacaud at free.fr>
Date: Tue Apr 1 16:48:04 2008 +0200
[SVG] Fix stroke-image test failure.
The pattern transform inherit the object transform matrix, and that was not
taken into account.
diff --git a/src/cairo-svg-surface.c b/src/cairo-svg-surface.c
index 1b7b3e8..951068b 100644
--- a/src/cairo-svg-surface.c
+++ b/src/cairo-svg-surface.c
@@ -486,15 +486,21 @@ _cairo_svg_surface_show_page (void *abstract_surface)
static void
_cairo_svg_surface_emit_transform (cairo_output_stream_t *output,
char const *attribute_str,
- cairo_matrix_t *matrix)
+ const cairo_matrix_t *object_matrix,
+ const cairo_matrix_t *parent_matrix)
{
- if (!_cairo_matrix_is_identity (matrix))
+ cairo_matrix_t matrix = *object_matrix;
+
+ if (parent_matrix != NULL)
+ cairo_matrix_multiply (&matrix, &matrix, parent_matrix);
+
+ if (!_cairo_matrix_is_identity (&matrix))
_cairo_output_stream_printf (output,
"%s=\"matrix(%f,%f,%f,%f,%f,%f)\"",
attribute_str,
- matrix->xx, matrix->yx,
- matrix->xy, matrix->yy,
- matrix->x0, matrix->y0);
+ matrix.xx, matrix.yx,
+ matrix.xy, matrix.yy,
+ matrix.x0, matrix.y0);
}
typedef struct
@@ -654,7 +660,8 @@ _cairo_svg_document_emit_bitmap_glyph_data (cairo_svg_document_t *document,
}
_cairo_output_stream_printf (document->xml_node_glyphs, "<g");
- _cairo_svg_surface_emit_transform (document->xml_node_glyphs, " transform", &image->base.device_transform_inverse);
+ _cairo_svg_surface_emit_transform (document->xml_node_glyphs, " transform",
+ &image->base.device_transform_inverse, NULL);
_cairo_output_stream_printf (document->xml_node_glyphs, ">/n");
for (y = 0, row = image->data, rows = image->height; rows; row += image->stride, rows--, y++) {
@@ -950,6 +957,7 @@ _cairo_svg_surface_emit_composite_image_pattern (cairo_output_stream_t *output
cairo_svg_surface_t *svg_surface,
cairo_surface_pattern_t *pattern,
int pattern_id,
+ const cairo_matrix_t *parent_matrix,
const char *extra_attributes)
{
cairo_surface_t *surface;
@@ -981,7 +989,7 @@ _cairo_svg_surface_emit_composite_image_pattern (cairo_output_stream_t *output
"width=\"%d\" height=\"%d\"",
pattern_id,
extents.width, extents.height);
- _cairo_svg_surface_emit_transform (output, " patternTransform", &p2u);
+ _cairo_svg_surface_emit_transform (output, " patternTransform", &p2u, parent_matrix);
_cairo_output_stream_printf (output, ">\n");
}
@@ -990,7 +998,7 @@ _cairo_svg_surface_emit_composite_image_pattern (cairo_output_stream_t *output
extents.width, extents.height);
if (pattern_id == invalid_pattern_id)
- _cairo_svg_surface_emit_transform (output, " transform", &p2u);
+ _cairo_svg_surface_emit_transform (output, " transform", &p2u, parent_matrix);
if (extra_attributes)
_cairo_output_stream_printf (output, " %s", extra_attributes);
@@ -1144,6 +1152,7 @@ _cairo_svg_surface_emit_composite_meta_pattern (cairo_output_stream_t *output,
cairo_svg_surface_t *surface,
cairo_surface_pattern_t *pattern,
int pattern_id,
+ const cairo_matrix_t *parent_matrix,
const char *extra_attributes)
{
cairo_svg_document_t *document = surface->document;
@@ -1171,7 +1180,7 @@ _cairo_svg_surface_emit_composite_meta_pattern (cairo_output_stream_t *output,
pattern_id,
meta_surface->width_pixels,
meta_surface->height_pixels);
- _cairo_svg_surface_emit_transform (output, " patternTransform", &p2u);
+ _cairo_svg_surface_emit_transform (output, " patternTransform", &p2u, parent_matrix);
_cairo_output_stream_printf (output, ">\n");
}
@@ -1180,7 +1189,7 @@ _cairo_svg_surface_emit_composite_meta_pattern (cairo_output_stream_t *output,
id);
if (pattern_id == invalid_pattern_id)
- _cairo_svg_surface_emit_transform (output, " transform", &p2u);
+ _cairo_svg_surface_emit_transform (output, " transform", &p2u, parent_matrix);
if (extra_attributes)
_cairo_output_stream_printf (output, " %s", extra_attributes);
@@ -1198,16 +1207,17 @@ _cairo_svg_surface_emit_composite_pattern (cairo_output_stream_t *output,
cairo_svg_surface_t *surface,
cairo_surface_pattern_t *pattern,
int pattern_id,
+ const cairo_matrix_t *parent_matrix,
const char *extra_attributes)
{
if (_cairo_surface_is_meta (pattern->surface)) {
return _cairo_svg_surface_emit_composite_meta_pattern (output, surface, pattern,
- pattern_id, extra_attributes);
+ pattern_id, parent_matrix, extra_attributes);
}
return _cairo_svg_surface_emit_composite_image_pattern (output, surface, pattern,
- pattern_id, extra_attributes);
+ pattern_id, parent_matrix, extra_attributes);
}
static void
@@ -1253,7 +1263,8 @@ static cairo_status_t
_cairo_svg_surface_emit_surface_pattern (cairo_svg_surface_t *surface,
cairo_surface_pattern_t *pattern,
cairo_output_stream_t *style,
- cairo_bool_t is_stroke)
+ cairo_bool_t is_stroke,
+ const cairo_matrix_t *parent_matrix)
{
cairo_svg_document_t *document = surface->document;
cairo_status_t status;
@@ -1262,7 +1273,7 @@ _cairo_svg_surface_emit_surface_pattern (cairo_svg_surface_t *surface,
pattern_id = document->pattern_id++;
status = _cairo_svg_surface_emit_composite_pattern (document->xml_node_defs,
surface, pattern,
- pattern_id, NULL);
+ pattern_id, parent_matrix, NULL);
if (status)
return status;
@@ -1458,7 +1469,8 @@ static cairo_status_t
_cairo_svg_surface_emit_linear_pattern (cairo_svg_surface_t *surface,
cairo_linear_pattern_t *pattern,
cairo_output_stream_t *style,
- cairo_bool_t is_stroke)
+ cairo_bool_t is_stroke,
+ const cairo_matrix_t *parent_matrix)
{
cairo_svg_document_t *document = surface->document;
double x0, y0, x1, y1;
@@ -1483,7 +1495,7 @@ _cairo_svg_surface_emit_linear_pattern (cairo_svg_surface_t *surface,
x0, y0, x1, y1);
_cairo_svg_surface_emit_pattern_extend (document->xml_node_defs, &pattern->base.base),
- _cairo_svg_surface_emit_transform (document->xml_node_defs, "gradientTransform", &p2u);
+ _cairo_svg_surface_emit_transform (document->xml_node_defs, "gradientTransform", &p2u, parent_matrix);
_cairo_output_stream_printf (document->xml_node_defs, ">\n");
status = _cairo_svg_surface_emit_pattern_stops (document->xml_node_defs,
@@ -1509,7 +1521,8 @@ static cairo_status_t
_cairo_svg_surface_emit_radial_pattern (cairo_svg_surface_t *surface,
cairo_radial_pattern_t *pattern,
cairo_output_stream_t *style,
- cairo_bool_t is_stroke)
+ cairo_bool_t is_stroke,
+ const cairo_matrix_t *parent_matrix)
{
cairo_svg_document_t *document = surface->document;
cairo_matrix_t p2u;
@@ -1560,7 +1573,7 @@ _cairo_svg_surface_emit_radial_pattern (cairo_svg_surface_t *surface,
document->radial_pattern_id,
x1, y1,
x1, y1, r1);
- _cairo_svg_surface_emit_transform (document->xml_node_defs, "gradientTransform", &p2u);
+ _cairo_svg_surface_emit_transform (document->xml_node_defs, "gradientTransform", &p2u, parent_matrix);
_cairo_output_stream_printf (document->xml_node_defs, ">\n");
if (extend == CAIRO_EXTEND_NONE || n_stops < 1)
@@ -1644,7 +1657,7 @@ _cairo_svg_surface_emit_radial_pattern (cairo_svg_surface_t *surface,
_cairo_output_stream_printf (document->xml_node_defs, "spreadMethod=\"repeat\" ");
else
_cairo_svg_surface_emit_pattern_extend (document->xml_node_defs, &pattern->base.base);
- _cairo_svg_surface_emit_transform (document->xml_node_defs, "gradientTransform", &p2u);
+ _cairo_svg_surface_emit_transform (document->xml_node_defs, "gradientTransform", &p2u, parent_matrix);
_cairo_output_stream_printf (document->xml_node_defs, ">\n");
/* To support cairo's EXTEND_NONE, (for which SVG has no similar
@@ -1693,20 +1706,25 @@ static cairo_status_t
_cairo_svg_surface_emit_pattern (cairo_svg_surface_t *surface,
cairo_pattern_t *pattern,
cairo_output_stream_t *output,
- cairo_bool_t is_stroke)
+ cairo_bool_t is_stroke,
+ const cairo_matrix_t *parent_matrix)
{
switch (pattern->type) {
case CAIRO_PATTERN_TYPE_SOLID:
- return _cairo_svg_surface_emit_solid_pattern (surface, (cairo_solid_pattern_t *) pattern, output, is_stroke);
+ return _cairo_svg_surface_emit_solid_pattern (surface, (cairo_solid_pattern_t *) pattern,
+ output, is_stroke);
case CAIRO_PATTERN_TYPE_SURFACE:
- return _cairo_svg_surface_emit_surface_pattern (surface, (cairo_surface_pattern_t *) pattern, output, is_stroke);
+ return _cairo_svg_surface_emit_surface_pattern (surface, (cairo_surface_pattern_t *) pattern,
+ output, is_stroke, parent_matrix);
case CAIRO_PATTERN_TYPE_LINEAR:
- return _cairo_svg_surface_emit_linear_pattern (surface, (cairo_linear_pattern_t *) pattern, output, is_stroke);
+ return _cairo_svg_surface_emit_linear_pattern (surface, (cairo_linear_pattern_t *) pattern,
+ output, is_stroke, parent_matrix);
case CAIRO_PATTERN_TYPE_RADIAL:
- return _cairo_svg_surface_emit_radial_pattern (surface, (cairo_radial_pattern_t *) pattern, output, is_stroke);
+ return _cairo_svg_surface_emit_radial_pattern (surface, (cairo_radial_pattern_t *) pattern,
+ output, is_stroke, parent_matrix);
}
return _cairo_error (CAIRO_STATUS_PATTERN_TYPE_MISMATCH);
}
@@ -1716,14 +1734,15 @@ _cairo_svg_surface_emit_fill_style (cairo_output_stream_t *output,
cairo_svg_surface_t *surface,
cairo_operator_t op,
cairo_pattern_t *source,
- cairo_fill_rule_t fill_rule)
+ cairo_fill_rule_t fill_rule,
+ cairo_matrix_t *parent_matrix)
{
_cairo_output_stream_printf (output,
"fill-rule: %s; ",
fill_rule == CAIRO_FILL_RULE_EVEN_ODD ?
"evenodd" : "nonzero");
_cairo_svg_surface_emit_operator (output, surface, op);
- return _cairo_svg_surface_emit_pattern (surface, source, output, FALSE);
+ return _cairo_svg_surface_emit_pattern (surface, source, output, FALSE, parent_matrix);
}
static cairo_status_t
@@ -1731,7 +1750,8 @@ _cairo_svg_surface_emit_stroke_style (cairo_output_stream_t *output,
cairo_svg_surface_t *surface,
cairo_operator_t op,
cairo_pattern_t *source,
- cairo_stroke_style_t *stroke_style)
+ cairo_stroke_style_t *stroke_style,
+ cairo_matrix_t *parent_matrix)
{
cairo_status_t status;
const char *line_cap, *line_join;
@@ -1773,7 +1793,7 @@ _cairo_svg_surface_emit_stroke_style (cairo_output_stream_t *output,
line_cap,
line_join);
- status = _cairo_svg_surface_emit_pattern (surface, source, output, TRUE);
+ status = _cairo_svg_surface_emit_pattern (surface, source, output, TRUE, parent_matrix);
if (status)
return status;
@@ -1823,11 +1843,13 @@ _cairo_svg_surface_fill_stroke (void *abstract_surface,
cairo_status_t status;
_cairo_output_stream_printf (surface->xml_node, "<path style=\"");
- status = _cairo_svg_surface_emit_fill_style (surface->xml_node, surface, fill_op, fill_source, fill_rule);
+ status = _cairo_svg_surface_emit_fill_style (surface->xml_node, surface, fill_op,
+ fill_source, fill_rule, stroke_ctm_inverse);
if (status)
return status;
- status = _cairo_svg_surface_emit_stroke_style (surface->xml_node, surface, stroke_op, stroke_source, stroke_style);
+ status = _cairo_svg_surface_emit_stroke_style (surface->xml_node, surface, stroke_op,
+ stroke_source, stroke_style, stroke_ctm_inverse);
if (status)
return status;
@@ -1837,7 +1859,7 @@ _cairo_svg_surface_fill_stroke (void *abstract_surface,
if (status)
return status;
- _cairo_svg_surface_emit_transform (surface->xml_node, " transform", stroke_ctm);
+ _cairo_svg_surface_emit_transform (surface->xml_node, " transform", stroke_ctm, NULL);
_cairo_output_stream_printf (surface->xml_node, "/>\n");
return CAIRO_STATUS_SUCCESS;
@@ -1861,7 +1883,7 @@ _cairo_svg_surface_fill (void *abstract_surface,
assert (_cairo_svg_surface_operation_supported (surface, op, source));
_cairo_output_stream_printf (surface->xml_node, "<path style=\" stroke:none;");
- status = _cairo_svg_surface_emit_fill_style (surface->xml_node, surface, op, source, fill_rule);
+ status = _cairo_svg_surface_emit_fill_style (surface->xml_node, surface, op, source, fill_rule, NULL);
if (status)
return status;
@@ -1910,6 +1932,7 @@ _cairo_svg_surface_emit_paint (cairo_output_stream_t *output,
surface,
(cairo_surface_pattern_t *) source,
invalid_pattern_id,
+ NULL,
extra_attributes);
_cairo_output_stream_printf (output,
@@ -1918,7 +1941,7 @@ _cairo_svg_surface_emit_paint (cairo_output_stream_t *output,
"style=\"",
surface->width, surface->height);
_cairo_svg_surface_emit_operator (output, surface, op);
- status = _cairo_svg_surface_emit_pattern (surface, source, output, FALSE);
+ status = _cairo_svg_surface_emit_pattern (surface, source, output, FALSE, NULL);
if (status)
return status;
@@ -2083,14 +2106,15 @@ _cairo_svg_surface_stroke (void *abstract_dst,
assert (_cairo_svg_surface_operation_supported (surface, op, source));
_cairo_output_stream_printf (surface->xml_node, "<path style=\"fill: none; ");
- status = _cairo_svg_surface_emit_stroke_style (surface->xml_node, surface, op, source, stroke_style);
+ status = _cairo_svg_surface_emit_stroke_style (surface->xml_node, surface, op,
+ source, stroke_style, ctm_inverse);
_cairo_output_stream_printf (surface->xml_node, "\" ");
status = _cairo_svg_surface_emit_path (surface->xml_node, path, ctm_inverse);
if (status)
return status;
- _cairo_svg_surface_emit_transform (surface->xml_node, " transform", ctm);
+ _cairo_svg_surface_emit_transform (surface->xml_node, " transform", ctm, NULL);
_cairo_output_stream_printf (surface->xml_node, "/>\n");
return CAIRO_STATUS_SUCCESS;
@@ -2127,7 +2151,7 @@ _cairo_svg_surface_show_glyphs (void *abstract_surface,
_cairo_output_stream_printf (surface->xml_node, "<g style=\"");
status = _cairo_svg_surface_emit_pattern (surface, pattern,
- surface->xml_node, FALSE);
+ surface->xml_node, FALSE, NULL);
if (status)
return status;
More information about the cairo-commit
mailing list