diff options
Diffstat (limited to 'internal/color/color.go')
| -rw-r--r-- | internal/color/color.go | 37 |
1 files changed, 34 insertions, 3 deletions
diff --git a/internal/color/color.go b/internal/color/color.go index 22fa143..13fca69 100644 --- a/internal/color/color.go +++ b/internal/color/color.go @@ -243,6 +243,24 @@ func NoColor() ColorSpec { return ColorSpec{Fg: -1, Bg: -1} } +// Average returns a ColorSpec whose foreground is the RGB midpoint of the two +// inputs' foregrounds. If only one input has a foreground, that one is used; if +// neither does, NoColor is returned. Styles and background are not carried over. +func Average(a, b ColorSpec) ColorSpec { + if a.Fg < 0 && b.Fg < 0 { + return NoColor() + } + if a.Fg < 0 { + return ColorSpec{Fg: b.Fg, Bg: -1} + } + if b.Fg < 0 { + return ColorSpec{Fg: a.Fg, Bg: -1} + } + r1, g1, b1 := Xterm256ToRGB(a.Fg) + r2, g2, b2 := Xterm256ToRGB(b.Fg) + return ColorSpec{Fg: NearestXterm256((r1+r2)/2, (g1+g2)/2, (b1+b2)/2), Bg: -1} +} + func Parse(input string) ColorSpec { spec := ColorSpec{Fg: -1, Bg: -1} for _, token := range strings.Fields(input) { @@ -254,14 +272,14 @@ func Parse(input string) ColorSpec { case token == "underline": spec.Underline = true case strings.HasPrefix(token, "bg:"): - if n, err := strconv.Atoi(strings.TrimPrefix(token, "bg:")); err == nil && n >= 0 && n <= 255 { + if n, ok := parseColorIndex(strings.TrimPrefix(token, "bg:")); ok { spec.Bg = n } case strings.HasPrefix(token, "g:"): parts := strings.Split(token[2:], ",") var stops []int for _, p := range parts { - if n, err := strconv.Atoi(strings.TrimSpace(p)); err == nil && n >= 0 && n <= 255 { + if n, ok := parseColorIndex(strings.TrimSpace(p)); ok { stops = append(stops, n) } } @@ -269,7 +287,7 @@ func Parse(input string) ColorSpec { spec.Gradient = stops } default: - if n, err := strconv.Atoi(token); err == nil && n >= 0 && n <= 255 { + if n, ok := parseColorIndex(token); ok { spec.Fg = n } } @@ -277,6 +295,19 @@ func Parse(input string) ColorSpec { return spec } +// parseColorIndex parses a 1-2 digit hexadecimal color index (00-FF, case +// insensitive) into its 0-255 value. Out-of-range or non-hex input fails. +func parseColorIndex(s string) (int, bool) { + if s == "" { + return 0, false + } + n, err := strconv.ParseUint(s, 16, 0) + if err != nil || n > 255 { + return 0, false + } + return int(n), true +} + func (s ColorSpec) Empty() bool { return s.Fg < 0 && s.Bg < 0 && !s.Bold && !s.Dim && !s.Underline && len(s.Gradient) == 0 } |
