peniko/
blend.rs

1// Copyright 2022 the Peniko Authors
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3
4/// Defines the color mixing function for a [blend operation](BlendMode).
5///
6/// See [W3C's *Compositing and Blending Level 1* draft](https://www.w3.org/TR/compositing-1/) for more details.
7/// Illustrations fall under the [W3C open license](https://www.w3.org/copyright/software-license/).
8#[derive(Copy, Clone, PartialEq, Eq, Debug)]
9#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
10#[repr(u8)]
11pub enum Mix {
12    /// Default attribute which specifies no blending. The blending formula simply selects the source color.
13    ///
14    /// ![](https://www.w3.org/TR/compositing-1/examples/normal.png)
15    Normal = 0,
16    /// Source color is multiplied by the destination color and replaces the destination.
17    ///
18    /// ![](https://www.w3.org/TR/compositing-1/examples/multiply.png)
19    Multiply = 1,
20    /// Multiplies the complements of the backdrop and source color values, then complements the result.
21    ///
22    /// ![](https://www.w3.org/TR/compositing-1/examples/screen.png)
23    Screen = 2,
24    /// Multiplies or screens the colors, depending on the backdrop color value.
25    ///
26    /// ![](https://www.w3.org/TR/compositing-1/examples/overlay.png)
27    Overlay = 3,
28    /// Selects the darker of the backdrop and source colors.
29    ///
30    /// ![](https://www.w3.org/TR/compositing-1/examples/darken.png)
31    Darken = 4,
32    /// Selects the lighter of the backdrop and source colors.
33    ///
34    /// ![](https://www.w3.org/TR/compositing-1/examples/lighten.png)
35    Lighten = 5,
36    /// Brightens the backdrop color to reflect the source color. Painting with black produces no
37    /// change.
38    ///
39    /// ![](https://www.w3.org/TR/compositing-1/examples/colordodge.png)
40    ColorDodge = 6,
41    /// Darkens the backdrop color to reflect the source color. Painting with white produces no
42    /// change.
43    ///
44    /// ![](https://www.w3.org/TR/compositing-1/examples/colorburn.png)
45    ColorBurn = 7,
46    /// Multiplies or screens the colors, depending on the source color value. The effect is
47    /// similar to shining a harsh spotlight on the backdrop.
48    ///
49    /// ![](https://www.w3.org/TR/compositing-1/examples/hardlight.png)
50    HardLight = 8,
51    /// Darkens or lightens the colors, depending on the source color value. The effect is similar
52    /// to shining a diffused spotlight on the backdrop.
53    ///
54    /// ![](https://www.w3.org/TR/compositing-1/examples/softlight.png)
55    SoftLight = 9,
56    /// Subtracts the darker of the two constituent colors from the lighter color.
57    ///
58    /// ![](https://www.w3.org/TR/compositing-1/examples/difference.png)
59    Difference = 10,
60    /// Produces an effect similar to that of the `Difference` mode but lower in contrast. Painting
61    /// with white inverts the backdrop color; painting with black produces no change.
62    ///
63    /// ![](https://www.w3.org/TR/compositing-1/examples/exclusion.png)
64    Exclusion = 11,
65    /// Creates a color with the hue of the source color and the saturation and luminosity of the
66    /// backdrop color.
67    ///
68    /// ![](https://www.w3.org/TR/compositing-1/examples/hue.png)
69    Hue = 12,
70    /// Creates a color with the saturation of the source color and the hue and luminosity of the
71    /// backdrop color. Painting with this mode in an area of the backdrop that is a pure gray
72    /// (no saturation) produces no change.
73    ///
74    /// ![](https://www.w3.org/TR/compositing-1/examples/saturation.png)
75    Saturation = 13,
76    /// Creates a color with the hue and saturation of the source color and the luminosity of the
77    /// backdrop color. This preserves the gray levels of the backdrop and is useful for coloring
78    /// monochrome images or tinting color images.
79    ///
80    /// ![](https://www.w3.org/TR/compositing-1/examples/color.png)
81    Color = 14,
82    /// Creates a color with the luminosity of the source color and the hue and saturation of the
83    /// backdrop color. This produces an inverse effect to that of the `Color` mode.
84    ///
85    /// ![](https://www.w3.org/TR/compositing-1/examples/luminosity.png)
86    Luminosity = 15,
87    /// `Clip` was similar to `Normal`, but was optimised for clipping (by avoiding
88    /// blending in areas where there was no clip path).
89    ///
90    /// This optimisation is however unrelated to mixing, and so will no longer
91    /// be indicated with this enum.
92    ///
93    /// If you were using this with Vello, you should use the (new) `push_clip_layer` function instead.
94    #[deprecated(note = "Use `push_clip_layer` instead.", since = "0.5.0")]
95    Clip = 128,
96    // NOTICE: If a new value is added, be sure to update the bytemuck CheckedBitPattern impl.
97}
98
99/// Defines the layer composition function for a [blend operation](BlendMode).
100///
101/// See [W3C's *Compositing and Blending Level 1* draft](https://www.w3.org/TR/compositing-1/) for more details.
102/// Illustrations fall under the [W3C open license](https://www.w3.org/copyright/software-license/).
103#[derive(Copy, Clone, PartialEq, Eq, Debug)]
104#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
105#[repr(u8)]
106pub enum Compose {
107    /// No regions are enabled.
108    ///
109    /// ![](https://www.w3.org/TR/compositing-1/examples/PD_clr.svg)
110    Clear = 0,
111    /// Only the source will be present.
112    ///
113    /// ![](https://www.w3.org/TR/compositing-1/examples/PD_src.svg)
114    Copy = 1,
115    /// Only the destination will be present.
116    ///
117    /// ![](https://www.w3.org/TR/compositing-1/examples/PD_dst.svg)
118    Dest = 2,
119    /// The source is placed over the destination.
120    ///
121    /// ![](https://www.w3.org/TR/compositing-1/examples/PD_src-over.svg)
122    SrcOver = 3,
123    /// The destination is placed over the source.
124    ///
125    /// ![](https://www.w3.org/TR/compositing-1/examples/PD_dst-over.svg)
126    DestOver = 4,
127    /// The parts of the source that overlap with the destination are placed.
128    ///
129    /// ![](https://www.w3.org/TR/compositing-1/examples/PD_src-in.svg)
130    SrcIn = 5,
131    /// The parts of the destination that overlap with the source are placed.
132    ///
133    /// ![](https://www.w3.org/TR/compositing-1/examples/PD_dst-in.svg)
134    DestIn = 6,
135    /// The parts of the source that fall outside of the destination are placed.
136    ///
137    /// ![](https://www.w3.org/TR/compositing-1/examples/PD_src-out.svg)
138    SrcOut = 7,
139    /// The parts of the destination that fall outside of the source are placed.
140    ///
141    /// ![](https://www.w3.org/TR/compositing-1/examples/PD_dst-out.svg)
142    DestOut = 8,
143    /// The parts of the source which overlap the destination replace the destination. The
144    /// destination is placed everywhere else.
145    ///
146    /// ![](https://www.w3.org/TR/compositing-1/examples/PD_src-atop.svg)
147    SrcAtop = 9,
148    /// The parts of the destination which overlaps the source replace the source. The source is
149    /// placed everywhere else.
150    ///
151    /// ![](https://www.w3.org/TR/compositing-1/examples/PD_dst-atop.svg)
152    DestAtop = 10,
153    /// The non-overlapping regions of source and destination are combined.
154    ///
155    /// ![](https://www.w3.org/TR/compositing-1/examples/PD_xor.svg)
156    Xor = 11,
157    /// The sum of the source image and destination image is displayed.
158    Plus = 12,
159    /// Allows two elements to cross fade by changing their opacities from 0 to 1 on one
160    /// element and 1 to 0 on the other element.
161    PlusLighter = 13,
162    // NOTICE: If a new value is added, be sure to modify `MAX_VALUE` in the bytemuck impl.
163}
164
165/// Blend mode consisting of [color mixing](Mix) and [composition functions](Compose).
166#[derive(Copy, Clone, PartialEq, Eq, Debug)]
167#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
168pub struct BlendMode {
169    /// The color mixing function.
170    pub mix: Mix,
171    /// The layer composition function.
172    pub compose: Compose,
173}
174
175impl BlendMode {
176    /// Creates a new blend mode from color mixing and layer composition
177    /// functions.
178    #[must_use]
179    pub const fn new(mix: Mix, compose: Compose) -> Self {
180        Self { mix, compose }
181    }
182}
183
184impl Default for BlendMode {
185    fn default() -> Self {
186        Self {
187            mix: Mix::Normal,
188            compose: Compose::SrcOver,
189        }
190    }
191}
192
193impl From<Mix> for BlendMode {
194    fn from(mix: Mix) -> Self {
195        Self {
196            mix,
197            compose: Compose::SrcOver,
198        }
199    }
200}
201
202impl From<Compose> for BlendMode {
203    fn from(compose: Compose) -> Self {
204        Self {
205            mix: Mix::Normal,
206            compose,
207        }
208    }
209}