From 8dad956513eba5cea9ce895c6f5351ff9f95c835 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Sat, 26 Jan 2019 11:00:44 +0100 Subject: [PATCH] style: Use Rust lengths for margin / padding / inset. Also for the intersection observer root margin, since it was easier to fix it up and clean it up than not doing it. This is the first big step to get rid of nscoord. It duplicates a bit of logic in nsLayoutUtils since for now max/min-width/height are still represented with nsStyleCoord, but I think I prefer to land this incrementally. I didn't add helpers for the physical accessors of the style rect sides that nsStyleSides has (top/bottom/left/right) since I think we generally should encourage the logical versions, but let me know if you want me to do that. Differential Revision: https://phabricator.services.mozilla.com/D17739 --- components/style/cbindgen.toml | 30 +++++++- components/style/properties/gecko.mako.rs | 9 +-- components/style/values/computed/length.rs | 1 + components/style/values/generics/rect.rs | 1 + components/style/values/specified/gecko.rs | 87 ++++++++-------------- 5 files changed, 64 insertions(+), 64 deletions(-) diff --git a/components/style/cbindgen.toml b/components/style/cbindgen.toml index 25f88f64b3a..d76a57c9541 100644 --- a/components/style/cbindgen.toml +++ b/components/style/cbindgen.toml @@ -9,11 +9,15 @@ autogen_warning = """/* DO NOT MODIFY THIS MANUALLY! This file was generated usi */ #include "nsCoord.h" #include "Units.h" +#include "mozilla/gfx/Types.h" class nsAtom; namespace mozilla { + class WritingMode; + enum LogicalSide : uint8_t; namespace css { struct URLValue; } + // Work-around weird cbindgen renaming. typedef css::URLValue StyleURLValue; typedef nsAtom StylensAtom; @@ -71,13 +75,17 @@ include = [ "Resize", "Overflow", "LengthPercentage", + "NonNegativeLengthPercentage", + "LengthPercentageOrAuto", + "Rect", + "IntersectionObserverRootMargin", ] item_types = ["enums", "structs", "typedefs"] [export.body] "LengthPercentage" = """ // Defined in nsStyleCoord.h - static inline StyleLengthPercentage Zero(); + static constexpr inline StyleLengthPercentage Zero(); inline bool HasPercent() const; inline bool ConvertsToLength() const; inline nscoord ToLength() const; @@ -90,3 +98,23 @@ item_types = ["enums", "structs", "typedefs"] inline nscoord Resolve(nscoord aPercentageBasis) const; template inline nscoord ResolveWith(T aPercentageGetter) const; """ + +"LengthPercentageOrAuto" = """ + inline const StyleLengthPercentage& AsLengthPercentage() const; + inline bool HasPercent() const; + inline bool ConvertsToLength() const; +""" + +"Rect" = """ + // Defined in nsStyleCoord.h + template inline bool All(Predicate) const; + template inline bool Any(Predicate) const; + + // Defined in WritingModes.h + inline const T& Get(mozilla::Side) const; + inline const T& Get(mozilla::WritingMode, mozilla::LogicalSide) const; + inline const T& GetIStart(mozilla::WritingMode) const; + inline const T& GetBStart(mozilla::WritingMode) const; + inline const T& GetIEnd(mozilla::WritingMode) const; + inline const T& GetBEnd(mozilla::WritingMode) const; +""" diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index a11d08ba44f..798e39adb27 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -772,11 +772,12 @@ def set_gecko_property(ffi_name, expr): <%def name="impl_split_style_coord(ident, gecko_ffi_name, index)"> #[allow(non_snake_case)] pub fn set_${ident}(&mut self, v: longhands::${ident}::computed_value::T) { - v.to_gecko_style_coord(&mut self.gecko.${gecko_ffi_name}.data_at_mut(${index})); + self.gecko.${gecko_ffi_name}.${index} = v; } #[allow(non_snake_case)] pub fn copy_${ident}_from(&mut self, other: &Self) { - self.gecko.${gecko_ffi_name}.data_at_mut(${index}).copy_from(&other.gecko.${gecko_ffi_name}.data_at(${index})); + self.gecko.${gecko_ffi_name}.${index} = + other.gecko.${gecko_ffi_name}.${index}; } #[allow(non_snake_case)] pub fn reset_${ident}(&mut self, other: &Self) { @@ -785,9 +786,7 @@ def set_gecko_property(ffi_name, expr): #[allow(non_snake_case)] pub fn clone_${ident}(&self) -> longhands::${ident}::computed_value::T { - use crate::properties::longhands::${ident}::computed_value::T; - T::from_gecko_style_coord(&self.gecko.${gecko_ffi_name}.data_at(${index})) - .expect("clone for ${ident} failed") + self.gecko.${gecko_ffi_name}.${index} } diff --git a/components/style/values/computed/length.rs b/components/style/values/computed/length.rs index ae585695506..c779594202b 100644 --- a/components/style/values/computed/length.rs +++ b/components/style/values/computed/length.rs @@ -457,6 +457,7 @@ impl IsZeroLength for LengthPercentage { #[derive( Animate, Clone, ComputeSquaredDistance, Copy, MallocSizeOf, PartialEq, ToAnimatedZero, ToCss, )] +#[repr(C, u8)] pub enum LengthPercentageOrAuto { LengthPercentage(LengthPercentage), Auto, diff --git a/components/style/values/generics/rect.rs b/components/style/values/generics/rect.rs index 985a9c4a320..de7237e694d 100644 --- a/components/style/values/generics/rect.rs +++ b/components/style/values/generics/rect.rs @@ -23,6 +23,7 @@ use style_traits::{CssWriter, ParseError, ToCss}; ToAnimatedValue, ToComputedValue, )] +#[repr(C)] pub struct Rect(pub T, pub T, pub T, pub T); impl Rect { diff --git a/components/style/values/specified/gecko.rs b/components/style/values/specified/gecko.rs index 02bd5505123..8259430bf20 100644 --- a/components/style/values/specified/gecko.rs +++ b/components/style/values/specified/gecko.rs @@ -4,21 +4,19 @@ //! Specified types for legacy Gecko-only properties. -use crate::gecko::values::GeckoStyleCoordConvertible; -use crate::gecko_bindings::sugar::ns_style_coord::{CoordData, CoordDataMut}; use crate::parser::{Parse, ParserContext}; -use crate::values::computed; +use crate::values::computed::{self, LengthPercentage}; use crate::values::computed::length::CSSPixelLength; use crate::values::generics::gecko::ScrollSnapPoint as GenericScrollSnapPoint; use crate::values::generics::rect::Rect; -use crate::values::specified::length::LengthPercentage; +use crate::values::specified::length::LengthPercentage as SpecifiedLengthPercentage; use cssparser::{Parser, Token}; use std::fmt; use style_traits::values::SequenceWriter; use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss}; /// A specified type for scroll snap points. -pub type ScrollSnapPoint = GenericScrollSnapPoint; +pub type ScrollSnapPoint = GenericScrollSnapPoint; impl Parse for ScrollSnapPoint { fn parse<'i, 't>( @@ -29,62 +27,34 @@ impl Parse for ScrollSnapPoint { return Ok(GenericScrollSnapPoint::None); } input.expect_function_matching("repeat")?; + // FIXME(emilio): This won't clamp properly when animating. let length = - input.parse_nested_block(|i| LengthPercentage::parse_non_negative(context, i))?; + input.parse_nested_block(|i| SpecifiedLengthPercentage::parse_non_negative(context, i))?; Ok(GenericScrollSnapPoint::Repeat(length)) } } -/// A component of an IntersectionObserverRootMargin. -#[derive(Clone, Copy, Debug, PartialEq, ToCss)] -pub enum PixelOrPercentage { - /// An absolute length in pixels (px) - Pixel(CSSPixelLength), - /// A percentage (%) - Percentage(computed::Percentage), -} - -impl Parse for PixelOrPercentage { - fn parse<'i, 't>( - _context: &ParserContext, - input: &mut Parser<'i, 't>, - ) -> Result> { - let location = input.current_source_location(); - let token = input.next()?; - let value = match *token { - Token::Dimension { - value, ref unit, .. - } => { - match_ignore_ascii_case! { unit, - "px" => Ok(PixelOrPercentage::Pixel(CSSPixelLength::new(value))), - _ => Err(()), - } - }, - Token::Percentage { unit_value, .. } => Ok(PixelOrPercentage::Percentage( - computed::Percentage(unit_value), - )), - _ => Err(()), - }; - value.map_err(|()| location.new_custom_error(StyleParseErrorKind::UnspecifiedError)) - } -} - -impl GeckoStyleCoordConvertible for PixelOrPercentage { - fn to_gecko_style_coord(&self, coord: &mut T) { - match *self { - PixelOrPercentage::Pixel(ref l) => l.to_gecko_style_coord(coord), - PixelOrPercentage::Percentage(ref pc) => pc.to_gecko_style_coord(coord), - } - } - - fn from_gecko_style_coord(coord: &T) -> Option { - CSSPixelLength::from_gecko_style_coord(coord) - .map(PixelOrPercentage::Pixel) - .or_else(|| { - computed::Percentage::from_gecko_style_coord(coord) - .map(PixelOrPercentage::Percentage) - }) - } +fn parse_pixel_or_percent<'i, 't>( + _context: &ParserContext, + input: &mut Parser<'i, 't>, +) -> Result> { + let location = input.current_source_location(); + let token = input.next()?; + let value = match *token { + Token::Dimension { + value, ref unit, .. + } => { + match_ignore_ascii_case! { unit, + "px" => Ok(LengthPercentage::new(CSSPixelLength::new(value), None)), + _ => Err(()), + } + }, + Token::Percentage { unit_value, .. } => Ok( + LengthPercentage::new_percent(computed::Percentage(unit_value)) + ), + _ => Err(()), + }; + value.map_err(|()| location.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } /// The value of an IntersectionObserver's rootMargin property. @@ -93,14 +63,15 @@ impl GeckoStyleCoordConvertible for PixelOrPercentage { /// calc() values are not allowed. /// /// -pub struct IntersectionObserverRootMargin(pub Rect); +#[repr(transparent)] +pub struct IntersectionObserverRootMargin(pub Rect); impl Parse for IntersectionObserverRootMargin { fn parse<'i, 't>( context: &ParserContext, input: &mut Parser<'i, 't>, ) -> Result> { - let rect = Rect::parse_with(context, input, PixelOrPercentage::parse)?; + let rect = Rect::parse_with(context, input, parse_pixel_or_percent)?; Ok(IntersectionObserverRootMargin(rect)) } }