@@ -97,12 +97,18 @@ impl<'de> Deserialize<'de> for RGBA {
97
97
D : Deserializer < ' de > ,
98
98
{
99
99
let ( r, g, b, a) = Deserialize :: deserialize ( deserializer) ?;
100
- Ok ( RGBA :: new ( r, g, b, a) )
100
+ Ok ( Self :: new ( r, g, b, a) )
101
101
}
102
102
}
103
103
104
104
// NOTE: `RGBA` should not implement `ToCss` because it is an internal primitive that does not directly represent a CSS value.
105
105
106
+ #[ inline]
107
+ fn f32_to_f64 ( f : f32 ) -> f64 {
108
+ const PRECISION : f64 = 1e6 ;
109
+ ( f64:: from ( f) * PRECISION ) . round ( ) / PRECISION
110
+ }
111
+
106
112
/// <hue>
107
113
/// <https://w3c.github.io/csswg-drafts/css-color-4/#hue-syntax>
108
114
#[ derive( Clone , Copy , PartialEq , Debug ) ]
@@ -296,10 +302,10 @@ impl SrgbColor {
296
302
blue,
297
303
alpha,
298
304
} => (
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. ) ,
303
309
) ,
304
310
Self :: Hsl {
305
311
hue,
@@ -308,15 +314,15 @@ impl SrgbColor {
308
314
alpha,
309
315
} => {
310
316
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. ) ,
314
320
) ;
315
321
(
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. ) ,
320
326
)
321
327
}
322
328
Self :: Hwb {
@@ -326,15 +332,15 @@ impl SrgbColor {
326
332
alpha,
327
333
} => {
328
334
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. ) ,
332
338
) ;
333
339
(
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. ) ,
338
344
)
339
345
}
340
346
}
@@ -350,10 +356,10 @@ impl SrgbColor {
350
356
let ( red, green, blue, alpha) : ( f64 , f64 , f64 , f32 ) = self . to_floats ( ) ;
351
357
352
358
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 ,
357
363
}
358
364
}
359
365
}
@@ -435,7 +441,7 @@ impl ToCss for CielabColor {
435
441
CielabColor :: CieLab ( lab_coords) => {
436
442
dest. write_str ( "lab(" ) ?;
437
443
match lab_coords. lightness {
438
- Some ( lightness) => lightness. to_css ( dest) ?,
444
+ Some ( lightness) => lightness. clamp ( 0. , 100. ) . to_css ( dest) ?,
439
445
None => dest. write_str ( "none" ) ?,
440
446
} ;
441
447
dest. write_str ( " " ) ?;
@@ -462,7 +468,7 @@ impl ToCss for CielabColor {
462
468
CielabColor :: CieLch ( lch_coords) => {
463
469
dest. write_str ( "lch(" ) ?;
464
470
match lch_coords. lightness {
465
- Some ( lightness) => lightness. to_css ( dest) ?,
471
+ Some ( lightness) => lightness. clamp ( 0. , 100. ) . to_css ( dest) ?,
466
472
None => dest. write_str ( "none" ) ?,
467
473
} ;
468
474
dest. write_str ( " " ) ?;
@@ -542,7 +548,7 @@ impl ToCss for OklabColor {
542
548
OklabColor :: OkLab ( lab_coords) => {
543
549
dest. write_str ( "oklab(" ) ?;
544
550
match lab_coords. lightness {
545
- Some ( lightness) => lightness. to_css ( dest) ?,
551
+ Some ( lightness) => lightness. clamp ( 0. , 1. ) . to_css ( dest) ?,
546
552
None => dest. write_str ( "none" ) ?,
547
553
} ;
548
554
dest. write_str ( " " ) ?;
@@ -569,7 +575,7 @@ impl ToCss for OklabColor {
569
575
OklabColor :: OkLch ( lch_coords) => {
570
576
dest. write_str ( "oklch(" ) ?;
571
577
match lch_coords. lightness {
572
- Some ( lightness) => lightness. to_css ( dest) ?,
578
+ Some ( lightness) => lightness. clamp ( 0. , 1. ) . to_css ( dest) ?,
573
579
None => dest. write_str ( "none" ) ?,
574
580
} ;
575
581
dest. write_str ( " " ) ?;
@@ -1198,15 +1204,15 @@ where
1198
1204
) ) )
1199
1205
} )
1200
1206
. 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) ?) ) ;
1202
1208
1203
1209
input. expect_comma ( ) ?;
1204
1210
1205
- let green = Some ( component_parser. parse_percentage ( input) ? as f64 ) ;
1211
+ let green = Some ( f32_to_f64 ( component_parser. parse_percentage ( input) ?) ) ;
1206
1212
1207
1213
input. expect_comma ( ) ?;
1208
1214
1209
- let blue = Some ( component_parser. parse_percentage ( input) ? as f64 ) ;
1215
+ let blue = Some ( f32_to_f64 ( component_parser. parse_percentage ( input) ?) ) ;
1210
1216
1211
1217
let alpha = parse_alpha_component ( component_parser, input, true ) ?;
1212
1218
@@ -1276,11 +1282,11 @@ where
1276
1282
1277
1283
input. expect_comma ( ) ?;
1278
1284
1279
- let saturation = Some ( input . expect_percentage ( ) ?) ;
1285
+ let saturation = Some ( component_parser . parse_percentage ( input ) ?) ;
1280
1286
1281
1287
input. expect_comma ( ) ?;
1282
1288
1283
- let lightness = Some ( input . expect_percentage ( ) ?) ;
1289
+ let lightness = Some ( component_parser . parse_percentage ( input ) ?) ;
1284
1290
1285
1291
let alpha = parse_alpha_component ( component_parser, input, true ) ?;
1286
1292
@@ -2649,6 +2655,16 @@ mod tests {
2649
2655
. to_floats( ) ,
2650
2656
( 0.75 , 0.25 , 0.25 , 1.0 )
2651
2657
) ;
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
+ ) ;
2652
2668
assert_eq ! (
2653
2669
SrgbColor :: Hwb {
2654
2670
hue: None ,
@@ -5505,6 +5521,7 @@ mod tests {
5505
5521
// assert_eq!(super::hsl_to_rgb(120. / 360., 0.75, 0.85), (0.7375, 0.9625, 0.7375));
5506
5522
assert_eq ! ( super :: hsl_to_rgb( 240. / 360. , 1. , 0.5 ) , ( 0. , 0. , 1. ) ) ;
5507
5523
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. ) ) ;
5508
5525
assert_eq ! ( super :: hsl_to_rgb( 360. / 360. , 1. , 0.5 ) , ( 1. , 0. , 0. ) ) ;
5509
5526
assert_eq ! ( super :: hsl_to_rgb( 0. / 360. , 1. , 1. ) , ( 1. , 1. , 1. ) ) ;
5510
5527
assert_eq ! ( super :: hsl_to_rgb( 0. / 360. , 0. , 1. ) , ( 1. , 1. , 1. ) ) ;
0 commit comments