mirror of
https://github.com/servo/servo.git
synced 2025-08-03 04:30:10 +01:00
Implement serialization of linear-gradient the same ways as in Gecko
This commit is contained in:
parent
9d74ae890b
commit
6ae4bf6ee8
3 changed files with 81 additions and 49 deletions
|
@ -56,7 +56,7 @@ use style::properties::longhands::border_image_repeat::computed_value::RepeatKey
|
|||
use style::properties::style_structs;
|
||||
use style::servo::restyle_damage::REPAINT;
|
||||
use style::values::{Either, RGBA};
|
||||
use style::values::computed::{Gradient, GradientItem, LengthOrPercentage};
|
||||
use style::values::computed::{Angle, Gradient, GradientItem, LengthOrPercentage};
|
||||
use style::values::computed::{LengthOrPercentageOrAuto, NumberOrPercentage, Position};
|
||||
use style::values::computed::effects::SimpleShadow;
|
||||
use style::values::computed::image::{EndingShape, LineDirection};
|
||||
|
@ -1214,6 +1214,18 @@ impl FragmentDisplayListBuilding for Fragment {
|
|||
-> display_list::Gradient {
|
||||
let angle = match *direction {
|
||||
LineDirection::Angle(angle) => angle.radians(),
|
||||
LineDirection::Horizontal(x) => {
|
||||
match x {
|
||||
X::Left => Angle::Degree(270.).radians(),
|
||||
X::Right => Angle::Degree(90.).radians(),
|
||||
}
|
||||
},
|
||||
LineDirection::Vertical(y) => {
|
||||
match y {
|
||||
Y::Top => Angle::Degree(0.).radians(),
|
||||
Y::Bottom => Angle::Degree(180.).radians(),
|
||||
}
|
||||
},
|
||||
LineDirection::Corner(horizontal, vertical) => {
|
||||
// This the angle for one of the diagonals of the box. Our angle
|
||||
// will either be this one, this one + PI, or one of the other
|
||||
|
|
|
@ -15,6 +15,7 @@ use gecko_bindings::bindings::{Gecko_InitializeImageCropRect, Gecko_SetImageElem
|
|||
use gecko_bindings::structs::{nsCSSUnit, nsStyleCoord_CalcValue, nsStyleImage};
|
||||
use gecko_bindings::structs::{nsresult, SheetType};
|
||||
use gecko_bindings::sugar::ns_style_coord::{CoordDataValue, CoordData, CoordDataMut};
|
||||
use std::f32::consts::PI;
|
||||
use stylesheets::{Origin, RulesMutateError};
|
||||
use values::computed::{Angle, CalcLengthOrPercentage, Gradient, Image};
|
||||
use values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto};
|
||||
|
@ -215,10 +216,35 @@ impl nsStyleImage {
|
|||
|
||||
match direction {
|
||||
LineDirection::Angle(angle) => {
|
||||
// PI radians (180deg) is ignored because it is the default value.
|
||||
if angle.radians() != PI {
|
||||
unsafe {
|
||||
(*gecko_gradient).mAngle.set(angle);
|
||||
}
|
||||
}
|
||||
},
|
||||
LineDirection::Horizontal(x) => {
|
||||
let x = match x {
|
||||
X::Left => 0.0,
|
||||
X::Right => 1.0,
|
||||
};
|
||||
|
||||
unsafe {
|
||||
(*gecko_gradient).mAngle.set(angle);
|
||||
(*gecko_gradient).mBgPosX.set_value(CoordDataValue::None);
|
||||
(*gecko_gradient).mBgPosY.set_value(CoordDataValue::None);
|
||||
(*gecko_gradient).mBgPosX
|
||||
.set_value(CoordDataValue::Percent(x));
|
||||
(*gecko_gradient).mBgPosY
|
||||
.set_value(CoordDataValue::Percent(0.5));
|
||||
}
|
||||
},
|
||||
LineDirection::Vertical(y) => {
|
||||
// Y::Bottom (to bottom) is ignored because it is the default value.
|
||||
if y == Y::Top {
|
||||
unsafe {
|
||||
(*gecko_gradient).mBgPosX
|
||||
.set_value(CoordDataValue::Percent(0.5));
|
||||
(*gecko_gradient).mBgPosY
|
||||
.set_value(CoordDataValue::Percent(0.0));
|
||||
}
|
||||
}
|
||||
},
|
||||
LineDirection::Corner(horiz, vert) => {
|
||||
|
@ -232,7 +258,6 @@ impl nsStyleImage {
|
|||
};
|
||||
|
||||
unsafe {
|
||||
(*gecko_gradient).mAngle.set_value(CoordDataValue::None);
|
||||
(*gecko_gradient).mBgPosX
|
||||
.set_value(CoordDataValue::Percent(percent_x));
|
||||
(*gecko_gradient).mBgPosY
|
||||
|
@ -245,14 +270,9 @@ impl nsStyleImage {
|
|||
if let Some(position) = position {
|
||||
(*gecko_gradient).mBgPosX.set(position.horizontal);
|
||||
(*gecko_gradient).mBgPosY.set(position.vertical);
|
||||
} else {
|
||||
(*gecko_gradient).mBgPosX.set_value(CoordDataValue::None);
|
||||
(*gecko_gradient).mBgPosY.set_value(CoordDataValue::None);
|
||||
}
|
||||
if let Some(angle) = angle {
|
||||
(*gecko_gradient).mAngle.set(angle);
|
||||
} else {
|
||||
(*gecko_gradient).mAngle.set_value(CoordDataValue::None);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -304,12 +324,7 @@ impl nsStyleImage {
|
|||
unsafe {
|
||||
if let Some(angle) = angle {
|
||||
(*gecko_gradient).mAngle.set(angle);
|
||||
} else {
|
||||
(*gecko_gradient).mAngle.set_value(CoordDataValue::None);
|
||||
}
|
||||
|
||||
(*gecko_gradient).mBgPosX.set_value(CoordDataValue::None);
|
||||
(*gecko_gradient).mBgPosY.set_value(CoordDataValue::None);
|
||||
}
|
||||
|
||||
// Setting radius values depending shape
|
||||
|
|
|
@ -55,6 +55,10 @@ pub type GradientKind = GenericGradientKind<
|
|||
pub enum LineDirection {
|
||||
/// An angle.
|
||||
Angle(Angle),
|
||||
/// A horizontal direction.
|
||||
Horizontal(X),
|
||||
/// A vertical direction.
|
||||
Vertical(Y),
|
||||
/// A corner.
|
||||
Corner(X, Y),
|
||||
/// A Position and an Angle for legacy `-moz-` prefixed gradient.
|
||||
|
@ -78,9 +82,11 @@ impl GenericLineDirection for LineDirection {
|
|||
fn points_downwards(&self) -> bool {
|
||||
match *self {
|
||||
LineDirection::Angle(angle) => angle.radians() == PI,
|
||||
LineDirection::Vertical(Y::Bottom) => true,
|
||||
LineDirection::Corner(..) => false,
|
||||
#[cfg(feature = "gecko")]
|
||||
LineDirection::MozPosition(_, _) => false,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -89,6 +95,18 @@ impl GenericLineDirection for LineDirection {
|
|||
{
|
||||
match *self {
|
||||
LineDirection::Angle(ref angle) => angle.to_css(dest),
|
||||
LineDirection::Horizontal(x) => {
|
||||
if compat_mode == CompatMode::Modern {
|
||||
dest.write_str("to ")?;
|
||||
}
|
||||
x.to_css(dest)
|
||||
},
|
||||
LineDirection::Vertical(y) => {
|
||||
if compat_mode == CompatMode::Modern {
|
||||
dest.write_str("to ")?;
|
||||
}
|
||||
y.to_css(dest)
|
||||
},
|
||||
LineDirection::Corner(x, y) => {
|
||||
if compat_mode == CompatMode::Modern {
|
||||
dest.write_str("to ")?;
|
||||
|
@ -116,38 +134,19 @@ impl GenericLineDirection for LineDirection {
|
|||
}
|
||||
}
|
||||
|
||||
impl SpecifiedLineDirection {
|
||||
/// Takes a modern linear gradient angle and convert it to Gecko's old coordinate for
|
||||
/// webkit-prefixed version
|
||||
fn to_gecko_coordinate(modern_angle: f32, _compat_mode: CompatMode) -> f32 {
|
||||
#[cfg(feature = "gecko")]
|
||||
{
|
||||
return match _compat_mode {
|
||||
CompatMode::WebKit => -modern_angle + 270.,
|
||||
_ => modern_angle,
|
||||
}
|
||||
}
|
||||
#[cfg(feature = "servo")]
|
||||
modern_angle
|
||||
}
|
||||
impl ToComputedValue for SpecifiedLineDirection {
|
||||
type ComputedValue = LineDirection;
|
||||
|
||||
/// Manually derived to_computed_value
|
||||
fn to_computed_value(&self, context: &Context, compat_mode: CompatMode) -> LineDirection {
|
||||
fn to_computed_value(&self, context: &Context) -> Self::ComputedValue {
|
||||
match *self {
|
||||
SpecifiedLineDirection::Angle(ref angle) => {
|
||||
LineDirection::Angle(angle.to_computed_value(context))
|
||||
},
|
||||
SpecifiedLineDirection::Horizontal(X::Left) => {
|
||||
LineDirection::Angle(Angle::Degree(SpecifiedLineDirection::to_gecko_coordinate(270., compat_mode)))
|
||||
SpecifiedLineDirection::Horizontal(x) => {
|
||||
LineDirection::Horizontal(x)
|
||||
},
|
||||
SpecifiedLineDirection::Horizontal(X::Right) => {
|
||||
LineDirection::Angle(Angle::Degree(SpecifiedLineDirection::to_gecko_coordinate(90., compat_mode)))
|
||||
},
|
||||
SpecifiedLineDirection::Vertical(Y::Top) => {
|
||||
LineDirection::Angle(Angle::Degree(SpecifiedLineDirection::to_gecko_coordinate(0., compat_mode)))
|
||||
},
|
||||
SpecifiedLineDirection::Vertical(Y::Bottom) => {
|
||||
LineDirection::Angle(Angle::Degree(SpecifiedLineDirection::to_gecko_coordinate(180., compat_mode)))
|
||||
SpecifiedLineDirection::Vertical(y) => {
|
||||
LineDirection::Vertical(y)
|
||||
},
|
||||
SpecifiedLineDirection::Corner(x, y) => {
|
||||
LineDirection::Corner(x, y)
|
||||
|
@ -160,11 +159,17 @@ impl SpecifiedLineDirection {
|
|||
}
|
||||
}
|
||||
|
||||
fn from_computed_value(computed: &LineDirection) -> Self {
|
||||
fn from_computed_value(computed: &Self::ComputedValue) -> Self {
|
||||
match *computed {
|
||||
LineDirection::Angle(ref angle) => {
|
||||
SpecifiedLineDirection::Angle(ToComputedValue::from_computed_value(angle))
|
||||
},
|
||||
LineDirection::Horizontal(x) => {
|
||||
SpecifiedLineDirection::Horizontal(x)
|
||||
},
|
||||
LineDirection::Vertical(y) => {
|
||||
SpecifiedLineDirection::Vertical(y)
|
||||
},
|
||||
LineDirection::Corner(x, y) => {
|
||||
SpecifiedLineDirection::Corner(x, y)
|
||||
},
|
||||
|
@ -182,7 +187,7 @@ impl ToComputedValue for SpecifiedGradient {
|
|||
|
||||
fn to_computed_value(&self, context: &Context) -> Self::ComputedValue {
|
||||
Self::ComputedValue {
|
||||
kind: self.kind.to_computed_value(context, self.compat_mode),
|
||||
kind: self.kind.to_computed_value(context),
|
||||
items: self.items.to_computed_value(context),
|
||||
repeating: self.repeating,
|
||||
compat_mode: self.compat_mode
|
||||
|
@ -199,12 +204,13 @@ impl ToComputedValue for SpecifiedGradient {
|
|||
}
|
||||
}
|
||||
|
||||
impl SpecifiedGradientKind {
|
||||
/// Manually derived to_computed_value
|
||||
pub fn to_computed_value(&self, context: &Context, compat_mode: CompatMode) -> GradientKind {
|
||||
impl ToComputedValue for SpecifiedGradientKind {
|
||||
type ComputedValue = GradientKind;
|
||||
|
||||
fn to_computed_value(&self, context: &Context) -> Self::ComputedValue {
|
||||
match self {
|
||||
&GenericGradientKind::Linear(ref line_direction) => {
|
||||
GenericGradientKind::Linear(line_direction.to_computed_value(context, compat_mode))
|
||||
GenericGradientKind::Linear(line_direction.to_computed_value(context))
|
||||
},
|
||||
&GenericGradientKind::Radial(ref ending_shape, ref position, ref angle) => {
|
||||
GenericGradientKind::Radial(ending_shape.to_computed_value(context),
|
||||
|
@ -214,8 +220,7 @@ impl SpecifiedGradientKind {
|
|||
}
|
||||
}
|
||||
|
||||
/// Manually derived from_computed_value
|
||||
pub fn from_computed_value(computed: &GradientKind) -> SpecifiedGradientKind {
|
||||
fn from_computed_value(computed: &Self::ComputedValue) -> Self {
|
||||
match *computed {
|
||||
GenericGradientKind::Linear(line_direction) => {
|
||||
GenericGradientKind::Linear(SpecifiedLineDirection::from_computed_value(&line_direction))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue