diff --git a/components/style/gecko_bindings/sugar/mod.rs b/components/style/gecko_bindings/sugar/mod.rs index de981bd289a..7811cf73d06 100644 --- a/components/style/gecko_bindings/sugar/mod.rs +++ b/components/style/gecko_bindings/sugar/mod.rs @@ -6,8 +6,6 @@ mod ns_com_ptr; mod ns_compatibility; -mod ns_css_shadow_array; -mod ns_css_shadow_item; pub mod ns_css_value; mod ns_style_auto_array; pub mod ns_style_coord; diff --git a/components/style/gecko_bindings/sugar/ns_css_shadow_array.rs b/components/style/gecko_bindings/sugar/ns_css_shadow_array.rs deleted file mode 100644 index c0c6c2d9e36..00000000000 --- a/components/style/gecko_bindings/sugar/ns_css_shadow_array.rs +++ /dev/null @@ -1,78 +0,0 @@ -/* 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 https://mozilla.org/MPL/2.0/. */ - -//! Rust helpers for Gecko's `nsCSSShadowArray`. - -use crate::gecko_bindings::bindings::Gecko_AddRefCSSShadowArrayArbitraryThread; -use crate::gecko_bindings::bindings::Gecko_NewCSSShadowArray; -use crate::gecko_bindings::bindings::Gecko_ReleaseCSSShadowArrayArbitraryThread; -use crate::gecko_bindings::structs::{nsCSSShadowArray, nsCSSShadowItem, RefPtr}; -use std::ops::{Deref, DerefMut}; -use std::{ptr, slice}; - -impl RefPtr { - /// Replaces the current `nsCSSShadowArray` with a new one of len `len`. - pub fn replace_with_new(&mut self, len: u32) { - unsafe { - if !self.mRawPtr.is_null() { - Gecko_ReleaseCSSShadowArrayArbitraryThread(self.mRawPtr); - } - - self.mRawPtr = if len == 0 { - ptr::null_mut() - } else { - Gecko_NewCSSShadowArray(len) - } - } - } - - /// Sets the value to other `nsCSSShadowArray`, bumping and decreasing - /// refcounts as needed. - /// - /// TODO(emilio): Seems like this could move to `refptr.rs`, and be more - /// generic. - pub fn copy_from(&mut self, other: &Self) { - unsafe { - if !self.mRawPtr.is_null() { - Gecko_ReleaseCSSShadowArrayArbitraryThread(self.mRawPtr); - } - if !other.mRawPtr.is_null() { - Gecko_AddRefCSSShadowArrayArbitraryThread(other.mRawPtr); - } - - self.mRawPtr = other.mRawPtr; - } - } -} - -impl Deref for RefPtr { - type Target = [nsCSSShadowItem]; - fn deref(&self) -> &[nsCSSShadowItem] { - if self.mRawPtr.is_null() { - &[] - } else { - unsafe { - slice::from_raw_parts( - (*self.mRawPtr).mArray.as_ptr(), - (*self.mRawPtr).mLength as usize, - ) - } - } - } -} - -impl DerefMut for RefPtr { - fn deref_mut(&mut self) -> &mut [nsCSSShadowItem] { - if self.mRawPtr.is_null() { - &mut [] - } else { - unsafe { - slice::from_raw_parts_mut( - (*self.mRawPtr).mArray.as_mut_ptr(), - (*self.mRawPtr).mLength as usize, - ) - } - } - } -} diff --git a/components/style/gecko_bindings/sugar/ns_css_shadow_item.rs b/components/style/gecko_bindings/sugar/ns_css_shadow_item.rs deleted file mode 100644 index 03d68576dea..00000000000 --- a/components/style/gecko_bindings/sugar/ns_css_shadow_item.rs +++ /dev/null @@ -1,59 +0,0 @@ -/* 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 https://mozilla.org/MPL/2.0/. */ - -//! Rust helpers for Gecko's `nsCSSShadowItem`. - -use crate::gecko_bindings::structs::nsCSSShadowItem; -use crate::values::computed::effects::{BoxShadow, SimpleShadow}; -use app_units::Au; - -impl nsCSSShadowItem { - /// Sets this item from the given box shadow. - #[inline] - pub fn set_from_box_shadow(&mut self, shadow: BoxShadow) { - self.set_from_simple_shadow(shadow.base); - self.mSpread = shadow.spread.to_i32_au(); - self.mInset = shadow.inset; - } - - /// Returns this item as a box shadow. - #[inline] - pub fn to_box_shadow(&self) -> BoxShadow { - BoxShadow { - base: self.extract_simple_shadow(), - spread: Au(self.mSpread).into(), - inset: self.mInset, - } - } - - /// Sets this item from the given simple shadow. - #[inline] - pub fn set_from_simple_shadow(&mut self, shadow: SimpleShadow) { - self.mXOffset = shadow.horizontal.to_i32_au(); - self.mYOffset = shadow.vertical.to_i32_au(); - self.mRadius = shadow.blur.0.to_i32_au(); - self.mSpread = 0; - self.mInset = false; - self.mColor = shadow.color.into(); - } - - /// Gets a simple shadow from this item. - #[inline] - fn extract_simple_shadow(&self) -> SimpleShadow { - SimpleShadow { - color: self.mColor.into(), - horizontal: Au(self.mXOffset).into(), - vertical: Au(self.mYOffset).into(), - blur: Au(self.mRadius).into(), - } - } - - /// Returns this item as a simple shadow. - #[inline] - pub fn to_simple_shadow(&self) -> SimpleShadow { - debug_assert_eq!(self.mSpread, 0); - debug_assert_eq!(self.mInset, false); - self.extract_simple_shadow() - } -} diff --git a/components/style/properties/data.py b/components/style/properties/data.py index ae307077690..12bd3ce38ae 100644 --- a/components/style/properties/data.py +++ b/components/style/properties/data.py @@ -174,6 +174,7 @@ class Longhand(object): logical=False, logical_group=None, alias=None, extra_prefixes=None, boxed=False, flags=None, allowed_in_page_rule=False, allow_quirks=False, ignored_when_colors_disabled=False, + simple_vector_bindings=False, vector=False, servo_restyle_damage="repaint"): self.name = name if not spec: @@ -210,6 +211,7 @@ class Longhand(object): self.allow_quirks = allow_quirks self.ignored_when_colors_disabled = ignored_when_colors_disabled self.is_vector = vector + self.simple_vector_bindings = simple_vector_bindings # https://drafts.csswg.org/css-animations/#keyframes # > The inside of accepts any CSS property diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index 6f37f889e6b..85befa09a3c 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -28,7 +28,6 @@ use crate::gecko_bindings::bindings::Gecko_CopyListStyleImageFrom; use crate::gecko_bindings::bindings::Gecko_EnsureImageLayersLength; use crate::gecko_bindings::bindings::Gecko_SetCursorArrayLength; use crate::gecko_bindings::bindings::Gecko_SetCursorImageValue; -use crate::gecko_bindings::bindings::Gecko_NewCSSShadowArray; use crate::gecko_bindings::bindings::Gecko_nsStyleFont_SetLang; use crate::gecko_bindings::bindings::Gecko_nsStyleFont_CopyLangFrom; use crate::gecko_bindings::bindings::Gecko_SetListStyleImageNone; @@ -56,7 +55,7 @@ use crate::values::{self, CustomIdent, Either, KeyframesName, None_}; use crate::values::computed::{NonNegativeLength, Percentage, TransitionProperty}; use crate::values::computed::BorderStyle; use crate::values::computed::font::FontSize; -use crate::values::computed::effects::{BoxShadow, Filter, SimpleShadow}; +use crate::values::computed::effects::Filter; use crate::values::generics::column::ColumnCount; use crate::values::generics::transform::TransformStyle; use crate::values::generics::url::UrlOrNone; @@ -3455,31 +3454,7 @@ fn static_assert() { <%self:impl_trait style_struct_name="Effects" - skip_longhands="box-shadow clip filter"> - pub fn set_box_shadow(&mut self, v: I) - where I: IntoIterator, - I::IntoIter: ExactSizeIterator - { - let v = v.into_iter(); - self.gecko.mBoxShadow.replace_with_new(v.len() as u32); - for (servo, gecko_shadow) in v.zip(self.gecko.mBoxShadow.iter_mut()) { - gecko_shadow.set_from_box_shadow(servo); - } - } - - pub fn copy_box_shadow_from(&mut self, other: &Self) { - self.gecko.mBoxShadow.copy_from(&other.gecko.mBoxShadow); - } - - pub fn reset_box_shadow(&mut self, other: &Self) { - self.copy_box_shadow_from(other) - } - - pub fn clone_box_shadow(&self) -> longhands::box_shadow::computed_value::T { - let buf = self.gecko.mBoxShadow.iter().map(|v| v.to_box_shadow()).collect(); - longhands::box_shadow::computed_value::List(buf) - } - + skip_longhands="clip filter"> pub fn set_clip(&mut self, v: longhands::clip::computed_value::T) { use crate::gecko_bindings::structs::NS_STYLE_CLIP_AUTO; use crate::gecko_bindings::structs::NS_STYLE_CLIP_RECT; @@ -3603,7 +3578,6 @@ fn static_assert() { I::IntoIter: ExactSizeIterator, { use crate::values::generics::effects::Filter::*; - use crate::gecko_bindings::structs::nsCSSShadowArray; use crate::gecko_bindings::structs::nsStyleFilter; use crate::gecko_bindings::structs::NS_STYLE_FILTER_BLUR; use crate::gecko_bindings::structs::NS_STYLE_FILTER_BRIGHTNESS; @@ -3644,19 +3618,10 @@ fn static_assert() { DropShadow(shadow) => { gecko_filter.mType = NS_STYLE_FILTER_DROP_SHADOW; - - fn init_shadow(filter: &mut nsStyleFilter) -> &mut nsCSSShadowArray { - unsafe { - let ref mut union = filter.__bindgen_anon_1; - let shadow_array: &mut *mut nsCSSShadowArray = union.mDropShadow.as_mut(); - *shadow_array = Gecko_NewCSSShadowArray(1); - - &mut **shadow_array - } + unsafe { + let ref mut union = gecko_filter.__bindgen_anon_1; + ptr::write(union.mDropShadow.as_mut(), shadow); } - - let gecko_shadow = init_shadow(gecko_filter); - gecko_shadow.mArray[0].set_from_simple_shadow(shadow); }, Url(ref url) => { unsafe { @@ -3715,7 +3680,7 @@ fn static_assert() { }, NS_STYLE_FILTER_DROP_SHADOW => { Filter::DropShadow(unsafe { - (**filter.__bindgen_anon_1.mDropShadow.as_ref()).mArray[0].to_simple_shadow() + (*filter.__bindgen_anon_1.mDropShadow.as_ref()).clone() }) }, NS_STYLE_FILTER_URL => { @@ -3761,7 +3726,7 @@ fn static_assert() { <%self:impl_trait style_struct_name="InheritedText" - skip_longhands="text-align text-emphasis-style text-shadow + skip_longhands="text-align text-emphasis-style -webkit-text-stroke-width text-emphasis-position"> <% text_align_keyword = Keyword("text-align", @@ -3769,32 +3734,6 @@ fn static_assert() { gecko_strip_moz_prefix=False) %> ${impl_keyword('text_align', 'mTextAlign', text_align_keyword)} - pub fn set_text_shadow(&mut self, v: I) - where - I: IntoIterator, - I::IntoIter: ExactSizeIterator - { - let v = v.into_iter(); - self.gecko.mTextShadow.replace_with_new(v.len() as u32); - for (servo, gecko_shadow) in v.zip(self.gecko.mTextShadow.iter_mut()) { - gecko_shadow.set_from_simple_shadow(servo); - } - } - - pub fn copy_text_shadow_from(&mut self, other: &Self) { - self.gecko.mTextShadow.copy_from(&other.gecko.mTextShadow); - } - - pub fn reset_text_shadow(&mut self, other: &Self) { - self.copy_text_shadow_from(other) - } - - // FIXME(emilio): Remove by sharing representation. - pub fn clone_text_shadow(&self) -> longhands::text_shadow::computed_value::T { - let iter = self.gecko.mTextShadow.iter().map(|v| v.to_simple_shadow()); - longhands::text_shadow::computed_value::List(crate::ArcSlice::from_iter(iter)) - } - fn clear_text_emphasis_style_if_string(&mut self) { if self.gecko.mTextEmphasisStyle == structs::NS_STYLE_TEXT_EMPHASIS_STYLE_STRING as u8 { self.gecko.mTextEmphasisStyleString.truncate(); diff --git a/components/style/properties/helpers.mako.rs b/components/style/properties/helpers.mako.rs index 808c10b0504..a890534518f 100644 --- a/components/style/properties/helpers.mako.rs +++ b/components/style/properties/helpers.mako.rs @@ -90,12 +90,16 @@ // * computed_value::List is just a convenient alias that you can use for the // computed value list, since this is in the computed_value module. // +// If simple_vector_bindings is true, then we don't use the complex iterator +// machinery and set_foo_from, and just compute the value like any other +// longhand. <%def name="vector_longhand(name, animation_value_type=None, vector_animation_type=None, allow_empty=False, + simple_vector_bindings=False, separator='Comma', **kwargs)"> <%call expr="longhand(name, animation_value_type=animation_value_type, vector=True, - **kwargs)"> + simple_vector_bindings=simple_vector_bindings, **kwargs)"> #[allow(unused_imports)] use smallvec::SmallVec; @@ -237,6 +241,20 @@ } % endif + % if simple_vector_bindings: + impl From for UnderlyingList { + #[inline] + fn from(l: ComputedList) -> Self { + l.0 + } + } + impl From> for ComputedList { + #[inline] + fn from(l: UnderlyingList) -> Self { + List(l) + } + } + % endif % if vector_animation_type: % if not animation_value_type: @@ -345,6 +363,7 @@ pub use self::single_value::SpecifiedValue as SingleSpecifiedValue; + % if not simple_vector_bindings: impl SpecifiedValue { fn compute_iter<'a, 'cx, 'cx_a>( &'a self, @@ -353,6 +372,7 @@ computed_value::Iter::new(context, &self.0) } } + % endif impl ToComputedValue for SpecifiedValue { type ComputedValue = computed_value::T; @@ -473,7 +493,7 @@ .set_writing_mode_dependency(context.builder.writing_mode); % endif - % if property.is_vector: + % if property.is_vector and not property.simple_vector_bindings: // In the case of a vector property we want to pass down an // iterator so that this can be computed without allocation. // diff --git a/components/style/properties/longhands/effects.mako.rs b/components/style/properties/longhands/effects.mako.rs index 0b3f96f0dde..aead5f56508 100644 --- a/components/style/properties/longhands/effects.mako.rs +++ b/components/style/properties/longhands/effects.mako.rs @@ -23,6 +23,7 @@ ${helpers.predefined_type( "BoxShadow", None, vector=True, + simple_vector_bindings=True, animation_value_type="AnimatedBoxShadowList", vector_animation_type="with_zero", extra_prefixes="webkit", diff --git a/components/style/properties/longhands/inherited_text.mako.rs b/components/style/properties/longhands/inherited_text.mako.rs index cdd7df93256..b864bc483f9 100644 --- a/components/style/properties/longhands/inherited_text.mako.rs +++ b/components/style/properties/longhands/inherited_text.mako.rs @@ -218,6 +218,7 @@ ${helpers.predefined_type( vector_animation_type="with_zero", animation_value_type="AnimatedTextShadowList", ignored_when_colors_disabled=True, + simple_vector_bindings=True, flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER", spec="https://drafts.csswg.org/css-text-decor-3/#text-shadow-property", )} diff --git a/components/style/properties/properties.mako.rs b/components/style/properties/properties.mako.rs index a9fa35ba444..1e92066c765 100644 --- a/components/style/properties/properties.mako.rs +++ b/components/style/properties/properties.mako.rs @@ -3444,7 +3444,7 @@ impl<'a> StyleBuilder<'a> { } % endif - % if not property.is_vector: + % if not property.is_vector or property.simple_vector_bindings: /// Set the `${property.ident}` to the computed value `value`. #[allow(non_snake_case)] pub fn set_${property.ident}( diff --git a/components/style/values/animated/effects.rs b/components/style/values/animated/effects.rs index 87f58fb2f82..2f11e1b994d 100644 --- a/components/style/values/animated/effects.rs +++ b/components/style/values/animated/effects.rs @@ -9,22 +9,18 @@ use crate::values::computed::length::Length; #[cfg(feature = "gecko")] use crate::values::computed::url::ComputedUrl; use crate::values::computed::{Angle, Number}; -use crate::values::generics::effects::BoxShadow as GenericBoxShadow; use crate::values::generics::effects::Filter as GenericFilter; use crate::values::generics::effects::SimpleShadow as GenericSimpleShadow; #[cfg(not(feature = "gecko"))] use crate::values::Impossible; -/// An animated value for a single `box-shadow`. -pub type BoxShadow = GenericBoxShadow; +/// An animated value for the `drop-shadow()` filter. +type AnimatedSimpleShadow = GenericSimpleShadow; /// An animated value for a single `filter`. #[cfg(feature = "gecko")] -pub type Filter = GenericFilter; +pub type Filter = GenericFilter; /// An animated value for a single `filter`. #[cfg(not(feature = "gecko"))] pub type Filter = GenericFilter; - -/// An animated value for the `drop-shadow()` filter. -pub type SimpleShadow = GenericSimpleShadow; diff --git a/components/style/values/generics/effects.rs b/components/style/values/generics/effects.rs index aa56fc1bbb3..a27adc49e52 100644 --- a/components/style/values/generics/effects.rs +++ b/components/style/values/generics/effects.rs @@ -19,9 +19,10 @@ ToResolvedValue, ToShmem, )] -pub struct BoxShadow { +#[repr(C)] +pub struct GenericBoxShadow { /// The base shadow. - pub base: SimpleShadow, + pub base: GenericSimpleShadow, /// The spread radius. pub spread: ShapeLength, /// Whether this is an inset box shadow. @@ -30,6 +31,8 @@ pub struct BoxShadow { pub inset: bool, } +pub use self::GenericBoxShadow as BoxShadow; + /// A generic value for a single `filter`. #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] #[animation(no_bound(Url))] @@ -100,7 +103,8 @@ pub enum Filter { ToResolvedValue, ToShmem, )] -pub struct SimpleShadow { +#[repr(C)] +pub struct GenericSimpleShadow { /// Color. pub color: Color, /// Horizontal radius. @@ -110,3 +114,5 @@ pub struct SimpleShadow { /// Blur radius. pub blur: ShapeLength, } + +pub use self::GenericSimpleShadow as SimpleShadow;