mirror of
https://github.com/servo/servo.git
synced 2025-07-30 10:40:27 +01:00
style: Use the owned slice type for basic shape polygon coordinates.
This enables destructors for tagged unions in cbindgen, implemented in: * https://github.com/eqrion/cbindgen/pull/333 Which allow us to properly generate a destructor for the cbindgen-generated StyleBasicShape (which now contains an OwnedSlice). For now, we still use the glue code to go from Box<BasicShape> to UniquePtr<BasicShape>. But that will change in the future when we generate even more stuff and remove all the glue. I could add support for copy-constructor generation to cbindgen for tagged enums, but I'm not sure if it'll end up being needed, and copy-constructing unions in C++ is always very tricky. Differential Revision: https://phabricator.services.mozilla.com/D29769
This commit is contained in:
parent
330bccd659
commit
559235edad
9 changed files with 79 additions and 218 deletions
|
@ -532,28 +532,17 @@ impl nsStyleImage {
|
|||
|
||||
pub mod basic_shape {
|
||||
//! Conversions from and to CSS shape representations.
|
||||
|
||||
use crate::gecko::values::GeckoStyleCoordConvertible;
|
||||
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::refptr::RefPtr;
|
||||
use crate::values::computed::basic_shape::{
|
||||
BasicShape, ClippingShape, FloatAreaShape, ShapeRadius,
|
||||
BasicShape, ClippingShape, FloatAreaShape,
|
||||
};
|
||||
use crate::values::computed::length::LengthPercentage;
|
||||
use crate::values::computed::motion::OffsetPath;
|
||||
use crate::values::computed::url::ComputedUrl;
|
||||
use crate::values::generics::basic_shape::{
|
||||
BasicShape as GenericBasicShape, InsetRect, Polygon,
|
||||
};
|
||||
use crate::values::generics::basic_shape::{Circle, Ellipse, Path, PolygonCoord};
|
||||
use crate::values::generics::basic_shape::{GeometryBox, ShapeBox, ShapeSource};
|
||||
use crate::values::generics::rect::Rect;
|
||||
use crate::values::generics::basic_shape::{Path, GeometryBox, ShapeBox, ShapeSource};
|
||||
use crate::values::specified::SVGPathData;
|
||||
use std::borrow::Borrow;
|
||||
|
||||
impl StyleShapeSource {
|
||||
/// Convert StyleShapeSource to ShapeSource except URL and Image
|
||||
|
@ -569,7 +558,7 @@ pub mod basic_shape {
|
|||
StyleShapeSourceType::Box => Some(ShapeSource::Box(self.mReferenceBox.into())),
|
||||
StyleShapeSourceType::Shape => {
|
||||
let other_shape = unsafe { &*self.__bindgen_anon_1.mBasicShape.as_ref().mPtr };
|
||||
let shape = other_shape.into();
|
||||
let shape = Box::new(other_shape.clone());
|
||||
let reference_box = if self.mReferenceBox == StyleGeometryBox::NoBox {
|
||||
None
|
||||
} else {
|
||||
|
@ -653,67 +642,6 @@ pub mod basic_shape {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a StyleBasicShape> for BasicShape {
|
||||
fn from(other: &'a StyleBasicShape) -> Self {
|
||||
match other.mType {
|
||||
StyleBasicShapeType::Inset => {
|
||||
let t = LengthPercentage::from_gecko_style_coord(&other.mCoordinates[0]);
|
||||
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 = other.mRadius;
|
||||
let rect = Rect::new(
|
||||
t.expect("inset() offset should be a length, percentage, or calc value"),
|
||||
r.expect("inset() offset should be a length, percentage, or calc value"),
|
||||
b.expect("inset() offset should be a length, percentage, or calc value"),
|
||||
l.expect("inset() offset should be a length, percentage, or calc value"),
|
||||
);
|
||||
GenericBasicShape::Inset(InsetRect { rect, round })
|
||||
},
|
||||
StyleBasicShapeType::Circle => GenericBasicShape::Circle(Circle {
|
||||
radius: (&other.mCoordinates[0]).into(),
|
||||
position: other.mPosition,
|
||||
}),
|
||||
StyleBasicShapeType::Ellipse => GenericBasicShape::Ellipse(Ellipse {
|
||||
semiaxis_x: (&other.mCoordinates[0]).into(),
|
||||
semiaxis_y: (&other.mCoordinates[1]).into(),
|
||||
position: other.mPosition,
|
||||
}),
|
||||
StyleBasicShapeType::Polygon => {
|
||||
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(PolygonCoord(
|
||||
LengthPercentage::from_gecko_style_coord(&other.mCoordinates[x])
|
||||
.expect(
|
||||
"polygon() coordinate should be a length, percentage, \
|
||||
or calc value",
|
||||
),
|
||||
LengthPercentage::from_gecko_style_coord(&other.mCoordinates[y])
|
||||
.expect(
|
||||
"polygon() coordinate should be a length, percentage, \
|
||||
or calc value",
|
||||
),
|
||||
))
|
||||
}
|
||||
GenericBasicShape::Polygon(Polygon {
|
||||
fill: other.mFillRule,
|
||||
coordinates: coords,
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a nsStyleCoord> for ShapeRadius {
|
||||
fn from(other: &'a nsStyleCoord) -> Self {
|
||||
let other = other.borrow();
|
||||
ShapeRadius::from_gecko_style_coord(other)
|
||||
.expect("<shape-radius> should be a length, percentage, calc, or keyword value")
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ShapeBox> for StyleGeometryBox {
|
||||
fn from(reference: ShapeBox) -> Self {
|
||||
use crate::gecko_bindings::structs::StyleGeometryBox::*;
|
||||
|
|
|
@ -8,12 +8,10 @@
|
|||
|
||||
use crate::counter_style::{Symbol, Symbols};
|
||||
use crate::gecko_bindings::structs::{nsStyleCoord, CounterStylePtr};
|
||||
use crate::gecko_bindings::structs::{StyleGridTrackBreadth, StyleShapeRadius};
|
||||
use crate::gecko_bindings::structs::StyleGridTrackBreadth;
|
||||
use crate::gecko_bindings::sugar::ns_style_coord::{CoordData, CoordDataMut, CoordDataValue};
|
||||
use crate::values::computed::basic_shape::ShapeRadius as ComputedShapeRadius;
|
||||
use crate::values::computed::{Angle, Length, LengthPercentage};
|
||||
use crate::values::computed::{Number, NumberOrPercentage, Percentage};
|
||||
use crate::values::generics::basic_shape::ShapeRadius;
|
||||
use crate::values::generics::gecko::ScrollSnapPoint;
|
||||
use crate::values::generics::grid::{TrackBreadth, TrackKeyword};
|
||||
use crate::values::generics::length::LengthPercentageOrAuto;
|
||||
|
@ -192,35 +190,6 @@ impl<L: GeckoStyleCoordConvertible> GeckoStyleCoordConvertible for TrackBreadth<
|
|||
}
|
||||
}
|
||||
|
||||
impl GeckoStyleCoordConvertible for ComputedShapeRadius {
|
||||
fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
|
||||
match *self {
|
||||
ShapeRadius::ClosestSide => coord.set_value(CoordDataValue::Enumerated(
|
||||
StyleShapeRadius::ClosestSide as u32,
|
||||
)),
|
||||
ShapeRadius::FarthestSide => coord.set_value(CoordDataValue::Enumerated(
|
||||
StyleShapeRadius::FarthestSide as u32,
|
||||
)),
|
||||
ShapeRadius::Length(lp) => lp.to_gecko_style_coord(coord),
|
||||
}
|
||||
}
|
||||
|
||||
fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> {
|
||||
match coord.as_value() {
|
||||
CoordDataValue::Enumerated(v) => {
|
||||
if v == StyleShapeRadius::ClosestSide as u32 {
|
||||
Some(ShapeRadius::ClosestSide)
|
||||
} else if v == StyleShapeRadius::FarthestSide as u32 {
|
||||
Some(ShapeRadius::FarthestSide)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
},
|
||||
_ => GeckoStyleCoordConvertible::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 {
|
||||
|
|
|
@ -20,6 +20,9 @@ use to_shmem::{SharedMemoryBuilder, ToShmem};
|
|||
///
|
||||
/// But handling fat pointers with cbindgen both in structs and argument
|
||||
/// positions more generally is a bit tricky.
|
||||
///
|
||||
/// cbindgen:derive-eq=false
|
||||
/// cbindgen:derive-neq=false
|
||||
#[repr(C)]
|
||||
pub struct OwnedSlice<T: Sized> {
|
||||
ptr: NonNull<T>,
|
||||
|
|
|
@ -4046,16 +4046,15 @@ fn set_style_svg_path(
|
|||
|
||||
<%def name="impl_shape_source(ident, gecko_ffi_name)">
|
||||
pub fn set_${ident}(&mut self, v: longhands::${ident}::computed_value::T) {
|
||||
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::values::GeckoStyleCoordConvertible;
|
||||
use crate::values::generics::basic_shape::{BasicShape, ShapeSource};
|
||||
use crate::values::generics::basic_shape::ShapeSource;
|
||||
use crate::gecko_bindings::structs::StyleShapeSourceType;
|
||||
use crate::gecko_bindings::structs::StyleGeometryBox;
|
||||
|
||||
let ref mut ${ident} = self.gecko.${gecko_ffi_name};
|
||||
|
||||
// clean up existing struct
|
||||
unsafe { Gecko_DestroyShapeSource(${ident}) };
|
||||
// clean up existing struct.
|
||||
unsafe { bindings::Gecko_DestroyShapeSource(${ident}) };
|
||||
|
||||
${ident}.mType = StyleShapeSourceType::None;
|
||||
|
||||
match v {
|
||||
|
@ -4084,72 +4083,12 @@ fn set_style_svg_path(
|
|||
}
|
||||
ShapeSource::Path(p) => set_style_svg_path(${ident}, &p.path, p.fill),
|
||||
ShapeSource::Shape(servo_shape, maybe_box) => {
|
||||
fn init_shape(${ident}: &mut StyleShapeSource, basic_shape_type: StyleBasicShapeType)
|
||||
-> &mut StyleBasicShape {
|
||||
unsafe {
|
||||
// Create StyleBasicShape in StyleShapeSource. mReferenceBox and mType
|
||||
// will be set manually later.
|
||||
Gecko_NewBasicShape(${ident}, basic_shape_type);
|
||||
&mut *${ident}.__bindgen_anon_1.mBasicShape.as_mut().mPtr
|
||||
}
|
||||
unsafe {
|
||||
${ident}.__bindgen_anon_1.mBasicShape.as_mut().mPtr =
|
||||
Box::into_raw(servo_shape);
|
||||
}
|
||||
match servo_shape {
|
||||
BasicShape::Inset(inset) => {
|
||||
let shape = init_shape(${ident}, 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();
|
||||
inset.rect.0.to_gecko_style_coord(&mut shape.mCoordinates[0]);
|
||||
shape.mCoordinates[1].leaky_set_null();
|
||||
inset.rect.1.to_gecko_style_coord(&mut shape.mCoordinates[1]);
|
||||
shape.mCoordinates[2].leaky_set_null();
|
||||
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]);
|
||||
shape.mRadius = inset.round;
|
||||
}
|
||||
BasicShape::Circle(circ) => {
|
||||
let shape = init_shape(${ident}, 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 shape = init_shape(${ident}, 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 shape = init_shape(${ident}, 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 = poly.fill;
|
||||
}
|
||||
}
|
||||
|
||||
${ident}.mReferenceBox = maybe_box.map(Into::into)
|
||||
.unwrap_or(StyleGeometryBox::NoBox);
|
||||
${ident}.mReferenceBox =
|
||||
maybe_box.map(Into::into).unwrap_or(StyleGeometryBox::NoBox);
|
||||
${ident}.mType = StyleShapeSourceType::Shape;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -87,8 +87,8 @@ ${helpers.predefined_type(
|
|||
"basic_shape::ClippingShape",
|
||||
"generics::basic_shape::ShapeSource::None",
|
||||
products="gecko",
|
||||
boxed=True,
|
||||
animation_value_type="basic_shape::ClippingShape",
|
||||
boxed=True,
|
||||
flags="CREATES_STACKING_CONTEXT",
|
||||
spec="https://drafts.fxtf.org/css-masking/#propdef-clip-path",
|
||||
)}
|
||||
|
|
|
@ -16,7 +16,6 @@ use crate::values::computed::Image;
|
|||
use crate::values::specified::SVGPathData;
|
||||
use crate::values::CSSFloat;
|
||||
use app_units::Au;
|
||||
use euclid::Point2D;
|
||||
use smallvec::SmallVec;
|
||||
use std::cmp;
|
||||
|
||||
|
@ -241,16 +240,10 @@ impl Animate for Au {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T> Animate for Point2D<T>
|
||||
where
|
||||
T: Animate,
|
||||
{
|
||||
impl<T: Animate> Animate for Box<T> {
|
||||
#[inline]
|
||||
fn animate(&self, other: &Self, procedure: Procedure) -> Result<Self, ()> {
|
||||
Ok(Point2D::new(
|
||||
self.x.animate(&other.x, procedure)?,
|
||||
self.y.animate(&other.y, procedure)?,
|
||||
))
|
||||
Ok(Box::new((**self).animate(&other, procedure)?))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -288,6 +281,24 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<T> ToAnimatedValue for Box<T>
|
||||
where
|
||||
T: ToAnimatedValue,
|
||||
{
|
||||
type AnimatedValue = Box<<T as ToAnimatedValue>::AnimatedValue>;
|
||||
|
||||
#[inline]
|
||||
fn to_animated_value(self) -> Self::AnimatedValue {
|
||||
Box::new((*self).to_animated_value())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn from_animated_value(animated: Self::AnimatedValue) -> Self {
|
||||
Box::new(T::from_animated_value(*animated))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl<T> ToAnimatedValue for Box<[T]>
|
||||
where
|
||||
T: ToAnimatedValue,
|
||||
|
@ -328,7 +339,7 @@ where
|
|||
|
||||
#[inline]
|
||||
fn from_animated_value(animated: Self::AnimatedValue) -> Self {
|
||||
Box::from_animated_value(animated.into_box()).into()
|
||||
Self::from(Box::from_animated_value(animated.into_box()))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ pub type ClippingShape = generic::ClippingShape<BasicShape, ComputedUrl>;
|
|||
pub type FloatAreaShape = generic::FloatAreaShape<BasicShape, Image>;
|
||||
|
||||
/// A computed basic shape.
|
||||
pub type BasicShape = generic::BasicShape<
|
||||
pub type BasicShape = generic::GenericBasicShape<
|
||||
LengthPercentage,
|
||||
LengthPercentage,
|
||||
LengthPercentage,
|
||||
|
@ -41,7 +41,7 @@ pub type Ellipse =
|
|||
generic::Ellipse<LengthPercentage, LengthPercentage, NonNegativeLengthPercentage>;
|
||||
|
||||
/// The computed value of `ShapeRadius`
|
||||
pub type ShapeRadius = generic::ShapeRadius<NonNegativeLengthPercentage>;
|
||||
pub type ShapeRadius = generic::GenericShapeRadius<NonNegativeLengthPercentage>;
|
||||
|
||||
impl ToCss for Circle {
|
||||
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
|
||||
use crate::values::animated::{Animate, Procedure, ToAnimatedZero};
|
||||
use crate::values::distance::{ComputeSquaredDistance, SquaredDistance};
|
||||
use crate::values::generics::border::BorderRadius;
|
||||
use crate::values::generics::position::Position;
|
||||
use crate::values::generics::border::GenericBorderRadius;
|
||||
use crate::values::generics::position::GenericPosition;
|
||||
use crate::values::generics::rect::Rect;
|
||||
use crate::values::specified::SVGPathData;
|
||||
use crate::Zero;
|
||||
|
@ -89,7 +89,7 @@ pub enum ShapeBox {
|
|||
pub enum ShapeSource<BasicShape, ReferenceBox, ImageOrUrl> {
|
||||
#[animation(error)]
|
||||
ImageOrUrl(ImageOrUrl),
|
||||
Shape(BasicShape, Option<ReferenceBox>),
|
||||
Shape(Box<BasicShape>, Option<ReferenceBox>),
|
||||
#[animation(error)]
|
||||
Box(ReferenceBox),
|
||||
#[css(function)]
|
||||
|
@ -113,7 +113,8 @@ pub enum ShapeSource<BasicShape, ReferenceBox, ImageOrUrl> {
|
|||
ToResolvedValue,
|
||||
ToShmem,
|
||||
)]
|
||||
pub enum BasicShape<H, V, LengthPercentage, NonNegativeLengthPercentage> {
|
||||
#[repr(C, u8)]
|
||||
pub enum GenericBasicShape<H, V, LengthPercentage, NonNegativeLengthPercentage> {
|
||||
Inset(
|
||||
#[css(field_bound)]
|
||||
#[shmem(field_bound)]
|
||||
|
@ -129,9 +130,11 @@ pub enum BasicShape<H, V, LengthPercentage, NonNegativeLengthPercentage> {
|
|||
#[shmem(field_bound)]
|
||||
Ellipse<H, V, NonNegativeLengthPercentage>,
|
||||
),
|
||||
Polygon(Polygon<LengthPercentage>),
|
||||
Polygon(GenericPolygon<LengthPercentage>),
|
||||
}
|
||||
|
||||
pub use self::GenericBasicShape as BasicShape;
|
||||
|
||||
/// <https://drafts.csswg.org/css-shapes/#funcdef-inset>
|
||||
#[allow(missing_docs)]
|
||||
#[css(function = "inset")]
|
||||
|
@ -148,10 +151,11 @@ pub enum BasicShape<H, V, LengthPercentage, NonNegativeLengthPercentage> {
|
|||
ToResolvedValue,
|
||||
ToShmem,
|
||||
)]
|
||||
#[repr(C)]
|
||||
pub struct InsetRect<LengthPercentage, NonNegativeLengthPercentage> {
|
||||
pub rect: Rect<LengthPercentage>,
|
||||
#[shmem(field_bound)]
|
||||
pub round: BorderRadius<NonNegativeLengthPercentage>,
|
||||
pub round: GenericBorderRadius<NonNegativeLengthPercentage>,
|
||||
}
|
||||
|
||||
/// <https://drafts.csswg.org/css-shapes/#funcdef-circle>
|
||||
|
@ -171,9 +175,10 @@ pub struct InsetRect<LengthPercentage, NonNegativeLengthPercentage> {
|
|||
ToResolvedValue,
|
||||
ToShmem,
|
||||
)]
|
||||
#[repr(C)]
|
||||
pub struct Circle<H, V, NonNegativeLengthPercentage> {
|
||||
pub position: Position<H, V>,
|
||||
pub radius: ShapeRadius<NonNegativeLengthPercentage>,
|
||||
pub position: GenericPosition<H, V>,
|
||||
pub radius: GenericShapeRadius<NonNegativeLengthPercentage>,
|
||||
}
|
||||
|
||||
/// <https://drafts.csswg.org/css-shapes/#funcdef-ellipse>
|
||||
|
@ -193,10 +198,11 @@ pub struct Circle<H, V, NonNegativeLengthPercentage> {
|
|||
ToResolvedValue,
|
||||
ToShmem,
|
||||
)]
|
||||
#[repr(C)]
|
||||
pub struct Ellipse<H, V, NonNegativeLengthPercentage> {
|
||||
pub position: Position<H, V>,
|
||||
pub semiaxis_x: ShapeRadius<NonNegativeLengthPercentage>,
|
||||
pub semiaxis_y: ShapeRadius<NonNegativeLengthPercentage>,
|
||||
pub position: GenericPosition<H, V>,
|
||||
pub semiaxis_x: GenericShapeRadius<NonNegativeLengthPercentage>,
|
||||
pub semiaxis_y: GenericShapeRadius<NonNegativeLengthPercentage>,
|
||||
}
|
||||
|
||||
/// <https://drafts.csswg.org/css-shapes/#typedef-shape-radius>
|
||||
|
@ -216,7 +222,8 @@ pub struct Ellipse<H, V, NonNegativeLengthPercentage> {
|
|||
ToResolvedValue,
|
||||
ToShmem,
|
||||
)]
|
||||
pub enum ShapeRadius<NonNegativeLengthPercentage> {
|
||||
#[repr(C, u8)]
|
||||
pub enum GenericShapeRadius<NonNegativeLengthPercentage> {
|
||||
Length(NonNegativeLengthPercentage),
|
||||
#[animation(error)]
|
||||
ClosestSide,
|
||||
|
@ -224,10 +231,12 @@ pub enum ShapeRadius<NonNegativeLengthPercentage> {
|
|||
FarthestSide,
|
||||
}
|
||||
|
||||
pub use self::GenericShapeRadius as ShapeRadius;
|
||||
|
||||
/// A generic type for representing the `polygon()` function
|
||||
///
|
||||
/// <https://drafts.csswg.org/css-shapes/#funcdef-polygon>
|
||||
#[css(comma, function)]
|
||||
#[css(comma, function = "polygon")]
|
||||
#[derive(
|
||||
Clone,
|
||||
Debug,
|
||||
|
@ -240,15 +249,18 @@ pub enum ShapeRadius<NonNegativeLengthPercentage> {
|
|||
ToResolvedValue,
|
||||
ToShmem,
|
||||
)]
|
||||
pub struct Polygon<LengthPercentage> {
|
||||
#[repr(C)]
|
||||
pub struct GenericPolygon<LengthPercentage> {
|
||||
/// The filling rule for a polygon.
|
||||
#[css(skip_if = "fill_is_default")]
|
||||
pub fill: FillRule,
|
||||
/// A collection of (x, y) coordinates to draw the polygon.
|
||||
#[css(iterable)]
|
||||
pub coordinates: Vec<PolygonCoord<LengthPercentage>>,
|
||||
pub coordinates: crate::OwnedSlice<PolygonCoord<LengthPercentage>>,
|
||||
}
|
||||
|
||||
pub use self::GenericPolygon as Polygon;
|
||||
|
||||
/// Coordinates for Polygon.
|
||||
#[derive(
|
||||
Clone,
|
||||
|
@ -262,6 +274,7 @@ pub struct Polygon<LengthPercentage> {
|
|||
ToResolvedValue,
|
||||
ToShmem,
|
||||
)]
|
||||
#[repr(C)]
|
||||
pub struct PolygonCoord<LengthPercentage>(pub LengthPercentage, pub LengthPercentage);
|
||||
|
||||
// https://drafts.csswg.org/css-shapes/#typedef-fill-rule
|
||||
|
@ -393,7 +406,8 @@ where
|
|||
this.1.animate(&other.1, procedure)?,
|
||||
))
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
.collect::<Result<Vec<_>, _>>()?
|
||||
.into();
|
||||
Ok(Polygon {
|
||||
fill: self.fill,
|
||||
coordinates,
|
||||
|
|
|
@ -55,7 +55,7 @@ pub type Ellipse =
|
|||
pub type ShapeRadius = generic::ShapeRadius<NonNegativeLengthPercentage>;
|
||||
|
||||
/// The specified value of `Polygon`
|
||||
pub type Polygon = generic::Polygon<LengthPercentage>;
|
||||
pub type Polygon = generic::GenericPolygon<LengthPercentage>;
|
||||
|
||||
#[cfg(feature = "gecko")]
|
||||
fn is_clip_path_path_enabled(context: &ParserContext) -> bool {
|
||||
|
@ -138,11 +138,11 @@ where
|
|||
}
|
||||
|
||||
if let Some(shp) = shape {
|
||||
return Ok(ShapeSource::Shape(shp, ref_box));
|
||||
return Ok(ShapeSource::Shape(Box::new(shp), ref_box));
|
||||
}
|
||||
|
||||
ref_box
|
||||
.map(|v| ShapeSource::Box(v))
|
||||
.map(ShapeSource::Box)
|
||||
.ok_or(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||
}
|
||||
}
|
||||
|
@ -152,7 +152,7 @@ impl Parse for GeometryBox {
|
|||
_context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
if let Ok(shape_box) = input.try(|i| ShapeBox::parse(i)) {
|
||||
if let Ok(shape_box) = input.try(ShapeBox::parse) {
|
||||
return Ok(GeometryBox::ShapeBox(shape_box));
|
||||
}
|
||||
|
||||
|
@ -352,17 +352,14 @@ impl Polygon {
|
|||
})
|
||||
.unwrap_or_default();
|
||||
|
||||
let buf = input.parse_comma_separated(|i| {
|
||||
let coordinates = input.parse_comma_separated(|i| {
|
||||
Ok(PolygonCoord(
|
||||
LengthPercentage::parse(context, i)?,
|
||||
LengthPercentage::parse(context, i)?,
|
||||
))
|
||||
})?;
|
||||
})?.into();
|
||||
|
||||
Ok(Polygon {
|
||||
fill: fill,
|
||||
coordinates: buf,
|
||||
})
|
||||
Ok(Polygon { fill, coordinates })
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue