[librsvg: 2/3] tile: move cairo code out of the tile filter
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg: 2/3] tile: move cairo code out of the tile filter
- Date: Thu, 9 Jan 2020 20:01:23 +0000 (UTC)
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]