Documentation ¶
Overview ¶
Package color implements parsing, formatting, and manipulating CSS colours based on the CSS Color Module Level 4 (W3C Candidate Recommendation Draft), 1 November 2022.
NOTE - INCOMPLETE! DO NOT USE YET.
Note that named colors and system colors are not implemented.
Disclaimer: although this software runs against a thorough and diverse set of test cases, no claims are made of this software's performance or conformance against the W3C Specification itself because it has not yet been tested against the relevant W3C test suite.
This software includes material derived from CSS Color Module Level 4, W3C Candidate Recommendation Draft, 1 November 2022. Copyright © 2021 W3C® (MIT, ERCIM, Keio, Beihang). See LICENSE-PARTS.txt and TRADEMARKS.md.
## "Specified", "Computed", "Actual" and "Used" values in CSS
CSS has the concept of "specified", "computed", "actual" and "used" values. For example, "rgb(512, 128, 0)" may be the specified value. CSS says it is not invalid, but is clamped to "rgb(255, 128, 0)" at compute time. Similarly, color(display-p3 1.0844 0.43 0.1) is "valid", remains so at compute time, but is out of gamut and so the "actual" value is the color given by gamut mapping the color for the display. This distinction is up to the caller to manage, but function documentation will give notes on how to achieve this.
## “Missing” Color Components and the none Keyword
Sometimes, a color component can be "missing". In CSS this can be manually specified by the keyword "none". In this Go implementation, the distinction between missing and present values is implemented with the maybe.M type.
Color components can also be "powerless". For example, in hsl(), the hue component is powerless when the saturation component is 0% - this is a grayscale color, and hue has no effect on it, no matter its value. A powerless component automatically produced by color space conversion will be set to missing.
See section 4.4 of the specification for more details.
TODO only actually need float16 precision...
Index ¶
- Constants
- Variables
- func Equal(a Color, b Color) bool
- type Color
- func HSL(hue maybe.M[float64], saturation maybe.M[float64], lightness maybe.M[float64], ...) Color
- func Hexadecimal(red, green, blue, alpha uint8) Color
- func Map(dest Space, c Color) Color
- func ParseColor(tokenizer Tokenizer) (Color, error)
- func ParseColorString(s string) (Color, error)
- func RGB(red maybe.M[float64], green maybe.M[float64], blue maybe.M[float64], ...) Color
- type Space
- type Tokenizer
- type WhitePoint
Constants ¶
const ( // SpaceSRGB is the colour space used by RGB, HSL, HWB. SpaceSRGB = Space("sRGB") // SpaceSRGBLinear predefined colour space is "the same as sRGB except that // the transfer function is linear-light (there is no gamma-encoding)." SpaceSRGBLinear = Space("sRGB-linear") // SpaceDisplayP3 has the same transfer curve as sRGB but a wider gamut. // "Modern displays, TVs, laptop screens and phone screens are able to // display all, or nearly all, of the display-p3 gamut." SpaceDisplayP3 = Space("display-p3") // SpaceA98RGB is inaccurate, but with a wider gamut than sRGB. It was // developed by Adobe and often used in Photoshop and with some // professional displays. SpaceA98RGB = Space("a98-RGB") // SpaceProPhotoRGB (also known as ROMM RGB) was developed by Kodak and // is often used in digital photography due to its very wide gamut. SpaceProPhotoRGB = Space("prophoto-RGB") // SpaceRec2020 (the ITU-R BT.2020-2 colour space) has a very wide // gamut and is used in ultra-high-definition television. SpaceRec2020 = Space("rec2020") // SpaceXYZ is a CIE XYZ colour space that covers the full gamut of // human vision. The Y component represents luminosity and the XZ plane // contains all possible chromaticities at that luminance. SpaceXYZ = SpaceXYZD65 // SpaceXYZD50 is the CIE XYZ color space with a D50 white point. SpaceXYZD50 = Space("xyz-d50") // SpaceXYZD65 is the CIE XYZ color space with a D65 white point. SpaceXYZD65 = Space("xyz-d65") )
Variables ¶
var ( ErrTooManyFunctionArguments = fmt.Errorf("too many function arguments") ErrSyntax = fmt.Errorf("invalid color syntax") ErrUnexpectedEOF = fmt.Errorf("unexpected end of file") ErrUnexpectedTrailing = fmt.Errorf("unexpected trailing input") ErrNotSupportedNamedOrSystem = fmt.Errorf("named and system colors not supported") ErrUnrecognisedFunction = fmt.Errorf("unrecognised function") ErrInvalidArguments = fmt.Errorf("invalid function arguments") ErrInvalidHex = fmt.Errorf("invalid hexadecimal color") )
var D50 = WhitePoint{0.345700, 0.358500}
var D65 = WhitePoint{0.312700, 0.329000}
Functions ¶
Types ¶
type Color ¶
type Color struct {
// contains filtered or unexported fields
}
func HSL ¶
func HSL( hue maybe.M[float64], saturation maybe.M[float64], lightness maybe.M[float64], alpha maybe.M[float64], ) Color
HSL returns a color as if specified by the CSS hsl() function. However, each argument here is specified in the normalized range [0,1] (but may lie outside this range until computed). The computed value needs to clamp the input to the allowed range with the Color.Norm method, which also converts a HSL color to RGB.
func Hexadecimal ¶
Hexadecimal returns a color as if specified in a CSS RGB hexadecimal notation (e.g. #FFCC77).
func Map ¶
Map performs gamut mapping of a colour using the CSS gamut mapping algorithm. It returns a gamut mapped colour still in its original colour space, but representable in the destination color space.
This is necessary when a colour (in any color space) is to be represented in a destination colour space where it would be could not be physically produced on a display device (e.g. a screen).
The destination colour space may be the same colour space as the input colour's space. For example, color(srgb 200% 0% 0%) is a valid colour, and could be used as a gradient stop, but is out of gamut for the sRGB color space and needs gamut mapping.
Some destination color spaces are not intended for display, and therefore have no gamut limits, and therefore perform no gamut mapping. These are the XYZ, Lab, LCH, Oklab, Oklch spaces.
Note that for other purposes, such as print, different gamut mapping functions (not specified by CSS) may be more appropriate.
func ParseColor ¶
ParseColor parses a color value from CSS tokens.
Note: the caller should ensure that, after a valid color is returned, the tokenizer produces token.EOF() (possibly preceded by whitespace) if necessary when parsing an entire input as a color.
func ParseColorString ¶
ParseColorString parses a color value from a string containing a color in CSS syntax.
func RGB ¶
func RGB( red maybe.M[float64], green maybe.M[float64], blue maybe.M[float64], alpha maybe.M[float64], ) Color
RGB returns a color as if specified by the CSS rgb() function. However, each argument here is specified in the normalized range [0,1] (but may lie outside this range until computed). The computed value needs to clamp the input to the allowed range with the Color.Norm method.
func (Color) Norm ¶
Norm performs some steps to "normalise" a Color as part of turning a "specified" value into a "computed" value.
For colours specified as hexadecimal, rgb(), rgba(), hsl(), hsla(), hwb(), or named colours, this involves clamping to the normalised range for each colour component, and converting to the rgb representation.
For colours specified as lab() or lch(), oklab(), or oklch(), this involves clamping to the normalised range for each colour component where a bound exists.
For colours specified by the color() function, values are not clamped (this means that, although valid, they may still be out of gamut).
For colours specified by the color() function using the "xyz" color space (which is an alias of the xyz-d65 color space), the computed and used value is in the xyz-d65 color space.
All alpha values are clamped to the range [0, 1].
func (Color) String ¶
String returns a serialised representation of the color.
Note that serialised colours are normally derived from the computed, not specified, colour. Therefore, this function is only compliant with the spec when serialising a computed colour. The Color.Norm method can help with calculating a computed colour.
Even though the spec does not define behaviour for serialising non-computed values, this function still returns a useful serialisation for such values which is generally the same as the serialisation of a computed value without clamping or rgb conversion applied.
Note that serialisation generally uses a fallback legacy format as far as possible. For example, the color returned by parsing "rgb(128 64 32 / 50%)" will always be serialised into the legacy format "rgba(128, 64, 32, 0.5)".
type Space ¶
type Space string
Space is a color space. It describes "an organization of colours with respect to an underlying colorimetric model, such that there is a clear, objectively-measurable meaning for any colour in that colour space. This also means that the same color can be expressed in multiple color spaces, or transformed from one color space to another, while still looking the same."
type Tokenizer ¶
Tokenizer produces CSS tokens - it is implemented, for example, by a tokenizer.Tokenizer.
type WhitePoint ¶
type WhitePoint struct {
X, Y float64
}
WhitePoint defines the colour white under a certain viewing condition, such as daylight, as chromaticity coordinates (x,y) of a perfectly reflecting diffuser.
For the purposes of CSS, these are only the coordinates for a 2 degree standard observer.
Wikipedia says "if the color of an object is recorded under one illuminant, then it is possible to estimate the color of that object under another illuminant, given only the white points of the two illuminants."