diff options
Diffstat (limited to 'chromium/third_party/blink/renderer/core/layout/line/inline_flow_box.cc')
-rw-r--r-- | chromium/third_party/blink/renderer/core/layout/line/inline_flow_box.cc | 103 |
1 files changed, 63 insertions, 40 deletions
diff --git a/chromium/third_party/blink/renderer/core/layout/line/inline_flow_box.cc b/chromium/third_party/blink/renderer/core/layout/line/inline_flow_box.cc index 6de638ad9a3..16a18e75153 100644 --- a/chromium/third_party/blink/renderer/core/layout/line/inline_flow_box.cc +++ b/chromium/third_party/blink/renderer/core/layout/line/inline_flow_box.cc @@ -168,7 +168,7 @@ void InlineFlowBox::AddToLine(InlineBox* child) { should_clear_descendants_have_same_line_height_and_baseline = true; } else { if (child->GetLineLayoutItem().IsBR()) { - // FIXME: This is dumb. We only turn off because current layout test + // FIXME: This is dumb. We only turn off because current web test // results expect the <br> to be 0-height on the baseline. // Other than making a zillion tests have to regenerate results, there's // no reason to ditch the optimization here. @@ -202,7 +202,8 @@ void InlineFlowBox::AddToLine(InlineBox* child) { child->ClearKnownToHaveNoOverflow(); } else if (child->GetLineLayoutItem().IsAtomicInlineLevel()) { LineLayoutBox box = LineLayoutBox(child->GetLineLayoutItem()); - if (box.HasOverflowModel() || box.HasSelfPaintingLayer()) + if (box.HasLayoutOverflow() || box.HasVisualOverflow() || + box.HasSelfPaintingLayer()) child->ClearKnownToHaveNoOverflow(); } else if (!child->GetLineLayoutItem().IsBR() && (child->GetLineLayoutItem() @@ -299,11 +300,12 @@ void InlineFlowBox::Move(const LayoutSize& delta) { continue; child->Move(delta); } - if (overflow_) { - // FIXME: Rounding error here since overflow was pixel snapped, but nobody - // other than list markers passes non-integral values here. - overflow_->Move(delta.Width(), delta.Height()); - } + // FIXME: Rounding error here since overflow was pixel snapped, but nobody + // other than list markers passes non-integral values here. + if (LayoutOverflowIsSet()) + overflow_->layout_overflow->Move(delta.Width(), delta.Height()); + if (VisualOverflowIsSet()) + overflow_->visual_overflow->Move(delta.Width(), delta.Height()); } LineBoxList* InlineFlowBox::LineBoxes() const { @@ -918,15 +920,18 @@ void InlineFlowBox::PlaceBoxesInBlockDirection( } } -void InlineFlowBox::OverrideVisualOverflowFromLogicalRect( +bool InlineFlowBox::OverrideVisualOverflowFromLogicalRect( const LayoutRect& logical_visual_overflow, LayoutUnit line_top, LayoutUnit line_bottom) { // If we are setting an overflow, then we can't pretend not to have an // overflow. ClearKnownToHaveNoOverflow(); + LayoutRect old_visual_overflow_rect = + VisualOverflowRect(line_top, line_bottom); SetVisualOverflowFromLogicalRect(logical_visual_overflow, line_top, line_bottom); + return VisualOverflowRect(line_top, line_bottom) != old_visual_overflow_rect; } void InlineFlowBox::OverrideLayoutOverflowFromLogicalRect( @@ -1121,24 +1126,11 @@ inline void InlineFlowBox::AddTextBoxVisualOverflow( text_box->SetLogicalOverflowRect(logical_visual_overflow); } -inline void InlineFlowBox::AddReplacedChildOverflow( +inline void InlineFlowBox::AddReplacedChildLayoutOverflow( const InlineBox* inline_box, - LayoutRect& logical_layout_overflow, - LayoutRect& logical_visual_overflow) { + LayoutRect& logical_layout_overflow) { LineLayoutBox box = LineLayoutBox(inline_box->GetLineLayoutItem()); - // Visual overflow only propagates if the box doesn't have a self-painting - // layer. This rectangle does not include transforms or relative positioning - // (since those objects always have self-painting layers), but it does need to - // be adjusted for writing-mode differences. - if (!box.HasSelfPaintingLayer()) { - LayoutRect child_logical_visual_overflow = - box.LogicalVisualOverflowRectForPropagation(); - child_logical_visual_overflow.Move(inline_box->LogicalLeft(), - inline_box->LogicalTop()); - logical_visual_overflow.Unite(child_logical_visual_overflow); - } - // Layout overflow internal to the child box only propagates if the child box // doesn't have overflow clip set. Otherwise the child border box propagates // as layout overflow. This rectangle must include transforms and relative @@ -1150,6 +1142,38 @@ inline void InlineFlowBox::AddReplacedChildOverflow( logical_layout_overflow.Unite(child_logical_layout_overflow); } +void InlineFlowBox::AddReplacedChildrenVisualOverflow(LayoutUnit line_top, + LayoutUnit line_bottom) { + LayoutRect logical_visual_overflow = + VisualOverflowRect(line_top, line_bottom); + bool visual_overflow_may_have_changed = false; + for (InlineBox* curr = FirstChild(); curr; curr = curr->NextOnLine()) { + const LineLayoutItem& item = curr->GetLineLayoutItem(); + if (item.IsOutOfFlowPositioned() || item.IsText() || item.IsLayoutInline()) + continue; + + LineLayoutBox box = LineLayoutBox(curr->GetLineLayoutItem()); + + // Visual overflow only propagates if the box doesn't have a self-painting + // layer. This rectangle does not include transforms or relative positioning + // (since those objects always have self-painting layers), but it does need + // to be adjusted for writing-mode differences. + if (!box.HasSelfPaintingLayer()) { + LayoutRect child_logical_visual_overflow = + box.LogicalVisualOverflowRectForPropagation(); + child_logical_visual_overflow.Move(curr->LogicalLeft(), + curr->LogicalTop()); + logical_visual_overflow.Unite(child_logical_visual_overflow); + ClearKnownToHaveNoOverflow(); + visual_overflow_may_have_changed = true; + } + } + if (visual_overflow_may_have_changed) { + SetVisualOverflowFromLogicalRect(logical_visual_overflow, line_top, + line_bottom); + } +} + static void ComputeGlyphOverflow( InlineTextBox* text, const LineLayoutText& layout_text, @@ -1187,12 +1211,11 @@ void InlineFlowBox::ComputeOverflow( GlyphOverflowAndFallbackFontsMap& text_box_data_map) { // If we know we have no overflow, we can just bail. if (KnownToHaveNoOverflow()) { - DCHECK(!overflow_); + DCHECK(!LayoutOverflowIsSet() && !VisualOverflowIsSet()); return; } - if (overflow_) - overflow_.reset(); + overflow_.reset(); // Visual overflow just includes overflow for stuff we need to issues paint // invalidations for ourselves. Self-painting layers are ignored. @@ -1250,8 +1273,7 @@ void InlineFlowBox::ComputeOverflow( logical_layout_overflow = LogicalFrameRectIncludingLineHeight(line_top, line_bottom); } - AddReplacedChildOverflow(curr, logical_layout_overflow, - logical_visual_overflow); + AddReplacedChildLayoutOverflow(curr, logical_layout_overflow); } } @@ -1267,10 +1289,13 @@ void InlineFlowBox::SetLayoutOverflow(const LayoutRect& rect, if (frame_box.Contains(rect) || rect.IsEmpty()) return; - if (!overflow_) - overflow_ = std::make_unique<SimpleOverflowModel>(frame_box, frame_box); + if (!LayoutOverflowIsSet()) { + if (!overflow_) + overflow_ = std::make_unique<SimpleOverflowModel>(); + overflow_->layout_overflow.emplace(frame_box); + } - overflow_->SetLayoutOverflow(rect); + overflow_->layout_overflow->SetLayoutOverflow(rect); } void InlineFlowBox::SetVisualOverflow(const LayoutRect& rect, @@ -1279,10 +1304,13 @@ void InlineFlowBox::SetVisualOverflow(const LayoutRect& rect, if (frame_box.Contains(rect) || rect.IsEmpty()) return; - if (!overflow_) - overflow_ = std::make_unique<SimpleOverflowModel>(frame_box, frame_box); + if (!VisualOverflowIsSet()) { + if (!overflow_) + overflow_ = std::make_unique<SimpleOverflowModel>(); + overflow_->visual_overflow.emplace(frame_box); + } - overflow_->SetVisualOverflow(rect); + overflow_->visual_overflow->SetVisualOverflow(rect); } void InlineFlowBox::SetVisualOverflowFromLogicalRect( @@ -1479,11 +1507,6 @@ LayoutUnit InlineFlowBox::PlaceEllipsisBox(bool ltr, // If our flow is ltr then iterate over the boxes from left to right, // otherwise iterate from right to left. Varying the order allows us to // correctly hide the boxes following the ellipsis. - LayoutUnit relative_offset = - BoxModelObject().IsInline() && BoxModelObject().IsRelPositioned() - ? BoxModelObject().RelativePositionLogicalOffset().Width() - : LayoutUnit(); - logical_left_offset += relative_offset; InlineBox* box = ltr ? FirstChild() : LastChild(); // NOTE: these will cross after foundBox = true. @@ -1513,7 +1536,7 @@ LayoutUnit InlineFlowBox::PlaceEllipsisBox(bool ltr, box = box->PrevOnLine(); } } - return result + relative_offset; + return result; } void InlineFlowBox::ClearTruncation() { |