diff --git a/float-pigment-forest/src/layout/layout_impl.rs b/float-pigment-forest/src/layout/layout_impl.rs index 45258c5..33803bf 100644 --- a/float-pigment-forest/src/layout/layout_impl.rs +++ b/float-pigment-forest/src/layout/layout_impl.rs @@ -8,7 +8,7 @@ use float_pigment_css::{ }, }; use float_pigment_layout::{ - DefLength, Edge, EdgeOption, InlineMeasure, InlineUnit, LayoutNode, LayoutStyle, + DefLength, EdgeOption, InlineMeasure, InlineUnit, InlineUnitMetadata, LayoutNode, LayoutStyle, LayoutTreeNode, LayoutTreeVisitor, MeasureResult, OptionNum, OptionSize, Point, Size, Vector, }; @@ -240,22 +240,8 @@ impl LayoutTreeNode for Node { min: Size, max: Size, max_content: OptionSize, - ) -> Self::InlineUnit { - let measure_res = self.measure_block_size(env, req_size, min, max, max_content, false); - let size = measure_res.size; - LayoutInlineUnit { - offset: Point::zero(), - size, - first_baseline_ascent: Vector::new( - measure_res.first_baseline_ascent.x, - measure_res.first_baseline_ascent.y, - ), - last_baseline_ascent: Vector::new( - measure_res.last_baseline_ascent.x, - measure_res.last_baseline_ascent.y, - ), - is_inline_block: false, - } + ) -> MeasureResult { + self.measure_block_size(env, req_size, min, max, max_content, false) } } @@ -290,7 +276,6 @@ pub struct LayoutInlineUnit { size: Size, first_baseline_ascent: Vector, last_baseline_ascent: Vector, - is_inline_block: bool, } impl LayoutInlineUnit { @@ -304,26 +289,16 @@ impl LayoutInlineUnit { }, ) } - fn adjust_inline_size(&mut self, padding_border: Edge) { - if self.is_inline_block { - return; - } - self.size.height += padding_border.vertical(); - self.size.width += padding_border.horizontal(); - self.first_baseline_ascent.y += padding_border.top; - self.last_baseline_ascent.y += padding_border.top; - } } impl InlineUnit for LayoutInlineUnit { type Env = Env; - fn inline_block(_env: &mut Env, _node: &Node, size: Size, baseline_ascent: Len) -> Self { + fn new(_env: &mut Env, _node: &Node, res: MeasureResult) -> Self { Self { offset: Point::zero(), - size, - first_baseline_ascent: Vector::new(Len::zero(), baseline_ascent), - last_baseline_ascent: Vector::new(Len::zero(), baseline_ascent), - is_inline_block: true, + size: res.size, + first_baseline_ascent: res.first_baseline_ascent, + last_baseline_ascent: res.last_baseline_ascent, } } } @@ -399,7 +374,7 @@ impl InlineMeasure for LayoutInlineMeasure { fn block_size( _env: &mut Env, block_node: &Node, - inline_nodes: Vec<(LayoutInlineUnit, EdgeOption, Edge)>, + inline_nodes: Vec>, req_size: OptionSize, _max_content_with_max_size: OptionSize, _update_position: bool, @@ -421,11 +396,8 @@ impl InlineMeasure for LayoutInlineMeasure { if let Some(suggested_width) = suggested_width.val() { inline_nodes .into_iter() - .for_each(|(mut inline_unit, margin, padding_border)| { - inline_unit.adjust_inline_size(padding_border); - if (current_line.total_inline_size - + inline_unit.size.width - + margin.horizontal() + .for_each(|InlineUnitMetadata { unit, margin }| { + if (current_line.total_inline_size + unit.size.width + margin.horizontal() > suggested_width) && !current_line.is_empty() { @@ -434,14 +406,13 @@ impl InlineMeasure for LayoutInlineMeasure { current_line = Line::default(); current_line.block_start = prev_line_block_start; } - current_line.collect_inline_unit(inline_unit, margin); + current_line.collect_inline_unit(unit, margin); }); } else { inline_nodes .into_iter() - .for_each(|(mut inline_unit, margin, padding_border)| { - inline_unit.adjust_inline_size(padding_border); - current_line.collect_inline_unit(inline_unit, margin); + .for_each(|InlineUnitMetadata { unit, margin }| { + current_line.collect_inline_unit(unit, margin); }); } if !current_line.is_empty() { diff --git a/float-pigment-layout/src/algo/flow.rs b/float-pigment-layout/src/algo/flow.rs index 8a43363..366a835 100644 --- a/float-pigment-layout/src/algo/flow.rs +++ b/float-pigment-layout/src/algo/flow.rs @@ -568,14 +568,20 @@ impl Flow for LayoutUnit { parent_is_block: true, }, ); - T::InlineUnit::inline_block( + T::InlineUnit::new( env, child_node, - *child_res.size, - child_res.last_baseline_ascent.main_axis(axis_info.dir), + MeasureResult { + size: *child_res.size, + first_baseline_ascent: child_res.first_baseline_ascent, + last_baseline_ascent: child_res.last_baseline_ascent, + }, ) }; - (unit, child_margin, child_padding_border) + InlineUnitMetadata { + unit, + margin: child_margin, + } }) .collect(); let (block_size, positions) = T::InlineMeasure::block_size( diff --git a/float-pigment-layout/src/lib.rs b/float-pigment-layout/src/lib.rs index 7d7795b..763fc07 100644 --- a/float-pigment-layout/src/lib.rs +++ b/float-pigment-layout/src/lib.rs @@ -168,7 +168,7 @@ pub trait LayoutTreeNode: Sized { min: Size, max: Size, max_content: OptionSize, - ) -> Self::InlineUnit; + ) -> MeasureResult; /// A notifier that the layout size of itself (or any node in the subtree) has been re-evaluated. /// @@ -380,7 +380,7 @@ pub trait InlineMeasure { fn block_size( env: &mut Self::Env, block_node: &T, - inline_nodes: Vec<(Self::InlineUnit, EdgeOption, Edge)>, + inline_nodes: Vec>, req_size: OptionSize, max_content_with_max_size: OptionSize, update_position: bool, @@ -390,18 +390,21 @@ pub trait InlineMeasure { ); } +/// Inline unit with some metadata. +#[allow(missing_docs)] +#[derive(Debug)] +pub struct InlineUnitMetadata { + pub unit: T::InlineUnit, + pub margin: EdgeOption, +} + /// A helper type as the inline form of a tree node. pub trait InlineUnit { /// Some custom environment data. type Env; /// Construct from a tree node with specified size and baseline information. - fn inline_block( - env: &mut Self::Env, - node: &T, - size: Size, - baseline_ascent: T::Length, - ) -> Self; + fn new(env: &mut Self::Env, node: &T, result: MeasureResult) -> Self; } /// The result of the measure function. diff --git a/float-pigment-layout/src/unit.rs b/float-pigment-layout/src/unit.rs index f4ae630..7b76c80 100644 --- a/float-pigment-layout/src/unit.rs +++ b/float-pigment-layout/src/unit.rs @@ -617,7 +617,7 @@ impl LayoutUnit { self.css_border_box_size(node, parent_inner_size, border, padding_border); let min_max_limit = self.normalized_min_max_limit(node, parent_inner_size, border, padding_border); - let ret = node.measure_inline_unit( + let r = node.measure_inline_unit( env, OptionSize::new( req_size.width - padding_border.horizontal(), @@ -638,6 +638,23 @@ impl LayoutUnit { max_content.height - padding_border.vertical(), ), ); + let size = Size::new( + r.size.width + padding_border.horizontal(), + r.size.height + padding_border.vertical(), + ); + let first_baseline_ascent = + r.first_baseline_ascent + Vector::new(padding_border.left, padding_border.top); + let last_baseline_ascent = + r.last_baseline_ascent + Vector::new(padding_border.left, padding_border.top); + let ret = T::InlineUnit::new( + env, + node, + MeasureResult { + size, + first_baseline_ascent, + last_baseline_ascent, + }, + ); Some(ret) } else { None