@@ -225,6 +225,40 @@ pub enum SrgbColor {
225225 } ,
226226}
227227
228+ /// <https://w3c.github.io/csswg-drafts/css-color-4/#hsl-to-rgb>
229+ #[ inline]
230+ pub fn hsl_to_rgb ( hue : f32 , saturation : f32 , lightness : f32 ) -> ( f32 , f32 , f32 ) {
231+ let mut hue = hue;
232+
233+ if hue < 0. {
234+ hue += 1. ;
235+ }
236+
237+ let f = |n : f32 | -> f32 {
238+ let k = ( hue. mul_add ( 12. , n) ) % 12. ;
239+ let a = saturation * lightness. min ( 1. - lightness) ;
240+
241+ a. mul_add ( -( -1f32 ) . max ( ( k - 3. ) . min ( 9. - k) . min ( 1. ) ) , lightness)
242+ } ;
243+
244+ ( f ( 0. ) , f ( 8. ) , f ( 4. ) )
245+ }
246+
247+ /// <https://w3c.github.io/csswg-drafts/css-color-4/#hwb-to-rgb>
248+ #[ inline]
249+ pub fn hwb_to_rgb ( hue : f32 , whiteness : f32 , blackness : f32 ) -> ( f32 , f32 , f32 ) {
250+ if whiteness + blackness >= 1. {
251+ let gray = whiteness / ( whiteness + blackness) ;
252+ return ( gray, gray, gray) ;
253+ }
254+
255+ let ( red, green, blue) = hsl_to_rgb ( hue, 1. , 0.5 ) ;
256+
257+ let f = |c : f32 | -> f32 { c. mul_add ( 1. - whiteness - blackness, whiteness) } ;
258+
259+ ( f ( red) , f ( green) , f ( blue) )
260+ }
261+
228262impl SrgbColor {
229263 /// Construct an sRGB color from its component channels.
230264 pub fn new (
@@ -1551,56 +1585,6 @@ where
15511585 ) ) )
15521586}
15531587
1554- /// https://w3c.github.io/csswg-drafts/css-color-4/#hwb-to-rgb
1555- #[ inline]
1556- pub fn hwb_to_rgb ( h : f32 , w : f32 , b : f32 ) -> ( f32 , f32 , f32 ) {
1557- if w + b >= 1.0 {
1558- let gray = w / ( w + b) ;
1559- return ( gray, gray, gray) ;
1560- }
1561-
1562- let ( mut red, mut green, mut blue) = hsl_to_rgb ( h, 1.0 , 0.5 ) ;
1563- let x = 1.0 - w - b;
1564- red = red * x + w;
1565- green = green * x + w;
1566- blue = blue * x + w;
1567- ( red, green, blue)
1568- }
1569-
1570- /// https://w3c.github.io/csswg-drafts/css-color-4/#hsl-to-rgb
1571- /// except with h pre-multiplied by 3, to avoid some rounding errors.
1572- #[ inline]
1573- pub fn hsl_to_rgb ( hue : f32 , saturation : f32 , lightness : f32 ) -> ( f32 , f32 , f32 ) {
1574- fn hue_to_rgb ( m1 : f32 , m2 : f32 , mut h3 : f32 ) -> f32 {
1575- if h3 < 0. {
1576- h3 += 3.
1577- }
1578- if h3 > 3. {
1579- h3 -= 3.
1580- }
1581- if h3 * 2. < 1. {
1582- m1 + ( m2 - m1) * h3 * 2.
1583- } else if h3 * 2. < 3. {
1584- m2
1585- } else if h3 < 2. {
1586- m1 + ( m2 - m1) * ( 2. - h3) * 2.
1587- } else {
1588- m1
1589- }
1590- }
1591- let m2 = if lightness <= 0.5 {
1592- lightness * ( saturation + 1. )
1593- } else {
1594- lightness + saturation - lightness * saturation
1595- } ;
1596- let m1 = lightness * 2. - m2;
1597- let hue_times_3 = hue * 3. ;
1598- let red = hue_to_rgb ( m1, m2, hue_times_3 + 1. ) ;
1599- let green = hue_to_rgb ( m1, m2, hue_times_3) ;
1600- let blue = hue_to_rgb ( m1, m2, hue_times_3 - 1. ) ;
1601- ( red, green, blue)
1602- }
1603-
16041588#[ cfg( test) ]
16051589mod tests {
16061590 use crate :: ParserInput ;
0 commit comments