1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00
v/vlib/gx/color.v

310 lines
5.1 KiB
V

module gx
pub const (
black = Color{
r: 0
g: 0
b: 0
}
gray = Color{
r: 128
g: 128
b: 128
}
white = Color{
r: 255
g: 255
b: 255
}
red = Color{
r: 255
g: 0
b: 0
}
green = Color{
r: 0
g: 255
b: 0
}
blue = Color{
r: 0
g: 0
b: 255
}
yellow = Color{
r: 255
g: 255
b: 0
}
magenta = Color{
r: 255
g: 0
b: 255
}
cyan = Color{
r: 0
g: 255
b: 255
}
orange = Color{
r: 255
g: 165
b: 0
}
purple = Color{
r: 128
g: 0
b: 128
}
indigo = Color{
r: 75
g: 0
b: 130
}
pink = Color{
r: 255
g: 192
b: 203
}
violet = Color{
r: 238
g: 130
b: 238
}
dark_blue = Color{
r: 0
g: 0
b: 139
}
dark_gray = Color{
r: 169
g: 169
b: 169
}
dark_green = Color{
r: 0
g: 100
b: 0
}
dark_red = Color{
r: 139
g: 0
b: 0
}
light_blue = Color{
r: 173
g: 216
b: 230
}
light_gray = Color{
r: 211
g: 211
b: 211
}
light_green = Color{
r: 144
g: 238
b: 144
}
light_red = Color{
r: 255
g: 204
b: 203
}
)
// Color represents a 32 bit color value in sRGB format
pub struct Color {
pub mut:
r u8
g u8
b u8
a u8 = 255
}
// hex takes in a 32 bit integer and splits it into 4 byte values
pub fn hex(color int) Color {
return Color{
r: u8((color >> 24) & 0xFF)
g: u8((color >> 16) & 0xFF)
b: u8((color >> 8) & 0xFF)
a: u8(color & 0xFF)
}
}
// rgb builds a Color instance from given r, g, b values
pub fn rgb(r u8, g u8, b u8) Color {
return Color{
r: r
g: g
b: b
}
}
// rgba builds a Color instance from given r, g, b, a values
pub fn rgba(r u8, g u8, b u8, a u8) Color {
return Color{
r: r
g: g
b: b
a: a
}
}
// + adds `b` to `a`, with a maximum value of 255 for each channel
pub fn (a Color) + (b Color) Color {
mut na := int(a.a) + b.a
mut nr := int(a.r) + b.r
mut ng := int(a.g) + b.g
mut nb := int(a.b) + b.b
if na > 255 {
na = 255
}
if nr > 255 {
nr = 255
}
if ng > 255 {
ng = 255
}
if nb > 255 {
nb = 255
}
return Color{
r: u8(nr)
g: u8(ng)
b: u8(nb)
a: u8(na)
}
}
// - subtracts `b` from `a`, with a minimum value of 0 for each channel
pub fn (a Color) - (b Color) Color {
mut na := if a.a > b.a { a.a } else { b.a }
mut nr := int(a.r) - b.r
mut ng := int(a.g) - b.g
mut nb := int(a.b) - b.b
if na < 0 {
na = 0
}
if nr < 0 {
nr = 0
}
if ng < 0 {
ng = 0
}
if nb < 0 {
nb = 0
}
return Color{
r: u8(nr)
g: u8(ng)
b: u8(nb)
a: u8(na)
}
}
// * multiplies Color `c` and `c2` keeping channel values in [0, 255] range
pub fn (c Color) * (c2 Color) Color {
return Color{
r: c.r * c2.r
g: c.g * c2.g
b: c.b * c2.b
a: c.a * c2.a
}
}
// / divides `c` by `c2` and converts each channel's value to u8(int)
pub fn (c Color) / (c2 Color) Color {
return Color{
r: c.r / c2.r
g: c.g / c2.g
b: c.b / c2.b
a: c.a / c2.a
}
}
// over implements an `a` over `b` operation.
// see https://keithp.com/~keithp/porterduff/p253-porter.pdf
pub fn (a Color) over(b Color) Color {
aa := f32(a.a) / 255
ab := f32(b.a) / 255
ar := aa + ab * (1 - aa)
//
rr := (f32(a.r) * aa + f32(b.r) * ab * (1 - aa)) / ar
gr := (f32(a.g) * aa + f32(b.g) * ab * (1 - aa)) / ar
br := (f32(a.b) * aa + f32(b.b) * ab * (1 - aa)) / ar
return Color{
r: u8(rr)
g: u8(gr)
b: u8(br)
a: u8(ar * 255)
}
}
// eq checks if color `c` and `c2` are equal in every channel
pub fn (c Color) eq(c2 Color) bool {
return c.r == c2.r && c.g == c2.g && c.b == c2.b && c.a == c2.a
}
// str returns a string representation of the Color `c`
pub fn (c Color) str() string {
return 'Color{${c.r}, ${c.g}, ${c.b}, ${c.a}}'
}
// rgba8 converts a color value to an int in the RGBA8 order.
// see https://developer.apple.com/documentation/coreimage/ciformat
[inline]
pub fn (c Color) rgba8() int {
return int(u32(c.r) << 24 | u32(c.g) << 16 | u32(c.b) << 8 | u32(c.a))
}
// bgra8 converts a color value to an int in the BGRA8 order.
// see https://developer.apple.com/documentation/coreimage/ciformat
[inline]
pub fn (c Color) bgra8() int {
return int(u32(c.b) << 24 | u32(c.g) << 16 | u32(c.r) << 8 | u32(c.a))
}
// abgr8 converts a color value to an int in the ABGR8 order.
// see https://developer.apple.com/documentation/coreimage/ciformat
[inline]
pub fn (c Color) abgr8() int {
return int(u32(c.a) << 24 | u32(c.b) << 16 | u32(c.g) << 8 | u32(c.r))
}
const (
string_colors = {
'blue': blue
'red': red
'green': green
'yellow': yellow
'orange': orange
'purple': purple
'black': black
'gray': gray
'indigo': indigo
'pink': pink
'violet': violet
'white': white
'dark_blue': dark_blue
'dark_gray': dark_gray
'dark_green': dark_green
'dark_red': dark_red
'light_blue': light_blue
'light_gray': light_gray
'light_green': light_green
'light_red': light_red
}
)
// color_from_string returns a Color, corresponding to the given string
// or black Color if string is not found in lookup table
pub fn color_from_string(s string) Color {
return gx.string_colors[s]
}
// to_css_string returns a CSS compatible string e.g. `rgba(10,11,12,13)` of the color `c`.
pub fn (c Color) to_css_string() string {
return 'rgba(${c.r},${c.g},${c.b},${c.a})'
}