Skip to content

Commit 1d8181c

Browse files
authored
Add InterpolationAlphaSpace to Gradient (#115)
Work towards linebender/vello#1056, I think the best solution is to support both both ways of dealing with alpha during interpolation, thus we need to repr this in `Gradient` with newly introduced `InterpolationAlphaSpace`. `InterpolationAlphaSpace` and it's docs are copied from linebender/color#191. Depends on linebender/color#191 This is breaking change. --------- Signed-off-by: sagudev <[email protected]>
1 parent f3d54e2 commit 1d8181c

File tree

5 files changed

+60
-7
lines changed

5 files changed

+60
-7
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,13 @@ This release has an [MSRV] of 1.82.
2020
- `Style` now impl `PartialEq`. ([#114][] by [@liferooter][])
2121
- Add `Bgra8` variant to `ImageFormat`. ([#120][] by [@sagudev][])
2222
- Provide `ImageAlphaType` with `ImageData`. ([#121][] by [@sagudev][])
23+
- Breaking change: Add `InterpolationAlphaSpace` to `Gradient` to chose how color channels should be handled when interpolating between transparent colors. ([#121][] by [@sagudev][])
2324

2425
### Changed
2526

2627
- Breaking change: `Image` has been renamed to `ImageBrush`, which now consists of an `ImageData` and an `ImageSampler`. ([#117][], [#123][] by [@nicoburns][], [@DJMcNab][])
2728
- Breaking change: `Font` has been renamed to `FontData` to match `ImageData`. ([#126][] by [@nicoburns][])
29+
- Update to `color` 0.3.2. ([#115][] by [@sagudev][])
2830

2931
### Raw Resource Changes
3032

@@ -147,6 +149,7 @@ This release has an [MSRV] of 1.70.
147149
[#103]: https://github.com/linebender/peniko/pull/103
148150
[#104]: https://github.com/linebender/peniko/pull/104
149151
[#114]: https://github.com/linebender/peniko/pull/114
152+
[#115]: https://github.com/linebender/peniko/pull/115
150153
[#117]: https://github.com/linebender/peniko/pull/117
151154
[#120]: https://github.com/linebender/peniko/pull/120
152155
[#121]: https://github.com/linebender/peniko/pull/121

Cargo.lock

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ serde = [
3737
kurbo = { version = "0.12.0", default-features = false }
3838
smallvec = "1.15.0"
3939
bytemuck = { version = "1.23.0", default-features = false, optional = true }
40-
color = { version = "0.3.1", default-features = false }
40+
color = { version = "0.3.2", default-features = false }
4141
linebender_resource_handle = { version = "0.1.0", default-features = false }
4242
serde = { version = "1.0.219", default-features = false, optional = true, features = [
4343
"alloc",

src/gradient.rs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,39 @@ impl SweepGradientPosition {
219219
}
220220
}
221221

222+
/// Defines how color channels should be handled when interpolating
223+
/// between transparent colors.
224+
#[derive(Clone, Copy, Default, Debug, PartialEq)]
225+
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
226+
pub enum InterpolationAlphaSpace {
227+
/// Colors are interpolated with their color channels premultiplied by the alpha
228+
/// channel. This is almost always what you want.
229+
///
230+
/// Used when interpolating colors in the premultiplied alpha space, which allows
231+
/// for correct interpolation when colors are transparent. This matches behavior
232+
/// described in [CSS Color Module Level 4 § 12.3].
233+
///
234+
/// Following the convention of CSS Color Module Level 4, in cylindrical color
235+
/// spaces the hue channel is not premultiplied. If it were, interpolation would
236+
/// give undesirable results. See also [`color::PremulColor`].
237+
///
238+
/// [CSS Color Module Level 4 § 12.3]: https://drafts.csswg.org/css-color/#interpolation-alpha
239+
#[default]
240+
Premultiplied = 0,
241+
/// Colors are interpolated without premultiplying their color channels by the alpha channel.
242+
///
243+
/// This causes color information to leak out of transparent colors. For example, when
244+
/// interpolating from a fully transparent red to a fully opaque blue in sRGB, this
245+
/// method will go through an intermediate purple.
246+
///
247+
/// Used when interpolating colors in the unpremultiplied (straight) alpha space.
248+
/// This matches behavior of gradients in the HTML `canvas` element.
249+
/// See [The 2D rendering context § Fill and stroke styles].
250+
///
251+
/// [The 2D rendering context § Fill and stroke styles]: https://html.spec.whatwg.org/multipage/#interpolation
252+
Unpremultiplied = 1,
253+
}
254+
222255
/// Properties for the supported [gradient](Gradient) types.
223256
#[derive(Copy, Clone, PartialEq, Debug)]
224257
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
@@ -271,6 +304,8 @@ pub struct Gradient {
271304
///
272305
/// [CSS Color Module Level 4 § 12.4]: https://drafts.csswg.org/css-color/#hue-interpolation
273306
pub hue_direction: HueDirection,
307+
/// Alpha space to be used for interpolation
308+
pub interpolation_alpha_space: InterpolationAlphaSpace,
274309
/// Color stop collection.
275310
pub stops: ColorStops,
276311
}
@@ -286,6 +321,7 @@ impl Default for Gradient {
286321
extend: Extend::default(),
287322
interpolation_cs: DEFAULT_GRADIENT_COLOR_SPACE,
288323
hue_direction: HueDirection::default(),
324+
interpolation_alpha_space: InterpolationAlphaSpace::default(),
289325
stops: ColorStops::default(),
290326
}
291327
}
@@ -299,6 +335,7 @@ impl Gradient {
299335
extend: Extend::default(),
300336
interpolation_cs: DEFAULT_GRADIENT_COLOR_SPACE,
301337
hue_direction: HueDirection::default(),
338+
interpolation_alpha_space: InterpolationAlphaSpace::default(),
302339
stops: ColorStops::default(),
303340
}
304341
}
@@ -311,6 +348,7 @@ impl Gradient {
311348
extend: Extend::default(),
312349
interpolation_cs: DEFAULT_GRADIENT_COLOR_SPACE,
313350
hue_direction: HueDirection::default(),
351+
interpolation_alpha_space: InterpolationAlphaSpace::default(),
314352
stops: ColorStops::default(),
315353
}
316354
}
@@ -333,6 +371,7 @@ impl Gradient {
333371
extend: Extend::default(),
334372
interpolation_cs: DEFAULT_GRADIENT_COLOR_SPACE,
335373
hue_direction: HueDirection::default(),
374+
interpolation_alpha_space: InterpolationAlphaSpace::default(),
336375
stops: ColorStops::default(),
337376
}
338377
}
@@ -345,6 +384,7 @@ impl Gradient {
345384
extend: Extend::default(),
346385
interpolation_cs: DEFAULT_GRADIENT_COLOR_SPACE,
347386
hue_direction: HueDirection::default(),
387+
interpolation_alpha_space: InterpolationAlphaSpace::default(),
348388
stops: ColorStops::default(),
349389
}
350390
}
@@ -363,6 +403,16 @@ impl Gradient {
363403
self
364404
}
365405

406+
/// Builder method for setting the interpolation alpha space.
407+
#[must_use]
408+
pub const fn with_interpolation_alpha_space(
409+
mut self,
410+
interpolation_alpha_space: InterpolationAlphaSpace,
411+
) -> Self {
412+
self.interpolation_alpha_space = interpolation_alpha_space;
413+
self
414+
}
415+
366416
/// Builder method for setting the hue direction when interpolating within a cylindrical color space.
367417
#[must_use]
368418
pub const fn with_hue_direction(mut self, hue_direction: HueDirection) -> Self {

src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ pub use linebender_resource_handle::{self, Blob, FontData, WeakBlob};
4747
pub use blend::{BlendMode, Compose, Mix};
4848
pub use brush::{Brush, BrushRef, Extend};
4949
pub use gradient::{
50-
ColorStop, ColorStops, ColorStopsSource, Gradient, GradientKind, LinearGradientPosition,
51-
RadialGradientPosition, SweepGradientPosition,
50+
ColorStop, ColorStops, ColorStopsSource, Gradient, GradientKind, InterpolationAlphaSpace,
51+
LinearGradientPosition, RadialGradientPosition, SweepGradientPosition,
5252
};
5353
pub use image::{
5454
ImageAlphaType, ImageBrush, ImageBrushRef, ImageData, ImageFormat, ImageQuality, ImageSampler,

0 commit comments

Comments
 (0)