mirror of
https://github.com/servo/servo.git
synced 2025-08-07 14:35:33 +01:00
Don't use Point2D<f32> for cubic curves anymore
This commit is contained in:
parent
e57ed3d42f
commit
5ffa523ccd
5 changed files with 70 additions and 83 deletions
|
@ -9,7 +9,6 @@ use Atom;
|
||||||
use bezier::Bezier;
|
use bezier::Bezier;
|
||||||
use context::SharedStyleContext;
|
use context::SharedStyleContext;
|
||||||
use dom::OpaqueNode;
|
use dom::OpaqueNode;
|
||||||
use euclid::Point2D;
|
|
||||||
use font_metrics::FontMetricsProvider;
|
use font_metrics::FontMetricsProvider;
|
||||||
use properties::{self, CascadeFlags, ComputedValues, ComputedValuesInner, Importance};
|
use properties::{self, CascadeFlags, ComputedValues, ComputedValuesInner, Importance};
|
||||||
use properties::animated_properties::{AnimatableLonghand, AnimatedProperty, TransitionProperty};
|
use properties::animated_properties::{AnimatableLonghand, AnimatedProperty, TransitionProperty};
|
||||||
|
@ -369,18 +368,10 @@ impl PropertyAnimation {
|
||||||
|
|
||||||
/// Update the given animation at a given point of progress.
|
/// Update the given animation at a given point of progress.
|
||||||
pub fn update(&self, style: &mut ComputedValues, time: f64) {
|
pub fn update(&self, style: &mut ComputedValues, time: f64) {
|
||||||
let solve_bezier = |(p1, p2): (Point2D<_>, Point2D<_>)| {
|
|
||||||
let epsilon = 1. / (200. * (self.duration.seconds() as f64));
|
let epsilon = 1. / (200. * (self.duration.seconds() as f64));
|
||||||
let bezier = Bezier::new(
|
|
||||||
Point2D::new(p1.x as f64, p1.y as f64),
|
|
||||||
Point2D::new(p2.x as f64, p2.y as f64),
|
|
||||||
);
|
|
||||||
bezier.solve(time, epsilon)
|
|
||||||
};
|
|
||||||
|
|
||||||
let progress = match self.timing_function {
|
let progress = match self.timing_function {
|
||||||
GenericTimingFunction::CubicBezier(p1, p2) => {
|
GenericTimingFunction::CubicBezier { x1, y1, x2, y2 } => {
|
||||||
solve_bezier((p1, p2))
|
Bezier::new(x1, y1, x2, y2).solve(time, epsilon)
|
||||||
},
|
},
|
||||||
GenericTimingFunction::Steps(steps, StepPosition::Start) => {
|
GenericTimingFunction::Steps(steps, StepPosition::Start) => {
|
||||||
(time * (steps as f64)).ceil() / (steps as f64)
|
(time * (steps as f64)).ceil() / (steps as f64)
|
||||||
|
@ -405,7 +396,8 @@ impl PropertyAnimation {
|
||||||
out
|
out
|
||||||
},
|
},
|
||||||
GenericTimingFunction::Keyword(keyword) => {
|
GenericTimingFunction::Keyword(keyword) => {
|
||||||
solve_bezier(keyword.to_bezier_points())
|
let (x1, x2, y1, y2) = keyword.to_bezier();
|
||||||
|
Bezier::new(x1, x2, y1, y2).solve(time, epsilon)
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
#![deny(missing_docs)]
|
#![deny(missing_docs)]
|
||||||
|
|
||||||
use euclid::Point2D;
|
use values::CSSFloat;
|
||||||
|
|
||||||
const NEWTON_METHOD_ITERATIONS: u8 = 8;
|
const NEWTON_METHOD_ITERATIONS: u8 = 8;
|
||||||
|
|
||||||
|
@ -31,12 +31,12 @@ impl Bezier {
|
||||||
/// The start and end points are always (0, 0) and (1, 1) so that a transition or animation
|
/// The start and end points are always (0, 0) and (1, 1) so that a transition or animation
|
||||||
/// starts at 0% and ends at 100%.
|
/// starts at 0% and ends at 100%.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(p1: Point2D<f64>, p2: Point2D<f64>) -> Bezier {
|
pub fn new(x1: CSSFloat, y1: CSSFloat, x2: CSSFloat, y2: CSSFloat) -> Bezier {
|
||||||
let cx = 3.0 * p1.x;
|
let cx = 3. * x1 as f64;
|
||||||
let bx = 3.0 * (p2.x - p1.x) - cx;
|
let bx = 3. * (x2 as f64 - x1 as f64) - cx;
|
||||||
|
|
||||||
let cy = 3.0 * p1.y;
|
let cy = 3. * y1 as f64;
|
||||||
let by = 3.0 * (p2.y - p1.y) - cy;
|
let by = 3. * (y2 as f64 - y1 as f64) - cy;
|
||||||
|
|
||||||
Bezier {
|
Bezier {
|
||||||
ax: 1.0 - cx - bx,
|
ax: 1.0 - cx - bx,
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use euclid::{Point2D, TypedPoint2D};
|
|
||||||
use gecko_bindings::structs::{nsTimingFunction, nsTimingFunction_Type};
|
use gecko_bindings::structs::{nsTimingFunction, nsTimingFunction_Type};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use values::computed::ToComputedValue;
|
use values::computed::ToComputedValue;
|
||||||
|
@ -28,18 +27,19 @@ impl nsTimingFunction {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_as_bezier(&mut self,
|
fn set_as_bezier(
|
||||||
|
&mut self,
|
||||||
function_type: nsTimingFunction_Type,
|
function_type: nsTimingFunction_Type,
|
||||||
p1: Point2D<f32>,
|
x1: f32, y1: f32, x2: f32, y2: f32,
|
||||||
p2: Point2D<f32>) {
|
) {
|
||||||
self.mType = function_type;
|
self.mType = function_type;
|
||||||
unsafe {
|
unsafe {
|
||||||
let ref mut gecko_cubic_bezier =
|
let ref mut gecko_cubic_bezier =
|
||||||
unsafe { self.__bindgen_anon_1.mFunc.as_mut() };
|
unsafe { self.__bindgen_anon_1.mFunc.as_mut() };
|
||||||
gecko_cubic_bezier.mX1 = p1.x;
|
gecko_cubic_bezier.mX1 = x1;
|
||||||
gecko_cubic_bezier.mY1 = p1.y;
|
gecko_cubic_bezier.mY1 = y1;
|
||||||
gecko_cubic_bezier.mX2 = p2.x;
|
gecko_cubic_bezier.mX2 = x2;
|
||||||
gecko_cubic_bezier.mY2 = p2.y;
|
gecko_cubic_bezier.mY2 = y2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -67,14 +67,15 @@ impl From<TimingFunction> for nsTimingFunction {
|
||||||
debug_assert!(frames.value() >= 2);
|
debug_assert!(frames.value() >= 2);
|
||||||
tf.set_as_frames(frames.value() as u32);
|
tf.set_as_frames(frames.value() as u32);
|
||||||
},
|
},
|
||||||
GenericTimingFunction::CubicBezier(p1, p2) => {
|
GenericTimingFunction::CubicBezier { x1, y1, x2, y2 } => {
|
||||||
tf.set_as_bezier(nsTimingFunction_Type::CubicBezier,
|
tf.set_as_bezier(
|
||||||
Point2D::new(p1.x.get(), p1.y.get()),
|
nsTimingFunction_Type::CubicBezier,
|
||||||
Point2D::new(p2.x.get(), p2.y.get()));
|
x1.get(), y1.get(), x2.get(), y2.get(),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
GenericTimingFunction::Keyword(keyword) => {
|
GenericTimingFunction::Keyword(keyword) => {
|
||||||
let (p1, p2) = keyword.to_bezier_points();
|
let (x1, y1, x2, y2) = keyword.to_bezier();
|
||||||
tf.set_as_bezier(keyword.into(), p1, p2)
|
tf.set_as_bezier(keyword.into(), x1, y1, x2, y2);
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
tf
|
tf
|
||||||
|
@ -114,11 +115,14 @@ impl From<nsTimingFunction> for ComputedTimingFunction {
|
||||||
GenericTimingFunction::Keyword(TimingKeyword::EaseInOut)
|
GenericTimingFunction::Keyword(TimingKeyword::EaseInOut)
|
||||||
},
|
},
|
||||||
nsTimingFunction_Type::CubicBezier => {
|
nsTimingFunction_Type::CubicBezier => {
|
||||||
GenericTimingFunction::CubicBezier(
|
unsafe {
|
||||||
TypedPoint2D::new(unsafe { function.__bindgen_anon_1.mFunc.as_ref().mX1 },
|
GenericTimingFunction::CubicBezier {
|
||||||
unsafe { function.__bindgen_anon_1.mFunc.as_ref().mY1 }),
|
x1: function.__bindgen_anon_1.mFunc.as_ref().mX1,
|
||||||
TypedPoint2D::new(unsafe { function.__bindgen_anon_1.mFunc.as_ref().mX2 },
|
y1: function.__bindgen_anon_1.mFunc.as_ref().mY1,
|
||||||
unsafe { function.__bindgen_anon_1.mFunc.as_ref().mY2 }))
|
x2: function.__bindgen_anon_1.mFunc.as_ref().mX2,
|
||||||
|
y2: function.__bindgen_anon_1.mFunc.as_ref().mY2,
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
|
|
||||||
//! Generic types for CSS values that are related to transformations.
|
//! Generic types for CSS values that are related to transformations.
|
||||||
|
|
||||||
use euclid::Point2D;
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use style_traits::{HasViewportPercentage, ToCss};
|
use style_traits::{HasViewportPercentage, ToCss};
|
||||||
use values::CSSFloat;
|
use values::CSSFloat;
|
||||||
|
@ -44,7 +43,8 @@ pub enum TimingFunction<Integer, Number> {
|
||||||
/// `linear | ease | ease-in | ease-out | ease-in-out`
|
/// `linear | ease | ease-in | ease-out | ease-in-out`
|
||||||
Keyword(TimingKeyword),
|
Keyword(TimingKeyword),
|
||||||
/// `cubic-bezier(<number>, <number>, <number>, <number>)`
|
/// `cubic-bezier(<number>, <number>, <number>, <number>)`
|
||||||
CubicBezier(Point2D<Number>, Point2D<Number>),
|
#[allow(missing_docs)]
|
||||||
|
CubicBezier { x1: Number, y1: Number, x2: Number, y2: Number },
|
||||||
/// `step-start | step-end | steps(<integer>, [ start | end ]?)`
|
/// `step-start | step-end | steps(<integer>, [ start | end ]?)`
|
||||||
Steps(Integer, StepPosition),
|
Steps(Integer, StepPosition),
|
||||||
/// `frames(<integer>)`
|
/// `frames(<integer>)`
|
||||||
|
@ -100,15 +100,15 @@ where
|
||||||
{
|
{
|
||||||
match *self {
|
match *self {
|
||||||
TimingFunction::Keyword(keyword) => keyword.to_css(dest),
|
TimingFunction::Keyword(keyword) => keyword.to_css(dest),
|
||||||
TimingFunction::CubicBezier(ref p1, ref p2) => {
|
TimingFunction::CubicBezier { ref x1, ref y1, ref x2, ref y2 } => {
|
||||||
dest.write_str("cubic-bezier(")?;
|
dest.write_str("cubic-bezier(")?;
|
||||||
p1.x.to_css(dest)?;
|
x1.to_css(dest)?;
|
||||||
dest.write_str(", ")?;
|
dest.write_str(", ")?;
|
||||||
p1.y.to_css(dest)?;
|
y1.to_css(dest)?;
|
||||||
dest.write_str(", ")?;
|
dest.write_str(", ")?;
|
||||||
p2.x.to_css(dest)?;
|
x2.to_css(dest)?;
|
||||||
dest.write_str(", ")?;
|
dest.write_str(", ")?;
|
||||||
p2.y.to_css(dest)?;
|
y2.to_css(dest)?;
|
||||||
dest.write_str(")")
|
dest.write_str(")")
|
||||||
},
|
},
|
||||||
TimingFunction::Steps(ref intervals, position) => {
|
TimingFunction::Steps(ref intervals, position) => {
|
||||||
|
@ -130,15 +130,16 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TimingKeyword {
|
impl TimingKeyword {
|
||||||
/// Returns this timing keyword as a pair of `cubic-bezier()` points.
|
/// Returns the keyword as a quadruplet of Bezier point coordinates
|
||||||
|
/// `(x1, y1, x2, y2)`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn to_bezier_points(self) -> (Point2D<CSSFloat>, Point2D<CSSFloat>) {
|
pub fn to_bezier(self) -> (CSSFloat, CSSFloat, CSSFloat, CSSFloat) {
|
||||||
match self {
|
match self {
|
||||||
TimingKeyword::Linear => (Point2D::new(0., 0.), Point2D::new(1., 1.)),
|
TimingKeyword::Linear => (0., 0., 1., 1.),
|
||||||
TimingKeyword::Ease => (Point2D::new(0.25, 0.1), Point2D::new(0.25, 1.)),
|
TimingKeyword::Ease => (0.25, 0.1, 0.25, 1.),
|
||||||
TimingKeyword::EaseIn => (Point2D::new(0.42, 0.), Point2D::new(1., 1.)),
|
TimingKeyword::EaseIn => (0.42, 0., 1., 1.),
|
||||||
TimingKeyword::EaseOut => (Point2D::new(0., 0.), Point2D::new(0.58, 1.)),
|
TimingKeyword::EaseOut => (0., 0., 0.58, 1.),
|
||||||
TimingKeyword::EaseInOut => (Point2D::new(0.42, 0.), Point2D::new(0.58, 1.)),
|
TimingKeyword::EaseInOut => (0.42, 0., 0.58, 1.),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
//! Specified types for CSS values that are related to transformations.
|
//! Specified types for CSS values that are related to transformations.
|
||||||
|
|
||||||
use cssparser::Parser;
|
use cssparser::Parser;
|
||||||
use euclid::Point2D;
|
|
||||||
use parser::{Parse, ParserContext};
|
use parser::{Parse, ParserContext};
|
||||||
use selectors::parser::SelectorParseError;
|
use selectors::parser::SelectorParseError;
|
||||||
use style_traits::{ParseError, StyleParseError};
|
use style_traits::{ParseError, StyleParseError};
|
||||||
|
@ -160,20 +159,19 @@ impl Parse for TimingFunction {
|
||||||
input.parse_nested_block(move |i| {
|
input.parse_nested_block(move |i| {
|
||||||
(match_ignore_ascii_case! { &function,
|
(match_ignore_ascii_case! { &function,
|
||||||
"cubic-bezier" => {
|
"cubic-bezier" => {
|
||||||
let p1x = Number::parse(context, i)?;
|
let x1 = Number::parse(context, i)?;
|
||||||
i.expect_comma()?;
|
i.expect_comma()?;
|
||||||
let p1y = Number::parse(context, i)?;
|
let y1 = Number::parse(context, i)?;
|
||||||
i.expect_comma()?;
|
i.expect_comma()?;
|
||||||
let p2x = Number::parse(context, i)?;
|
let x2 = Number::parse(context, i)?;
|
||||||
i.expect_comma()?;
|
i.expect_comma()?;
|
||||||
let p2y = Number::parse(context, i)?;
|
let y2 = Number::parse(context, i)?;
|
||||||
|
|
||||||
if p1x.get() < 0.0 || p1x.get() > 1.0 || p2x.get() < 0.0 || p2x.get() > 1.0 {
|
if x1.get() < 0.0 || x1.get() > 1.0 || x2.get() < 0.0 || x2.get() > 1.0 {
|
||||||
return Err(StyleParseError::UnspecifiedError.into());
|
return Err(StyleParseError::UnspecifiedError.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
let (p1, p2) = (Point2D::new(p1x, p1y), Point2D::new(p2x, p2y));
|
Ok(GenericTimingFunction::CubicBezier { x1, y1, x2, y2 })
|
||||||
Ok(GenericTimingFunction::CubicBezier(p1, p2))
|
|
||||||
},
|
},
|
||||||
"steps" => {
|
"steps" => {
|
||||||
let steps = Integer::parse_positive(context, i)?;
|
let steps = Integer::parse_positive(context, i)?;
|
||||||
|
@ -206,17 +204,13 @@ impl ToComputedValue for TimingFunction {
|
||||||
GenericTimingFunction::Keyword(keyword) => {
|
GenericTimingFunction::Keyword(keyword) => {
|
||||||
GenericTimingFunction::Keyword(keyword)
|
GenericTimingFunction::Keyword(keyword)
|
||||||
},
|
},
|
||||||
GenericTimingFunction::CubicBezier(p1, p2) => {
|
GenericTimingFunction::CubicBezier { x1, y1, x2, y2 } => {
|
||||||
GenericTimingFunction::CubicBezier(
|
GenericTimingFunction::CubicBezier {
|
||||||
Point2D::new(
|
x1: x1.to_computed_value(context),
|
||||||
p1.x.to_computed_value(context),
|
y1: y1.to_computed_value(context),
|
||||||
p1.y.to_computed_value(context),
|
x2: x2.to_computed_value(context),
|
||||||
),
|
y2: y2.to_computed_value(context),
|
||||||
Point2D::new(
|
}
|
||||||
p2.x.to_computed_value(context),
|
|
||||||
p2.y.to_computed_value(context),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
},
|
},
|
||||||
GenericTimingFunction::Steps(steps, position) => {
|
GenericTimingFunction::Steps(steps, position) => {
|
||||||
GenericTimingFunction::Steps(
|
GenericTimingFunction::Steps(
|
||||||
|
@ -238,17 +232,13 @@ impl ToComputedValue for TimingFunction {
|
||||||
GenericTimingFunction::Keyword(keyword) => {
|
GenericTimingFunction::Keyword(keyword) => {
|
||||||
GenericTimingFunction::Keyword(keyword)
|
GenericTimingFunction::Keyword(keyword)
|
||||||
},
|
},
|
||||||
GenericTimingFunction::CubicBezier(p1, p2) => {
|
GenericTimingFunction::CubicBezier { ref x1, ref y1, ref x2, ref y2 } => {
|
||||||
GenericTimingFunction::CubicBezier(
|
GenericTimingFunction::CubicBezier {
|
||||||
Point2D::new(
|
x1: Number::from_computed_value(x1),
|
||||||
Number::from_computed_value(&p1.x),
|
y1: Number::from_computed_value(y1),
|
||||||
Number::from_computed_value(&p1.y),
|
x2: Number::from_computed_value(x2),
|
||||||
),
|
y2: Number::from_computed_value(y2),
|
||||||
Point2D::new(
|
}
|
||||||
Number::from_computed_value(&p2.x),
|
|
||||||
Number::from_computed_value(&p2.y),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
},
|
},
|
||||||
GenericTimingFunction::Steps(steps, position) => {
|
GenericTimingFunction::Steps(steps, position) => {
|
||||||
GenericTimingFunction::Steps(
|
GenericTimingFunction::Steps(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue