Skip to content

Commit 9c38d86

Browse files
committed
Share more code between hsl and hwb parsing.
1 parent 62d63fe commit 9c38d86

File tree

1 file changed

+13
-45
lines changed

1 file changed

+13
-45
lines changed

src/color.rs

+13-45
Original file line numberDiff line numberDiff line change
@@ -564,8 +564,8 @@ where
564564
{
565565
let (red, green, blue, uses_commas) = match_ignore_ascii_case! { name,
566566
"rgb" | "rgba" => parse_rgb_components_rgb(component_parser, arguments)?,
567-
"hsl" | "hsla" => parse_rgb_components_hsl(component_parser, arguments)?,
568-
"hwb" => parse_rgb_components_hwb(component_parser, arguments)?,
567+
"hsl" | "hsla" => parse_hsl_hwb(component_parser, arguments, hsl_to_rgb)?,
568+
"hwb" => parse_hsl_hwb(component_parser, arguments, hwb_to_rgb)?,
569569
_ => return Err(arguments.new_unexpected_token_error(Token::Ident(name.to_owned().into()))),
570570
};
571571

@@ -624,10 +624,15 @@ where
624624
Ok((red, green, blue, uses_commas))
625625
}
626626

627+
/// Parses hsl and hbw syntax, which happens to be identical.
628+
///
629+
/// https://drafts.csswg.org/css-color/#the-hsl-notation
630+
/// https://drafts.csswg.org/css-color/#the-hbw-notation
627631
#[inline]
628-
fn parse_rgb_components_hsl<'i, 't, ComponentParser>(
632+
fn parse_hsl_hwb<'i, 't, ComponentParser>(
629633
component_parser: &ComponentParser,
630634
arguments: &mut Parser<'i, 't>,
635+
to_rgb: impl FnOnce(f32, f32, f32) -> (f32, f32, f32),
631636
) -> Result<(u8, u8, u8, bool), ParseError<'i, ComponentParser::Error>>
632637
where
633638
ComponentParser: ColorComponentParser<'i>,
@@ -641,54 +646,17 @@ where
641646
let hue = hue_normalized_degrees / 360.;
642647

643648
// Saturation and lightness are clamped to 0% ... 100%
644-
// https://drafts.csswg.org/css-color/#the-hsl-notation
645649
let uses_commas = arguments.try_parse(|i| i.expect_comma()).is_ok();
646650

647-
let saturation = component_parser.parse_percentage(arguments)?;
648-
let saturation = saturation.max(0.).min(1.);
651+
let first_percentage = component_parser.parse_percentage(arguments)?.max(0.).min(1.);
649652

650653
if uses_commas {
651654
arguments.expect_comma()?;
652655
}
653656

654-
let lightness = component_parser.parse_percentage(arguments)?;
655-
let lightness = lightness.max(0.).min(1.);
656-
657-
let (red, green, blue) = hsl_to_rgb(hue, saturation, lightness);
658-
let red = clamp_unit_f32(red);
659-
let green = clamp_unit_f32(green);
660-
let blue = clamp_unit_f32(blue);
661-
Ok((red, green, blue, uses_commas))
662-
}
663-
664-
#[inline]
665-
fn parse_rgb_components_hwb<'i, 't, ComponentParser>(
666-
component_parser: &ComponentParser,
667-
arguments: &mut Parser<'i, 't>,
668-
) -> Result<(u8, u8, u8, bool), ParseError<'i, ComponentParser::Error>>
669-
where
670-
ComponentParser: ColorComponentParser<'i>,
671-
{
672-
let hue_degrees = component_parser.parse_angle_or_number(arguments)?.degrees();
673-
674-
// Subtract an integer before rounding, to avoid some rounding errors:
675-
let hue_normalized_degrees = hue_degrees - 360. * (hue_degrees / 360.).floor();
676-
let hue = hue_normalized_degrees / 360.;
677-
678-
let uses_commas = arguments.try_parse(|i| i.expect_comma()).is_ok();
679-
680-
let whiteness = component_parser.parse_percentage(arguments)?;
681-
let whiteness = whiteness.max(0.).min(1.);
682-
683-
if uses_commas {
684-
arguments.expect_comma()?;
685-
}
686-
687-
let blackness = component_parser.parse_percentage(arguments)?;
688-
let blackness = blackness.max(0.).min(1.);
689-
690-
let (red, green, blue) = hwb_to_rgb(hue, whiteness, blackness);
657+
let second_percentage = component_parser.parse_percentage(arguments)?.max(0.).min(1.);
691658

659+
let (red, green, blue) = to_rgb(hue, first_percentage, second_percentage);
692660
let red = clamp_unit_f32(red);
693661
let green = clamp_unit_f32(green);
694662
let blue = clamp_unit_f32(blue);
@@ -711,10 +679,10 @@ fn hwb_to_rgb(h: f32, w: f32, b: f32) -> (f32, f32, f32) {
711679
(red, green, blue)
712680
}
713681

682+
/// https://drafts.csswg.org/css-color/#hsl-color
683+
/// except with h pre-multiplied by 3, to avoid some rounding errors.
714684
#[inline]
715685
fn hsl_to_rgb(hue: f32, saturation: f32, lightness: f32) -> (f32, f32, f32) {
716-
// https://drafts.csswg.org/css-color/#hsl-color
717-
// except with h pre-multiplied by 3, to avoid some rounding errors.
718686
fn hue_to_rgb(m1: f32, m2: f32, mut h3: f32) -> f32 {
719687
if h3 < 0. {
720688
h3 += 3.

0 commit comments

Comments
 (0)