From a3c3f6b89290b9e1d369784b69fb1f5b106fdeba Mon Sep 17 00:00:00 2001 From: RazrFalcon Date: Sat, 15 Dec 2018 16:42:40 +0200 Subject: Added RectExt::bbox_transform. --- src/backend_cairo/mask.rs | 2 +- src/backend_cairo/pattern.rs | 2 +- src/backend_qt/mask.rs | 2 +- src/backend_qt/pattern.rs | 2 +- src/backend_utils/filter.rs | 20 ++++++++++++-------- src/geom.rs | 30 ++++++++++++++++++++++++++++-- 6 files changed, 44 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/backend_cairo/mask.rs b/src/backend_cairo/mask.rs index 7b364f5..6a93dc9 100644 --- a/src/backend_cairo/mask.rs +++ b/src/backend_cairo/mask.rs @@ -30,7 +30,7 @@ pub fn apply( mask_cr.set_matrix(sub_cr.get_matrix()); let r = if mask.units == usvg::Units::ObjectBoundingBox { - mask.rect.transform(usvg::Transform::from_bbox(bbox)) + mask.rect.bbox_transform(bbox) } else { mask.rect }; diff --git a/src/backend_cairo/pattern.rs b/src/backend_cairo/pattern.rs index 9b81b5e..96a8b6a 100644 --- a/src/backend_cairo/pattern.rs +++ b/src/backend_cairo/pattern.rs @@ -24,7 +24,7 @@ pub fn apply( cr: &cairo::Context, ) { let r = if pattern.units == usvg::Units::ObjectBoundingBox { - pattern.rect.transform(usvg::Transform::from_bbox(bbox)) + pattern.rect.bbox_transform(bbox) } else { pattern.rect }; diff --git a/src/backend_qt/mask.rs b/src/backend_qt/mask.rs index febe82b..46d20d9 100644 --- a/src/backend_qt/mask.rs +++ b/src/backend_qt/mask.rs @@ -27,7 +27,7 @@ pub fn apply( mask_p.set_transform(&sub_p.get_transform()); let r = if mask.units == usvg::Units::ObjectBoundingBox { - mask.rect.transform(usvg::Transform::from_bbox(bbox)) + mask.rect.bbox_transform(bbox) } else { mask.rect }; diff --git a/src/backend_qt/pattern.rs b/src/backend_qt/pattern.rs index 2401cbf..f609e95 100644 --- a/src/backend_qt/pattern.rs +++ b/src/backend_qt/pattern.rs @@ -20,7 +20,7 @@ pub fn apply( brush: &mut qt::Brush, ) { let r = if pattern.units == usvg::Units::ObjectBoundingBox { - pattern.rect.transform(usvg::Transform::from_bbox(bbox)) + pattern.rect.bbox_transform(bbox) } else { pattern.rect }; diff --git a/src/backend_utils/filter.rs b/src/backend_utils/filter.rs index 11b850e..12f9366 100644 --- a/src/backend_utils/filter.rs +++ b/src/backend_utils/filter.rs @@ -610,12 +610,17 @@ fn calc_subregion( usvg::FilterKind::FeImage(..) => { // `feImage` uses the object bbox. if filter.primitive_units == usvg::Units::ObjectBoundingBox { - return Rect::new( - bbox.x + bbox.width * primitive.x.unwrap_or(0.0), - bbox.y + bbox.height * primitive.y.unwrap_or(0.0), - bbox.width * primitive.width.unwrap_or(1.0), - bbox.height * primitive.height.unwrap_or(1.0), - ).transform(*ts).to_screen_rect(); + // TODO: wrong + let ts_bbox = Rect::new(ts.e, ts.f, ts.a, ts.d); + + let r = Rect::new( + primitive.x.unwrap_or(0.0), + primitive.y.unwrap_or(0.0), + primitive.width.unwrap_or(1.0), + primitive.height.unwrap_or(1.0), + ); + + return r.bbox_transform(bbox).bbox_transform(ts_bbox).to_screen_rect(); } else { filter_region } @@ -631,9 +636,8 @@ fn calc_subregion( primitive.width.unwrap_or(1.0), primitive.height.unwrap_or(1.0), ); - let ts = usvg::Transform::from_bbox(subregion_bbox); - region.to_rect().transform(ts) + region.to_rect().bbox_transform(subregion_bbox) } else { let (dx, dy) = ts.get_translate(); let (sx, sy) = ts.get_scale(); diff --git a/src/geom.rs b/src/geom.rs index cccd26e..cf61bc9 100644 --- a/src/geom.rs +++ b/src/geom.rs @@ -97,12 +97,15 @@ fn size_scale(s1: ScreenSize, s2: ScreenSize, expand: bool) -> ScreenSize { pub trait RectExt { /// Creates a new `Rect` for bounding box calculation. /// - /// Shorthand for `Rect::from_xywh(f64::MAX, f64::MAX, 1.0, 1.0)`. + /// Shorthand for `Rect::new(f64::MAX, f64::MAX, 1.0, 1.0)`. fn new_bbox() -> Self; - /// Expands the `Rect` to the specified size. + /// Expands the `Rect` to the provided size. fn expand(&mut self, r: Rect); + /// Transforms the `Rect` using the provided `bbox`. + fn bbox_transform(&self, bbox: Rect) -> Self; + /// Returns rect's size in screen units. fn to_screen_size(&self) -> ScreenSize; @@ -132,6 +135,15 @@ impl RectExt for Rect { } } + fn bbox_transform(&self, bbox: Rect) -> Self { + let x = self.x * bbox.width + bbox.x; + let y = self.y * bbox.height + bbox.y; + let w = self.width * bbox.width; + let h = self.height * bbox.height; + + Self::new(x, y, w, h) + } + fn to_screen_size(&self) -> ScreenSize { self.size().to_screen_size() } @@ -245,3 +257,17 @@ impl From<(i32, i32, u32, u32)> for ScreenRect { fn f64_min(v1: f64, v2: f64) -> f64 { if v1 < v2 { v1 } else { v2 } } + + +#[cfg(test)] +mod tests { + use super::*; + use usvg::FuzzyEq; + + #[test] + fn bbox_transform_1() { + let r = Rect::new(10.0, 20.0, 30.0, 40.0); + assert!(r.bbox_transform(Rect::new(0.2, 0.3, 0.4, 0.5)) + .fuzzy_eq(&Rect::new(4.2, 10.3, 12.0, 20.0))); + } +} -- cgit v1.2.3