[librsvg/rect: 7/10] bbox: use Rect



commit 14d93548c1eee63a1f1a4b75e0526532c1a3d163
Author: Paolo Borelli <pborelli gnome org>
Date:   Sun Dec 8 15:28:44 2019 +0100

    bbox: use Rect

 rsvg_internals/src/bbox.rs            | 43 ++++++++++----------------------
 rsvg_internals/src/clip_path.rs       |  8 +++---
 rsvg_internals/src/drawing_ctx.rs     |  9 ++++---
 rsvg_internals/src/filter.rs          | 35 ++++++++++++--------------
 rsvg_internals/src/filters/bounds.rs  |  8 +++---
 rsvg_internals/src/filters/context.rs | 31 ++++++++++-------------
 rsvg_internals/src/gradient.rs        |  9 +++----
 rsvg_internals/src/handle.rs          | 35 +++++++++++++++-----------
 rsvg_internals/src/image.rs           |  9 +++----
 rsvg_internals/src/mask.rs            | 18 +++-----------
 rsvg_internals/src/pattern.rs         | 10 ++++----
 rsvg_internals/src/text.rs            | 47 ++++++++++++++++-------------------
 12 files changed, 113 insertions(+), 149 deletions(-)
---
diff --git a/rsvg_internals/src/bbox.rs b/rsvg_internals/src/bbox.rs
index d8bde22a..9f7b4a75 100644
--- a/rsvg_internals/src/bbox.rs
+++ b/rsvg_internals/src/bbox.rs
@@ -1,12 +1,12 @@
 use cairo;
 
-use crate::rect::RectangleExt;
+use crate::rect::{Rect, TransformRect};
 
 #[derive(Debug, Copy, Clone)]
 pub struct BoundingBox {
     pub affine: cairo::Matrix,
-    pub rect: Option<cairo::Rectangle>,     // without stroke
-    pub ink_rect: Option<cairo::Rectangle>, // with stroke
+    pub rect: Option<Rect>,     // without stroke
+    pub ink_rect: Option<Rect>, // with stroke
 }
 
 impl BoundingBox {
@@ -18,22 +18,14 @@ impl BoundingBox {
         }
     }
 
-    pub fn with_rect(self, rect: Option<cairo::Rectangle>) -> BoundingBox {
+    pub fn with_rect(self, rect: Option<Rect>) -> BoundingBox {
         BoundingBox { rect, ..self }
     }
 
-    pub fn with_ink_rect(self, ink_rect: Option<cairo::Rectangle>) -> BoundingBox {
+    pub fn with_ink_rect(self, ink_rect: Option<Rect>) -> BoundingBox {
         BoundingBox { ink_rect, ..self }
     }
 
-    pub fn with_extents(self, extents: (f64, f64, f64, f64)) -> BoundingBox {
-        self.with_rect(rect_from_extents(extents))
-    }
-
-    pub fn with_ink_extents(self, extents: (f64, f64, f64, f64)) -> BoundingBox {
-        self.with_ink_rect(rect_from_extents(extents))
-    }
-
     fn combine(&mut self, src: &BoundingBox, clip: bool) {
         if src.rect.is_none() && src.ink_rect.is_none() {
             return;
@@ -58,28 +50,19 @@ impl BoundingBox {
     }
 }
 
-fn rect_from_extents((x1, y1, x2, y2): (f64, f64, f64, f64)) -> Option<cairo::Rectangle> {
-    Some(cairo::Rectangle {
-        x: x1,
-        y: y1,
-        width: x2 - x1,
-        height: y2 - y1,
-    })
-}
-
 fn combine_rects(
-    r1: Option<cairo::Rectangle>,
-    r2: Option<cairo::Rectangle>,
+    r1: Option<Rect>,
+    r2: Option<Rect>,
     affine: &cairo::Matrix,
     clip: bool,
-) -> Option<cairo::Rectangle> {
+) -> Option<Rect> {
     match (r1, r2, clip) {
         (r1, None, _) => r1,
-        (None, Some(r2), _) => Some(r2.transform(&affine)),
-        (Some(r1), Some(r2), true) => r2
-            .transform(&affine)
+        (None, Some(r2), _) => Some(affine.transform_rect(&r2)),
+        (Some(r1), Some(r2), true) => affine
+            .transform_rect(&r2)
             .intersection(&r1)
-            .or_else(|| Some(cairo::Rectangle::new(0.0, 0.0, 0.0, 0.0))),
-        (Some(r1), Some(r2), false) => Some(r2.transform(&affine).union(&r1)),
+            .or_else(|| Some(Rect::default())),
+        (Some(r1), Some(r2), false) => Some(affine.transform_rect(&r2).union(&r1)),
     }
 }
diff --git a/rsvg_internals/src/clip_path.rs b/rsvg_internals/src/clip_path.rs
index 5dfd21a2..3d9225d3 100644
--- a/rsvg_internals/src/clip_path.rs
+++ b/rsvg_internals/src/clip_path.rs
@@ -43,12 +43,12 @@ impl ClipPath {
                     let bbox_rect = bbox.rect.as_ref().unwrap();
 
                     cr.transform(cairo::Matrix::new(
-                        bbox_rect.width,
+                        bbox_rect.width(),
                         0.0,
                         0.0,
-                        bbox_rect.height,
-                        bbox_rect.x,
-                        bbox_rect.y,
+                        bbox_rect.height(),
+                        bbox_rect.x0,
+                        bbox_rect.y0,
                     ))
                 }
 
diff --git a/rsvg_internals/src/drawing_ctx.rs b/rsvg_internals/src/drawing_ctx.rs
index 54fae97d..8961724e 100644
--- a/rsvg_internals/src/drawing_ctx.rs
+++ b/rsvg_internals/src/drawing_ctx.rs
@@ -964,19 +964,22 @@ fn compute_stroke_and_fill_box(cr: &cairo::Context, values: &ComputedValues) ->
     // paths for the icon's shape.  We need to be able to compute the bounding
     // rectangle's extents, even when it has no fill nor stroke.
 
-    let fb = BoundingBox::new(&affine).with_ink_extents(cr.fill_extents());
+    let (x0, y0, x1, y1) = cr.fill_extents();
+    let fb = BoundingBox::new(&affine).with_ink_rect(Some(Rect::new(x0, y0, x1, y1)));
     bbox.insert(&fb);
 
     // Bounding box for stroke
 
     if values.stroke.0 != PaintServer::None {
-        let sb = BoundingBox::new(&affine).with_ink_extents(cr.stroke_extents());
+        let (x0, y0, x1, y1) = cr.stroke_extents();
+        let sb = BoundingBox::new(&affine).with_ink_rect(Some(Rect::new(x0, y0, x1, y1)));
         bbox.insert(&sb);
     }
 
     // objectBoundingBox
 
-    let ob = BoundingBox::new(&affine).with_extents(cr.path_extents());
+    let (x0, y0, x1, y1) = cr.path_extents();
+    let ob = BoundingBox::new(&affine).with_rect(Some(Rect::new(x0, y0, x1, y1)));
     bbox.insert(&ob);
 
     // restore tolerance
diff --git a/rsvg_internals/src/filter.rs b/rsvg_internals/src/filter.rs
index a1779740..d6d37acc 100644
--- a/rsvg_internals/src/filter.rs
+++ b/rsvg_internals/src/filter.rs
@@ -10,6 +10,7 @@ use crate::node::{NodeResult, NodeTrait, RsvgNode};
 use crate::parsers::{Parse, ParseValue};
 use crate::properties::ComputedValues;
 use crate::property_bag::PropertyBag;
+use crate::rect::Rect;
 
 /// The <filter> node.
 pub struct Filter {
@@ -75,22 +76,23 @@ impl Filter {
 
         // 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 == CoordUnits::ObjectBoundingBox {
-            cairo::Rectangle {
-                x: self.x.length,
-                y: self.y.length,
-                width: self.width.length,
-                height: self.height.length,
-            }
+        let (x, y, w, h) = if self.filterunits == CoordUnits::ObjectBoundingBox {
+            (
+                self.x.length,
+                self.y.length,
+                self.width.length,
+                self.height.length,
+            )
         } else {
-            cairo::Rectangle {
-                x: self.x.normalize(values, &params),
-                y: self.y.normalize(values, &params),
-                width: self.width.normalize(values, &params),
-                height: self.height.normalize(values, &params),
-            }
+            (
+                self.x.normalize(values, &params),
+                self.y.normalize(values, &params),
+                self.width.normalize(values, &params),
+                self.height.normalize(values, &params),
+            )
         };
 
+        let rect = Rect::new(x, y, x + w, y + h);
         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
@@ -98,12 +100,7 @@ impl Filter {
         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 rect = Rect::from_size(width, height);
         let other_bbox = BoundingBox::new(&cairo::Matrix::identity()).with_rect(Some(rect));
         bbox.clip(&other_bbox);
 
diff --git a/rsvg_internals/src/filters/bounds.rs b/rsvg_internals/src/filters/bounds.rs
index 8799ad56..8983ea02 100644
--- a/rsvg_internals/src/filters/bounds.rs
+++ b/rsvg_internals/src/filters/bounds.rs
@@ -114,16 +114,16 @@ impl<'a> BoundsBuilder<'a> {
             let rect = self.bbox.rect.as_mut().unwrap();
 
             if let Some(x) = self.x {
-                rect.x = x.normalize(values, &params);
+                rect.x0 = x.normalize(values, &params);
             }
             if let Some(y) = self.y {
-                rect.y = y.normalize(values, &params);
+                rect.y0 = y.normalize(values, &params);
             }
             if let Some(width) = self.width {
-                rect.width = width.normalize(values, &params);
+                rect.x1 = rect.x0 + width.normalize(values, &params);
             }
             if let Some(height) = self.height {
-                rect.height = height.normalize(values, &params);
+                rect.y1 = rect.y1 + height.normalize(values, &params);
             }
         }
 
diff --git a/rsvg_internals/src/filters/context.rs b/rsvg_internals/src/filters/context.rs
index 1dd8a886..e3719198 100644
--- a/rsvg_internals/src/filters/context.rs
+++ b/rsvg_internals/src/filters/context.rs
@@ -107,12 +107,7 @@ impl FilterContext {
 
         // The rect can be empty (for example, if the filter is applied to an empty group).
         // However, with userSpaceOnUse it's still possible to create images with a filter.
-        let bbox_rect = node_bbox.rect.unwrap_or(cairo::Rectangle {
-            x: 0.0,
-            y: 0.0,
-            width: 0.0,
-            height: 0.0,
-        });
+        let bbox_rect = node_bbox.rect.unwrap_or_default();
 
         let node_data = filter_node.borrow();
         let filter = node_data.get_impl::<Filter>();
@@ -121,12 +116,12 @@ impl FilterContext {
             CoordUnits::UserSpaceOnUse => cr_affine,
             CoordUnits::ObjectBoundingBox => {
                 let affine = cairo::Matrix::new(
-                    bbox_rect.width,
-                    0f64,
-                    0f64,
-                    bbox_rect.height,
-                    bbox_rect.x,
-                    bbox_rect.y,
+                    bbox_rect.width(),
+                    0.0,
+                    0.0,
+                    bbox_rect.height(),
+                    bbox_rect.x0,
+                    bbox_rect.y0,
                 );
                 cairo::Matrix::multiply(&affine, &cr_affine)
             }
@@ -136,12 +131,12 @@ impl FilterContext {
             CoordUnits::UserSpaceOnUse => cr_affine,
             CoordUnits::ObjectBoundingBox => {
                 let affine = cairo::Matrix::new(
-                    bbox_rect.width,
-                    0f64,
-                    0f64,
-                    bbox_rect.height,
-                    bbox_rect.x,
-                    bbox_rect.y,
+                    bbox_rect.width(),
+                    0.0,
+                    0.0,
+                    bbox_rect.height(),
+                    bbox_rect.x0,
+                    bbox_rect.y0,
                 );
                 cairo::Matrix::multiply(&affine, &cr_affine)
             }
diff --git a/rsvg_internals/src/gradient.rs b/rsvg_internals/src/gradient.rs
index 638d1b3a..1fa672e1 100644
--- a/rsvg_internals/src/gradient.rs
+++ b/rsvg_internals/src/gradient.rs
@@ -15,7 +15,6 @@ use crate::parsers::{Parse, ParseValue};
 use crate::properties::ComputedValues;
 use crate::property_bag::PropertyBag;
 use crate::property_defs::StopColor;
-use crate::rect::RectangleExt;
 use crate::unit_interval::UnitInterval;
 
 /// Contents of a <stop> element for gradient color stops
@@ -740,12 +739,12 @@ impl Gradient {
         if self.units == GradientUnits(CoordUnits::ObjectBoundingBox) {
             let bbox_rect = bbox.rect.unwrap();
             let bbox_matrix = cairo::Matrix::new(
-                bbox_rect.width,
+                bbox_rect.width(),
                 0.0,
                 0.0,
-                bbox_rect.height,
-                bbox_rect.x,
-                bbox_rect.y,
+                bbox_rect.height(),
+                bbox_rect.x0,
+                bbox_rect.y0,
             );
             affine = cairo::Matrix::multiply(&affine, &bbox_matrix);
         }
diff --git a/rsvg_internals/src/handle.rs b/rsvg_internals/src/handle.rs
index 09468dc1..eb8f9d21 100644
--- a/rsvg_internals/src/handle.rs
+++ b/rsvg_internals/src/handle.rs
@@ -293,12 +293,16 @@ impl Handle {
         );
         let root = self.document.root();
 
-        let bbox = draw_ctx.draw_node_from_stack(&CascadedValues::new_from_node(&root), &root, false)?;
+        let bbox =
+            draw_ctx.draw_node_from_stack(&CascadedValues::new_from_node(&root), &root, false)?;
 
-        let ink_rect = bbox.ink_rect.unwrap_or_else(|| cairo::Rectangle::new(0.0, 0.0, 0.0, 0.0));
-        let logical_rect = bbox.rect.unwrap_or_else(|| cairo::Rectangle::new(0.0, 0.0, 0.0, 0.0));
+        let ink_rect = bbox.ink_rect.unwrap_or_default();
+        let logical_rect = bbox.rect.unwrap_or_default();
 
-        Ok((ink_rect, logical_rect))
+        Ok((
+            cairo::Rectangle::from(ink_rect),
+            cairo::Rectangle::from(logical_rect),
+        ))
     }
 
     /// Returns (ink_rect, logical_rect)
@@ -320,10 +324,8 @@ impl Handle {
             if let Some((root_width, root_height)) =
                 node.borrow().get_impl::<Svg>().get_size(&values, dpi)
             {
-                let ink_r = cairo::Rectangle::from_size(
-                    f64::from(root_width),
-                    f64::from(root_height),
-                );
+                let ink_r =
+                    cairo::Rectangle::from_size(f64::from(root_width), f64::from(root_height));
 
                 let logical_r = ink_r;
 
@@ -493,13 +495,16 @@ impl Handle {
 
         let bbox = self.get_bbox_for_element(&node, dpi, is_testing)?;
 
-        let ink_rect = bbox.ink_rect.unwrap_or_else(|| cairo::Rectangle::new(0.0, 0.0, 0.0, 0.0));
-        let logical_rect = bbox.rect.unwrap_or_else(|| cairo::Rectangle::new(0.0, 0.0, 0.0, 0.0));
+        let ink_rect = bbox.ink_rect.unwrap_or_default();
+        let logical_rect = bbox.rect.unwrap_or_default();
 
         // Translate so ink_rect is always at offset (0, 0)
-        let ofs = (-ink_rect.x, -ink_rect.y);
+        let ofs = (-ink_rect.x0, -ink_rect.y0);
 
-        Ok((ink_rect.translate(ofs), logical_rect.translate(ofs)))
+        Ok((
+            cairo::Rectangle::from(ink_rect.translate(ofs)),
+            cairo::Rectangle::from(logical_rect.translate(ofs)),
+        ))
     }
 
     pub fn render_element(
@@ -521,7 +526,7 @@ impl Handle {
             return Ok(());
         }
 
-        let ink_r = bbox.ink_rect.unwrap_or_else(|| cairo::Rectangle::new(0.0, 0.0, 0.0, 0.0));
+        let ink_r = bbox.ink_rect.unwrap_or_default();
 
         if ink_r.is_empty() {
             return Ok(());
@@ -532,11 +537,11 @@ impl Handle {
         cr.save();
 
         let factor =
-            (element_viewport.width / ink_r.width).min(element_viewport.height / ink_r.height);
+            (element_viewport.width / ink_r.width()).min(element_viewport.height / ink_r.height());
 
         cr.translate(element_viewport.x, element_viewport.y);
         cr.scale(factor, factor);
-        cr.translate(-ink_r.x, -ink_r.y);
+        cr.translate(-ink_r.x0, -ink_r.y0);
 
         let mut draw_ctx = DrawingCtx::new(
             self.document.clone(),
diff --git a/rsvg_internals/src/image.rs b/rsvg_internals/src/image.rs
index b4b9281e..94615c5c 100644
--- a/rsvg_internals/src/image.rs
+++ b/rsvg_internals/src/image.rs
@@ -98,12 +98,9 @@ impl NodeTrait for Image {
 
             // The bounding box for <image> is decided by the values of x, y, w, h and not by
             // the final computed image bounds.
-            let bbox = dc.empty_bbox().with_rect(Some(cairo::Rectangle {
-                x,
-                y,
-                width: w,
-                height: h,
-            }));
+            let bbox = dc
+                .empty_bbox()
+                .with_rect(Some(Rect::new(x, y, x + w, y + h)));
 
             dc.with_saved_cr(&mut |dc| {
                 let cr = dc.get_cairo_context();
diff --git a/rsvg_internals/src/mask.rs b/rsvg_internals/src/mask.rs
index 08fb5a49..6afaed55 100644
--- a/rsvg_internals/src/mask.rs
+++ b/rsvg_internals/src/mask.rs
@@ -56,6 +56,8 @@ impl Mask {
         }
 
         let bbox_rect = bbox.rect.as_ref().unwrap();
+        let (bb_x, bb_y) = (bbox_rect.x0, bbox_rect.y0);
+        let (bb_w, bb_h) = (bbox_rect.width(), bbox_rect.height());
 
         let cascaded = CascadedValues::new_from_node(mask_node);
         let values = cascaded.get();
@@ -90,12 +92,7 @@ impl Mask {
             draw_ctx.push_cairo_context(mask_cr);
 
             let (x, y, w, h) = if mask_units == CoordUnits::ObjectBoundingBox {
-                (
-                    x * bbox_rect.width + bbox_rect.x,
-                    y * bbox_rect.height + bbox_rect.y,
-                    w * bbox_rect.width,
-                    h * bbox_rect.height,
-                )
+                (x * bb_w + bb_x, y * bb_h + bb_y, w * bb_w, h * bb_h)
             } else {
                 (x, y, w, h)
             };
@@ -104,14 +101,7 @@ impl Mask {
 
             {
                 let _params = if content_units == CoordUnits::ObjectBoundingBox {
-                    let bbtransform = cairo::Matrix::new(
-                        bbox_rect.width,
-                        0.0,
-                        0.0,
-                        bbox_rect.height,
-                        bbox_rect.x,
-                        bbox_rect.y,
-                    );
+                    let bbtransform = cairo::Matrix::new(bb_w, 0.0, 0.0, bb_h, bb_x, bb_y);
 
                     draw_ctx.get_cairo_context().transform(bbtransform);
 
diff --git a/rsvg_internals/src/pattern.rs b/rsvg_internals/src/pattern.rs
index edc4f81d..e047d6d6 100644
--- a/rsvg_internals/src/pattern.rs
+++ b/rsvg_internals/src/pattern.rs
@@ -261,8 +261,8 @@ impl AsPaintSource for ResolvedPattern {
         match units {
             PatternUnits(CoordUnits::ObjectBoundingBox) => {
                 let bbrect = bbox.rect.unwrap();
-                bbwscale = bbrect.width;
-                bbhscale = bbrect.height;
+                bbwscale = bbrect.width();
+                bbhscale = bbrect.height();
             }
 
             PatternUnits(CoordUnits::UserSpaceOnUse) => {
@@ -302,8 +302,8 @@ impl AsPaintSource for ResolvedPattern {
             PatternUnits(CoordUnits::ObjectBoundingBox) => {
                 let bbrect = bbox.rect.unwrap();
                 affine.translate(
-                    bbrect.x + pattern_x * bbrect.width,
-                    bbrect.y + pattern_y * bbrect.height,
+                    bbrect.x0 + pattern_x * bbrect.width(),
+                    bbrect.y0 + pattern_y * bbrect.height(),
                 );
             }
 
@@ -338,7 +338,7 @@ impl AsPaintSource for ResolvedPattern {
             let bbrect = bbox.rect.unwrap();
 
             caffine = cairo::Matrix::identity();
-            caffine.scale(bbrect.width, bbrect.height);
+            caffine.scale(bbrect.width(), bbrect.height());
 
             draw_ctx.push_view_box(1.0, 1.0)
         } else {
diff --git a/rsvg_internals/src/text.rs b/rsvg_internals/src/text.rs
index 29f13c84..a16fe04a 100644
--- a/rsvg_internals/src/text.rs
+++ b/rsvg_internals/src/text.rs
@@ -17,17 +17,10 @@ use crate::parsers::ParseValue;
 use crate::properties::ComputedValues;
 use crate::property_bag::PropertyBag;
 use crate::property_defs::{
-    Direction,
-    FontStretch,
-    FontStyle,
-    FontVariant,
-    TextAnchor,
-    TextRendering,
-    UnicodeBidi,
-    WritingMode,
-    XmlLang,
-    XmlSpace,
+    Direction, FontStretch, FontStyle, FontVariant, TextAnchor, TextRendering, UnicodeBidi,
+    WritingMode, XmlLang, XmlSpace,
 };
+use crate::rect::Rect;
 use crate::space::{xml_space_normalize, NormalizeDefault, XmlSpaceNormalize};
 
 /// An absolutely-positioned array of `Span`s
@@ -350,7 +343,9 @@ impl PositionedSpan {
                     pangocairo::functions::layout_path(&cr, &self.layout);
 
                     if !clipping {
-                        let ib = BoundingBox::new(&affine).with_ink_extents(cr.stroke_extents());
+                        let (x0, y0, x1, y1) = cr.stroke_extents();
+                        let ib = BoundingBox::new(&affine)
+                            .with_ink_rect(Some(Rect::new(x0, y0, x1, y1)));
                         cr.stroke();
                         bbox.insert(&ib);
                     }
@@ -378,25 +373,25 @@ impl PositionedSpan {
         let ink_height = f64::from(ink.height);
         let pango_scale = f64::from(pango::SCALE);
 
-        let rect = if gravity_is_vertical(gravity) {
-            cairo::Rectangle {
-                x: x + (ink_x - ink_height) / pango_scale,
-                y: y + ink_y / pango_scale,
-                width: ink_height / pango_scale,
-                height: ink_width / pango_scale,
-            }
+        let (x, y, w, h) = if gravity_is_vertical(gravity) {
+            (
+                x + (ink_x - ink_height) / pango_scale,
+                y + ink_y / pango_scale,
+                ink_height / pango_scale,
+                ink_width / pango_scale,
+            )
         } else {
-            cairo::Rectangle {
-                x: x + ink_x / pango_scale,
-                y: y + ink_y / pango_scale,
-                width: ink_width / pango_scale,
-                height: ink_height / pango_scale,
-            }
+            (
+                x + ink_x / pango_scale,
+                y + ink_y / pango_scale,
+                ink_width / pango_scale,
+                ink_height / pango_scale,
+            )
         };
 
         let bbox = BoundingBox::new(affine)
-            .with_rect(Some(rect))
-            .with_ink_rect(Some(rect));
+            .with_rect(Some(Rect::new(x, y, x + w, y + h)))
+            .with_ink_rect(Some(Rect::new(x, y, x + w, y + h)));
 
         Some(bbox)
     }


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