[librsvg: 2/8] DrawingCtx.nested() - replaces push_cairo_context / pop_cairo_context




commit e3bb911b2cd860e4e4671c87ea9712913bb35d26
Author: Federico Mena Quintero <federico gnome org>
Date:   Wed May 5 19:38:34 2021 -0500

    DrawingCtx.nested() - replaces push_cairo_context / pop_cairo_context
    
    The cr_stack is just used to keep a stack of surfaces for compositing
    and their transforms (for compositing in get_snapshot(), used by the
    filters code).
    
    In reality, push_cairo_context / pop_cairo_context were used as a way
    to paint to another cr, that comes from another surface.
    
    Now, we can create a "nested" DrawingCtx with respect to the other cr.
    Maybe this will let us unify DrawingCtx / surface / cr creation.

 src/drawing_ctx.rs | 90 +++++++++++++++++++++++++++++++-----------------------
 1 file changed, 52 insertions(+), 38 deletions(-)
---
diff --git a/src/drawing_ctx.rs b/src/drawing_ctx.rs
index 640d880f..190115e5 100644
--- a/src/drawing_ctx.rs
+++ b/src/drawing_ctx.rs
@@ -243,6 +243,12 @@ impl Drop for SavedCr<'_> {
     }
 }
 
+impl Drop for DrawingCtx {
+    fn drop(&mut self) {
+        self.cr_stack.borrow_mut().pop();
+    }
+}
+
 impl DrawingCtx {
     fn new(
         cr: &cairo::Context,
@@ -270,6 +276,23 @@ impl DrawingCtx {
         }
     }
 
+    fn nested(&self, cr: cairo::Context) -> DrawingCtx {
+        let cr_stack = self.cr_stack.clone();
+
+        cr_stack.borrow_mut().push(self.cr.clone());
+
+        DrawingCtx {
+            initial_viewport: self.initial_viewport,
+            dpi: self.dpi,
+            cr_stack,
+            cr,
+            viewport_stack: self.viewport_stack.clone(),
+            drawsub_stack: Vec::new(),
+            measuring: self.measuring,
+            testing: self.testing,
+        }
+    }
+
     pub fn toplevel_viewport(&self) -> Rect {
         *self.initial_viewport.vbox
     }
@@ -302,17 +325,6 @@ impl DrawingCtx {
         res
     }
 
-    // Temporary hack while we unify surface/cr/affine creation
-    fn push_cairo_context(&mut self, cr: cairo::Context) {
-        self.cr_stack.borrow_mut().push(self.cr.clone());
-        self.cr = cr;
-    }
-
-    // Temporary hack while we unify surface/cr/affine creation
-    fn pop_cairo_context(&mut self) {
-        self.cr = self.cr_stack.borrow_mut().pop().unwrap();
-    }
-
     fn size_for_temporary_surface(&self) -> (i32, i32) {
         let rect = self.toplevel_viewport();
 
@@ -565,9 +577,9 @@ impl DrawingCtx {
 
             let _params = self.push_coord_units(mask.get_content_units());
 
-            self.push_cairo_context(mask_cr);
+            let mut mask_draw_ctx = self.nested(mask_cr);
 
-            let res = self.with_discrete_layer(
+            let res = mask_draw_ctx.with_discrete_layer(
                 mask_node,
                 acquired_nodes,
                 values,
@@ -575,8 +587,6 @@ impl DrawingCtx {
                 &mut |an, dc| mask_node.draw_children(an, &cascaded, dc, false),
             );
 
-            self.pop_cairo_context();
-
             res?;
         }
 
@@ -667,36 +677,40 @@ impl DrawingCtx {
 
                 cr.set_matrix(affines.for_temporary_surface.into());
 
-                saved_cr.draw_ctx.push_cairo_context(cr);
-
-                // Draw!
+                let node_name = format!("{}", node);
 
-                let mut res = draw_fn(acquired_nodes, saved_cr.draw_ctx);
+                let (source_surface, mut res, bbox) = {
+                    let mut temporary_draw_ctx = saved_cr.draw_ctx.nested(cr);
 
-                let bbox = if let Ok(ref bbox) = res {
-                    *bbox
-                } else {
-                    BoundingBox::new().with_transform(affines.for_temporary_surface)
-                };
+                    // Draw!
 
-                // Filter
+                    let res = draw_fn(acquired_nodes, &mut temporary_draw_ctx);
 
-                let node_name = format!("{}", node);
+                    let bbox = if let Ok(ref bbox) = res {
+                        *bbox
+                    } else {
+                        BoundingBox::new().with_transform(affines.for_temporary_surface)
+                    };
 
-                let surface_to_filter = SharedImageSurface::copy_from_surface(
-                    &cairo::ImageSurface::try_from(saved_cr.draw_ctx.cr.get_target()).unwrap(),
-                )?;
+                    // Filter
 
-                let source_surface = saved_cr.draw_ctx.run_filters(
-                    surface_to_filter,
-                    &filters,
-                    acquired_nodes,
-                    &node_name,
-                    values,
-                    bbox,
-                )?;
+                    let surface_to_filter = SharedImageSurface::copy_from_surface(
+                        &cairo::ImageSurface::try_from(temporary_draw_ctx.cr.get_target()).unwrap(),
+                    )?;
 
-                saved_cr.draw_ctx.pop_cairo_context();
+                    (
+                        temporary_draw_ctx.run_filters(
+                            surface_to_filter,
+                            &filters,
+                            acquired_nodes,
+                            &node_name,
+                            values,
+                            bbox,
+                        )?,
+                        res,
+                        bbox,
+                    )
+                };
 
                 // Set temporary surface as source
 


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