Auto merge of #7502 - bjwbell:elliptical-borders, r=pcwalton

gfx: Add elliptical border radius support

TODO: Add code for parsing shorthand border-radius e.g. "border-radius: 10px 5% / 20px".

r? @pcwalton

<!-- Reviewable:start -->
[<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/7502)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2015-09-04 18:46:24 -06:00
commit 5bad6b1b6e
9 changed files with 603 additions and 305 deletions

View file

@ -377,9 +377,9 @@ pub mod longhands {
// FIXME(#4126): when gfx supports painting it, make this Size2D<LengthOrPercentage>
% for corner in ["top-left", "top-right", "bottom-right", "bottom-left"]:
${predefined_type("border-" + corner + "-radius", "LengthOrPercentage",
"computed::LengthOrPercentage::Length(Au(0))",
"parse_non_negative")}
${predefined_type("border-" + corner + "-radius", "BorderRadiusSize",
"computed::BorderRadiusSize::zero()",
"parse")}
% endfor
${new_style_struct("Outline", is_inherited=False)}
@ -5135,16 +5135,16 @@ pub mod shorthands {
'border-%s-radius' % (corner)
for corner in ['top-left', 'top-right', 'bottom-right', 'bottom-left']
)}">
use util::geometry::Au;
use values::specified::{Length, LengthOrPercentage};
use values::specified::BorderRadiusSize;
let _ignored = context;
fn parse_one_set_of_border_radii(mut input: &mut Parser)
-> Result<[LengthOrPercentage; 4], ()> {
-> Result<[BorderRadiusSize; 4], ()> {
let mut count = 0;
let mut values = [LengthOrPercentage::Length(Length::Absolute(Au(0))); 4];
let mut values = [BorderRadiusSize::zero(); 4];
while count < 4 {
if let Ok(value) = input.try(LengthOrPercentage::parse) {
if let Ok(value) = input.try(BorderRadiusSize::parse_one_radii) {
values[count] = value;
count += 1;
} else {
@ -5162,7 +5162,7 @@ pub mod shorthands {
}
let radii = try!(parse_one_set_of_border_radii(input));
// TODO(pcwalton): Elliptical borders.
// TODO(bjwbell): Finish parsing code for elliptical borders.
Ok(Longhands {
border_top_left_radius: Some(radii[0]),

View file

@ -834,6 +834,46 @@ pub mod specified {
}
}
#[derive(Clone, PartialEq, Copy, Debug, HeapSizeOf)]
pub struct BorderRadiusSize(pub Size2D<LengthOrPercentage>);
impl BorderRadiusSize {
pub fn zero() -> BorderRadiusSize {
let zero = LengthOrPercentage::Length(Length::Absolute(Au(0)));
BorderRadiusSize(Size2D::new(zero, zero))
}
}
impl ToCss for BorderRadiusSize {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
let BorderRadiusSize(size) = *self;
try!(size.width.to_css(dest));
try!(dest.write_str(" "));
size.height.to_css(dest)
}
}
impl BorderRadiusSize {
pub fn circle(radius: LengthOrPercentage) -> BorderRadiusSize {
BorderRadiusSize(Size2D::new(radius, radius))
}
pub fn parse_one_radii(input: &mut Parser) -> Result<BorderRadiusSize, ()> {
if let Ok(first) = LengthOrPercentage::parse_non_negative(input) {
Ok(BorderRadiusSize(Size2D::new(first, first)))
} else {
Err(())
}
}
#[allow(dead_code)]
#[inline]
pub fn parse(input: &mut Parser) -> Result<BorderRadiusSize, ()> {
let first = try!(LengthOrPercentage::parse_non_negative(input));
let second = input.try(LengthOrPercentage::parse_non_negative).unwrap_or(first);
Ok(BorderRadiusSize(Size2D::new(first, second)))
}
}
// http://dev.w3.org/csswg/css2/colors.html#propdef-background-position
#[derive(Clone, PartialEq, Copy)]
pub enum PositionComponent {
@ -1091,6 +1131,22 @@ pub mod specified {
}
}
pub fn parse_border_radius(input: &mut Parser) -> Result<BorderRadiusSize, ()> {
input.try(BorderRadiusSize::parse).or_else(|()| {
match_ignore_ascii_case! { try!(input.expect_ident()),
"thin" =>
Ok(BorderRadiusSize::circle(
LengthOrPercentage::Length(Length::from_px(1.)))),
"medium" =>
Ok(BorderRadiusSize::circle(
LengthOrPercentage::Length(Length::from_px(3.)))),
"thick" =>
Ok(BorderRadiusSize::circle(
LengthOrPercentage::Length(Length::from_px(5.))))
_ => Err(())
}
})
}
pub fn parse_border_width(input: &mut Parser) -> Result<Length, ()> {
input.try(Length::parse_non_negative).or_else(|()| {
@ -1302,6 +1358,36 @@ pub mod computed {
}
#[derive(PartialEq, Clone, Copy, HeapSizeOf)]
pub struct BorderRadiusSize(pub Size2D<LengthOrPercentage>);
impl BorderRadiusSize {
pub fn zero() -> BorderRadiusSize {
BorderRadiusSize(Size2D::new(LengthOrPercentage::Length(Au(0)), LengthOrPercentage::Length(Au(0))))
}
}
impl ToComputedValue for specified::BorderRadiusSize {
type ComputedValue = BorderRadiusSize;
#[inline]
fn to_computed_value(&self, context: &Context) -> BorderRadiusSize {
let specified::BorderRadiusSize(s) = *self;
let w = s.width.to_computed_value(context);
let h = s.height.to_computed_value(context);
BorderRadiusSize(Size2D::new(w, h))
}
}
impl ::cssparser::ToCss for BorderRadiusSize {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
let BorderRadiusSize(s) = *self;
try!(s.width.to_css(dest));
try!(dest.write_str("/"));
s.height.to_css(dest)
}
}
#[derive(PartialEq, Clone, Copy, HeapSizeOf)]
pub enum LengthOrPercentage {
Length(Au),