Commit 12e458fa authored by Koji Ishii's avatar Koji Ishii Committed by Commit Bot

[LayoutNG] Match AddSelfOutlineRects to legacy

For AddSelfOutlineRects to reach to LayoutInline that has
a continuation, this patch splits the logic in
AddSelfOutlineRects so that it can be called recursively.

In doing so, the logic flow and functions are organized to
match to the one in LayoutObject tree.

Bug: 889721
Cq-Include-Trybots: luci.chromium.try:linux_layout_tests_layout_ng
Change-Id: I79e00ea7c37c94bf06e564a69fe7fc5da4f72349
Reviewed-on: https://chromium-review.googlesource.com/1246881
Commit-Queue: Koji Ishii <kojii@chromium.org>
Reviewed-by: default avatarAleks Totic <atotic@chromium.org>
Cr-Commit-Position: refs/heads/master@{#595028}
parent c0a0eff7
......@@ -351,7 +351,6 @@ crbug.com/807708 fast/css-intrinsic-dimensions/width-avoid-floats.html [ Failure
crbug.com/591099 fast/css/absolute-inline-alignment-2.html [ Pass ]
crbug.com/591099 fast/css/case-transform.html [ Failure ]
crbug.com/835484 fast/css/focus-ring-recursive-continuations.html [ Failure ]
crbug.com/835484 fast/css/focus-ring-recursive-inlines.html [ Failure ]
crbug.com/591099 fast/css/getComputedStyle/computed-style-percentage-top-with-position-inline.html [ Failure ]
crbug.com/835484 fast/css/outline-auto-empty-rects.html [ Failure ]
crbug.com/835484 fast/css/outline-narrowLine.html [ Failure ]
......
......@@ -5,7 +5,7 @@
#include "third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h"
#include "third_party/blink/renderer/core/editing/position_with_affinity.h"
#include "third_party/blink/renderer/core/layout/layout_box.h"
#include "third_party/blink/renderer/core/layout/layout_block_flow.h"
#include "third_party/blink/renderer/core/layout/layout_inline.h"
#include "third_party/blink/renderer/core/layout/layout_object.h"
#include "third_party/blink/renderer/core/layout/layout_object_inlines.h"
......@@ -77,6 +77,12 @@ bool NGPhysicalBoxFragment::ShouldClipOverflow() const {
ToLayoutBox(layout_object)->ShouldClipOverflow();
}
bool NGPhysicalBoxFragment::HasControlClip() const {
const LayoutObject* layout_object = GetLayoutObject();
DCHECK(layout_object);
return layout_object->IsBox() && ToLayoutBox(layout_object)->HasControlClip();
}
LayoutRect NGPhysicalBoxFragment::OverflowClipRect(
const LayoutPoint& location,
OverlayScrollbarClipBehavior overlay_scrollbar_clip_behavior) const {
......@@ -150,14 +156,11 @@ void NGPhysicalBoxFragment::AddSelfOutlineRects(
Vector<LayoutRect>* outline_rects,
const LayoutPoint& additional_offset,
NGOutlineType outline_type) const {
DCHECK(GetLayoutObject());
// TODO(kojii): Needs inline_element_continuation logic from
// LayoutBlockFlow::AddOutlineRects?
const LayoutObject* layout_object = GetLayoutObject();
if (!layout_object->IsAnonymousBlock() && !layout_object->IsLayoutInline()) {
LayoutRect outline_rect(additional_offset, Size().ToLayoutSize());
outline_rects->push_back(outline_rect);
}
DCHECK(layout_object);
if (layout_object->IsLayoutInline()) {
Vector<LayoutRect> blockflow_outline_rects;
ToLayoutInline(layout_object)
......@@ -174,46 +177,24 @@ void NGPhysicalBoxFragment::AddSelfOutlineRects(
}
return;
}
if (!layout_object->IsBox())
return;
if (outline_type == NGOutlineType::kDontIncludeBlockVisualOverflow)
return;
if (HasOverflowClip() && ToLayoutBox(layout_object)->HasControlClip())
return;
DCHECK(layout_object->IsBox());
for (const auto& child : Children()) {
// List markers have no outline
if (child->IsListMarker())
continue;
if (child->IsLineBox()) {
// Traverse children of the linebox
Vector<NGPhysicalFragmentWithOffset> line_children =
NGInlineFragmentTraversal::DescendantsOf(
ToNGPhysicalLineBoxFragment(*child));
for (const auto& line_child : line_children) {
Vector<LayoutRect> line_child_rects;
line_child_rects.push_back(
line_child.RectInContainerBox().ToLayoutRect());
DCHECK(line_child.fragment->GetLayoutObject());
line_child.fragment->GetLayoutObject()->LocalToAncestorRects(
line_child_rects, ToLayoutBoxModelObject(GetLayoutObject()),
child.Offset().ToLayoutPoint(), additional_offset);
if (!line_child_rects.IsEmpty())
outline_rects->push_back(line_child_rects[0]);
}
} else {
DCHECK(child->GetLayoutObject());
LayoutObject* child_layout = child->GetLayoutObject();
Vector<LayoutRect> child_rects;
child_rects.push_back(child->InkOverflow().ToLayoutRect());
child_layout->LocalToAncestorRects(
child_rects, ToLayoutBoxModelObject(GetLayoutObject()), LayoutPoint(),
additional_offset);
if (!child_rects.IsEmpty())
outline_rects->push_back(child_rects[0]);
}
// For anonymous blocks, the children add outline rects.
if (!layout_object->IsAnonymous()) {
outline_rects->emplace_back(additional_offset, Size().ToLayoutSize());
}
if (outline_type == NGOutlineType::kIncludeBlockVisualOverflow &&
!HasOverflowClip() && !HasControlClip()) {
AddOutlineRectsForNormalChildren(outline_rects, additional_offset,
outline_type);
// TODO(kojii): LayoutBlock::AddOutlineRects handles positioned objects
// here. Do we need it?
}
// TODO(kojii): Needs inline_element_continuation logic from
// LayoutBlockFlow::AddOutlineRects?
}
NGPhysicalOffsetRect NGPhysicalBoxFragment::InkOverflow(bool apply_clip) const {
......
......@@ -49,6 +49,7 @@ class CORE_EXPORT NGPhysicalBoxFragment final
// overflow clip; i.e., AllowOverflowClip() returns false.
bool HasOverflowClip() const;
bool ShouldClipOverflow() const;
bool HasControlClip() const;
NGPhysicalOffsetRect ScrollableOverflow() const;
......
......@@ -4,6 +4,13 @@
#include "third_party/blink/renderer/core/layout/ng/ng_physical_container_fragment.h"
#include "third_party/blink/renderer/core/layout/layout_block_flow.h"
#include "third_party/blink/renderer/core/layout/layout_inline.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment.h"
#include "third_party/blink/renderer/core/layout/ng/ng_outline_utils.h"
#include "third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h"
#include "third_party/blink/renderer/platform/geometry/layout_rect.h"
namespace blink {
NGPhysicalContainerFragment::NGPhysicalContainerFragment(
......@@ -28,4 +35,91 @@ NGPhysicalContainerFragment::NGPhysicalContainerFragment(
DCHECK(children.IsEmpty()); // Ensure move semantics is used.
}
void NGPhysicalContainerFragment::AddOutlineRectsForNormalChildren(
Vector<LayoutRect>* outline_rects,
const LayoutPoint& additional_offset,
NGOutlineType outline_type) const {
for (const auto& child : Children()) {
// Outlines of out-of-flow positioned descendants are handled in
// NGPhysicalBoxFragment::AddSelfOutlineRects().
if (child->IsOutOfFlowPositioned())
continue;
// Outline of an element continuation or anonymous block continuation is
// added when we iterate the continuation chain.
// See NGPhysicalBoxFragment::AddSelfOutlineRects().
if (LayoutObject* child_layout_object = child->GetLayoutObject()) {
if (child_layout_object->IsElementContinuation() ||
(child_layout_object->IsLayoutBlockFlow() &&
ToLayoutBlockFlow(child_layout_object)
->IsAnonymousBlockContinuation()))
continue;
}
AddOutlineRectsForDescendant(child, outline_rects, additional_offset,
outline_type);
}
}
void NGPhysicalContainerFragment::AddOutlineRectsForDescendant(
const NGLink& descendant,
Vector<LayoutRect>* outline_rects,
const LayoutPoint& additional_offset,
NGOutlineType outline_type) const {
if (descendant->IsText() || descendant->IsListMarker())
return;
if (const NGPhysicalBoxFragment* descendant_box =
ToNGPhysicalBoxFragmentOrNull(descendant.get())) {
LayoutObject* descendant_layout_object = descendant_box->GetLayoutObject();
DCHECK(descendant_layout_object);
if (descendant_box->HasLayer()) {
Vector<LayoutRect> layer_outline_rects;
descendant_box->AddSelfOutlineRects(&layer_outline_rects, LayoutPoint(),
outline_type);
descendant_layout_object->LocalToAncestorRects(
layer_outline_rects, ToLayoutBoxModelObject(GetLayoutObject()),
LayoutPoint(), additional_offset);
outline_rects->AppendVector(layer_outline_rects);
return;
}
if (descendant_layout_object->IsBox()) {
descendant_box->AddSelfOutlineRects(
outline_rects,
additional_offset + descendant.Offset().ToLayoutPoint(),
outline_type);
return;
}
DCHECK(descendant_layout_object->IsLayoutInline());
LayoutInline* descendant_layout_inline =
ToLayoutInline(descendant_layout_object);
// As an optimization, an ancestor has added rects for its line boxes
// covering descendants' line boxes, so descendants don't need to add line
// boxes again. For example, if the parent is a LayoutBlock, it adds rects
// for its line box which cover the line boxes of this LayoutInline. So
// the LayoutInline needs to add rects for children and continuations
// only.
if (!NGOutlineUtils::IsInlineOutlineNonpaintingFragment(*descendant)) {
descendant_layout_inline->AddOutlineRectsForChildrenAndContinuations(
*outline_rects, additional_offset, outline_type);
}
return;
}
if (const NGPhysicalLineBoxFragment* descendant_line_box =
ToNGPhysicalLineBoxFragmentOrNull(descendant.get())) {
descendant_line_box->AddOutlineRectsForNormalChildren(
outline_rects, additional_offset + descendant.Offset().ToLayoutPoint(),
outline_type);
if (!descendant_line_box->Size().IsEmpty()) {
outline_rects->emplace_back(additional_offset,
descendant_line_box->Size().ToLayoutSize());
}
}
}
} // namespace blink
......@@ -13,6 +13,8 @@
namespace blink {
enum class NGOutlineType;
class CORE_EXPORT NGPhysicalContainerFragment : public NGPhysicalFragment {
public:
const Vector<NGLink>& Children() const { return children_; }
......@@ -22,6 +24,14 @@ class CORE_EXPORT NGPhysicalContainerFragment : public NGPhysicalFragment {
return contents_ink_overflow_;
}
void AddOutlineRectsForNormalChildren(Vector<LayoutRect>* outline_rects,
const LayoutPoint& additional_offset,
NGOutlineType outline_type) const;
void AddOutlineRectsForDescendant(const NGLink& descendant,
Vector<LayoutRect>* rects,
const LayoutPoint& additional_offset,
NGOutlineType outline_type) const;
protected:
// This modifies the passed-in children vector.
NGPhysicalContainerFragment(LayoutObject*,
......
......@@ -278,7 +278,7 @@ Node* NGPhysicalFragment::GetNode() const {
}
bool NGPhysicalFragment::HasLayer() const {
return layout_object_->HasLayer();
return layout_object_ && layout_object_->HasLayer();
}
PaintLayer* NGPhysicalFragment::Layer() const {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment