/* 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 http://mozilla.org/MPL/2.0/. */ //! Generic types for CSS values related to borders. use euclid::Size2D; use std::fmt; use style_traits::ToCss; use values::generics::rect::Rect; /// A generic value for a single side of a `border-image-width` property. #[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[derive(Clone, Copy, Debug, PartialEq, ToComputedValue, ToCss)] pub enum BorderImageSideWidth { /// `` Length(LengthOrPercentage), /// `` Number(Number), /// `auto` Auto, } /// A generic value for the `border-image-slice` property. #[derive(Clone, Copy, Debug, PartialEq, ToComputedValue)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct BorderImageSlice { /// The offsets. pub offsets: Rect, /// Whether to fill the middle part. pub fill: bool, } /// A generic value for `border-radius`, `outline-radius` and `inset()`. /// /// https://drafts.csswg.org/css-backgrounds-3/#border-radius #[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[derive(Animate, Clone, ComputeSquaredDistance, Copy, Debug)] #[derive(PartialEq, ToComputedValue)] pub struct BorderRadius { /// The top left radius. pub top_left: BorderCornerRadius, /// The top right radius. pub top_right: BorderCornerRadius, /// The bottom right radius. pub bottom_right: BorderCornerRadius, /// The bottom left radius. pub bottom_left: BorderCornerRadius, } /// A generic value for `border-*-radius` longhand properties. #[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[derive(Animate, Clone, ComputeSquaredDistance, Copy, Debug)] #[derive(PartialEq, ToComputedValue)] pub struct BorderCornerRadius(pub Size2D); impl From for BorderImageSlice where N: Clone, { #[inline] fn from(value: N) -> Self { Self { offsets: value.into(), fill: false, } } } impl ToCss for BorderImageSlice where N: PartialEq + ToCss, { fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { self.offsets.to_css(dest)?; if self.fill { dest.write_str(" fill")?; } Ok(()) } } 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, } } } impl BorderRadius where L: PartialEq + ToCss { /// Serialises two given rects following the syntax of the `border-radius`` /// property. pub fn serialize_rects(widths: Rect<&L>, heights: Rect<&L>, dest: &mut W) -> fmt::Result where W: fmt::Write, { widths.to_css(dest)?; if widths.0 != heights.0 || widths.1 != heights.1 || widths.2 != heights.2 || widths.3 != heights.3 { dest.write_str(" / ")?; heights.to_css(dest)?; } Ok(()) } } impl ToCss for BorderRadius where L: PartialEq + ToCss { fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { let BorderRadius { top_left: ref tl, top_right: ref tr, bottom_right: ref br, bottom_left: ref bl, } = *self; let widths = Rect::new(&tl.0.width, &tr.0.width, &br.0.width, &bl.0.width); let heights = Rect::new(&tl.0.height, &tr.0.height, &br.0.height, &bl.0.height); Self::serialize_rects(widths, heights, dest) } } impl BorderCornerRadius { #[inline] /// Create a new `BorderCornerRadius` for an area of given width and height. pub fn new(width: L, height: L) -> BorderCornerRadius { BorderCornerRadius(Size2D::new(width, height)) } } impl From for BorderCornerRadius { fn from(radius: L) -> Self { Self::new(radius.clone(), radius) } } impl ToCss for BorderCornerRadius where L: ToCss, { fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { self.0.width.to_css(dest)?; dest.write_str(" ")?; self.0.height.to_css(dest) } }