/* 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/. */ //! Generic types for CSS values related to borders. use crate::values::generics::rect::Rect; use crate::values::generics::size::Size2D; use crate::Zero; use std::fmt::{self, Write}; use style_traits::{CssWriter, ToCss}; /// A generic value for a single side of a `border-image-width` property. #[derive( Animate, Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf, Parse, PartialEq, SpecifiedValueInfo, ToAnimatedValue, ToAnimatedZero, ToComputedValue, ToCss, ToResolvedValue, ToShmem, )] #[repr(C, u8)] pub enum GenericBorderImageSideWidth { /// `` /// /// NOTE: Numbers need to be before length-percentagess, in order to parse /// them first, since `0` should be a number, not the `0px` length. Number(N), /// `` LengthPercentage(LP), /// `auto` Auto, } pub use self::GenericBorderImageSideWidth as BorderImageSideWidth; /// A generic value for the `border-image-slice` property. #[derive( Animate, Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToAnimatedValue, ToAnimatedZero, ToComputedValue, ToCss, ToResolvedValue, ToShmem, )] #[repr(C)] pub struct GenericBorderImageSlice { /// The offsets. #[css(field_bound)] pub offsets: Rect, /// Whether to fill the middle part. #[animation(constant)] #[css(represents_keyword)] pub fill: bool, } pub use self::GenericBorderImageSlice as BorderImageSlice; /// A generic value for the `border-*-radius` longhand properties. #[derive( Animate, Clone, ComputeSquaredDistance, Copy, Debug, Deserialize, MallocSizeOf, PartialEq, SpecifiedValueInfo, Serialize, ToAnimatedValue, ToAnimatedZero, ToComputedValue, ToCss, ToResolvedValue, ToShmem, )] #[repr(C)] pub struct GenericBorderCornerRadius( #[css(field_bound)] #[shmem(field_bound)] pub Size2D, ); pub use self::GenericBorderCornerRadius as BorderCornerRadius; impl BorderCornerRadius { /// Trivially create a `BorderCornerRadius`. pub fn new(w: L, h: L) -> Self { BorderCornerRadius(Size2D::new(w, h)) } } impl Zero for BorderCornerRadius { fn zero() -> Self { BorderCornerRadius(Size2D::zero()) } fn is_zero(&self) -> bool { self.0.is_zero() } } /// A generic value for the `border-spacing` property. #[derive( Animate, Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToAnimatedValue, ToAnimatedZero, ToComputedValue, ToCss, ToResolvedValue, ToShmem, )] #[repr(transparent)] pub struct BorderSpacing( #[css(field_bound)] #[shmem(field_bound)] pub Size2D, ); impl BorderSpacing { /// Trivially create a `BorderCornerRadius`. pub fn new(w: L, h: L) -> Self { BorderSpacing(Size2D::new(w, h)) } } /// A generic value for `border-radius` and `inset()`. /// /// #[derive( Animate, Clone, ComputeSquaredDistance, Copy, Debug, Deserialize, MallocSizeOf, PartialEq, SpecifiedValueInfo, Serialize, ToAnimatedValue, ToComputedValue, ToResolvedValue, ToShmem, )] #[repr(C)] pub struct GenericBorderRadius { /// The top left radius. #[shmem(field_bound)] pub top_left: GenericBorderCornerRadius, /// The top right radius. pub top_right: GenericBorderCornerRadius, /// The bottom right radius. pub bottom_right: GenericBorderCornerRadius, /// The bottom left radius. pub bottom_left: GenericBorderCornerRadius, } pub use self::GenericBorderRadius as BorderRadius; impl BorderRadius { /// Returns a new `BorderRadius`. #[inline] pub fn new( tl: BorderCornerRadius, tr: BorderCornerRadius, br: BorderCornerRadius, bl: BorderCornerRadius, ) -> Self { BorderRadius { top_left: tl, top_right: tr, bottom_right: br, bottom_left: bl, } } /// Serialises two given rects following the syntax of the `border-radius`` /// property. pub fn serialize_rects( widths: Rect<&L>, heights: Rect<&L>, dest: &mut CssWriter, ) -> fmt::Result where L: PartialEq + ToCss, W: Write, { widths.to_css(dest)?; if widths != heights { dest.write_str(" / ")?; heights.to_css(dest)?; } Ok(()) } } impl Zero for BorderRadius { fn zero() -> Self { Self::new( BorderCornerRadius::::zero(), BorderCornerRadius::::zero(), BorderCornerRadius::::zero(), BorderCornerRadius::::zero(), ) } fn is_zero(&self) -> bool { self.top_left.is_zero() && self.top_right.is_zero() && self.bottom_right.is_zero() && self.bottom_left.is_zero() } } impl ToCss for BorderRadius where L: PartialEq + ToCss, { fn to_css(&self, dest: &mut CssWriter) -> fmt::Result where W: Write, { let BorderRadius { top_left: BorderCornerRadius(ref tl), top_right: BorderCornerRadius(ref tr), bottom_right: BorderCornerRadius(ref br), bottom_left: BorderCornerRadius(ref bl), } = *self; let widths = Rect::new(&tl.width, &tr.width, &br.width, &bl.width); let heights = Rect::new(&tl.height, &tr.height, &br.height, &bl.height); Self::serialize_rects(widths, heights, dest) } }