Skip to content

Commit 43162c1

Browse files
committed
Use Gecko's behavior for calculating percent colors
1 parent eeb215f commit 43162c1

File tree

5 files changed

+6822
-8142
lines changed

5 files changed

+6822
-8142
lines changed

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22

33
name = "cssparser"
4-
version = "0.13.1"
4+
version = "0.13.3"
55
authors = [ "Simon Sapin <simon.sapin@exyr.org>" ]
66

77
description = "Rust implementation of CSS Syntax Level 3"

src/color.rs

+16-9
Original file line numberDiff line numberDiff line change
@@ -386,18 +386,25 @@ fn parse_color_hash(value: &str) -> Result<Color, ()> {
386386
}
387387

388388
fn clamp_unit_f32(val: f32) -> u8 {
389-
// Scale by 256, not 255, so that each of the 256 u8 values has an equal range
390-
// of f32 values mapping to it. Floor before clamping.
389+
// Whilst scaling by 256 and flooring would provide
390+
// an equal distribution of integers to percentage inputs,
391+
// this is not what Gecko does so we instead multiply by 255
392+
// and round (adding 0.5 and flooring is equivalent to rounding)
391393
//
392-
// Clamping to 256 and flooring after would let 1.0 map to 256, and
394+
// Chrome does something similar for the alpha value, but not
395+
// the rgb values.
396+
//
397+
// See https://bugzilla.mozilla.org/show_bug.cgi?id=1340484
398+
//
399+
// Clamping to 256 and rounding after would let 1.0 map to 256, and
393400
// `256.0_f32 as u8` is undefined behavior:
394401
//
395402
// https://github.com/rust-lang/rust/issues/10184
396-
clamp_256_f32(val * 256.)
403+
clamp_floor_256_f32(val * 255.)
397404
}
398405

399-
fn clamp_256_f32(val: f32) -> u8 {
400-
val.floor().max(0.).min(255.) as u8
406+
fn clamp_floor_256_f32(val: f32) -> u8 {
407+
val.round().max(0.).min(255.) as u8
401408
}
402409

403410
#[inline]
@@ -449,8 +456,8 @@ fn parse_rgb_components_rgb(arguments: &mut Parser) -> Result<(u8, u8, u8, bool)
449456
// https://drafts.csswg.org/css-color/#rgb-functions
450457
match try!(arguments.next()) {
451458
Token::Number(NumericValue { value: v, .. }) => {
452-
red = clamp_256_f32(v);
453-
green = clamp_256_f32(match try!(arguments.next()) {
459+
red = clamp_floor_256_f32(v);
460+
green = clamp_floor_256_f32(match try!(arguments.next()) {
454461
Token::Number(NumericValue { value: v, .. }) => v,
455462
Token::Comma => {
456463
uses_commas = true;
@@ -461,7 +468,7 @@ fn parse_rgb_components_rgb(arguments: &mut Parser) -> Result<(u8, u8, u8, bool)
461468
if uses_commas {
462469
try!(arguments.expect_comma());
463470
}
464-
blue = clamp_256_f32(try!(arguments.expect_number()));
471+
blue = clamp_floor_256_f32(try!(arguments.expect_number()));
465472
}
466473
Token::Percentage(ref v) => {
467474
red = clamp_unit_f32(v.unit_value);

src/css-parsing-tests/color3.json

+67-67
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,10 @@
5151
"rgb(12.5%, 25%, 50%)", [32, 64, 128, 255],
5252
"RGB(100%, 100%, 100%)", [255, 255, 255, 255],
5353
"rgB(0%, 0%, 0%)", [0, 0, 0, 255],
54-
"rgB(37.5%, 75%, 0%)", [96, 192, 0, 255],
55-
"rgb(37.5%,75%,0%)", [96, 192, 0, 255],
56-
"rgb(37.5%\t, 75%, 0%)", [96, 192, 0, 255],
57-
"rgb(/* R */ 37.5%, /* G */ 75%, /* B */ 0%)", [96, 192, 0, 255],
54+
"rgB(37.5%, 75%, 0%)", [96, 191, 0, 255],
55+
"rgb(37.5%,75%,0%)", [96, 191, 0, 255],
56+
"rgb(37.5%\t, 75%, 0%)", [96, 191, 0, 255],
57+
"rgb(/* R */ 37.5%, /* G */ 75%, /* B */ 0%)", [96, 191, 0, 255],
5858
"rgb(-12%, 110%, 1400%)", [0, 255, 255, 255],
5959

6060
"rgb(10%, 50%, 0)", null,
@@ -111,10 +111,10 @@
111111

112112
"HSL(0, 0%, 0%)", [0, 0, 0, 255],
113113
"hsL(0, 100%, 50%)", [255, 0, 0, 255],
114-
"hsl(60, 100%, 37.5%)", [192, 192, 0, 255],
115-
"hsl(780, 100%, 37.5%)", [192, 192, 0, 255],
116-
"hsl(-300, 100%, 37.5%)", [192, 192, 0, 255],
117-
"hsl(300, 50%, 50%)", [192, 64, 192, 255],
114+
"hsl(60, 100%, 37.5%)", [191, 191, 0, 255],
115+
"hsl(780, 100%, 37.5%)", [191, 191, 0, 255],
116+
"hsl(-300, 100%, 37.5%)", [191, 191, 0, 255],
117+
"hsl(300, 50%, 50%)", [191, 64, 191, 255],
118118

119119
"hsl(10, 50%, 0)", null,
120120
"hsl(50%, 50%, 0%)", null,
@@ -126,11 +126,11 @@
126126
"hsl(0, 0%)", null,
127127
"hsl(0, 0%, 0%, 0%)", [0, 0, 0, 0],
128128

129-
"HSLA(-300, 100%, 37.5%, 1)", [192, 192, 0, 255],
130-
"hsLA(-300, 100%, 37.5%, 12)", [192, 192, 0, 255],
131-
"hsla(-300, 100%, 37.5%, 0.2)", [192, 192, 0, 51],
132-
"hsla(-300, 100%, 37.5%, 0)", [192, 192, 0, 0],
133-
"hsla(-300, 100%, 37.5%, -3)", [192, 192, 0, 0],
129+
"HSLA(-300, 100%, 37.5%, 1)", [191, 191, 0, 255],
130+
"hsLA(-300, 100%, 37.5%, 12)", [191, 191, 0, 255],
131+
"hsla(-300, 100%, 37.5%, 0.2)", [191, 191, 0, 51],
132+
"hsla(-300, 100%, 37.5%, 0)", [191, 191, 0, 0],
133+
"hsla(-300, 100%, 37.5%, -3)", [191, 191, 0, 0],
134134

135135
"hsla(10, 50%, 0, 1)", null,
136136
"hsla(50%, 50%, 0%, 1)", null,
@@ -166,10 +166,10 @@
166166

167167
"HSL(0 0% 0%)", [0, 0, 0, 255],
168168
"hsL(0 100% 50%)", [255, 0, 0, 255],
169-
"hsl(60 100% 37.5%)", [192, 192, 0, 255],
169+
"hsl(60 100% 37.5%)", [191, 191, 0, 255],
170170

171-
"HSLA(-300 100% 37.5% /1)", [192, 192, 0, 255],
172-
"hsLA(-300 100% 37.5% /12)", [192, 192, 0, 255],
171+
"HSLA(-300 100% 37.5% /1)", [191, 191, 0, 255],
172+
"hsLA(-300 100% 37.5% /12)", [191, 191, 0, 255],
173173

174174
"hsl(0, 0 0 0)", null,
175175
"hsl(0 0, 0 0)", null,
@@ -179,79 +179,79 @@
179179
"hsla(0%, 0% 0%)", null,
180180
"hsla(0% 0% 0%, 0%)", null,
181181

182-
"hsla(120.0, 75%, 50%, 20%)", [32, 224, 32, 51],
183-
"hsla(120, 75%, 50%, 0.4)", [32, 224, 32, 102],
184-
"hsla(120 75% 50% / 60%)", [32, 224, 32, 153],
185-
"hsla(120.0 75% 50% / 1.0)", [32, 224, 32, 255],
186-
"hsla(120/* comment */75%/* comment */50%/1.0)", [32, 224, 32, 255],
187-
"hsla(120,/* comment */75%,/* comment */50%,100%)", [32, 224, 32, 255],
188-
"hsla(120.0, 75%, 50%)", [32, 224, 32, 255],
189-
"hsla(120 75% 50%)", [32, 224, 32, 255],
190-
"hsla(120/* comment */75%/* comment */50%)", [32, 224, 32, 255],
191-
"hsla(120/* comment */,75%,/* comment */50%)", [32, 224, 32, 255],
192-
"hsl(120, 75%, 50%, 0.2)", [32, 224, 32, 51],
193-
"hsl(120, 75%, 50%, 40%)", [32, 224, 32, 102],
194-
"hsl(120 75% 50% / 0.6)", [32, 224, 32, 153],
195-
"hsl(120 75% 50% / 80%)", [32, 224, 32, 204],
196-
"hsl(120/* comment */75%/* comment */50%/1.0)", [32, 224, 32, 255],
197-
"hsl(120/* comment */75%/* comment */50%/100%)", [32, 224, 32, 255],
198-
"hsl(120,/* comment */75%,/* comment */50%,1.0)", [32, 224, 32, 255],
199-
"hsl(120,/* comment */75%,/* comment */50%,100%)", [32, 224, 32, 255],
200-
"hsl(120/* comment */75%/* comment */50%)", [32, 224, 32, 255],
201-
"hsl(120/* comment */,75%,/* comment */50%)", [32, 224, 32, 255],
202-
"hsla(120, 75%, 50%, 0.2)", [32, 224, 32, 51],
203-
"hsl(240, 75%, 50%)", [32, 32, 224, 255],
204-
"hsla(120, 75%, 50%)", [32, 224, 32, 255],
205-
"hsla(120.0, 75%, 50%)", [32, 224, 32, 255],
206-
"hsla(1.2e2, 75%, 50%)", [32, 224, 32, 255],
207-
"hsla(1.2E2, 75%, 50%)", [32, 224, 32, 255],
208-
"hsla(60, 75%, 50%)", [224, 224, 32, 255],
209-
"hsl(120, 75%, 50%, 0.2)", [32, 224, 32, 51],
210-
"hsl(120.0, 75%, 50%, 0.4)", [32, 224, 32, 102],
211-
"hsl(1.2e2, 75%, 50%, 0.6)", [32, 224, 32, 153],
212-
"hsl(1.2E2, 75%, 50%, 0.8)", [32, 224, 32, 204],
213-
"hsl(60.0, 75%, 50%, 1.0)", [224, 224, 32, 255],
214-
"rgb(10%, 60%, 10%, 20%)", [25, 153, 25, 51],
182+
"hsla(120.0, 75%, 50%, 20%)", [32, 223, 32, 51],
183+
"hsla(120, 75%, 50%, 0.4)", [32, 223, 32, 102],
184+
"hsla(120 75% 50% / 60%)", [32, 223, 32, 153],
185+
"hsla(120.0 75% 50% / 1.0)", [32, 223, 32, 255],
186+
"hsla(120/* comment */75%/* comment */50%/1.0)", [32, 223, 32, 255],
187+
"hsla(120,/* comment */75%,/* comment */50%,100%)", [32, 223, 32, 255],
188+
"hsla(120.0, 75%, 50%)", [32, 223, 32, 255],
189+
"hsla(120 75% 50%)", [32, 223, 32, 255],
190+
"hsla(120/* comment */75%/* comment */50%)", [32, 223, 32, 255],
191+
"hsla(120/* comment */,75%,/* comment */50%)", [32, 223, 32, 255],
192+
"hsl(120, 75%, 50%, 0.2)", [32, 223, 32, 51],
193+
"hsl(120, 75%, 50%, 40%)", [32, 223, 32, 102],
194+
"hsl(120 75% 50% / 0.6)", [32, 223, 32, 153],
195+
"hsl(120 75% 50% / 80%)", [32, 223, 32, 204],
196+
"hsl(120/* comment */75%/* comment */50%/1.0)", [32, 223, 32, 255],
197+
"hsl(120/* comment */75%/* comment */50%/100%)", [32, 223, 32, 255],
198+
"hsl(120,/* comment */75%,/* comment */50%,1.0)", [32, 223, 32, 255],
199+
"hsl(120,/* comment */75%,/* comment */50%,100%)", [32, 223, 32, 255],
200+
"hsl(120/* comment */75%/* comment */50%)", [32, 223, 32, 255],
201+
"hsl(120/* comment */,75%,/* comment */50%)", [32, 223, 32, 255],
202+
"hsla(120, 75%, 50%, 0.2)", [32, 223, 32, 51],
203+
"hsl(240, 75%, 50%)", [32, 32, 223, 255],
204+
"hsla(120, 75%, 50%)", [32, 223, 32, 255],
205+
"hsla(120.0, 75%, 50%)", [32, 223, 32, 255],
206+
"hsla(1.2e2, 75%, 50%)", [32, 223, 32, 255],
207+
"hsla(1.2E2, 75%, 50%)", [32, 223, 32, 255],
208+
"hsla(60, 75%, 50%)", [223, 223, 32, 255],
209+
"hsl(120, 75%, 50%, 0.2)", [32, 223, 32, 51],
210+
"hsl(120.0, 75%, 50%, 0.4)", [32, 223, 32, 102],
211+
"hsl(1.2e2, 75%, 50%, 0.6)", [32, 223, 32, 153],
212+
"hsl(1.2E2, 75%, 50%, 0.8)", [32, 223, 32, 204],
213+
"hsl(60.0, 75%, 50%, 1.0)", [223, 223, 32, 255],
214+
"rgb(10%, 60%, 10%, 20%)", [26, 153, 26, 51],
215215
"rgb(10, 175, 10, 0.4)", [10, 175, 10, 102],
216216
"rgb(10 175 10 / 60%)", [10, 175, 10, 153],
217217
"rgb(10.0 175.0 10.0 / 0.8)", [10, 175, 10, 204],
218218
"rgb(10/* comment */175/* comment */10/100%)", [10, 175, 10, 255],
219219
"rgb(10,/* comment */150,/* comment */50)", [10, 150, 50, 255],
220-
"rgb(10%, 60%, 10%)", [25, 153, 25, 255],
220+
"rgb(10%, 60%, 10%)", [26, 153, 26, 255],
221221
"rgb(10.0 100.0 100.0)", [10, 100, 100, 255],
222222
"rgb(10/* comment */75/* comment */125)", [10, 75, 125, 255],
223223
"rgb(10.0, 50.0, 150.0)", [10, 50, 150, 255],
224224
"rgba(10.0, 175.0, 10.0, 0.2)", [10, 175, 10, 51],
225225
"rgba(10, 175, 10, 40%)", [10, 175, 10, 102],
226-
"rgba(10% 75% 10% / 0.6)", [25, 192, 25, 153],
226+
"rgba(10% 75% 10% / 0.6)", [26, 191, 26, 153],
227227
"rgba(10 175 10 / 80%)", [10, 175, 10, 204],
228228
"rgba(10/* comment */175/* comment */10/100%)", [10, 175, 10, 255],
229229
"rgba(10,/* comment */150,/* comment */50)", [10, 150, 50, 255],
230230
"rgba(10.0, 125.0, 75.0)", [10, 125, 75, 255],
231-
"rgba(10%, 45%, 45%)", [25, 115, 115, 255],
231+
"rgba(10%, 45%, 45%)", [26, 115, 115, 255],
232232
"rgba(10/* comment */75/* comment */125)", [10, 75, 125, 255],
233233
"rgba(10.0, 50.0, 150.0)", [10, 50, 150, 255],
234234
"rgb(10, 175, 10, 0.2)", [10, 175, 10, 51],
235235
"rgb(10, 175, 10, 0.4)", [10, 175, 10, 102],
236236
"rgb(10, 175, 10, 0.6)", [10, 175, 10, 153],
237-
"rgb(10%, 70%, 10%, 0.8)", [25, 179, 25, 204],
238-
"rgb(10%, 70%, 10%, 1.0)", [25, 179, 25, 255],
237+
"rgb(10%, 70%, 10%, 0.8)", [26, 179, 26, 204],
238+
"rgb(10%, 70%, 10%, 1.0)", [26, 179, 26, 255],
239239
"rgba(10, 150, 50)", [10, 150, 50, 255],
240240
"rgba(10, 125, 75)", [10, 125, 75, 255],
241-
"rgba(10%,40%, 40%)", [25, 102, 102, 255],
242-
"rgba(10%, 45%, 50%)", [25, 115, 128, 255],
243-
"rgba(10%, 50%, 60%)", [25, 128, 153, 255],
241+
"rgba(10%,40%, 40%)", [26, 102, 102, 255],
242+
"rgba(10%, 45%, 50%)", [26, 115, 128, 255],
243+
"rgba(10%, 50%, 60%)", [26, 128, 153, 255],
244244

245-
"hsla(120deg, 75%, 50%, 0.4)", [32, 224, 32, 102],
246-
"hsla(120DEG, 75%, 50%, 0.4)", [32, 224, 32, 102],
247-
"hsla(120deG, 75%, 50%, 0.4)", [32, 224, 32, 102],
248-
"hsla(133.33333333grad, 75%, 50%, 0.6)", [32, 224, 32, 153],
249-
"hsla(2.0943951024rad, 75%, 50%, 0.8)", [32, 224, 32, 204],
250-
"hsla(0.3333333333turn, 75%, 50%, 1.0)", [32, 224, 32, 255],
251-
"hsl(600deg, 75%, 50%)", [32, 32, 224, 255],
252-
"hsl(1066.66666666grad, 75%, 50%)", [32, 32, 224, 255],
253-
"hsl(10.4719755118rad, 75%, 50%)", [32, 32, 224, 255],
254-
"hsl(2.6666666666turn, 75%, 50%)", [32, 32, 224, 255],
245+
"hsla(120deg, 75%, 50%, 0.4)", [32, 223, 32, 102],
246+
"hsla(120DEG, 75%, 50%, 0.4)", [32, 223, 32, 102],
247+
"hsla(120deG, 75%, 50%, 0.4)", [32, 223, 32, 102],
248+
"hsla(133.33333333grad, 75%, 50%, 0.6)", [32, 223, 32, 153],
249+
"hsla(2.0943951024rad, 75%, 50%, 0.8)", [32, 223, 32, 204],
250+
"hsla(0.3333333333turn, 75%, 50%, 1.0)", [32, 223, 32, 255],
251+
"hsl(600deg, 75%, 50%)", [32, 32, 223, 255],
252+
"hsl(1066.66666666grad, 75%, 50%)", [32, 32, 223, 255],
253+
"hsl(10.4719755118rad, 75%, 50%)", [32, 32, 223, 255],
254+
"hsl(2.6666666666turn, 75%, 50%)", [32, 32, 223, 255],
255255

256256
"rgb(-2147483649, 4294967298, -18446744073709551619) /* https://github.com/w3c/web-platform-tests/blob/master/2dcontext/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-3.html */",
257257
[0, 255, 0, 255],

0 commit comments

Comments
 (0)