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 rect: PhysicalRect<Au>,
22 pub children: Vec<Fragment>,
23
24 scrollable_overflow: Option<PhysicalRect<Au>>,
26
27 pub style: ServoArc<ComputedValues>,
29
30 pub cumulative_containing_block_rect: PhysicalRect<Au>,
33}
34
35impl PositioningFragment {
36 pub fn new_anonymous(
37 style: ServoArc<ComputedValues>,
38 rect: PhysicalRect<Au>,
39 children: Vec<Fragment>,
40 ) -> ArcRefCell<Self> {
41 Self::new_with_base_fragment(BaseFragment::anonymous(), style, rect, children)
42 }
43
44 pub fn new_empty(
45 base_fragment_info: BaseFragmentInfo,
46 rect: PhysicalRect<Au>,
47 style: ServoArc<ComputedValues>,
48 ) -> ArcRefCell<Self> {
49 Self::new_with_base_fragment(base_fragment_info.into(), style, rect, Vec::new())
50 }
51
52 fn new_with_base_fragment(
53 base: BaseFragment,
54 style: ServoArc<ComputedValues>,
55 rect: PhysicalRect<Au>,
56 children: Vec<Fragment>,
57 ) -> ArcRefCell<Self> {
58 ArcRefCell::new(PositioningFragment {
59 base,
60 style,
61 rect,
62 children,
63 scrollable_overflow: None,
64 cumulative_containing_block_rect: PhysicalRect::zero(),
65 })
66 }
67
68 pub(crate) fn set_containing_block(&mut self, containing_block: &PhysicalRect<Au>) {
69 self.cumulative_containing_block_rect = *containing_block;
70 }
71
72 pub fn offset_by_containing_block(&self, rect: &PhysicalRect<Au>) -> PhysicalRect<Au> {
73 rect.translate(self.cumulative_containing_block_rect.origin.to_vector())
74 }
75
76 pub(crate) fn calculate_scrollable_overflow(&mut self) {
77 self.scrollable_overflow = Some(self.children.iter().fold(
78 PhysicalRect::zero(),
79 |acc, child| {
80 acc.union(
81 &child
82 .calculate_scrollable_overflow_for_parent()
83 .translate(self.rect.origin.to_vector()),
84 )
85 },
86 ));
87 }
88
89 pub(crate) fn scrollable_overflow_for_parent(&self) -> PhysicalRect<Au> {
90 self.scrollable_overflow.expect(
91 "Should only call `scrollable_overflow_for_parent()` after calculating overflow",
92 )
93 }
94
95 pub fn print(&self, tree: &mut PrintTree) {
96 tree.new_level(format!(
97 "PositioningFragment\
98 \nbase={:?}\
99 \nrect={:?}\
100 \nscrollable_overflow={:?}",
101 self.base, self.rect, self.scrollable_overflow
102 ));
103
104 for child in &self.children {
105 child.print(tree);
106 }
107 tree.end_level();
108 }
109}