diff options
author | Martin Robinson <mrobinson@igalia.com> | 2017-03-20 10:45:59 +0100 |
---|---|---|
committer | Martin Robinson <mrobinson@igalia.com> | 2017-04-17 17:06:43 +0200 |
commit | 4451b8a771e5f5120fdfe619027d088d1ad1efd1 (patch) | |
tree | 3fdf1ac8a19f8ab66bd9cee2adfb3a031e72520d /components/layout/flow.rs | |
parent | b9274b7527b9171dae34f87a039ea98ef2e5fbe8 (diff) | |
download | servo-4451b8a771e5f5120fdfe619027d088d1ad1efd1.tar.gz servo-4451b8a771e5f5120fdfe619027d088d1ad1efd1.zip |
Used shared clips for overflow:hidden and CSS clip
Instead of passing down a complex clipping region to each item, used
shared clipping to handle overflow:hidden and CSS clips. In addition to
being more efficient, this should also fix quite a few issues related
to absolutely positioned elements.
One existing reftest is slightly modified to avoid tickling a quirk
with the way that WebRender rasterizes masks. We are working out how to
best express these combined masks with the API or need to. The change
does not affect the original subject of the reftest.
Fixes #13109.
Fixes #10151.
Fixes #7575.
Fixes #8074.
Fixes #8780.
Diffstat (limited to 'components/layout/flow.rs')
-rw-r--r-- | components/layout/flow.rs | 65 |
1 files changed, 25 insertions, 40 deletions
diff --git a/components/layout/flow.rs b/components/layout/flow.rs index 945943a27c5..372d76a404c 100644 --- a/components/layout/flow.rs +++ b/components/layout/flow.rs @@ -29,13 +29,12 @@ use app_units::Au; use block::{BlockFlow, FormattingContextType}; use context::LayoutContext; use display_list_builder::DisplayListBuildState; -use euclid::{Matrix4D, Point2D, Size2D}; +use euclid::{Matrix4D, Point2D, Rect, Size2D}; use flex::FlexFlow; use floats::{Floats, SpeculatedFloatPlacement}; use flow_list::{FlowList, MutFlowListIterator}; use flow_ref::{FlowRef, WeakFlowRef}; -use fragment::{Fragment, FragmentBorderBoxIterator, Overflow}; -use gfx::display_list::ClippingRegion; +use fragment::{CoordinateSystem, Fragment, FragmentBorderBoxIterator, Overflow}; use gfx_traits::{ScrollRootId, StackingContextId}; use gfx_traits::print_tree::PrintTree; use inline::InlineFlow; @@ -43,7 +42,7 @@ use model::{CollapsibleMargins, IntrinsicISizes, MarginCollapseInfo}; use multicol::MulticolFlow; use parallel::FlowParallelInfo; use serde::ser::{Serialize, SerializeStruct, Serializer}; -use servo_geometry::{au_rect_to_f32_rect, f32_rect_to_au_rect}; +use servo_geometry::{au_rect_to_f32_rect, f32_rect_to_au_rect, max_rect}; use std::{fmt, mem, raw}; use std::iter::Zip; use std::slice::IterMut; @@ -264,6 +263,24 @@ pub trait Flow: fmt::Debug + Sync + Send + 'static { } } + let border_box = self.as_block().fragment.stacking_relative_border_box( + &base(self).stacking_relative_position, + &base(self).early_absolute_position_info.relative_containing_block_size, + base(self).early_absolute_position_info.relative_containing_block_mode, + CoordinateSystem::Own); + if overflow_x::T::visible != self.as_block().fragment.style.get_box().overflow_x { + overflow.paint.origin.x = Au(0); + overflow.paint.size.width = border_box.size.width; + overflow.scroll.origin.x = Au(0); + overflow.scroll.size.width = border_box.size.width; + } + if overflow_x::T::visible != self.as_block().fragment.style.get_box().overflow_y.0 { + overflow.paint.origin.y = Au(0); + overflow.paint.size.height = border_box.size.height; + overflow.scroll.origin.y = Au(0); + overflow.scroll.size.height = border_box.size.height; + } + if !self.as_block().fragment.establishes_stacking_context() || self.as_block().fragment.style.get_box().transform.0.is_none() { overflow.translate(&position.origin); @@ -311,40 +328,8 @@ pub trait Flow: fmt::Debug + Sync + Send + 'static { FlowClass::Block | FlowClass::TableCaption | FlowClass::TableCell => { - let overflow_x = self.as_block().fragment.style.get_box().overflow_x; - let overflow_y = self.as_block().fragment.style.get_box().overflow_y; - for kid in mut_base(self).children.iter_mut() { - let mut kid_overflow = kid.get_overflow_in_parent_coordinates(); - - // If the overflow for this flow is hidden on a given axis, just - // put the existing overflow in the kid rect, so that the union - // has no effect on this axis. - match overflow_x { - overflow_x::T::hidden => { - kid_overflow.paint.origin.x = overflow.paint.origin.x; - kid_overflow.paint.size.width = overflow.paint.size.width; - kid_overflow.scroll.origin.x = overflow.scroll.origin.x; - kid_overflow.scroll.size.width = overflow.scroll.size.width; - } - overflow_x::T::scroll | - overflow_x::T::auto | - overflow_x::T::visible => {} - } - - match overflow_y.0 { - overflow_x::T::hidden => { - kid_overflow.paint.origin.y = overflow.paint.origin.y; - kid_overflow.paint.size.height = overflow.paint.size.height; - kid_overflow.scroll.origin.y = overflow.scroll.origin.y; - kid_overflow.scroll.size.height = overflow.scroll.size.height; - } - overflow_x::T::scroll | - overflow_x::T::auto | - overflow_x::T::visible => {} - } - - overflow.union(&kid_overflow) + overflow.union(&kid.get_overflow_in_parent_coordinates()); } } _ => {} @@ -957,10 +942,10 @@ pub struct BaseFlow { /// assignment. pub late_absolute_position_info: LateAbsolutePositionInfo, - /// The clipping region for this flow and its descendants, in the coordinate system of the + /// The clipping rectangle for this flow and its descendants, in the coordinate system of the /// nearest ancestor stacking context. If this flow itself represents a stacking context, then /// this is in the flow's own coordinate system. - pub clip: ClippingRegion, + pub clip: Rect<Au>, /// The writing mode for this flow. pub writing_mode: WritingMode, @@ -1115,7 +1100,7 @@ impl BaseFlow { absolute_cb: ContainingBlockLink::new(), early_absolute_position_info: EarlyAbsolutePositionInfo::new(writing_mode), late_absolute_position_info: LateAbsolutePositionInfo::new(), - clip: ClippingRegion::max(), + clip: max_rect(), flags: flags, writing_mode: writing_mode, thread_id: 0, |