Add Circle to basic_shape.rs

This commit is contained in:
Manish Goregaokar 2016-08-01 16:10:17 +05:30
parent 44e33bcdc5
commit 77f345476f
No known key found for this signature in database
GPG key ID: 3BBF4D3E2EF79F98
3 changed files with 88 additions and 4 deletions

View file

@ -9,6 +9,7 @@
use values::computed::{Length, LengthOrPercentage}; use values::computed::{Length, LengthOrPercentage};
use values::computed::BorderRadiusSize; use values::computed::BorderRadiusSize;
use values::computed::position::Position;
use std::fmt; use std::fmt;
use cssparser::{self, Parser, ToCss, Token}; use cssparser::{self, Parser, ToCss, Token};
@ -16,11 +17,20 @@ use cssparser::{self, Parser, ToCss, Token};
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub enum BasicShape { pub enum BasicShape {
Inset(InsetRect), Inset(InsetRect),
// Circle(Circle), Circle(Circle),
// Ellipse(Ellipse), // Ellipse(Ellipse),
// Polygon(Polygon), // Polygon(Polygon),
} }
impl ToCss for BasicShape {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
match *self {
BasicShape::Inset(rect) => rect.to_css(dest),
BasicShape::Circle(circle) => circle.to_css(dest),
}
}
}
#[derive(Clone, PartialEq, Copy, Debug)] #[derive(Clone, PartialEq, Copy, Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct InsetRect { pub struct InsetRect {
@ -50,6 +60,21 @@ impl ToCss for InsetRect {
} }
} }
#[derive(Clone, PartialEq, Copy, Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct Circle {
pub radius: ShapeRadius,
pub position: Position,
}
impl ToCss for Circle {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
try!(self.radius.to_css(dest));
try!(dest.write_str(" at "));
self.position.to_css(dest)
}
}
/// https://drafts.csswg.org/css-shapes/#typedef-shape-radius /// https://drafts.csswg.org/css-shapes/#typedef-shape-radius
#[derive(Clone, PartialEq, Copy, Debug)] #[derive(Clone, PartialEq, Copy, Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]

View file

@ -16,6 +16,7 @@ use url::Url;
use properties::shorthands::parse_four_sides; use properties::shorthands::parse_four_sides;
use values::specified::{Length, LengthOrPercentage}; use values::specified::{Length, LengthOrPercentage};
use values::specified::BorderRadiusSize; use values::specified::BorderRadiusSize;
use values::specified::position::{Position, PositionComponent};
use values::computed::{Context, ToComputedValue}; use values::computed::{Context, ToComputedValue};
use values::computed::basic_shape as computed_basic_shape; use values::computed::basic_shape as computed_basic_shape;
@ -23,7 +24,7 @@ use values::computed::basic_shape as computed_basic_shape;
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub enum BasicShape { pub enum BasicShape {
Inset(InsetRect), Inset(InsetRect),
// Circle(Circle), Circle(Circle),
// Ellipse(Ellipse), // Ellipse(Ellipse),
// Polygon(Polygon), // Polygon(Polygon),
} }
@ -32,6 +33,8 @@ impl BasicShape {
pub fn parse(input: &mut Parser) -> Result<BasicShape, ()> { pub fn parse(input: &mut Parser) -> Result<BasicShape, ()> {
if let Ok(result) = input.try(InsetRect::parse) { if let Ok(result) = input.try(InsetRect::parse) {
Ok(BasicShape::Inset(result)) Ok(BasicShape::Inset(result))
} else if let Ok(result) = input.try(Circle::parse) {
Ok(BasicShape::Circle(result))
} else { } else {
Err(()) Err(())
} }
@ -42,6 +45,7 @@ impl ToCss for BasicShape {
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 {
match *self { match *self {
BasicShape::Inset(rect) => rect.to_css(dest), BasicShape::Inset(rect) => rect.to_css(dest),
BasicShape::Circle(circle) => circle.to_css(dest),
} }
} }
} }
@ -53,6 +57,7 @@ impl ToComputedValue for BasicShape {
fn to_computed_value(&self, cx: &Context) -> Self::ComputedValue { fn to_computed_value(&self, cx: &Context) -> Self::ComputedValue {
match *self { match *self {
BasicShape::Inset(rect) => computed_basic_shape::BasicShape::Inset(rect.to_computed_value(cx)), BasicShape::Inset(rect) => computed_basic_shape::BasicShape::Inset(rect.to_computed_value(cx)),
BasicShape::Circle(circle) => computed_basic_shape::BasicShape::Circle(circle.to_computed_value(cx)),
} }
} }
} }
@ -85,7 +90,7 @@ impl InsetRect {
left: l, left: l,
round: None, round: None,
}; };
if let Ok(_) = input.expect_ident_matching("round") { if let Ok(_) = input.try(|input| input.expect_ident_matching("round")) {
rect.round = Some(try!(BorderRadius::parse(input))); rect.round = Some(try!(BorderRadius::parse(input)));
} }
Ok(rect) Ok(rect)
@ -126,6 +131,60 @@ impl ToComputedValue for InsetRect {
} }
} }
#[derive(Clone, PartialEq, Copy, Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct Circle {
pub radius: ShapeRadius,
pub position: Position,
}
impl Circle {
pub fn parse(input: &mut Parser) -> Result<Circle, ()> {
match_ignore_ascii_case! { try!(input.expect_function()),
"circle" => {
Ok(try!(input.parse_nested_block(Circle::parse_function)))
},
_ => Err(())
}
}
pub fn parse_function(input: &mut Parser) -> Result<Circle, ()> {
let radius = input.try(ShapeRadius::parse).ok().unwrap_or_else(Default::default);
let position = if let Ok(_) = input.try(|input| input.expect_ident_matching("at")) {
try!(Position::parse(input))
} else {
// Defaults to origin
try!(Position::new(PositionComponent::Center, PositionComponent::Center))
};
Ok(Circle {
radius: radius,
position: position,
})
}
}
impl ToCss for Circle {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
if ShapeRadius::ClosestSide != self.radius {
try!(self.radius.to_css(dest));
try!(dest.write_str(" "));
}
try!(dest.write_str("at "));
self.position.to_css(dest)
}
}
impl ToComputedValue for Circle {
type ComputedValue = computed_basic_shape::Circle;
#[inline]
fn to_computed_value(&self, cx: &Context) -> Self::ComputedValue {
computed_basic_shape::Circle {
radius: self.radius.to_computed_value(cx),
position: self.position.to_computed_value(cx),
}
}
}
/// https://drafts.csswg.org/css-shapes/#typedef-shape-radius /// https://drafts.csswg.org/css-shapes/#typedef-shape-radius
#[derive(Clone, PartialEq, Copy, Debug)] #[derive(Clone, PartialEq, Copy, Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]

View file

@ -49,7 +49,7 @@ pub enum PositionComponent {
} }
impl Position { impl Position {
fn new(first: PositionComponent, second: PositionComponent) pub fn new(first: PositionComponent, second: PositionComponent)
-> Result<Position, ()> { -> Result<Position, ()> {
let (horiz, vert) = match (category(first), category(second)) { let (horiz, vert) = match (category(first), category(second)) {
// Don't allow two vertical keywords or two horizontal keywords. // Don't allow two vertical keywords or two horizontal keywords.