[librsvg: 4/7] Move all the internals from cairo:Rect to Rect
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg: 4/7] Move all the internals from cairo:Rect to Rect
- Date: Tue, 10 Dec 2019 13:56:00 +0000 (UTC)
commit aa3311e90084cae055d02f551ccd59091e330f94
Author: Paolo Borelli <pborelli gnome org>
Date: Sun Dec 8 13:45:42 2019 +0100
Move all the internals from cairo:Rect to Rect
Note: this breaks three reftests for me, but they might be
just different approximation
rsvg_internals/src/aspect_ratio.rs | 175 ++++++++++++----------------------
rsvg_internals/src/bbox.rs | 34 +++----
rsvg_internals/src/clip_path.rs | 8 +-
rsvg_internals/src/drawing_ctx.rs | 51 +++++-----
rsvg_internals/src/filter.rs | 6 +-
rsvg_internals/src/filters/bounds.rs | 18 ++--
rsvg_internals/src/filters/context.rs | 31 +++---
rsvg_internals/src/filters/image.rs | 24 ++---
rsvg_internals/src/gradient.rs | 9 +-
rsvg_internals/src/handle.rs | 55 +++++------
rsvg_internals/src/image.rs | 8 +-
rsvg_internals/src/marker.rs | 23 ++---
rsvg_internals/src/mask.rs | 7 +-
rsvg_internals/src/pattern.rs | 28 +++---
rsvg_internals/src/rect.rs | 43 +++------
rsvg_internals/src/structure.rs | 29 +++---
rsvg_internals/src/text.rs | 6 +-
17 files changed, 238 insertions(+), 317 deletions(-)
---
diff --git a/rsvg_internals/src/aspect_ratio.rs b/rsvg_internals/src/aspect_ratio.rs
index a42362d0..52941c0b 100644
--- a/rsvg_internals/src/aspect_ratio.rs
+++ b/rsvg_internals/src/aspect_ratio.rs
@@ -27,6 +27,7 @@ use cairo;
use crate::error::ValueErrorKind;
use crate::float_eq_cairo::ApproxEqCairo;
use crate::parsers::Parse;
+use crate::rect::Rect;
use crate::viewbox::ViewBox;
use cssparser::{CowRcStr, Parser};
@@ -124,25 +125,29 @@ impl AspectRatio {
}
}
- pub fn compute(&self, vbox: &ViewBox, viewport: &cairo::Rectangle) -> (f64, f64, f64, f64) {
+ pub fn compute(&self, vbox: &ViewBox, viewport: &Rect) -> Rect {
match self.align {
- None => (viewport.x, viewport.y, viewport.width, viewport.height),
+ None => *viewport,
Some(Align { x, y, fit }) => {
- let w_factor = viewport.width / vbox.width;
- let h_factor = viewport.height / vbox.height;
+ let (vb_width, vb_height) = (vbox.width, vbox.height);
+ let (vp_width, vp_height) = viewport.size();
+
+ let w_factor = vp_width / vb_width;
+ let h_factor = vp_height / vb_height;
+
let factor = match fit {
FitMode::Meet => w_factor.min(h_factor),
FitMode::Slice => w_factor.max(h_factor),
};
- let w = vbox.width * factor;
- let h = vbox.height * factor;
+ let w = vb_width * factor;
+ let h = vb_height * factor;
- let xpos = x.compute(viewport.x, viewport.width, w);
- let ypos = y.compute(viewport.y, viewport.height, h);
+ let xpos = x.compute(viewport.x0, vp_width, w);
+ let ypos = y.compute(viewport.y0, vp_height, h);
- (xpos, ypos, w, h)
+ Rect::new(xpos, ypos, xpos + w, ypos + h)
}
}
}
@@ -152,7 +157,7 @@ impl AspectRatio {
pub fn viewport_to_viewbox_transform(
&self,
vbox: Option<ViewBox>,
- viewport: &cairo::Rectangle,
+ viewport: &Rect,
) -> Option<cairo::Matrix> {
// width or height set to 0 disables rendering of the element
// https://www.w3.org/TR/SVG/struct.html#SVGElementWidthAttribute
@@ -160,7 +165,7 @@ impl AspectRatio {
// https://www.w3.org/TR/SVG/struct.html#ImageElementWidthAttribute
// https://www.w3.org/TR/SVG/painting.html#MarkerWidthAttribute
- if viewport.width.approx_eq_cairo(0.0) || viewport.height.approx_eq_cairo(0.0) {
+ if viewport.is_empty() {
return None;
}
@@ -172,16 +177,16 @@ impl AspectRatio {
// https://www.w3.org/TR/SVG/coords.html#ViewBoxAttribute
None
} else {
- let (x, y, w, h) = self.compute(&vbox, viewport);
+ let r = self.compute(&vbox, viewport);
let mut matrix = cairo::Matrix::identity();
- matrix.translate(x, y);
- matrix.scale(w / vbox.width, h / vbox.height);
+ matrix.translate(r.x0, r.y0);
+ matrix.scale(r.width() / vbox.width, r.height() / vbox.height);
matrix.translate(-vbox.x, -vbox.y);
Some(matrix)
}
} else {
let mut matrix = cairo::Matrix::identity();
- matrix.translate(viewport.x, viewport.y);
+ matrix.translate(viewport.x0, viewport.y0);
Some(matrix)
}
}
@@ -251,8 +256,6 @@ impl Parse for AspectRatio {
mod tests {
use super::*;
use crate::float_eq_cairo::ApproxEqCairo;
- use crate::rect::RectangleExt;
- use cairo::Rectangle;
#[test]
fn parsing_invalid_strings_yields_error() {
@@ -337,139 +340,87 @@ mod tests {
);
}
- fn assert_quadruples_equal(a: &(f64, f64, f64, f64), b: &(f64, f64, f64, f64)) {
- assert_approx_eq_cairo!(a.0, b.0);
- assert_approx_eq_cairo!(a.1, b.1);
- assert_approx_eq_cairo!(a.2, b.2);
- assert_approx_eq_cairo!(a.3, b.3);
+ fn assert_rect_equal(r1: &Rect, r2: &Rect) {
+ assert_approx_eq_cairo!(r1.x0, r2.x0);
+ assert_approx_eq_cairo!(r1.y0, r2.y0);
+ assert_approx_eq_cairo!(r1.x1, r2.x1);
+ assert_approx_eq_cairo!(r1.y1, r2.y1);
}
#[test]
fn aligns() {
+ let viewbox = ViewBox::new(0.0, 0.0, 1.0, 10.0);
+
let foo = AspectRatio::parse_str("xMinYMin meet").unwrap();
- let foo = foo.compute(
- &ViewBox::new(0.0, 0.0, 1.0, 10.0),
- &Rectangle::new(0.0, 0.0, 10.0, 1.0),
- );
- assert_quadruples_equal(&foo, &(0.0, 0.0, 0.1, 1.0));
+ let foo = foo.compute(&viewbox, &Rect::from_size(10.0, 1.0));
+ assert_rect_equal(&foo, &Rect::from_size(0.1, 1.0));
let foo = AspectRatio::parse_str("xMinYMin slice").unwrap();
- let foo = foo.compute(
- &ViewBox::new(0.0, 0.0, 1.0, 10.0),
- &Rectangle::new(0.0, 0.0, 10.0, 1.0),
- );
- assert_quadruples_equal(&foo, &(0.0, 0.0, 10.0, 100.0));
+ let foo = foo.compute(&viewbox, &Rect::from_size(10.0, 1.0));
+ assert_rect_equal(&foo, &Rect::from_size(10.0, 100.0));
let foo = AspectRatio::parse_str("xMinYMid meet").unwrap();
- let foo = foo.compute(
- &ViewBox::new(0.0, 0.0, 1.0, 10.0),
- &Rectangle::new(0.0, 0.0, 10.0, 1.0),
- );
- assert_quadruples_equal(&foo, &(0.0, 0.0, 0.1, 1.0));
+ let foo = foo.compute(&viewbox, &Rect::from_size(10.0, 1.0));
+ assert_rect_equal(&foo, &Rect::from_size(0.1, 1.0));
let foo = AspectRatio::parse_str("xMinYMid slice").unwrap();
- let foo = foo.compute(
- &ViewBox::new(0.0, 0.0, 1.0, 10.0),
- &Rectangle::new(0.0, 0.0, 10.0, 1.0),
- );
- assert_quadruples_equal(&foo, &(0.0, -49.5, 10.0, 100.0));
+ let foo = foo.compute(&viewbox, &Rect::from_size(10.0, 1.0));
+ assert_rect_equal(&foo, &Rect::new(0.0, -49.5, 10.0, 100.0 - 49.5));
let foo = AspectRatio::parse_str("xMinYMax meet").unwrap();
- let foo = foo.compute(
- &ViewBox::new(0.0, 0.0, 1.0, 10.0),
- &Rectangle::new(0.0, 0.0, 10.0, 1.0),
- );
- assert_quadruples_equal(&foo, &(0.0, 0.0, 0.1, 1.0));
+ let foo = foo.compute(&viewbox, &Rect::from_size(10.0, 1.0));
+ assert_rect_equal(&foo, &Rect::from_size(0.1, 1.0));
let foo = AspectRatio::parse_str("xMinYMax slice").unwrap();
- let foo = foo.compute(
- &ViewBox::new(0.0, 0.0, 1.0, 10.0),
- &Rectangle::new(0.0, 0.0, 10.0, 1.0),
- );
- assert_quadruples_equal(&foo, &(0.0, -99.0, 10.0, 100.0));
+ let foo = foo.compute(&viewbox, &Rect::from_size(10.0, 1.0));
+ assert_rect_equal(&foo, &Rect::new(0.0, -99.0, 10.0, 1.0));
let foo = AspectRatio::parse_str("xMidYMin meet").unwrap();
- let foo = foo.compute(
- &ViewBox::new(0.0, 0.0, 1.0, 10.0),
- &Rectangle::new(0.0, 0.0, 10.0, 1.0),
- );
- assert_quadruples_equal(&foo, &(4.95, 0.0, 0.1, 1.0));
+ let foo = foo.compute(&viewbox, &Rect::from_size(10.0, 1.0));
+ assert_rect_equal(&foo, &Rect::new(4.95, 0.0, 4.95 + 0.1, 1.0));
let foo = AspectRatio::parse_str("xMidYMin slice").unwrap();
- let foo = foo.compute(
- &ViewBox::new(0.0, 0.0, 1.0, 10.0),
- &Rectangle::new(0.0, 0.0, 10.0, 1.0),
- );
- assert_quadruples_equal(&foo, &(0.0, 0.0, 10.0, 100.0));
+ let foo = foo.compute(&viewbox, &Rect::from_size(10.0, 1.0));
+ assert_rect_equal(&foo, &Rect::from_size(10.0, 100.0));
let foo = AspectRatio::parse_str("xMidYMid meet").unwrap();
- let foo = foo.compute(
- &ViewBox::new(0.0, 0.0, 1.0, 10.0),
- &Rectangle::new(0.0, 0.0, 10.0, 1.0),
- );
- assert_quadruples_equal(&foo, &(4.95, 0.0, 0.1, 1.0));
+ let foo = foo.compute(&viewbox, &Rect::from_size(10.0, 1.0));
+ assert_rect_equal(&foo, &Rect::new(4.95, 0.0, 4.95 + 0.1, 1.0));
let foo = AspectRatio::parse_str("xMidYMid slice").unwrap();
- let foo = foo.compute(
- &ViewBox::new(0.0, 0.0, 1.0, 10.0),
- &Rectangle::new(0.0, 0.0, 10.0, 1.0),
- );
- assert_quadruples_equal(&foo, &(0.0, -49.5, 10.0, 100.0));
+ let foo = foo.compute(&viewbox, &Rect::from_size(10.0, 1.0));
+ assert_rect_equal(&foo, &Rect::new(0.0, -49.5, 10.0, 100.0 - 49.5));
let foo = AspectRatio::parse_str("xMidYMax meet").unwrap();
- let foo = foo.compute(
- &ViewBox::new(0.0, 0.0, 1.0, 10.0),
- &Rectangle::new(0.0, 0.0, 10.0, 1.0),
- );
- assert_quadruples_equal(&foo, &(4.95, 0.0, 0.1, 1.0));
+ let foo = foo.compute(&viewbox, &Rect::from_size(10.0, 1.0));
+ assert_rect_equal(&foo, &Rect::new(4.95, 0.0, 4.95 + 0.1, 1.0));
let foo = AspectRatio::parse_str("xMidYMax slice").unwrap();
- let foo = foo.compute(
- &ViewBox::new(0.0, 0.0, 1.0, 10.0),
- &Rectangle::new(0.0, 0.0, 10.0, 1.0),
- );
- assert_quadruples_equal(&foo, &(0.0, -99.0, 10.0, 100.0));
+ let foo = foo.compute(&viewbox, &Rect::from_size(10.0, 1.0));
+ assert_rect_equal(&foo, &Rect::new(0.0, -99.0, 10.0, 1.0));
let foo = AspectRatio::parse_str("xMaxYMin meet").unwrap();
- let foo = foo.compute(
- &ViewBox::new(0.0, 0.0, 1.0, 10.0),
- &Rectangle::new(0.0, 0.0, 10.0, 1.0),
- );
- assert_quadruples_equal(&foo, &(9.9, 0.0, 0.1, 1.0));
+ let foo = foo.compute(&viewbox, &Rect::from_size(10.0, 1.0));
+ assert_rect_equal(&foo, &Rect::new(9.9, 0.0, 10.0, 1.0));
let foo = AspectRatio::parse_str("xMaxYMin slice").unwrap();
- let foo = foo.compute(
- &ViewBox::new(0.0, 0.0, 1.0, 10.0),
- &Rectangle::new(0.0, 0.0, 10.0, 1.0),
- );
- assert_quadruples_equal(&foo, &(0.0, 0.0, 10.0, 100.0));
+ let foo = foo.compute(&viewbox, &Rect::from_size(10.0, 1.0));
+ assert_rect_equal(&foo, &Rect::from_size(10.0, 100.0));
let foo = AspectRatio::parse_str("xMaxYMid meet").unwrap();
- let foo = foo.compute(
- &ViewBox::new(0.0, 0.0, 1.0, 10.0),
- &Rectangle::new(0.0, 0.0, 10.0, 1.0),
- );
- assert_quadruples_equal(&foo, &(9.9, 0.0, 0.1, 1.0));
+ let foo = foo.compute(&viewbox, &Rect::from_size(10.0, 1.0));
+ assert_rect_equal(&foo, &Rect::new(9.9, 0.0, 10.0, 1.0));
let foo = AspectRatio::parse_str("xMaxYMid slice").unwrap();
- let foo = foo.compute(
- &ViewBox::new(0.0, 0.0, 1.0, 10.0),
- &Rectangle::new(0.0, 0.0, 10.0, 1.0),
- );
- assert_quadruples_equal(&foo, &(0.0, -49.5, 10.0, 100.0));
+ let foo = foo.compute(&viewbox, &Rect::from_size(10.0, 1.0));
+ assert_rect_equal(&foo, &Rect::new(0.0, -49.5, 10.0, 100.0 - 49.5));
let foo = AspectRatio::parse_str("xMaxYMax meet").unwrap();
- let foo = foo.compute(
- &ViewBox::new(0.0, 0.0, 1.0, 10.0),
- &Rectangle::new(0.0, 0.0, 10.0, 1.0),
- );
- assert_quadruples_equal(&foo, &(9.9, 0.0, 0.1, 1.0));
+ let foo = foo.compute(&viewbox, &Rect::from_size(10.0, 1.0));
+ assert_rect_equal(&foo, &Rect::new(9.9, 0.0, 10.0, 1.0));
let foo = AspectRatio::parse_str("xMaxYMax slice").unwrap();
- let foo = foo.compute(
- &ViewBox::new(0.0, 0.0, 1.0, 10.0),
- &Rectangle::new(0.0, 0.0, 10.0, 1.0),
- );
- assert_quadruples_equal(&foo, &(0.0, -99.0, 10.0, 100.0));
+ let foo = foo.compute(&viewbox, &Rect::from_size(10.0, 1.0));
+ assert_rect_equal(&foo, &Rect::new(0.0, -99.0, 10.0, 1.0));
}
}
diff --git a/rsvg_internals/src/bbox.rs b/rsvg_internals/src/bbox.rs
index 2c4d7c82..1912d57c 100644
--- a/rsvg_internals/src/bbox.rs
+++ b/rsvg_internals/src/bbox.rs
@@ -1,12 +1,12 @@
use cairo;
-use crate::rect::{RectangleExt, TransformRect};
+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,14 +18,14 @@ impl BoundingBox {
}
}
- pub fn with_rect(self, rect: cairo::Rectangle) -> BoundingBox {
+ pub fn with_rect(self, rect: Rect) -> BoundingBox {
BoundingBox {
rect: Some(rect),
..self
}
}
- pub fn with_ink_rect(self, ink_rect: cairo::Rectangle) -> BoundingBox {
+ pub fn with_ink_rect(self, ink_rect: Rect) -> BoundingBox {
BoundingBox {
ink_rect: Some(ink_rect),
..self
@@ -62,18 +62,18 @@ impl BoundingBox {
}
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(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))),
+ .or_else(|| Some(Rect::default())),
(Some(r1), Some(r2), false) => Some(affine.transform_rect(&r2).union(&r1)),
}
}
@@ -84,9 +84,9 @@ mod tests {
#[test]
fn combine() {
- let r1 = cairo::Rectangle::new(1.0, 2.0, 3.0, 4.0);
- let r2 = cairo::Rectangle::new(1.5, 2.5, 3.0, 4.0);
- let r3 = cairo::Rectangle::new(10.0, 11.0, 12.0, 13.0);
+ let r1 = Rect::new(1.0, 2.0, 3.0, 4.0);
+ let r2 = Rect::new(1.5, 2.5, 3.5, 4.5);
+ let r3 = Rect::new(10.0, 11.0, 12.0, 13.0);
let affine = cairo::Matrix::new(1.0, 0.0, 0.0, 1.0, 0.5, 0.5);
let res = combine_rects(None, None, &affine, true);
@@ -102,18 +102,18 @@ mod tests {
assert_eq!(res, Some(r1));
let res = combine_rects(None, Some(r2), &affine, true);
- assert_eq!(res, Some(cairo::Rectangle::new(2.0, 3.0, 3.0, 4.0)));
+ assert_eq!(res, Some(Rect::new(2.0, 3.0, 4.0, 5.0)));
let res = combine_rects(None, Some(r2), &affine, false);
- assert_eq!(res, Some(cairo::Rectangle::new(2.0, 3.0, 3.0, 4.0)));
+ assert_eq!(res, Some(Rect::new(2.0, 3.0, 4.0, 5.0)));
let res = combine_rects(Some(r1), Some(r2), &affine, true);
- assert_eq!(res, Some(cairo::Rectangle::new(2.0, 3.0, 2.0, 3.0)));
+ assert_eq!(res, Some(Rect::new(2.0, 3.0, 3.0, 4.0)));
let res = combine_rects(Some(r1), Some(r3), &affine, true);
- assert_eq!(res, Some(cairo::Rectangle::new(0.0, 0.0, 0.0, 0.0)));
+ assert_eq!(res, Some(Rect::default()));
let res = combine_rects(Some(r1), Some(r2), &affine, false);
- assert_eq!(res, Some(cairo::Rectangle::new(1.0, 2.0, 4.0, 5.0)));
+ assert_eq!(res, Some(Rect::new(1.0, 2.0, 4.0, 5.0)));
}
}
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 a776b468..ad74c097 100644
--- a/rsvg_internals/src/drawing_ctx.rs
+++ b/rsvg_internals/src/drawing_ctx.rs
@@ -23,7 +23,7 @@ use crate::properties::ComputedValues;
use crate::property_defs::{
ClipRule, FillRule, ShapeRendering, StrokeDasharray, StrokeLinecap, StrokeLinejoin,
};
-use crate::rect::RectangleExt;
+use crate::rect::Rect;
use crate::surface_utils::shared_surface::SharedImageSurface;
use crate::unit_interval::UnitInterval;
use crate::viewbox::ViewBox;
@@ -79,7 +79,7 @@ pub struct DrawingCtx {
initial_affine: cairo::Matrix,
- rect: cairo::Rectangle,
+ rect: Rect,
dpi: Dpi,
// This is a mitigation for SVG files that try to instance a huge number of
@@ -104,7 +104,7 @@ impl DrawingCtx {
document: Rc<Document>,
node: Option<&RsvgNode>,
cr: &cairo::Context,
- viewport: &cairo::Rectangle,
+ viewport: Rect,
dpi: Dpi,
measuring: bool,
testing: bool,
@@ -116,12 +116,10 @@ impl DrawingCtx {
let (rect, vbox) = if measuring {
(
- cairo::Rectangle::new(0.0, 0.0, 1.0, 1.0),
+ Rect::from_size(1.0, 1.0),
ViewBox::new(0.0, 0.0, 1.0, 1.0),
)
} else {
- let rect = *viewport;
-
// https://www.w3.org/TR/SVG2/coords.html#InitialCoordinateSystem
//
// "For the outermost svg element, the SVG user agent must
@@ -137,11 +135,11 @@ impl DrawingCtx {
let vbox = ViewBox {
x: 0.0,
y: 0.0,
- width: viewport.width,
- height: viewport.height,
+ width: viewport.width(),
+ height: viewport.height(),
};
- (rect, vbox)
+ (viewport, vbox)
};
let mut view_box_stack = Vec::new();
@@ -171,7 +169,7 @@ impl DrawingCtx {
draw_ctx
}
- pub fn toplevel_viewport(&self) -> cairo::Rectangle {
+ pub fn toplevel_viewport(&self) -> Rect {
self.rect
}
@@ -212,7 +210,7 @@ impl DrawingCtx {
}
fn size_for_temporary_surface(&self) -> (i32, i32) {
- let (viewport_width, viewport_height) = (self.rect.width, self.rect.height);
+ let (viewport_width, viewport_height) = (self.rect.width(), self.rect.height());
let (scaled_width, scaled_height) = self
.initial_affine_with_offset()
@@ -292,25 +290,30 @@ impl DrawingCtx {
pub fn push_new_viewport(
&self,
vbox: Option<ViewBox>,
- viewport: &cairo::Rectangle,
+ viewport: Rect,
preserve_aspect_ratio: AspectRatio,
clip_mode: Option<ClipMode>,
) -> Option<ViewParams> {
if let Some(ref clip) = clip_mode {
if *clip == ClipMode::ClipToViewport {
- self.clip(viewport.x, viewport.y, viewport.width, viewport.height);
+ self.clip(viewport);
}
}
preserve_aspect_ratio
- .viewport_to_viewbox_transform(vbox, viewport)
+ .viewport_to_viewbox_transform(vbox, &viewport)
.and_then(|matrix| {
self.cr.transform(matrix);
if let Some(vbox) = vbox {
if let Some(ref clip) = clip_mode {
if *clip == ClipMode::ClipToVbox {
- self.clip(vbox.x, vbox.y, vbox.width, vbox.height);
+ self.clip(Rect::new(
+ vbox.x,
+ vbox.y,
+ vbox.x + vbox.width,
+ vbox.y + vbox.height,
+ ));
}
}
@@ -535,7 +538,7 @@ impl DrawingCtx {
fn initial_affine_with_offset(&self) -> cairo::Matrix {
let mut initial_with_offset = self.initial_affine;
- initial_with_offset.translate(self.rect.x, self.rect.y);
+ initial_with_offset.translate(self.rect.x0, self.rect.y0);
initial_with_offset
}
@@ -783,10 +786,9 @@ impl DrawingCtx {
res.and_then(|_: ()| Ok(bbox))
}
- pub fn clip(&self, x: f64, y: f64, w: f64, h: f64) {
+ pub fn clip(&self, rect: Rect) {
let cr = self.get_cairo_context();
-
- cr.rectangle(x, y, w, h);
+ cr.rectangle(rect.x0, rect.y0, rect.width(), rect.height());
cr.clip();
}
@@ -842,10 +844,7 @@ impl DrawingCtx {
cr.set_matrix(affine);
self.cr = cr;
- self.rect.x = 0.0;
- self.rect.y = 0.0;
- self.rect.width = width;
- self.rect.height = height;
+ self.rect = Rect::from_size(width, height);
let res = self.draw_node_from_stack(cascaded, node, false);
@@ -966,21 +965,21 @@ fn compute_stroke_and_fill_box(cr: &cairo::Context, values: &ComputedValues) ->
// rectangle's extents, even when it has no fill nor stroke.
let (x0, y0, x1, y1) = cr.fill_extents();
- let fb = BoundingBox::new(&affine).with_ink_rect(cairo::Rectangle::from_extents(x0, y0, x1, y1));
+ let fb = BoundingBox::new(&affine).with_ink_rect(Rect::new(x0, y0, x1, y1));
bbox.insert(&fb);
// Bounding box for stroke
if values.stroke.0 != PaintServer::None {
let (x0, y0, x1, y1) = cr.stroke_extents();
- let sb = BoundingBox::new(&affine).with_ink_rect(cairo::Rectangle::from_extents(x0, y0, x1, y1));
+ let sb = BoundingBox::new(&affine).with_ink_rect(Rect::new(x0, y0, x1, y1));
bbox.insert(&sb);
}
// objectBoundingBox
let (x0, y0, x1, y1) = cr.path_extents();
- let ob = BoundingBox::new(&affine).with_rect(cairo::Rectangle::from_extents(x0, y0, x1, y1));
+ let ob = BoundingBox::new(&affine).with_rect(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 3d5cd5f1..f9a1541d 100644
--- a/rsvg_internals/src/filter.rs
+++ b/rsvg_internals/src/filter.rs
@@ -10,7 +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::RectangleExt;
+use crate::rect::Rect;
/// The <filter> node.
pub struct Filter {
@@ -92,7 +92,7 @@ impl Filter {
)
};
- let rect = cairo::Rectangle::new(x, y, w, h);
+ let rect = Rect::new(x, y, x + w, y + h);
let other_bbox = BoundingBox::new(&affine).with_rect(rect);
// At this point all of the previous viewbox and matrix business gets converted to pixel
@@ -100,7 +100,7 @@ impl Filter {
bbox.insert(&other_bbox);
// Finally, clip to the width and height of our surface.
- let rect = cairo::Rectangle::from_size(width, height);
+ let rect = Rect::from_size(width, height);
let other_bbox = BoundingBox::new(&cairo::Matrix::identity()).with_rect(rect);
bbox.clip(&other_bbox);
diff --git a/rsvg_internals/src/filters/bounds.rs b/rsvg_internals/src/filters/bounds.rs
index 28291541..bc26962e 100644
--- a/rsvg_internals/src/filters/bounds.rs
+++ b/rsvg_internals/src/filters/bounds.rs
@@ -4,7 +4,7 @@ use cairo;
use crate::bbox::BoundingBox;
use crate::drawing_ctx::DrawingCtx;
use crate::length::*;
-use crate::rect::IRect;
+use crate::rect::{IRect, Rect};
use super::context::{FilterContext, FilterInput};
@@ -74,7 +74,7 @@ impl<'a> BoundsBuilder<'a> {
}
/// Returns the final exact bounds.
- pub fn into_rect(self, draw_ctx: &mut DrawingCtx) -> cairo::Rectangle {
+ pub fn into_rect(self, draw_ctx: &mut DrawingCtx) -> Rect {
let mut bbox = self.apply_properties(draw_ctx);
let effects_region = self.ctx.effects_region();
@@ -91,7 +91,7 @@ impl<'a> BoundsBuilder<'a> {
/// Returns the final pixel bounds without clipping to the filter effects region.
///
/// Used by feImage.
- pub fn into_rect_without_clipping(self, draw_ctx: &mut DrawingCtx) -> cairo::Rectangle {
+ pub fn into_rect_without_clipping(self, draw_ctx: &mut DrawingCtx) -> Rect {
self.apply_properties(draw_ctx).rect.unwrap().into()
}
@@ -118,16 +118,20 @@ impl<'a> BoundsBuilder<'a> {
let rect = self.bbox.rect.as_mut().unwrap();
if let Some(x) = self.x {
- rect.x = x.normalize(values, ¶ms);
+ let w = rect.width();
+ rect.x0 = x.normalize(values, ¶ms);
+ rect.x1 = rect.x0 + w;
}
if let Some(y) = self.y {
- rect.y = y.normalize(values, ¶ms);
+ let h = rect.height();
+ rect.y0 = y.normalize(values, ¶ms);
+ rect.y1 = rect.y0 + h;
}
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.y0 + 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/filters/image.rs b/rsvg_internals/src/filters/image.rs
index 22c0e22e..9e668038 100644
--- a/rsvg_internals/src/filters/image.rs
+++ b/rsvg_internals/src/filters/image.rs
@@ -5,10 +5,10 @@ use crate::allowed_url::{Fragment, Href};
use crate::aspect_ratio::AspectRatio;
use crate::drawing_ctx::DrawingCtx;
use crate::error::{NodeError, RenderingError};
-use crate::float_eq_cairo::ApproxEqCairo;
use crate::node::{CascadedValues, NodeResult, NodeTrait, RsvgNode};
use crate::parsers::ParseValue;
use crate::property_bag::PropertyBag;
+use crate::rect::Rect;
use crate::surface_utils::shared_surface::{SharedImageSurface, SurfaceType};
use crate::viewbox::ViewBox;
@@ -40,7 +40,7 @@ impl FeImage {
&self,
ctx: &FilterContext,
draw_ctx: &mut DrawingCtx,
- bounds: cairo::Rectangle,
+ bounds: Rect,
fragment: &Fragment,
) -> Result<ImageSurface, FilterError> {
let acquired_drawable = draw_ctx
@@ -99,8 +99,8 @@ impl FeImage {
&self,
ctx: &FilterContext,
draw_ctx: &DrawingCtx,
- bounds: &cairo::Rectangle,
- unclipped_bounds: &cairo::Rectangle,
+ bounds: &Rect,
+ unclipped_bounds: &Rect,
href: &Href,
) -> Result<ImageSurface, FilterError> {
let surface = if let Href::PlainUrl(ref url) = *href {
@@ -119,7 +119,7 @@ impl FeImage {
)?;
// TODO: this goes through a f64->i32->f64 conversion.
- let (x, y, w, h) = self.aspect.compute(
+ let r = self.aspect.compute(
&ViewBox::new(
0.0,
0.0,
@@ -129,18 +129,18 @@ impl FeImage {
&unclipped_bounds,
);
- if w.approx_eq_cairo(0.0) || h.approx_eq_cairo(0.0) {
+ if r.is_empty() {
return Ok(output_surface);
}
let ptn = surface.to_cairo_pattern();
let mut matrix = cairo::Matrix::new(
- w / f64::from(surface.width()),
- 0f64,
- 0f64,
- h / f64::from(surface.height()),
- x,
- y,
+ r.width() / f64::from(surface.width()),
+ 0.0,
+ 0.0,
+ r.height() / f64::from(surface.height()),
+ r.x0,
+ r.y0,
);
matrix.invert();
ptn.set_matrix(matrix);
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 853d55db..6b47309f 100644
--- a/rsvg_internals/src/handle.rs
+++ b/rsvg_internals/src/handle.rs
@@ -15,7 +15,7 @@ use crate::dpi::Dpi;
use crate::drawing_ctx::DrawingCtx;
use crate::error::{DefsLookupErrorKind, LoadingError, RenderingError};
use crate::node::{CascadedValues, RsvgNode};
-use crate::rect::RectangleExt;
+use crate::rect::{IRect, Rect};
use crate::structure::{IntrinsicDimensions, Svg};
use url::Url;
@@ -276,7 +276,7 @@ impl Handle {
fn get_node_geometry_with_viewport(
&self,
node: &RsvgNode,
- viewport: &cairo::Rectangle,
+ viewport: Rect,
dpi: Dpi,
is_testing: bool,
) -> Result<(cairo::Rectangle, cairo::Rectangle), RenderingError> {
@@ -293,12 +293,13 @@ 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,16 +321,13 @@ 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 logical_r = ink_r;
+ let rect = IRect::from_size(root_width, root_height);
- return Ok((ink_r, logical_r));
+ return Ok((cairo::Rectangle::from(rect), cairo::Rectangle::from(rect)));
}
}
- self.get_node_geometry_with_viewport(&node, &unit_rectangle(), dpi, is_testing)
+ self.get_node_geometry_with_viewport(&node, unit_rectangle(), dpi, is_testing)
}
fn get_node_or_root(&self, id: Option<&str>) -> Result<RsvgNode, RenderingError> {
@@ -348,6 +346,7 @@ impl Handle {
is_testing: bool,
) -> Result<(cairo::Rectangle, cairo::Rectangle), RenderingError> {
let node = self.get_node_or_root(id)?;
+ let viewport = Rect::from(*viewport);
self.get_node_geometry_with_viewport(&node, viewport, dpi, is_testing)
}
@@ -443,7 +442,7 @@ impl Handle {
self.document.clone(),
node.as_ref(),
cr,
- viewport,
+ Rect::from(*viewport),
dpi,
false,
is_testing,
@@ -470,7 +469,7 @@ impl Handle {
self.document.clone(),
None,
&cr,
- &unit_rectangle(),
+ unit_rectangle(),
dpi,
true,
is_testing,
@@ -490,13 +489,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(
@@ -518,7 +520,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(());
@@ -529,17 +531,17 @@ 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(),
None,
&cr,
- &unit_rectangle(),
+ unit_rectangle(),
dpi,
false,
is_testing,
@@ -589,11 +591,6 @@ fn locale_from_environment() -> Locale {
locale
}
-fn unit_rectangle() -> cairo::Rectangle {
- cairo::Rectangle {
- x: 0.0,
- y: 0.0,
- width: 1.0,
- height: 1.0,
- }
+fn unit_rectangle() -> Rect {
+ Rect::from_size(1.0, 1.0)
}
diff --git a/rsvg_internals/src/image.rs b/rsvg_internals/src/image.rs
index 23b4d3af..46f924c6 100644
--- a/rsvg_internals/src/image.rs
+++ b/rsvg_internals/src/image.rs
@@ -1,5 +1,4 @@
use cairo;
-use cairo::Rectangle;
use markup5ever::{expanded_name, local_name, namespace_url, ns};
use crate::allowed_url::Href;
@@ -12,7 +11,7 @@ use crate::length::*;
use crate::node::*;
use crate::parsers::ParseValue;
use crate::property_bag::PropertyBag;
-use crate::rect::RectangleExt;
+use crate::rect::Rect;
use crate::viewbox::ViewBox;
#[derive(Default)]
@@ -99,7 +98,8 @@ 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(cairo::Rectangle::new(x, y, w, h));
+ let rect = Rect::new(x, y, x + w, y + h);
+ let bbox = dc.empty_bbox().with_rect(rect);
dc.with_saved_cr(&mut |dc| {
let cr = dc.get_cairo_context();
@@ -109,7 +109,7 @@ impl NodeTrait for Image {
if let Some(_params) = dc.push_new_viewport(
Some(ViewBox::new(0.0, 0.0, image_width, image_height)),
- &Rectangle::new(x, y, w, h),
+ Rect::new(x, y, x + w, y + h),
self.aspect,
clip_mode,
) {
diff --git a/rsvg_internals/src/marker.rs b/rsvg_internals/src/marker.rs
index 4edbf600..a62c64ec 100644
--- a/rsvg_internals/src/marker.rs
+++ b/rsvg_internals/src/marker.rs
@@ -18,7 +18,7 @@ use crate::parsers::{Parse, ParseValue};
use crate::path_builder::*;
use crate::properties::{ComputedValues, SpecifiedValue, SpecifiedValues};
use crate::property_bag::PropertyBag;
-use crate::rect::RectangleExt;
+use crate::rect::Rect;
use crate::viewbox::*;
// markerUnits attribute: https://www.w3.org/TR/SVG/painting.html#MarkerElement
@@ -150,16 +150,15 @@ impl Marker {
}
let params = if let Some(vbox) = self.vbox {
- let (_, _, w, h) = self.aspect.compute(
- &vbox,
- &cairo::Rectangle::from_size(marker_width, marker_height),
- );
-
if vbox.width.approx_eq_cairo(0.0) || vbox.height.approx_eq_cairo(0.0) {
return Ok(dc.empty_bbox());
}
- cr.scale(w / vbox.width, h / vbox.height);
+ let r = self
+ .aspect
+ .compute(&vbox, &Rect::from_size(marker_width, marker_height));
+
+ cr.scale(r.width() / vbox.width, r.height() / vbox.height);
dc.push_view_box(vbox.width, vbox.height)
} else {
@@ -172,11 +171,13 @@ impl Marker {
);
if !values.is_overflow() {
- if let Some(vbox) = self.vbox {
- dc.clip(vbox.x, vbox.y, vbox.width, vbox.height);
+ let clip_rect = if let Some(vbox) = self.vbox {
+ Rect::new(vbox.x, vbox.y, vbox.x + vbox.width, vbox.y + vbox.height)
} else {
- dc.clip(0.0, 0.0, marker_width, marker_height);
- }
+ Rect::from_size(marker_width, marker_height)
+ };
+
+ dc.clip(clip_rect);
}
dc.with_discrete_layer(node, values, clipping, &mut |dc| {
diff --git a/rsvg_internals/src/mask.rs b/rsvg_internals/src/mask.rs
index ee25288d..b995151e 100644
--- a/rsvg_internals/src/mask.rs
+++ b/rsvg_internals/src/mask.rs
@@ -10,6 +10,7 @@ use crate::node::{CascadedValues, NodeDraw, NodeResult, NodeTrait, RsvgNode};
use crate::parsers::{Parse, ParseValue};
use crate::property_bag::PropertyBag;
use crate::property_defs::Opacity;
+use crate::rect::Rect;
use crate::surface_utils::{shared_surface::SharedImageSurface, shared_surface::SurfaceType};
coord_units!(MaskUnits, CoordUnits::ObjectBoundingBox);
@@ -55,8 +56,8 @@ impl Mask {
}
let bbox_rect = bbox.rect.as_ref().unwrap();
- let (bb_x, bb_y) = (bbox_rect.x, bbox_rect.y);
- let (bb_w, bb_h) = (bbox_rect.width, bbox_rect.height);
+ let (bb_x, bb_y) = (bbox_rect.x0, bbox_rect.y0);
+ let (bb_w, bb_h) = bbox_rect.size();
let cascaded = CascadedValues::new_from_node(mask_node);
let values = cascaded.get();
@@ -96,7 +97,7 @@ impl Mask {
(x, y, w, h)
};
- draw_ctx.clip(x, y, w, h);
+ draw_ctx.clip(Rect::new(x, y, x + w, y + h));
{
let _params = if content_units == CoordUnits::ObjectBoundingBox {
diff --git a/rsvg_internals/src/pattern.rs b/rsvg_internals/src/pattern.rs
index fe65edf5..5354f086 100644
--- a/rsvg_internals/src/pattern.rs
+++ b/rsvg_internals/src/pattern.rs
@@ -16,7 +16,7 @@ use crate::paint_server::{AsPaintSource, PaintSource};
use crate::parsers::ParseValue;
use crate::properties::ComputedValues;
use crate::property_bag::PropertyBag;
-use crate::rect::RectangleExt;
+use crate::rect::Rect;
use crate::unit_interval::UnitInterval;
use crate::viewbox::*;
@@ -259,11 +259,7 @@ impl AsPaintSource for ResolvedPattern {
// Work out the size of the rectangle so it takes into account the object bounding box
let (bbwscale, bbhscale) = match units {
- PatternUnits(CoordUnits::ObjectBoundingBox) => {
- let rect = bbox.rect.unwrap();
- (rect.width, rect.height)
- }
-
+ PatternUnits(CoordUnits::ObjectBoundingBox) => bbox.rect.unwrap().size(),
PatternUnits(CoordUnits::UserSpaceOnUse) => (1.0, 1.0),
};
@@ -298,8 +294,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(),
);
}
@@ -316,23 +312,25 @@ impl AsPaintSource for ResolvedPattern {
// Create the pattern contents coordinate system
let _params = if let Some(vbox) = vbox {
// If there is a vbox, use that
- let (mut x, mut y, w, h) = preserve_aspect_ratio.compute(
+ let r = preserve_aspect_ratio.compute(
&vbox,
- &cairo::Rectangle::from_size(scaled_width, scaled_height),
+ &Rect::from_size(scaled_width, scaled_height),
);
- x -= vbox.x * w / vbox.width;
- y -= vbox.y * h / vbox.height;
+ let sw = r.width() / vbox.width;
+ let sh = r.height() / vbox.height;
+ let x = r.x0 - vbox.x * sw;
+ let y = r.y0 - vbox.y * sh;
- caffine = cairo::Matrix::new(w / vbox.width, 0.0, 0.0, h / vbox.height, x, y);
+ caffine = cairo::Matrix::new(sw, 0.0, 0.0, sh, x, y);
draw_ctx.push_view_box(vbox.width, vbox.height)
} else if content_units == PatternContentUnits(CoordUnits::ObjectBoundingBox) {
// If coords are in terms of the bounding box, use them
- let bbrect = bbox.rect.unwrap();
+ let (bbw, bbh) = bbox.rect.unwrap().size();
caffine = cairo::Matrix::identity();
- caffine.scale(bbrect.width, bbrect.height);
+ caffine.scale(bbw, bbh);
draw_ctx.push_view_box(1.0, 1.0)
} else {
diff --git a/rsvg_internals/src/rect.rs b/rsvg_internals/src/rect.rs
index 9d29127d..162ca1b2 100644
--- a/rsvg_internals/src/rect.rs
+++ b/rsvg_internals/src/rect.rs
@@ -321,16 +321,16 @@ impl RectangleExt for cairo::Rectangle {
}
pub trait TransformRect {
- fn transform_rect(&self, rect: &cairo::Rectangle) -> cairo::Rectangle;
+ fn transform_rect(&self, rect: &Rect) -> Rect;
}
impl TransformRect for cairo::Matrix {
- fn transform_rect(&self, rect: &cairo::Rectangle) -> cairo::Rectangle {
+ fn transform_rect(&self, rect: &Rect) -> Rect {
let points = vec![
- self.transform_point(rect.x, rect.y),
- self.transform_point(rect.x + rect.width, rect.y),
- self.transform_point(rect.x, rect.y + rect.height),
- self.transform_point(rect.x + rect.width, rect.y + rect.height),
+ self.transform_point(rect.x0, rect.y0),
+ self.transform_point(rect.x1, rect.y0),
+ self.transform_point(rect.x0, rect.y1),
+ self.transform_point(rect.x1, rect.y1),
];
let (mut xmin, mut ymin, mut xmax, mut ymax) = {
@@ -357,11 +357,11 @@ impl TransformRect for cairo::Matrix {
}
}
- cairo::Rectangle {
- x: xmin,
- y: ymin,
- width: xmax - xmin,
- height: ymax - ymin,
+ Rect {
+ x0: xmin,
+ y0: ymin,
+ x1: xmax,
+ y1: ymax,
}
}
}
@@ -441,25 +441,4 @@ mod tests {
assert_approx_eq_cairo!(4.34_f64, r.width);
assert_approx_eq_cairo!(4.34_f64, r.height);
}
-
- #[test]
- fn transform_rect() {
- let r = cairo::Rectangle {
- x: 0.42,
- y: 0.42,
- width: 3.14,
- height: 3.14,
- };
-
- let m = cairo::Matrix::identity();
- let tr = m.transform_rect(&r);
- assert_eq!(tr, r);
-
- let m = cairo::Matrix::new(2.0, 0.0, 0.0, 2.0, 1.5, 1.5);
- let tr = m.transform_rect(&r);
- assert_approx_eq_cairo!(2.34_f64, tr.x);
- assert_approx_eq_cairo!(2.34_f64, tr.y);
- assert_approx_eq_cairo!(6.28_f64, tr.width);
- assert_approx_eq_cairo!(6.28_f64, tr.height);
- }
}
diff --git a/rsvg_internals/src/structure.rs b/rsvg_internals/src/structure.rs
index 02c6aa6e..473855cb 100644
--- a/rsvg_internals/src/structure.rs
+++ b/rsvg_internals/src/structure.rs
@@ -1,4 +1,3 @@
-use cairo::Rectangle;
use markup5ever::{expanded_name, local_name, namespace_url, ns};
use crate::allowed_url::Fragment;
@@ -14,7 +13,7 @@ use crate::parsers::{Parse, ParseValue};
use crate::properties::ComputedValues;
use crate::property_bag::PropertyBag;
use crate::property_defs::Overflow;
-use crate::rect::RectangleExt;
+use crate::rect::Rect;
use crate::viewbox::*;
#[derive(Default)]
@@ -162,15 +161,15 @@ impl Svg {
(x, y, w, h)
}
- fn get_viewport(&self, values: &ComputedValues, params: &ViewParams) -> Rectangle {
+ fn get_viewport(&self, values: &ComputedValues, params: &ViewParams) -> Rect {
let (x, y, w, h) = self.get_unnormalized_viewport();
- Rectangle::new(
- x.normalize(values, ¶ms),
- y.normalize(values, ¶ms),
- w.normalize(values, ¶ms),
- h.normalize(values, ¶ms),
- )
+ let nx = x.normalize(values, ¶ms);
+ let ny = y.normalize(values, ¶ms);
+ let nw = w.normalize(values, ¶ms);
+ let nh = h.normalize(values, ¶ms);
+
+ Rect::new(nx, ny, nx + nw, ny + nh)
}
}
@@ -247,8 +246,8 @@ impl NodeTrait for Svg {
Some(ViewBox {
x: 0.0,
y: 0.0,
- width: svg_viewport.width,
- height: svg_viewport.height,
+ width: svg_viewport.width(),
+ height: svg_viewport.height(),
})
}),
)
@@ -256,7 +255,7 @@ impl NodeTrait for Svg {
draw_ctx.with_discrete_layer(node, values, clipping, &mut |dc| {
let _params =
- dc.push_new_viewport(vbox, &viewport, self.preserve_aspect_ratio, clip_mode);
+ dc.push_new_viewport(vbox, viewport, self.preserve_aspect_ratio, clip_mode);
node.draw_children(cascaded, dc, clipping)
})
@@ -376,11 +375,9 @@ impl NodeTrait for Use {
return Ok(draw_ctx.empty_bbox());
}
- let viewport = Rectangle::new(nx, ny, nw, nh);
-
if child.borrow().get_type() != NodeType::Symbol {
let cr = draw_ctx.get_cairo_context();
- cr.translate(viewport.x, viewport.y);
+ cr.translate(nx, ny);
draw_ctx.with_discrete_layer(node, values, clipping, &mut |dc| {
dc.draw_node_from_stack(
@@ -404,7 +401,7 @@ impl NodeTrait for Use {
draw_ctx.with_discrete_layer(node, values, clipping, &mut |dc| {
let _params = dc.push_new_viewport(
symbol.vbox,
- &viewport,
+ Rect::new(nx, ny, nx + nw, ny + nh),
symbol.preserve_aspect_ratio,
clip_mode,
);
diff --git a/rsvg_internals/src/text.rs b/rsvg_internals/src/text.rs
index 90cea086..58c43743 100644
--- a/rsvg_internals/src/text.rs
+++ b/rsvg_internals/src/text.rs
@@ -28,7 +28,7 @@ use crate::property_defs::{
XmlLang,
XmlSpace,
};
-use crate::rect::RectangleExt;
+use crate::rect::Rect;
use crate::space::{xml_space_normalize, NormalizeDefault, XmlSpaceNormalize};
/// An absolutely-positioned array of `Span`s
@@ -352,7 +352,7 @@ impl PositionedSpan {
if !clipping {
let (x0, y0, x1, y1) = cr.stroke_extents();
- let r = cairo::Rectangle::from_extents(x0, y0, x1, y1);
+ let r = Rect::new(x0, y0, x1, y1);
let ib = BoundingBox::new(&affine).with_ink_rect(r);
cr.stroke();
bbox.insert(&ib);
@@ -397,7 +397,7 @@ impl PositionedSpan {
)
};
- let r = cairo::Rectangle::new(x, y, w, h);
+ let r = Rect::new(x, y, x + w, y + h);
let bbox = BoundingBox::new(affine).with_rect(r).with_ink_rect(r);
Some(bbox)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]