Skip to content

Commit

Permalink
fix: RGBA implementations for non-hex color values
Browse files Browse the repository at this point in the history
  • Loading branch information
muesli committed Sep 30, 2022
1 parent cabfd38 commit 651d126
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 51 deletions.
55 changes: 4 additions & 51 deletions color.go
@@ -1,7 +1,6 @@
package lipgloss

import (
"image/color"
"sync"

"github.com/muesli/termenv"
Expand Down Expand Up @@ -144,7 +143,7 @@ func (c Color) color() termenv.Color {
//
// Red: 0x0, Green: 0x0, Blue: 0x0, Alpha: 0xFF.
func (c Color) RGBA() (r, g, b, a uint32) {
return hexToColor(c.value()).RGBA()
return termenv.ConvertToRGB(c.color()).RGBA()
}

// AdaptiveColor provides color options for light and dark backgrounds. The
Expand Down Expand Up @@ -175,8 +174,7 @@ func (ac AdaptiveColor) color() termenv.Color {
//
// Red: 0x0, Green: 0x0, Blue: 0x0, Alpha: 0xFF.
func (ac AdaptiveColor) RGBA() (r, g, b, a uint32) {
cf := hexToColor(ac.value())
return cf.RGBA()
return termenv.ConvertToRGB(ac.color()).RGBA()
}

// CompleteColor specifies exact values for truecolor, ANSI256, and ANSI color
Expand Down Expand Up @@ -209,7 +207,7 @@ func (c CompleteColor) color() termenv.Color {
//
// Red: 0x0, Green: 0x0, Blue: 0x0, Alpha: 0xFFFF
func (c CompleteColor) RGBA() (r, g, b, a uint32) {
return hexToColor(c.value()).RGBA()
return termenv.ConvertToRGB(c.color()).RGBA()
}

// CompleteColor specifies exact values for truecolor, ANSI256, and ANSI color
Expand All @@ -236,50 +234,5 @@ func (cac CompleteAdaptiveColor) color() termenv.Color {
//
// Red: 0x0, Green: 0x0, Blue: 0x0, Alpha: 0xFFFF
func (cac CompleteAdaptiveColor) RGBA() (r, g, b, a uint32) {
return hexToColor(cac.value()).RGBA()
}

// hexToColor translates a hex color string (#RRGGBB or #RGB) into a color.RGB,
// which satisfies the color.Color interface. If an invalid string is passed
// black with 100% opacity will be returned: or, in hex format, 0x000000FF.
func hexToColor(hex string) (c color.RGBA) {
c.A = 0xFF

if hex == "" || hex[0] != '#' {
return c
}

const (
fullFormat = 7 // #RRGGBB
shortFormat = 4 // #RGB
)

switch len(hex) {
case fullFormat:
const offset = 4
c.R = hexToByte(hex[1])<<offset + hexToByte(hex[2])
c.G = hexToByte(hex[3])<<offset + hexToByte(hex[4])
c.B = hexToByte(hex[5])<<offset + hexToByte(hex[6])
case shortFormat:
const offset = 0x11
c.R = hexToByte(hex[1]) * offset
c.G = hexToByte(hex[2]) * offset
c.B = hexToByte(hex[3]) * offset
}

return c
}

func hexToByte(b byte) byte {
const offset = 10
switch {
case b >= '0' && b <= '9':
return b - '0'
case b >= 'a' && b <= 'f':
return b - 'a' + offset
case b >= 'A' && b <= 'F':
return b - 'A' + offset
}
// Invalid, but just return 0.
return 0
return termenv.ConvertToRGB(cac.color()).RGBA()
}
46 changes: 46 additions & 0 deletions color_test.go
@@ -1,6 +1,7 @@
package lipgloss

import (
"image/color"
"testing"

"github.com/muesli/termenv"
Expand Down Expand Up @@ -225,3 +226,48 @@ func TestRGBA(t *testing.T) {
}
}
}

// hexToColor translates a hex color string (#RRGGBB or #RGB) into a color.RGB,
// which satisfies the color.Color interface. If an invalid string is passed
// black with 100% opacity will be returned: or, in hex format, 0x000000FF.
func hexToColor(hex string) (c color.RGBA) {
c.A = 0xFF

if hex == "" || hex[0] != '#' {
return c
}

const (
fullFormat = 7 // #RRGGBB
shortFormat = 4 // #RGB
)

switch len(hex) {
case fullFormat:
const offset = 4
c.R = hexToByte(hex[1])<<offset + hexToByte(hex[2])
c.G = hexToByte(hex[3])<<offset + hexToByte(hex[4])
c.B = hexToByte(hex[5])<<offset + hexToByte(hex[6])
case shortFormat:
const offset = 0x11
c.R = hexToByte(hex[1]) * offset
c.G = hexToByte(hex[2]) * offset
c.B = hexToByte(hex[3]) * offset
}

return c
}

func hexToByte(b byte) byte {
const offset = 10
switch {
case b >= '0' && b <= '9':
return b - '0'
case b >= 'a' && b <= 'f':
return b - 'a' + offset
case b >= 'A' && b <= 'F':
return b - 'A' + offset
}
// Invalid, but just return 0.
return 0
}

0 comments on commit 651d126

Please sign in to comment.