mirror of
https://github.com/servo/servo.git
synced 2025-08-06 06:00:15 +01:00
layout: Split overflow calculation after fragment tree construction (#37203)
Instead of computing scrollable overflow while constructing the fragment tree, we will now do it later. In the future this will also allow to only recalculate the overflow without rebuilding the tree when transform properties change, but that's left for a follow-up. Stylo PR: https://github.com/servo/stylo/pull/194 Testing: One test is now passing (more investigation is needed), but otherwise this isn't expected to have any effect. Signed-off-by: Oriol Brufau <obrufau@igalia.com> Co-authored-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
parent
079198c898
commit
de2da3b1e1
11 changed files with 148 additions and 96 deletions
|
@ -2,14 +2,14 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use std::cell::Cell;
|
||||
|
||||
use app_units::Au;
|
||||
use base::print_tree::PrintTree;
|
||||
use compositing_traits::display_list::AxesScrollSensitivity;
|
||||
use euclid::default::Size2D;
|
||||
use fxhash::FxHashSet;
|
||||
use malloc_size_of_derive::MallocSizeOf;
|
||||
use style::animation::AnimationSetKey;
|
||||
use webrender_api::units;
|
||||
|
||||
use super::{BoxFragment, ContainingBlockManager, Fragment};
|
||||
use crate::ArcRefCell;
|
||||
|
@ -30,7 +30,7 @@ pub struct FragmentTree {
|
|||
|
||||
/// The scrollable overflow rectangle for the entire tree
|
||||
/// <https://drafts.csswg.org/css-overflow/#scrollable>
|
||||
pub(crate) scrollable_overflow: PhysicalRect<Au>,
|
||||
scrollable_overflow: Cell<Option<PhysicalRect<Au>>>,
|
||||
|
||||
/// The containing block used in the layout of this fragment tree.
|
||||
pub(crate) initial_containing_block: PhysicalRect<Au>,
|
||||
|
@ -43,13 +43,12 @@ impl FragmentTree {
|
|||
pub(crate) fn new(
|
||||
layout_context: &LayoutContext,
|
||||
root_fragments: Vec<Fragment>,
|
||||
scrollable_overflow: PhysicalRect<Au>,
|
||||
initial_containing_block: PhysicalRect<Au>,
|
||||
viewport_scroll_sensitivity: AxesScrollSensitivity,
|
||||
) -> Self {
|
||||
let fragment_tree = Self {
|
||||
root_fragments,
|
||||
scrollable_overflow,
|
||||
scrollable_overflow: Cell::default(),
|
||||
initial_containing_block,
|
||||
viewport_scroll_sensitivity,
|
||||
};
|
||||
|
@ -97,11 +96,35 @@ impl FragmentTree {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn scrollable_overflow(&self) -> units::LayoutSize {
|
||||
units::LayoutSize::from_untyped(Size2D::new(
|
||||
self.scrollable_overflow.size.width.to_f32_px(),
|
||||
self.scrollable_overflow.size.height.to_f32_px(),
|
||||
))
|
||||
pub(crate) fn scrollable_overflow(&self) -> PhysicalRect<Au> {
|
||||
self.scrollable_overflow
|
||||
.get()
|
||||
.expect("Should only call `scrollable_overflow()` after calculating overflow")
|
||||
}
|
||||
|
||||
pub(crate) fn calculate_scrollable_overflow(&self) {
|
||||
self.scrollable_overflow
|
||||
.set(Some(self.root_fragments.iter().fold(
|
||||
PhysicalRect::zero(),
|
||||
|acc, child| {
|
||||
let child_overflow = child.calculate_scrollable_overflow_for_parent();
|
||||
|
||||
// https://drafts.csswg.org/css-overflow/#scrolling-direction
|
||||
// We want to clip scrollable overflow on box-start and inline-start
|
||||
// sides of the scroll container.
|
||||
//
|
||||
// FIXME(mrobinson, bug 25564): This should take into account writing
|
||||
// mode.
|
||||
let child_overflow = PhysicalRect::new(
|
||||
euclid::Point2D::zero(),
|
||||
euclid::Size2D::new(
|
||||
child_overflow.size.width + child_overflow.origin.x,
|
||||
child_overflow.size.height + child_overflow.origin.y,
|
||||
),
|
||||
);
|
||||
acc.union(&child_overflow)
|
||||
},
|
||||
)));
|
||||
}
|
||||
|
||||
pub(crate) fn find<T>(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue