diff options
author | Emilio Cobos Álvarez <emilio@crisal.io> | 2019-02-24 10:47:53 -0800 |
---|---|---|
committer | Emilio Cobos Álvarez <emilio@crisal.io> | 2019-03-13 15:08:12 +0100 |
commit | 197065f6bc425592a6d0b59a4e0e13ebe9c12b52 (patch) | |
tree | 4ff619e3109fa72bd664eb57e1df5a140850306a /components/style | |
parent | aad4dac5b422ff107484d7dccbc0f33ce8251755 (diff) | |
download | servo-197065f6bc425592a6d0b59a4e0e13ebe9c12b52.tar.gz servo-197065f6bc425592a6d0b59a4e0e13ebe9c12b52.zip |
style: Use rust lengths for border corners.
The test in https://github.com/web-platform-tests/wpt/pull/15423 hasn't been
synced over yet, but it passes with this patch of course.
Differential Revision: https://phabricator.services.mozilla.com/D20960
Diffstat (limited to 'components/style')
-rw-r--r-- | components/style/cbindgen.toml | 7 | ||||
-rw-r--r-- | components/style/gecko/conversions.rs | 67 | ||||
-rw-r--r-- | components/style/gecko_bindings/sugar/ns_style_coord.rs | 60 | ||||
-rw-r--r-- | components/style/properties/gecko.mako.rs | 61 | ||||
-rw-r--r-- | components/style/values/computed/border.rs | 10 | ||||
-rw-r--r-- | components/style/values/generics/border.rs | 19 | ||||
-rw-r--r-- | components/style/values/generics/size.rs | 1 |
7 files changed, 51 insertions, 174 deletions
diff --git a/components/style/cbindgen.toml b/components/style/cbindgen.toml index 0b8719c4dbf..82ed48ab290 100644 --- a/components/style/cbindgen.toml +++ b/components/style/cbindgen.toml @@ -13,6 +13,7 @@ autogen_warning = """/* DO NOT MODIFY THIS MANUALLY! This file was generated usi class nsAtom; namespace mozilla { class WritingMode; + enum HalfCorner : uint8_t; enum LogicalSide : uint8_t; namespace css { struct URLValue; @@ -88,6 +89,8 @@ include = [ "Position", "BackgroundSize", "BorderImageSlice", + "BorderSpacing", + "BorderRadius", "NonNegativeLengthOrNumberRect", "Perspective", "ZIndex", @@ -185,3 +188,7 @@ item_types = ["enums", "structs", "typedefs"] inline const T& GetIEnd(mozilla::WritingMode) const; inline const T& GetBEnd(mozilla::WritingMode) const; """ + +"GenericBorderRadius" = """ + inline const StyleLengthPercentage& Get(mozilla::HalfCorner) const; +""" diff --git a/components/style/gecko/conversions.rs b/components/style/gecko/conversions.rs index 2a2ae268395..4cbf759c2d8 100644 --- a/components/style/gecko/conversions.rs +++ b/components/style/gecko/conversions.rs @@ -575,17 +575,15 @@ pub mod basic_shape { //! Conversions from and to CSS shape representations. use crate::gecko::values::GeckoStyleCoordConvertible; - use crate::gecko_bindings::structs::{nsStyleCoord, nsStyleCorners}; + use crate::gecko_bindings::structs::nsStyleCoord; use crate::gecko_bindings::structs::{StyleBasicShape, StyleBasicShapeType}; use crate::gecko_bindings::structs::{ StyleGeometryBox, StyleShapeSource, StyleShapeSourceType, }; - use crate::gecko_bindings::sugar::ns_style_coord::{CoordDataMut, CoordDataValue}; use crate::gecko_bindings::sugar::refptr::RefPtr; use crate::values::computed::basic_shape::{ BasicShape, ClippingShape, FloatAreaShape, ShapeRadius, }; - use crate::values::computed::border::{BorderCornerRadius, BorderRadius}; use crate::values::computed::length::LengthPercentage; use crate::values::computed::motion::OffsetPath; use crate::values::computed::url::ComputedUrl; @@ -594,9 +592,7 @@ pub mod basic_shape { }; use crate::values::generics::basic_shape::{Circle, Ellipse, Path, PolygonCoord}; use crate::values::generics::basic_shape::{GeometryBox, ShapeBox, ShapeSource}; - use crate::values::generics::border::BorderRadius as GenericBorderRadius; use crate::values::generics::rect::Rect; - use crate::values::generics::NonNegative; use crate::values::specified::SVGPathData; use std::borrow::Borrow; @@ -706,7 +702,7 @@ pub mod basic_shape { let r = LengthPercentage::from_gecko_style_coord(&other.mCoordinates[1]); let b = LengthPercentage::from_gecko_style_coord(&other.mCoordinates[2]); let l = LengthPercentage::from_gecko_style_coord(&other.mCoordinates[3]); - let round: BorderRadius = (&other.mRadius).into(); + let round = other.mRadius; let round = if round.all_zero() { None } else { Some(round) }; let rect = Rect::new( t.expect("inset() offset should be a length, percentage, or calc value"), @@ -752,65 +748,6 @@ pub mod basic_shape { } } - impl<'a> From<&'a nsStyleCorners> for BorderRadius { - fn from(other: &'a nsStyleCorners) -> Self { - let get_corner = |index| { - BorderCornerRadius::new( - NonNegative( - LengthPercentage::from_gecko_style_coord(&other.data_at(index)).expect( - "<border-radius> should be a length, percentage, or calc value", - ), - ), - NonNegative( - LengthPercentage::from_gecko_style_coord(&other.data_at(index + 1)).expect( - "<border-radius> should be a length, percentage, or calc value", - ), - ), - ) - }; - - GenericBorderRadius { - top_left: get_corner(0), - top_right: get_corner(2), - bottom_right: get_corner(4), - bottom_left: get_corner(6), - } - } - } - - // Can't be a From impl since we need to set an existing - // nsStyleCorners, not create a new one - impl BorderRadius { - /// Set this `BorderRadius` into a given `nsStyleCoord`. - pub fn set_corners(&self, other: &mut nsStyleCorners) { - let mut set_corner = |field: &BorderCornerRadius, index| { - field - .0 - .width() - .to_gecko_style_coord(&mut other.data_at_mut(index)); - field - .0 - .height() - .to_gecko_style_coord(&mut other.data_at_mut(index + 1)); - }; - set_corner(&self.top_left, 0); - set_corner(&self.top_right, 2); - set_corner(&self.bottom_right, 4); - set_corner(&self.bottom_left, 6); - } - } - - /// We use None for a nonexistant radius, but Gecko uses (0 0 0 0 / 0 0 0 0) - pub fn set_corners_from_radius(radius: Option<BorderRadius>, other: &mut nsStyleCorners) { - if let Some(radius) = radius { - radius.set_corners(other); - } else { - for i in 0..8 { - other.data_at_mut(i).set_value(CoordDataValue::Coord(0)); - } - } - } - impl<'a> From<&'a nsStyleCoord> for ShapeRadius { fn from(other: &'a nsStyleCoord) -> Self { let other = other.borrow(); diff --git a/components/style/gecko_bindings/sugar/ns_style_coord.rs b/components/style/gecko_bindings/sugar/ns_style_coord.rs index 4f188297d5e..133ce4d9b7b 100644 --- a/components/style/gecko_bindings/sugar/ns_style_coord.rs +++ b/components/style/gecko_bindings/sugar/ns_style_coord.rs @@ -6,7 +6,7 @@ use crate::gecko_bindings::bindings; use crate::gecko_bindings::structs::{nsStyleCoord, nsStyleCoord_Calc, nsStyleCoord_CalcValue}; -use crate::gecko_bindings::structs::{nsStyleCorners, nsStyleSides}; +use crate::gecko_bindings::structs::nsStyleSides; use crate::gecko_bindings::structs::{nsStyleUnion, nsStyleUnit, nscoord}; use std::mem; @@ -123,64 +123,6 @@ unsafe impl<'a> CoordDataMut for SidesDataMut<'a> { } } -impl nsStyleCorners { - /// Get a `nsStyleCoord` like object representing the given index's value - /// and unit. - #[inline] - pub fn data_at(&self, index: usize) -> CornersData { - CornersData { - corners: self, - index: index, - } - } - - /// Get a `nsStyleCoord` like object representing the mutable given index's - /// value and unit. - #[inline] - pub fn data_at_mut(&mut self, index: usize) -> CornersDataMut { - CornersDataMut { - corners: self, - index: index, - } - } -} - -/// A `nsStyleCoord`-like struct on top of `nsStyleCorners`. -pub struct CornersData<'a> { - corners: &'a nsStyleCorners, - index: usize, -} - -/// A `nsStyleCoord`-like struct on top of a mutable `nsStyleCorners` reference. -pub struct CornersDataMut<'a> { - corners: &'a mut nsStyleCorners, - index: usize, -} - -unsafe impl<'a> CoordData for CornersData<'a> { - fn unit(&self) -> nsStyleUnit { - unsafe { self.corners.get_mUnits()[self.index] } - } - fn union(&self) -> nsStyleUnion { - unsafe { self.corners.get_mValues()[self.index] } - } -} -unsafe impl<'a> CoordData for CornersDataMut<'a> { - fn unit(&self) -> nsStyleUnit { - unsafe { self.corners.get_mUnits()[self.index] } - } - fn union(&self) -> nsStyleUnion { - unsafe { self.corners.get_mValues()[self.index] } - } -} -unsafe impl<'a> CoordDataMut for CornersDataMut<'a> { - unsafe fn values_mut(&mut self) -> (&mut nsStyleUnit, &mut nsStyleUnion) { - let unit = &mut self.corners.get_mUnits_mut()[self.index] as *mut _; - let value = &mut self.corners.get_mValues_mut()[self.index] as *mut _; - (&mut *unit, &mut *value) - } -} - /// Enum representing the tagged union that is CoordData. /// /// In release mode this should never actually exist in the code, and will be diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index b1be315e7a0..65ee8bc1053 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -52,7 +52,7 @@ use crate::rule_tree::StrongRuleNode; use crate::selector_parser::PseudoElement; use servo_arc::{Arc, RawOffsetArc}; use std::marker::PhantomData; -use std::mem::{forget, uninitialized, transmute, zeroed}; +use std::mem::{forget, uninitialized, zeroed}; use std::{cmp, ops, ptr}; use crate::values::{self, CustomIdent, Either, KeyframesName, None_}; use crate::values::computed::{NonNegativeLength, Percentage, TransitionProperty}; @@ -817,34 +817,23 @@ def set_gecko_property(ffi_name, expr): } </%def> -<%def name="impl_corner_style_coord(ident, gecko_ffi_name, x_index, y_index)"> +<%def name="impl_corner_style_coord(ident, gecko_ffi_name, corner)"> #[allow(non_snake_case)] pub fn set_${ident}(&mut self, v: longhands::${ident}::computed_value::T) { - v.0.width().to_gecko_style_coord(&mut self.gecko.${gecko_ffi_name}.data_at_mut(${x_index})); - v.0.height().to_gecko_style_coord(&mut self.gecko.${gecko_ffi_name}.data_at_mut(${y_index})); + self.gecko.${gecko_ffi_name}.${corner} = v; } #[allow(non_snake_case)] pub fn copy_${ident}_from(&mut self, other: &Self) { - self.gecko.${gecko_ffi_name}.data_at_mut(${x_index}) - .copy_from(&other.gecko.${gecko_ffi_name}.data_at(${x_index})); - self.gecko.${gecko_ffi_name}.data_at_mut(${y_index}) - .copy_from(&other.gecko.${gecko_ffi_name}.data_at(${y_index})); + self.gecko.${gecko_ffi_name}.${corner} = + other.gecko.${gecko_ffi_name}.${corner}; } #[allow(non_snake_case)] pub fn reset_${ident}(&mut self, other: &Self) { self.copy_${ident}_from(other) } - #[allow(non_snake_case)] pub fn clone_${ident}(&self) -> longhands::${ident}::computed_value::T { - use crate::values::computed::border::BorderCornerRadius; - let width = GeckoStyleCoordConvertible::from_gecko_style_coord( - &self.gecko.${gecko_ffi_name}.data_at(${x_index})) - .expect("Failed to clone ${ident}"); - let height = GeckoStyleCoordConvertible::from_gecko_style_coord( - &self.gecko.${gecko_ffi_name}.data_at(${y_index})) - .expect("Failed to clone ${ident}"); - BorderCornerRadius::new(width, height) + self.gecko.${gecko_ffi_name}.${corner} } </%def> @@ -1387,14 +1376,6 @@ class Side(object): self.ident = name.lower() self.index = index -class Corner(object): - def __init__(self, vert, horiz, index): - self.x_name = "HalfCorner::eCorner" + vert + horiz + "X" - self.y_name = "HalfCorner::eCorner" + vert + horiz + "Y" - self.ident = (vert + "_" + horiz).lower() - self.x_index = 2 * index - self.y_index = 2 * index + 1 - class GridLine(object): def __init__(self, name): self.ident = "grid-" + name.lower() @@ -1402,19 +1383,12 @@ class GridLine(object): self.gecko = "m" + to_camel_case(self.ident) SIDES = [Side("Top", 0), Side("Right", 1), Side("Bottom", 2), Side("Left", 3)] -CORNERS = [Corner("Top", "Left", 0), Corner("Top", "Right", 1), - Corner("Bottom", "Right", 2), Corner("Bottom", "Left", 3)] +CORNERS = ["top_left", "top_right", "bottom_right", "bottom_left"] GRID_LINES = map(GridLine, ["row-start", "row-end", "column-start", "column-end"]) %> #[allow(dead_code)] fn static_assert() { - unsafe { - % for corner in CORNERS: - transmute::<_, [u32; ${corner.x_index}]>([1; structs::${corner.x_name} as usize]); - transmute::<_, [u32; ${corner.y_index}]>([1; structs::${corner.y_name} as usize]); - % endfor - } // Note: using the above technique with an enum hits a rust bug when |structs| is in a different crate. % for side in SIDES: { const DETAIL: u32 = [0][(structs::Side::eSide${side.name} as usize != ${side.index}) as usize]; let _ = DETAIL; } @@ -1425,7 +1399,7 @@ fn static_assert() { <% skip_border_longhands = " ".join(["border-{0}-{1}".format(x.ident, y) for x in SIDES for y in ["color", "style", "width"]] + - ["border-{0}-radius".format(x.ident.replace("_", "-")) + ["border-{0}-radius".format(x.replace("_", "-")) for x in CORNERS]) %> <%self:impl_trait style_struct_name="Border" @@ -1494,10 +1468,9 @@ fn static_assert() { % endfor % for corner in CORNERS: - <% impl_corner_style_coord("border_%s_radius" % corner.ident, + <% impl_corner_style_coord("border_%s_radius" % corner, "mBorderRadius", - corner.x_index, - corner.y_index) %> + corner) %> % endfor pub fn set_border_image_source(&mut self, image: longhands::border_image_source::computed_value::T) { @@ -2027,7 +2000,7 @@ fn static_assert() { </%self:impl_trait> <% skip_outline_longhands = " ".join("outline-style outline-width".split() + - ["-moz-outline-radius-{0}".format(x.ident.replace("_", "")) + ["-moz-outline-radius-{0}".format(x.replace("_", "")) for x in CORNERS]) %> <%self:impl_trait style_struct_name="Outline" skip_longhands="${skip_outline_longhands}"> @@ -2059,10 +2032,9 @@ fn static_assert() { round_to_pixels=True) %> % for corner in CORNERS: - <% impl_corner_style_coord("_moz_outline_radius_%s" % corner.ident.replace("_", ""), + <% impl_corner_style_coord("_moz_outline_radius_%s" % corner.replace("_", ""), "mOutlineRadius", - corner.x_index, - corner.y_index) %> + corner) %> % endfor pub fn outline_has_nonzero_width(&self) -> bool { @@ -4593,7 +4565,6 @@ fn set_style_svg_path( use crate::gecko_bindings::bindings::{Gecko_NewBasicShape, Gecko_DestroyShapeSource}; use crate::gecko_bindings::structs::{StyleBasicShape, StyleBasicShapeType, StyleShapeSourceType}; use crate::gecko_bindings::structs::{StyleGeometryBox, StyleShapeSource}; - use crate::gecko::conversions::basic_shape::set_corners_from_radius; use crate::gecko::values::GeckoStyleCoordConvertible; use crate::values::generics::basic_shape::{BasicShape, ShapeSource}; @@ -4658,8 +4629,10 @@ fn set_style_svg_path( inset.rect.2.to_gecko_style_coord(&mut shape.mCoordinates[2]); shape.mCoordinates[3].leaky_set_null(); inset.rect.3.to_gecko_style_coord(&mut shape.mCoordinates[3]); - - set_corners_from_radius(inset.round, &mut shape.mRadius); + shape.mRadius = match inset.round { + Some(radius) => radius, + None => crate::values::computed::BorderRadius::zero(), + }; } BasicShape::Circle(circ) => { let shape = init_shape(${ident}, StyleBasicShapeType::Circle); diff --git a/components/style/values/computed/border.rs b/components/style/values/computed/border.rs index 7b42dd0e879..0d4862ee469 100644 --- a/components/style/values/computed/border.rs +++ b/components/style/values/computed/border.rs @@ -87,6 +87,16 @@ impl BorderCornerRadius { } impl BorderRadius { + /// Returns a `0` border radius. + pub fn zero() -> Self { + Self { + top_left: BorderCornerRadius::zero(), + top_right: BorderCornerRadius::zero(), + bottom_right: BorderCornerRadius::zero(), + bottom_left: BorderCornerRadius::zero(), + } + } + /// Returns whether all the values are `0px`. pub fn all_zero(&self) -> bool { fn all(corner: &BorderCornerRadius) -> bool { diff --git a/components/style/values/generics/border.rs b/components/style/values/generics/border.rs index 148f74e3834..bfc7ac5814a 100644 --- a/components/style/values/generics/border.rs +++ b/components/style/values/generics/border.rs @@ -53,7 +53,10 @@ pub use self::GenericBorderImageSlice as BorderImageSlice; ToComputedValue, ToCss, )] -pub struct BorderCornerRadius<L>(#[css(field_bound)] pub Size2D<L>); +#[repr(C)] +pub struct GenericBorderCornerRadius<L>(#[css(field_bound)] pub Size2D<L>); + +pub use self::GenericBorderCornerRadius as BorderCornerRadius; impl<L> BorderCornerRadius<L> { /// Trivially create a `BorderCornerRadius`. @@ -77,6 +80,7 @@ impl<L> BorderCornerRadius<L> { ToComputedValue, ToCss, )] +#[repr(transparent)] pub struct BorderSpacing<L>(#[css(field_bound)] pub Size2D<L>); impl<L> BorderSpacing<L> { @@ -101,17 +105,20 @@ impl<L> BorderSpacing<L> { ToAnimatedValue, ToComputedValue, )] -pub struct BorderRadius<LengthPercentage> { +#[repr(C)] +pub struct GenericBorderRadius<LengthPercentage> { /// The top left radius. - pub top_left: BorderCornerRadius<LengthPercentage>, + pub top_left: GenericBorderCornerRadius<LengthPercentage>, /// The top right radius. - pub top_right: BorderCornerRadius<LengthPercentage>, + pub top_right: GenericBorderCornerRadius<LengthPercentage>, /// The bottom right radius. - pub bottom_right: BorderCornerRadius<LengthPercentage>, + pub bottom_right: GenericBorderCornerRadius<LengthPercentage>, /// The bottom left radius. - pub bottom_left: BorderCornerRadius<LengthPercentage>, + pub bottom_left: GenericBorderCornerRadius<LengthPercentage>, } +pub use self::GenericBorderRadius as BorderRadius; + impl<L> BorderRadius<L> { /// Returns a new `BorderRadius<L>`. #[inline] diff --git a/components/style/values/generics/size.rs b/components/style/values/generics/size.rs index c67d6e82781..28c1ed5a36b 100644 --- a/components/style/values/generics/size.rs +++ b/components/style/values/generics/size.rs @@ -25,6 +25,7 @@ use style_traits::{CssWriter, ParseError, ToCss}; ToComputedValue, )] #[allow(missing_docs)] +#[repr(C)] pub struct Size2D<L> { pub width: L, pub height: L, |