mirror of
https://github.com/servo/servo.git
synced 2025-08-04 13:10:20 +01:00
Fix parsing of ClipRect
This commit is contained in:
parent
050d9d9097
commit
d7c227f614
6 changed files with 94 additions and 27 deletions
|
@ -1259,8 +1259,10 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
};
|
};
|
||||||
|
|
||||||
// FIXME(pcwalton, #2795): Get the real container size.
|
// FIXME(pcwalton, #2795): Get the real container size.
|
||||||
let clip_origin = Point2D::new(stacking_relative_border_box.origin.x + style_clip_rect.left,
|
let clip_origin = Point2D::new(stacking_relative_border_box.origin.x +
|
||||||
stacking_relative_border_box.origin.y + style_clip_rect.top);
|
style_clip_rect.left.unwrap_or(Au(0)),
|
||||||
|
stacking_relative_border_box.origin.y +
|
||||||
|
style_clip_rect.top.unwrap_or(Au(0)));
|
||||||
let right = style_clip_rect.right.unwrap_or(stacking_relative_border_box.size.width);
|
let right = style_clip_rect.right.unwrap_or(stacking_relative_border_box.size.width);
|
||||||
let bottom = style_clip_rect.bottom.unwrap_or(stacking_relative_border_box.size.height);
|
let bottom = style_clip_rect.bottom.unwrap_or(stacking_relative_border_box.size.height);
|
||||||
let clip_size = Size2D::new(right - clip_origin.x, bottom - clip_origin.y);
|
let clip_size = Size2D::new(right - clip_origin.x, bottom - clip_origin.y);
|
||||||
|
|
|
@ -2286,8 +2286,8 @@ fn static_assert() {
|
||||||
self.gecko.mImageRegion.height = 0;
|
self.gecko.mImageRegion.height = 0;
|
||||||
}
|
}
|
||||||
Either::First(rect) => {
|
Either::First(rect) => {
|
||||||
self.gecko.mImageRegion.x = rect.left.0;
|
self.gecko.mImageRegion.x = rect.left.unwrap_or(Au(0)).0;
|
||||||
self.gecko.mImageRegion.y = rect.top.0;
|
self.gecko.mImageRegion.y = rect.top.unwrap_or(Au(0)).0;
|
||||||
self.gecko.mImageRegion.height = rect.bottom.unwrap_or(Au(0)).0 - self.gecko.mImageRegion.y;
|
self.gecko.mImageRegion.height = rect.bottom.unwrap_or(Au(0)).0 - self.gecko.mImageRegion.y;
|
||||||
self.gecko.mImageRegion.width = rect.right.unwrap_or(Au(0)).0 - self.gecko.mImageRegion.x;
|
self.gecko.mImageRegion.width = rect.right.unwrap_or(Au(0)).0 - self.gecko.mImageRegion.x;
|
||||||
}
|
}
|
||||||
|
@ -2356,6 +2356,8 @@ fn static_assert() {
|
||||||
pub fn set_clip(&mut self, v: longhands::clip::computed_value::T) {
|
pub fn set_clip(&mut self, v: longhands::clip::computed_value::T) {
|
||||||
use gecko_bindings::structs::NS_STYLE_CLIP_AUTO;
|
use gecko_bindings::structs::NS_STYLE_CLIP_AUTO;
|
||||||
use gecko_bindings::structs::NS_STYLE_CLIP_RECT;
|
use gecko_bindings::structs::NS_STYLE_CLIP_RECT;
|
||||||
|
use gecko_bindings::structs::NS_STYLE_CLIP_LEFT_AUTO;
|
||||||
|
use gecko_bindings::structs::NS_STYLE_CLIP_TOP_AUTO;
|
||||||
use gecko_bindings::structs::NS_STYLE_CLIP_RIGHT_AUTO;
|
use gecko_bindings::structs::NS_STYLE_CLIP_RIGHT_AUTO;
|
||||||
use gecko_bindings::structs::NS_STYLE_CLIP_BOTTOM_AUTO;
|
use gecko_bindings::structs::NS_STYLE_CLIP_BOTTOM_AUTO;
|
||||||
use values::Either;
|
use values::Either;
|
||||||
|
@ -2363,8 +2365,19 @@ fn static_assert() {
|
||||||
match v {
|
match v {
|
||||||
Either::First(rect) => {
|
Either::First(rect) => {
|
||||||
self.gecko.mClipFlags = NS_STYLE_CLIP_RECT as u8;
|
self.gecko.mClipFlags = NS_STYLE_CLIP_RECT as u8;
|
||||||
self.gecko.mClip.x = rect.left.0;
|
if let Some(left) = rect.left {
|
||||||
self.gecko.mClip.y = rect.top.0;
|
self.gecko.mClip.x = left.0;
|
||||||
|
} else {
|
||||||
|
self.gecko.mClip.x = 0;
|
||||||
|
self.gecko.mClipFlags |= NS_STYLE_CLIP_LEFT_AUTO as u8;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(top) = rect.top {
|
||||||
|
self.gecko.mClip.y = top.0;
|
||||||
|
} else {
|
||||||
|
self.gecko.mClip.y = 0;
|
||||||
|
self.gecko.mClipFlags |= NS_STYLE_CLIP_TOP_AUTO as u8;
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(bottom) = rect.bottom {
|
if let Some(bottom) = rect.bottom {
|
||||||
self.gecko.mClip.height = bottom.0 - self.gecko.mClip.y;
|
self.gecko.mClip.height = bottom.0 - self.gecko.mClip.y;
|
||||||
|
|
|
@ -294,17 +294,22 @@ pub type LoPOrNumber = Either<LengthOrPercentage, Number>;
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
/// A computed cliprect for clip and image-region
|
/// A computed cliprect for clip and image-region
|
||||||
pub struct ClipRect {
|
pub struct ClipRect {
|
||||||
pub top: Au,
|
pub top: Option<Au>,
|
||||||
pub right: Option<Au>,
|
pub right: Option<Au>,
|
||||||
pub bottom: Option<Au>,
|
pub bottom: Option<Au>,
|
||||||
pub left: Au,
|
pub left: Option<Au>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToCss for ClipRect {
|
impl ToCss for ClipRect {
|
||||||
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("rect("));
|
try!(dest.write_str("rect("));
|
||||||
try!(self.top.to_css(dest));
|
if let Some(top) = self.top {
|
||||||
try!(dest.write_str(", "));
|
try!(top.to_css(dest));
|
||||||
|
try!(dest.write_str(", "));
|
||||||
|
} else {
|
||||||
|
try!(dest.write_str("auto, "));
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(right) = self.right {
|
if let Some(right) = self.right {
|
||||||
try!(right.to_css(dest));
|
try!(right.to_css(dest));
|
||||||
try!(dest.write_str(", "));
|
try!(dest.write_str(", "));
|
||||||
|
@ -319,7 +324,11 @@ impl ToCss for ClipRect {
|
||||||
try!(dest.write_str("auto, "));
|
try!(dest.write_str("auto, "));
|
||||||
}
|
}
|
||||||
|
|
||||||
try!(self.left.to_css(dest));
|
if let Some(left) = self.left {
|
||||||
|
try!(left.to_css(dest));
|
||||||
|
} else {
|
||||||
|
try!(dest.write_str("auto"));
|
||||||
|
}
|
||||||
dest.write_str(")")
|
dest.write_str(")")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -849,10 +849,10 @@ impl LoPOrNumber {
|
||||||
|
|
||||||
impl HasViewportPercentage for ClipRect {
|
impl HasViewportPercentage for ClipRect {
|
||||||
fn has_viewport_percentage(&self) -> bool {
|
fn has_viewport_percentage(&self) -> bool {
|
||||||
self.top.has_viewport_percentage() ||
|
self.top.as_ref().map_or(false, |x| x.has_viewport_percentage()) ||
|
||||||
self.right.as_ref().map_or(false, |x| x.has_viewport_percentage()) ||
|
self.right.as_ref().map_or(false, |x| x.has_viewport_percentage()) ||
|
||||||
self.bottom.as_ref().map_or(false, |x| x.has_viewport_percentage()) ||
|
self.bottom.as_ref().map_or(false, |x| x.has_viewport_percentage()) ||
|
||||||
self.left.has_viewport_percentage()
|
self.left.as_ref().map_or(false, |x| x.has_viewport_percentage())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -860,14 +860,14 @@ impl HasViewportPercentage for ClipRect {
|
||||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
/// rect(<top>, <left>, <bottom>, <right>) used by clip and image-region
|
/// rect(<top>, <left>, <bottom>, <right>) used by clip and image-region
|
||||||
pub struct ClipRect {
|
pub struct ClipRect {
|
||||||
/// <top> (<length> | <auto>). Auto maps to 0
|
/// <top> (<length> | <auto>)
|
||||||
pub top: Length,
|
pub top: Option<Length>,
|
||||||
/// <right> (<length> | <auto>)
|
/// <right> (<length> | <auto>)
|
||||||
pub right: Option<Length>,
|
pub right: Option<Length>,
|
||||||
/// <bottom> (<length> | <auto>)
|
/// <bottom> (<length> | <auto>)
|
||||||
pub bottom: Option<Length>,
|
pub bottom: Option<Length>,
|
||||||
/// <left> (<length> | <auto>). Auto maps to 0
|
/// <left> (<length> | <auto>)
|
||||||
pub left: Length,
|
pub left: Option<Length>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -875,8 +875,12 @@ impl ToCss for ClipRect {
|
||||||
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("rect("));
|
try!(dest.write_str("rect("));
|
||||||
|
|
||||||
try!(self.top.to_css(dest));
|
if let Some(ref top) = self.top {
|
||||||
try!(dest.write_str(", "));
|
try!(top.to_css(dest));
|
||||||
|
try!(dest.write_str(", "));
|
||||||
|
} else {
|
||||||
|
try!(dest.write_str("auto, "));
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(ref right) = self.right {
|
if let Some(ref right) = self.right {
|
||||||
try!(right.to_css(dest));
|
try!(right.to_css(dest));
|
||||||
|
@ -892,7 +896,11 @@ impl ToCss for ClipRect {
|
||||||
try!(dest.write_str("auto, "));
|
try!(dest.write_str("auto, "));
|
||||||
}
|
}
|
||||||
|
|
||||||
try!(self.left.to_css(dest));
|
if let Some(ref left) = self.left {
|
||||||
|
try!(left.to_css(dest));
|
||||||
|
} else {
|
||||||
|
try!(dest.write_str("auto"));
|
||||||
|
}
|
||||||
|
|
||||||
try!(dest.write_str(")"));
|
try!(dest.write_str(")"));
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -905,20 +913,20 @@ impl ToComputedValue for ClipRect {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_computed_value(&self, context: &Context) -> super::computed::ClipRect {
|
fn to_computed_value(&self, context: &Context) -> super::computed::ClipRect {
|
||||||
super::computed::ClipRect {
|
super::computed::ClipRect {
|
||||||
top: self.top.to_computed_value(context),
|
top: self.top.as_ref().map(|top| top.to_computed_value(context)),
|
||||||
right: self.right.as_ref().map(|right| right.to_computed_value(context)),
|
right: self.right.as_ref().map(|right| right.to_computed_value(context)),
|
||||||
bottom: self.bottom.as_ref().map(|bottom| bottom.to_computed_value(context)),
|
bottom: self.bottom.as_ref().map(|bottom| bottom.to_computed_value(context)),
|
||||||
left: self.left.to_computed_value(context),
|
left: self.left.as_ref().map(|left| left.to_computed_value(context)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_computed_value(computed: &super::computed::ClipRect) -> Self {
|
fn from_computed_value(computed: &super::computed::ClipRect) -> Self {
|
||||||
ClipRect {
|
ClipRect {
|
||||||
top: ToComputedValue::from_computed_value(&computed.top),
|
top: computed.top.map(|top| ToComputedValue::from_computed_value(&top)),
|
||||||
right: computed.right.map(|right| ToComputedValue::from_computed_value(&right)),
|
right: computed.right.map(|right| ToComputedValue::from_computed_value(&right)),
|
||||||
bottom: computed.bottom.map(|bottom| ToComputedValue::from_computed_value(&bottom)),
|
bottom: computed.bottom.map(|bottom| ToComputedValue::from_computed_value(&bottom)),
|
||||||
left: ToComputedValue::from_computed_value(&computed.left),
|
left: computed.left.map(|left| ToComputedValue::from_computed_value(&left)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -939,7 +947,6 @@ impl Parse for ClipRect {
|
||||||
return Err(())
|
return Err(())
|
||||||
}
|
}
|
||||||
|
|
||||||
// NB: `top` and `left` are 0 if `auto` per CSS 2.1 11.1.2.
|
|
||||||
input.parse_nested_block(|input| {
|
input.parse_nested_block(|input| {
|
||||||
let top = try!(parse_argument(context, input));
|
let top = try!(parse_argument(context, input));
|
||||||
let right;
|
let right;
|
||||||
|
@ -958,10 +965,10 @@ impl Parse for ClipRect {
|
||||||
left = try!(parse_argument(context, input));
|
left = try!(parse_argument(context, input));
|
||||||
}
|
}
|
||||||
Ok(ClipRect {
|
Ok(ClipRect {
|
||||||
top: top.unwrap_or(Length::zero()),
|
top: top,
|
||||||
right: right,
|
right: right,
|
||||||
bottom: bottom,
|
bottom: bottom,
|
||||||
left: left.unwrap_or(Length::zero()),
|
left: left,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
35
tests/unit/style/parsing/effects.rs
Normal file
35
tests/unit/style/parsing/effects.rs
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
use cssparser::Parser;
|
||||||
|
use media_queries::CSSErrorReporterTest;
|
||||||
|
use servo_url::ServoUrl;
|
||||||
|
use style::parser::ParserContext;
|
||||||
|
use style::stylesheets::Origin;
|
||||||
|
use style_traits::ToCss;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_clip() {
|
||||||
|
use style::properties::longhands::clip;
|
||||||
|
|
||||||
|
assert_roundtrip_with_context!(clip::parse, "auto");
|
||||||
|
assert_roundtrip_with_context!(clip::parse, "rect(1px, 2px, 3px, 4px)");
|
||||||
|
assert_roundtrip_with_context!(clip::parse, "rect(1px, auto, auto, 4px)");
|
||||||
|
assert_roundtrip_with_context!(clip::parse, "rect(auto, auto, auto, auto)");
|
||||||
|
|
||||||
|
// Non-standard syntax
|
||||||
|
assert_roundtrip_with_context!(clip::parse,
|
||||||
|
"rect(1px 2px 3px 4px)",
|
||||||
|
"rect(1px, 2px, 3px, 4px)");
|
||||||
|
assert_roundtrip_with_context!(clip::parse,
|
||||||
|
"rect(auto 2px 3px auto)",
|
||||||
|
"rect(auto, 2px, 3px, auto)");
|
||||||
|
assert_roundtrip_with_context!(clip::parse,
|
||||||
|
"rect(1px auto auto 4px)",
|
||||||
|
"rect(1px, auto, auto, 4px)");
|
||||||
|
assert_roundtrip_with_context!(clip::parse,
|
||||||
|
"rect(auto auto auto auto)",
|
||||||
|
"rect(auto, auto, auto, auto)");
|
||||||
|
}
|
||||||
|
|
|
@ -82,6 +82,7 @@ mod background;
|
||||||
mod basic_shape;
|
mod basic_shape;
|
||||||
mod border;
|
mod border;
|
||||||
mod column;
|
mod column;
|
||||||
|
mod effects;
|
||||||
mod font;
|
mod font;
|
||||||
mod image;
|
mod image;
|
||||||
mod inherited_box;
|
mod inherited_box;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue