From 80ac29e7cdcfdc1728c92047ea571cb01dc9f626 Mon Sep 17 00:00:00 2001 From: Meghan Denny Date: Thu, 14 Sep 2023 20:22:25 -0700 Subject: [PATCH] add HSL --- HSL.zig | 26 ++++++++++++++++++++++++++ mod.zig | 1 + sRGB.zig | 19 +++++++++++++++++++ x.zig | 3 +++ 4 files changed, 49 insertions(+) create mode 100644 HSL.zig create mode 100644 x.zig diff --git a/HSL.zig b/HSL.zig new file mode 100644 index 0000000000000000000000000000000000000000..e88ad72d5c87b33b6db69088fbda5da5512545de --- /dev/null +++ b/HSL.zig @@ -0,0 +1,26 @@ +//! object representing a single color in the HSL colorspace with h channel value from 0-360 and s,l channel values from 0-1 + +const std = @import("std"); +const Self = @This(); + +h: f32, // hue +s: f32, // saturation +l: f32, // luminance +a: f32, // alpha + +pub fn initHSLA(h: f32, s: f32, l: f32, a: f32) Self { + std.debug.assert(h >= 0.0 and h <= 1.0); + std.debug.assert(s >= 0.0 and s <= 1.0); + std.debug.assert(l >= 0.0 and l <= 1.0); + std.debug.assert(a >= 0.0 and a <= 1.0); + return Self{ + .h = h, + .s = s, + .l = l, + .a = a, + }; +} + +pub fn eql(x: Self, y: Self) bool { + return x.h == y.h and x.s == y.s and x.l == y.l and x.a == y.a; +} diff --git a/mod.zig b/mod.zig index 0ec6c5ec197751f5b06dd8dee9af7de1fbe07c3c..621e3dcdf45a9f1b7de0842ba0dac64e832ed6cd 100644 --- a/mod.zig +++ b/mod.zig @@ -4,3 +4,4 @@ const color = @This(); pub const sRGB = @import("./sRGB.zig"); pub const LinearRgb = @import("./LinearRgb.zig"); pub const CMYK = @import("./CMYK.zig"); +pub const HSL = @import("./HSL.zig"); diff --git a/sRGB.zig b/sRGB.zig index 20b9cb019ad8591ccee5352062a45906b821a170..a93e9cfeab7ce6db934e8aa91b4570756a964ce1 100644 --- a/sRGB.zig +++ b/sRGB.zig @@ -3,6 +3,7 @@ const std = @import("std"); const Self = @This(); const color = @import("./mod.zig"); +const _x = @import("./x.zig"); r: u8, // red value g: u8, // green value @@ -107,3 +108,21 @@ pub fn to_cmyk(x: Self) color.CMYK { const a = f.a; return color.CMYK.initCMYKA(c, m, y, k, a); } + +pub fn to_hsl(x: Self) color.HSL { + const f = x.to_float(); + const cmax = @max(f.r, f.g, f.b); + const cmin = @min(f.r, f.g, f.b); + const delta = cmax - cmin; + const h = blk: { + if (delta == 0) break :blk 0; + if (cmax == f.r) break :blk ((((f.g - f.b) / delta) % 6) * 60) % 360; + if (cmax == f.g) break :blk ((((f.b - f.r) / delta) + 2) * 60) % 360; + if (cmax == f.b) break :blk ((((f.r - f.g) / delta) + 4) * 60) % 360; + unreachable; + }; + const l = (cmax + cmin) / 2; + const s = if (delta == 0) 0 else delta / (1 - _x.abs(2 * l - 1)); + const a = f.a; + return color.HSL.initHSLA(h, s, l, a); +} diff --git a/x.zig b/x.zig new file mode 100644 index 0000000000000000000000000000000000000000..04b5125dc952773a5e972841ba06962a14d0aade --- /dev/null +++ b/x.zig @@ -0,0 +1,3 @@ +pub fn abs(x: f32) f32 { + return if (x < 0.0) -x else x; +} -- 2.54.0