/* This Source Code Form is subject to the terms of the Mozilla Public *License,v.2.0.IfacopyoftheMPLwasnotdistributedwiththis
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
/// <https://drafts.fxtf.org/css-masking-1/#typedef-geometry-box> #[allow(missing_docs)] #[derive(
Animate,
Clone,
ComputeSquaredDistance,
Copy,
Debug,
MallocSizeOf,
PartialEq,
Parse,
SpecifiedValueInfo,
ToAnimatedValue,
ToComputedValue,
ToCss,
ToResolvedValue,
ToShmem,
ToTyped,
)] #[repr(u8)] pubenum ShapeGeometryBox { /// Depending on which kind of element this style value applied on, the /// default value of the reference-box can be different. For an HTML /// element, the default value of reference-box is border-box; for an SVG /// element, the default value is fill-box. Since we can not determine the /// default value at parsing time, we keep this value to make a decision on /// it. #[css(skip)]
ElementDependent,
FillBox,
StrokeBox,
ViewBox,
ShapeBox(ShapeBox),
}
/// Skip the serialization if the author omits the box or specifies border-box. #[inline] fn is_default_box_for_clip_path(b: &ShapeGeometryBox) -> bool { // Note: for clip-path, ElementDependent is always border-box, so we have to check both of them // for serialization.
matches!(b, ShapeGeometryBox::ElementDependent)
|| matches!(b, ShapeGeometryBox::ShapeBox(ShapeBox::BorderBox))
}
/// A value for the `clip-path` property. #[allow(missing_docs)] #[derive(
Animate,
Clone,
ComputeSquaredDistance,
Debug,
MallocSizeOf,
PartialEq,
SpecifiedValueInfo,
ToAnimatedValue,
ToComputedValue,
ToCss,
ToResolvedValue,
ToShmem,
ToTyped,
)] #[animation(no_bound(U))] #[repr(u8)] pubenum GenericClipPath<BasicShape, U> { #[animation(error)]
None, #[animation(error)] // XXX This will likely change to skip since it seems Typed OM Level 1 // won't be updated to cover this case even though there's some preparation // in WPT tests for this. #[typed(todo)]
Url(U), #[typed(skip)]
Shape( #[animation(field_bound)] Box<BasicShape>, #[css(skip_if = "is_default_box_for_clip_path")] ShapeGeometryBox,
), #[animation(error)] Box(ShapeGeometryBox),
}
/// A generic type for representing the `polygon()` function /// /// <https://drafts.csswg.org/css-shapes/#funcdef-polygon> #[derive(
Clone,
Debug,
Deserialize,
MallocSizeOf,
PartialEq,
Serialize,
SpecifiedValueInfo,
ToAnimatedValue,
ToComputedValue,
ToCss,
ToResolvedValue,
ToShmem,
)] #[css(comma, function = "polygon")] #[repr(C)] pubstruct GenericPolygon<LengthPercentage> { /// The filling rule for a polygon. #[css(skip_if = "is_default")] pub fill: FillRule, /// A collection of (x, y) coordinates to draw the polygon. #[css(iterable)] pub coordinates: crate::OwnedSlice<PolygonCoord<LengthPercentage>>,
}
/// path() function or shape() function. #[derive(
Clone,
ComputeSquaredDistance,
Debug,
Deserialize,
MallocSizeOf,
PartialEq,
Serialize,
SpecifiedValueInfo,
ToAnimatedValue,
ToComputedValue,
ToCss,
ToResolvedValue,
ToShmem,
)] #[repr(C, u8)] pubenum GenericPathOrShapeFunction<Angle, Position, LengthPercentage> { /// Defines a path with SVG path syntax.
Path(Path), /// Defines a shape function, which is identical to path() but it uses the CSS syntax.
Shape( #[css(field_bound)] #[compute(field_bound)]
Shape<Angle, Position, LengthPercentage>,
),
}
// https://drafts.csswg.org/css-shapes/#typedef-fill-rule // NOTE: Basic shapes spec says that these are the only two values, however // https://www.w3.org/TR/SVG/painting.html#FillRuleProperty // says that it can also be `inherit` #[allow(missing_docs)] #[derive(
Animate,
Clone,
ComputeSquaredDistance,
Copy,
Debug,
Deserialize,
Eq,
MallocSizeOf,
Parse,
PartialEq,
Serialize,
SpecifiedValueInfo,
ToAnimatedValue,
ToComputedValue,
ToCss,
ToResolvedValue,
ToShmem,
ToTyped,
)] #[repr(u8)] pubenum FillRule {
Nonzero,
Evenodd,
}
/// The path function. /// /// https://drafts.csswg.org/css-shapes-1/#funcdef-basic-shape-path #[derive(
Animate,
Clone,
ComputeSquaredDistance,
Debug,
Deserialize,
MallocSizeOf,
PartialEq,
Serialize,
SpecifiedValueInfo,
ToAnimatedValue,
ToComputedValue,
ToCss,
ToResolvedValue,
ToShmem,
)] #[css(comma, function = "path")] #[repr(C)] pubstruct Path { /// The filling rule for the svg path. #[css(skip_if = "is_default")] pub fill: FillRule, /// The svg path data. pub path: SVGPathData,
}
impl Path { /// Returns the slice of PathCommand. #[inline] pubfn commands(&self) -> &[PathCommand] { self.path.commands()
}
}
impl<Length> ToCss for InsetRect<Length> where
Length: ToCss + PartialEq + Zero,
{ fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result where
W: Write,
{
dest.write_str("inset(")?; self.rect.to_css(dest)?; if !self.round.is_zero() {
dest.write_str(" round ")?; self.round.to_css(dest)?;
}
dest.write_char(')')
}
}
impl<Position, LengthPercentage> ToCss for Circle<Position, LengthPercentage> where
LengthPercentage: ToCss + PartialEq,
Position: ToCss,
{ fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result where
W: Write,
{ let has_radius = self.radius != Default::default();
dest.write_str("circle(")?; if has_radius { self.radius.to_css(dest)?;
}
// Preserve the `at <position>` even if it specified the default value. // https://github.com/w3c/csswg-drafts/issues/8695 if !matches!(self.position, GenericPositionOrAuto::Auto) { if has_radius {
dest.write_char(' ')?;
}
dest.write_str("at ")?; self.position.to_css(dest)?;
}
dest.write_char(')')
}
}
impl<Position, LengthPercentage> ToCss for Ellipse<Position, LengthPercentage> where
LengthPercentage: ToCss + PartialEq,
Position: ToCss,
{ fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result where
W: Write,
{ let has_radii = self.semiaxis_x != Default::default() || self.semiaxis_y != Default::default();
dest.write_str("ellipse(")?; if has_radii { self.semiaxis_x.to_css(dest)?;
dest.write_char(' ')?; self.semiaxis_y.to_css(dest)?;
}
// Preserve the `at <position>` even if it specified the default value. // https://github.com/w3c/csswg-drafts/issues/8695 if !matches!(self.position, GenericPositionOrAuto::Auto) { if has_radii {
dest.write_char(' ')?;
}
dest.write_str("at ")?; self.position.to_css(dest)?;
}
dest.write_char(')')
}
}
/// The shape function defined in css-shape-2. /// shape() = shape(<fill-rule>? from <coordinate-pair>, <shape-command>#) /// /// https://drafts.csswg.org/css-shapes-2/#shape-function #[derive(
Clone,
Debug,
Deserialize,
MallocSizeOf,
PartialEq,
Serialize,
SpecifiedValueInfo,
ToAnimatedValue,
ToComputedValue,
ToResolvedValue,
ToShmem,
)] #[repr(C)] pubstruct Shape<Angle, Position, LengthPercentage> { /// The filling rule for this shape. pub fill: FillRule, /// The shape command data. Note that the starting point will be the first command in this /// slice. // Note: The first command is always GenericShapeCommand::Move. #[compute(field_bound)] pub commands: crate::OwnedSlice<GenericShapeCommand<Angle, Position, LengthPercentage>>,
}
impl<Angle, Position, LengthPercentage> ToCss for Shape<Angle, Position, LengthPercentage> where
Angle: ToCss + Zero,
Position: ToCss,
LengthPercentage: PartialEq + ToCss,
{ fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result where
W: Write,
{ use style_traits::values::SequenceWriter;
// Per spec, we must have the first move command and at least one following command.
debug_assert!(self.commands.len() > 1);
dest.write_str("shape(")?; if !is_default(&self.fill) { self.fill.to_css(dest)?;
dest.write_char(' ')?;
}
dest.write_str("from ")?; match &self.commands[0] {
ShapeCommand::Move {
point: CommandEndPoint::ToPosition(pos),
} => pos.to_css(dest)?,
ShapeCommand::Move {
point: CommandEndPoint::ByCoordinate(coord),
} => coord.to_css(dest)?,
_ => unreachable!("The first command must be move"),
}
dest.write_str(", ")?;
{ letmut writer = SequenceWriter::new(dest, ", "); for command inself.commands.iter().skip(1) {
writer.item(command)?;
}
}
dest.write_char(')')
}
}
/// This is a more general shape(path) command type, for both shape() and path(). /// /// https://www.w3.org/TR/SVG11/paths.html#PathData /// https://drafts.csswg.org/css-shapes-2/#shape-function #[derive(
Animate,
Clone,
ComputeSquaredDistance,
Copy,
Debug,
Deserialize,
MallocSizeOf,
PartialEq,
Serialize,
SpecifiedValueInfo,
ToAnimatedValue,
ToAnimatedZero,
ToComputedValue,
ToResolvedValue,
ToShmem,
)] #[allow(missing_docs)] #[repr(C, u8)] pubenum GenericShapeCommand<Angle, Position, LengthPercentage> { /// The move command. Move {
point: CommandEndPoint<Position, LengthPercentage>,
}, /// The line command.
Line {
point: CommandEndPoint<Position, LengthPercentage>,
}, /// The hline command.
HLine { #[compute(field_bound)]
x: AxisEndPoint<LengthPercentage>,
}, /// The vline command.
VLine { #[compute(field_bound)]
y: AxisEndPoint<LengthPercentage>,
}, /// The cubic Bézier curve command.
CubicCurve {
point: CommandEndPoint<Position, LengthPercentage>,
control1: ControlPoint<Position, LengthPercentage>,
control2: ControlPoint<Position, LengthPercentage>,
}, /// The quadratic Bézier curve command.
QuadCurve {
point: CommandEndPoint<Position, LengthPercentage>,
control1: ControlPoint<Position, LengthPercentage>,
}, /// The smooth command.
SmoothCubic {
point: CommandEndPoint<Position, LengthPercentage>,
control2: ControlPoint<Position, LengthPercentage>,
}, /// The smooth quadratic Bézier curve command.
SmoothQuad {
point: CommandEndPoint<Position, LengthPercentage>,
}, /// The arc command.
Arc {
point: CommandEndPoint<Position, LengthPercentage>,
radii: ArcRadii<LengthPercentage>,
arc_sweep: ArcSweep,
arc_size: ArcSize,
rotate: Angle,
}, /// The closepath command.
Close,
}
pubuseself::GenericShapeCommand as ShapeCommand;
impl<Angle, Position, LengthPercentage> ToCss for ShapeCommand<Angle, Position, LengthPercentage> where
Angle: ToCss + Zero,
Position: ToCss,
LengthPercentage: PartialEq + ToCss,
{ fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result where
W: fmt::Write,
{ useself::ShapeCommand::*; match *self { Move { ref point } => {
dest.write_str("move ")?;
point.to_css(dest)
},
Line { ref point } => {
dest.write_str("line ")?;
point.to_css(dest)
},
HLine { ref x } => {
dest.write_str("hline ")?;
x.to_css(dest)
},
VLine { ref y } => {
dest.write_str("vline ")?;
y.to_css(dest)
},
CubicCurve { ref point, ref control1, ref control2,
} => {
dest.write_str("curve ")?;
point.to_css(dest)?;
dest.write_str(" with ")?;
control1.to_css(dest, point.is_abs())?;
dest.write_char(' ')?;
dest.write_char('/')?;
dest.write_char(' ')?;
control2.to_css(dest, point.is_abs())
},
QuadCurve { ref point, ref control1,
} => {
dest.write_str("curve ")?;
point.to_css(dest)?;
dest.write_str(" with ")?;
control1.to_css(dest, point.is_abs())
},
SmoothCubic { ref point, ref control2,
} => {
dest.write_str("smooth ")?;
point.to_css(dest)?;
dest.write_str(" with ")?;
control2.to_css(dest, point.is_abs())
},
SmoothQuad { ref point } => {
dest.write_str("smooth ")?;
point.to_css(dest)
},
Arc { ref point, ref radii,
arc_sweep,
arc_size, ref rotate,
} => {
dest.write_str("arc ")?;
point.to_css(dest)?;
dest.write_str(" of ")?;
radii.to_css(dest)?;
if matches!(arc_sweep, ArcSweep::Cw) {
dest.write_str(" cw")?;
}
if matches!(arc_size, ArcSize::Large) {
dest.write_str(" large")?;
}
if !rotate.is_zero() {
dest.write_str(" rotate ")?;
rotate.to_css(dest)?;
}
Ok(())
},
Close => dest.write_str("close"),
}
}
}
/// Defines the end point of the command, which can be specified in absolute or relative coordinates, /// determined by their "to" or "by" components respectively. /// https://drafts.csswg.org/css-shapes/#typedef-shape-command-end-point #[allow(missing_docs)] #[derive(
Animate,
Clone,
ComputeSquaredDistance,
Copy,
Debug,
Deserialize,
MallocSizeOf,
PartialEq,
Serialize,
SpecifiedValueInfo,
ToAnimatedValue,
ToAnimatedZero,
ToComputedValue,
ToResolvedValue,
ToShmem,
)] #[repr(C, u8)] pubenum CommandEndPoint<Position, LengthPercentage> {
ToPosition(Position),
ByCoordinate(CoordinatePair<LengthPercentage>),
}
impl<Position, LengthPercentage> CommandEndPoint<Position, LengthPercentage> { /// Return true if it is absolute, i.e. it is To. #[inline] pubfn is_abs(&self) -> bool {
matches!(self, CommandEndPoint::ToPosition(_))
}
}
/// Defines the end point for the commands <horizontal-line-command> and <vertical-line-command>, which /// can be specified in absolute or relative values, determined by their "to" or "by" components respectively. /// https://drafts.csswg.org/css-shapes-1/#typedef-shape-horizontal-line-command /// https://drafts.csswg.org/css-shapes-1/#typedef-shape-vertical-line-command #[allow(missing_docs)] #[derive(
Animate,
Clone,
Copy,
ComputeSquaredDistance,
Debug,
Deserialize,
MallocSizeOf,
PartialEq,
Parse,
Serialize,
SpecifiedValueInfo,
ToAnimatedValue,
ToAnimatedZero,
ToComputedValue,
ToResolvedValue,
ToShmem,
)] #[repr(u8)] pubenum AxisEndPoint<LengthPercentage> {
ToPosition(#[compute(field_bound)] AxisPosition<LengthPercentage>),
ByCoordinate(LengthPercentage),
}
impl<LengthPercentage> AxisEndPoint<LengthPercentage> { /// Return true if it is absolute, i.e. it is To. #[inline] pubfn is_abs(&self) -> bool {
matches!(self, AxisEndPoint::ToPosition(_))
}
}
/// Defines how the absolutely positioned end point for <horizontal-line-command> and /// <vertical-line-command> is positioned. /// https://drafts.csswg.org/css-shapes-1/#typedef-shape-horizontal-line-command /// https://drafts.csswg.org/css-shapes-1/#typedef-shape-vertical-line-command #[allow(missing_docs)] #[derive(
Animate,
Clone,
ComputeSquaredDistance,
Copy,
Debug,
Deserialize,
MallocSizeOf,
Parse,
PartialEq,
Serialize,
SpecifiedValueInfo,
ToAnimatedValue,
ToAnimatedZero,
ToCss,
ToResolvedValue,
ToShmem,
)] #[repr(u8)] pubenum AxisPosition<LengthPercentage> {
LengthPercent(LengthPercentage),
Keyword(AxisPositionKeyword),
}
/// The set of position keywords used in <horizontal-line-command> and <vertical-line-command> /// for absolute positioning. Note: this is the shared union list between hline and vline, so /// not every value is valid for either. I.e. hline cannot be positioned with top or y-start. /// https://drafts.csswg.org/css-shapes-1/#typedef-shape-horizontal-line-command /// https://drafts.csswg.org/css-shapes-1/#typedef-shape-vertical-line-command #[allow(missing_docs)] #[derive(
Animate,
Clone,
ComputeSquaredDistance,
Copy,
Debug,
Deserialize,
MallocSizeOf,
Parse,
PartialEq,
Serialize,
SpecifiedValueInfo,
ToAnimatedValue,
ToAnimatedZero,
ToCss,
ToResolvedValue,
ToShmem,
)] #[repr(u8)] pubenum AxisPositionKeyword {
Center,
Left,
Right,
Top,
Bottom,
XStart,
XEnd,
YStart,
YEnd,
}
/// Defines a control point for a quadratic or cubic Bézier curve, which can be specified /// in absolute or relative coordinates. /// https://drafts.csswg.org/css-shapes/#typedef-shape-control-point #[allow(missing_docs)] #[derive(
Animate,
Clone,
Copy,
ComputeSquaredDistance,
Debug,
Deserialize,
MallocSizeOf,
PartialEq,
Serialize,
SpecifiedValueInfo,
ToAnimatedValue,
ToAnimatedZero,
ToComputedValue,
ToResolvedValue,
ToShmem,
)] #[repr(C, u8)] pubenum ControlPoint<Position, LengthPercentage> {
Absolute(Position),
Relative(RelativeControlPoint<LengthPercentage>),
}
/// Defines a relative control point to a quadratic or cubic Bézier curve, dependent on the /// reference value. The default `None` is to be relative to the command’s starting point. /// https://drafts.csswg.org/css-shapes/#typedef-shape-relative-control-point #[allow(missing_docs)] #[derive(
Animate,
Clone,
Copy,
Debug,
Deserialize,
MallocSizeOf,
PartialEq,
Serialize,
SpecifiedValueInfo,
ToAnimatedValue,
ToAnimatedZero,
ToComputedValue,
ToResolvedValue,
ToShmem,
)] #[repr(C)] pubstruct RelativeControlPoint<LengthPercentage> { pub coord: CoordinatePair<LengthPercentage>, pub reference: ControlReference,
}
impl<LengthPercentage: ToCss> RelativeControlPoint<LengthPercentage> { fn to_css<W>(&self, dest: &mut CssWriter<W>, is_end_point_abs: bool) -> fmt::Result where
W: Write,
{ self.coord.to_css(dest)?; matchself.reference {
ControlReference::Origin if is_end_point_abs => Ok(()),
ControlReference::Start if !is_end_point_abs => Ok(()),
other => {
dest.write_str(" from ")?;
other.to_css(dest)
},
}
}
}
/// Defines the point of reference for a <relative-control-point>. /// /// When a reference is not specified, depending on whether the associated /// <command-end-point> is absolutely or relatively positioned, the default /// will be `Origin` or `Start`, respectively. /// https://drafts.csswg.org/css-shapes/#typedef-shape-relative-control-point #[allow(missing_docs)] #[derive(
Animate,
Clone,
Copy,
Debug,
Deserialize,
Eq,
MallocSizeOf,
PartialEq,
Parse,
Serialize,
SpecifiedValueInfo,
ToAnimatedValue,
ToAnimatedZero,
ToComputedValue,
ToCss,
ToResolvedValue,
ToShmem,
)] #[repr(C)] pubenum ControlReference {
Start,
End,
Origin,
}
/// Defines the radiuses for an <arc-command>. /// /// The first <length-percentage> is the ellipse's horizontal radius, and the second is /// the vertical radius. If only one value is provided, it is used for both radii, and any /// <percentage> is resolved against the direction-agnostic size of the reference box. /// https://drafts.csswg.org/css-shapes-1/#typedef-shape-arc-command #[allow(missing_docs)] #[derive(
Animate,
Clone,
ComputeSquaredDistance,
Copy,
Debug,
Deserialize,
MallocSizeOf,
PartialEq,
Serialize,
SpecifiedValueInfo,
ToAnimatedValue,
ToAnimatedZero,
ToComputedValue,
ToCss,
ToResolvedValue,
ToShmem,
)] #[repr(C)] pubstruct ArcRadii<LengthPercentage> { pub rx: LengthPercentage, pub ry: Optional<LengthPercentage>,
}
/// This indicates that the arc that is traced around the ellipse clockwise or counter-clockwise /// from the center. /// https://drafts.csswg.org/css-shapes-2/#typedef-shape-arc-sweep #[derive(
Clone,
Copy,
Debug,
Deserialize,
FromPrimitive,
MallocSizeOf,
Parse,
PartialEq,
Serialize,
SpecifiedValueInfo,
ToAnimatedValue,
ToAnimatedZero,
ToComputedValue,
ToCss,
ToResolvedValue,
ToShmem,
)] #[repr(u8)] pubenum ArcSweep { /// Counter-clockwise. The default value. (This also represents 0 in the svg path.)
Ccw = 0, /// Clockwise. (This also represents 1 in the svg path.)
Cw = 1,
}
impl Animate for ArcSweep { fn animate(&self, other: &Self, procedure: Procedure) -> Result<Self, ()> { use num_traits::FromPrimitive; // If an arc command has different <arc-sweep> between its starting and ending list, then // the interpolated result uses cw for any progress value between 0 and 1. // Note: we cast progress from f64->f32->f64 to drop tiny noise near 0.0. let progress = procedure.weights().1as f32 as f64; let procedure = Procedure::Interpolate { progress };
(*selfas i32 as f32)
.animate(&(*other as i32 as f32), procedure)
.map(|v| ArcSweep::from_u8((v > 0.) as u8).unwrap_or(ArcSweep::Ccw))
}
}
impl ComputeSquaredDistance for ArcSweep { fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
(*selfas i32).compute_squared_distance(&(*other as i32))
}
}
/// This indicates that the larger or smaller, respectively, of the two possible arcs must be /// chosen. /// https://drafts.csswg.org/css-shapes-2/#typedef-shape-arc-size #[derive(
Clone,
Copy,
Debug,
Deserialize,
FromPrimitive,
MallocSizeOf,
Parse,
PartialEq,
Serialize,
SpecifiedValueInfo,
ToAnimatedValue,
ToAnimatedZero,
ToComputedValue,
ToCss,
ToResolvedValue,
ToShmem,
)] #[repr(u8)] pubenum ArcSize { /// Choose the small one. The default value. (This also represents 0 in the svg path.)
Small = 0, /// Choose the large one. (This also represents 1 in the svg path.)
Large = 1,
}
impl Animate for ArcSize { fn animate(&self, other: &Self, procedure: Procedure) -> Result<Self, ()> { use num_traits::FromPrimitive; // If it has different <arc-size> keywords, then the interpolated result uses large for any // progress value between 0 and 1. // Note: we cast progress from f64->f32->f64 to drop tiny noise near 0.0. let progress = procedure.weights().1as f32 as f64; let procedure = Procedure::Interpolate { progress };
(*selfas i32 as f32)
.animate(&(*other as i32 as f32), procedure)
.map(|v| ArcSize::from_u8((v > 0.) as u8).unwrap_or(ArcSize::Small))
}
}
impl ComputeSquaredDistance for ArcSize { fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
(*selfas i32).compute_squared_distance(&(*other as i32))
}
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.19 Sekunden
(vorverarbeitet am 2026-08-25)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.