diff --git a/color.go b/color.go new file mode 100644 index 0000000..4ef740b --- /dev/null +++ b/color.go @@ -0,0 +1,55 @@ +package tins2020 + +import ( + "errors" + "regexp" + + "github.com/veandco/go-sdl2/sdl" +) + +var hexColorRE = regexp.MustCompile(`^#?([0-9A-Fa-f]{2})-?([0-9A-Fa-f]{2})-?([0-9A-Fa-f]{2})-?([0-9A-Fa-f]{2})?$`) + +func HexColor(s string) (sdl.Color, error) { + match := hexColorRE.FindStringSubmatch(s) + if match == nil { + return sdl.Color{}, errors.New("invalid color format") + } + values, err := HexToInts(match[1:]...) + if err != nil { + return sdl.Color{}, err + } + a := 255 + if len(match[4]) > 0 { + a = values[3] + } + return sdl.Color{R: uint8(values[0]), G: uint8(values[1]), B: uint8(values[2]), A: uint8(a)}, nil +} + +func HexToInt(s string) (int, error) { + var i int + for _, c := range s { + i *= 16 + if c >= '0' && c <= '9' { + i += int(c - '0') + } else if c >= 'A' && c <= 'F' { + i += int(c - 'A' + 10) + } else if c >= 'a' && c <= 'f' { + i += int(c - 'a' + 10) + } else { + return 0, errors.New("hex digit not supported") + } + } + return i, nil +} + +func HexToInts(s ...string) ([]int, error) { + ints := make([]int, len(s)) + for i, s := range s { + value, err := HexToInt(s) + if err != nil { + return nil, err + } + ints[i] = value + } + return ints, nil +} diff --git a/color_test.go b/color_test.go new file mode 100644 index 0000000..0b6f08e --- /dev/null +++ b/color_test.go @@ -0,0 +1,33 @@ +package tins2020 + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/veandco/go-sdl2/sdl" +) + +func TestHexColor(t *testing.T) { + type test struct { + Hex string + Success bool + Expected sdl.Color + } + tests := []test{ + test{Hex: "#AA3939", Success: true, Expected: sdl.Color{R: 170, G: 57, B: 57, A: 255}}, + test{Hex: "AA3939", Success: true, Expected: sdl.Color{R: 170, G: 57, B: 57, A: 255}}, + test{Hex: "#AA3939BB", Success: true, Expected: sdl.Color{R: 170, G: 57, B: 57, A: 187}}, + test{Hex: "AG3939", Success: false, Expected: sdl.Color{}}, + test{Hex: "AA3939A", Success: false, Expected: sdl.Color{}}, + test{Hex: "AA39A", Success: false, Expected: sdl.Color{}}, + } + for _, test := range tests { + color, err := HexColor(test.Hex) + if test.Success { + assert.Nil(t, err) + assert.Equal(t, color, test.Expected) + } else { + assert.NotNil(t, err) + } + } +}