Move solve_axis function to module level

This commit is contained in:
Simon Sapin 2019-12-08 01:06:29 +01:00
parent 29067225a4
commit be8df1d114

View file

@ -170,7 +170,7 @@ impl<'a> AbsolutelyPositionedFragment<'a> {
block: LengthOrAuto::LengthPercentage(u.block),
};
replaced_used_size = Some(u);
}
},
Err(_non_replaced) => {
let box_size = style.box_size();
size = Vec2 {
@ -178,21 +178,138 @@ impl<'a> AbsolutelyPositionedFragment<'a> {
block: box_size.block.percentage_relative_to(cbbs),
};
replaced_used_size = None;
},
}
}
let padding = style.padding().percentages_relative_to(cbis);
let border = style.border_width();
let computed_margin = style.margin().percentages_relative_to(cbis);
let pb = &padding + &border;
let (inline_anchor, inline_size, margin_inline_start, margin_inline_end) = solve_axis(
cbis,
pb.inline_sum(),
computed_margin.inline_start,
computed_margin.inline_end,
/* avoid_negative_margin_start */ true,
self.box_offsets.inline,
size.inline,
);
let (block_anchor, block_size, margin_block_start, margin_block_end) = solve_axis(
cbis,
pb.block_sum(),
computed_margin.block_start,
computed_margin.block_end,
/* avoid_negative_margin_start */ false,
self.box_offsets.block,
size.block,
);
let margin = Sides {
inline_start: margin_inline_start,
inline_end: margin_inline_end,
block_start: margin_block_start,
block_end: margin_block_end,
};
let mut absolutely_positioned_fragments = Vec::new();
let (size, mut fragments) = match self.absolutely_positioned_box.contents.as_replaced() {
Ok(replaced) => {
// https://drafts.csswg.org/css2/visudet.html#abs-replaced-width
// https://drafts.csswg.org/css2/visudet.html#abs-replaced-height
let style = &self.absolutely_positioned_box.contents.style;
let size = replaced_used_size.unwrap();
let fragments = replaced.make_fragments(style, size.clone());
(size, fragments)
},
Err(non_replaced) => {
// https://drafts.csswg.org/css2/visudet.html#abs-non-replaced-width
// https://drafts.csswg.org/css2/visudet.html#abs-non-replaced-height
let inline_size = inline_size.auto_is(|| {
let available_size = match inline_anchor {
Anchor::Start(start) => {
cbis - start - pb.inline_sum() - margin.inline_sum()
},
Anchor::End(end) => cbis - end - pb.inline_sum() - margin.inline_sum(),
};
self.absolutely_positioned_box
.contents
.content_sizes
.shrink_to_fit(available_size)
});
let containing_block_for_children = ContainingBlock {
inline_size,
block_size,
style,
};
// https://drafts.csswg.org/css-writing-modes/#orthogonal-flows
assert_eq!(
containing_block.style.writing_mode,
containing_block_for_children.style.writing_mode,
"Mixed writing modes are not supported yet"
);
let dummy_tree_rank = 0;
let independent_layout = non_replaced.layout(
layout_context,
&containing_block_for_children,
dummy_tree_rank,
&mut absolutely_positioned_fragments,
);
let size = Vec2 {
inline: inline_size,
block: block_size.auto_is(|| independent_layout.content_block_size),
};
(size, independent_layout.fragments)
},
};
let inline_start = match inline_anchor {
Anchor::Start(start) => start + pb.inline_start + margin.inline_start,
Anchor::End(end) => cbbs - end - pb.inline_end - margin.inline_end - size.inline,
};
let block_start = match block_anchor {
Anchor::Start(start) => start + pb.block_start + margin.block_start,
Anchor::End(end) => cbbs - end - pb.block_end - margin.block_end - size.block,
};
let content_rect = Rect {
start_corner: Vec2 {
inline: inline_start,
block: block_start,
},
size,
};
AbsolutelyPositionedFragment::in_positioned_containing_block(
layout_context,
&absolutely_positioned_fragments,
&mut fragments,
&content_rect.size,
&padding,
style,
);
Fragment::Box(BoxFragment {
style: style.clone(),
children: fragments,
content_rect,
padding,
border,
margin,
block_margins_collapsed_with_children: CollapsedBlockMargins::zero(),
})
}
}
enum Anchor {
Start(Length),
End(Length),
}
/// This unifies both:
/// This unifies some of the parts in common in:
///
/// * https://drafts.csswg.org/css2/visudet.html#abs-non-replaced-width
/// * https://drafts.csswg.org/css2/visudet.html#abs-non-replaced-height
@ -271,12 +388,8 @@ impl<'a> AbsolutelyPositionedFragment<'a> {
margin_start = computed_margin_start.auto_is(Length::zero);
margin_end = computed_margin_end.auto_is(Length::zero);
// FIXME(nox): What happens if that is negative?
used_size = containing_size -
start -
end -
padding_border_sum -
margin_start -
margin_end
used_size =
containing_size - start - end - padding_border_sum - margin_start - margin_end
};
(
Anchor::Start(start),
@ -288,122 +401,6 @@ impl<'a> AbsolutelyPositionedFragment<'a> {
}
}
let (inline_anchor, inline_size, margin_inline_start, margin_inline_end) = solve_axis(
cbis,
pb.inline_sum(),
computed_margin.inline_start,
computed_margin.inline_end,
/* avoid_negative_margin_start */ true,
self.box_offsets.inline,
size.inline,
);
let (block_anchor, block_size, margin_block_start, margin_block_end) = solve_axis(
cbis,
pb.block_sum(),
computed_margin.block_start,
computed_margin.block_end,
/* avoid_negative_margin_start */ false,
self.box_offsets.block,
size.block,
);
let margin = Sides {
inline_start: margin_inline_start,
inline_end: margin_inline_end,
block_start: margin_block_start,
block_end: margin_block_end,
};
let mut absolutely_positioned_fragments = Vec::new();
let (size, mut fragments) = match self.absolutely_positioned_box.contents.as_replaced() {
Ok(replaced) => {
// https://drafts.csswg.org/css2/visudet.html#abs-replaced-width
// https://drafts.csswg.org/css2/visudet.html#abs-replaced-height
let style = &self.absolutely_positioned_box.contents.style;
let size = replaced_used_size.unwrap();
let fragments = replaced.make_fragments(style, size.clone());
(size, fragments)
},
Err(non_replaced) => {
// https://drafts.csswg.org/css2/visudet.html#abs-non-replaced-width
// https://drafts.csswg.org/css2/visudet.html#abs-non-replaced-height
let inline_size = inline_size.auto_is(|| {
let available_size = match inline_anchor {
Anchor::Start(start) => cbis - start - pb.inline_sum() - margin.inline_sum(),
Anchor::End(end) => cbis - end - pb.inline_sum() - margin.inline_sum(),
};
self.absolutely_positioned_box
.contents
.content_sizes
.shrink_to_fit(available_size)
});
let containing_block_for_children = ContainingBlock {
inline_size,
block_size,
style,
};
// https://drafts.csswg.org/css-writing-modes/#orthogonal-flows
assert_eq!(
containing_block.style.writing_mode,
containing_block_for_children.style.writing_mode,
"Mixed writing modes are not supported yet"
);
let dummy_tree_rank = 0;
let independent_layout = non_replaced.layout(
layout_context,
&containing_block_for_children,
dummy_tree_rank,
&mut absolutely_positioned_fragments,
);
let size = Vec2 {
inline: inline_size,
block: block_size.auto_is(|| independent_layout.content_block_size),
};
(size, independent_layout.fragments)
},
};
let inline_start = match inline_anchor {
Anchor::Start(start) => start + pb.inline_start + margin.inline_start,
Anchor::End(end) => cbbs - end - pb.inline_end - margin.inline_end - size.inline,
};
let block_start = match block_anchor {
Anchor::Start(start) => start + pb.block_start + margin.block_start,
Anchor::End(end) => cbbs - end - pb.block_end - margin.block_end - size.block,
};
let content_rect = Rect {
start_corner: Vec2 {
inline: inline_start,
block: block_start,
},
size,
};
AbsolutelyPositionedFragment::in_positioned_containing_block(
layout_context,
&absolutely_positioned_fragments,
&mut fragments,
&content_rect.size,
&padding,
style,
);
Fragment::Box(BoxFragment {
style: style.clone(),
children: fragments,
content_rect,
padding,
border,
margin,
block_margins_collapsed_with_children: CollapsedBlockMargins::zero(),
})
}
}
pub(crate) fn adjust_static_positions(
absolutely_positioned_fragments: &mut [AbsolutelyPositionedFragment],
child_fragments: &mut [Fragment],