aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEmilio Cobos Álvarez <emilio@crisal.io>2019-05-16 23:03:29 +0000
committerEmilio Cobos Álvarez <emilio@crisal.io>2019-05-29 16:14:10 +0200
commitbbc77e39773e7c3ca37e177998d3e4c4059ac5c4 (patch)
treea977400d31a874c06b2467d11d906c0288abbef2
parent2bc4c42d4533db11759b49a2159082343f34ec52 (diff)
downloadservo-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.rs1
-rw-r--r--components/style/properties/gecko.mako.rs60
-rw-r--r--components/style/properties/longhands/inherited_svg.mako.rs6
-rw-r--r--components/style/values/mod.rs1
-rw-r--r--components/style/values/specified/svg.rs81
-rw-r--r--components/style_traits/arc_slice.rs10
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.