mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
style: Use rust types for gradient stops.
This doesn't clean up all that much, yet, but it's a step in the right direction. Differential Revision: https://phabricator.services.mozilla.com/D29168
This commit is contained in:
parent
e40500622e
commit
8123007717
4 changed files with 52 additions and 63 deletions
|
@ -24,7 +24,7 @@ use crate::values::computed::{Integer, LengthPercentage};
|
||||||
use crate::values::computed::{Length, Percentage, TextAlign};
|
use crate::values::computed::{Length, Percentage, TextAlign};
|
||||||
use crate::values::generics::box_::VerticalAlign;
|
use crate::values::generics::box_::VerticalAlign;
|
||||||
use crate::values::generics::grid::{TrackListValue, TrackSize};
|
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::values::generics::rect::Rect;
|
||||||
use crate::Zero;
|
use crate::Zero;
|
||||||
use app_units::Au;
|
use app_units::Au;
|
||||||
|
@ -154,7 +154,6 @@ impl nsStyleImage {
|
||||||
|
|
||||||
// FIXME(emilio): This is really complex, we should use cbindgen for this.
|
// FIXME(emilio): This is really complex, we should use cbindgen for this.
|
||||||
fn set_gradient(&mut self, gradient: Gradient) {
|
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_CORNER as CLOSEST_CORNER;
|
||||||
use self::structs::NS_STYLE_GRADIENT_SIZE_CLOSEST_SIDE as CLOSEST_SIDE;
|
use self::structs::NS_STYLE_GRADIENT_SIZE_CLOSEST_SIDE as CLOSEST_SIDE;
|
||||||
use self::structs::NS_STYLE_GRADIENT_SIZE_FARTHEST_CORNER as FARTHEST_CORNER;
|
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() {
|
for (index, item) in gradient.items.into_iter().enumerate() {
|
||||||
// NB: stops are guaranteed to be none in the gecko side by
|
|
||||||
// default.
|
|
||||||
|
|
||||||
let gecko_stop = unsafe { &mut (*gecko_gradient).mStops[index] };
|
let gecko_stop = unsafe { &mut (*gecko_gradient).mStops[index] };
|
||||||
let mut coord = nsStyleCoord::null();
|
*gecko_stop = item;
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe {
|
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_CORNER as FARTHEST_CORNER;
|
||||||
use self::structs::NS_STYLE_GRADIENT_SIZE_FARTHEST_SIDE as FARTHEST_SIDE;
|
use self::structs::NS_STYLE_GRADIENT_SIZE_FARTHEST_SIDE as FARTHEST_SIDE;
|
||||||
use crate::values::computed::position::Position;
|
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};
|
use crate::values::generics::image::{EndingShape, GradientKind, ShapeExtent};
|
||||||
|
|
||||||
let gecko_gradient = bindings::Gecko_GetGradientImageValue(self)
|
let gecko_gradient = bindings::Gecko_GetGradientImageValue(self)
|
||||||
|
@ -531,24 +513,7 @@ impl nsStyleImage {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let items = gecko_gradient
|
let items = gecko_gradient.mStops.iter().cloned().collect();
|
||||||
.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 compat_mode = if gecko_gradient.mMozLegacySyntax {
|
let compat_mode = if gecko_gradient.mMozLegacySyntax {
|
||||||
CompatMode::Moz
|
CompatMode::Moz
|
||||||
} else if gecko_gradient.mLegacySyntax {
|
} else if gecko_gradient.mLegacySyntax {
|
||||||
|
|
|
@ -55,7 +55,7 @@ pub enum LineDirection {
|
||||||
pub type EndingShape = generic::EndingShape<Length, LengthPercentage>;
|
pub type EndingShape = generic::EndingShape<Length, LengthPercentage>;
|
||||||
|
|
||||||
/// A computed gradient item.
|
/// A computed gradient item.
|
||||||
pub type GradientItem = generic::GradientItem<Color, LengthPercentage>;
|
pub type GradientItem = generic::GenericGradientItem<Color, LengthPercentage>;
|
||||||
|
|
||||||
/// A computed color stop.
|
/// A computed color stop.
|
||||||
pub type ColorStop = generic::ColorStop<Color, LengthPercentage>;
|
pub type ColorStop = generic::ColorStop<Color, LengthPercentage>;
|
||||||
|
|
|
@ -135,13 +135,23 @@ pub enum ShapeExtent {
|
||||||
#[derive(
|
#[derive(
|
||||||
Clone, Copy, Debug, MallocSizeOf, PartialEq, ToComputedValue, ToCss, ToResolvedValue, ToShmem,
|
Clone, Copy, Debug, MallocSizeOf, PartialEq, ToComputedValue, ToCss, ToResolvedValue, ToShmem,
|
||||||
)]
|
)]
|
||||||
pub enum GradientItem<Color, LengthPercentage> {
|
#[repr(C, u8)]
|
||||||
/// A color stop.
|
pub enum GenericGradientItem<Color, LengthPercentage> {
|
||||||
ColorStop(ColorStop<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.
|
/// An interpolation hint.
|
||||||
InterpolationHint(LengthPercentage),
|
InterpolationHint(LengthPercentage),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub use self::GenericGradientItem as GradientItem;
|
||||||
|
|
||||||
/// A color stop.
|
/// A color stop.
|
||||||
/// <https://drafts.csswg.org/css-images/#typedef-color-stop-list>
|
/// <https://drafts.csswg.org/css-images/#typedef-color-stop-list>
|
||||||
#[derive(
|
#[derive(
|
||||||
|
@ -154,6 +164,20 @@ pub struct ColorStop<Color, LengthPercentage> {
|
||||||
pub position: Option<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.
|
/// Specified values for a paint worklet.
|
||||||
/// <https://drafts.css-houdini.org/css-paint-api/>
|
/// <https://drafts.css-houdini.org/css-paint-api/>
|
||||||
#[cfg_attr(feature = "servo", derive(MallocSizeOf))]
|
#[cfg_attr(feature = "servo", derive(MallocSizeOf))]
|
||||||
|
|
|
@ -484,24 +484,24 @@ impl Gradient {
|
||||||
if reverse_stops {
|
if reverse_stops {
|
||||||
p.reverse();
|
p.reverse();
|
||||||
}
|
}
|
||||||
Ok(generic::GradientItem::ColorStop(generic::ColorStop {
|
Ok(generic::GradientItem::ComplexColorStop {
|
||||||
color: color,
|
color,
|
||||||
position: Some(p.into()),
|
position: p.into(),
|
||||||
}))
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.unwrap_or(vec![]);
|
.unwrap_or(vec![]);
|
||||||
|
|
||||||
if items.is_empty() {
|
if items.is_empty() {
|
||||||
items = vec![
|
items = vec![
|
||||||
generic::GradientItem::ColorStop(generic::ColorStop {
|
generic::GradientItem::ComplexColorStop {
|
||||||
color: Color::transparent().into(),
|
color: Color::transparent().into(),
|
||||||
position: Some(Percentage::zero().into()),
|
position: Percentage::zero().into(),
|
||||||
}),
|
},
|
||||||
generic::GradientItem::ColorStop(generic::ColorStop {
|
generic::GradientItem::ComplexColorStop {
|
||||||
color: Color::transparent().into(),
|
color: Color::transparent().into(),
|
||||||
position: Some(Percentage::hundred().into()),
|
position: Percentage::hundred().into(),
|
||||||
}),
|
},
|
||||||
];
|
];
|
||||||
} else if items.len() == 1 {
|
} else if items.len() == 1 {
|
||||||
let first = items[0].clone();
|
let first = items[0].clone();
|
||||||
|
@ -510,12 +510,12 @@ impl Gradient {
|
||||||
items.sort_by(|a, b| {
|
items.sort_by(|a, b| {
|
||||||
match (a, b) {
|
match (a, b) {
|
||||||
(
|
(
|
||||||
&generic::GradientItem::ColorStop(ref a),
|
&generic::GradientItem::ComplexColorStop { position: ref a_position, .. },
|
||||||
&generic::GradientItem::ColorStop(ref b),
|
&generic::GradientItem::ComplexColorStop { position: ref b_position, .. },
|
||||||
) => match (&a.position, &b.position) {
|
) => match (a_position, b_position) {
|
||||||
(
|
(
|
||||||
&Some(LengthPercentage::Percentage(a)),
|
&LengthPercentage::Percentage(a),
|
||||||
&Some(LengthPercentage::Percentage(b)),
|
&LengthPercentage::Percentage(b),
|
||||||
) => {
|
) => {
|
||||||
return a.0.partial_cmp(&b.0).unwrap_or(Ordering::Equal);
|
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)) {
|
if let Ok(multi_position) = input.try(|i| LengthPercentage::parse(context, i)) {
|
||||||
let stop_color = stop.color.clone();
|
let stop_color = stop.color.clone();
|
||||||
items.push(generic::GradientItem::ColorStop(stop));
|
items.push(stop.into_item());
|
||||||
items.push(generic::GradientItem::ColorStop(ColorStop {
|
items.push(ColorStop {
|
||||||
color: stop_color,
|
color: stop_color,
|
||||||
position: Some(multi_position),
|
position: Some(multi_position),
|
||||||
}));
|
}.into_item());
|
||||||
} else {
|
} else {
|
||||||
items.push(generic::GradientItem::ColorStop(stop));
|
items.push(stop.into_item());
|
||||||
}
|
}
|
||||||
|
|
||||||
seen_stop = true;
|
seen_stop = true;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue