From ca011ce28882a29ca8d989ff2c0f8a9f1daf2135 Mon Sep 17 00:00:00 2001 From: FlareFlo Date: Sat, 16 Nov 2024 15:29:09 +0100 Subject: [PATCH] Refactor NaN handling and deduplicate sanitization step --- src/color.rs | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/color.rs b/src/color.rs index f5e5505970..2826a9fe07 100644 --- a/src/color.rs +++ b/src/color.rs @@ -385,25 +385,29 @@ impl FromPrimitive for T { // Note that in to-integer-conversion we are performing rounding but NumCast::from is implemented // as truncate towards zero. We emulate rounding by adding a bias. -const NAN_CLAMP_TO: f32 = 1.0; +// All other special values are clamped inbetween 0.0 and 1.0 (infinities and subnormals) +// NaN however always maps to NaN therefore we have to force it towards some value. +// 1.0 (white) was picked as firefox and chrome choose to map NaN to that. +#[inline] +fn sanitize_nan(i: f32) -> f32 { + if i.is_nan() { + 1.0 + } else { + i + } +} impl FromPrimitive for u8 { fn from_primitive(float: f32) -> Self { - let mut inner = (float.clamp(0.0, 1.0) * u8::MAX as f32).round(); - if inner.is_nan() { - inner = NAN_CLAMP_TO; - } - NumCast::from(inner).unwrap() + let inner = (float.clamp(0.0, 1.0) * u8::MAX as f32).round(); + NumCast::from(sanitize_nan(inner)).unwrap() } } impl FromPrimitive for u16 { fn from_primitive(float: f32) -> Self { let mut inner = (float.clamp(0.0, 1.0) * u16::MAX as f32).round(); - if inner.is_nan() { - inner = NAN_CLAMP_TO; - } - NumCast::from(inner).unwrap() + NumCast::from(sanitize_nan(inner)).unwrap() } }