@@ -97,12 +97,18 @@ impl<'de> Deserialize<'de> for RGBA {
9797 D : Deserializer < ' de > ,
9898 {
9999 let ( r, g, b, a) = Deserialize :: deserialize ( deserializer) ?;
100- Ok ( RGBA :: new ( r, g, b, a) )
100+ Ok ( Self :: new ( r, g, b, a) )
101101 }
102102}
103103
104104// NOTE: `RGBA` should not implement `ToCss` because it is an internal primitive that does not directly represent a CSS value.
105105
106+ #[ inline]
107+ fn f32_to_f64 ( f : f32 ) -> f64 {
108+ const PRECISION : f64 = 1e6 ;
109+ ( f64:: from ( f) * PRECISION ) . round ( ) / PRECISION
110+ }
111+
106112/// <hue>
107113/// <https://w3c.github.io/csswg-drafts/css-color-4/#hue-syntax>
108114#[ derive( Clone , Copy , PartialEq , Debug ) ]
@@ -296,10 +302,10 @@ impl SrgbColor {
296302 blue,
297303 alpha,
298304 } => (
299- red. unwrap_or ( 0. ) ,
300- green. unwrap_or ( 0. ) ,
301- blue. unwrap_or ( 0. ) ,
302- alpha. unwrap_or ( AlphaValue :: new ( 0. ) ) . number ,
305+ red. unwrap_or ( 0. ) . clamp ( 0. , 1. ) ,
306+ green. unwrap_or ( 0. ) . clamp ( 0. , 1. ) ,
307+ blue. unwrap_or ( 0. ) . clamp ( 0. , 1. ) ,
308+ alpha. unwrap_or ( AlphaValue :: new ( 0. ) ) . number . clamp ( 0. , 1. ) ,
303309 ) ,
304310 Self :: Hsl {
305311 hue,
@@ -308,15 +314,15 @@ impl SrgbColor {
308314 alpha,
309315 } => {
310316 let ( r, g, b) = hsl_to_rgb (
311- hue. unwrap_or ( Hue :: new ( 0. ) ) . degrees ,
312- saturation. unwrap_or ( 0. ) ,
313- lightness. unwrap_or ( 0. ) ,
317+ hue. unwrap_or ( Hue :: new ( 0. ) ) . degrees % 360. / 360. ,
318+ saturation. unwrap_or ( 0. ) . clamp ( 0. , 1. ) ,
319+ lightness. unwrap_or ( 0. ) . clamp ( 0. , 1. ) ,
314320 ) ;
315321 (
316- r as f64 ,
317- g as f64 ,
318- b as f64 ,
319- alpha. unwrap_or ( AlphaValue :: new ( 0. ) ) . number ,
322+ f32_to_f64 ( r ) ,
323+ f32_to_f64 ( g ) ,
324+ f32_to_f64 ( b ) ,
325+ alpha. unwrap_or ( AlphaValue :: new ( 0. ) ) . number . clamp ( 0. , 1. ) ,
320326 )
321327 }
322328 Self :: Hwb {
@@ -326,15 +332,15 @@ impl SrgbColor {
326332 alpha,
327333 } => {
328334 let ( r, g, b) = hwb_to_rgb (
329- hue. unwrap_or ( Hue :: new ( 0. ) ) . degrees ,
330- whiteness. unwrap_or ( 0. ) ,
331- blackness. unwrap_or ( 0. ) ,
335+ hue. unwrap_or ( Hue :: new ( 0. ) ) . degrees % 360. / 360. ,
336+ whiteness. unwrap_or ( 0. ) . clamp ( 0. , 1. ) ,
337+ blackness. unwrap_or ( 0. ) . clamp ( 0. , 1. ) ,
332338 ) ;
333339 (
334- r as f64 ,
335- g as f64 ,
336- b as f64 ,
337- alpha. unwrap_or ( AlphaValue :: new ( 0. ) ) . number ,
340+ f32_to_f64 ( r ) ,
341+ f32_to_f64 ( g ) ,
342+ f32_to_f64 ( b ) ,
343+ alpha. unwrap_or ( AlphaValue :: new ( 0. ) ) . number . clamp ( 0. , 1. ) ,
338344 )
339345 }
340346 }
@@ -350,10 +356,10 @@ impl SrgbColor {
350356 let ( red, green, blue, alpha) : ( f64 , f64 , f64 , f32 ) = self . to_floats ( ) ;
351357
352358 RGBA {
353- red : ( red. clamp ( 0. , 1. ) * 255. ) . round ( ) as u8 ,
354- green : ( green. clamp ( 0. , 1. ) * 255. ) . round ( ) as u8 ,
355- blue : ( blue. clamp ( 0. , 1. ) * 255. ) . round ( ) as u8 ,
356- alpha : ( alpha. clamp ( 0. , 1. ) * 255. ) . round ( ) as u8 ,
359+ red : ( red * 255. ) . round ( ) as u8 ,
360+ green : ( green * 255. ) . round ( ) as u8 ,
361+ blue : ( blue * 255. ) . round ( ) as u8 ,
362+ alpha : ( alpha * 255. ) . round ( ) as u8 ,
357363 }
358364 }
359365}
@@ -435,7 +441,7 @@ impl ToCss for CielabColor {
435441 CielabColor :: CieLab ( lab_coords) => {
436442 dest. write_str ( "lab(" ) ?;
437443 match lab_coords. lightness {
438- Some ( lightness) => lightness. to_css ( dest) ?,
444+ Some ( lightness) => lightness. clamp ( 0. , 100. ) . to_css ( dest) ?,
439445 None => dest. write_str ( "none" ) ?,
440446 } ;
441447 dest. write_str ( " " ) ?;
@@ -462,7 +468,7 @@ impl ToCss for CielabColor {
462468 CielabColor :: CieLch ( lch_coords) => {
463469 dest. write_str ( "lch(" ) ?;
464470 match lch_coords. lightness {
465- Some ( lightness) => lightness. to_css ( dest) ?,
471+ Some ( lightness) => lightness. clamp ( 0. , 100. ) . to_css ( dest) ?,
466472 None => dest. write_str ( "none" ) ?,
467473 } ;
468474 dest. write_str ( " " ) ?;
@@ -542,7 +548,7 @@ impl ToCss for OklabColor {
542548 OklabColor :: OkLab ( lab_coords) => {
543549 dest. write_str ( "oklab(" ) ?;
544550 match lab_coords. lightness {
545- Some ( lightness) => lightness. to_css ( dest) ?,
551+ Some ( lightness) => lightness. clamp ( 0. , 1. ) . to_css ( dest) ?,
546552 None => dest. write_str ( "none" ) ?,
547553 } ;
548554 dest. write_str ( " " ) ?;
@@ -569,7 +575,7 @@ impl ToCss for OklabColor {
569575 OklabColor :: OkLch ( lch_coords) => {
570576 dest. write_str ( "oklch(" ) ?;
571577 match lch_coords. lightness {
572- Some ( lightness) => lightness. to_css ( dest) ?,
578+ Some ( lightness) => lightness. clamp ( 0. , 1. ) . to_css ( dest) ?,
573579 None => dest. write_str ( "none" ) ?,
574580 } ;
575581 dest. write_str ( " " ) ?;
@@ -1198,15 +1204,15 @@ where
11981204 ) ) )
11991205 } )
12001206 . or ( arguments. try_parse ( |input| {
1201- let red = Some ( component_parser. parse_percentage ( input) ? as f64 ) ;
1207+ let red = Some ( f32_to_f64 ( component_parser. parse_percentage ( input) ?) ) ;
12021208
12031209 input. expect_comma ( ) ?;
12041210
1205- let green = Some ( component_parser. parse_percentage ( input) ? as f64 ) ;
1211+ let green = Some ( f32_to_f64 ( component_parser. parse_percentage ( input) ?) ) ;
12061212
12071213 input. expect_comma ( ) ?;
12081214
1209- let blue = Some ( component_parser. parse_percentage ( input) ? as f64 ) ;
1215+ let blue = Some ( f32_to_f64 ( component_parser. parse_percentage ( input) ?) ) ;
12101216
12111217 let alpha = parse_alpha_component ( component_parser, input, true ) ?;
12121218
@@ -1276,11 +1282,11 @@ where
12761282
12771283 input. expect_comma ( ) ?;
12781284
1279- let saturation = Some ( input . expect_percentage ( ) ?) ;
1285+ let saturation = Some ( component_parser . parse_percentage ( input ) ?) ;
12801286
12811287 input. expect_comma ( ) ?;
12821288
1283- let lightness = Some ( input . expect_percentage ( ) ?) ;
1289+ let lightness = Some ( component_parser . parse_percentage ( input ) ?) ;
12841290
12851291 let alpha = parse_alpha_component ( component_parser, input, true ) ?;
12861292
@@ -2649,6 +2655,16 @@ mod tests {
26492655 . to_floats( ) ,
26502656 ( 0.75 , 0.25 , 0.25 , 1.0 )
26512657 ) ;
2658+ assert_eq ! (
2659+ SrgbColor :: Hsl {
2660+ hue: Some ( Hue { degrees: 60. } ) ,
2661+ saturation: Some ( 1.0 ) ,
2662+ lightness: Some ( 0.375 ) ,
2663+ alpha: Some ( AlphaValue { number: 1.0 } )
2664+ }
2665+ . to_floats( ) ,
2666+ ( 0.75 , 0.75 , 0.0 , 1.0 )
2667+ ) ;
26522668 assert_eq ! (
26532669 SrgbColor :: Hwb {
26542670 hue: None ,
@@ -5505,6 +5521,7 @@ mod tests {
55055521 // assert_eq!(super::hsl_to_rgb(120. / 360., 0.75, 0.85), (0.7375, 0.9625, 0.7375));
55065522 assert_eq ! ( super :: hsl_to_rgb( 240. / 360. , 1. , 0.5 ) , ( 0. , 0. , 1. ) ) ;
55075523 assert_eq ! ( super :: hsl_to_rgb( 60. / 360. , 1. , 0.5 ) , ( 1. , 1. , 0. ) ) ;
5524+ assert_eq ! ( super :: hsl_to_rgb( 60. / 360. , 1. , 0.375 ) , ( 0.75 , 0.75 , 0. ) ) ;
55085525 assert_eq ! ( super :: hsl_to_rgb( 360. / 360. , 1. , 0.5 ) , ( 1. , 0. , 0. ) ) ;
55095526 assert_eq ! ( super :: hsl_to_rgb( 0. / 360. , 1. , 1. ) , ( 1. , 1. , 1. ) ) ;
55105527 assert_eq ! ( super :: hsl_to_rgb( 0. / 360. , 0. , 1. ) , ( 1. , 1. , 1. ) ) ;
0 commit comments