swf2ass-go/types/math/color.go

87 lines
1.8 KiB
Go

package math
import (
"fmt"
"math"
)
type PackedColor uint32
func NewPackedColor(r, g, b, a uint8) PackedColor {
return PackedColor((uint64(a) << 24) | (uint64(r) << 16) | (uint64(g) << 8) | uint64(b))
}
func (c PackedColor) Alpha() uint8 {
return uint8((c >> 24) & 0xFF)
}
func (c PackedColor) R() uint8 {
return uint8((c >> 16) & 0xFF)
}
func (c PackedColor) G() uint8 {
return uint8((c >> 8) & 0xFF)
}
func (c PackedColor) B() uint8 {
return uint8(c & 0xFF)
}
func (c PackedColor) Color() Color {
return Color{
R: c.R(),
G: c.G(),
B: c.B(),
Alpha: c.Alpha(),
}
}
type Color struct {
R, G, B, Alpha uint8
}
func (c Color) Packed() PackedColor {
return NewPackedColor(c.R, c.G, c.B, c.Alpha)
}
func (c Color) Equals(o Color, alpha bool) bool {
if !alpha {
return c.R == o.R && c.G == o.G && c.B == o.B
}
return c == o
}
func intPowD(a, b uint8) int64 {
return (int64(a) - int64(b)) * (int64(a) - int64(b))
}
func (c Color) Distance(o Color, alpha bool) float64 {
dist := intPowD(c.R, o.R) + intPowD(c.G, o.G) + intPowD(c.B, o.B)
if alpha {
dist += intPowD(c.Alpha, o.Alpha)
}
return math.Sqrt(float64(dist))
}
func (c Color) ToLinearRGB() Color {
return Color{
R: uint8(math.Pow(float64(c.R)/255, 2.2) * 255),
G: uint8(math.Pow(float64(c.G)/255, 2.2) * 255),
B: uint8(math.Pow(float64(c.B)/255, 2.2) * 255),
Alpha: uint8(math.Pow(float64(c.Alpha)/255, 2.2) * 255),
}
}
func (c Color) ToSRGB() Color {
return Color{
R: uint8(math.Pow(float64(c.R)/255, 0.4545) * 255),
G: uint8(math.Pow(float64(c.G)/255, 0.4545) * 255),
B: uint8(math.Pow(float64(c.B)/255, 0.4545) * 255),
Alpha: uint8(math.Pow(float64(c.Alpha)/255, 0.4545) * 255),
}
}
func (c Color) String() string {
return fmt.Sprintf("rgba(%d,%d,%d,%d)", c.R, c.G, c.B, c.Alpha)
}