/* This Source Code Form is subject to the terms of the Mozilla Public * 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/. */ //! Computed values. use app_units::Au; use euclid::size::Size2D; use font_metrics::FontMetricsProvider; use media_queries::Device; use properties::ComputedValues; use std::fmt; use style_traits::ToCss; use super::{CSSFloat, CSSInteger, RGBA, specified}; use super::specified::grid::{TrackBreadth as GenericTrackBreadth, TrackSize as GenericTrackSize}; pub use cssparser::Color as CSSColor; pub use self::image::{AngleOrCorner, EndingShape as GradientShape, Gradient, GradientKind, Image, ImageRect}; pub use self::image::{LengthOrKeyword, LengthOrPercentageOrKeyword}; pub use super::{Auto, Either, None_}; #[cfg(feature = "gecko")] pub use super::specified::{AlignItems, AlignJustifyContent, AlignJustifySelf, JustifyItems}; pub use super::specified::{BorderStyle, GridLine, Percentage, UrlOrNone}; pub use super::specified::url::SpecifiedUrl; pub use self::length::{CalcLengthOrPercentage, Length, LengthOrNumber, LengthOrPercentage, LengthOrPercentageOrAuto}; pub use self::length::{LengthOrPercentageOrAutoOrContent, LengthOrPercentageOrNone, LengthOrNone}; pub use self::length::{MaxLength, MinLength}; pub use self::position::Position; pub mod basic_shape; pub mod image; pub mod length; pub mod position; /// A `Context` is all the data a specified value could ever need to compute /// itself and be transformed to a computed value. pub struct Context<'a> { /// Whether the current element is the root element. pub is_root_element: bool, /// The Device holds the viewport and other external state. pub device: &'a Device, /// The style we're inheriting from. pub inherited_style: &'a ComputedValues, /// The style of the layout parent node. This will almost always be /// `inherited_style`, except when `display: contents` is at play, in which /// case it's the style of the last ancestor with a `display` value that /// isn't `contents`. pub layout_parent_style: &'a ComputedValues, /// Values access through this need to be in the properties "computed /// early": color, text-decoration, font-size, display, position, float, /// border-*-style, outline-style, font-family, writing-mode... pub style: ComputedValues, /// A font metrics provider, used to access font metrics to implement /// font-relative units. pub font_metrics_provider: &'a FontMetricsProvider, /// Whether or not we are computing the media list in a media query pub in_media_query: bool, } impl<'a> Context<'a> { /// Whether the current element is the root element. pub fn is_root_element(&self) -> bool { self.is_root_element } /// The current viewport size. pub fn viewport_size(&self) -> Size2D { self.device.au_viewport_size() } /// The style we're inheriting from. pub fn inherited_style(&self) -> &ComputedValues { &self.inherited_style } /// The current style. Note that only "eager" properties should be accessed /// from here, see the comment in the member. pub fn style(&self) -> &ComputedValues { &self.style } /// A mutable reference to the current style. pub fn mutate_style(&mut self) -> &mut ComputedValues { &mut self.style } } /// A trait to represent the conversion between computed and specified values. pub trait ToComputedValue { /// The computed value type we're going to be converted to. type ComputedValue; /// Convert a specified value to a computed value, using itself and the data /// inside the `Context`. #[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; } /// A marker trait to represent that the specified value is also the computed /// value. pub trait ComputedValueAsSpecified {} impl ToComputedValue for T where T: ComputedValueAsSpecified + Clone, { type ComputedValue = T; #[inline] fn to_computed_value(&self, _context: &Context) -> T { self.clone() } #[inline] fn from_computed_value(computed: &T) -> Self { computed.clone() } } /// A computed `` value. #[derive(Clone, PartialEq, PartialOrd, Copy, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf, Deserialize, Serialize))] pub struct Angle { radians: CSSFloat, } impl Angle { /// Construct a computed `Angle` value from a radian amount. pub fn from_radians(radians: CSSFloat) -> Self { Angle { radians: radians, } } /// Return the amount of radians this angle represents. #[inline] pub fn radians(&self) -> CSSFloat { self.radians } /// Returns an angle that represents a rotation of zero radians. pub fn zero() -> Self { Self::from_radians(0.0) } } impl ToCss for Angle { fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write, { write!(dest, "{}rad", self.radians()) } } /// A computed `