[librsvg: 22/27] Resolve a gradient's final opacity directly in PaintServer.resolve()




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]