-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathcolor.go
86 lines (68 loc) · 1.66 KB
/
color.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
package layout
import "math"
type Color interface {
// RGBA returns the non-alpha-premultiplied red, green, blue and alpha values
// for the color. Each value ranges within [0, 0xff].
RGBA8() (r, g, b, a uint8)
}
// RGB represents an 24bit color
type RGB struct{ R, G, B uint8 }
func (rgb RGB) RGBA8() (r, g, b, a uint8) { return rgb.R, rgb.G, rgb.B, 0xFF }
// RGBA represents an 24bit color
type RGBA struct{ R, G, B, A uint8 }
func (rgb RGBA) RGBA8() (r, g, b, a uint8) { return rgb.R, rgb.G, rgb.B, rgb.A }
// HSL represents an color in hue, saturation and lightness space
type HSL struct{ H, S, L float32 }
func (hsl HSL) RGBA8() (r, g, b, a uint8) {
return HSLA{hsl.H, hsl.S, hsl.L, 1.0}.RGBA8()
}
// HSLA represents an color in hue, saturation and lightness space
type HSLA struct{ H, S, L, A float32 }
func (hsl HSLA) RGBA8() (r, g, b, a uint8) {
rf, gf, bf, af := hsla(hsl.H, hsl.S, hsl.L, hsl.A)
return sat8(rf), sat8(gf), sat8(bf), sat8(af)
}
func hue(v1, v2, h float32) float32 {
if h < 0 {
h += 1
}
if h > 1 {
h -= 1
}
if 6*h < 1 {
return v1 + (v2-v1)*6*h
} else if 2*h < 1 {
return v2
} else if 3*h < 2 {
return v1 + (v2-v1)*(2.0/3.0-h)*6
}
return v1
}
func hsla(h, s, l, a float32) (r, g, b, ra float32) {
if s == 0 {
return l, l, l, a
}
h = float32(math.Mod(float64(h), 1))
var v2 float32
if l < 0.5 {
v2 = l * (1 + s)
} else {
v2 = (l + s) - s*l
}
v1 := 2*l - v2
r = hue(v1, v2, h+1.0/3.0)
g = hue(v1, v2, h)
b = hue(v1, v2, h-1.0/3.0)
ra = a
return
}
// sat8 converts 0..1 float to 0..0xFF uint16
func sat8(v float32) uint8 {
v = v * 0xFF
if v >= 0xFF {
return 0xFF
} else if v <= 0 {
return 0
}
return uint8(v)
}