aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/style/gecko/conversions.rs45
-rw-r--r--components/style/values/computed/image.rs2
-rw-r--r--components/style/values/generics/image.rs30
-rw-r--r--components/style/values/specified/image.rs38
4 files changed, 52 insertions, 63 deletions
diff --git a/components/style/gecko/conversions.rs b/components/style/gecko/conversions.rs
index 44dbc1bb04b..7b73f00e73e 100644
--- a/components/style/gecko/conversions.rs
+++ b/components/style/gecko/conversions.rs
@@ -24,7 +24,7 @@ use crate::values::computed::{Integer, LengthPercentage};
use crate::values::computed::{Length, Percentage, TextAlign};
use crate::values::generics::box_::VerticalAlign;
use crate::values::generics::grid::{TrackListValue, TrackSize};
-use crate::values::generics::image::{CompatMode, GradientItem, Image as GenericImage};
+use crate::values::generics::image::{CompatMode, Image as GenericImage};
use crate::values::generics::rect::Rect;
use crate::Zero;
use app_units::Au;
@@ -154,7 +154,6 @@ impl nsStyleImage {
// FIXME(emilio): This is really complex, we should use cbindgen for this.
fn set_gradient(&mut self, gradient: Gradient) {
- use self::structs::nsStyleCoord;
use self::structs::NS_STYLE_GRADIENT_SIZE_CLOSEST_CORNER as CLOSEST_CORNER;
use self::structs::NS_STYLE_GRADIENT_SIZE_CLOSEST_SIDE as CLOSEST_SIDE;
use self::structs::NS_STYLE_GRADIENT_SIZE_FARTHEST_CORNER as FARTHEST_CORNER;
@@ -329,26 +328,9 @@ impl nsStyleImage {
},
};
- for (index, item) in gradient.items.iter().enumerate() {
- // NB: stops are guaranteed to be none in the gecko side by
- // default.
-
+ for (index, item) in gradient.items.into_iter().enumerate() {
let gecko_stop = unsafe { &mut (*gecko_gradient).mStops[index] };
- let mut coord = nsStyleCoord::null();
-
- match *item {
- GradientItem::ColorStop(ref stop) => {
- gecko_stop.mColor = stop.color.into();
- gecko_stop.mIsInterpolationHint = false;
- coord.set(stop.position);
- },
- GradientItem::InterpolationHint(hint) => {
- gecko_stop.mIsInterpolationHint = true;
- coord.set(Some(hint));
- },
- }
-
- gecko_stop.mLocation.move_from(coord);
+ *gecko_stop = item;
}
unsafe {
@@ -419,7 +401,7 @@ impl nsStyleImage {
use self::structs::NS_STYLE_GRADIENT_SIZE_FARTHEST_CORNER as FARTHEST_CORNER;
use self::structs::NS_STYLE_GRADIENT_SIZE_FARTHEST_SIDE as FARTHEST_SIDE;
use crate::values::computed::position::Position;
- use crate::values::generics::image::{Circle, ColorStop, Ellipse};
+ use crate::values::generics::image::{Circle, Ellipse};
use crate::values::generics::image::{EndingShape, GradientKind, ShapeExtent};
let gecko_gradient = bindings::Gecko_GetGradientImageValue(self)
@@ -531,24 +513,7 @@ impl nsStyleImage {
},
};
- let items = gecko_gradient
- .mStops
- .iter()
- .map(|ref stop| {
- if stop.mIsInterpolationHint {
- GradientItem::InterpolationHint(
- LengthPercentage::from_gecko_style_coord(&stop.mLocation)
- .expect("mLocation could not convert to LengthPercentage"),
- )
- } else {
- GradientItem::ColorStop(ColorStop {
- color: stop.mColor.into(),
- position: LengthPercentage::from_gecko_style_coord(&stop.mLocation),
- })
- }
- })
- .collect();
-
+ let items = gecko_gradient.mStops.iter().cloned().collect();
let compat_mode = if gecko_gradient.mMozLegacySyntax {
CompatMode::Moz
} else if gecko_gradient.mLegacySyntax {
diff --git a/components/style/values/computed/image.rs b/components/style/values/computed/image.rs
index 4070e51815a..70ecad6a04e 100644
--- a/components/style/values/computed/image.rs
+++ b/components/style/values/computed/image.rs
@@ -55,7 +55,7 @@ pub enum LineDirection {
pub type EndingShape = generic::EndingShape<Length, LengthPercentage>;
/// A computed gradient item.
-pub type GradientItem = generic::GradientItem<Color, LengthPercentage>;
+pub type GradientItem = generic::GenericGradientItem<Color, LengthPercentage>;
/// A computed color stop.
pub type ColorStop = generic::ColorStop<Color, LengthPercentage>;
diff --git a/components/style/values/generics/image.rs b/components/style/values/generics/image.rs
index 71d6a1b3849..1442ce604a2 100644
--- a/components/style/values/generics/image.rs
+++ b/components/style/values/generics/image.rs
@@ -135,13 +135,23 @@ pub enum ShapeExtent {
#[derive(
Clone, Copy, Debug, MallocSizeOf, PartialEq, ToComputedValue, ToCss, ToResolvedValue, ToShmem,
)]
-pub enum GradientItem<Color, LengthPercentage> {
- /// A color stop.
- ColorStop(ColorStop<Color, LengthPercentage>),
+#[repr(C, u8)]
+pub enum GenericGradientItem<Color, LengthPercentage> {
+ /// A simple color stop, without position.
+ SimpleColorStop(Color),
+ /// A complex color stop, with a position.
+ ComplexColorStop {
+ /// The color for the stop.
+ color: Color,
+ /// The position for the stop.
+ position: LengthPercentage,
+ },
/// An interpolation hint.
InterpolationHint(LengthPercentage),
}
+pub use self::GenericGradientItem as GradientItem;
+
/// A color stop.
/// <https://drafts.csswg.org/css-images/#typedef-color-stop-list>
#[derive(
@@ -154,6 +164,20 @@ pub struct ColorStop<Color, LengthPercentage> {
pub position: Option<LengthPercentage>,
}
+impl<Color, LengthPercentage> ColorStop<Color, LengthPercentage> {
+ /// Convert the color stop into an appropriate `GradientItem`.
+ #[inline]
+ pub fn into_item(self) -> GradientItem<Color, LengthPercentage> {
+ match self.position {
+ Some(position) => GradientItem::ComplexColorStop {
+ color: self.color,
+ position,
+ },
+ None => GradientItem::SimpleColorStop(self.color),
+ }
+ }
+}
+
/// Specified values for a paint worklet.
/// <https://drafts.css-houdini.org/css-paint-api/>
#[cfg_attr(feature = "servo", derive(MallocSizeOf))]
diff --git a/components/style/values/specified/image.rs b/components/style/values/specified/image.rs
index 84571a43ad5..a387d8e07c2 100644
--- a/components/style/values/specified/image.rs
+++ b/components/style/values/specified/image.rs
@@ -484,24 +484,24 @@ impl Gradient {
if reverse_stops {
p.reverse();
}
- Ok(generic::GradientItem::ColorStop(generic::ColorStop {
- color: color,
- position: Some(p.into()),
- }))
+ Ok(generic::GradientItem::ComplexColorStop {
+ color,
+ position: p.into(),
+ })
})
})
.unwrap_or(vec![]);
if items.is_empty() {
items = vec![
- generic::GradientItem::ColorStop(generic::ColorStop {
+ generic::GradientItem::ComplexColorStop {
color: Color::transparent().into(),
- position: Some(Percentage::zero().into()),
- }),
- generic::GradientItem::ColorStop(generic::ColorStop {
+ position: Percentage::zero().into(),
+ },
+ generic::GradientItem::ComplexColorStop {
color: Color::transparent().into(),
- position: Some(Percentage::hundred().into()),
- }),
+ position: Percentage::hundred().into(),
+ },
];
} else if items.len() == 1 {
let first = items[0].clone();
@@ -510,12 +510,12 @@ impl Gradient {
items.sort_by(|a, b| {
match (a, b) {
(
- &generic::GradientItem::ColorStop(ref a),
- &generic::GradientItem::ColorStop(ref b),
- ) => match (&a.position, &b.position) {
+ &generic::GradientItem::ComplexColorStop { position: ref a_position, .. },
+ &generic::GradientItem::ComplexColorStop { position: ref b_position, .. },
+ ) => match (a_position, b_position) {
(
- &Some(LengthPercentage::Percentage(a)),
- &Some(LengthPercentage::Percentage(b)),
+ &LengthPercentage::Percentage(a),
+ &LengthPercentage::Percentage(b),
) => {
return a.0.partial_cmp(&b.0).unwrap_or(Ordering::Equal);
},
@@ -960,13 +960,13 @@ impl GradientItem {
if let Ok(multi_position) = input.try(|i| LengthPercentage::parse(context, i)) {
let stop_color = stop.color.clone();
- items.push(generic::GradientItem::ColorStop(stop));
- items.push(generic::GradientItem::ColorStop(ColorStop {
+ items.push(stop.into_item());
+ items.push(ColorStop {
color: stop_color,
position: Some(multi_position),
- }));
+ }.into_item());
} else {
- items.push(generic::GradientItem::ColorStop(stop));
+ items.push(stop.into_item());
}
seen_stop = true;