-
-
Notifications
You must be signed in to change notification settings - Fork 4
/
web_color.go
123 lines (109 loc) · 2.43 KB
/
web_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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
package coloring
import (
"fmt"
"image/color"
"strconv"
)
// Like color.RGBA but we can be serialized to JSON!
type WebColor struct {
R byte
G byte
B byte
A byte
}
func (c WebColor) MarshalJSON() ([]byte, error) {
if c.A != 255 {
return []byte(fmt.Sprintf(
"\"#%02x%02x%02x%02x\"",
c.R,
c.G,
c.B,
c.A,
)), nil
}
return []byte(fmt.Sprintf(
"\"#%02x%02x%02x\"",
c.R,
c.G,
c.B,
)), nil
}
func (c WebColor) RGBA() (r, g, b, a uint32) {
r = uint32(c.R)
r |= r << 8
g = uint32(c.G)
g |= g << 8
b = uint32(c.B)
b |= b << 8
a = uint32(c.A)
a |= a << 8
return
}
func (c WebColor) RGBA8() color.RGBA {
return color.RGBA{
R: c.R,
G: c.G,
B: c.B,
A: c.A,
}
}
func (c *WebColor) unmarshalJson6Digit(data []byte) error {
hex := string(data)
r, err := strconv.ParseUint(hex[2:4], 16, 8)
if err != nil {
return fmt.Errorf("unable to parse r component of color '%s': %w", hex, err)
}
g, err := strconv.ParseUint(hex[4:6], 16, 8)
if err != nil {
return fmt.Errorf("unable to parse g component of color '%s': %w", hex, err)
}
b, err := strconv.ParseUint(hex[6:8], 16, 8)
if err != nil {
return fmt.Errorf("unable to parse b component of color '%s': %w", hex, err)
}
var a uint64 = 255
if len(data) == 11 {
a, err = strconv.ParseUint(hex[8:10], 16, 8)
if err != nil {
return fmt.Errorf("unable to parse a component of color '%s': %w", hex, err)
}
}
c.R = byte(r)
c.G = byte(g)
c.B = byte(b)
c.A = byte(a)
return nil
}
func (c *WebColor) unmarshalJson3Digit(data []byte) error {
hex := string(data)
r, err := strconv.ParseUint(hex[2:3]+hex[2:3], 16, 8)
if err != nil {
return fmt.Errorf("unable to parse r component of color '%s': %w", hex, err)
}
g, err := strconv.ParseUint(hex[3:4]+hex[3:4], 16, 8)
if err != nil {
return fmt.Errorf("unable to parse g component of color '%s': %w", hex, err)
}
b, err := strconv.ParseUint(hex[4:5]+hex[4:5], 16, 8)
if err != nil {
return fmt.Errorf("unable to parse b component of color '%s': %w", hex, err)
}
var a uint64 = 255
if len(data) == 7 {
a, err = strconv.ParseUint(hex[5:6]+hex[5:6], 16, 8)
if err != nil {
return fmt.Errorf("unable to parse a component of color '%s': %w", hex, err)
}
}
c.R = byte(r)
c.G = byte(g)
c.B = byte(b)
c.A = byte(a)
return nil
}
func (c *WebColor) UnmarshalJSON(data []byte) error {
if len(data) == 6 || len(data) == 7 {
return c.unmarshalJson3Digit(data)
}
return c.unmarshalJson6Digit(data)
}