From 395f6be0a60d5c44426f18a5d7a6f53d1d7d471d Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Tue, 27 Jun 2017 13:48:34 +0200 Subject: [PATCH] Use the Separator trait for the filter property --- components/gfx/display_list/mod.rs | 9 ++-- components/layout/display_list_builder.rs | 2 +- components/layout/webrender_helpers.rs | 31 +++++++------ components/style/properties/gecko.mako.rs | 22 +++++---- components/style/properties/helpers.mako.rs | 6 +-- .../helpers/animated_properties.mako.rs | 4 +- .../style/properties/longhand/effects.mako.rs | 6 ++- components/style/values/animated/effects.rs | 28 ++++++++---- components/style/values/computed/effects.rs | 17 ------- components/style/values/computed/mod.rs | 2 +- components/style/values/generics/effects.rs | 45 ------------------- components/style/values/specified/effects.rs | 23 +--------- components/style/values/specified/mod.rs | 2 +- 13 files changed, 66 insertions(+), 131 deletions(-) diff --git a/components/gfx/display_list/mod.rs b/components/gfx/display_list/mod.rs index 789aea4725cc..c8430ab61ad7 100644 --- a/components/gfx/display_list/mod.rs +++ b/components/gfx/display_list/mod.rs @@ -28,7 +28,8 @@ use std::cmp::{self, Ordering}; use std::collections::HashMap; use std::fmt; use std::sync::Arc; -use style::computed_values::{border_style, filter, image_rendering}; +use style::computed_values::{border_style, image_rendering}; +use style::values::computed::Filter; use style_traits::cursor::Cursor; use text::TextRun; use text::glyph::ByteIndex; @@ -419,7 +420,7 @@ pub struct StackingContext { pub z_index: i32, /// CSS filters to be applied to this stacking context (including opacity). - pub filters: filter::T, + pub filters: Vec, /// The blend mode with which this stacking context blends with its backdrop. pub mix_blend_mode: MixBlendMode, @@ -448,7 +449,7 @@ impl StackingContext { bounds: &Rect, overflow: &Rect, z_index: i32, - filters: filter::T, + filters: Vec, mix_blend_mode: MixBlendMode, transform: Option>, transform_style: TransformStyle, @@ -479,7 +480,7 @@ impl StackingContext { &Rect::zero(), &Rect::zero(), 0, - filter::T::none(), + vec![], MixBlendMode::Normal, None, TransformStyle::Flat, diff --git a/components/layout/display_list_builder.rs b/components/layout/display_list_builder.rs index 8828994c0563..0f3e484b816e 100644 --- a/components/layout/display_list_builder.rs +++ b/components/layout/display_list_builder.rs @@ -2010,7 +2010,7 @@ impl FragmentDisplayListBuilding for Fragment { // Create the filter pipeline. let effects = self.style().get_effects(); - let mut filters = effects.filter.clone().0.into_vec(); + let mut filters = effects.filter.0.clone(); if effects.opacity != 1.0 { filters.push(Filter::Opacity(effects.opacity)) } diff --git a/components/layout/webrender_helpers.rs b/components/layout/webrender_helpers.rs index bba2ae20b376..d556bd4c92ef 100644 --- a/components/layout/webrender_helpers.rs +++ b/components/layout/webrender_helpers.rs @@ -13,9 +13,8 @@ use gfx::display_list::{BorderDetails, BorderRadii, BoxShadowClipMode, ClippingR use gfx::display_list::{DisplayItem, DisplayList, DisplayListTraversal, StackingContextType}; use msg::constellation_msg::PipelineId; use style::computed_values::{image_rendering, mix_blend_mode, transform_style}; -use style::computed_values::filter; -use style::values::computed::BorderStyle; -use style::values::generics::effects::Filter; +use style::values::computed::{BorderStyle, Filter}; +use style::values::generics::effects::Filter as GenericFilter; use webrender_traits::{self, DisplayListBuilder, ExtendMode}; use webrender_traits::{LayoutTransform, ClipId, ClipRegionToken}; @@ -202,21 +201,21 @@ trait ToFilterOps { fn to_filter_ops(&self) -> Vec; } -impl ToFilterOps for filter::T { +impl ToFilterOps for Vec { fn to_filter_ops(&self) -> Vec { - let mut result = Vec::with_capacity(self.0.len()); - for filter in self.0.iter() { + let mut result = Vec::with_capacity(self.len()); + for filter in self.iter() { match *filter { - Filter::Blur(radius) => result.push(webrender_traits::FilterOp::Blur(radius)), - Filter::Brightness(amount) => result.push(webrender_traits::FilterOp::Brightness(amount)), - Filter::Contrast(amount) => result.push(webrender_traits::FilterOp::Contrast(amount)), - Filter::Grayscale(amount) => result.push(webrender_traits::FilterOp::Grayscale(amount)), - Filter::HueRotate(angle) => result.push(webrender_traits::FilterOp::HueRotate(angle.radians())), - Filter::Invert(amount) => result.push(webrender_traits::FilterOp::Invert(amount)), - Filter::Opacity(amount) => result.push(webrender_traits::FilterOp::Opacity(amount.into())), - Filter::Saturate(amount) => result.push(webrender_traits::FilterOp::Saturate(amount)), - Filter::Sepia(amount) => result.push(webrender_traits::FilterOp::Sepia(amount)), - Filter::DropShadow(ref shadow) => match *shadow {}, + GenericFilter::Blur(radius) => result.push(webrender_traits::FilterOp::Blur(radius)), + GenericFilter::Brightness(amount) => result.push(webrender_traits::FilterOp::Brightness(amount)), + GenericFilter::Contrast(amount) => result.push(webrender_traits::FilterOp::Contrast(amount)), + GenericFilter::Grayscale(amount) => result.push(webrender_traits::FilterOp::Grayscale(amount)), + GenericFilter::HueRotate(angle) => result.push(webrender_traits::FilterOp::HueRotate(angle.radians())), + GenericFilter::Invert(amount) => result.push(webrender_traits::FilterOp::Invert(amount)), + GenericFilter::Opacity(amount) => result.push(webrender_traits::FilterOp::Opacity(amount.into())), + GenericFilter::Saturate(amount) => result.push(webrender_traits::FilterOp::Saturate(amount)), + GenericFilter::Sepia(amount) => result.push(webrender_traits::FilterOp::Sepia(amount)), + GenericFilter::DropShadow(ref shadow) => match *shadow {}, } } result diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index f3c1df9cf6e8..25611a3925c1 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -60,7 +60,7 @@ use std::ptr; use stylearc::Arc; use std::cmp; use values::{Auto, CustomIdent, Either, KeyframesName}; -use values::computed::Shadow; +use values::computed::{Filter, Shadow}; use values::specified::length::Percentage; use computed_values::border_style; @@ -3300,7 +3300,11 @@ fn static_assert() { 'Opacity', 'Saturate', 'Sepia' ] %> - pub fn set_filter(&mut self, v: longhands::filter::computed_value::T) { + pub fn set_filter(&mut self, v: I) + where + I: IntoIterator, + I::IntoIter: ExactSizeIterator, + { use values::generics::effects::Filter::*; use gecko_bindings::structs::nsCSSShadowArray; use gecko_bindings::structs::nsStyleFilter; @@ -3320,12 +3324,13 @@ fn static_assert() { gecko_filter.mFilterParameter.set_value(value); } + let v = v.into_iter(); unsafe { - Gecko_ResetFilters(&mut self.gecko, v.0.len()); + Gecko_ResetFilters(&mut self.gecko, v.len()); } - debug_assert!(v.0.len() == self.gecko.mFilters.len()); + debug_assert_eq!(v.len(), self.gecko.mFilters.len()); - for (servo, gecko_filter) in v.0.into_vec().into_iter().zip(self.gecko.mFilters.iter_mut()) { + for (servo, gecko_filter) in v.zip(self.gecko.mFilters.iter_mut()) { match servo { % for func in FILTER_FUNCTIONS: ${func}(factor) => fill_filter(NS_STYLE_FILTER_${func.upper()}, @@ -3372,7 +3377,7 @@ fn static_assert() { } pub fn clone_filter(&self) -> longhands::filter::computed_value::T { - use values::generics::effects::{Filter, FilterList}; + use values::generics::effects::Filter; use values::specified::url::SpecifiedUrl; use gecko_bindings::structs::NS_STYLE_FILTER_BLUR; use gecko_bindings::structs::NS_STYLE_FILTER_BRIGHTNESS; @@ -3422,7 +3427,7 @@ fn static_assert() { _ => {}, } } - FilterList(filters.into_boxed_slice()) + longhands::filter::computed_value::T(filters) } @@ -3942,10 +3947,9 @@ clip-path } pub fn clone_stroke_dasharray(&self) -> longhands::stroke_dasharray::computed_value::T { - use smallvec::SmallVec; use values::computed::LengthOrPercentage; - let mut vec = SmallVec::new(); + let mut vec = vec![]; for gecko in self.gecko.mStrokeDasharray.iter() { match gecko.as_value() { CoordDataValue::Factor(number) => vec.push(Either::First(number)), diff --git a/components/style/properties/helpers.mako.rs b/components/style/properties/helpers.mako.rs index 13a64beaa5f8..6a08e9242b9e 100644 --- a/components/style/properties/helpers.mako.rs +++ b/components/style/properties/helpers.mako.rs @@ -88,7 +88,7 @@ use std::fmt; #[allow(unused_imports)] use style_traits::HasViewportPercentage; - use style_traits::ToCss; + use style_traits::{Separator, ToCss}; pub mod single_value { #[allow(unused_imports)] @@ -186,7 +186,7 @@ % endif } for i in iter { - dest.write_str(", ")?; + dest.write_str(::style_traits::${separator}::separator())?; i.to_css(dest)?; } Ok(()) @@ -213,7 +213,7 @@ % endif } for i in iter { - dest.write_str(", ")?; + dest.write_str(::style_traits::${separator}::separator())?; i.to_css(dest)?; } Ok(()) diff --git a/components/style/properties/helpers/animated_properties.mako.rs b/components/style/properties/helpers/animated_properties.mako.rs index 854e24f77e6e..9b882af01500 100644 --- a/components/style/properties/helpers/animated_properties.mako.rs +++ b/components/style/properties/helpers/animated_properties.mako.rs @@ -3340,11 +3340,11 @@ impl Animatable for AnimatedFilterList { } } - Ok(filters.into()) + Ok(AnimatedFilterList(filters)) } fn add(&self, other: &Self) -> Result { - Ok(self.0.iter().chain(other.0.iter()).cloned().collect::>().into()) + Ok(AnimatedFilterList(self.0.iter().chain(other.0.iter()).cloned().collect())) } #[inline] diff --git a/components/style/properties/longhand/effects.mako.rs b/components/style/properties/longhand/effects.mako.rs index 7522308a20d8..9c34c54efb59 100644 --- a/components/style/properties/longhand/effects.mako.rs +++ b/components/style/properties/longhand/effects.mako.rs @@ -43,8 +43,10 @@ ${helpers.predefined_type("clip", ${helpers.predefined_type( "filter", - "FilterList", - "computed::FilterList::none()", + "Filter", + None, + vector=True, + separator="Space", animation_value_type="AnimatedFilterList", extra_prefixes="webkit", flags="CREATES_STACKING_CONTEXT FIXPOS_CB", diff --git a/components/style/values/animated/effects.rs b/components/style/values/animated/effects.rs index bbf60483613c..4c248e5d1ef3 100644 --- a/components/style/values/animated/effects.rs +++ b/components/style/values/animated/effects.rs @@ -5,21 +5,21 @@ //! Animated types for CSS values related to effects. use properties::animated_properties::{Animatable, IntermediateColor}; +use properties::longhands::filter::computed_value::T as ComputedFilterList; #[cfg(not(feature = "gecko"))] use values::Impossible; use values::computed::{Angle, Number}; #[cfg(feature = "gecko")] use values::computed::effects::Filter as ComputedFilter; -#[cfg(feature = "gecko")] -use values::computed::effects::FilterList as ComputedFilterList; use values::computed::effects::SimpleShadow as ComputedSimpleShadow; use values::computed::length::Length; use values::generics::effects::Filter as GenericFilter; -use values::generics::effects::FilterList as GenericFilterList; use values::generics::effects::SimpleShadow as GenericSimpleShadow; /// An animated value for the `filter` property. -pub type FilterList = GenericFilterList; +#[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[derive(Clone, Debug, PartialEq)] +pub struct FilterList(pub Vec); /// An animated value for a single `filter`. #[cfg(feature = "gecko")] @@ -32,19 +32,31 @@ pub type Filter = GenericFilter; /// An animated value for the `drop-shadow()` filter. pub type SimpleShadow = GenericSimpleShadow; -#[cfg(feature = "gecko")] impl From for FilterList { + #[cfg(not(feature = "gecko"))] + #[inline] + fn from(filters: ComputedFilterList) -> Self { + FilterList(filters.0) + } + + #[cfg(feature = "gecko")] #[inline] fn from(filters: ComputedFilterList) -> Self { - filters.0.into_vec().into_iter().map(|f| f.into()).collect::>().into() + FilterList(filters.0.into_iter().map(|f| f.into()).collect()) } } -#[cfg(feature = "gecko")] impl From for ComputedFilterList { + #[cfg(not(feature = "gecko"))] + #[inline] + fn from(filters: FilterList) -> Self { + ComputedFilterList(filters.0) + } + + #[cfg(feature = "gecko")] #[inline] fn from(filters: FilterList) -> Self { - filters.0.into_vec().into_iter().map(|f| f.into()).collect::>().into() + ComputedFilterList(filters.0.into_iter().map(|f| f.into()).collect()) } } diff --git a/components/style/values/computed/effects.rs b/components/style/values/computed/effects.rs index fb5ae5453a6d..3a0abecc9ece 100644 --- a/components/style/values/computed/effects.rs +++ b/components/style/values/computed/effects.rs @@ -10,12 +10,8 @@ use values::computed::{Angle, Number}; use values::computed::color::Color; use values::computed::length::Length; use values::generics::effects::Filter as GenericFilter; -use values::generics::effects::FilterList as GenericFilterList; use values::generics::effects::SimpleShadow as GenericSimpleShadow; -/// A computed value for the `filter` property. -pub type FilterList = GenericFilterList; - /// A computed value for a single `filter`. #[cfg(feature = "gecko")] pub type Filter = GenericFilter; @@ -26,16 +22,3 @@ pub type Filter = GenericFilter; /// A computed value for the `drop-shadow()` filter. pub type SimpleShadow = GenericSimpleShadow; - -impl FilterList { - /// Returns the resulting opacity of this filter pipeline. - pub fn opacity(&self) -> Number { - let mut opacity = 0.; - for filter in &*self.0 { - if let GenericFilter::Opacity(factor) = *filter { - opacity *= factor - } - } - opacity - } -} diff --git a/components/style/values/computed/mod.rs b/components/style/values/computed/mod.rs index 0bd99f194706..c1571e319847 100644 --- a/components/style/values/computed/mod.rs +++ b/components/style/values/computed/mod.rs @@ -28,7 +28,7 @@ pub use self::background::BackgroundSize; pub use self::border::{BorderImageSlice, BorderImageWidth, BorderImageSideWidth}; pub use self::border::{BorderRadius, BorderCornerRadius}; pub use self::color::{Color, RGBAColor}; -pub use self::effects::FilterList; +pub use self::effects::Filter; pub use self::flex::FlexBasis; pub use self::image::{Gradient, GradientItem, ImageLayer, LineDirection, Image, ImageRect}; #[cfg(feature = "gecko")] diff --git a/components/style/values/generics/effects.rs b/components/style/values/generics/effects.rs index 3b29429dd513..3331a9cf03e6 100644 --- a/components/style/values/generics/effects.rs +++ b/components/style/values/generics/effects.rs @@ -4,18 +4,9 @@ //! Generic types for CSS values related to effects. -use std::fmt; -use style_traits::ToCss; #[cfg(feature = "gecko")] use values::specified::url::SpecifiedUrl; -/// A generic value for the `filter` property. -/// -/// Keyword `none` is represented by an empty slice. -#[cfg_attr(feature = "servo", derive(Deserialize, HeapSizeOf, Serialize))] -#[derive(Clone, Debug, HasViewportPercentage, PartialEq, ToComputedValue)] -pub struct FilterList(pub Box<[Filter]>); - /// A generic value for a single `filter`. #[cfg_attr(feature = "servo", derive(Deserialize, HeapSizeOf, Serialize))] #[derive(Clone, Debug, HasViewportPercentage, PartialEq, ToComputedValue, ToCss)] @@ -71,39 +62,3 @@ pub struct SimpleShadow { /// Blur radius. pub blur: ShapeLength, } - -impl FilterList { - /// Returns `none`. - #[inline] - pub fn none() -> Self { - FilterList(vec![].into_boxed_slice()) - } -} - -impl From> for FilterList { - #[inline] - fn from(vec: Vec) -> Self { - FilterList(vec.into_boxed_slice()) - } -} - -impl ToCss for FilterList -where - F: ToCss, -{ - fn to_css(&self, dest: &mut W) -> fmt::Result - where - W: fmt::Write - { - if let Some((first, rest)) = self.0.split_first() { - first.to_css(dest)?; - for filter in rest { - dest.write_str(" ")?; - filter.to_css(dest)?; - } - Ok(()) - } else { - dest.write_str("none") - } - } -} diff --git a/components/style/values/specified/effects.rs b/components/style/values/specified/effects.rs index abd02653ed9d..29cc79f8742f 100644 --- a/components/style/values/specified/effects.rs +++ b/components/style/values/specified/effects.rs @@ -12,7 +12,6 @@ use values::Impossible; use values::computed::{Context, Number as ComputedNumber, ToComputedValue}; use values::computed::effects::SimpleShadow as ComputedSimpleShadow; use values::generics::effects::Filter as GenericFilter; -use values::generics::effects::FilterList as GenericFilterList; use values::generics::effects::SimpleShadow as GenericSimpleShadow; use values::specified::{Angle, Percentage}; use values::specified::color::Color; @@ -20,9 +19,6 @@ use values::specified::length::Length; #[cfg(feature = "gecko")] use values::specified::url::SpecifiedUrl; -/// A specified value for the `filter` property. -pub type FilterList = GenericFilterList; - /// A specified value for a single `filter`. #[cfg(feature = "gecko")] pub type Filter = GenericFilter; @@ -46,23 +42,6 @@ pub enum Factor { /// A specified value for the `drop-shadow()` filter. pub type SimpleShadow = GenericSimpleShadow, Length, Option>; -impl Parse for FilterList { - #[inline] - fn parse<'i, 't>( - context: &ParserContext, - input: &mut Parser<'i, 't> - ) -> Result> { - let mut filters = vec![]; - while let Ok(filter) = input.try(|i| Filter::parse(context, i)) { - filters.push(filter); - } - if filters.is_empty() { - input.expect_ident_matching("none")?; - } - Ok(GenericFilterList(filters.into_boxed_slice())) - } -} - impl Parse for Filter { #[inline] fn parse<'i, 't>( @@ -113,7 +92,7 @@ impl Parse for Factor { impl ToComputedValue for Factor { /// This should actually be `ComputedNumberOrPercentage`, but layout uses - /// `computed::effects::FilterList` directly in `StackingContext`. + /// `computed::effects::Filter` directly in `StackingContext`. type ComputedValue = ComputedNumber; #[inline] diff --git a/components/style/values/specified/mod.rs b/components/style/values/specified/mod.rs index 63063163f4b9..a8be8583576c 100644 --- a/components/style/values/specified/mod.rs +++ b/components/style/values/specified/mod.rs @@ -33,7 +33,7 @@ pub use self::background::BackgroundSize; pub use self::border::{BorderCornerRadius, BorderImageSlice, BorderImageWidth}; pub use self::border::{BorderImageSideWidth, BorderRadius, BorderSideWidth}; pub use self::color::{Color, RGBAColor}; -pub use self::effects::FilterList; +pub use self::effects::Filter; pub use self::flex::FlexBasis; #[cfg(feature = "gecko")] pub use self::gecko::ScrollSnapPoint;