Skip to content

Commit 9eab920

Browse files
committed
use external color parser package
1 parent 71a7dd7 commit 9eab920

File tree

4 files changed

+58
-47
lines changed

4 files changed

+58
-47
lines changed

color.go

Lines changed: 8 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -6,58 +6,19 @@
66
package sm
77

88
import (
9-
"fmt"
109
"image/color"
11-
"regexp"
12-
"strings"
10+
11+
"github.com/mazznoer/csscolorparser"
1312
)
1413

15-
// ParseColorString parses hex color strings (i.e. `0xRRGGBB`, `#RRGGBB`, `0xRRGGBBAA`, `#RRGGBBAA`), and names colors (e.g. 'black', 'blue', ...)
14+
// ParseColorString parses hex color strings (i.e. `#RRGGBB`, `RRGGBBAA`, `#RRGGBBAA`), and named colors (e.g. 'black', 'blue', ...)
1615
func ParseColorString(s string) (color.Color, error) {
17-
s = strings.ToLower(strings.TrimSpace(s))
18-
19-
re := regexp.MustCompile(`^(0x|#)([A-Fa-f0-9]{6})$`)
20-
matches := re.FindStringSubmatch(s)
21-
if matches != nil {
22-
var r, g, b int
23-
fmt.Sscanf(matches[2], "%2x%2x%2x", &r, &g, &b)
24-
return color.RGBA{uint8(r), uint8(g), uint8(b), 0xff}, nil
25-
}
26-
27-
re = regexp.MustCompile(`^(0x|#)([A-Fa-f0-9]{8})$`)
28-
matches = re.FindStringSubmatch(s)
29-
if matches != nil {
30-
var r, g, b, a int
31-
fmt.Sscanf(matches[2], "%2x%2x%2x%2x", &r, &g, &b, &a)
32-
rr := float64(r) * float64(a) / 256.0
33-
gg := float64(g) * float64(a) / 256.0
34-
bb := float64(b) * float64(a) / 256.0
35-
return color.RGBA{uint8(rr), uint8(gg), uint8(bb), uint8(a)}, nil
36-
}
37-
38-
switch s {
39-
case "black":
40-
return color.RGBA{0x00, 0x00, 0x00, 0xff}, nil
41-
case "blue":
42-
return color.RGBA{0x00, 0x00, 0xff, 0xff}, nil
43-
case "brown":
44-
return color.RGBA{0x96, 0x4b, 0x00, 0xff}, nil
45-
case "green":
46-
return color.RGBA{0x00, 0xff, 0x00, 0xff}, nil
47-
case "orange":
48-
return color.RGBA{0xff, 0x7f, 0x00, 0xff}, nil
49-
case "purple":
50-
return color.RGBA{0x7f, 0x00, 0x7f, 0xff}, nil
51-
case "red":
52-
return color.RGBA{0xff, 0x00, 0x00, 0xff}, nil
53-
case "yellow":
54-
return color.RGBA{0xff, 0xff, 0x00, 0xff}, nil
55-
case "white":
56-
return color.RGBA{0xff, 0xff, 0xff, 0xff}, nil
57-
case "transparent":
58-
return color.RGBA{0x00, 0x00, 0x00, 0x00}, nil
16+
if col, err := csscolorparser.Parse(s); err != nil {
17+
return nil, err
18+
} else {
19+
r, g, b, a := col.RGBA255()
20+
return color.RGBA{r, g, b, a}, nil
5921
}
60-
return color.Transparent, fmt.Errorf("cannot parse color string '%s'", s)
6122
}
6223

6324
// Luminance computes the luminance (~ brightness) of the given color. Range: 0.0 for black to 1.0 for white.

color_test.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package sm
2+
3+
import (
4+
"image/color"
5+
"testing"
6+
)
7+
8+
type string_color_err struct {
9+
input string
10+
expected_color color.Color
11+
expected_error bool
12+
}
13+
14+
func TestParseColor(t *testing.T) {
15+
for _, test := range []string_color_err{
16+
{"WHITE", color.RGBA{0xFF, 0xFF, 0xFF, 0xFF}, false},
17+
{"white", color.RGBA{0xFF, 0xFF, 0xFF, 0xFF}, false},
18+
{"yellow", color.RGBA{0xFF, 0xFF, 0x00, 0xFF}, false},
19+
{"transparent", color.RGBA{0x00, 0x00, 0x00, 0x00}, false},
20+
{"#FF00FF42", color.RGBA{0xFF, 0x00, 0xFF, 0x42}, false},
21+
{"#ff00ff42", color.RGBA{0xFF, 0x00, 0xFF, 0x42}, false},
22+
{"#ff00ff", color.RGBA{0xFF, 0x00, 0xFF, 0xFF}, false},
23+
{"#f0f", color.RGBA{0xFF, 0x00, 0xFF, 0xFF}, false},
24+
{"FF00FF42", color.RGBA{0xFF, 0x00, 0xFF, 0x42}, false},
25+
{"ff00ff42", color.RGBA{0xFF, 0x00, 0xFF, 0x42}, false},
26+
{"ff00ff", color.RGBA{0xFF, 0x00, 0xFF, 0xFF}, false},
27+
{"f0f", color.RGBA{0xFF, 0x00, 0xFF, 0xFF}, false},
28+
{"bad-name", color.RGBA{0x00, 0x00, 0x00, 0x00}, true},
29+
{"#FF00F", color.RGBA{0x00, 0x00, 0x00, 0x00}, true},
30+
{"#GGGGGG", color.RGBA{0x00, 0x00, 0x00, 0x00}, true},
31+
{"", color.RGBA{0x00, 0x00, 0x00, 0x00}, true},
32+
} {
33+
c, err := ParseColorString(test.input)
34+
if test.expected_error {
35+
if err == nil {
36+
t.Errorf("error expected when parsing '%s'", test.input)
37+
}
38+
} else {
39+
if err != nil {
40+
t.Errorf("unexpected error when parsing '%s': %v", test.input, err)
41+
}
42+
if c != test.expected_color {
43+
t.Errorf("unexpected color when parsing '%s': %v expected: %v", test.input, c, test.expected_color)
44+
}
45+
}
46+
}
47+
}

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ require (
1313

1414
require (
1515
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
16+
github.com/mazznoer/csscolorparser v0.1.3 // indirect
1617
golang.org/x/net v0.22.0 // indirect
1718
golang.org/x/sys v0.18.0 // indirect
1819
golang.org/x/text v0.14.0 // indirect

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ github.com/golang/geo v0.0.0-20230421003525-6adc56603217/go.mod h1:8wI0hitZ3a1Ix
1313
github.com/jessevdk/go-flags v1.5.0 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LFvc=
1414
github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4=
1515
github.com/joeshaw/gengen v0.0.0-20190604015154-c77d87825f5a/go.mod h1:v2qvRL8Xwk4OlARK6gPlf2JreZXzv0dYp/8+kUJ0y7Q=
16+
github.com/mazznoer/csscolorparser v0.1.3 h1:vug4zh6loQxAUxfU1DZEu70gTPufDPspamZlHAkKcxE=
17+
github.com/mazznoer/csscolorparser v0.1.3/go.mod h1:Aj22+L/rYN/Y6bj3bYqO3N6g1dtdHtGfQ32xZ5PJQic=
1618
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
1719
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
1820
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=

0 commit comments

Comments
 (0)