From 7c8d1d51444d758ecd11e1c9f0b2c4bb49a06292 Mon Sep 17 00:00:00 2001 From: Bruce Mitchener Date: Wed, 27 Nov 2024 22:03:35 +0700 Subject: [PATCH] Add `with_alpha` for `Brush`, `Gradient`, `Image` There is now a `with_alpha` to go along with `multiply_alpha` that sets the alpha to the given value. This makes it work the same as for colors with the same sort of API. While doing this, some code for multiplying alpha on a gradient was moved to `Gradient` to make the interfaces the same on all things that support this. Fixes #51. --- CHANGELOG.md | 2 ++ src/brush.rs | 18 +++++++++++------- src/gradient.rs | 45 ++++++++++++++++++++++++++++++++++++--------- src/image.rs | 12 ++++++++++++ 4 files changed, 61 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 99928d1..1063ccf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ This release has an [MSRV] of 1.82. - `Image` now stores the alpha as an `f32` ([#65][] by [@waywardmonkeys][]) - Use `color` crate. See below for details ([#63][] by [@waywardmonkeys][]) +- `Gradient`, `Image`, `Brush` now have `with_alpha` and `Gradient` also gets a `multiply_alpha` ([#67][] by [@waywardmonkeys][]) ### Color Changes @@ -76,6 +77,7 @@ This release has an [MSRV] of 1.70. [#52]: https://github.com/linebender/peniko/pull/52 [#63]: https://github.com/linebender/peniko/pull/63 [#65]: https://github.com/linebender/peniko/pull/65 +[#67]: https://github.com/linebender/peniko/pull/67 [@DJMcNab]: https://github.com/DJMcNab [@ratmice]: https://github.com/ratmice diff --git a/src/brush.rs b/src/brush.rs index b76678a..83eef15 100644 --- a/src/brush.rs +++ b/src/brush.rs @@ -56,6 +56,16 @@ impl Default for Brush { } impl Brush { + /// Returns the brush with the alpha component set to `alpha`. + #[must_use] + pub fn with_alpha(self, alpha: f32) -> Self { + match self { + Self::Solid(color) => color.with_alpha(alpha).into(), + Self::Gradient(gradient) => gradient.with_alpha(alpha).into(), + Self::Image(image) => image.with_alpha(alpha).into(), + } + } + /// Returns the brush with the alpha component multiplied by `alpha`. /// The behaviour of this transformation is undefined if `alpha` is negative. /// @@ -73,13 +83,7 @@ impl Brush { } else { match self { Self::Solid(color) => color.multiply_alpha(alpha).into(), - Self::Gradient(mut gradient) => { - gradient - .stops - .iter_mut() - .for_each(|stop| *stop = stop.multiply_alpha(alpha)); - gradient.into() - } + Self::Gradient(gradient) => gradient.multiply_alpha(alpha).into(), Self::Image(image) => image.multiply_alpha(alpha).into(), } } diff --git a/src/gradient.rs b/src/gradient.rs index 490d885..b2316da 100644 --- a/src/gradient.rs +++ b/src/gradient.rs @@ -36,15 +36,13 @@ impl PartialEq for ColorStop { impl Eq for ColorStop {} impl ColorStop { - /// Returns the color stop with the alpha component multiplied by the specified - /// factor. + /// Returns the color stop with the alpha component set to `alpha`. #[must_use] - #[deprecated( - since = "0.2.0", - note = "This method has been renamed to `multiply_alpha`." - )] - pub fn with_alpha_factor(self, alpha: f32) -> Self { - self.multiply_alpha(alpha) + pub fn with_alpha(self, alpha: f32) -> Self { + Self { + offset: self.offset, + color: self.color.with_alpha(alpha), + } } /// Returns the color stop with the alpha component multiplied by `alpha`. @@ -52,13 +50,23 @@ impl ColorStop { /// /// If any resulting alphas would overflow, these currently saturate (to opaque). #[must_use] - #[track_caller] pub fn multiply_alpha(self, alpha: f32) -> Self { Self { offset: self.offset, color: self.color.multiply_alpha(alpha), } } + + /// Returns the color stop with the alpha component multiplied by the specified + /// factor. + #[must_use] + #[deprecated( + since = "0.2.0", + note = "This method has been renamed to `multiply_alpha`." + )] + pub fn with_alpha_factor(self, alpha: f32) -> Self { + self.multiply_alpha(alpha) + } } impl From<(f32, AlphaColor)> for ColorStop { @@ -225,6 +233,25 @@ impl Gradient { stops.collect_stops(&mut self.stops); self } + + /// Returns the gradient with the alpha component for all color stops set to `alpha`. + #[must_use] + pub fn with_alpha(mut self, alpha: f32) -> Self { + self.stops + .iter_mut() + .for_each(|stop| *stop = stop.with_alpha(alpha)); + self + } + + /// Returns the gradient with the alpha component for all color stops + /// multiplied by `alpha`. + #[must_use] + pub fn multiply_alpha(mut self, alpha: f32) -> Self { + self.stops + .iter_mut() + .for_each(|stop| *stop = stop.multiply_alpha(alpha)); + self + } } /// Trait for types that represent a source of color stops. diff --git a/src/image.rs b/src/image.rs index 724cb22..9f26b22 100644 --- a/src/image.rs +++ b/src/image.rs @@ -67,6 +67,18 @@ impl Image { self } + /// Returns the image with the alpha multiplier set to `alpha`. + #[must_use] + #[track_caller] + pub fn with_alpha(mut self, alpha: f32) -> Self { + debug_assert!( + alpha.is_finite() && alpha >= 0.0, + "A non-finite or negative alpha ({alpha}) is meaningless." + ); + self.alpha = alpha; + self + } + /// Returns the image with the alpha multiplier multiplied again by `alpha`. /// The behaviour of this transformation is undefined if `alpha` is negative. #[must_use]