[librsvg] DrawingCtx::push_view_box(): Return a ViewParams object
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg] DrawingCtx::push_view_box(): Return a ViewParams object
- Date: Wed, 12 Sep 2018 11:54:18 +0000 (UTC)
commit 36fe10413222b4e2d5163e843c5ec1b8d90507c6
Author: Federico Mena Quintero <federico gnome org>
Date: Tue Sep 4 15:02:08 2018 -0500
DrawingCtx::push_view_box(): Return a ViewParams object
We will later make this object pop the viewbox when dropped.
rsvg_internals/src/drawing_ctx.rs | 4 +-
rsvg_internals/src/filters/context.rs | 12 +++---
rsvg_internals/src/gradient.rs | 62 ++++++++++++++++---------------
rsvg_internals/src/marker.rs | 10 ++---
rsvg_internals/src/mask.rs | 70 +++++++++++++++++++----------------
rsvg_internals/src/pattern.rs | 37 ++++++++++--------
rsvg_internals/src/viewport.rs | 11 ++++--
7 files changed, 114 insertions(+), 92 deletions(-)
---
diff --git a/rsvg_internals/src/drawing_ctx.rs b/rsvg_internals/src/drawing_ctx.rs
index 1f9e82c2..c58b9534 100644
--- a/rsvg_internals/src/drawing_ctx.rs
+++ b/rsvg_internals/src/drawing_ctx.rs
@@ -191,9 +191,11 @@ impl<'a> DrawingCtx<'a> {
}
}
- pub fn push_view_box(&mut self, width: f64, height: f64) {
+ pub fn push_view_box(&mut self, width: f64, height: f64) -> ViewParams {
self.vb_stack.push(self.vb);
self.vb = ViewBox::new(0.0, 0.0, width, height);
+
+ self.get_view_params()
}
pub fn pop_view_box(&mut self) {
diff --git a/rsvg_internals/src/filters/context.rs b/rsvg_internals/src/filters/context.rs
index 98c5eb50..1a5aecbc 100644
--- a/rsvg_internals/src/filters/context.rs
+++ b/rsvg_internals/src/filters/context.rs
@@ -125,9 +125,11 @@ fn compute_effects_region(
// It's done this way because with ObjectBoundingBox, non-percentage values are supposed to
// represent the fractions of the referenced node, and with width and height = 1, 1 this
// works out exactly like that.
- if filter.filterunits.get() == CoordUnits::ObjectBoundingBox {
- draw_ctx.push_view_box(1.0, 1.0);
- }
+ let params = if filter.filterunits.get() == CoordUnits::ObjectBoundingBox {
+ draw_ctx.push_view_box(1.0, 1.0)
+ } else {
+ draw_ctx.get_view_params()
+ };
// With filterunits == ObjectBoundingBox, lengths represent fractions or percentages of the
// referencing node. No units are allowed (it's checked during attribute parsing).
@@ -139,8 +141,6 @@ fn compute_effects_region(
height: filter.height.get().get_unitless(),
}
} else {
- let params = draw_ctx.get_view_params();
-
cairo::Rectangle {
x: filter.x.get().normalize(values, ¶ms),
y: filter.y.get().normalize(values, ¶ms),
@@ -445,7 +445,7 @@ impl FilterContext {
// See comments in compute_effects_region() for how this works.
if filter.primitiveunits.get() == CoordUnits::ObjectBoundingBox {
- draw_ctx.push_view_box(1.0, 1.0);
+ let _params = draw_ctx.push_view_box(1.0, 1.0);
let rv = f(Box::new(Length::get_unitless));
draw_ctx.pop_view_box();
diff --git a/rsvg_internals/src/gradient.rs b/rsvg_internals/src/gradient.rs
index ea1186f6..bcde6f06 100644
--- a/rsvg_internals/src/gradient.rs
+++ b/rsvg_internals/src/gradient.rs
@@ -502,24 +502,26 @@ fn set_linear_gradient_on_pattern(
if let GradientVariant::Linear { x1, y1, x2, y2 } = gradient.variant {
let units = gradient.common.units.unwrap();
- if units == GradientUnits(CoordUnits::ObjectBoundingBox) {
- draw_ctx.push_view_box(1.0, 1.0);
- }
+ {
+ let params = if units == GradientUnits(CoordUnits::ObjectBoundingBox) {
+ draw_ctx.push_view_box(1.0, 1.0)
+ } else {
+ draw_ctx.get_view_params()
+ };
- let params = draw_ctx.get_view_params();
+ let mut pattern = cairo::LinearGradient::new(
+ x1.as_ref().unwrap().normalize(values, ¶ms),
+ y1.as_ref().unwrap().normalize(values, ¶ms),
+ x2.as_ref().unwrap().normalize(values, ¶ms),
+ y2.as_ref().unwrap().normalize(values, ¶ms),
+ );
- let mut pattern = cairo::LinearGradient::new(
- x1.as_ref().unwrap().normalize(values, ¶ms),
- y1.as_ref().unwrap().normalize(values, ¶ms),
- x2.as_ref().unwrap().normalize(values, ¶ms),
- y2.as_ref().unwrap().normalize(values, ¶ms),
- );
+ if units == GradientUnits(CoordUnits::ObjectBoundingBox) {
+ draw_ctx.pop_view_box();
+ }
- if units == GradientUnits(CoordUnits::ObjectBoundingBox) {
- draw_ctx.pop_view_box();
+ set_common_on_pattern(gradient, draw_ctx, &mut pattern, bbox, opacity);
}
-
- set_common_on_pattern(gradient, draw_ctx, &mut pattern, bbox, opacity);
} else {
unreachable!();
}
@@ -584,27 +586,29 @@ fn set_radial_gradient_on_pattern(
if let GradientVariant::Radial { cx, cy, r, fx, fy } = gradient.variant {
let units = gradient.common.units.unwrap();
- if units == GradientUnits(CoordUnits::ObjectBoundingBox) {
- draw_ctx.push_view_box(1.0, 1.0);
- }
+ {
+ let params = if units == GradientUnits(CoordUnits::ObjectBoundingBox) {
+ draw_ctx.push_view_box(1.0, 1.0)
+ } else {
+ draw_ctx.get_view_params()
+ };
- let params = draw_ctx.get_view_params();
+ let n_cx = cx.as_ref().unwrap().normalize(values, ¶ms);
+ let n_cy = cy.as_ref().unwrap().normalize(values, ¶ms);
+ let n_r = r.as_ref().unwrap().normalize(values, ¶ms);
+ let n_fx = fx.as_ref().unwrap().normalize(values, ¶ms);
+ let n_fy = fy.as_ref().unwrap().normalize(values, ¶ms);
- let n_cx = cx.as_ref().unwrap().normalize(values, ¶ms);
- let n_cy = cy.as_ref().unwrap().normalize(values, ¶ms);
- let n_r = r.as_ref().unwrap().normalize(values, ¶ms);
- let n_fx = fx.as_ref().unwrap().normalize(values, ¶ms);
- let n_fy = fy.as_ref().unwrap().normalize(values, ¶ms);
+ let (new_fx, new_fy) = fix_focus_point(n_fx, n_fy, n_cx, n_cy, n_r);
- let (new_fx, new_fy) = fix_focus_point(n_fx, n_fy, n_cx, n_cy, n_r);
+ let mut pattern = cairo::RadialGradient::new(new_fx, new_fy, 0.0, n_cx, n_cy, n_r);
- let mut pattern = cairo::RadialGradient::new(new_fx, new_fy, 0.0, n_cx, n_cy, n_r);
+ if units == GradientUnits(CoordUnits::ObjectBoundingBox) {
+ draw_ctx.pop_view_box();
+ }
- if units == GradientUnits(CoordUnits::ObjectBoundingBox) {
- draw_ctx.pop_view_box();
+ set_common_on_pattern(gradient, draw_ctx, &mut pattern, bbox, opacity);
}
-
- set_common_on_pattern(gradient, draw_ctx, &mut pattern, bbox, opacity);
} else {
unreachable!();
}
diff --git a/rsvg_internals/src/marker.rs b/rsvg_internals/src/marker.rs
index 47022cf3..fd2269ca 100644
--- a/rsvg_internals/src/marker.rs
+++ b/rsvg_internals/src/marker.rs
@@ -159,7 +159,7 @@ impl NodeMarker {
affine.scale(line_width, line_width);
}
- if let Some(vbox) = self.vbox.get() {
+ let params = if let Some(vbox) = self.vbox.get() {
let (_, _, w, h) = self.aspect.get().compute(
vbox.0.width,
vbox.0.height,
@@ -171,12 +171,10 @@ impl NodeMarker {
affine.scale(w / vbox.0.width, h / vbox.0.height);
- draw_ctx.push_view_box(vbox.0.width, vbox.0.height);
+ draw_ctx.push_view_box(vbox.0.width, vbox.0.height)
} else {
- draw_ctx.push_view_box(marker_width, marker_height);
- }
-
- let params = draw_ctx.get_view_params();
+ draw_ctx.push_view_box(marker_width, marker_height)
+ };
affine.translate(
-self.ref_x.get().normalize(&values, ¶ms),
diff --git a/rsvg_internals/src/mask.rs b/rsvg_internals/src/mask.rs
index f0ede8d1..010e8294 100644
--- a/rsvg_internals/src/mask.rs
+++ b/rsvg_internals/src/mask.rs
@@ -83,20 +83,24 @@ impl NodeMask {
let mask_units = CoordUnits::from(self.units.get());
let content_units = CoordUnits::from(self.content_units.get());
- if mask_units == CoordUnits::ObjectBoundingBox {
- draw_ctx.push_view_box(1.0, 1.0);
- }
+ let (x, y, w, h) = {
+ let params = if mask_units == CoordUnits::ObjectBoundingBox {
+ draw_ctx.push_view_box(1.0, 1.0)
+ } else {
+ draw_ctx.get_view_params()
+ };
- let params = draw_ctx.get_view_params();
+ let x = self.x.get().normalize(&values, ¶ms);
+ let y = self.y.get().normalize(&values, ¶ms);
+ let w = self.width.get().normalize(&values, ¶ms);
+ let h = self.height.get().normalize(&values, ¶ms);
- let x = self.x.get().normalize(&values, ¶ms);
- let y = self.y.get().normalize(&values, ¶ms);
- let w = self.width.get().normalize(&values, ¶ms);
- let h = self.height.get().normalize(&values, ¶ms);
+ if mask_units == CoordUnits::ObjectBoundingBox {
+ draw_ctx.pop_view_box();
+ }
- if mask_units == CoordUnits::ObjectBoundingBox {
- draw_ctx.pop_view_box();
- }
+ (x, y, w, h)
+ };
// Use a scope because mask_cr needs to release the
// reference to the surface before we access the pixels
@@ -130,32 +134,36 @@ impl NodeMask {
draw_ctx.clip(x, y, w, h);
}
- 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 _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,
+ );
- mask_cr.transform(bbtransform);
+ mask_cr.transform(bbtransform);
- draw_ctx.push_view_box(1.0, 1.0);
- }
+ draw_ctx.push_view_box(1.0, 1.0)
+ } else {
+ draw_ctx.get_view_params()
+ };
- let res = draw_ctx.with_discrete_layer(node, values, false, &mut |dc| {
- node.draw_children(&cascaded, dc, false)
- });
+ let res = draw_ctx.with_discrete_layer(node, values, false, &mut |dc| {
+ node.draw_children(&cascaded, dc, false)
+ });
- if content_units == CoordUnits::ObjectBoundingBox {
- draw_ctx.pop_view_box();
- }
+ if content_units == CoordUnits::ObjectBoundingBox {
+ draw_ctx.pop_view_box();
+ }
- draw_ctx.set_cairo_context(&save_cr);
+ draw_ctx.set_cairo_context(&save_cr);
- res
+ res
+ }
}?;
let opacity = {
diff --git a/rsvg_internals/src/pattern.rs b/rsvg_internals/src/pattern.rs
index 3c458cfb..4eb79f88 100644
--- a/rsvg_internals/src/pattern.rs
+++ b/rsvg_internals/src/pattern.rs
@@ -268,20 +268,24 @@ fn set_pattern_on_draw_context(
let vbox = pattern.vbox.unwrap();
let preserve_aspect_ratio = pattern.preserve_aspect_ratio.unwrap();
- if units == PatternUnits(CoordUnits::ObjectBoundingBox) {
- draw_ctx.push_view_box(1.0, 1.0);
- }
+ let (pattern_x, pattern_y, pattern_width, pattern_height) = {
+ let params = if units == PatternUnits(CoordUnits::ObjectBoundingBox) {
+ draw_ctx.push_view_box(1.0, 1.0)
+ } else {
+ draw_ctx.get_view_params()
+ };
- let params = draw_ctx.get_view_params();
+ let pattern_x = pattern.x.unwrap().normalize(values, ¶ms);
+ let pattern_y = pattern.y.unwrap().normalize(values, ¶ms);
+ let pattern_width = pattern.width.unwrap().normalize(values, ¶ms);
+ let pattern_height = pattern.height.unwrap().normalize(values, ¶ms);
- let pattern_x = pattern.x.unwrap().normalize(values, ¶ms);
- let pattern_y = pattern.y.unwrap().normalize(values, ¶ms);
- let pattern_width = pattern.width.unwrap().normalize(values, ¶ms);
- let pattern_height = pattern.height.unwrap().normalize(values, ¶ms);
+ if units == PatternUnits(CoordUnits::ObjectBoundingBox) {
+ draw_ctx.pop_view_box();
+ }
- if units == PatternUnits(CoordUnits::ObjectBoundingBox) {
- draw_ctx.pop_view_box();
- }
+ (pattern_x, pattern_y, pattern_width, pattern_height)
+ };
// Work out the size of the rectangle so it takes into account the object bounding box
@@ -346,7 +350,7 @@ fn set_pattern_on_draw_context(
let pushed_view_box: bool;
// Create the pattern contents coordinate system
- if let Some(vbox) = vbox {
+ 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(
vbox.0.width,
@@ -362,8 +366,9 @@ fn set_pattern_on_draw_context(
caffine = cairo::Matrix::new(w / vbox.0.width, 0.0, 0.0, h / vbox.0.height, x, y);
- draw_ctx.push_view_box(vbox.0.width, vbox.0.height);
+ let params = draw_ctx.push_view_box(vbox.0.width, vbox.0.height);
pushed_view_box = true;
+ params
} else if content_units == PatternContentUnits(CoordUnits::ObjectBoundingBox) {
// If coords are in terms of the bounding box, use them
let bbrect = bbox.rect.unwrap();
@@ -371,12 +376,14 @@ fn set_pattern_on_draw_context(
caffine = cairo::Matrix::identity();
caffine.scale(bbrect.width, bbrect.height);
- draw_ctx.push_view_box(1.0, 1.0);
+ let params = draw_ctx.push_view_box(1.0, 1.0);
pushed_view_box = true;
+ params
} else {
caffine = cairo::Matrix::identity();
pushed_view_box = false;
- }
+ draw_ctx.get_view_params()
+ };
if !scwscale.approx_eq_cairo(&1.0) || !schscale.approx_eq_cairo(&1.0) {
let mut scalematrix = cairo::Matrix::identity();
diff --git a/rsvg_internals/src/viewport.rs b/rsvg_internals/src/viewport.rs
index 0c1857d9..7c3a762b 100644
--- a/rsvg_internals/src/viewport.rs
+++ b/rsvg_internals/src/viewport.rs
@@ -47,7 +47,7 @@ pub fn draw_in_viewport(
dc.clip(vx, vy, vw, vh);
}
- if let Some(vbox) = vbox {
+ let _params = if let Some(vbox) = vbox {
// the preserveAspectRatio attribute is only used if viewBox is specified
// https://www.w3.org/TR/SVG/coords.html#PreserveAspectRatioAttribute
@@ -57,7 +57,7 @@ pub fn draw_in_viewport(
return Ok(());
}
- dc.push_view_box(vbox.0.width, vbox.0.height);
+ let params = dc.push_view_box(vbox.0.width, vbox.0.height);
let (x, y, w, h) =
preserve_aspect_ratio.compute(vbox.0.width, vbox.0.height, vx, vy, vw, vh);
@@ -71,11 +71,14 @@ pub fn draw_in_viewport(
if do_clip && clip_mode == ClipMode::ClipToVbox {
dc.clip(vbox.0.x, vbox.0.y, vbox.0.width, vbox.0.height);
}
+
+ params
} else {
- dc.push_view_box(vw, vh);
+ let params = dc.push_view_box(vw, vh);
affine.translate(vx, vy);
dc.get_cairo_context().set_matrix(affine);
- }
+ params
+ };
let res = draw_fn(dc);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]