[librsvg: 7/10] rect: add translate and intersection for IRect



commit 36121848226c5033ac7e2702dfea343f63df69da
Author: Paolo Borelli <pborelli gnome org>
Date:   Sun Nov 24 19:40:54 2019 +0100

    rect: add translate and intersection for IRect
    
    Add the methods available in euclid.
    Use them in the offset filter.

 rsvg_internals/src/filters/offset.rs | 16 +++++-----------
 rsvg_internals/src/rect.rs           | 27 +++++++++++++++++++++++++++
 2 files changed, 32 insertions(+), 11 deletions(-)
---
diff --git a/rsvg_internals/src/filters/offset.rs b/rsvg_internals/src/filters/offset.rs
index d606a869..195eca66 100644
--- a/rsvg_internals/src/filters/offset.rs
+++ b/rsvg_internals/src/filters/offset.rs
@@ -6,9 +6,7 @@ use crate::error::AttributeResultExt;
 use crate::node::{NodeResult, NodeTrait, RsvgNode};
 use crate::parsers;
 use crate::property_bag::PropertyBag;
-use crate::rect::IRect;
 use crate::surface_utils::shared_surface::SharedImageSurface;
-use crate::util::clamp;
 
 use super::context::{FilterContext, FilterOutput, FilterResult};
 use super::{FilterEffect, FilterError, PrimitiveWithInput};
@@ -66,21 +64,17 @@ impl FilterEffect for FeOffset {
 
         let (ox, oy) = ctx.paffine().transform_distance(self.dx, self.dy);
 
-        // output_bounds contains all pixels within bounds,
-        // for which (x - ox) and (y - oy) also lie within bounds.
-        let output_bounds = IRect::new(
-            clamp(bounds.x0 + ox as i32, bounds.x0, bounds.x1),
-            clamp(bounds.y0 + oy as i32, bounds.y0, bounds.y1),
-            clamp(bounds.x1 + ox as i32, bounds.x0, bounds.x1),
-            clamp(bounds.y1 + oy as i32, bounds.y0, bounds.y1),
-        );
-
         let output_surface = ImageSurface::create(
             cairo::Format::ARgb32,
             ctx.source_graphic().width(),
             ctx.source_graphic().height(),
         )?;
 
+        // output_bounds contains all pixels within bounds,
+        // for which (x - ox) and (y - oy) also lie within bounds.
+        if let Some(output_bounds) = bounds
+            .translate((ox as i32, oy as i32))
+            .intersection(&bounds)
         {
             let cr = cairo::Context::new(&output_surface);
             let r = cairo::Rectangle::from(output_bounds);
diff --git a/rsvg_internals/src/rect.rs b/rsvg_internals/src/rect.rs
index 694b11ec..d2856a1d 100644
--- a/rsvg_internals/src/rect.rs
+++ b/rsvg_internals/src/rect.rs
@@ -176,6 +176,33 @@ impl IRect {
             y1: (f64::from(self.y1) * y).ceil() as i32,
         }
     }
+
+    /// Returns an `IRect` translated by the given amounts.
+    #[inline]
+    pub fn translate(&self, by: (i32, i32)) -> IRect {
+        IRect {
+            x0: self.x0 + by.0,
+            y0: self.y0 + by.1,
+            x1: self.x1 + by.0,
+            y1: self.y1 + by.1,
+        }
+    }
+
+    #[inline]
+    pub fn intersection(&self, rect: &Self) -> Option<IRect> {
+        let (x0, y0, x1, y1) = (
+            self.x0.max(rect.x0),
+            self.y0.max(rect.y0),
+            self.x1.min(rect.x1),
+            self.y1.min(rect.y1),
+        );
+
+        if x1 > x0 && y1 > y0 {
+            Some(IRect { x0, y0, x1, y1 })
+        } else {
+            None
+        }
+    }
 }
 
 impl From<cairo::Rectangle> for IRect {


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