@@ -225,6 +225,40 @@ pub enum SrgbColor {
225
225
} ,
226
226
}
227
227
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
+
228
262
impl SrgbColor {
229
263
/// Construct an sRGB color from its component channels.
230
264
pub fn new (
@@ -1551,56 +1585,6 @@ where
1551
1585
) ) )
1552
1586
}
1553
1587
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
-
1604
1588
#[ cfg( test) ]
1605
1589
mod tests {
1606
1590
use crate :: ParserInput ;
0 commit comments