package zntg import ( "errors" "image/color" "regexp" ) var hexColorRE = regexp.MustCompile(`^#?([0-9A-Fa-f]{2})-?([0-9A-Fa-f]{2})-?([0-9A-Fa-f]{2})-?([0-9A-Fa-f]{2})?$`) // HexColor parses hexadecimal string s and returns the RGBA color. Accepted are 3 or 4 components (R, G, B, A) following an optional hash character '#'. func HexColor(s string) (color.RGBA, error) { match := hexColorRE.FindStringSubmatch(s) if match == nil { return color.RGBA{}, errors.New("invalid color format") } values, err := HexToInts(match[1:]...) if err != nil { return color.RGBA{}, err } a := 255 if len(match[4]) > 0 { a = values[3] } return color.RGBA{R: uint8(values[0]), G: uint8(values[1]), B: uint8(values[2]), A: uint8(a)}, nil } // HexToInt tries to convert a string with hexadecimal characters to an integer. 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 } // HexToInts tries to convert multiple strings with hexadecimal characters to a slice of integers. 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 } // MustHexColor parses hexadecimal string s and returns the RGBA color. If the conversion fails it panics. func MustHexColor(s string) color.RGBA { color, err := HexColor(s) if err != nil { panic(err) } return color }