librsvg r1139 - trunk



Author: doml
Date: Sat Jan 19 16:47:05 2008
New Revision: 1139
URL: http://svn.gnome.org/viewvc/librsvg?rev=1139&view=rev

Log:
2008-01-19  Bertram Felgenhauer <bertram felgenhauer googlemail com>

	* Bug 500787 - translation gets ignored when rendering an svg 
with cairo in the context of a cairo_push_group()



Modified:
   trunk/ChangeLog
   trunk/rsvg-cairo-clip.c
   trunk/rsvg-cairo-draw.c
   trunk/rsvg-cairo-render.c
   trunk/rsvg-cairo-render.h

Modified: trunk/rsvg-cairo-clip.c
==============================================================================
--- trunk/rsvg-cairo-clip.c	(original)
+++ trunk/rsvg-cairo-clip.c	Sat Jan 19 16:47:05 2008
@@ -41,18 +41,21 @@
 struct RsvgCairoClipRender {
     RsvgRender super;
     cairo_t *cr;
+    RsvgCairoRender *parent;
 };
 
 static void
-rsvg_cairo_clip_apply_affine (cairo_t *cr, const double affine[6])
+rsvg_cairo_clip_apply_affine (RsvgCairoClipRender *render, const double affine[6])
 {
 	cairo_matrix_t matrix;
+	gboolean nest = render->cr != render->parent->initial_cr;
 
 	cairo_matrix_init (&matrix,
 					   affine[0], affine[1],
 					   affine[2], affine[3],
-					   affine[4], affine[5]);
-	cairo_set_matrix (cr, &matrix);
+					   affine[4] + (nest ? 0 : render->parent->offset_x),
+					   affine[5] + (nest ? 0 : render->parent->offset_y));
+	cairo_set_matrix (render->cr, &matrix);
 }
 
 static void
@@ -62,14 +65,11 @@
 	RsvgState *state = rsvg_state_current (ctx);
     cairo_t *cr;
     RsvgBpath *bpath;
-	cairo_matrix_t save;
     int i;
 
     cr = render->cr;
 
-	cairo_get_matrix (cr, &save);
-
-	rsvg_cairo_clip_apply_affine (cr, state->affine);
+	rsvg_cairo_clip_apply_affine (render, state->affine);
 
     if (rsvg_state_current (ctx)->clip_rule == FILL_RULE_EVENODD)
         cairo_set_fill_rule (((RsvgCairoRender *) ctx->render)->cr, CAIRO_FILL_RULE_EVEN_ODD);
@@ -96,7 +96,6 @@
             break;
         }
     }
-	cairo_set_matrix (cr, &save);
 }
 
 static void
@@ -130,7 +129,7 @@
 }
 
 static RsvgRender *
-rsvg_cairo_clip_render_new (cairo_t * cr)
+rsvg_cairo_clip_render_new (cairo_t * cr, RsvgCairoRender *parent)
 {
     RsvgCairoClipRender *cairo_render = g_new0 (RsvgCairoClipRender, 1);
 
@@ -142,6 +141,7 @@
     cairo_render->super.add_clipping_rect = rsvg_cairo_clip_add_clipping_rect;
     cairo_render->super.get_image_of_node = NULL;
     cairo_render->cr = cr;
+    cairo_render->parent = parent;
 
     return &cairo_render->super;
 }
@@ -152,7 +152,7 @@
     RsvgCairoRender *save = (RsvgCairoRender *) ctx->render;
     double affinesave[6];
     int i;
-    ctx->render = rsvg_cairo_clip_render_new (save->cr);
+    ctx->render = rsvg_cairo_clip_render_new (save->cr, save);
 
     /* Horribly dirty hack to have the bbox premultiplied to everything */
     if (clip->units == objectBoundingBox) {

Modified: trunk/rsvg-cairo-draw.c
==============================================================================
--- trunk/rsvg-cairo-draw.c	(original)
+++ trunk/rsvg-cairo-draw.c	Sat Jan 19 16:47:05 2008
@@ -417,6 +417,7 @@
         _rsvg_pop_view_box (ctx);
 }
 
+/* note: _set_source_rsvg_paint_server does not change cairo's CTM */
 static void
 _set_source_rsvg_paint_server (RsvgDrawingCtx * ctx,
                                guint32 current_color_rgb,
@@ -440,14 +441,17 @@
 }
 
 static void
-_set_rsvg_affine (cairo_t * cr, const double affine[6])
+_set_rsvg_affine (RsvgCairoRender * render, const double affine[6])
 {
+    cairo_t * cr = render->cr;
     cairo_matrix_t matrix;
+    gboolean nest = cr != render->initial_cr;
 
     cairo_matrix_init (&matrix,
                        affine[0], affine[1],
                        affine[2], affine[3],
-                       affine[4], affine[5]);
+                       affine[4] + (nest ? 0 : render->offset_x),
+                       affine[5] + (nest ? 0 : render->offset_y));
     cairo_set_matrix (cr, &matrix);
 }
 
@@ -471,11 +475,9 @@
     PangoRectangle logical;
     RsvgBbox bbox;
 
-    cairo_save (render->cr);
-
 	_rsvg_cairo_set_text_antialias (render->cr, state->text_rendering_type);
 
-    _set_rsvg_affine (render->cr, state->affine);
+    _set_rsvg_affine (render, state->affine);
     cairo_set_line_width (render->cr, _rsvg_css_normalize_length (&state->stroke_width, ctx, 'h'));
 
     pango_cairo_update_layout (render->cr, layout);
@@ -513,8 +515,6 @@
                                        bbox, rsvg_state_current (ctx)->current_color);
         cairo_stroke (render->cr);
     }
-
-    cairo_restore (render->cr);
 }
 
 void
@@ -540,11 +540,9 @@
 
     cr = render->cr;
 
-    cairo_save (cr);
-
 	_rsvg_cairo_set_shape_antialias (cr, state->shape_rendering_type);
 
-    _set_rsvg_affine (cr, state->affine);
+    _set_rsvg_affine (render, state->affine);
 
     cairo_set_line_width (cr, _rsvg_css_normalize_length (&state->stroke_width, ctx, 'h'));
     cairo_set_miter_limit (cr, state->miter_limit);
@@ -634,7 +632,6 @@
 
         cairo_stroke (cr);
     }
-    cairo_restore (cr);
 
     if (need_tmpbuf)
         rsvg_cairo_pop_discrete_layer (ctx);
@@ -670,8 +667,7 @@
     bbox.h = h;
     bbox.virgin = 0;
 
-    cairo_save (render->cr);
-    _set_rsvg_affine (render->cr, state->affine);
+    _set_rsvg_affine (render, state->affine);
     cairo_scale (render->cr, w / dwidth, h / dheight);
     pixbuf_x *= dwidth / w;
     pixbuf_y *= dheight / h;
@@ -763,8 +759,6 @@
     cairo_surface_destroy (surface);
 
     rsvg_bbox_insert (&render->bbox, &bbox);
-
-    cairo_restore (render->cr);
 }
 
 static void
@@ -779,6 +773,7 @@
     guint32 rowstride = width * 4, row, i;
     double affinesave[6];
     double sx, sy, sw, sh;
+    gboolean nest = cr != render->initial_cr;
 
     if (self->maskunits == objectBoundingBox)
         _rsvg_push_view_box (ctx, 1, 1);
@@ -845,7 +840,10 @@
 
     cairo_destroy (mask_cr);
 
-    cairo_mask_surface (cr, surface, 0, 0);
+    cairo_identity_matrix (cr);
+    cairo_mask_surface (cr, surface,
+                        nest ? 0 : render->offset_x,
+                        nest ? 0 : render->offset_y);
     cairo_surface_destroy (surface);
     g_free (pixels);
 }
@@ -948,9 +946,11 @@
     cairo_surface_destroy (surface);
 
     for (i = g_list_last (render->cr_stack); i != NULL; i = g_list_previous (i)) {
-        cairo_t *draw;
-        draw = i->data;
-        cairo_set_source_surface (cr, cairo_get_target (draw), 0, 0);
+        cairo_t *draw = i->data;
+        gboolean nest = draw != render->initial_cr;
+        cairo_set_source_surface (cr, cairo_get_target (draw),
+                                  nest ? 0 : -render->offset_x,
+                                  nest ? 0 : -render->offset_y);
         cairo_paint (cr);
     }
 
@@ -967,6 +967,7 @@
     GdkPixbuf *output = NULL;
     cairo_surface_t *surface = NULL;
     RsvgState *state = rsvg_state_current (ctx);
+    gboolean nest;
 
     if (rsvg_state_current (ctx)->clip_path_ref)
         if (((RsvgClipPath *) rsvg_state_current (ctx)->clip_path_ref)->units == objectBoundingBox)
@@ -999,7 +1000,11 @@
     render->cr = (cairo_t *) render->cr_stack->data;
     render->cr_stack = g_list_delete_link (render->cr_stack, render->cr_stack);
 
-    cairo_set_source_surface (render->cr, surface, 0, 0);
+    nest = render->cr != render->initial_cr;
+    cairo_identity_matrix (render->cr);
+    cairo_set_source_surface (render->cr, surface,
+                              nest ? 0 : render->offset_x,
+                              nest ? 0 : render->offset_y);
 
     if (lateclip)
         rsvg_cairo_clip (ctx, rsvg_state_current (ctx)->clip_path_ref, &render->bbox);
@@ -1040,15 +1045,11 @@
 {
     RsvgCairoRender *render = (RsvgCairoRender *) ctx->render;
     cairo_t *cr = render->cr;
-    cairo_matrix_t save;
 
-    cairo_get_matrix (cr, &save);
-    _set_rsvg_affine (cr, rsvg_state_current (ctx)->affine);
+    _set_rsvg_affine (render, rsvg_state_current (ctx)->affine);
 
     cairo_rectangle (cr, x, y, w, h);
     cairo_clip (cr);
-
-    cairo_set_matrix (cr, &save);
 }
 
 GdkPixbuf *

Modified: trunk/rsvg-cairo-render.c
==============================================================================
--- trunk/rsvg-cairo-render.c	(original)
+++ trunk/rsvg-cairo-render.c	Sat Jan 19 16:47:05 2008
@@ -65,6 +65,7 @@
     cairo_render->height = height;
     cairo_render->offset_x = 0;
     cairo_render->offset_y = 0;
+    cairo_render->initial_cr = cr;
     cairo_render->cr = cr;
     cairo_render->cr_stack = NULL;
     cairo_render->bb_stack = NULL;
@@ -176,8 +177,8 @@
     _rsvg_affine_multiply (state->affine, affine, state->affine);
 
     /* adjust transform so that the corner of the bounding box above is
-     * at (0,0) - we compensate for this in rsvg_handle_render_cairo_sub()
-     * below */
+     * at (0,0) - we compensate for this in _set_rsvg_affine() in
+     * rsvg-cairo-render.c and a few other places */
     state->affine[4] -= render->offset_x;
     state->affine[5] -= render->offset_y;
 
@@ -203,9 +204,6 @@
 {
     RsvgDrawingCtx *draw;
     RsvgNode *drawsub = NULL;
-    RsvgCairoRender *render;
-    cairo_surface_t *surface = cairo_get_target (cr);
-    double save_dx, save_dy;
 
     g_return_if_fail (handle != NULL);
 
@@ -226,20 +224,9 @@
 
     rsvg_state_push (draw);
     cairo_save (cr);
-    cairo_identity_matrix (cr);
-
-    /* adjust the underlying surface's device offset such that the
-     * bounding box from rsvg_cairo_new_drawing_ctx is placed correctly */
-    cairo_surface_get_device_offset (surface, &save_dx, &save_dy);
-    render = (RsvgCairoRender *) draw->render;
-    cairo_surface_set_device_offset (surface,
-                                     save_dx + render->offset_x,
-                                     save_dy + render->offset_y);
 
     rsvg_node_draw ((RsvgNode *) handle->priv->treebase, draw, 0);
 
-    cairo_surface_set_device_offset (surface, save_dx, save_dy);
-
     cairo_restore (cr);
     rsvg_state_pop (draw);
     rsvg_drawing_ctx_free (draw);

Modified: trunk/rsvg-cairo-render.h
==============================================================================
--- trunk/rsvg-cairo-render.h	(original)
+++ trunk/rsvg-cairo-render.h	Sat Jan 19 16:47:05 2008
@@ -37,6 +37,8 @@
     cairo_t *cr;
     double width;
     double height;
+
+    cairo_t *initial_cr;
     double offset_x;
     double offset_y;
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]