mirror of
https://github.com/servo/servo.git
synced 2025-08-05 13:40:08 +01:00
Auto merge of #13163 - Manishearth:conditional-compilation, r=bholley
Use conditional compilation for stylo properties; output unimplemented logs for all properties Till now we were only emitting unimplemented property logs for properties which servo implements but stylo doesn't. This list is getting smaller, and we really should be emitting this for any unexpected property we encounter. I also made it so that longhands which stylo does not implement will not be compiled in stylo builds; instead of what we currently do, which is to parse them and then basically ignore the result. There are still a few exceptions -- we generate stubs for properties that are parts of shorthands because otherwise we'd have to add fiddly conditional compilation to the shorthand code. r? @bholley cc @emilio <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/13163) <!-- Reviewable:end -->
This commit is contained in:
commit
58205f1a78
12 changed files with 279 additions and 234 deletions
|
@ -468,39 +468,70 @@ impl Debug for ${style_struct.gecko_struct_name} {
|
||||||
|
|
||||||
<%def name="raw_impl_trait(style_struct, skip_longhands='', skip_additionals='')">
|
<%def name="raw_impl_trait(style_struct, skip_longhands='', skip_additionals='')">
|
||||||
<%
|
<%
|
||||||
longhands = [x for x in style_struct.longhands
|
longhands = [x for x in style_struct.longhands
|
||||||
if not (skip_longhands == "*" or x.name in skip_longhands.split())]
|
if not (skip_longhands == "*" or x.name in skip_longhands.split())]
|
||||||
|
|
||||||
#
|
#
|
||||||
# Make a list of types we can't auto-generate.
|
# Make a list of types we can't auto-generate.
|
||||||
#
|
#
|
||||||
force_stub = [];
|
force_stub = [];
|
||||||
# These are currently being shuffled to a different style struct on the gecko side.
|
# These are currently being shuffled to a different style struct on the gecko side.
|
||||||
force_stub += ["backface-visibility", "transform-box", "transform-style"]
|
force_stub += ["backface-visibility", "transform-box", "transform-style"]
|
||||||
# These live in an nsFont member in Gecko. Should be straightforward to do manually.
|
# These live in an nsFont member in Gecko. Should be straightforward to do manually.
|
||||||
force_stub += ["font-kerning", "font-stretch", "font-variant"]
|
force_stub += ["font-kerning", "font-stretch", "font-variant"]
|
||||||
# These have unusual representations in gecko.
|
# These have unusual representations in gecko.
|
||||||
force_stub += ["list-style-type", "text-overflow"]
|
force_stub += ["list-style-type", "text-overflow"]
|
||||||
# In a nsTArray, have to be done manually, but probably not too much work
|
# In a nsTArray, have to be done manually, but probably not too much work
|
||||||
# (the "filling them", not the "making them work")
|
# (the "filling them", not the "making them work")
|
||||||
force_stub += ["animation-name", "animation-duration",
|
force_stub += ["animation-name", "animation-duration",
|
||||||
"animation-timing-function", "animation-iteration-count",
|
"animation-timing-function", "animation-iteration-count",
|
||||||
"animation-direction", "animation-play-state",
|
"animation-direction", "animation-play-state",
|
||||||
"animation-fill-mode", "animation-delay"]
|
"animation-fill-mode", "animation-delay"]
|
||||||
|
|
||||||
# Types used with predefined_type()-defined properties that we can auto-generate.
|
# These are part of shorthands so we must include them in stylo builds,
|
||||||
predefined_types = {
|
# but we haven't implemented the stylo glue for the longhand
|
||||||
|
# so we generate a stub
|
||||||
|
force_stub += ["list-style-image", # box
|
||||||
|
"flex-basis", # position
|
||||||
|
|
||||||
|
# transition
|
||||||
|
"transition-duration", "transition-timing-function",
|
||||||
|
"transition-property", "transition-delay",
|
||||||
|
|
||||||
|
"background-size", # background
|
||||||
|
"column-count", # column
|
||||||
|
]
|
||||||
|
|
||||||
|
# Types used with predefined_type()-defined properties that we can auto-generate.
|
||||||
|
predefined_types = {
|
||||||
"LengthOrPercentage": impl_style_coord,
|
"LengthOrPercentage": impl_style_coord,
|
||||||
"LengthOrPercentageOrAuto": impl_style_coord,
|
"LengthOrPercentageOrAuto": impl_style_coord,
|
||||||
"LengthOrPercentageOrNone": impl_style_coord,
|
"LengthOrPercentageOrNone": impl_style_coord,
|
||||||
"Number": impl_simple,
|
"Number": impl_simple,
|
||||||
"Opacity": impl_simple,
|
"Opacity": impl_simple,
|
||||||
}
|
}
|
||||||
|
|
||||||
keyword_longhands = [x for x in longhands if x.keyword and not x.name in force_stub]
|
keyword_longhands = [x for x in longhands if x.keyword and not x.name in force_stub]
|
||||||
predefined_longhands = [x for x in longhands
|
predefined_longhands = [x for x in longhands
|
||||||
if x.predefined_type in predefined_types and not x.name in force_stub]
|
if x.predefined_type in predefined_types and not x.name in force_stub]
|
||||||
stub_longhands = [x for x in longhands if x not in keyword_longhands + predefined_longhands]
|
stub_longhands = [x for x in longhands if x not in keyword_longhands + predefined_longhands]
|
||||||
|
|
||||||
|
# If one of the longhands is not handled
|
||||||
|
# by either:
|
||||||
|
# - being a keyword
|
||||||
|
# - being a predefined longhand
|
||||||
|
# - being a longhand with manual glue code (i.e. in skip_longhands)
|
||||||
|
# - being generated as a stub
|
||||||
|
#
|
||||||
|
# then we raise an error here.
|
||||||
|
#
|
||||||
|
# If you hit this error, please add `product="servo"` to the longhand.
|
||||||
|
# In case the longhand is used in a shorthand, add it to the force_stub
|
||||||
|
# list above.
|
||||||
|
for stub in stub_longhands:
|
||||||
|
if stub.name not in force_stub:
|
||||||
|
raise Exception("Don't know what to do with longhand %s in style struct %s"
|
||||||
|
% (stub.name,style_struct. gecko_struct_name))
|
||||||
%>
|
%>
|
||||||
impl ${style_struct.gecko_struct_name} {
|
impl ${style_struct.gecko_struct_name} {
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -9,18 +9,12 @@ use properties::PropertyDeclaration;
|
||||||
use properties::longhands;
|
use properties::longhands;
|
||||||
use properties::longhands::background_position::computed_value::T as BackgroundPosition;
|
use properties::longhands::background_position::computed_value::T as BackgroundPosition;
|
||||||
use properties::longhands::background_size::computed_value::T as BackgroundSize;
|
use properties::longhands::background_size::computed_value::T as BackgroundSize;
|
||||||
use properties::longhands::border_spacing::computed_value::T as BorderSpacing;
|
|
||||||
use properties::longhands::clip::computed_value::ClipRect;
|
|
||||||
use properties::longhands::font_weight::computed_value::T as FontWeight;
|
use properties::longhands::font_weight::computed_value::T as FontWeight;
|
||||||
use properties::longhands::line_height::computed_value::T as LineHeight;
|
use properties::longhands::line_height::computed_value::T as LineHeight;
|
||||||
use properties::longhands::text_shadow::computed_value::T as TextShadowList;
|
use properties::longhands::text_shadow::computed_value::T as TextShadowList;
|
||||||
use properties::longhands::text_shadow::computed_value::TextShadow;
|
use properties::longhands::text_shadow::computed_value::TextShadow;
|
||||||
use properties::longhands::box_shadow::computed_value::T as BoxShadowList;
|
use properties::longhands::box_shadow::computed_value::T as BoxShadowList;
|
||||||
use properties::longhands::box_shadow::single_value::computed_value::T as BoxShadow;
|
use properties::longhands::box_shadow::single_value::computed_value::T as BoxShadow;
|
||||||
use properties::longhands::transform::computed_value::ComputedMatrix;
|
|
||||||
use properties::longhands::transform::computed_value::ComputedOperation as TransformOperation;
|
|
||||||
use properties::longhands::transform::computed_value::T as TransformList;
|
|
||||||
use properties::longhands::transform_origin::computed_value::T as TransformOrigin;
|
|
||||||
use properties::longhands::vertical_align::computed_value::T as VerticalAlign;
|
use properties::longhands::vertical_align::computed_value::T as VerticalAlign;
|
||||||
use properties::longhands::visibility::computed_value::T as Visibility;
|
use properties::longhands::visibility::computed_value::T as Visibility;
|
||||||
use properties::longhands::z_index::computed_value::T as ZIndex;
|
use properties::longhands::z_index::computed_value::T as ZIndex;
|
||||||
|
@ -32,6 +26,8 @@ use values::computed::{BorderRadiusSize, LengthOrNone};
|
||||||
use values::computed::{CalcLengthOrPercentage, LengthOrPercentage};
|
use values::computed::{CalcLengthOrPercentage, LengthOrPercentage};
|
||||||
use values::computed::position::Position;
|
use values::computed::position::Position;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// NB: This needs to be here because it needs all the longhands generated
|
// NB: This needs to be here because it needs all the longhands generated
|
||||||
// beforehand.
|
// beforehand.
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||||
|
@ -296,18 +292,6 @@ impl Interpolate for VerticalAlign {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://drafts.csswg.org/css-transitions/#animtype-simple-list
|
|
||||||
impl Interpolate for BorderSpacing {
|
|
||||||
#[inline]
|
|
||||||
fn interpolate(&self, other: &Self, time: f64) -> Result<Self, ()> {
|
|
||||||
Ok(BorderSpacing {
|
|
||||||
horizontal: try!(self.horizontal.interpolate(&other.horizontal, time)),
|
|
||||||
vertical: try!(self.vertical.interpolate(&other.vertical, time)),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Interpolate for BackgroundSize {
|
impl Interpolate for BackgroundSize {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn interpolate(&self, other: &Self, time: f64) -> Result<Self, ()> {
|
fn interpolate(&self, other: &Self, time: f64) -> Result<Self, ()> {
|
||||||
|
@ -492,19 +476,6 @@ impl Interpolate for FontWeight {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://drafts.csswg.org/css-transitions/#animtype-rect
|
|
||||||
impl Interpolate for ClipRect {
|
|
||||||
#[inline]
|
|
||||||
fn interpolate(&self, other: &Self, time: f64) -> Result<Self, ()> {
|
|
||||||
Ok(ClipRect {
|
|
||||||
top: try!(self.top.interpolate(&other.top, time)),
|
|
||||||
right: try!(self.right.interpolate(&other.right, time)),
|
|
||||||
bottom: try!(self.bottom.interpolate(&other.bottom, time)),
|
|
||||||
left: try!(self.left.interpolate(&other.left, time)),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// https://drafts.csswg.org/css-transitions/#animtype-simple-list
|
/// https://drafts.csswg.org/css-transitions/#animtype-simple-list
|
||||||
impl Interpolate for Position {
|
impl Interpolate for Position {
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -573,138 +544,6 @@ impl Interpolate for TextShadowList {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check if it's possible to do a direct numerical interpolation
|
|
||||||
/// between these two transform lists.
|
|
||||||
/// http://dev.w3.org/csswg/css-transforms/#transform-transform-animation
|
|
||||||
fn can_interpolate_list(from_list: &[TransformOperation],
|
|
||||||
to_list: &[TransformOperation]) -> bool {
|
|
||||||
// Lists must be equal length
|
|
||||||
if from_list.len() != to_list.len() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Each transform operation must match primitive type in other list
|
|
||||||
for (from, to) in from_list.iter().zip(to_list) {
|
|
||||||
match (from, to) {
|
|
||||||
(&TransformOperation::Matrix(..), &TransformOperation::Matrix(..)) |
|
|
||||||
(&TransformOperation::Skew(..), &TransformOperation::Skew(..)) |
|
|
||||||
(&TransformOperation::Translate(..), &TransformOperation::Translate(..)) |
|
|
||||||
(&TransformOperation::Scale(..), &TransformOperation::Scale(..)) |
|
|
||||||
(&TransformOperation::Rotate(..), &TransformOperation::Rotate(..)) |
|
|
||||||
(&TransformOperation::Perspective(..), &TransformOperation::Perspective(..)) => {}
|
|
||||||
_ => {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Interpolate two transform lists.
|
|
||||||
/// http://dev.w3.org/csswg/css-transforms/#interpolation-of-transforms
|
|
||||||
fn interpolate_transform_list(from_list: &[TransformOperation],
|
|
||||||
to_list: &[TransformOperation],
|
|
||||||
time: f64) -> TransformList {
|
|
||||||
let mut result = vec![];
|
|
||||||
|
|
||||||
if can_interpolate_list(from_list, to_list) {
|
|
||||||
for (from, to) in from_list.iter().zip(to_list) {
|
|
||||||
match (from, to) {
|
|
||||||
(&TransformOperation::Matrix(from),
|
|
||||||
&TransformOperation::Matrix(_to)) => {
|
|
||||||
// TODO(gw): Implement matrix decomposition and interpolation
|
|
||||||
result.push(TransformOperation::Matrix(from));
|
|
||||||
}
|
|
||||||
(&TransformOperation::Skew(fx, fy),
|
|
||||||
&TransformOperation::Skew(tx, ty)) => {
|
|
||||||
let ix = fx.interpolate(&tx, time).unwrap();
|
|
||||||
let iy = fy.interpolate(&ty, time).unwrap();
|
|
||||||
result.push(TransformOperation::Skew(ix, iy));
|
|
||||||
}
|
|
||||||
(&TransformOperation::Translate(fx, fy, fz),
|
|
||||||
&TransformOperation::Translate(tx, ty, tz)) => {
|
|
||||||
let ix = fx.interpolate(&tx, time).unwrap();
|
|
||||||
let iy = fy.interpolate(&ty, time).unwrap();
|
|
||||||
let iz = fz.interpolate(&tz, time).unwrap();
|
|
||||||
result.push(TransformOperation::Translate(ix, iy, iz));
|
|
||||||
}
|
|
||||||
(&TransformOperation::Scale(fx, fy, fz),
|
|
||||||
&TransformOperation::Scale(tx, ty, tz)) => {
|
|
||||||
let ix = fx.interpolate(&tx, time).unwrap();
|
|
||||||
let iy = fy.interpolate(&ty, time).unwrap();
|
|
||||||
let iz = fz.interpolate(&tz, time).unwrap();
|
|
||||||
result.push(TransformOperation::Scale(ix, iy, iz));
|
|
||||||
}
|
|
||||||
(&TransformOperation::Rotate(fx, fy, fz, fa),
|
|
||||||
&TransformOperation::Rotate(tx, ty, tz, ta)) => {
|
|
||||||
let norm_f = ((fx * fx) + (fy * fy) + (fz * fz)).sqrt();
|
|
||||||
let norm_t = ((tx * tx) + (ty * ty) + (tz * tz)).sqrt();
|
|
||||||
let (fx, fy, fz) = (fx / norm_f, fy / norm_f, fz / norm_f);
|
|
||||||
let (tx, ty, tz) = (tx / norm_t, ty / norm_t, tz / norm_t);
|
|
||||||
if fx == tx && fy == ty && fz == tz {
|
|
||||||
let ia = fa.interpolate(&ta, time).unwrap();
|
|
||||||
result.push(TransformOperation::Rotate(fx, fy, fz, ia));
|
|
||||||
} else {
|
|
||||||
// TODO(gw): Implement matrix decomposition and interpolation
|
|
||||||
result.push(TransformOperation::Rotate(fx, fy, fz, fa));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
(&TransformOperation::Perspective(fd),
|
|
||||||
&TransformOperation::Perspective(_td)) => {
|
|
||||||
// TODO(gw): Implement matrix decomposition and interpolation
|
|
||||||
result.push(TransformOperation::Perspective(fd));
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
// This should be unreachable due to the can_interpolate_list() call.
|
|
||||||
unreachable!();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// TODO(gw): Implement matrix decomposition and interpolation
|
|
||||||
result.extend_from_slice(from_list);
|
|
||||||
}
|
|
||||||
|
|
||||||
TransformList(Some(result))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Build an equivalent 'identity transform function list' based
|
|
||||||
/// on an existing transform list.
|
|
||||||
/// http://dev.w3.org/csswg/css-transforms/#none-transform-animation
|
|
||||||
fn build_identity_transform_list(list: &[TransformOperation]) -> Vec<TransformOperation> {
|
|
||||||
let mut result = vec!();
|
|
||||||
|
|
||||||
for operation in list {
|
|
||||||
match *operation {
|
|
||||||
TransformOperation::Matrix(..) => {
|
|
||||||
let identity = ComputedMatrix::identity();
|
|
||||||
result.push(TransformOperation::Matrix(identity));
|
|
||||||
}
|
|
||||||
TransformOperation::Skew(..) => {
|
|
||||||
result.push(TransformOperation::Skew(Angle(0.0), Angle(0.0)));
|
|
||||||
}
|
|
||||||
TransformOperation::Translate(..) => {
|
|
||||||
result.push(TransformOperation::Translate(LengthOrPercentage::zero(),
|
|
||||||
LengthOrPercentage::zero(),
|
|
||||||
Au(0)));
|
|
||||||
}
|
|
||||||
TransformOperation::Scale(..) => {
|
|
||||||
result.push(TransformOperation::Scale(1.0, 1.0, 1.0));
|
|
||||||
}
|
|
||||||
TransformOperation::Rotate(..) => {
|
|
||||||
result.push(TransformOperation::Rotate(0.0, 0.0, 1.0, Angle(0.0)));
|
|
||||||
}
|
|
||||||
TransformOperation::Perspective(..) => {
|
|
||||||
// http://dev.w3.org/csswg/css-transforms/#identity-transform-function
|
|
||||||
let identity = ComputedMatrix::identity();
|
|
||||||
result.push(TransformOperation::Matrix(identity));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
result
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Interpolate for BoxShadowList {
|
impl Interpolate for BoxShadowList {
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -780,42 +619,173 @@ impl Interpolate for LengthOrNone {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Interpolate for TransformOrigin {
|
% if product == "servo":
|
||||||
fn interpolate(&self, other: &Self, time: f64) -> Result<Self, ()> {
|
use properties::longhands::transform::computed_value::ComputedMatrix;
|
||||||
Ok(TransformOrigin {
|
use properties::longhands::transform::computed_value::ComputedOperation as TransformOperation;
|
||||||
horizontal: try!(self.horizontal.interpolate(&other.horizontal, time)),
|
use properties::longhands::transform::computed_value::T as TransformList;
|
||||||
vertical: try!(self.vertical.interpolate(&other.vertical, time)),
|
|
||||||
depth: try!(self.depth.interpolate(&other.depth, time)),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// https://drafts.csswg.org/css-transforms/#interpolation-of-transforms
|
/// Check if it's possible to do a direct numerical interpolation
|
||||||
impl Interpolate for TransformList {
|
/// between these two transform lists.
|
||||||
#[inline]
|
/// http://dev.w3.org/csswg/css-transforms/#transform-transform-animation
|
||||||
fn interpolate(&self, other: &TransformList, time: f64) -> Result<Self, ()> {
|
fn can_interpolate_list(from_list: &[TransformOperation],
|
||||||
// http://dev.w3.org/csswg/css-transforms/#interpolation-of-transforms
|
to_list: &[TransformOperation]) -> bool {
|
||||||
let result = match (&self.0, &other.0) {
|
// Lists must be equal length
|
||||||
(&Some(ref from_list), &Some(ref to_list)) => {
|
if from_list.len() != to_list.len() {
|
||||||
// Two lists of transforms
|
return false;
|
||||||
interpolate_transform_list(from_list, &to_list, time)
|
}
|
||||||
}
|
|
||||||
(&Some(ref from_list), &None) => {
|
|
||||||
// http://dev.w3.org/csswg/css-transforms/#none-transform-animation
|
|
||||||
let to_list = build_identity_transform_list(from_list);
|
|
||||||
interpolate_transform_list(from_list, &to_list, time)
|
|
||||||
}
|
|
||||||
(&None, &Some(ref to_list)) => {
|
|
||||||
// http://dev.w3.org/csswg/css-transforms/#none-transform-animation
|
|
||||||
let from_list = build_identity_transform_list(to_list);
|
|
||||||
interpolate_transform_list(&from_list, to_list, time)
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
// http://dev.w3.org/csswg/css-transforms/#none-none-animation
|
|
||||||
TransformList(None)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(result)
|
// Each transform operation must match primitive type in other list
|
||||||
|
for (from, to) in from_list.iter().zip(to_list) {
|
||||||
|
match (from, to) {
|
||||||
|
(&TransformOperation::Matrix(..), &TransformOperation::Matrix(..)) |
|
||||||
|
(&TransformOperation::Skew(..), &TransformOperation::Skew(..)) |
|
||||||
|
(&TransformOperation::Translate(..), &TransformOperation::Translate(..)) |
|
||||||
|
(&TransformOperation::Scale(..), &TransformOperation::Scale(..)) |
|
||||||
|
(&TransformOperation::Rotate(..), &TransformOperation::Rotate(..)) |
|
||||||
|
(&TransformOperation::Perspective(..), &TransformOperation::Perspective(..)) => {}
|
||||||
|
_ => {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
true
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
/// Build an equivalent 'identity transform function list' based
|
||||||
|
/// on an existing transform list.
|
||||||
|
/// http://dev.w3.org/csswg/css-transforms/#none-transform-animation
|
||||||
|
fn build_identity_transform_list(list: &[TransformOperation]) -> Vec<TransformOperation> {
|
||||||
|
let mut result = vec!();
|
||||||
|
|
||||||
|
for operation in list {
|
||||||
|
match *operation {
|
||||||
|
TransformOperation::Matrix(..) => {
|
||||||
|
let identity = ComputedMatrix::identity();
|
||||||
|
result.push(TransformOperation::Matrix(identity));
|
||||||
|
}
|
||||||
|
TransformOperation::Skew(..) => {
|
||||||
|
result.push(TransformOperation::Skew(Angle(0.0), Angle(0.0)));
|
||||||
|
}
|
||||||
|
TransformOperation::Translate(..) => {
|
||||||
|
result.push(TransformOperation::Translate(LengthOrPercentage::zero(),
|
||||||
|
LengthOrPercentage::zero(),
|
||||||
|
Au(0)));
|
||||||
|
}
|
||||||
|
TransformOperation::Scale(..) => {
|
||||||
|
result.push(TransformOperation::Scale(1.0, 1.0, 1.0));
|
||||||
|
}
|
||||||
|
TransformOperation::Rotate(..) => {
|
||||||
|
result.push(TransformOperation::Rotate(0.0, 0.0, 1.0, Angle(0.0)));
|
||||||
|
}
|
||||||
|
TransformOperation::Perspective(..) => {
|
||||||
|
// http://dev.w3.org/csswg/css-transforms/#identity-transform-function
|
||||||
|
let identity = ComputedMatrix::identity();
|
||||||
|
result.push(TransformOperation::Matrix(identity));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Interpolate two transform lists.
|
||||||
|
/// http://dev.w3.org/csswg/css-transforms/#interpolation-of-transforms
|
||||||
|
fn interpolate_transform_list(from_list: &[TransformOperation],
|
||||||
|
to_list: &[TransformOperation],
|
||||||
|
time: f64) -> TransformList {
|
||||||
|
let mut result = vec![];
|
||||||
|
|
||||||
|
if can_interpolate_list(from_list, to_list) {
|
||||||
|
for (from, to) in from_list.iter().zip(to_list) {
|
||||||
|
match (from, to) {
|
||||||
|
(&TransformOperation::Matrix(from),
|
||||||
|
&TransformOperation::Matrix(_to)) => {
|
||||||
|
// TODO(gw): Implement matrix decomposition and interpolation
|
||||||
|
result.push(TransformOperation::Matrix(from));
|
||||||
|
}
|
||||||
|
(&TransformOperation::Skew(fx, fy),
|
||||||
|
&TransformOperation::Skew(tx, ty)) => {
|
||||||
|
let ix = fx.interpolate(&tx, time).unwrap();
|
||||||
|
let iy = fy.interpolate(&ty, time).unwrap();
|
||||||
|
result.push(TransformOperation::Skew(ix, iy));
|
||||||
|
}
|
||||||
|
(&TransformOperation::Translate(fx, fy, fz),
|
||||||
|
&TransformOperation::Translate(tx, ty, tz)) => {
|
||||||
|
let ix = fx.interpolate(&tx, time).unwrap();
|
||||||
|
let iy = fy.interpolate(&ty, time).unwrap();
|
||||||
|
let iz = fz.interpolate(&tz, time).unwrap();
|
||||||
|
result.push(TransformOperation::Translate(ix, iy, iz));
|
||||||
|
}
|
||||||
|
(&TransformOperation::Scale(fx, fy, fz),
|
||||||
|
&TransformOperation::Scale(tx, ty, tz)) => {
|
||||||
|
let ix = fx.interpolate(&tx, time).unwrap();
|
||||||
|
let iy = fy.interpolate(&ty, time).unwrap();
|
||||||
|
let iz = fz.interpolate(&tz, time).unwrap();
|
||||||
|
result.push(TransformOperation::Scale(ix, iy, iz));
|
||||||
|
}
|
||||||
|
(&TransformOperation::Rotate(fx, fy, fz, fa),
|
||||||
|
&TransformOperation::Rotate(tx, ty, tz, ta)) => {
|
||||||
|
let norm_f = ((fx * fx) + (fy * fy) + (fz * fz)).sqrt();
|
||||||
|
let norm_t = ((tx * tx) + (ty * ty) + (tz * tz)).sqrt();
|
||||||
|
let (fx, fy, fz) = (fx / norm_f, fy / norm_f, fz / norm_f);
|
||||||
|
let (tx, ty, tz) = (tx / norm_t, ty / norm_t, tz / norm_t);
|
||||||
|
if fx == tx && fy == ty && fz == tz {
|
||||||
|
let ia = fa.interpolate(&ta, time).unwrap();
|
||||||
|
result.push(TransformOperation::Rotate(fx, fy, fz, ia));
|
||||||
|
} else {
|
||||||
|
// TODO(gw): Implement matrix decomposition and interpolation
|
||||||
|
result.push(TransformOperation::Rotate(fx, fy, fz, fa));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(&TransformOperation::Perspective(fd),
|
||||||
|
&TransformOperation::Perspective(_td)) => {
|
||||||
|
// TODO(gw): Implement matrix decomposition and interpolation
|
||||||
|
result.push(TransformOperation::Perspective(fd));
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
// This should be unreachable due to the can_interpolate_list() call.
|
||||||
|
unreachable!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// TODO(gw): Implement matrix decomposition and interpolation
|
||||||
|
result.extend_from_slice(from_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
TransformList(Some(result))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// https://drafts.csswg.org/css-transforms/#interpolation-of-transforms
|
||||||
|
impl Interpolate for TransformList {
|
||||||
|
#[inline]
|
||||||
|
fn interpolate(&self, other: &TransformList, time: f64) -> Result<Self, ()> {
|
||||||
|
// http://dev.w3.org/csswg/css-transforms/#interpolation-of-transforms
|
||||||
|
let result = match (&self.0, &other.0) {
|
||||||
|
(&Some(ref from_list), &Some(ref to_list)) => {
|
||||||
|
// Two lists of transforms
|
||||||
|
interpolate_transform_list(from_list, &to_list, time)
|
||||||
|
}
|
||||||
|
(&Some(ref from_list), &None) => {
|
||||||
|
// http://dev.w3.org/csswg/css-transforms/#none-transform-animation
|
||||||
|
let to_list = build_identity_transform_list(from_list);
|
||||||
|
interpolate_transform_list(from_list, &to_list, time)
|
||||||
|
}
|
||||||
|
(&None, &Some(ref to_list)) => {
|
||||||
|
// http://dev.w3.org/csswg/css-transforms/#none-transform-animation
|
||||||
|
let from_list = build_identity_transform_list(to_list);
|
||||||
|
interpolate_transform_list(&from_list, to_list, time)
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
// http://dev.w3.org/csswg/css-transforms/#none-none-animation
|
||||||
|
TransformList(None)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
% endif
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -153,7 +153,7 @@
|
||||||
</%helpers:longhand>
|
</%helpers:longhand>
|
||||||
|
|
||||||
// FIXME: This prop should be animatable.
|
// FIXME: This prop should be animatable.
|
||||||
<%helpers:longhand name="column-gap" experimental="True" animatable="False">
|
<%helpers:longhand name="column-gap" experimental="True" products="servo" animatable="False">
|
||||||
use cssparser::ToCss;
|
use cssparser::ToCss;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use values::LocalToCss;
|
use values::LocalToCss;
|
||||||
|
|
|
@ -173,7 +173,7 @@
|
||||||
}
|
}
|
||||||
</%helpers:longhand>
|
</%helpers:longhand>
|
||||||
|
|
||||||
<%helpers:longhand name="counter-increment" animatable="False">
|
<%helpers:longhand name="counter-increment" products="servo" animatable="False">
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use super::content;
|
use super::content;
|
||||||
use values::NoViewportPercentage;
|
use values::NoViewportPercentage;
|
||||||
|
@ -245,7 +245,7 @@
|
||||||
}
|
}
|
||||||
</%helpers:longhand>
|
</%helpers:longhand>
|
||||||
|
|
||||||
<%helpers:longhand name="counter-reset" animatable="False">
|
<%helpers:longhand name="counter-reset" products="servo" animatable="False">
|
||||||
pub use super::counter_increment::{SpecifiedValue, computed_value, get_initial_value};
|
pub use super::counter_increment::{SpecifiedValue, computed_value, get_initial_value};
|
||||||
use super::counter_increment::{parse_common};
|
use super::counter_increment::{parse_common};
|
||||||
|
|
||||||
|
|
|
@ -175,7 +175,7 @@ ${helpers.predefined_type("opacity",
|
||||||
</%helpers:vector_longhand>
|
</%helpers:vector_longhand>
|
||||||
|
|
||||||
// FIXME: This prop should be animatable
|
// FIXME: This prop should be animatable
|
||||||
<%helpers:longhand name="clip" animatable="False">
|
<%helpers:longhand name="clip" products="servo" animatable="False">
|
||||||
use cssparser::ToCss;
|
use cssparser::ToCss;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use values::LocalToCss;
|
use values::LocalToCss;
|
||||||
|
@ -185,6 +185,7 @@ ${helpers.predefined_type("opacity",
|
||||||
|
|
||||||
pub mod computed_value {
|
pub mod computed_value {
|
||||||
use app_units::Au;
|
use app_units::Au;
|
||||||
|
use properties::animated_properties::Interpolate;
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq, Copy, Debug)]
|
#[derive(Clone, PartialEq, Eq, Copy, Debug)]
|
||||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
|
@ -198,6 +199,20 @@ ${helpers.predefined_type("opacity",
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
pub struct T(pub Option<ClipRect>);
|
pub struct T(pub Option<ClipRect>);
|
||||||
|
|
||||||
|
|
||||||
|
/// https://drafts.csswg.org/css-transitions/#animtype-rect
|
||||||
|
impl Interpolate for ClipRect {
|
||||||
|
#[inline]
|
||||||
|
fn interpolate(&self, other: &Self, time: f64) -> Result<Self, ()> {
|
||||||
|
Ok(ClipRect {
|
||||||
|
top: try!(self.top.interpolate(&other.top, time)),
|
||||||
|
right: try!(self.right.interpolate(&other.right, time)),
|
||||||
|
bottom: try!(self.bottom.interpolate(&other.bottom, time)),
|
||||||
|
left: try!(self.left.interpolate(&other.left, time)),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToCss for computed_value::T {
|
impl ToCss for computed_value::T {
|
||||||
|
@ -364,7 +379,7 @@ ${helpers.predefined_type("opacity",
|
||||||
</%helpers:longhand>
|
</%helpers:longhand>
|
||||||
|
|
||||||
// FIXME: This prop should be animatable
|
// FIXME: This prop should be animatable
|
||||||
<%helpers:longhand name="filter" animatable="False">
|
<%helpers:longhand name="filter" products="servo" animatable="False">
|
||||||
//pub use self::computed_value::T as SpecifiedValue;
|
//pub use self::computed_value::T as SpecifiedValue;
|
||||||
use cssparser::ToCss;
|
use cssparser::ToCss;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
@ -617,7 +632,7 @@ ${helpers.predefined_type("opacity",
|
||||||
}
|
}
|
||||||
</%helpers:longhand>
|
</%helpers:longhand>
|
||||||
|
|
||||||
<%helpers:longhand name="transform" animatable="True">
|
<%helpers:longhand name="transform" products="servo" animatable="True">
|
||||||
use app_units::Au;
|
use app_units::Au;
|
||||||
use values::CSSFloat;
|
use values::CSSFloat;
|
||||||
use values::HasViewportPercentage;
|
use values::HasViewportPercentage;
|
||||||
|
@ -1196,7 +1211,7 @@ ${helpers.single_keyword("transform-style",
|
||||||
"auto flat preserve-3d",
|
"auto flat preserve-3d",
|
||||||
animatable=False)}
|
animatable=False)}
|
||||||
|
|
||||||
<%helpers:longhand name="transform-origin" animatable="True">
|
<%helpers:longhand name="transform-origin" products="servo" animatable="True">
|
||||||
use app_units::Au;
|
use app_units::Au;
|
||||||
use values::LocalToCss;
|
use values::LocalToCss;
|
||||||
use values::HasViewportPercentage;
|
use values::HasViewportPercentage;
|
||||||
|
@ -1206,6 +1221,7 @@ ${helpers.single_keyword("transform-style",
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
pub mod computed_value {
|
pub mod computed_value {
|
||||||
|
use properties::animated_properties::Interpolate;
|
||||||
use values::computed::{Length, LengthOrPercentage};
|
use values::computed::{Length, LengthOrPercentage};
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||||
|
@ -1215,6 +1231,16 @@ ${helpers.single_keyword("transform-style",
|
||||||
pub vertical: LengthOrPercentage,
|
pub vertical: LengthOrPercentage,
|
||||||
pub depth: Length,
|
pub depth: Length,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Interpolate for T {
|
||||||
|
fn interpolate(&self, other: &Self, time: f64) -> Result<Self, ()> {
|
||||||
|
Ok(T {
|
||||||
|
horizontal: try!(self.horizontal.interpolate(&other.horizontal, time)),
|
||||||
|
vertical: try!(self.vertical.interpolate(&other.vertical, time)),
|
||||||
|
depth: try!(self.depth.interpolate(&other.depth, time)),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HasViewportPercentage for SpecifiedValue {
|
impl HasViewportPercentage for SpecifiedValue {
|
||||||
|
@ -1288,10 +1314,11 @@ ${helpers.single_keyword("transform-style",
|
||||||
${helpers.predefined_type("perspective",
|
${helpers.predefined_type("perspective",
|
||||||
"LengthOrNone",
|
"LengthOrNone",
|
||||||
"computed::LengthOrNone::None",
|
"computed::LengthOrNone::None",
|
||||||
|
products="servo",
|
||||||
animatable=True)}
|
animatable=True)}
|
||||||
|
|
||||||
// FIXME: This prop should be animatable
|
// FIXME: This prop should be animatable
|
||||||
<%helpers:longhand name="perspective-origin" animatable="False">
|
<%helpers:longhand name="perspective-origin" products="servo" animatable="False">
|
||||||
use values::HasViewportPercentage;
|
use values::HasViewportPercentage;
|
||||||
use values::specified::{LengthOrPercentage, Percentage};
|
use values::specified::{LengthOrPercentage, Percentage};
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ ${helpers.single_keyword("color-adjust",
|
||||||
"economy exact", products="gecko",
|
"economy exact", products="gecko",
|
||||||
animatable=False)}
|
animatable=False)}
|
||||||
|
|
||||||
<%helpers:longhand name="image-rendering" animatable="False">
|
<%helpers:longhand name="image-rendering" products="servo" animatable="False">
|
||||||
pub mod computed_value {
|
pub mod computed_value {
|
||||||
use cssparser::ToCss;
|
use cssparser::ToCss;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
|
@ -16,7 +16,7 @@ ${helpers.single_keyword("caption-side", "top bottom",
|
||||||
extra_gecko_values="right left top-outside bottom-outside",
|
extra_gecko_values="right left top-outside bottom-outside",
|
||||||
animatable=False)}
|
animatable=False)}
|
||||||
|
|
||||||
<%helpers:longhand name="border-spacing" animatable="False">
|
<%helpers:longhand name="border-spacing" products="servo" animatable="False">
|
||||||
use app_units::Au;
|
use app_units::Au;
|
||||||
use values::LocalToCss;
|
use values::LocalToCss;
|
||||||
use values::HasViewportPercentage;
|
use values::HasViewportPercentage;
|
||||||
|
@ -26,6 +26,7 @@ ${helpers.single_keyword("caption-side", "top bottom",
|
||||||
|
|
||||||
pub mod computed_value {
|
pub mod computed_value {
|
||||||
use app_units::Au;
|
use app_units::Au;
|
||||||
|
use properties::animated_properties::Interpolate;
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, RustcEncodable)]
|
#[derive(Clone, Copy, Debug, PartialEq, RustcEncodable)]
|
||||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
|
@ -33,6 +34,17 @@ ${helpers.single_keyword("caption-side", "top bottom",
|
||||||
pub horizontal: Au,
|
pub horizontal: Au,
|
||||||
pub vertical: Au,
|
pub vertical: Au,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// https://drafts.csswg.org/css-transitions/#animtype-simple-list
|
||||||
|
impl Interpolate for T {
|
||||||
|
#[inline]
|
||||||
|
fn interpolate(&self, other: &Self, time: f64) -> Result<Self, ()> {
|
||||||
|
Ok(T {
|
||||||
|
horizontal: try!(self.horizontal.interpolate(&other.horizontal, time)),
|
||||||
|
vertical: try!(self.vertical.interpolate(&other.vertical, time)),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HasViewportPercentage for SpecifiedValue {
|
impl HasViewportPercentage for SpecifiedValue {
|
||||||
|
|
|
@ -192,7 +192,7 @@
|
||||||
</%helpers:longhand>
|
</%helpers:longhand>
|
||||||
|
|
||||||
// FIXME: This prop should be animatable.
|
// FIXME: This prop should be animatable.
|
||||||
<%helpers:longhand name="letter-spacing" animatable="False">
|
<%helpers:longhand name="letter-spacing" products="servo" animatable="False">
|
||||||
use cssparser::ToCss;
|
use cssparser::ToCss;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use values::LocalToCss;
|
use values::LocalToCss;
|
||||||
|
|
|
@ -96,7 +96,7 @@ ${helpers.single_keyword("list-style-type", """
|
||||||
}
|
}
|
||||||
</%helpers:longhand>
|
</%helpers:longhand>
|
||||||
|
|
||||||
<%helpers:longhand name="quotes" animatable="False">
|
<%helpers:longhand name="quotes" products="servo" animatable="False">
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use values::NoViewportPercentage;
|
use values::NoViewportPercentage;
|
||||||
|
|
|
@ -78,4 +78,4 @@ ${helpers.predefined_type("outline-color", "CSSColor", "::cssparser::Color::Curr
|
||||||
animatable=False)}
|
animatable=False)}
|
||||||
% endfor
|
% endfor
|
||||||
|
|
||||||
${helpers.predefined_type("outline-offset", "Length", "Au(0)", animatable=True)}
|
${helpers.predefined_type("outline-offset", "Length", "Au(0)", products="servo", animatable=True)}
|
||||||
|
|
|
@ -110,7 +110,7 @@ ${helpers.single_keyword("align-self", "auto stretch flex-start flex-end center
|
||||||
animatable=False)}
|
animatable=False)}
|
||||||
|
|
||||||
// https://drafts.csswg.org/css-flexbox/#propdef-order
|
// https://drafts.csswg.org/css-flexbox/#propdef-order
|
||||||
<%helpers:longhand name="order" animatable="True">
|
<%helpers:longhand name="order" products="servo" animatable="True">
|
||||||
use values::computed::ComputedValueAsSpecified;
|
use values::computed::ComputedValueAsSpecified;
|
||||||
|
|
||||||
impl ComputedValueAsSpecified for SpecifiedValue {}
|
impl ComputedValueAsSpecified for SpecifiedValue {}
|
||||||
|
|
|
@ -1152,7 +1152,12 @@ impl PropertyDeclaration {
|
||||||
},
|
},
|
||||||
% endfor
|
% endfor
|
||||||
|
|
||||||
_ => PropertyDeclarationParseResult::UnknownProperty
|
_ => {
|
||||||
|
if cfg!(all(debug_assertions, feature = "gecko")) && !name.starts_with('-') {
|
||||||
|
println!("stylo: Unimplemented property setter: {}", name);
|
||||||
|
}
|
||||||
|
PropertyDeclarationParseResult::UnknownProperty
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue