[librsvg: 5/7] viewbox: make viewbox a newtype on Rect
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg: 5/7] viewbox: make viewbox a newtype on Rect
- Date: Tue, 10 Dec 2019 13:56:05 +0000 (UTC)
commit d20b4f972175cc934664e5c1edddbbaaa7f50e0e
Author: Paolo Borelli <pborelli gnome org>
Date: Sun Dec 8 19:39:03 2019 +0100
viewbox: make viewbox a newtype on Rect
librsvg/c_api.rs | 8 ++++----
librsvg_crate/src/lib.rs | 7 +------
rsvg_internals/src/aspect_ratio.rs | 11 +++++------
rsvg_internals/src/drawing_ctx.rs | 30 +++++++++---------------------
rsvg_internals/src/filters/image.rs | 6 ++----
rsvg_internals/src/image.rs | 2 +-
rsvg_internals/src/marker.rs | 15 +++++++--------
rsvg_internals/src/pattern.rs | 10 +++++-----
rsvg_internals/src/structure.rs | 12 +++++-------
rsvg_internals/src/viewbox.rs | 34 +++++-----------------------------
10 files changed, 44 insertions(+), 91 deletions(-)
---
diff --git a/librsvg/c_api.rs b/librsvg/c_api.rs
index 7acd53e6..276ec5ee 100644
--- a/librsvg/c_api.rs
+++ b/librsvg/c_api.rs
@@ -229,10 +229,10 @@ impl From<RsvgRectangle> for cairo::Rectangle {
impl From<ViewBox> for RsvgRectangle {
fn from(vb: ViewBox) -> RsvgRectangle {
RsvgRectangle {
- x: vb.x,
- y: vb.y,
- width: vb.width,
- height: vb.height,
+ x: vb.0.x0,
+ y: vb.0.y0,
+ width: vb.0.width(),
+ height: vb.0.height(),
}
}
}
diff --git a/librsvg_crate/src/lib.rs b/librsvg_crate/src/lib.rs
index e1833501..1514b884 100644
--- a/librsvg_crate/src/lib.rs
+++ b/librsvg_crate/src/lib.rs
@@ -465,12 +465,7 @@ impl<'a> CairoRenderer<'a> {
IntrinsicDimensions {
width: d.width.map(Into::into),
height: d.height.map(Into::into),
- vbox: d.vbox.map(|v| cairo::Rectangle {
- x: v.x,
- y: v.y,
- width: v.width,
- height: v.height,
- }),
+ vbox: d.vbox.map(|v| cairo::Rectangle::from(v.0)),
}
}
diff --git a/rsvg_internals/src/aspect_ratio.rs b/rsvg_internals/src/aspect_ratio.rs
index 52941c0b..e77c6a5e 100644
--- a/rsvg_internals/src/aspect_ratio.rs
+++ b/rsvg_internals/src/aspect_ratio.rs
@@ -25,7 +25,6 @@ use std::ops::Deref;
use cairo;
use crate::error::ValueErrorKind;
-use crate::float_eq_cairo::ApproxEqCairo;
use crate::parsers::Parse;
use crate::rect::Rect;
use crate::viewbox::ViewBox;
@@ -130,7 +129,7 @@ impl AspectRatio {
None => *viewport,
Some(Align { x, y, fit }) => {
- let (vb_width, vb_height) = (vbox.width, vbox.height);
+ let (vb_width, vb_height) = vbox.0.size();
let (vp_width, vp_height) = viewport.size();
let w_factor = vp_width / vb_width;
@@ -172,7 +171,7 @@ impl AspectRatio {
// the preserveAspectRatio attribute is only used if viewBox is specified
// https://www.w3.org/TR/SVG/coords.html#PreserveAspectRatioAttribute
if let Some(vbox) = vbox {
- if vbox.width.approx_eq_cairo(0.0) || vbox.height.approx_eq_cairo(0.0) {
+ if vbox.0.is_empty() {
// Width or height of 0 for the viewBox disables rendering of the element
// https://www.w3.org/TR/SVG/coords.html#ViewBoxAttribute
None
@@ -180,8 +179,8 @@ impl AspectRatio {
let r = self.compute(&vbox, viewport);
let mut matrix = cairo::Matrix::identity();
matrix.translate(r.x0, r.y0);
- matrix.scale(r.width() / vbox.width, r.height() / vbox.height);
- matrix.translate(-vbox.x, -vbox.y);
+ matrix.scale(r.width() / vbox.0.width(), r.height() / vbox.0.height());
+ matrix.translate(-vbox.0.x0, -vbox.0.y0);
Some(matrix)
}
} else {
@@ -349,7 +348,7 @@ mod tests {
#[test]
fn aligns() {
- let viewbox = ViewBox::new(0.0, 0.0, 1.0, 10.0);
+ let viewbox = ViewBox(Rect::from_size(1.0, 10.0));
let foo = AspectRatio::parse_str("xMinYMin meet").unwrap();
let foo = foo.compute(&viewbox, &Rect::from_size(10.0, 1.0));
diff --git a/rsvg_internals/src/drawing_ctx.rs b/rsvg_internals/src/drawing_ctx.rs
index ad74c097..03728b19 100644
--- a/rsvg_internals/src/drawing_ctx.rs
+++ b/rsvg_internals/src/drawing_ctx.rs
@@ -115,10 +115,8 @@ impl DrawingCtx {
// while the code gets refactored not to need special cases for that.
let (rect, vbox) = if measuring {
- (
- Rect::from_size(1.0, 1.0),
- ViewBox::new(0.0, 0.0, 1.0, 1.0),
- )
+ let unit_rect = Rect::from_size(1.0, 1.0);
+ (unit_rect, ViewBox(unit_rect))
} else {
// https://www.w3.org/TR/SVG2/coords.html#InitialCoordinateSystem
//
@@ -132,12 +130,7 @@ impl DrawingCtx {
// "... the initial viewport coordinate system (and therefore
// the initial user coordinate system) must have its origin at
// the top/left of the viewport"
- let vbox = ViewBox {
- x: 0.0,
- y: 0.0,
- width: viewport.width(),
- height: viewport.height(),
- };
+ let vbox = ViewBox(Rect::from_size(viewport.width(), viewport.height()));
(viewport, vbox)
};
@@ -255,13 +248,13 @@ impl DrawingCtx {
pub fn get_view_params(&self) -> ViewParams {
let view_box_stack = self.view_box_stack.borrow();
let last = view_box_stack.len() - 1;
- let stack_top = &view_box_stack[last];
+ let top_rect = &view_box_stack[last].0;
ViewParams {
dpi_x: self.dpi.x(),
dpi_y: self.dpi.y(),
- view_box_width: stack_top.width,
- view_box_height: stack_top.height,
+ view_box_width: top_rect.width(),
+ view_box_height: top_rect.height(),
view_box_stack: None,
}
}
@@ -276,7 +269,7 @@ impl DrawingCtx {
pub fn push_view_box(&self, width: f64, height: f64) -> ViewParams {
self.view_box_stack
.borrow_mut()
- .push(ViewBox::new(0.0, 0.0, width, height));
+ .push(ViewBox(Rect::from_size(width, height)));
ViewParams {
dpi_x: self.dpi.x(),
@@ -308,16 +301,11 @@ impl DrawingCtx {
if let Some(vbox) = vbox {
if let Some(ref clip) = clip_mode {
if *clip == ClipMode::ClipToVbox {
- self.clip(Rect::new(
- vbox.x,
- vbox.y,
- vbox.x + vbox.width,
- vbox.y + vbox.height,
- ));
+ self.clip(vbox.0);
}
}
- Some(self.push_view_box(vbox.width, vbox.height))
+ Some(self.push_view_box(vbox.0.width(), vbox.0.height()))
} else {
Some(self.get_view_params())
}
diff --git a/rsvg_internals/src/filters/image.rs b/rsvg_internals/src/filters/image.rs
index 9e668038..2018989f 100644
--- a/rsvg_internals/src/filters/image.rs
+++ b/rsvg_internals/src/filters/image.rs
@@ -120,12 +120,10 @@ impl FeImage {
// TODO: this goes through a f64->i32->f64 conversion.
let r = self.aspect.compute(
- &ViewBox::new(
- 0.0,
- 0.0,
+ &ViewBox(Rect::from_size(
f64::from(surface.width()),
f64::from(surface.height()),
- ),
+ )),
&unclipped_bounds,
);
diff --git a/rsvg_internals/src/image.rs b/rsvg_internals/src/image.rs
index 46f924c6..f3f65396 100644
--- a/rsvg_internals/src/image.rs
+++ b/rsvg_internals/src/image.rs
@@ -108,7 +108,7 @@ impl NodeTrait for Image {
let image_height = f64::from(image_height);
if let Some(_params) = dc.push_new_viewport(
- Some(ViewBox::new(0.0, 0.0, image_width, image_height)),
+ Some(ViewBox(Rect::from_size(image_width, image_height))),
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 a62c64ec..a396fb0c 100644
--- a/rsvg_internals/src/marker.rs
+++ b/rsvg_internals/src/marker.rs
@@ -150,7 +150,7 @@ impl Marker {
}
let params = if let Some(vbox) = self.vbox {
- if vbox.width.approx_eq_cairo(0.0) || vbox.height.approx_eq_cairo(0.0) {
+ if vbox.0.is_empty() {
return Ok(dc.empty_bbox());
}
@@ -158,9 +158,10 @@ impl Marker {
.aspect
.compute(&vbox, &Rect::from_size(marker_width, marker_height));
- cr.scale(r.width() / vbox.width, r.height() / vbox.height);
+ let (vb_width, vb_height) = vbox.0.size();
+ cr.scale(r.width() / vb_width, r.height() / vb_height);
- dc.push_view_box(vbox.width, vbox.height)
+ dc.push_view_box(vb_width, vb_height)
} else {
dc.push_view_box(marker_width, marker_height)
};
@@ -171,11 +172,9 @@ impl Marker {
);
if !values.is_overflow() {
- let clip_rect = if let Some(vbox) = self.vbox {
- Rect::new(vbox.x, vbox.y, vbox.x + vbox.width, vbox.y + vbox.height)
- } else {
- Rect::from_size(marker_width, marker_height)
- };
+ let clip_rect = self
+ .vbox
+ .map_or_else(|| Rect::from_size(marker_width, marker_height), |vb| vb.0);
dc.clip(clip_rect);
}
diff --git a/rsvg_internals/src/pattern.rs b/rsvg_internals/src/pattern.rs
index 5354f086..bfefbe2a 100644
--- a/rsvg_internals/src/pattern.rs
+++ b/rsvg_internals/src/pattern.rs
@@ -317,14 +317,14 @@ impl AsPaintSource for ResolvedPattern {
&Rect::from_size(scaled_width, scaled_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;
+ let sw = r.width() / vbox.0.width();
+ let sh = r.height() / vbox.0.height();
+ let x = r.x0 - vbox.0.x0 * sw;
+ let y = r.y0 - vbox.0.y0 * sh;
caffine = cairo::Matrix::new(sw, 0.0, 0.0, sh, x, y);
- draw_ctx.push_view_box(vbox.width, vbox.height)
+ draw_ctx.push_view_box(vbox.0.width(), vbox.0.height())
} else if content_units == PatternContentUnits(CoordUnits::ObjectBoundingBox) {
// If coords are in terms of the bounding box, use them
let (bbw, bbh) = bbox.rect.unwrap().size();
diff --git a/rsvg_internals/src/structure.rs b/rsvg_internals/src/structure.rs
index 473855cb..c06deaf5 100644
--- a/rsvg_internals/src/structure.rs
+++ b/rsvg_internals/src/structure.rs
@@ -107,7 +107,7 @@ impl Svg {
match (w, h, self.vbox) {
(w, h, Some(vbox)) => {
- let params = ViewParams::new(dpi.x(), dpi.y(), vbox.width, vbox.height);
+ let params = ViewParams::new(dpi.x(), dpi.y(), vbox.0.width(), vbox.0.height());
Some((
w.normalize(values, ¶ms).round() as i32,
@@ -243,12 +243,10 @@ impl NodeTrait for Svg {
// Use our viewBox if available, or try to derive one from
// the intrinsic dimensions.
self.vbox.or_else(|| {
- Some(ViewBox {
- x: 0.0,
- y: 0.0,
- width: svg_viewport.width(),
- height: svg_viewport.height(),
- })
+ Some(ViewBox(Rect::from_size(
+ svg_viewport.width(),
+ svg_viewport.height(),
+ )))
}),
)
};
diff --git a/rsvg_internals/src/viewbox.rs b/rsvg_internals/src/viewbox.rs
index ac18d4d9..0f59c0f8 100644
--- a/rsvg_internals/src/viewbox.rs
+++ b/rsvg_internals/src/viewbox.rs
@@ -3,30 +3,10 @@ use cssparser::Parser;
use crate::error::*;
use crate::number_list::{NumberList, NumberListLength};
use crate::parsers::Parse;
+use crate::rect::Rect;
#[derive(Debug, Copy, Clone, PartialEq)]
-pub struct ViewBox {
- pub x: f64,
- pub y: f64,
- pub width: f64,
- pub height: f64,
-}
-
-impl ViewBox {
- pub fn new(x: f64, y: f64, w: f64, h: f64) -> ViewBox {
- assert!(
- w >= 0.0 && h >= 0.0,
- "width and height must not be negative"
- );
-
- ViewBox {
- x,
- y,
- width: w,
- height: h,
- }
- }
-}
+pub struct ViewBox(pub Rect);
impl Parse for ViewBox {
// Parse a viewBox attribute
@@ -46,7 +26,7 @@ impl Parse for ViewBox {
let (x, y, width, height) = (v[0], v[1], v[2], v[3]);
if width >= 0.0 && height >= 0.0 {
- Ok(ViewBox::new(x, y, width, height))
+ Ok(ViewBox(Rect::new(x, y, x + width, y + height)))
} else {
Err(ValueErrorKind::value_error("width and height must not be negative"))
}
@@ -61,25 +41,21 @@ mod tests {
fn parses_valid_viewboxes() {
assert_eq!(
ViewBox::parse_str(" 1 2 3 4"),
- Ok(ViewBox::new(1.0, 2.0, 3.0, 4.0))
+ Ok(ViewBox(Rect::new(1.0, 2.0, 4.0, 6.0)))
);
assert_eq!(
ViewBox::parse_str(" -1.5 -2.5e1,34,56e2 "),
- Ok(ViewBox::new(-1.5, -25.0, 34.0, 5600.0))
+ Ok(ViewBox(Rect::new(-1.5, -25.0, 32.5, 5575.0)))
);
}
#[test]
fn parsing_invalid_viewboxes_yields_error() {
assert!(is_parse_error(&ViewBox::parse_str("")));
-
assert!(is_value_error(&ViewBox::parse_str(" 1,2,-3,-4 ")));
-
assert!(is_parse_error(&ViewBox::parse_str("qwerasdfzxcv")));
-
assert!(is_parse_error(&ViewBox::parse_str(" 1 2 3 4 5")));
-
assert!(is_parse_error(&ViewBox::parse_str(" 1 2 foo 3 4")));
// https://gitlab.gnome.org/GNOME/librsvg/issues/344
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]