Skip to main content

incular_rendering/
color_space.rs

1//! The color space Incular composites in.
2//!
3//! Incular blends, filters and interpolates gamma-encoded sRGB components
4//! directly, as Flutter (Skia and Impeller), browsers and CSS do. An
5//! `rgba(20, 20, 24, 220)` panel over a light page therefore looks like the
6//! near-black its components describe instead of the mid-grey that blending
7//! in linear light produces. Renderers must keep every source color, sampled
8//! texel, gradient stop and framebuffer value in this one space: they upload
9//! [`working_rgba`] values and render into non-sRGB targets so the GPU
10//! neither decodes nor encodes at the boundary.
11
12use incular_core::Color;
13
14/// Straight encoded-sRGB components of `color` normalized to `0.0..=1.0`:
15/// the value a renderer's shaders and blend units operate on.
16#[must_use]
17pub fn working_rgba(color: Color) -> [f32; 4] {
18    [color.red, color.green, color.blue, color.alpha].map(|channel| f32::from(channel) / 255.)
19}
20
21/// [`working_rgba`] with RGB multiplied by alpha.
22#[must_use]
23pub fn premultiplied_working_rgba(color: Color) -> [f32; 4] {
24    let [red, green, blue, alpha] = working_rgba(color);
25    [red * alpha, green * alpha, blue * alpha, alpha]
26}