[librsvg] librsvg_crate: geometry_for_element() now takes a viewport
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg] librsvg_crate: geometry_for_element() now takes a viewport
- Date: Tue, 5 Mar 2019 01:29:34 +0000 (UTC)
commit 1ab33c940c940b5484713f8fbba8c1cb2ea6f6ad
Author: Federico Mena Quintero <federico gnome org>
Date: Mon Mar 4 19:27:02 2019 -0600
librsvg_crate: geometry_for_element() now takes a viewport
SVG really wants to be rendered/measured as *scalable*, based on the
viewport size you want it in.
This is especially important for SVGs which have percent dimensions:
<svg width="100%" height="100%" viewBox=...>
In those, asking for the dimensions of an element doesn't make sense
unless there's a viewport size against which the "100%" will be
resolved.
In the C API, we resolved percent sizes to "SVG has no size".
librsvg_crate/src/lib.rs | 6 ++--
librsvg_crate/tests/intrinsic-dimensions.rs | 53 +++++++++++++++++++++++++----
rsvg_internals/src/handle.rs | 13 +++++--
3 files changed, 61 insertions(+), 11 deletions(-)
---
diff --git a/librsvg_crate/src/lib.rs b/librsvg_crate/src/lib.rs
index b3231d7b..a7741baf 100644
--- a/librsvg_crate/src/lib.rs
+++ b/librsvg_crate/src/lib.rs
@@ -377,7 +377,8 @@ impl<'a> CairoRenderer<'a> {
}
}
- /// Computes the (ink_rect, logical_rect) of an SVG element.
+ /// Computes the (ink_rect, logical_rect) of an SVG element, as if
+ /// it were rendered to a specific viewport.
///
/// Element IDs should look like an URL fragment identifier; for
/// example, pass `Some("#foo")` to get the geometry of the
@@ -403,10 +404,11 @@ impl<'a> CairoRenderer<'a> {
pub fn geometry_for_element(
&self,
id: Option<&str>,
+ viewport: &cairo::Rectangle,
) -> Result<(cairo::Rectangle, cairo::Rectangle), RenderingError> {
self.handle
.0
- .get_geometry_for_element(id)
+ .get_geometry_for_element(id, viewport)
.map(|(i, l)| (i.into(), l.into()))
}
diff --git a/librsvg_crate/tests/intrinsic-dimensions.rs b/librsvg_crate/tests/intrinsic-dimensions.rs
index 564ad2c5..a132eb34 100644
--- a/librsvg_crate/tests/intrinsic-dimensions.rs
+++ b/librsvg_crate/tests/intrinsic-dimensions.rs
@@ -79,7 +79,15 @@ fn root_geometry_with_percent_viewport() {
);
let renderer = CairoRenderer::new(&svg);
- let (ink_r, logical_r) = renderer.geometry_for_element(None).unwrap();
+
+ let viewport = cairo::Rectangle {
+ x: 0.0,
+ y: 0.0,
+ width: 100.0,
+ height: 100.0,
+ };
+
+ let (ink_r, logical_r) = renderer.geometry_for_element(None, &viewport).unwrap();
let rect = cairo::Rectangle {
x: 10.0,
@@ -102,7 +110,15 @@ fn element_geometry_with_percent_viewport() {
);
let renderer = CairoRenderer::new(&svg);
- let (ink_r, logical_r) = renderer.geometry_for_element(Some("#foo")).unwrap();
+
+ let viewport = cairo::Rectangle {
+ x: 0.0,
+ y: 0.0,
+ width: 100.0,
+ height: 100.0,
+ };
+
+ let (ink_r, logical_r) = renderer.geometry_for_element(Some("#foo"), &viewport).unwrap();
let rect = cairo::Rectangle {
x: 10.0,
@@ -126,7 +142,15 @@ fn element_geometry_viewport_viewbox() {
);
let renderer = CairoRenderer::new(&svg);
- let (ink_r, logical_r) = renderer.geometry_for_element(Some("#two")).unwrap();
+
+ let viewport = cairo::Rectangle {
+ x: 0.0,
+ y: 0.0,
+ width: 100.0,
+ height: 400.0,
+ };
+
+ let (ink_r, logical_r) = renderer.geometry_for_element(Some("#two"), &viewport).unwrap();
let rect = cairo::Rectangle {
x: 0.0,
@@ -146,8 +170,16 @@ fn element_geometry_for_nonexistent_element() {
"#,
);
+ let viewport = cairo::Rectangle {
+ x: 0.0,
+ y: 0.0,
+ width: 100.0,
+ height: 100.0,
+ };
+
let renderer = CairoRenderer::new(&svg);
- match renderer.geometry_for_element(Some("#foo")) {
+
+ match renderer.geometry_for_element(Some("#foo"), &viewport) {
Err(RenderingError::InvalidId(DefsLookupErrorKind::NotFound)) => (),
_ => panic!(),
}
@@ -161,18 +193,25 @@ fn element_geometry_for_invalid_id() {
"#,
);
+ let viewport = cairo::Rectangle {
+ x: 0.0,
+ y: 0.0,
+ width: 100.0,
+ height: 100.0,
+ };
+
let renderer = CairoRenderer::new(&svg);
- match renderer.geometry_for_element(Some("foo")) {
+ match renderer.geometry_for_element(Some("foo"), &viewport) {
Err(RenderingError::InvalidId(DefsLookupErrorKind::CannotLookupExternalReferences)) => (),
_ => panic!(),
}
- match renderer.geometry_for_element(Some("foo.svg#foo")) {
+ match renderer.geometry_for_element(Some("foo.svg#foo"), &viewport) {
Err(RenderingError::InvalidId(DefsLookupErrorKind::CannotLookupExternalReferences)) => (),
_ => panic!(),
}
- match renderer.geometry_for_element(Some("")) {
+ match renderer.geometry_for_element(Some(""), &viewport) {
Err(RenderingError::InvalidId(DefsLookupErrorKind::HrefError(HrefError::ParseError))) => (),
_ => panic!(),
}
diff --git a/rsvg_internals/src/handle.rs b/rsvg_internals/src/handle.rs
index 41bb1751..22b27a72 100644
--- a/rsvg_internals/src/handle.rs
+++ b/rsvg_internals/src/handle.rs
@@ -448,9 +448,17 @@ impl Handle {
height: 1.0,
};
+ self.get_node_geometry_with_viewport(node, &viewport)
+ }
+
+ fn get_node_geometry_with_viewport(
+ &self,
+ node: &RsvgNode,
+ viewport: &cairo::Rectangle,
+ ) -> Result<(RsvgRectangle, RsvgRectangle), RenderingError> {
let target = ImageSurface::create(cairo::Format::Rgb24, 1, 1)?;
let cr = cairo::Context::new(&target);
- let mut draw_ctx = self.create_drawing_ctx_for_node(&cr, &viewport, Some(node));
+ let mut draw_ctx = self.create_drawing_ctx_for_node(&cr, viewport, Some(node));
let root = self.get_root();
draw_ctx.draw_node_from_stack(&root.get_cascaded_values(), &root, false)?;
@@ -513,9 +521,10 @@ impl Handle {
pub fn get_geometry_for_element(
&self,
id: Option<&str>,
+ viewport: &cairo::Rectangle,
) -> Result<(RsvgRectangle, RsvgRectangle), RenderingError> {
let node = self.get_node_or_root(id)?;
- self.get_node_geometry(&node)
+ self.get_node_geometry_with_viewport(&node, viewport)
}
fn lookup_node(&self, id: &str) -> Result<RsvgNode, DefsLookupErrorKind> {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]