Make ShapeRadius generic

This commit is contained in:
Ravi Shankar 2017-04-12 23:13:59 +05:30
parent b2b3f99427
commit a36bf9efc4
4 changed files with 72 additions and 98 deletions

View file

@ -15,7 +15,8 @@ use values::{Auto, Either, ExtremumLength, None_, Normal};
use values::computed::{Angle, LengthOrPercentage, LengthOrPercentageOrAuto}; use values::computed::{Angle, LengthOrPercentage, LengthOrPercentageOrAuto};
use values::computed::{LengthOrPercentageOrNone, Number, NumberOrPercentage}; use values::computed::{LengthOrPercentageOrNone, Number, NumberOrPercentage};
use values::computed::{MaxLength, MinLength}; use values::computed::{MaxLength, MinLength};
use values::computed::basic_shape::ShapeRadius; use values::computed::basic_shape::ShapeRadius as ComputedShapeRadius;
use values::generics::basic_shape::ShapeRadius;
use values::specified::Percentage; use values::specified::Percentage;
use values::specified::grid::{TrackBreadth, TrackKeyword}; use values::specified::grid::{TrackBreadth, TrackKeyword};
@ -205,15 +206,13 @@ impl<L: GeckoStyleCoordConvertible> GeckoStyleCoordConvertible for TrackBreadth<
} }
} }
impl GeckoStyleCoordConvertible for ShapeRadius { impl GeckoStyleCoordConvertible for ComputedShapeRadius {
fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) { fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
match *self { match *self {
ShapeRadius::ClosestSide => { ShapeRadius::ClosestSide =>
coord.set_value(CoordDataValue::Enumerated(StyleShapeRadius::ClosestSide as u32)) coord.set_value(CoordDataValue::Enumerated(StyleShapeRadius::ClosestSide as u32)),
} ShapeRadius::FarthestSide =>
ShapeRadius::FarthestSide => { coord.set_value(CoordDataValue::Enumerated(StyleShapeRadius::FarthestSide as u32)),
coord.set_value(CoordDataValue::Enumerated(StyleShapeRadius::FarthestSide as u32))
}
ShapeRadius::Length(lop) => lop.to_gecko_style_coord(coord), ShapeRadius::Length(lop) => lop.to_gecko_style_coord(coord),
} }
} }

View file

@ -11,7 +11,7 @@ use std::fmt;
use style_traits::ToCss; use style_traits::ToCss;
use values::computed::LengthOrPercentage; use values::computed::LengthOrPercentage;
use values::computed::position::Position; use values::computed::position::Position;
use values::generics::basic_shape::BorderRadius as GenericBorderRadius; use values::generics::basic_shape::{BorderRadius as GenericBorderRadius, ShapeRadius as GenericShapeRadius};
use values::specified::url::SpecifiedUrl; use values::specified::url::SpecifiedUrl;
pub use values::specified::basic_shape::{self, FillRule, GeometryBox, ShapeBox}; pub use values::specified::basic_shape::{self, FillRule, GeometryBox, ShapeBox};
@ -171,31 +171,10 @@ impl ToCss for Polygon {
} }
} }
/// https://drafts.csswg.org/css-shapes/#typedef-shape-radius
#[derive(Clone, PartialEq, Copy, Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
#[allow(missing_docs)]
pub enum ShapeRadius {
Length(LengthOrPercentage),
ClosestSide,
FarthestSide,
}
impl Default for ShapeRadius {
fn default() -> Self {
ShapeRadius::ClosestSide
}
}
impl ToCss for ShapeRadius {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
match *self {
ShapeRadius::Length(lop) => lop.to_css(dest),
ShapeRadius::ClosestSide => dest.write_str("closest-side"),
ShapeRadius::FarthestSide => dest.write_str("farthest-side"),
}
}
}
/// The computed value of `BorderRadius` /// The computed value of `BorderRadius`
pub type BorderRadius = GenericBorderRadius<LengthOrPercentage>; pub type BorderRadius = GenericBorderRadius<LengthOrPercentage>;
/// The computed value of `ShapeRadius`
pub type ShapeRadius = GenericShapeRadius<LengthOrPercentage>;
impl Copy for ShapeRadius {}

View file

@ -78,3 +78,51 @@ impl<L: ToComputedValue> ToComputedValue for BorderRadius<L> {
} }
} }
} }
/// https://drafts.csswg.org/css-shapes/#typedef-shape-radius
#[derive(Clone, PartialEq, Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
#[allow(missing_docs)]
pub enum ShapeRadius<L> {
Length(L),
ClosestSide,
FarthestSide,
}
impl<L> Default for ShapeRadius<L> {
#[inline]
fn default() -> Self { ShapeRadius::ClosestSide }
}
impl<L: ToCss> ToCss for ShapeRadius<L> {
#[inline]
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
match *self {
ShapeRadius::Length(ref lop) => lop.to_css(dest),
ShapeRadius::ClosestSide => dest.write_str("closest-side"),
ShapeRadius::FarthestSide => dest.write_str("farthest-side"),
}
}
}
impl<L: ToComputedValue> ToComputedValue for ShapeRadius<L> {
type ComputedValue = ShapeRadius<L::ComputedValue>;
#[inline]
fn to_computed_value(&self, cx: &Context) -> Self::ComputedValue {
match *self {
ShapeRadius::Length(ref lop) => ShapeRadius::Length(lop.to_computed_value(cx)),
ShapeRadius::ClosestSide => ShapeRadius::ClosestSide,
ShapeRadius::FarthestSide => ShapeRadius::FarthestSide,
}
}
#[inline]
fn from_computed_value(computed: &Self::ComputedValue) -> Self {
match *computed {
ShapeRadius::Length(ref lop) => ShapeRadius::Length(ToComputedValue::from_computed_value(lop)),
ShapeRadius::ClosestSide => ShapeRadius::ClosestSide,
ShapeRadius::FarthestSide => ShapeRadius::FarthestSide,
}
}
}

View file

@ -17,7 +17,7 @@ use values::HasViewportPercentage;
use values::computed::{ComputedValueAsSpecified, Context, ToComputedValue}; use values::computed::{ComputedValueAsSpecified, Context, ToComputedValue};
use values::computed::basic_shape as computed_basic_shape; use values::computed::basic_shape as computed_basic_shape;
use values::generics::BorderRadiusSize; use values::generics::BorderRadiusSize;
use values::generics::basic_shape::BorderRadius as GenericBorderRadius; use values::generics::basic_shape::{BorderRadius as GenericBorderRadius, ShapeRadius as GenericShapeRadius};
use values::specified::{LengthOrPercentage, Percentage}; use values::specified::{LengthOrPercentage, Percentage};
use values::specified::position::{Keyword, Position}; use values::specified::position::{Keyword, Position};
use values::specified::url::SpecifiedUrl; use values::specified::url::SpecifiedUrl;
@ -411,7 +411,7 @@ impl Parse for Circle {
impl ToCss for Circle { impl ToCss for Circle {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
try!(dest.write_str("circle(")); try!(dest.write_str("circle("));
if ShapeRadius::ClosestSide != self.radius { if GenericShapeRadius::ClosestSide != self.radius {
try!(self.radius.to_css(dest)); try!(self.radius.to_css(dest));
try!(dest.write_str(" ")); try!(dest.write_str(" "));
} }
@ -485,7 +485,7 @@ impl Parse for Ellipse {
impl ToCss for Ellipse { impl ToCss for Ellipse {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
try!(dest.write_str("ellipse(")); try!(dest.write_str("ellipse("));
if !self.semiaxis_x.is_default() || !self.semiaxis_y.is_default() { if self.semiaxis_x != ShapeRadius::default() || self.semiaxis_y != ShapeRadius::default() {
try!(self.semiaxis_x.to_css(dest)); try!(self.semiaxis_x.to_css(dest));
try!(dest.write_str(" ")); try!(dest.write_str(" "));
try!(self.semiaxis_y.to_css(dest)); try!(self.semiaxis_y.to_css(dest));
@ -614,72 +614,20 @@ impl ToComputedValue for Polygon {
} }
} }
/// https://drafts.csswg.org/css-shapes/#typedef-shape-radius /// The specified value of `ShapeRadius`
#[derive(Clone, PartialEq, Debug)] pub type ShapeRadius = GenericShapeRadius<LengthOrPercentage>;
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
#[allow(missing_docs)]
pub enum ShapeRadius {
Length(LengthOrPercentage),
ClosestSide,
FarthestSide,
}
impl ShapeRadius {
fn is_default(&self) -> bool {
*self == ShapeRadius::ClosestSide
}
}
impl Default for ShapeRadius {
fn default() -> Self {
ShapeRadius::ClosestSide
}
}
impl Parse for ShapeRadius { impl Parse for ShapeRadius {
fn parse(context: &ParserContext, input: &mut Parser) -> Result<Self, ()> { fn parse(context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
input.try(|i| LengthOrPercentage::parse_non_negative(context, i)).map(ShapeRadius::Length).or_else(|_| { if let Ok(lop) = input.try(|i| LengthOrPercentage::parse_non_negative(context, i)) {
match_ignore_ascii_case! { &try!(input.expect_ident()), return Ok(GenericShapeRadius::Length(lop))
"closest-side" => Ok(ShapeRadius::ClosestSide), }
"farthest-side" => Ok(ShapeRadius::FarthestSide),
match_ignore_ascii_case! { &input.expect_ident()?,
"closest-side" => Ok(GenericShapeRadius::ClosestSide),
"farthest-side" => Ok(GenericShapeRadius::FarthestSide),
_ => Err(()) _ => Err(())
} }
})
}
}
impl ToCss for ShapeRadius {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
match *self {
ShapeRadius::Length(ref lop) => lop.to_css(dest),
ShapeRadius::ClosestSide => dest.write_str("closest-side"),
ShapeRadius::FarthestSide => dest.write_str("farthest-side"),
}
}
}
impl ToComputedValue for ShapeRadius {
type ComputedValue = computed_basic_shape::ShapeRadius;
#[inline]
fn to_computed_value(&self, cx: &Context) -> Self::ComputedValue {
match *self {
ShapeRadius::Length(ref lop) =>
computed_basic_shape::ShapeRadius::Length(lop.to_computed_value(cx)),
ShapeRadius::ClosestSide => computed_basic_shape::ShapeRadius::ClosestSide,
ShapeRadius::FarthestSide => computed_basic_shape::ShapeRadius::FarthestSide,
}
}
#[inline]
fn from_computed_value(computed: &Self::ComputedValue) -> Self {
match *computed {
computed_basic_shape::ShapeRadius::Length(ref lop) =>
ShapeRadius::Length(ToComputedValue::from_computed_value(lop)),
computed_basic_shape::ShapeRadius::ClosestSide => ShapeRadius::ClosestSide,
computed_basic_shape::ShapeRadius::FarthestSide => ShapeRadius::FarthestSide,
}
} }
} }