aboutsummaryrefslogtreecommitdiffstats
path: root/components/style
diff options
context:
space:
mode:
authorEmilio Cobos Álvarez <emilio@crisal.io>2019-02-24 10:47:53 -0800
committerEmilio Cobos Álvarez <emilio@crisal.io>2019-03-13 15:08:12 +0100
commit197065f6bc425592a6d0b59a4e0e13ebe9c12b52 (patch)
tree4ff619e3109fa72bd664eb57e1df5a140850306a /components/style
parentaad4dac5b422ff107484d7dccbc0f33ce8251755 (diff)
downloadservo-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.toml7
-rw-r--r--components/style/gecko/conversions.rs67
-rw-r--r--components/style/gecko_bindings/sugar/ns_style_coord.rs60
-rw-r--r--components/style/properties/gecko.mako.rs61
-rw-r--r--components/style/values/computed/border.rs10
-rw-r--r--components/style/values/generics/border.rs19
-rw-r--r--components/style/values/generics/size.rs1
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,