mirror of
https://github.com/servo/servo.git
synced 2025-08-05 13:40:08 +01:00
Cleanup Polygon and make it generic
This commit is contained in:
parent
a36bf9efc4
commit
f4b18643c2
4 changed files with 118 additions and 141 deletions
|
@ -329,6 +329,7 @@ pub mod basic_shape {
|
|||
use values::computed::basic_shape::*;
|
||||
use values::computed::position;
|
||||
use values::generics::BorderRadiusSize as GenericBorderRadiusSize;
|
||||
use values::generics::basic_shape::FillRule;
|
||||
|
||||
// using Borrow so that we can have a non-moving .into()
|
||||
impl<T: Borrow<StyleBasicShape>> From<T> for BasicShape {
|
||||
|
|
|
@ -12,9 +12,11 @@ use style_traits::ToCss;
|
|||
use values::computed::LengthOrPercentage;
|
||||
use values::computed::position::Position;
|
||||
use values::generics::basic_shape::{BorderRadius as GenericBorderRadius, ShapeRadius as GenericShapeRadius};
|
||||
use values::generics::basic_shape::Polygon as GenericPolygon;
|
||||
use values::specified::url::SpecifiedUrl;
|
||||
|
||||
pub use values::specified::basic_shape::{self, FillRule, GeometryBox, ShapeBox};
|
||||
pub use values::generics::basic_shape::FillRule;
|
||||
pub use values::specified::basic_shape::{self, GeometryBox, ShapeBox};
|
||||
|
||||
#[derive(Clone, PartialEq, Debug)]
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
|
@ -141,35 +143,8 @@ impl ToCss for Ellipse {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Debug)]
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
#[allow(missing_docs)]
|
||||
/// https://drafts.csswg.org/css-shapes/#funcdef-polygon
|
||||
pub struct Polygon {
|
||||
pub fill: FillRule,
|
||||
pub coordinates: Vec<(LengthOrPercentage, LengthOrPercentage)>,
|
||||
}
|
||||
|
||||
impl ToCss for Polygon {
|
||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||
try!(dest.write_str("polygon("));
|
||||
let mut need_space = false;
|
||||
if self.fill != Default::default() {
|
||||
try!(self.fill.to_css(dest));
|
||||
try!(dest.write_str(", "));
|
||||
}
|
||||
for coord in &self.coordinates {
|
||||
if need_space {
|
||||
try!(dest.write_str(", "));
|
||||
}
|
||||
try!(coord.0.to_css(dest));
|
||||
try!(dest.write_str(" "));
|
||||
try!(coord.1.to_css(dest));
|
||||
need_space = true;
|
||||
}
|
||||
dest.write_str(")")
|
||||
}
|
||||
}
|
||||
/// The computed value of `Polygon`
|
||||
pub type Polygon = GenericPolygon<LengthOrPercentage>;
|
||||
|
||||
/// The computed value of `BorderRadius`
|
||||
pub type BorderRadius = GenericBorderRadius<LengthOrPercentage>;
|
||||
|
|
|
@ -5,11 +5,14 @@
|
|||
//! CSS handling for the [`basic-shape`](https://drafts.csswg.org/css-shapes/#typedef-basic-shape)
|
||||
//! types that are generic over their `ToCss` implementations.
|
||||
|
||||
use cssparser::Parser;
|
||||
use euclid::size::Size2D;
|
||||
use parser::{Parse, ParserContext};
|
||||
use properties::shorthands::serialize_four_sides;
|
||||
use std::ascii::AsciiExt;
|
||||
use std::fmt;
|
||||
use style_traits::ToCss;
|
||||
use values::computed::{Context, ToComputedValue};
|
||||
use values::computed::{ComputedValueAsSpecified, Context, ToComputedValue};
|
||||
use values::generics::BorderRadiusSize;
|
||||
|
||||
/// A generic type used for `border-radius`, `outline-radius` and `inset()` values.
|
||||
|
@ -126,3 +129,108 @@ impl<L: ToComputedValue> ToComputedValue for ShapeRadius<L> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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`
|
||||
define_css_keyword_enum!(FillRule:
|
||||
"nonzero" => NonZero,
|
||||
"evenodd" => EvenOdd
|
||||
);
|
||||
|
||||
impl ComputedValueAsSpecified for FillRule {}
|
||||
|
||||
impl Default for FillRule {
|
||||
#[inline]
|
||||
fn default() -> Self { FillRule::NonZero }
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Debug)]
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
/// A generic type for representing the `polygon()` function
|
||||
///
|
||||
/// https://drafts.csswg.org/css-shapes/#funcdef-polygon
|
||||
pub struct Polygon<L> {
|
||||
/// The filling rule for a polygon.
|
||||
pub fill: FillRule,
|
||||
/// A collection of (x, y) coordinates to draw the polygon.
|
||||
pub coordinates: Vec<(L, L)>,
|
||||
}
|
||||
|
||||
impl<L: Parse> Polygon<L> {
|
||||
/// Parse the inner arguments of a `polygon` function.
|
||||
pub fn parse_function_arguments(context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
|
||||
let fill = input.try(|i| -> Result<_, ()> {
|
||||
let fill = FillRule::parse(i)?;
|
||||
i.expect_comma()?; // only eat the comma if there is something before it
|
||||
Ok(fill)
|
||||
}).ok().unwrap_or_default();
|
||||
|
||||
let buf = input.parse_comma_separated(|i| {
|
||||
Ok((L::parse(context, i)?, L::parse(context, i)?))
|
||||
})?;
|
||||
|
||||
Ok(Polygon {
|
||||
fill: fill,
|
||||
coordinates: buf,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<L: Parse> Parse for Polygon<L> {
|
||||
fn parse(context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
|
||||
match input.expect_function() {
|
||||
Ok(ref s) if s.eq_ignore_ascii_case("polygon") =>
|
||||
input.parse_nested_block(|i| Polygon::parse_function_arguments(context, i)),
|
||||
_ => Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<L: ToCss> ToCss for Polygon<L> {
|
||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||
dest.write_str("polygon(")?;
|
||||
if self.fill != FillRule::default() {
|
||||
self.fill.to_css(dest)?;
|
||||
dest.write_str(", ")?;
|
||||
}
|
||||
|
||||
for (i, coord) in self.coordinates.iter().enumerate() {
|
||||
if i > 0 {
|
||||
dest.write_str(", ")?;
|
||||
}
|
||||
|
||||
coord.0.to_css(dest)?;
|
||||
dest.write_str(" ")?;
|
||||
coord.1.to_css(dest)?;
|
||||
}
|
||||
|
||||
dest.write_str(")")
|
||||
}
|
||||
}
|
||||
|
||||
impl<L: ToComputedValue> ToComputedValue for Polygon<L> {
|
||||
type ComputedValue = Polygon<L::ComputedValue>;
|
||||
|
||||
#[inline]
|
||||
fn to_computed_value(&self, cx: &Context) -> Self::ComputedValue {
|
||||
Polygon {
|
||||
fill: self.fill.to_computed_value(cx),
|
||||
coordinates: self.coordinates.iter().map(|c| {
|
||||
(c.0.to_computed_value(cx), c.1.to_computed_value(cx))
|
||||
}).collect(),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn from_computed_value(computed: &Self::ComputedValue) -> Self {
|
||||
Polygon {
|
||||
fill: ToComputedValue::from_computed_value(&computed.fill),
|
||||
coordinates: computed.coordinates.iter().map(|c| {
|
||||
(ToComputedValue::from_computed_value(&c.0),
|
||||
ToComputedValue::from_computed_value(&c.1))
|
||||
}).collect(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ use values::computed::{ComputedValueAsSpecified, Context, ToComputedValue};
|
|||
use values::computed::basic_shape as computed_basic_shape;
|
||||
use values::generics::BorderRadiusSize;
|
||||
use values::generics::basic_shape::{BorderRadius as GenericBorderRadius, ShapeRadius as GenericShapeRadius};
|
||||
use values::generics::basic_shape::Polygon as GenericPolygon;
|
||||
use values::specified::{LengthOrPercentage, Percentage};
|
||||
use values::specified::position::{Keyword, Position};
|
||||
use values::specified::url::SpecifiedUrl;
|
||||
|
@ -520,99 +521,8 @@ impl ToComputedValue for Ellipse {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Clone, PartialEq, Debug)]
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
/// https://drafts.csswg.org/css-shapes/#funcdef-polygon
|
||||
#[allow(missing_docs)]
|
||||
pub struct Polygon {
|
||||
pub fill: FillRule,
|
||||
pub coordinates: Vec<(LengthOrPercentage, LengthOrPercentage)>,
|
||||
}
|
||||
|
||||
impl Polygon {
|
||||
#[allow(missing_docs)]
|
||||
pub fn parse_function_arguments(context: &ParserContext, input: &mut Parser) -> Result<Polygon, ()> {
|
||||
let fill = input.try(|input| {
|
||||
let fill = FillRule::parse(input);
|
||||
// only eat the comma if there is something before it
|
||||
try!(input.expect_comma());
|
||||
fill
|
||||
}).ok().unwrap_or_else(Default::default);
|
||||
|
||||
let buf = try!(input.parse_comma_separated(|input| {
|
||||
Ok((try!(LengthOrPercentage::parse(context, input)),
|
||||
try!(LengthOrPercentage::parse(context, input))))
|
||||
}));
|
||||
|
||||
Ok(Polygon {
|
||||
fill: fill,
|
||||
coordinates: buf,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Parse for Polygon {
|
||||
fn parse(context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
|
||||
match input.try(|i| i.expect_function()) {
|
||||
Ok(ref s) if s.eq_ignore_ascii_case("polygon") =>
|
||||
input.parse_nested_block(|i| Polygon::parse_function_arguments(context, i)),
|
||||
_ => Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToCss for Polygon {
|
||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||
try!(dest.write_str("polygon("));
|
||||
let mut need_space = false;
|
||||
if self.fill != Default::default() {
|
||||
try!(self.fill.to_css(dest));
|
||||
try!(dest.write_str(", "));
|
||||
}
|
||||
|
||||
for coord in &self.coordinates {
|
||||
if need_space {
|
||||
try!(dest.write_str(", "));
|
||||
}
|
||||
|
||||
try!(coord.0.to_css(dest));
|
||||
try!(dest.write_str(" "));
|
||||
try!(coord.1.to_css(dest));
|
||||
need_space = true;
|
||||
}
|
||||
|
||||
dest.write_str(")")
|
||||
}
|
||||
}
|
||||
|
||||
impl ToComputedValue for Polygon {
|
||||
type ComputedValue = computed_basic_shape::Polygon;
|
||||
|
||||
#[inline]
|
||||
fn to_computed_value(&self, cx: &Context) -> Self::ComputedValue {
|
||||
computed_basic_shape::Polygon {
|
||||
fill: self.fill.to_computed_value(cx),
|
||||
coordinates: self.coordinates.iter()
|
||||
.map(|c| {
|
||||
(c.0.to_computed_value(cx),
|
||||
c.1.to_computed_value(cx))
|
||||
}).collect(),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn from_computed_value(computed: &Self::ComputedValue) -> Self {
|
||||
Polygon {
|
||||
fill: ToComputedValue::from_computed_value(&computed.fill),
|
||||
coordinates: computed.coordinates.iter()
|
||||
.map(|c| {
|
||||
(ToComputedValue::from_computed_value(&c.0),
|
||||
ToComputedValue::from_computed_value(&c.1))
|
||||
}).collect(),
|
||||
}
|
||||
}
|
||||
}
|
||||
/// The specified value of `Polygon`
|
||||
pub type Polygon = GenericPolygon<LengthOrPercentage>;
|
||||
|
||||
/// The specified value of `ShapeRadius`
|
||||
pub type ShapeRadius = GenericShapeRadius<LengthOrPercentage>;
|
||||
|
@ -677,23 +587,6 @@ fn parse_one_set_of_border_values(context: &ParserContext, mut input: &mut Parse
|
|||
}
|
||||
}
|
||||
|
||||
// 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`
|
||||
define_css_keyword_enum!(FillRule:
|
||||
"nonzero" => NonZero,
|
||||
"evenodd" => EvenOdd
|
||||
);
|
||||
|
||||
impl ComputedValueAsSpecified for FillRule {}
|
||||
|
||||
impl Default for FillRule {
|
||||
fn default() -> Self {
|
||||
FillRule::NonZero
|
||||
}
|
||||
}
|
||||
|
||||
/// https://drafts.fxtf.org/css-masking-1/#typedef-geometry-box
|
||||
#[derive(Clone, PartialEq, Copy, Debug)]
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue