use crate::{stimulus::Stimulus, Alpha};
use super::{BlendFunction, PreAlpha, Premultiply};
pub trait BlendWith {
type Color: Premultiply;
#[must_use]
fn blend_with<F>(self, destination: Self, blend_function: F) -> Self
where
F: BlendFunction<Self::Color>;
}
impl<C> BlendWith for PreAlpha<C>
where
C: Premultiply,
{
type Color = C;
#[inline]
fn blend_with<F>(self, other: Self, blend_function: F) -> Self
where
F: BlendFunction<Self::Color>,
{
blend_function.apply_to(self, other)
}
}
impl<C> BlendWith for Alpha<C, C::Scalar>
where
C: Premultiply,
{
type Color = C;
fn blend_with<F>(self, destination: Self, blend_function: F) -> Self
where
F: crate::blend::BlendFunction<Self::Color>,
{
self.premultiply()
.blend_with(destination.premultiply(), blend_function)
.unpremultiply()
}
}
impl<C> BlendWith for C
where
C: Premultiply,
C::Scalar: Stimulus,
{
type Color = C;
fn blend_with<F>(self, other: Self, blend_function: F) -> Self
where
F: BlendFunction<Self::Color>,
{
PreAlpha::new_opaque(self)
.blend_with(PreAlpha::new_opaque(other), blend_function)
.unpremultiply()
.color
}
}