layout: make margin in pbm use app unit (#31621)

* make margin in pbm use app unit

* Simplification

* Consistently resolve inline margins as Au, like block margins

---------

Co-authored-by: Oriol Brufau <obrufau@igalia.com>
This commit is contained in:
atbrakhi 2024-03-13 08:45:20 +05:30 committed by GitHub
parent 0b4b544910
commit 0fda14263a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 119 additions and 114 deletions

View file

@ -67,7 +67,7 @@ struct FlexItem<'a> {
/// Sum of padding, border, and margin (with `auto` assumed to be zero) in each axis. /// Sum of padding, border, and margin (with `auto` assumed to be zero) in each axis.
/// This is the difference between an outer and inner size. /// This is the difference between an outer and inner size.
pbm_auto_is_zero: FlexRelativeVec2<Length>, pbm_auto_is_zero: FlexRelativeVec2<Au>,
/// <https://drafts.csswg.org/css-flexbox/#algo-main-item> /// <https://drafts.csswg.org/css-flexbox/#algo-main-item>
flex_base_size: Length, flex_base_size: Length,
@ -509,7 +509,7 @@ impl<'a> FlexItem<'a> {
inline: min_size.inline.auto_is(automatic_min_size), inline: min_size.inline.auto_is(automatic_min_size),
block: min_size.block.auto_is(Length::zero), block: min_size.block.auto_is(Length::zero),
}; };
let margin_auto_is_zero = pbm.margin.auto_is(Length::zero); let margin_auto_is_zero = pbm.margin.auto_is(Au::zero);
let content_box_size = flex_context.vec2_to_flex_relative(content_box_size); let content_box_size = flex_context.vec2_to_flex_relative(content_box_size);
let content_max_size = flex_context.vec2_to_flex_relative(max_size); let content_max_size = flex_context.vec2_to_flex_relative(max_size);
@ -519,8 +519,8 @@ impl<'a> FlexItem<'a> {
let border = flex_context.sides_to_flex_relative(pbm.border); let border = flex_context.sides_to_flex_relative(pbm.border);
let padding_border = padding.sum_by_axis() + border.sum_by_axis(); let padding_border = padding.sum_by_axis() + border.sum_by_axis();
let pbm_auto_is_zero = FlexRelativeVec2 { let pbm_auto_is_zero = FlexRelativeVec2 {
main: padding_border.main.into(), main: padding_border.main,
cross: padding_border.cross.into(), cross: padding_border.cross,
} + margin_auto_is_zero.sum_by_axis(); } + margin_auto_is_zero.sum_by_axis();
let align_self = flex_context.align_for(&box_.style().clone_align_self()); let align_self = flex_context.align_for(&box_.style().clone_align_self());
@ -535,9 +535,7 @@ impl<'a> FlexItem<'a> {
let hypothetical_main_size = let hypothetical_main_size =
flex_base_size.clamp_between_extremums(content_min_size.main, content_max_size.main); flex_base_size.clamp_between_extremums(content_min_size.main, content_max_size.main);
let margin: FlexRelativeSides<AuOrAuto> = flex_context let margin: FlexRelativeSides<AuOrAuto> = flex_context.sides_to_flex_relative(pbm.margin);
.sides_to_flex_relative(pbm.margin)
.map(|v| v.map(|v| v.into()));
Self { Self {
box_, box_,
@ -652,7 +650,7 @@ fn collect_flex_lines<'items, LineResult>(
let line = FlexLine { let line = FlexLine {
outer_hypothetical_main_sizes_sum: items outer_hypothetical_main_sizes_sum: items
.iter() .iter()
.map(|item| item.hypothetical_main_size + item.pbm_auto_is_zero.main) .map(|item| item.hypothetical_main_size + item.pbm_auto_is_zero.main.into())
.sum(), .sum(),
items, items,
}; };
@ -663,7 +661,7 @@ fn collect_flex_lines<'items, LineResult>(
let mut line_so_far_is_empty = true; let mut line_so_far_is_empty = true;
let mut index = 0; let mut index = 0;
while let Some(item) = items.get(index) { while let Some(item) = items.get(index) {
let item_size = item.hypothetical_main_size + item.pbm_auto_is_zero.main; let item_size = item.hypothetical_main_size + item.pbm_auto_is_zero.main.into();
let line_size_would_be = line_size_so_far + item_size; let line_size_would_be = line_size_so_far + item_size;
let item_fits = line_size_would_be <= container_main_size; let item_fits = line_size_would_be <= container_main_size;
if item_fits || line_so_far_is_empty { if item_fits || line_so_far_is_empty {
@ -739,7 +737,7 @@ impl FlexLine<'_> {
item.content_box_size.cross.is_auto() && item.content_box_size.cross.is_auto() &&
!(item.margin.cross_start.is_auto() || item.margin.cross_end.is_auto()) !(item.margin.cross_start.is_auto() || item.margin.cross_end.is_auto())
{ {
(line_cross_size - item.pbm_auto_is_zero.cross).clamp_between_extremums( (line_cross_size - item.pbm_auto_is_zero.cross.into()).clamp_between_extremums(
item.content_min_size.cross, item.content_min_size.cross,
item.content_max_size.cross, item.content_max_size.cross,
) )
@ -922,11 +920,12 @@ impl FlexLine<'_> {
.map(|((item, target_main_size), frozen)| { .map(|((item, target_main_size), frozen)| {
item.pbm_auto_is_zero.main + item.pbm_auto_is_zero.main +
if frozen.get() { if frozen.get() {
target_main_size.get() target_main_size.get().into()
} else { } else {
item.flex_base_size item.flex_base_size.into()
} }
}) })
.map(|t| t.into())
.sum() .sum()
}; };
// https://drafts.csswg.org/css-flexbox/#initial-free-space // https://drafts.csswg.org/css-flexbox/#initial-free-space
@ -1155,7 +1154,7 @@ impl<'items> FlexLine<'items> {
.iter() .iter()
.zip(&*self.items) .zip(&*self.items)
.map(|(item_result, item)| { .map(|(item_result, item)| {
item_result.hypothetical_cross_size + item.pbm_auto_is_zero.cross item_result.hypothetical_cross_size + item.pbm_auto_is_zero.cross.into()
}); });
// FIXME: add support for `align-self: baseline` // FIXME: add support for `align-self: baseline`
// and computing the baseline of flex items. // and computing the baseline of flex items.
@ -1256,8 +1255,8 @@ impl FlexItem<'_> {
(AuOrAuto::Auto, AuOrAuto::Auto) => 2., (AuOrAuto::Auto, AuOrAuto::Auto) => 2.,
_ => 1., _ => 1.,
}; };
let outer_size = self.pbm_auto_is_zero.cross + item_cross_content_size; let outer_size = self.pbm_auto_is_zero.cross + item_cross_content_size.into();
let available = line_cross_size - outer_size; let available = line_cross_size - outer_size.into();
let start; let start;
let end; let end;
if available > Length::zero() { if available > Length::zero() {
@ -1310,11 +1309,11 @@ impl FlexItem<'_> {
match self.align_self { match self.align_self {
AlignItems::Stretch | AlignItems::FlexStart => Length::zero(), AlignItems::Stretch | AlignItems::FlexStart => Length::zero(),
AlignItems::FlexEnd => { AlignItems::FlexEnd => {
let margin_box_cross = *content_size + self.pbm_auto_is_zero.cross; let margin_box_cross = *content_size + self.pbm_auto_is_zero.cross.into();
line_cross_size - margin_box_cross line_cross_size - margin_box_cross
}, },
AlignItems::Center => { AlignItems::Center => {
let margin_box_cross = *content_size + self.pbm_auto_is_zero.cross; let margin_box_cross = *content_size + self.pbm_auto_is_zero.cross.into();
(line_cross_size - margin_box_cross) / 2. (line_cross_size - margin_box_cross) / 2.
}, },
// FIXME: handle baseline alignment // FIXME: handle baseline alignment

View file

@ -113,9 +113,9 @@ impl<'a> PlacementAmongFloats<'a> {
(current_bands, next_band) (current_bands, next_band)
}; };
let min_inline_start = float_context.containing_block_info.inline_start + let min_inline_start = float_context.containing_block_info.inline_start +
pbm.margin.inline_start.auto_is(Length::zero).into(); pbm.margin.inline_start.auto_is(Au::zero);
let max_inline_end = (float_context.containing_block_info.inline_end - let max_inline_end = (float_context.containing_block_info.inline_end -
pbm.margin.inline_end.auto_is(Length::zero).into()) pbm.margin.inline_end.auto_is(Au::zero))
.max(min_inline_start + object_size.inline); .max(min_inline_start + object_size.inline);
PlacementAmongFloats { PlacementAmongFloats {
float_context, float_context,
@ -259,7 +259,7 @@ impl<'a> PlacementAmongFloats<'a> {
pub(crate) fn set_inline_size(&mut self, inline_size: Au, pbm: &PaddingBorderMargin) { pub(crate) fn set_inline_size(&mut self, inline_size: Au, pbm: &PaddingBorderMargin) {
self.object_size.inline = inline_size; self.object_size.inline = inline_size;
self.max_inline_end = (self.float_context.containing_block_info.inline_end - self.max_inline_end = (self.float_context.containing_block_info.inline_end -
pbm.margin.inline_end.auto_is(Length::zero).into()) pbm.margin.inline_end.auto_is(Au::zero))
.max(self.min_inline_start + inline_size); .max(self.min_inline_start + inline_size);
} }
@ -911,8 +911,8 @@ impl FloatBox {
// Margin is computed this way regardless of whether the element is replaced // Margin is computed this way regardless of whether the element is replaced
// or non-replaced. // or non-replaced.
let pbm = style.padding_border_margin(containing_block); let pbm = style.padding_border_margin(containing_block);
let margin = pbm.margin.auto_is(Length::zero); let margin = pbm.margin.auto_is(Au::zero);
let pbm_sums = &(&pbm.padding + &pbm.border) + &margin.clone().into(); let pbm_sums = &(&pbm.padding + &pbm.border) + &margin.clone();
let (content_size, children); let (content_size, children);
match self.contents { match self.contents {
@ -991,7 +991,7 @@ impl FloatBox {
content_rect, content_rect,
pbm.padding.into(), pbm.padding.into(),
pbm.border.into(), pbm.border.into(),
margin, margin.into(),
// Clearance is handled internally by the float placement logic, so there's no need // Clearance is handled internally by the float placement logic, so there's no need
// to store it explicitly in the fragment. // to store it explicitly in the fragment.
None, // clearance None, // clearance

View file

@ -724,7 +724,8 @@ impl<'a, 'b> InlineFormattingContextState<'a, 'b> {
.pbm .pbm
.margin .margin
.inline_start .inline_start
.auto_is(Length::zero) .auto_is(Au::zero)
.into()
} }
let line_item = inline_box_state let line_item = inline_box_state
@ -758,7 +759,12 @@ impl<'a, 'b> InlineFormattingContextState<'a, 'b> {
if inline_box_state.is_last_fragment { if inline_box_state.is_last_fragment {
let pbm_end = Length::from( let pbm_end = Length::from(
inline_box_state.pbm.padding.inline_end + inline_box_state.pbm.border.inline_end, inline_box_state.pbm.padding.inline_end + inline_box_state.pbm.border.inline_end,
) + inline_box_state.pbm.margin.inline_end.auto_is(Length::zero); ) + inline_box_state
.pbm
.margin
.inline_end
.auto_is(Au::zero)
.into();
self.current_line_segment.inline_size += pbm_end; self.current_line_segment.inline_size += pbm_end;
} }
} }
@ -1922,8 +1928,8 @@ impl IndependentFormattingContext {
) { ) {
let style = self.style(); let style = self.style();
let pbm = style.padding_border_margin(ifc.containing_block); let pbm = style.padding_border_margin(ifc.containing_block);
let margin = pbm.margin.auto_is(Length::zero); let margin = pbm.margin.auto_is(Au::zero);
let pbm_sums = &(&pbm.padding + &pbm.border) + &margin.clone().into(); let pbm_sums = &(&pbm.padding + &pbm.border) + &margin.clone();
let mut child_positioning_context = None; let mut child_positioning_context = None;
// We need to know the inline size of the atomic before deciding whether to do the line break. // We need to know the inline size of the atomic before deciding whether to do the line break.
@ -1950,7 +1956,7 @@ impl IndependentFormattingContext {
content_rect.into(), content_rect.into(),
pbm.padding.into(), pbm.padding.into(),
pbm.border.into(), pbm.border.into(),
margin, margin.into(),
None, /* clearance */ None, /* clearance */
CollapsedBlockMargins::zero(), CollapsedBlockMargins::zero(),
) )
@ -2039,7 +2045,7 @@ impl IndependentFormattingContext {
content_rect.into(), content_rect.into(),
pbm.padding.into(), pbm.padding.into(),
pbm.border.into(), pbm.border.into(),
margin, margin.into(),
None, None,
CollapsedBlockMargins::zero(), CollapsedBlockMargins::zero(),
) )

View file

@ -294,19 +294,19 @@ impl InlineBoxLineItem {
let style = self.style.clone(); let style = self.style.clone();
let mut padding = self.pbm.padding.clone(); let mut padding = self.pbm.padding.clone();
let mut border = self.pbm.border.clone(); let mut border = self.pbm.border.clone();
let mut margin = self.pbm.margin.auto_is(Length::zero); let mut margin = self.pbm.margin.auto_is(Au::zero);
if !self.is_first_fragment { if !self.is_first_fragment {
padding.inline_start = Au::zero(); padding.inline_start = Au::zero();
border.inline_start = Au::zero(); border.inline_start = Au::zero();
margin.inline_start = Length::zero(); margin.inline_start = Au::zero();
} }
if !self.is_last_fragment_of_ib_split { if !self.is_last_fragment_of_ib_split {
padding.inline_end = Au::zero(); padding.inline_end = Au::zero();
border.inline_end = Au::zero(); border.inline_end = Au::zero();
margin.inline_end = Length::zero(); margin.inline_end = Au::zero();
} }
let pbm_sums = &(&padding + &border) + &margin.map(|t| (*t).into()); let pbm_sums = &(&padding + &border) + &margin;
state.inline_position += pbm_sums.inline_start.into(); state.inline_position += pbm_sums.inline_start.into();
let space_above_baseline = self.calculate_space_above_baseline(); let space_above_baseline = self.calculate_space_above_baseline();
@ -342,9 +342,9 @@ impl InlineBoxLineItem {
if !self.is_last_fragment_of_ib_split || !saw_end { if !self.is_last_fragment_of_ib_split || !saw_end {
padding.inline_end = Au::zero(); padding.inline_end = Au::zero();
border.inline_end = Au::zero(); border.inline_end = Au::zero();
margin.inline_end = Length::zero(); margin.inline_end = Au::zero();
} }
let pbm_sums = &(&padding + &border) + &margin.clone().into(); let pbm_sums = &(&padding + &border) + &margin.clone();
// If the inline box didn't have any content at all, don't add a Fragment for it. // If the inline box didn't have any content at all, don't add a Fragment for it.
let box_has_padding_border_or_margin = pbm_sums.inline_sum() > Au::zero(); let box_has_padding_border_or_margin = pbm_sums.inline_sum() > Au::zero();
@ -385,7 +385,7 @@ impl InlineBoxLineItem {
content_rect, content_rect,
padding.into(), padding.into(),
border.into(), border.into(),
margin, margin.into(),
None, /* clearance */ None, /* clearance */
CollapsedBlockMargins::zero(), CollapsedBlockMargins::zero(),
); );

View file

@ -116,8 +116,8 @@ impl BlockLevelBox {
} }
let pbm = style.padding_border_margin(containing_block); let pbm = style.padding_border_margin(containing_block);
let start_margin = pbm.margin.block_start.auto_is(Length::zero); let start_margin = pbm.margin.block_start.auto_is(Au::zero);
collected_margin.adjoin_assign(&CollapsedMargin::new(start_margin)); collected_margin.adjoin_assign(&CollapsedMargin::new(start_margin.into()));
let child_boxes = match self { let child_boxes = match self {
BlockLevelBox::SameFormattingContextBlock { ref contents, .. } => match contents { BlockLevelBox::SameFormattingContextBlock { ref contents, .. } => match contents {
@ -140,11 +140,13 @@ impl BlockLevelBox {
.content_box_size(containing_block, &pbm) .content_box_size(containing_block, &pbm)
.inline .inline
.auto_is(|| { .auto_is(|| {
let margin_inline_start = pbm.margin.inline_start.auto_is(Length::zero); let margin_inline_start = pbm.margin.inline_start.auto_is(Au::zero);
let margin_inline_end = pbm.margin.inline_end.auto_is(Length::zero); let margin_inline_end = pbm.margin.inline_end.auto_is(Au::zero);
Length::from(containing_block.inline_size - pbm.padding_border_sums.inline) - (containing_block.inline_size -
pbm.padding_border_sums.inline -
margin_inline_start - margin_inline_start -
margin_inline_end margin_inline_end)
.into()
}) })
.clamp_between_extremums(min_inline_size, max_inline_size); .clamp_between_extremums(min_inline_size, max_inline_size);
@ -173,8 +175,8 @@ impl BlockLevelBox {
return false; return false;
} }
let end_margin = pbm.margin.block_end.auto_is(Length::zero); let end_margin = pbm.margin.block_end.auto_is(Au::zero);
collected_margin.adjoin_assign(&CollapsedMargin::new(end_margin)); collected_margin.adjoin_assign(&CollapsedMargin::new(end_margin.into()));
true true
} }
@ -933,7 +935,7 @@ impl NonReplacedFormattingContext {
let effective_margin_inline_start; let effective_margin_inline_start;
let (margin_block_start, margin_block_end) = let (margin_block_start, margin_block_end) =
solve_block_margins_for_in_flow_block_level(&pbm); solve_block_margins_for_in_flow_block_level(&pbm);
let collapsed_margin_block_start = CollapsedMargin::new(margin_block_start); let collapsed_margin_block_start = CollapsedMargin::new(margin_block_start.into());
// From https://drafts.csswg.org/css2/#floats: // From https://drafts.csswg.org/css2/#floats:
// "The border box of a table, a block-level replaced element, or an element in // "The border box of a table, a block-level replaced element, or an element in
@ -1111,10 +1113,10 @@ impl NonReplacedFormattingContext {
} }
let margin = LogicalSides { let margin = LogicalSides {
inline_start: margin_inline_start, inline_start: margin_inline_start.into(),
inline_end: margin_inline_end, inline_end: margin_inline_end.into(),
block_start: margin_block_start, block_start: margin_block_start.into(),
block_end: margin_block_end, block_end: margin_block_end.into(),
}; };
// Clearance prevents margin collapse between this block and previous ones, // Clearance prevents margin collapse between this block and previous ones,
@ -1139,7 +1141,7 @@ impl NonReplacedFormattingContext {
clearance.unwrap_or_else(Length::zero).into(), clearance.unwrap_or_else(Length::zero).into(),
inline: pbm.padding.inline_start + inline: pbm.padding.inline_start +
pbm.border.inline_start + pbm.border.inline_start +
effective_margin_inline_start.into(), effective_margin_inline_start,
}, },
size: content_size.into(), size: content_size.into(),
}; };
@ -1191,7 +1193,7 @@ fn layout_in_flow_replaced_block_level(
// sufficient space. They may even make the border box of said element narrower // sufficient space. They may even make the border box of said element narrower
// than defined by section 10.3.3. CSS 2 does not define when a UA may put said // than defined by section 10.3.3. CSS 2 does not define when a UA may put said
// element next to the float or by how much said element may become narrower." // element next to the float or by how much said element may become narrower."
let collapsed_margin_block_start = CollapsedMargin::new(margin_block_start); let collapsed_margin_block_start = CollapsedMargin::new(margin_block_start.into());
let size = &content_size + &pbm.padding_border_sums.clone(); let size = &content_size + &pbm.padding_border_sums.clone();
( (
clearance, clearance,
@ -1217,7 +1219,7 @@ fn layout_in_flow_replaced_block_level(
sequential_layout_state.collapse_margins(); sequential_layout_state.collapse_margins();
sequential_layout_state sequential_layout_state
.advance_block_position(size.block + clearance.unwrap_or_else(Length::zero).into()); .advance_block_position(size.block + clearance.unwrap_or_else(Length::zero).into());
sequential_layout_state.adjoin_assign(&CollapsedMargin::new(margin_block_end)); sequential_layout_state.adjoin_assign(&CollapsedMargin::new(margin_block_end.into()));
} else { } else {
clearance = None; clearance = None;
( (
@ -1231,19 +1233,17 @@ fn layout_in_flow_replaced_block_level(
}; };
let margin = LogicalSides { let margin = LogicalSides {
inline_start: margin_inline_start, inline_start: margin_inline_start.into(),
inline_end: margin_inline_end, inline_end: margin_inline_end.into(),
block_start: margin_block_start, block_start: margin_block_start.into(),
block_end: margin_block_end, block_end: margin_block_end.into(),
}; };
let start_corner = LogicalVec2 { let start_corner = LogicalVec2 {
block: pbm.padding.block_start + block: pbm.padding.block_start +
pbm.border.block_start + pbm.border.block_start +
clearance.unwrap_or_else(Length::zero).into(), clearance.unwrap_or_else(Length::zero).into(),
inline: pbm.padding.inline_start + inline: pbm.padding.inline_start + pbm.border.inline_start + effective_margin_inline_start,
pbm.border.inline_start +
effective_margin_inline_start.into(),
}; };
let content_rect = LogicalRect { let content_rect = LogicalRect {
@ -1306,11 +1306,13 @@ fn solve_containing_block_padding_and_border_for_in_flow_box<'a>(
let inline_size = box_size let inline_size = box_size
.inline .inline
.auto_is(|| { .auto_is(|| {
let margin_inline_start = pbm.margin.inline_start.auto_is(Length::zero); let margin_inline_start = pbm.margin.inline_start.auto_is(Au::zero);
let margin_inline_end = pbm.margin.inline_end.auto_is(Length::zero); let margin_inline_end = pbm.margin.inline_end.auto_is(Au::zero);
Length::from(containing_block.inline_size - pbm.padding_border_sums.inline) - (containing_block.inline_size -
pbm.padding_border_sums.inline -
margin_inline_start - margin_inline_start -
margin_inline_end margin_inline_end)
.into()
}) })
.clamp_between_extremums(min_box_size.inline, max_box_size.inline); .clamp_between_extremums(min_box_size.inline, max_box_size.inline);
@ -1353,22 +1355,22 @@ fn solve_margins(
let block_margins = solve_block_margins_for_in_flow_block_level(pbm); let block_margins = solve_block_margins_for_in_flow_block_level(pbm);
ResolvedMargins { ResolvedMargins {
margin: LogicalSides { margin: LogicalSides {
inline_start: inline_margins.0, inline_start: inline_margins.0.into(),
inline_end: inline_margins.1, inline_end: inline_margins.1.into(),
block_start: block_margins.0, block_start: block_margins.0.into(),
block_end: block_margins.1, block_end: block_margins.1.into(),
}, },
effective_margin_inline_start, effective_margin_inline_start: effective_margin_inline_start.into(),
} }
} }
/// Resolves 'auto' margins of an in-flow block-level box in the block axis. /// Resolves 'auto' margins of an in-flow block-level box in the block axis.
/// <https://drafts.csswg.org/css2/#normal-block> /// <https://drafts.csswg.org/css2/#normal-block>
/// <https://drafts.csswg.org/css2/#block-root-margin> /// <https://drafts.csswg.org/css2/#block-root-margin>
fn solve_block_margins_for_in_flow_block_level(pbm: &PaddingBorderMargin) -> (Length, Length) { fn solve_block_margins_for_in_flow_block_level(pbm: &PaddingBorderMargin) -> (Au, Au) {
( (
pbm.margin.block_start.auto_is(Length::zero), pbm.margin.block_start.auto_is(Au::zero),
pbm.margin.block_end.auto_is(Length::zero), pbm.margin.block_end.auto_is(Au::zero),
) )
} }
@ -1377,18 +1379,18 @@ fn solve_block_margins_for_in_flow_block_level(pbm: &PaddingBorderMargin) -> (Le
/// The provided free space should already take margins into account. In particular, /// The provided free space should already take margins into account. In particular,
/// it should be zero if there is an auto margin. /// it should be zero if there is an auto margin.
/// <https://drafts.csswg.org/css-align/#justify-block> /// <https://drafts.csswg.org/css-align/#justify-block>
fn justify_self_alignment(containing_block: &ContainingBlock, free_space: Length) -> Length { fn justify_self_alignment(containing_block: &ContainingBlock, free_space: Au) -> Au {
let style = containing_block.style; let style = containing_block.style;
debug_assert!(free_space >= Length::zero()); debug_assert!(free_space >= Au::zero());
match style.clone_text_align() { match style.clone_text_align() {
TextAlignKeyword::ServoCenter => free_space / 2., TextAlignKeyword::ServoCenter => free_space / 2,
TextAlignKeyword::ServoLeft if !style.writing_mode.line_left_is_inline_start() => { TextAlignKeyword::ServoLeft if !style.writing_mode.line_left_is_inline_start() => {
free_space free_space
}, },
TextAlignKeyword::ServoRight if style.writing_mode.line_left_is_inline_start() => { TextAlignKeyword::ServoRight if style.writing_mode.line_left_is_inline_start() => {
free_space free_space
}, },
_ => Length::zero(), _ => Au::zero(),
} }
} }
@ -1408,25 +1410,25 @@ fn solve_inline_margins_for_in_flow_block_level(
containing_block: &ContainingBlock, containing_block: &ContainingBlock,
pbm: &PaddingBorderMargin, pbm: &PaddingBorderMargin,
inline_size: Length, inline_size: Length,
) -> ((Length, Length), Length) { ) -> ((Au, Au), Au) {
let free_space = let free_space =
Length::from(containing_block.inline_size - pbm.padding_border_sums.inline) - inline_size; containing_block.inline_size - pbm.padding_border_sums.inline - inline_size.into();
let mut justification = Length::zero(); let mut justification = Au::zero();
let inline_margins = match (pbm.margin.inline_start, pbm.margin.inline_end) { let inline_margins = match (pbm.margin.inline_start, pbm.margin.inline_end) {
(LengthOrAuto::Auto, LengthOrAuto::Auto) => { (AuOrAuto::Auto, AuOrAuto::Auto) => {
let start = Length::zero().max(free_space / 2.); let start = Au::zero().max(free_space / 2);
(start, free_space - start) (start, free_space - start)
}, },
(LengthOrAuto::Auto, LengthOrAuto::LengthPercentage(end)) => { (AuOrAuto::Auto, AuOrAuto::LengthPercentage(end)) => {
(Length::zero().max(free_space - end), end) (Au::zero().max(free_space - end), end)
}, },
(LengthOrAuto::LengthPercentage(start), LengthOrAuto::Auto) => (start, free_space - start), (AuOrAuto::LengthPercentage(start), AuOrAuto::Auto) => (start, free_space - start),
(LengthOrAuto::LengthPercentage(start), LengthOrAuto::LengthPercentage(end)) => { (AuOrAuto::LengthPercentage(start), AuOrAuto::LengthPercentage(end)) => {
// In the cases above, the free space is zero after taking 'auto' margins into account. // In the cases above, the free space is zero after taking 'auto' margins into account.
// But here we may still have some free space to perform 'justify-self' alignment. // But here we may still have some free space to perform 'justify-self' alignment.
// This aligns the margin box within the containing block, or in other words, // This aligns the margin box within the containing block, or in other words,
// aligns the border box within the margin-shrunken containing block. // aligns the border box within the margin-shrunken containing block.
let free_space = Length::zero().max(free_space - start - end); let free_space = Au::zero().max(free_space - start - end);
justification = justify_self_alignment(containing_block, free_space); justification = justify_self_alignment(containing_block, free_space);
(start, end) (start, end)
}, },
@ -1450,25 +1452,21 @@ fn solve_inline_margins_avoiding_floats(
pbm: &PaddingBorderMargin, pbm: &PaddingBorderMargin,
inline_size: Length, inline_size: Length,
placement_rect: LogicalRect<Length>, placement_rect: LogicalRect<Length>,
) -> ((Length, Length), Length) { ) -> ((Au, Au), Au) {
let free_space = placement_rect.size.inline - inline_size; let free_space = Au::from(placement_rect.size.inline - inline_size);
debug_assert!(free_space >= Length::zero()); debug_assert!(free_space >= Au::zero());
let cb_info = &sequential_layout_state.floats.containing_block_info; let cb_info = &sequential_layout_state.floats.containing_block_info;
let start_adjustment = placement_rect.start_corner.inline - cb_info.inline_start.into(); let start_adjustment = Au::from(placement_rect.start_corner.inline) - cb_info.inline_start;
let end_adjustment = Length::from(cb_info.inline_end) - placement_rect.max_inline_position(); let end_adjustment = cb_info.inline_end - placement_rect.max_inline_position().into();
let mut justification = Length::zero(); let mut justification = Au::zero();
let inline_margins = match (pbm.margin.inline_start, pbm.margin.inline_end) { let inline_margins = match (pbm.margin.inline_start, pbm.margin.inline_end) {
(LengthOrAuto::Auto, LengthOrAuto::Auto) => { (AuOrAuto::Auto, AuOrAuto::Auto) => {
let half = free_space / 2.; let half = free_space / 2;
(start_adjustment + half, end_adjustment + free_space - half) (start_adjustment + half, end_adjustment + free_space - half)
}, },
(LengthOrAuto::Auto, LengthOrAuto::LengthPercentage(end)) => { (AuOrAuto::Auto, AuOrAuto::LengthPercentage(end)) => (start_adjustment + free_space, end),
(start_adjustment + free_space, end) (AuOrAuto::LengthPercentage(start), AuOrAuto::Auto) => (start, end_adjustment + free_space),
}, (AuOrAuto::LengthPercentage(start), AuOrAuto::LengthPercentage(end)) => {
(LengthOrAuto::LengthPercentage(start), LengthOrAuto::Auto) => {
(start, end_adjustment + free_space)
},
(LengthOrAuto::LengthPercentage(start), LengthOrAuto::LengthPercentage(end)) => {
// The spec says 'justify-self' aligns the margin box within the float-shrunken // The spec says 'justify-self' aligns the margin box within the float-shrunken
// containing block. That's wrong (https://github.com/w3c/csswg-drafts/issues/9963), // containing block. That's wrong (https://github.com/w3c/csswg-drafts/issues/9963),
// and Blink and WebKit are broken anyways. So we match Gecko instead: this aligns // and Blink and WebKit are broken anyways. So we match Gecko instead: this aligns
@ -1494,7 +1492,7 @@ fn solve_clearance_and_inline_margins_avoiding_floats(
pbm: &PaddingBorderMargin, pbm: &PaddingBorderMargin,
size: LogicalVec2<Length>, size: LogicalVec2<Length>,
style: &Arc<ComputedValues>, style: &Arc<ComputedValues>,
) -> (Option<Length>, (Length, Length), Length) { ) -> (Option<Length>, (Au, Au), Au) {
let (clearance, placement_rect) = sequential_layout_state let (clearance, placement_rect) = sequential_layout_state
.calculate_clearance_and_inline_adjustment( .calculate_clearance_and_inline_adjustment(
style.get_box().clear, style.get_box().clear,

View file

@ -126,8 +126,8 @@ impl<T: Zero> LogicalVec2<T> {
} }
} }
impl LogicalVec2<LengthOrAuto> { impl<T: Clone> LogicalVec2<AutoOr<T>> {
pub fn auto_is(&self, f: impl Fn() -> Length) -> LogicalVec2<Length> { pub fn auto_is(&self, f: impl Fn() -> T) -> LogicalVec2<T> {
self.map(|t| t.auto_is(&f)) self.map(|t| t.auto_is(&f))
} }
} }
@ -335,8 +335,8 @@ impl LogicalSides<LengthPercentageOrAuto<'_>> {
} }
} }
impl LogicalSides<LengthOrAuto> { impl<T: Clone> LogicalSides<AutoOr<T>> {
pub fn auto_is(&self, f: impl Fn() -> Length) -> LogicalSides<Length> { pub fn auto_is(&self, f: impl Fn() -> T) -> LogicalSides<T> {
self.map(|s| s.auto_is(&f)) self.map(|s| s.auto_is(&f))
} }
} }

View file

@ -504,8 +504,8 @@ impl HoistedAbsolutelyPositionedBox {
let inline_axis_solver = AbsoluteAxisSolver { let inline_axis_solver = AbsoluteAxisSolver {
containing_size: cbis, containing_size: cbis,
padding_border_sum: pbm.padding_border_sums.inline, padding_border_sum: pbm.padding_border_sums.inline,
computed_margin_start: pbm.margin.inline_start.map(|t| t.into()), computed_margin_start: pbm.margin.inline_start,
computed_margin_end: pbm.margin.inline_end.map(|t| t.into()), computed_margin_end: pbm.margin.inline_end,
avoid_negative_margin_start: true, avoid_negative_margin_start: true,
box_offsets: &shared_fragment.box_offsets.inline, box_offsets: &shared_fragment.box_offsets.inline,
}; };
@ -513,8 +513,8 @@ impl HoistedAbsolutelyPositionedBox {
let block_axis_solver = AbsoluteAxisSolver { let block_axis_solver = AbsoluteAxisSolver {
containing_size: cbbs, containing_size: cbbs,
padding_border_sum: pbm.padding_border_sums.block, padding_border_sum: pbm.padding_border_sums.block,
computed_margin_start: pbm.margin.block_start.map(|t| t.into()), computed_margin_start: pbm.margin.block_start,
computed_margin_end: pbm.margin.block_end.map(|t| t.into()), computed_margin_end: pbm.margin.block_end,
avoid_negative_margin_start: false, avoid_negative_margin_start: false,
box_offsets: &shared_fragment.box_offsets.block, box_offsets: &shared_fragment.box_offsets.block,
}; };

View file

@ -22,7 +22,8 @@ use webrender_api as wr;
use crate::dom_traversal::Contents; use crate::dom_traversal::Contents;
use crate::geom::{ use crate::geom::{
LengthOrAuto, LengthPercentageOrAuto, LogicalSides, LogicalVec2, PhysicalSides, PhysicalSize, AuOrAuto, LengthOrAuto, LengthPercentageOrAuto, LogicalSides, LogicalVec2, PhysicalSides,
PhysicalSize,
}; };
use crate::ContainingBlock; use crate::ContainingBlock;
@ -118,7 +119,7 @@ impl DisplayLayoutInternal {
pub(crate) struct PaddingBorderMargin { pub(crate) struct PaddingBorderMargin {
pub padding: LogicalSides<Au>, pub padding: LogicalSides<Au>,
pub border: LogicalSides<Au>, pub border: LogicalSides<Au>,
pub margin: LogicalSides<LengthOrAuto>, pub margin: LogicalSides<AuOrAuto>,
/// Pre-computed sums in each axis /// Pre-computed sums in each axis
pub padding_border_sums: LogicalVec2<Au>, pub padding_border_sums: LogicalVec2<Au>,
@ -351,6 +352,9 @@ impl ComputedValuesExt for ComputedValues {
.padding(containing_block.style.writing_mode) .padding(containing_block.style.writing_mode)
.percentages_relative_to(cbis.into()); .percentages_relative_to(cbis.into());
let border = self.border_width(containing_block.style.writing_mode); let border = self.border_width(containing_block.style.writing_mode);
let margin = self
.margin(containing_block.style.writing_mode)
.percentages_relative_to(cbis.into());
PaddingBorderMargin { PaddingBorderMargin {
padding_border_sums: LogicalVec2 { padding_border_sums: LogicalVec2 {
inline: (padding.inline_sum() + border.inline_sum()).into(), inline: (padding.inline_sum() + border.inline_sum()).into(),
@ -358,9 +362,7 @@ impl ComputedValuesExt for ComputedValues {
}, },
padding: padding.into(), padding: padding.into(),
border: border.into(), border: border.into(),
margin: self margin: margin.map(|t| t.map(|m| m.into())),
.margin(containing_block.style.writing_mode)
.percentages_relative_to(cbis.into()),
} }
} }