Skip to content

Commit

Permalink
use external color parser package
Browse files Browse the repository at this point in the history
  • Loading branch information
flopp committed Apr 21, 2024
1 parent 71a7dd7 commit 9eab920
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 47 deletions.
55 changes: 8 additions & 47 deletions color.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,58 +6,19 @@
package sm

import (
"fmt"
"image/color"
"regexp"
"strings"

"github.com/mazznoer/csscolorparser"
)

// ParseColorString parses hex color strings (i.e. `0xRRGGBB`, `#RRGGBB`, `0xRRGGBBAA`, `#RRGGBBAA`), and names colors (e.g. 'black', 'blue', ...)
// ParseColorString parses hex color strings (i.e. `#RRGGBB`, `RRGGBBAA`, `#RRGGBBAA`), and named colors (e.g. 'black', 'blue', ...)
func ParseColorString(s string) (color.Color, error) {
s = strings.ToLower(strings.TrimSpace(s))

re := regexp.MustCompile(`^(0x|#)([A-Fa-f0-9]{6})$`)
matches := re.FindStringSubmatch(s)
if matches != nil {
var r, g, b int
fmt.Sscanf(matches[2], "%2x%2x%2x", &r, &g, &b)
return color.RGBA{uint8(r), uint8(g), uint8(b), 0xff}, nil
}

re = regexp.MustCompile(`^(0x|#)([A-Fa-f0-9]{8})$`)
matches = re.FindStringSubmatch(s)
if matches != nil {
var r, g, b, a int
fmt.Sscanf(matches[2], "%2x%2x%2x%2x", &r, &g, &b, &a)
rr := float64(r) * float64(a) / 256.0
gg := float64(g) * float64(a) / 256.0
bb := float64(b) * float64(a) / 256.0
return color.RGBA{uint8(rr), uint8(gg), uint8(bb), uint8(a)}, nil
}

switch s {
case "black":
return color.RGBA{0x00, 0x00, 0x00, 0xff}, nil
case "blue":
return color.RGBA{0x00, 0x00, 0xff, 0xff}, nil
case "brown":
return color.RGBA{0x96, 0x4b, 0x00, 0xff}, nil
case "green":
return color.RGBA{0x00, 0xff, 0x00, 0xff}, nil
case "orange":
return color.RGBA{0xff, 0x7f, 0x00, 0xff}, nil
case "purple":
return color.RGBA{0x7f, 0x00, 0x7f, 0xff}, nil
case "red":
return color.RGBA{0xff, 0x00, 0x00, 0xff}, nil
case "yellow":
return color.RGBA{0xff, 0xff, 0x00, 0xff}, nil
case "white":
return color.RGBA{0xff, 0xff, 0xff, 0xff}, nil
case "transparent":
return color.RGBA{0x00, 0x00, 0x00, 0x00}, nil
if col, err := csscolorparser.Parse(s); err != nil {
return nil, err
} else {

Check failure on line 18 in color.go

View workflow job for this annotation

GitHub Actions / tests

if block ends with a return statement, so drop this else and outdent its block (move short variable declaration to its own line if necessary)
r, g, b, a := col.RGBA255()
return color.RGBA{r, g, b, a}, nil
}
return color.Transparent, fmt.Errorf("cannot parse color string '%s'", s)
}

// Luminance computes the luminance (~ brightness) of the given color. Range: 0.0 for black to 1.0 for white.
Expand Down
47 changes: 47 additions & 0 deletions color_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package sm

import (
"image/color"
"testing"
)

type string_color_err struct {
input string
expected_color color.Color
expected_error bool
}

func TestParseColor(t *testing.T) {
for _, test := range []string_color_err{
{"WHITE", color.RGBA{0xFF, 0xFF, 0xFF, 0xFF}, false},
{"white", color.RGBA{0xFF, 0xFF, 0xFF, 0xFF}, false},
{"yellow", color.RGBA{0xFF, 0xFF, 0x00, 0xFF}, false},
{"transparent", color.RGBA{0x00, 0x00, 0x00, 0x00}, false},
{"#FF00FF42", color.RGBA{0xFF, 0x00, 0xFF, 0x42}, false},
{"#ff00ff42", color.RGBA{0xFF, 0x00, 0xFF, 0x42}, false},
{"#ff00ff", color.RGBA{0xFF, 0x00, 0xFF, 0xFF}, false},
{"#f0f", color.RGBA{0xFF, 0x00, 0xFF, 0xFF}, false},
{"FF00FF42", color.RGBA{0xFF, 0x00, 0xFF, 0x42}, false},
{"ff00ff42", color.RGBA{0xFF, 0x00, 0xFF, 0x42}, false},
{"ff00ff", color.RGBA{0xFF, 0x00, 0xFF, 0xFF}, false},
{"f0f", color.RGBA{0xFF, 0x00, 0xFF, 0xFF}, false},
{"bad-name", color.RGBA{0x00, 0x00, 0x00, 0x00}, true},
{"#FF00F", color.RGBA{0x00, 0x00, 0x00, 0x00}, true},
{"#GGGGGG", color.RGBA{0x00, 0x00, 0x00, 0x00}, true},
{"", color.RGBA{0x00, 0x00, 0x00, 0x00}, true},
} {
c, err := ParseColorString(test.input)
if test.expected_error {
if err == nil {
t.Errorf("error expected when parsing '%s'", test.input)
}
} else {
if err != nil {
t.Errorf("unexpected error when parsing '%s': %v", test.input, err)
}
if c != test.expected_color {
t.Errorf("unexpected color when parsing '%s': %v expected: %v", test.input, c, test.expected_color)
}
}
}
}
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ require (

require (
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
github.com/mazznoer/csscolorparser v0.1.3 // indirect
golang.org/x/net v0.22.0 // indirect
golang.org/x/sys v0.18.0 // indirect
golang.org/x/text v0.14.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ github.com/golang/geo v0.0.0-20230421003525-6adc56603217/go.mod h1:8wI0hitZ3a1Ix
github.com/jessevdk/go-flags v1.5.0 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LFvc=
github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4=
github.com/joeshaw/gengen v0.0.0-20190604015154-c77d87825f5a/go.mod h1:v2qvRL8Xwk4OlARK6gPlf2JreZXzv0dYp/8+kUJ0y7Q=
github.com/mazznoer/csscolorparser v0.1.3 h1:vug4zh6loQxAUxfU1DZEu70gTPufDPspamZlHAkKcxE=
github.com/mazznoer/csscolorparser v0.1.3/go.mod h1:Aj22+L/rYN/Y6bj3bYqO3N6g1dtdHtGfQ32xZ5PJQic=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
Expand Down

0 comments on commit 9eab920

Please sign in to comment.