layout/
layout_box_base.rs1use std::fmt::{Debug, Formatter};
6
7use app_units::Au;
8use atomic_refcell::AtomicRefCell;
9use malloc_size_of_derive::MallocSizeOf;
10use servo_arc::Arc;
11use style::properties::ComputedValues;
12
13use crate::context::LayoutContext;
14use crate::formatting_contexts::Baselines;
15use crate::fragment_tree::{BaseFragmentInfo, CollapsedBlockMargins, Fragment, SpecificLayoutInfo};
16use crate::positioned::PositioningContext;
17use crate::sizing::{ComputeInlineContentSizes, InlineContentSizesResult, SizeConstraint};
18use crate::{ConstraintSpace, ContainingBlockSize};
19
20#[derive(MallocSizeOf)]
27pub(crate) struct LayoutBoxBase {
28 pub base_fragment_info: BaseFragmentInfo,
29 pub style: Arc<ComputedValues>,
30 pub cached_inline_content_size:
31 AtomicRefCell<Option<Box<(SizeConstraint, InlineContentSizesResult)>>>,
32 pub cached_layout_result: AtomicRefCell<Option<Box<CacheableLayoutResultAndInputs>>>,
33 pub fragments: AtomicRefCell<Vec<Fragment>>,
34}
35
36impl LayoutBoxBase {
37 pub(crate) fn new(base_fragment_info: BaseFragmentInfo, style: Arc<ComputedValues>) -> Self {
38 Self {
39 base_fragment_info,
40 style,
41 cached_inline_content_size: AtomicRefCell::default(),
42 cached_layout_result: AtomicRefCell::default(),
43 fragments: AtomicRefCell::default(),
44 }
45 }
46
47 pub(crate) fn inline_content_sizes(
50 &self,
51 layout_context: &LayoutContext,
52 constraint_space: &ConstraintSpace,
53 layout_box: &impl ComputeInlineContentSizes,
54 ) -> InlineContentSizesResult {
55 let mut cache = self.cached_inline_content_size.borrow_mut();
56 if let Some(cached_inline_content_size) = cache.as_ref() {
57 let (previous_cb_block_size, result) = **cached_inline_content_size;
58 if !result.depends_on_block_constraints ||
59 previous_cb_block_size == constraint_space.block_size
60 {
61 return result;
62 }
63 }
65
66 let result =
67 layout_box.compute_inline_content_sizes_with_fixup(layout_context, constraint_space);
68 *cache = Some(Box::new((constraint_space.block_size, result)));
69 result
70 }
71
72 pub(crate) fn clear_fragment_layout_cache(&self) {
75 self.fragments.borrow_mut().clear();
76 *self.cached_layout_result.borrow_mut() = None;
77 *self.cached_inline_content_size.borrow_mut() = None;
78 }
79
80 pub(crate) fn fragments(&self) -> Vec<Fragment> {
81 self.fragments.borrow().clone()
82 }
83
84 pub(crate) fn add_fragment(&self, fragment: Fragment) {
85 self.fragments.borrow_mut().push(fragment);
86 }
87
88 pub(crate) fn set_fragment(&self, fragment: Fragment) {
89 *self.fragments.borrow_mut() = vec![fragment];
90 }
91
92 pub(crate) fn clear_fragments(&self) {
93 self.fragments.borrow_mut().clear();
94 }
95
96 pub(crate) fn repair_style(&mut self, new_style: &Arc<ComputedValues>) {
97 self.style = new_style.clone();
98 for fragment in self.fragments.borrow_mut().iter_mut() {
99 fragment.repair_style(new_style);
100 }
101 }
102}
103
104impl Debug for LayoutBoxBase {
105 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
106 f.debug_struct("LayoutBoxBase").finish()
107 }
108}
109
110#[derive(Clone, MallocSizeOf)]
111pub(crate) struct CacheableLayoutResult {
112 pub fragments: Vec<Fragment>,
113
114 pub content_block_size: Au,
116
117 pub collapsible_margins_in_children: CollapsedBlockMargins,
120
121 pub content_inline_size_for_table: Option<Au>,
125
126 pub baselines: Baselines,
130
131 pub depends_on_block_constraints: bool,
133
134 pub specific_layout_info: Option<SpecificLayoutInfo>,
136}
137
138#[derive(MallocSizeOf)]
140pub(crate) struct CacheableLayoutResultAndInputs {
141 pub result: CacheableLayoutResult,
143
144 pub containing_block_for_children_size: ContainingBlockSize,
147
148 pub positioning_context: PositioningContext,
151}