From e2f8e046701de89cf859ce20b9b96dfbacd88376 Mon Sep 17 00:00:00 2001 From: Jonathan Johnson Date: Thu, 11 Jan 2024 14:58:27 -0800 Subject: [PATCH] Fixing infintite loop in ColorSchemeBuilder `generate_error` can technically fail to generate a contrasting color if the primary color is desaturated too much. This is beacuse we never increase the saturation. This change makes the color scheme builder stop one iteration shy of a full circle. --- src/styles.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/styles.rs b/src/styles.rs index f979ab0..79e7be4 100644 --- a/src/styles.rs +++ b/src/styles.rs @@ -13,6 +13,7 @@ use std::sync::Arc; use ahash::AHashMap; use figures::units::{Lp, Px, UPx}; use figures::{Fraction, IntoSigned, IntoUnsigned, Rect, ScreenScale, Size, Zero}; +use intentional::Cast; pub use kludgine::cosmic_text::{FamilyOwned, Style, Weight}; pub use kludgine::shapes::CornerRadii; pub use kludgine::Color; @@ -2283,11 +2284,15 @@ impl ColorSchemeBuilder { fn generate_error(&self, secondary: ColorSource, tertiary: ColorSource) -> ColorSource { let mut error = ColorSource::new(30., self.primary.saturation); - while [self.primary, secondary, tertiary] - .iter() - .any(|c| c.contrast_between(error) < 0.10) + let shift_degrees = self.hue_shift.into_positive_degrees().ceil().cast::(); + let mut iters_left = (360 - (shift_degrees - 1)) / shift_degrees; + while iters_left > 0 + && [self.primary, secondary, tertiary] + .iter() + .any(|c| c.contrast_between(error) < 0.20) { error.hue -= self.hue_shift; + iters_left -= 1; } error