Skip to content

Commit f51305b

Browse files
committed
Bug 2007772 - Refactor color-mix items into a single unit. r=layout-reviewers,firefox-style-system-reviewers,dshin
To allow parsing multiple items in the color-mix function, change the items to be single units. Differential Revision: https://phabricator.services.mozilla.com/D278116
1 parent a0842a4 commit f51305b

File tree

7 files changed

+117
-85
lines changed

7 files changed

+117
-85
lines changed

servo/components/style/color/mix.rs

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ use crate::derives::*;
1010
use crate::parser::{Parse, ParserContext};
1111
use crate::values::generics::color::ColorMixFlags;
1212
use cssparser::Parser;
13-
use smallvec::SmallVec;
1413
use std::fmt::{self, Write};
1514
use style_traits::{CssWriter, ParseError, ToCss};
1615

@@ -166,24 +165,6 @@ impl ColorMixItem {
166165
}
167166
}
168167

169-
/// Mix two colors into one.
170-
#[inline]
171-
pub fn mix(
172-
interpolation: ColorInterpolationMethod,
173-
left_color: &AbsoluteColor,
174-
left_weight: f32,
175-
right_color: &AbsoluteColor,
176-
right_weight: f32,
177-
flags: ColorMixFlags,
178-
) -> AbsoluteColor {
179-
let items = [
180-
ColorMixItem::new(*left_color, left_weight),
181-
ColorMixItem::new(*right_color, right_weight),
182-
];
183-
184-
mix_many(interpolation, items, flags)
185-
}
186-
187168
/// Mix N colors into one (left-to-right fold).
188169
pub fn mix_many(
189170
interpolation: ColorInterpolationMethod,

servo/components/style/values/animated/color.rs

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,23 @@ use crate::color::AbsoluteColor;
99
use crate::values::animated::{Animate, Procedure, ToAnimatedZero};
1010
use crate::values::computed::Percentage;
1111
use crate::values::distance::{ComputeSquaredDistance, SquaredDistance};
12-
use crate::values::generics::color::{ColorMixFlags, GenericColor, GenericColorMix};
12+
use crate::values::generics::color::{
13+
ColorMixFlags, GenericColor, GenericColorMix, GenericColorMixItem,
14+
};
1315

1416
impl Animate for AbsoluteColor {
1517
#[inline]
1618
fn animate(&self, other: &Self, procedure: Procedure) -> Result<Self, ()> {
19+
use crate::color::mix;
20+
1721
let (left_weight, right_weight) = procedure.weights();
18-
Ok(crate::color::mix::mix(
22+
23+
Ok(mix::mix_many(
1924
ColorInterpolationMethod::best_interpolation_between(self, other),
20-
self,
21-
left_weight as f32,
22-
other,
23-
right_weight as f32,
25+
[
26+
mix::ColorMixItem::new(*self, left_weight as f32),
27+
mix::ColorMixItem::new(*other, right_weight as f32),
28+
],
2429
ColorMixFlags::empty(),
2530
))
2631
}
@@ -61,10 +66,14 @@ impl Animate for Color {
6166
let (left_weight, right_weight) = procedure.weights();
6267
Ok(Self::from_color_mix(ColorMix {
6368
interpolation: ColorInterpolationMethod::srgb(),
64-
left: self.clone(),
65-
left_percentage: Percentage(left_weight as f32),
66-
right: other.clone(),
67-
right_percentage: Percentage(right_weight as f32),
69+
left: GenericColorMixItem {
70+
color: self.clone(),
71+
percentage: Percentage(left_weight as f32),
72+
},
73+
right: GenericColorMixItem {
74+
color: other.clone(),
75+
percentage: Percentage(right_weight as f32),
76+
},
6877
// See https://github.com/w3c/csswg-drafts/issues/7324
6978
flags: ColorMixFlags::empty(),
7079
}))

servo/components/style/values/computed/color.rs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -75,14 +75,16 @@ impl Color {
7575
},
7676
Self::CurrentColor => *current_color,
7777
Self::ColorMix(ref mix) => {
78-
let left = mix.left.resolve_to_absolute(current_color);
79-
let right = mix.right.resolve_to_absolute(current_color);
80-
crate::color::mix::mix(
78+
use crate::color::mix;
79+
80+
let left = mix.left.color.resolve_to_absolute(current_color);
81+
let right = mix.right.color.resolve_to_absolute(current_color);
82+
mix::mix_many(
8183
mix.interpolation,
82-
&left,
83-
mix.left_percentage.to_percentage(),
84-
&right,
85-
mix.right_percentage.to_percentage(),
84+
[
85+
mix::ColorMixItem::new(left, mix.left.percentage.to_percentage()),
86+
mix::ColorMixItem::new(right, mix.right.percentage.to_percentage()),
87+
],
8688
mix.flags,
8789
)
8890
},

servo/components/style/values/generics/color.rs

Lines changed: 44 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,24 @@ bitflags! {
4242
}
4343
}
4444

45+
/// One `(color, percentage)` component of a `color-mix()` expression.
46+
#[derive(
47+
Clone,
48+
Debug,
49+
MallocSizeOf,
50+
PartialEq,
51+
ToAnimatedValue,
52+
ToComputedValue,
53+
ToResolvedValue,
54+
ToShmem,
55+
)]
56+
#[allow(missing_docs)]
57+
#[repr(C)]
58+
pub struct GenericColorMixItem<Color, Percentage> {
59+
pub color: Color,
60+
pub percentage: Percentage,
61+
}
62+
4563
/// A restricted version of the css `color-mix()` function, which only supports
4664
/// percentages.
4765
///
@@ -60,10 +78,8 @@ bitflags! {
6078
#[repr(C)]
6179
pub struct GenericColorMix<Color, Percentage> {
6280
pub interpolation: ColorInterpolationMethod,
63-
pub left: Color,
64-
pub left_percentage: Percentage,
65-
pub right: Color,
66-
pub right_percentage: Percentage,
81+
pub left: GenericColorMixItem<Color, Percentage>,
82+
pub right: GenericColorMixItem<Color, Percentage>,
6783
pub flags: ColorMixFlags,
6884
}
6985

@@ -75,20 +91,20 @@ impl<Color: ToCss, Percentage: ToCss + ToPercentage> ToCss for ColorMix<Color, P
7591
W: Write,
7692
{
7793
fn can_omit<Percentage: ToPercentage>(
78-
percent: &Percentage,
79-
other: &Percentage,
94+
a: &Percentage,
95+
b: &Percentage,
8096
is_left: bool,
8197
) -> bool {
82-
if percent.is_calc() {
98+
if a.is_calc() {
8399
return false;
84100
}
85-
if percent.to_percentage() == 0.5 {
86-
return other.to_percentage() == 0.5;
101+
if a.to_percentage() == 0.5 {
102+
return b.to_percentage() == 0.5;
87103
}
88104
if is_left {
89105
return false;
90106
}
91-
(1.0 - percent.to_percentage() - other.to_percentage()).abs() <= f32::EPSILON
107+
(1.0 - a.to_percentage() - b.to_percentage()).abs() <= f32::EPSILON
92108
}
93109

94110
dest.write_str("color-mix(")?;
@@ -101,17 +117,20 @@ impl<Color: ToCss, Percentage: ToCss + ToPercentage> ToCss for ColorMix<Color, P
101117
dest.write_str(", ")?;
102118
}
103119

104-
self.left.to_css(dest)?;
105-
if !can_omit(&self.left_percentage, &self.right_percentage, true) {
120+
self.left.color.to_css(dest)?;
121+
if !can_omit(&self.left.percentage, &self.right.percentage, true) {
106122
dest.write_char(' ')?;
107-
self.left_percentage.to_css(dest)?;
123+
self.left.percentage.to_css(dest)?;
108124
}
125+
109126
dest.write_str(", ")?;
110-
self.right.to_css(dest)?;
111-
if !can_omit(&self.right_percentage, &self.left_percentage, false) {
127+
128+
self.right.color.to_css(dest)?;
129+
if !can_omit(&self.right.percentage, &self.left.percentage, false) {
112130
dest.write_char(' ')?;
113-
self.right_percentage.to_css(dest)?;
131+
self.right.percentage.to_css(dest)?;
114132
}
133+
115134
dest.write_char(')')
116135
}
117136
}
@@ -123,15 +142,17 @@ impl<Percentage> ColorMix<GenericColor<Percentage>, Percentage> {
123142
where
124143
Percentage: ToPercentage,
125144
{
126-
let left = self.left.as_absolute()?;
127-
let right = self.right.as_absolute()?;
145+
use crate::color::mix;
146+
147+
let left = self.left.color.as_absolute()?;
148+
let right = self.right.color.as_absolute()?;
128149

129-
Some(crate::color::mix::mix(
150+
Some(mix::mix_many(
130151
self.interpolation,
131-
&left,
132-
self.left_percentage.to_percentage(),
133-
&right,
134-
self.right_percentage.to_percentage(),
152+
[
153+
mix::ColorMixItem::new(*left, self.left.percentage.to_percentage()),
154+
mix::ColorMixItem::new(*right, self.right.percentage.to_percentage()),
155+
],
135156
self.flags,
136157
))
137158
}

servo/components/style/values/specified/color.rs

Lines changed: 37 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ use crate::media_queries::Device;
1212
use crate::parser::{Parse, ParserContext};
1313
use crate::values::computed::{Color as ComputedColor, Context, ToComputedValue};
1414
use crate::values::generics::color::{
15-
ColorMixFlags, GenericCaretColor, GenericColorMix, GenericColorOrAuto, GenericLightDark,
15+
ColorMixFlags, GenericCaretColor, GenericColorMix, GenericColorMixItem, GenericColorOrAuto,
16+
GenericLightDark,
1617
};
1718
use crate::values::specified::Percentage;
1819
use crate::values::{normalize, CustomIdent};
@@ -83,10 +84,14 @@ impl ColorMix {
8384
// to preserve floating point precision.
8485
Ok(ColorMix {
8586
interpolation,
86-
left,
87-
left_percentage,
88-
right,
89-
right_percentage,
87+
left: GenericColorMixItem {
88+
color: left,
89+
percentage: left_percentage,
90+
},
91+
right: GenericColorMixItem {
92+
color: right,
93+
percentage: right_percentage,
94+
},
9095
flags: ColorMixFlags::NORMALIZE_WEIGHTS | ColorMixFlags::RESULT_IN_MODERN_SYNTAX,
9196
})
9297
})
@@ -586,8 +591,13 @@ impl Color {
586591
&& ld.dark.honored_in_forced_colors_mode(allow_transparent)
587592
},
588593
Self::ColorMix(ref mix) => {
589-
mix.left.honored_in_forced_colors_mode(allow_transparent)
590-
&& mix.right.honored_in_forced_colors_mode(allow_transparent)
594+
mix.left
595+
.color
596+
.honored_in_forced_colors_mode(allow_transparent)
597+
&& mix
598+
.right
599+
.color
600+
.honored_in_forced_colors_mode(allow_transparent)
591601
},
592602
Self::ContrastColor(ref c) => c.honored_in_forced_colors_mode(allow_transparent),
593603
}
@@ -625,14 +635,17 @@ impl Color {
625635
Self::Absolute(c) => Some(c.color),
626636
Self::ColorFunction(ref color_function) => color_function.resolve_to_absolute().ok(),
627637
Self::ColorMix(ref mix) => {
628-
let left = mix.left.resolve_to_absolute()?;
629-
let right = mix.right.resolve_to_absolute()?;
630-
Some(crate::color::mix::mix(
638+
use crate::color::mix;
639+
640+
let left = mix.left.color.resolve_to_absolute()?;
641+
let right = mix.right.color.resolve_to_absolute()?;
642+
643+
Some(mix::mix_many(
631644
mix.interpolation,
632-
&left,
633-
mix.left_percentage.to_percentage(),
634-
&right,
635-
mix.right_percentage.to_percentage(),
645+
[
646+
mix::ColorMixItem::new(left, mix.left.percentage.to_percentage()),
647+
mix::ColorMixItem::new(right, mix.right.percentage.to_percentage()),
648+
],
636649
mix.flags,
637650
))
638651
},
@@ -783,15 +796,19 @@ impl Color {
783796
Color::ColorMix(ref mix) => {
784797
use crate::values::computed::percentage::Percentage;
785798

786-
let left = mix.left.to_computed_color(context)?;
787-
let right = mix.right.to_computed_color(context)?;
799+
let left = mix.left.color.to_computed_color(context)?;
800+
let right = mix.right.color.to_computed_color(context)?;
788801

789802
ComputedColor::from_color_mix(GenericColorMix {
790803
interpolation: mix.interpolation,
791-
left,
792-
left_percentage: Percentage(mix.left_percentage.get()),
793-
right,
794-
right_percentage: Percentage(mix.right_percentage.get()),
804+
left: GenericColorMixItem {
805+
color: left,
806+
percentage: Percentage(mix.left.percentage.get()),
807+
},
808+
right: GenericColorMixItem {
809+
color: right,
810+
percentage: Percentage(mix.right.percentage.get()),
811+
},
795812
flags: mix.flags,
796813
})
797814
},

servo/components/style/values/specified/image.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ impl Color {
8383
if mix.flags.contains(ColorMixFlags::RESULT_IN_MODERN_SYNTAX) {
8484
true
8585
} else {
86-
mix.left.has_modern_syntax() || mix.right.has_modern_syntax()
86+
mix.left.color.has_modern_syntax() || mix.right.color.has_modern_syntax()
8787
}
8888
},
8989
Self::LightDark(ld) => ld.light.has_modern_syntax() || ld.dark.has_modern_syntax(),

servo/ports/geckolib/glue.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9787,12 +9787,14 @@ pub extern "C" fn Servo_InterpolateColor(
97879787
end_color: &AbsoluteColor,
97889788
progress: f32,
97899789
) -> AbsoluteColor {
9790-
style::color::mix::mix(
9790+
use style::color::mix;
9791+
9792+
mix::mix_many(
97919793
interpolation,
9792-
start_color,
9793-
1.0 - progress,
9794-
end_color,
9795-
progress,
9794+
[
9795+
mix::ColorMixItem::new(*start_color, 1.0 - progress),
9796+
mix::ColorMixItem::new(*end_color, progress),
9797+
],
97969798
ColorMixFlags::empty(),
97979799
)
97989800
}

0 commit comments

Comments
 (0)