[librsvg] compute_effects_region(): Make into a method of NodeFilter
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg] compute_effects_region(): Make into a method of NodeFilter
- Date: Thu, 7 Feb 2019 22:26:32 +0000 (UTC)
commit 85ffed8b9096ea42fc7053d0cea51fc1d30e79bf
Author: Federico Mena Quintero <federico gnome org>
Date: Fri Jan 25 20:41:51 2019 -0600
compute_effects_region(): Make into a method of NodeFilter
The first argument of that function was "filter_node: &RsvgNode",
which was immediately turned into
let filter = filter_node.get_impl::<NodeFilter>().unwrap();
The function pulls out the filter's x/y/width/height and transforms
them, so it makes some sense that this functionality should be a
method of NodeFilter.
rsvg_internals/src/filters/context.rs | 71 +----------------------------------
rsvg_internals/src/filters/node.rs | 71 +++++++++++++++++++++++++++++++++++
2 files changed, 72 insertions(+), 70 deletions(-)
---
diff --git a/rsvg_internals/src/filters/context.rs b/rsvg_internals/src/filters/context.rs
index ab063d5e..0194c429 100644
--- a/rsvg_internals/src/filters/context.rs
+++ b/rsvg_internals/src/filters/context.rs
@@ -92,74 +92,6 @@ pub struct FilterContext {
paffine: cairo::Matrix,
}
-/// Computes and returns the filter effects region.
-fn compute_effects_region(
- filter_node: &RsvgNode,
- computed_from_target_node: &ComputedValues,
- draw_ctx: &mut DrawingCtx,
- affine: cairo::Matrix,
- width: f64,
- height: f64,
-) -> BoundingBox {
- // Filters use the properties of the target node.
- let values = computed_from_target_node;
-
- let filter = filter_node.get_impl::<NodeFilter>().unwrap();
-
- let mut bbox = BoundingBox::new(&cairo::Matrix::identity());
-
- // affine is set up in FilterContext::new() in such a way that for
- // filterunits == ObjectBoundingBox affine includes scaling to correct width, height and this
- // is why width and height are set to 1, 1 (and for filterunits == UserSpaceOnUse affine
- // doesn't include scaling because in this case the correct width, height already happens to be
- // the viewbox width, height).
- //
- // It's done this way because with ObjectBoundingBox, non-percentage values are supposed to
- // represent the fractions of the referenced node, and with width and height = 1, 1 this
- // works out exactly like that.
- let params = if filter.filterunits.get() == CoordUnits::ObjectBoundingBox {
- draw_ctx.push_view_box(1.0, 1.0)
- } else {
- draw_ctx.get_view_params()
- };
-
- // With filterunits == ObjectBoundingBox, lengths represent fractions or percentages of the
- // referencing node. No units are allowed (it's checked during attribute parsing).
- let rect = if filter.filterunits.get() == CoordUnits::ObjectBoundingBox {
- cairo::Rectangle {
- x: filter.x.get().get_unitless(),
- y: filter.y.get().get_unitless(),
- width: filter.width.get().get_unitless(),
- height: filter.height.get().get_unitless(),
- }
- } else {
- cairo::Rectangle {
- x: filter.x.get().normalize(values, ¶ms),
- y: filter.y.get().normalize(values, ¶ms),
- width: filter.width.get().normalize(values, ¶ms),
- height: filter.height.get().normalize(values, ¶ms),
- }
- };
-
- let other_bbox = BoundingBox::new(&affine).with_rect(Some(rect));
-
- // At this point all of the previous viewbox and matrix business gets converted to pixel
- // coordinates in the final surface, because bbox is created with an identity affine.
- bbox.insert(&other_bbox);
-
- // Finally, clip to the width and height of our surface.
- let rect = cairo::Rectangle {
- x: 0f64,
- y: 0f64,
- width,
- height,
- };
- let other_bbox = BoundingBox::new(&cairo::Matrix::identity()).with_rect(Some(rect));
- bbox.clip(&other_bbox);
-
- bbox
-}
-
impl FilterContext {
/// Creates a new `FilterContext`.
pub fn new(
@@ -222,8 +154,7 @@ impl FilterContext {
last_result: None,
previous_results: HashMap::new(),
background_surface: UnsafeCell::new(None),
- effects_region: compute_effects_region(
- filter_node,
+ effects_region: filter.compute_effects_region(
computed_from_node_being_filtered,
draw_ctx,
affine,
diff --git a/rsvg_internals/src/filters/node.rs b/rsvg_internals/src/filters/node.rs
index b30e710a..cc569eae 100644
--- a/rsvg_internals/src/filters/node.rs
+++ b/rsvg_internals/src/filters/node.rs
@@ -1,12 +1,17 @@
//! The <filter> node.
use std::cell::Cell;
+use cairo::{self, MatrixTrait};
+
use attributes::Attribute;
+use bbox::BoundingBox;
use coord_units::CoordUnits;
+use drawing_ctx::DrawingCtx;
use error::ValueErrorKind;
use length::{LengthHorizontal, LengthUnit, LengthVertical};
use node::{NodeResult, NodeTrait, RsvgNode};
use parsers::{Parse, ParseError, ParseValue};
+use properties::ComputedValues;
use property_bag::PropertyBag;
/// The <filter> node.
@@ -32,6 +37,72 @@ impl NodeFilter {
primitiveunits: Cell::new(CoordUnits::UserSpaceOnUse),
}
}
+
+ /// Computes and returns the filter effects region.
+ pub fn compute_effects_region(
+ &self,
+ computed_from_target_node: &ComputedValues,
+ draw_ctx: &mut DrawingCtx,
+ affine: cairo::Matrix,
+ width: f64,
+ height: f64,
+ ) -> BoundingBox {
+ // Filters use the properties of the target node.
+ let values = computed_from_target_node;
+
+ let mut bbox = BoundingBox::new(&cairo::Matrix::identity());
+
+ // affine is set up in FilterContext::new() in such a way that for
+ // filterunits == ObjectBoundingBox affine includes scaling to correct width, height and
+ // this is why width and height are set to 1, 1 (and for filterunits ==
+ // UserSpaceOnUse affine doesn't include scaling because in this case the correct
+ // width, height already happens to be the viewbox width, height).
+ //
+ // It's done this way because with ObjectBoundingBox, non-percentage values are supposed to
+ // represent the fractions of the referenced node, and with width and height = 1, 1 this
+ // works out exactly like that.
+ let params = if self.filterunits.get() == CoordUnits::ObjectBoundingBox {
+ draw_ctx.push_view_box(1.0, 1.0)
+ } else {
+ draw_ctx.get_view_params()
+ };
+
+ // With filterunits == ObjectBoundingBox, lengths represent fractions or percentages of the
+ // referencing node. No units are allowed (it's checked during attribute parsing).
+ let rect = if self.filterunits.get() == CoordUnits::ObjectBoundingBox {
+ cairo::Rectangle {
+ x: self.x.get().get_unitless(),
+ y: self.y.get().get_unitless(),
+ width: self.width.get().get_unitless(),
+ height: self.height.get().get_unitless(),
+ }
+ } else {
+ cairo::Rectangle {
+ x: self.x.get().normalize(values, ¶ms),
+ y: self.y.get().normalize(values, ¶ms),
+ width: self.width.get().normalize(values, ¶ms),
+ height: self.height.get().normalize(values, ¶ms),
+ }
+ };
+
+ let other_bbox = BoundingBox::new(&affine).with_rect(Some(rect));
+
+ // At this point all of the previous viewbox and matrix business gets converted to pixel
+ // coordinates in the final surface, because bbox is created with an identity affine.
+ bbox.insert(&other_bbox);
+
+ // Finally, clip to the width and height of our surface.
+ let rect = cairo::Rectangle {
+ x: 0f64,
+ y: 0f64,
+ width,
+ height,
+ };
+ let other_bbox = BoundingBox::new(&cairo::Matrix::identity()).with_rect(Some(rect));
+ bbox.clip(&other_bbox);
+
+ bbox
+ }
}
impl NodeTrait for NodeFilter {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]