[cairo-commit] libsvg-cairo/src svg-cairo-internal.h, 1.18, 1.19 svg_cairo.c, 1.36, 1.37 svg_cairo_state.c, 1.13, 1.14

Carl Worth commit at pdx.freedesktop.org
Thu May 12 11:12:43 PDT 2005


Committed by: cworth

Update of /cvs/cairo/libsvg-cairo/src
In directory gabe:/tmp/cvs-serv17232/src

Modified Files:
	svg-cairo-internal.h svg_cairo.c svg_cairo_state.c 
Log Message:

        * src/svg-cairo-internal.h:
        * src/svg_cairo.c: (svg_cairo_create), (_svg_cairo_begin_group),
        (_svg_cairo_begin_element), (_svg_cairo_end_group),
        (_svg_cairo_quadratic_curve_to), (_svg_cairo_set_gradient),
        (_svg_cairo_set_pattern), (_svg_cairo_select_font),
        (_svg_cairo_transform), (_svg_cairo_render_ellipse),
        (_svg_cairo_render_image), (_svg_cairo_copy_cairo_state),
        (_svg_cairo_push_state), (_svg_cairo_pop_state),
        (_svg_cairo_arc_to):
        * src/svg_cairo_state.c: (_svg_cairo_state_init),
        (_svg_cairo_state_init_copy), (_svg_cairo_state_deinit): Port to
        latest cairo API changes. Cleanup implementation of group
        opacity. Re-enable group opacity now that cairo_paint_with_alpha
        exists. All thanks to Owen Taylor.


Index: svg-cairo-internal.h
===================================================================
RCS file: /cvs/cairo/libsvg-cairo/src/svg-cairo-internal.h,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -d -r1.18 -r1.19
--- svg-cairo-internal.h	26 Apr 2005 20:00:00 -0000	1.18
+++ svg-cairo-internal.h	12 May 2005 18:12:41 -0000	1.19
@@ -42,6 +42,7 @@
 
 typedef struct svg_cairo_state {
     cairo_surface_t *child_surface;
+    cairo_t *saved_cr;
 
     svg_color_t color;
 

Index: svg_cairo.c
===================================================================
RCS file: /cvs/cairo/libsvg-cairo/src/svg_cairo.c,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -d -r1.36 -r1.37
--- svg_cairo.c	2 May 2005 14:42:01 -0000	1.36
+++ svg_cairo.c	12 May 2005 18:12:41 -0000	1.37
@@ -192,7 +192,8 @@
 _cairo_status_to_svg_status (cairo_status_t xr_status);
 
 static svg_status_t
-_svg_cairo_push_state (svg_cairo_t *svg_cairo);
+_svg_cairo_push_state (svg_cairo_t     *svg_cairo,
+		       cairo_surface_t *child_surface);
 
 static svg_status_t
 _svg_cairo_pop_state (svg_cairo_t *svg_cairo);
@@ -266,7 +267,7 @@
     if (status)
 	return status;
 
-    _svg_cairo_push_state (*svg_cairo);
+    _svg_cairo_push_state (*svg_cairo, NULL);
 
     return SVG_CAIRO_STATUS_SUCCESS;
 }
@@ -375,27 +376,19 @@
 _svg_cairo_begin_group (void *closure, double opacity)
 {
     svg_cairo_t *svg_cairo = closure;
+    cairo_surface_t *child_surface = NULL;
 
     cairo_save (svg_cairo->cr);
 
     if (opacity != 1.0) {
-	cairo_matrix_t ctm;
-
-	svg_cairo->state->child_surface = cairo_surface_create_similar (cairo_current_target_surface (svg_cairo->cr),
-							    CAIRO_FORMAT_ARGB32,
-							    svg_cairo->state->viewport_width,
-							    svg_cairo->state->viewport_height);
-
-	/* We have to maintain the CTM over cairo_set_target_surface
-	 * which replaces it with an indentity matrix. This will all
-	 * change as cairo_set_target_surface will be removed and
-	 * cairo_begin_group will be added. */
-	cairo_get_matrix (svg_cairo->cr, &ctm);
-	cairo_set_target_surface (svg_cairo->cr, svg_cairo->state->child_surface);
-	cairo_set_matrix (svg_cairo->cr, &ctm);
+	child_surface = cairo_surface_create_similar (cairo_get_target (svg_cairo->cr),
+						      CAIRO_FORMAT_ARGB32,
+						      svg_cairo->state->viewport_width,
+						      svg_cairo->state->viewport_height);
+	svg_cairo->state->child_surface = child_surface;
     }
 
-    _svg_cairo_push_state (svg_cairo);
+    _svg_cairo_push_state (svg_cairo, child_surface);
 
     return _cairo_status_to_svg_status (cairo_status (svg_cairo->cr));
 }
@@ -409,7 +402,7 @@
 
     cairo_save (svg_cairo->cr);
 
-    _svg_cairo_push_state (svg_cairo);
+    _svg_cairo_push_state (svg_cairo, NULL);
 
     return _cairo_status_to_svg_status (cairo_status (svg_cairo->cr));
 }
@@ -437,12 +430,9 @@
 
     if (opacity != 1.0) {
 	cairo_save (svg_cairo->cr);
-	/* XXX: Need to use opacity here, but cairo doesn't provide
-	 * the right API right now. */
 	cairo_identity_matrix (svg_cairo->cr);
-	cairo_move_to (svg_cairo->cr, 0, 0);
-	cairo_show_surface (svg_cairo->cr, svg_cairo->state->child_surface,
-		       svg_cairo->state->viewport_width, svg_cairo->state->viewport_height);
+	cairo_set_source_surface (svg_cairo->cr, svg_cairo->state->child_surface, 0, 0);
+	cairo_paint_with_alpha (svg_cairo->cr, opacity);
 	cairo_restore (svg_cairo->cr);
 	cairo_surface_destroy (svg_cairo->state->child_surface);
 	svg_cairo->state->child_surface = NULL;
@@ -495,7 +485,7 @@
     svg_cairo_t *svg_cairo = closure;
     double x, y;
 
-    cairo_current_point (svg_cairo->cr, &x, &y);
+    cairo_get_current_point (svg_cairo->cr, &x, &y);
 
     cairo_curve_to (svg_cairo->cr,
 		    x  + 2.0/3.0 * (x1 - x),  y  + 2.0/3.0 * (y1 - y),
@@ -549,10 +539,10 @@
 {
     svg_gradient_stop_t *stop;
     cairo_pattern_t *pattern = NULL;
-    cairo_matrix_t *matrix, *gradient_matrix;
+    cairo_matrix_t matrix, gradient_matrix;
     int i;
 
-    matrix = cairo_matrix_create ();
+    cairo_matrix_init_identity (&matrix);
 
     switch (gradient->units) {
     case SVG_GRADIENT_UNITS_USER:
@@ -566,8 +556,8 @@
 	else
 	    cairo_stroke_extents (svg_cairo->cr, &x1, &y1, &x2, &y2);
 
-	cairo_matrix_translate (matrix, x1, y1);
-	cairo_matrix_scale (matrix, x2 - x1, y2 - y1);
+	cairo_matrix_translate (&matrix, x1, y1);
+	cairo_matrix_scale (&matrix, x2 - x1, y2 - y1);
 	svg_cairo->state->bbox = 1;
     } break;
     }
@@ -622,19 +612,16 @@
     
     cairo_pattern_set_filter (pattern, CAIRO_FILTER_BILINEAR);
 
-    gradient_matrix = cairo_matrix_create ();
-    cairo_matrix_set_affine (gradient_matrix,
-			     gradient->transform[0], gradient->transform[1],
-			     gradient->transform[2], gradient->transform[3],
-			     gradient->transform[4], gradient->transform[5]);
-    cairo_matrix_multiply (matrix, matrix, gradient_matrix);
-    cairo_matrix_destroy (gradient_matrix);
+    cairo_matrix_init (&gradient_matrix,
+		       gradient->transform[0], gradient->transform[1],
+		       gradient->transform[2], gradient->transform[3],
+		       gradient->transform[4], gradient->transform[5]);
+    cairo_matrix_multiply (&matrix, &matrix, &gradient_matrix);
     
-    cairo_matrix_invert (matrix);
-    cairo_pattern_set_matrix (pattern, matrix);
-    cairo_matrix_destroy (matrix);
+    cairo_matrix_invert (&matrix);
+    cairo_pattern_set_matrix (pattern, &matrix);
     
-    cairo_set_pattern (svg_cairo->cr, pattern);
+    cairo_set_source (svg_cairo->cr, pattern);
     cairo_pattern_destroy (pattern);
     svg_cairo->state->bbox = 0;
     
@@ -673,14 +660,14 @@
     cairo_new_path (svg_cairo->cr);
     cairo_save (svg_cairo->cr);
 
-    pattern_surface = cairo_surface_create_similar (cairo_current_target_surface (svg_cairo->cr),
+    pattern_surface = cairo_surface_create_similar (cairo_get_target (svg_cairo->cr),
 						    CAIRO_FORMAT_ARGB32,
 						    (int) (width_px + 0.5),
 						    (int) (height_px + 0.5));
 
-    cairo_set_target_surface (svg_cairo->cr, pattern_surface);
-
-    _svg_cairo_push_state (svg_cairo);
+    _svg_cairo_push_state (svg_cairo, pattern_surface);
+    cairo_identity_matrix (svg_cairo->cr);
+    
     svg_cairo->state->fill_paint.type = SVG_PAINT_TYPE_NONE;
     svg_cairo->state->stroke_paint.type = SVG_PAINT_TYPE_NONE;
     
@@ -802,8 +789,8 @@
 	break;
     }
 
-    cairo_select_font (svg_cairo->cr, family, slant, weight);
-    cairo_scale_font (svg_cairo->cr, svg_cairo->state->font_size);
+    cairo_select_font_face (svg_cairo->cr, family, slant, weight);
+    cairo_set_font_size (svg_cairo->cr, svg_cairo->state->font_size);
     svg_cairo->state->font_dirty = 0;
 
     return _cairo_status_to_svg_status (cairo_status (svg_cairo->cr));
@@ -1004,14 +991,10 @@
 		  double e, double f)
 {
     svg_cairo_t *svg_cairo = closure;
-    cairo_matrix_t *matrix;
-
-    matrix = cairo_matrix_create ();
-    cairo_matrix_set_affine (matrix, a, b, c, d, e, f);
-
-    cairo_concat_matrix (svg_cairo->cr, matrix);
+    cairo_matrix_t matrix;
 
-    cairo_matrix_destroy (matrix);
+    cairo_matrix_init (&matrix, a, b, c, d, e, f);
+    cairo_transform (svg_cairo->cr, &matrix);
 
     return _cairo_status_to_svg_status (cairo_status (svg_cairo->cr));    
 }
@@ -1089,7 +1072,7 @@
 		      svg_length_t *ry_len)
 {
     svg_cairo_t *svg_cairo = closure;
-    cairo_matrix_t *matrix;
+    cairo_matrix_t matrix;
 
     double cx, cy, rx, ry;
 
@@ -1098,8 +1081,7 @@
     _svg_cairo_length_to_pixel (svg_cairo, rx_len, &rx);
     _svg_cairo_length_to_pixel (svg_cairo, ry_len, &ry);
 
-    matrix = cairo_matrix_create ();
-    cairo_current_matrix (svg_cairo->cr, matrix);
+    cairo_get_matrix (svg_cairo->cr, &matrix);
 
     cairo_translate (svg_cairo->cr, cx, cy);
     cairo_scale (svg_cairo->cr, 1.0, ry / rx);
@@ -1107,8 +1089,7 @@
     cairo_arc (svg_cairo->cr, 0, 0, rx, 0, 2 * M_PI);
     cairo_close_path (svg_cairo->cr);
 
-    cairo_set_matrix (svg_cairo->cr, matrix);
-    cairo_matrix_destroy (matrix);
+    cairo_set_matrix (svg_cairo->cr, &matrix);
 
      _svg_cairo_render_path (svg_cairo);
 
@@ -1242,20 +1223,14 @@
     _svg_cairo_length_to_pixel (svg_cairo, width_len, &width);
     _svg_cairo_length_to_pixel (svg_cairo, height_len, &height);
 
-    surface = cairo_surface_create_for_image ((unsigned char *)data, CAIRO_FORMAT_ARGB32,
-					      data_width, data_height, data_width *4);
-    cairo_move_to (svg_cairo->cr, x, y);
+    surface = cairo_image_surface_create_for_data ((unsigned char *)data, CAIRO_FORMAT_ARGB32,
+						   data_width, data_height, data_width *4);
+    cairo_translate (svg_cairo->cr, x, y);
     cairo_scale (svg_cairo->cr, width / data_width, height / data_height);
-    /* XXX: Cairo is currently lacking the API we need here to paint
-     * an image with some translucence. */
-#if 0
-    cairo_set_alpha (svg_cairo->cr, svg_cairo->state->opacity);
-#endif
-
-    cairo_show_surface (svg_cairo->cr,
-			surface,
-			data_width, data_height);
 
+    cairo_set_source_surface (svg_cairo->cr, surface, 0, 0);
+    cairo_paint_with_alpha (svg_cairo->cr, svg_cairo->state->opacity);
+    
     cairo_surface_destroy (surface);
 
     cairo_restore (svg_cairo->cr);
@@ -1275,8 +1250,36 @@
     }
 }
 
+static void
+_svg_cairo_copy_cairo_state (svg_cairo_t *svg_cairo,
+			     cairo_t     *old_cr,
+			     cairo_t     *new_cr)
+{
+    cairo_matrix_t ctm;
+    
+    cairo_get_matrix (old_cr, &ctm);
+    cairo_set_matrix (new_cr, &ctm);
+
+    /* For simplicity copy all the state, some of these aren't needed,
+     * since we don't change them.
+     */
+    cairo_set_operator (new_cr, cairo_get_operator (old_cr));
+    cairo_set_source (new_cr, cairo_get_source (old_cr));
+    cairo_set_tolerance (new_cr, cairo_get_tolerance (old_cr));
+    cairo_set_fill_rule (new_cr, cairo_get_fill_rule (old_cr));
+    cairo_set_line_width (new_cr, cairo_get_line_width (old_cr));
+    cairo_set_line_cap (new_cr, cairo_get_line_cap (old_cr));
+    cairo_set_line_join (new_cr, cairo_get_line_join (old_cr));
+    cairo_set_miter_limit (new_cr, cairo_get_miter_limit (old_cr));
+
+    /* There is no cairo_get_dash, but we already have a copy ourselves */
+    cairo_set_dash (new_cr,
+		    svg_cairo->state->dash, svg_cairo->state->num_dashes, svg_cairo->state->dash_offset);
+}
+
 static svg_status_t
-_svg_cairo_push_state (svg_cairo_t *svg_cairo)
+_svg_cairo_push_state (svg_cairo_t     *svg_cairo,
+		       cairo_surface_t *child_surface)
 {
     if (!svg_cairo->state)
     {
@@ -1285,7 +1288,22 @@
 	svg_cairo->state->viewport_height = svg_cairo->viewport_height;
     }
     else
+    {
+	if (child_surface)
+	{
+	    cairo_t *new_cr = cairo_create (child_surface);
+	    if (!new_cr)
+		return SVG_STATUS_NO_MEMORY;
+	    
+	    svg_cairo->state->saved_cr = svg_cairo->cr;
+	    svg_cairo->cr = new_cr;
+	    
+	    _svg_cairo_copy_cairo_state (svg_cairo, svg_cairo->state->saved_cr, svg_cairo->cr);
+	}
 	svg_cairo->state = _svg_cairo_state_push (svg_cairo->state);
+    }
+
+    
     if (svg_cairo->state == NULL)
 	return SVG_STATUS_NO_MEMORY;
 
@@ -1297,6 +1315,12 @@
 {
     svg_cairo->state = _svg_cairo_state_pop (svg_cairo->state);
 
+    if (svg_cairo->state && svg_cairo->state->saved_cr) {
+	cairo_destroy (svg_cairo->cr);
+	svg_cairo->cr = svg_cairo->state->saved_cr;
+	svg_cairo->state->saved_cr = NULL;
+    }
+
     return SVG_STATUS_SUCCESS;
 }
 
@@ -1502,7 +1526,7 @@
     rx = fabs (rx);
     ry = fabs (ry);
 
-    cairo_current_point (svg_cairo->cr, &curx, &cury);
+    cairo_get_current_point (svg_cairo->cr, &curx, &cury);
 
     sin_th = sin (x_axis_rotation * (M_PI / 180.0));
     cos_th = cos (x_axis_rotation * (M_PI / 180.0));

Index: svg_cairo_state.c
===================================================================
RCS file: /cvs/cairo/libsvg-cairo/src/svg_cairo_state.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- svg_cairo_state.c	26 Apr 2005 20:00:00 -0000	1.13
+++ svg_cairo_state.c	12 May 2005 18:12:41 -0000	1.14
@@ -46,6 +46,7 @@
     state->stroke_opacity;
     */
     state->child_surface = NULL;
+    state->saved_cr = NULL;
 
     state->font_family = strdup (SVG_CAIRO_FONT_FAMILY_DEFAULT);
     if (state->font_family == NULL)
@@ -81,8 +82,9 @@
 
     *state = *other;
 
-    /* We don't need our own child_surface at this point. */
+    /* We don't need our own child_surface or saved cr at this point. */
     state->child_surface = NULL;
+    state->saved_cr = NULL;
 
     if (other->font_family)
 	state->font_family = strdup ((char *) other->font_family);
@@ -107,7 +109,12 @@
 	cairo_surface_destroy(state->child_surface);
 	state->child_surface = NULL;
     }
-    
+
+    if (state->saved_cr) {
+	cairo_destroy(state->saved_cr);
+	state->saved_cr = NULL;
+    }
+
     if (state->font_family) {
 	free (state->font_family);
 	state->font_family = NULL;




More information about the cairo-commit mailing list