mirror of
https://github.com/servo/servo.git
synced 2025-08-03 04:30:10 +01:00
Introduce a PaddingBorderMargin
helper
This commit is contained in:
parent
5f75f7ffdd
commit
0e35d70ca8
4 changed files with 101 additions and 102 deletions
|
@ -421,13 +421,11 @@ impl InlineBox {
|
|||
ifc: &mut InlineFormattingContextState<'box_tree, '_, '_>,
|
||||
) -> PartialInlineBoxFragment<'box_tree> {
|
||||
let style = self.style.clone();
|
||||
let cbis = ifc.containing_block.inline_size;
|
||||
let mut padding = style.padding().percentages_relative_to(cbis);
|
||||
let mut border = style.border_width();
|
||||
let mut margin = style
|
||||
.margin()
|
||||
.percentages_relative_to(cbis)
|
||||
.auto_is(Length::zero);
|
||||
let pbm = style.padding_border_margin(&ifc.containing_block);
|
||||
let mut padding = pbm.padding;
|
||||
let mut border = pbm.border;
|
||||
let mut margin = pbm.margin.auto_is(Length::zero);
|
||||
|
||||
if self.first_fragment {
|
||||
ifc.inline_position += padding.inline_start + border.inline_start + margin.inline_start;
|
||||
} else {
|
||||
|
@ -530,18 +528,14 @@ fn layout_atomic(
|
|||
ifc: &mut InlineFormattingContextState,
|
||||
atomic: &IndependentFormattingContext,
|
||||
) {
|
||||
let cbis = ifc.containing_block.inline_size;
|
||||
let padding = atomic.style.padding().percentages_relative_to(cbis);
|
||||
let border = atomic.style.border_width();
|
||||
let margin = atomic
|
||||
.style
|
||||
.margin()
|
||||
.percentages_relative_to(cbis)
|
||||
.auto_is(Length::zero);
|
||||
let pbm = &(&padding + &border) + &margin;
|
||||
ifc.inline_position += pbm.inline_start;
|
||||
let pbm = atomic.style.padding_border_margin(&ifc.containing_block);
|
||||
let padding = pbm.padding;
|
||||
let border = pbm.border;
|
||||
let margin = pbm.margin.auto_is(Length::zero);
|
||||
let pbm_sums = &(&padding + &border) + &margin;
|
||||
ifc.inline_position += pbm_sums.inline_start;
|
||||
let mut start_corner = Vec2 {
|
||||
block: pbm.block_start,
|
||||
block: pbm_sums.block_start,
|
||||
inline: ifc.inline_position - ifc.current_nesting_level.inline_start,
|
||||
};
|
||||
if atomic.style.clone_position().is_relative() {
|
||||
|
@ -577,9 +571,10 @@ fn layout_atomic(
|
|||
.auto_is(Length::zero);
|
||||
|
||||
// https://drafts.csswg.org/css2/visudet.html#inlineblock-width
|
||||
let cbis = ifc.containing_block.inline_size;
|
||||
let tentative_inline_size =
|
||||
box_size.inline.percentage_relative_to(cbis).auto_is(|| {
|
||||
let available_size = cbis - pbm.inline_sum();
|
||||
let available_size = cbis - pbm_sums.inline_sum();
|
||||
atomic.content_sizes.shrink_to_fit(available_size)
|
||||
});
|
||||
|
||||
|
@ -641,10 +636,10 @@ fn layout_atomic(
|
|||
},
|
||||
};
|
||||
|
||||
ifc.inline_position += pbm.inline_end + fragment.content_rect.size.inline;
|
||||
ifc.inline_position += pbm_sums.inline_end + fragment.content_rect.size.inline;
|
||||
ifc.current_nesting_level
|
||||
.max_block_size_of_fragments_so_far
|
||||
.max_assign(pbm.block_sum() + fragment.content_rect.size.block);
|
||||
.max_assign(pbm_sums.block_sum() + fragment.content_rect.size.block);
|
||||
ifc.current_nesting_level
|
||||
.fragments_so_far
|
||||
.push(Fragment::Box(fragment));
|
||||
|
|
|
@ -14,7 +14,7 @@ use crate::fragments::{CollapsedBlockMargins, CollapsedMargin, Fragment};
|
|||
use crate::geom::flow_relative::{Rect, Sides, Vec2};
|
||||
use crate::positioned::{AbsolutelyPositionedBox, PositioningContext};
|
||||
use crate::replaced::ReplacedContent;
|
||||
use crate::style_ext::ComputedValuesExt;
|
||||
use crate::style_ext::{ComputedValuesExt, PaddingBorderMargin};
|
||||
use crate::ContainingBlock;
|
||||
use rayon::iter::{IndexedParallelIterator, IntoParallelRefIterator, ParallelIterator};
|
||||
use rayon_croissant::ParallelIteratorExt;
|
||||
|
@ -350,12 +350,7 @@ fn layout_in_flow_non_replaced_block_level(
|
|||
tree_rank: usize,
|
||||
float_context: Option<&mut FloatContext>,
|
||||
) -> BoxFragment {
|
||||
let cbis = containing_block.inline_size;
|
||||
let padding = style.padding().percentages_relative_to(cbis);
|
||||
let border = style.border_width();
|
||||
let margin = style.margin().percentages_relative_to(cbis);
|
||||
let pb = &padding + &border;
|
||||
let pb_inline_sum = pb.inline_sum();
|
||||
let pbm = style.padding_border_margin(containing_block);
|
||||
|
||||
let box_size = style.box_size().percentages_relative_to(containing_block);
|
||||
let max_box_size = style
|
||||
|
@ -368,22 +363,18 @@ fn layout_in_flow_non_replaced_block_level(
|
|||
|
||||
// https://drafts.csswg.org/css2/visudet.html#min-max-widths
|
||||
let solve_inline_margins = |inline_size| {
|
||||
solve_inline_margins_for_in_flow_block_level(
|
||||
containing_block,
|
||||
pb_inline_sum,
|
||||
margin.inline_start,
|
||||
margin.inline_end,
|
||||
inline_size,
|
||||
)
|
||||
solve_inline_margins_for_in_flow_block_level(containing_block, &pbm, inline_size)
|
||||
};
|
||||
let (mut inline_size, mut inline_margins) =
|
||||
if let Some(inline_size) = box_size.inline.non_auto() {
|
||||
(inline_size, solve_inline_margins(inline_size))
|
||||
} else {
|
||||
let margin_inline_start = margin.inline_start.auto_is(Length::zero);
|
||||
let margin_inline_end = margin.inline_end.auto_is(Length::zero);
|
||||
let margin_inline_sum = margin_inline_start + margin_inline_end;
|
||||
let inline_size = cbis - pb_inline_sum - margin_inline_sum;
|
||||
let margin_inline_start = pbm.margin.inline_start.auto_is(Length::zero);
|
||||
let margin_inline_end = pbm.margin.inline_end.auto_is(Length::zero);
|
||||
let inline_size = containing_block.inline_size -
|
||||
pbm.padding_border_sums.inline -
|
||||
margin_inline_start -
|
||||
margin_inline_end;
|
||||
(inline_size, (margin_inline_start, margin_inline_end))
|
||||
};
|
||||
if let Some(max_inline_size) = max_box_size.inline {
|
||||
|
@ -400,8 +391,8 @@ fn layout_in_flow_non_replaced_block_level(
|
|||
let margin = Sides {
|
||||
inline_start: inline_margins.0,
|
||||
inline_end: inline_margins.1,
|
||||
block_start: margin.block_start.auto_is(Length::zero),
|
||||
block_end: margin.block_end.auto_is(Length::zero),
|
||||
block_start: pbm.margin.block_start.auto_is(Length::zero),
|
||||
block_end: pbm.margin.block_end.auto_is(Length::zero),
|
||||
};
|
||||
|
||||
// https://drafts.csswg.org/css2/visudet.html#min-max-heights
|
||||
|
@ -427,8 +418,10 @@ fn layout_in_flow_non_replaced_block_level(
|
|||
let mut content_block_size;
|
||||
match block_level_kind {
|
||||
NonReplacedContents::SameFormattingContextBlock(contents) => {
|
||||
let this_start_margin_can_collapse_with_children = pb.block_start == Length::zero();
|
||||
let this_end_margin_can_collapse_with_children = pb.block_end == Length::zero() &&
|
||||
let start_margin_can_collapse_with_children = pbm.padding.block_start == Length::zero() &&
|
||||
pbm.border.block_start == Length::zero();
|
||||
let end_margin_can_collapse_with_children = pbm.padding.block_end == Length::zero() &&
|
||||
pbm.border.block_end == Length::zero() &&
|
||||
block_size == LengthOrAuto::Auto &&
|
||||
min_box_size.block == Length::zero();
|
||||
|
||||
|
@ -438,13 +431,13 @@ fn layout_in_flow_non_replaced_block_level(
|
|||
&containing_block_for_children,
|
||||
tree_rank,
|
||||
float_context,
|
||||
CollapsibleWithParentStartMargin(this_start_margin_can_collapse_with_children),
|
||||
CollapsibleWithParentStartMargin(start_margin_can_collapse_with_children),
|
||||
);
|
||||
fragments = flow_layout.fragments;
|
||||
content_block_size = flow_layout.content_block_size;
|
||||
let mut collapsible_margins_in_children = flow_layout.collapsible_margins_in_children;
|
||||
|
||||
if this_start_margin_can_collapse_with_children {
|
||||
if start_margin_can_collapse_with_children {
|
||||
block_margins_collapsed_with_children
|
||||
.start
|
||||
.adjoin_assign(&collapsible_margins_in_children.start);
|
||||
|
@ -457,7 +450,7 @@ fn layout_in_flow_non_replaced_block_level(
|
|||
));
|
||||
}
|
||||
}
|
||||
if this_end_margin_can_collapse_with_children {
|
||||
if end_margin_can_collapse_with_children {
|
||||
block_margins_collapsed_with_children
|
||||
.end
|
||||
.adjoin_assign(&collapsible_margins_in_children.end);
|
||||
|
@ -465,8 +458,8 @@ fn layout_in_flow_non_replaced_block_level(
|
|||
content_block_size += collapsible_margins_in_children.end.solve();
|
||||
}
|
||||
block_margins_collapsed_with_children.collapsed_through =
|
||||
this_start_margin_can_collapse_with_children &&
|
||||
this_end_margin_can_collapse_with_children &&
|
||||
start_margin_can_collapse_with_children &&
|
||||
end_margin_can_collapse_with_children &&
|
||||
collapsible_margins_in_children.collapsed_through;
|
||||
},
|
||||
NonReplacedContents::EstablishesAnIndependentFormattingContext(non_replaced) => {
|
||||
|
@ -485,8 +478,8 @@ fn layout_in_flow_non_replaced_block_level(
|
|||
});
|
||||
let content_rect = Rect {
|
||||
start_corner: Vec2 {
|
||||
block: pb.block_start,
|
||||
inline: pb.inline_start + margin.inline_start,
|
||||
block: pbm.padding.block_start + pbm.border.block_start,
|
||||
inline: pbm.padding.inline_start + pbm.border.inline_start + margin.inline_start,
|
||||
},
|
||||
size: Vec2 {
|
||||
block: block_size,
|
||||
|
@ -498,8 +491,8 @@ fn layout_in_flow_non_replaced_block_level(
|
|||
style.clone(),
|
||||
fragments,
|
||||
content_rect,
|
||||
padding,
|
||||
border,
|
||||
pbm.padding,
|
||||
pbm.border,
|
||||
margin,
|
||||
block_margins_collapsed_with_children,
|
||||
)
|
||||
|
@ -514,32 +507,22 @@ fn layout_in_flow_replaced_block_level<'a>(
|
|||
style: &Arc<ComputedValues>,
|
||||
replaced: &ReplacedContent,
|
||||
) -> BoxFragment {
|
||||
let pbm = style.padding_border_margin(containing_block);
|
||||
let size = replaced.used_size_as_if_inline_element(containing_block, style);
|
||||
|
||||
let cbis = containing_block.inline_size;
|
||||
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 (margin_inline_start, margin_inline_end) = solve_inline_margins_for_in_flow_block_level(
|
||||
containing_block,
|
||||
pb.inline_sum(),
|
||||
computed_margin.inline_start,
|
||||
computed_margin.inline_end,
|
||||
size.inline,
|
||||
);
|
||||
let (margin_inline_start, margin_inline_end) =
|
||||
solve_inline_margins_for_in_flow_block_level(containing_block, &pbm, size.inline);
|
||||
let margin = Sides {
|
||||
inline_start: margin_inline_start,
|
||||
inline_end: margin_inline_end,
|
||||
block_start: computed_margin.block_start.auto_is(Length::zero),
|
||||
block_end: computed_margin.block_end.auto_is(Length::zero),
|
||||
block_start: pbm.margin.block_start.auto_is(Length::zero),
|
||||
block_end: pbm.margin.block_end.auto_is(Length::zero),
|
||||
};
|
||||
let fragments = replaced.make_fragments(style, size.clone());
|
||||
let content_rect = Rect {
|
||||
start_corner: Vec2 {
|
||||
block: pb.block_start,
|
||||
inline: pb.inline_start + margin.inline_start,
|
||||
block: pbm.padding.block_start + pbm.border.block_start,
|
||||
inline: pbm.padding.inline_start + pbm.border.inline_start + margin.inline_start,
|
||||
},
|
||||
size,
|
||||
};
|
||||
|
@ -549,8 +532,8 @@ fn layout_in_flow_replaced_block_level<'a>(
|
|||
style.clone(),
|
||||
fragments,
|
||||
content_rect,
|
||||
padding,
|
||||
border,
|
||||
pbm.padding,
|
||||
pbm.border,
|
||||
margin,
|
||||
block_margins_collapsed_with_children,
|
||||
)
|
||||
|
@ -558,15 +541,13 @@ fn layout_in_flow_replaced_block_level<'a>(
|
|||
|
||||
fn solve_inline_margins_for_in_flow_block_level(
|
||||
containing_block: &ContainingBlock,
|
||||
padding_border_inline_sum: Length,
|
||||
computed_margin_inline_start: LengthOrAuto,
|
||||
computed_margin_inline_end: LengthOrAuto,
|
||||
pbm: &PaddingBorderMargin,
|
||||
inline_size: Length,
|
||||
) -> (Length, Length) {
|
||||
let inline_margins = containing_block.inline_size - padding_border_inline_sum - inline_size;
|
||||
match (computed_margin_inline_start, computed_margin_inline_end) {
|
||||
(LengthOrAuto::Auto, LengthOrAuto::Auto) => (inline_margins / 2., inline_margins / 2.),
|
||||
(LengthOrAuto::Auto, LengthOrAuto::LengthPercentage(end)) => (inline_margins - end, end),
|
||||
(LengthOrAuto::LengthPercentage(start), _) => (start, inline_margins - start),
|
||||
let available = containing_block.inline_size - pbm.padding_border_sums.inline - inline_size;
|
||||
match (pbm.margin.inline_start, pbm.margin.inline_end) {
|
||||
(LengthOrAuto::Auto, LengthOrAuto::Auto) => (available / 2., available / 2.),
|
||||
(LengthOrAuto::Auto, LengthOrAuto::LengthPercentage(end)) => (available - end, end),
|
||||
(LengthOrAuto::LengthPercentage(start), _) => (start, available - start),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -405,9 +405,10 @@ impl HoistedAbsolutelyPositionedBox {
|
|||
for_nearest_containing_block_for_all_descendants: &mut Vec<HoistedAbsolutelyPositionedBox>,
|
||||
containing_block: &DefiniteContainingBlock,
|
||||
) -> BoxFragment {
|
||||
let style = &self.absolutely_positioned_box.contents.style;
|
||||
let cbis = containing_block.size.inline;
|
||||
let cbbs = containing_block.size.block;
|
||||
let style = &self.absolutely_positioned_box.contents.style;
|
||||
let pbm = style.padding_border_margin(&containing_block.into());
|
||||
|
||||
let size;
|
||||
let replaced_used_size;
|
||||
|
@ -432,16 +433,11 @@ impl HoistedAbsolutelyPositionedBox {
|
|||
},
|
||||
}
|
||||
|
||||
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_axis = solve_axis(
|
||||
cbis,
|
||||
pb.inline_sum(),
|
||||
computed_margin.inline_start.clone(),
|
||||
computed_margin.inline_end.clone(),
|
||||
pbm.padding_border_sums.inline,
|
||||
pbm.margin.inline_start,
|
||||
pbm.margin.inline_end,
|
||||
/* avoid_negative_margin_start */ true,
|
||||
self.box_offsets.inline.clone(),
|
||||
size.inline,
|
||||
|
@ -449,9 +445,9 @@ impl HoistedAbsolutelyPositionedBox {
|
|||
|
||||
let block_axis = solve_axis(
|
||||
cbis,
|
||||
pb.block_sum(),
|
||||
computed_margin.block_start.clone(),
|
||||
computed_margin.block_end.clone(),
|
||||
pbm.padding_border_sums.block,
|
||||
pbm.margin.block_start,
|
||||
pbm.margin.block_end,
|
||||
/* avoid_negative_margin_start */ false,
|
||||
self.box_offsets.block.clone(),
|
||||
size.block,
|
||||
|
@ -483,14 +479,14 @@ impl HoistedAbsolutelyPositionedBox {
|
|||
// 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_axis.size.auto_is(|| {
|
||||
let available_size = match inline_axis.anchor {
|
||||
Anchor::Start(start) => {
|
||||
cbis - start - pb.inline_sum() - margin.inline_sum()
|
||||
},
|
||||
Anchor::End(end) => {
|
||||
cbis - end - pb.inline_sum() - margin.inline_sum()
|
||||
},
|
||||
let anchor = match inline_axis.anchor {
|
||||
Anchor::Start(start) => start,
|
||||
Anchor::End(end) => end,
|
||||
};
|
||||
let available_size = cbis -
|
||||
anchor -
|
||||
pbm.padding_border_sums.inline -
|
||||
margin.inline_sum();
|
||||
self.absolutely_positioned_box
|
||||
.contents
|
||||
.content_sizes
|
||||
|
@ -526,6 +522,7 @@ impl HoistedAbsolutelyPositionedBox {
|
|||
},
|
||||
};
|
||||
|
||||
let pb = &pbm.padding + &pbm.border;
|
||||
let inline_start = match inline_axis.anchor {
|
||||
Anchor::Start(start) => start + pb.inline_start + margin.inline_start,
|
||||
Anchor::End(end) => {
|
||||
|
@ -550,8 +547,8 @@ impl HoistedAbsolutelyPositionedBox {
|
|||
style.clone(),
|
||||
fragments,
|
||||
content_rect,
|
||||
padding,
|
||||
border,
|
||||
pbm.padding,
|
||||
pbm.border,
|
||||
margin,
|
||||
CollapsedBlockMargins::zero(),
|
||||
)
|
||||
|
|
|
@ -3,11 +3,12 @@
|
|||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use crate::geom::{flow_relative, PhysicalSides, PhysicalSize};
|
||||
use crate::ContainingBlock;
|
||||
use style::computed_values::mix_blend_mode::T as ComputedMixBlendMode;
|
||||
use style::computed_values::position::T as ComputedPosition;
|
||||
use style::computed_values::transform_style::T as ComputedTransformStyle;
|
||||
use style::properties::ComputedValues;
|
||||
use style::values::computed::{Length, LengthPercentage, LengthPercentageOrAuto};
|
||||
use style::values::computed::{Length, LengthOrAuto, LengthPercentage, LengthPercentageOrAuto};
|
||||
use style::values::computed::{NonNegativeLengthPercentage, Size};
|
||||
use style::values::generics::box_::Perspective;
|
||||
use style::values::generics::length::MaxSize;
|
||||
|
@ -43,6 +44,16 @@ pub(crate) enum DisplayInside {
|
|||
FlowRoot,
|
||||
}
|
||||
|
||||
/// Percentages resolved but not `auto` margins
|
||||
pub(crate) struct PaddingBorderMargin {
|
||||
pub padding: flow_relative::Sides<Length>,
|
||||
pub border: flow_relative::Sides<Length>,
|
||||
pub margin: flow_relative::Sides<LengthOrAuto>,
|
||||
|
||||
/// Pre-computed sums in each axis
|
||||
pub padding_border_sums: flow_relative::Vec2<Length>,
|
||||
}
|
||||
|
||||
pub(crate) trait ComputedValuesExt {
|
||||
fn inline_size_is_length(&self) -> bool;
|
||||
fn inline_box_offsets_are_both_non_auto(&self) -> bool;
|
||||
|
@ -50,6 +61,7 @@ pub(crate) trait ComputedValuesExt {
|
|||
fn box_size(&self) -> flow_relative::Vec2<LengthPercentageOrAuto>;
|
||||
fn min_box_size(&self) -> flow_relative::Vec2<LengthPercentageOrAuto>;
|
||||
fn max_box_size(&self) -> flow_relative::Vec2<MaxSize<LengthPercentage>>;
|
||||
fn padding_border_margin(&self, containing_block: &ContainingBlock) -> PaddingBorderMargin;
|
||||
fn padding(&self) -> flow_relative::Sides<LengthPercentage>;
|
||||
fn border_width(&self) -> flow_relative::Sides<Length>;
|
||||
fn margin(&self) -> flow_relative::Sides<LengthPercentageOrAuto>;
|
||||
|
@ -135,7 +147,21 @@ impl ComputedValuesExt for ComputedValues {
|
|||
)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn padding_border_margin(&self, containing_block: &ContainingBlock) -> PaddingBorderMargin {
|
||||
let cbis = containing_block.inline_size;
|
||||
let padding = self.padding().percentages_relative_to(cbis);
|
||||
let border = self.border_width();
|
||||
PaddingBorderMargin {
|
||||
padding_border_sums: flow_relative::Vec2 {
|
||||
inline: padding.inline_sum() + border.inline_sum(),
|
||||
block: padding.block_sum() + border.block_sum(),
|
||||
},
|
||||
padding,
|
||||
border,
|
||||
margin: self.margin().percentages_relative_to(cbis),
|
||||
}
|
||||
}
|
||||
|
||||
fn padding(&self) -> flow_relative::Sides<LengthPercentage> {
|
||||
let padding = self.get_padding();
|
||||
flow_relative::Sides::from_physical(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue