1 use float::Float;
2 use num_traits::{One, Zero};
3 
4 use blend::{BlendFunction, PreAlpha};
5 use {cast, clamp, ComponentWise};
6 
7 ///A trait for colors that can be blended together.
8 ///
9 ///Blending can either be performed through the predefined blend modes, or a
10 ///custom blend functions.
11 ///
12 ///_Note: The default implementations of the blend modes are meant for color
13 ///components in the range [0.0, 1.0] and may otherwise produce strange
14 ///results._
15 pub trait Blend: Sized
16 where
17     <Self::Color as ComponentWise>::Scalar: Float,
18 {
19     ///The core color type. Typically `Self` for color types without alpha.
20     type Color: Blend<Color = Self::Color> + ComponentWise;
21 
22     ///Convert the color to premultiplied alpha.
into_premultiplied(self) -> PreAlpha<Self::Color, <Self::Color as ComponentWise>::Scalar>23     fn into_premultiplied(self) -> PreAlpha<Self::Color, <Self::Color as ComponentWise>::Scalar>;
24 
25     ///Convert the color from premultiplied alpha.
from_premultiplied( color: PreAlpha<Self::Color, <Self::Color as ComponentWise>::Scalar>, ) -> Self26     fn from_premultiplied(
27         color: PreAlpha<Self::Color, <Self::Color as ComponentWise>::Scalar>,
28     ) -> Self;
29 
30     ///Blend self, as the source color, with `destination`, using
31     ///`blend_function`. Anything that implements `BlendFunction` is
32     ///acceptable, including functions and closures.
33     ///
34     ///```
35     ///use palette::{LinSrgb, LinSrgba, Blend};
36     ///use palette::blend::PreAlpha;
37     ///
38     ///type PreRgba = PreAlpha<LinSrgb<f32>, f32>;
39     ///
40     ///fn blend_mode(a: PreRgba, b: PreRgba) -> PreRgba {
41     ///    PreAlpha {
42     ///        color: LinSrgb::new(a.red * b.green, a.green * b.blue, a.blue * b.red),
43     ///        alpha: a.alpha * b.alpha,
44     ///    }
45     ///}
46     ///
47     ///let a = LinSrgba::new(0.2, 0.5, 0.1, 0.8);
48     ///let b = LinSrgba::new(0.6, 0.3, 0.5, 0.1);
49     ///let c = a.blend(b, blend_mode);
50     ///```
blend<F>(self, destination: Self, blend_function: F) -> Self where F: BlendFunction<Self::Color>,51     fn blend<F>(self, destination: Self, blend_function: F) -> Self
52     where
53         F: BlendFunction<Self::Color>,
54     {
55         Self::from_premultiplied(
56             blend_function.apply_to(self.into_premultiplied(), destination.into_premultiplied()),
57         )
58     }
59 
60     ///Place `self` over `other`. This is the good old common alpha
61     ///composition equation.
over(self, other: Self) -> Self62     fn over(self, other: Self) -> Self {
63         let one = <Self::Color as ComponentWise>::Scalar::one();
64         let zero = <Self::Color as ComponentWise>::Scalar::zero();
65 
66         let src = self.into_premultiplied();
67         let dst = other.into_premultiplied();
68 
69         let result = PreAlpha {
70             color: src
71                 .color
72                 .component_wise(&dst.color, |a, b| a + b * (one - src.alpha)),
73             alpha: clamp(src.alpha + dst.alpha - src.alpha * dst.alpha, zero, one),
74         };
75 
76         Self::from_premultiplied(result)
77     }
78 
79     ///Results in the parts of `self` that overlaps the visible parts of
80     ///`other`.
inside(self, other: Self) -> Self81     fn inside(self, other: Self) -> Self {
82         let one = <Self::Color as ComponentWise>::Scalar::one();
83         let zero = <Self::Color as ComponentWise>::Scalar::zero();
84 
85         let src = self.into_premultiplied();
86         let dst = other.into_premultiplied();
87 
88         let result = PreAlpha {
89             color: src.color.component_wise_self(|a| a * dst.alpha),
90             alpha: clamp(src.alpha * dst.alpha, zero, one),
91         };
92 
93         Self::from_premultiplied(result)
94     }
95 
96     ///Results in the parts of `self` that lies outside the visible parts of
97     ///`other`.
outside(self, other: Self) -> Self98     fn outside(self, other: Self) -> Self {
99         let one = <Self::Color as ComponentWise>::Scalar::one();
100         let zero = <Self::Color as ComponentWise>::Scalar::zero();
101 
102         let src = self.into_premultiplied();
103         let dst = other.into_premultiplied();
104 
105         let result = PreAlpha {
106             color: src.color.component_wise_self(|a| a * (one - dst.alpha)),
107             alpha: clamp(src.alpha * (one - dst.alpha), zero, one),
108         };
109 
110         Self::from_premultiplied(result)
111     }
112 
113     ///Place `self` over only the visible parts of `other`.
atop(self, other: Self) -> Self114     fn atop(self, other: Self) -> Self {
115         let one = <Self::Color as ComponentWise>::Scalar::one();
116         let zero = <Self::Color as ComponentWise>::Scalar::zero();
117 
118         let src = self.into_premultiplied();
119         let dst = other.into_premultiplied();
120 
121         let result = PreAlpha {
122             color: src
123                 .color
124                 .component_wise(&dst.color, |a, b| a * dst.alpha + b * (one - src.alpha)),
125             alpha: clamp(dst.alpha, zero, one),
126         };
127 
128         Self::from_premultiplied(result)
129     }
130 
131     ///Results in either `self` or `other`, where they do not overlap.
xor(self, other: Self) -> Self132     fn xor(self, other: Self) -> Self {
133         let one = <Self::Color as ComponentWise>::Scalar::one();
134         let zero = <Self::Color as ComponentWise>::Scalar::zero();
135         let two = one + one;
136 
137         let src = self.into_premultiplied();
138         let dst = other.into_premultiplied();
139 
140         let result = PreAlpha {
141             color: src.color.component_wise(&dst.color, |a, b| {
142                 a * (one - dst.alpha) + b * (one - src.alpha)
143             }),
144             alpha: clamp(
145                 src.alpha + dst.alpha - two * src.alpha * dst.alpha,
146                 zero,
147                 one,
148             ),
149         };
150 
151         Self::from_premultiplied(result)
152     }
153 
154     ///Add `self` and `other`. This uses the alpha component to regulate the
155     ///effect, so it's not just plain component wise addition.
plus(self, other: Self) -> Self156     fn plus(self, other: Self) -> Self {
157         let one = <Self::Color as ComponentWise>::Scalar::one();
158         let zero = <Self::Color as ComponentWise>::Scalar::zero();
159 
160         let src = self.into_premultiplied();
161         let dst = other.into_premultiplied();
162 
163         let result = PreAlpha {
164             color: src.color.component_wise(&dst.color, |a, b| a + b),
165             alpha: clamp(src.alpha + dst.alpha, zero, one),
166         };
167 
168         Self::from_premultiplied(result)
169     }
170 
171     ///Multiply `self` with `other`. This uses the alpha component to regulate
172     ///the effect, so it's not just plain component wise multiplication.
multiply(self, other: Self) -> Self173     fn multiply(self, other: Self) -> Self {
174         let one = <Self::Color as ComponentWise>::Scalar::one();
175         let zero = <Self::Color as ComponentWise>::Scalar::zero();
176 
177         let src = self.into_premultiplied();
178         let dst = other.into_premultiplied();
179 
180         let result = PreAlpha {
181             color: src.color.component_wise(&dst.color, |a, b| {
182                 a * b + a * (one - dst.alpha) + b * (one - src.alpha)
183             }),
184             alpha: clamp(src.alpha + dst.alpha - src.alpha * dst.alpha, zero, one),
185         };
186 
187         Self::from_premultiplied(result)
188     }
189 
190     ///Make a color which is at least as light as `self` or `other`.
screen(self, other: Self) -> Self191     fn screen(self, other: Self) -> Self {
192         let one = <Self::Color as ComponentWise>::Scalar::one();
193         let zero = <Self::Color as ComponentWise>::Scalar::zero();
194 
195         let src = self.into_premultiplied();
196         let dst = other.into_premultiplied();
197 
198         let result = PreAlpha {
199             color: src.color.component_wise(&dst.color, |a, b| a + b - a * b),
200             alpha: clamp(src.alpha + dst.alpha - src.alpha * dst.alpha, zero, one),
201         };
202 
203         Self::from_premultiplied(result)
204     }
205 
206     ///Multiply `self` or `other` if other is dark, or screen them if `other`
207     ///is light. This results in an S curve.
overlay(self, other: Self) -> Self208     fn overlay(self, other: Self) -> Self {
209         let one = <Self::Color as ComponentWise>::Scalar::one();
210         let zero = <Self::Color as ComponentWise>::Scalar::zero();
211         let two = one + one;
212 
213         let src = self.into_premultiplied();
214         let dst = other.into_premultiplied();
215 
216         let result = PreAlpha {
217             color: src.color.component_wise(&dst.color, |a, b| {
218                 if b * two <= dst.alpha {
219                     two * a * b + a * (one - dst.alpha) + b * (one - src.alpha)
220                 } else {
221                     a * (one + dst.alpha) + b * (one + src.alpha)
222                         - two * a * b
223                         - src.alpha * dst.alpha
224                 }
225             }),
226             alpha: clamp(src.alpha + dst.alpha - src.alpha * dst.alpha, zero, one),
227         };
228 
229         Self::from_premultiplied(result)
230     }
231 
232     ///Return the darkest parts of `self` and `other`.
darken(self, other: Self) -> Self233     fn darken(self, other: Self) -> Self {
234         let one = <Self::Color as ComponentWise>::Scalar::one();
235         let zero = <Self::Color as ComponentWise>::Scalar::zero();
236 
237         let src = self.into_premultiplied();
238         let dst = other.into_premultiplied();
239 
240         let result = PreAlpha {
241             color: src.color.component_wise(&dst.color, |a, b| {
242                 (a * dst.alpha).min(b * src.alpha) + a * (one - dst.alpha) + b * (one - src.alpha)
243             }),
244             alpha: clamp(src.alpha + dst.alpha - src.alpha * dst.alpha, zero, one),
245         };
246 
247         Self::from_premultiplied(result)
248     }
249 
250     ///Return the lightest parts of `self` and `other`.
lighten(self, other: Self) -> Self251     fn lighten(self, other: Self) -> Self {
252         let one = <Self::Color as ComponentWise>::Scalar::one();
253         let zero = <Self::Color as ComponentWise>::Scalar::zero();
254 
255         let src = self.into_premultiplied();
256         let dst = other.into_premultiplied();
257 
258         let result = PreAlpha {
259             color: src.color.component_wise(&dst.color, |a, b| {
260                 (a * dst.alpha).max(b * src.alpha) + a * (one - dst.alpha) + b * (one - src.alpha)
261             }),
262             alpha: clamp(src.alpha + dst.alpha - src.alpha * dst.alpha, zero, one),
263         };
264 
265         Self::from_premultiplied(result)
266     }
267 
268     ///Lighten `other` to reflect `self`. Results in `other` if `self` is
269     ///black.
dodge(self, other: Self) -> Self270     fn dodge(self, other: Self) -> Self {
271         let one = <Self::Color as ComponentWise>::Scalar::one();
272         let zero = <Self::Color as ComponentWise>::Scalar::zero();
273 
274         let src = self.into_premultiplied();
275         let dst = other.into_premultiplied();
276 
277         let result = PreAlpha {
278             color: src.color.component_wise(&dst.color, |a, b| {
279                 if a == src.alpha && !b.is_normal() {
280                     a * (one - dst.alpha)
281                 } else if a == src.alpha {
282                     src.alpha * dst.alpha + a * (one - dst.alpha) + b * (one - src.alpha)
283                 } else {
284                     src.alpha * dst.alpha * one.min((b / dst.alpha) * src.alpha / (src.alpha - a))
285                         + a * (one - dst.alpha)
286                         + b * (one - src.alpha)
287                 }
288             }),
289             alpha: clamp(src.alpha + dst.alpha - src.alpha * dst.alpha, zero, one),
290         };
291 
292         Self::from_premultiplied(result)
293     }
294 
295     ///Darken `other` to reflect `self`. Results in `other` if `self` is
296     ///white.
burn(self, other: Self) -> Self297     fn burn(self, other: Self) -> Self {
298         let one = <Self::Color as ComponentWise>::Scalar::one();
299         let zero = <Self::Color as ComponentWise>::Scalar::zero();
300 
301         let src = self.into_premultiplied();
302         let dst = other.into_premultiplied();
303 
304         let result = PreAlpha {
305             color: src.color.component_wise(&dst.color, |a, b| {
306                 if !a.is_normal() && b == dst.alpha {
307                     src.alpha * dst.alpha + b * (one - src.alpha)
308                 } else if !a.is_normal() {
309                     b * (one - src.alpha)
310                 } else {
311                     src.alpha * dst.alpha * (one - one.min((one - b / dst.alpha) * src.alpha / a))
312                         + a * (one - dst.alpha)
313                         + b * (one - src.alpha)
314                 }
315             }),
316             alpha: clamp(src.alpha + dst.alpha - src.alpha * dst.alpha, zero, one),
317         };
318 
319         Self::from_premultiplied(result)
320     }
321 
322     ///Multiply `self` or `other` if other is dark, or screen them if `self`
323     ///is light. This is similar to `overlay`, but depends on `self` instead
324     ///of `other`.
hard_light(self, other: Self) -> Self325     fn hard_light(self, other: Self) -> Self {
326         let one = <Self::Color as ComponentWise>::Scalar::one();
327         let zero = <Self::Color as ComponentWise>::Scalar::zero();
328         let two = one + one;
329 
330         let src = self.into_premultiplied();
331         let dst = other.into_premultiplied();
332 
333         let result = PreAlpha {
334             color: src.color.component_wise(&dst.color, |a, b| {
335                 if a * two <= src.alpha {
336                     two * a * b + a * (one - dst.alpha) + b * (one - src.alpha)
337                 } else {
338                     a * (one + dst.alpha) + b * (one + src.alpha)
339                         - two * a * b
340                         - src.alpha * dst.alpha
341                 }
342             }),
343             alpha: clamp(src.alpha + dst.alpha - src.alpha * dst.alpha, zero, one),
344         };
345 
346         Self::from_premultiplied(result)
347     }
348 
349     ///Lighten `other` if `self` is light, or darken `other` as if it's burned
350     ///if `self` is dark. The effect is increased if the components of `self`
351     ///is further from 0.5.
soft_light(self, other: Self) -> Self352     fn soft_light(self, other: Self) -> Self {
353         let one = <Self::Color as ComponentWise>::Scalar::one();
354         let zero = <Self::Color as ComponentWise>::Scalar::zero();
355         let two = one + one;
356 
357         let src = self.into_premultiplied();
358         let dst = other.into_premultiplied();
359 
360         let result = PreAlpha {
361             color: src.color.component_wise(&dst.color, |a, b| {
362                 let m = if dst.alpha.is_normal() {
363                     b / dst.alpha
364                 } else {
365                     zero
366                 };
367 
368                 if a * two <= src.alpha {
369                     b * (src.alpha + (two * a - src.alpha) * (one - m))
370                         + a * (one - dst.alpha)
371                         + b * (one - src.alpha)
372                 } else if b * cast(4.0) <= dst.alpha {
373                     let m2 = m * m;
374                     let m3 = m2 * m;
375 
376                     dst.alpha
377                         * (two * a - src.alpha)
378                         * (m3 * cast(16.0) - m2 * cast(12.0) - m * cast(3.0))
379                         + a
380                         - a * dst.alpha
381                         + b
382                 } else {
383                     dst.alpha * (two * a - src.alpha) * (m.sqrt() - m) + a - a * dst.alpha + b
384                 }
385             }),
386             alpha: clamp(src.alpha + dst.alpha - src.alpha * dst.alpha, zero, one),
387         };
388 
389         Self::from_premultiplied(result)
390     }
391 
392     ///Return the absolute difference between `self` and `other`. It's
393     ///basically `abs(self - other)`, but regulated by the alpha component.
difference(self, other: Self) -> Self394     fn difference(self, other: Self) -> Self {
395         let one = <Self::Color as ComponentWise>::Scalar::one();
396         let zero = <Self::Color as ComponentWise>::Scalar::zero();
397         let two = one + one;
398 
399         let src = self.into_premultiplied();
400         let dst = other.into_premultiplied();
401 
402         let result = PreAlpha {
403             color: src.color.component_wise(&dst.color, |a, b| {
404                 a + b - two * (a * dst.alpha).min(b * src.alpha)
405             }),
406             alpha: clamp(src.alpha + dst.alpha - src.alpha * dst.alpha, zero, one),
407         };
408 
409         Self::from_premultiplied(result)
410     }
411 
412     ///Similar to `difference`, but appears to result in a lower contrast.
413     ///`other` is inverted if `self` is white, and preserved if `self` is
414     ///black.
exclusion(self, other: Self) -> Self415     fn exclusion(self, other: Self) -> Self {
416         let one = <Self::Color as ComponentWise>::Scalar::one();
417         let zero = <Self::Color as ComponentWise>::Scalar::zero();
418         let two = one + one;
419 
420         let src = self.into_premultiplied();
421         let dst = other.into_premultiplied();
422 
423         let result = PreAlpha {
424             color: src
425                 .color
426                 .component_wise(&dst.color, |a, b| a + b - two * a * b),
427             alpha: clamp(src.alpha + dst.alpha - src.alpha * dst.alpha, zero, one),
428         };
429 
430         Self::from_premultiplied(result)
431     }
432 }
433