mirror of
https://github.com/charmbracelet/lipgloss.git
synced 2024-09-11 22:17:12 +03:00
fix: RGBA implementations for non-hex color values
This commit is contained in:
parent
cabfd38a13
commit
651d1265e7
55
color.go
55
color.go
@ -1,7 +1,6 @@
|
||||
package lipgloss
|
||||
|
||||
import (
|
||||
"image/color"
|
||||
"sync"
|
||||
|
||||
"github.com/muesli/termenv"
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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()
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package lipgloss
|
||||
|
||||
import (
|
||||
"image/color"
|
||||
"testing"
|
||||
|
||||
"github.com/muesli/termenv"
|
||||
@ -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
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user