[librsvg: 2/3] tile: move cairo code out of the tile filter



commit 18c63d8d2310a3b72578532a6fc610c04b7a498b
Author: Paolo Borelli <pborelli gnome org>
Date:   Tue Jan 7 19:50:19 2020 +0100

    tile: move cairo code out of the tile filter
    
    Factor out a tile and paint_repeated_image method on SharedImageSurface

 rsvg_internals/src/filters/tile.rs                 | 61 +++++-----------------
 rsvg_internals/src/surface_utils/shared_surface.rs | 48 +++++++++++++++++
 2 files changed, 60 insertions(+), 49 deletions(-)
---
diff --git a/rsvg_internals/src/filters/tile.rs b/rsvg_internals/src/filters/tile.rs
index 11362f46..06239ce2 100644
--- a/rsvg_internals/src/filters/tile.rs
+++ b/rsvg_internals/src/filters/tile.rs
@@ -1,7 +1,6 @@
 use crate::drawing_ctx::DrawingCtx;
 use crate::node::{NodeResult, NodeTrait, RsvgNode};
 use crate::property_bag::PropertyBag;
-use crate::surface_utils::shared_surface::SharedImageSurface;
 
 use super::context::{FilterContext, FilterInput, FilterOutput, FilterResult};
 use super::{FilterEffect, FilterError, PrimitiveWithInput};
@@ -41,62 +40,26 @@ impl FilterEffect for FeTile {
         // feTile doesn't consider its inputs in the filter primitive subregion calculation.
         let bounds = self.base.get_bounds(ctx).into_irect(draw_ctx);
 
-        let output_surface = match input {
-            FilterInput::StandardInput(surface) => surface,
+        let surface = match input {
+            FilterInput::StandardInput(input_surface) => input_surface,
             FilterInput::PrimitiveOutput(FilterOutput {
-                surface,
+                surface: input_surface,
                 bounds: input_bounds,
             }) => {
-                // Create a surface containing just the region to tile.
-                let bounded_input_surface = cairo::ImageSurface::create(
-                    cairo::Format::ARgb32,
-                    input_bounds.width(),
-                    input_bounds.height(),
-                )?;
-
-                {
-                    let cr = cairo::Context::new(&bounded_input_surface);
-                    surface.set_as_source_surface(
-                        &cr,
-                        f64::from(-input_bounds.x0),
-                        f64::from(-input_bounds.y0),
-                    );
-                    cr.paint();
-                }
-
-                // Make a pattern out of the tile region.
-                let ptn = cairo::SurfacePattern::create(&bounded_input_surface);
-                ptn.set_extend(cairo::Extend::Repeat);
-                let mut mat = cairo::Matrix::identity();
-                mat.translate(f64::from(-input_bounds.x0), f64::from(-input_bounds.y0));
-                ptn.set_matrix(mat);
-
-                let output_surface = cairo::ImageSurface::create(
-                    cairo::Format::ARgb32,
-                    ctx.source_graphic().width(),
-                    ctx.source_graphic().height(),
-                )?;
-
-                {
-                    let cr = cairo::Context::new(&output_surface);
-                    let r = cairo::Rectangle::from(bounds);
-                    cr.rectangle(r.x, r.y, r.width, r.height);
-                    cr.clip();
-
-                    cr.set_source(&ptn);
-                    cr.paint();
-                }
-
-                SharedImageSurface::new(output_surface, surface.surface_type())?
+                let tile_surface = input_surface.tile(input_bounds)?;
+
+                ctx.source_graphic().paint_image_tiled(
+                    bounds,
+                    &tile_surface,
+                    input_bounds.x0,
+                    input_bounds.y0,
+                )?
             }
         };
 
         Ok(FilterResult {
             name: self.base.result.clone(),
-            output: FilterOutput {
-                surface: output_surface,
-                bounds,
-            },
+            output: FilterOutput { surface, bounds },
         })
     }
 
diff --git a/rsvg_internals/src/surface_utils/shared_surface.rs 
b/rsvg_internals/src/surface_utils/shared_surface.rs
index 9b4abb0f..6332764f 100644
--- a/rsvg_internals/src/surface_utils/shared_surface.rs
+++ b/rsvg_internals/src/surface_utils/shared_surface.rs
@@ -1001,6 +1001,54 @@ impl SharedImageSurface {
         SharedImageSurface::new(output_surface, image.surface_type)
     }
 
+    /// Creates a new surface with the size and content specified in `bounds`
+    #[inline]
+    pub fn tile(&self, bounds: IRect) -> Result<SharedImageSurface, cairo::Status> {
+        let output_surface =
+            cairo::ImageSurface::create(cairo::Format::ARgb32, bounds.width(), bounds.height())?;
+
+        {
+            let cr = cairo::Context::new(&output_surface);
+            self.set_as_source_surface(&cr, f64::from(-bounds.x0), f64::from(-bounds.y0));
+            cr.paint();
+        }
+
+        SharedImageSurface::new(output_surface, self.surface_type)
+    }
+
+    /// Returns a new surface of the same size, with the contents of the specified
+    /// image repeated to fill the bounds and starting from the given position.
+    #[inline]
+    pub fn paint_image_tiled(
+        &self,
+        bounds: IRect,
+        image: &SharedImageSurface,
+        x: i32,
+        y: i32,
+    ) -> Result<SharedImageSurface, cairo::Status> {
+        let output_surface =
+            cairo::ImageSurface::create(cairo::Format::ARgb32, self.width, self.height)?;
+
+        {
+            let cr = cairo::Context::new(&output_surface);
+
+            let ptn = image.to_cairo_pattern();
+            ptn.set_extend(cairo::Extend::Repeat);
+            let mut mat = cairo::Matrix::identity();
+            mat.translate(f64::from(-x), f64::from(-y));
+            ptn.set_matrix(mat);
+
+            let r = cairo::Rectangle::from(bounds);
+            cr.rectangle(r.x, r.y, r.width, r.height);
+            cr.clip();
+
+            cr.set_source(&ptn);
+            cr.paint();
+        }
+
+        SharedImageSurface::new(output_surface, image.surface_type)
+    }
+
     /// Performs the combination of two input surfaces using Porter-Duff
     /// compositing operators
     ///


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