diff options
author | Martin Robinson <mrobinson@igalia.com> | 2025-04-19 12:17:03 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-04-19 10:17:03 +0000 |
commit | 7787cab521ccc6b4d8533ebe9b45563046e0463d (patch) | |
tree | d1277fa3846f24cc99859310da3d7f099c73bfc5 /components/layout_2020/fragment_tree/fragment_tree.rs | |
parent | 3ab5b8c4472129798b63cfb40b63ae672763b653 (diff) | |
download | servo-7787cab521ccc6b4d8533ebe9b45563046e0463d.tar.gz servo-7787cab521ccc6b4d8533ebe9b45563046e0463d.zip |
layout: Combine `layout_2020` and `layout_thread_2020` into a crate called `layout` (#36613)
Now that legacy layout has been removed, the name `layout_2020` doesn't
make much sense any longer, also it's 2025 now for better or worse. The
split between the "layout thread" and "layout" also doesn't make as much
sense since layout doesn't run on it's own thread. There's a possibility
that it will in the future, but that should be something that the user
of the crate controls rather than layout iself.
This is part of the larger layout interface cleanup and optimization
that
@Looriool and I are doing.
Testing: Covered by existing tests as this is just code movement.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Diffstat (limited to 'components/layout_2020/fragment_tree/fragment_tree.rs')
-rw-r--r-- | components/layout_2020/fragment_tree/fragment_tree.rs | 194 |
1 files changed, 0 insertions, 194 deletions
diff --git a/components/layout_2020/fragment_tree/fragment_tree.rs b/components/layout_2020/fragment_tree/fragment_tree.rs deleted file mode 100644 index bb3c659466c..00000000000 --- a/components/layout_2020/fragment_tree/fragment_tree.rs +++ /dev/null @@ -1,194 +0,0 @@ -/* 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 https://mozilla.org/MPL/2.0/. */ - -use app_units::Au; -use base::print_tree::PrintTree; -use compositing_traits::display_list::AxesScrollSensitivity; -use euclid::default::{Point2D, Rect, Size2D}; -use fxhash::FxHashSet; -use malloc_size_of_derive::MallocSizeOf; -use style::animation::AnimationSetKey; -use style::dom::OpaqueNode; -use webrender_api::units; - -use super::{ContainingBlockManager, Fragment, Tag}; -use crate::display_list::StackingContext; -use crate::flow::CanvasBackground; -use crate::geom::{PhysicalPoint, PhysicalRect}; - -#[derive(MallocSizeOf)] -pub struct FragmentTree { - /// Fragments at the top-level of the tree. - /// - /// If the root element has `display: none`, there are zero fragments. - /// Otherwise, there is at least one: - /// - /// * The first fragment is generated by the root element. - /// * There may be additional fragments generated by positioned boxes - /// that have the initial containing block. - pub(crate) root_fragments: Vec<Fragment>, - - /// The scrollable overflow rectangle for the entire tree - /// <https://drafts.csswg.org/css-overflow/#scrollable> - pub(crate) scrollable_overflow: PhysicalRect<Au>, - - /// The containing block used in the layout of this fragment tree. - pub(crate) initial_containing_block: PhysicalRect<Au>, - - /// <https://drafts.csswg.org/css-backgrounds/#special-backgrounds> - pub(crate) canvas_background: CanvasBackground, - - /// Whether or not the viewport is sensitive to scroll input events. - pub viewport_scroll_sensitivity: AxesScrollSensitivity, -} - -impl FragmentTree { - pub(crate) fn build_display_list( - &self, - builder: &mut crate::display_list::DisplayListBuilder, - root_stacking_context: &StackingContext, - ) { - // Paint the canvas’ background (if any) before/under everything else - root_stacking_context.build_canvas_background_display_list( - builder, - self, - &self.initial_containing_block, - ); - root_stacking_context.build_display_list(builder); - } - - pub fn print(&self) { - let mut print_tree = PrintTree::new("Fragment Tree".to_string()); - for fragment in &self.root_fragments { - fragment.print(&mut print_tree); - } - } - - 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 find<T>( - &self, - mut process_func: impl FnMut(&Fragment, usize, &PhysicalRect<Au>) -> Option<T>, - ) -> Option<T> { - let info = ContainingBlockManager { - for_non_absolute_descendants: &self.initial_containing_block, - for_absolute_descendants: None, - for_absolute_and_fixed_descendants: &self.initial_containing_block, - }; - self.root_fragments - .iter() - .find_map(|child| child.find(&info, 0, &mut process_func)) - } - - pub fn remove_nodes_in_fragment_tree_from_set(&self, set: &mut FxHashSet<AnimationSetKey>) { - self.find(|fragment, _, _| { - let tag = fragment.tag()?; - set.remove(&AnimationSetKey::new(tag.node, tag.pseudo)); - None::<()> - }); - } - - /// Get the vector of rectangles that surrounds the fragments of the node with the given address. - /// This function answers the `getClientRects()` query and the union of the rectangles answers - /// the `getBoundingClientRect()` query. - /// - /// TODO: This function is supposed to handle scroll offsets, but that isn't happening at all. - pub fn get_content_boxes_for_node(&self, requested_node: OpaqueNode) -> Vec<Rect<Au>> { - let mut content_boxes = Vec::new(); - let tag_to_find = Tag::new(requested_node); - self.find(|fragment, _, containing_block| { - if fragment.tag() != Some(tag_to_find) { - return None::<()>; - } - - let fragment_relative_rect = match fragment { - Fragment::Box(fragment) | Fragment::Float(fragment) => { - fragment.borrow().border_rect() - }, - Fragment::Positioning(fragment) => fragment.borrow().rect, - Fragment::Text(fragment) => fragment.borrow().rect, - Fragment::AbsoluteOrFixedPositioned(_) | - Fragment::Image(_) | - Fragment::IFrame(_) => return None, - }; - - let rect = fragment_relative_rect.translate(containing_block.origin.to_vector()); - - content_boxes.push(rect.to_untyped()); - None::<()> - }); - content_boxes - } - - pub fn get_border_dimensions_for_node(&self, requested_node: OpaqueNode) -> Rect<i32> { - let tag_to_find = Tag::new(requested_node); - self.find(|fragment, _, _containing_block| { - if fragment.tag() != Some(tag_to_find) { - return None; - } - - let rect = match fragment { - Fragment::Box(fragment) | Fragment::Float(fragment) => { - // https://drafts.csswg.org/cssom-view/#dom-element-clienttop - // " If the element has no associated CSS layout box or if the - // CSS layout box is inline, return zero." For this check we - // also explicitly ignore the list item portion of the display - // style. - let fragment = fragment.borrow(); - if fragment.is_inline_box() { - return Some(Rect::zero()); - } - if fragment.is_table_wrapper() { - // For tables the border actually belongs to the table grid box, - // so we need to include it in the dimension of the table wrapper box. - let mut rect = fragment.border_rect(); - rect.origin = PhysicalPoint::zero(); - rect - } else { - let mut rect = fragment.padding_rect(); - rect.origin = PhysicalPoint::new(fragment.border.left, fragment.border.top); - rect - } - }, - Fragment::Positioning(fragment) => fragment.borrow().rect.cast_unit(), - Fragment::Text(text_fragment) => text_fragment.borrow().rect, - _ => return None, - }; - - let rect = Rect::new( - Point2D::new(rect.origin.x.to_f32_px(), rect.origin.y.to_f32_px()), - Size2D::new(rect.size.width.to_f32_px(), rect.size.height.to_f32_px()), - ); - Some(rect.round().to_i32().to_untyped()) - }) - .unwrap_or_else(Rect::zero) - } - - pub fn get_scrolling_area_for_viewport(&self) -> PhysicalRect<Au> { - let mut scroll_area = self.initial_containing_block; - for fragment in self.root_fragments.iter() { - scroll_area = fragment - .scrolling_area(&self.initial_containing_block) - .union(&scroll_area); - } - scroll_area - } - - pub fn get_scrolling_area_for_node(&self, requested_node: OpaqueNode) -> PhysicalRect<Au> { - let tag_to_find = Tag::new(requested_node); - let scroll_area = self.find(|fragment, _, containing_block| { - if fragment.tag() == Some(tag_to_find) { - Some(fragment.scrolling_area(containing_block)) - } else { - None - } - }); - scroll_area.unwrap_or_else(PhysicalRect::<Au>::zero) - } -} |