101 lines
2.2 KiB
Swift
101 lines
2.2 KiB
Swift
import SDL2
|
|
import HSLuv
|
|
|
|
|
|
public struct Colour: Equatable { let r, g, b, a: Float }
|
|
|
|
public extension Colour
|
|
{
|
|
static var zero: Self { .init(r: 0, g: 0, b: 0, a: 0) }
|
|
static var black: Self { .init(r: 0, g: 0, b: 0, a: 1) }
|
|
static var white: Self { .init(r: 1, g: 1, b: 1, a: 1) }
|
|
|
|
init(r: Float, g: Float, b: Float)
|
|
{
|
|
self.init(r: r, g: g, b: b, a: 1.0)
|
|
}
|
|
|
|
init(fromSdl: SDL_Color)
|
|
{
|
|
self.init(
|
|
r: Float(fromSdl.r) / 0xFF,
|
|
g: Float(fromSdl.g) / 0xFF,
|
|
b: Float(fromSdl.b) / 0xFF,
|
|
a: Float(fromSdl.a) / 0xFF)
|
|
}
|
|
|
|
init(fromRgb24: UInt32)
|
|
{
|
|
self.init(
|
|
r: Float((fromRgb24 >> 16) & 0xFF) / 0xFF,
|
|
g: Float((fromRgb24 >> 8) & 0xFF) / 0xFF,
|
|
b: Float((fromRgb24 >> 0) & 0xFF) / 0xFF,
|
|
a: 1)
|
|
}
|
|
|
|
init(fromRgba32: UInt32)
|
|
{
|
|
self.init(
|
|
r: Float((fromRgba32 >> 24) & 0xFF) / 0xFF,
|
|
g: Float((fromRgba32 >> 16) & 0xFF) / 0xFF,
|
|
b: Float((fromRgba32 >> 8) & 0xFF) / 0xFF,
|
|
a: Float((fromRgba32 >> 0) & 0xFF) / 0xFF)
|
|
}
|
|
|
|
init(grey v: Float)
|
|
{
|
|
self.init(r: v, g: v, b: v)
|
|
}
|
|
|
|
func mix(with rhs: Colour, _ amount: Float) -> Colour
|
|
{
|
|
let x = amount.saturate
|
|
return Colour(
|
|
r: Float.lerp(r, rhs.r, x),
|
|
g: Float.lerp(g, rhs.g, x),
|
|
b: Float.lerp(b, rhs.b, x),
|
|
a: Float.lerp(a, rhs.a, x))
|
|
}
|
|
|
|
func lighten(by: Double) -> Colour
|
|
{
|
|
var hue = CGFloat(), sat = CGFloat(), light = CGFloat()
|
|
rgbToHsluv(CGFloat(r), CGFloat(g), CGFloat(b), &hue, &sat, &light)
|
|
let gamma: CGFloat = 3.0
|
|
light = pow((pow(light / 100, 1 / gamma) + CGFloat(by) * 0.8).saturate, gamma) * 100
|
|
var newR = CGFloat(), newG = CGFloat(), newB = CGFloat()
|
|
hsluvToRgb(hue, sat, light, &newR, &newG, &newB)
|
|
return Colour(r: Float(newR), g: Float(newG), b: Float(newB), a: a)
|
|
}
|
|
|
|
var linear: Colour { get
|
|
{
|
|
Colour(
|
|
r: linearFromSrgb(r),
|
|
g: linearFromSrgb(g),
|
|
b: linearFromSrgb(b),
|
|
a: a)
|
|
} }
|
|
|
|
func setAlpha(_ newAlpha: Float) -> Colour
|
|
{
|
|
return Colour(r: r, g: g, b: b, a: newAlpha)
|
|
}
|
|
}
|
|
|
|
|
|
@inline(__always) fileprivate func srgbFromLinear(_ x: Float) -> Float
|
|
{
|
|
return (x < 0.0031308)
|
|
? x * 12.92
|
|
: 1.055 * pow(x, 1.0 / 2.4) - 0.055
|
|
}
|
|
|
|
@inline(__always) fileprivate func linearFromSrgb(_ x: Float) -> Float
|
|
{
|
|
return (x < 0.04045)
|
|
? x / 12.92
|
|
: pow((x + 0.055) / 1.055, 2.4)
|
|
}
|
|
|