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::basic_shape::*;
|
||||||
use values::computed::position;
|
use values::computed::position;
|
||||||
use values::generics::BorderRadiusSize as GenericBorderRadiusSize;
|
use values::generics::BorderRadiusSize as GenericBorderRadiusSize;
|
||||||
|
use values::generics::basic_shape::FillRule;
|
||||||
|
|
||||||
// using Borrow so that we can have a non-moving .into()
|
// using Borrow so that we can have a non-moving .into()
|
||||||
impl<T: Borrow<StyleBasicShape>> From<T> for BasicShape {
|
impl<T: Borrow<StyleBasicShape>> From<T> for BasicShape {
|
||||||
|
|
|
@ -12,9 +12,11 @@ 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, ShapeRadius as GenericShapeRadius};
|
use values::generics::basic_shape::{BorderRadius as GenericBorderRadius, ShapeRadius as GenericShapeRadius};
|
||||||
|
use values::generics::basic_shape::Polygon as GenericPolygon;
|
||||||
use values::specified::url::SpecifiedUrl;
|
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)]
|
#[derive(Clone, PartialEq, Debug)]
|
||||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
|
@ -141,35 +143,8 @@ impl ToCss for Ellipse {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug)]
|
/// The computed value of `Polygon`
|
||||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
pub type Polygon = GenericPolygon<LengthOrPercentage>;
|
||||||
#[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 `BorderRadius`
|
/// The computed value of `BorderRadius`
|
||||||
pub type BorderRadius = GenericBorderRadius<LengthOrPercentage>;
|
pub type BorderRadius = GenericBorderRadius<LengthOrPercentage>;
|
||||||
|
|
|
@ -5,11 +5,14 @@
|
||||||
//! CSS handling for the [`basic-shape`](https://drafts.csswg.org/css-shapes/#typedef-basic-shape)
|
//! CSS handling for the [`basic-shape`](https://drafts.csswg.org/css-shapes/#typedef-basic-shape)
|
||||||
//! types that are generic over their `ToCss` implementations.
|
//! types that are generic over their `ToCss` implementations.
|
||||||
|
|
||||||
|
use cssparser::Parser;
|
||||||
use euclid::size::Size2D;
|
use euclid::size::Size2D;
|
||||||
|
use parser::{Parse, ParserContext};
|
||||||
use properties::shorthands::serialize_four_sides;
|
use properties::shorthands::serialize_four_sides;
|
||||||
|
use std::ascii::AsciiExt;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use style_traits::ToCss;
|
use style_traits::ToCss;
|
||||||
use values::computed::{Context, ToComputedValue};
|
use values::computed::{ComputedValueAsSpecified, Context, ToComputedValue};
|
||||||
use values::generics::BorderRadiusSize;
|
use values::generics::BorderRadiusSize;
|
||||||
|
|
||||||
/// A generic type used for `border-radius`, `outline-radius` and `inset()` values.
|
/// 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::computed::basic_shape as computed_basic_shape;
|
||||||
use values::generics::BorderRadiusSize;
|
use values::generics::BorderRadiusSize;
|
||||||
use values::generics::basic_shape::{BorderRadius as GenericBorderRadius, ShapeRadius as GenericShapeRadius};
|
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::{LengthOrPercentage, Percentage};
|
||||||
use values::specified::position::{Keyword, Position};
|
use values::specified::position::{Keyword, Position};
|
||||||
use values::specified::url::SpecifiedUrl;
|
use values::specified::url::SpecifiedUrl;
|
||||||
|
@ -520,99 +521,8 @@ impl ToComputedValue for Ellipse {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The specified value of `Polygon`
|
||||||
#[derive(Clone, PartialEq, Debug)]
|
pub type Polygon = GenericPolygon<LengthOrPercentage>;
|
||||||
#[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 `ShapeRadius`
|
/// The specified value of `ShapeRadius`
|
||||||
pub type ShapeRadius = GenericShapeRadius<LengthOrPercentage>;
|
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
|
/// https://drafts.fxtf.org/css-masking-1/#typedef-geometry-box
|
||||||
#[derive(Clone, PartialEq, Copy, Debug)]
|
#[derive(Clone, PartialEq, Copy, Debug)]
|
||||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue