diff options
author | Emilio Cobos Álvarez <emilio@crisal.io> | 2019-05-16 23:03:29 +0000 |
---|---|---|
committer | Emilio Cobos Álvarez <emilio@crisal.io> | 2019-05-29 16:14:10 +0200 |
commit | bbc77e39773e7c3ca37e177998d3e4c4059ac5c4 (patch) | |
tree | a977400d31a874c06b2467d11d906c0288abbef2 | |
parent | 2bc4c42d4533db11759b49a2159082343f34ec52 (diff) | |
download | servo-bbc77e39773e7c3ca37e177998d3e4c4059ac5c4.tar.gz servo-bbc77e39773e7c3ca37e177998d3e4c4059ac5c4.zip |
style: Share computed and specified value representation of -moz-context-properties.
Differential Revision: https://phabricator.services.mozilla.com/D30545
-rw-r--r-- | components/style/gecko_string_cache/mod.rs | 1 | ||||
-rw-r--r-- | components/style/properties/gecko.mako.rs | 60 | ||||
-rw-r--r-- | components/style/properties/longhands/inherited_svg.mako.rs | 6 | ||||
-rw-r--r-- | components/style/values/mod.rs | 1 | ||||
-rw-r--r-- | components/style/values/specified/svg.rs | 81 | ||||
-rw-r--r-- | components/style_traits/arc_slice.rs | 10 |
6 files changed, 89 insertions, 70 deletions
diff --git a/components/style/gecko_string_cache/mod.rs b/components/style/gecko_string_cache/mod.rs index d71d192166a..b8f3ff7f048 100644 --- a/components/style/gecko_string_cache/mod.rs +++ b/components/style/gecko_string_cache/mod.rs @@ -53,6 +53,7 @@ macro_rules! local_name { /// This is either a strong reference to a dynamic atom (an nsAtom pointer), /// or an offset from gGkAtoms to the nsStaticAtom object. #[derive(Eq, PartialEq)] +#[repr(C)] pub struct Atom(usize); /// An atom *without* a strong reference. diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index 2f223fd971a..79a258b2d9a 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -303,14 +303,14 @@ impl ${style_struct.gecko_struct_name} { <%def name="impl_simple_clone(ident, gecko_ffi_name)"> #[allow(non_snake_case)] pub fn clone_${ident}(&self) -> longhands::${ident}::computed_value::T { - From::from(self.gecko.${gecko_ffi_name}) + From::from(self.gecko.${gecko_ffi_name}.clone()) } </%def> <%def name="impl_simple_copy(ident, gecko_ffi_name, *kwargs)"> #[allow(non_snake_case)] pub fn copy_${ident}_from(&mut self, other: &Self) { - self.gecko.${gecko_ffi_name} = other.gecko.${gecko_ffi_name}; + self.gecko.${gecko_ffi_name} = other.gecko.${gecko_ffi_name}.clone(); } #[allow(non_snake_case)] @@ -4120,7 +4120,7 @@ clip-path </%self:impl_trait> <%self:impl_trait style_struct_name="InheritedSVG" - skip_longhands="paint-order stroke-dasharray -moz-context-properties"> + skip_longhands="paint-order stroke-dasharray"> pub fn set_paint_order(&mut self, v: longhands::paint_order::computed_value::T) { self.gecko.mPaintOrder = v.0; } @@ -4180,60 +4180,6 @@ clip-path } SVGStrokeDashArray::Values(self.gecko.mStrokeDasharray.iter().cloned().collect()) } - - #[allow(non_snake_case)] - pub fn _moz_context_properties_count(&self) -> usize { - self.gecko.mContextProps.len() - } - - // FIXME(emilio): Remove by sharing representation. - #[allow(non_snake_case)] - pub fn clone__moz_context_properties(&self) -> longhands::_moz_context_properties::computed_value::T { - use crate::values::specified::svg::MozContextProperties; - let buf = self.gecko.mContextProps.iter().map(|v| { - MozContextProperties(CustomIdent(unsafe { Atom::from_raw(v.mRawPtr) })) - }).collect::<Vec<_>>(); - longhands::_moz_context_properties::computed_value::List(crate::ArcSlice::from_iter(buf.into_iter())) - } - - #[allow(non_snake_case)] - pub fn set__moz_context_properties<I>(&mut self, v: I) - where - I: IntoIterator<Item = longhands::_moz_context_properties::computed_value::single_value::T>, - I::IntoIter: ExactSizeIterator - { - let v = v.into_iter(); - unsafe { - bindings::Gecko_nsStyleSVG_SetContextPropertiesLength(&mut *self.gecko, v.len() as u32); - } - - let s = &mut *self.gecko; - s.mContextPropsBits = 0; - for (gecko, servo) in s.mContextProps.iter_mut().zip(v) { - if (servo.0).0 == atom!("fill") { - s.mContextPropsBits |= structs::NS_STYLE_CONTEXT_PROPERTY_FILL as u8; - } else if (servo.0).0 == atom!("stroke") { - s.mContextPropsBits |= structs::NS_STYLE_CONTEXT_PROPERTY_STROKE as u8; - } else if (servo.0).0 == atom!("fill-opacity") { - s.mContextPropsBits |= structs::NS_STYLE_CONTEXT_PROPERTY_FILL_OPACITY as u8; - } else if (servo.0).0 == atom!("stroke-opacity") { - s.mContextPropsBits |= structs::NS_STYLE_CONTEXT_PROPERTY_STROKE_OPACITY as u8; - } - gecko.mRawPtr = (servo.0).0.into_addrefed(); - } - } - - #[allow(non_snake_case)] - pub fn copy__moz_context_properties_from(&mut self, other: &Self) { - unsafe { - bindings::Gecko_nsStyleSVG_CopyContextProperties(&mut *self.gecko, &*other.gecko); - } - } - - #[allow(non_snake_case)] - pub fn reset__moz_context_properties(&mut self, other: &Self) { - self.copy__moz_context_properties_from(other) - } </%self:impl_trait> <%self:impl_trait style_struct_name="Color"> diff --git a/components/style/properties/longhands/inherited_svg.mako.rs b/components/style/properties/longhands/inherited_svg.mako.rs index b4ad07f4dc0..c3e16ee475f 100644 --- a/components/style/properties/longhands/inherited_svg.mako.rs +++ b/components/style/properties/longhands/inherited_svg.mako.rs @@ -194,10 +194,8 @@ ${helpers.predefined_type( ${helpers.predefined_type( "-moz-context-properties", "MozContextProperties", - initial_value=None, - vector=True, - animation_value_type="none", + "computed::MozContextProperties::default()", products="gecko", + animation_value_type="none", spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/-moz-context-properties)", - allow_empty=True, )} diff --git a/components/style/values/mod.rs b/components/style/values/mod.rs index e2da4984084..36ea909ab87 100644 --- a/components/style/values/mod.rs +++ b/components/style/values/mod.rs @@ -174,6 +174,7 @@ impl<A: Debug, B: Debug> Debug for Either<A, B> { ToResolvedValue, ToShmem, )] +#[repr(C)] pub struct CustomIdent(pub Atom); impl CustomIdent { diff --git a/components/style/values/specified/svg.rs b/components/style/values/specified/svg.rs index dd4990782a0..88604924deb 100644 --- a/components/style/values/specified/svg.rs +++ b/components/style/values/specified/svg.rs @@ -12,7 +12,7 @@ use crate::values::specified::AllowQuirks; use crate::values::specified::LengthPercentage; use crate::values::specified::{NonNegativeLengthPercentage, Opacity}; use crate::values::CustomIdent; -use cssparser::Parser; +use cssparser::{Parser, Token}; use std::fmt::{self, Write}; use style_traits::{CommaWithSpace, CssWriter, ParseError, Separator}; use style_traits::{StyleParseErrorKind, ToCss}; @@ -243,11 +243,28 @@ impl ToCss for SVGPaintOrder { } } +bitflags! { + /// The context properties we understand. + #[derive(Default, MallocSizeOf, SpecifiedValueInfo, ToComputedValue, ToResolvedValue, ToShmem)] + #[repr(C)] + pub struct ContextPropertyBits: u8 { + /// `fill` + const FILL = 1 << 0; + /// `stroke` + const STROKE = 1 << 1; + /// `fill-opacity` + const FILL_OPACITY = 1 << 2; + /// `stroke-opacity` + const STROKE_OPACITY = 1 << 3; + } +} + /// Specified MozContextProperties value. /// Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/-moz-context-properties) #[derive( Clone, Debug, + Default, MallocSizeOf, PartialEq, SpecifiedValueInfo, @@ -256,19 +273,65 @@ impl ToCss for SVGPaintOrder { ToResolvedValue, ToShmem, )] -pub struct MozContextProperties(pub CustomIdent); +#[repr(C)] +pub struct MozContextProperties { + #[css(iterable, if_empty = "none")] + #[ignore_malloc_size_of = "Arc"] + idents: crate::ArcSlice<CustomIdent>, + #[css(skip)] + bits: ContextPropertyBits, +} impl Parse for MozContextProperties { fn parse<'i, 't>( _context: &ParserContext, input: &mut Parser<'i, 't>, ) -> Result<MozContextProperties, ParseError<'i>> { - let location = input.current_source_location(); - let i = input.expect_ident()?; - Ok(MozContextProperties(CustomIdent::from_ident( - location, - i, - &["all", "none", "auto"], - )?)) + let mut values = vec![]; + let mut bits = ContextPropertyBits::empty(); + loop { + { + let location = input.current_source_location(); + let ident = input.expect_ident()?; + + if ident.eq_ignore_ascii_case("none") && values.is_empty() { + return Ok(Self::default()); + } + + let ident = CustomIdent::from_ident( + location, + ident, + &["all", "none", "auto"], + )?; + + if ident.0 == atom!("fill") { + bits.insert(ContextPropertyBits::FILL); + } else if ident.0 == atom!("stroke") { + bits.insert(ContextPropertyBits::STROKE); + } else if ident.0 == atom!("fill-opacity") { + bits.insert(ContextPropertyBits::FILL_OPACITY); + } else if ident.0 == atom!("stroke-opacity") { + bits.insert(ContextPropertyBits::STROKE_OPACITY); + } + + values.push(ident); + } + + let location = input.current_source_location(); + match input.next() { + Ok(&Token::Comma) => continue, + Err(..) => break, + Ok(other) => return Err(location.new_unexpected_token_error(other.clone())), + } + } + + if values.is_empty() { + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); + } + + Ok(MozContextProperties { + idents: crate::ArcSlice::from_iter(values.into_iter()), + bits, + }) } } diff --git a/components/style_traits/arc_slice.rs b/components/style_traits/arc_slice.rs index 1541d4be3d9..be50e21c0bb 100644 --- a/components/style_traits/arc_slice.rs +++ b/components/style_traits/arc_slice.rs @@ -85,6 +85,16 @@ impl<T> ArcSlice<T> { mem::forget(self); ret } + + /// Leaks an empty arc slice pointer, and returns it. Only to be used to + /// construct ArcSlices from FFI. + #[inline] + pub fn leaked_empty_ptr() -> *mut std::os::raw::c_void { + let empty: ArcSlice<_> = EMPTY_ARC_SLICE.clone(); + let ptr = empty.0.ptr(); + std::mem::forget(empty); + ptr as *mut _ + } } /// The inner pointer of an ArcSlice<T>, to be sent via FFI. |