Skip to content

Commit f990ee8

Browse files
committed
Merge branch 'feat-layout-algorithm-in-result'
2 parents cc649fe + ff00cde commit f990ee8

3 files changed

Lines changed: 83 additions & 9 deletions

File tree

float-pigment-layout/src/algo/flow.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -733,7 +733,16 @@ impl<T: LayoutTreeNode> Flow<T> for LayoutUnit<T> {
733733
}
734734
last_baseline_ascent_option =
735735
Some(child_res.last_baseline_ascent + baseline_diff);
736-
child.save_all_results(child_node, env, node_inner_size);
736+
if child_node.should_measure(env) {
737+
child.save_all_results(child_node, env, node_inner_size, LayoutAlgorithm::InlineMeasure);
738+
} else {
739+
child.update_result_layout_algorithm(|x| match x {
740+
LayoutAlgorithm::Block => LayoutAlgorithm::InlineBlock,
741+
LayoutAlgorithm::Flex => LayoutAlgorithm::InlineFlex,
742+
LayoutAlgorithm::Grid => LayoutAlgorithm::InlineGrid,
743+
x => x,
744+
});
745+
}
737746
}
738747
}
739748
}
@@ -759,6 +768,7 @@ impl<T: LayoutTreeNode> Flow<T> for LayoutUnit<T> {
759768
middle_node,
760769
env,
761770
node_inner_size,
771+
LayoutAlgorithm::Inline,
762772
);
763773
let (_, border, padding_border) = middle_node_layout_unit
764774
.margin_border_padding(middle_node, node_inner_size);

float-pigment-layout/src/lib.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,12 @@ impl<T: LayoutTreeNode> LayoutNode<T> {
354354
self.unit.borrow().computed_style()
355355
}
356356

357+
/// Get the layout algorithm used for this node.
358+
#[inline]
359+
pub fn layout_algorithm(&self) -> LayoutAlgorithm {
360+
self.unit.borrow().layout_algorithm
361+
}
362+
357363
/// Check all nodes that has been `mark_dirty`, and update the layout results of the whole tree.
358364
///
359365
/// Should only be called on the tree root node.
@@ -489,3 +495,41 @@ impl<L: LengthNum> Default for ComputedStyle<L> {
489495
}
490496
}
491497
}
498+
499+
/// The supported layout algorithms.
500+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
501+
pub enum LayoutAlgorithm {
502+
/// Used when the node has no layout, e.g. `display: none`.
503+
None,
504+
505+
/// Used when the node is an inline node.
506+
///
507+
/// `display: inline` does not guarantee this.
508+
/// For example, if the parent node has `display: flex`,
509+
/// this node will not be an inline node.
510+
Inline,
511+
512+
/// Used when the node measured as an inline node.
513+
InlineMeasure,
514+
515+
/// Used when the node is a block node.
516+
Block,
517+
518+
/// Used when the node is an inline-block node.
519+
InlineBlock,
520+
521+
/// Used when the node measured as a block node.
522+
BlockMeasure,
523+
524+
/// Used when the node is a flex container, e.g. `display: flex`.
525+
Flex,
526+
527+
/// Used when the node is an inline-flex node.
528+
InlineFlex,
529+
530+
/// Used when the node is a grid container, e.g. `display: grid`.
531+
Grid,
532+
533+
/// Used when the node is an inline-grid node.
534+
InlineGrid,
535+
}

float-pigment-layout/src/unit.rs

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ pub(crate) struct LayoutUnit<T: LayoutTreeNode> {
88
pub(crate) result_padding_rect: Rect<T::Length>,
99
pub(crate) result_content_rect: Rect<T::Length>,
1010
pub(crate) computed_style: ComputedStyle<T::Length>,
11+
pub(crate) layout_algorithm: LayoutAlgorithm,
1112
}
1213

1314
impl<T: LayoutTreeNode> LayoutUnit<T> {
@@ -18,6 +19,7 @@ impl<T: LayoutTreeNode> LayoutUnit<T> {
1819
result_padding_rect: Rect::zero(),
1920
result_content_rect: Rect::zero(),
2021
computed_style: ComputedStyle::default(),
22+
layout_algorithm: LayoutAlgorithm::None,
2123
}
2224
}
2325

@@ -130,6 +132,7 @@ impl<T: LayoutTreeNode> LayoutUnit<T> {
130132
self.result = Rect::zero();
131133
self.result_padding_rect = Rect::zero();
132134
self.result_content_rect = Rect::zero();
135+
self.layout_algorithm = LayoutAlgorithm::None;
133136
node.tree_visitor().for_each_child(|child_node, _| {
134137
child_node
135138
.layout_node()
@@ -144,14 +147,24 @@ impl<T: LayoutTreeNode> LayoutUnit<T> {
144147
node: &T,
145148
request: ComputeRequest<T::Length>,
146149
) -> ComputeResult<T::Length> {
150+
let style = node.style();
151+
let mut layout_algorithm = match style.display() {
152+
Display::None => LayoutAlgorithm::None,
153+
Display::Block
154+
| Display::InlineBlock
155+
| Display::Inline => LayoutAlgorithm::Block,
156+
Display::Flex | Display::InlineFlex => LayoutAlgorithm::Flex,
157+
Display::Grid | Display::InlineGrid => LayoutAlgorithm::Grid,
158+
Display::FlowRoot => todo!(),
159+
};
160+
147161
let ret = if let Some(r) = self.cache.read(node, &request) {
148162
// if cached, use the cache value
149163
// info!("!!! {:p} cache req {:?}", self, request);
150164
r
151165
} else {
152166
// do request
153167
// info!("!!! {:p} req {:?}", self, request);
154-
let style = node.style();
155168
let (margin, border, padding_border) =
156169
self.margin_border_padding(node, *request.parent_inner_size);
157170
if let Some(ret) = self.compute_measure_block_if_exists(
@@ -162,10 +175,11 @@ impl<T: LayoutTreeNode> LayoutUnit<T> {
162175
border,
163176
padding_border,
164177
) {
178+
layout_algorithm = LayoutAlgorithm::BlockMeasure;
165179
ret
166180
} else {
167-
match style.display() {
168-
Display::None => {
181+
match layout_algorithm {
182+
LayoutAlgorithm::None => {
169183
self.clear_display_none_result(node);
170184
ComputeResult {
171185
size: Normalized(Size::zero()),
@@ -174,7 +188,7 @@ impl<T: LayoutTreeNode> LayoutUnit<T> {
174188
collapsed_margin: CollapsedBlockMargin::zero(),
175189
}
176190
}
177-
Display::Block | Display::InlineBlock | Display::Inline => {
191+
LayoutAlgorithm::Block => {
178192
algo::flow::Flow::compute(
179193
self,
180194
env,
@@ -185,7 +199,7 @@ impl<T: LayoutTreeNode> LayoutUnit<T> {
185199
padding_border,
186200
)
187201
}
188-
Display::Flex | Display::InlineFlex => algo::flex_box::FlexBox::compute(
202+
LayoutAlgorithm::Flex => algo::flex_box::FlexBox::compute(
189203
self,
190204
env,
191205
node,
@@ -194,7 +208,7 @@ impl<T: LayoutTreeNode> LayoutUnit<T> {
194208
border,
195209
padding_border,
196210
),
197-
Display::Grid | Display::InlineGrid => algo::grid::GridContainer::compute(
211+
LayoutAlgorithm::Grid => algo::grid::GridContainer::compute(
198212
self,
199213
env,
200214
node,
@@ -203,13 +217,13 @@ impl<T: LayoutTreeNode> LayoutUnit<T> {
203217
border,
204218
padding_border,
205219
),
206-
Display::FlowRoot => todo!(),
220+
_ => unreachable!(),
207221
}
208222
}
209223
};
210224

211225
if request.kind == ComputeRequestKind::Position {
212-
self.save_all_results(node, env, *request.parent_inner_size);
226+
self.save_all_results(node, env, *request.parent_inner_size, layout_algorithm);
213227
}
214228
// info!("!!! {:p} res {:?} {:?}", self, request, ret);
215229
ret
@@ -220,13 +234,19 @@ impl<T: LayoutTreeNode> LayoutUnit<T> {
220234
node: &T,
221235
env: &mut T::Env,
222236
parent_inner_size: OptionSize<T::Length>,
237+
layout_algorithm: LayoutAlgorithm,
223238
) {
224239
let (margin, border, padding_border) = self.margin_border_padding(node, parent_inner_size);
225240
self.save_border_padding_result(border, padding_border);
226241
self.save_computed_style(margin, border, padding_border - border);
242+
self.layout_algorithm = layout_algorithm;
227243
node.size_updated(env, self.result.size, &self.computed_style);
228244
}
229245

246+
pub(crate) fn update_result_layout_algorithm(&mut self, f: impl FnOnce(LayoutAlgorithm) -> LayoutAlgorithm) {
247+
self.layout_algorithm = f(self.layout_algorithm);
248+
}
249+
230250
pub(crate) fn save_computed_style(
231251
&mut self,
232252
margin: EdgeOption<T::Length>,

0 commit comments

Comments
 (0)