mirror of
https://github.com/servo/servo.git
synced 2025-08-06 06:00:15 +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 context::SharedStyleContext;
|
||||
use dom::OpaqueNode;
|
||||
use euclid::Point2D;
|
||||
use font_metrics::FontMetricsProvider;
|
||||
use properties::{self, CascadeFlags, ComputedValues, ComputedValuesInner, Importance};
|
||||
use properties::animated_properties::{AnimatableLonghand, AnimatedProperty, TransitionProperty};
|
||||
|
@ -369,18 +368,10 @@ impl PropertyAnimation {
|
|||
|
||||
/// Update the given animation at a given point of progress.
|
||||
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 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 epsilon = 1. / (200. * (self.duration.seconds() as f64));
|
||||
let progress = match self.timing_function {
|
||||
GenericTimingFunction::CubicBezier(p1, p2) => {
|
||||
solve_bezier((p1, p2))
|
||||
GenericTimingFunction::CubicBezier { x1, y1, x2, y2 } => {
|
||||
Bezier::new(x1, y1, x2, y2).solve(time, epsilon)
|
||||
},
|
||||
GenericTimingFunction::Steps(steps, StepPosition::Start) => {
|
||||
(time * (steps as f64)).ceil() / (steps as f64)
|
||||
|
@ -405,7 +396,8 @@ impl PropertyAnimation {
|
|||
out
|
||||
},
|
||||
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)]
|
||||
|
||||
use euclid::Point2D;
|
||||
use values::CSSFloat;
|
||||
|
||||
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
|
||||
/// starts at 0% and ends at 100%.
|
||||
#[inline]
|
||||
pub fn new(p1: Point2D<f64>, p2: Point2D<f64>) -> Bezier {
|
||||
let cx = 3.0 * p1.x;
|
||||
let bx = 3.0 * (p2.x - p1.x) - cx;
|
||||
pub fn new(x1: CSSFloat, y1: CSSFloat, x2: CSSFloat, y2: CSSFloat) -> Bezier {
|
||||
let cx = 3. * x1 as f64;
|
||||
let bx = 3. * (x2 as f64 - x1 as f64) - cx;
|
||||
|
||||
let cy = 3.0 * p1.y;
|
||||
let by = 3.0 * (p2.y - p1.y) - cy;
|
||||
let cy = 3. * y1 as f64;
|
||||
let by = 3. * (y2 as f64 - y1 as f64) - cy;
|
||||
|
||||
Bezier {
|
||||
ax: 1.0 - cx - bx,
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
* 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/. */
|
||||
|
||||
use euclid::{Point2D, TypedPoint2D};
|
||||
use gecko_bindings::structs::{nsTimingFunction, nsTimingFunction_Type};
|
||||
use std::mem;
|
||||
use values::computed::ToComputedValue;
|
||||
|
@ -28,18 +27,19 @@ impl nsTimingFunction {
|
|||
}
|
||||
}
|
||||
|
||||
fn set_as_bezier(&mut self,
|
||||
function_type: nsTimingFunction_Type,
|
||||
p1: Point2D<f32>,
|
||||
p2: Point2D<f32>) {
|
||||
fn set_as_bezier(
|
||||
&mut self,
|
||||
function_type: nsTimingFunction_Type,
|
||||
x1: f32, y1: f32, x2: f32, y2: f32,
|
||||
) {
|
||||
self.mType = function_type;
|
||||
unsafe {
|
||||
let ref mut gecko_cubic_bezier =
|
||||
unsafe { self.__bindgen_anon_1.mFunc.as_mut() };
|
||||
gecko_cubic_bezier.mX1 = p1.x;
|
||||
gecko_cubic_bezier.mY1 = p1.y;
|
||||
gecko_cubic_bezier.mX2 = p2.x;
|
||||
gecko_cubic_bezier.mY2 = p2.y;
|
||||
gecko_cubic_bezier.mX1 = x1;
|
||||
gecko_cubic_bezier.mY1 = y1;
|
||||
gecko_cubic_bezier.mX2 = x2;
|
||||
gecko_cubic_bezier.mY2 = y2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -67,14 +67,15 @@ impl From<TimingFunction> for nsTimingFunction {
|
|||
debug_assert!(frames.value() >= 2);
|
||||
tf.set_as_frames(frames.value() as u32);
|
||||
},
|
||||
GenericTimingFunction::CubicBezier(p1, p2) => {
|
||||
tf.set_as_bezier(nsTimingFunction_Type::CubicBezier,
|
||||
Point2D::new(p1.x.get(), p1.y.get()),
|
||||
Point2D::new(p2.x.get(), p2.y.get()));
|
||||
GenericTimingFunction::CubicBezier { x1, y1, x2, y2 } => {
|
||||
tf.set_as_bezier(
|
||||
nsTimingFunction_Type::CubicBezier,
|
||||
x1.get(), y1.get(), x2.get(), y2.get(),
|
||||
);
|
||||
},
|
||||
GenericTimingFunction::Keyword(keyword) => {
|
||||
let (p1, p2) = keyword.to_bezier_points();
|
||||
tf.set_as_bezier(keyword.into(), p1, p2)
|
||||
let (x1, y1, x2, y2) = keyword.to_bezier();
|
||||
tf.set_as_bezier(keyword.into(), x1, y1, x2, y2);
|
||||
},
|
||||
}
|
||||
tf
|
||||
|
@ -114,11 +115,14 @@ impl From<nsTimingFunction> for ComputedTimingFunction {
|
|||
GenericTimingFunction::Keyword(TimingKeyword::EaseInOut)
|
||||
},
|
||||
nsTimingFunction_Type::CubicBezier => {
|
||||
GenericTimingFunction::CubicBezier(
|
||||
TypedPoint2D::new(unsafe { function.__bindgen_anon_1.mFunc.as_ref().mX1 },
|
||||
unsafe { function.__bindgen_anon_1.mFunc.as_ref().mY1 }),
|
||||
TypedPoint2D::new(unsafe { function.__bindgen_anon_1.mFunc.as_ref().mX2 },
|
||||
unsafe { function.__bindgen_anon_1.mFunc.as_ref().mY2 }))
|
||||
unsafe {
|
||||
GenericTimingFunction::CubicBezier {
|
||||
x1: function.__bindgen_anon_1.mFunc.as_ref().mX1,
|
||||
y1: function.__bindgen_anon_1.mFunc.as_ref().mY1,
|
||||
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.
|
||||
|
||||
use euclid::Point2D;
|
||||
use std::fmt;
|
||||
use style_traits::{HasViewportPercentage, ToCss};
|
||||
use values::CSSFloat;
|
||||
|
@ -44,7 +43,8 @@ pub enum TimingFunction<Integer, Number> {
|
|||
/// `linear | ease | ease-in | ease-out | ease-in-out`
|
||||
Keyword(TimingKeyword),
|
||||
/// `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 ]?)`
|
||||
Steps(Integer, StepPosition),
|
||||
/// `frames(<integer>)`
|
||||
|
@ -100,15 +100,15 @@ where
|
|||
{
|
||||
match *self {
|
||||
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(")?;
|
||||
p1.x.to_css(dest)?;
|
||||
x1.to_css(dest)?;
|
||||
dest.write_str(", ")?;
|
||||
p1.y.to_css(dest)?;
|
||||
y1.to_css(dest)?;
|
||||
dest.write_str(", ")?;
|
||||
p2.x.to_css(dest)?;
|
||||
x2.to_css(dest)?;
|
||||
dest.write_str(", ")?;
|
||||
p2.y.to_css(dest)?;
|
||||
y2.to_css(dest)?;
|
||||
dest.write_str(")")
|
||||
},
|
||||
TimingFunction::Steps(ref intervals, position) => {
|
||||
|
@ -130,15 +130,16 @@ where
|
|||
}
|
||||
|
||||
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]
|
||||
pub fn to_bezier_points(self) -> (Point2D<CSSFloat>, Point2D<CSSFloat>) {
|
||||
pub fn to_bezier(self) -> (CSSFloat, CSSFloat, CSSFloat, CSSFloat) {
|
||||
match self {
|
||||
TimingKeyword::Linear => (Point2D::new(0., 0.), Point2D::new(1., 1.)),
|
||||
TimingKeyword::Ease => (Point2D::new(0.25, 0.1), Point2D::new(0.25, 1.)),
|
||||
TimingKeyword::EaseIn => (Point2D::new(0.42, 0.), Point2D::new(1., 1.)),
|
||||
TimingKeyword::EaseOut => (Point2D::new(0., 0.), Point2D::new(0.58, 1.)),
|
||||
TimingKeyword::EaseInOut => (Point2D::new(0.42, 0.), Point2D::new(0.58, 1.)),
|
||||
TimingKeyword::Linear => (0., 0., 1., 1.),
|
||||
TimingKeyword::Ease => (0.25, 0.1, 0.25, 1.),
|
||||
TimingKeyword::EaseIn => (0.42, 0., 1., 1.),
|
||||
TimingKeyword::EaseOut => (0., 0., 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.
|
||||
|
||||
use cssparser::Parser;
|
||||
use euclid::Point2D;
|
||||
use parser::{Parse, ParserContext};
|
||||
use selectors::parser::SelectorParseError;
|
||||
use style_traits::{ParseError, StyleParseError};
|
||||
|
@ -160,20 +159,19 @@ impl Parse for TimingFunction {
|
|||
input.parse_nested_block(move |i| {
|
||||
(match_ignore_ascii_case! { &function,
|
||||
"cubic-bezier" => {
|
||||
let p1x = Number::parse(context, i)?;
|
||||
let x1 = Number::parse(context, i)?;
|
||||
i.expect_comma()?;
|
||||
let p1y = Number::parse(context, i)?;
|
||||
let y1 = Number::parse(context, i)?;
|
||||
i.expect_comma()?;
|
||||
let p2x = Number::parse(context, i)?;
|
||||
let x2 = Number::parse(context, i)?;
|
||||
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());
|
||||
}
|
||||
|
||||
let (p1, p2) = (Point2D::new(p1x, p1y), Point2D::new(p2x, p2y));
|
||||
Ok(GenericTimingFunction::CubicBezier(p1, p2))
|
||||
Ok(GenericTimingFunction::CubicBezier { x1, y1, x2, y2 })
|
||||
},
|
||||
"steps" => {
|
||||
let steps = Integer::parse_positive(context, i)?;
|
||||
|
@ -206,17 +204,13 @@ impl ToComputedValue for TimingFunction {
|
|||
GenericTimingFunction::Keyword(keyword) => {
|
||||
GenericTimingFunction::Keyword(keyword)
|
||||
},
|
||||
GenericTimingFunction::CubicBezier(p1, p2) => {
|
||||
GenericTimingFunction::CubicBezier(
|
||||
Point2D::new(
|
||||
p1.x.to_computed_value(context),
|
||||
p1.y.to_computed_value(context),
|
||||
),
|
||||
Point2D::new(
|
||||
p2.x.to_computed_value(context),
|
||||
p2.y.to_computed_value(context),
|
||||
),
|
||||
)
|
||||
GenericTimingFunction::CubicBezier { x1, y1, x2, y2 } => {
|
||||
GenericTimingFunction::CubicBezier {
|
||||
x1: x1.to_computed_value(context),
|
||||
y1: y1.to_computed_value(context),
|
||||
x2: x2.to_computed_value(context),
|
||||
y2: y2.to_computed_value(context),
|
||||
}
|
||||
},
|
||||
GenericTimingFunction::Steps(steps, position) => {
|
||||
GenericTimingFunction::Steps(
|
||||
|
@ -238,17 +232,13 @@ impl ToComputedValue for TimingFunction {
|
|||
GenericTimingFunction::Keyword(keyword) => {
|
||||
GenericTimingFunction::Keyword(keyword)
|
||||
},
|
||||
GenericTimingFunction::CubicBezier(p1, p2) => {
|
||||
GenericTimingFunction::CubicBezier(
|
||||
Point2D::new(
|
||||
Number::from_computed_value(&p1.x),
|
||||
Number::from_computed_value(&p1.y),
|
||||
),
|
||||
Point2D::new(
|
||||
Number::from_computed_value(&p2.x),
|
||||
Number::from_computed_value(&p2.y),
|
||||
),
|
||||
)
|
||||
GenericTimingFunction::CubicBezier { ref x1, ref y1, ref x2, ref y2 } => {
|
||||
GenericTimingFunction::CubicBezier {
|
||||
x1: Number::from_computed_value(x1),
|
||||
y1: Number::from_computed_value(y1),
|
||||
x2: Number::from_computed_value(x2),
|
||||
y2: Number::from_computed_value(y2),
|
||||
}
|
||||
},
|
||||
GenericTimingFunction::Steps(steps, position) => {
|
||||
GenericTimingFunction::Steps(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue