colr 0.3.1

A general purpose, extensible color type unifying color models and their operations at the type level.
Documentation
//! Screen blend mode for linear colors.

use crate::Color;
use crate::BackingStore;
use crate::ChannelMap;
use crate::model::Rgb;
use crate::primaries::Primaries;
use crate::transfer::Linear;

impl<P, L> Color<[f32; 3], Rgb<P, Linear, L>>
where
    P: Primaries,
    L: BackingStore<[f32; 3]>,
{
    /// Screen blend: `1 - (1 - self) * (1 - rhs)` per channel.
    #[inline(always)]
    pub fn screen(self, rhs: Self) -> Self {
        let [a0, a1, a2] = self.inner();
        let [b0, b1, b2] = rhs.inner();
        Color::new([
            1.0 - (1.0 - a0) * (1.0 - b0),
            1.0 - (1.0 - a1) * (1.0 - b1),
            1.0 - (1.0 - a2) * (1.0 - b2),
        ])
    }
}

impl<P, L> Color<[f32; 4], Rgb<P, Linear, L>>
where
    P: Primaries,
    L: BackingStore<[f32; 4]> + ChannelMap<4>,
{
    /// Screen blend: `1 - (1 - self) * (1 - rhs)` per color channel. Alpha passes through from `self`.
    #[inline(always)]
    pub fn screen(self, rhs: Self) -> Self {
        let s = self.inner();
        let r = rhs.inner();
        let [ri, gi, bi, _] = L::INDICES;
        let mut out = s;
        out[ri] = 1.0 - (1.0 - s[ri]) * (1.0 - r[ri]);
        out[gi] = 1.0 - (1.0 - s[gi]) * (1.0 - r[gi]);
        out[bi] = 1.0 - (1.0 - s[bi]) * (1.0 - r[bi]);
        Color::new(out)
    }
}