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