diff --git a/materialyoucolor/temperature/temperature_cache.py b/materialyoucolor/temperature/temperature_cache.py index 52c5de6..5c442a4 100644 --- a/materialyoucolor/temperature/temperature_cache.py +++ b/materialyoucolor/temperature/temperature_cache.py @@ -117,6 +117,13 @@ def complement(self) -> Hct: warmest_hue = self.warmest.hue warmest_temp = self.temps_by_hct.get(self.warmest, 0.0) range_temp = warmest_temp - coldest_temp + + # At a tone extreme every hue resolves to the same color, leaving no range to + # divide by; return the input, as relative_temperature does in that case. + if range_temp == 0.0: + self.complement_cache = self.hcts_by_hue[round(self.input.hue)] + return self.complement_cache + start_hue_is_coldest_to_warmest = TemperatureCache.is_between( self.input.hue, coldest_hue, warmest_hue ) diff --git a/tests/test_all.py b/tests/test_all.py index 1d1d715..59637e5 100644 --- a/tests/test_all.py +++ b/tests/test_all.py @@ -19,6 +19,7 @@ from materialyoucolor.scheme.scheme import Scheme from materialyoucolor.scheme.scheme_android import SchemeAndroid from materialyoucolor.score.score import Score +from materialyoucolor.temperature.temperature_cache import TemperatureCache from materialyoucolor.utils.color_utils import hex_from_rgba, rgba_from_argb @@ -119,6 +120,21 @@ def get_current_rss_mb(): selected = Score.score(colors) + +# Regression: tone extremes leave TemperatureCache with a zero temperature range, +# which used to make complement raise ZeroDivisionError (issue #28). +def check_tone_extremes(): + for argb in [0xFFFFFFFF, 0xFF000000, 0xFF010101]: + source = Hct.from_int(argb) + assert TemperatureCache(source).complement.to_int() == source.to_int() + for spec_version in ["2021", "2025"]: + for is_dark in [False, True]: + # SchemeFidelity reaches complement via get_tertiary_palette. + SchemeFidelity(source, is_dark, 0.0, spec_version=spec_version) + + +check_tone_extremes() + if os.name == "nt": exit(0)