[librsvg/librsvg-2.48] clip_to_node - Use a new function BoundingBox.rect_to_transform
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg/librsvg-2.48] clip_to_node - Use a new function BoundingBox.rect_to_transform
- Date: Thu, 30 Apr 2020 21:28:14 +0000 (UTC)
commit a12435fd60dcf5f5fcd9ca4997ada7fdc8ad5821
Author: Federico Mena Quintero <federico gnome org>
Date: Wed Apr 29 19:53:54 2020 -0500
clip_to_node - Use a new function BoundingBox.rect_to_transform
This checks the bbox.rect and the given CoordUnits, so that
ObjectBoundingBox with an empty bbox.rect will not produce an invalid
transform.
rsvg_internals/src/bbox.rs | 31 +++++++++++++++++++++++++++++++
rsvg_internals/src/drawing_ctx.rs | 38 +++++++++++---------------------------
2 files changed, 42 insertions(+), 27 deletions(-)
---
diff --git a/rsvg_internals/src/bbox.rs b/rsvg_internals/src/bbox.rs
index 311ebafc..46dba3a0 100644
--- a/rsvg_internals/src/bbox.rs
+++ b/rsvg_internals/src/bbox.rs
@@ -1,5 +1,6 @@
//! Bounding boxes that know their coordinate space.
+use crate::coord_units::CoordUnits;
use crate::rect::Rect;
use crate::transform::Transform;
@@ -69,6 +70,36 @@ impl BoundingBox {
pub fn ink_rect_is_empty(&self) -> bool {
self.ink_rect.map(|r| r.is_empty()).unwrap_or(true)
}
+
+ /// Creates a transform to map to the `self.rect`.
+ ///
+ /// This depends on a `CoordUnits` parameter. When this is
+ /// `CoordUnits::ObjectBoundingBox`, the bounding box must not be
+ /// empty, since the calling code would then not have a usable
+ /// size to work with. In that case, if the bbox is empty, this
+ /// function returns `Err(())`.
+ ///
+ /// Usually calling code can simply ignore the action it was about
+ /// to take if this function returns an error.
+ pub fn rect_to_transform(&self, units: CoordUnits) -> Result<Transform, ()> {
+ match units {
+ CoordUnits::UserSpaceOnUse => Ok(Transform::identity()),
+ CoordUnits::ObjectBoundingBox => {
+ if self.rect_is_empty() {
+ Err(())
+ } else {
+ let r = self.rect.as_ref().unwrap();
+ let t = Transform::new_unchecked(r.width(), 0.0, 0.0, r.height(), r.x0, r.y0);
+
+ if t.is_invertible() {
+ Ok(t)
+ } else {
+ Err(())
+ }
+ }
+ }
+ }
+ }
}
fn combine_rects(
diff --git a/rsvg_internals/src/drawing_ctx.rs b/rsvg_internals/src/drawing_ctx.rs
index 53467413..db6e30f0 100644
--- a/rsvg_internals/src/drawing_ctx.rs
+++ b/rsvg_internals/src/drawing_ctx.rs
@@ -334,33 +334,17 @@ impl DrawingCtx {
acquired_nodes: &mut AcquiredNodes,
bbox: &BoundingBox,
) -> Result<(), RenderingError> {
- if let Some(node) = clip_node {
- let units = node.borrow().get_impl::<ClipPath>().get_units();
+ if clip_node.is_none() {
+ return Ok(());
+ }
- if units == CoordUnits::ObjectBoundingBox && bbox.rect.is_none() {
- // The node being clipped is empty / doesn't have a
- // bounding box, so there's nothing to clip!
- return Ok(());
- }
+ let node = clip_node.as_ref().unwrap();
+ let units = node.borrow().get_impl::<ClipPath>().get_units();
+ if let Ok(transform) = bbox.rect_to_transform(units) {
let cascaded = CascadedValues::new_from_node(node);
- let transform = if units == CoordUnits::ObjectBoundingBox {
- let bbox_rect = bbox.rect.as_ref().unwrap();
-
- Some(Transform::new_unchecked(
- bbox_rect.width(),
- 0.0,
- 0.0,
- bbox_rect.height(),
- bbox_rect.x0,
- bbox_rect.y0,
- ))
- } else {
- Transform::identity()
- };
-
- self.with_saved_transform(transform, &mut |dc| {
+ self.with_saved_transform(Some(transform), &mut |dc| {
let cr = dc.get_cairo_context();
// here we don't push a layer because we are clipping
@@ -371,10 +355,10 @@ impl DrawingCtx {
res
})
.and_then(|_bbox|
- // Clipping paths do not contribute to bounding boxes (they should,
- // but we need Real Computational Geometry(tm), so ignore the
- // bbox from the clip path.
- Ok(()))
+ // Clipping paths do not contribute to bounding boxes (they should,
+ // but we need Real Computational Geometry(tm), so ignore the
+ // bbox from the clip path.
+ Ok(()))
} else {
Ok(())
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]