[librsvg: 22/27] Resolve a gradient's final opacity directly in PaintServer.resolve()
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg: 22/27] Resolve a gradient's final opacity directly in PaintServer.resolve()
- Date: Fri, 5 Mar 2021 23:36:27 +0000 (UTC)
commit 249ac9cc344e636e10d9a5d099dd9a4bc621f980
Author: Federico Mena Quintero <federico gnome org>
Date: Fri Mar 5 14:47:31 2021 -0600
Resolve a gradient's final opacity directly in PaintServer.resolve()
This lets us avoid passing the opacity in several places, and
DrawingCtx.set_gradient() can avoid tweaking the stop color values.
src/drawing_ctx.rs | 6 ++----
src/gradient.rs | 36 +++++++++++++++++++++++-------------
src/paint_server.rs | 4 ++--
3 files changed, 27 insertions(+), 19 deletions(-)
---
diff --git a/src/drawing_ctx.rs b/src/drawing_ctx.rs
index 7a916d40..5cfe1ee2 100644
--- a/src/drawing_ctx.rs
+++ b/src/drawing_ctx.rs
@@ -981,7 +981,6 @@ impl DrawingCtx {
fn set_gradient(
self: &mut DrawingCtx,
gradient: &UserSpaceGradient,
- opacity: UnitInterval,
) -> Result<bool, RenderingError> {
let g = match gradient.variant {
GradientVariant::Linear { x1, y1, x2, y2 } => {
@@ -1003,14 +1002,13 @@ impl DrawingCtx {
for stop in &gradient.stops {
let UnitInterval(stop_offset) = stop.offset;
- let UnitInterval(o) = opacity;
g.add_color_stop_rgba(
stop_offset,
f64::from(stop.rgba.red_f32()),
f64::from(stop.rgba.green_f32()),
f64::from(stop.rgba.blue_f32()),
- f64::from(stop.rgba.alpha_f32()) * o,
+ f64::from(stop.rgba.alpha_f32()),
);
}
@@ -1120,7 +1118,7 @@ impl DrawingCtx {
) -> Result<bool, RenderingError> {
match *paint_source {
UserSpacePaintSource::Gradient(ref gradient, c) => {
- if self.set_gradient(gradient, opacity)? {
+ if self.set_gradient(gradient)? {
Ok(true)
} else if let Some(c) = c {
self.set_color(c)
diff --git a/src/gradient.rs b/src/gradient.rs
index c8881ff1..3fdd6072 100644
--- a/src/gradient.rs
+++ b/src/gradient.rs
@@ -426,7 +426,7 @@ impl UnresolvedGradient {
/// Looks for <stop> children inside a linearGradient or radialGradient node,
/// and adds their info to the UnresolvedGradient &self.
- fn add_color_stops_from_node(&mut self, node: &Node) {
+ fn add_color_stops_from_node(&mut self, node: &Node, opacity: UnitInterval) {
assert!(matches!(
*node.borrow_element(),
Element::LinearGradient(_) | Element::RadialGradient(_)
@@ -441,11 +441,14 @@ impl UnresolvedGradient {
} else {
let cascaded = CascadedValues::new_from_node(&child);
let values = cascaded.get();
- let rgba = resolve_color(
- &values.stop_color().0,
- values.stop_opacity().0,
- values.color().0,
- );
+
+ let UnitInterval(stop_opacity) = values.stop_opacity().0;
+ let UnitInterval(o) = opacity;
+
+ let composed_opacity = UnitInterval(stop_opacity * o);
+
+ let rgba =
+ resolve_color(&values.stop_color().0, composed_opacity, values.color().0);
self.add_color_stop(stop.offset, rgba);
}
@@ -574,7 +577,7 @@ impl Draw for LinearGradient {}
macro_rules! impl_gradient {
($gradient_type:ident, $other_type:ident) => {
impl $gradient_type {
- fn get_unresolved(&self, node: &Node) -> Unresolved {
+ fn get_unresolved(&self, node: &Node, opacity: UnitInterval) -> Unresolved {
let mut gradient = UnresolvedGradient {
units: self.common.units,
transform: self.common.transform,
@@ -583,7 +586,7 @@ macro_rules! impl_gradient {
variant: self.get_unresolved_variant(),
};
- gradient.add_color_stops_from_node(node);
+ gradient.add_color_stops_from_node(node, opacity);
Unresolved {
gradient,
@@ -595,11 +598,12 @@ macro_rules! impl_gradient {
&self,
node: &Node,
acquired_nodes: &mut AcquiredNodes<'_>,
+ opacity: UnitInterval,
) -> Result<ResolvedGradient, AcquireError> {
let Unresolved {
mut gradient,
mut fallback,
- } = self.get_unresolved(node);
+ } = self.get_unresolved(node, opacity);
let mut stack = NodeStack::new();
@@ -613,8 +617,12 @@ macro_rules! impl_gradient {
}
let unresolved = match *acquired_node.borrow_element() {
- Element::$gradient_type(ref g) => g.get_unresolved(&acquired_node),
- Element::$other_type(ref g) => g.get_unresolved(&acquired_node),
+ Element::$gradient_type(ref g) => {
+ g.get_unresolved(&acquired_node, opacity)
+ }
+ Element::$other_type(ref g) => {
+ g.get_unresolved(&acquired_node, opacity)
+ }
_ => return Err(AcquireError::InvalidLinkType(node_id.clone())),
};
@@ -749,7 +757,8 @@ mod tests {
Attributes::new(),
));
- let unresolved = borrow_element_as!(node, LinearGradient).get_unresolved(&node);
+ let unresolved = borrow_element_as!(node, LinearGradient)
+ .get_unresolved(&node, UnitInterval::clamp(1.0));
let gradient = unresolved.gradient.resolve_from_defaults();
assert!(gradient.is_resolved());
@@ -758,7 +767,8 @@ mod tests {
Attributes::new(),
));
- let unresolved = borrow_element_as!(node, RadialGradient).get_unresolved(&node);
+ let unresolved = borrow_element_as!(node, RadialGradient)
+ .get_unresolved(&node, UnitInterval::clamp(1.0));
let gradient = unresolved.gradient.resolve_from_defaults();
assert!(gradient.is_resolved());
}
diff --git a/src/paint_server.rs b/src/paint_server.rs
index 724c1531..f9a125aa 100644
--- a/src/paint_server.rs
+++ b/src/paint_server.rs
@@ -97,7 +97,7 @@ impl PaintServer {
match *node.borrow_element() {
Element::LinearGradient(ref g) => {
- g.resolve(&node, acquired_nodes).map(|g| {
+ g.resolve(&node, acquired_nodes, opacity).map(|g| {
PaintSource::Gradient(
g,
alternate.map(|c| resolve_color(&c, opacity, current_color)),
@@ -111,7 +111,7 @@ impl PaintServer {
)
}),
Element::RadialGradient(ref g) => {
- g.resolve(&node, acquired_nodes).map(|g| {
+ g.resolve(&node, acquired_nodes, opacity).map(|g| {
PaintSource::Gradient(
g,
alternate.map(|c| resolve_color(&c, opacity, current_color)),
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]