layout/fragment_tree/
positioning_fragment.rs1use app_units::Au;
6use base::print_tree::PrintTree;
7use malloc_size_of_derive::MallocSizeOf;
8use servo_arc::Arc as ServoArc;
9use style::properties::ComputedValues;
10
11use super::{BaseFragment, BaseFragmentInfo, Fragment};
12use crate::cell::ArcRefCell;
13use crate::geom::PhysicalRect;
14
15#[derive(MallocSizeOf)]
19pub(crate) struct PositioningFragment {
20 pub base: BaseFragment,
21 pub children: Vec<Fragment>,
22
23 scrollable_overflow: Option<PhysicalRect<Au>>,
25
26 pub cumulative_containing_block_rect: PhysicalRect<Au>,
29}
30
31impl PositioningFragment {
32 pub fn new_anonymous(
33 style: ServoArc<ComputedValues>,
34 rect: PhysicalRect<Au>,
35 children: Vec<Fragment>,
36 ) -> ArcRefCell<Self> {
37 Self::new_with_base_fragment_info(BaseFragmentInfo::anonymous(), style, rect, children)
38 }
39
40 pub fn new_empty(
41 base_fragment_info: BaseFragmentInfo,
42 rect: PhysicalRect<Au>,
43 style: ServoArc<ComputedValues>,
44 ) -> ArcRefCell<Self> {
45 Self::new_with_base_fragment_info(base_fragment_info, style, rect, Vec::new())
46 }
47
48 fn new_with_base_fragment_info(
49 base_fragment_info: BaseFragmentInfo,
50 style: ServoArc<ComputedValues>,
51 rect: PhysicalRect<Au>,
52 children: Vec<Fragment>,
53 ) -> ArcRefCell<Self> {
54 ArcRefCell::new(PositioningFragment {
55 base: BaseFragment::new(base_fragment_info, style.into(), rect),
56 children,
57 scrollable_overflow: None,
58 cumulative_containing_block_rect: PhysicalRect::zero(),
59 })
60 }
61
62 pub(crate) fn set_containing_block(&mut self, containing_block: &PhysicalRect<Au>) {
63 self.cumulative_containing_block_rect = *containing_block;
64 }
65
66 pub fn offset_by_containing_block(&self, rect: &PhysicalRect<Au>) -> PhysicalRect<Au> {
67 rect.translate(self.cumulative_containing_block_rect.origin.to_vector())
68 }
69
70 pub(crate) fn calculate_scrollable_overflow(&mut self) {
71 self.scrollable_overflow = Some(self.children.iter().fold(
72 PhysicalRect::zero(),
73 |acc, child| {
74 acc.union(
75 &child
76 .calculate_scrollable_overflow_for_parent()
77 .translate(self.base.rect.origin.to_vector()),
78 )
79 },
80 ));
81 }
82
83 pub(crate) fn scrollable_overflow_for_parent(&self) -> PhysicalRect<Au> {
84 self.scrollable_overflow.expect(
85 "Should only call `scrollable_overflow_for_parent()` after calculating overflow",
86 )
87 }
88
89 pub fn print(&self, tree: &mut PrintTree) {
90 tree.new_level(format!(
91 "PositioningFragment\
92 \nbase={:?}\
93 \nrect={:?}\
94 \nscrollable_overflow={:?}",
95 self.base, self.base.rect, self.scrollable_overflow
96 ));
97
98 for child in &self.children {
99 child.print(tree);
100 }
101 tree.end_level();
102 }
103}