// Copyright 2026 Leo Cheng
// SPDX-License-Identifier: Apache-2.0
// Pixels handed to the colour package, and colour handed back.
//
// This library keeps a pixel as four samples and does not know what a colour
// space is beyond the one the file declared. Turning a hue, blending in a
// perceptual space or asking what a colour is called are therefore not its
// business: they belong to the colour library, which owns the spaces and the
// conversions between them. These two functions are the whole of the seam.
///|
/// The pixel as a colour in sRGB, alpha included.
pub fn Pixel::to_color(self : Pixel) -> @moonrgba.Color {
@moonrgba.Color::srgb(self.r, self.g, self.b, alpha=self.a)
}
///|
/// The colour as a pixel, converted to sRGB first.
///
/// A colour outside sRGB is brought into it rather than clipped in whatever
/// space it arrived in, and the conversion keeps the alpha it was given.
pub fn Pixel::of_color(color : @moonrgba.Color) -> Pixel {
let rgb = color.to_srgb()
{ r: rgb.x, g: rgb.y, b: rgb.z, a: color.alpha, }
}
///|
/// The pixel with its hue turned, in degrees.
///
/// Done in HSL so that the hue is what moves: lightness and saturation come out
/// as they went in, which is not true of a hue rotation done by mixing channel
/// matrices. A grey pixel has no hue to turn and comes back unchanged.
pub fn Pixel::rotate_hue(self : Pixel, degrees : Double) -> Pixel {
if self.r == self.g && self.g == self.b {
return self
}
let hsl = self.to_color().to_hsl()
let turned = hsl.x + degrees
let hue = turned - 360.0 * (turned / 360.0).floor()
Pixel::of_color(@moonrgba.Color::hsl(hue, hsl.y, hsl.z, alpha=self.a))
}