Skip to content

Commit 3440569

Browse files
committed
WIP: Get tests to pass (except lab/lch)
1 parent e1c0cee commit 3440569

File tree

2 files changed

+103
-52
lines changed

2 files changed

+103
-52
lines changed

src/color.rs

Lines changed: 49 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -97,12 +97,18 @@ impl<'de> Deserialize<'de> for RGBA {
9797
D: Deserializer<'de>,
9898
{
9999
let (r, g, b, a) = Deserialize::deserialize(deserializer)?;
100-
Ok(RGBA::new(r, g, b, a))
100+
Ok(Self::new(r, g, b, a))
101101
}
102102
}
103103

104104
// NOTE: `RGBA` should not implement `ToCss` because it is an internal primitive that does not directly represent a CSS value.
105105

106+
#[inline]
107+
fn f32_to_f64(f: f32) -> f64 {
108+
const PRECISION: f64 = 1e6;
109+
(f64::from(f) * PRECISION).round() / PRECISION
110+
}
111+
106112
/// <hue>
107113
/// <https://w3c.github.io/csswg-drafts/css-color-4/#hue-syntax>
108114
#[derive(Clone, Copy, PartialEq, Debug)]
@@ -296,10 +302,10 @@ impl SrgbColor {
296302
blue,
297303
alpha,
298304
} => (
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.),
303309
),
304310
Self::Hsl {
305311
hue,
@@ -308,15 +314,15 @@ impl SrgbColor {
308314
alpha,
309315
} => {
310316
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.),
314320
);
315321
(
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.),
320326
)
321327
}
322328
Self::Hwb {
@@ -326,15 +332,15 @@ impl SrgbColor {
326332
alpha,
327333
} => {
328334
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.),
332338
);
333339
(
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.),
338344
)
339345
}
340346
}
@@ -350,10 +356,10 @@ impl SrgbColor {
350356
let (red, green, blue, alpha): (f64, f64, f64, f32) = self.to_floats();
351357

352358
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,
357363
}
358364
}
359365
}
@@ -435,7 +441,7 @@ impl ToCss for CielabColor {
435441
CielabColor::CieLab(lab_coords) => {
436442
dest.write_str("lab(")?;
437443
match lab_coords.lightness {
438-
Some(lightness) => lightness.to_css(dest)?,
444+
Some(lightness) => lightness.clamp(0., 100.).to_css(dest)?,
439445
None => dest.write_str("none")?,
440446
};
441447
dest.write_str(" ")?;
@@ -462,7 +468,7 @@ impl ToCss for CielabColor {
462468
CielabColor::CieLch(lch_coords) => {
463469
dest.write_str("lch(")?;
464470
match lch_coords.lightness {
465-
Some(lightness) => lightness.to_css(dest)?,
471+
Some(lightness) => lightness.clamp(0., 100.).to_css(dest)?,
466472
None => dest.write_str("none")?,
467473
};
468474
dest.write_str(" ")?;
@@ -542,7 +548,7 @@ impl ToCss for OklabColor {
542548
OklabColor::OkLab(lab_coords) => {
543549
dest.write_str("oklab(")?;
544550
match lab_coords.lightness {
545-
Some(lightness) => lightness.to_css(dest)?,
551+
Some(lightness) => lightness.clamp(0., 1.).to_css(dest)?,
546552
None => dest.write_str("none")?,
547553
};
548554
dest.write_str(" ")?;
@@ -569,7 +575,7 @@ impl ToCss for OklabColor {
569575
OklabColor::OkLch(lch_coords) => {
570576
dest.write_str("oklch(")?;
571577
match lch_coords.lightness {
572-
Some(lightness) => lightness.to_css(dest)?,
578+
Some(lightness) => lightness.clamp(0., 1.).to_css(dest)?,
573579
None => dest.write_str("none")?,
574580
};
575581
dest.write_str(" ")?;
@@ -1198,15 +1204,15 @@ where
11981204
)))
11991205
})
12001206
.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)?));
12021208

12031209
input.expect_comma()?;
12041210

1205-
let green = Some(component_parser.parse_percentage(input)? as f64);
1211+
let green = Some(f32_to_f64(component_parser.parse_percentage(input)?));
12061212

12071213
input.expect_comma()?;
12081214

1209-
let blue = Some(component_parser.parse_percentage(input)? as f64);
1215+
let blue = Some(f32_to_f64(component_parser.parse_percentage(input)?));
12101216

12111217
let alpha = parse_alpha_component(component_parser, input, true)?;
12121218

@@ -1276,11 +1282,11 @@ where
12761282

12771283
input.expect_comma()?;
12781284

1279-
let saturation = Some(input.expect_percentage()?);
1285+
let saturation = Some(component_parser.parse_percentage(input)?);
12801286

12811287
input.expect_comma()?;
12821288

1283-
let lightness = Some(input.expect_percentage()?);
1289+
let lightness = Some(component_parser.parse_percentage(input)?);
12841290

12851291
let alpha = parse_alpha_component(component_parser, input, true)?;
12861292

@@ -2649,6 +2655,16 @@ mod tests {
26492655
.to_floats(),
26502656
(0.75, 0.25, 0.25, 1.0)
26512657
);
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+
);
26522668
assert_eq!(
26532669
SrgbColor::Hwb {
26542670
hue: None,
@@ -5505,6 +5521,7 @@ mod tests {
55055521
// assert_eq!(super::hsl_to_rgb(120. / 360., 0.75, 0.85), (0.7375, 0.9625, 0.7375));
55065522
assert_eq!(super::hsl_to_rgb(240. / 360., 1., 0.5), (0., 0., 1.));
55075523
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.));
55085525
assert_eq!(super::hsl_to_rgb(360. / 360., 1., 0.5), (1., 0., 0.));
55095526
assert_eq!(super::hsl_to_rgb(0. / 360., 1., 1.), (1., 1., 1.));
55105527
assert_eq!(super::hsl_to_rgb(0. / 360., 0., 1.), (1., 1., 1.));

src/tests.rs

Lines changed: 54 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,12 @@ use serde_json::{self, json, Map, Value};
1313
use self::test::Bencher;
1414

1515
use super::{
16-
color::{rgb, rgba},
1716
parse_important, parse_nth, parse_one_declaration, parse_one_rule, stylesheet_encoding,
18-
AbsoluteColor, AtRuleParser, BasicParseError, BasicParseErrorKind, Color, CowRcStr,
19-
DeclarationListParser, DeclarationParser, Delimiter, EncodingSupport, ParseError,
20-
ParseErrorKind, Parser, ParserInput, ParserState, QualifiedRuleParser, RuleListParser,
21-
SourceLocation, ToCss, Token, TokenSerializationType, UnicodeRange, RGBA,
17+
AtRuleParser, BasicParseError, BasicParseErrorKind, CielabColor, Color, CowRcStr, CurrentColor,
18+
DeclarationListParser, DeclarationParser, Delimiter, DeprecatedColor, EncodingSupport,
19+
NamedColor, OklabColor, ParseError, ParseErrorKind, Parser, ParserInput, ParserState,
20+
QualifiedRuleParser, RuleListParser, SourceLocation, SrgbColor, ToCss, Token,
21+
TokenSerializationType, UnicodeRange,
2222
};
2323

2424
macro_rules! JArray {
@@ -398,7 +398,14 @@ fn color4_lab_lch_oklab_oklch() {
398398
run_color_tests(
399399
include_str!("css-parsing-tests/color4_lab_lch_oklab_oklch.json"),
400400
|c| match c {
401-
Ok(color) => Value::Array(vec![color.to_json(), color.to_css_string().to_json()]),
401+
Ok(color) => Value::Array(vec![
402+
color.to_json(),
403+
match color {
404+
Color::CielabColor(cielab_color) => cielab_color.to_css_string().to_json(),
405+
Color::OklabColor(oklab_color) => oklab_color.to_css_string().to_json(),
406+
_ => Value::Null,
407+
},
408+
]),
402409
Err(_) => Value::Null,
403410
},
404411
)
@@ -533,25 +540,25 @@ fn serialize_bad_tokens() {
533540

534541
#[test]
535542
fn serialize_current_color() {
536-
let c = Color::CurrentColor;
543+
let c = CurrentColor;
537544
assert!(c.to_css_string() == "currentcolor");
538545
}
539546

540547
#[test]
541548
fn serialize_rgb_full_alpha() {
542-
let c = rgb(255, 230, 204);
549+
let c = SrgbColor::from_ints(255, 230, 204, 255);
543550
assert_eq!(c.to_css_string(), "rgb(255, 230, 204)");
544551
}
545552

546553
#[test]
547554
fn serialize_rgba() {
548-
let c = rgba(26, 51, 77, 0.125);
549-
assert_eq!(c.to_css_string(), "rgba(26, 51, 77, 0.125)");
555+
let c = SrgbColor::from_ints(26, 51, 77, 32);
556+
assert_eq!(c.to_css_string(), "rgba(26, 51, 77, 0.12549)");
550557
}
551558

552559
#[test]
553560
fn serialize_rgba_two_digit_float_if_roundtrips() {
554-
let c = Color::Absolute(AbsoluteColor::Rgba(RGBA::from_floats(0., 0., 0., 0.5)));
561+
let c = SrgbColor::from_floats(0., 0., 0., 0.5);
555562
assert_eq!(c.to_css_string(), "rgba(0, 0, 0, 0.5)");
556563
}
557564

@@ -843,16 +850,43 @@ where
843850
impl ToJson for Color {
844851
fn to_json(&self) -> Value {
845852
match *self {
846-
Color::CurrentColor => "currentcolor".to_json(),
847-
Color::Absolute(absolute) => match absolute {
848-
AbsoluteColor::Rgba(ref rgba) => {
849-
json!([rgba.red, rgba.green, rgba.blue, rgba.alpha])
853+
Color::SrgbColor(ref srgb_color)
854+
| Color::NamedColor(NamedColor {
855+
value: ref srgb_color,
856+
..
857+
}) => {
858+
let rgba = srgb_color.to_rgba();
859+
json!([rgba.red, rgba.green, rgba.blue, srgb_color.to_floats().3])
860+
}
861+
Color::SystemColor(ref system_color)
862+
| Color::DeprecatedColor(DeprecatedColor {
863+
same_as: ref system_color,
864+
..
865+
}) => system_color.name.to_json(),
866+
Color::CurrentColor(CurrentColor) => "currentcolor".to_json(),
867+
Color::CielabColor(CielabColor::CieLab(ref lab_coords))
868+
| Color::OklabColor(OklabColor::OkLab(ref lab_coords)) => json!([
869+
lab_coords.lightness,
870+
lab_coords.a,
871+
lab_coords.b,
872+
match lab_coords.alpha {
873+
Some(alpha) => alpha.number,
874+
None => 0.,
850875
}
851-
AbsoluteColor::Lab(ref c) => json!([c.lightness, c.a, c.b, c.alpha]),
852-
AbsoluteColor::Lch(ref c) => json!([c.lightness, c.chroma, c.hue, c.alpha]),
853-
AbsoluteColor::Oklab(ref c) => json!([c.lightness, c.a, c.b, c.alpha]),
854-
AbsoluteColor::Oklch(ref c) => json!([c.lightness, c.chroma, c.hue, c.alpha]),
855-
},
876+
]),
877+
Color::CielabColor(CielabColor::CieLch(ref lch_coords))
878+
| Color::OklabColor(OklabColor::OkLch(ref lch_coords)) => json!([
879+
lch_coords.lightness,
880+
lch_coords.chroma,
881+
match lch_coords.hue {
882+
Some(hue) => hue.degrees,
883+
None => 0.,
884+
},
885+
match lch_coords.alpha {
886+
Some(alpha) => alpha.number,
887+
None => 0.,
888+
}
889+
]),
856890
}
857891
}
858892
}

0 commit comments

Comments
 (0)