/* This Source Code Form is subject to the terms of the Mozilla Public *License,v.2.0.IfacopyoftheMPLwasnotdistributedwiththis
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
//! Computed values.
useself::transform::DirectionVector; usesuper::animated::ToAnimatedValue; usesuper::generics::grid::GridTemplateComponent as GenericGridTemplateComponent; usesuper::generics::grid::ImplicitGridTracks as GenericImplicitGridTracks; usesuper::generics::grid::{GenericGridLine, GenericTrackBreadth}; usesuper::generics::grid::{GenericTrackSize, TrackList as GenericTrackList}; usesuper::generics::transform::IsParallelTo; usesuper::generics::{self, GreaterThanOrEqualToOne, NonNegative, ZeroToOne}; usesuper::specified; usesuper::{CSSFloat, CSSInteger}; usecrate::computed_value_flags::ComputedValueFlags; usecrate::context::QuirksMode; usecrate::custom_properties::ComputedCustomProperties; usecrate::font_metrics::{FontMetrics, FontMetricsOrientation}; usecrate::media_queries::Device; #[cfg(feature = "gecko")] usecrate::properties; usecrate::properties::{ComputedValues, StyleBuilder}; usecrate::rule_cache::RuleCacheConditions; usecrate::stylesheets::container_rule::{
ContainerInfo, ContainerSizeQuery, ContainerSizeQueryResult,
}; usecrate::stylist::Stylist; usecrate::values::specified::length::FontBaseSize; usecrate::{ArcSlice, Atom, One}; use euclid::{default, Point2D, Rect, Size2D}; use servo_arc::Arc; use std::cell::RefCell; use std::cmp; use std::f32; use std::ops::{Add, Sub};
/// A `Context` is all the data a specified value could ever need to compute /// itself and be transformed to a computed value. pubstruct Context<'a> { /// Values accessed 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 builder: StyleBuilder<'a>,
/// A cached computed system font value, for use by gecko. /// /// See properties/longhands/font.mako.rs #[cfg(feature = "gecko")] pub cached_system_font: Option<properties::longhands::system_font::ComputedSystemFont>,
/// A dummy option for servo so initializing a computed::Context isn't /// painful. /// /// TODO(emilio): Make constructors for Context, and drop this. #[cfg(feature = "servo")] pub cached_system_font: Option<()>,
/// Whether or not we are computing the media list in a media query. pub in_media_query: bool,
/// Whether or not we are computing the container query condition. pub in_container_query: bool,
/// The quirks mode of this context. pub quirks_mode: QuirksMode,
/// Whether this computation is being done for a SMIL animation. /// /// This is used to allow certain properties to generate out-of-range /// values, which SMIL allows. pub for_smil_animation: bool,
/// Returns the container information to evaluate a given container query. pub container_info: Option<ContainerInfo>,
/// Whether we're computing a value for a non-inherited property. /// False if we are computed a value for an inherited property or not computing for a property /// at all (e.g. in a media query evaluation). pub for_non_inherited_property: bool,
/// The conditions to cache a rule node on the rule cache. /// /// FIXME(emilio): Drop the refcell. pub rule_cache_conditions: RefCell<&'a mut RuleCacheConditions>,
/// Container size query for this context.
container_size_query: RefCell<ContainerSizeQuery<'a>>,
}
/// Creates a context suitable for computing the initial value of @property. pubfn new_for_initial_at_property_value(
stylist: &'a Stylist,
rule_cache_conditions: &'a mut RuleCacheConditions,
) -> Self { Self {
builder: StyleBuilder::new(stylist.device(), Some(stylist), None, None, None, false),
cached_system_font: None, // Because font-relative values are disallowed in @property initial values, we do not // need to keep track of whether we're in a media query, whether we're in a container // query, and so on.
in_media_query: false,
in_container_query: false,
quirks_mode: stylist.quirks_mode(),
container_info: None,
for_smil_animation: false,
for_non_inherited_property: false,
rule_cache_conditions: RefCell::new(rule_cache_conditions),
container_size_query: RefCell::new(ContainerSizeQuery::none()),
}
}
/// The current device. pubfn device(&self) -> &Device { self.builder.device
}
/// Get the inherited custom properties map. pubfn inherited_custom_properties(&self) -> &ComputedCustomProperties {
&self.builder.inherited_custom_properties()
}
/// Whether the style is for the root element. pubfn is_root_element(&self) -> bool { self.builder.is_root_element
}
let (wm, font) = match base_size {
FontBaseSize::CurrentStyle => (style.writing_mode, style.get_font()), // This is only used for font-size computation.
FontBaseSize::InheritedStyle => {
(*style.inherited_writing_mode(), style.get_parent_font())
},
};
/// A trait to represent the conversion between computed and specified values. /// /// This trait is derivable with `#[derive(ToComputedValue)]`. The derived /// implementation just calls `ToComputedValue::to_computed_value` on each field /// of the passed value. The deriving code assumes that if the type isn't /// generic, then the trait can be implemented as simple `Clone::clone` calls, /// this means that a manual implementation with `ComputedValue = Self` is bogus /// if it returns anything else than a clone. pubtrait 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`. fn to_computed_value(&self, context: &Context) -> Self::ComputedValue;
/// 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;
}
impl<A, B> ToComputedValue for (A, B) where
A: ToComputedValue,
B: ToComputedValue,
{ type ComputedValue = (
<A as ToComputedValue>::ComputedValue,
<B as ToComputedValue>::ComputedValue,
);
impl<T> ToComputedValue for default::Size2D<T> where
T: ToComputedValue,
{ type ComputedValue = default::Size2D<<T as ToComputedValue>::ComputedValue>;
impl<T> ToComputedValue forcrate::OwnedSlice<T> where
T: ToComputedValue,
{ type ComputedValue = crate::OwnedSlice<<T as ToComputedValue>::ComputedValue>;
impl<T> ToComputedValue for thin_vec::ThinVec<T> where
T: ToComputedValue,
{ type ComputedValue = thin_vec::ThinVec<<T as ToComputedValue>::ComputedValue>;
// NOTE(emilio): This is implementable more generically, but it's unlikely // what you want there, as it forces you to have an extra allocation. // // We could do that if needed, ideally with specialization for the case where // ComputedValue = T. But we don't need it for now. impl<T> ToComputedValue for Arc<T> where
T: ToComputedValue<ComputedValue = T>,
{ type ComputedValue = Self;
/// A `<number>` value. pubtype Number = CSSFloat;
impl IsParallelTo for (Number, Number, Number) { fn is_parallel_to(&self, vector: &DirectionVector) -> bool { use euclid::approxeq::ApproxEq; // If a and b is parallel, the angle between them is 0deg, so // a x b = |a|*|b|*sin(0)*n = 0 * n, |a x b| == 0. let self_vector = DirectionVector::new(self.0, self.1, self.2);
self_vector
.cross(*vector)
.square_length()
.approx_eq(&0.0f32)
}
}
/// A wrapper of Number, but the value >= 0. pubtype NonNegativeNumber = NonNegative<CSSFloat>;
impl ToAnimatedValue for NonNegativeNumber { type AnimatedValue = CSSFloat;
/// rect(...) | auto pubtype ClipRect = generics::GenericClipRect<LengthOrAuto>;
/// rect(...) | auto pubtype ClipRectOrAuto = generics::GenericClipRectOrAuto<ClipRect>;
/// The computed value of a grid `<track-breadth>` pubtype TrackBreadth = GenericTrackBreadth<LengthPercentage>;
/// The computed value of a grid `<track-size>` pubtype TrackSize = GenericTrackSize<LengthPercentage>;
/// The computed value of a grid `<track-size>+` pubtype ImplicitGridTracks = GenericImplicitGridTracks<TrackSize>;
/// The computed value of a grid `<track-list>` /// (could also be `<auto-track-list>` or `<explicit-track-list>`) pubtype TrackList = GenericTrackList<LengthPercentage, Integer>;
/// The computed value of a `<grid-line>`. pubtype GridLine = GenericGridLine<Integer>;
impl ClipRect { /// Given a border box, resolves the clip rect against the border box /// in the same space the border box is in pubfn for_border_rect<T: Copy + From<Length> + Add<Output = T> + Sub<Output = T>, U>(
&self,
border_box: Rect<T, U>,
) -> Rect<T, U> { fn extract_clip_component<T: From<Length>>(p: &LengthOrAuto, or: T) -> T { match *p {
LengthOrAuto::Auto => or,
LengthOrAuto::LengthPercentage(ref length) => T::from(*length),
}
}
let clip_origin = Point2D::new(
From::from(self.left.auto_is(|| Length::new(0.))),
From::from(self.top.auto_is(|| Length::new(0.))),
); let right = extract_clip_component(&self.right, border_box.size.width); let bottom = extract_clip_component(&self.bottom, border_box.size.height); let clip_size = Size2D::new(right - clip_origin.x, bottom - clip_origin.y);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.