summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFederico Mena Quintero <federico@gnome.org>2020-09-22 14:39:29 -0500
committerFederico Mena Quintero <federico@gnome.org>2020-10-02 11:54:51 -0500
commitf3da52791bd4ea076cc41fd8bd27035cabb1c6fe (patch)
treecc285d19731b29cb45f1df2f2ae6caee6af9a0ea
parenta116a421ae11ec4613868449c56de7c7c46d0658 (diff)
downloadlibrsvg-f3da52791bd4ea076cc41fd8bd27035cabb1c6fe.tar.gz
Add helper DrawingCtx.push_coord_units()
This takes care of the pattern of pushing a unit-sized viewBox for objectBoundingBox. https://www.w3.org/TR/SVG2/coords.html#ObjectBoundingBoxUnits
-rw-r--r--rsvg_internals/src/drawing_ctx.rs47
-rw-r--r--rsvg_internals/src/filter.rs15
-rw-r--r--rsvg_internals/src/filters/context.rs6
3 files changed, 20 insertions, 48 deletions
diff --git a/rsvg_internals/src/drawing_ctx.rs b/rsvg_internals/src/drawing_ctx.rs
index 2144f46b..aed39b92 100644
--- a/rsvg_internals/src/drawing_ctx.rs
+++ b/rsvg_internals/src/drawing_ctx.rs
@@ -307,6 +307,14 @@ impl DrawingCtx {
.expect("view_box_stack must never be empty!")
}
+ pub fn push_coord_units(&self, units: CoordUnits) -> ViewParams {
+ if units == CoordUnits::ObjectBoundingBox {
+ self.push_view_box(1.0, 1.0)
+ } else {
+ self.get_view_params()
+ }
+ }
+
/// Gets the viewport that was last pushed with `push_view_box()`.
pub fn get_view_params(&self) -> ViewParams {
let vbox = self.get_top_viewbox();
@@ -448,12 +456,7 @@ impl DrawingCtx {
let mask_units = mask.get_units();
let mask_rect = {
- let params = if mask_units == CoordUnits::ObjectBoundingBox {
- self.push_view_box(1.0, 1.0)
- } else {
- self.get_view_params()
- };
-
+ let params = self.push_coord_units(mask_units);
mask.get_rect(&values, &params)
};
@@ -495,11 +498,7 @@ impl DrawingCtx {
mask_cr.transform(bbtransform.into());
}
- let _params = if mask.get_content_units() == CoordUnits::ObjectBoundingBox {
- self.push_view_box(1.0, 1.0)
- } else {
- self.get_view_params()
- };
+ let _params = self.push_coord_units(mask.get_content_units());
self.push_cairo_context(mask_cr);
@@ -899,18 +898,14 @@ impl DrawingCtx {
values: &ComputedValues,
bbox: &BoundingBox,
) -> Result<bool, RenderingError> {
- let units = gradient.get_units();
- let transform = if let Ok(t) = bbox.rect_to_transform(units.0) {
+ let GradientUnits(units) = gradient.get_units();
+ let transform = if let Ok(t) = bbox.rect_to_transform(units) {
t
} else {
return Ok(false);
};
- let params = if units == GradientUnits(CoordUnits::ObjectBoundingBox) {
- self.push_view_box(1.0, 1.0)
- } else {
- self.get_view_params()
- };
+ let params = self.push_coord_units(units);
let g = match gradient.get_variant() {
GradientVariant::Linear { x1, y1, x2, y2 } => {
@@ -990,11 +985,7 @@ impl DrawingCtx {
let content_units = pattern.get_content_units();
let pattern_transform = pattern.get_transform();
- let params = if units == PatternUnits(CoordUnits::ObjectBoundingBox) {
- self.push_view_box(1.0, 1.0)
- } else {
- self.get_view_params()
- };
+ let params = self.push_coord_units(units.0);
let pattern_rect = pattern.get_rect(values, &params);
@@ -1062,7 +1053,9 @@ impl DrawingCtx {
self.push_view_box(vbox.width(), vbox.height())
} else {
- caffine = if content_units == PatternContentUnits(CoordUnits::ObjectBoundingBox) {
+ let PatternContentUnits(content_units) = content_units;
+
+ caffine = if content_units == CoordUnits::ObjectBoundingBox {
// If coords are in terms of the bounding box, use them
let (bbw, bbh) = bbox.rect.unwrap().size();
Transform::new_scale(bbw, bbh)
@@ -1070,11 +1063,7 @@ impl DrawingCtx {
Transform::identity()
};
- if content_units == PatternContentUnits(CoordUnits::ObjectBoundingBox) {
- self.push_view_box(1.0, 1.0)
- } else {
- self.get_view_params()
- }
+ self.push_coord_units(content_units)
};
if !scwscale.approx_eq_cairo(1.0) || !schscale.approx_eq_cairo(1.0) {
diff --git a/rsvg_internals/src/filter.rs b/rsvg_internals/src/filter.rs
index f06a3ac5..7d73eab9 100644
--- a/rsvg_internals/src/filter.rs
+++ b/rsvg_internals/src/filter.rs
@@ -67,20 +67,7 @@ impl Filter {
let mut bbox = BoundingBox::new();
- // transform is set up in FilterContext::new() in such a way that for
- // filterunits == ObjectBoundingBox it includes scaling to correct width, height and
- // this is why width and height are set to 1, 1 (and for filterunits ==
- // UserSpaceOnUse, transform doesn't include scaling because in this case the correct
- // width, height already happens to be the viewbox width, height).
- //
- // 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.
- let params = if self.filterunits == CoordUnits::ObjectBoundingBox {
- draw_ctx.push_view_box(1.0, 1.0)
- } else {
- draw_ctx.get_view_params()
- };
+ let params = draw_ctx.push_coord_units(self.filterunits);
// With filterunits == ObjectBoundingBox, lengths represent fractions or percentages of the
// referencing node. No units are allowed (it's checked during attribute parsing).
diff --git a/rsvg_internals/src/filters/context.rs b/rsvg_internals/src/filters/context.rs
index d1a4c5d2..4fc47512 100644
--- a/rsvg_internals/src/filters/context.rs
+++ b/rsvg_internals/src/filters/context.rs
@@ -252,11 +252,7 @@ impl FilterContext {
pub fn get_view_params(&self, draw_ctx: &mut DrawingCtx) -> ViewParams {
// See comments in compute_effects_region() for how this works.
let units = borrow_element_as!(self.node, Filter).get_primitive_units();
- if units == CoordUnits::ObjectBoundingBox {
- draw_ctx.push_view_box(1.0, 1.0)
- } else {
- draw_ctx.get_view_params()
- }
+ draw_ctx.push_coord_units(units)
}
/// Retrieves the filter input surface according to the SVG rules.