Commit f98d25da authored by Koji Ishii's avatar Koji Ishii Committed by Chromium LUCI CQ

Add |NGPhysicalBoxFragment::IsOutlineOwner|

This patch adds |NGPhysicalBoxFragment::IsOutlineOwner|, by
moving the logic from a static function in |NGOutlineUtils|.

By exposing the |InlineContainerFragmentIfOutlineOwner|,
|AddOutlineRectsForInlineBox| no longer needs to traverse
all fragments. Instead, it now creates an |NGInlineCursor|
only for the container fragment.

This patch has no behavior changes.

Bug: 1145048
Change-Id: Ia4a084d5708d870a38800bed3494bcd869daf175
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2567842
Auto-Submit: Koji Ishii <kojii@chromium.org>
Reviewed-by: default avatarYoshifumi Inoue <yosin@chromium.org>
Reviewed-by: default avatarKent Tamura <tkent@chromium.org>
Commit-Queue: Kent Tamura <tkent@chromium.org>
Commit-Queue: Koji Ishii <kojii@chromium.org>
Cr-Commit-Position: refs/heads/master@{#832693}
parent 9c3ad397
......@@ -21,35 +21,4 @@ bool NGOutlineUtils::HasPaintedOutline(const ComputedStyle& style,
return true;
}
bool NGOutlineUtils::ShouldPaintOutline(
const NGPhysicalBoxFragment& physical_fragment) {
if (!physical_fragment.IsInlineBox())
return true;
// In order to compute united outlines, collect all rectangles of inline
// fragments for |LayoutInline| if |this| is the first inline fragment.
// Otherwise return none.
const LayoutObject* layout_object = physical_fragment.GetLayoutObject();
DCHECK(layout_object);
DCHECK(layout_object->IsLayoutInline());
NGInlineCursor cursor;
cursor.MoveTo(*layout_object);
DCHECK(cursor);
if (cursor.Current().BoxFragment() == &physical_fragment)
return true;
if (!cursor.IsBlockFragmented())
return false;
// When |LayoutInline| is block fragmented, unite rectangles for each block
// fragment. To do this, return |true| if |this| is the first inline fragment
// of a block fragment.
while (true) {
wtf_size_t fragment_index = cursor.ContainerFragmentIndex();
cursor.MoveToNextForSameLayoutObject();
DCHECK(cursor);
if (cursor.Current().BoxFragment() == &physical_fragment)
return fragment_index != cursor.ContainerFragmentIndex();
}
}
} // namespace blink
......@@ -12,19 +12,12 @@ namespace blink {
class ComputedStyle;
class Node;
class NGPhysicalBoxFragment;
class CORE_EXPORT NGOutlineUtils {
STATIC_ONLY(NGOutlineUtils);
public:
static bool HasPaintedOutline(const ComputedStyle& style, const Node* node);
// Returns true if this fragment should paint an outline.
//
// Specifically a |LayoutInline| can be split across multiple flows. The
// first fragment produced should paint the outline for *all* fragments.
static bool ShouldPaintOutline(const NGPhysicalBoxFragment&);
};
} // namespace blink
......
......@@ -653,6 +653,39 @@ PhysicalSize NGPhysicalBoxFragment::ScrollSize() const {
return {box->ScrollWidth(), box->ScrollHeight()};
}
const NGPhysicalBoxFragment*
NGPhysicalBoxFragment::InlineContainerFragmentIfOutlineOwner() const {
DCHECK(IsInlineBox());
// In order to compute united outlines, collect all rectangles of inline
// fragments for |LayoutInline| if |this| is the first inline fragment.
// Otherwise return none.
const LayoutObject* layout_object = GetLayoutObject();
DCHECK(layout_object);
DCHECK(layout_object->IsLayoutInline());
NGInlineCursor cursor;
cursor.MoveTo(*layout_object);
DCHECK(cursor);
if (cursor.Current().BoxFragment() == this)
return &cursor.ContainerFragment();
if (!cursor.IsBlockFragmented())
return nullptr;
// When |LayoutInline| is block fragmented, unite rectangles for each block
// fragment. To do this, return |true| if |this| is the first inline fragment
// of a block fragment.
for (wtf_size_t previous_fragment_index = cursor.ContainerFragmentIndex();;) {
cursor.MoveToNextForSameLayoutObject();
DCHECK(cursor);
const wtf_size_t fragment_index = cursor.ContainerFragmentIndex();
if (cursor.Current().BoxFragment() == this) {
if (fragment_index != previous_fragment_index)
return &cursor.ContainerFragment();
return nullptr;
}
previous_fragment_index = fragment_index;
}
}
PhysicalRect NGPhysicalBoxFragment::ComputeSelfInkOverflow() const {
DCHECK_EQ(PostLayout(), this);
CheckCanUpdateInkOverflow();
......@@ -663,8 +696,7 @@ PhysicalRect NGPhysicalBoxFragment::ComputeSelfInkOverflow() const {
DCHECK(GetLayoutObject());
PhysicalRect ink_overflow(LocalRect());
ink_overflow.Expand(style.BoxDecorationOutsets());
if (NGOutlineUtils::HasPaintedOutline(style, GetNode()) &&
NGOutlineUtils::ShouldPaintOutline(*this)) {
if (NGOutlineUtils::HasPaintedOutline(style, GetNode()) && IsOutlineOwner()) {
Vector<PhysicalRect> outline_rects;
// The result rects are in coordinates of this object's border box.
AddSelfOutlineRects(PhysicalOffset(),
......@@ -705,7 +737,7 @@ void NGPhysicalBoxFragment::AddOutlineRects(
inline_container_relative, outline_rects);
return;
}
DCHECK(NGOutlineUtils::ShouldPaintOutline(*this));
DCHECK(IsOutlineOwner());
// For anonymous blocks, the children add outline rects.
if (!IsAnonymousBlock())
......@@ -743,7 +775,9 @@ void NGPhysicalBoxFragment::AddOutlineRectsForInlineBox(
DCHECK_EQ(PostLayout(), this);
DCHECK(IsInlineBox());
if (!NGOutlineUtils::ShouldPaintOutline(*this))
const NGPhysicalBoxFragment* container =
InlineContainerFragmentIfOutlineOwner();
if (!container)
return;
// In order to compute united outlines, collect all rectangles of inline
......@@ -756,27 +790,17 @@ void NGPhysicalBoxFragment::AddOutlineRectsForInlineBox(
DCHECK(GetLayoutObject()->IsLayoutInline());
const auto* layout_object = To<LayoutInline>(GetLayoutObject());
const wtf_size_t initial_rects_size = rects->size();
NGInlineCursor cursor;
NGInlineCursor cursor(*container);
cursor.MoveTo(*layout_object);
DCHECK(cursor);
wtf_size_t fragment_index = cursor.ContainerFragmentIndex();
#if DCHECK_IS_ON()
bool has_this_fragment = false;
for (;; cursor.MoveToNextForSameLayoutObject()) {
if (!cursor) {
DCHECK(has_this_fragment);
break;
}
if (fragment_index != cursor.ContainerFragmentIndex()) {
// If this block fragment has |this|, exit the loop.
if (has_this_fragment)
break;
// Otherwise clear the result and continue to the next block fragment.
fragment_index = cursor.ContainerFragmentIndex();
rects->Shrink(initial_rects_size);
}
#endif
for (; cursor; cursor.MoveToNextForSameLayoutObject()) {
const NGInlineCursorPosition& current = cursor.Current();
#if DCHECK_IS_ON()
has_this_fragment = has_this_fragment || current.BoxFragment() == this;
#endif
if (!current.Size().IsZero())
rects->push_back(current.RectInContainerFragment());
......@@ -787,6 +811,9 @@ void NGPhysicalBoxFragment::AddOutlineRectsForInlineBox(
AddOutlineRectsForCursor(rects, PhysicalOffset(), outline_type,
layout_object, &descendants);
}
#if DCHECK_IS_ON()
DCHECK(has_this_fragment);
#endif
DCHECK_GE(rects->size(), initial_rects_size);
if (rects->size() <= initial_rects_size)
return;
......
......@@ -226,6 +226,13 @@ class CORE_EXPORT NGPhysicalBoxFragment final
const HitTestLocation& hit_test_location,
const PhysicalOffset& accumulated_offset) const;
// In order to paint united outline rectangles, the "owner" fragment paints
// outlines for non-owner fragments.
bool IsOutlineOwner() const {
return !IsInlineBox() || InlineContainerFragmentIfOutlineOwner();
}
const NGPhysicalBoxFragment* InlineContainerFragmentIfOutlineOwner() const;
// Returns the |ComputedStyle| to use for painting outlines. When |this| is
// a block in a continuation-chain, it may need to paint outlines if its
// ancestor inline boxes in the DOM tree has outlines.
......
......@@ -12,7 +12,6 @@
#include "third_party/blink/renderer/core/layout/ng/inline/ng_ruby_utils.h"
#include "third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.h"
#include "third_party/blink/renderer/core/layout/ng/ng_layout_overflow_calculator.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/core/layout/ng/ng_relative_utils.h"
#include "third_party/blink/renderer/platform/geometry/layout_rect.h"
......@@ -360,7 +359,7 @@ void NGPhysicalContainerFragment::AddOutlineRectsForDescendant(
// 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::ShouldPaintOutline(*descendant_box)) {
if (descendant_box->IsOutlineOwner()) {
// We don't pass additional_offset here because the function requires
// additional_offset to be the offset from the containing block.
descendant_layout_inline->AddOutlineRectsForChildrenAndContinuations(
......
......@@ -25,7 +25,6 @@
#include "third_party/blink/renderer/core/layout/ng/ng_fragment.h"
#include "third_party/blink/renderer/core/layout/ng/ng_ink_overflow.h"
#include "third_party/blink/renderer/core/layout/ng/ng_outline_type.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/core/layout/ng/ng_physical_container_fragment.h"
#include "third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h"
......
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