[librsvg: 24/27] Store a pattern's intended opacity in the ResolvedPattern / UserSpacePattern
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg: 24/27] Store a pattern's intended opacity in the ResolvedPattern / UserSpacePattern
- Date: Fri, 5 Mar 2021 23:36:27 +0000 (UTC)
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]