@@ -182,6 +182,122 @@ impl ToCss for RGBA {
182182 }
183183}
184184
185+ #[ derive( Clone , Copy , PartialEq , Debug ) ]
186+ pub struct Hsl {
187+ /// The hue component.
188+ pub hue : f32 ,
189+ /// The saturation component.
190+ pub saturation : f32 ,
191+ /// The lightness component.
192+ pub lightness : f32 ,
193+ /// The alpha component.
194+ pub alpha : f32 ,
195+ }
196+
197+ impl Hsl {
198+ pub fn new ( hue : f32 , saturation : f32 , lightness : f32 , alpha : f32 ) -> Self {
199+ Self {
200+ hue,
201+ saturation,
202+ lightness,
203+ alpha,
204+ }
205+ }
206+ }
207+
208+ impl ToCss for Hsl {
209+ fn to_css < W > ( & self , dest : & mut W ) -> fmt:: Result
210+ where
211+ W : fmt:: Write ,
212+ {
213+ // HSL serializes to RGB, so we have to convert it.
214+ let ( red, green, blue) = hsl_to_rgb (
215+ self . hue / 360.0 , // Hue is expected in range [0..1].
216+ self . saturation ,
217+ self . lightness ,
218+ ) ;
219+
220+ RGBA :: from_floats ( red, green, blue, self . alpha ) . to_css ( dest)
221+ }
222+ }
223+
224+ #[ cfg( feature = "serde" ) ]
225+ impl Serialize for Hsl {
226+ fn serialize < S > ( & self , serializer : S ) -> Result < S :: Ok , S :: Error >
227+ where
228+ S : Serializer ,
229+ {
230+ ( self . hue , self . saturation , self . lightness , self . alpha ) . serialize ( serializer)
231+ }
232+ }
233+
234+ #[ cfg( feature = "serde" ) ]
235+ impl < ' de > Deserialize < ' de > for Hsl {
236+ fn deserialize < D > ( deserializer : D ) -> Result < Self , D :: Error >
237+ where
238+ D : Deserializer < ' de > ,
239+ {
240+ let ( lightness, a, b, alpha) = Deserialize :: deserialize ( deserializer) ?;
241+ Ok ( Self :: new ( lightness, a, b, alpha) )
242+ }
243+ }
244+
245+ #[ derive( Clone , Copy , PartialEq , Debug ) ]
246+ pub struct Hwb {
247+ /// The hue component.
248+ pub hue : f32 ,
249+ /// The whiteness component.
250+ pub whiteness : f32 ,
251+ /// The blackness component.
252+ pub blackness : f32 ,
253+ /// The alpha component.
254+ pub alpha : f32 ,
255+ }
256+
257+ impl Hwb {
258+ pub fn new ( hue : f32 , whiteness : f32 , blackness : f32 , alpha : f32 ) -> Self {
259+ Self {
260+ hue,
261+ whiteness,
262+ blackness,
263+ alpha,
264+ }
265+ }
266+ }
267+
268+ impl ToCss for Hwb {
269+ fn to_css < W > ( & self , dest : & mut W ) -> fmt:: Result
270+ where
271+ W : fmt:: Write ,
272+ {
273+ // HWB serializes to RGB, so we have to convert it.
274+ let ( red, green, blue) = hwb_to_rgb ( self . hue / 360.0 , self . whiteness , self . blackness ) ;
275+
276+ RGBA :: from_floats ( red, green, blue, self . alpha ) . to_css ( dest)
277+ }
278+ }
279+
280+ #[ cfg( feature = "serde" ) ]
281+ impl Serialize for Hwb {
282+ fn serialize < S > ( & self , serializer : S ) -> Result < S :: Ok , S :: Error >
283+ where
284+ S : Serializer ,
285+ {
286+ ( self . hue , self . whiteness , self . blackness , self . alpha ) . serialize ( serializer)
287+ }
288+ }
289+
290+ #[ cfg( feature = "serde" ) ]
291+ impl < ' de > Deserialize < ' de > for Hwb {
292+ fn deserialize < D > ( deserializer : D ) -> Result < Self , D :: Error >
293+ where
294+ D : Deserializer < ' de > ,
295+ {
296+ let ( lightness, whiteness, blackness, alpha) = Deserialize :: deserialize ( deserializer) ?;
297+ Ok ( Self :: new ( lightness, whiteness, blackness, alpha) )
298+ }
299+ }
300+
185301// NOTE: LAB and OKLAB is not declared inside the [impl_lab_like] macro,
186302// because it causes cbindgen to ignore them.
187303
@@ -482,6 +598,10 @@ pub enum Color {
482598 CurrentColor ,
483599 /// Specify sRGB colors directly by their red/green/blue/alpha chanels.
484600 Rgba ( RGBA ) ,
601+ /// Specifies a color in sRGB using hue, saturation and lightness components.
602+ Hsl ( Hsl ) ,
603+ /// Specifies a color in sRGB using hue, whiteness and blackness components.
604+ Hwb ( Hwb ) ,
485605 /// Specifies a CIELAB color by CIE Lightness and its a- and b-axis hue
486606 /// coordinates (red/green-ness, and yellow/blue-ness) using the CIE LAB
487607 /// rectangular coordinate model.
@@ -508,6 +628,8 @@ impl ToCss for Color {
508628 match * self {
509629 Color :: CurrentColor => dest. write_str ( "currentcolor" ) ,
510630 Color :: Rgba ( rgba) => rgba. to_css ( dest) ,
631+ Color :: Hsl ( hsl) => hsl. to_css ( dest) ,
632+ Color :: Hwb ( hwb) => hwb. to_css ( dest) ,
511633 Color :: Lab ( lab) => lab. to_css ( dest) ,
512634 Color :: Lch ( lch) => lch. to_css ( dest) ,
513635 Color :: Oklab ( lab) => lab. to_css ( dest) ,
@@ -666,6 +788,12 @@ pub trait FromParsedColor {
666788 /// Construct a new color from red, green, blue and alpha components.
667789 fn from_rgba ( red : u8 , green : u8 , blue : u8 , alpha : f32 ) -> Self ;
668790
791+ /// Construct a new color from hue, saturation, lightness and alpha components.
792+ fn from_hsl ( hue : f32 , saturation : f32 , lightness : f32 , alpha : f32 ) -> Self ;
793+
794+ /// Construct a new color from hue, blackness, whiteness and alpha components.
795+ fn from_hwb ( hue : f32 , whiteness : f32 , blackness : f32 , alpha : f32 ) -> Self ;
796+
669797 /// Construct a new color from the `lab` notation.
670798 fn from_lab ( lightness : f32 , a : f32 , b : f32 , alpha : f32 ) -> Self ;
671799
@@ -725,6 +853,16 @@ impl FromParsedColor for Color {
725853 Color :: Rgba ( RGBA :: new ( red, green, blue, alpha) )
726854 }
727855
856+ #[ inline]
857+ fn from_hsl ( hue : f32 , saturation : f32 , lightness : f32 , alpha : f32 ) -> Self {
858+ Color :: Hsl ( Hsl :: new ( hue, saturation, lightness, alpha) )
859+ }
860+
861+ #[ inline]
862+ fn from_hwb ( hue : f32 , whiteness : f32 , blackness : f32 , alpha : f32 ) -> Self {
863+ Color :: Hwb ( Hwb :: new ( hue, whiteness, blackness, alpha) )
864+ }
865+
728866 #[ inline]
729867 fn from_lab ( lightness : f32 , a : f32 , b : f32 , alpha : f32 ) -> Self {
730868 Color :: Lab ( Lab :: new ( lightness, a, b, alpha) )
@@ -1102,14 +1240,7 @@ where
11021240 let saturation = saturation. clamp ( 0.0 , 1.0 ) ;
11031241 let lightness = lightness. clamp ( 0.0 , 1.0 ) ;
11041242
1105- let ( red, green, blue) = hsl_to_rgb ( hue / 360.0 , saturation, lightness) ;
1106-
1107- Ok ( P :: Output :: from_rgba (
1108- clamp_unit_f32 ( red) ,
1109- clamp_unit_f32 ( green) ,
1110- clamp_unit_f32 ( blue) ,
1111- alpha,
1112- ) )
1243+ Ok ( P :: Output :: from_hsl ( hue, saturation, lightness, alpha) )
11131244}
11141245
11151246/// Parses hwb syntax.
@@ -1135,14 +1266,7 @@ where
11351266 let whiteness = whiteness. clamp ( 0.0 , 1.0 ) ;
11361267 let blackness = blackness. clamp ( 0.0 , 1.0 ) ;
11371268
1138- let ( red, green, blue) = hwb_to_rgb ( hue / 360.0 , whiteness, blackness) ;
1139-
1140- Ok ( P :: Output :: from_rgba (
1141- clamp_unit_f32 ( red) ,
1142- clamp_unit_f32 ( green) ,
1143- clamp_unit_f32 ( blue) ,
1144- alpha,
1145- ) )
1269+ Ok ( P :: Output :: from_hwb ( hue, whiteness, blackness, alpha) )
11461270}
11471271
11481272/// https://drafts.csswg.org/css-color-4/#hwb-to-rgb
0 commit comments