Refactor BorderRadius and move it to the border modules

BorderRadius now parses itself reusing Rect<T>.
This commit is contained in:
Anthony Ramine 2017-05-28 11:24:25 +02:00
parent 4144dc74db
commit af3ede418b
20 changed files with 269 additions and 286 deletions

View file

@ -4,6 +4,7 @@
//! Generic types for CSS values related to borders.
use euclid::Size2D;
use std::fmt;
use style_traits::ToCss;
use values::generics::rect::Rect;
@ -30,6 +31,27 @@ pub struct BorderImageSlice<NumberOrPercentage> {
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(Clone, Copy, Debug, HasViewportPercentage, PartialEq, ToComputedValue)]
pub struct BorderRadius<LengthOrPercentage> {
/// The top left radius.
pub top_left: BorderRadiusSize<LengthOrPercentage>,
/// The top right radius.
pub top_right: BorderRadiusSize<LengthOrPercentage>,
/// The bottom right radius.
pub bottom_right: BorderRadiusSize<LengthOrPercentage>,
/// The bottom left radius.
pub bottom_left: BorderRadiusSize<LengthOrPercentage>,
}
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq, ToComputedValue)]
/// A generic value for `border-*-radius` longhand properties.
pub struct BorderRadiusSize<L>(pub Size2D<L>);
impl<L, N> ToCss for BorderImageWidthSide<L, N>
where L: ToCss, N: ToCss,
{
@ -69,3 +91,81 @@ impl<N> ToCss for BorderImageSlice<N>
Ok(())
}
}
impl<L> BorderRadius<L> {
/// Returns a new `BorderRadius<L>`.
#[inline]
pub fn new(tl: BorderRadiusSize<L>,
tr: BorderRadiusSize<L>,
br: BorderRadiusSize<L>,
bl: BorderRadiusSize<L>)
-> Self {
BorderRadius {
top_left: tl,
top_right: tr,
bottom_right: br,
bottom_left: bl,
}
}
}
impl<L> BorderRadius<L>
where L: PartialEq + ToCss
{
/// Serialises two given rects following the syntax of the `border-radius``
/// property.
pub fn serialize_rects<W>(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<L> ToCss for BorderRadius<L>
where L: PartialEq + ToCss
{
fn to_css<W>(&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<L> BorderRadiusSize<L> {
#[inline]
/// Create a new `BorderRadiusSize` for an area of given width and height.
pub fn new(width: L, height: L) -> BorderRadiusSize<L> {
BorderRadiusSize(Size2D::new(width, height))
}
}
impl<L: Clone> From<L> for BorderRadiusSize<L> {
fn from(radius: L) -> Self {
Self::new(radius.clone(), radius)
}
}
impl<L> ToCss for BorderRadiusSize<L>
where L: ToCss,
{
fn to_css<W>(&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)
}
}