Skip to content

Commit

Permalink
Fix issues with has_content and also ending pbm
Browse files Browse the repository at this point in the history
  • Loading branch information
mrobinson committed Oct 26, 2023
1 parent 5708473 commit 719fdb3
Showing 1 changed file with 51 additions and 31 deletions.
82 changes: 51 additions & 31 deletions components/layout_2020/flow/inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -365,12 +365,15 @@ impl<'a, 'b> InlineFormattingContextState<'a, 'b> {
base_fragment_info: BaseFragmentInfo,
parent_style: &Arc<ComputedValues>,
font_metrics: FontMetrics,
font_key: FontInstanceKey
font_key: FontInstanceKey,
) {
let inline_advance = Length::from(glyph_store.total_advance());

let is_non_preserved_whitespace =
glyph_store.is_whitespace() && !parent_style.get_inherited_text().white_space.preserve_spaces();
let is_non_preserved_whitespace = glyph_store.is_whitespace() &&
!parent_style
.get_inherited_text()
.white_space
.preserve_spaces();
if is_non_preserved_whitespace {
self.current_line_segment.trailing_whitespace_size = inline_advance;
}
Expand All @@ -380,32 +383,41 @@ impl<'a, 'b> InlineFormattingContextState<'a, 'b> {
debug_assert!(font_key == text_run.font_key);
text_run.text.push(glyph_store);
self.current_line_segment.size.inline += inline_advance;

if !is_non_preserved_whitespace {
self.current_line_segment.has_content = true;
}
return;
}
},
_ => {},
}
self.push_content_line_item_to_unbreakable_segment(
inline_advance,
LineItem::TextRun(TextRunLineItem {
text: vec!(glyph_store),
text: vec![glyph_store],
base_fragment_info: base_fragment_info.into(),
parent_style: parent_style.clone(),
font_metrics,
font_key,
text_decoration_line: self.current_inline_container_state().text_decoration_line,
}),
!is_non_preserved_whitespace,
);
}

fn push_content_line_item_to_unbreakable_segment(
&mut self,
inline_size: Length,
line_item: LineItem,
counts_as_content: bool,
) {
// This item is content, which means that we need to update the size of the
// current segment and also propagate the whitespace setting to the current
// nesting level.
self.current_line_segment.has_content = true;
if counts_as_content {
self.current_line_segment.has_content = true;
}

self.current_line_segment.size.inline += inline_size;
self.current_line_segment
.size
Expand Down Expand Up @@ -439,7 +451,8 @@ impl<'a, 'b> InlineFormattingContextState<'a, 'b> {
}

let potential_line_size = LogicalVec2 {
inline: self.current_line.inline_position + self.current_line_segment.size.inline - self.current_line_segment.trailing_whitespace_size,
inline: self.current_line.inline_position + self.current_line_segment.size.inline -
self.current_line_segment.trailing_whitespace_size,
block: self
.current_line_max_block_size()
.max(self.current_line_segment.size.block),
Expand All @@ -452,9 +465,7 @@ impl<'a, 'b> InlineFormattingContextState<'a, 'b> {
}

fn commit_current_segment_to_line(&mut self) {
println!(" > Committing current segment");
if !self.current_line.has_content {
println!(" > trim whitespace");
self.current_line_segment.trim_leading_whitespace();
}

Expand Down Expand Up @@ -482,17 +493,15 @@ impl<'a, 'b> InlineFormattingContextState<'a, 'b> {
Some(placement_among_floats) => placement_among_floats.size.inline,
None => self.containing_block.inline_size,
} - line_inline_size_without_trailing_whitespace;
println!("available inline size: {available_inline_size:?} {:?} - {line_inline_size_without_trailing_whitespace:?}", self.containing_block.inline_size);

// If this float doesn't fit on the current line or a previous float didn't fit on
// the current line, we need to place it starting at the next line BUT still as
// children of this line's hierarchy of inline boxes (for the purposes of properly
// parenting in their stacking contexts). Once all the line content is gathered we
// will place them later.
let has_content = self.current_line.has_content || self.current_line_segment.has_content;
let has_content =
self.current_line.has_content || self.current_line_segment.has_content;
let fits_on_line = !has_content || inline_size <= available_inline_size;
println!("has content: {} {}", self.current_line.has_content, self.current_line_segment.has_content);
println!("fits on line: {fits_on_line} {inline_size:?} <= {available_inline_size:?}");
let needs_placement_later =
self.current_line.has_floats_waiting_to_be_placed || !fits_on_line;

Expand All @@ -511,10 +520,8 @@ impl<'a, 'b> InlineFormattingContextState<'a, 'b> {
inline: line_inline_size_without_trailing_whitespace,
block: self.current_line.max_block_size,
});
println!(" * old placement: {:?}", self.current_line.placement_among_floats);
self.current_line
.replace_placement_among_floats(new_placement);
println!(" * new placement: {:?}", self.current_line.placement_among_floats);
}

if self.current_line.line_items.is_empty() {
Expand All @@ -528,11 +535,26 @@ impl<'a, 'b> InlineFormattingContextState<'a, 'b> {
assert!(!will_break);
}

self.current_line.line_items.append(&mut segment_items);
let to_skip = match (
self.current_line.line_items.last_mut(),
segment_items.first_mut(),
) {
(
Some(LineItem::TextRun(last_line_item)),
Some(LineItem::TextRun(first_segment_item)),
) => {
last_line_item.text.append(&mut first_segment_item.text);
1
},
_ => 0,
};

self.current_line
.line_items
.extend(segment_items.into_iter().skip(to_skip));

self.current_line.has_content |= self.current_line_segment.has_content;
self.current_line_segment.has_content = false;
println!(" > line has content {}", self.current_line.has_content);

self.current_line_segment.trailing_whitespace_size = Length::zero();
self.current_line_segment.size = LogicalVec2::zero();
Expand Down Expand Up @@ -1210,10 +1232,8 @@ impl InlineFormattingContext {
}

ifc.process_soft_line_wrap_opportunity();
println!("----------------- committing segment at end of ifc");
ifc.commit_current_segment_to_line();
ifc.finish_current_line_and_reset();
println!(">>>>>>>>>>>>>>>>>.");

let mut collapsible_margins_in_children = CollapsedBlockMargins::zero();
let content_block_size = ifc.current_line.start_position.block;
Expand Down Expand Up @@ -1427,6 +1447,7 @@ impl IndependentFormattingContext {
size,
positioning_context: child_positioning_context,
}),
true,
);

if let Some(linebreaker) = ifc.linebreaker.as_mut() {
Expand Down Expand Up @@ -1557,10 +1578,10 @@ impl TextRun {
ifc.process_hard_line_wrap();
}

{
let text = &self.text[run.range.begin().to_usize()..run.range.end().to_usize()];
println!("Processing: {text:?}");
}
//{
// let text = &self.text[run.range.begin().to_usize()..run.range.end().to_usize()];
// println!("Processing: {text:?}");
//}

// If this whitespace forces a line break, queue up a hard line break the next time we
// see any content. We don't line break immediately, because we'd like to finish processing
Expand All @@ -1574,9 +1595,7 @@ impl TextRun {
// need to put it on a new line *before* actually triggering the hard line break.
//
// `process_soft_line_wrap_opportunity` handles both of these cases.
println!("------- hard line break soft wrap");
ifc.process_soft_line_wrap_opportunity();
println!("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<");

// We need to ensure that the appropriate space for a linebox is created even if there
// was no other content on this line. We mark the line as having content (needing a
Expand Down Expand Up @@ -1943,13 +1962,14 @@ struct InlineBoxLineItem {
pbm: PaddingBorderMargin,
block_size: Length,

// Whether this is the first fragment for this inline box. This means that it's the
// first potentially split box of a block-in-inline-split (or only if there's no
// split) and also the first appearance of this fragment on any line.
/// Whether this is the first fragment for this inline box. This means that it's the
/// first potentially split box of a block-in-inline-split (or only if there's no
/// split) and also the first appearance of this fragment on any line.
is_first_fragment: bool,

// Whether this is the last fragment for this inline box. This means that it's the
// last potentially split box of a block-in-inline-split (or only if there's no split).
/// Whether this is the last fragment for this inline box. This means that it's the
/// last potentially split box of a block-in-inline-split (or the only fragment if
/// there's no split).
is_last_fragment_of_ib_split: bool,
}

Expand Down Expand Up @@ -2000,7 +2020,7 @@ impl InlineBoxLineItem {
// Only add ending padding, border, margin if this is the last fragment of a
// potential block-in-inline split and this line included the actual end of this
// fragment (it doesn't continue on the next line).
if self.is_last_fragment_of_ib_split && saw_end {
if !self.is_last_fragment_of_ib_split || !saw_end {
padding.inline_end = Length::zero();
border.inline_end = Length::zero();
margin.inline_end = Length::zero();
Expand Down

0 comments on commit 719fdb3

Please sign in to comment.