From 36d22d82aa202bb199967e9512281e9a53db42c9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 21:33:14 +0200 Subject: Adding upstream version 115.7.0esr. Signed-off-by: Daniel Baumann --- .../style/values/generics/basic_shape.rs | 513 +++++++++++++++++++++ 1 file changed, 513 insertions(+) create mode 100644 servo/components/style/values/generics/basic_shape.rs (limited to 'servo/components/style/values/generics/basic_shape.rs') diff --git a/servo/components/style/values/generics/basic_shape.rs b/servo/components/style/values/generics/basic_shape.rs new file mode 100644 index 0000000000..00d682a169 --- /dev/null +++ b/servo/components/style/values/generics/basic_shape.rs @@ -0,0 +1,513 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +//! CSS handling for the [`basic-shape`](https://drafts.csswg.org/css-shapes/#typedef-basic-shape) +//! types that are generic over their `ToCss` implementations. + +use crate::values::animated::{lists, Animate, Procedure, ToAnimatedZero}; +use crate::values::distance::{ComputeSquaredDistance, SquaredDistance}; +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; +use std::fmt::{self, Write}; +use style_traits::{CssWriter, ToCss}; + +/// +#[allow(missing_docs)] +#[derive( + Animate, + Clone, + ComputeSquaredDistance, + Copy, + Debug, + MallocSizeOf, + PartialEq, + Parse, + SpecifiedValueInfo, + ToAnimatedValue, + ToComputedValue, + ToCss, + ToResolvedValue, + ToShmem, +)] +#[repr(u8)] +pub enum 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), +} + +impl Default for ShapeGeometryBox { + fn default() -> Self { + Self::ElementDependent + } +} + +/// https://drafts.csswg.org/css-shapes-1/#typedef-shape-box +#[allow(missing_docs)] +#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] +#[derive( + Animate, + Clone, + Copy, + ComputeSquaredDistance, + Debug, + Eq, + MallocSizeOf, + Parse, + PartialEq, + SpecifiedValueInfo, + ToAnimatedValue, + ToComputedValue, + ToCss, + ToResolvedValue, + ToShmem, +)] +#[repr(u8)] +pub enum ShapeBox { + MarginBox, + BorderBox, + PaddingBox, + ContentBox, +} + +impl Default for ShapeBox { + fn default() -> Self { + ShapeBox::MarginBox + } +} + +/// A value for the `clip-path` property. +#[allow(missing_docs)] +#[derive( + Animate, + Clone, + ComputeSquaredDistance, + Debug, + MallocSizeOf, + PartialEq, + SpecifiedValueInfo, + ToAnimatedValue, + ToComputedValue, + ToCss, + ToResolvedValue, + ToShmem, +)] +#[animation(no_bound(U))] +#[repr(u8)] +pub enum GenericClipPath { + #[animation(error)] + None, + #[animation(error)] + Url(U), + #[css(function)] + Path(Path), + Shape( + Box, + #[css(skip_if = "is_default")] ShapeGeometryBox, + ), + #[animation(error)] + Box(ShapeGeometryBox), +} + +pub use self::GenericClipPath as ClipPath; + +/// A value for the `shape-outside` property. +#[allow(missing_docs)] +#[derive( + Animate, + Clone, + ComputeSquaredDistance, + Debug, + MallocSizeOf, + PartialEq, + SpecifiedValueInfo, + ToAnimatedValue, + ToComputedValue, + ToCss, + ToResolvedValue, + ToShmem, +)] +#[animation(no_bound(I))] +#[repr(u8)] +pub enum GenericShapeOutside { + #[animation(error)] + None, + #[animation(error)] + Image(I), + Shape(Box, #[css(skip_if = "is_default")] ShapeBox), + #[animation(error)] + Box(ShapeBox), +} + +pub use self::GenericShapeOutside as ShapeOutside; + +#[allow(missing_docs)] +#[derive( + Animate, + Clone, + ComputeSquaredDistance, + Debug, + MallocSizeOf, + PartialEq, + SpecifiedValueInfo, + ToAnimatedValue, + ToComputedValue, + ToCss, + ToResolvedValue, + ToShmem, +)] +#[repr(C, u8)] +pub enum GenericBasicShape { + Inset( + #[css(field_bound)] + #[shmem(field_bound)] + InsetRect, + ), + Circle( + #[css(field_bound)] + #[shmem(field_bound)] + Circle, + ), + Ellipse( + #[css(field_bound)] + #[shmem(field_bound)] + Ellipse, + ), + Polygon(GenericPolygon), +} + +pub use self::GenericBasicShape as BasicShape; + +/// +#[allow(missing_docs)] +#[derive( + Animate, + Clone, + ComputeSquaredDistance, + Debug, + MallocSizeOf, + PartialEq, + SpecifiedValueInfo, + ToAnimatedValue, + ToComputedValue, + ToResolvedValue, + ToShmem, +)] +#[css(function = "inset")] +#[repr(C)] +pub struct InsetRect { + pub rect: Rect, + #[shmem(field_bound)] + pub round: GenericBorderRadius, +} + +/// +#[allow(missing_docs)] +#[derive( + Animate, + Clone, + ComputeSquaredDistance, + Copy, + Debug, + MallocSizeOf, + PartialEq, + SpecifiedValueInfo, + ToAnimatedValue, + ToComputedValue, + ToResolvedValue, + ToShmem, +)] +#[css(function)] +#[repr(C)] +pub struct Circle { + pub position: GenericPosition, + pub radius: GenericShapeRadius, +} + +/// +#[allow(missing_docs)] +#[derive( + Animate, + Clone, + ComputeSquaredDistance, + Copy, + Debug, + MallocSizeOf, + PartialEq, + SpecifiedValueInfo, + ToAnimatedValue, + ToComputedValue, + ToResolvedValue, + ToShmem, +)] +#[css(function)] +#[repr(C)] +pub struct Ellipse { + pub position: GenericPosition, + pub semiaxis_x: GenericShapeRadius, + pub semiaxis_y: GenericShapeRadius, +} + +/// +#[allow(missing_docs)] +#[derive( + Animate, + Clone, + ComputeSquaredDistance, + Copy, + Debug, + MallocSizeOf, + Parse, + PartialEq, + SpecifiedValueInfo, + ToAnimatedValue, + ToComputedValue, + ToCss, + ToResolvedValue, + ToShmem, +)] +#[repr(C, u8)] +pub enum GenericShapeRadius { + Length(NonNegativeLengthPercentage), + #[animation(error)] + ClosestSide, + #[animation(error)] + FarthestSide, +} + +pub use self::GenericShapeRadius as ShapeRadius; + +/// A generic type for representing the `polygon()` function +/// +/// +#[derive( + Clone, + Debug, + MallocSizeOf, + PartialEq, + SpecifiedValueInfo, + ToAnimatedValue, + ToComputedValue, + ToCss, + ToResolvedValue, + ToShmem, +)] +#[css(comma, function = "polygon")] +#[repr(C)] +pub struct GenericPolygon { + /// 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>, +} + +pub use self::GenericPolygon as Polygon; + +/// Coordinates for Polygon. +#[derive( + Animate, + Clone, + ComputeSquaredDistance, + Debug, + MallocSizeOf, + PartialEq, + SpecifiedValueInfo, + ToAnimatedValue, + ToComputedValue, + ToCss, + ToResolvedValue, + ToShmem, +)] +#[repr(C)] +pub struct PolygonCoord(pub LengthPercentage, pub 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)] +#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] +#[derive( + Clone, + Copy, + Debug, + Eq, + MallocSizeOf, + Parse, + PartialEq, + SpecifiedValueInfo, + ToAnimatedValue, + ToComputedValue, + ToCss, + ToResolvedValue, + ToShmem, +)] +#[repr(u8)] +pub enum FillRule { + Nonzero, + Evenodd, +} + +/// The path function defined in css-shape-2. +/// +/// https://drafts.csswg.org/css-shapes-2/#funcdef-path +#[derive( + Animate, + Clone, + ComputeSquaredDistance, + Debug, + MallocSizeOf, + PartialEq, + SpecifiedValueInfo, + ToAnimatedValue, + ToComputedValue, + ToCss, + ToResolvedValue, + ToShmem, +)] +#[css(comma)] +#[repr(C)] +pub struct Path { + /// The filling rule for the svg path. + #[css(skip_if = "is_default")] + #[animation(constant)] + pub fill: FillRule, + /// The svg path data. + pub path: SVGPathData, +} + +impl ToAnimatedZero for ClipPath { + fn to_animated_zero(&self) -> Result { + Err(()) + } +} + +impl ToAnimatedZero for ShapeOutside { + fn to_animated_zero(&self) -> Result { + Err(()) + } +} + +impl ToCss for InsetRect +where + Length: ToCss + PartialEq, + NonNegativeLength: ToCss + PartialEq + Zero, +{ + fn to_css(&self, dest: &mut CssWriter) -> 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 ToCss for Circle +where + GenericPosition: ToCss, + NonNegativeLengthPercentage: ToCss + PartialEq, +{ + fn to_css(&self, dest: &mut CssWriter) -> fmt::Result + where + W: Write, + { + dest.write_str("circle(")?; + if self.radius != Default::default() { + self.radius.to_css(dest)?; + dest.write_char(' ')?; + } + dest.write_str("at ")?; + self.position.to_css(dest)?; + dest.write_char(')') + } +} + +impl ToCss for Ellipse +where + GenericPosition: ToCss, + NonNegativeLengthPercentage: ToCss + PartialEq, +{ + fn to_css(&self, dest: &mut CssWriter) -> fmt::Result + where + W: Write, + { + dest.write_str("ellipse(")?; + if self.semiaxis_x != Default::default() || self.semiaxis_y != Default::default() { + self.semiaxis_x.to_css(dest)?; + dest.write_char(' ')?; + self.semiaxis_y.to_css(dest)?; + dest.write_char(' ')?; + } + dest.write_str("at ")?; + self.position.to_css(dest)?; + dest.write_char(')') + } +} + +impl Default for ShapeRadius { + #[inline] + fn default() -> Self { + ShapeRadius::ClosestSide + } +} + +impl Animate for Polygon +where + L: Animate, +{ + fn animate(&self, other: &Self, procedure: Procedure) -> Result { + if self.fill != other.fill { + return Err(()); + } + let coordinates = + lists::by_computed_value::animate(&self.coordinates, &other.coordinates, procedure)?; + Ok(Polygon { + fill: self.fill, + coordinates, + }) + } +} + +impl ComputeSquaredDistance for Polygon +where + L: ComputeSquaredDistance, +{ + fn compute_squared_distance(&self, other: &Self) -> Result { + if self.fill != other.fill { + return Err(()); + } + lists::by_computed_value::squared_distance(&self.coordinates, &other.coordinates) + } +} + +impl Default for FillRule { + #[inline] + fn default() -> Self { + FillRule::Nonzero + } +} + +#[inline] +fn is_default(fill: &T) -> bool { + *fill == Default::default() +} -- cgit v1.2.3