@@ -63,101 +63,49 @@ fn normalize_hue(hue: f32) -> f32 {
63
63
#[ repr( C ) ]
64
64
pub struct RGBA {
65
65
/// The red component.
66
- pub red : u8 ,
66
+ pub red : Option < u8 > ,
67
67
/// The green component.
68
- pub green : u8 ,
68
+ pub green : Option < u8 > ,
69
69
/// The blue component.
70
- pub blue : u8 ,
70
+ pub blue : Option < u8 > ,
71
71
/// The alpha component.
72
- pub alpha : f32 ,
72
+ pub alpha : Option < f32 > ,
73
73
}
74
74
75
75
impl RGBA {
76
76
/// Constructs a new RGBA value from float components. It expects the red,
77
77
/// green, blue and alpha channels in that order, and all values will be
78
78
/// clamped to the 0.0 ... 1.0 range.
79
79
#[ inline]
80
- pub fn from_floats ( red : f32 , green : f32 , blue : f32 , alpha : f32 ) -> Self {
80
+ pub fn from_floats (
81
+ red : Option < f32 > ,
82
+ green : Option < f32 > ,
83
+ blue : Option < f32 > ,
84
+ alpha : Option < f32 > ,
85
+ ) -> Self {
81
86
Self :: new (
82
- clamp_unit_f32 ( red ) ,
83
- clamp_unit_f32 ( green ) ,
84
- clamp_unit_f32 ( blue ) ,
85
- alpha. max ( 0.0 ) . min ( 1.0 ) ,
87
+ red . map ( |r| clamp_unit_f32 ( r ) ) ,
88
+ green . map ( |g| clamp_unit_f32 ( g ) ) ,
89
+ blue . map ( |b| clamp_unit_f32 ( b ) ) ,
90
+ alpha. map ( |a| a . clamp ( 0.0 , OPAQUE ) ) ,
86
91
)
87
92
}
88
93
89
- /// Returns a transparent color.
90
- #[ inline]
91
- pub fn transparent ( ) -> Self {
92
- Self :: new ( 0 , 0 , 0 , 0.0 )
93
- }
94
-
95
94
/// Same thing, but with `u8` values instead of floats in the 0 to 1 range.
96
95
#[ inline]
97
- pub const fn new ( red : u8 , green : u8 , blue : u8 , alpha : f32 ) -> Self {
96
+ pub const fn new (
97
+ red : Option < u8 > ,
98
+ green : Option < u8 > ,
99
+ blue : Option < u8 > ,
100
+ alpha : Option < f32 > ,
101
+ ) -> Self {
98
102
Self {
99
103
red,
100
104
green,
101
105
blue,
102
106
alpha,
103
107
}
104
108
}
105
-
106
- /// Returns the red channel in a floating point number form, from 0 to 1.
107
- #[ inline]
108
- pub fn red_f32 ( & self ) -> f32 {
109
- self . red as f32 / 255.0
110
- }
111
-
112
- /// Returns the green channel in a floating point number form, from 0 to 1.
113
- #[ inline]
114
- pub fn green_f32 ( & self ) -> f32 {
115
- self . green as f32 / 255.0
116
- }
117
-
118
- /// Returns the blue channel in a floating point number form, from 0 to 1.
119
- #[ inline]
120
- pub fn blue_f32 ( & self ) -> f32 {
121
- self . blue as f32 / 255.0
122
- }
123
-
124
- /// Returns the alpha channel in a floating point number form, from 0 to 1.
125
- #[ inline]
126
- pub fn alpha_f32 ( & self ) -> f32 {
127
- self . alpha
128
- }
129
-
130
- /// Parse a color hash, without the leading '#' character.
131
- #[ inline]
132
- pub fn parse_hash ( value : & [ u8 ] ) -> Result < Self , ( ) > {
133
- Ok ( match value. len ( ) {
134
- 8 => Self :: new (
135
- from_hex ( value[ 0 ] ) ? * 16 + from_hex ( value[ 1 ] ) ?,
136
- from_hex ( value[ 2 ] ) ? * 16 + from_hex ( value[ 3 ] ) ?,
137
- from_hex ( value[ 4 ] ) ? * 16 + from_hex ( value[ 5 ] ) ?,
138
- ( from_hex ( value[ 6 ] ) ? * 16 + from_hex ( value[ 7 ] ) ?) as f32 / 255.0 ,
139
- ) ,
140
- 6 => Self :: new (
141
- from_hex ( value[ 0 ] ) ? * 16 + from_hex ( value[ 1 ] ) ?,
142
- from_hex ( value[ 2 ] ) ? * 16 + from_hex ( value[ 3 ] ) ?,
143
- from_hex ( value[ 4 ] ) ? * 16 + from_hex ( value[ 5 ] ) ?,
144
- OPAQUE ,
145
- ) ,
146
- 4 => Self :: new (
147
- from_hex ( value[ 0 ] ) ? * 17 ,
148
- from_hex ( value[ 1 ] ) ? * 17 ,
149
- from_hex ( value[ 2 ] ) ? * 17 ,
150
- ( from_hex ( value[ 3 ] ) ? * 17 ) as f32 / 255.0 ,
151
- ) ,
152
- 3 => Self :: new (
153
- from_hex ( value[ 0 ] ) ? * 17 ,
154
- from_hex ( value[ 1 ] ) ? * 17 ,
155
- from_hex ( value[ 2 ] ) ? * 17 ,
156
- OPAQUE ,
157
- ) ,
158
- _ => return Err ( ( ) ) ,
159
- } )
160
- }
161
109
}
162
110
163
111
#[ cfg( feature = "serde" ) ]
@@ -186,17 +134,17 @@ impl ToCss for RGBA {
186
134
where
187
135
W : fmt:: Write ,
188
136
{
189
- let has_alpha = self . alpha != OPAQUE ;
137
+ let has_alpha = self . alpha . unwrap_or ( 0.0 ) != OPAQUE ;
190
138
191
139
dest. write_str ( if has_alpha { "rgba(" } else { "rgb(" } ) ?;
192
- self . red . to_css ( dest) ?;
140
+ self . red . unwrap_or ( 0 ) . to_css ( dest) ?;
193
141
dest. write_str ( ", " ) ?;
194
- self . green . to_css ( dest) ?;
142
+ self . green . unwrap_or ( 0 ) . to_css ( dest) ?;
195
143
dest. write_str ( ", " ) ?;
196
- self . blue . to_css ( dest) ?;
144
+ self . blue . unwrap_or ( 0 ) . to_css ( dest) ?;
197
145
198
146
// Legacy syntax does not allow none components.
199
- serialize_alpha ( dest, Some ( self . alpha ) , true ) ?;
147
+ serialize_alpha ( dest, Some ( self . alpha . unwrap_or ( 0.0 ) ) , true ) ?;
200
148
201
149
dest. write_char ( ')' )
202
150
}
@@ -242,7 +190,7 @@ impl ToCss for Hsl {
242
190
self . lightness . unwrap_or ( 0.0 ) ,
243
191
) ;
244
192
245
- RGBA :: from_floats ( red, green, blue, self . alpha . unwrap_or ( 0.0 ) ) . to_css ( dest)
193
+ RGBA :: from_floats ( Some ( red) , Some ( green) , Some ( blue) , self . alpha ) . to_css ( dest)
246
194
}
247
195
}
248
196
@@ -307,7 +255,7 @@ impl ToCss for Hwb {
307
255
self . blackness . unwrap_or ( 0.0 ) ,
308
256
) ;
309
257
310
- RGBA :: from_floats ( red, green, blue, self . alpha . unwrap_or ( 0.0 ) ) . to_css ( dest)
258
+ RGBA :: from_floats ( Some ( red) , Some ( green) , Some ( blue) , self . alpha ) . to_css ( dest)
311
259
}
312
260
}
313
261
@@ -892,6 +840,42 @@ pub trait FromParsedColor {
892
840
) -> Self ;
893
841
}
894
842
843
+ /// Parse a color hash, without the leading '#' character.
844
+ #[ inline]
845
+
846
+ pub fn parse_hash_color < ' i , ' t , P > ( value : & [ u8 ] ) -> Result < P :: Output , ( ) >
847
+ where
848
+ P : ColorParser < ' i > ,
849
+ {
850
+ Ok ( match value. len ( ) {
851
+ 8 => P :: Output :: from_rgba (
852
+ from_hex ( value[ 0 ] ) ? * 16 + from_hex ( value[ 1 ] ) ?,
853
+ from_hex ( value[ 2 ] ) ? * 16 + from_hex ( value[ 3 ] ) ?,
854
+ from_hex ( value[ 4 ] ) ? * 16 + from_hex ( value[ 5 ] ) ?,
855
+ ( from_hex ( value[ 6 ] ) ? * 16 + from_hex ( value[ 7 ] ) ?) as f32 / 255.0 ,
856
+ ) ,
857
+ 6 => P :: Output :: from_rgba (
858
+ from_hex ( value[ 0 ] ) ? * 16 + from_hex ( value[ 1 ] ) ?,
859
+ from_hex ( value[ 2 ] ) ? * 16 + from_hex ( value[ 3 ] ) ?,
860
+ from_hex ( value[ 4 ] ) ? * 16 + from_hex ( value[ 5 ] ) ?,
861
+ OPAQUE ,
862
+ ) ,
863
+ 4 => P :: Output :: from_rgba (
864
+ from_hex ( value[ 0 ] ) ? * 17 ,
865
+ from_hex ( value[ 1 ] ) ? * 17 ,
866
+ from_hex ( value[ 2 ] ) ? * 17 ,
867
+ ( from_hex ( value[ 3 ] ) ? * 17 ) as f32 / 255.0 ,
868
+ ) ,
869
+ 3 => P :: Output :: from_rgba (
870
+ from_hex ( value[ 0 ] ) ? * 17 ,
871
+ from_hex ( value[ 1 ] ) ? * 17 ,
872
+ from_hex ( value[ 2 ] ) ? * 17 ,
873
+ OPAQUE ,
874
+ ) ,
875
+ _ => return Err ( ( ) ) ,
876
+ } )
877
+ }
878
+
895
879
/// Parse a CSS color with the specified [`ColorComponentParser`] and return a
896
880
/// new color value on success.
897
881
pub fn parse_color_with < ' i , ' t , P > (
@@ -904,8 +888,9 @@ where
904
888
let location = input. current_source_location ( ) ;
905
889
let token = input. next ( ) ?;
906
890
match * token {
907
- Token :: Hash ( ref value) | Token :: IDHash ( ref value) => RGBA :: parse_hash ( value. as_bytes ( ) )
908
- . map ( |rgba| P :: Output :: from_rgba ( rgba. red , rgba. green , rgba. blue , rgba. alpha ) ) ,
891
+ Token :: Hash ( ref value) | Token :: IDHash ( ref value) => {
892
+ parse_hash_color :: < P > ( value. as_bytes ( ) )
893
+ }
909
894
Token :: Ident ( ref value) => parse_color_keyword ( & * value) ,
910
895
Token :: Function ( ref name) => {
911
896
let name = name. clone ( ) ;
@@ -926,7 +911,7 @@ impl FromParsedColor for Color {
926
911
927
912
#[ inline]
928
913
fn from_rgba ( red : u8 , green : u8 , blue : u8 , alpha : f32 ) -> Self {
929
- Color :: Rgba ( RGBA :: new ( red, green, blue, alpha) )
914
+ Color :: Rgba ( RGBA :: new ( Some ( red) , Some ( green) , Some ( blue) , Some ( alpha) ) )
930
915
}
931
916
932
917
fn from_hsl (
0 commit comments