Auto merge of #13228 - Manishearth:uncompute, r=heycam

Add uncompute functionality (WIP)

As discussed in Taipei we plan to do animations in Stylo on the Rust side. For cascading properly, we need to "uncompute" these,
i.e. convert them into a cascadeable specified value which when computed gets us the same thing again.

This patch starts work on this. Before writing uncompute code for everything, I'd like to check that this is an acceptable amount of mako magic,
and that the general design is okay (to avoid having to rewrite everything once it's done).

Preliminary r? @SimonSapin @birtles

<!-- 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/13228)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2016-09-22 23:14:48 -05:00 committed by GitHub
commit fb52bb7c8d
19 changed files with 576 additions and 50 deletions

View file

@ -147,6 +147,12 @@
fn to_computed_value(&self, context: &Context) -> computed_value::T {
computed_value::T(self.0.iter().map(|x| x.to_computed_value(context)).collect())
}
#[inline]
fn from_computed_value(computed: &computed_value::T) -> Self {
SpecifiedValue(computed.0.iter()
.map(|x| ToComputedValue::from_computed_value(x))
.collect())
}
}
% else:
${caller.body()}

View file

@ -74,6 +74,15 @@ ${helpers.predefined_type("background-color", "CSSColor",
computed_value::T(Some(image.to_computed_value(context))),
}
}
#[inline]
fn from_computed_value(computed: &computed_value::T) -> Self {
match *computed {
computed_value::T(None) => SpecifiedValue(None),
computed_value::T(Some(ref image)) =>
SpecifiedValue(Some(ToComputedValue::from_computed_value(image))),
}
}
}
</%helpers:vector_longhand>
@ -191,7 +200,7 @@ ${helpers.single_keyword("background-origin",
}
}
impl HasViewportPercentage for SpecifiedExplicitSize {
impl HasViewportPercentage for ExplicitSize {
fn has_viewport_percentage(&self) -> bool {
return self.width.has_viewport_percentage() || self.height.has_viewport_percentage();
}
@ -199,12 +208,12 @@ ${helpers.single_keyword("background-origin",
#[derive(Clone, PartialEq, Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct SpecifiedExplicitSize {
pub struct ExplicitSize {
pub width: specified::LengthOrPercentageOrAuto,
pub height: specified::LengthOrPercentageOrAuto,
}
impl ToCss for SpecifiedExplicitSize {
impl ToCss for ExplicitSize {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
try!(self.width.to_css(dest));
try!(dest.write_str(" "));
@ -232,7 +241,7 @@ ${helpers.single_keyword("background-origin",
#[derive(Clone, PartialEq, Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub enum SpecifiedValue {
Explicit(SpecifiedExplicitSize),
Explicit(ExplicitSize),
Cover,
Contain,
}
@ -263,6 +272,19 @@ ${helpers.single_keyword("background-origin",
SpecifiedValue::Contain => computed_value::T::Contain,
}
}
#[inline]
fn from_computed_value(computed: &computed_value::T) -> Self {
match *computed {
computed_value::T::Explicit(ref size) => {
SpecifiedValue::Explicit(ExplicitSize {
width: ToComputedValue::from_computed_value(&size.width),
height: ToComputedValue::from_computed_value(&size.height),
})
}
computed_value::T::Cover => SpecifiedValue::Cover,
computed_value::T::Contain => SpecifiedValue::Contain,
}
}
}
#[inline]
@ -274,7 +296,7 @@ ${helpers.single_keyword("background-origin",
}
#[inline]
pub fn get_initial_specified_value() -> SpecifiedValue {
SpecifiedValue::Explicit(SpecifiedExplicitSize {
SpecifiedValue::Explicit(ExplicitSize {
width: specified::LengthOrPercentageOrAuto::Auto,
height: specified::LengthOrPercentageOrAuto::Auto,
})
@ -311,7 +333,7 @@ ${helpers.single_keyword("background-origin",
height = try!(specified::LengthOrPercentageOrAuto::parse(input));
}
Ok(SpecifiedValue::Explicit(SpecifiedExplicitSize {
Ok(SpecifiedValue::Explicit(ExplicitSize {
width: width,
height: height,
}))

View file

@ -65,6 +65,11 @@
fn to_computed_value(&self, context: &Context) -> computed_value::T {
self.0.to_computed_value(context)
}
#[inline]
fn from_computed_value(computed: &computed_value::T) -> Self {
SpecifiedValue(ToComputedValue::from_computed_value(computed))
}
}
</%helpers:longhand>
% endfor

View file

@ -115,6 +115,10 @@ ${helpers.single_keyword("position", "static absolute relative fixed",
*self
}
}
#[inline]
fn from_computed_value(computed: &computed_value::T) -> SpecifiedValue {
*computed
}
}
</%helpers:single_keyword_computed>
@ -240,6 +244,20 @@ ${helpers.single_keyword("clear", "none left right both",
computed_value::T::LengthOrPercentage(value.to_computed_value(context)),
}
}
#[inline]
fn from_computed_value(computed: &computed_value::T) -> Self {
match *computed {
% for keyword in vertical_align_keywords:
computed_value::T::${to_rust_ident(keyword)} => {
SpecifiedValue::${to_rust_ident(keyword)}
}
% endfor
computed_value::T::LengthOrPercentage(value) =>
SpecifiedValue::LengthOrPercentage(
ToComputedValue::from_computed_value(&value)
),
}
}
}
</%helpers:longhand>
@ -266,6 +284,7 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto",
use cssparser::ToCss;
use std::fmt;
use values::computed::ComputedValueAsSpecified;
pub use self::computed_value::T as SpecifiedValue;
@ -284,14 +303,7 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto",
pub struct T(pub super::super::overflow_x::computed_value::T);
}
impl ToComputedValue for SpecifiedValue {
type ComputedValue = computed_value::T;
#[inline]
fn to_computed_value(&self, context: &Context) -> computed_value::T {
computed_value::T(self.0.to_computed_value(context))
}
}
impl ComputedValueAsSpecified for SpecifiedValue {}
pub fn get_initial_value() -> computed_value::T {
computed_value::T(overflow_x::get_initial_value())
@ -372,6 +384,7 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto",
use euclid::point::{Point2D, TypedPoint2D};
use std::marker::PhantomData;
use values::computed::ComputedValueAsSpecified;
pub use self::computed_value::SingleComputedValue as SingleSpecifiedValue;
pub use self::computed_value::T as SpecifiedValue;
@ -416,6 +429,7 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto",
use cssparser::ToCss;
use euclid::point::Point2D;
use std::fmt;
use values::computed::ComputedValueAsSpecified;
pub use self::TransitionTimingFunction as SingleComputedValue;
@ -490,14 +504,7 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto",
use values::NoViewportPercentage;
impl NoViewportPercentage for SpecifiedValue {}
impl ToComputedValue for SpecifiedValue {
type ComputedValue = computed_value::T;
#[inline]
fn to_computed_value(&self, _: &Context) -> computed_value::T {
(*self).clone()
}
}
impl ComputedValueAsSpecified for SpecifiedValue {}
#[inline]
pub fn get_initial_value() -> computed_value::T {
@ -567,6 +574,9 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto",
<%helpers:longhand name="transition-property"
need_index="True"
animatable="False">
use values::computed::ComputedValueAsSpecified;
pub use self::computed_value::SingleComputedValue as SingleSpecifiedValue;
pub use self::computed_value::T as SpecifiedValue;
@ -616,14 +626,7 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto",
use values::NoViewportPercentage;
impl NoViewportPercentage for SpecifiedValue {}
impl ToComputedValue for SpecifiedValue {
type ComputedValue = computed_value::T;
#[inline]
fn to_computed_value(&self, _: &Context) -> computed_value::T {
(*self).clone()
}
}
impl ComputedValueAsSpecified for SpecifiedValue { }
</%helpers:longhand>
<%helpers:longhand name="transition-delay"

View file

@ -18,6 +18,14 @@
fn to_computed_value(&self, _context: &Context) -> computed_value::T {
self.parsed
}
#[inline]
fn from_computed_value(computed: &computed_value::T) -> Self {
CSSRGBA {
parsed: *computed,
authored: None,
}
}
}
pub type SpecifiedValue = CSSRGBA;

View file

@ -70,6 +70,14 @@
computed_value::T(Some(l.to_computed_value(context)))
}
}
#[inline]
fn from_computed_value(computed: &computed_value::T) -> Self {
match *computed {
computed_value::T(None) => SpecifiedValue::Auto,
computed_value::T(Some(l)) =>
SpecifiedValue::Specified(ToComputedValue::from_computed_value(&l))
}
}
}
pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
@ -136,6 +144,15 @@
computed_value::T(Some(count))
}
}
#[inline]
fn from_computed_value(computed: &computed_value::T) -> Self {
match *computed {
computed_value::T(None) => SpecifiedValue::Auto,
computed_value::T(Some(count)) =>
SpecifiedValue::Specified(count)
}
}
}
pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
@ -216,6 +233,14 @@
computed_value::T(Some(l.to_computed_value(context)))
}
}
#[inline]
fn from_computed_value(computed: &computed_value::T) -> Self {
match *computed {
computed_value::T(None) => SpecifiedValue::Normal,
computed_value::T(Some(l)) =>
SpecifiedValue::Specified(ToComputedValue::from_computed_value(&l))
}
}
}
pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {

View file

@ -111,6 +111,18 @@ ${helpers.predefined_type("opacity",
inset: self.inset,
}
}
#[inline]
fn from_computed_value(computed: &computed_value::T) -> Self {
SpecifiedValue {
offset_x: ToComputedValue::from_computed_value(&computed.offset_x),
offset_y: ToComputedValue::from_computed_value(&computed.offset_y),
blur_radius: ToComputedValue::from_computed_value(&computed.blur_radius),
spread_radius: ToComputedValue::from_computed_value(&computed.spread_radius),
color: Some(ToComputedValue::from_computed_value(&computed.color)),
inset: computed.inset,
}
}
}
pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
@ -329,6 +341,16 @@ ${helpers.predefined_type("opacity",
left: value.left.to_computed_value(context),
}))
}
#[inline]
fn from_computed_value(computed: &computed_value::T) -> Self {
SpecifiedValue(computed.0.map(|value| SpecifiedClipRect {
top: ToComputedValue::from_computed_value(&value.top),
right: value.right.map(|right| ToComputedValue::from_computed_value(&right)),
bottom: value.bottom.map(|bottom| ToComputedValue::from_computed_value(&bottom)),
left: ToComputedValue::from_computed_value(&value.left),
}))
}
}
pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
@ -629,6 +651,23 @@ ${helpers.predefined_type("opacity",
}
}).collect() }
}
fn from_computed_value(computed: &computed_value::T) -> Self {
SpecifiedValue(computed.filters.iter().map(|value| {
match *value {
computed_value::Filter::Blur(factor) =>
SpecifiedFilter::Blur(ToComputedValue::from_computed_value(&factor)),
computed_value::Filter::Brightness(factor) => SpecifiedFilter::Brightness(factor),
computed_value::Filter::Contrast(factor) => SpecifiedFilter::Contrast(factor),
computed_value::Filter::Grayscale(factor) => SpecifiedFilter::Grayscale(factor),
computed_value::Filter::HueRotate(factor) => SpecifiedFilter::HueRotate(factor),
computed_value::Filter::Invert(factor) => SpecifiedFilter::Invert(factor),
computed_value::Filter::Opacity(factor) => SpecifiedFilter::Opacity(factor),
computed_value::Filter::Saturate(factor) => SpecifiedFilter::Saturate(factor),
computed_value::Filter::Sepia(factor) => SpecifiedFilter::Sepia(factor),
}
}).collect())
}
}
</%helpers:longhand>
@ -1113,6 +1152,43 @@ ${helpers.predefined_type("opacity",
computed_value::T(Some(result))
}
#[inline]
fn from_computed_value(computed: &computed_value::T) -> Self {
SpecifiedValue(computed.0.as_ref().map(|computed| {
let mut result = vec!();
for operation in computed {
match *operation {
computed_value::ComputedOperation::Matrix(ref matrix) => {
result.push(SpecifiedOperation::Matrix(*matrix));
}
computed_value::ComputedOperation::Translate(ref tx, ref ty, ref tz) => {
// XXXManishearth we lose information here; perhaps we should try to
// recover the original function? Not sure if this can be observed.
result.push(SpecifiedOperation::Translate(TranslateKind::Translate,
ToComputedValue::from_computed_value(tx),
ToComputedValue::from_computed_value(ty),
ToComputedValue::from_computed_value(tz)));
}
computed_value::ComputedOperation::Scale(sx, sy, sz) => {
result.push(SpecifiedOperation::Scale(sx, sy, sz));
}
computed_value::ComputedOperation::Rotate(ax, ay, az, theta) => {
result.push(SpecifiedOperation::Rotate(ax, ay, az, theta));
}
computed_value::ComputedOperation::Skew(theta_x, theta_y) => {
result.push(SpecifiedOperation::Skew(theta_x, theta_y));
}
computed_value::ComputedOperation::Perspective(ref d) => {
result.push(SpecifiedOperation::Perspective(
ToComputedValue::from_computed_value(d)
));
}
};
}
result
}).unwrap_or(Vec::new()))
}
}
</%helpers:longhand>
@ -1309,6 +1385,15 @@ ${helpers.single_keyword("transform-style",
depth: self.depth.to_computed_value(context),
}
}
#[inline]
fn from_computed_value(computed: &computed_value::T) -> Self {
SpecifiedValue {
horizontal: ToComputedValue::from_computed_value(&computed.horizontal),
vertical: ToComputedValue::from_computed_value(&computed.vertical),
depth: ToComputedValue::from_computed_value(&computed.depth),
}
}
}
</%helpers:longhand>
@ -1395,6 +1480,14 @@ ${helpers.predefined_type("perspective",
vertical: self.vertical.to_computed_value(context),
}
}
#[inline]
fn from_computed_value(computed: &computed_value::T) -> Self {
SpecifiedValue {
horizontal: ToComputedValue::from_computed_value(&computed.horizontal),
vertical: ToComputedValue::from_computed_value(&computed.vertical),
}
}
}
</%helpers:longhand>

View file

@ -249,6 +249,15 @@ ${helpers.single_keyword("font-variant",
},
}
}
#[inline]
fn from_computed_value(computed: &computed_value::T) -> Self {
match *computed {
% for weight in range(100, 901, 100):
computed_value::T::Weight${weight} => SpecifiedValue::Weight${weight},
% endfor
}
}
}
</%helpers:longhand>
@ -310,6 +319,13 @@ ${helpers.single_keyword("font-variant",
}
}
}
#[inline]
fn from_computed_value(computed: &computed_value::T) -> Self {
SpecifiedValue(LengthOrPercentage::Length(
ToComputedValue::from_computed_value(computed)
))
}
}
/// <length> | <percentage> | <absolute-size> | <relative-size>
pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {

View file

@ -88,14 +88,8 @@ ${helpers.single_keyword("color-adjust",
}
}
impl ToComputedValue for SpecifiedValue {
type ComputedValue = computed_value::T;
#[inline]
fn to_computed_value(&self, _: &Context) -> computed_value::T {
*self
}
}
use values::computed::ComputedValueAsSpecified;
impl ComputedValueAsSpecified for SpecifiedValue { }
</%helpers:longhand>
// Used in the bottom-up flow construction traversal to avoid constructing flows for

View file

@ -94,6 +94,14 @@ ${helpers.single_keyword("caption-side", "top bottom",
vertical: self.vertical.to_computed_value(context),
}
}
#[inline]
fn from_computed_value(computed: &computed_value::T) -> Self {
SpecifiedValue {
horizontal: ToComputedValue::from_computed_value(&computed.horizontal),
vertical: ToComputedValue::from_computed_value(&computed.vertical),
}
}
}
pub fn parse(_: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue,()> {

View file

@ -127,6 +127,22 @@
}
}
}
#[inline]
fn from_computed_value(computed: &computed_value::T) -> Self {
match *computed {
computed_value::T::Normal => SpecifiedValue::Normal,
% if product == "gecko":
computed_value::T::MozBlockHeight => SpecifiedValue::MozBlockHeight,
% endif
computed_value::T::Number(value) => SpecifiedValue::Number(value),
computed_value::T::Length(au) => {
SpecifiedValue::LengthOrPercentage(specified::LengthOrPercentage::Length(
ToComputedValue::from_computed_value(&au)
))
}
}
}
}
</%helpers:longhand>
@ -255,6 +271,13 @@
computed_value::T(Some(l.to_computed_value(context)))
}
}
#[inline]
fn from_computed_value(computed: &computed_value::T) -> Self {
computed.0.map(|ref au| {
SpecifiedValue::Specified(ToComputedValue::from_computed_value(au))
}).unwrap_or(SpecifiedValue::Normal)
}
}
pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
@ -329,6 +352,13 @@
computed_value::T(Some(l.to_computed_value(context))),
}
}
#[inline]
fn from_computed_value(computed: &computed_value::T) -> Self {
computed.0.map(|ref lop| {
SpecifiedValue::Specified(ToComputedValue::from_computed_value(lop))
}).unwrap_or(SpecifiedValue::Normal)
}
}
pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
@ -688,6 +718,17 @@ ${helpers.single_keyword("text-justify",
}
}).collect())
}
fn from_computed_value(computed: &computed_value::T) -> Self {
SpecifiedValue(computed.0.iter().map(|value| {
SpecifiedTextShadow {
offset_x: ToComputedValue::from_computed_value(&value.offset_x),
offset_y: ToComputedValue::from_computed_value(&value.offset_y),
blur_radius: ToComputedValue::from_computed_value(&value.blur_radius),
color: Some(ToComputedValue::from_computed_value(&value.color)),
}
}).collect())
}
}
</%helpers:longhand>

View file

@ -81,6 +81,14 @@ ${helpers.single_keyword("list-style-type", """
SpecifiedValue::Url(ref url) => computed_value::T(Some(url.clone())),
}
}
#[inline]
fn from_computed_value(computed: &computed_value::T) -> Self {
match *computed {
computed_value::T(None) => SpecifiedValue::None,
computed_value::T(Some(ref url)) => SpecifiedValue::Url(url.clone()),
}
}
}
pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {

View file

@ -66,6 +66,11 @@ ${helpers.predefined_type("outline-color", "CSSColor", "::cssparser::Color::Curr
fn to_computed_value(&self, context: &Context) -> computed_value::T {
self.0.to_computed_value(context)
}
#[inline]
fn from_computed_value(computed: &computed_value::T) -> Self {
SpecifiedValue(ToComputedValue::from_computed_value(computed))
}
}
</%helpers:longhand>

View file

@ -238,5 +238,16 @@ ${helpers.single_keyword("mask-composite",
computed_value::T::Url(url.clone(), data.clone()),
}
}
#[inline]
fn from_computed_value(computed: &computed_value::T) -> Self {
match *computed {
computed_value::T::None => SpecifiedValue::None,
computed_value::T::Image(ref image) =>
SpecifiedValue::Image(ToComputedValue::from_computed_value(image)),
computed_value::T::Url(ref url, ref data) =>
SpecifiedValue::Url(url.clone(), data.clone()),
}
}
}
</%helpers:vector_longhand>

View file

@ -41,6 +41,13 @@ pub trait ToComputedValue {
#[inline]
fn to_computed_value(&self, _context: &Context) -> Self::ComputedValue;
#[inline]
/// Convert a computed value to specified value form.
///
/// This will be used for recascading during animation.
/// Such from_computed_valued values should recompute to the same value.
fn from_computed_value(computed: &Self::ComputedValue) -> Self;
}
pub trait ComputedValueAsSpecified {}
@ -52,6 +59,11 @@ impl<T> ToComputedValue for T where T: ComputedValueAsSpecified + Clone {
fn to_computed_value(&self, _context: &Context) -> T {
self.clone()
}
#[inline]
fn from_computed_value(computed: &T) -> Self {
computed.clone()
}
}
impl ToComputedValue for specified::CSSColor {
@ -61,6 +73,14 @@ impl ToComputedValue for specified::CSSColor {
fn to_computed_value(&self, _context: &Context) -> CSSColor {
self.parsed
}
#[inline]
fn from_computed_value(computed: &CSSColor) -> Self {
specified::CSSColor {
parsed: *computed,
authored: None,
}
}
}
impl ComputedValueAsSpecified for specified::BorderStyle {}
@ -82,6 +102,11 @@ impl ToComputedValue for specified::Length {
length.to_computed_value(context.style().get_font().clone_font_size())
}
}
#[inline]
fn from_computed_value(computed: &Au) -> Self {
specified::Length::Absolute(*computed)
}
}
#[derive(Clone, PartialEq, Copy, Debug)]
@ -170,6 +195,15 @@ impl ToComputedValue for specified::CalcLengthOrPercentage {
context.style().root_font_size())
}
#[inline]
fn from_computed_value(computed: &CalcLengthOrPercentage) -> Self {
specified::CalcLengthOrPercentage {
absolute: computed.length,
percentage: computed.percentage.map(specified::Percentage),
..Default::default()
}
}
}
@ -192,6 +226,13 @@ impl ToComputedValue for specified::BorderRadiusSize {
let h = self.0.height.to_computed_value(context);
BorderRadiusSize(Size2D::new(w, h))
}
#[inline]
fn from_computed_value(computed: &BorderRadiusSize) -> Self {
let w = ToComputedValue::from_computed_value(&computed.0.width);
let h = ToComputedValue::from_computed_value(&computed.0.height);
specified::BorderRadiusSize(Size2D::new(w, h))
}
}
impl ::cssparser::ToCss for BorderRadiusSize {
@ -264,6 +305,24 @@ impl ToComputedValue for specified::LengthOrPercentage {
}
}
}
fn from_computed_value(computed: &LengthOrPercentage) -> Self {
match *computed {
LengthOrPercentage::Length(value) => {
specified::LengthOrPercentage::Length(
ToComputedValue::from_computed_value(&value)
)
}
LengthOrPercentage::Percentage(value) => {
specified::LengthOrPercentage::Percentage(specified::Percentage(value))
}
LengthOrPercentage::Calc(calc) => {
specified::LengthOrPercentage::Calc(
ToComputedValue::from_computed_value(&calc)
)
}
}
}
}
impl ::cssparser::ToCss for LengthOrPercentage {
@ -331,6 +390,26 @@ impl ToComputedValue for specified::LengthOrPercentageOrAuto {
}
}
}
#[inline]
fn from_computed_value(computed: &LengthOrPercentageOrAuto) -> Self {
match *computed {
LengthOrPercentageOrAuto::Auto => specified::LengthOrPercentageOrAuto::Auto,
LengthOrPercentageOrAuto::Length(value) => {
specified::LengthOrPercentageOrAuto::Length(
ToComputedValue::from_computed_value(&value)
)
}
LengthOrPercentageOrAuto::Percentage(value) => {
specified::LengthOrPercentageOrAuto::Percentage(specified::Percentage(value))
}
LengthOrPercentageOrAuto::Calc(calc) => {
specified::LengthOrPercentageOrAuto::Calc(
ToComputedValue::from_computed_value(&calc)
)
}
}
}
}
impl ::cssparser::ToCss for LengthOrPercentageOrAuto {
@ -390,6 +469,32 @@ impl ToComputedValue for specified::LengthOrPercentageOrAutoOrContent {
}
}
}
#[inline]
fn from_computed_value(computed: &LengthOrPercentageOrAutoOrContent) -> Self {
match *computed {
LengthOrPercentageOrAutoOrContent::Auto => {
specified::LengthOrPercentageOrAutoOrContent::Auto
}
LengthOrPercentageOrAutoOrContent::Content => {
specified::LengthOrPercentageOrAutoOrContent::Content
}
LengthOrPercentageOrAutoOrContent::Length(value) => {
specified::LengthOrPercentageOrAutoOrContent::Length(
ToComputedValue::from_computed_value(&value)
)
}
LengthOrPercentageOrAutoOrContent::Percentage(value) => {
specified::LengthOrPercentageOrAutoOrContent::Percentage(specified::Percentage(value))
}
LengthOrPercentageOrAutoOrContent::Calc(calc) => {
specified::LengthOrPercentageOrAutoOrContent::Calc(
ToComputedValue::from_computed_value(&calc)
)
}
}
}
}
impl ::cssparser::ToCss for LengthOrPercentageOrAutoOrContent {
@ -445,6 +550,26 @@ impl ToComputedValue for specified::LengthOrPercentageOrNone {
}
}
}
#[inline]
fn from_computed_value(computed: &LengthOrPercentageOrNone) -> Self {
match *computed {
LengthOrPercentageOrNone::None => specified::LengthOrPercentageOrNone::None,
LengthOrPercentageOrNone::Length(value) => {
specified::LengthOrPercentageOrNone::Length(
ToComputedValue::from_computed_value(&value)
)
}
LengthOrPercentageOrNone::Percentage(value) => {
specified::LengthOrPercentageOrNone::Percentage(specified::Percentage(value))
}
LengthOrPercentageOrNone::Calc(calc) => {
specified::LengthOrPercentageOrNone::Calc(
ToComputedValue::from_computed_value(&calc)
)
}
}
}
}
impl ::cssparser::ToCss for LengthOrPercentageOrNone {
@ -492,6 +617,18 @@ impl ToComputedValue for specified::LengthOrNone {
}
}
}
#[inline]
fn from_computed_value(computed: &LengthOrNone) -> Self {
match *computed {
LengthOrNone::Length(au) => {
specified::LengthOrNone::Length(ToComputedValue::from_computed_value(&au))
}
LengthOrNone::None => {
specified::LengthOrNone::None
}
}
}
}
impl ::cssparser::ToCss for LengthOrNone {
@ -517,6 +654,20 @@ impl ToComputedValue for specified::Image {
}
}
}
#[inline]
fn from_computed_value(computed: &Image) -> Self {
match *computed {
Image::Url(ref url, ref extra_data) => {
specified::Image::Url(url.clone(), extra_data.clone())
},
Image::LinearGradient(ref linear_gradient) => {
specified::Image::LinearGradient(
ToComputedValue::from_computed_value(linear_gradient)
)
}
}
}
}
@ -638,6 +789,25 @@ impl ToComputedValue for specified::LinearGradient {
}).collect()
}
}
#[inline]
fn from_computed_value(computed: &LinearGradient) -> Self {
let LinearGradient {
angle_or_corner,
ref stops
} = *computed;
specified::LinearGradient {
angle_or_corner: angle_or_corner,
stops: stops.iter().map(|stop| {
specified::ColorStop {
color: ToComputedValue::from_computed_value(&stop.color),
position: match stop.position {
None => None,
Some(value) => Some(ToComputedValue::from_computed_value(&value)),
},
}
}).collect()
}
}
}
pub type Length = Au;
pub type Number = CSSFloat;

View file

@ -94,6 +94,7 @@ impl<T: Parse + PartialEq + Copy> ShapeSource<T> {
impl<T: ToComputedValue> ToComputedValue for ShapeSource<T> {
type ComputedValue = computed_basic_shape::ShapeSource<T::ComputedValue>;
#[inline]
fn to_computed_value(&self, cx: &Context) -> Self::ComputedValue {
match *self {
@ -111,6 +112,24 @@ impl<T: ToComputedValue> ToComputedValue for ShapeSource<T> {
ShapeSource::None => computed_basic_shape::ShapeSource::None,
}
}
#[inline]
fn from_computed_value(computed: &Self::ComputedValue) -> Self {
match *computed {
computed_basic_shape::ShapeSource::Url(ref url, ref data) => {
ShapeSource::Url(url.clone(), data.clone())
}
computed_basic_shape::ShapeSource::Shape(ref shape, ref reference) => {
ShapeSource::Shape(
ToComputedValue::from_computed_value(shape),
reference.as_ref().map(|r| ToComputedValue::from_computed_value(r)))
}
computed_basic_shape::ShapeSource::Box(ref reference) => {
ShapeSource::Box(ToComputedValue::from_computed_value(reference))
}
computed_basic_shape::ShapeSource::None => ShapeSource::None,
}
}
}
#[derive(Clone, PartialEq, Debug)]
@ -169,6 +188,23 @@ impl ToComputedValue for BasicShape {
BasicShape::Polygon(ref poly) => computed_basic_shape::BasicShape::Polygon(poly.to_computed_value(cx)),
}
}
#[inline]
fn from_computed_value(computed: &Self::ComputedValue) -> Self {
match *computed {
computed_basic_shape::BasicShape::Inset(ref rect) => {
BasicShape::Inset(ToComputedValue::from_computed_value(rect))
}
computed_basic_shape::BasicShape::Circle(ref circle) => {
BasicShape::Circle(ToComputedValue::from_computed_value(circle))
}
computed_basic_shape::BasicShape::Ellipse(ref e) => {
BasicShape::Ellipse(ToComputedValue::from_computed_value(e))
}
computed_basic_shape::BasicShape::Polygon(ref poly) => {
BasicShape::Polygon(ToComputedValue::from_computed_value(poly))
}
}
}
}
#[derive(Clone, PartialEq, Copy, Debug)]
@ -239,6 +275,17 @@ impl ToComputedValue for InsetRect {
round: self.round.map(|r| r.to_computed_value(cx)),
}
}
#[inline]
fn from_computed_value(computed: &Self::ComputedValue) -> Self {
InsetRect {
top: ToComputedValue::from_computed_value(&computed.top),
right: ToComputedValue::from_computed_value(&computed.right),
bottom: ToComputedValue::from_computed_value(&computed.bottom),
left: ToComputedValue::from_computed_value(&computed.left),
round: computed.round.map(|ref r| ToComputedValue::from_computed_value(r)),
}
}
}
/// https://drafts.csswg.org/css-shapes/#basic-shape-serialization
@ -384,6 +431,14 @@ impl ToComputedValue for Circle {
position: self.position.to_computed_value(cx),
}
}
#[inline]
fn from_computed_value(computed: &Self::ComputedValue) -> Self {
Circle {
radius: ToComputedValue::from_computed_value(&computed.radius),
position: ToComputedValue::from_computed_value(&computed.position),
}
}
}
#[derive(Clone, PartialEq, Copy, Debug)]
@ -454,6 +509,15 @@ impl ToComputedValue for Ellipse {
position: self.position.to_computed_value(cx),
}
}
#[inline]
fn from_computed_value(computed: &Self::ComputedValue) -> Self {
Ellipse {
semiaxis_x: ToComputedValue::from_computed_value(&computed.semiaxis_x),
semiaxis_y: ToComputedValue::from_computed_value(&computed.semiaxis_y),
position: ToComputedValue::from_computed_value(&computed.position),
}
}
}
@ -528,6 +592,19 @@ impl ToComputedValue for Polygon {
.collect(),
}
}
#[inline]
fn from_computed_value(computed: &Self::ComputedValue) -> Self {
Polygon {
fill: ToComputedValue::from_computed_value(&computed.fill),
coordinates: computed.coordinates.iter()
.map(|c| {
(ToComputedValue::from_computed_value(&c.0),
ToComputedValue::from_computed_value(&c.1))
})
.collect(),
}
}
}
/// https://drafts.csswg.org/css-shapes/#typedef-shape-radius
@ -582,6 +659,17 @@ impl ToComputedValue for ShapeRadius {
ShapeRadius::FarthestSide => computed_basic_shape::ShapeRadius::FarthestSide,
}
}
#[inline]
fn from_computed_value(computed: &Self::ComputedValue) -> Self {
match *computed {
computed_basic_shape::ShapeRadius::Length(ref lop) => {
ShapeRadius::Length(ToComputedValue::from_computed_value(lop))
}
computed_basic_shape::ShapeRadius::ClosestSide => ShapeRadius::ClosestSide,
computed_basic_shape::ShapeRadius::FarthestSide => ShapeRadius::FarthestSide,
}
}
}
/// https://drafts.csswg.org/css-backgrounds-3/#border-radius
@ -674,6 +762,16 @@ impl ToComputedValue for BorderRadius {
bottom_left: self.bottom_left.to_computed_value(cx),
}
}
#[inline]
fn from_computed_value(computed: &Self::ComputedValue) -> Self {
BorderRadius {
top_left: ToComputedValue::from_computed_value(&computed.top_left),
top_right: ToComputedValue::from_computed_value(&computed.top_right),
bottom_right: ToComputedValue::from_computed_value(&computed.bottom_right),
bottom_left: ToComputedValue::from_computed_value(&computed.bottom_left),
}
}
}
/// https://drafts.csswg.org/css-shapes/#typedef-fill-rule

View file

@ -17,7 +17,7 @@ use std::fmt;
use std::ops::Mul;
use style_traits::values::specified::AllowedNumericType;
use super::{CSSFloat, FONT_MEDIUM_PX, HasViewportPercentage, LocalToCss, NoViewportPercentage};
use super::computed::{self, Context, ToComputedValue};
use super::computed::{self, ComputedValueAsSpecified, Context, ToComputedValue};
use url::Url;
pub mod basic_shape;
@ -456,7 +456,7 @@ enum CalcUnit {
Time,
}
#[derive(Clone, PartialEq, Copy, Debug)]
#[derive(Clone, PartialEq, Copy, Debug, Default)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct CalcLengthOrPercentage {
pub absolute: Option<Au>,
@ -1525,14 +1525,7 @@ impl Time {
}
}
impl ToComputedValue for Time {
type ComputedValue = Time;
#[inline]
fn to_computed_value(&self, _: &Context) -> Time {
*self
}
}
impl ComputedValueAsSpecified for Time {}
impl ToCss for Time {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
@ -1572,6 +1565,11 @@ impl ToComputedValue for Number {
#[inline]
fn to_computed_value(&self, _: &Context) -> CSSFloat { self.0 }
#[inline]
fn from_computed_value(computed: &CSSFloat) -> Self {
Number(*computed)
}
}
impl ToCss for Number {
@ -1605,6 +1603,11 @@ impl ToComputedValue for Opacity {
self.0
}
}
#[inline]
fn from_computed_value(computed: &CSSFloat) -> Self {
Opacity(*computed)
}
}
impl ToCss for Opacity {

View file

@ -329,6 +329,16 @@ impl ToComputedValue for Position {
vertical: vertical,
}
}
#[inline]
fn from_computed_value(computed: &computed_position::Position) -> Position {
Position {
horiz_keyword: None,
horiz_position: Some(ToComputedValue::from_computed_value(&computed.horizontal)),
vert_keyword: None,
vert_position: Some(ToComputedValue::from_computed_value(&computed.vertical)),
}
}
}
impl HasViewportPercentage for PositionComponent {