[librsvg: 24/27] Store a pattern's intended opacity in the ResolvedPattern / UserSpacePattern




commit 90427b87cf3ddf1f49a48ff73be407e372e10a4f
Author: Federico Mena Quintero <federico gnome org>
Date:   Fri Mar 5 16:05:10 2021 -0600

    Store a pattern's intended opacity in the ResolvedPattern / UserSpacePattern
    
    This is similar to baking gradients together with their final
    opacity.  A pattern's opacity is not applied until the end, when
    painting its pattern surface with the opacity, unlike a gradient's,
    which can be built into each stop's opacity.
    
    If we ever switch to generating gradient surfaces (analogous to
    pattern surfaces), we can handle both in the same way.

 src/drawing_ctx.rs     | 17 +++++++----------
 src/filters/context.rs |  2 --
 src/paint_server.rs    | 14 ++++++++------
 src/pattern.rs         | 10 ++++++++--
 4 files changed, 23 insertions(+), 20 deletions(-)
---
diff --git a/src/drawing_ctx.rs b/src/drawing_ctx.rs
index 5cfe1ee2..7f84d654 100644
--- a/src/drawing_ctx.rs
+++ b/src/drawing_ctx.rs
@@ -1022,7 +1022,6 @@ impl DrawingCtx {
         &mut self,
         pattern: &UserSpacePattern,
         acquired_nodes: &mut AcquiredNodes<'_>,
-        opacity: UnitInterval,
     ) -> Result<bool, RenderingError> {
         if approx_eq!(f64, pattern.width, 0.0) || approx_eq!(f64, pattern.height, 0.0) {
             return Ok(false);
@@ -1068,7 +1067,7 @@ impl DrawingCtx {
 
         // Draw everything
         self.with_cairo_context(&cr_pattern, &mut |dc| {
-            dc.with_alpha(opacity, &mut |dc| {
+            dc.with_alpha(pattern.opacity, &mut |dc| {
                 let pattern_cascaded = CascadedValues::new_from_node(&pattern.node_with_children);
                 let pattern_values = pattern_cascaded.get();
                 dc.with_discrete_layer(
@@ -1113,7 +1112,6 @@ impl DrawingCtx {
     fn set_paint_source(
         &mut self,
         paint_source: &UserSpacePaintSource,
-        opacity: UnitInterval,
         acquired_nodes: &mut AcquiredNodes<'_>,
     ) -> Result<bool, RenderingError> {
         match *paint_source {
@@ -1127,7 +1125,7 @@ impl DrawingCtx {
                 }
             }
             UserSpacePaintSource::Pattern(ref pattern, c) => {
-                if self.set_pattern(pattern, acquired_nodes, opacity)? {
+                if self.set_pattern(pattern, acquired_nodes)? {
                     Ok(true)
                 } else if let Some(c) = c {
                     self.set_color(c)
@@ -1147,7 +1145,6 @@ impl DrawingCtx {
         height: i32,
         acquired_nodes: &mut AcquiredNodes<'_>,
         paint_source: &UserSpacePaintSource,
-        opacity: UnitInterval,
     ) -> Result<SharedImageSurface, cairo::Status> {
         let mut surface = ExclusiveImageSurface::new(width, height, SurfaceType::SRgb)?;
 
@@ -1155,7 +1152,7 @@ impl DrawingCtx {
             // FIXME: we are ignoring any error
 
             let _ = self.with_cairo_context(cr, &mut |dc| {
-                dc.set_paint_source(paint_source, opacity, acquired_nodes)
+                dc.set_paint_source(paint_source, acquired_nodes)
                     .map(|had_paint_server| {
                         if had_paint_server {
                             cr.paint();
@@ -1207,7 +1204,7 @@ impl DrawingCtx {
             .resolve(acquired_nodes, values.stroke_opacity().0, values.color().0)?
             .to_user_space(bbox, self, values);
 
-        self.set_paint_source(&paint_source, values.stroke_opacity().0, acquired_nodes)
+        self.set_paint_source(&paint_source, acquired_nodes)
             .map(|had_paint_server| {
                 if had_paint_server {
                     cr.stroke_preserve();
@@ -1230,7 +1227,7 @@ impl DrawingCtx {
             .resolve(acquired_nodes, values.fill_opacity().0, values.color().0)?
             .to_user_space(bbox, self, values);
 
-        self.set_paint_source(&paint_source, values.fill_opacity().0, acquired_nodes)
+        self.set_paint_source(&paint_source, acquired_nodes)
             .map(|had_paint_server| {
                 if had_paint_server {
                     cr.fill_preserve();
@@ -1420,7 +1417,7 @@ impl DrawingCtx {
 
             saved_cr
                 .draw_ctx
-                .set_paint_source(&paint_source, values.fill_opacity().0, acquired_nodes)
+                .set_paint_source(&paint_source, acquired_nodes)
                 .map(|had_paint_server| {
                     if had_paint_server {
                         pangocairo::functions::update_layout(&cr, &layout);
@@ -1445,7 +1442,7 @@ impl DrawingCtx {
 
                 saved_cr
                     .draw_ctx
-                    .set_paint_source(&paint_source, values.stroke_opacity().0, acquired_nodes)
+                    .set_paint_source(&paint_source, acquired_nodes)
                     .map(|had_paint_server| {
                         if had_paint_server {
                             need_layout_path = true;
diff --git a/src/filters/context.rs b/src/filters/context.rs
index c5eed5a4..6321cedb 100644
--- a/src/filters/context.rs
+++ b/src/filters/context.rs
@@ -300,7 +300,6 @@ impl FilterContext {
                         self.source_surface.height(),
                         acquired_nodes,
                         &fill_paint_source,
-                        values.fill_opacity().0,
                     )
                     .map_err(FilterError::CairoError)
                     .map(FilterInput::StandardInput)
@@ -319,7 +318,6 @@ impl FilterContext {
                         self.source_surface.height(),
                         acquired_nodes,
                         &stroke_paint_source,
-                        values.stroke_opacity().0,
                     )
                     .map_err(FilterError::CairoError)
                     .map(FilterInput::StandardInput)
diff --git a/src/paint_server.rs b/src/paint_server.rs
index f9a125aa..ec275089 100644
--- a/src/paint_server.rs
+++ b/src/paint_server.rs
@@ -104,12 +104,14 @@ impl PaintServer {
                                 )
                             })
                         }
-                        Element::Pattern(ref p) => p.resolve(&node, acquired_nodes).map(|p| {
-                            PaintSource::Pattern(
-                                p,
-                                alternate.map(|c| resolve_color(&c, opacity, current_color)),
-                            )
-                        }),
+                        Element::Pattern(ref p) => {
+                            p.resolve(&node, acquired_nodes, opacity).map(|p| {
+                                PaintSource::Pattern(
+                                    p,
+                                    alternate.map(|c| resolve_color(&c, opacity, current_color)),
+                                )
+                            })
+                        }
                         Element::RadialGradient(ref g) => {
                             g.resolve(&node, acquired_nodes, opacity).map(|g| {
                                 PaintSource::Gradient(
diff --git a/src/pattern.rs b/src/pattern.rs
index d09d9b78..c9273ec9 100644
--- a/src/pattern.rs
+++ b/src/pattern.rs
@@ -16,6 +16,7 @@ use crate::parsers::ParseValue;
 use crate::properties::ComputedValues;
 use crate::rect::Rect;
 use crate::transform::Transform;
+use crate::unit_interval::UnitInterval;
 use crate::viewbox::*;
 use crate::xml::Attributes;
 
@@ -97,6 +98,7 @@ pub struct ResolvedPattern {
     y: Length<Vertical>,
     width: ULength<Horizontal>,
     height: ULength<Vertical>,
+    opacity: UnitInterval,
 
     // Link to the node whose children are the pattern's resolved children.
     children: Children,
@@ -109,6 +111,7 @@ pub struct UserSpacePattern {
     pub transform: Transform,
     pub coord_transform: Transform,
     pub content_transform: Transform,
+    pub opacity: UnitInterval,
     pub node_with_children: Node,
 }
 
@@ -155,7 +158,7 @@ impl SetAttributes for Pattern {
 impl Draw for Pattern {}
 
 impl UnresolvedPattern {
-    fn into_resolved(self) -> ResolvedPattern {
+    fn into_resolved(self, opacity: UnitInterval) -> ResolvedPattern {
         assert!(self.is_resolved());
 
         ResolvedPattern {
@@ -168,6 +171,7 @@ impl UnresolvedPattern {
             y: self.common.y.unwrap(),
             width: self.common.width.unwrap(),
             height: self.common.height.unwrap(),
+            opacity,
 
             children: self.children.to_resolved(),
         }
@@ -386,6 +390,7 @@ impl ResolvedPattern {
             transform: self.transform,
             coord_transform,
             content_transform,
+            opacity: self.opacity,
             node_with_children,
         })
     }
@@ -408,6 +413,7 @@ impl Pattern {
         &self,
         node: &Node,
         acquired_nodes: &mut AcquiredNodes<'_>,
+        opacity: UnitInterval,
     ) -> Result<ResolvedPattern, AcquireError> {
         let Unresolved {
             mut pattern,
@@ -454,7 +460,7 @@ impl Pattern {
             }
         }
 
-        Ok(pattern.into_resolved())
+        Ok(pattern.into_resolved(opacity))
     }
 }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]