diff --git a/src/algo.rs b/src/algo.rs
index e22c21244..343e147c6 100644
--- a/src/algo.rs
+++ b/src/algo.rs
@@ -63,7 +63,7 @@ impl Forest {
|| style.max_size.height.is_defined();
let result = if has_root_min_max {
- let first_pass = self.compute_internal(root, style.size.resolve(size), size, false);
+ let first_pass = self.compute_internal(root, style.size.resolve(size), size, false, true);
self.compute_internal(
root,
@@ -83,9 +83,11 @@ impl Forest {
},
size,
true,
+ true,
)
} else {
- self.compute_internal(root, style.size.resolve(size), size, true)
+ self.compute_internal(root, style.size.resolve(size), size, true, true)
+
};
self.nodes[root].layout = result::Layout { order: 0, size: result.size, location: Point::zero() };
@@ -113,6 +115,14 @@ impl Forest {
}
}
+ fn cache(&mut self, node: NodeId, main_size: bool) -> &mut Option<result::Cache> {
+ if main_size {
+ &mut self.nodes[node].main_size_layout_cache
+ } else {
+ &mut self.nodes[node].other_layout_cache
+ }
+ }
+
#[allow(clippy::cognitive_complexity)]
fn compute_internal(
&mut self,
@@ -120,11 +130,12 @@ impl Forest {
node_size: Size<Number>,
parent_size: Size<Number>,
perform_layout: bool,
+ main_size: bool,
) -> ComputeResult {
self.nodes[node].is_dirty = false;
// First we check if we have a result for the given input
- if let Some(ref cache) = self.nodes[node].layout_cache {
+ if let Some(ref cache) = self.cache(node, main_size) {
if cache.perform_layout || !perform_layout {
let width_compatible = if let Number::Defined(width) = node_size.width {
sys::abs(width - cache.result.size.width) < f32::EPSILON
@@ -187,7 +198,7 @@ impl Forest {
#[cfg(any(feature = "std", feature = "alloc"))]
MeasureFunc::Boxed(measure) => ComputeResult { size: measure(node_size) },
};
- self.nodes[node].layout_cache =
+ *self.cache(node, main_size) =
Some(result::Cache { node_size, parent_size, perform_layout, result: result.clone() });
return result;
}
@@ -331,6 +342,7 @@ impl Forest {
},
available_space,
false,
+ true,
)
.size
.main(dir)
@@ -349,7 +361,7 @@ impl Forest {
// webkit handled various scenarios. Can probably be solved better by passing in
// min-content max-content constraints from the top
let min_main = self
- .compute_internal(child.node, Size::undefined(), available_space, false)
+ .compute_internal(child.node, Size::undefined(), available_space, false, false)
.size
.main(dir)
.maybe_max(child.min_size.main(dir))
@@ -455,6 +467,7 @@ impl Forest {
},
available_space,
false,
+ false,
)
.size
.main(dir)
@@ -594,7 +607,7 @@ impl Forest {
// min-content max-content constraints from the top. Need to figure out correct thing to do here as
// just piling on more conditionals.
let min_main = if is_row && self.nodes[child.node].measure.is_none() {
- self.compute_internal(child.node, Size::undefined(), available_space, false)
+ self.compute_internal(child.node, Size::undefined(), available_space, false, false)
.size
.width
.maybe_min(child.size.width)
@@ -676,6 +689,7 @@ impl Forest {
height: if is_row { available_space.height } else { container_size.main(dir).into() },
},
false,
+ false,
)
.size
.cross(dir)
@@ -723,6 +737,7 @@ impl Forest {
height: if is_row { node_size.height } else { container_size.height.into() },
},
true,
+ false
);
child.baseline = calc_baseline(
@@ -1048,7 +1063,7 @@ impl Forest {
// layout we are done now.
if !perform_layout {
let result = ComputeResult { size: container_size };
- self.nodes[node].layout_cache =
+ *self.cache(node, main_size) =
Some(result::Cache { node_size, parent_size, perform_layout, result: result.clone() });
return result;
}
@@ -1121,6 +1136,7 @@ impl Forest {
child.target_size.map(|s| s.into()),
container_size.map(|s| s.into()),
true,
+ false,
);
let offset_main = total_offset_main
@@ -1218,7 +1234,8 @@ impl Forest {
child,
Size { width, height },
Size { width: container_width, height: container_height },
- true,
+ true,
+ false,
);
let free_main_space = container_size.main(dir)
@@ -1308,7 +1325,7 @@ impl Forest {
}
let result = ComputeResult { size: container_size };
- self.nodes[node].layout_cache =
+ *self.cache(node, main_size) =
Some(result::Cache { node_size, parent_size, perform_layout, result: result.clone() });
result
diff --git a/src/forest.rs b/src/forest.rs
index cdd26ec1b..d29dfbf9b 100644
--- a/src/forest.rs
+++ b/src/forest.rs
@@ -13,17 +13,18 @@ pub(crate) struct NodeData {
pub(crate) style: Style,
pub(crate) measure: Option<MeasureFunc>,
pub(crate) layout: Layout,
- pub(crate) layout_cache: Option<Cache>,
+ pub(crate) main_size_layout_cache: Option<Cache>,
+ pub(crate) other_layout_cache: Option<Cache>,
pub(crate) is_dirty: bool,
}
impl NodeData {
fn new_leaf(style: Style, measure: MeasureFunc) -> Self {
- Self { style, measure: Some(measure), layout_cache: None, layout: Layout::new(), is_dirty: true }
+ Self { style, measure: Some(measure), main_size_layout_cache: None, other_layout_cache: None, layout: Layout::new(), is_dirty: true }
}
fn new(style: Style) -> Self {
- Self { style, measure: None, layout_cache: None, layout: Layout::new(), is_dirty: true }
+ Self { style, measure: None, main_size_layout_cache: None, other_layout_cache: None, layout: Layout::new(), is_dirty: true }
}
}
@@ -157,7 +158,8 @@ impl Forest {
pub fn mark_dirty(&mut self, node: NodeId) {
fn mark_dirty_impl(nodes: &mut sys::Vec<NodeData>, parents: &[sys::ParentsVec<NodeId>], node_id: NodeId) {
let node = &mut nodes[node_id];
- node.layout_cache = None;
+ node.main_size_layout_cache = None;
+ node.other_layout_cache = None;
node.is_dirty = true;
for parent in &parents[node_id] {