[librsvg/wip/dimensions-api] AspectRatio.compute(): take the destination viewport as a cairo::Rectangle
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg/wip/dimensions-api] AspectRatio.compute(): take the destination viewport as a cairo::Rectangle
- Date: Sat, 9 Feb 2019 17:49:27 +0000 (UTC)
commit 8368470b13cf09a3a3a46101f3e1f114a1e37b35
Author: Federico Mena Quintero <federico gnome org>
Date: Fri Feb 8 20:15:33 2019 -0600
AspectRatio.compute(): take the destination viewport as a cairo::Rectangle
... and actually name the argument "viewport", since that is what the
SVG spec calls it.
rsvg_internals/src/aspect_ratio.rs | 113 ++++++++++++++++++++++++++----------
rsvg_internals/src/filters/image.rs | 14 +++--
rsvg_internals/src/image.rs | 8 ++-
rsvg_internals/src/marker.rs | 11 ++--
rsvg_internals/src/pattern.rs | 14 +++--
rsvg_internals/src/rect.rs | 10 ++++
rsvg_internals/src/viewport.rs | 6 +-
7 files changed, 124 insertions(+), 52 deletions(-)
---
diff --git a/rsvg_internals/src/aspect_ratio.rs b/rsvg_internals/src/aspect_ratio.rs
index f686b336..8af83ed3 100644
--- a/rsvg_internals/src/aspect_ratio.rs
+++ b/rsvg_internals/src/aspect_ratio.rs
@@ -22,6 +22,8 @@
use std::ops::Deref;
+use cairo;
+
use cssparser::{CowRcStr, Parser};
use error::ValueErrorKind;
use parsers::Parse;
@@ -122,20 +124,13 @@ impl AspectRatio {
}
}
- pub fn compute(
- &self,
- vbox: &ViewBox,
- dest_x: f64,
- dest_y: f64,
- dest_width: f64,
- dest_height: f64,
- ) -> (f64, f64, f64, f64) {
+ pub fn compute(&self, vbox: &ViewBox, viewport: &cairo::Rectangle) -> (f64, f64, f64, f64) {
match self.align {
- None => (dest_x, dest_y, dest_width, dest_height),
+ None => (viewport.x, viewport.y, viewport.width, viewport.height),
Some(Align { x, y, fit }) => {
- let w_factor = dest_width / vbox.width;
- let h_factor = dest_height / vbox.height;
+ let w_factor = viewport.width / vbox.width;
+ let h_factor = viewport.height / vbox.height;
let factor = match fit {
FitMode::Meet => w_factor.min(h_factor),
FitMode::Slice => w_factor.max(h_factor),
@@ -144,8 +139,8 @@ impl AspectRatio {
let w = vbox.width * factor;
let h = vbox.height * factor;
- let xpos = x.compute(dest_x, dest_width, w);
- let ypos = y.compute(dest_y, dest_height, h);
+ let xpos = x.compute(viewport.x, viewport.width, w);
+ let ypos = y.compute(viewport.y, viewport.height, h);
(xpos, ypos, w, h)
}
@@ -216,7 +211,9 @@ impl Parse for AspectRatio {
#[cfg(test)]
mod tests {
use super::*;
+ use cairo::Rectangle;
use float_eq_cairo::ApproxEqCairo;
+ use rect::RectangleExt;
#[test]
fn parsing_invalid_strings_yields_error() {
@@ -311,75 +308,129 @@ mod tests {
#[test]
fn aligns() {
let foo = AspectRatio::parse_str("xMinYMin meet").unwrap();
- let foo = foo.compute(&ViewBox::new(0.0, 0.0, 1.0, 10.0), 0.0, 0.0, 10.0, 1.0);
+ 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 = AspectRatio::parse_str("xMinYMin slice").unwrap();
- let foo = foo.compute(&ViewBox::new(0.0, 0.0, 1.0, 10.0), 0.0, 0.0, 10.0, 1.0);
+ 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 = AspectRatio::parse_str("xMinYMid meet").unwrap();
- let foo = foo.compute(&ViewBox::new(0.0, 0.0, 1.0, 10.0), 0.0, 0.0, 10.0, 1.0);
+ 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 = AspectRatio::parse_str("xMinYMid slice").unwrap();
- let foo = foo.compute(&ViewBox::new(0.0, 0.0, 1.0, 10.0), 0.0, 0.0, 10.0, 1.0);
+ 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 = AspectRatio::parse_str("xMinYMax meet").unwrap();
- let foo = foo.compute(&ViewBox::new(0.0, 0.0, 1.0, 10.0), 0.0, 0.0, 10.0, 1.0);
+ 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 = AspectRatio::parse_str("xMinYMax slice").unwrap();
- let foo = foo.compute(&ViewBox::new(0.0, 0.0, 1.0, 10.0), 0.0, 0.0, 10.0, 1.0);
+ 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 = AspectRatio::parse_str("xMidYMin meet").unwrap();
- let foo = foo.compute(&ViewBox::new(0.0, 0.0, 1.0, 10.0), 0.0, 0.0, 10.0, 1.0);
+ 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 = AspectRatio::parse_str("xMidYMin slice").unwrap();
- let foo = foo.compute(&ViewBox::new(0.0, 0.0, 1.0, 10.0), 0.0, 0.0, 10.0, 1.0);
+ 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 = AspectRatio::parse_str("xMidYMid meet").unwrap();
- let foo = foo.compute(&ViewBox::new(0.0, 0.0, 1.0, 10.0), 0.0, 0.0, 10.0, 1.0);
+ 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 = AspectRatio::parse_str("xMidYMid slice").unwrap();
- let foo = foo.compute(&ViewBox::new(0.0, 0.0, 1.0, 10.0), 0.0, 0.0, 10.0, 1.0);
+ 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 = AspectRatio::parse_str("xMidYMax meet").unwrap();
- let foo = foo.compute(&ViewBox::new(0.0, 0.0, 1.0, 10.0), 0.0, 0.0, 10.0, 1.0);
+ 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 = AspectRatio::parse_str("xMidYMax slice").unwrap();
- let foo = foo.compute(&ViewBox::new(0.0, 0.0, 1.0, 10.0), 0.0, 0.0, 10.0, 1.0);
+ 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 = AspectRatio::parse_str("xMaxYMin meet").unwrap();
- let foo = foo.compute(&ViewBox::new(0.0, 0.0, 1.0, 10.0), 0.0, 0.0, 10.0, 1.0);
+ 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 = AspectRatio::parse_str("xMaxYMin slice").unwrap();
- let foo = foo.compute(&ViewBox::new(0.0, 0.0, 1.0, 10.0), 0.0, 0.0, 10.0, 1.0);
+ 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 = AspectRatio::parse_str("xMaxYMid meet").unwrap();
- let foo = foo.compute(&ViewBox::new(0.0, 0.0, 1.0, 10.0), 0.0, 0.0, 10.0, 1.0);
+ 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 = AspectRatio::parse_str("xMaxYMid slice").unwrap();
- let foo = foo.compute(&ViewBox::new(0.0, 0.0, 1.0, 10.0), 0.0, 0.0, 10.0, 1.0);
+ 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 = AspectRatio::parse_str("xMaxYMax meet").unwrap();
- let foo = foo.compute(&ViewBox::new(0.0, 0.0, 1.0, 10.0), 0.0, 0.0, 10.0, 1.0);
+ 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 = AspectRatio::parse_str("xMaxYMax slice").unwrap();
- let foo = foo.compute(&ViewBox::new(0.0, 0.0, 1.0, 10.0), 0.0, 0.0, 10.0, 1.0);
+ 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));
}
}
diff --git a/rsvg_internals/src/filters/image.rs b/rsvg_internals/src/filters/image.rs
index bb28e456..e517a31e 100644
--- a/rsvg_internals/src/filters/image.rs
+++ b/rsvg_internals/src/filters/image.rs
@@ -1,6 +1,6 @@
use std::cell::{Cell, RefCell};
-use cairo::{self, ImageSurface, MatrixTrait, PatternTrait};
+use cairo::{self, ImageSurface, MatrixTrait, PatternTrait, Rectangle};
use allowed_url::{Fragment, Href};
use aspect_ratio::AspectRatio;
@@ -11,7 +11,7 @@ use float_eq_cairo::ApproxEqCairo;
use node::{CascadedValues, NodeResult, NodeTrait, RsvgNode};
use parsers::{ParseError, ParseValue};
use property_bag::PropertyBag;
-use rect::IRect;
+use rect::{IRect, RectangleExt};
use surface_utils::shared_surface::{SharedImageSurface, SurfaceType};
use viewbox::ViewBox;
@@ -134,10 +134,12 @@ impl Image {
f64::from(surface.width()),
f64::from(surface.height()),
),
- f64::from(render_bounds.x0),
- f64::from(render_bounds.y0),
- f64::from(render_bounds.x1 - render_bounds.x0),
- f64::from(render_bounds.y1 - render_bounds.y0),
+ &Rectangle::new(
+ f64::from(render_bounds.x0),
+ f64::from(render_bounds.y0),
+ f64::from(render_bounds.x1 - render_bounds.x0),
+ f64::from(render_bounds.y1 - render_bounds.y0),
+ ),
);
if w.approx_eq_cairo(&0.0) || h.approx_eq_cairo(&0.0) {
diff --git a/rsvg_internals/src/image.rs b/rsvg_internals/src/image.rs
index a3f0306b..01fc92b2 100644
--- a/rsvg_internals/src/image.rs
+++ b/rsvg_internals/src/image.rs
@@ -1,5 +1,5 @@
use cairo;
-use cairo::{MatrixTrait, PatternTrait};
+use cairo::{MatrixTrait, PatternTrait, Rectangle};
use std::cell::{Cell, RefCell};
use allowed_url::Href;
@@ -13,6 +13,7 @@ use length::{LengthHorizontal, LengthVertical};
use node::*;
use parsers::{ParseError, ParseValue};
use property_bag::PropertyBag;
+use rect::RectangleExt;
use viewbox::ViewBox;
pub struct NodeImage {
@@ -124,7 +125,10 @@ impl NodeTrait for NodeImage {
let width = f64::from(width);
let height = f64::from(height);
- let (x, y, w, h) = aspect.compute(&ViewBox::new(0.0, 0.0, width, height), x, y, w, h);
+ let (x, y, w, h) = aspect.compute(
+ &ViewBox::new(0.0, 0.0, width, height),
+ &Rectangle::new(x, y, w, h),
+ );
let cr = dc.get_cairo_context();
diff --git a/rsvg_internals/src/marker.rs b/rsvg_internals/src/marker.rs
index 082eb90e..fa401e8a 100644
--- a/rsvg_internals/src/marker.rs
+++ b/rsvg_internals/src/marker.rs
@@ -2,7 +2,7 @@ use std::cell::Cell;
use std::f64::consts::*;
use std::ops::Deref;
-use cairo::MatrixTrait;
+use cairo::{MatrixTrait, Rectangle};
use cssparser::{CowRcStr, Parser, Token};
use allowed_url::Fragment;
@@ -19,6 +19,7 @@ use parsers::{Parse, ParseError, ParseValue};
use path_builder::*;
use properties::{ComputedValues, SpecifiedValue, SpecifiedValues};
use property_bag::PropertyBag;
+use rect::RectangleExt;
use viewbox::*;
// markerUnits attribute: https://www.w3.org/TR/SVG/painting.html#MarkerElement
@@ -152,10 +153,10 @@ impl NodeMarker {
}
let params = if let Some(vbox) = self.vbox.get() {
- let (_, _, w, h) =
- self.aspect
- .get()
- .compute(&vbox, 0.0, 0.0, marker_width, marker_height);
+ let (_, _, w, h) = self.aspect.get().compute(
+ &vbox,
+ &Rectangle::new(0.0, 0.0, marker_width, marker_height),
+ );
if vbox.width.approx_eq_cairo(&0.0) || vbox.height.approx_eq_cairo(&0.0) {
return Ok(());
diff --git a/rsvg_internals/src/pattern.rs b/rsvg_internals/src/pattern.rs
index 28634956..6e0b51db 100644
--- a/rsvg_internals/src/pattern.rs
+++ b/rsvg_internals/src/pattern.rs
@@ -1,6 +1,5 @@
use cairo;
-use cairo::MatrixTrait;
-use cairo::PatternTrait;
+use cairo::{MatrixTrait, PatternTrait};
use std::cell::RefCell;
use std::f64;
use std::rc::*;
@@ -19,6 +18,7 @@ use paint_server::PaintSource;
use parsers::ParseValue;
use properties::ComputedValues;
use property_bag::PropertyBag;
+use rect::RectangleExt;
use unit_interval::UnitInterval;
use viewbox::*;
@@ -368,10 +368,12 @@ impl PaintSource for NodePattern {
// If there is a vbox, use that
let (mut x, mut y, w, h) = preserve_aspect_ratio.compute(
&vbox,
- 0.0,
- 0.0,
- pattern_width * bbwscale,
- pattern_height * bbhscale,
+ &cairo::Rectangle::new(
+ 0.0,
+ 0.0,
+ pattern_width * bbwscale,
+ pattern_height * bbhscale,
+ ),
);
x -= vbox.x * w / vbox.width;
diff --git a/rsvg_internals/src/rect.rs b/rsvg_internals/src/rect.rs
index dc43aec5..c2035152 100644
--- a/rsvg_internals/src/rect.rs
+++ b/rsvg_internals/src/rect.rs
@@ -4,6 +4,7 @@ use cairo::MatrixTrait;
use float_eq_cairo::ApproxEqCairo;
pub trait RectangleExt {
+ fn new(x: f64, y: f64, width: f64, height: f64) -> cairo::Rectangle;
fn is_empty(&self) -> bool;
fn intersect(&self, rect: &cairo::Rectangle) -> cairo::Rectangle;
fn union(&self, rect: &cairo::Rectangle) -> cairo::Rectangle;
@@ -12,6 +13,15 @@ pub trait RectangleExt {
}
impl RectangleExt for cairo::Rectangle {
+ fn new(x: f64, y: f64, width: f64, height: f64) -> cairo::Rectangle {
+ cairo::Rectangle {
+ x,
+ y,
+ width,
+ height,
+ }
+ }
+
fn is_empty(&self) -> bool {
self.width.approx_eq_cairo(&0.0) || self.height.approx_eq_cairo(&0.0)
}
diff --git a/rsvg_internals/src/viewport.rs b/rsvg_internals/src/viewport.rs
index 3f9103d8..f2641cf5 100644
--- a/rsvg_internals/src/viewport.rs
+++ b/rsvg_internals/src/viewport.rs
@@ -1,5 +1,5 @@
use cairo;
-use cairo::MatrixTrait;
+use cairo::{MatrixTrait, Rectangle};
use aspect_ratio::AspectRatio;
use drawing_ctx::DrawingCtx;
@@ -7,6 +7,7 @@ use error::RenderingError;
use float_eq_cairo::ApproxEqCairo;
use node::RsvgNode;
use properties::ComputedValues;
+use rect::RectangleExt;
use viewbox::*;
#[derive(Debug, Copy, Clone, PartialEq)]
@@ -59,7 +60,8 @@ pub fn draw_in_viewport(
let params = dc.push_view_box(vbox.width, vbox.height);
- let (x, y, w, h) = preserve_aspect_ratio.compute(&vbox, vx, vy, vw, vh);
+ let (x, y, w, h) =
+ preserve_aspect_ratio.compute(&vbox, &Rectangle::new(vx, vy, vw, vh));
affine.translate(x, y);
affine.scale(w / vbox.width, h / vbox.height);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]