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 /// 
15 Normal = 0,
16 /// Source color is multiplied by the destination color and replaces the destination.
17 ///
18 /// 
19 Multiply = 1,
20 /// Multiplies the complements of the backdrop and source color values, then complements the result.
21 ///
22 /// 
23 Screen = 2,
24 /// Multiplies or screens the colors, depending on the backdrop color value.
25 ///
26 /// 
27 Overlay = 3,
28 /// Selects the darker of the backdrop and source colors.
29 ///
30 /// 
31 Darken = 4,
32 /// Selects the lighter of the backdrop and source colors.
33 ///
34 /// 
35 Lighten = 5,
36 /// Brightens the backdrop color to reflect the source color. Painting with black produces no
37 /// change.
38 ///
39 /// 
40 ColorDodge = 6,
41 /// Darkens the backdrop color to reflect the source color. Painting with white produces no
42 /// change.
43 ///
44 /// 
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 /// 
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 /// 
55 SoftLight = 9,
56 /// Subtracts the darker of the two constituent colors from the lighter color.
57 ///
58 /// 
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 /// 
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 /// 
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 /// 
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 /// 
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 /// 
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 /// 
110 Clear = 0,
111 /// Only the source will be present.
112 ///
113 /// 
114 Copy = 1,
115 /// Only the destination will be present.
116 ///
117 /// 
118 Dest = 2,
119 /// The source is placed over the destination.
120 ///
121 /// 
122 SrcOver = 3,
123 /// The destination is placed over the source.
124 ///
125 /// 
126 DestOver = 4,
127 /// The parts of the source that overlap with the destination are placed.
128 ///
129 /// 
130 SrcIn = 5,
131 /// The parts of the destination that overlap with the source are placed.
132 ///
133 /// 
134 DestIn = 6,
135 /// The parts of the source that fall outside of the destination are placed.
136 ///
137 /// 
138 SrcOut = 7,
139 /// The parts of the destination that fall outside of the source are placed.
140 ///
141 /// 
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 /// 
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 /// 
152 DestAtop = 10,
153 /// The non-overlapping regions of source and destination are combined.
154 ///
155 /// 
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}