Skip to content

Commit cc54fbc

Browse files
authored
Auto merge of servo#29836 - stshine:newline, r=mrobinson
layout_2020: Do linebreak for atomic inline-level elements <!-- Please describe your changes on the following line: --> --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `___` with appropriate data: --> - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors - [x] These changes fix servo#29591 (GitHub issue number if applicable) <!-- Either: --> - [x] There are tests for these changes OR <!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.--> <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->
2 parents 9b79547 + 65445ad commit cc54fbc

27 files changed

+75
-91
lines changed

components/layout_2020/flow/inline.rs

Lines changed: 73 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use app_units::Au;
2323
use atomic_refcell::AtomicRef;
2424
use gfx::text::text_run::GlyphRun;
2525
use servo_arc::Arc;
26+
use style::computed_values::white_space::T as WhiteSpace;
2627
use style::logical_geometry::WritingMode;
2728
use style::properties::ComputedValues;
2829
use style::values::computed::{Length, LengthPercentage, Percentage};
@@ -74,6 +75,7 @@ struct InlineNestingLevelState<'box_tree> {
7475
inline_start: Length,
7576
max_block_size_of_fragments_so_far: Length,
7677
positioning_context: Option<PositioningContext>,
78+
white_space: WhiteSpace,
7779
/// Indicates whether this nesting level have text decorations in effect.
7880
/// From https://drafts.csswg.org/css-text-decor/#line-decoration
7981
// "When specified on or propagated to a block container that establishes
@@ -125,6 +127,34 @@ impl<'box_tree, 'a, 'b> InlineFormattingContextState<'box_tree, 'a, 'b> {
125127

126128
self.positioning_context.push(hoisted_box);
127129
}
130+
131+
/// Finish layout of all the partial inline boxes in the current line,
132+
/// finish current line and start a new one.
133+
fn finish_line_and_reset(&mut self, layout_context: &LayoutContext) {
134+
self.current_nesting_level.inline_start = Length::zero();
135+
let mut nesting_level = &mut self.current_nesting_level;
136+
for partial in self.partial_inline_boxes_stack.iter_mut().rev() {
137+
partial.finish_layout(
138+
layout_context,
139+
nesting_level,
140+
&mut self.inline_position,
141+
true,
142+
);
143+
partial.start_corner.inline = Length::zero();
144+
partial.padding.inline_start = Length::zero();
145+
partial.border.inline_start = Length::zero();
146+
partial.margin.inline_start = Length::zero();
147+
partial.parent_nesting_level.inline_start = Length::zero();
148+
nesting_level = &mut partial.parent_nesting_level;
149+
}
150+
self.lines.finish_line(
151+
nesting_level,
152+
self.containing_block,
153+
self.sequential_layout_state.as_mut().map(|c| &mut **c),
154+
self.inline_position,
155+
);
156+
self.inline_position = Length::zero();
157+
}
128158
}
129159

130160
struct Lines {
@@ -297,6 +327,7 @@ impl InlineFormattingContext {
297327
inline_start: Length::zero(),
298328
max_block_size_of_fragments_so_far: Length::zero(),
299329
positioning_context: None,
330+
white_space: containing_block.style.clone_inherited_text().white_space,
300331
text_decoration_line: self.text_decoration_line,
301332
},
302333
sequential_layout_state,
@@ -503,6 +534,7 @@ impl InlineBox {
503534
start_corner += &relative_adjustement(&style, ifc.containing_block)
504535
}
505536
let positioning_context = PositioningContext::new_for_style(&style);
537+
let white_space = style.clone_inherited_text().white_space;
506538
let text_decoration_line =
507539
ifc.current_nesting_level.text_decoration_line | style.clone_text_decoration_line();
508540
PartialInlineBoxFragment {
@@ -523,6 +555,7 @@ impl InlineBox {
523555
inline_start: ifc.inline_position,
524556
max_block_size_of_fragments_so_far: Length::zero(),
525557
positioning_context,
558+
white_space,
526559
text_decoration_line: text_decoration_line,
527560
},
528561
),
@@ -590,16 +623,12 @@ fn layout_atomic(
590623
let pbm = style.padding_border_margin(&ifc.containing_block);
591624
let margin = pbm.margin.auto_is(Length::zero);
592625
let pbm_sums = &(&pbm.padding + &pbm.border) + &margin;
593-
ifc.inline_position += pbm_sums.inline_start;
594-
let mut start_corner = Vec2 {
595-
block: pbm_sums.block_start,
596-
inline: ifc.inline_position - ifc.current_nesting_level.inline_start,
597-
};
598-
if style.clone_position().is_relative() {
599-
start_corner += &relative_adjustement(&style, ifc.containing_block)
600-
}
626+
let position = style.clone_position();
601627

602-
let fragment = match atomic {
628+
let mut child_positioning_context = None;
629+
630+
// We need to know the inline size of the atomic before deciding whether to do the line break.
631+
let mut fragment = match atomic {
603632
IndependentFormattingContext::Replaced(replaced) => {
604633
let size = replaced.contents.used_size_as_if_inline_element(
605634
ifc.containing_block,
@@ -610,7 +639,10 @@ fn layout_atomic(
610639
let fragments = replaced
611640
.contents
612641
.make_fragments(&replaced.style, size.clone());
613-
let content_rect = Rect { start_corner, size };
642+
let content_rect = Rect {
643+
start_corner: Vec2::zero(),
644+
size,
645+
};
614646
BoxFragment::new(
615647
replaced.base_fragment_info,
616648
replaced.style.clone(),
@@ -663,16 +695,14 @@ fn layout_atomic(
663695
let collects_for_nearest_positioned_ancestor = ifc
664696
.positioning_context
665697
.collects_for_nearest_positioned_ancestor();
666-
let mut child_positioning_context =
667-
PositioningContext::new_for_subtree(collects_for_nearest_positioned_ancestor);
698+
child_positioning_context = Some(PositioningContext::new_for_subtree(
699+
collects_for_nearest_positioned_ancestor,
700+
));
668701
let independent_layout = non_replaced.layout(
669702
layout_context,
670-
&mut child_positioning_context,
703+
child_positioning_context.as_mut().unwrap(),
671704
&containing_block_for_children,
672705
);
673-
child_positioning_context
674-
.adjust_static_position_of_hoisted_fragments_with_offset(&start_corner);
675-
ifc.positioning_context.append(child_positioning_context);
676706

677707
// https://drafts.csswg.org/css2/visudet.html#block-root-margin
678708
let tentative_block_size = box_size
@@ -686,7 +716,7 @@ fn layout_atomic(
686716
.clamp_between_extremums(min_box_size.block, max_box_size.block);
687717

688718
let content_rect = Rect {
689-
start_corner,
719+
start_corner: Vec2::zero(),
690720
size: Vec2 {
691721
block: block_size,
692722
inline: inline_size,
@@ -707,6 +737,31 @@ fn layout_atomic(
707737
},
708738
};
709739

740+
if fragment.content_rect.size.inline + pbm_sums.inline_sum() >
741+
ifc.containing_block.inline_size - ifc.inline_position &&
742+
ifc.current_nesting_level.white_space.allow_wrap() &&
743+
ifc.current_nesting_level.fragments_so_far.len() != 0
744+
{
745+
ifc.finish_line_and_reset(layout_context);
746+
}
747+
748+
ifc.inline_position += pbm_sums.inline_start;
749+
let mut start_corner = Vec2 {
750+
block: pbm_sums.block_start,
751+
inline: ifc.inline_position - ifc.current_nesting_level.inline_start,
752+
};
753+
if position.is_relative() {
754+
start_corner += &relative_adjustement(atomic.style(), ifc.containing_block)
755+
}
756+
757+
if let Some(mut child_positioning_context) = child_positioning_context.take() {
758+
child_positioning_context
759+
.adjust_static_position_of_hoisted_fragments_with_offset(&start_corner);
760+
ifc.positioning_context.append(child_positioning_context);
761+
}
762+
763+
fragment.content_rect.start_corner = start_corner;
764+
710765
ifc.inline_position += pbm_sums.inline_end + fragment.content_rect.size.inline;
711766
ifc.current_nesting_level
712767
.max_block_size_of_fragments_so_far
@@ -888,30 +943,7 @@ impl TextRun {
888943
if runs.as_slice().is_empty() && !force_line_break {
889944
break;
890945
} else {
891-
// New line
892-
ifc.current_nesting_level.inline_start = Length::zero();
893-
let mut nesting_level = &mut ifc.current_nesting_level;
894-
for partial in ifc.partial_inline_boxes_stack.iter_mut().rev() {
895-
partial.finish_layout(
896-
layout_context,
897-
nesting_level,
898-
&mut ifc.inline_position,
899-
true,
900-
);
901-
partial.start_corner.inline = Length::zero();
902-
partial.padding.inline_start = Length::zero();
903-
partial.border.inline_start = Length::zero();
904-
partial.margin.inline_start = Length::zero();
905-
partial.parent_nesting_level.inline_start = Length::zero();
906-
nesting_level = &mut partial.parent_nesting_level;
907-
}
908-
ifc.lines.finish_line(
909-
nesting_level,
910-
ifc.containing_block,
911-
ifc.sequential_layout_state.as_mut().map(|c| &mut **c),
912-
ifc.inline_position,
913-
);
914-
ifc.inline_position = Length::zero();
946+
ifc.finish_line_and_reset(layout_context);
915947
}
916948
}
917949
}

tests/wpt/meta/css/CSS2/floats-clear/floats-026.xht.ini

Lines changed: 0 additions & 2 deletions
This file was deleted.

tests/wpt/meta/css/CSS2/floats-clear/floats-027.xht.ini

Lines changed: 0 additions & 2 deletions
This file was deleted.

tests/wpt/meta/css/CSS2/margin-padding-clear/margin-collapse-014.xht.ini

Lines changed: 0 additions & 2 deletions
This file was deleted.

tests/wpt/meta/css/CSS2/positioning/absolute-non-replaced-height-003.xht.ini

Lines changed: 0 additions & 2 deletions
This file was deleted.

tests/wpt/meta/css/CSS2/positioning/absolute-non-replaced-height-004.xht.ini

Lines changed: 0 additions & 2 deletions
This file was deleted.

tests/wpt/meta/css/CSS2/positioning/absolute-non-replaced-height-005.xht.ini

Lines changed: 0 additions & 2 deletions
This file was deleted.

tests/wpt/meta/css/CSS2/positioning/absolute-non-replaced-height-006.xht.ini

Lines changed: 0 additions & 2 deletions
This file was deleted.

tests/wpt/meta/css/CSS2/positioning/absolute-non-replaced-height-010.xht.ini

Lines changed: 0 additions & 2 deletions
This file was deleted.

tests/wpt/meta/css/CSS2/positioning/absolute-non-replaced-height-011.xht.ini

Lines changed: 0 additions & 2 deletions
This file was deleted.

0 commit comments

Comments
 (0)