[librsvg/rect: 7/10] bbox: use Rect
- From: Paolo Borelli <pborelli src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg/rect: 7/10] bbox: use Rect
- Date: Sun, 8 Dec 2019 20:05:45 +0000 (UTC)
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, ¶ms),
- y: self.y.normalize(values, ¶ms),
- width: self.width.normalize(values, ¶ms),
- height: self.height.normalize(values, ¶ms),
- }
+ (
+ self.x.normalize(values, ¶ms),
+ self.y.normalize(values, ¶ms),
+ self.width.normalize(values, ¶ms),
+ self.height.normalize(values, ¶ms),
+ )
};
+ 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, ¶ms);
+ rect.x0 = x.normalize(values, ¶ms);
}
if let Some(y) = self.y {
- rect.y = y.normalize(values, ¶ms);
+ rect.y0 = y.normalize(values, ¶ms);
}
if let Some(width) = self.width {
- rect.width = width.normalize(values, ¶ms);
+ rect.x1 = rect.x0 + width.normalize(values, ¶ms);
}
if let Some(height) = self.height {
- rect.height = height.normalize(values, ¶ms);
+ rect.y1 = rect.y1 + height.normalize(values, ¶ms);
}
}
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]