[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