Commit f93f9f66 authored by Morten Stenshorne's avatar Morten Stenshorne Committed by Commit Bot

[LayoutNG] Inline everything in legacy_layout_tree_walking.h

The functions are simple, and getting rid of the function call overhead should
be a good thing.

Change-Id: I419eaf5726eeacd8e69327f6649d69d717dde11e
Reviewed-on: https://chromium-review.googlesource.com/c/1484782
Commit-Queue: Morten Stenshorne <mstensho@chromium.org>
Reviewed-by: default avatarIan Kilpatrick <ikilpatrick@chromium.org>
Cr-Commit-Position: refs/heads/master@{#635723}
parent 3d02967e
......@@ -401,7 +401,6 @@ blink_core_sources("layout") {
"ng/layout_ng_table_caption.h",
"ng/layout_ng_table_cell.cc",
"ng/layout_ng_table_cell.h",
"ng/legacy_layout_tree_walking.cc",
"ng/legacy_layout_tree_walking.h",
"ng/list/layout_ng_list_item.cc",
"ng/list/layout_ng_list_item.h",
......
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/core/layout/ng/legacy_layout_tree_walking.h"
#include "third_party/blink/renderer/core/layout/ng/layout_ng_block_flow.h"
namespace blink {
// We still have the legacy layout tree structure, which means that a multicol
// container LayoutBlockFlow will consist of a LayoutFlowThread child, followed
// by zero or more siblings of type LayoutMultiColumnSet and/or
// LayoutMultiColumnSpannerPlaceholder. NG needs to skip these special
// objects. The actual content is inside the flow thread.
LayoutObject* GetLayoutObjectForFirstChildNode(LayoutBlock* parent) {
LayoutObject* child = parent->FirstChild();
if (!child)
return nullptr;
if (child->IsLayoutFlowThread())
return ToLayoutBlockFlow(child)->FirstChild();
// The rendered legend is a child of the anonymous wrapper inside the fieldset
// container. If we find it, skip it. As far as NG is concerned, the rendered
// legend is a child of the fieldset container.
if (UNLIKELY(child->IsRenderedLegend()))
return child->NextSibling();
return child;
}
LayoutObject* GetLayoutObjectForParentNode(LayoutObject* object) {
// First check that we're not walking where we shouldn't be walking.
DCHECK(!object->IsLayoutFlowThread());
DCHECK(!object->IsLayoutMultiColumnSet());
DCHECK(!object->IsLayoutMultiColumnSpannerPlaceholder());
LayoutObject* parent = object->Parent();
if (!parent)
return nullptr;
// The parent of the rendered legend is the fieldset container, as far as NG
// is concerned. Skip the anonymous wrapper in-between.
if (UNLIKELY(object->IsRenderedLegend()))
return parent->Parent();
if (parent->IsLayoutFlowThread())
return parent->Parent();
return parent;
}
LayoutObject* GetLayoutObjectForNextSiblingNode(LayoutObject* object) {
// We don't expect to walk the layout tree starting at the rendered legend,
// and we'll skip over it if we find it. The renderered legend will be handled
// by a special algorithm, and should be invisible among siblings.
DCHECK(!object->IsRenderedLegend());
LayoutObject* next = object->NextSibling();
if (!next)
return nullptr;
if (UNLIKELY(next->IsRenderedLegend()))
return next->NextSibling();
return next;
}
bool AreNGBlockFlowChildrenInline(const LayoutBlock* block) {
if (block->ChildrenInline())
return true;
if (const auto* first_child = block->FirstChild()) {
if (first_child->IsLayoutFlowThread())
return first_child->ChildrenInline();
}
return false;
}
bool IsManagedByLayoutNG(const LayoutObject& object) {
if (!object.IsLayoutNGMixin() && !object.IsLayoutNGFlexibleBox())
return false;
const auto* containing_block = object.ContainingBlock();
if (!containing_block)
return false;
return IsLayoutNGContainingBlock(containing_block);
}
bool IsLayoutNGContainingBlock(const LayoutBlock* containing_block) {
if (containing_block->IsLayoutFlowThread())
containing_block = containing_block->ContainingBlock();
return containing_block && (containing_block->IsLayoutNGMixin() ||
containing_block->IsLayoutNGFlexibleBox());
}
} // namespace blink
......@@ -5,38 +5,105 @@
#ifndef LegacyLayoutTreeWalking_h
#define LegacyLayoutTreeWalking_h
namespace blink {
#include "third_party/blink/renderer/core/layout/layout_block_flow.h"
// We still have the legacy layout tree structure, which means that a multicol
// container LayoutBlockFlow will consist of a LayoutFlowThread child, followed
// by zero or more siblings of type LayoutMultiColumnSet and/or
// LayoutMultiColumnSpannerPlaceholder. NG needs to skip these special
// objects. The actual content is inside the flow thread. There are similar
// complications for fieldset / legend.
class LayoutBlock;
class LayoutObject;
namespace blink {
// Return the layout object that should be the first child NGLayoutInputNode of
// |parent|. Normally this will just be the first layout object child, but there
// are certain layout objects that should be skipped for NG.
LayoutObject* GetLayoutObjectForFirstChildNode(LayoutBlock*);
inline LayoutObject* GetLayoutObjectForFirstChildNode(LayoutBlock* parent) {
LayoutObject* child = parent->FirstChild();
if (!child)
return nullptr;
if (child->IsLayoutFlowThread())
return ToLayoutBlockFlow(child)->FirstChild();
// The rendered legend is a child of the anonymous wrapper inside the fieldset
// container. If we find it, skip it. As far as NG is concerned, the rendered
// legend is a child of the fieldset container.
if (UNLIKELY(child->IsRenderedLegend()))
return child->NextSibling();
return child;
}
// Return the layout object that should be the parent NGLayoutInputNode of
// |object|. Normally this will just be the parent layout object, but there
// are certain layout objects that should be skipped for NG.
LayoutObject* GetLayoutObjectForParentNode(LayoutObject*);
inline LayoutObject* GetLayoutObjectForParentNode(LayoutObject* object) {
// First check that we're not walking where we shouldn't be walking.
DCHECK(!object->IsLayoutFlowThread());
DCHECK(!object->IsLayoutMultiColumnSet());
DCHECK(!object->IsLayoutMultiColumnSpannerPlaceholder());
LayoutObject* parent = object->Parent();
if (!parent)
return nullptr;
// The parent of the rendered legend is the fieldset container, as far as NG
// is concerned. Skip the anonymous wrapper in-between.
if (UNLIKELY(object->IsRenderedLegend()))
return parent->Parent();
if (parent->IsLayoutFlowThread())
return parent->Parent();
return parent;
}
// Return the layout object that should be the sibling NGLayoutInputNode of
// |object|. Normally this will just be the next sibling layout object, but
// there are certain layout objects that should be skipped for NG.
LayoutObject* GetLayoutObjectForNextSiblingNode(LayoutObject*);
inline LayoutObject* GetLayoutObjectForNextSiblingNode(LayoutObject* object) {
// We don't expect to walk the layout tree starting at the rendered legend,
// and we'll skip over it if we find it. The renderered legend will be handled
// by a special algorithm, and should be invisible among siblings.
DCHECK(!object->IsRenderedLegend());
LayoutObject* next = object->NextSibling();
if (!next)
return nullptr;
if (UNLIKELY(next->IsRenderedLegend()))
return next->NextSibling();
return next;
}
// Return true if the NGLayoutInputNode children of the NGLayoutInputNode
// established by |block| will be inline; see LayoutObject::ChildrenInline().
bool AreNGBlockFlowChildrenInline(const LayoutBlock*);
// Return true if the layout object is a LayoutNG object that is managed by the
// LayoutNG engine (i.e. its containing block is a LayoutNG object as well).
bool IsManagedByLayoutNG(const LayoutObject&);
inline bool AreNGBlockFlowChildrenInline(const LayoutBlock* block) {
if (block->ChildrenInline())
return true;
if (const auto* first_child = block->FirstChild()) {
if (first_child->IsLayoutFlowThread())
return first_child->ChildrenInline();
}
return false;
}
// Return true if the block is of NG type, or if it's a block invisible to
// LayoutNG and it has an NG containg block. False if it's hosted by the legacy
// layout engine.
bool IsLayoutNGContainingBlock(const LayoutBlock*);
inline bool IsLayoutNGContainingBlock(const LayoutBlock* containing_block) {
if (containing_block->IsLayoutFlowThread())
containing_block = containing_block->ContainingBlock();
return containing_block && (containing_block->IsLayoutNGMixin() ||
containing_block->IsLayoutNGFlexibleBox());
}
// Return true if the layout object is a LayoutNG object that is managed by the
// LayoutNG engine (i.e. its containing block is a LayoutNG object as well).
inline bool IsManagedByLayoutNG(const LayoutObject& object) {
if (!object.IsLayoutNGMixin() && !object.IsLayoutNGFlexibleBox())
return false;
const auto* containing_block = object.ContainingBlock();
if (!containing_block)
return false;
return IsLayoutNGContainingBlock(containing_block);
}
} // namespace blink
......
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