diff --git a/components/layout/display_list/builder.rs b/components/layout/display_list/builder.rs index ac4cb73a148..d268f8428d3 100644 --- a/components/layout/display_list/builder.rs +++ b/components/layout/display_list/builder.rs @@ -63,7 +63,7 @@ use style::properties::{style_structs, ComputedValues}; use style::servo::restyle_damage::ServoRestyleDamage; use style::values::computed::effects::SimpleShadow; use style::values::computed::image::Image; -use style::values::computed::{ClipRectOrAuto, Gradient, LengthOrAuto}; +use style::values::computed::{ClipRectOrAuto, Gradient}; use style::values::generics::background::BackgroundSize; use style::values::generics::image::PaintWorklet; use style::values::specified::ui::CursorKind; @@ -2701,26 +2701,7 @@ impl BlockFlow { _ => return, } - fn extract_clip_component(p: &LengthOrAuto) -> Option { - match *p { - LengthOrAuto::Auto => None, - LengthOrAuto::LengthPercentage(ref length) => Some(Au::from(*length)), - } - } - - let clip_origin = Point2D::new( - stacking_relative_border_box.origin.x + - extract_clip_component(&style_clip_rect.left).unwrap_or_default(), - stacking_relative_border_box.origin.y + - extract_clip_component(&style_clip_rect.top).unwrap_or_default(), - ); - let right = extract_clip_component(&style_clip_rect.right) - .unwrap_or(stacking_relative_border_box.size.width); - let bottom = extract_clip_component(&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_rect = Rect::new(clip_origin, clip_size); + let clip_rect = style_clip_rect.for_border_rect(stacking_relative_border_box); preserved_state.push_clip(state, clip_rect, self.positioning()); let new_index = state.add_clip_scroll_node(ClipScrollNode { diff --git a/components/style/values/computed/mod.rs b/components/style/values/computed/mod.rs index 547c1618f70..c05fb1ef0fe 100644 --- a/components/style/values/computed/mod.rs +++ b/components/style/values/computed/mod.rs @@ -22,11 +22,12 @@ use crate::properties; use crate::properties::{ComputedValues, LonghandId, StyleBuilder}; use crate::rule_cache::RuleCacheConditions; use crate::{ArcSlice, Atom, One}; -use euclid::default::Size2D; +use euclid::{default, Point2D, Rect, Size2D}; use servo_arc::Arc; use std::cell::RefCell; use std::cmp; use std::f32; +use std::ops::{Add, Sub}; #[cfg(feature = "gecko")] pub use self::align::{ @@ -208,7 +209,7 @@ impl<'a> Context<'a> { } /// The current viewport size, used to resolve viewport units. - pub fn viewport_size_for_viewport_unit_resolution(&self) -> Size2D { + pub fn viewport_size_for_viewport_unit_resolution(&self) -> default::Size2D { self.builder .device .au_viewport_size_for_viewport_unit_resolution() @@ -353,11 +354,11 @@ where } } -impl ToComputedValue for Size2D +impl ToComputedValue for default::Size2D where T: ToComputedValue, { - type ComputedValue = Size2D<::ComputedValue>; + type ComputedValue = default::Size2D<::ComputedValue>; #[inline] fn to_computed_value(&self, context: &Context) -> Self::ComputedValue { @@ -814,3 +815,29 @@ pub type GridLine = GenericGridLine; /// ` | ` pub type GridTemplateComponent = GenericGridTemplateComponent; + +impl ClipRect { + /// Given a border box, resolves the clip rect against the border box + /// in the same space the border box is in + pub fn for_border_rect + Add + Sub, U>( + &self, + border_box: Rect, + ) -> Rect { + fn extract_clip_component>(p: &LengthOrAuto, or: T) -> T { + match *p { + LengthOrAuto::Auto => or, + LengthOrAuto::LengthPercentage(ref length) => T::from(*length), + } + } + + let clip_origin = Point2D::new( + From::from(self.left.auto_is(|| Length::new(0.))), + From::from(self.top.auto_is(|| Length::new(0.))), + ); + let right = extract_clip_component(&self.right, border_box.size.width); + let bottom = extract_clip_component(&self.bottom, border_box.size.height); + let clip_size = Size2D::new(right - clip_origin.x, bottom - clip_origin.y); + + Rect::new(clip_origin, clip_size).translate(border_box.origin.to_vector()) + } +}