Skip to main content

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    // NOTICE: If a new value is added, be sure to modify `MAX_VALUE` in the `bytemuck::Contiguous` impl.
88}
89
90/// Defines the layer composition function for a [blend operation](BlendMode).
91///
92/// See [W3C's *Compositing and Blending Level 1* draft](https://www.w3.org/TR/compositing-1/) for more details.
93/// Illustrations fall under the [W3C open license](https://www.w3.org/copyright/software-license/).
94#[derive(Copy, Clone, PartialEq, Eq, Debug)]
95#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
96#[repr(u8)]
97pub enum Compose {
98    /// No regions are enabled.
99    ///
100    /// ![](https://www.w3.org/TR/compositing-1/examples/PD_clr.svg)
101    Clear = 0,
102    /// Only the source will be present.
103    ///
104    /// ![](https://www.w3.org/TR/compositing-1/examples/PD_src.svg)
105    Copy = 1,
106    /// Only the destination will be present.
107    ///
108    /// ![](https://www.w3.org/TR/compositing-1/examples/PD_dst.svg)
109    Dest = 2,
110    /// The source is placed over the destination.
111    ///
112    /// ![](https://www.w3.org/TR/compositing-1/examples/PD_src-over.svg)
113    SrcOver = 3,
114    /// The destination is placed over the source.
115    ///
116    /// ![](https://www.w3.org/TR/compositing-1/examples/PD_dst-over.svg)
117    DestOver = 4,
118    /// The parts of the source that overlap with the destination are placed.
119    ///
120    /// ![](https://www.w3.org/TR/compositing-1/examples/PD_src-in.svg)
121    SrcIn = 5,
122    /// The parts of the destination that overlap with the source are placed.
123    ///
124    /// ![](https://www.w3.org/TR/compositing-1/examples/PD_dst-in.svg)
125    DestIn = 6,
126    /// The parts of the source that fall outside of the destination are placed.
127    ///
128    /// ![](https://www.w3.org/TR/compositing-1/examples/PD_src-out.svg)
129    SrcOut = 7,
130    /// The parts of the destination that fall outside of the source are placed.
131    ///
132    /// ![](https://www.w3.org/TR/compositing-1/examples/PD_dst-out.svg)
133    DestOut = 8,
134    /// The parts of the source which overlap the destination replace the destination. The
135    /// destination is placed everywhere else.
136    ///
137    /// ![](https://www.w3.org/TR/compositing-1/examples/PD_src-atop.svg)
138    SrcAtop = 9,
139    /// The parts of the destination which overlaps the source replace the source. The source is
140    /// placed everywhere else.
141    ///
142    /// ![](https://www.w3.org/TR/compositing-1/examples/PD_dst-atop.svg)
143    DestAtop = 10,
144    /// The non-overlapping regions of source and destination are combined.
145    ///
146    /// ![](https://www.w3.org/TR/compositing-1/examples/PD_xor.svg)
147    Xor = 11,
148    /// The sum of the source image and destination image is displayed.
149    Plus = 12,
150    /// Allows two elements to cross fade by changing their opacities from 0 to 1 on one
151    /// element and 1 to 0 on the other element.
152    PlusLighter = 13,
153    // NOTICE: If a new value is added, be sure to modify `MAX_VALUE` in the `bytemuck::Contiguous` impl.
154}
155
156/// Blend mode consisting of [color mixing](Mix) and [composition functions](Compose).
157#[derive(Copy, Clone, PartialEq, Eq, Debug)]
158#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
159pub struct BlendMode {
160    /// The color mixing function.
161    pub mix: Mix,
162    /// The layer composition function.
163    pub compose: Compose,
164}
165
166impl BlendMode {
167    /// Creates a new blend mode from color mixing and layer composition
168    /// functions.
169    #[must_use]
170    pub const fn new(mix: Mix, compose: Compose) -> Self {
171        Self { mix, compose }
172    }
173}
174
175impl Default for BlendMode {
176    fn default() -> Self {
177        Self {
178            mix: Mix::Normal,
179            compose: Compose::SrcOver,
180        }
181    }
182}
183
184impl From<Mix> for BlendMode {
185    fn from(mix: Mix) -> Self {
186        Self {
187            mix,
188            compose: Compose::SrcOver,
189        }
190    }
191}
192
193impl From<Compose> for BlendMode {
194    fn from(compose: Compose) -> Self {
195        Self {
196            mix: Mix::Normal,
197            compose,
198        }
199    }
200}