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