aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/style/gecko_conversions.rs179
-rw-r--r--components/style/gecko_values.rs25
-rw-r--r--components/style/properties/gecko.mako.rs136
-rw-r--r--components/style/values/computed/basic_shape.rs2
-rw-r--r--components/style/values/specified/basic_shape.rs2
-rwxr-xr-xports/geckolib/binding_tools/regen.py5
-rw-r--r--ports/geckolib/gecko_bindings/bindings.rs8
-rw-r--r--ports/geckolib/gecko_bindings/structs_debug.rs49
-rw-r--r--ports/geckolib/gecko_bindings/structs_release.rs49
-rw-r--r--ports/geckolib/gecko_bindings/sugar/ns_style_coord.rs11
-rw-r--r--ports/geckolib/string_cache/atom_macro.rs14
-rw-r--r--tests/unit/style/parsing/basic_shape.rs1
12 files changed, 432 insertions, 49 deletions
diff --git a/components/style/gecko_conversions.rs b/components/style/gecko_conversions.rs
index ede574d181e..4e3a5acf2c9 100644
--- a/components/style/gecko_conversions.rs
+++ b/components/style/gecko_conversions.rs
@@ -79,3 +79,182 @@ impl From<nsStyleCoord_CalcValue> for LengthOrPercentage {
}
}
}
+
+pub mod basic_shape {
+ use euclid::size::Size2D;
+ use gecko_bindings::structs::StyleClipPathGeometryBox;
+ use gecko_bindings::structs::{StyleBasicShape, StyleBasicShapeType, StyleFillRule};
+ use gecko_bindings::structs::{nsStyleCoord, nsStyleCorners, nsStyleImageLayers_Position};
+ use gecko_bindings::sugar::ns_style_coord::{CoordDataMut, CoordDataValue};
+ use gecko_values::GeckoStyleCoordConvertible;
+ use std::borrow::Borrow;
+ use values::computed::basic_shape::*;
+ use values::computed::position::Position;
+ use values::computed::{BorderRadiusSize, LengthOrPercentage};
+
+ // using Borrow so that we can have a non-moving .into()
+ impl<T: Borrow<StyleBasicShape>> From<T> for BasicShape {
+ fn from(other: T) -> Self {
+ let other = other.borrow();
+ match other.mType {
+ StyleBasicShapeType::Inset => {
+ let t = LengthOrPercentage::from_gecko_style_coord(&other.mCoordinates[0]);
+ let r = LengthOrPercentage::from_gecko_style_coord(&other.mCoordinates[1]);
+ let b = LengthOrPercentage::from_gecko_style_coord(&other.mCoordinates[2]);
+ let l = LengthOrPercentage::from_gecko_style_coord(&other.mCoordinates[3]);
+ let round = (&other.mRadius).into();
+ BasicShape::Inset(InsetRect {
+ top: t.expect("inset() offset should be a length, percentage, or calc value"),
+ right: r.expect("inset() offset should be a length, percentage, or calc value"),
+ bottom: b.expect("inset() offset should be a length, percentage, or calc value"),
+ left: l.expect("inset() offset should be a length, percentage, or calc value"),
+ round: Some(round),
+ })
+ }
+ StyleBasicShapeType::Circle => {
+ BasicShape::Circle(Circle {
+ radius: (&other.mCoordinates[0]).into(),
+ position: (&other.mPosition).into()
+ })
+ }
+ StyleBasicShapeType::Ellipse => {
+ BasicShape::Ellipse(Ellipse {
+ semiaxis_x: (&other.mCoordinates[0]).into(),
+ semiaxis_y: (&other.mCoordinates[1]).into(),
+ position: (&other.mPosition).into()
+ })
+ }
+ StyleBasicShapeType::Polygon => {
+ let fill_rule = if other.mFillRule == StyleFillRule::Evenodd {
+ FillRule::EvenOdd
+ } else {
+ FillRule::NonZero
+ };
+ let mut coords = Vec::with_capacity(other.mCoordinates.len() / 2);
+ for i in 0..(other.mCoordinates.len() / 2) {
+ let x = 2 * i;
+ let y = x + 1;
+ coords.push((LengthOrPercentage::from_gecko_style_coord(&other.mCoordinates[x])
+ .expect("polygon() coordinate should be a length, percentage, or calc value"),
+ LengthOrPercentage::from_gecko_style_coord(&other.mCoordinates[y])
+ .expect("polygon() coordinate should be a length, percentage, or calc value")
+ ))
+ }
+ BasicShape::Polygon(Polygon {
+ fill: fill_rule,
+ coordinates: coords,
+ })
+ }
+ }
+ }
+ }
+
+ impl<T: Borrow<nsStyleCorners>> From<T> for BorderRadius {
+ fn from(other: T) -> Self {
+ let other = other.borrow();
+ let get_corner = |index| {
+ BorderRadiusSize(Size2D::new(
+ LengthOrPercentage::from_gecko_style_coord(&other.data_at(index))
+ .expect("<border-radius> should be a length, percentage, or calc value"),
+ LengthOrPercentage::from_gecko_style_coord(&other.data_at(index + 1))
+ .expect("<border-radius> should be a length, percentage, or calc value")))
+ };
+
+ BorderRadius {
+ 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 {
+ pub fn set_corners(&self, other: &mut nsStyleCorners) {
+ let mut set_corner = |field: &BorderRadiusSize, 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));
+ }
+ }
+ }
+
+ // Can't be a From impl since we need to set an existing
+ // nsStyleImageLayers_Position, not create a new one
+ impl From<Position> for nsStyleImageLayers_Position {
+ fn from(other: Position) -> Self {
+ nsStyleImageLayers_Position {
+ mXPosition: other.horizontal.into(),
+ mYPosition: other.vertical.into()
+ }
+ }
+ }
+
+ impl<T: Borrow<nsStyleCoord>> From<T> for ShapeRadius {
+ fn from(other: T) -> Self {
+ let other = other.borrow();
+ ShapeRadius::from_gecko_style_coord(other)
+ .expect("<shape-radius> should be a length, percentage, calc, or keyword value")
+ }
+ }
+
+ impl<T: Borrow<nsStyleImageLayers_Position>> From<T> for Position {
+ fn from(other: T) -> Self {
+ let other = other.borrow();
+ Position {
+ horizontal: other.mXPosition.into(),
+ vertical: other.mYPosition.into(),
+ }
+ }
+ }
+
+ impl From<GeometryBox> for StyleClipPathGeometryBox {
+ fn from(reference: GeometryBox) -> Self {
+ use gecko_bindings::structs::StyleClipPathGeometryBox::*;
+ match reference {
+ GeometryBox::ShapeBox(ShapeBox::Content) => Content,
+ GeometryBox::ShapeBox(ShapeBox::Padding) => Padding,
+ GeometryBox::ShapeBox(ShapeBox::Border) => Border,
+ GeometryBox::ShapeBox(ShapeBox::Margin) => Margin,
+ GeometryBox::Fill => Fill,
+ GeometryBox::Stroke => Stroke,
+ GeometryBox::View => View,
+ }
+ }
+ }
+
+ // Will panic on NoBox
+ // Ideally these would be implemented on Option<T>,
+ // but coherence doesn't like that and TryFrom isn't stable
+ impl From<StyleClipPathGeometryBox> for GeometryBox {
+ fn from(reference: StyleClipPathGeometryBox) -> Self {
+ use gecko_bindings::structs::StyleClipPathGeometryBox::*;
+ match reference {
+ NoBox => panic!("Shouldn't convert NoBox to GeometryBox"),
+ Content => GeometryBox::ShapeBox(ShapeBox::Content),
+ Padding => GeometryBox::ShapeBox(ShapeBox::Padding),
+ Border => GeometryBox::ShapeBox(ShapeBox::Border),
+ Margin => GeometryBox::ShapeBox(ShapeBox::Margin),
+ Fill => GeometryBox::Fill,
+ Stroke => GeometryBox::Stroke,
+ View => GeometryBox::View,
+ }
+ }
+ }
+}
diff --git a/components/style/gecko_values.rs b/components/style/gecko_values.rs
index efbcb7db93e..f3c570f34cc 100644
--- a/components/style/gecko_values.rs
+++ b/components/style/gecko_values.rs
@@ -7,12 +7,13 @@
use app_units::Au;
use cssparser::RGBA;
use gecko_bindings::structs::nsStyleCoord;
+use gecko_bindings::structs::{NS_RADIUS_CLOSEST_SIDE, NS_RADIUS_FARTHEST_SIDE};
use gecko_bindings::sugar::ns_style_coord::{CoordDataValue, CoordData, CoordDataMut};
use std::cmp::max;
use values::computed::Angle;
+use values::computed::basic_shape::ShapeRadius;
use values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto, LengthOrPercentageOrNone};
-
pub trait StyleCoordHelpers {
fn set<T: GeckoStyleCoordConvertible>(&mut self, val: T);
}
@@ -94,6 +95,28 @@ impl GeckoStyleCoordConvertible for LengthOrPercentageOrNone {
}
}
+impl GeckoStyleCoordConvertible for ShapeRadius {
+ fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
+ match *self {
+ ShapeRadius::ClosestSide => {
+ coord.set_value(CoordDataValue::Enumerated(NS_RADIUS_CLOSEST_SIDE))
+ }
+ ShapeRadius::FarthestSide => {
+ coord.set_value(CoordDataValue::Enumerated(NS_RADIUS_FARTHEST_SIDE))
+ }
+ ShapeRadius::Length(lop) => lop.to_gecko_style_coord(coord),
+ }
+ }
+
+ fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> {
+ match coord.as_value() {
+ CoordDataValue::Enumerated(NS_RADIUS_CLOSEST_SIDE) => Some(ShapeRadius::ClosestSide),
+ CoordDataValue::Enumerated(NS_RADIUS_FARTHEST_SIDE) => Some(ShapeRadius::FarthestSide),
+ _ => LengthOrPercentage::from_gecko_style_coord(coord).map(ShapeRadius::Length),
+ }
+ }
+}
+
impl<T: GeckoStyleCoordConvertible> GeckoStyleCoordConvertible for Option<T> {
fn to_gecko_style_coord<U: CoordDataMut>(&self, coord: &mut U) {
if let Some(ref me) = *self {
diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs
index 95cc6de7cb3..ab16ef7c148 100644
--- a/components/style/properties/gecko.mako.rs
+++ b/components/style/properties/gecko.mako.rs
@@ -1265,7 +1265,7 @@ fn static_assert() {
</%self:impl_trait>
<%self:impl_trait style_struct_name="SVG"
- skip_longhands="flood-color lighting-color stop-color"
+ skip_longhands="flood-color lighting-color stop-color clip-path"
skip_additionals="*">
<% impl_color("flood_color", "mFloodColor") %>
@@ -1274,6 +1274,140 @@ fn static_assert() {
<% impl_color("stop_color", "mStopColor") %>
+ pub fn set_clip_path(&mut self, v: longhands::clip_path::computed_value::T) {
+ use gecko_bindings::bindings::{Gecko_NewBasicShape, Gecko_DestroyClipPath};
+ use gecko_bindings::structs::StyleClipPathGeometryBox;
+ use gecko_bindings::structs::{StyleBasicShape, StyleBasicShapeType, StyleShapeSourceType};
+ use gecko_bindings::structs::{StyleClipPath, StyleFillRule};
+ use gecko_conversions::basic_shape::set_corners_from_radius;
+ use gecko_values::GeckoStyleCoordConvertible;
+ use values::computed::basic_shape::*;
+ let ref mut clip_path = self.gecko.mClipPath;
+ // clean up existing struct
+ unsafe { Gecko_DestroyClipPath(clip_path) };
+
+ clip_path.mType = StyleShapeSourceType::None_;
+
+ match v {
+ ShapeSource::Url(..) => println!("stylo: clip-path: url() not yet implemented"),
+ ShapeSource::None => {} // don't change the type
+ ShapeSource::Box(reference) => {
+ clip_path.mReferenceBox = reference.into();
+ clip_path.mType = StyleShapeSourceType::Box;
+ }
+ ShapeSource::Shape(servo_shape, maybe_box) => {
+ clip_path.mReferenceBox = maybe_box.map(Into::into)
+ .unwrap_or(StyleClipPathGeometryBox::NoBox);
+ clip_path.mType = StyleShapeSourceType::Shape;
+
+ fn init_shape(clip_path: &mut StyleClipPath, ty: StyleBasicShapeType) -> &mut StyleBasicShape {
+ unsafe {
+ // We have to be very careful to avoid a copy here!
+ let ref mut union = clip_path.StyleShapeSource_nsStyleStruct_h_unnamed_26;
+ let mut shape: &mut *mut StyleBasicShape = union.mBasicShape.as_mut();
+ *shape = Gecko_NewBasicShape(ty);
+ &mut **shape
+ }
+ }
+ match servo_shape {
+ BasicShape::Inset(rect) => {
+ let mut shape = init_shape(clip_path, StyleBasicShapeType::Inset);
+ unsafe { shape.mCoordinates.set_len(4) };
+
+ // set_len() can't call constructors, so the coordinates
+ // can contain any value. set_value() attempts to free
+ // allocated coordinates, so we don't want to feed it
+ // garbage values which it may misinterpret.
+ // Instead, we use leaky_set_value to blindly overwrite
+ // the garbage data without
+ // attempting to clean up.
+ shape.mCoordinates[0].leaky_set_null();
+ rect.top.to_gecko_style_coord(&mut shape.mCoordinates[0]);
+ shape.mCoordinates[1].leaky_set_null();
+ rect.right.to_gecko_style_coord(&mut shape.mCoordinates[1]);
+ shape.mCoordinates[2].leaky_set_null();
+ rect.bottom.to_gecko_style_coord(&mut shape.mCoordinates[2]);
+ shape.mCoordinates[3].leaky_set_null();
+ rect.left.to_gecko_style_coord(&mut shape.mCoordinates[3]);
+
+ set_corners_from_radius(rect.round, &mut shape.mRadius);
+ }
+ BasicShape::Circle(circ) => {
+ let mut shape = init_shape(clip_path, StyleBasicShapeType::Circle);
+ unsafe { shape.mCoordinates.set_len(1) };
+ shape.mCoordinates[0].leaky_set_null();
+ circ.radius.to_gecko_style_coord(&mut shape.mCoordinates[0]);
+
+ shape.mPosition = circ.position.into();
+ }
+ BasicShape::Ellipse(el) => {
+ let mut shape = init_shape(clip_path, StyleBasicShapeType::Ellipse);
+ unsafe { shape.mCoordinates.set_len(2) };
+ shape.mCoordinates[0].leaky_set_null();
+ el.semiaxis_x.to_gecko_style_coord(&mut shape.mCoordinates[0]);
+ shape.mCoordinates[1].leaky_set_null();
+ el.semiaxis_y.to_gecko_style_coord(&mut shape.mCoordinates[1]);
+
+ shape.mPosition = el.position.into();
+ }
+ BasicShape::Polygon(poly) => {
+ let mut shape = init_shape(clip_path, StyleBasicShapeType::Polygon);
+ unsafe {
+ shape.mCoordinates.set_len(poly.coordinates.len() as u32 * 2);
+ }
+ for (i, coord) in poly.coordinates.iter().enumerate() {
+ shape.mCoordinates[2 * i].leaky_set_null();
+ shape.mCoordinates[2 * i + 1].leaky_set_null();
+ coord.0.to_gecko_style_coord(&mut shape.mCoordinates[2 * i]);
+ coord.1.to_gecko_style_coord(&mut shape.mCoordinates[2 * i + 1]);
+ }
+ shape.mFillRule = if poly.fill == FillRule::EvenOdd {
+ StyleFillRule::Evenodd
+ } else {
+ StyleFillRule::Nonzero
+ };
+ }
+ }
+ }
+ }
+
+ }
+
+ pub fn copy_clip_path_from(&mut self, other: &Self) {
+ use gecko_bindings::bindings::Gecko_CopyClipPathValueFrom;
+ unsafe {
+ Gecko_CopyClipPathValueFrom(&mut self.gecko.mClipPath, &other.gecko.mClipPath);
+ }
+ }
+
+ pub fn clone_clip_path(&self) -> longhands::clip_path::computed_value::T {
+ use gecko_bindings::structs::StyleShapeSourceType;
+ use gecko_bindings::structs::StyleClipPathGeometryBox;
+ use values::computed::basic_shape::*;
+ let ref clip_path = self.gecko.mClipPath;
+
+ match clip_path.mType {
+ StyleShapeSourceType::None_ => ShapeSource::None,
+ StyleShapeSourceType::Box => {
+ ShapeSource::Box(clip_path.mReferenceBox.into())
+ }
+ StyleShapeSourceType::URL => {
+ warn!("stylo: clip-path: url() not implemented yet");
+ Default::default()
+ }
+ StyleShapeSourceType::Shape => {
+ let reference = if let StyleClipPathGeometryBox::NoBox = clip_path.mReferenceBox {
+ None
+ } else {
+ Some(clip_path.mReferenceBox.into())
+ };
+ let union = clip_path.StyleShapeSource_nsStyleStruct_h_unnamed_26;
+ let shape = unsafe { &**union.mBasicShape.as_ref() };
+ ShapeSource::Shape(shape.into(), reference)
+ }
+ }
+ }
+
</%self:impl_trait>
<%self:impl_trait style_struct_name="Color"
diff --git a/components/style/values/computed/basic_shape.rs b/components/style/values/computed/basic_shape.rs
index d9cce727e02..fcb57ad1405 100644
--- a/components/style/values/computed/basic_shape.rs
+++ b/components/style/values/computed/basic_shape.rs
@@ -11,9 +11,9 @@ use cssparser::ToCss;
use properties::shorthands::serialize_four_sides;
use std::fmt;
use url::Url;
+use values::computed::UrlExtraData;
use values::computed::position::Position;
use values::computed::{BorderRadiusSize, LengthOrPercentage};
-use values::computed::UrlExtraData;
pub use values::specified::basic_shape::{FillRule, GeometryBox, ShapeBox};
diff --git a/components/style/values/specified/basic_shape.rs b/components/style/values/specified/basic_shape.rs
index 250ce35c250..b20877c8c43 100644
--- a/components/style/values/specified/basic_shape.rs
+++ b/components/style/values/specified/basic_shape.rs
@@ -14,9 +14,9 @@ use std::fmt;
use url::Url;
use values::computed::basic_shape as computed_basic_shape;
use values::computed::{Context, ToComputedValue, ComputedValueAsSpecified};
+use values::specified::UrlExtraData;
use values::specified::position::Position;
use values::specified::{BorderRadiusSize, LengthOrPercentage, Percentage};
-use values::specified::UrlExtraData;
/// A shape source, for some reference box
///
diff --git a/ports/geckolib/binding_tools/regen.py b/ports/geckolib/binding_tools/regen.py
index ba041fc9200..1a309679bf9 100755
--- a/ports/geckolib/binding_tools/regen.py
+++ b/ports/geckolib/binding_tools/regen.py
@@ -106,8 +106,6 @@ COMPILATION_TARGETS = {
"Maybe", # <- AlignedStorage, which means templated union, which
# means impossible to represent in stable rust as of
# right now.
- # Union handling falls over for templated types.
- "StyleShapeSource", "StyleClipPath", "StyleShapeOutside",
],
},
# Generation of the ffi bindings.
@@ -143,7 +141,8 @@ COMPILATION_TARGETS = {
"nsStyleCoord::Calc", "nsRestyleHint", "ServoElementSnapshot",
"nsChangeHint", "SheetParsingMode", "nsMainThreadPtrHandle",
"nsMainThreadPtrHolder", "nscolor", "nsFont", "FontFamilyList",
- "FontFamilyType", "nsIAtom", "nsStyleContext"
+ "FontFamilyType", "nsIAtom", "nsStyleContext", "StyleClipPath",
+ "StyleBasicShapeType", "StyleBasicShape"
],
"void_types": [
"nsINode", "nsIDocument", "nsIPrincipal", "nsIURI",
diff --git a/ports/geckolib/gecko_bindings/bindings.rs b/ports/geckolib/gecko_bindings/bindings.rs
index 2a330fb21b6..6c428f750a4 100644
--- a/ports/geckolib/gecko_bindings/bindings.rs
+++ b/ports/geckolib/gecko_bindings/bindings.rs
@@ -152,6 +152,9 @@ use structs::nsStyleContext;
unsafe impl Send for nsStyleContext {}
unsafe impl Sync for nsStyleContext {}
impl HeapSizeOf for nsStyleContext { fn heap_size_of_children(&self) -> usize { 0 } }
+use structs::StyleClipPath;
+use structs::StyleBasicShapeType;
+use structs::StyleBasicShape;
pub type RawGeckoNode = nsINode;
pub enum Element { }
@@ -320,6 +323,11 @@ extern "C" {
pub fn Gecko_SetStyleCoordCalcValue(unit: *mut nsStyleUnit,
value: *mut nsStyleUnion,
calc: CalcValue);
+ pub fn Gecko_CopyClipPathValueFrom(dst: *mut StyleClipPath,
+ src: *const StyleClipPath);
+ pub fn Gecko_DestroyClipPath(clip: *mut StyleClipPath);
+ pub fn Gecko_NewBasicShape(type_: StyleBasicShapeType)
+ -> *mut StyleBasicShape;
pub fn Gecko_AddRefCalcArbitraryThread(aPtr: *mut Calc);
pub fn Gecko_ReleaseCalcArbitraryThread(aPtr: *mut Calc);
pub fn Servo_StylesheetFromUTF8Bytes(bytes: *const u8, length: u32,
diff --git a/ports/geckolib/gecko_bindings/structs_debug.rs b/ports/geckolib/gecko_bindings/structs_debug.rs
index aba838068c0..3c36cdb3980 100644
--- a/ports/geckolib/gecko_bindings/structs_debug.rs
+++ b/ports/geckolib/gecko_bindings/structs_debug.rs
@@ -5452,7 +5452,7 @@ fn bindgen_test_layout_nsStyleSides() {
assert_eq!(::std::mem::align_of::<nsStyleSides>() , 8usize);
}
/**
- * Class that represents a set of top-left/top-right/bottom-left/bottom-right
+ * Class that represents a set of top-left/top-right/bottom-right/bottom-left
* nsStyleCoord pairs. This is used to hold the dimensions of the
* corners of a box (for, e.g., border-radius and outline-radius).
*/
@@ -6375,8 +6375,7 @@ fn bindgen_test_layout_StyleAnimation() {
#[repr(C)]
#[derive(Debug)]
pub struct StyleBasicShape {
- pub mRefCnt: nsAutoRefCnt,
- pub _mOwningThread: nsAutoOwningThread,
+ pub mRefCnt: ThreadSafeAutoRefCnt,
pub mType: StyleBasicShapeType,
pub mFillRule: StyleFillRule,
pub mCoordinates: nsTArray<nsStyleCoord>,
@@ -6385,29 +6384,37 @@ pub struct StyleBasicShape {
}
#[test]
fn bindgen_test_layout_StyleBasicShape() {
- assert_eq!(::std::mem::size_of::<StyleBasicShape>() , 128usize);
+ assert_eq!(::std::mem::size_of::<StyleBasicShape>() , 120usize);
assert_eq!(::std::mem::align_of::<StyleBasicShape>() , 8usize);
}
#[repr(C)]
-pub struct StyleShapeSource;
-#[repr(C)]
-pub struct StyleClipPath {
- pub _bindgen_opaque_blob: [u64; 2usize],
-}
-#[test]
-fn bindgen_test_layout_StyleClipPath() {
- assert_eq!(::std::mem::size_of::<StyleClipPath>() , 16usize);
- assert_eq!(::std::mem::align_of::<StyleClipPath>() , 8usize);
+#[derive(Debug)]
+pub struct StyleShapeSource<ReferenceBox> {
+ pub StyleShapeSource_nsStyleStruct_h_unnamed_26: StyleShapeSource_nsStyleStruct_h_unnamed_26<ReferenceBox>,
+ pub mType: StyleShapeSourceType,
+ pub mReferenceBox: ReferenceBox,
}
#[repr(C)]
-pub struct StyleShapeOutside {
- pub _bindgen_opaque_blob: [u64; 2usize],
+#[derive(Debug, Copy, Clone)]
+pub struct StyleShapeSource_nsStyleStruct_h_unnamed_26<ReferenceBox> {
+ pub mBasicShape: __BindgenUnionField<*mut StyleBasicShape>,
+ pub mURL: __BindgenUnionField<*mut FragmentOrURL>,
+ pub _bindgen_data_: u64,
+ pub _phantom0: ::std::marker::PhantomData<ReferenceBox>,
}
-#[test]
-fn bindgen_test_layout_StyleShapeOutside() {
- assert_eq!(::std::mem::size_of::<StyleShapeOutside>() , 16usize);
- assert_eq!(::std::mem::align_of::<StyleShapeOutside>() , 8usize);
+impl <ReferenceBox> StyleShapeSource_nsStyleStruct_h_unnamed_26<ReferenceBox>
+ {
+ pub unsafe fn mBasicShape(&mut self) -> *mut *mut StyleBasicShape {
+ let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_);
+ ::std::mem::transmute(raw.offset(0))
+ }
+ pub unsafe fn mURL(&mut self) -> *mut *mut FragmentOrURL {
+ let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_);
+ ::std::mem::transmute(raw.offset(0))
+ }
}
+pub type StyleClipPath = StyleShapeSource<StyleClipPathGeometryBox>;
+pub type StyleShapeOutside = StyleShapeSource<StyleShapeOutsideShapeBox>;
#[repr(C)]
pub struct nsStyleDisplay {
pub mBinding: RefPtr<URLValue>,
@@ -6461,7 +6468,7 @@ pub struct nsStyleDisplay {
pub mAnimationFillModeCount: u32,
pub mAnimationPlayStateCount: u32,
pub mAnimationIterationCountCount: u32,
- pub mShapeOutside: [u64; 2usize],
+ pub mShapeOutside: StyleShapeOutside,
}
#[test]
fn bindgen_test_layout_nsStyleDisplay() {
@@ -6797,7 +6804,7 @@ fn bindgen_test_layout_nsStyleFilter() {
#[repr(C)]
pub struct nsStyleSVGReset {
pub mMask: nsStyleImageLayers,
- pub mClipPath: [u64; 2usize],
+ pub mClipPath: StyleClipPath,
pub mStopColor: nscolor,
pub mFloodColor: nscolor,
pub mLightingColor: nscolor,
diff --git a/ports/geckolib/gecko_bindings/structs_release.rs b/ports/geckolib/gecko_bindings/structs_release.rs
index 26dc0b01f61..358a0c8cd7d 100644
--- a/ports/geckolib/gecko_bindings/structs_release.rs
+++ b/ports/geckolib/gecko_bindings/structs_release.rs
@@ -5431,7 +5431,7 @@ fn bindgen_test_layout_nsStyleSides() {
assert_eq!(::std::mem::align_of::<nsStyleSides>() , 8usize);
}
/**
- * Class that represents a set of top-left/top-right/bottom-left/bottom-right
+ * Class that represents a set of top-left/top-right/bottom-right/bottom-left
* nsStyleCoord pairs. This is used to hold the dimensions of the
* corners of a box (for, e.g., border-radius and outline-radius).
*/
@@ -6353,8 +6353,7 @@ fn bindgen_test_layout_StyleAnimation() {
#[repr(C)]
#[derive(Debug)]
pub struct StyleBasicShape {
- pub mRefCnt: nsAutoRefCnt,
- pub _mOwningThread: nsAutoOwningThread,
+ pub mRefCnt: ThreadSafeAutoRefCnt,
pub mType: StyleBasicShapeType,
pub mFillRule: StyleFillRule,
pub mCoordinates: nsTArray<nsStyleCoord>,
@@ -6363,29 +6362,37 @@ pub struct StyleBasicShape {
}
#[test]
fn bindgen_test_layout_StyleBasicShape() {
- assert_eq!(::std::mem::size_of::<StyleBasicShape>() , 128usize);
+ assert_eq!(::std::mem::size_of::<StyleBasicShape>() , 120usize);
assert_eq!(::std::mem::align_of::<StyleBasicShape>() , 8usize);
}
#[repr(C)]
-pub struct StyleShapeSource;
-#[repr(C)]
-pub struct StyleClipPath {
- pub _bindgen_opaque_blob: [u64; 2usize],
-}
-#[test]
-fn bindgen_test_layout_StyleClipPath() {
- assert_eq!(::std::mem::size_of::<StyleClipPath>() , 16usize);
- assert_eq!(::std::mem::align_of::<StyleClipPath>() , 8usize);
+#[derive(Debug)]
+pub struct StyleShapeSource<ReferenceBox> {
+ pub StyleShapeSource_nsStyleStruct_h_unnamed_26: StyleShapeSource_nsStyleStruct_h_unnamed_26<ReferenceBox>,
+ pub mType: StyleShapeSourceType,
+ pub mReferenceBox: ReferenceBox,
}
#[repr(C)]
-pub struct StyleShapeOutside {
- pub _bindgen_opaque_blob: [u64; 2usize],
+#[derive(Debug, Copy, Clone)]
+pub struct StyleShapeSource_nsStyleStruct_h_unnamed_26<ReferenceBox> {
+ pub mBasicShape: __BindgenUnionField<*mut StyleBasicShape>,
+ pub mURL: __BindgenUnionField<*mut FragmentOrURL>,
+ pub _bindgen_data_: u64,
+ pub _phantom0: ::std::marker::PhantomData<ReferenceBox>,
}
-#[test]
-fn bindgen_test_layout_StyleShapeOutside() {
- assert_eq!(::std::mem::size_of::<StyleShapeOutside>() , 16usize);
- assert_eq!(::std::mem::align_of::<StyleShapeOutside>() , 8usize);
+impl <ReferenceBox> StyleShapeSource_nsStyleStruct_h_unnamed_26<ReferenceBox>
+ {
+ pub unsafe fn mBasicShape(&mut self) -> *mut *mut StyleBasicShape {
+ let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_);
+ ::std::mem::transmute(raw.offset(0))
+ }
+ pub unsafe fn mURL(&mut self) -> *mut *mut FragmentOrURL {
+ let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_);
+ ::std::mem::transmute(raw.offset(0))
+ }
}
+pub type StyleClipPath = StyleShapeSource<StyleClipPathGeometryBox>;
+pub type StyleShapeOutside = StyleShapeSource<StyleShapeOutsideShapeBox>;
#[repr(C)]
pub struct nsStyleDisplay {
pub mBinding: RefPtr<URLValue>,
@@ -6439,7 +6446,7 @@ pub struct nsStyleDisplay {
pub mAnimationFillModeCount: u32,
pub mAnimationPlayStateCount: u32,
pub mAnimationIterationCountCount: u32,
- pub mShapeOutside: [u64; 2usize],
+ pub mShapeOutside: StyleShapeOutside,
}
#[test]
fn bindgen_test_layout_nsStyleDisplay() {
@@ -6774,7 +6781,7 @@ fn bindgen_test_layout_nsStyleFilter() {
#[repr(C)]
pub struct nsStyleSVGReset {
pub mMask: nsStyleImageLayers,
- pub mClipPath: [u64; 2usize],
+ pub mClipPath: StyleClipPath,
pub mStopColor: nscolor,
pub mFloodColor: nscolor,
pub mLightingColor: nscolor,
diff --git a/ports/geckolib/gecko_bindings/sugar/ns_style_coord.rs b/ports/geckolib/gecko_bindings/sugar/ns_style_coord.rs
index a13f08ea37b..74d20ff3a58 100644
--- a/ports/geckolib/gecko_bindings/sugar/ns_style_coord.rs
+++ b/ports/geckolib/gecko_bindings/sugar/ns_style_coord.rs
@@ -211,6 +211,17 @@ pub trait CoordDataMut : CoordData {
*union = other.union();
}
+ /// Useful for initializing uninits
+ /// (set_value may segfault on uninits)
+ fn leaky_set_null(&mut self) {
+ use structs::nsStyleUnit::*;
+ unsafe {
+ let (unit, union) = self.values_mut();
+ *unit = eStyleUnit_Null;
+ *union.mInt.as_mut() = 0;
+ }
+ }
+
#[inline(always)]
fn set_value(&mut self, value: CoordDataValue) {
use self::CoordDataValue::*;
diff --git a/ports/geckolib/string_cache/atom_macro.rs b/ports/geckolib/string_cache/atom_macro.rs
index 18a49396372..e7ccfca12ad 100644
--- a/ports/geckolib/string_cache/atom_macro.rs
+++ b/ports/geckolib/string_cache/atom_macro.rs
@@ -1172,6 +1172,8 @@ pub enum nsICSSAnonBoxPseudo {}
pub static nsGkAtoms_minheight: *mut nsIAtom;
#[link_name = "_ZN9nsGkAtoms13minimum_scaleE"]
pub static nsGkAtoms_minimum_scale: *mut nsIAtom;
+ #[link_name = "_ZN9nsGkAtoms9minlengthE"]
+ pub static nsGkAtoms_minlength: *mut nsIAtom;
#[link_name = "_ZN9nsGkAtoms6minposE"]
pub static nsGkAtoms_minpos: *mut nsIAtom;
#[link_name = "_ZN9nsGkAtoms9minusSignE"]
@@ -3838,6 +3840,8 @@ pub enum nsICSSAnonBoxPseudo {}
pub static nsGkAtoms_onmozinterruptbegin: *mut nsIAtom;
#[link_name = "_ZN9nsGkAtoms17onmozinterruptendE"]
pub static nsGkAtoms_onmozinterruptend: *mut nsIAtom;
+ #[link_name = "_ZN9nsGkAtoms14ondevicechangeE"]
+ pub static nsGkAtoms_ondevicechange: *mut nsIAtom;
#[link_name = "_ZN9nsGkAtoms12cdataTagNameE"]
pub static nsGkAtoms_cdataTagName: *mut nsIAtom;
#[link_name = "_ZN9nsGkAtoms14commentTagNameE"]
@@ -6083,6 +6087,8 @@ pub enum nsICSSAnonBoxPseudo {}
pub static nsGkAtoms_minheight: *mut nsIAtom;
#[link_name = "?minimum_scale@nsGkAtoms@@2PEAVnsIAtom@@EA"]
pub static nsGkAtoms_minimum_scale: *mut nsIAtom;
+ #[link_name = "?minlength@nsGkAtoms@@2PEAVnsIAtom@@EA"]
+ pub static nsGkAtoms_minlength: *mut nsIAtom;
#[link_name = "?minpos@nsGkAtoms@@2PEAVnsIAtom@@EA"]
pub static nsGkAtoms_minpos: *mut nsIAtom;
#[link_name = "?minusSign@nsGkAtoms@@2PEAVnsIAtom@@EA"]
@@ -8749,6 +8755,8 @@ pub enum nsICSSAnonBoxPseudo {}
pub static nsGkAtoms_onmozinterruptbegin: *mut nsIAtom;
#[link_name = "?onmozinterruptend@nsGkAtoms@@2PEAVnsIAtom@@EA"]
pub static nsGkAtoms_onmozinterruptend: *mut nsIAtom;
+ #[link_name = "?ondevicechange@nsGkAtoms@@2PEAVnsIAtom@@EA"]
+ pub static nsGkAtoms_ondevicechange: *mut nsIAtom;
#[link_name = "?cdataTagName@nsGkAtoms@@2PEAVnsIAtom@@EA"]
pub static nsGkAtoms_cdataTagName: *mut nsIAtom;
#[link_name = "?commentTagName@nsGkAtoms@@2PEAVnsIAtom@@EA"]
@@ -10994,6 +11002,8 @@ pub enum nsICSSAnonBoxPseudo {}
pub static nsGkAtoms_minheight: *mut nsIAtom;
#[link_name = "?minimum_scale@nsGkAtoms@@2PAVnsIAtom@@A"]
pub static nsGkAtoms_minimum_scale: *mut nsIAtom;
+ #[link_name = "?minlength@nsGkAtoms@@2PAVnsIAtom@@A"]
+ pub static nsGkAtoms_minlength: *mut nsIAtom;
#[link_name = "?minpos@nsGkAtoms@@2PAVnsIAtom@@A"]
pub static nsGkAtoms_minpos: *mut nsIAtom;
#[link_name = "?minusSign@nsGkAtoms@@2PAVnsIAtom@@A"]
@@ -13660,6 +13670,8 @@ pub enum nsICSSAnonBoxPseudo {}
pub static nsGkAtoms_onmozinterruptbegin: *mut nsIAtom;
#[link_name = "?onmozinterruptend@nsGkAtoms@@2PAVnsIAtom@@A"]
pub static nsGkAtoms_onmozinterruptend: *mut nsIAtom;
+ #[link_name = "?ondevicechange@nsGkAtoms@@2PAVnsIAtom@@A"]
+ pub static nsGkAtoms_ondevicechange: *mut nsIAtom;
#[link_name = "?cdataTagName@nsGkAtoms@@2PAVnsIAtom@@A"]
pub static nsGkAtoms_cdataTagName: *mut nsIAtom;
#[link_name = "?commentTagName@nsGkAtoms@@2PAVnsIAtom@@A"]
@@ -15332,6 +15344,7 @@ macro_rules! atom {
("min") => { $crate::atom_macro::unsafe_atom_from_static($crate::atom_macro::nsGkAtoms_min as *mut _) };
("minheight") => { $crate::atom_macro::unsafe_atom_from_static($crate::atom_macro::nsGkAtoms_minheight as *mut _) };
("minimum-scale") => { $crate::atom_macro::unsafe_atom_from_static($crate::atom_macro::nsGkAtoms_minimum_scale as *mut _) };
+("minlength") => { $crate::atom_macro::unsafe_atom_from_static($crate::atom_macro::nsGkAtoms_minlength as *mut _) };
("minpos") => { $crate::atom_macro::unsafe_atom_from_static($crate::atom_macro::nsGkAtoms_minpos as *mut _) };
("minus-sign") => { $crate::atom_macro::unsafe_atom_from_static($crate::atom_macro::nsGkAtoms_minusSign as *mut _) };
("minwidth") => { $crate::atom_macro::unsafe_atom_from_static($crate::atom_macro::nsGkAtoms_minwidth as *mut _) };
@@ -16665,6 +16678,7 @@ macro_rules! atom {
("ondevicelight") => { $crate::atom_macro::unsafe_atom_from_static($crate::atom_macro::nsGkAtoms_ondevicelight as *mut _) };
("onmozinterruptbegin") => { $crate::atom_macro::unsafe_atom_from_static($crate::atom_macro::nsGkAtoms_onmozinterruptbegin as *mut _) };
("onmozinterruptend") => { $crate::atom_macro::unsafe_atom_from_static($crate::atom_macro::nsGkAtoms_onmozinterruptend as *mut _) };
+("ondevicechange") => { $crate::atom_macro::unsafe_atom_from_static($crate::atom_macro::nsGkAtoms_ondevicechange as *mut _) };
("#cdata-section") => { $crate::atom_macro::unsafe_atom_from_static($crate::atom_macro::nsGkAtoms_cdataTagName as *mut _) };
("#comment") => { $crate::atom_macro::unsafe_atom_from_static($crate::atom_macro::nsGkAtoms_commentTagName as *mut _) };
("#document") => { $crate::atom_macro::unsafe_atom_from_static($crate::atom_macro::nsGkAtoms_documentNodeName as *mut _) };
diff --git a/tests/unit/style/parsing/basic_shape.rs b/tests/unit/style/parsing/basic_shape.rs
index b3702dfc8cd..62755582b37 100644
--- a/tests/unit/style/parsing/basic_shape.rs
+++ b/tests/unit/style/parsing/basic_shape.rs
@@ -3,6 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use parsing::parse;
+use style::parser::Parse;
use style::values::specified::basic_shape::*;
// Ensure that basic-shape sub-functions parse as both basic shapes